.Title MCE - CLI Commandline Editor ; .Ident -V4.28- ; This identcode appears in MCE messages ; .Enable LC ; ; Copyright (C) 1987-1998 ; ; J.H. Hamakers, ; pAkUiT International ; Elsbes 40 ; 3069 LN Rotterdam ; The Netherlands ; Phone : +31 - 10 - 407 86 31 ; E-Mail : hamakers@pobox.com ; Internet : http://members.tripod.com/~hans_hamakers ; ; 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. ; ; TO LET ONE SOURCE BE RESPONSIBLE FOR NEW RELEASES ; PLEASE CONTACT ME FOR PROBLEMS OR SUGGESTIONS ; ; +---------------------------------------------------+ ; | See MCEREL.TXT 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 with @MCEBLD .Iff .If Ne IDNPRE-10 .Error ;MCE -- MCEPRE.MAC not compatible with this version of MCE. .Error ; Please build again with @MCEBLD .EndC .EndC ; .If Df CLISUP&PRO .Error ;MCE -- Can't have multiple CLI support on a PRO. .Error ; Please build again or edit MCEPRE.MAC .EndC ;CLISUP&PRO ; .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 ,GTSK$S ,MRKT$S ,QIO$ .MCall SDIR$S ,SPND$S ,SPWN$ ,SREX$S ,STSE$ .MCall STSE$S ,WTSE$ .If Df FILE .MCall CSI$ ,CSI$1 ,CSI$2 .MCall GET$S ,CLOSE$ ,NMBLK$ ,OPEN$R .MCall FDBDF$ ,FDRC$A ,FDOP$A ,FSRSZ$ .MCall GDIR$ .EndC ;FILE .IIf Df FILE!SYLOGIN .MCall FEAT$S .IIf Df FILE!UPR .MCall GMCR$ .IIf Df RTMESS!RTEXIT!TMOTIM!HTMESS!HTEXIT .MCall GLUN$S .IIf Df TMOTIM .MCall ASTX$S .IIf Df TMOTIM&TMOSET .MCall CMKT$S .IIf Df STATUS&TMOTIM .MCall QIOW$S .IIf Df CLISUP!FILE .MCall GCII$ ; ; 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 MINCHR MINCHR = 1 .IIf Ndf OLDDEF OLDDEF = 1 .IIf Ndf OVSDEF OVSDEF = 0 .IIf Ndf MAXFIF .IIf Df STA MAXFIF = 22. .IIf Ndf MAXFIF .IIf Ndf STA MAXFIF = 23. .IIf Df EDT .IIf Ndf EDTDEF EDTDEF = 0 .IIf Df EXTNPR .IIf Ndf PRMDEF PRMDEF = 1 .IIf Df STATUS .IIf Ndf STADEF STADEF = 1 .IIf Df VT2XX .IIf Ndf MAXHLP MAXHLP = " " .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 PRO .Rad50 \...CA2\ ; Current CLI .Iff ;PRO .If Df CLISUP .Rad50 \CLI...\ ; Current CLI .Iff ;CLISUP .Rad50 \MCR...\ ; Task for Systems without alternate CLI-Supp. .EndC ;CLISUP .EndC ;PRO .=$$$ ; 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 FILE&SYLOGIN SYLDEV: .Ascii /SYS$LOGIN:/ ; SYS$LOGIN on RSX-11M-Plus SYDEVL = .-SYLDEV .EndC ;FILE&SYLOGIN .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 dynamically changed. ; ; ; Pool information ..... ; POOLTX: .Ascii /MCE -- Pool:/ POOLDT: .BlkB 18. ; ; Startup text ..... ; STRTXT: .If Df PRO .Ascii \MCE -- PRO Commandline Editor \ .Iff ;PRO .If Df CLISUP .Ascii \MCE -- CLI Commandline Editor \ .Iff ;CLISUP .Ascii \MCE -- MCR Commandline Editor \ .EndC ;CLISUP .EndC ;PRO IDENT: .Ascii \ \ ; Ident will be placed here STRLEN=.-STRTXT-1 NEWLIN Z ; ; Pause text ..... ; PSETXT: .Ascii \MCE -- Suspended; Type "RES \ TSKNAM: .Ascii \ " to continue .....\ NEWLIN 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, Exitstatus :\ EXSTDA: .Ascii \ \ NEWLIN .Ascii \ --->\ EXSTML=.-EXSTMS .EndC ;COMPND .If Df STATUS ; ; Statusline ..... ; STATX1: .Ascii "D" ; Line Down, Line Up, .Ascii "M" ; to avoid problems with last line. STATX2: .Ascii "7" ; Save cursor .Ascii "[1;23r" ; Set scrolling region .Ascii "[24;1H" ; Line 24 .Ascii "[7m" ; Inverse video 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 "8" ; Restore cursor STALN2=.-STATX2 STALN1=.-STATX1 .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 ; .If Df STATUS ; ; Scrolling region clear ; REGCLR: .Ascii "[24;1H" ; Clear .Ascii "[A" ; .Ascii "[132C" ; .Ascii "[1J" ; scrolling .Ascii "[H" ; region REGCLL=.-REGCLR ; ; ; Statusline clear ..... ; STACLR: .Ascii "7" .Ascii "[1;24r" .Ascii "8" .Ascii "[J" STACLN=.-STACLR .EndC ;STATUS ; ; Various messages ..... ; .If Ndf PRO BYETXT: .Asciz /BYE/ ; Bye after time-out EXITXT: .Asciz /MCE Exit/ ; Exit command on TT0: time-out .EndC ;NDF PRO ENDTXT: NEWLIN ; Exit .Asciz /MCE -- Exit/ ; message ERRTXT: NEWLIN .Asciz /MCE -- Internal Command Error/ CRET: ; Only NOPOOL: NEWLIN .Asciz /MCE -- Pool exhausted - Install MCE with a larger Increment/ TOOLON: NEWLIN .Asciz /MCE -- Command too long/ CONTXT: .Asciz /MCE -- Continuing ...../ .If Df PWD PASTXT: .Ascii .Ascii /MCE -- Lock terminal/ .Ascii /Password >/ PASTXL=.-PASTXT VFYTXT: .Ascii .Ascii /Verification>/ VFYTXL=.-VFYTXT LCKTXT: .Ascii .Ascii /MCE -- This terminal is Locked/ LCKTXL=.-LCKTXT ULKTXT: .Ascii .Ascii /Unlock Password>/ ULKTXL=.-ULKTXT .EndC ;PWD .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 Df VT2XX .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 can't use/ NEWLIN .Ascii / and keys./ NEWLIN .Ascii / Generate MCE.HLP and MCE.TSK together with / .Ascii /MCEBLD.CMD/ NOHLEN=.-NOHTXT .EndC ;MAXHLP-'A .EndC ;VT2XX ; ; RT:,HT and LT: Messages ..... ; .If Df RTEXIT!HTEXIT .Iif Df RTEXIT RTTXT: .Iif Df HTEXIT HTTXT: NEWLIN .Ascii /MCE -- Started on a Remote Terminal. Exiting ...../ .Ascii NEWLIN .Iif Df RTEXIT RTTXTL=.-RTTXT .Iif Df HTEXIT HTTXTL=.-HTTXT .EndC ;RTEXIT!HTEXIT .If Df RTMESS!HTMESS .Iif Df RTMESS RTTXT: .Iif Df HTMESS HTTXT: NEWLIN .Ascii /MCE -- ** WARNING ** Started on a Remote Terminal./ NEWLIN .Ascii / If your local system is OpenVMS with its Commandline/ NEWLIN .Ascii / editor enabled please type "MCE EXIT"/ NEWLIN .Iif Df RTMESS RTTXTL=.-RTTXT .Iif Df HTMESS HTTXTL=.-HTTXT .EndC ;RTMESS!HTMESS .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 .If Df PWD .Ascii /LOCK/ ; Password locking ICLOCK .EndC ;PWD .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/ ; Set Keypad mode on/off ICKEYP .EndC ;EDT .If Df EXTNPR .Ascii /PROM/ ; Extended prompt on/off ICPROM .EndC ;EXTNPR .If Df FILE .Ascii /CHAI/ ; Chain to other file (= READ) ICREAD .Ascii /READ/ ; Read definition file 'MCE READ filespec' ICREAD .Ascii /REPL/ ; Replace translations by new file ICREPL .EndC ;FILE .If Df STATUS .Ascii /STAT/ ; Status line on/off ICSTAT .EndC ;STATUS .If Df TMOTIM&TMOSET .Ascii /TIMO/ ; Time-out Value in minutes ICTIMO .EndC ;TMOTIM&TMOSET .Ascii /UPFI/ ; Up Find ICUPFI .If Df UPR .Ascii /USPR/ ; Userprompt ICUSPR .EndC ;UPR 0 ; End of table marker .PSect IDATA ; ; Various variables and buffers ..... ; ; ------------------------------------------------------------- ; GTKBUF: .BlkW 2 ; TaskName ; ; Next buffers overlap GTKBUF ..... ; FREE: .BlkW 2 ; Free memory listhead IOSTAT: .BlkW 2 ; I/O Statusblock POOL: .BlkW 3 ; Pool information FIFPTR: 0 ; Ptr to current Entry (for UP, DOWN keys ; and PRICMD, PRIFIF) FIFCNT: .Byte 0 ; Number of entries in FIFO CHAR: .Byte 0 ; Input-character ; .=GTKBUF+32. ; Buffer is 16 words long ; ; ------------------------------------------------------------- ; MAXF: MAXFIF ; FIFO size MINC: MINCHR ; Command length to be saved 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 ; Start address of selected range .EndC ;EDT .If Df TMOTIM!RTMESS!RTEXIT!HTMESS!HTEXIT GLUNB: .BlkW 6. .EndC ;TMOTIM!RTMESS!RTEXIT!HTMESS!HTEXIT ; ; Flags, buffers and other bytes ..... ; ECHFLG: .Byte 0 ; If ne : Echo Commandline ; - change with MCE ECHO on/off 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 Command buffer OLDFLG: .Byte 0 ; If ne : Old command, not edited OVSFLG: .Byte OVSDEF ; If ne : Auto overstrike ; - change with MCE OVERstrike on/off MODFLG: .Byte OVSDEF ; If odd: Overstrike mode ; - change with ^A PRIFLG: .Byte 0 ; If ne : Command buffer being printed out 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 UPFFLG: .Byte 1 ; If ne : Up Find function enabled ; - change with MCE UPFI on/off UFAFLG: .Byte 0 ; If ne : Up Find function active .If Df CLISUP!FILE CLIFLG: .Byte 0 ; If ne : GETCLI was successful .EndC ;CLISUP!FILE .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 SAVWRD: .BlkB CMDSIZ ; Last deleted word SAVLIN: .BlkB CMDSIZ ; Last deleted line SAVCHR: .Byte 0 ; Last deleted character SELFLG: .Byte 0 ; if ne : Ansi-selective range active .EndC ;EDT .If Df STATUS FIFPOI: .Byte 0 ; Current FIFO Entry number .EndC ;STATUS .If Df PWD PWDBUF: .BlkB 8. ; Password buffer VRFBUF: .BlkB 8. ; Password verify buffer TMPBUF: .Byte 0 ; Temporary Buffer .EndC ;PWD .If Df EXTNPR PRMFLG: .Byte PRMDEF ; if ne : extended prompt ; - Change with MCE PROMpt on/off .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 UPR USERPL: .Byte 0 ; User prompt length .EndC ;UPR .If Df TMOTIM TT0FLG: .Byte 0 ; If ne : TI: = TT0: .If Df TMOSET TMOFLG: .Byte TMOON ; Time-out ON/OFF flag .Even TMOVAL: TMOTIM ; Time-out value in minutes .EndC ;TMOSET .Even TMOCNT: TMOTIM ; Counter for time-out .EndC ;TMOTIM .Even ; ; FIFO Buffer descriptors ..... ; FIFO: 0, FIFO ; FIFO Buffer list head ; ; List head offsets ..... ; F.1ST = 0 ; Pointer to first entry F.LAST = 2 ; Pointer to last entry ; ; FIFO entry offsets ..... ; FI.NXT = 0 ; Pointer to next Entry FI.LEN = 2 ; Length of entry FI.TXT = 4 ; Text, terminated by binary 0 ; ; ; Translation buffer ..... ; (same entries as in FIFO) ; TRNBUF: 0, TRNBUF ; Command definitions list head ; ; Terminal characteristics buffers ..... ; SFGMCB: ANI: .Byte TC.ANI,0 ; ANSI Terminal HLD: .Byte TC.HLD,0 ; Hold screen mode .If Df STATUS .Byte TC.WID,0 ; Buffersize .EndC ;STATUS SFGMCL = .-SFGMCB .If Df STATUS STGMCB: .Byte TC.WID,90. ; New buffersize. ; A bit longer for statusline STGMCL = .-STGMCB .EndC ;STATUS ;-------------------------------------------------------- ; | ; Prompt area ..... | ; | PRBUFL = 24. ; | ; | .If Df UPR ; | ; | UPRLEN = PRBUFL-4 ; Length of userprompt | ; | .EndC ;UPR ; | ; | .BlkB PRBUFL ; Prompt buffer | .Even ; | DEFPR: .Ascii ; must be kept together .Ascii ; | CMDBUF: .BlkB CMDSIZ ; Current buffer | CMDEND: ; | .Even ; | ;-------------------------------------------------------- ; ; Various buffers ..... ; SAVBUF: .BlkB CMDSIZ ; Save Buffer RCLBUF: .BlkB CMDSIZ ; Recall Buffer .Even .If Df FILE ; ; MCR Commandline 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 (only if GDIR fails) ; ; 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 ; ; Buffer to receive Directory information (M+) ; GD.LOG = 5 ; GDIR: GDIR$ GD.LOG,CURDIR,CURDRL,GDIRL GDIRL: 0 ; Length of directorystring ; ; Current directory string ..... ; CURDRL = 40. ; CURDIR: .BlkB CURDRL .EndC ;FILE ; ; ---- THE WHOLE AREA IS CLEARED SO DO NOT SPLIT. --------------v ; | ; Command check buffers and flags ..... | ; | CMDDES: 0, 0 ; Descriptor of whole remainder | PARDES: ; Descriptor of P0 .. P8 | .Rept 9. ; | 0, 0 ; | .EndR ; | ; | P.LEN = 0 ; Bytecount | P.ADR = 2 ; Address | P.SIZ = 4 ; Length of an entry | ; | FTCFLG: .Byte 0 ; Parameter fetched flag | OVMFLG: .Byte 0 ; Send Overflow Message flag | STRFLG: .Byte 0 ; Find command with "*" enabled (ne 0) FNDFLG: .Byte 0 ; Temporary Flag: "*" encountered in compare .Even ; | CMDARL = .-CMDDES ; Command area length | ; --------------------------------------------------------------- .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) EXENO ; CTRL/N ESCAP+1 ; CTRL/O = SS3 8-bit ctrl. char. in 7-bit mode ; See note in release notes ; PAUSE ; CTRL/P loop+1 ; CTRL/Q (XON) DISPLY ; 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, UNDCHR ; ESC O l , DELCHR / UNDLCHR DELRW, UNDWRD ; 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 EXELEA, EXELEA ; ESC O s 3 CHAR / SPECIN DELAY, PAUSE ; 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 PRICMD, SHVERS ; ESC O x 8 SECTION / FILL PRIFIF, SHFREE ; ESC O y 9 APPEND / REPLACE EXEC, EXENO ; ESC O M ENTER ENTER / SUBST 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, UNDLIN ; 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 .If Df EDT KEYVT2 <2 > ,PASTE ,<$I> ; Insert here KEYVT2 <3 > ,CUT ,<$R> ; Remove KEYVT2 <4 > ,SELECT ,<$S> ; Select .Iff ;EDT KEYVT2 <2 > , ,<$I> ; Insert here KEYVT2 <3 > , ,<$R> ; Remove KEYVT2 <4 > , ,<$S> ; Select .EndC ;EDT KEYVT2 <5 > ,PRVHLP ,<$P> ; Prev. Screen KEYVT2 <6 > ,NXTHLP ,<$N> ; Next Screen .If Df VT4XX KEYVT2 <11> , ,<1 > ; F1 KEYVT2 <12> , ,<2 > ; F2 KEYVT2 <13> , ,<3 > ; F3 KEYVT2 <14> , ,<4 > ; F4 KEYVT2 <15> , ,<5 > ; F5 .EndC ;VT4XX 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> ,CHOVER ,<14> ; F14 KEYVT2 <28> ,HELP ,<15> ; F15 HELP KEYVT2 <29> ,EXENW ,<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: ; ; Get task identcode ..... ; ; 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 ; ; Get TaskName for PAUSE message ..... ; GTSK$S #GTKBUF ; Get Task information ; ; Convert TaskName ..... ; MOV #TSKNAM,R0 ; R0 => Version field address MOV GTKBUF,R1 ; 1st 3 RAD50 char. CALL $C5TA ; Convert MOV GTKBUF+2,R1 ; 2nd 3 RAD50 char. CALL $C5TA ; Convert ; ; Specify EXIT-AST to cleanup things when MCE gets aborted ..... ; SREX$S #EXAST ; Specify exit ast ; ; Initialize memory pool ..... ; MOV #FREE,R0 ; R0 => Free memory listhead CALL $INIDM ; Initialize Free Memory ; ; Get terminal characteristics ..... ; CALL TERM ; Get terminal info ; ; Initialize Commandline buffer ..... ; CALL CLRBUF ; Initialize CMDBUF buffer .If Ndf SILENT ; ; Let the people know what we are ..... ; MOV #STRTXT,R0 ; Print CALL IOMSG ; Startup message .EndC ;NDF SILENT .If Df TMOTIM!RTMESS!RTEXIT!HTMESS!HTEXIT ; ; Get information from terminal line ..... ; MOV #GLUNB,R0 ; Buffer GLUN$S #TI,R0 ; Get terminal information .If Df RTMESS!RTEXIT ; ; RT Remote terminal handling ..... ; CMP (R0),#"RT ; Remote terminal RT ? BNE 30$ ; No : => 30$ MOV #RTTXT,ADR ; Print MOV #RTTXTL,LEN ; the CALL IOW ; RT message .If Df RTEXIT JMP EXIT ; .EndC ;RTEXIT 30$: .EndC ;RTMESS!RTEXIT .If Df HTMESS!HTEXIT ; ; HT Remote terminal handling ..... ; CMP (R0),#"HT ; Remote terminal HT ? BNE 31$ ; No : => 31$ MOV #HTTXT,ADR ; Print MOV #HTTXTL,LEN ; the CALL IOW ; HT message .If Df HTEXIT JMP EXIT ; .EndC ;HTEXIT 31$: .EndC ;HTMESS!HTEXIT .If Df TMOTIM ; ; Terminal Time-Out handling ..... ; CMP (R0),#"TT ; Normal terminal ? BNE 40$ ; No : => 40$ TSTB 2(R0) ; TT0 ? BNE 40$ ; No : => 40$ INCB TT0FLG ; Set TT0: flag 40$: .If Df TMOSET TSTB TMOFLG ; Time-out wanted ? BEQ 50$ ; No: => 50$ CALL MARK ; Marktime for time-out 50$: .Iff ;TMOSET CALL MARK ; Marktime for time-out .EndC ;TMOSET .EndC ;TMOTIM .EndC ;TMOTIM!RTMESS!RTEXIT!HTMESS!HTEXIT .If Df FILE ; ; See if INIT-File is present and process it ..... ; CALL FILOP ; Open MCEINI file .EndC ;FILE .SbTtl MCE - RESTAR -- Get next Line, Main-Loop ; RESTAR: ; ; Attach the terminal ..... ; MOV #IO.ATT,CODE ; Attach CALL IO ; the terminal .If Df FILE ; ; Process file input, if any ..... ; TSTB FILINP ; File Input ? BEQ 10$ ; No : => 10$ CALL FILREA ; Goto EXEC1 if something read 10$: ; then come back to RESTAR .EndC ;FILE ; ; Clear various flags ..... ; CLRB NEXFLG ; Clear NoExecute flag CLRB LEAFLG ; Clear Leave pointer flag CLRB OLDFLG ; Clear Old command flag CLRB UFAFLG ; Clear UP Find active flag .If Df EDT CLR SELSTR ; Clear start of select CLRB SELFLG ; Clear ANSI-select flag CLRB GOLDFL ; Clear "GOLD" .EndC ;EDT ; ; Insert/overstrike mode ..... ; BICB INSFLG,MODFLG ; Clear overstrike mode if Auto Insert BISB OVSFLG,MODFLG ; Set overstrike mode if Auto Overstrike ; ; Get terminal characteristics ..... ; CALL TERM ; Get terminal info .If Df EDT ; ; Setup EDT keypad ..... ; TSTB EDTFLG ; EDT Keys enabled ? BEQ 20$ ; No : => 20$ MOV #APLTXT,ADR ; Application keypad MOV #2,LEN ; Length CALL IOW ; Write 20$: .EndC ;EDT ; ; Set our tasks default directory ..... ; SD.TI=6 ; SDIR$S #SD.TI ; Set task DDS to terminal DDS .If Df CLISUP!FILE ; ; Get information from our current CLI ..... ; CALL GETCLI ; Get CLI information .EndC ;CLISUP!FILE .If Df STATUS ; ; Display the status line ..... ; CALL PRISTA ; Status line .EndC ;STATUS .SbTtl MCE - PRIPRM -- Print the prompt ; PRIPRM: ; ; Set up to form prompt ..... ; MOV #IO.CCO,CODE ; Cancel MOV PROMLF,ADR ; Start of prompt buffer MOV #CMDBUF+2,R3 ; Point behind prompt buffer (Room for [) MOVB #'[,-(R3) ; Insert '[' (Hold screen mode) MOVB #ESC,-(R3) ; Insert ESC (Hold screen mode) .If Df UPR ; ; User prompt ..... ; MOVB USERPL,R0 ; Do we have a prompt ? BEQ 10$ ; No : => 10$ SUB R0,R3 ; Point to Userprompt BR 50$ ; => 50$ 10$: .EndC ;UPR .If Df CLISUP ; ; CLI prompt ..... ; TSTB CLIFLG ; GETGLI ok ? BNE 20$ ; Yes : => 20$ MOV #^RMCR,TASK ; MCR... only to spawn to MOVB #'>,-(R3) ; Default prompt BR 50$ ; Continue with default prompt ; 20$: ; ; 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 30$: MOVB -(R0),(SP) ; Save character CMPB (SP),#CR ; ? BEQ 40$ ; Yes : => 40$ CMPB (SP),#LF ; ? BEQ 40$ ; Yes : => 40$ MOVB (SP),-(R3) ; Copy character 40$: SOB R4,30$ ; Next character TST (SP)+ ; Flush space .Iff ;CLISUP .If Df PRO MOVB #' ,-(R3) ; Default prompt MOVB #'$,-(R3) ; for PRO .Iff ;PRO MOVB #'>,-(R3) ; Default prompt .EndC ;PRO .EndC ;CLISUP 50$: .If Df EXTNPR ; ; Extended prompt ..... ; TSTB PRMFLG ; Extended prompt ? BEQ 80$ ; No : => 80$ .If Df EDT ; ; EDT Flag in prompt ..... ; 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 ; ; Insert/overstrike mode flag in prompt ..... ; MOVB #'+,-(R3) ; Assume insert mode BITB #1,MODFLG ; Overstrike ? BEQ 80$ ; No : => 80$ MOVB #'-,(R3) ; Overstrike 80$: .EndC ;EXTNPR ; ; Rest of prompt ..... ; 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 ; - 90$: ; ; Hold screen mode ..... ; TSTB HLD+1 ; Hold screen mode ? BEQ 100$ ; No : => 100$ ADD #4,LEN ; Adjust length for Hold screen escseq. SUB #2,ADR ; Adjust address 100$: ; ; Display PROMPT ..... ; 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: ; ; Put this address on top of stack, so we can do a RETURN to come back ..... ; MOV #LOOP,-(SP) ; ; ; Read with special terminator characters and no echo ..... ; 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 ; ; Check if time-out has occurred ..... ; 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 CALLR 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$: ; ; Delete char. key ..... ; CMPB R4,#DEL ; Delete ? BNE 50$ ; No : => 50$ CALLR DELEC ; => Delete char. 50$: ; ; Prepare to process via dispatch table ..... ; BIC #177740,R4 ; IO.RST: all ctrl-char in iostat MOV R4,R3 ; Copy in R3 ASL R3 ; Word offset BIT #1,DSPTAB(R3) ; Allowed to be translated ? BEQ 60$ ; Yes : => 60$ MOV DSPTAB(R3),R3 ; Take address BIC #1,R3 ; Clear bit 0 CALLR (R3) ; Do action routine 60$: ; ; Check if Control Character has to be translated ..... ; MOVB #'^,SAVBUF ; Insert key MOVB R4,SAVBUF+1 ; as ^x 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,PARDES+P.LEN ; P0 Length = 2 ; PROCESS: ; ; Check if there is any translation to do ..... ; MOV #SAVBUF,PARDES+P.ADR ; P0 Address MOV R2,-(SP) ; Save R2 CALL FNDCMD ; Find cmd MOV (SP)+,R2 ; Restore R2 BCS 10$ ; No entry found : => 10$ CALLR PROCMD ; Process Command 10$: CALLR @(R4) ; <== Go via Dispatch table .SbTtl MCE - INSERT -- Insert one character ; INSERT: ; ; Insert (CHAR) into edit buffer ..... ; CMP R2,#CMDEND ; Still Room ? BHIS 40$ ; 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 40$ ; No : => LOOP MOV R1,R2 ; Increment end ptr BR 40$ ; => 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 ; ; Selected range processing ..... ; TSTB SELFLG ; ANSI-Select active ? BEQ 30$ ; No : => 30$ CALLR DISPLY ; Rewrite line 30$: .EndC ;EDT CALLR UPDATE ; Rewrite line 40$: RETURN ; .SbTtl .SbTtl MCE ----------- *** Escape Sequences *** .SbTtl MCE - ESCAP -- Filter out Escape Sequences ; ESCAP: ; ; An escape character was read ..... ; .ENABL LSB ; ; ; Test for legal combinations ..... ; 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 ; ; Test for = ..... ; CMPB IOSTAT+1,#ESC ; ? BNE 10$ ; No : => 10$ CALLR EXENW ; Execute no-wait 10$: ; ; Test for up-arrow ..... ; CMPB R0,#'A ; ? BNE 70$ ; No : => 70$ ; ; .SbTtl MCE - UP -- Older command UP: ; ; UP-ARROW ..... ; MOV FIFO+F.1ST,R5 ; Take first entry BEQ DWNUP ; Empty => DWNUP TSTB UFAFLG ; UP Find active ? BEQ 15$ ; No : => 15$ CALLR RECALL ; => Find 15$: TST FIFPTR ; Old pointer ? BNE 40$ ; Defined : => 40$ TSTB UPFFLG ; UP Find enabled ? BEQ 18$ ; No : => 18$ CMP #CMDBUF,R2 ; Empty line ? BEQ 18$ ; Yes : => 18$ CMP R1,R2 ; Cursor at EOL ? BNE 18$ ; No : => 18$ INCB UFAFLG ; Up find active ! CALLR RECALL ; => Find 18$: MOV FIFO+F.LAST,FIFPTR ; Take newest entry .If Df STATUS MOVB FIFCNT,FIFPOI ; Newest entry .EndC ;STATUS BR DWNUP ; => DWNUP 40$: CMP FI.NXT(R5),FIFPTR ; Does this point to me ? BNE 30$ ; No : => 30$ .If Df STATUS DECB FIFPOI ; One older .EndC ;STATUS BR 50$ ; => 50$ 30$: MOV FI.NXT(R5),R5 ; Next BNE 40$ ; Got one : => 40$ ; TSTB RNGFLG ; Ringbuffer ? BEQ DWNUP ; No : => DWNUP .If Df STATUS CLRB FIFPOI ; None .EndC ;STATUS 50$: MOV R5,FIFPTR ; Found - load BR DWNUP ; and display ; 70$: ; ; Test for down-arrow ..... ; CMPB R0,#'B ; ? BNE 110$ ; No : => 110$ ; ; .SbTtl MCE - DOWN -- Newer command ; DOWN: ; ; DOWN-ARROW ..... ; TST FIFO+F.1ST ; Any entry at all ? BEQ DWNUP ; No : => DWNUP MOV FIFPTR,R5 ; Get Ptr of buffer BNE 90$ ; Defined : => 90$ TSTB RNGFLG ; Ringbuffer ? BEQ DWNUP ; No : => DWNUP ; MOV FIFO+F.1ST,FIFPTR ; Take oldest .If Df STATUS MOVB #1,FIFPOI ; Oldest .EndC ;STATUS BR DWNUP ; => DWNUP 90$: .If Df STATUS INCB FIFPOI ; One newer .EndC ;STATUS MOV FI.NXT(R5),FIFPTR ; Next BNE DWNUP ; .If Df STATUS CLRB FIFPOI ; None .EndC ;STATUS DWNUP: .If Df EDT CLR SELSTR ; Clear start of select CLRB SELFLG ; Clear ANSI-select flag .EndC ;EDT .If Df STATUS CALL GETFIF ; Load CMDBUF from FIFO CALLR PRIST1 ; Print status line (Update of FIFO pointer) .Iff ;STATUS CALLR GETFIF ; Load CMDBUF from FIFO .EndC ;STATUS 110$: ; ; Test for right-arrow ..... ; CMPB R0,#'C ; ? BNE 130$ ; No : => 130$ ; ; .SbTtl MCE - RIGHT -- Cursor right ; RIGHT: ; ; RIGHT-ARROW ..... ; CMP R1,R2 ; End of text ? BHIS 120$ ; Yes : => 120$ 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$ CALLR DISPLY ; Rewrite line .EndC ;EDT 120$: RETURN ; ; 130$: ; ; Test for left-arrow ..... ; CMPB R0,#'D ; ? BNE 150$ ; No : => 150$ ; ; .SbTtl MCE - LEFT -- Cursor left ; LEFT: ; ; LEFT-ARROW ..... ; CALL SPBACK ; Cursor left one space .If Df EDT TSTB SELFLG ; ANSI-Select active ? BEQ 140$ ; No : => 140$ CALLR DISPLY ; Rewrite line 140$: .EndC ;EDT RETURN ; ; 150$: .If Df EDT ; ; Test for EDT-KEYS ..... ; TSTB EDTFLG ; EDT Keys enabled ? BEQ 200$ ; No : => 200$ ; ; Test for key ..... ; CMPB R0,#'M ; ? BNE 160$ ; No : => 160$ MOVB #<'z-'l>,R0 ; BR 180$ ; 160$: ; ; Test for EDT-PFx keys ..... ; CMPB R0,#'P ; + BLO 170$ ; PFx range ? CMPB R0,#'S ; No : => 170$ BHI 170$ ; - ADD #<'z-'l-'P+1>,R0 ; Relocate to table offset BR 180$ ; => 180$ 170$: ; ; Test for EDT-Keypad keys ..... ; CMPB R0,#'l ; + BLO 200$ ; Within Keypad range ? CMPB R0,#'y ; No : => 200$ BHI 200$ ; - SUB #'l,R0 ; Normalize 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$: ; ; Process EDT-Keys via EDT-Keys Dispatch table ..... ; CALLR @EDTTAB(R0) ; Do EDT function 200$: .EndC ;EDT ; ; Test for normal PF-KEYS ..... ; SUB #'P,R0 ; Any PFn key ? BLO 210$ ; No : => VT2KEY CMP R0,#'S-'P ; > PF4 ? BLOS 220$ ; No : => 220$ 210$: CALLR VT2KEY ; => VT2KEY 220$: ; ; Check if key has to be translated ..... ; 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,PARDES+P.LEN ; P0 Length MOV #SAVBUF,PARDES+P.ADR ; P0 Address MOV R2,-(SP) ; Save R2 CALL FNDCMD ; Find cmd MOV (SP)+,R2 ; Restore R2 MOV (SP)+,R0 ; Restore R0 BCS 230$ ; CALLR PROCMD ; Entry found : => Process command 230$: MOV R2,R1 ; Point to end of buffer ASL R0 ; 2 Word ASL R0 ; offset ; ; Process keys via PC offset ..... ; ADD R0,PC ; Branch CALLR TRANSL ; CALLR RECALL ; CALLR PRICMD ; CALLR PRIFIF ; ; .DSABL LSB .SbTtl MCE - VT2KEY -- VT2xx Functionkeys ; VT2KEY: .If Df VT2XX ; ; Check if function key : ; ; [n~ n 1..6 ; or ; [nn~ nn 11..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 10$ ; Yes: => 10$ 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$ 10$: MOV (SP)+,R0 ; Retrieve word SWAB R0 ; Adjust MOV #VT2TAB,R4 ; R4 => VT2XX table MOV #VT2LEN/6,R5 ; R5 = Table length 20$: CMP R0,(R4)+ ; Look for table entry BNE 30$ ; Not found : => 30$ CALLR VT2FN ; Found : => VT2FN 30$: CMP (R4)+,(R4)+ ; Next entry SOB R5,20$ ; Try next RETURN ; Not found : => LOOP 40$: TST (SP)+ ; Flush word 50$: CALLR 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,PARDES+P.LEN ; Assume P0 Length = 3 CMPB SAVBUF+2,#BLNK ; Blank ? BNE 10$ ; No : => 10$ DEC PARDES+P.LEN ; P0 Length = 2 10$: CALLR PROCESS ; Go via table .EndC ;VT2XX .SbTtl MCE - TDVTST -- TDV2230 Key support ; TDVKEY: .If Df TDV2XX ; ; 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,PARDES+P.LEN ; P0 Length ASL R4 ; Make word offset ADD #TDVTAB,R4 ; Add table address CALLR PROCES ; 10$: .EndC ;TDV2XX RETURN ; .SbTtl MCE - PROCMD -- Process command ; PROCMD: MOV R1,R0 ; Find start of text ; PROCR0: ; ; 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 CALLR EXEC3 ; Execute without display .SbTtl .SbTtl MCE ----------- *** Key actions *** .SbTtl MCE - BEGLIN -- Begin of line ; BEGLIN: .If Df EDT ; ; Selected range processing ..... ; TSTB SELFLG ; ANSI-Select active ? BEQ 10$ ; No :=> 10$ MOV #CMDBUF,R1 ; Cursor at pos 1 CALLR DISPLY ; Rewrite line .EndC ;EDT 10$: ; ; Put cursor at begin of line ..... ; CALL SPBACK ; Back space one position BCC 10$ ; If CC not yet at the begin RETURN ; ; ; .SbTtl MCE - CHOVER -- Flip between insert and overstrike mode ; CHOVER: ; ; Change mode flag ..... ; INCB MODFLG ; Change mode CHOV1: .If Df EXTNPR ; ; Change extended prompt ..... ; TSTB PRMFLG ; Extended prompt ? BEQ 30$ ; No : => 30$ MOV PROMPT,R4 ; R4 => Prompt TSTB (R4)+ ; R4 => Mode character MOVB #'+,(R4) ; Assume insert mode BITB #1,MODFLG ; Overstrike ? BEQ 20$ ; No : => 20$ MOVB #'-,(R4) ; Overstrike 20$: CALLR DISPLY ; Rewrite line 30$: .EndC ;EXTNPR RETURN ; ; ; .SbTtl MCE - CLRLIN -- Clear line ; CLRLIN: ; ; Clear line ..... ; .If Df EDT ; ; Save deleted line for UNDLIN ..... ; MOV #CMDBUF,R0 ; R0 => CMDBUF CMP R2,R0 ; Empty line ? BEQ 10$ ; Yes : => 10$ MOV R2,R1 ; Cursor at EOL MOV #SAVLIN,R4 ; R4 => SAVLIN CALL SAVE ; Save line 10$: .EndC ;EDT ; ; Clear flags, pointers and buffer ..... ; CLRB OLDFLG ; Clear CLRB UFAFLG ; flags CLR FIFPTR ; Clear FIFO pointer .If Df STATUS CLRB FIFPOI ; Clear FIFO pointers .EndC ;STATUS CALLR CLRALL ; Clear all ; ; .SbTtl MCE - DELAY -- Detach and delay ; DELAY: CALL IOCRLF ; Print CALL DETACH ; Detach terminal MRKT$S #EFN,#10.,#2 ; Wait DIR$ #STOPIO ; 10 seconds MOV #RESTAR,(SP) ; Change return address => RESTAR RETURN ; ; ; .SbTtl MCE - DELCHR -- Delete character ; DELCHR: ; ; Delete character ..... ; .If Df EDT ; ; Selected range processing ..... ; 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$: ; ; Save deleted character for UNDCHR ..... ; TSTB EDTFLG ; EDT active ? BEQ 20$ ; No : => 20$ MOVB (R1),SAVCHR ; Save deleted character 20$: .EndC ;EDT ; ; Shift rest of line ..... ; MOV R1,R0 ; R0 => Cursor 30$: MOVB 1(R0),(R0)+ ; Shift string left CMP R0,R2 ; At EOL ? BLOS 30$ ; No : => 30$ .If Df EDT TSTB SELFLG ; ANSI-Select active ? BEQ 40$ ; No : => 40$ DEC R2 ; End of text CALL DISPLY ; Rewrite line BR 50$ ; 40$: .EndC ;EDT CALL UPDATE ; Rewrite line DEC R2 ; End of text 50$: CLRB OLDFLG ; No old command RETURN ; ; ; .SbTtl MCE - DELEC -- Delete left single char ; DELEC: ; ; Prepare for deleting character right ..... ; CALL SPBACK ; Back space one position BCS 10$ ; Error : => 10$ CALLR DELCHR ; => DELCHR 10$: RETURN ; ; .SbTtl MCE - DELEL -- Delete from start of line to cursor ; DELEL: ; ; Delete line left ..... ; MOV #CMDBUF,R0 ; R0 => CMDBUF CMP R1,R0 ; At begin of buffer ? BLOS 70$ ; Yes : => 70$ .If Df EDT ; ; Selected range processing ..... ; 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 10$: ; ; Save deleted line for UNDLIN ..... ; MOV #SAVLIN,R4 ; R4 => SAVLIN CALL SAVE ; Save line .EndC ;EDT 20$: CMP R1,R2 ; EOL ? BEQ 30$ ; Yes : => 30$ MOVB (R1)+,(R0)+ ; Shift string left .If Df EDT ; ; Selected range processing ..... ; TST SELSTR ; Selective range active ? BEQ 20$ ; No : => 20$ DEC SELSTR ; Backup range .EndC ;EDT BR 20$ ; => 20$ ; 30$: ; ; Fill deleted positions with BLANK ..... ; MOV R0,R2 ; End of text 40$: CMP R0,#CMDEND ; End of buffer ? BHIS 50$ ; Yes : => 50$ MOVB #BLNK,(R0)+ ; Fill with blank BR 40$ ; => 40$ 50$: CLRB OLDFLG ; No old command TSTB ANI+1 ; Ansi Screen ? BNE 60$ ; Yes : => 60$ .If Df EDT TSTB SELFLG ; ANSI-Select active ? BNE 60$ ; Yes : => 60$ .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 70$ ; => 70$ 60$: MOV #CMDBUF,R1 ; Reposition cursor CALLR DISPLY ; Rewrite line 70$: RETURN ; ; ; .SbTtl MCE - DELEW -- Delete left single word ; DELEW: ; ; Prepare for delete word left ..... ; CMP R1,#CMDBUF ; At begin of buffer ? BLOS 40$ ; 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 R1,R0 ; R0 = New cursor position MOV (SP)+,R1 ; R1 = Initial cursor position MOV R0,-(SP) ; Save new cursor position CALLR DELWRD ; => Delwrd 40$: RETURN ; ; ; .SbTtl MCE - DELRC -- Delete right single char ; DELRC: ; ; Prepare for delete character right ..... ; CMP R1,R2 ; At EOL ? BHIS 10$ ; Yes : => 10$ CALLR DELCHR ; 10$: RETURN ; ; ; .SbTtl MCE - DELRL -- Delete from cursor to eol ; DELRL: ; ; Delete line right ..... ; MOV R1,R0 ; R0 => Cursor .If Df EDT MOV #SAVLIN,R4 ; R4 => SAVLIN .EndC ;EDT ; ; Detete the line ..... ; 10$: CMP R0,R2 ; EOL ? BHIS 30$ ; Yes : => 30$ CLRB OLDFLG ; No old command .If Df EDT ; ; Save line for UNDLIN ..... ; TSTB EDTFLG ; EDT active ? BEQ 20$ ; No : => 20$ MOVB (R0),(R4)+ ; Save CLRB (R4) ; and terminate 20$: .EndC ;EDT MOVB #BLNK,(R0)+ ; Space BR 10$ ; 30$: .If Df EDT ; ; Selected range processing ..... ; TSTB SELFLG ; ANSI-Select active ? BEQ 40$ ; No : => 40$ MOV R1,R2 ; Cursor at EOL CALLR DISPLY ; Rewrite line 40$: .EndC ;EDT CALL UPDATE ; Rewrite line MOV R1,R2 ; Cursor at EOL RETURN ; ; ; .SbTtl MCE - DELRW -- Delete right single word ; DELRW: ; ; Prepare for delete word right ..... ; CMP R1,R2 ; At EOL ? BHIS 50$ ; 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 (SP),R0 ; R0 = Initial cursor position CALLR DELWRD ; 50$: RETURN ; ; ; .SbTtl MCE - DELWRD -- Delete single word ; DELWRD: .If Df EDT ; ; Save word for UNDWRD ..... ; MOV #SAVWRD,R4 ; R4 => Save Word buffer CALL SAVE ; Save word .EndC ;EDT DELWR1: .If Df EDT ; ; Selected range processing ..... ; TST SELSTR ; Selective range active ? BEQ 30$ ; No : => 30$ CMP R1,SELSTR ; Compare cursor with start of range BHI 20$ ; Right of start : => 20$ SUB R1,SELSTR ; Backup ADD R0,SELSTR ; range BR 30$ ; => 30$ 20$: CMP R0,SELSTR ; New cursor left of start range ? BHIS 30$ ; No : => 30$ MOV R0,SELSTR ; Update start of range 30$: .EndC ;EDT ; ; Delete and replace for BLANK ..... ; CMP R1,R2 ; EOL ? BHIS 40$ ; No : => 40$ MOVB (R1),(R0)+ ; Shift down MOVB #BLNK,(R1)+ ; Must be replaced by space BR DELWR1 ; => DELWR1 40$: MOV R0,R2 ; New end ptr MOV (SP)+,R1 ; Restore cursor CLRB OLDFLG ; No old command CALLR DISPLY ; => Display ; ; .SbTtl MCE - ENDLIN -- Jump to end of text ; ENDLIN: ; ; Put cursor at end of line ..... ; .If Df EDT ; ; Selected range processing ..... ; TSTB SELFLG ; ANSI-Select active ? BEQ 10$ ; No : => 10$ MOV R2,R1 ; End of text CALLR DISPLY ; Rewrite line 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$: RETURN ; ; ; .SbTtl MCE - HELP -- Help key ; HELP: ; ; or Spawn "HELP MCE " ; MOVB #' ,HPAGE ; Take CLRB HPAG0 ; main help ; HELPGO: ; ; Spawn "HELP MCE xxxxx" ..... ; CALL CLRSCR ; Clear screen MOV #HLPTXT,R0 ; Move HELP MCE into Buffer CALLR PROCR0 ; => Process command in R0 ; ; .SbTtl MCE - MOVWRD -- Move word ; MOVWRD: ; ; Move cursor one word to the left ..... ; 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$: CALLR DISPLY ; ; ; .SbTtl MCE - PRICMD -- Print Cmd buffer and put pointer to end of queue ; PRICMD: MOV #TRNBUF+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 10$: MOV @FIFPTR,FIFPTR ; Next PTR BEQ 20$ ; Done : => 20$ CALL GETFIF ; Display CALL IOCRLF ; New line BR 10$ ; => 10$ 20$: CLRB PRIFLG ; Flag command buffer print-out CALL CLRBUF ; Clear edit buffer (FIFPTR already cleared) CALLR DISPLY ; Display prompt ; ; .SbTtl MCE - RECALL -- Recall a command ; RECALL: ; ; Key, Recall ..... ; .If Df STATUS CALL RECCMD ; Recall Command CALLR PRIST1 ; Display status line (FIFO pointer updated) .Iff ;STATUS CALLR RECCMD ; Recall Command .EndC ;STATUS ; ; .SbTtl MCE - TRANSL -- Translate a command ; TRANSL: ; ; Key, Translate ..... ; MOV #CMDBUF,R0 ; R0 => CMDBUF CMP R2,R0 ; Something in buffer ? BEQ 10$ ; 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 10$: RETURN ; .If Df EDT .SbTtl .SbTtl MCE ----------- *** EDT-Key actions *** .SbTtl MCE - CUT -- Put selective range in Paste buffer ; CUT: ; TSTB EDTFLG ; EDT Active ? BEQ 40$ ; No : => 40$ 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,R0 ; R0 = Start MOV SELSTR,R1 ; R1 = End BR 20$ ; => 20$ 10$: MOV SELSTR,R0 ; R0 = Start 20$: MOV #PSTBUF,R4 ; R4 => Save buffer CALL SAVE ; Save sel. range MOV R0,-(SP) ; Save new cursor pos. CLR SELSTR ; Range not active CLRB SELFLG ; Clear Ansi-select flag CALLR DELWR1 ; Delete range 40$: RETURN ; ; ; .SbTtl MCE - EDTHLP -- Keypad Help ; EDTHLP: ; CALL CLRSCR ; Clear screen MOV #EDTTXT,R0 ; EDT helptext CALLR PROCR0 ; => Process command in R0 ; ; .SbTtl MCE - GOLD -- "GOLD" Key ; GOLD: INCB GOLDFL ; Set "GOLD" flag RETURN ; ; ; .SbTtl MCE - PASTE -- Put Paste buffer in at cursor position ; PASTE: TSTB EDTFLG ; EDT Active ? BEQ 10$ ; No : => LOOP MOV #PSTBUF,R4 ; R4 => PSTBUF CALLR PUTBUF ; Put in Edit buffer 10$: RETURN ; ; ; .SbTtl MCE - PUTBUF -- Put UND item or PASTE buffer in line ; PUTBUF: ; ; Insert the undeleted item back in the edit buffer ..... ; CLR R5 ; Clear counter 10$: TSTB (R4)+ ; EOS ? BEQ 20$ ; Yes : => 20$ INC R5 ; Next BR 10$ ; => 20$: TST R5 ; Any chars. ? BEQ 80$ ; No : => LOOP SUB R5,R4 ; R4 => DEC R4 ; Start of string CLRB OLDFLG ; No old command 30$: CMP R2,#CMDEND ; Still Room ? BHIS 80$ ; No : => 80$ MOV R4,ADR ; + MOV #1,LEN ; Echo character CALL IOW ; - BITB #1,MODFLG ; Overstrike ? BEQ 40$ ; No : => 40$ ; MOVB (R4)+,(R1)+ ; Overstrike CMP R1,R2 ; At end ? BLOS 60$ ; No : => Loop MOV R1,R2 ; Increment end ptr BR 60$ ; => Loop 40$: INC R2 ; No overstrike - shift MOV R2,R0 ; R0 => EOL 50$: MOVB -(R0),1(R0) ; Shift string right CMP R0,R1 ; At cursor ? BHI 50$ ; No : => 50$ MOVB (R4)+,(R1)+ ; Insert new character 60$: SOB R5,30$ ; ; TSTB SELFLG ; ANSI-Select active ? BEQ 70$ ; No : => 70$ CALLR DISPLY ; Rewrite line 70$: CALLR UPDATE ; Rewrite line 80$: RETURN ; ; ; .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$ CALLR DISPLY ; 10$: RETURN ; ; ; .SbTtl MCE - SELECT -- Select key ; SELECT: TSTB EDTFLG ; EDT Active ? BEQ 10$ ; No : => 10$ MOV R1,SELSTR ; Save of select address MOVB ANI+1,SELFLG ; Set Ansi-select flag BEQ 10$ ; No Ansi : => 10$ CALLR DISPLY ; 10$: RETURN ; ; ; .SbTtl MCE - SHFREE -- Free pool ; SHFREE: MOV #RESTAR,(SP) ; Change return address CALLR ICFREE ; Display Free pool ; ; .SbTtl MCE - SHVERS -- Version ; SHVERS: MOV #RESTAR,(SP) ; Change return address CALLR ICVERS ; Display Version ; ; .SbTtl MCE - UNDCHR -- Undelete character ; UNDCHR: ; ; Insert the undeleted character back in the edit buffer ..... ; MOV SAVCHR,CHAR ; Take saved character BEQ 10$ ; Not present => CALLR INSERT ; Insert it 10$: RETURN ; ; ; .SbTtl MCE - UNDLIN -- Undelete line ; UNDLIN: ; ; Prepare for Undelete line ..... ; MOV #SAVLIN,R4 ; R4 => Saved line CALLR PUTBUF ; => ; ; .SbTtl MCE - UNDWRD -- Undelete word ; UNDWRD: ; ; Prepare for Undelete word ..... ; MOV #SAVWRD,R4 ; R4 => Saved word CALLR PUTBUF ; => .EndC ;EDT .If Df VT2XX .SbTtl .SbTtl MCE ----------- *** VT2XX-Key actions *** .If LT MAXHLP-'A .SbTtl MCE - NXTHLP -- Next screen .SbTtl MCE - PRVHLP -- Previous screen NXTHLP: PRVHLP: ; ; Previous/Next help not supported ..... ; MOV #NOHTXT,ADR ; No help page MOV #NOHLEN,LEN ; CALL IOW ; information MOV #RESTAR,(SP) ; Change return address => RESTAR RETURN ; .Iff ;MAXHLP-'A ; ; .SbTtl MCE - NXTHLP -- Next screen ; NXTHLP: ; ; Next help screen ..... ; 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$: ; ; Spawn "HELP MCE" ..... ; CALLR HELPGO ; => ; ; .SbTtl MCE - PRVHLP -- Previous screen ; PRVHLP: ; ; Previous help screen ..... ; DECB HPAGE ; Previous screen CMPB HPAGE,#'A ; Low limit ? BHIS 10$ ; No => 10$ MOVB #' ,HPAGE ; Take CLRB HPAG0 ; main help 10$: ; ; Spawn "HELP MCE" ..... ; CALLR HELPGO ; => .EndC ;MAXHLP-'A .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 CALLR EXENW ; 20$: RETURN ; .EndC ;VT2XX .SbTtl .SbTtl MCE ----------- *** Command execution *** .SbTtl MCE - EXELEA -- Execute and leave pointer ; EXELEA: INCB LEAFLG ; Don't clear pointers CALLR EXEC1 ; => EXEC1 ; ; .SbTtl MCE - EXENO -- Save command without execution ; EXENO: INCB NEXFLG ; Don't execute CALLR EXEC1 ; => EXEC1 ; ; .SbTtl MCE - EXENW -- Execute command no-wait ; EXENW: CLR WAITFL ; Clear EVF CALLR 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 OLDFLG ; Old command ? BEQ 20$ ; No : => Load in FIFO TSTB SOLFLG ; Save old commands ? BEQ 30$ ; No : => Don't load in FIFO CMP FIFPTR,FIFO+F.LAST ; Is this the last entry in the FIFO? BEQ 30$ ; Yes: => Don't load twice in sequence 20$: CALL LDFIF ; Load into FIFO 30$: TSTB LEAFLG ; Leave pointers ? BNE EXEC2 ; Yes : => EXEC2 CLR FIFPTR ; Clear FIFO pointer .If Df STATUS CLRB FIFPOI ; Clear FIFO pointers .EndC ;STATUS TSTB NEXFLG ; Execute ? BNE 50$ ; No : => 50$ EXEC2: CALL CMDCHK ; Check for command Translation BCS 50$ ; Nothing to execute EXEC3: .If Df TMOTIM CLR TMOCNT ; Disable time-outs (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 ; .If NDF COMPND CALL INTERN ; Internal command , BYE or LOG ? BCC 50$ ; If C clear: no command for CLI .EndC ;COMPND CALL DOEXEC ; Execute 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$: MOV #RESTAR,(SP) ; Change return address => RESTAR RETURN ; .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 ; ; Input : R0 => Buffer ; LEN = Length ; ; Check if the command (The first in a compound commandline AFTER translation) ; is BYE, LOG[out] or an internal command starting with "MCE". ; To check for the special commands after translation offers the ; possibility to define any other string for Logout or Bye. ; (E.g.: LOGOF*F := BYE, BYE := LOGOUT) ; INTERN returns the C-bit set, if no internal command was found (i.e. the ; buffer has to be submitted to the CLI.) ; C-Bit 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 recognized 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 .If Ndf PRO 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 DOEXE1 ; Submit "BYE" to MCR... CALLR EXITI ; Immediate task exit 30$: .EndC ;NDF PRO 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 ; (12345678 ) ; (MCE XXXXxxx) ; Ignore any behind the first 8. ; 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 := Uppercased 1st 2 characters SWAB R3 ; BIC #" ,R3 ; - CLR R4 ; + BISB (R0)+,R4 ; SWAB R4 ; BISB (R0)+,R4 ; R4 := Uppercased 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 for next 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 for next 80$: CALL @(R1) ; EXECute internal command ; BCS 150$ ; Not OK ? => 150$ ; ; Commandline is already saved. See if we have to flush it ..... ; 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 MOV #CMDSIZ+1,R3 ; Values from 1..CMDSIZ+1 ; (one more to avoid saving) 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 BCS 10$ ; CALLR CLEFIF ; Clear FIFO 10$: 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 ; CALL IOCRLF ; Newline MOV #POOLTX,ADR ; ADR => Message MOV R0,LEN ; SUB #POOLTX+1,LEN ; LEN = Length CALLR IOW ; Write ; ; .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 ; ; ; .If Df PWD .SbTtl MCE - ICLOCK -- LOCK terminal ; ; Lock the terminal with a password ..... ; ICLOCK: MOV #IO.ATT,CODE ; Attach CALL IO ; the terminal MOV #PASTXT,ADR ; => "PASSWORD>" MOV #PASTXL,LEN ; Length CALL IOW ; Print the message MOV #PWDBUF,R0 ; R0 => Buffer CALL GETPWD ; Read the password TSTB PWDBUF ; Any password ? BEQ 20$ ; No : => 20$ MOV #VFYTXT,ADR ; => "VERIFICATION>" MOV #VFYTXL,LEN ; Length CALL PWDVFY ; Verification BCS 20$ ; No match => 20$ MOV #LCKTXT,ADR ; => "LOCKED" MOV #LCKTXL,LEN ; Length CALL IOW ; Print the message 10$: MOV #ULKTXT,ADR ; => "UNLOCK PASSWORD>" MOV #ULKTXL,LEN ; Length CALL PWDVFY ; Verification BCS 10$ ; No match => 10$ 20$: MOV #IO.DET,CODE ; Detach CALLR IO ; the terminal ; PWDVFY: ; CALL IOW ; Print message MOV #VRFBUF,R0 ; Get CALL GETPWD ; Password MOV #PWDBUF,R0 ; R0 => Password MOV #VRFBUF,R1 ; R1 => Verification MOV #8.,R2 ; Count 10$: CMPB (R0)+,(R1)+ ; Compare BNE 20$ ; Not equal => 20$ SOB R2,10$ ; Next CLC ; Equal RETURN ; 20$: SEC ; Not Equal RETURN ; ; GETPWD: ; MOV #8.,R2 ; R2 = Buffersize MOV R0,-(SP) ; Save address 10$: CLRB (R0)+ ; Clear SOB R2,10$ ; Buffer MOV (SP)+,R0 ; Restore address ; MOV #TMPBUF,R1 ; Buffer address MOV R1,ADR ; Buffer address MOV #1.,LEN ; Characters to read MOV #8.,R2 ; R2 = Buffersize 20$: MOV #IO.RNE!TF.RAL,CODE ; Read-All No-Echo CALL IO ; Do IO CMPB (R1),#CR ; Return ? BEQ 30$ ; Yes : => 30$ CMPB (R1),#BLNK ; < Space ? BLOS 20$ ; Yes : => 20$ CMPB (R1),#'~ ; > ~ ? BHI 20$ ; Yes : => 20$ MOVB (R1),(R0)+ ; Copy in buffer MOVB #'*,(R1) ; Echo '*' CALL IOW ; Do IO SOB R2,20$ ; Max. 8 characters 30$: RETURN ; .EndC ;PWD ; ; .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 ;EXTNPR ; ; .SbTtl MCE - ICPURG -- Purge ; ; Delete current translation table ..... ; ICPURG: ; MOV #TRNBUF+F.1ST,R0 ; Queue header for Translation 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 ; ; Replace command definitions ..... ; ICREPL: ; MOV R0,-(SP) ; Save pointer CALL ICPURG ; Delete current translation table MOV (SP)+,R0 ; Restore pointer CALLR 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 delimiter CMP LEN,#1 ; No blank or just one blank left ? BHI 30$ ; No : => 30$ CALL STAFIL ; Fill statusline CALL IOCRLF ; 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 .If Df TMOTIM&TMOSET ; ; .SbTtl MCE - ICTIMO -- TIMO x ; ; Time-out Value ..... ; ICTIMO: ; MOV #TMOVAL,R5 ; R5 => Destination MOV #999.,R3 ; Values from 1...999 MOV R0,-(SP) ; Save current pointer to Commandline CALL VALUE ; Test if time-out value on Commandline BCS 10$ ; No: => 10$ TST (SP)+ ; Forget about old command pointer BR 30$ ; and return 10$: MOV (SP)+,R0 ; Restore Commandline pointer MOV #TMOFLG,R3 ; R3 => Flag CALL ONOFF ; Maybe it is ON/OFF BCS 40$ ; Neither return with CS .If Df STATUS CALL PRIST1 ; Print statusline (TMO status updated) .EndC ;STATUS CALL CANMRK ; Clean old Time-out ASTs TSTB TMOFLG ; Time-out ON ? BEQ 30$ ; No: => 30$ CALL MARK ; Set up next time-out 30$: CLC 40$: RETURN .EndC ;TMOTIM&TMOSET ; ; .SbTtl MCE - ICUPFI -- Up Find ; ; Up find ..... ; ICUPFI: ; MOV #UPFFLG,R3 ; UP Find Flag CALLR ONOFF ; => On/Off .If Df UPR ; ; .SbTtl MCE - ICUSPR -- Get user Prompt ; ; User Prompt ..... ; ICUSPR: ; CALL DELSEA ; Search for delimiter CALL SUPRR0 ; Suppress MOV LEN,R4 ; Save MOVB R4,USERPL ; length BEQ 20$ ; Zero ? Yes : => 20$ MOV #CMDBUF,R3 ; R3 => Prompt area ADD R4,R0 ; R0 => End of prompt 10$: MOVB -(R0),-(R3) ; Copy SOB R4,10$ ; Prompt 20$: CALLR SUCCES ; .EndC ;UPR ; ; .SbTtl MCE - ICVERS -- Version ; ; Show version ..... ; ICVERS: ; CALL IOCRLF ; Cr Lf MOV #STRTXT,ADR ; Print MOV #STRLEN,LEN ; Print CALLR IOW ; Startup message .SbTtl MCE - CLEFIF -- Clear FIFO ; ; 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 -- Delimiter search ; ; Search BLANK ..... ; 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 delimiter CALL SUPRR0 ; Suppress BCS NOSUCC ; Empty : => NOSUCC BICB #40,(R0) ; Uppercase CMPB (R0)+,#'O ; 'O ? BNE NOSUCC ; No : => NOSUCC BICB #40,(R0) ; Uppercase CMPB (R0),#'N ; 'N ? BNE 30$ ; No : => 30$ MOVB #1,(R3) ; Set flag BR SUCCES ; 30$: CMPB (R0)+,#'F ; 'F ? BNE NOSUCC ; No : => NOSUCC BICB #40,(R0) ; Uppercase 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 ; ; Convert value of MCE XXXX nnn command ..... ; VALUE: ; CALL DELSEA ; Search for delimiter CALL SUPRR0 ; Suppress BCS NOSUCC ; Empty : => NOSUCC CALL $CDTB ; Convert TST R1 ; Empty ? BEQ NOSUCC ; Yes : => NOSUCC CMP R1,R3 ; Too large ? BHI NOSUCC ; Yes : => NOSUCC MOV R1,(R5) ; Insert value BR SUCCES ; .SbTtl .SbTtl MCE ----------- *** Subroutines **** .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 - CLRALL -- Clear ALL ; CLRALL: .If Df EDT CLR SELSTR ; Clear start of select CLRB SELFLG ; Clear ANSI-select flag .EndC ;EDT CALL CLRBUF ; Clear edit buffer .If Df STATUS CALL DISPLY ; Display prompt CALLR PRIST1 ; Print status line .Iff ;STATUS CALLR DISPLY ; Display prompt .EndC ;STATUS ; ; .SbTtl MCE - CLRBUF -- Clear Buffer CMDBUF ; CLRBUF: ; MOV #CMDBUF+CMDSIZ,R1 ; R1 => CMDBUF end MOV #CMDSIZ,R5 ; R5 = CMDSIZ 10$: MOVB #BLNK,-(R1) ; Reset CMDBUF to blank SOB R5,10$ ; Go back if not the end MOV R1,R2 ; R2 => CMDBUF RETURN ; ; ; .SbTtl MCE - CLRSCR -- Clear Screen ; CLRSCR: ; TSTB ANI+1 ; Ansi Screen ? BNE 10$ ; Yes : => 10$ CALLR IOCRLF ; Blank line 10$: .If Df STATUS TSTB STAFLG ; Status line on ? BEQ 20$ ; No : => 20$ MOV #REGCLR,ADR ; Clear MOV #REGCLL,LEN ; region CALLR IOW ; 20$: .EndC ;STATUS MOV #SCRCLR,ADR ; Clear MOV #SCRCLL,LEN ; screen CALLR IOW ; .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 #CMDDES,R1 ; + MOV #CMDARL/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 #PARDES,R5 ; R5 => Current Parameter Descriptor MOV R3,P.ADR(R5) ; Start of P0 20$: ; ; Store single char ..... ; MOVB (R1)+,R0 ; R0 = char CALL CNVUPC ; Uppercase and check for space 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,#PARDES ; Is this P0 ? BNE 50$ ; No : => 50$ MOV R3,CMDDES+P.ADR ; Load start Address of remainder DEC CMDDES+P.ADR ; Point to space 50$: CMP R5,#8.*P.SIZ+PARDES ; Already on P8 ? BHIS 60$ ; Yes : => 60$, put it all there ADD #P.SIZ,R5 ; Next Parameter MOV R3,P.ADR(R5) ; Start address BR 70$ ; Do not count 60$: ; ; No delimiter found ..... ; INC P.LEN(R5) ; Count char 70$: SOB R2,20$ ; Next character 80$: ; MOV R3,LEN ; Calculate SUB #SAVBUF,LEN ; Compressed length MOV CMDDES+P.ADR,R2 ; Remainder Descriptor defined ? BEQ 90$ ; No => 90$ SUB R2,R3 ; Calculate length MOV R3,CMDDES+P.LEN ; Store length ; ; Now everything is uppercased, compressed, parsed and moved into SAVBUF ; Check if we define a new command ":=" in P1 ; 90$: MOV #PARDES+P.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 command buffer 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 FTCFLG ; Buffer already fetched ? BLT 160$ ; Yes : => 160$ MOV #CMDDES,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 OVMFLG ; 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 ; Delimiter ? 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 STATUS ; ; Restore buffersize ..... ; TSTB STAFLG ; Statusline wanted ? BEQ 10$ ; No : => 10$ MOV LEN,-(SP) ; Save length MOV #SFGMCB,ADR ; GMC Buffer MOV #SFGMCL,LEN ; GMC Bufferlength MOV #SF.SMC,CODE ; SMC Code CALL IO ; Do it MOV (SP)+,LEN ; Restore length 10$: .EndC ;STATUS .If Df EDT TSTB EDTFLG ; EDT Keys enabled ? BEQ 20$ ; No : => 20$ MOV LEN,-(SP) ; Save length MOV #NUMTXT,ADR ; Numeric keypad MOV #2,LEN ; Length CALL IOW ; Write MOV (SP)+,LEN ; Restore length 20$: .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 ; R3 => 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 ; Preceded 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 CALL SUPRR0 ; Ignore leading blanks (Start at R0) BCS 60$ ; If C set : Empty command CALL TSTINT ; Look if internal command BCC 60$ ; Yes: => Finished processing CALLR DOEXE1 ; Process last or only command 40$: MOV R2,LEN ; Load new length DEC LEN ; Flush trailing space INC R2 ; Account for &-sign SUB R2,R4 ; Compute unused string length BEQ 50$ ; Empty ? Yes : => 50$ ; ; Execute ..... ; CALL SUPRR0 ; Ignore leading blanks (Start at R0) BCS 60$ ; If C set : Empty command CALL TSTINT ; Look if internal command BCC 50$ ; Yes: => Next part CALL DOEXE1 ; Go execute it STSE$S WAITFL ; Stop for execution CMP EXSTAT,#EX$SUC ; Successful ? 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 ; TSTINT: MOV R3,-(SP) ; Save R3,R4 MOV R4,-(SP) ; CALL INTERN ; Internal command ? MOV (SP)+,R4 ; Restore R3,R4 MOV (SP)+,R3 ; RETURN ; C-BIT Set : No Internal command .EndC ;COMPND DOEXE1: ; .If Df COMPND CALL SUPRR0 ; Suppress Leading spaces .EndC ;COMPND TSTB ECHFLG ; Echo ? BEQ 10$ ; No : => 10$ ; ; Echo ..... ; 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 present CALL GETMCR ; Get Commandline (startup file) BCC FILOP2 ; Test status of GMCR: 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' .If Df FILE&SYLOGIN FEAT$S #FE$LOG ; Logical Names supported? CMP $DSW,#EX$SUC ; EX$SUC means yes BMI FILOP4 ; No: => FILOP4 MOV #SYLDEV,FDSPT+2 ; Try file 'SYS$LOGIN:xxx.CLI' MOV #SYDEVL,FDSPT ; Copy to FDSPT table .EndC ;FILE&SYLOGIN 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 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 - PARDES of P0 defined ; - STRFLG .ne.0 to allow abbreviated 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,STRFLG ; Enable abbreviations BR 10$ ; FNDCMD: CLRB STRFLG ; Ignore "*" in translation buffer 10$: MOV #TRNBUF+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 PARDES+P.LEN,R3 ; Length to be compared BLE 100$ ; Zero : => 100$ MOV PARDES+P.ADR,R2 ; Start addr of P0 TSTB STRFLG ; Without abbreviation ? BEQ 80$ ; Yes : => 80$ ; ; Check for match, accepting any "*" in command definition ; CLRB FNDFLG ; Reset Flag: "*" found in Cmd Translation 30$: CMPB (R1),#'* ; Check for "*" in translation buffer BNE 40$ ; Not yet found : => 40$ INCB FNDFLG ; 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 FNDFLG ; 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 FNDFLG ; 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 definition ; 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 ; R2 => CMDBUF MOV #CMDSIZ,R5 ; R5 = CMDSIZ 10$: TSTB PRIFLG ; Print command buffer ? 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 position ? 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: ; CLRB CLIFLG ; Clear GETCLI ok flag DIR$ #GCLI ; Get CLI information BCS 10$ ; Error is C set INCB CLIFLG ; Set CGLI OK flag .If Df CLISUP&FILE MOV CLINAM,FILTYP ; Use CLI name for file type .EndC ;CLISUP&FILE 10$: .If Df FILE DIR$ #GDIR ; Get directory information BCS 20$ ; Error : => 20$ MOV #CURDIR,R2 ; R2 => String MOV GDIRL,R1 ; R1 = Length BR 30$ ; => 30$ 20$: TSTB CLIFLG ; GCLI OK ? BEQ 40$ ; No : => 40$ 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 30$: CALLR .WDFDR ; Write default directory .EndC ;FILE 40$: 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. ; Commandline 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$ SOB R2,10$ ; Count remaining char 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 components 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 .If Df TMOSET MOV TMOVAL,TMOCNT ; Set new time-out count .Iff ;TMOSET MOV #TMOTIM,TMOCNT ; Set new time-out count .EndC ;TMOSET .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 ;(;) .If Df TMOSET ; .SbTtl MCE - CANMRK -- Cancel Marktime CANMRK: CMKT$S ,#TIMAST ; RETURN ; .EndC ;TMOSET .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*P.SIZ+PARDES ; P2 defined ? BNE 10$ ; Yes : => 10$, must load TST 3*P.SIZ+PARDES+P.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,TRNBUF+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,TRNBUF+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 - PAUSE -- Suspend task ; PAUSE: ; MOV #PSETXT,R0 ; Print CALL IOMSG ; message MRKT$S #EFN,#1.,#2 ; Wait DIR$ #STOPIO ; 1 second CALL DETACH ; Detach terminal SPND$S ; Suspend MOV #CONTXT,R0 ; Print CALL IOMSG ; message CALLR DISPLY ; Rewrite line .If Df 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: MOV FIFO+F.1ST,R5 ; R5 => Oldest Entry in FIFO BEQ 60$ ; Empty : => 50$ 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$: .If Df STATUS MOVB #1,R4 ; Start above oldest .EndC ;STATUS CLR -(SP) ; Room for Pointer to FIFO entry 25$: ; ; Check next entry in FIFO ; MOV #RCLBUF,R1 ; R1 => Source to Compare TSTB (R1) ; Search mask defined ? BEQ 50$ ; No : => 50$ MOV R5,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 R5,(SP) ; Source exhausted - match found .If Df STATUS MOVB R4,FIFPOI ; Store FIFO entry number .EndC ;STATUS 40$: .If Df STATUS INCB R4 ; One newer .EndC ;STATUS MOV FI.NXT(R5),R5 ; R5 => Next entry BEQ 50$ ; No more : => 50$ CMP R5,FIFPTR ; Continue search ? BNE 25$ ; Yes : => 25$ 50$: MOV (SP)+,FIFPTR ; Pop Pointer to entry if any .If Df STATUS BNE 60$ ; Any pointer ? => 60$ CLRB FIFPOI ; .EndC ;STATUS 60$: CALLR GETFIF ; Load from FIFO (or delete CMDBUF buffer) .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 ; .If Df EDT ; .SbTtl MCE - SAVE -- Save deleted Word/Line ; SAVE : TSTB EDTFLG ; EDT active ? BEQ 20$ ; No : => 20$ MOV R0,R3 ; Copy startaddress 10$: MOVB (R3)+,(R4)+ ; Copy CLRB (R4) ; and terminate CMP R3,R1 ; End ? BNE 10$ ; No : => 10$ 20$: RETURN ; .EndC ;EDT ; .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 cursor 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 ; R0 => Tmo value in statusline .If Df TMOSET TSTB TMOFLG ; Time-out ON ? BNE 30$ ; Yes : => 30$ MOVB TMOFLG,R1 ; No : CALL OFFON ; Insert "off" BR 60$ ; Don't display the Time-out count 30$: TST TMOCNT ; TMOCNT zero (= current Input) ? BEQ 40$ ; Yes : => Insert TMOVAL instead MOV TMOCNT,R1 ; Time-out count BR 50$ ; 40$: MOV TMOVAL,R1 ; Take TMOVAL 50$: .Iff ;TMOSET MOV TMOCNT,R1 ; Time-out count .EndC ;TMOSET MOV #15012,R2 ; Params. CALL $CBTA ; Convert 60$: .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 P.LEN(R1),R5 ; R5 = Length BEQ 30$ ; Empty : => 30$ MOV P.ADR(R1),R1 ; R1 = Source Addr 10$: CMP R2,#CMDEND ; In range ? BLO 20$ ; Yes : => 160 DECB OVMFLG ; 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 #PARDES,R3 ; R3 => Descriptor MOV R3,R1 ; CALL STORE ; Load it MOV R2,2*2(SP) ; Load R2 after return DECB FTCFLG ; 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: ; ; Get current characteristics ..... ; 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$: TSTB STAFLG ; Statusline wanted ? BEQ 20$ ; No : => 20$ ; ; Set new buffersize ..... ; MOV #STGMCB,ADR ; SMC Buffer MOV #STGMCL,LEN ; SMC Bufferlength MOV #SF.SMC,CODE ; SMC Code CALLR IO ; Do it 20$: 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 DEC TMOCNT ;; Timeout ? BMI 10$ ;; Should not be < 0 BNE 20$ ;; Not yet done ; ; Timed out - kill pending read ; MOV #IO.KIL,CODE ;; Kill CALL IO ;; pending read 10$: CLR TMOCNT ;; BR 30$ 20$: .If Df STATUS CALL STAFIL ;; Fill statusline TSTB STAFLG ;; Statusline wanted ? BEQ 30$ ;; No : => 30$ QIOW$S #IO.WBT,#TI,#EFNAST,,,,<#STATX2,#STALN2,#0> .EndC ;STATUS 30$: .If Df TMOSET TSTB TMOFLG ;; Still Timeout ON? BEQ 40$ ;; No: => 40$ CALL MARK ;; Mark time 40$: .Iff ;TMOSET CALL MARK ;; Mark time .EndC ;TMOSET 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 ; Address 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 ; Address 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