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