.TITLE MCE - CLI-Commandline-Editor .IDENT -V4.2d- ;JHB03 .ENABLE LC ; ; Copyright (c) 1988 ; ; J.H. Hamakers, ; ASEA Brown Boveri 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 | ; +---------------------------------------------------+ ; .SBTTL MCE - Macros, Constants, Variables .MCALL QIO$S ,QIOW$S ,EXIT$S ,SPWN$S ,STSE$ ,STSE$S .MCALL MRKT$S ,SDIR$S ,SREX$S ,WTSE$ ,DIR$ .IF DF COMPND ;JHB03 ;JHB03 .MCALL WTSE$S ;JHB03 ;JHB03 .ENDC ;COMPND ;JHB03 .IF DF TMOTIM .MCALL ASTX$S ,GLUN$S .ENDC ;TMOTIM .IF DF CLISUP .MCALL GCII$S .ENDC ;CLISUP .NLIST BEX ; ; Local symbol definitions ; BUFSIZ = 76. ; (this is max for >SET /BUF=TI:80.) ; BELL = 7 BKSP = 10 LF = 12 CR = 15 ESC = 33 BLNK = 40 DEL = 177 SS3 = 217 ; SS3 8-bit control character ; TI = 1 ; TI: LUN INI = 2 ; MCEINI.xxx LUN EFN = 1 ; Eventflag .IF DF TMOTIM&STATUS EFNAST = 2 ; Eventflag in TIMAST .ENDC ;TMOTIM&STATUS .IIF NDF MAXFIF MAXFIF = 23. .IIF NDF MINCHR MINCHR = 0 .IF DF FILE .MCALL CSI$ .MCALL DIR$,GMCR$ .MCALL CSI$1,CSI$2 .MCALL FSRSZ$,FDBDF$,FDRC$A,FDOP$A,OPEN$R,GET$S,CLOSE$,NMBLK$ CSI$ ; Define CSI control block offsets FSRSZ$ 1 .PSECT IDATA,D,RW STOPIO: STSE$ EFN ; Normaly we STOP for I/O. When MCE is aborted WAITIO: WTSE$ ; we WAIT for I/O. We use this directive here ; to copy the DIC-code to STOPIO (See EXAST:) FDBIN: FDBDF$ ; FDB for initialization FDRC$A ,NEW,BUFSIZ FDOP$A INI,FDSPT,DFNB,FO.RD DEV: .ASCII /LB:/ ; Device Name DEVL = .-DEV DIR: .IF DF A$SV .ASCII /[2,2]/ ; Directory .IFF ;A$SV .ASCII /[1,2]/ ; Directory .ENDC ;A$SV DIRL = .-DIR .EVEN ; ; Default startup file name block ; ; Default file name (if no CLI support) is 'MCEINI.CMD' ; default device is SY: (but superimposed by the first LB: in DSPT ; SY: in the DFNB will be effective for files specified in the ; invoking MCR commandline. Specifying 'MCE XXX' thus results in ; file name 'SY0:XXX.CMD' ; Note, that the file-type in DFNB will be overwritten by the CLI name ; DFNB: NMBLK$ MCEINI,CMD,0,SY,0 DFTYP = DFNB+N.FTYP ; Define address of RAD-50 filetype ; FDSPT: DEVL,DEV ; File Descriptor: Device FDIR: DIRL,DIR ; Directory string at begin 0 ,0 ; No File name (DFNB will be used) ; ; CSI$ Control block ; CSIBLK: CSI$ .BLKB C.SIZE .EVEN .ENDC ;FILE POOLTX: .ASCII /MCE -- Pool:/ POOLDT: .BLKB 18. .EVEN POOL: 0,0,0 ; Pool information MAXF: MAXFIF ; Fifo size MINC: MINCHR ; Commandlength to be saved .PSECT PDATA,D,RO ; ; Text Formats ; STRTXT: .ASCII \MCE -- CLI-Commandline-Editor V4.2d\ ;JHB03 ; .IF DF A$SV .ASCII \/ASV\ .ENDC ;A$SV .IF DF VT2XX .ASCII \/VT2\ .ENDC ;VT2XX .IF DF TDV2XX .ASCII \/TDV\ .ENDC ;TDV2XX .ASCIZ ENDTXT: .ASCII EXITXT: .ASCIZ /MCE -- Exit/ CRET: NOPOOL: .ASCIZ /MCE -- Pool exhausted - Install MCE with INC/ ERRTXT: .ASCIZ /MCE -- Internal command error/ TOOLON: .ASCIZ /MCE -- Command too long/ .IF DF FILE FLSTXT: .ASCIZ /MCE -- Filespecification syntax error/ FILTXT: .ASCIZ /MCE -- File open error/ .ENDC ;FILE .IF DF TMOTIM BYETXT: .ASCIZ /BYE/ .ENDC ;TMOTIM .IF DF VT2XX VT2ESQ: .ASCII /[23~/ ; VT2XX Picture VT2ESL = .-VT2ESQ ; .ENDC ;VT2XX HLPTXT: .IF DF A$SV .ASCIZ \HELP ASV MCE\ .IFF ;A$SV .IF DF HLPNEW .ASCIZ \HELP /MCE\ .IFF ;HLPNEW .ASCIZ \HELP MCE\ .ENDC ;HLPNEW .ENDC ;A$SV .IF DF EDT APLTXT: .ASCII /=/ NUMTXT: .ASCII />/ EDTTXT: .IF DF A$SV .ASCIZ \HELP ASV MCE KEYPAD\ .IFF ;A$SV .IF DF HLPNEW .ASCIZ \HELP /MCE KEYPAD\ .IFF ;HLPNEW .ASCIZ \HELP MCE KEYPAD\ .ENDC ;HLPNEW .ENDC ;A$SV .ENDC ;EDT .EVEN ; ; internal MCE command dispatch table (see subroutine Intern) ; INTCMD: .ASCII /EXIT/ ; Task exit EXIT .ASCII /PURG/ ; Delete all command translations ICPURG .ASCII /RING/ ; FIFO is a ringbuffer ICRING .ASCII /LIST/ ; FIFO is a list ICLIST .ASCII /FREE/ ; Free poolspace ICFREE .ASCII /FISZ/ ; Fifo maximum ICMAXF .ASCII /CMSZ/ ; Minimum cmd size ICMINC .ASCII /CLEA/ ; Clear fifo ICCLEA .ASCII /VERS/ ; Version ICVERS .ASCII /SVIN/ ; Save Internal commands on/of ICSVIN .ASCII /SVOL/ ; Save Old commands on/of ICSVOL .IF DF STATUS .ASCII /STAT/ ; Status line on/of ICSTAT .ENDC ;STATUS .IF DF FILE .ASCII /READ/ ; Read definition file 'MCE READ filespc' ICREAD .ASCII /CHAI/ ; Chain to other file (= READ) ICREAD .ASCII /REPL/ ; Replace translations by new file ICREPL .ENDC ;FILE .IF DF EDT .ASCII /KEYP/ ICKEYP .ENDC ;EDT 0 ; End of table marker ; .PSECT IDATA ; ; data ; ; ; FIFO Buffer descriptors ; ; Entry offsets : ; ;FNXT = 0 ; Pointer to next Entry FLEN = 2 ; Length of entry FTXT = 4 ; Text, terminated by binary 0 FIFO: 0, FIFO ; Header FIFO Buffer: FIFCNT: .BYTE 0 ; Number of entries in FIFO FIFPOI: .BYTE 0 ; Entry number FIFPTR: 0 ; Ptr to current Entry (for UP, DOWN keys) ; ; Commandbuffer, same entries as in FIFO ; CMDB: 0, CMDB ; Header command definitions ; FREE: 0, 0 ; Free memory listhead ; ; Terminal characteristics buffer ; SFGMCB: ANI: .BYTE TC.ANI,0 ; ANSII 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 IOSTAT: .BLKW 2 ; I/O Statusblock ; PROMLF: DEFPR ; Point to default prompt with PROMPT: DEFPR+1 ; Point to default prompt with ; ; Buffers ; .IF DF STATUS STATX1: .ASCII "D" .ASCII "M" STATX2: .ASCII "7" .ASCII "[1;23r" .ASCII "[24;1H" .ASCII "[7m" STATX3: .ASCII "MCE-V4.2c FIFO:" STALIR: .ASCII "list/" .ASCII "xx/" .ASCII "xx/" .ASCII "xx CMSZ:" STACMD: .ASCII "xx KEYP:" STAKEY: .ASCII "xxx SVINT:" STASVI: .ASCII "xxx SVOLD:" STASVR: .ASCII "xxx TMO:" STATMO: .ASCII "no " STALN3=.-STATX3 .ASCII "[K" .ASCII "[0m" .ASCII "8" STALN2=.-STATX2 STALN1=.-STATX1 STACLR: .ASCII "7" .ASCII "[1;24r" .ASCII "8" .ASCII "[J" STACLN=.-STACLR .ENDC ;STATUS .BLKB 16. ; Prompt buffer .ASCII '/' ; Hold screen esc seq. DEFPR: .ASCII ; Default prompt with new line .ASCII \+>\ ; without new line DEFPRL=.-DEFPR .EVEN NEW: ; Current Buffer, word aligned .ASCII '[' ; Hold screen esc seq. .REPT BUFSIZ+4-2 ; .ASCII ; Must be blanked .ENDR ; .EVEN SAVB: .BLKB BUFSIZ+4 ; Save Buffer (start on even boundary) RECB: .BLKB BUFSIZ+4 ; Recall Buffer BS: .REPT BUFSIZ+2 ; Backspace buffer for .ASCII ; cursor positioning .ENDR .EVEN .IF DF FILE ; ; MCR command line directive and buffer ; GMCR: GMCR$ MCRLIN=GMCR+G.MCRB .ENDC ;FILE .IF DF CLISUP .IF DF FILE ; ; IF DF FILE : GCLI buffer overlaps GMCR buffer ; $$$=. ; Save ALC .=GMCR ; Map GMCR buffer .IFTF ;FILE ; ; Buffer to receive CLI information: ; GCISIZ = 50. GCLI: .BLKB GCISIZ ; For GCII$S .IFT ;FILE .=$$$ ; Restore ALC .ENDC ;FILE TASK: .RAD50 \CLI...\ ; Current CLI .IFF ;CLISUP .PSECT PDATA TASK: .RAD50 \MCR...\ ; Task for Systems without CLI-Support .PSECT IDATA .ENDC ;CLISUP CODE: 0 ; QIO-Functioncode ADR: 0 ; Buffer-address LEN: 0 ; Buffer-lengh (to output) WAITFL: 0 ; Event flag ; CHAR: .BYTE 0 ; Input-character ; ; Flags ; OVSTMO: .BYTE 0 ; If ne : Overstrike mode NOLOAD: .BYTE 0 ; If ne : Don't load Command in Commandbuffer NOEXEC: .BYTE 0 ; If ne : Don't execute Command RING: .BYTE 0 ; If ne : FIFO is a ringbuffer SINFLG: .BYTE 1 ; If ne : Internal commands are saved SOLFLG: .BYTE 1 ; If ne : Old commands are saved OLDFLG: .BYTE 0 ; If ne : Old command , not edited .IF DF STATUS STAFLG: .BYTE 1 ; If ne : Status line is displayed .ENDC ;STATUS .IF DF FILE FILINP: .BYTE 0 ; If ne : File Input FILINI: .BYTE 0 ; If ne : Startup file being processed FILREX: .BYTE 0 ; If ne : MCE Read or MCE Replace being ;JHA99 ; processed ;JHA99 .ENDC ;FILE .IF DF EDT EDTFLG: .BYTE 0 ; If ne : EDT Mode active GOLDFL: .BYTE 0 ; If ne : "GOLD" pushed .ENDC ;EDT .IF DF TMOTIM TTN: .BYTE 0 ; Terminal Number TMOCNT: .BYTE TMOTIM ; Counter for timeout .ENDC ;TMOTIM .EVEN CDSC: 0, 0 ; Descriptor of whole remainder PDSC: ; Descriptor of P0 .. P8 .REPT 9. 0, 0 .ENDR 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 ; ; Here 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 CLRBUF ; 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 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 loop ; 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 loop, loop ; ESC O n . SELECT / RESET loop, loop ; ESC O o BEGLIN, CLRBUF ; 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 loop, loop ; 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 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 > , ,<$I> ; Insert here KEYVT2 <3 > , ,<$R> ; Remove KEYVT2 <4 > , ,<$S> ; Select KEYVT2 <5 > , ,<$P> ; Prev. Screen KEYVT2 <6 > , ,<$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 .IF DF TDV2XX TDVTAB: ; Action routine Key ; loop ; F1 loop ; F2 loop ; F3 loop ; F4 loop ; F5 loop ; F6 loop ; F7 .ENDC ;TDV2XX .SBTTL MCE - START -- INIT-Code ; ; Register usage ; ; R0 Scratch Pointer ; R1 Cursor in NEW ; R2 First free byte in NEW (End of Text) ; R3 Scratch ; R4 Scratch ; R5 Scratch Counter ; .PSECT CODE,I,RO ; START: SREX$S #EXAST ; Specify exit ast MOV #FREE,R0 ; R0 => Free memory listhead CALL $INIDM ; Initialize Free Memory CALL TERM ; Get terminal info .IF DF TMOTIM MOV #NEW+1&^C1,R0 ; Temporary buffer, word aligned GLUN$S #TI,R0 ; Get terminal number MOVB 2(R0),TTN ; And save it CALL MARK ; Marktime for timeout .ENDC ;TMOTIM .IF NDF SILENT MOV #STRTXT,R0 ; Print CALL IOMSG ; Startup message .ENDC ;SILENT .IF DF FILE CALL FILOP ; Open MCEINI file .ENDC ;FILE .SBTTL MCE - RESTAR -- Get next Line, Main-Loop ; RESTAR: CLRB NOEXEC ; Always execute .IF DF EDT 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 ; Numeric 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 PRSTAT ; Print status line JMP PRPROM ; => Print prompt ; ; .SBTTL MCE - PRSTAT -- Print the status line ; PRSTAT: MOV #STATX1,ADR ; Print MOV #STALN1,LEN ; The BR PRSTA2 ; Statusline PRSTA1: MOV #STATX2,ADR ; Print MOV #STALN2,LEN ; The BR PRSTA2 ; status line PRSTA2: CALL STAFIL ; Fill status record ;;;; TSTB ANI+1 ; Ansii Screen ? ;JHA99 ;;;; BEQ 10$ ; No : => 10$ ;JHA99 TSTB STAFLG ; Statusline wanted ? BEQ 10$ ; No : => 10$ CALLR IOW ; Statusline 10$: RETURN ; ; .SBTTL MCE - STAFIL -- Fill status line ; STAFIL: ; MOV R1,-(SP) ; Save R1 MOV R2,-(SP) ; Save R2 MOV #STALIR,R0 ; + TSTB RING ; 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 ; - MOV #STAKEY,R0 ; + MOV #EDTFLG,R1 ; Keypad CALL OFFON ; - 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 ; ; OFFON: ; ; Depending on flag in R1 : Fill with ON or OFF ; MOVB #'o,(R0)+ ; + TSTB (R1) ; BEQ 10$ ; MOVB #'n,(R0)+ ; MOVB #' ,(R0)+ ; RETURN 10$: MOVB #'f,(R0)+ ; MOVB #'f,(R0)+ ; RETURN ; - ; ; CONV: MOV #11012,R2 ; Convert 2 chars CALLR $CBTA ; Convert .ENDC ;STATUS .SBTTL MCE - PRPROM -- Print the prompt ; PRPROM: MOV #IO.CCO,CODE ; Cancel MOV PROMLF,ADR ; Start of prompt buffer MOV #DEFPRL,LEN ; Assume default prompt .IF DF CLISUP CALL GETCLI ; Get CLI information BCC 10$ ; Success : => 10$ MOV #^RMCR,TASK ; MCR... only JMP 60$ ; Continue with default prompt ; 10$: ; ; Copy CLI prompt ; MOV #GCLI+G.CIDP,R0 ; R0 => CLI Prompt information MOVB (R0)+,R4 ; Get length, advance to prompt string ADD R4,R0 ; Point behind CLI prompt MOV #NEW+2,R3 ; Point behind prompt buffer (ROOM for ESC[) MOVB #'[,-(R3) ; Insert '[' ( hold screen mode ) MOVB #ESC,-(R3) ; Insert ESC ( hold screen mode ) 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 .IF DF EDT TSTB EDTFLG ; EDT mode active ? BEQ 40$ ; No : => 40$ .IF DF STATUS TSTB STAFLG ; Status line ? BNE 40$ ; Yes : => 40$ .ENDC ;STATUS MOVB #':,-(R3) ; Display EDT mode active 40$: .ENDC ;EDT MOVB #'+,-(R3) ; Assume insert mode BITB #1,OVSTMO ; Overstrike ? BEQ 50$ ; No : => 50$ MOVB #'-,(R3) ; Overstrike 50$: MOVB #CR,-(R3) ; Insert MOVB #LF,-(R3) ; Insert MOVB #'/,-1(R3) ; Insert '/' ( hold screen mode ) MOVB #ESC,-2(R3) ; Insert ( hold screen mode ) MOV #NEW,LEN ; Point behind prompt buffer SUB R3,LEN ; Length MOV R3,PROMPT ; + MOV R3,PROMLF ; Adjust INC PROMPT ; Pointers MOV PROMLF,ADR ; - 60$: TSTB HLD+1 ; Hold screen mode ? BEQ 70$ ; No : => 70$ ADD #4,LEN ; Adjust length for Hold screen escseq. SUB #2,ADR ; Adjust address 70$: .ENDC ;CLISUP CALL IO ; Output prompt ; ; Clear edit buffer and setup R1 and R2 as pointers ; CALL CLRNEW ; Clear edit buffer .SBTTL MCE - LOOP -- Accept next Char. for input and dispatch it ; LOOP: MOV #IO.RST!TF.RNE!TF.RAL,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 20$ ; No : => 20$ MOV #BYETXT,R0 ; Assume "BYE" TSTB TTN ; Are we on TT0: ? BNE 10$ ; No : => 10$, Spawn BYE MOV #EXITXT,R0 ; "MCE EXIT" 10$: CALL GETBUF ; Copy in NEW CALL DISPLY ; Display JMP EXEC ; Execute "BYE" or "MCE EXIT" command 20$: .ENDC ;TMOTIM MOVB IOSTAT+1,R4 ; Test for branch table ; ; The following 2 lines test if there is a VT2xx/VT3xx Terminal ; in 8-Bit Ctrl-Mode on an 8-Bit line that sends ; 'P' - 'S' when pressing 'PF1' - 'PF4' ; On a 7-Bit line (217) is stripped to (17) ; CMPB R4,#SS3 ; 'SS3' Control-String ? BNE 30$ ; No : => 30$ JMP ESCAP ; Process as 30$: BIC #177600,R4 ; 7-bit ASCII CMPB R4,#DEL ; Delete ? BNE 40$ ; No : => 40$ JMP DELEC ; => Delete char. 40$: 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 50$ ; Yes : => 50$ MOV DSPTAB(R3),R3 ; Take address BIC #1,R3 ; Clear bit 0 JMP (R3) ; Do action routine 50$: ; ; Check if to be translated ; MOVB #'^,SAVB ; Insert MOVB R4,SAVB+1 ; key BISB #100,SAVB+1 ; Make ASCII CMPB SAVB+1,#'_ ; "_" ? BNE 60$ ; No : => 60$ MOVB #'?,SAVB+1 ; Make "?" 60$: ASL R4 ; Word offset ADD #DSPTAB,R4 ; Add table address MOV #2,PDSC ; P0 Length = 2 PROCESS: MOV #SAVB,PDSC+2 ; 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 MCE - BEGLIN -- Begin of line ; BEGLIN: CALL SPBACK ; Back space one position BCC BEGLIN ; If CC not yet at the begin BR LOOP1 ; => LOOP ; ; .SBTTL MCE - CHOVER -- Flip between insert and overstrike mode ; CHOVER: INCB OVSTMO ; Change mode MOV PROMLF,R4 ; R4 => Prompt CMPB (R4)+,(R4)+ ; R4 => Mode character CMPB (R4),#'+ ; "+" ? BEQ 10$ ; Yes : => 10$ MOVB #'+,(R4) ; Insert "+" BR 20$ ; => 20$ 10$: MOVB #'-,(R4) ; Insert "-" 20$: CALL DISPLY ; Rewrite line 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,#NEW ; At begin of buffer ? BLOS 50$ ; Yes : => 50$ MOV #NEW,R0 ; R0 => NEW 10$: CMP R1,R2 ; EOL ? BEQ 20$ ; Yes : => 20$ MOVB (R1)+,(R0)+ ; Shift string left BR 10$ ; => 10$ 20$: MOV R0,R2 ; End of text 30$: CMP R0,#NEW+BUFSIZ ; End of buffer ? BHIS 40$ ; Yes : => 40$ MOVB #BLNK,(R0)+ ; Fill with blank BR 30$ ; => 30$ 40$: MOV PROMPT,ADR ; + MOV R1,LEN ; Rewrite line SUB PROMPT,LEN ; CALL IOW ; - MOV #NEW,LEN ; + SUB PROMPT,LEN ; Reposition cursor CALL IO ; MOV #NEW,R1 ; - CLRB OLDFLG ; No old command 50$: BR LOOP1 ; => LOOP ; ; .SBTTL MCE - DELEW -- Delete left single word ; DELEW: CMP R1,#NEW ; At begin of buffer ? BLOS LOOP1 ; Yes : => LOOP MOV R1,-(SP) ; Save cursor position 10$: DEC R1 ; Cursor left CMP R1,#NEW ; 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 ; LOOP1: JMP LOOP ; => LOOP ; .SBTTL MCE - DELRC -- Delete right single char ; DELRC: CMP R1,R2 ; At EOL ? BHIS LOOP1 ; Yes : => LOOP DELCHR: MOV R1,R0 ; R0 => Cursor 10$: MOVB 1(R0),(R0)+ ; Shift string left CMP R0,R2 ; At EOL ? BLOS 10$ ; No : => 10$ CALL UPDATE ; Rewrite line DEC R2 ; End of text CLRB OLDFLG ; No old command BR LOOP1 ; => 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$: CALL UPDATE ; Rewrite line MOV R1,R2 ; Cursor at EOL 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: CMP R0,R2 ; EOL ? BHIS 10$ ; No : => 10$ MOVB (R0),(R1)+ ; Shift down MOVB #BLNK,(R0)+ ; Must be replaced by space BR DELWRD ; => DELWRD 10$: MOV R1,R2 ; New end ptr MOV (SP)+,R1 ; Restore cursor CLRB OLDFLG ; No old command RETYPE: CALL DISPLY ; Write buffer BR LOOP1 ; => LOOP ; ; .SBTTL MCE - ENDLIN -- Jump to end of text ; ENDLIN: MOV R1,ADR ; + MOV R2,LEN ; Write from cursor to end SUB R1,LEN ; BEQ 10$ ; CALL IOW ; - MOV R2,R1 ; End of text 10$: BR LOOP1 ; => LOOP ; ; .SBTTL MCE - INSERT -- Insert one character ; INSERT: CMP R2,#NEW+BUFSIZ ; Still Room ? BHIS LOOP1 ; No : => LOOP MOV #CHAR,ADR ; + MOV #1,LEN ; Echo character CALL IOW ; - CLRB OLDFLG ; No old command BITB #1,OVSTMO ; 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 CALL UPDATE ; Rewrite line BR LOOP1 ; => LOOP ; ; .SBTTL MCE - MOVWRD -- Move word ; MOVWRD: CMP R1,R2 ; At EOL ? BLO 10$ ; No => 10$ MOV #NEW,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 ; BR LOOP1 ; => LOOP .SBTTL MCE - ESCAP -- Escape Sequences / FIFO - Commands ; .ENABL LSB ESCAP: 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 70$ ; No : => 70$ ; ; UP-ARROW ..... ; UP: MOV FIFPTR,R5 ; Get Ptr of buffer BNE 20$ ; Defined : => 20$ TST FIFO ; Any entry ? BEQ 90$ ; No : => 90$ MOV FIFO+2,FIFPTR ; Take MOVB FIFCNT,FIFPOI ; newest entry BR 90$ ; => 90$ 20$: MOV #FIFO,R5 ; Find previous entry 30$: MOV (R5),R5 ; Next BNE 40$ ; Got one : => 40$ TSTB RING ; Ringbuffer ? BNE 50$ ; Yes : => 50$ BR 90$ ; => 90$ 40$: CMP (R5),FIFPTR ; Does this point to me ? BNE 30$ ; No : => 30$ DECB FIFPOI ; One older BR 60$ ; 50$: CLRB FIFPOI ; None 60$: MOV R5,FIFPTR ; Found - load BR 90$ ; and display ; 70$: CMPB R0,#'B ; ? BNE 120$ ; No : => 120$ ; ; DOWN-ARROW ..... ; DOWN:: MOV FIFPTR,R5 ; Get Ptr of buffer BNE 80$ ; Defined : => 80$ TST FIFO ; Any entry at all ? BEQ 90$ ; No : => 90$ TSTB RING ; Ringbuffer ? BEQ 100$ ; No : => 100$ MOV FIFO,FIFPTR ; Take oldest MOVB #1,FIFPOI ; Oldest BR 90$ ; => 90$ 80$: TST (R5) ; Goto next buffer if any BEQ CLRBUF ; No more : => CLRBUF MOV (R5),FIFPTR ; Next INCB FIFPOI ; One newer 90$: CALL GEFIFO ; Load NEW from FIFO BR 110$ ; => 110$ ; ; CLEAR LINE ..... ; CLRBUF: CALL CLEAR ; Clear flags and pointers 100$: CALL CLRNEW ; Clear edit buffer CALL DISPLY ; and display prompt 110$: .IF DF STATUS CALL PRSTA1 ; Print status line .ENDC ;STATUS BR LOOP2 ; => LOOP ; ; CLEAR: ; ; Clear flags and pointers ; CLRB OLDFLG ; No old command CLR FIFPTR ; CLRB FIFPOI ; None RETURN ; ; ; 120$: 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 BR LOOP2 ; => LOOP ; 130$: CMPB R0,#'D ; ? BNE 140$ ; No : => 140$ ; ; LEFT-ARROW ..... ; .SBTTL MCE - LEFT -- Cursor left ; LEFT: CALL SPBACK ; Cursor left one space BR LOOP2 ; => LOOP ; 140$: .IF DF EDT ; ; EDT-KEYS ..... ; TSTB EDTFLG ; EDT Keys enabled ? BEQ 190$ ; No : => 190$ CMPB R0,#'M ; ? BNE 150$ ; No : => 150$ JMP EXEC ; Execute 150$: CMPB R0,#'P ; + BLO 160$ ; PFx range ? CMPB R0,#'S ; No : => 160$ BHI 160$ ; - ADD #<'z-'l-'P>,R0 ; Relocate to table offset BR 170$ ; => 170$ 160$: CMPB R0,#'l ; + BLO 190$ ; Within Keypad range ? CMPB R0,#'y ; No : => 180$ BHI 180$ ; - SUB #'l,R0 ; Make 170$: ASL R0 ; dispatchtable ASL R0 ; offset TSTB GOLDFL ; Gold ? BEQ 180$ ; Yes : => 180$ TST (R0)+ ; Point to "GOLD" entry CLRB GOLDFL ; Clear "GOLD" 180$: JMP @EDTTAB(R0) ; Do EDT function 190$: CLRB GOLDFL ; Clear "GOLD" .ENDC ;EDT ; ; PF-KEYS ..... ; SUB #'P,R0 ; Any PFn key ? BLO VT2KEY ; No : => VT2KEY CMP R0,#'S-'P ; > PF4 ? BHI VT2KEY ; Yes : => VT2KEY MOV R0,-(SP) ; Save 0..3 for .. MOV #"PF,SAVB ; "PF' in SAVBUF ADD #'1,R0 ; Make ascii from PR-number MOV R0,SAVB+2 ; Insert in SAVBUF MOV #3,PDSC ; P0 Length MOV #SAVB,PDSC+2 ; 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 PRSTA1 ; Dispay status line .ENDC ;STATUS BR LOOP2 ; => LOOP ; ; .SBTTL MCE - TRANSL -- Translate a command ; TRANSL: ; ; Translate ; CMP R2,#NEW ; Something in buffer ? BEQ LOOP2 ; No : => LOOP DECB NOLOAD ; Disable command load SUB #NEW,R2 ; Calculate Length MOV R2,LEN ; Store CALL CMDCHK ; Command Translation MOV LEN,R2 ; Restore R2 ADD #NEW,R2 ; Point MOV R2,R1 ; to end CALL DISPLY ; Write line CLRB NOLOAD ; Enable command load BR LOOP2 ; => LOOP ; .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: MOV #EDTTXT,R0 ; EDT helptext BR FUNCEX ; => FUNCEX .ENDC ;EDT ; ; .SBTTL MCE - HELP -- Help key ; ; or Spawn "HELP MCE" ; HELP: MOV #HLPTXT,R0 ; Move HELP MCE into Buffer BR FUNCEX ; => FUNCEX ; .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 new buffer SUB #NEW,R2 ; Calculate length MOV R2,LEN ; Save it CALL DETACH ; Detach terminal JMP EXEC3 ; Execute without display .SBTTL MCE - VT2KEY -- VT2xx Functionkeys ; VT2KEY: .IF DF VT2XX!TDV2XX CMPB TTP+1,#T.V2XX ; VT2xx ? BEQ 10$ ; Yes : => 10$ JMP TDVTST ; => TDVTST 10$: .ENDC ;VT2XX!TDV2XX .IF DF VT2XX ; ; 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 EX1 ; 1..6 ? CMPB R0,#'6 ; BHI EX1 ; - 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 EX2 ; 0..9 ? CMPB R0,#'9 ; BHI EX2 ; - CLRB (SP) ; Clear byte BISB R0,(SP) ; Insert in word CALL IO ; Next char. CMPB CHAR,#'~ ; Tilde ? BNE EX2 ; No: => EX2 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 EX2: TST (SP)+ ; Flush word EX1: JMP LOOP00 ; => LOOP00 ; ; .SBTTL MCE - VT2FN -- Check if VT2xx key to be translated ; VT2FN: ; ; Check if to be translated ; MOVB #'F,SAVB ; Insert MOVB 2(R4),SAVB+1 ; key MOVB 3(R4),SAVB+2 ; ident MOV #3,PDSC ; Assume P0 Length = 3 CMPB SAVB+2,#BLNK ; Blank ? BNE 10$ ; No : => 10$ DEC PDSC ; 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$: .ENDC ;VT2XX JMP LOOP ; => LOOP .SBTTL MCE - TDVTST -- TDV2230 Key support ; TDVTST: .IF DF TDV2XX ; ; O ... ; CMPB TTP+1,#200 ; TDV2XX ? BNE 10$ ; No: => 10$ ; ; 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,SAVB ; Insert MOVB R4,R0 ; ADD #'1,R0 ; key code MOVB R0,SAVB+1 ; ; MOV #2,PDSC ; P0 Length ASL R4 ; Make word offset ADD #TDVTAB,R4 ; Add table address JMP PROCES ; 10$: .ENDC ;TDV2XX JMP LOOP ; => LOOP .SBTTL MCE - DELAY -- Detach and delay ; DELAY: CALL IOCR ; Print CALL DETACH ; Detach terminal MRKT$S #EFN,#10.,#2 ; Wait STSE$S #EFN ; 10 seconds JMP RESTAR ; => RESTAR ; ; .SBTTL MCE - SAVE -- Save command without execution ; SAVE: INCB NOEXEC ; Don't execute BR EXEC1 ; => EXEC1 ; ; .SBTTL MCE - EXECNW -- Execute command no-wait ; .ENABL LSB EXECNW: CLR WAITFL ; Clear EVF BR EXEC1 ; => EXEC1 ; ; .SBTTL MCE - EXEC -- Execute command ; EXEC: MOV #1,WAITFL ; EVF = 1 EXEC1: CALL IOCR ; Print CALL DETACH ; Detach terminal SUB #NEW,R2 ; Calculate Length MOV R2,LEN ; Store BLE 60$ ; Zero : => 60$ ; MOV R2,R1 ; R1 = Counter MOV #NEW,R5 ; R5 => NEW buffer 10$: CMPB (R5)+,#BLNK ; A space ? BNE 20$ ; No : => 20$ SOB R1,10$ ; Look for non space BR 60$ ; Only spaces => 60$ 20$: TSTB SOLFLG ; Save old commands ? BNE 30$ ; Yes : => 30$ TSTB OLDFLG ; Old command ? BNE 40$ ; Yes : => 40$ 30$: CALL LDFIF ; Load into FIFO 40$: CALL CLEAR ; Clear flags and pointers TSTB NOEXEC ; Execute ? BNE 60$ ; No : => 60$ EXEC2: CALL CMDCHK ; Check for command Translation BCS 60$ ; Nothing to execute EXEC3: .IF DF TMOTIM CLRB TMOCNT ; Disable timeouts (until next IO) .ENDC ;TMOTIM CALL INTERN ; Internal command or BYE ? BCC 60$ ; If C clear: no command for CLI CALL DOEXEC ; Excute command in buffer NEW TST WAITFL ; Wait ? BNE 50$ ; Yes : => 50$ INC WAITFL ; Make flag #1 MRKT$S WAITFL,#20.,#1 ; Allow task to run 50$: STSE$S WAITFL ; Stop until done 60$: 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 EXITS: .IF DF STATUS TSTB ANI+1 ; Ansii Screen ? ;JHA99 BEQ 10$ ; No : => 10$ :JHA99 MOV #STACLR,ADR ; MOV #STACLN,LEN ; CALL IOW ; 10$: ;JHA99 .ENDC ;STATUS CALL DETACH ; Detach terminal EXIT$S ; Exit ; ; .SBTTL MCE - CLFIF -- Clear first entry of FIFO buffer ; CLFIF: MOV #FIFO,R0 ; This header CALL FRENT ; Free entry from queue BCC 10$ ; Empty : => 10$ DECB FIFCNT ; Adjust count 10$: RETURN ; ; ; .SBTTL MCE - CLRNEW -- Clear Buffer NEW ; CLRNEW: MOV #NEW,R1 ; R1 => NEW MOV R1,R2 ; R2 => NEW MOV #BUFSIZ,R5 ; R5 = BUFSIZ 10$: MOVB #BLNK,(R1)+ ; Reset NEW TO BLANK SOB R5,10$ ; Go back if not the end MOV R2,R1 ; R1 => NEW RETURN ; ; ; .SBTTL MCE - DETACH -- Detach terminal ; DETACH: .IF DF EDT TSTB EDTFLG ; EDT Keys enabled ? BEQ 10$ ; No : => 10$ MOV #NUMTXT,ADR ; Numeric keypad MOV LEN,-(SP) ; Save length 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 ; Ansii 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 ; Ansii Screen ? BEQ 40$ ; No : => 40$ ADD #3,LEN ; Make Escseq visible 40$: 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 50$ ; CALLR IO ; - 50$: RETURN ; ; ; .SBTTL MCE - DOEXEC -- Submit command to CLI ; DOEXEC: .IF DF COMPND ;JHB03 ;JHB03 MOV #NEW,R0 ; R0 => Buffer ;JHB03 MOV R0,R3 ; Copy start of command ;JHB03 10$: ;JHB03 MOV LEN,R1 ; R1 = Length ;JHB03 CLR R2 ; Compute length here ;JHB03 20$: ;JHB03 CMPB (R3)+,#'& ; Ampersand here ? ;JHB03 BEQ 30$ ; If eq yes ;JHB03 INC R2 ; Count command length ;JHB03 SOB R1,20$ ; End of story ? ;JHB03 MOV R2,R1 ; Load new length ;JHB03 BR GVCLI2 ; Process as last command to CLI ;JHB03 30$: ;JHB03 MOV R2,R1 ; Load new length ;JHB03 INC R2 ; Account for &-sign ;JHB03 SUB R2,LEN ; Compute unused string length ;JHB03 CALL GVCLI1 ; Go execute it ;JHB03 MOV R3,R0 ; Set to unused string ;JHB03 BR 10$ ; Go for next part ;JHB03 ; GVCLI1: ;JHB03 CMPB (R0),#BLNK ; Blank ? ;JHB03 BNE 10$ ; No : => 10$ ;JHB03 INC R0 ; Next ;JHB03 DEC R1 ; char. ;JHB03 BR GVCLI1 ; Again ;JHB03 10$: ;JHB03 SPWN$S #TASK,,,,,#EFN,,,R0,R1 ; *** EXECUTE COMMAND *** ;JHB03 WTSE$S #EFN ; ;JHB03 ; ;JHB03 RETURN ; ;JHB03 ;JHB03 .IFF ;COMPND ;JHB03 MOV LEN,R1 ; R1 = Length MOV #NEW,R0 ; R0 => Buffer .ENDC ;COMPND ;JHB03 GVCLI2: ;JHB03 CMPB (R0),#BLNK ; Blank ? BNE 10$ ; No : => 10$ INC R0 ; Next DEC R1 ; char. BR GVCLI2 ; Again 10$: SPWN$S #TASK,,,,,WAITFL,,,R0,R1 ; *** EXECUTE COMMAND *** ; RETURN ; ; ; .SBTTL MCE - FRENT -- Free entry from queue ; ; Header in R0. CC-C clear if it was empty ; FRENT: JSR R5,.SAVR1 ; Save Regs MOV (R0),R2 ; Get entry if any CLC ; Assume empty BEQ 20$ ; None : => 20$ MOV (R2),(R0) ; Remove from head of queue BNE 10$ ; More entries MOV R0,2(R0) ; This was last one 10$: MOV FLEN(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 - GEFIFO -- Get FIFO Buffer, pointed to by FIFPTR ; GEFIFO: 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 #FTXT,R0 ; Get start of text 20$: CALL GETBUF ; Load buffer CALLR DISPLY ; and display ; ; .SBTTL MCE - GETBUF -- Load Buffer into NEW ; ; R0 points to source ; GETBUF: MOV #NEW,R1 ; R1 => NEW MOV R1,R2 ; R1 => NEW MOV #BUFSIZ,R5 ; R5 = BUFSIZ 10$: MOVB (R0)+,(R1)+ ; (R0) --> NEW BEQ 30$ ; Zero : => 30$ CMPB -1(R1),#BLNK ; Blank ? BEQ 20$ ; Yes : => 20$ MOV R1,R2 ; R2 => Behind last 20$: SOB R5,10$ ; Go back if not the end BR 40$ ; => 40$ 30$: MOVB #BLNK,-1(R1) ; Overprint 000 (.ASCIZ) 40$: MOV R2,R1 ; Both at the end RETURN ; ; ; .SBTTL MCE - IO -- General I/O Routine ; IO: .IF DF TMOTIM MOVB #TMOTIM,TMOCNT ; Set new timeoutcount .ENDC ;TMOTIM QIO$S CODE,#TI,#EFN,,#IOSTAT,, DIR$ #STOPIO ; Stop for I/O (or wait when aborted) RETURN ; ; ; .SBTTL MCE - IOCR -- Print ; IOCR: MOV #IO.CCO,CODE ; Cancel MOV #CRET,ADR ; Print MOV #1,LEN ; Length BR IO ; Go to IO ; ; .SBTTL MCE - IOMSG -- Print Message ; ; Print a Msg in (R0) ; IOMSG: CALL IOCR ; Print CALL GETBUF ; (R0) --> NEW CALL DISPLY ; Write line CALLR CLRNEW ; ; ; .SBTTL MCE - IOW -- Write routine ; IOW: MOV #IO.WVB,CODE ; write BR IO ; Go to IO ; ; .SBTTL MCE - LDFIF -- Load NEW into FIFO Buffer ; ; Input: R2 - Length ; LDFIF: JSR R5,.SAVR1 ; Save Regs MOV R2,R5 ; Length BEQ 40$ ; Zero : => 40$ CMP R2,MINC ; Save it ? BLO 40$ ; No : => 40$ MOV R5,R1 ; Save it ADD #FTXT+2,R1 ; Increment for header CMPB FIFCNT,MAXF ; Maximum reached ? BLO 20$ ; No : => 20$ 10$: CALL CLFIF ; Release one 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 (R0) ; No next entry MOV R0,@FIFO+2 ; Link to previous MOV R0,FIFO+2 ; New last entry MOV R1,FLEN(R0) ; Total length ADD #FTXT,R0 ; Point to text field MOV #NEW,R1 ; Source text 30$: MOVB (R1)+,(R0)+ ; Load SOB R5,30$ ; string CLRB (R0) ; End of string INCB FIFCNT ; Count 40$: RETURN ; ; ; .SBTTL MCE - PRICMD -- Print Cmd buffer and put pointer to end of queue ; PRICMD: MOV #CMDB, FIFPTR ; Point to CMD buffer BR PRIXXX ; => PRIXXX ; ; .SBTTL MCE - PRIFIF -- Print FIFO and put pointer to end of queue ; PRIFIF: MOV #FIFO, FIFPTR ; Point to FIFO PRIXXX: MOV PROMLF,ADR ; + MOV #1,LEN ; Print CALL IOW ; - MOV @FIFPTR, FIFPTR ; Next PTR BEQ 10$ ; Done : => 10$ CALL GEFIFO ; Display BR PRIXXX ; => PRIXXX 10$: CALL CLRNEW ; Clear edit buffer (FIFPTR already cleared) CALLR DISPLY ; and display prompt ; ; .SBTTL MCE - SPBACK -- Backspace 1 char. ; SPBACK: CMP R1,#NEW ; 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 ; ; .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 ;JHA99 TSTB ANI+1 ; ANSII Terminal ;JHA99 BNE 10$ ; Yes : => 10$ ;JHA99 CLRB STAFLG ; No statusline possible ;JHA99 10$: ;JHA99 RETURN ; ;JHA99 .IFF ;STATUS CALLR IO ; Do it .ENDC ;STATUS ; ; .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 FILE .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: .IF DF CLISUP CALL GETCLI ; Get CLI info/filetype .ENDC ;CLISUP 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 BCS FILCLO ; No more records : => Close file MOV F.NRBD(R0),R2 ; Length BLE FILREA ; Empty line : => FILREA MOV R2,LEN ; Store length TST (SP)+ ; Do not return MOV #1,WAITFL ; Wait for execution of commands JMP EXEC2 ; but execute directly ; ; .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 BCC FILREA ; If opened : => FILREA 10$: RETURN ; .ENDC ;FILE .IF DF CLISUP .SBTTL MCE - GETCLI -- Get CLI information ; GETCLI: GCII$S #GCLI,#GCISIZ .IF DF FILE BCS 10$ ; Error is C set ; ; Choose the startup file type according to the CLI in use: ; MOV G.CICL+GCLI,DFTYP ; Use CLI name for file type 10$: .ENDC ;FILE RETURN ; .ENDC ;CLISUP .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 ; ; .SBTTL MCE - MARK -- Next Marktime MARK: MRKT$S ,#60.,#2,#TIMAST;(;) RETURN ;(;) .ENDC ;TMOTIM .SBTTL MCE - FNDCMD -- Find entry in command table .SBTTL MCE - FNDCMA -- Find entry in command table with "*" ; ; FNDCMD - Find entry in Command (=Translation-) Table ; FNDCMA - Find entry in Command (=Translation-) Table - accept Abbreviations ; ; 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) ; .ENABL LSB FNDCMA: MOVB #1,CTSTAR ; Enable abbreviations BR 10$ FNDCMD: CLRB CTSTAR ; Ignore "*" in translation buffer 10$: MOV #CMDB,R0 ; R0 => Commandbuffer MOV R3,-(SP) ; Save R3 MOV R1,-(SP) ; Save R1 CLR -(SP) ; For previous entry 20$: MOV R0,(SP) ; Save previous entry TST (R0) ; Any next entry ? BEQ 100$ ; No : => 100$, end of list MOV (R0),R0 ; Take next entry MOV R0,R1 ; R1 => Entry ADD #FTXT,R1 ; R1 => Text MOV PDSC,R3 ; Length to be compared BLE 100$ ; Zero : => 100$ MOV PDSC+2,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 - 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 ; ; R2 - length of buffer in NEW (also stored in LEN) ; on return: LEN updated, all Regs destroyed ; CMDCHK: MOV #CDSC,R0 ; + MOV #CLL/2,R1 ; 10$: ; Clear scratch buffer CLR (R0)+ ; SOB R1,10$ ; - MOV #NEW,R1 ; R1 => Source Buffer MOV #SAVB,R3 ; R3 => Destination Buffer MOV #PDSC,R5 ; R5 => Current Parameter Descriptor MOV R3,2(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 40$ ; No delimiter found : => 40$ CMP R5,#PDSC ; Is this P0 ? BNE 30$ ; No : => 30$ MOV R3,CDSC+2 ; Load start Address 30$: ; ; To next Pn ; CMP R5,#8.*4+PDSC ; Already on P8 ? BHIS 40$ ; Yes : => 40$, put it all there ADD #4,R5 ; Next Parameter MOV R3,2(R5) ; Start address BR 50$ ; Do not count 40$: ; ; No delimiter found ; INC (R5) ; Count char 50$: SOB R2,20$ ; Next character ; MOV CDSC+2,R2 ; Remainder Descriptor defined ? BEQ 60$ ; No => 60$ SUB R2,R3 ; Calculate length MOV R3,CDSC ; Store length ; ; Now everything is moved into SAVB ; Check if we define a new command ":=" in P1 ; 60$: MOV #4+PDSC,R2 ; R2 => P1 descr CMP (R2)+,#2 ; Correct length ? BNE 70$ ; No => 70$ MOV (R2),R2 ; R2 => string CMPB (R2)+,#': ; + BNE 70$ ; CMPB (R2)+,#'= ; ":=" BNE 70$ ; - JMP NEWCMD ; Match found ; ; Try find an entry in the commandbuffer with key P0 ; 70$: CALL FNDCMA ; Check in table BCC 80$ ; Entry found => 80$ CLC ; Indicate success RETURN ; 80$: ; ; Entry found, R1 points to Text ; MOV #NEW,R2 ; R2 => Destination 90$: ; ; Assemble buffer NEW ; MOVB (R1)+,R0 ; Next char BEQ 110$ ; All done : => 110$ CMPB R0,#'' ; Could it be 'Pn' ? BNE 100$ ; No : => 100$ CALL SUBST ; Check it and substitute if necessary BCS 90$ ; Already substituted : => 90$ 100$: MOVB R0,(R2)+ ; Store character in NEW BR 90$ ; Next char from CMD Buf 110$: ; ; Whole buffer moved to NEW ; TSTB CFETCH ; Buffer already feched ? BLT 120$ ; Yes : => 120$ MOV #CDSC,R1 ; This descriptor to append CALL STORE ; Store 120$: ; ; All done, execute new command ; SUB #NEW,R2 ; Calculate new length MOV R2,LEN ; and store TSTB OVMSG ; Buffer overflow ? BEQ 130$ ; No : => 130$ MOV #TOOLON,R0 ; Give CALL IOMSG ; message SEC ; Not success 130$: RETURN ; ; ; STORE: ; ; Append string with descriptor (R1) to NEW ; MOV (R1)+,R5 ; R5 = Length BEQ 30$ ; Empty : => 30$ MOV (R1),R1 ; R1 = Source Addr 10$: CMP R2, #NEW+BUFSIZ ; In range ? BLO 20$ ; Yes : => 160 DECB OVMSG ; Mark for Ovflw RETURN ; 20$: MOVB (R1)+,(R2)+ ; Copy SOB R5,10$ ; characters 30$: RETURN ; 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 substit RETURN ; 20$: ; ; Substitution string found ; MOV R1,2(SP) ; Set up R1 after retunr 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 - 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 ; .SBTTL MCE - NEWCMD -- Define new command or delete command ; ; Define new command in command buffer, or delete it ; NEWCMD: TSTB NOLOAD ; Skip processing ? BNE 50$ ; Yes : => 50$ CALL FNDCMD ; Check if in table BCC 60$ ; Yes : => 60$, release old entry TST 2*4+PDSC ; P2 defined ? BNE 10$ ; Yes : => 10$, must load TST 3*4+PDSC+2 ; 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 #FTXT+1,R1 ; With overhead 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 (R3),(R0) ; Link to previous entry BNE 30$ ; MOV R0,CMDB+2 ; We will be last one 30$: MOV R0,(R3) ; MOV R1,FLEN(R0) ; Total length ADD #FTXT,R0 ; R0 => Start of text MOV #SAVB,R1 ; R1 => Source MOV LEN,R2 ; R2 = Length 40$: MOVB (R1)+,(R0)+ ; Copy SOB R2,40$ ; text CLRB (R0) ; Write delimiter 50$: SEC ; Nothing to execute RETURN ; 60$: ; ; Release old entry ; MOV (R0),(R2) ; Link remainder BNE 70$ ; More entries : => 70$ MOV R2,CMDB+2 ; This was last one 70$: MOV FLEN(R0),R1 ; R1 = Length MOV R0,R2 ; MOV #FREE,R0 ; R0 => Free memory listhead CALL $RLCB ; Release it BR NEWCMD ; Find more to release .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,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 #NEW,R1 ; R1 => Source Buffer MOV #RECB,R3 ; R3 => Destination Buffer SUB R1,R2 ; R2 = Length BLE 20$ ; Zero : => 20$ 10$: ; ; Store single char into RECB ; 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 #RECB,R1 ; R1 => Source to Compare TSTB (R1) ; Search mask defined ? BEQ 50$ ; No : => 50$ MOV R4,R3 ; R3 => Entry ADD #FTXT,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 (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 GEFIFO ; Load from FIFO (or delete NEW buffer) RETURN ; .IF DF FILE ; .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 #GMCR+G.MCRB,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 [1,2]directory MOV #FDSPT,FDBIN+F.DSPT ; Reset DSPT pointer in FDB 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 - INTERN -- Check for internal commands (EXIT/BYE) ; Check if the command (AFTER translation) is BYE 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) ; Intern returns C set, if no intern command, i.e. the buffer NEW ; has to be submitted to the CLI. ; C clear on return, if internal command found, no CLI submit. ; .macro cmpuc src,what,action,label ; Compare upper case char .NCHR $$$$$L, .if gt $$$$$L-1 mov src,R0 bic #" ,R0 cmp R0,#"what .iff movb src,R0 bicb #' ,R0 cmpb R0,#''what .endc action label .endm ; INTERN: ; ; To be recognised as an internal command, at least 3 characters ; must be present. ; Internal commands trapped are: ; BYE : the RSX logout command ; MCE action: MCE internal actions ; JSR R5,.SAVR1 ; Save registers CMP LEN,#3 ; Length in range ? BLT 20$ ; No : => 20$ CMPUC NEW+0,BY,bne 10$; BY ? CMPUC NEW+2,E,bne 10$ ; E ? CLR WAITFL ; Do not wait CALL DOEXEC ; Submit BYE to CLI CALLR EXITS ; Immediate task exit 10$: CMPUC NEW+0,MC,bne 20$; MC ? CMPUC NEW+2,E,beq 30$ ; E ? 20$: SEC ; No internal command trapped RETURN ; ; ; Internal command strings must not be less than 8 characters in length ; Ignore anything else ; 30$: CMP LEN,#8. ; "MCE action?" BLT 140$ ; N BIC #" ,NEW+4 ; 'action' verb upper case BIC #" ,NEW+6 ; 4 characters MOV #INTCMD,R1 ; Point to internal command table 40$: TST (R1) ; End of table reached ? BEQ 140$ ; Yes : => 140$ CMP NEW+4,(R1)+ ; First 2 characters match ? BEQ 50$ ADD #4,R1 ; Point to next table entry BR 40$ ; Look ahead 50$: CMP NEW+6,(R1)+ ; Second 2 characters match ? BEQ 60$ ; If eq Yes: action verb match TST (R1)+ ; Point to next table entry BR 40$ ; Look ahead 60$: CALL @(R1) ; EXECute internal command BCS 140$ ; Not OK ? => 140$ TSTB SINFLG ; Save internal command ? BNE 130$ ; Yes : => 130$ TSTB FILREX ; Read or Replace being processed ? ;JHA99 BNE 70$ ; Yes : => 70$ ;JHA99 TSTB FILINP ; File input ? ;JHA99 BNE 130$ ; Yes : => 130$ ;JHA99 70$: CLRB FILREX ; Clear flag ;JHA99 MOV FIFO,R0 ; R0 => First entry BEQ 120$ ; No entries : => 120$ MOV FIFO+2,R2 ; R2 => Last entry CMP R0,R2 ; 1st = last ? BEQ 100$ ; Yes : => 100$ 80$: CMP (R0),R2 ; (R0) => last ? BEQ 90$ ; Yes : Delete this one MOV (R0),R0 ; Next BR 80$ ; => 80$ 90$: MOV R0,FIFO+2 ; New last CLR (R0) ; Last MOV #FREE,R0 ; R0 => Free listhead MOV FLEN(R2),R1 ; R1 = Length CALL $RLCB ; Release block BR 110$ ; => 110$ 100$: CALL FRENT ; Free entry 110$: DECB FIFCNT ; One less 120$: CLC ; Success 130$: RETURN ; 140$: MOV #ERRTXT,R0 ; Error CALLR IOMSG ; Message .SBTTL MCE - -- INTERNAL action routines ; ; .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 - 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 .IF DF EDT ; .SBTTL MCE - ICKEYP -- Keypad on/off ; ; Keypad On/Off ; ICKEYP: ; MOV #EDTFLG,R3 ; R3 => Flag BR ONOFF ; => On / Off .ENDC ;EDT ; .SBTTL MCE - ICLIST -- LIST ; ; FIFO is LIST ; ICLIST: ; CLRB RING ; Indicate LIST JMP SUCCES ; ; ; .SBTTL MCE - ICMAXF -- Fisz x ; ; Fifo size ; ICMAXF: ; MOV #MAXF,R5 ; R5 => Destination CALL VALUE ; Get value CLEFIF: CMPB FIFCNT, MAXF ; Maximum reached ? BLOS 10$ ; No : => 10$ CALL CLFIF ; Release one entry BCS CLEFIF ; => CLEFIF 10$: BR SUCCES ; ; ; .SBTTL MCE - ICMINC -- Cmsz x ; ; CMD Size ; ICMINC: ; MOV #MINC,R5 ; R5 => Destination ; VALUE: MOV #NEW+9.,R0 ; Point behind 'MCE XXXX ' CALL $CDTB ; Convert MOV R1,(R5) ; Insert value RETURN ; ; ; .SBTTL MCE - ICPURG -- Purge ; ; delete current translation table ; ICPURG: ; MOV #CMDB,R0 ; Queue header for TR table CALL FRENT ; Delete table entry BCS ICPURG ; Id C SET there may be more entries RETURN ; ; .IF DF FILE .SBTTL MCE - ICREAD -- Read ; ; read commands from file specified ; ICREAD: ; 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 #NEW+4,r1 ; Point behind 'MCE ' MOV LEN,R2 ; Length of command SUB #4.,R2 ; Remaining # characters CALL GETFIL ; Get new file name BCS 20$ ; Error => 20$ CALL FILOP1 ; Read file(s) INCB FILREX ; Read or Replace being processed ;JHA99 20$: BR SUCCES ; Always success .SBTTL MCE - ICREPL -- Replace ; ICREPL: CALL ICPURG ; Delete current translation table BR ICREAD ; .ENDC ;FILE ; .SBTTL MCE - ICRING -- Ring ; ; FIFO is RING buffer ; ICRING: MOVB #1,RING ; Indicate RING BR SUCCES ; ; .IF DF STATUS .SBTTL MCE - ICSTAT -- Status [ on/off ] ; ; Status ; ICSTAT: ; MOV #NEW+8.,R0 ; Point behind "MCE XXXX" MOV LEN,R2 ; Take SUB #8.,R2 ; length BNE 10$ ; Not Zero : => 10$ CALL STAFIL ; Fill statusline MOV #STATX3,ADR ; Address MOV #STALN3,LEN ; Length CALLR IOW ; 10$: TSTB ANI+1 ; ANSII Terminal ? ;JHA99 BEQ 20$ ; No : => 20$ ;JHA99 MOV #STAFLG,R3 ; R3 => Flag MOVB (R3),R2 ; Old status ;JHA99 MOV R2,-(SP) ; Save it ;JHA99 CALL ONOFF ; => On / Off MOV (SP)+,R2 ; Restore ;JHA99 BCS 20$ ; TSTB #STAFLG ; Off ? BNE 20$ ; No : => 20$ TSTB R2 ; Was it on ? ;JHA99 BEQ 20$ ; no : => 20$ ;JHA99 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 BR ONOFF ; => On / Off ; ; .SBTTL MCE - ICSVOL -- Old commands on/off ; ; Save old commands On/Off ; ICSVOL: ; MOV #SOLFLG,R3 ; R3 => Flag BR ONOFF ; => On / Off ; ; .SBTTL MCE - ICVERS -- Version ; ; Show version ; ICVERS: ; MOV #STRTXT, R0 ; Print CALLR IOMSG ; Startup message ; ; ON/OFF ; ; R3 => Byte flag ; ONOFF: MOV #NEW+8.,R0 ; Point behind "MCE XXXX" MOV LEN,R2 ; Take SUB #8.,R2 ; length BEQ 40$ ; Zero : => 40$ 10$: CMPB #BLNK,(R0)+ ; Mnemonic delimiter ? BEQ 20$ ; Yes : => 20$ SOB R2,10$ ; Count remaining char BR 40$ ; => 40$ 20$: BICB #40,(R0) ; Upcase CMPB (R0)+,#'O ; 'O ? BNE 40$ ; No : => 40$ BICB #40,(R0) ; Upcase CMPB (R0),#'N ; 'N ? BNE 30$ ; No : => 30$ INCB (R3) ; Set flag BR SUCCES ; 30$: CMPB (R0)+,#'F ; 'F ? BNE 40$ ; No : => 40$ BICB #40,(R0) ; Upcase CMPB (R0),#'F ; 'F ? BNE 40$ ; No : => 40$ CLRB (R3) ; Reset flag BR SUCCES ; 40$: BR NOSUCC ; Error ; SUCCES: CLC ; Succes RETURN ; NOSUCC: SEC ; Not Succes RETURN ; ; .END START