.TITLE MCE - CLI-Commandline-Editor ; .IDENT -V4.22- ; this identcode appears in MCE messages ; .ENABLE LC ; ; Copyright (c) 1988 ; ; J.H. Hamakers, ; Asea Brown Boveri Industie b.v. ; P.O.Box 301 ; 3000 AH Rotterdam ; The Netherlands ; Phone : +31 - 10 - 4078631 ; ; All rights reserved ; ; This software may be copied and distributed ONLY ; on a non profit basis and with the inclusion of ; the above copyright statement. ; ; PLEASE CONTACT ME FOR PROBLEMS OR SUGGESTIONS ; ; +---------------------------------------------------+ ; | See MCEREL.DOC for information about this release | ; +---------------------------------------------------+ ; ; Test the ident of MCEPRE.MAC ..... ; .IF NDF IDNPRE .ERROR ;MCE -- MCEPRE.MAC not compatible with this version of MCE. .ERROR ; Please build again. .IFF .IF NE IDNPRE-4. .ERROR ;MCE -- MCEPRE.MAC not compatible with this version of MCE. .ERROR ; Please build again. .ENDC .ENDC ; .SBTTL MCE ----------- *** Macros, Constants, Variables etc. *** ; ; Psects used ..... ; .PSECT CODE ,I,RO .PSECT IDATA,D,RW .PSECT PDATA,D,RO .PSECT ; ; Macro calls ..... ; .MCALL DIR$ ,EXIT$S ,MRKT$S ,QIO$ ,SDIR$S .MCALL SPWN$ ,SREX$S ,STSE$ ,STSE$S ,WTSE$ .IF DF FILE .MCALL CSI$ ,CSI$1 ,CSI$2 .MCALL GET$S ,CLOSE$ ,GMCR$ ,NMBLK$ ,OPEN$R .MCALL FDBDF$ ,FDRC$A ,FDOP$A ,FSRSZ$ .ENDC ;FILE .IIF DF CLISUP!FILE .MCALL GCII$ .IIF DF RTMESS!RTEXIT!TMOTIM .MCALL GLUN$S .IIF DF TMOTIM .MCALL ASTX$S .IIF DF STATUS&TMOTIM .MCALL QIOW$S ; ; Local symbol definitions ..... ; CMDSIZ = 78. ; BELL = 7 BKSP = 10 LF = 12 CR = 15 ESC = 33 BLNK = 40 DEL = 177 ; TI = 1 ; TI: LUN INILUN = 2 ; MCEINI.xxx LUN EFN = 1 ; Eventflag .IF DF STATUS&TMOTIM EFNAST = 2 ; Eventflag in TIMAST .ENDC ;STATUS&TMOTIM .IIF NDF INSDEF INSDEF = 0 .IIF NDF INTDEF INTDEF = 1 .IIF NDF MAXFIF MAXFIF = 22. .IIF NDF MINCHR MINCHR = 1 .IIF NDF OLDDEF OLDDEF = 1 .IIF NDF OVSDEF OVSDEF = 0 .IIF DF EDT .IIF NDF EDTDEF EDTDEF = 0 .IIF DF EXTNPR .IIF NDF PRMDEF PRMDEF = 1 .IIF DF STATUS .IIF NDF STADEF STADEF = 1 .NLIST BEX .MACRO NEWLIN Z .IF B Z .ASCII .IFF .ASCIZ .ENDC .ENDM NEWLIN ; ; Stopfor/Waitfor I/O DPBs ..... ; ; Normally we STOP for I/O. When MCE is aborted we WAIT for I/O. ; We use the WTSE$ directive here to copy the DIC-code to STOPIO. ; (See EXAST:) ; .PSECT PDATA WAITIO: WTSE$ .PSECT IDATA STOPIO: STSE$ EFN ; ; DBPs ..... ; .IF DF COMPND SPAWN: SPWN$ ,,,,,,,EXSTAT .IFF ;COMPND SPAWN: SPWN$ .ENDC ;COMPND ; TASK = SPAWN+S.PWTN ; Taskname WAITFL = SPAWN+S.PWEF ; Event flag $$$=. .=TASK .IF DF CLISUP .RAD50 \CLI...\ ; Current CLI .IFF ;CLISUP .RAD50 \MCR...\ ; Task for Systems without alternate CLI-Supp. .ENDC ;CLISUP .=$$$ ; QIODIR: QIO$ ,TI,EFN,,IOSTAT ; ADR = QIODIR+Q.IOPL ; I/O Bufferaddress CODE = QIODIR+Q.IOFN ; I/O Functioncode LEN = QIODIR+Q.IOPL+2 ; I/O length ; ( Also used for Spawn ) ; ; File stuff ..... ; .IF DF FILE FSRSZ$ 1 ; File storage region .PSECT IDATA ; ; FDB for MCEINI files ..... ; FDBIN: FDBDF$ FDRC$A ,CMDBUF ,CMDSIZ FDOP$A INILUN ,FDSPT ,NAMBLK ,FO.RD ; ; Descriptor dispatch table ..... ; FDSPT: DEVL ,DEV ; Device string FDIR: DIRL ,DIR ; Directory string at startup 0 ,0 ; No File name ( NAMBLK will be used ) ; ; Descriptors ..... ; ; Device descriptor in RW data section for it can be overwritten ; DEV: .ASCII /LB:/ ; Device Name DEVL = .-DEV .EVEN .PSECT PDATA .IF DF A$SV DIR: .ASCII /[2,2]/ .IFF ;A$SV DIR: .ASCII /[1,2]/ .ENDC ;A$SV DIRL = .-DIR .EVEN .PSECT IDATA ; ; Default startup filename block ..... ; ; Default filename ( if no alternate CLI support ) is 'MCEINI.CMD'. ; Default device is SY: ( but superimposed by LB: in FDSPT ). ; SY: in the NAMBLK will be effective for files specified in the ; invoking MCR/DCL commandline. Specifying 'MCE XXX' thus results in ; file name 'SY0:XXX.CMD'. ; Note, that the filetype in NAMBLK will be overwritten by the CLI name. ; ( See GETCLI ) ; NAMBLK: NMBLK$ MCEINI ,CMD ,0 ,SY ,0 ; FILTYP = NAMBLK+N.FTYP ; Address of RAD-50 filetype ; ; CSI$ Control block ..... ; CSIBLK: CSI$ ; Define CSI control block offsets .BLKB C.SIZE .EVEN .ENDC ;FILE ; ; Variable textstrings ..... ; ; These textstrings are in RW Psects for they are dynamicly changed. ; ; ; - Pool information ... ; POOLTX: .ASCII /MCE -- Pool:/ POOLDT: .BLKB 18. ; ; - Startup text ... ; .IF DF CLISUP STRTXT: .ASCII \MCE -- CLI-Commandline-Editor \ .IFF ;CLISUP STRTXT: .ASCII \MCE -- MCR-Commandline-Editor \ .ENDC ;CLISUP IDENT: .ASCII \ \ ; Ident will be placed here .IIF DF A$SV .ASCII \/ASV\ .IIF DF VT2XX .ASCII \/VT2\ .IIF DF TDV2XX .ASCII \/TDV\ NEWLIN Z ; ; - Help spawn string ... ; HLPTXT: .ASCII \HELP \ .IIF DF HLPNEW .ASCII \/\ .IIF DF A$SV .ASCII \ASV \ .ASCII \MCE\ HPAG0: .ASCII <0>\MCE\ HPAGE: .ASCIZ \ \ .IF DF COMPND ; ; - Terminating a compound commandline ... ; EXSTMS: NEWLIN .ASCII \MCE -- Terminated Compound Commandline, Exit status :\ EXSTDA: .ASCII \ \ NEWLIN .ASCII \ --->\ EXSTML=.-EXSTMS .ENDC ;COMPND .IF DF STATUS ; ; - Statusline ... ; STATX1: .ASCII "D" .ASCII "M" STATX2: .ASCII "7" .ASCII "[1;23r" .ASCII "[24;1H" .ASCII "[7m" STATX3: .ASCII "MCE-" IDENT2: .ASCII " FIFO:" STALIR: .ASCII "list/" .ASCII "xx/" .ASCII "xx/" .ASCII "xx CMSZ:" STACMD: .ASCII "xx KEYP:" STAKEY: .ASCII "no SVINT:" STASVI: .ASCII "xxx SVOLD:" STASVR: .ASCII "xxx TMO:" STATMO: .ASCII "no " STALN3=.-STATX3 .ASCII "[K" .ASCII "[m" .ASCII "8" STALN2=.-STATX2 STALN1=.-STATX1 ; ; - Statusline clear .. ; STACLR: .ASCII "7" .ASCII "[1;24r" .ASCII "8" .ASCII "[J" STACLN=.-STACLR .ENDC ;STATUS .EVEN .PSECT PDATA ; ; Permanent strings ..... ; BS: .REPT CMDSIZ ; Backspace buffer for .ASCII ; cursor positioning .ENDR ; ; SCRCLR: .ASCII "[H" ; Clear .ASCII "[J" ; screen SCRCLL=.-SCRCLR ; ; ; - Various messages ... ; BYETXT: .ASCIZ /BYE/ ENDTXT: NEWLIN ; Exit EXITXT: .ASCIZ /MCE -- Exit/ ; message ERRTXT: NEWLIN .ASCIZ /MCE -- Internal command error/ CRET: ; Only NOPOOL: NEWLIN .ASCIZ /MCE -- Pool exhausted - Install MCE with INC/ TOOLON: NEWLIN .ASCIZ /MCE -- Command too long/ .IF DF EDT APLTXT: .ASCII /=/ EDTTXT: .ASCII \HELP \ .IIF DF HLPNEW .ASCII \/\ .IIF DF A$SV .ASCII \ASV \ .ASCIZ \MCE KEYPAD\ INV: .ASCII /[7m/ INVL =.-INV NOR: .ASCII /[m/ NORL =.-NOR NUMTXT: .ASCII />/ .ENDC ;EDT .IF DF FILE FLSTXT: NEWLIN .ASCIZ /MCE -- Filespecification syntax error/ FILTXT: NEWLIN .ASCIZ /MCE -- File open error/ .ENDC ;FILE .IF LT MAXHLP-'A ; ; - This text is needed when MCE is not build together with a HELP-file ... ; NOHTXT: NEWLIN .ASCII /MCE -- No information about number of HELP pages, / .ASCII /so cannot use NXT and PRV keys/ NEWLIN .ASCII / Generate MCE.HLP and MCE.TSK together with / .ASCII /MCEBLD.CMD/ NOHLEN=.-NOHTXT .ENDC ;MAXHLP-'A ; ; - RT: Messages ... ; .IF DF RTEXIT RTTXT: NEWLIN .ASCII /MCE -- Started on a remote terminal (RT:) Exiting ...../ NEWLIN RTTXTL=.-RTTXT .ENDC ;RTEXIT .IF DF RTMESS RTTXT: NEWLIN .ASCII /MCE -- ** WARNING ** Started on a remote terminal (RT:)/ NEWLIN .ASCII / If your local system is VMS with its commandline editor/ NEWLIN .ASCII / enabled please type "MCE EXIT"/ NEWLIN RTTXTL=.-RTTXT .ENDC ;RTMESS .IF DF VT2XX VT2ESQ: .ASCII /[23~/ ; VT2XX Picture VT2ESL = .-VT2ESQ ; .ENDC ;VT2XX .EVEN ; ; Internal MCE command dispatch table ..... ; ( See subroutine INTERN ) ; INTCMD: .ASCII /CLEA/ ; Clear FIFO ICCLEA .ASCII /CMSZ/ ; Minimum cmd size ICCMSZ .ASCII /ECHO/ ; Echo commandline ICECHO .ASCII /EXIT/ ; Task exit EXIT .ASCII /FISZ/ ; FIFO maximum ICFISZ .ASCII /FREE/ ; Free poolspace ICFREE .ASCII /INSE/ ; Auto insert mode ICINSE .ASCII /LIST/ ; FIFO is a list ICLIST .ASCII /OVER/ ; Auto overstrike mode ICOVER .ASCII /PURG/ ; Delete all command translations ICPURG .ASCII /RING/ ; FIFO is a ringbuffer ICRING .ASCII /SVIN/ ; Save Internal commands on/off ICSVIN .ASCII /SVOL/ ; Save Old commands on/off ICSVOL .ASCII /VERS/ ; Version ICVERS .IF DF EDT .ASCII /KEYP/ ICKEYP .ENDC ;EDT .IF DF EXTNPR .ASCII /PROM/ ICPROM .ENDC ;EXTNPR .IF DF FILE .ASCII /CHAI/ ; Chain to other file (= READ) ICREAD .ASCII /READ/ ; Read definition file 'MCE READ filespc' ICREAD .ASCII /REPL/ ; Replace translations by new file ICREPL .ENDC ;FILE .IF DF STATUS .ASCII /STAT/ ; Status line on/off ICSTAT .ENDC ;STATUS 0 ; End of table marker .PSECT IDATA ; ; Various variables and buffers ..... ; FREE: .BLKW 2 ; Free memory listhead IOSTAT: .BLKW 2 ; I/O Statusblock MAXF: MAXFIF ; FIFO size MINC: MINCHR ; Commandlength to be saved POOL: .BLKW 3 ; Pool information PROMLF: DEFPR ; Point to default prompt with PROMPT: DEFPR+1 ; Point to default prompt with .IF DF COMPND EXSTAT: .BLKW 8. ; Exit status block .ENDC ;COMPND .IF DF EDT SELSTR: 0 ; Address of select start .ENDC ;EDT .IF DF TMOTIM!RTMESS!RTEXIT GLUNB: .BLKW 6. .ENDC ;TMOTIM!RTMESS!RTEXIT ; ; Flags, buffers and other bytes ..... ; CHAR: .BYTE 0 ; Input-character ECHFLG: .BYTE 0 ; If ne : Echo commandline INSFLG: .BYTE INSDEF ; If ne : Auto insert ; - change with MCE INSErt on/off LEAFLG: .BYTE 0 ; If ne : Leave FIFO pointer ( CTRL/X ) NEXFLG: .BYTE 0 ; If ne : Don't execute Command ( CTRL/N ) NLOFLG: .BYTE 0 ; If ne : Don't load Command in Commandbuffer OLDFLG: .BYTE 0 ; If ne : Old command , not edited OVSFLG: .BYTE OVSDEF ; If ne : Auto overstike ; - change with MCE OVERstrike on/off MODFLG: .BYTE OVSDEF ; If odd: Overstrike mode ; - change with ^A PRIFLG: .BYTE 0 ; If ne : Commandbuffer being printout RNGFLG: .BYTE 0 ; If ne : FIFO is a ringbuffer ; - change with MCE LIST/RING SINFLG: .BYTE INTDEF ; If ne : Internal commands are saved ; - change with MCE SVINtern on/off SOLFLG: .BYTE OLDDEF ; If ne : Old commands are saved ; - change with MCE SVOLd on/off .IF DF EDT EDTFLG: .BYTE EDTDEF ; If ne : EDT Mode active ; - change with MCE KEYPad on/off GOLDFL: .BYTE 0 ; If ne : "GOLD" pushed PSTBUF: .BLKB CMDSIZ ; Paste buffer PSTLEN: .BYTE 0 ; Length of string in Paste buffer SELFLG: .BYTE 0 ; if ne : Ansi-selective range active .ENDC ;EDT .IF DF EXTNPR PRMFLG: .BYTE PRMDEF ; if ne : extended prompt .ENDC ;EXTNPR .IF DF FILE FILINI: .BYTE 0 ; If ne : Startup file being processed FILINP: .BYTE 0 ; If ne : File Input FILREX: .BYTE 0 ; If ne : MCE Read or MCE Replace being ; processed .ENDC ;FILE .IF DF STATUS STAFLG: .BYTE STADEF ; If ne : Status line is displayed ; - change with MCE STATus on/off .ENDC ;STATUS .IF DF TMOTIM TMOCNT: .BYTE TMOTIM ; Counter for timeout TT0FLG: .BYTE 0 ; If ne : TI: = TT0: .ENDC ;TMOTIM .EVEN ; ; FIFO Buffer descriptors ..... ; FIFO: 0, FIFO ; Header FIFO Buffer ; F.1ST = 0 ; Pointer to first entry F.LAST = 2 ; Pointer to last entry ; FI.NXT = 0 ; Pointer to next Entry FI.LEN = 2 ; Length of entry FI.TXT = 4 ; Text, terminated by binary 0 ; FIFCNT: .BYTE 0 ; Number of entries in FIFO FIFPOI: .BYTE 0 ; Entry number FIFPTR: 0 ; Ptr to current Entry (for UP, DOWN keys) ; ; Translation buffer ..... ; ( same entries as in FIFO ) ; TRNB: 0, TRNB ; Header command definitions ; ; Terminal characteristics buffer ..... ; SFGMCB: ANI: .BYTE TC.ANI,0 ; ANSI Terminal HLD: .BYTE TC.HLD,0 ; Hold screen mode .IF DF VT2XX!TDV2XX TTP: .BYTE TC.TTP,0 ; Get terminal type .ENDC ;VT2XX!TDV2XX SFGMCL = .-SFGMCB ; ; Prompt area ..... ; .BLKB 24. ; Prompt buffer .EVEN DEFPR: .ASCII ; .ASCII ; CMDBUF: .BLKB CMDSIZ ; Current buffer CMDEND: .EVEN SAVBUF: .BLKB CMDSIZ ; Save Buffer RCLBUF: .BLKB CMDSIZ ; Recall Buffer .EVEN .IF DF FILE ; ; MCR command line directive and buffer ..... ; GMCR: GMCR$ ; MCRLIN = GMCR+G.MCRB .ENDC ;FILE .IF DF CLISUP!FILE ; ; Buffer to receive CLI information ..... ; ; Things taken from cli information are : ; ; - CLI name to test if DCL CLISUP ; - CLI name as filetype CLISUP&FILE ; - Prompt CLISUP ; - Current Directory FILE ; ; CLIBSZ = 50. ; GCLI: GCII$ CLIBUF,CLIBSZ CLIBUF: .BLKB CLIBSZ ; Information buffer ; .ENDC ;CLISUP!FILE .IF DF CLISUP CLIPRM = CLIBUF+G.CIDP ; CLI prompt CLINAM = CLIBUF+G.CICL ; CLI name .ENDC ;CLISUP .IF DF FILE CLIUIC = CLIBUF+G.CICU ; Current UIC ; ; Current directory string ..... ; CURDIR: .BLKB 40. .ENDC ;FILE ; ------------------------------------------------------------------- ; Command check buffers and flags .... ; The whole area is cleared so do not split. ; CDSC: 0, 0 ; Descriptor of whole remainder PDSC: ; Descriptor of P0 .. P8 .REPT 9. 0, 0 .ENDR ; PX.LEN = 0 ; Bytecount PX.ADR = 2 ; Address PX.SIZ = 4 ; Length of an entry ; CFETCH: .BYTE 0 ; Flag if Paramter fetched OVMSG: .BYTE 0 ; Send Overflow Message CTSTAR: .BYTE 0 ; Find command with "*" enabled (ne 0) TMPFLG: .BYTE 0 ; Temporary Flag: "*" encountered in compare .EVEN CLL = .-CDSC ; Region to be cleared from CDSC ; ------------------------------------------------------------------- .SBTTL MCE - DSPTAB -- Jumptable .PSECT PDATA ; ; JUMP TABLE ; ; This is the dispatch table for control characters. ; The table contains the addresses of the action routines for the ; different codes. ; When bit 0 of an address is set, the corresponding ctrl-key ; may not be superimposed by a definition. ; DSPTAB: INSERT+1 ; SINGLE CHR. CHOVER ; CTRL/A UP ; CTRL/B CLRLIN ; CTRL/C LEFT ; CTRL/D ENDLIN ; CTRL/E RIGHT ; CTRL/F loop ; CTRL/G BEGLIN ; BS (CTRL/H) MOVWRD ; HT (CTRL/I) DELEW ; LF (CTRL/J) DELRL ; CTRL/K loop ; CTRL/L EXEC+1 ; CR (CTRL/M) SAVE ; CTRL/N ESCAP+1 ; CTRL/O = SS3 8-bit ctrl. char. in 7-bit mode ; See note in release notes ; loop ; CTRL/P loop+1 ; CTRL/Q (XON) RETYPE ; CTRL/R loop+1 ; CTRL/S (XOFF) DELAY ; CTRL/T DELEL ; CTRL/U DELRC ; CTRL/V DELRW ; CTRL/W EXELEA ; CTRL/X EXIT ; CTRL/Y loop ; CTRL/Z ESCAP+1 ; ESC (CTRL/[) loop ; CTRL/\ (CTRL/|) loop ; CTRL/] (CTRL/}) loop ; CTRL/^ (CTRL/~) HELP ; CTRL/? .IF DF EDT .SBTTL MCE - EDTTAB -- EDT-Key Jumptable ; EDTTAB: ; ; normal gold esc. sequ key EDT GOLD EDT DELRC, DELRC ; ESC O l , DELCHR / UNDLCHR DELRW, DELRW ; ESC O m - DELWRD / UNDLWRD SELECT, RESET ; ESC O n . SELECT / RESET loop, loop ; ESC O o BEGLIN, CLRLIN ; ESC O p 0 BLINE / OPENLINE MOVWRD, MOVWRD ; ESC O q 1 WORD / CHNGCAS ENDLIN, DELRL ; ESC O r 2 EOL / DELEOL loop, loop ; ESC O s 3 CHAR / SPECIN loop, loop ; ESC O t 4 ADVANCE / BOTTOM loop, loop ; ESC O u 5 BACKUP / TOP CUT, PASTE ; ESC O v 6 CUT / PASTE TRANSL, TRANSL ; ESC O w 7 PAGE / COMMAND PRINTC, SHVERS ; ESC O x 8 SECTION / FILL PRINTF, SHFREE ; ESC O y 9 APPEND / REPLACE GOLD, GOLD ; ESC O P PF1 GOLD / GOLD EDTHLP, EDTHLP ; ESC O Q PF2 HELP / HELP RECALL, RECALL ; ESC O R PF3 FINDNXT / FIND DELRL, DELRL ; ESC O S PF4 DELLIN / UNDLIN .ENDC ;EDT .IF DF TDV2XX .SBTTL MCE - TDVTAB -- TDV2230 Key table ; TDVTAB: ; Action routine Key ; loop ; F1 loop ; F2 loop ; F3 loop ; F4 loop ; F5 loop ; F6 loop ; F7 .ENDC ;TDV2XX .IF DF VT2XX .SBTTL MCE - VT2TAB -- VT2XX Key table ; ; Entry: ; ; Word 1 : 2 Ascii char. from esc-seq. ; Word 2 : Action routine address ; Word 3 : 2 Ascii char. from key ; .MACRO KEYVT2,ESC,ACT,KEY .ASCII /ESC/ .IF NB ACT ACT .IFF LOOP .ENDC .ASCII /KEY/ .ENDM ; VT2TAB: KEYVT2 <1 > ,RECALL ,<$F> ; Find KEYVT2 <2 > ,PASTE ,<$I> ; Insert here KEYVT2 <3 > ,CUT ,<$R> ; Remove KEYVT2 <4 > ,SELECT ,<$S> ; Select KEYVT2 <5 > ,PRVHLP ,<$P> ; Prev. Screen KEYVT2 <6 > ,NXTHLP ,<$N> ; Next Screen ; KEYVT2 <17> , ,<6 > ; F6 KEYVT2 <18> , ,<7 > ; F7 KEYVT2 <19> , ,<8 > ; F8 KEYVT2 <20> , ,<9 > ; F9 KEYVT2 <21> , ,<10> ; F10 KEYVT2 <23> ,VT2ESC ,<11> ; F11 ESC KEYVT2 <24> ,BEGLIN ,<12> ; F12 BS KEYVT2 <25> ,DELEW ,<13> ; F13 LF KEYVT2 <26> , ,<14> ; F14 KEYVT2 <28> ,HELP ,<15> ; F15 HELP KEYVT2 <29> ,EXECNW ,<16> ; F16 DO KEYVT2 <31> , ,<17> ; F17 KEYVT2 <32> , ,<18> ; F18 KEYVT2 <33> , ,<19> ; F19 KEYVT2 <34> , ,<20> ; F20 ; VT2LEN =.-VT2TAB .ENDC ;VT2XX .SBTTL .SBTTL MCE ----------- *** Start of Code *** .SBTTL MCE - START -- INIT-Code ; ; Register usage ; ; R0 Scratch Pointer ; R1 Cursor in CMDBUF ; R2 First free byte in CMDBUF (End of Text) ; R3 Scratch ; R4 Scratch ; R5 Scratch Counter ; .PSECT CODE ; START: ; ; TKB puts in R3 and R4 the Task identcode in RAD50 format from the ; .IDENT directive or from the IDENT option in the TKB-CMD file. ; We use this to put in MCE's prompts ( See Multi-Tasker july 85 ) ; MOV #IDENT,R0 ; R0 => Version field address MOV R3,R1 ; 1st 3 RAD50 char. CALL $C5TA ; Convert MOV R4,R1 ; 2nd 3 RAD50 char. CALL $C5TA ; Convert .IF DF STATUS MOV #IDENT,R0 ; R0 => Version field address MOV #IDENT2,R1 ; R1 => Version field address statusline MOV #6,R2 ; R2 = Counter 10$: MOVB (R0)+,(R1)+ ; Copy SOB R2,10$ ; ident. .ENDC ;STATUS SREX$S #EXAST ; Specify exit ast MOV #FREE,R0 ; R0 => Free memory listhead CALL $INIDM ; Initialize Free Memory CALL TERM ; Get terminal info CALL CLRBUF ; Initialize CMDBUF buffer .IF NDF SILENT MOV #STRTXT,R0 ; Print CALL IOMSG ; Startup message .ENDC ;SILENT .IF DF TMOTIM!RTMESS!RTEXIT MOV #GLUNB,R0 ; Buffer GLUN$S #TI,R0 ; Get terminal information .IF DF RTMESS!RTEXIT CMP (R0),#"RT ; Remote terminal ? BNE 20$ ; No : => 20$ MOV #RTTXT,ADR ; Print MOV #RTTXTL,LEN ; Print CALL IOW ; RT message .IF DF RTEXIT JMP EXIT ; .ENDC ;RTEXIT 20$: .ENDC ;RTMESS!RTEXIT .IF DF TMOTIM CMP (R0),#"TT ; Normal terminal ? BNE 30$ ; No : => 30$ TSTB 2(R0) ; TT0 ? BNE 30$ ; No : => 30$ INCB TT0FLG ; Set TT0: flag 30$: CALL MARK ; Marktime for timeout .ENDC ;TMOTIM .ENDC ;TMOTIM!RTMESS!RTEXIT .IF DF FILE CALL FILOP ; Open MCEINI file .ENDC ;FILE .SBTTL MCE - RESTAR -- Get next Line, Main-Loop ; RESTAR: CLRB NEXFLG ; + CLRB LEAFLG ; Clear flags CLRB OLDFLG ; - .IF DF EDT CLR SELSTR ; Clear start of select CLRB SELFLG ; Clear ANSI-select flag CLRB GOLDFL ; Clear "GOLD" .ENDC ;EDT CALL TERM ; Get terminal info .IF DF FILE TSTB FILINP ; File Input ? BEQ 10$ ; No : => 10$ CALL FILREA ; Goto EXEC1 if something read 10$: ; then come back to RESTAR .ENDC ;FILE MOV #IO.ATT,CODE ; Attach CALL IO ; the terminal .IF DF EDT TSTB EDTFLG ; EDT Keys enabled ? BEQ 20$ ; No : => 20$ MOV #APLTXT,ADR ; Aplication keypad MOV #2,LEN ; Length CALL IOW ; Write 20$: .ENDC ;EDT ; ; Set our task default directory string to that of the terminal. We ; need to do that since the last command could have been a SET /DEF ; RSX11M does nothing with this directive so it doesn't have to be ; conditionalized ; SDIR$S #SD.TI ; Set task DDS to terminal DDS .IF DF STATUS CALL PRISTA ; Print status line .ENDC ;STATUS .SBTTL MCE - PRIPRM -- Print the prompt ; PRIPRM: MOV #IO.CCO,CODE ; Cancel MOV PROMLF,ADR ; Start of prompt buffer MOV #CMDBUF+2,R3 ; Point behind prompt buffer ( Room for ESC[ ) MOVB #'[,-(R3) ; Insert '[' ( Hold screen mode ) MOVB #ESC,-(R3) ; Insert ESC ( Hold screen mode ) .IF DF CLISUP!FILE CALL GETCLI ; Get CLI information .ENDC ;CLISUP!FILE .IF DF CLISUP BCC 10$ ; Success : => 10$ MOV #^RMCR,TASK ; MCR... only BR 40$ ; Continue with default prompt ; 10$: ; ; Copy CLI prompt ; MOV #CLIPRM,R0 ; R0 => CLI Prompt information MOVB (R0)+,R4 ; Get length, advance to prompt string ADD R4,R0 ; Point behind CLI prompt CLR -(SP) ; Reserve space 20$: MOVB -(R0),(SP) ; Save character CMPB (SP),#CR ; ? BEQ 30$ ; Yes : => 30$ CMPB (SP),#LF ; ? BEQ 30$ ; Yes : => 30$ MOVB (SP),-(R3) ; Copy character 30$: SOB R4,20$ ; Next character TST (SP)+ ; Flush space BR 50$ ; => 50$ 40$: .ENDC ;CLISUP MOVB #'>,-(R3) ; Default prompt 50$: BICB INSFLG,MODFLG ; Clear overstrike mode if Auto Insert BISB OVSFLG,MODFLG ; Set overstrike mode if Auto Overstrike .IF DF EXTNPR TSTB PRMFLG ; Extended prompt ? BEQ 70$ ; No : => 70$ .IF DF EDT TSTB EDTFLG ; EDT mode active ? BEQ 60$ ; No : => 60$ .IF DF STATUS TSTB STAFLG ; Status line ? BNE 60$ ; Yes : => 60$ .ENDC ;STATUS MOVB #':,-(R3) ; Display EDT mode active 60$: .ENDC ;EDT MOVB #'+,-(R3) ; Assume insert mode BITB #1,MODFLG ; Overstrike ? BEQ 70$ ; No : => 70$ MOVB #'-,(R3) ; Overstrike 70$: .ENDC ;EXTNPR MOVB #CR,-(R3) ; Insert MOVB #LF,-(R3) ; Insert MOVB #'/,-1(R3) ; Insert '/' ( hold screen mode ) MOVB #ESC,-2(R3) ; Insert ( hold screen mode ) MOV #CMDBUF,LEN ; Point behind prompt buffer SUB R3,LEN ; Length MOV R3,PROMPT ; + MOV R3,PROMLF ; Adjust INC PROMPT ; Pointers MOV PROMLF,ADR ; - 80$: TSTB HLD+1 ; Hold screen mode ? BEQ 90$ ; No : => 90$ ADD #4,LEN ; Adjust length for Hold screen escseq. SUB #2,ADR ; Adjust address 90$: CALL IO ; Output prompt ; ; Clear edit buffer and setup R1 and R2 as pointers ; CALL CLRBUF ; Clear edit buffer .SBTTL MCE - LOOP -- Accept next Char. for input and dispatch it ; LOOP: MOV #IO.RST!TF.RNE,CODE ; Accept one chr. MOV #CHAR,ADR ; 1 Character buffer MOV #1,LEN ; Length CALL IO ; Read 1 char LOOP00: .IF DF TMOTIM CMPB IOSTAT,#IE.ABO ; IO killed ? (time-out) BNE 30$ ; No : => 30$ MOV #BYETXT,R0 ; Assume "BYE" TSTB TT0FLG ; Are we on TT0: ? BNE 10$ ; Yes : => 10$ MOV #^RMCR,TASK ; MCR... BR 20$ ; => 20$ 10$: MOV #EXITXT,R0 ; "MCE EXIT" 20$: CALL GETBUF ; Copy in CMDBUF CALL DISPLY ; Display JMP EXEC ; Execute "BYE" or "MCE EXIT" command 30$: .ENDC ;TMOTIM MOVB IOSTAT+1,R4 ; Test for branch table BIC #177600,R4 ; Make 7-Bit ASCII ; ( See note in release notes ) 40$: CMPB R4,#DEL ; Delete ? BNE 50$ ; No : => 50$ JMP DELEC ; => Delete char. 50$: BIC #177740,R4 ; IO.RST: all ctrl-char in iostat MOV R4,R3 ; Copy in R3 ASL R3 ; Word offset BIT #1,DSPTAB(R3) ; May be translated ? BEQ 60$ ; Yes : => 60$ MOV DSPTAB(R3),R3 ; Take address BIC #1,R3 ; Clear bit 0 JMP (R3) ; Do action routine 60$: ; ; Check if to be translated ; MOVB #'^,SAVBUF ; Insert MOVB R4,SAVBUF+1 ; key BISB #100,SAVBUF+1 ; Make ASCII CMPB SAVBUF+1,#'_ ; "_" ? BNE 70$ ; No : => 70$ MOVB #'?,SAVBUF+1 ; Make "?" 70$: ASL R4 ; Word offset ADD #DSPTAB,R4 ; Add table address MOV #2,PDSC+PX.LEN ; P0 Length = 2 PROCESS: MOV #SAVBUF,PDSC+PX.ADR ; P0 Address MOV R2,-(SP) ; Save R2 CALL FNDCMD ; Find cmd MOV (SP)+,R2 ; Restore R2 BCS 10$ ; No entry found : => 10$ JMP FUNC ; Proccess it 10$: JMP @(R4) ; <== Dispatch .SBTTL .SBTTL MCE ----------- *** Key actions *** .SBTTL MCE - BEGLIN -- Begin of line ; BEGLIN: .IF DF EDT TSTB SELFLG ; ANSI-Select active ? BEQ 10$ ; No :=> 10$ MOV #CMDBUF,R1 ; Cursor at pos 1 CALL DISPLY ; Rewrite line JMP LOOP ; => LOOP .ENDC ;EDT 10$: CALL SPBACK ; Back space one position BCC 10$ ; If CC not yet at the begin JMP LOOP ; => LOOP ; ; .SBTTL MCE - CHOVER -- Flip between insert and overstrike mode ; CHOVER: INCB MODFLG ; Change mode .IF DF EXTNPR TSTB PRMFLG ; Extended prompt ? BEQ 20$ ; No : => 20$ MOV PROMPT,R4 ; R4 => Prompt TSTB (R4)+ ; R4 => Mode character MOVB #'+,(R4) ; Insert "+" BITB #1,MODFLG ; Overstrike ? BEQ 10$ ; No : => 10$ MOVB #'-,(R4) ; Insert "-" 10$: CALL DISPLY ; Rewrite line 20$: .ENDC ;EXTNPR BR LOOP1 ; => LOOP ; ; .SBTTL MCE - DELEC -- Delete left single char ; DELEC: CALL SPBACK ; Back space one position BCS LOOP1 ; Error : => LOOP BR DELCHR ; => DELCHR ; ; .SBTTL MCE - DELEL -- Delete from start of line to cursor ; DELEL: CMP R1,#CMDBUF ; At begin of buffer ? BLOS 60$ ; Yes : => 60$ MOV #CMDBUF,R0 ; R0 => CMDBUF .IF DF EDT TST SELSTR ; Selective range active ? BEQ 10$ ; No : => 10$ CMP R1,SELSTR ; Compare cursor with start of range BLO 10$ ; Left of start : => 10$ MOV R1,SELSTR ; Backup range .ENDC ;EDT 10$: CMP R1,R2 ; EOL ? BEQ 20$ ; Yes : => 20$ MOVB (R1)+,(R0)+ ; Shift string left .IF DF EDT TST SELSTR ; Selective range active ? BEQ 10$ ; No : => 10$ DEC SELSTR ; Backup range .ENDC ;EDT BR 10$ ; => 10$ 20$: MOV R0,R2 ; End of text 30$: CMP R0,#CMDEND ; End of buffer ? BHIS 40$ ; Yes : => 40$ MOVB #BLNK,(R0)+ ; Fill with blank BR 30$ ; => 30$ 40$: CLRB OLDFLG ; No old command TSTB ANI+1 ; Ansi Screen ? BNE 50$ ; Yes : => 50$ .IF DF EDT TSTB SELFLG ; ANSI-Select active ? BNE 50$ ; Yes : => 50$ .ENDC ;EDT MOV PROMPT,ADR ; + MOV R1,LEN ; Rewrite line SUB PROMPT,LEN ; CALL IOW ; - MOV #CMDBUF,LEN ; + SUB PROMPT,LEN ; Reposition cursor CALL IO ; MOV #CMDBUF,R1 ; - BR 60$ ; => 60$ 50$: MOV #CMDBUF,R1 ; Reposition cursor CALL DISPLY ; Rewrite line 60$: BR LOOP1 ; => LOOP ; ; .SBTTL MCE - DELEW -- Delete left single word ; DELEW: CMP R1,#CMDBUF ; At begin of buffer ? BLOS LOOP1 ; Yes : => LOOP MOV R1,-(SP) ; Save cursor position 10$: DEC R1 ; Cursor left CMP R1,#CMDBUF ; At begin of buffer ? BLOS 30$ ; Yes : => 30$ MOVB -1(R1),R0 ; Get previous char CMPB R0,#BLNK ; Space ? BNE 20$ ; No : => 20$ CMPB R0,(R1) ; Was previous one a space ? BEQ 10$ ; Yes : => 10$, delete it 20$: CALL SRWORD ; Search word BCC 10$ ; 30$: MOV (SP)+,R0 ; R0 = Initial cursor position MOV R1,-(SP) ; Save new cursor position BR DELWRD ; => Delwrd ; ; .SBTTL MCE - DELRC -- Delete right single char ; DELRC: CMP R1,R2 ; At EOL ? BHIS LOOP1 ; Yes : => LOOP DELCHR: .IF DF EDT TST SELSTR ; Selective range active ? BEQ 10$ ; No : => 10$ CMP R1,SELSTR ; Compare cursor with start of range BHI 10$ ; Right of start DEC SELSTR ; Backup range 10$: .ENDC ;EDT MOV R1,R0 ; R0 => Cursor 20$: MOVB 1(R0),(R0)+ ; Shift string left CMP R0,R2 ; At EOL ? BLOS 20$ ; No : => 20$ .IF DF EDT TSTB SELFLG ; ANSI-Select active ? BEQ 30$ ; No : => 30$ DEC R2 ; End of text CALL DISPLY ; Rewrite line BR 40$ ; 30$: .ENDC ;EDT CALL UPDATE ; Rewrite line DEC R2 ; End of text 40$: CLRB OLDFLG ; No old command ; LOOP1: JMP LOOP ; => LOOP ; .SBTTL MCE - DELRL -- Delete from cursor to eol ; DELRL: MOV R1,R0 ; R0 => Cursor 10$: CMP R0,R2 ; EOL ? BHIS 20$ ; Yes : => 20$ CLRB OLDFLG ; No old command MOVB #BLNK,(R0)+ ; Space BR 10$ ; 20$: .IF DF EDT TSTB SELFLG ; ANSI-Select active ? BEQ 30$ ; No : => 30$ MOV R1,R2 ; Cursor at EOL CALL DISPLY ; Rewrite line BR 40$ ; 30$: .ENDC ;EDT CALL UPDATE ; Rewrite line MOV R1,R2 ; Cursor at EOL 40$: BR LOOP1 ; => LOOP ; ; .SBTTL MCE - DELRW -- Delete right single word ; DELRW: CMP R1,R2 ; At EOL ? BHIS LOOP1 ; Yes : => LOOP MOV R1,-(SP) ; Save cursor position 10$: MOVB (R1)+,R0 ; Get char CMPB R0,#BLNK ; Space ? BNE 20$ ; No : => 20$ CMPB R0,(R1) ; Is next one a space ? BEQ 30$ ; Yes : => 30$, delete it 20$: CALL SRWORD ; Search word BCS 40$ ; 30$: CMP R1,R2 ; At EOL ? BLO 10$ ; No : => 10$ 40$: MOV R1,R0 ; R0 = Current cursor position MOV (SP),R1 ; R1 = Initial cursor position ; DELWRD: .IF DF EDT TST SELSTR ; Selective range active ? BEQ 20$ ; No : => 20$ CMP R0,SELSTR ; Compare cursor with start of range BHI 10$ ; Right of start : => 10$ SUB R0,SELSTR ; Backup ADD R1,SELSTR ; range BR 20$ ; => 20$ 10$: CMP R1,SELSTR ; New cursor left of start range ? BHIS 20$ ; No : => 20$ MOV R1,SELSTR ; Update start of range 20$: .ENDC ;EDT CMP R0,R2 ; EOL ? BHIS 30$ ; No : => 30$ MOVB (R0),(R1)+ ; Shift down MOVB #BLNK,(R0)+ ; Must be replaced by space BR DELWRD ; => DELWRD 30$: MOV R1,R2 ; New end ptr MOV (SP)+,R1 ; Restore cursor CLRB OLDFLG ; No old command ; ; .SBTTL MCE - RETYPE -- Retype line ; RETYPE: CALL DISPLY ; Write buffer BR LOOP1 ; => LOOP ; ; .SBTTL MCE - ENDLIN -- Jump to end of text ; ENDLIN: .IF DF EDT TSTB SELFLG ; ANSI-Select active ? BEQ 10$ ; No : => 10$ MOV R2,R1 ; End of text CALL DISPLY ; Rewrite line BR 20$ ; 10$: .ENDC ;EDT MOV R1,ADR ; + MOV R2,LEN ; Write from cursor to end SUB R1,LEN ; BEQ 20$ ; CALL IOW ; - MOV R2,R1 ; End of text 20$: BR LOOP1 ; => LOOP ; ; .SBTTL MCE - INSERT -- Insert one character ; INSERT: CMP R2,#CMDEND ; Still Room ? BHIS LOOP1 ; No : => LOOP MOV #CHAR,ADR ; + MOV #1,LEN ; Echo character CALL IOW ; - CLRB OLDFLG ; No old command BITB #1,MODFLG ; Overstrike ? BEQ 10$ ; No : => 10$ MOVB CHAR,(R1)+ ; Overstrike CMP R1,R2 ; At end ? BLOS LOOP1 ; No : => LOOP MOV R1,R2 ; Increment end ptr BR LOOP1 ; => LOOP 10$: INC R2 ; No overstrike - shift MOV R2,R0 ; R0 => EOL 20$: MOVB -(R0),1(R0) ; Shift string right CMP R0,R1 ; At cursor ? BHI 20$ ; No : => 20$ MOVB CHAR,(R1)+ ; Insert new character .IF DF EDT TSTB SELFLG ; ANSI-Select active ? BEQ 30$ ; No : => 30$ CALL DISPLY ; Rewrite line BR 40$ ; 30$: .ENDC ;EDT CALL UPDATE ; Rewrite line 40$: BR LOOP1 ; => LOOP ; ; .SBTTL MCE - MOVWRD -- Move word ; MOVWRD: CMP R1,R2 ; At EOL ? BLO 10$ ; No => 10$ MOV #CMDBUF,R1 ; Set at begin BR 40$ ; => 40$ 10$: MOVB (R1)+,R0 ; Get char CMPB R0,#BLNK ; Space ? BNE 20$ ; No : => 20$ CMPB R0,(R1) ; Is next one a space ? BEQ 30$ ; Yes : => 30$ 20$: CALL SRWORD ; Search word BCS 40$ ; 30$: CMP R1,R2 ; At EOL ? BLO 10$ ; No : => 10$ 40$: CALL DISPLY ; JMP LOOP ; => LOOP .SBTTL .SBTTL MCE ----------- *** Escape Sequences *** .SBTTL MCE - ESCAP -- Filter out Escape Sequences ; ESCAP: .ENABL LSB ; CALL IO ; Read next char MOVB CHAR,R0 ; R0 = Character CMPB R0,#'[ ; [ ? BEQ ESCAP ; Yes : => ESCAP CMPB R0,#'O ; O ? BEQ ESCAP ; Yes : => ESCAP CMPB R0,#'? ; ? ? BEQ ESCAP ; Yes : => ESCAP CMPB IOSTAT+1,#ESC ; ? BNE 10$ ; No : => 10$ JMP EXECNW ; Execute no-wait 10$: CMPB R0,#'A ; ? BNE 60$ ; No : => 60$ ; ; UP-ARROW ..... ; .SBTTL MCE - UP -- Older command UP: MOV FIFPTR,R5 ; Get Ptr of buffer BNE 20$ ; Defined : => 20$ TST FIFO+F.1ST ; Any entry ? BEQ 80$ ; No : => 80$ MOV FIFO+F.LAST,FIFPTR ; Take MOVB FIFCNT,FIFPOI ; newest entry BR 80$ ; => 80$ 20$: MOV #FIFO+F.1ST,R5 ; Find previous entry 30$: MOV FI.NXT(R5),R5 ; Next BNE 40$ ; Got one : => 40$ TSTB RNGFLG ; Ringbuffer ? BEQ 80$ ; No : => 80$ CLRB FIFPOI ; None BR 50$ ; => 50$ 40$: CMP FI.NXT(R5),FIFPTR ; Does this point to me ? BNE 30$ ; No : => 30$ DECB FIFPOI ; One older 50$: MOV R5,FIFPTR ; Found - load BR 80$ ; and display ; 60$: CMPB R0,#'B ; ? BNE 110$ ; No : => 110$ ; ; DOWN-ARROW ..... ; .SBTTL MCE - DOWN -- Newer command ; DOWN: MOV FIFPTR,R5 ; Get Ptr of buffer BNE 70$ ; Defined : => 70$ TST FIFO+F.1ST ; Any entry at all ? BEQ 80$ ; No : => 80$ TSTB RNGFLG ; Ringbuffer ? BEQ 90$ ; No : => 90$ MOV FIFO+F.1ST,FIFPTR ; Take oldest MOVB #1,FIFPOI ; Oldest BR 80$ ; => 80$ 70$: TST FI.NXT(R5) ; Goto next buffer if any BEQ CLRLIN ; No more : => CLRLIN MOV FI.NXT(R5),FIFPTR ; Next INCB FIFPOI ; One newer 80$: .IF DF EDT CLR SELSTR ; Clear start of select CLRB SELFLG ; Clear ANSI-select flag .ENDC ;EDT CALL GETFIF ; Load CMDBUF from FIFO BR 100$ ; => 100$ ; ; CLEAR LINE ..... ; .SBTTL MCE - CLRLIN -- Clear line CLRLIN: CLRB OLDFLG ; Clear flag CALL CLEAR ; Clear FIFO pointers 90$: .IF DF EDT CLR SELSTR ; Clear start of select CLRB SELFLG ; Clear ANSI-select flag .ENDC ;EDT CALL CLRBUF ; Clear edit buffer CALL DISPLY ; and display prompt 100$: .IF DF STATUS CALL PRIST1 ; Print status line .ENDC ;STATUS BR LOOP2 ; => LOOP ; 110$: CMPB R0,#'C ; ? BNE 130$ ; No : => 130$ ; ; RIGHT-ARROW ..... ; .SBTTL MCE - RIGHT -- Cursor right ; RIGHT: CMP R1,R2 ; End of text ? BHIS LOOP2 ; Yes : => LOOP MOV R1,ADR ; Rewrite MOV #1,LEN ; Character CALL IOW ; at Cursor position INC R1 ; Shift cursor right .IF DF EDT TSTB SELFLG ; ANSI-Select active ? BEQ 120$ ; No : => 120$ CALL DISPLY ; Rewrite line 120$: .ENDC ;EDT BR LOOP2 ; => LOOP ; 130$: CMPB R0,#'D ; ? BNE 150$ ; No : => 150$ ; ; LEFT-ARROW ..... ; .SBTTL MCE - LEFT -- Cursor left ; LEFT: CALL SPBACK ; Cursor left one space .IF DF EDT TSTB SELFLG ; ANSI-Select active ? BEQ 140$ ; No : => 140$ CALL DISPLY ; Rewrite line 140$: .ENDC ;EDT BR LOOP2 ; => LOOP ; 150$: .IF DF EDT ; ; EDT-KEYS ..... ; TSTB EDTFLG ; EDT Keys enabled ? BEQ 200$ ; No : => 200$ CMPB R0,#'M ; ? BNE 160$ ; No : => 160$ JMP EXEC ; Execute 160$: CMPB R0,#'P ; + BLO 170$ ; PFx range ? CMPB R0,#'S ; No : => 170$ BHI 170$ ; - ADD #<'z-'l-'P>,R0 ; Relocate to table offset BR 180$ ; => 180$ 170$: CMPB R0,#'l ; + BLO 200$ ; Within Keypad range ? CMPB R0,#'y ; No : => 200$ BHI 200$ ; - SUB #'l,R0 ; Make 180$: ASL R0 ; dispatchtable ASL R0 ; offset TSTB GOLDFL ; Gold ? BEQ 190$ ; No : => 190$ TST (R0)+ ; Point to "GOLD" entry CLRB GOLDFL ; Clear "GOLD" 190$: JMP @EDTTAB(R0) ; Do EDT function 200$: .ENDC ;EDT ; ; PF-KEYS ..... ; SUB #'P,R0 ; Any PFn key ? BLO 210$ ; No : => VT2KEY CMP R0,#'S-'P ; > PF4 ? BLOS 220$ ; Yes : => VT2KEY 210$: JMP VT2KEY ; 220$: MOV R0,-(SP) ; Save 0..3 for .. MOV #"PF,SAVBUF ; "PF' in SAVBUF ADD #'1,R0 ; Make ascii from PR-number MOV R0,SAVBUF+2 ; Insert in SAVBUF MOV #3,PDSC+PX.LEN ; P0 Length MOV #SAVBUF,PDSC+PX.ADR ; P0 Address MOV R2,-(SP) ; Save R2 CALL FNDCMD ; Find cmd MOV (SP)+,R2 ; Restore R2 MOV (SP)+,R0 ; Restore R0 BCC FUNC ; Entry found : => FUNC ; MOV R2,R1 ; Point to end of buffer ASL R0 ; Word offset ADD R0,PC ; Branch BR TRANSL ; BR RECALL ; BR PRINTC ; ; ; ; Fall through to PRINTF, adjacency assumed ; .DSABL LSB .SBTTL MCE - PRINTF -- Print FIFO buffer ; PRINTF: ; ; Print FIFO ..... ; CALL PRIFIF ; Print whole FIFO BR LOOP2 ; => LOOP ; ; LOOP2: JMP LOOP ; => LOOP ; ; .SBTTL MCE - PRINTC -- Print command buffer ; PRINTC: ; ; Print CMD Buffer ; CALL PRICMD ; Print command buffer BR LOOP2 ; => LOOP ; ; .SBTTL MCE - RECALL -- Recall a command ; RECALL: ; ; - RECALL ; CALL RECCMD ; Recall Command .IF DF STATUS CALL PRIST1 ; Dispay status line .ENDC ;STATUS BR LOOP2 ; => LOOP ; ; .SBTTL MCE - TRANSL -- Translate a command ; TRANSL: ; ; Translate ; MOV #CMDBUF,R0 ; R0 => CMDBUF CMP R2,R0 ; Something in buffer ? BEQ LOOP2 ; No : => LOOP INCB NLOFLG ; Disable command load SUB R0,R2 ; Calculate Length MOV R2,LEN ; Make length CALL CMDCHK ; Command Translation MOV LEN,R2 ; Restore R2 ADD #CMDBUF,R2 ; Point MOV R2,R1 ; to end CALL DISPLY ; Write line CLRB NLOFLG ; Enable command load BR LOOP2 ; => LOOP ; ; .SBTTL MCE - FUNC -- Exectute function key commands ; FUNC: MOV R1,R0 ; Find start of text FUNCEX: ; ; Execute command in (R0) ; CALL IOCR ; Clear current line CALL GETBUF ; Load CMDBUF buffer MOV #CMDBUF,R0 ; R0 => CMDBUF SUB R0,R2 ; Calculate length MOV R2,LEN ; Save it CALL DETACH ; Detach terminal JMP EXEC3 ; Execute without display .IF DF VT2XX .IF LT MAXHLP-'A .SBTTL MCE - PRVHLP -- Previous screen .SBTTL MCE - NXTHLP -- Next screen PRVHLP: NXTHLP: MOV #NOHTXT,ADR ; No help page MOV #NOHLEN,LEN ; CALL IOW ; information JMP RESTAR ; .IFF ;MAXHLP-'A ; ; .SBTTL MCE - PRVHLP -- Previous screen ; ; Spawn "HELP MCE" ; PRVHLP: DECB HPAGE ; Previous screen CMPB HPAGE,#'A ; Low limit ? BHIS 10$ ; No => 10$ MOVB #' ,HPAGE ; Take CLRB HPAG0 ; main help 10$: BR HELPGO ; => ; ; .SBTTL MCE - NXTHLP -- Next screen ; ; Spawn "HELP MCE" ; NXTHLP: ; TSTB HPAG0 ; Was main help last ? BNE 10$ ; No : => 10$ MOVB #' ,HPAG0 ; Sub topics MOVB #'A-1,HPAGE ; Init for first subtopic 10$: INCB HPAGE ; Next screen CMPB HPAGE,#MAXHLP ; High limit ? BLOS 20$ ; No => 20$ MOVB #MAXHLP,HPAGE ; Take last help 20$: BR HELPGO ; => .ENDC ;MAXHLP-'A .ENDC ;VT2XX ; ; .SBTTL MCE - HELP -- Help key ; ; or Spawn "HELP MCE " ; HELP: MOVB #' ,HPAGE ; Take CLRB HPAG0 ; main help HELPGO: CALL CLRSCR ; Clear screen MOV #HLPTXT,R0 ; Move HELP MCE into Buffer BR FUNCEX ; => FUNCEX .IF DF EDT .SBTTL MCE - GOLD -- "GOLD" Key ; GOLD: INCB GOLDFL ; Set "GOLD" flag BR LOOP2 ; => LOOP ; ; .SBTTL MCE - SHVERS -- Version ; SHVERS: MOV #RESTAR,-(SP) ; RESTAR as return address CALLR ICVERS ; Display Version ; ; .SBTTL MCE - SHFREE -- Free pool ; SHFREE: MOV #RESTAR,-(SP) ; RESTAR as return address CALLR ICFREE ; Display Free pool ; ; .SBTTL MCE - EDTHLP -- Keypad Help ; EDTHLP: TSTB ANI+1 ; Ansi Screen ? BEQ 10$ ; No : => 10$ MOV #SCRCLR,ADR ; Clear MOV #SCRCLL,LEN ; screen CALL IOW ; 10$: MOV #EDTTXT,R0 ; EDT helptext BR FUNCEX ; => FUNCEX ; ; .SBTTL MCE - SELECT -- Select key ; SELECT: MOV R1,SELSTR ; Save of select address MOVB ANI+1,SELFLG ; Set Ansi-select flag BEQ 10$ ; No Ansi : => 10$ CALL DISPLY ; 10$: BR LOOP3 ; => LOOP ; ; .SBTTL MCE - RESET -- Reset key ; RESET: CLR SELSTR ; Clear start of select CLRB SELFLG ; Clear Ansi-select flag TSTB ANI+1 ; Test Ansi-flag BEQ 10$ ; No Ansi : => 10$ CALL DISPLY ; 10$: BR LOOP3 ; => LOOP ; ; .SBTTL MCE - CUT -- Put selective range in Paste buffer ; CUT: TST SELSTR ; Range active ? BEQ 40$ ; No : => 40$ CMP R1,SELSTR ; Compare cursor with start of range BEQ 40$ ; - Equal => 40$ BHI 10$ ; - Right => 10$ MOV R1,R4 ; R4 = Start MOV SELSTR,R0 ; R0 = End BR 20$ ; => 20$ 10$: MOV SELSTR,R4 ; R4 = Start MOV R1,R0 ; R0 = End 20$: MOV R4,R1 ; R1 => Start MOV #PSTBUF,R3 ; R3 => Save buffer CLRB PSTLEN ; Clear length MOV R4,-(SP) ; Save new cursor pos. 30$: MOVB (R4)+,(R3)+ ; Copy character INCB PSTLEN ; Update length CMP R4,R0 ; At the end ? BLO 30$ ; No : => 30$ CLR SELSTR ; Range not active CLRB SELFLG ; Clear Ansi-select flag JMP DELWRD ; Delete range 40$: BR LOOP3 ; => LOOP ; ; .SBTTL MCE - PASTE -- Put Paste buffer in at cursor position ; PASTE: CLR R4 ; R4 = Counter BISB PSTLEN,R4 ; R4 := length of PASTE string BEQ 60$ ; Zero : => 60$ MOV #PSTBUF,R5 ; R5 => PSTBUF CLRB OLDFLG ; No old command ; 10$: CMP R2,#CMDEND ; Still Room ? BHIS 60$ ; No : => 60$ MOV R5,ADR ; + MOV #1,LEN ; Echo character CALL IOW ; - BITB #1,MODFLG ; Overstrike ? BEQ 20$ ; No : => 10$ ; MOVB (R5)+,(R1)+ ; Overstrike CMP R1,R2 ; At end ? BLOS 40$ ; No : => Loop MOV R1,R2 ; Increment end ptr BR 40$ ; => Loop 20$: INC R2 ; No overstrike - shift MOV R2,R0 ; R0 => EOL 30$: MOVB -(R0),1(R0) ; Shift string right CMP R0,R1 ; At cursor ? BHI 30$ ; No : => 30$ MOVB (R5)+,(R1)+ ; Insert new character 40$: SOB R4,10$ ; ; TSTB SELFLG ; ANSI-Select active ? BEQ 50$ ; No : => 50$ CALL DISPLY ; Rewrite line BR 60$ ; 50$: CALL UPDATE ; Rewrite line 60$: ; LOOP3: JMP LOOP ; => LOOP .ENDC ;EDT .SBTTL MCE - VT2KEY -- VT2xx Functionkeys ; VT2KEY: .IF DF VT2XX CMPB TTP+1,#T.V2XX ; VT2xx ? BEQ 10$ ; Yes : => 10$ JMP TDVKEY ; => TDVKEY 10$: ; ; Check if function key : ; ; [n~ n 1..6 ; or ; [nn~ nn 17..34 ; MOVB CHAR,R0 ; R0 = character BIC #177600,R0 ; CMPB R0,#'1 ; + BLO 50$ ; 1..6 ? CMPB R0,#'6 ; BHI 50$ ; - SWAB R0 ; Char in highbyte BISB #BLNK,R0 ; Lowbyte = space MOV R0,-(SP) ; Save it CALL IO ; Next char. MOVB CHAR,R0 ; Take char. CMPB R0,#'~ ; Tilde ? BEQ 20$ ; Yes: => 20$ CMPB R0,#'0 ; + BLO 40$ ; 0..9 ? CMPB R0,#'9 ; BHI 40$ ; - CLRB (SP) ; Clear byte BISB R0,(SP) ; Insert in word CALL IO ; Next char. CMPB CHAR,#'~ ; Tilde ? BNE 40$ ; No: => 40$ 20$: MOV (SP)+,R0 ; Retrieve word SWAB R0 ; Adjust MOV #VT2TAB,R4 ; R4 => VT2XX table MOV #VT2LEN/6,R5 ; R5 = Table length 30$: CMP R0,(R4)+ ; Look for table entry BEQ VT2FN ; Found : => VT2FN CMP (R4)+,(R4)+ ; Next entry SOB R5,30$ ; Try next JMP LOOP ; Not found : => LOOP 40$: TST (SP)+ ; Flush word 50$: JMP LOOP00 ; => LOOP00 ; ; .SBTTL MCE - VT2FN -- Check if VT2xx key to be translated ; VT2FN: ; ; Check if to be translated ; MOVB #'F,SAVBUF ; Insert MOVB 2(R4),SAVBUF+1 ; key MOVB 3(R4),SAVBUF+2 ; ident MOV #3,PDSC+PX.LEN ; Assume P0 Length = 3 CMPB SAVBUF+2,#BLNK ; Blank ? BNE 10$ ; No : => 10$ DEC PDSC+PX.LEN ; P0 Length = 2 10$: JMP PROCESS ; Go via table ; ; .SBTTL MCE - VT2ESC -- Check for VT2XX ; ; Typed VT2xx F11 () key; look for a second one ; VT2ESC: CALL IO ; Next char CMPB IOSTAT+1,#ESC ; ? BNE 20$ ; No : => 20$ MOV #VT2ESQ,R4 ; R4 -> VT2XX ESC-SEQ. MOV #VT2ESL,R5 ; R5 = Length 10$: CALL IO ; Next char. CMPB CHAR,(R4)+ ; Match ? BNE 20$ ; No : => 20$ SOB R5,10$ ; Next JMP EXECNW ; 20$: JMP LOOP ; .ENDC ;VT2XX .SBTTL MCE - TDVTST -- TDV2230 Key support ; TDVKEY: .IF DF TDV2XX CMPB TTP+1,#200 ; TDV2XX ? BNE 10$ ; No: => 10$ ; ; O ... ; ; Test character is in the range of "T" - "Z" for F1..F7 ; MOVB CHAR,R4 ; R4 = Character BIC #177600,R4 ; SUB #'T,R4 ; Normalize BLT 10$ ; Less then : => 10$ CMPB R4,#'Z-'T ; In range ? BGT 10$ ; No : => 10$ ; ; Function ok: convert to string ; MOVB #'F,SAVBUF ; Insert MOVB R4,R0 ; ADD #'1,R0 ; key code MOVB R0,SAVBUF+1 ; ; MOV #2,PDSC+PX.LEN ; P0 Length ASL R4 ; Make word offset ADD #TDVTAB,R4 ; Add table address JMP PROCES ; 10$: .ENDC ;TDV2XX JMP LOOP ; => LOOP .SBTTL .SBTTL MCE ----------- *** Command execution *** .SBTTL MCE - DELAY -- Detach and delay ; DELAY: CALL IOCRLF ; Print CALL DETACH ; Detach terminal MRKT$S #EFN,#10.,#2 ; Wait DIR$ #STOPIO ; 10 seconds JMP RESTAR ; => RESTAR ; ; .SBTTL MCE - SAVE -- Save command without execution ; SAVE: INCB NEXFLG ; Don't execute BR EXEC1 ; => EXEC1 ; .SBTTL MCE - EXELEA -- Execute and leave pointer ; EXELEA: INCB LEAFLG ; Don't clear pointers BR EXEC1 ; => EXEC1 ; ; .SBTTL MCE - EXECNW -- Execute command no-wait ; EXECNW: CLR WAITFL ; Clear EVF BR EXEC1 ; => EXEC1 ; ; .SBTTL MCE - EXEC -- Execute command ; EXEC: .ENABL LSB MOV #1,WAITFL ; EVF = 1 EXEC1: CALL IOCR ; Print CALL DETACH ; Detach terminal SUB #CMDBUF,R2 ; Calculate Length MOV R2,LEN ; Store CALL SUPRES ; Ignore leading blanks BCS 50$ ; Empty ? => 50$ 10$: TSTB SOLFLG ; Save old commands ? BNE 20$ ; Yes : => 20$ TSTB OLDFLG ; Old command ? BNE 30$ ; Yes : => 30$ 20$: CALL LDFIF ; Load into FIFO 30$: TSTB LEAFLG ; Leave pointers ? BNE EXEC2 ; Yes : => EXEC2 CALL CLEAR ; Clear pointers TSTB NEXFLG ; Execute ? BNE 50$ ; No : => 50$ EXEC2: CALL CMDCHK ; Check for command Translation BCS 50$ ; Nothing to execute EXEC3: .IF DF TMOTIM CLRB TMOCNT ; Disable timeouts (until next IO) .ENDC ;TMOTIM CALL SUPRR0 ; Ignore leading blanks ( Start at R0 ) BCS 50$ ; If C set : Empty command ; ; R0 => First non blank character ; LEN = Length of command ; CALL INTERN ; Internal command , BYE or LOG ? BCC 50$ ; If C clear: no command for CLI CALL DOEXEC ; Excute command in buffer CMDBUF TST WAITFL ; Wait ? BNE 40$ ; Yes : => 40$ INC WAITFL ; Make flag #1 MRKT$S WAITFL,#20.,#1 ; Allow task to run 40$: STSE$S WAITFL ; Stop until done 50$: JMP RESTAR ; => RESTAR .DSABL LSB ; ; .SBTTL MCE - EXAST -- Task exit ast ; EXAST: ; ; Change STOP to WAIT ; MOV #IO.KIL,CODE ;; Kill CALL IO ;; pending read MOV WAITIO,STOPIO ;; Change DIC-code DIR$ #STOPIO ;; Wait for I/O ; ; .SBTTL MCE - EXIT -- Task exit ; EXIT: .IF NDF SILENT MOV #ENDTXT,R0 ; Exit CALL IOMSG ; message .ENDC ;SILENT ; .SBTTL MCE - EXITI -- Immediate Task exit ; EXITI: .IF DF STATUS TSTB ANI+1 ; Ansi Screen ? BEQ 10$ ; No : => 10$ MOV #STACLR,ADR ; Clear MOV #STACLN,LEN ; Statusline CALL IOW ; 10$: .ENDC ;STATUS CALL DETACH ; Detach terminal EXIT$S ; Exit .SBTTL .SBTTL MCE ----------- *** Internal Command Handling *** .SBTTL MCE - INTERN -- Check for internal commands ; Check if the command (AFTER translation) is BYE, LOG[out] or an ; internal command starting with the verb 'MCE '. ; To check for the special commands after translation offers the ; possibility to define any other string for exit/bye. ; (E.g.: LOGOF*F := BYE, BYE := LOGOUT ) ; INTERN returns C set, if no internal command, i.e. the buffer R0 => ; with length LEN has to be submitted to the CLI. ; C clear on return, if internal command found, no CLI submit. ; .MACRO CMPBNE Source,Char,Labl MovB Source,R3 BicB #40,R3 CmpB R3,#''Char Bne Labl .ENDM CMPBNE ; .MACRO CMPBEQ Source,Char,Labl MovB Source,R3 BicB #40,R3 CmpB R3,#''Char Beq Labl .ENDM CMPBEQ ; INTERN: ; ; To be recognised as an internal command, at least 3 characters ; must be present. ; Internal commands trapped are: ; BYE : the MCR RSX logout command ; LOG[OUT] : the DCL RSX logout command ; MCE action : MCE internal actions ; CMP LEN,#3 ; Length in range ? BLT 40$ ; No : => 40$ .IF DF CLISUP CMP CLINAM,#^RDCL ; In DCL ? BNE 10$ ; No : => 10$ CMPBNE (R0),L,10$ ; + CMPBNE 1(R0),O,10$ ; LOG ? CMPBEQ 2(R0),G,20$ ; - 10$: .ENDC ;CLISUP CMPBNE (R0),B,30$ ; + CMPBNE 1(R0),Y,30$ ; BYE ? CMPBNE 2(R0),E,30$ ; - 20$: MOV #^RMCR,TASK ; Force MCR... MOV #BYETXT,R0 ; Command to spawn is "BYE" CALL GETBUF ; Copy in CMDBUF MOV #CMDBUF,R0 ; R0 => CMDBUF MOV #3,LEN ; "BYE" = 3 char. CLR WAITFL ; Do not wait CALL DOEXEC ; Submit "BYE" to MCR... CALLR EXITI ; Immediate task exit 30$: CMPBNE (R0),M,40$ ; + CMPBNE 1(R0),C,40$ ; MCE ? CMPBEQ 2(R0),E,50$ ; - 40$: SEC ; No internal command trapped RETURN ; ; ; Internal command strings must not be less than 8 characters in length ; Ignore anything else ; 50$: MOV #INTCMD,R1 ; Point to internal command table ADD #3,R0 ; Point SUB #3,LEN ; behind "MCE" CALL SUPRR0 ; Suppress spaces BCS 150$ ; Empty => 150$ CMP LEN,#4 ; At least 4 characters left ? BLT 150$ ; No : => 150$ CLR R3 ; + BISB (R0)+,R3 ; SWAB R3 ; BISB (R0)+,R3 ; R3 := Upcased 1st 2 characters SWAB R3 ; BIC #" ,R3 ; - CLR R4 ; + BISB (R0)+,R4 ; SWAB R4 ; BISB (R0)+,R4 ; R4 := Upcased 2nd 2 characters SWAB R4 ; BIC #" ,R4 ; - SUB #4,LEN ; behind "MCE XXXX" 60$: ; ; Look for Verb in Table ..... ; TST (R1) ; End of table reached ? BEQ 150$ ; Yes : => 150$ CMP R3,(R1)+ ; First 2 characters match ? BEQ 70$ ; Yes : => 70$ ADD #4,R1 ; Point to next table entry BR 60$ ; Look ahead 70$: CMP R4,(R1)+ ; Second 2 characters match ? BEQ 80$ ; If eq Yes: action verb match TST (R1)+ ; Point to next table entry BR 60$ ; Look ahead 80$: CALL @(R1) ; EXECute internal command ; BCS 150$ ; Not OK ? => 150$ TSTB SINFLG ; Save internal command ? BNE 140$ ; Yes : => 140$ .IF DF FILE TSTB FILREX ; Read or Replace being processed ? BNE 90$ ; Yes : => 90$ TSTB FILINP ; File input ? BNE 140$ ; Yes : => 140$ 90$: CLRB FILREX ; Clear flag .ENDC ;FILE MOV FIFO+F.1ST,R0 ; R0 => First entry BEQ 140$ ; No entries : => 140$ MOV FIFO+F.LAST,R2 ; R2 => Last entry CMP R0,R2 ; 1st = last ? BEQ 120$ ; Yes : => 120$ 100$: CMP FI.NXT(R0),R2 ; Next = Last ? BEQ 110$ ; Yes : Delete this one MOV FI.NXT(R0),R0 ; Next BR 100$ ; => 100$ 110$: MOV R0,FIFO+F.LAST ; New last CLR (R0) ; Last MOV #FREE,R0 ; R0 => Free listhead MOV FI.LEN(R2),R1 ; R1 = Length CALL $RLCB ; Release block BR 130$ ; => 130$ 120$: MOV #FIFO+F.1ST,R0 ; R0 => Header CALL FRENT ; Free entry 130$: DECB FIFCNT ; One less 140$: CLC ; Success RETURN ; 150$: MOV #ERRTXT,R0 ; Error CALLR IOMSG ; Message .SBTTL MCE - ICCLEA -- Clear ; ; Clear FIFO ; ICCLEA: ; MOV MAXF,-(SP) ; Save maxFIFO CLR MAXF ; Clear CALL CLEFIF ; FIFO MOV (SP)+,MAXF ; Restore maxFIFO RETURN ; ; ; .SBTTL MCE - ICCMSZ -- Cmsz x ; ; CMD Size ; ICCMSZ: ; MOV #MINC,R5 ; R5 => Destination CALLR VALUE ; ; ; .SBTTL MCE - ICECHO -- Echo on/off ; ; Echo On/Off ; ICECHO: ; MOV #ECHFLG,R3 ; R3 => Flag CALLR ONOFF ; => On / Off ; ; .SBTTL MCE - ICFISZ -- Fisz x ; ; FIFO size ; ICFISZ: ; MOV #MAXF,R5 ; R5 => Destination CALL VALUE ; Get value BCC 10$ ; RETURN ; 10$: CALLR CLEFIF ; Clear fifo ; ; .SBTTL MCE - ICFREE -- Free ; ; Free poolspace ; ICFREE: MOV #POOL,R5 ; Point to pool raw data buffer CLR (R5)+ ; Clear number of fragments CLR (R5)+ ; Clear total pool CLR (R5) ; Clear biggest hole MOV FREE,R4 ; Get address of pool listhead BEQ 30$ ; No blocks : => 30$ 10$: TST (R4)+ ; R4 => Size CMP (R5),(R4) ; This size > stored ? BHIS 20$ ; No : => 20$ MOV (R4),(R5) ; Set new max 20$: ADD (R4),-(R5) ; Add this space to total INC -(R5) ; Increment number of pool fragments CMP (R5)+,(R5)+ ; Point R5 to end of raw data buffer MOV -(R4),R4 ; Get addr of next block BNE 10$ ; If ne more to examine 30$: MOV #POOLDT,R0 ; POOL message MOV #3,R4 ; 3 words to convert 40$: MOV (R5),R1 ; Binary value MOV #20012,R2 ; Parms. CALL $CBTA ; Convert MOVB #'.,(R0)+ ; Decimal MOVB #':,(R0)+ ; Terminate TST -(R5) ; Next SOB R4,40$ ; word ; CLRB -(R0) ; ASCIZ MOV #POOLTX,R0 ; R0 => Message CALLR IOMSG ; Write and return ; ; .SBTTL MCE - ICINSE -- Auto Insert on/off ; ; Auto insert On/Off ; ICINSE: ; MOV #INSFLG,R3 ; R3 => Flag CALL ONOFF ; => On / Off BCS 10$ ; Error : => 10$ TSTB (R3) ; Set ? BEQ 10$ ; No : => 10$ CLRB OVSFLG ; Clear auto overstrike 10$: RETURN ; ; .IF DF EDT ; .SBTTL MCE - ICKEYP -- Keypad on/off ; ; Keypad On/Off ; ICKEYP: ; MOV #EDTFLG,R3 ; R3 => Flag CALLR ONOFF ; => On / Off .ENDC ;EDT ; .SBTTL MCE - ICLIST -- LIST ; ; FIFO is LIST ; ICLIST: ; CLRB RNGFLG ; Indicate LIST RETURN ; ; ; .SBTTL MCE - ICOVER -- Auto Overstrike on/off ; ; Auto overstrike On/Off ; ICOVER: ; MOV #OVSFLG,R3 ; R3 => Flag CALL ONOFF ; => On / Off BCS 10$ ; Error : => 10$ TSTB (R3) ; Set ? BEQ 10$ ; No : => 10$ CLRB INSFLG ; Clear auto insert 10$: RETURN ; .IF DF EXTNPR .SBTTL MCE - ICPROM -- Prompt on/off ; ; Prompt On/Off ; ICPROM: ; MOV #PRMFLG,R3 ; R3 => Flag CALLR ONOFF ; => On / Off .ENDC ;PRMFLG ; .SBTTL MCE - ICPURG -- Purge ; ; Delete current translation table ; ICPURG: ; MOV #TRNB+F.1ST,R0 ; Queue header for Transtation table CALL FRENT ; Delete table entry BCS ICPURG ; More entries ? : => ICPURG RETURN ; ; .IF DF FILE .SBTTL MCE - ICREAD -- Read ; ; read commands from file specified ; ICREAD: ; MOV R0,-(SP) ; Save pointer TSTB FILINP ; Is a file open ? BEQ 10$ ; If eq no: just open new ; ; Close a file currently open, i.e. 'MCE READ' issued from ; inside a definition is equivalent to a 'MCE CHAIN' command ; CALL FILCLO ; Close current file 10$: MOV (SP)+,R1 ; Point behind 'MCE XXXX' MOV LEN,R2 ; Length of command CALL GETFIL ; Get new file name BCS 20$ ; Error => 20$ CALL FILOP1 ; Read file(s) INCB FILREX ; Read or Replace being processed 20$: CALLR SUCCES ; Always success .SBTTL MCE - ICREPL -- Replace ; ICREPL: MOV R0,-(SP) ; Save pointer CALL ICPURG ; Delete current translation table MOV (SP)+,R0 ; Restore pointer BR ICREAD ; .ENDC ;FILE ; .SBTTL MCE - ICRING -- Ring ; ; FIFO is RING buffer ; ICRING: MOVB #1,RNGFLG ; Indicate RING CALLR SUCCES ; ; .IF DF STATUS .SBTTL MCE - ICSTAT -- Status [ on/off ] ; ; Status ; ICSTAT: ; CALL DELSEA ; Search for delimitor TST LEN ; Left ? BNE 30$ ; Yes : => 30$ CALL STAFIL ; Fill statusline MOV #STATX3,ADR ; Address MOV #STALN3,LEN ; Length CALLR IOW ; 30$: TSTB ANI+1 ; ANSI Terminal ? BEQ 20$ ; No : => 20$ MOV #STAFLG,R3 ; R3 => Flag MOVB (R3),R2 ; Old status MOV R2,-(SP) ; Save it CALL ONOFF ; => On / Off MOV (SP)+,R2 ; Restore BCS 20$ ; TSTB STAFLG ; Off ? BNE 20$ ; No : => 20$ TSTB R2 ; Was it on ? BEQ 20$ ; no : => 20$ MOV #STACLR,ADR ; Address MOV #STACLN,LEN ; Length CALLR IOW ; Clear status line 20$: RETURN ; .ENDC ;STATUS ; .SBTTL MCE - ICSVIN -- Intern on/off ; ; Save internal commands On/Off ; ICSVIN: ; MOV #SINFLG,R3 ; R3 => Flag CALLR ONOFF ; => On / Off ; ; .SBTTL MCE - ICSVOL -- Old commands on/off ; ; Save old commands On/Off ; ICSVOL: ; MOV #SOLFLG,R3 ; R3 => Flag CALLR ONOFF ; => On / Off ; ; .SBTTL MCE - ICVERS -- Version ; ; Show version ; ICVERS: ; MOV #STRTXT,R0 ; Print CALLR IOMSG ; Startup message .SBTTL MCE - CLEFIF -- Clear Fifo ; CLEFIF: CMPB FIFCNT,MAXF ; Maximum reached ? BLOS 10$ ; No : => 10$ CALL CLFIFI ; Release first entry BCS CLEFIF ; More ? : => CLEFIF 10$: CALLR SUCCES ; ; ; .SBTTL MCE - DELSEA -- Delimitter search ; DELSEA: TST LEN ; Length BEQ 20$ ; Zero : => 20$ 10$: CMPB (R0),#BLNK ; Start with a Space ? BEQ 20$ ; Yes : => 20$ INC R0 ; Next := First DEC LEN ; One less BNE 10$ ; Not empty : => 10$ 20$: RETURN ; .SBTTL MCE - ONOFF -- Check for ON or OFF in command ; ; ON/OFF ; ; R3 => Byte flag ; ONOFF: CALL DELSEA ; Search for delimitor CALL SUPRR0 ; Suppress BCS NOSUCC ; Empty : => NOSUCC BICB #40,(R0) ; Upcase CMPB (R0)+,#'O ; 'O ? BNE NOSUCC ; No : => NOSUCC BICB #40,(R0) ; Upcase CMPB (R0),#'N ; 'N ? BNE 30$ ; No : => 30$ INCB (R3) ; Set flag BR SUCCES ; 30$: CMPB (R0)+,#'F ; 'F ? BNE NOSUCC ; No : => NOSUCC BICB #40,(R0) ; Upcase CMPB (R0),#'F ; 'F ? BNE NOSUCC ; No : => NOSUCC CLRB (R3) ; Reset flag ; SUCCES: CLC ; Succes RETURN ; NOSUCC: SEC ; Not Succes RETURN ; ; ; .SBTTL MCE - VALUE -- Convert value of MCE XXXX nnn command ; VALUE: CALL DELSEA ; Search for delimitor CALL SUPRR0 ; Suppress BCS NOSUCC ; Empty : => NOSUCC CALL $CDTB ; Convert TST R1 ; Empty ? BEQ NOSUCC ; Yes : => NOSUCC CMP R1,#99. ; Too large ? BHI NOSUCC ; Yes : => NOSUCC MOV R1,(R5) ; Insert value BR SUCCES ; .SBTTL .SBTTL MCE ----------- *** Subroutines **** .SBTTL MCE - CLEAR -- Clear flags and pointers ; CLEAR: ; CLR FIFPTR ; Clear CLRB FIFPOI ; pointers RETURN ; ; ; .SBTTL MCE - CLFIFI -- Clear first entry of FIFO buffer ; CLFIFI: MOV #FIFO+F.1ST,R0 ; This header CALL FRENT ; Free entry from queue BCC 10$ ; Empty : => 10$ DECB FIFCNT ; Adjust count 10$: RETURN ; ; ; .SBTTL MCE - CLRBUF -- Clear Buffer CMDBUF ; CLRBUF: MOV #CMDBUF,R1 ; R1 => CMDBUF MOV R1,R2 ; R2 => CMDBUF MOV #CMDSIZ,R5 ; R5 = CMDSIZ 10$: MOVB #BLNK,(R1)+ ; Reset CMDBUF to blank SOB R5,10$ ; Go back if not the end MOV R2,R1 ; R1 => CMDBUF RETURN ; ; ; .SBTTL MCE - CLRSCR -- Clear Screen ; CLRSCR: TSTB ANI+1 ; Ansi Screen ? BEQ 10$ ; No : => 10$ MOV #SCRCLR,ADR ; Clear MOV #SCRCLL,LEN ; screen CALLR IOW ; 10$: SEC ; Not cleared RETURN ; .SBTTL MCE - CMDCHK -- Check for Command definition ; ; Check for Command definition ; or replace first command word by stuff defined in command buffer ; P1..P8 may also be replaced ; ; R0 => Buffer ; LEN = Length ; ; ; CMDCHK: MOV R0,-(SP) ; Save pointer in CMDBUF MOV LEN,-(SP) ; Save initial length ; MOV #CDSC,R1 ; + MOV #CLL/2,R2 ; 10$: ; Clear scratch buffer CLR (R1)+ ; SOB R2,10$ ; - ; MOV R0,R1 ; R1 => Source Buffer MOV LEN,R2 ; R2 = Length MOV #SAVBUF,R3 ; R3 => Destination Buffer MOV #PDSC,R5 ; R5 => Current Parameter Descriptor MOV R3,PX.ADR(R5) ; Start of P0 20$: ; ; Store single char ; MOVB (R1)+,R0 ; R0 = char CALL CNVUPC ; Convert and check for delimiter MOVB R0,(R3)+ ; Store char in SAVBUF BCC 60$ ; No delimiter found : => 60$ 30$: CMPB (R1),#BLNK ; Another Space ? BNE 40$ ; No : => 40$ INC R1 ; Next SOB R2,30$ ; Character ; BR 80$ ; End : => 80$ 40$: ; ; To next Pn ; CMP R5,#PDSC ; Is this P0 ? BNE 50$ ; No : => 50$ MOV R3,CDSC+PX.ADR ; Load start Address of remainder DEC CDSC+PX.ADR ; Point to space 50$: CMP R5,#8.*PX.SIZ+PDSC ; Already on P8 ? BHIS 60$ ; Yes : => 60$, put it all there ADD #PX.SIZ,R5 ; Next Parameter MOV R3,PX.ADR(R5) ; Start address BR 70$ ; Do not count 60$: ; ; No delimiter found ; INC PX.LEN(R5) ; Count char 70$: SOB R2,20$ ; Next character 80$: ; MOV R3,LEN ; Calculate SUB #SAVBUF,LEN ; Compressed length MOV CDSC+PX.ADR,R2 ; Remainder Descriptor defined ? BEQ 90$ ; No => 90$ SUB R2,R3 ; Calculate length MOV R3,CDSC+PX.LEN ; Store length ; ; Now everything is moved into SAVBUF ; Check if we define a new command ":=" in P1 ; 90$: MOV #PDSC+PX.SIZ,R2 ; R2 => P1 descr CMP (R2)+,#2 ; Correct length ? BNE 100$ ; No => 100$ MOV (R2),R2 ; R2 => string CMPB (R2)+,#': ; + BNE 100$ ; CMPB (R2)+,#'= ; ":=" BNE 100$ ; - CALL NEWCMD ; Match found SEC ; Nothing to execute BR 110$ ; => ; ; Try find an entry in the commandbuffer with key P0 ; 100$: CALL FNDCMA ; Check in table BCC 120$ ; Entry found => 120$ CLC ; Indicate success 110$: MOV (SP)+,LEN ; Restore initial length MOV (SP)+,R0 ; Restore pointer in CMDBUF RETURN ; 120$: ; ; Entry found, R1 points to Text ; MOV #CMDBUF,R2 ; R2 => Destination 130$: ; ; Assemble buffer CMDBUF ; MOVB (R1)+,R0 ; Next char BEQ 150$ ; All done : => 150$ CMPB R0,#'' ; Could it be 'Pn' ? BNE 140$ ; No : => 140$ CALL SUBST ; Check it and substitute if necessary BCS 130$ ; Already substituted : => 130$ 140$: MOVB R0,(R2)+ ; Store character in CMDBUF BR 130$ ; Next char from CMD Buf 150$: ; ; Whole buffer moved to CMDBUF ; TSTB CFETCH ; Buffer already feched ? BLT 160$ ; Yes : => 160$ MOV #CDSC,R1 ; This descriptor to append CALL STORE ; Store 160$: ; ; All done, execute new command ; MOV #CMDBUF,R0 ; R0 => CMDBUF SUB R0,R2 ; Calculate new length MOV R2,LEN ; and store CMP (SP)+,(SP)+ ; Flush pointer and length TSTB OVMSG ; Buffer overflow ? BEQ 170$ ; No : => 170$ MOV #TOOLON,R0 ; Give CALL IOMSG ; message SEC ; Not success 170$: RETURN ; .SBTTL MCE - CNVUPC -- Convert to uppercase ; ; Convert to upper case, CC-C set if delimiter ; CNVUPC: CMPB R0,#'A+40 ; Convert to upper case BLO 10$ ; CMPB R0,#'Z+40 ; BHI 10$ ; BICB #40,R0 ; Convert to upper 10$: CMPB R0,#BLNK ; Delimter ? SEC ; BEQ 30$ ; Its a delimiter 20$: CLC ; Character within string 30$: RETURN ; .IF DF STATUS ; .SBTTL MCE - CONV -- Convert 2 characters -> ASCII ; CONV: MOV #11012,R2 ; Convert 2 chars CALLR $CBTA ; Convert .ENDC ;STATUS ; ; .SBTTL MCE - DETACH -- Detach terminal ; DETACH: .IF DF EDT TSTB EDTFLG ; EDT Keys enabled ? BEQ 10$ ; No : => 10$ MOV LEN,-(SP) ; Save length MOV #NUMTXT,ADR ; Numeric keypad MOV #2,LEN ; Length CALL IOW ; Write MOV (SP)+,LEN ; Restore length 10$: .ENDC ;EDT MOV #IO.DET,CODE ; Detach CALLR IO ; the terminal ; ; .SBTTL MCE - DISPLY -- Rewrite whole Line ; DISPLY: TSTB ANI+1 ; Ansi Screen ? BNE 20$ ; Yes : => 20$ CMP ADR,PROMLF ; Just new Line written ? BNE 10$ ; No : => 10$ CMP LEN,#2 ; Something written ? BLE 20$ ; No : => 20$ 10$: MOV PROMLF,ADR ; Line with BR 30$ ; => 30$ 20$: MOV PROMPT,ADR ; Line with 30$: MOV R2,LEN ; Calculate SUB ADR,LEN ; length MOV R0,-(SP) ; Save R0 MOV R2,R0 ; R0 => EOL MOVB #ESC,(R0)+ ; Append MOVB #'[,(R0)+ ; Clear till EOL MOVB #'K,(R0)+ ; Esc sequence TSTB ANI+1 ; Ansi Screen ? BEQ 40$ ; No : => 40$ ADD #3,LEN ; Make Escseq visible 40$: .IF DF EDT TST SELSTR ; Select active ? BEQ 70$ ; No : => 70$ CMP R1,SELSTR ; Compare cursor to start of sel range BEQ 70$ ; - Equal => 70$ MOV R3,-(SP) ; Save R3 MOV R4,-(SP) ; Save R4 BLO 50$ ; - Cursor left of start MOV SELSTR,R3 ; Start MOV R1,R4 ; End BR 60$ ; => 60$ 50$: MOV R1,R3 ; Start MOV SELSTR,R4 ; End 60$: CALL WRISEL ; Write selective range MOV (SP)+,R4 ; Restore R4 MOV (SP)+,R3 ; Restore R3 70$: .ENDC ;EDT CALL IOW ; Write MOVB #BLNK,-(R0) ; + MOVB #BLNK,-(R0) ; Flush Escseq MOVB #BLNK,-(R0) ; - MOV (SP)+,R0 ; Restore R0 MOV #BS,ADR ; + MOV R2,LEN ; SUB R1,LEN ; Restore Cursor BEQ 80$ ; CALLR IO ; - 80$: RETURN ; .SBTTL MCE - DOEXEC -- Submit command to CLI ; DOEXEC: ; ; R0 => First non blank character ; LEN = Length of command ; .IF DF COMPND MOV R0,R3 ; R0 => start of command MOV LEN,R4 ; R4 = Length INC WAITFL ; Always wait 10$: MOV R4,R1 ; R1 = Length BEQ 60$ ; Empty : => 60$ CLR R2 ; Compute length here 20$: CMPB (R3)+,#'& ; Ampersand here ? BNE 30$ ; No : => 30$ CMPB -2(R3),#BLNK ; Preceeded by a space ? BEQ 40$ ; Yes : => 40$ 30$: INC R2 ; Count command length SOB R1,20$ ; End of story ? ; MOV R2,LEN ; Load new length DEC WAITFL ; Restore wait condition CALLR DOEXE1 ; Process last or only command 40$: MOV R2,LEN ; Load new length INC R2 ; Account for &-sign SUB R2,R4 ; Compute unused string length BEQ 50$ ; Empty ? Yes : => 50$ ; ; Execute ..... ; CALL DOEXE1 ; Go execute it STSE$S WAITFL ; Stop for execution CMP EXSTAT,#EX$SUC ; Successfull ? BEQ 50$ ; Yes : => 50$ ; ; Message with exit status ..... ; MOV R0,-(SP) ; Save R0 MOV LEN,-(SP) ; Save Length MOV #EXSTDA,R0 ; R0 => ASCII buffer MOV EXSTAT,R1 ; R1 = Value MOV #27012,R2 ; R2 = Parameters CALL $CBTA ; Convert to ASCII MOV #EXSTMS,ADR ; MOV #EXSTML,LEN ; CALL IOW MOV (SP)+,LEN ; Restore Command length MOV (SP)+,ADR ; Restore Command pointer CALLR IOW 50$: MOV R3,R0 ; Set to unused string BR 10$ ; Go for next part 60$: RETURN ; .ENDC ;COMPND DOEXE1: ; .IF DF COMPND CALL SUPRR0 ; Suppress Leading spaces .ENDC ;COMPND TSTB ECHFLG ; Echo ? BEQ 10$ ; No : => 10$ MOV LEN,-(SP) ; Save length CALL IOCRLF ; New line MOV (SP),LEN ; Get length MOV R0,ADR ; Address of command CALL IOW ; Write command CALL IOCR ; New line MOV (SP)+,LEN ; Restore length 10$: ; ; *** EXECUTE COMMAND *** ; MOV R0 ,SPAWN+S.PWCA MOV LEN ,SPAWN+S.PWCL DIR$ #SPAWN ; RETURN ; .IF DF FILE ; .SBTTL MCE - FILCLO -- Close current MCEINI file ; FILCLO: CLRB FILINP ; No file input CLOSE$ #FDBIN ; Close inputfile TST FDIR ; Was it first default file ? BEQ 10$ ; No : => 10$ CALL FILOP3 ; Open next file BCS 10$ ; CALLR FILREA ; If opened : => FILREA 10$: RETURN ; ; ; .SBTTL MCE - FILOP -- Open MCEINI file from MCR line ; FILOP: INCB FILINI ; Startup file CALL GETMCR ; Get MCR commandline (startup file) BCC FILOP2 ; OK : => FILOP2 RETURN ; ; ; .SBTTL MCE - FILOP1 -- Open MCEINI file ; FILOP1: CLRB FILINI ; No startup FILOP2: CALL GETCLI ; Get CLI info CALL FILOP4 ; Open File LB:[1,2]xxx.CLI BCC FILRET ; Success TST FDIR ; Was it first default file ? BEQ 10$ ; No : => 10$ CALL FILOP3 ; Open 'SY:xxx.CLI' BCC FILRET ; Ok : => FILRET TSTB FILINI ; Startup ? BNE FILRET ; Yes : => FILRET 10$: MOV #FILTXT,R0 ; Error CALLR IOMSG ; Message ; FILOP3: CLR FDIR ; No directory descriptor MOV #"SY,DEV ; Try file 'SY:xxx.CLI' FILOP4: CLRB FILINP ; Assume file can not be opened OPEN$R #FDBIN ; Open input file BCS FILRET ; Not OK : => FILRET INCB FILINP ; Enable File Input FILRET: RETURN ; Return ; .SBTTL MCE - FILREA -- Read from MCEINI file ; FILREA: GET$S #FDBIN ; Get a record BCC 10$ ; CALLR FILCLO ; No more records : => Close file 10$: MOV F.NRBD(R0),LEN ; Length CALL REPLHT ; Replace TABs CALL SUPRES ; Ignore leading blanks BCS FILREA ; Empty line : => FILREA TST (SP)+ ; Do not return MOV #1,WAITFL ; Wait for execution of commands CALLR EXEC2 ; but execute directly .ENDC ;FILE .SBTTL MCE - FNDCMA -- Find entry in command table with "*" .SBTTL MCE - FNDCMD -- Find entry in command table ; ; ; Input - PDSC of P0 defined ; - CTSTAR .ne.0 to allow abreviated command if command ; definition contains "*" (a la VMS) ; Output - CC-C set - no entry found ; CC-C clr - entry found ; R0 - to entry ; R1 - to point to string after ":=" ; R2 - to previous entry (for remove and inserts) ; FNDCMA: .ENABL LSB MOVB #1,CTSTAR ; Enable abbrivations BR 10$ ; FNDCMD: CLRB CTSTAR ; Ignore "*" in translation buffer 10$: MOV #TRNB+F.1ST,R0 ; R0 => Translationbuffer MOV R3,-(SP) ; Save R3 MOV R1,-(SP) ; Save R1 CLR -(SP) ; For previous entry 20$: MOV R0,(SP) ; Save previous entry TST FI.NXT(R0) ; Any next entry ? BEQ 100$ ; No : => 100$, end of list MOV FI.NXT(R0),R0 ; Take next entry MOV R0,R1 ; R1 => Entry ADD #FI.TXT,R1 ; R1 => Text MOV PDSC+PX.LEN,R3 ; Length to be compared BLE 100$ ; Zero : => 100$ MOV PDSC+PX.ADR,R2 ; Start addr of P0 TSTB CTSTAR ; Without abbreviation ? BEQ 80$ ; Yes : => 80$ ; ; Check for match, accepting any "*" in command defintion ; CLRB TMPFLG ; Reset Flag: "*" found in Cmd Translation 30$: CMPB (R1),#'* ; Check for "*" in translation buffer BNE 40$ ; Not yet found : => 40$ INCB TMPFLG ; Found, remember it INC R1 ; Next char 40$: CMPB (R1),#BLNK ; End of translation buffer ? BEQ 60$ ; Yes : => 60$, terminate compare CMPB (R2)+,(R1)+ ; Equal ? BEQ 50$ ; Yes : => 50$ BGT 20$ ; NE and must come further down in list TSTB TMPFLG ; Passed entry - any "*" seen ? BNE 20$ ; Yes : => 20$, continue search BR 100$ ; We passed alphabetical order : => 100$ 50$: SOB R3,30$ ; Next char ; CMPB (R1),#BLNK ; End of input string ? BEQ 70$ ; Yes : => 70$ CMPB (R1),#'* ; Next byte end ? BEQ 70$ ; Yes : => 70$ 60$: TSTB TMPFLG ; Abbreviation possible ? BEQ 20$ ; No : => 20$ 70$: CMPB (R1)+,#BLNK ; End of string (or binary 0???) ? BHI 70$ ; Not yet found : => 70$ BR 90$ ; Point past key ; ; Check for match, ignoring any "*" in command defintion ; 80$: CMPB (R2)+,(R1)+ ; Compare BGT 20$ ; NE and must come further down in list BLT 100$ ; Already passed alphabetical order SOB R3,80$ ; Next ; CMPB (R1)+,#BLNK ; Followed by space ? BNE 100$ ; No : => 100$ 90$: ADD #3,R1 ; Skip ":= " CLC ; Successful MOV (SP)+,R2 ; R2 => Previous entry TST (SP)+ ; Flush old R1 BR 110$ ; 100$: SEC ; Not found MOV (SP)+,R2 ; R2 => Previous entry MOV (SP)+,R1 ; Old R1 110$: MOV (SP)+,R3 ; Restore R3 RETURN ; .DSABL LSB .SBTTL MCE - FRENT -- Free entry from queue ; ; Header in R0. CC-C clear if it was empty ; FRENT: JSR R5,.SAVR1 ; Save Regs MOV F.1ST(R0),R2 ; Get entry if any CLC ; Assume empty BEQ 20$ ; None : => 20$ MOV FI.NXT(R2),FI.NXT(R0) ; Remove from head of queue BNE 10$ ; More entries MOV R0,F.LAST(R0) ; This was last one 10$: MOV FI.LEN(R2),R1 ; R1 = Length of entry MOV #FREE,R0 ; R0 => Free memory list head CALL $RLCB ; Release memory block SEC ; Success 20$: RETURN ; ; ; .SBTTL MCE - GETBUF -- Load Buffer into CMDBUF ; ; R0 points to source ; GETBUF: MOV #CMDBUF,R1 ; R1 => CMDBUF MOV R1,R2 ; R1 => CMDBUF MOV #CMDSIZ,R5 ; R5 = CMDSIZ 10$: TSTB PRIFLG ; Print commandbuffer ? BEQ 30$ ; No : => 30$ CMPB (R0),#': ; Command definition ? BNE 30$ ; No : => 30$ CMPB -1(R0),#BLNK ; Space in front ? BNE 30$ ; No : => 30$ CMPB 1(R0),#'= ; Equal sign behind ? BNE 30$ ; No : => 30$ 20$: MOVB #BLNK,(R1)+ ; Insert spaces CMP R1,#CMDBUF+12. ; At posision ? BLO 20$ ; No : => 20$ 30$: MOVB (R0)+,(R1)+ ; (R0) --> CMDBUF BEQ 50$ ; Zero : => 50$ CMPB -1(R1),#BLNK ; Blank ? BEQ 40$ ; Yes : => 40$ MOV R1,R2 ; R2 => Behind last 40$: SOB R5,10$ ; Go back if not the end BR 60$ ; => 60$ 50$: MOVB #BLNK,-1(R1) ; Overprint 000 (.ASCIZ) 60$: MOV R2,R1 ; Both at the end RETURN ; .IF DF CLISUP!FILE ; ; .SBTTL MCE - GETCLI -- Get CLI information ; GETCLI: DIR$ #GCLI ; Get CLI information BCS 10$ ; Error is C set .IF DF CLISUP&FILE MOV CLINAM,FILTYP ; Use CLI name for file type .ENDC ;CLISUP&FILE .IF DF FILE CALL $SAVAL ; Save all registers MOV #CURDIR,R2 ; R2 => Ascii Current directory MOV CLIUIC,R3 ; Binary value from GCLI CLR R4 ; Parameters ( No lea. zeroes, add separ. ) CALL .PPASC ; Convert to ASCII MOV R2,R1 ; Calculate MOV #CURDIR,R2 ; length SUB R2,R1 ; and point to Ascii CALL .WDFDR ; Write default UIC .ENDC ;FILE 10$: RETURN ; .ENDC ;CLISUP!FILE ; ; .SBTTL MCE - GETFIF -- Get FIFO Buffer, pointed to by FIFPTR ; GETFIF: CLRB OLDFLG ; No old command MOV FIFPTR,R0 ; Get Ptr BNE 10$ ; Defined : => 10$ MOV #FIFPTR,R0 ; Null String BR 20$ ; => 20$ 10$: INCB OLDFLG ; Old command ADD #FI.TXT,R0 ; Get start of text 20$: CALL GETBUF ; Load buffer CALLR DISPLY ; and display ; ; .IF DF FILE ; .SBTTL MCE - GETFIL -- Get filespecification .SBTTL MCE - GETMCR -- Get filespecification from MCR command ; ; This subroutine dequeues the command which invokes MCE (if any), ; and overrides the default startup file name (MCEINI.xxx) by ; file specified in the commandline. ; Command line syntax is : 'MCE file_specification' ; .ENABL LSB GETMCR: DIR$ #GMCR ; Get commandline BCS 20$ ; Problem => 20$ MOV #MCRLIN,R1 ; Point to commandline MOV $DSW,R2 ; Length of line GETFIL: ; ; reset FDB file-name pointers ; MOV #"LB,DEV ; Reset default file volume MOV #DIRL,FDIR ; Restore pointer to default directory MOV #FDSPT,FDBIN+F.DSPT ; Reset DSPT pointer in FDB TST R2 ; Any length ? BEQ 20$ ; No : => 20$ 10$: CMPB #BLNK,(R1)+ ; Mnemonic delimiter ? BEQ 30$ DEC R2 ; Count remaining char BNE 10$ ; If eq: empty command 20$: CLC ; Success BR 50$ ; 30$: DEC R2 ; Flush space CSI$1 #CSIBLK,R1,R2 ; Syntax check BCS 40$ ; Syntax error: ignore it CSI$2 R0,OUTPUT ; Parse line into its com BCS 40$ ; No file: ignore it ; ; Now we have a file descriptor table inside the CSI parser block ; override the default DSPT pointing to MCEINI.CMD: ; MOV #CSIBLK+C.DSDS,FDBIN+F.DSPT ; New DSPT pointer CLR FDIR ; Indicate 'No more files' BR 50$ ; => 50$ 40$: MOV #FLSTXT,R0 ; Filespec CALL IOMSG ; syntax error SEC ; Indicate error 50$: RETURN ; .DSABL LSB .ENDC ;FILE .SBTTL MCE - IO -- General I/O Routine ; IO: .IF DF TMOTIM MOVB #TMOTIM,TMOCNT ; Set new timeoutcount .ENDC ;TMOTIM DIR$ #QIODIR ; Do I/O DIR$ #STOPIO ; Stop for I/O (or wait when aborted) RETURN ; ; ; .SBTTL MCE - IOCR -- Print ; IOCR: MOV #1,LEN ; Length BR IOCL ; => IOCL ; .SBTTL MCE - IOCRLF -- Print ; IOCRLF: MOV #2,LEN ; Length IOCL: MOV #IO.CCO,CODE ; Cancel MOV #CRET,ADR ; Print ( ) BR IO ; Go to IO ; ; .SBTTL MCE - IOMSG -- Print Message ; ; Print a Msg in (R0) ; IOMSG: CALL IOCRLF ; Print CALL GETBUF ; (R0) --> CMDBUF CALL DISPLY ; Write line CALLR CLRBUF ; ; ; .SBTTL MCE - IOW -- Write routine ; IOW: MOV #IO.WVB,CODE ; write BR IO ; Go to IO ; ; .SBTTL MCE - LDFIF -- Load CMDBUF into FIFO Buffer ; ; R0 => First non blank character ; LEN = Length of command ; LDFIF: CALL $SAVAL ; Save Regs MOV LEN,R5 ; R5 = Length BEQ 40$ ; Zero : => 40$ CMP R5,MINC ; Save it ? BLO 40$ ; No : => 40$ MOV R0,R4 ; R4 => Command MOV R5,R1 ; R1 = Length ADD #FI.TXT+1,R1 ; Increment for header and 0 byte CMPB FIFCNT,MAXF ; Maximum reached ? BLO 20$ ; No : => 20$ 10$: CALL CLFIFI ; Release first entry BCC 40$ ; Nothing to release 20$: MOV #FREE,R0 ; R0 => Free memory listhead CALL $RQCB ; Request core block BCS 10$ ; Nothing received yet - release more CLR FI.NXT(R0) ; No next entry MOV R0,@FIFO+F.LAST ; Link to previous MOV R0,FIFO+F.LAST ; New last entry MOV R1,FI.LEN(R0) ; Total length ADD #FI.TXT,R0 ; Point to text field MOV R4,R1 ; Source text 30$: MOVB (R1)+,(R0)+ ; Load SOB R5,30$ ; string CLRB (R0) ; End of string INCB FIFCNT ; Count 40$: RETURN ; .IF DF TMOTIM ; .SBTTL MCE - MARK -- Next Marktime MARK: MRKT$S ,#60.,#2,#TIMAST;(;) RETURN ;(;) .ENDC ;TMOTIM .SBTTL MCE - NEWCMD -- Define new command or delete command ; ; Define new command in command buffer, or delete it ; NEWCMD: TSTB NLOFLG ; Skip processing ? BNE 50$ ; Yes : => 50$ CALL FNDCMD ; Check if in table BCC 60$ ; Yes : => 60$, release old entry TST 2*PX.SIZ+PDSC ; P2 defined ? BNE 10$ ; Yes : => 10$, must load TST 3*PX.SIZ+PDSC+PX.ADR ; P3 with addr ? BEQ 50$ ; No : => 50$, delete only 10$: ; ; Insert new command ; MOV R2,R3 ; R3 => Entry after which to insert MOV LEN,R1 ; length of string BEQ 50$ ; Zero : => 50$ ADD #FI.TXT+1,R1 ; With overhead and 0 byte MOV #FREE,R0 ; R0 => Free memory listhead CALL $RQCB ; Request core block BCC 20$ ; Ok : => 20$ MOV #NOPOOL,R0 ; No more Pool CALL IOMSG ; Give the message BR 50$ ; => 50$ 20$: MOV FI.NXT(R3),FI.NXT(R0) ; Link to previous entry BNE 30$ ; MOV R0,TRNB+F.LAST ; We will be last one 30$: MOV R0,FI.NXT(R3) ; MOV R1,FI.LEN(R0) ; Total length ADD #FI.TXT,R0 ; R0 => Start of text MOV #SAVBUF,R1 ; R1 => Source MOV LEN,R2 ; R2 = Length 40$: MOVB (R1)+,(R0)+ ; Copy SOB R2,40$ ; text CLRB (R0) ; Write delimiter 50$: RETURN ; 60$: ; ; Release old entry ; MOV FI.NXT(R0),FI.NXT(R2) ; Link remainder BNE 70$ ; More entries : => 70$ MOV R2,TRNB+F.LAST ; This was last one 70$: MOV FI.LEN(R0),R1 ; R1 = Length MOV R0,R2 ; MOV #FREE,R0 ; R0 => Free memory listhead CALL $RLCB ; Release it BR NEWCMD ; Find more to release .IF DF STATUS ; .SBTTL MCE - OFFON -- Depending on flag in R1 : Fill with ON or OFF ; OFFON: ; MOVB #'o,(R0)+ ; + TSTB (R1) ; BEQ 10$ ; MOVB #'n,(R0)+ ; MOVB #' ,(R0)+ ; RETURN 10$: MOVB #'f,(R0)+ ; MOVB #'f,(R0)+ ; RETURN ; - .ENDC ;STATUS .SBTTL MCE - PRICMD -- Print Cmd buffer and put pointer to end of queue ; PRICMD: MOV #TRNB+F.1ST, FIFPTR ; Point to Translationbuffer INCB PRIFLG ; Flag Tarnslationbuffer print-out BR PRIXXX ; => PRIXXX ; ; .SBTTL MCE - PRIFIF -- Print FIFO and put pointer to end of queue ; PRIFIF: MOV #FIFO+F.1ST,FIFPTR ; Point to FIFO PRIXXX: CALL CLRSCR ; Clear screen BCC 20$ ; Cleared : => 20$ 10$: CALL IOCRLF ; Blank line 20$: MOV @FIFPTR,FIFPTR ; Next PTR BEQ 30$ ; Done : => 30$ CALL GETFIF ; Display BR 10$ ; => 10$ 30$: CLRB PRIFLG ; Flag commandbuffer print-out CALL IOCRLF ; Blank line CALL CLRBUF ; Clear edit buffer (FIFPTR already cleared) .IF DF STATUS CALL DISPLY ; and display prompt CALLR PRISTA ; Print status line .IFF ;STATUS CALLR DISPLY ; and display prompt .IFT ;STATUS .SBTTL MCE - PRISTA -- Print the status line ; PRISTA: MOV #STATX1,ADR ; Print MOV #STALN1,LEN ; The BR PRIST2 ; Statusline PRIST1: MOV #STATX2,ADR ; Print MOV #STALN2,LEN ; The BR PRIST2 ; status line PRIST2: CALL STAFIL ; Fill status record TSTB STAFLG ; Statusline wanted ? BEQ 10$ ; No : => 10$ CALLR IOW ; Statusline 10$: RETURN ; .ENDC ;STATUS .SBTTL MCE - RECCMD -- Recall command from FIFO ; ; Recall Command from FIFO by key ; RECCMD: CLR -(SP) ; Room for Pointer to FIFO entry MOVB FIFPOI,R5 ; R5 = FIFO entry number MOV FIFO+F.1ST,R4 ; R4 => Oldest Entry in FIFO BEQ 50$ ; Empty : => 50$ MOVB #1,R5 ; Start above oldest TST FIFPTR ; Old pointer ? BNE 20$ ; Defined : => 20$ MOV #CMDBUF,R1 ; R1 => Source Buffer MOV #RCLBUF,R3 ; R3 => Destination Buffer SUB R1,R2 ; R2 = Length BLE 20$ ; Zero : => 20$ 10$: ; ; Store single char into Recall buffer ; MOVB (R1)+,R0 ; R0 = next char CALL CNVUPC ; Convert MOVB R0,(R3)+ ; Store char SOB R2,10$ ; Next CLRB (R3) ; EOL 20$: ; ; Check next entry in FIFO ; MOV #RCLBUF,R1 ; R1 => Source to Compare TSTB (R1) ; Search mask defined ? BEQ 50$ ; No : => 50$ MOV R4,R3 ; R3 => Entry ADD #FI.TXT,R3 ; R3 => Text of entry 30$: MOVB (R3)+,R0 ; R0 = Next char BEQ 40$ ; EOL : => 40$ CALL CNVUPC ; Convert to uppercase CMPB R0,(R1)+ ; Compare with source BNE 40$ ; No match : => 40$ TSTB (R1) ; EOL ? BNE 30$ ; No : => 30$, Try next char MOV R4,(SP) ; Source exhausted - match found MOVB R5,FIFPOI ; Store FIFO entry number 40$: INCB R5 ; One newer MOV FI.NXT(R4),R4 ; R4 => Next entry BEQ 50$ ; No more : => 50$ CMP R4,FIFPTR ; Continue search ? BNE 20$ ; Yes : => 20$ 50$: MOV (SP)+,FIFPTR ; Pop Pointer to entry if any BNE 60$ ; Any pointer ? => 60$ CLRB FIFPOI ; 60$: CALL GETFIF ; Load from FIFO (or delete CMDBUF buffer) RETURN ; .SBTTL MCE - REPLHT -- Replace TABs ; REPLHT: ; MOV #CMDBUF,R0 ; R0 => CMDBUF MOV LEN,R2 ; Length BEQ 30$ ; Empty ? Yes : => 30$ 10$: CMPB (R0)+,#HT ; TAB ? BNE 20$ ; No : => 20$ MOVB #BLNK,-1(R0) ; Replace by space 20$: SOB R2,10$ ; 30$: RETURN ; ; ; .SBTTL MCE - SPBACK -- Backspace 1 char. ; SPBACK: CMP R1,#CMDBUF ; At begin of buffer ? BLOS 10$ ; Yes : => 10$ MOV #BS,ADR ; Write MOV #1,LEN ; a CALL IOW ; backspace DEC R1 ; Shift cursor RETURN ; 10$: SEC ; Indicate cursur error RETURN ; ; ; .SBTTL MCE - SRWORD -- Search for word ; SRWORD: CMPB R0,#'0 ; Digit ? BLO 10$ ; No : => 10$ CMPB R0,#'9 ; Digit ? BLO 20$ ; Yes : => 20$ CMPB R0,#'_ ; Special char ? BEQ 20$ ; Yes : => 20$ BIC #40,R0 ; Convert to uppercase CMPB R0,#'A ; Alphabetical ? BLO 10$ ; No : => 10$ CMPB R0,#'Z ; Alphabetical ? BLOS 20$ ; Yes : => 20$ 10$: SEC ; RETURN 20$: CLC ; RETURN .IF DF STATUS ; .SBTTL MCE - STAFIL -- Fill status line ; STAFIL: ; MOV R1,-(SP) ; Save R1 MOV R2,-(SP) ; Save R2 MOV #STALIR,R0 ; + TSTB RNGFLG ; BEQ 10$ ; MOVB #'r,(R0)+ ; MOVB #'i,(R0)+ ; MOVB #'n,(R0)+ ; MOVB #'g,(R0)+ ; Ring or List BR 20$ ; 10$: MOVB #'l,(R0)+ ; MOVB #'i,(R0)+ ; MOVB #'s,(R0)+ ; MOVB #'t,(R0)+ ; - 20$: TSTB (R0)+ ; + MOV MAXF,R1 ; Maxfif CALL CONV ; - TSTB (R0)+ ; + MOVB FIFCNT,R1 ; Fifcnt CALL CONV ; - TSTB (R0)+ ; + MOVB FIFPOI,R1 ; Fifpoi CALL CONV ; - MOV #STACMD,R0 ; + MOV MINC,R1 ; Minchr CALL CONV ; - .IF DF EDT MOV #STAKEY,R0 ; + MOV #EDTFLG,R1 ; Keypad CALL OFFON ; - .ENDC ;EDT MOV #STASVI,R0 ; + MOV #SINFLG,R1 ; Save internals CALL OFFON ; - MOV #STASVR,R0 ; + MOV #SOLFLG,R1 ; Save old CALL OFFON ; - .IF DF TMOTIM MOV #STATMO,R0 ; + MOVB TMOCNT,R1 ; Time-out count MOV #15012,R2 ; CALL $CBTA ; - .ENDC ;TMOTIM MOV (SP)+,R2 ; Restore R2 MOV (SP)+,R1 ; Restore R1 RETURN ; .ENDC ;STATUS ; .SBTTL MCE - STORE -- Append string with descriptor (R1) to CMDBUF ; STORE: ; ; MOV PX.LEN(R1),R5 ; R5 = Length BEQ 30$ ; Empty : => 30$ MOV PX.ADR(R1),R1 ; R1 = Source Addr 10$: CMP R2,#CMDEND ; In range ? BLO 20$ ; Yes : => 160 DECB OVMSG ; Mark for Ovflw RETURN ; 20$: MOVB (R1)+,(R2)+ ; Copy SOB R5,10$ ; characters 30$: RETURN ; ; .SBTTL MCE - SUBST -- Check and substitute if necessary SUBST: ; ; Substitute Pn's ; JSR R5,.SAVR1 ; Save Regs CMPB (R1)+,#'P ; Check next symbol BNE 10$ ; No match : => 10$ MOVB (R1)+,R3 ; Get Parameter number SUB #'0,R3 ; Decode BLE 10$ ; Illegal : => 10$ CMP R3,#8. ; In range ? BHI 10$ ; No : => 10$ CMPB (R1)+,R0 ; Endmark ? BEQ 20$ ; Yes : => 20$ 10$: CLC ; Tell no substitution RETURN ; 20$: ; ; Substitution string found ; MOV R1,2(SP) ; Set up R1 after return ASL R3 ; Param num ASL R3 ; times 4 ADD #PDSC,R3 ; R3 => Descriptor MOV R3,R1 ; CALL STORE ; Load it MOV R2,2*2(SP) ; Load R2 after return DECB CFETCH ; Mark that parameter fetched SEC ; Tell substituted RETURN ; ; ; .SBTTL MCE - SUPRES -- Suppress leading blanks ; SUPRES: ; MOV #CMDBUF,R0 ; R0 => CMDBUF ; .SBTTL MCE - SUPRR0 -- Suppress leading blanks ( Start at R0 ) ; SUPRR0: ; TST LEN ; Empty ? BEQ 20$ ; Yes : => 20$ 10$: CMPB (R0),#BLNK ; Start with a Space ? BNE 30$ ; No : => 30$ INC R0 ; Next := First DEC LEN ; One less BNE 10$ ; Not Empty : => 10$ 20$: SEC ; Return RETURN ; 30$: CLC ; Success RETURN ; ; ; .SBTTL MCE - TERM -- Get terminal information ; TERM: MOV #SFGMCB,ADR ; GMC Buffer MOV #SFGMCL,LEN ; GMC Bufferlength MOV #SF.GMC,CODE ; GMC Code .IF DF STATUS CALL IO ; Do it TSTB ANI+1 ; ANSI Terminal BNE 10$ ; Yes : => 10$ CLRB STAFLG ; No statusline possible 10$: RETURN ; .IFF ;STATUS CALLR IO ; Do it .ENDC ;STATUS .IF DF TMOTIM .SBTTL MCE - TIMAST -- TI: Time-out AST ; ; On timeout - log off (TT0: just exit) ; TIMAST: TST (SP)+ ;; Restore stack DECB TMOCNT ;; Timeout ? BLT 10$ ;; Should not have decremented BNE 20$ ;; Not yet ; ; Timed out - kill pending read ; MOV #IO.KIL,CODE ;; Kill CALL IO ;; pending read 10$: CLRB TMOCNT ;; 20$: .IF DF STATUS CALL STAFIL ;; Fill statusline TSTB STAFLG ;; Statusline wanted ? BEQ 30$ ;; No : => 30$ QIOW$S #IO.WVB,#TI,#EFNAST,,,,<#STATX2,#STALN2,#0> 30$: .ENDC ;STATUS CALL MARK ;; Mark time ASTX$S ;; Exit ast .ENDC ;TMOTIM ; ; .SBTTL MCE - UPDATE -- Update commandline ; ; Write from current Position to End of Line and reposition Cursor ; UPDATE: MOV R1,ADR ; Address of Cursor MOV R2,LEN ; R2 => EOL SUB R1,LEN ; Length BEQ 10$ ; Zero : => 10$ CALL IOW ; Write rest of line MOV #BS,ADR ; Address backspaces CALLR IO ; Reposition Cursor 10$: RETURN ; .IF DF EDT ; .SBTTL MCE - WRISEL -- Write selective range ; WRISEL: ; ; | B U F F E R . . . . . . . . . . |clrlin| ; ^ ^ ^ ^ ^ ; ADR R3 R4 R2 R0 ; start end ; | | ; LEN = length of buffer --------------+------+ ; TSTB ANI+1 ; Ansi Screen ? BEQ 10$ ; No : => 10$ MOV LEN,-(SP) ; Save length MOV R3,LEN ; Calculate SUB ADR,LEN ; length to start of range SUB LEN,(SP) ; Update restlength CALL IOW ; Write ; MOV #INV,ADR ; Addres of inv esc seq. MOV #INVL,LEN ; Length CALL IOW ; ; MOV R3,ADR ; Address of range MOV R4,LEN ; Calculate SUB R3,LEN ; length of range SUB LEN,(SP) ; Update restlength CALL IOW ; ; MOV #NOR,ADR ; Addres of inv esc seq. MOV #NORL,LEN ; Length CALL IOW ; ; MOV R4,ADR ; Address of rest MOV (SP)+,LEN ; Rest length 10$: RETURN ; .ENDC ;EDT .END START