Trailing-Edge
-
PDP-10 Archives
-
BB-M836C-BM
-
tools/exec-mods/execce.mac
There are 5 other files named execce.mac in the archive. Click here to see a list.
; UPD ID= 273, SNARK:<6.1.EXEC>EXECCE.MAC.16, 28-Jun-85 16:05:06 by PRATT
;More TCO 6.1.1404:
; Due to an aspect of the monitor, when the line is being read in
; image mode, and the terminal has pause on end-of-page set, and
; we continue to allow normal xon/xoff processing, the command editor
; will pause at eop even though we have typed input on every line.
; Fix this by removing the pause at eop setting and restore it if needed.
; UPD ID= 272, SNARK:<6.1.EXEC>EXECCE.MAC.15, 28-Jun-85 11:23:06 by PRATT
;More TCO 6.1.1404 - Fix SET EDIT MODE VMS not confirming properly
; UPD ID= 270, SNARK:<6.1.EXEC>EXECCE.MAC.14, 28-Jun-85 08:55:37 by PRATT
; In VMS mode, ^B should act like up-arrow
; Let user set a default VMS insert/overstrike mode, SED default is overstrike
; SED mode was not terminating the string correctly in overstrike mode
; Make SET EDIT xxx legal
; SET EDIT-xxx becomes invisible and will eventually go away
; Make INFO COMMAND code say EDIT xxx
; Fix INFO COMMAND code to say EDIT INT... instead of just INT...
; UPD ID= 267, SNARK:<6.1.EXEC>EXECCE.MAC.13, 25-Jun-85 15:59:13 by PRATT
;More TCO 6.1.1404 - Can't replace 1 instruction with 2 after skip insts.
; UPD ID= 266, SNARK:<6.1.EXEC>EXECCE.MAC.12, 25-Jun-85 12:57:44 by PRATT
;More TCO 6.1.1404:
; In CEERET, CETTMD is garbage. Make it a real location in EXECPR
; Whenever updating CETSAV for a new command, BLT the buffer to zero.
; Fix some bugs for checking for end of CETSAV buffer
; Don't blow up when trying to insert more than the CETSAV buffer holds
; Exiting and quiting are indistinguishable, give indication of aborting
; Edited commands are not be saved, save them
; UPD ID= 263, SNARK:<6.1.EXEC>EXECCE.MAC.11, 24-Jun-85 14:42:35 by PRATT
;More TCO 6.1.1404 - Fix VMS mode help
; UPD ID= 260, SNARK:<6.1.EXEC>EXECCE.MAC.10, 21-Jun-85 12:45:15 by EVANS
;More TCO 6.1.1404 - Add RECALL; make REDO and AGAIN invisible.
; UPD ID= 258, SNARK:<6.1.EXEC>EXECCE.MAC.9, 20-Jun-85 19:35:37 by PRATT
;Even more TCO 6.1.1404 - Fix problem with commands not being saved correctly
; UPD ID= 254, SNARK:<6.1.EXEC>EXECCE.MAC.8, 19-Jun-85 23:04:27 by PRATT
;More TCO 6.1.1404:
; Be paranoid over updating the linked lists
; Auto xon/xoff tty problems: remove ^S ^Q handling, leave page mode alone.
; Make certain memory to memory SOUTs use the ASOUT routine instead
; Add SED and VMS line editing modes (works only for vt100's for now)
; Let EMACs mode use arrow keys if vt100 style terminal
; Remove non-DEC tty types, customers must add their own
; Make commands table driven (more needs to be done)
; Lots of cleanup, Make lots of JRST CEINC's become RET's
; For alter-mode: when in insert mode, do the command if <cr> typed
; Use RSCANs instead of STIs for executing the edited line
; Do range checking so we don't overflow buffers (more needs to be done)
; UPD ID= 248, SNARK:<6.1.EXEC>EXECCE.MAC.7, 14-Jun-85 15:52:53 by EVANS
;More TCO 6.1.1404 - Don't save PCL subcommands to be in history.
; UPD ID= 245, SNARK:<6.1.EXEC>EXECCE.MAC.6, 10-Jun-85 09:15:05 by SANTIAGO
;More TCO 6.1.1404 - Don't let ^H be edit-interrupt character
; UPD ID= 222, SNARK:<6.1.EXEC>EXECCE.MAC.5, 10-Jun-85 08:43:00 by DMCDANIEL
;Take out copyrights, we do NOT own the command editor.
; UPD ID= 214, SNARK:<6.1.EXEC>EXECCE.MAC.4, 5-Jun-85 10:52:06 by EVANS
;More TCO 6.1.1404 - Add VT102 and VT200 terminals.
; UPD ID= 209, SNARK:<6.1.EXEC>EXECCE.MAC.3, 31-May-85 08:41:46 by EVANS
;More TCO 6.1.1404 - Fix extra line feeds in History from REDO and AGAIN.
; UPD ID= 208, SNARK:<6.1.EXEC>EXECCE.MAC.2, 24-May-85 14:18:46 by EVANS
;TCO 6.1.1404 - Bring all command editing routines into EXECCE, so command
; editor can be assembled conditionally.
;TOPS20 'EXECUTIVE' COMMAND LANGUAGE - COMMAND EDITOR ROUTINES
;Digital does not support this product; it is provided only as a tool.
;Original command editor by Billy Brown @ UTEXAS-20
;Modified by others since (notably Ittai Hershman @ NYU)
SEARCH EXECDE
TTITLE EXECCE
DEFINE CESTG <
TRVAR <CEPEOP,RVVFLG,CESVP,CEEOC,CADLFG,CEDUMB,CABKFG,CELPOS,CECPOS,CELPTR,CEDSEA,CENUMR,CEKBC>
>
; ROUTINE TO SAVE CONTENTS OF COMMAND BUFFER FOR LATER EDITING
; THIS WILL RETURN +2 IF SUCCESSFUL SAVE, +1 IF NOT SUCCESSFUL
CSAVE:: CALL SAVACS ;SAVE THE REGISTERS
SKIPE CEBPTR ;THIS ONE NOT TO BE SAVED?
JRST CSAVE5 ;QUIT NOW
MOVE A,SBLOCK+.CMIOJ ;GET PRIMARY JFNS
CAME A,[.PRIIN,,.PRIOU] ;A REAL, TYPED COMMAND?
JRST CSAVE5 ;NOPE, DON'T SAVE IT
SKIPE PCCIPF ;IF NOT PCL COMMAND, SAVE IT
JRST [ SKIPE PCLMID
JRST CSAVE5 ;IF NOT THE CALLING COMMAND, DON'T SAVE
SETOM PCLMID ;DON'T SAVE ANY MORE PCL COMMANDS
JRST .+2 ] ;BUT DO SAVE THIS ONE
SETZM PCLMID
LDB A,[POINT 7,CBUF,6] ;CHECK IT OUT FIRST
JUMPE A,CSAVE5 ;DON'T SAVE EMPTY COMMANDS
CAIN A,CR ;CR?
JRST CSAVE5 ;YES, DON'T SAVE
CAIN A,LF ;LF?
JRST CSAVE5 ;YES, EMPTY COMMAND, DON'T SAVE
MOVE A,[POINT 7,CBUF] ;POINT TO THE SOURCE
CALL PIOFF ;NO INTERRUPTS RIGHT NOW
MOVE B,CEFFL ;GET ADDRESS OF FIRST FREE LOCATION
CAIL B,CESAVE ;DON'T WANT TO POINT OUTSIDE OF BUFFER
CAILE B,CEBFEN ; IF SO, WE ARE SMASHING THINGS
JRST CSAVER ;SMASHING THINGS
CAME B,CE1ST ;ABOUT TO STOMP SOMEONE?
JRST CSAVE0 ;NO
HRRZ D,(B) ;GET ADDRESS OF NEXT ONE
HRRZS (D) ;TIE IT OFF
MOVEM D,CE1ST ;SAVE NEW ADDRESS
CAIL D,CESAVE ;DON'T WANT TO POINT OUTSIDE OF BUFFER
CAILE D,CEBFEN ; IF SO, WE ARE SMASHING THINGS
JRST CSAVER ;SMASHING THINGS
SOS CECNT ;DECREMENT THE COUNT
CSAVE0: CALL PION ;OKAY FOR INTERRUPTS NOW
HLL B,[POINT 7,0] ;POINT TO FIRST FREE SPOT
AOS B ;LEAVE ROOM FOR THE HEADER
CSAVE1: ILDB C,A ;GET NEXT BYTE
CAIN C,CR ;END ON CR
SETZ C,
CAIN C,LF ;END ON LINE FEED
SETZ C,
CSAVE2: IDPB C,B ;STORE THE BYTE
CALL PIOFF ;NO INTERRUPTS RIGHT NOW
HRRZ D,B ;GET ADDRESS WE JUST STORED IN
CAME D,CE1ST ;GOING OVER THE FIRST COMMAND?
JRST CSAVE3
HRRZ D,(D) ;GET ADDRESS OF NEXT ONE
HRRZS (D) ;TIE IT OFF
MOVEM D,CE1ST ;SAVE NEW ADDRESS
SOS CECNT ;DECREMENT THE COUNT
CSAVE3: CALL PION ;OKAY FOR INTERRUPTS NOW
HRRZ D,B ;GET ADDRESS AGAIN
CAIE D,CEBFEN ;PAST THE BUFFER?
JRST CSAVE4 ;NO
MOVE B,[POINT 7,CESAVE] ;YES, RESET TO THE TOP
JRST CSAVE2 ;AND TRY AGAIN
CSAVE4: JUMPN C,CSAVE1 ;GET NEXT CHARACTER IF NOT THE END
CALL PIOFF ;NO INTERRUPTS RIGHT NOW
HRRZ A,B ;GET ADDRESS OF LAST BYTE
AOS A ;BECOMES FIRST FREE LOCATION
CAIL A,CEBFEN ;STILL IN THE BUFFER?
MOVEI A,CESAVE ;NO, WRAP AROUND
EXCH A,CEFFL ;SAVE IT, A POINTS TO THE NEW BLOCK
HRRM A,@CELAST ;LINK THIS ONE IN
MOVE B,CELAST ;GET ADDRESS OF LAST ONE
HRLZM B,(A) ;LINK FROM NEW ONE TO OLD ONE
MOVEM A,CELAST ;UPDATE LAST COMMAND POINTER
AOS CECNT ;INCREMENT COUNT
CALL PION ;OKAY FOR INTERRUPTS NOW
CALL RESACS ;RESTORE ACS
SETOM CEBPTR ;MARK AS BEING SAVED
RETSKP ; SUCCESSFUL SAVE
CSAVER: ETYPE <%%Command editor problem: Pointers messed up, reseting them.%_>
CALL PIOFF
MOVEI A, CESAVE+2 ;INITIALIZE THE COMMAND EDITOR
MOVEM A, CESAVE ;
MOVEM A, CEFFL ;INITIALIZE FREE SPACE POINTER
MOVEI A, CESAVE ;INITIALIZE POINTER INTO TABLE
MOVEM A, CE1ST ;
MOVEM A, CELAST ;
MOVEI A, 1 ;INITIALIZE THE COMMAND COUNT
MOVEM A, CECNT ;
CALL PION
CSAVE5: CALL RESACS ;RESTORE ACS
RET ; COULDN'T SAVE COMMAND
;COMMAND LINE EDITOR
CEDITU::SETZM CEEOC ;CLEAR "EXITING" FLAG
SETZM RVVFLG ;MAKE SURE HILITE FLAG IS OFF
MOVEI A,.CTTRM ;GET OLD MODE WORD
RFMOD
MOVEM B,CETTMD ;SAVE THIS FOR CEERET AND CEQUIT
MOVEI D,CEERET ;GET ADDRESS OF TTY CLEAN-UP ROUTINE
MOVEM D,CERET ;MAKE SURE IT GETS CALLED ON ERROR
TXZ B,TT%IGN ;MAKE SURE IT SEES TT%WAK BITS
TXO B,TT%WAK ;WAKE ON EVERYTHING
TXZ B,TT%ECO ;TURN OFF ECHOING
; TXZ B,TT%PGM ;TURN OFF PAGING (^S, ^Q)
TXZ B,TT%TAB ;SPACES INSTEAD OF TAB
SFMOD
STPAR
MOVEI B,.MORXO ;GET SETTING OF PAUSE @ EOP
MTOPR
MOVEM C,CEPEOP ;SAVE IT
MOVEI B,.MOXOF
MOVEI C,.MOOFF ;NOW TURN IT OFF
MTOPR
MOVE B,[052525,,553125] ;PASS CR, ^I, FORMAT LF, NO NULLS
MOVE C,[252525,,652400] ;FORMAT ESCAPE
SFCOC
MOVEI A,.FHJOB
SETZ B, ;NO TERMINAL INTERRUPTS
STIW
ERJMP CJERRE
SETZM CELPOS ;INITIALIZE LINE NUMBER
MOVE A,CELAST ;GET THE FIRST COMMAND POINTER
MOVEM A,CELPTR ;INITIALIZE FOR CETOP
SKIPE CEDSEA ;SEARCH MODE?
CALL CESRCH ;YES, SO BEGIN DEFFERENTLY
SETZM CEDUMB ;ASSUME SMART TERMINAL
MOVE A,CEFLAG ;GET EDITOR TYPE
CAIN A,M.SED ;SED MODE ?
SETZM INSMOD ;YES - DEFAULT IS OVERSTRIKE
MOVE B,CEVMSD ;GET DEFAULT INSERT/OVRSTRIKE MODE
CAIN A,M.VMS ;VMS MODE ?
MOVEM B,INSMOD ;YES - SET DEFAULT MODE
CAIN A,M.EMCS ;EMACS MODE?
JRST CEDIT1 ;YES, SIMULATE UP CURSOR
MOVE A,COJFN ;ALTER MODE, GET TERMINAL TYPE
GTTYP
SKIPN EEOLTB(B) ;IS IT SMART?
SETOM CEDUMB ;NO
SETZM CADLFG ;INITIALIZE STUFF
SETZM CABKFG
CEDIT1: CALL CETOP ;SIMULATE INITIAL UP CURSOR
CALL CEINC ;GO EDIT THE LINE
RET
; SEARCH FOR INITIAL STRING -
; CELPTR AND A CONTAINS POINTER TO FIRST COMMAND
; CELPOS AND CELPTR UPDATED ON RETURN
CESRCH: SKIPL CEDSEA ;SEARCH MODE OR NUMBER MODE
JRST CENUMM ;NUMBER MODE
MOVE C,A ;BASE STRING HEADER
MOVE B,[POINT 7,1(C)] ;BASE STRING BYTE POINTER
MOVE A,[POINT 7,ATMBUF] ;POINT TO THE PREFIX STRING
STCMP
SKIPN A ;STRING ARE EQUAL?
RET ;YES, SO RETURN
TXNE A,SC%SUB ;SUBSTRING?
RET ;YES, SO RETURN
; GO TO PREVIOUS LINE
HLRZ A,@CELPTR ;TAKE THE LEFT HAND LINK
SKIPN A ;CHECK FOR END OF LIST
JRST CESRCL ;END OF LIST
AOS CELPOS ;INCREMENT THE LINE NUMBER
MOVEM A,CELPTR ;UPDATE POINTER
JRST CESRCH ;PROCESS THIS LINE
CESRCL: MOVE A,CELAST ;END OF LIST, GO BACK TO THE FIRST LINE
MOVEM A,CELPTR ;RESET THE POINTER
SETZM CELPOS ;RESET LINE NUMBER
TYPE <%Prefix not found - editing last command>
RET
; NUMBER MODE
CENUMM: SKIPGE C,CENUMR ;ONLY ALLOW POSITIVE NUMBERS
RET ;RETURN OTHERWISE POINTING AT CURRENT
CENUMA: HLRZ A,@CELPTR ;TAKE THE LEFT HAND LINK
SKIPN A ;CHECK FOR END OF LIST
JRST CENUML ;END OF LIST
AOS CELPOS ;INCREMENT THE LINE NUMBER
MOVEM A,CELPTR ;UPDATE POINTER
SOJGE C,CENUMA ;CONTINUE IF MORE TO GO
RET ;RETURN POINTING TO CURRENT LINE
CENUML: TYPE <%Requested command line lost - positioning at first command>
RET
CETOP: CALL LM ;KEEP IT PRETTY
CALL EEOLN ;ERRASE TO END OF LINE
SETZM CETSAV ;CLEAR OUT 1ST LOCATION
MOVE A,[CETSAV,,CETSAV+1] ;SET UP FOR THE BLT
BLT A,CETSAV+CETBLN ;CLEAR TO END OF BUFFER
MOVE A,CELPTR ;POINT TO THE CURRENT LINE
AOS A ;SKIP PAST THE HEADER
HLL A,[POINT 7,0] ;MAKE IT A POINTER
MOVE B,[POINT 7,CETSAV] ;POINT TO THE TEMP BUFFER
CETOP0: ILDB C,A ;GET NEXT BYTE
HRRZ D,A ;CHECK FOR WRAP AROUND
CAIE D,CEBFEN ;TOO FAR?
JRST CETOP1 ;NO
MOVE A,[POINT 7,CESAVE] ;YES, RESET THE POINTER
JRST CETOP0 ;AND START OVER
CETOP1: IDPB C,B ;MOVE IT
SKIPN C ;END ON NULL BYTE
IFSKP.
HRRZ D,B ;CHECK FOR CETSAV OVERRUN
CAIGE D,CETSAV+CETBLN ;USED UP CETSAV YET?
JRST CETOP0 ;NOPE, DO ANOTHER CHARACTER
SETO A,
ADJBP A,B ;DECREMENT POINTER
SETZ D,
DPB D,A ;PUT A NULL AT THE END
ENDIF.
SETZM CECPOS ;INITIALIZE POSITION
MOVE A,[POINT 7,CETSAV] ;GET A POINTER TO IT
MOVEM A,CEBPTR ;SAVE IT
SKIPN CEDUMB ;WRITE LINE FOR DUMB TERMINALS
JRST CETOP2
CALL CENUMB
MOVE A,CEBPTR
PSOUT
TYPE <
>
CETOP2: TYPE < > ;MAKE ROOM FOR THE LINE NUMBER
MOVE A,CEBPTR
SKIPN CEDUMB ;EMACS OR SMART ALTER MODE?
PSOUT ;YES, WRITE IT OUT
ETYPEC< TO THE BEGINNING
CALL CENUMB ;WRITE THE NUMBER
RET
CENUMB: MOVEI A,.CTTRM ;OUTPUT LINE# AS "DD:"
MOVN B,CELPOS ;GET (NEGATIVE) LINE NUMBER
JUMPE B,CENUM1 ;DO CURRENT LINE DIFFERENT
MOVE C,[NO%LFL!NO%OOV!NO%AST!FLD(3,NO%COL)!FLD(12,NO%RDX)]
NOUT
JFCL
ETYPE <:>
RET ;ALL DONE
CENUM1: ETYPE < **:> ;FOR CURRENT LINE
RET
; GET THE NEXT INPUT CHARACTER
CEINC: SKIPGE D,CEFLAG ;GET EDITOR TYPE
ERROR <No editor selected for command editing>
SETZ P3, ;MAKE SURE COUNT IS ZERO
HLRZ C,EDISP(D) ;GET DISPATCH ADR
CALL (C) ;GO GET A CHARACTER
HRRZ C,EDISP(D) ;GET ADR TO GO TO
CALL (C) ;GO HANDLE THE CHARACTER
SKIPN CEEOC ;EXITING ?
JRST CEINC ;NO
RET ;YES
;EDIT style command dispatch table
EDTCTB: CR,,CEEXIT ;<CRLF> - EXIT AND DO COMMAND
"E",,CEEXIT ;E - EXIT AND DO COMMAND
.CHCNU,,CETOP ;^U - START OVER
.CHLFD,,CEDOWN ;FL - NEXT LINE
.CHESC,,CEUP ;ESC - PREVIOUS LINE
.CHCNR,,CATYPE ;^R - RETYPE LINE
"L",,CARTYP ;^L - TYPE LINE AND START OVER
"P",,CATYPE ;P - RETYPE LINE
"Q",,CEQUIT ;Q - ABORT
.CHCNC,,CEQUIT ;^C - ABORT
"D",,CADEL ;D - DELETE CHARACTERS
"H",,CAHACK ;"H" - DELETE TO END, THEN INSERT
"I",,CAINST ;"I" - ENTER INSERT MODE
"R",,CADEIN ;"R" - REPLACE
"W",,CAFORW ;"W" - MOVE OVER WORDS
"X",,CAEXTN ;"X" - EXTEND LINE
"Z",,CADELZ ;"Z" - DELETE WORDS
":",,CACOLN ;DELETE REST OF LINE
"\",,CETRAN ;"\" - TRANSPOSE PREVIOUS TWO CHARS
.CHDEL,,CALEFT ;RUB - MOVE CURSOR LEFT
" ",,CARIGH ;SPACE - MOVE CURSOR RIGHT
.CHTAB,,CAEOLN ;TAB - MOVE TO END OF LINE
"?",,CAHELP ;? - GIVE HELP MESSAGE
EDTCLN==.-EDTCTB
;Here with uppercase character in B
ACEDSP: SETZ C, ;INIT THE INDEX
ACEDS0: CAIGE C,EDTCLN ;DONE ?
IFSKP.
CALL CEBELL ;YES - NO MATCH, RING THE BELL
RET ;TRY AGAIN
ENDIF.
HLRZ A,EDTCTB(C) ;GET CHARACTER
CAME A,B ;GOT A MATCH ?
AOJA C,ACEDS0 ;BUMP INDEX AND LOOP
HRRZ A,EDTCTB(C) ;GET DISPATCH ADDRESS
CALL (A) ;AND GO THERE
RET
;EDIT style "get a character routine"
ACEINP: SETZ P3, ;ASSUME NO NUMERIC ARGUMENT
ACEIN0: PBIN ;GET ALTER MODE COMMAND
CAIL A,"0" ;BIGGER THAN 0?
CAILE A,"9" ;SMALLER THAT 9?
JRST ACEIN1 ;NOT A NUMBER, OKAY
IMULI P3,^D10 ;NUMBER, UPDATE THE COUNT
ADD P3,A ;ADD THIS ONE IN
SUBI P3,"0" ;CONVERT TO BINARY
JRST ACEIN0 ;GET THE REST OF THE COMMAND
;Here make any lowercase characters become uppercase in ac B
ACEIN1: MOVE B,A ;COPY CHARACTER
CAIL B,"A"+40 ;LESS THAN LC A
CAILE B,"Z"+40 ;AND LESS THAN OR LC Z
SKIPA ;NOT LOWERCASE
SUBI B,40 ;MAKE LOWERCASE... UPPERCASE
RET
; HERE TO ENTER INSERT MODE
CAINST: CALL CAFLSH ;FLUSH ANYTHING WE HAD GOING
CANST0: PBIN ;GET NEXT CHARACTER
CAIN A,.CHESC ;ESCAPE?
RET ;YES, EXIT
CAIN A,.CHTAB ;A TAB?
JRST CAINOK ;YES, LET IT PASS
CAIN A,.CHCNC ;CONTROL C?
JRST CEQUIT ;YES, QUIT
CAIN A,.CHCRT ;<CR>
JRST CEEXIT ;YES - GO DO IT
CAIL A," " ;SOME CONTROL CODE?
CAIN A,.CHDEL ;OR RUBOUT?
SKIPA ;YES, ERROR
JRST CAINOK ;ITS OK
CALL CEBELL ;ERROR, RING BELL
JRST CANST0 ;AND TRY AGAIN
CAINOK: MOVE C,CEBPTR ;GET THE POINTER
SKIPE CEDUMB ;DUMP TERMINAL?
PBOUT ;YES, DISPLAY THE CHARACTER
CAINS1: ILDB B,C ;GET ONE THAT WAS THERE
SKIPN CEDUMB ;SMART TERMINAL?
PBOUT ;YES, OUTPUT IT
DPB A,C ;REPLACE IT
JUMPE A,CAINS2 ;EXIT AFTER A NULL BYTE
MOVE A,B ;SET UP TO REINSERT THE ONE
JRST CAINS1
CAINS2: AOS CECPOS ;UPDATE OUR POSITION
IBP CEBPTR ;AND OUR POINTER
SKIPE CEDUMB ;SMART TERMINAL
JRST CAINST ;NO, GET SOME MORE
ETYPES<TION THE CURSOR
CALL CENUMB ;MOVE PAST THE LINE NUMBER
MOVE A,COJFN ;POINT TO THE TERMINAL
HRROI B,CETSAV ;POINT TO THE STRING
MOVN C,CECPOS ;GET COUNT
SKIPE C ;DON'T GO FOREVER HERE
SOUT ;MOVE PAST THE OLD CHARACTERS
JRST CAINST ;DONE, GET SOME MORE
; HERE TO DELETE N CHARACTERS
CADEL: CALL ALTDEL ;DO ALTER MODE DELETE
RET ;DONE
; HERE TO DELETE N CHARACTERS THEN INSERT TEXT
CADEIN: CALL ALTDEL ;DO ALTER MODE DELETE
CALL CAFLDE ;SIGNAL END OF DELETE
JRST CAINST ;SO THE INSERT
; ALTER MODE DELETE ROUTINE
ALTDEL: MOVE A,CEBPTR
ILDB B,A
SKIPN B
RET
CALL CAFLBK ;FLUSH BACKSPACE MARKER
SKIPG P3 ;ZERO OR BAD ARGUMENT?
MOVEI P3,1 ;YES, MAKE IT THE DEFAULT
SETZ C, ;NEW COUNTER
SKIPE CEDUMB ;SMART TERMINAL
CALL CADELF ;NO, SIGNAL DELETE
MOVE B,CEBPTR ;GET THE POINTER
ALTDL1: ILDB A,B ;GET NEXT CHARACTER
JUMPE A,ALTD1A ;END?
AOS C ;NO, INCREMENT COUNT
SKIPE CEDUMB ;SMART TERMINAL?
PBOUT ;NO, ECHO CHARACTER
SOJG P3,ALTDL1
JRST ALTDL2
ALTD1A: SETO A, ;WENT TOO FAR, BACKUP POINTER
ADJBP A,B
MOVEM A,B
ALTDL2: SKIPN C
RET
MOVE A,CEBPTR
ALTDL3: ILDB C,B ;GET FIRST CHARACTER
IDPB C,A ;SAVE IN NEW POSITION
JUMPN C,ALTDL3
SKIPE CEDUMB ;SMART TERMINAL?
RET ;NO, DONE
ALTDL4: MOVE A,CEBPTR ;REWRITE THE SCREEN
PSOUT
CALL EEOLN
ETYPES<TION THE CURSOR
CALL CENUMB ;MOVE PAST THE LINE NUMBER
MOVE A,COJFN ;POINT TO THE TERMINAL
HRROI B,CETSAV ;POINT TO THE STRING
MOVN C,CECPOS ;GET COUNT
SKIPE C ;DON'T GO FOREVER HERE
SOUT ;MOVE PAST THE OLD CHARACTERS
RET
; HERE TO RETYPE THE LINE
CATYPE: CALL CAFLSH ;FLUSH EVERYTHING
SKIPN CEDUMB ;SMART TERMINAL?
JRST CEDISP ;YES, THIS IS A JOB FOR EMACS
MOVE A,CEBPTR ;FINISH THE LINE
PSOUT
ETYPE <
> ;GO TO NEW LINE
JRST CINST1 ;WRITE IT OUT
; HERE TO FINISH TYPING THE LINE AND START OVER
CARTYP: CALL CAFLSH
SETZM CECPOS ;RESET CHARACTER PSOITION
SKIPN CEDUMB ;SMART TERMINAL?
JRST CARTP1 ;YES
MOVE A,CEBPTR ;FINISH THE LINE
PSOUT
CARTP1: MOVE A,[POINT 7,CETSAV] ;RESET POINTER
MOVEM A,CEBPTR
ETYPE <
> ;NEW LINE
JRST CETOP2 ;AND START OVER
; HERE TO HACK AND INSERT
CAHACK: CALL CAFLBK
SKIPN CEDUMB ;SMART TERMINAL?
JRST CAHAK1 ;YES, DO IT THE EASY WAY
CALL CADELF ;SIGNAL DELETE
MOVE A,CEBPTR ;GET THE REST OF THE STRING
PSOUT ;OUTPUT IT
TYPE <\\> ;END OF DELETE
SETZM CADLFG
CAHAK1: SETZ A, ;CHOP OFF THE REST OF THE STRING
MOVE B,CEBPTR ;GET COPY OF POINTER
IDPB A,B ;CURSOR IS ONE POSITION PAST POINTER
CALL EEOLN ;JUST IN CASE
JRST CAINST ;START INSERTING
; HERE TO MOVE OVER WORDS
CAFORW: CALL CAFLSH
SKIPG P3
MOVEI P3,1
CAFRW1: CALL F.WORD ;GET COUNT TO NEXT WORD
ADDM B,CECPOS ;UPDATE POSITION
MOVN C,B ;GET NEGATIVE COUNT
MOVE A,COJFN ;MOVE OVER
MOVE B,CEBPTR
SKIPE C
SOUT ;WRITE IT OUT
MOVEM B,CEBPTR
SOJG P3,CAFRW1
RET
; HERE TO DELETE N WORDS
CADELZ: CALL CAFLBK
PUSH P,CEBPTR ;SAVE THE POINTER
SKIPG P3 ;ZERO OR NO ARGUMENT?
MOVEI P3,1 ;YES, MAKE IT THE DEFAULT
SETZ D, ;KEEP COUNT HERE
CADLZ1: CALL F.WORD ;GET COUNT TO NEXT WORD
SUB D,B ;KEEP NEGATIVE COUNT
ADJBP B,CEBPTR ;UPDATE POINTER
MOVEM B,CEBPTR
SOJG P3,CADLZ1
SKIPE A,CEDUMB ;SMART TERMINAL?
JRST CADLZ2 ;NO.
MOVE A,CEBPTR ;DESTINATION POINTER
POP P,CEBPTR ;SOURCE POINTER
JRST M.FIX ;FIX IT UP
CADLZ2: CALL CADELF ;SIGNAL DELETE
MOVE A,COJFN ;WRITE OUT DELETED STUFF
MOVE B,(P) ;POINT TO DELETED STUFF
MOVE C,D ;NUMBER OF CHARACTERS
SKIPE C ;SKIP IF NONE
SOUT
POP P,CEBPTR ;FIX THE POINTER
MOVE A,CEBPTR
CADLZ3: ILDB C,B ;GET FIRST CHARACTER
IDPB C,A ;SAVE IN NEW POSITION
JUMPN C,CADLZ3
RET
; HERE TO EXTEND THE LINE
CAEXTN: CALL CAFLSH
MOVE A,CEBPTR ;GET THE POINTER
PSOUT ;WRITE IT OUT
SETO B, ;BACKUP THE POINTER
ADJBP B,A
SETZ A, ;GET COUNT TOO
CAXTN1: ILDB A,CEBPTR ;GET NEXT CHARACTER
JUMPE A,CAXTN2
AOS CECPOS ;UPDATE POSITION
JRST CAXTN1
CAXTN2: MOVEM B,CEBPTR ;SAVE NEW POINTER
JRST CAINST ;GO TO INSERT MODE
; HERE TO JUMP TO THE END OF A LINE
CAEOLN: CALL CAFLSH
MOVE A,CEBPTR ;GET POINTER
PSOUT ;WRITE IT OUT
SETO B, ;BACK IT UP
ADJBP B,A
SETZ A, ;GET COUNT TOO
CAEOL1: ILDB A,CEBPTR ;GET NEXT CHARACTER
JUMPE A,CAEOL2
AOS CECPOS ;UPDATE POSITION
JRST CAEOL1
CAEOL2: MOVEM B,CEBPTR ;SAVE NEW POINTER
RET
; HERE TO DELETE THE REST OF THE LINE
CACOLN: CALL CAFLBK
SKIPN CEDUMB ;SMART TERMINAL?
JRST CACLN1 ;YES, SKIP THIS
CALL CADELF ;SIGNAL DELETE
MOVE A,CEBPTR ;GET POINTER
PSOUT ;WRITE THE RESTO OF THE STRING
TYPE <\\> ;SIGNAL NO MORE DELETE
SETZM CADLFG
CACLN1: SETZ A, ;CHOP OFF THE REST OF THE STRING
MOVE B,CEBPTR ;GET COPY OF POINTER
IDPB A,B ;CURSOR IS ONE POSITION PAST POINTER
CALL EEOLN ;JUST IN CASE
RET
; HERE TO MOVE TO RIGHT
CARIGH: CALL CAFLSH
SKIPG P3 ;ARGUMENT OK?
MOVEI P3,1 ;FIX IT UP
CARIG1: ILDB A,CEBPTR ;GET NEXT CHARACTER
JUMPE A,CARIG2 ;END OF LINE
AOS CECPOS ;UPDATE POSITION
PBOUT ;MOVE OVER
SOJG P3,CARIG1 ;DO THE REST
RET
CARIG2: SETO A, ;WENT TOO FAR
ADJBP A,CEBPTR ;BACK UP
MOVEM A,CEBPTR
RET
; HERE TO MOVE TO THE LEFT
CALEFT: CALL CAFLDE
SKIPN CECPOS ;BEGINNING OF LINE?
RET ;YES, SKIP
SKIPN P3 ;NO ARGUMENT?
MOVEI P3,1 ;MAKE IT A 1
CAML P3,CECPOS ;ARGUMENT TOO BIG?
MOVE P3,CECPOS ;YES, TRIM IT DOWN
SKIPE CEDUMB ;SMART TERMINAL
JRST CALFT1 ;NO
MOVN C,P3 ;FIX THE POINTER
ADJBP C,CEBPTR
MOVEM C,CEBPTR
MOVN A,P3 ;FIX POSITION
ADDM A,CECPOS
JRST CINST1 ;POSITION CURSOR
CALFT1: CALL CABAKF ;SIGNAL BACK MOVEMENT
CALFT2: LDB A,CEBPTR ;GET THIS CHARACTER
PBOUT ;OUTPUT IT
SETO B, ;MOVE THE POINTER BACK
ADJBP B,CEBPTR ;BACK UP THE POINTER
MOVEM B,CEBPTR
SOS CECPOS
SOJG P3,CALFT2 ;DO THE REST
RET
; ROUTINES TO PRINT \ AND \\ FOR DUMB TERMINAL ALTER MODE
CAFLSH: CALL CAFLBK ;FLUSH OUT BACKSPACE CHARACTER
CALL CAFLDE ;FLUSH OUT DELETE CHARACTER
RET
CAFLBK: SKIPN CEDUMB
RET
SKIPN CABKFG ;WERE WE BACKSPACING?
RET ;NO, NOTHING TO DO
SETZM CABKFG ;RESET THE FLAG
TYPE <\> ;SIGNAL END OF BACKSPACE
RET
CAFLDE: SKIPN CEDUMB ;DUMB TERMINAL?
RET ;YES, RETURN
SKIPN CADLFG ;WERE WE IN A DELETE?
RET ;NO
SETZM CADLFG ;RESET FLAG
TYPE <\\> ;SIGNAL END OF DELETE
RET
CABAKF: SKIPN CEDUMB
RET
SKIPN CABKFG ;SET?
ETYPE <\> ;NO, SIGNAL
SETOM CABKFG ;SET BACKSPACE FLAG
RET
CADELF: SKIPN CEDUMB
RET
SKIPN CADLFG ;SET?
ETYPE <\\> ;NO, SIGNAL
SETOM CADLFG ;SET DELETE FLAG
RET
; VMS MODE BEGINS HERE
;Here to dispatch given the uppercase character in B
VMSDSP: MOVE D,A ;SAVE REAL CHAR
SETZ C, ;INIT THE INDEX
VMSDS0: CAIGE C,VMSCLN ;DONE ?
IFSKP.
MOVE A,D ;GET REAL CHARACTER BACK
CAIL A," " ;SOME OTHER CONTROL CHARACTER?
JRST SEDINS ;INSERT THIS CHARACTER
CALL CEBELL ;YES - NO MATCH, RING THE BELL
RET ;TRY AGAIN
ENDIF.
LDB A,[POINT 7,VMSCTB(C),17] ;GET THE CHARACTER
CAME A,B ;GOT A MATCH ?
AOJA C,VMSDS0 ;BUMP INDEX AND LOOP
HRRZ B,VMSCTB(C) ;GET DISPATCH ADDRESS
CALL (B) ;AND GO THERE
RET
VMSCTB: .CHCRT,,CEEXIT ;^M - EXIT AND DO EDITED COMMAND
.CHCNA,,CINMOD ;^A - TOGGLE INSERT MODE
.CHCNB,,CEUP ;^B - PREVIOUS COMMAND
.CHCND,,CELEFT ;^D - LEFT
.CHCNF,,CERIGH ;^F - RIGHT
.CHCNE,,CEMEND ;^E - END OF LINE
.CHBSP,,CEBEGN ;^H - BEGINNING OF LINE
.CHTAB,,CINSRT ;^I - ALWAYS INSERT A TAB
.CHLFD,,METARB ;^J - PREVIOUS WORD DELETE
.CHCNC,,CEQUIT ;^C - ABORT
.CHCNU,,VMSBBW ;^U - BACK TO BEGINNING OF WORD
.CHCUN,,CVHELP ;^_ - HELP MESSAGE
.CHCNR,,CEDISP ;^R - REDISPLAY LINE
.CHCNO,,CRTLV ;^V - TAKE NEXT CHAR LITERALLY
.CHESC,,VMSESC ;ESCAPE - GET NEXT FEW CHARACTERS
.CHDEL,,CERUB ;DEL - DELETE CHAR AT LEFT OF CURSOR
VMSCLN==.-VMSCTB
;Here to delete from beginning of line to cursor
VMSBBW: PUSH P,CEBPTR ;SAVE CURRENT POINTER
CALL CEBEGN ;GO TO BEGINNING OF LINE
POP P,B ;GET BACK THE POINTER
MOVE A,CEBPTR ;DESTINATION IS BEGINNING OF BUFFER
SETZ C, ;COPY UNTIL END OF STRING
CALL ASOUT
MOVE A,CEBPTR
PSOUT
CALL EEOLN ;CLEAR OLD EOL
JRST CINST1
VMSESC: CALL ECEINC ;GET NEXT CHARACTER
CAIN B,"[" ;GOT A BRACKET
JRST BRAKET ;YES - HANDLE IT
MOVEI A,.PRIIN
CFIBF ;CLEAR THE INPUT BUFFER
CALL CEBELL ;NO, RING THE BELL
RET
; SED MODE BEGINS HERE
;Here to pick up a command character for SED mode
SEDINP: STKVAR <ECHR,CVECHR,CEMODW>
MOVEI A,.CTTRM ;ALLOW 8 BIT INPUT
RFMOD ;GET THE MODE WORD
MOVEM B,CEMODW ;SAVE IT
TXZ B,TT%DAM ;BINARY MODE
SFMOD
HRROI A,[BYTE (7) 33,"=",33,"<",0] ;SET TERMINAL TO APPLICATIONS MODE
PSOUT
PBIN ;GET A CHAR
CALL ACEIN1 ;MAKE BOTH REAL CHARACTER AND UPPERCASE
MOVEM B,CVECHR ;SAVE CONVERTED CHAR
MOVEM A,ECHR ;SAVE REAL CHAR
MOVE B,CEMODW ;RESTORE MODE WORD
MOVEI A,.CTTRM
SFMOD
MOVE A,ECHR ;GET BACK THE CHARS
MOVE B,CVECHR
RET
;Here to reset some things on exiting the editor
VTEXIT: HRROI A,[BYTE (7) 33,">",0] ;NO APPLICATIONS KEYPAD MODE
CALL CECCOC
SETZM SVSEDP ;CLEAR THE POINTER
SETZM INSMOD ;CLEAR INSERT MODE
RET
;Here to dispatch given the uppercase character in B
SEDDSP: MOVE D,A ;SAVE REAL CHAR
SETZ C, ;INIT THE INDEX
SEDDS0: CAIGE C,SEDCLN ;DONE ?
IFSKP.
MOVE A,D ;GET REAL CHARACTER BACK
CAIL A," " ;SOME OTHER CONTROL CHARACTER?
JRST SEDINS ;INSERT THIS CHARACTER
CALL CEBELL ;YES - NO MATCH, RING THE BELL
RET ;TRY AGAIN
ENDIF.
LDB A,[POINT 7,SEDCTB(C),17] ;GET THE CHARACTER
CAME A,B ;GOT A MATCH ?
AOJA C,SEDDS0 ;BUMP INDEX AND LOOP
HLRZ A,SEDCTB(C) ;GET FLAGS WORD
TRNE A,SD%RST ;NEED RESET 1ST ?
CALL SDRST1 ;YES
HRRZ A,SEDCTB(C) ;GET DISPATCH ADDRESS
CALL (A) ;AND GO THERE
RET
;Here to determine whether overstrike mode or insert mode
SEDINS: SKIPE INSMOD ;IN OVERSTRIKE MODE ?
IFSKP.
CALL OVRSTK ;YES
ELSE.
CALL CINSRT ;NO - IN INSERT MODE
ENDIF.
RET
SD%RST==400000 ;RESET "ENTER PARAM" BEFORE COMMAND XCTION
SEDCTB: .CHCRT!SD%RST,,CEEXIT ;^M - EXIT AND DO EDITED COMMAND
.CHBSP,,SEDRST ;BACKSPACE - RESET
.CHLFD!SD%RST,,CEKILL ;LINEFEED - KILL TO END OF LINE
.CHBEL,,SEDPUT ;^G - OUTPUT PICK BUFFER
.CHCNV,,SEDPCK ;^V - PICK
.CHVTB,,SDINSP ;^K - INSERT CHARACTER
.CHCNW!SD%RST,,CEUP ;^W - EDIT PREVIOUS COMMAND
.CHCNC!SD%RST,,CEQUIT ;^C - ABORT
.CHDEL!SD%RST,,CERUB ;RUBOUT - DELETE CHAR AT LEFT OF CURSOR
.CHFFD,,SEDKSP ;^L - DELETE CHARACTER AT CURSOR
.CHCNF,,SEDKIL ;^F - KILL TO END OF LINE
.CHCNU,,METAB ;^U - BACK TO BEGINNING OF WORD
.CHCUN,,CSHELP ;^_ - HELP MESSAGE
.CHCNR,,CEDISP ;^R - REDISPLAY LINE
.CHTAB,,NXTWRD ;TAB - FORWARD TO NEXT WORD
.CHCNO!SD%RST,,CRTLV ;^O - TAKE NEXT CHAR LITERALLY
.CHCNX!SD%RST,,CETRAN ;^X - TRANSPOSE CHARACTER
.CHESC,,ESCDSP ;ESCAPE - GET NEXT FEW CHARACTERS
SEDCLN==.-SEDCTB
ESCCTB: "[",,BRAKET ;LEFT SQUARE BRACKET
"O",,KEYP.O ;"O"
ESCCLN==.-ESCCTB
BRKCTB: "A"!SD%RST,,CEUP ;<ESC>[A - PREVIOUS COMMAND
"B"!SD%RST,,CEDOWN ;<ESC>[B - NEXT LINE
"C",,CERIGH ;<ESC>[C - CURSOR RIGHT
"D",,CELEFT ;<ESC>[D - CURSOR LEFT
BRKCLN==.-BRKCTB
KPOCTB: "P",,SEDENT ;ESCAPE O P == ENTER PARAMETER
"M",,CINMOD ;ESCAPE O M == INSERT-MODE
"A"!SD%RST,,CEUP ;ESCAPE O A == PREVIOUS LINE
"B"!SD%RST,,CEDOWN ;ESCAPE O B == NEXT LINE
"C",,CERIGH ;ESCAPE O C == RIGHT
"D",,CELEFT ;ESCAPE O D == LEFT
;These next few commands are normally lowercase (we converted them)
"T",,CEBEGN ;ESCAPE O T == START-OF-LINE
"V",,CEMEND ;ESCAPE O V == END-OF-LINE
"N"!SD%RST,,METARB ;ESCAPE O N == ERASE-WORD
"P"!SD%RST,,CETABI ;ESCAPE O P == REAL-TAB
"U",,CEDISP ;ESCAPE O U == REDISPLAY LINE
"S",,CSHELP ;ESCAPE O S == HELP
KPOCLN==.-KPOCTB
;Here to check for movement of the cursor as a parameter
CHKMOV: SETZ P3,
SKIPN B,SVSEDP ;GET SAVED PARAMETER POINTER
RET ;NONE - NO MOVEMENT
MOVE A,CEBPTR ;GET CURRENT POINTER
CALL SUBBP ;GET THE DIFFERENCE IN THE 2 POINTERS
MOVE P3,A ;GET COUNT IN RIGHT AC
JUMPE P3,CHKMV1 ;NO MOVEMENT ?
SKIPL P3 ;GOING FORWARDS ?
IFSKP.
MOVNS P3 ;THE COUNT BECOMES POSITIVE
MOVE A,CEBPTR ;EXCHANGE THE SAVED AND THE NEW POINTERS
EXCH A,SVSEDP
MOVEM A,CEBPTR
MOVE A,CECPOS ;EXCHANGE THE COUNTS
EXCH A,SVSEDC
MOVEM A,CECPOS
ENDIF.
RET
CHKMV1: CALL SDRST1 ;RESET PARAMETER
SETO P3, ;FLAG IT
RET
;Here to kill line/characters
SEDKIL: CALL CHKMOV ;CHECK MOVEMENT
JUMPL P3,SDRDSP ;GO REDISPLAY CHARACTER (NO REVERSE VIDEO)
JUMPE P3,SDKILL ;IF ZERO, KILL REST OF LINE
SETO P2, ;SAVE THE KILL TEXT
SDKIL0: STKVAR <SVCP>
MOVE A,CEBPTR ;GET CURRENT POINTER
MOVEM A,SVCP ;SAVE IT FOR LATER
CALL SEDUPD ;UPDATE CURSOR POSITION BEFORE DOING CMD
SKIPE P2 ;SAVE THE TEXT ?
CALL SEDSVK ;YES - SAVE TEXT THATS BEING KILLED
MOVE A,SVCP ;GET THE POINTER TO END OF KILL
PSOUT ;TYPE IT OUT
MOVE A,CEBPTR ;GET DESTINATION (BEGINNING OF KILL)
MOVE B,SVCP ;GET SOURCE IS END OF KILL
SETZ C, ;COPY UNTIL END OF STRING
CALL ASOUT
CALL EEOLN ;CLEAR OLD EOL
CALL SDRST1
JRST CINST1
;Here to delete space(s)
SEDKSP: CALL CHKMOV ;CHECK MOVEMENT
JUMPL P3,SDRDSP ;GO REDISPLAY CHARACTER (NO REVERSE VIDEO)
JUMPE P3,CERMSP ;ONLY DO ONE ? YES - JUST DO DELETE CHAR
SETZ P2, ;DO NOT SAVE TEXT BEFORE KILLING
JRST SDKIL0 ;GO KILL THE TEXT
;Here to save the text going into the kill buffer
; On return B/ updated CEBPTR
SEDSVK: MOVEI C,CEKBLN*5
CAML C,P3 ;IF STRING IS TO LONG, TRUNCATE IT
MOVE C,P3 ;IF STRING IS SHORT ENOUGH USE P3
MOVE A,[POINT 7,CEKBUF] ;POINT TO KILL BUFFER
MOVE B,CEBPTR ;ANY TO WHAT WE ARE KILLING
SETZ D,
SOUT
SETZ C, ;CHOP OFF THE REST OF THE STRING
IDPB C,A ;ADD A NULL TO THE END OF THE KILL BUFFER
RET
SDKILL: MOVEI P3,7777 ;GET BIG NUMBER OF BYTES
CALL SEDSVK ;SAVE TEXT THATS BEING KILLED
MOVE B,CEBPTR ;GET COPY OF POINTER
SETZ A,
SDKIL1: ILDB D,B ;GET THIS BYTE
JUMPE D,SDKIL2 ;DONE ON NULL
DPB A,B ;CURSOR IS ONE POSITION PAST POINTER
JRST SDKIL1 ;ONWARD
SDKIL2: CALL SDRST1 ;RESET PARAMETER
JRST EEOLN ;CLEAR TO EOL
;Here to insert spaces
SDINSP: CALL CHKMOV ;CHECK MOVEMENT
JUMPL P3,SDRDSP ;GO REDISPLAY CHARACTER (NO REVERSE VIDEO)
SKIPN P3
SKIPA P3,[1] ;IF ZERO, MAKE IT 1
CALL SEDUPD ;UPDATE CURSOR POSITION BEFORE DOING CMD
MOVE A,CEBPTR
CALL BUFFS ;LINE FROM CURRENT POS
MOVE B,A ;SAVE BUFFERED STRING
MOVE D,P3 ;GET THE COUNT
MOVE A,CEBPTR
MOVEI C,40 ;GET A SPACE
SDIS1: IDPB C,A ;DEPOSIT A SPACE
SOJG D,SDIS1 ;GO AROUND FOR ANOTHER
SETZ C, ;STOP ON NULL (A&B ALREADY SET UP)
CALL ASOUT ;MOVE REST OF STRING TO AFTER SPACES
MOVE A,CEBPTR ;GET CURRENT POINTER AGAIN
PSOUT ;TYPE THE LINE FROM CURRENT POS
CALL CINST1 ;GO TYPE CORRECT POS
JRST SDRST1
;Here to handle a pick
SEDPCK: CALL CHKMOV ;CHECK FOR MOVEMENT
JUMPL P3,SDRDSP ;GO REDISPLAY CHARACTER (NO REVERSE VIDEO)
CALL SEDUPD ;UPDATE CURSOR POSITION TO SAVED POS
SKIPN P3 ;ZERO ?
MOVEI P3,7777 ;YES - MAKE IT A BIG NUMBER
MOVE C,[POINT 7,CEPBUF] ;SAVE IN THE PUT BUFFER
MOVE D,CEBPTR
SDPK1: ILDB B,D ;GET A CHARACTER
IDPB B,C ;PUT IT IN THE PUT BUFFER
JUMPE B,SDPK2 ;DONE ON NULL
SOJG P3,SDPK1 ;GO AROUND FOR ANOTHER
SDPK2: SETZ B, ;DEPOSIT A NULL AT THE END
IDPB B,C
JRST SDRST1 ;ALL DONE
;Here to handle a PUT
SEDPUT: CALL CHKMOV ;CHECK FOR MOVEMENT
JUMPL P3,SDYANK ;GO HANDLE UNDELETE LINE
JUMPN P3,SDPERR ;PARAMETER EXCEPT NULL LOSES
MOVE A,[POINT 7,CEPBUF] ;GET POINTER TO PUT BUFFER
CALL BCOUNT ;GET NUMBER OF CHARACTERS IN THERE
MOVEM B,CEKBC ;SAVE IT
JUMPE B,SDNPUT ;NO PUT BUFFER
MOVE A,CEBPTR ;GET BUFFER POINTER
CALL BUFFS ;SAVE THE END OF THE LINE
MOVE B,A ;SAVE POINTER
MOVE A,CEKBC ;GET COUNT
ADJBP A,CEBPTR ;MAKE ROOM FOR THE KILLED TEXT
SETZ C, ;END ON A ZERO BYTE
CALL ASOUT ;MOVE END OF LINE OVER
MOVE A,CEBPTR ;GET POINTER TO HOLE
MOVE B,[POINT 7,CEPBUF] ;AND TO PUT BUFFER
SDPUT1: ILDB C,B ;GET NEXT BYTE
SKIPN C ;AT THE END?
JRST SDPUT2 ;YES
IDPB C,A ;NO, STORE IT
JRST SDPUT1 ;DO THE REST
SDPUT2: MOVE A,CEBPTR ;GET POINTER TO REST OF STRING
PSOUT ;UPDATE SCREEN
CALL CINST1 ;POSITION THE CURSOR
JRST SDRST1 ;ALL DONE
SDPERR: MOVEI A,.PRIIN
CFIBF ;CLEAR THE INPUT BUFFER
CALL CEBELL
TYPE <
?No parameters excepted for PUT at this time>
JRST CEDISP ;GO REDISPLAY THE LINE
SDYANK: CALL SDRST1 ;RESET ENTER PARAMETER
MOVE A,[POINT 7,CEKBUF] ;GET POINTER TO KILL BUFFER
ILDB B,A ;GET 1ST CHARACTER IN IT
JUMPN B,CEYANK ;IF NON-ZERO, THEN GOT KILL BUFFER
MOVEI A,.PRIIN
CFIBF ;CLEAR THE INPUT BUFFER
CALL CEBELL
TYPE <
?CLOSE buffer is empty>
JRST CEDISP ;GO REDISPLAY THE LINE
SDNPUT: CALL SDRST1 ;RESET ENTER PARAMETER
MOVEI A,.PRIIN
CFIBF ;CLEAR THE INPUT BUFFER
CALL CEBELL
TYPE <
?PUT buffer is empty>
JRST CEDISP ;GO REDISPLAY THE LINE
;Here to handle ENTER
SEDENT: MOVE A,CECPOS ;GET CHAR POS
MOVEM A,SVSEDC ;SAVE IT
MOVE A,CEBPTR ;GET THE CURRENT POINTER
MOVEM A,SVSEDP ;SAVE SED PARAMETER POINTER
ILDB D,A ;GET THE CHARACTER AT THE CURSOR
SETOM RVVFLG ;NEXT CHARACTER IS REVERSE VIDEO
RET
;Here to hi-lite the next character with reverse video
HILITE: SAVEAC <A,B,C,D>
MOVE D,A
SETZM RVVFLG ;CLEAR THE REVERSE VIDEO FLAG
HRROI A,[BYTE (7) 33,"[","7","m",0] ;REVERSE VIDEO
CALL CECCOC
MOVE A,D
PBOUT
HRROI A,[BYTE (7) 33,"[","0","m",0] ;NO REVERSE VIDEO ANYMORE
CALL CECCOC
RET
;Here to get rid of reversed video character
SDRDSP: CALL SEDUPD
RET
;Update cursor position before doing cmd
SEDUPD: MOVE A,SVSEDP ;GET OLD POINTER AND UPDATE TO CURRENT
MOVEM A,CEBPTR
MOVE A,SVSEDC ;GET OLD POS AND UPDATE TO CURRENT
MOVEM A,CECPOS
CALL CINST1 ;UPDATE CUROSR POS
RET
;Here to reset entering parameters
SEDRST: CALL SEDUPD ;UPDATE CURSOR POSITION
SDRST1: SETZM RVVFLG
SETZM SVSEDC ;CLEAR THE POS
SETZM SVSEDP ;CLEAR THE POINTER
RET
ESCDSP: CALL SEDINP ;GET NEXT CHARACTER
SETZ C, ;INIT THE INDEX
ESCDS0: CAIGE C,ESCCLN ;DONE ?
IFSKP.
CALL CEBELL ;YES - NO MATCH, RING THE BELL
RET ;TRY AGAIN
ENDIF.
LDB A,[POINT 7,ESCCTB(C),17] ;GET THE CHARACTER
CAME A,B ;GOT A MATCH ?
AOJA C,ESCDS0 ;BUMP INDEX AND LOOP
HLRZ A,ESCCTB(C) ;GET FLAGS WORD
TRNE A,SD%RST ;NEED RESET 1ST ?
CALL SDRST1 ;YES
HRRZ A,ESCCTB(C) ;GET DISPATCH ADDRESS
CALL (A) ;AND GO THERE
RET
KEYP.O: CALL SEDINP ;GET NEXT CHARACTER
SETZ C, ;INIT THE INDEX
KPODS0: CAIGE C,KPOCLN ;DONE ?
IFSKP.
CALL CEBELL ;YES - NO MATCH, RING THE BELL
RET ;TRY AGAIN
ENDIF.
LDB A,[POINT 7,KPOCTB(C),17] ;GET THE CHARACTER
CAME A,B ;GOT A MATCH ?
AOJA C,KPODS0 ;BUMP INDEX AND LOOP
HLRZ A,KPOCTB(C) ;GET FLAGS WORD
TRNE A,SD%RST ;NEED RESET 1ST ?
CALL SDRST1 ;YES
HRRZ A,KPOCTB(C) ;GET DISPATCH ADDRESS
CALL (A) ;AND GO THERE
RET
BRAKET: CALL SEDINP ;GET NEXT CHARACTER
SETZ C, ;INIT THE INDEX
BRKDS0: CAIGE C,BRKCLN ;DONE ?
IFSKP.
CALL CEBELL ;YES - NO MATCH, RING THE BELL
RET ;TRY AGAIN
ENDIF.
LDB A,[POINT 7,BRKCTB(C),17] ;GET THE CHARACTER
CAME A,B ;GOT A MATCH ?
AOJA C,BRKDS0 ;BUMP INDEX AND LOOP
HLRZ A,BRKCTB(C) ;GET FLAGS WORD
TRNE A,SD%RST ;NEED RESET 1ST ?
CALL SDRST1 ;YES
HRRZ A,BRKCTB(C) ;GET DISPATCH ADDRESS
CALL (A) ;AND GO THERE
RET
CETABI: MOVEI A,.CHTAB ;INSERT A REAL TAB
JRST CINSRT
CEINSP: MOVEI A," " ;INSERT A SPACE
JRST CINSRT
CINMOD: SETCMM INSMOD ;TOGGLE INSERT MODE/OVERSTRIKE MODE
RET
; HERE TO MOVE TO THE BEGINNING OF THE NEXT WORD
NXTWRD: CALL WRDSKP ;GET DESTINATION
ADDM B,CECPOS ;UPDATE POSITION
JUMPE B,CEINC ;NO MOVEMENT, STOP
MOVE C,B ;NUMBER OF CHARACTERS TO MOVE
ADJBP B,CEBPTR ;UPDATE POINTER
PUSH P,B ;SAVE IT
SKIPN RVVFLG ;REVERSE VIDEO THIS CHARACTER ?
IFSKP.
ILDB A,CEBPTR ;YES - GET POINTER
CALL HILITE
SOS C ;ONE LESS TO OUTPUT
ENDIF.
MOVE B,CEBPTR ;START OF WHAT WE WANT TO TYPE
MOVE A,COJFN ;PRIMARY OUTPUT
SOUT ;PRINT OVER ONE WORD
POP P,CEBPTR ;UPDATE POINTER
RET
; SUBROUTINE TO RETURN NUMBER OF SPACES UNTIL START OF NEXT WORD
; UNLIKE F.WORD, IT WILL SKIP OVER SPACES, TABS, AND CERTAIN DELIMITERS
WRDSKP: SETZ B, ;INITIALIZE COUNT
MOVE C,CEBPTR ;GET LOCAL COPY OF POINTER
WDSKP0: ILDB A,C ;GET THIS CHARACTER
AOS B ;UPDATE COUNT
JUMPE A,[RET] ;END OF LINE, QUIT
CALL CHKCHR ;CHECK THE CHAR
JRST WDSKP0 ;CHARACTER IS PART OF WORD
WDSKP1: ILDB A,C ;AT DELIMITER, GET NEXT CHARACTER
AOS B ;UPDATE COUNT
JUMPE A,[RET] ;END OF LINE
CALL CHKCHR ;CHECK THE CHAR
SOJA B,R ;AT BEGINNING OF NEW WORD
JRST WDSKP1 ;STILL IN DELIMITER
;CHECK THE CHARACTER
CHKCHR: CAIL A,"0"
CAILE A,"9"
SKIPA
RET
CAIL A,"A"
CAILE A,"Z"
SKIPA
RET
CAIL A,"a"
CAILE A,"z"
SKIPA
RET
RETSKP
; EMACS MODE BEGINS HERE
;Here to pick up a command character for emacs mode
ECEINC: STKVAR <CETYP,ECHR,CVECHR,CEMODW>
MOVEM D,CETYP ;SAVE EDITOR TYPE
MOVEI A,.CTTRM ;ALLOW 8 BIT INPUT
RFMOD ;GET THE MODE WORD
MOVEM B,CEMODW ;SAVE IT
TXZ B,TT%DAM ;BINARY MODE
SFMOD
PBIN ;GET CHARACTER
CALL ACEIN1 ;MAKE BOTH REAL CHARACTER AND UPPERCASE
MOVEM B,CVECHR ;SAVE CONVERTED CHAR
MOVEM A,ECHR ;SAVE REAL CHAR
MOVE B,CEMODW ;RESTORE MODE WORD
MOVEI A,.CTTRM
SFMOD
MOVE A,ECHR ;GET BACK THE CHARS
MOVE B,CVECHR
RET
;Here to dispatch given the uppercase character in B
ECEDSP: CALL ECDISP
RET
ECDISP: STKVAR <ECHR>
MOVEM A,ECHR
SKIPN CEMETA ;META KEY IN USE?
TRZ B,200 ;NO, TRIM PARITY BIT
MOVEI A,METAN1 ;SETUP IN CASE OF META KEY
TRZE B,200 ;META KEY USED?
RET ;YES - SPECIAL DISPATCH
SETZ C, ;INIT THE INDEX
ECEDS0: CAIGE C,EMCCLN ;DONE ?
IFSKP.
MOVE A,ECHR ;GET ACTUAL CHARACTER BACK
CAIL A," " ;SOME OTHER CONTROL CHARACTER?
JRST CINSRT ;INSERT THIS CHARACTER
CALL CEBELL ;YES - NO MATCH, RING THE BELL
RET ;TRY AGAIN
ENDIF.
HLRZ A,EMCCTB(C) ;GET CHARACTER
CAME A,B ;GOT A MATCH ?
AOJA C,ECEDS0 ;BUMP INDEX AND LOOP
HRRZ B,EMCCTB(C) ;GET DISPATCH ADDRESS
CALL (B) ;GO THERE, CHARACTER IN A
RET
EMCCTB: CR,,CEEXIT ;^M - EXIT AND DO EDITED COMMAND
.CHCNP,,CEUP ;^P - EDIT PREVIOUS COMMAND
.CHBEL,,CEQUIT ;^G - ABORT
.CHCNC,,CEQUIT ;^C - ABORT
.CHDEL,,CERUB ;RUBOUT - DELETE CHAR AT LEFT OF CURSOR
.CHCNB,,CELEFT ;^B - CURSOR LEFT
.CHCNF,,CERIGH ;^F - CURSOR RIGHT
.CHCNN,,CEDOWN ;^N - CURSOR DOWN
.CHCND,,CERMSP ;^D - DELETE CHARACTER AT CURSOR
.CHCNE,,CEMEND ;^E - MOVE TO END OF LINE
.CHCNA,,CEBEGN ;^A - MOVE TO BEGINNING OF LINE
.CHVTB,,CEKILL ;^K - KILL TO END OF LINE
.CHCNT,,CETRAN ;^T - TRANSPOSE CHARACTERS
.CHCNW,,METARB ;^W - SAME AS M-RUB
.CHCNY,,CEYANK ;^Y - YANK KILL BUFFER
.CHCUN,,CEHELP ;^_ - HELP MESSAGE
.CHFFD,,CEDISP ;^L - REDISPLAY LINE
.CHCNR,,CEDISP ;^R - REDISPLAY LINE
.CHTAB,,CINSRT ;TAB - INSERT WITHOUT V
.CHESC,,METAIN ;<ESC> - META PREFIX
; .CHCNQ,,CRTLV ;^Q - TAKE NEXT CHAR LITERALLY
.CHCNV,,CRTLV ;^V - TAKE NEXT CHAR LITERALLY
EMCCLN==.-EMCCTB
CRTLV: PBIN ;GET THE CHARACTER
JRST CINSRT ;PROCESS IT
; AN ESCAPE HAS BEEN ENTERED, GET THE NEXT COMMAND CHARACTER
METAIN: PBIN ;GET THE NEXT WORD
METAN1: CAIE A,"F" ;M-F - FORWARD TO END OF WORD
CAIN A,"f"
JRST METAF
CAIE A,"B" ;M-B - BACK TO BEGINNING OF WORD
CAIN A,"b"
JRST METAB
CAIE A,"D" ;M-D - DELETE TO END OF WORD
CAIN A,"d"
JRST METAD
CAIN A,.CHDEL ;M-RUB - DELETE BACK TO START OF WORD
JRST METARB
CAIN A,.CHESC ;M-ESC - STUFF COMMAND WITH <ESC>
JRST METAES
CAIN A,"?" ;M-? - STUFF COMMAND WITH ?
JRST METAQU
CAIN A,"[" ;BRACKET ?
JRST METESC ;YES - ALLOW
METAN2: MOVEI A,.PRIIN
CFIBF ;CLEAR THE INPUT BUFFER
CALL CEBELL ;ERROR, RING BELL
RET ;TRY AGAIN
METESC: MOVE A,COJFN ;GET TERMINAL TYPE
GTTYP
CAIN B,.TT100 ;VT100 ?
JRST BRAKET ;YES - OKAY TO USE ARROW KEYS
CAIN B,.TT102 ;VT102 ?
JRST BRAKET ;YES - OKAY TO USE ARROW KEYS
CAIN B,.TT125 ;VT125 ?
JRST BRAKET ;YES - OKAY TO USE ARROW KEYS
CAIN B,.TT131 ;VT131 ?
JRST BRAKET ;YES - OKAY TO USE ARROW KEYS
CAIN B,.TTK10 ;GIGI ?
JRST BRAKET ;YES - OKAY TO USE ARROW KEYS
CAIN B,.TTH19 ;H19 ?
JRST BRAKET ;YES - OKAY TO USE ARROW KEYS
JRST METAN2 ;NO ARROW KEY ALLOWED
;Here on overstrike mode for insert character
OVRSTK: MOVE C,CEBPTR ;GET THE POINTER
OVR1: HRRZ B,C ;GET ADDRESS FIELD OF THE POINTER
CAIGE B,CETSAV+CETBLN-1 ;ABOUT TO OVERFLOW THE BUFFER?
IFSKP.
CALL CEBELL ;YES, RING BELL
JRST CINST1 ;AND DON'T ACCEPT MORE INPUT
ENDIF.
ILDB B,C ;GET ONE THAT WAS THERE
DPB A,C ;REPLACE IT
SKIPE B ;WAS OLD ONE NULL ?
IFSKP.
MOVE D,C ;DON'T INCREMENT CURRENT POINTER
IDPB B,D ;MAKE SURE THE NEXT BYTE IS ALSO NULL
ENDIF.
JUMPE A,CINST0 ;EXIT AFTER A NULL BYTE
PBOUT ;OUTPUT IT
MOVE A,C ;GET CURRENT BYTE POINTER NOW
PSOUT ;OUTPUT REST OF STRING
MOVEM C,CEBPTR ;UPDATE POINTER
AOS A,CECPOS ;UPDATE POSITION
JRST CINST1 ;GO UPDATE CURSOR
; HERE TO INSERT A CHARACTER INTO THE COMMAND LINE
CINSRT: MOVE C,CEBPTR ;GET THE POINTER
CINST: HRRZ B,C ;GET ADDRESS FIELD OF THE POINTER
CAIGE B,CETSAV+CETBLN-1 ;ABOUT TO OVERFLOW THE BUFFER?
IFSKP.
CALL CEBELL ;YES, RING BELL
JRST CINST1 ;AND DON'T ACCEPT MORE INPUT
ENDIF.
ILDB B,C ;GET ONE THAT WAS THERE
DPB A,C ;REPLACE IT
JUMPE A,CINST0 ;EXIT AFTER A NULL BYTE
PBOUT ;OUTPUT IT
MOVE A,B ;SET UP TO REINSERT THE ONE
JRST CINST
CINST0: AOS A,CECPOS ;UPDATE EVERYTHING
IBP CEBPTR
CINST1: MOVE B,CEBPTR ;SEE WHAT WE'RE SUPPOSED TO POINT TO
ILDB A,B ;IF WE'RE SUPPOSED TO BE AT THE END
JUMPE A,R ; OF THE LINE, WE'RE ALREADY THERE
ETYPES<TION THE CURSOR
CALL CENUMB ;MOVE PAST THE LINE NUMBER
MOVE A,COJFN ;POINT TO THE TERMINAL
HRROI B,CETSAV ;POINT TO THE STRING
MOVN C,CECPOS ;GET COUNT
SKIPE C ;DON'T GO FOREVER HERE
SOUT ;MOVE PAST THE OLD CHARACTERS
RET
; MOVE THE CURSOR TO THE LEFT
CELEFT: SKIPN CECPOS ;AT BEGINNING OF BUFFER?
RET ;YES, DO NOTHING
LDB C,CEBPTR ;GET CHARACTER WE ARE GOING TO
SETO B,
ADJBP B,CEBPTR ;DECR BYTE PTR
MOVEM B,CEBPTR
SOS CECPOS ;DECR CHARACTER POSITION
CAIGE C," " ;SOME CONTROL CHARACTER?
JRST CINST1 ;YES, DON'T MESS UP
CALL CEBACK ;BACK UP
RET
; ERASE LAST CHARACTER
CERUB: SKIPN CECPOS ;AT BEGINNING OF BUFFER?
RET ;YES, DON'T DO ANYTHING
MOVE A,CEBPTR ;GET POINTER
ILDB C,A ;SEE IF WE ARE AT END OF LINE
SETO A, ;GET A -1
ADJBP A,CEBPTR ;DECREMENT THE BYTE POINTER
MOVEM A,CEBPTR ;SAVE IT
SOS CECPOS ;AND DECREMENT CHARACTER POSITION
JUMPN C,CERMSP ;IF NOT AT END OF LINE, RETYPE WHOLE THING
ILDB B,A ;GET CHARACTER WE'RE DELETING
CAIL B," " ;ARE WE DELETING A CONTROL CHARACTER
IFSKP. ;YES...
CAIE B,.CHESC ;AND NOT ESCAPE (SINGLE CHARACTER)
CALL CEBACK ;YES, WE HAVE TO BACK UP OVER TWO CHARS
ENDIF. ;
CALL CEBACK ;BACK UP SOME
JRST CEKILL ;AND KILL REST OF LINE
; MOVE THE CURSOR TO THE END OF THE LINE
CEMEND: MOVE B,CEBPTR ;SEE IF WE'RE POINTING AT ZERO BYTE
ILDB A,B
JUMPE A,CEMND1 ;AT END OF LINE, QUIT
AOS CECPOS
PBOUT ;MOVE OVER
JRST CEMEND+1
CEMND1: MOVNI C,1
ADJBP C,B
MOVEM C,CEBPTR ;MAKE BYTE POINTER AGREE WITH CURSOR
RET
; MOVE THE CURSOR TO THE RIGHT
CERIGH: MOVE B,CEBPTR ;SEE IF WE'RE POINTING AT ZERO BYTE
ILDB A,B
JUMPE A,CEINC ;AT END OF BUFFER, DO NOTHING
SKIPE RVVFLG ;REVERSE VIDEO THIS CHARACTER ?
IFSKP.
PBOUT ;NO - MOVE OVER
ELSE.
CALL HILITE ;YES
ENDIF.
AOS CECPOS ;INCR CHARACTER POSITION
IBP CEBPTR ;INCREMENT POINTER
RET
; MOVE TO THE NEXT COMMAND LINE
CEDOWN: HRRZ A,@CELPTR ;TAKE THE RIGHT HAND LINK
SKIPN A ;CHECK FOR END OF LIST
JRST CEDWN1 ;NOT AT END, SKIP THIS
SOS CELPOS ;DECREMENT THE LINE NUMBER
MOVEM A,CELPTR ;UPDATE POINTER
JRST CETOP ;PROCESS THIS LINE
CEDWN1: MOVE A,CE1ST ;END OF LIST, GO BACK TO THE FIRST LINE
MOVEM A,CELPTR ;RESET THE POINTER
MOVE A,CECNT ;GET RIGHT LINE NUMBER
SOS A
MOVEM A,CELPOS ;SET IT
JRST CETOP ;PROCESS THIS LINE
; MOVE TO THE PREVIOUS COMMAND LINE
CEUP: HLRZ A,@CELPTR ;TAKE THE LEFT HAND LINK
SKIPN A ;CHECK FOR END OF LIST
JRST CEUP1 ;NOT AT END
AOS CELPOS ;INCREMENT THE LINE NUMBER
MOVEM A,CELPTR ;UPDATE POINTER
JRST CETOP ;PROCESS THIS LINE
CEUP1: MOVE A,CELAST ;END OF LIST, GO BACK TO THE FIRST LINE
MOVEM A,CELPTR ;RESET THE POINTER
SETZM CELPOS ;RESET LINE NUMBER
JRST CETOP ;PROCESS THIS LINE
; HERE TO DELETE THE CHARACTER AT THE CURSOR
CERMSP: MOVE B,CEBPTR ;GET DESTINATION POINTER
MOVEI A,1
ADJBP A,CEBPTR ;POINTER TO SOURCE
LDB C,A ;ZERO BYTE?
JUMPE C,R ;YES, QUIT
SETZ C, ;NO, MOVE THE TEXT
SIN
ETYPEA<T OVER
CALL CENUMB ;WRITE THE LINE NUMBER
HRROI A,CETSAV ;AND THE LINE
PSOUT
CALL EEOLN
JRST CINST1 ;POSITION THE CURSOR
; HERE TO MOVE THE CURSOR TO THE BEGINNING OF THE LINE
CEBEGN: MOVEI A,CETSAV ;FIX POINTER
HLL A,[POINT 7,0]
MOVEM A,CEBPTR
SETZM CECPOS ;RESET POINTER TO BEGINNING OF LINE
ETYPEV< CURSOR TO BEGINNING
CALL CENUMB ;WRITE THE LINE NUMBER
RET
; HERE TO KILL EVERYTHING TO THE RIGHT OF THE CURSOR
CEKILL: MOVE A,[POINT 7,CEKBUF] ;POINT TO KILL BUFFER
MOVE B,CEBPTR ;ANY TO WHAT WE ARE KILLING
MOVEI C,CEKBLN*5 ;BUT ONLY SAVE 80 CHARS AT MOST
SETZ D, ;AND ON ZERO BYTE
SOUT ;SAVE IT
SETZ A, ;CHOP OFF THE REST OF THE STRING
IDPB A,B ;ADD A NULL TO THE END OF THE KILL BUFFER
MOVE B,CEBPTR ;GET COPY OF POINTER
IDPB A,B ;CURSOR IS ONE POSITION PAST POINTER
CALL EEOLN ;ERRASE IT FROM THE SCREEN
RET
; HERE TO YANK THE KILL BUFFER
CEYANK: MOVE A,[POINT 7,CEKBUF] ;GET POINTER TO KILL BUFFER
CALL BCOUNT ;GET NUMBER OF CHARACTERS IN THERE
MOVEM B,CEKBC ;SAVE IT
MOVE A,CEBPTR ;GET BUFFER POINTER
CALL BUFFS ;SAVE THE END OF THE LINE
MOVE B,A ;SAVE POINTER
MOVE A,CEKBC ;GET COUNT
ADJBP A,CEBPTR ;MAKE ROOM FOR THE KILLED TEXT
SETZ C, ;END ON A ZERO BYTE
CALL ASOUT ;MOVE END OF LINE OVER
MOVE A,CEBPTR ;GET POINTER TO HOLE
MOVE B,[POINT 7,CEKBUF] ;AND TO KILLED TEXT
CEYNK1: ILDB C,B ;GET NEXT BYTE
SKIPN C ;AT THE END?
JRST CEYNK2 ;YES
IDPB C,A ;NO, STORE IT
JRST CEYNK1 ;DO THE REST
CEYNK2: MOVE B,CEBPTR ;GET POINTER TO REST OF STRING
MOVE A,COJFN ;PRIMARY OUTPUT
SOUT ;UPDATE SCREEN
ERJMP KABOOM ;ABORT IF SOUT FAILS
MOVE A,CEKBC ;GET LENGTH OF ADDED TEXT
ADDM A,CECPOS ;UPDATE POSITION
ADJBP A,CEBPTR ;MOVE TO END OF UNKILLED TEXT
MOVEM A,CEBPTR ;SAVE UPDATED POINTER
JRST CINST1 ;POSITION THE CURSOR
; HERE TO SWAP THE CHARACTER AT THE CURSOR AND THE ONE BEFORE IT
CETRAN: SKIPN CECPOS ;BEGINNING OF LINE?
RET ;YES, SKIP
MOVE B,CEBPTR
ILDB A,B ;END OF LINE?
JUMPE A,CEINC
MOVE B,CEBPTR ;GET LOCAL POINTER
MOVEI A,1 ;SCOOT OVER ONE
ADJBP A,B
LDB C,A ;CHANGE THE CHARACTERS IN THE BUFFER
LDB D,B
DPB D,A
DPB C,B
ETYPEW<ITE THE LINE
CALL CENUMB
HRROI A,CETSAV
PSOUT
JRST CINST1 ;POSITION CURSOR
; HERE TO MOVE TO THE BEGINNING OF THE NEXT WORD
METAF: CALL F.WORD ;GET DESTINATION
ADDM B,CECPOS ;UPDATE POSITION
JUMPE B,CEINC ;NO MOVEMENT, STOP
MOVE C,B ;NUMBER OF CHARACTERS TO MOVE
ADJBP B,CEBPTR ;UPDATE POINTER
PUSH P,B ;SAVE IT
MOVE B,CEBPTR ;START OF WHAT WE WANT TO TYPE
MOVE A,COJFN ;PRIMARY OUTPUT
SOUT ;PRINT OVER ONE WORD
POP P,CEBPTR ;UPDATE POINTER
JRST CINST1 ;MOVE CURSOR OVER
; HERE TO MOVE TO THE BEGINNING OF THE PREVIOUS WORD
METAB: CALL B.WORD ;GET DESTINATION
JUMPE B,CEINC ;SKIP IF NO MOVEMENT
MOVNS B ;MAKE IT NEGATIVE
MOVE C,B ;GET A COPY OF IT
ADJBP C,CEBPTR ;UPDATE THE POINTER
MOVEM C,CEBPTR
ADDM B,CECPOS ;UPDATE POSITION
JRST CINST1 ;UPDATE CURSOR
METAB1: PUSH P,B ;SAVE NUMBER OF CHARACTERS TO BACK UP
CALL CEBACK ;BACK UP ONE
POP P,B ;GET COUNT BACK
AOJN B,METAB1 ;DECREMENT COUNT
RET ;POSITION CURSOR
; HERE TO DELETE UP TO THE BEGINNING OF THE NEXT WORD
METAD: CALL F.WORD ;GET DESTINATION
MOVE A,B ;GET COPY OF OFFSET
ADJBP A,CEBPTR ;POINTER TO DESTINATION
JRST M.FIX ;MOVE EVERYTHING
; HERE TO DELETE BACK TO THE BEGINNING OF THE PREVIOUS (OR THIS) WORD
METARB: SKIPN CECPOS ;Beginning of line?
RET ;YES, AN ERROR...GET THE NEXT COMMAND
MOVE A,CEBPTR ;GET POINTER
ILDB B,A ;AT THE END OF THE LINE?
PUSH P,B ;SAVE LAST CHARACTER
CALL B.WORD ;GET DESTINATION
MOVN D,B ;MAKE IT NEGATIVE
MOVE A,D
ADDM A,CECPOS ;FIX UP POSITION
ADJBP A,CEBPTR ;GET DESTINATION POINTER
EXCH A,CEBPTR ;FOOL M.FIX - WE ARE NOW A M-D
POP P,B ;GET CHAR WE SAVED
METAR1: JUMPE D,METAR2 ;NEED TO MOVE THE CURSOR OVER
PUSH P,A ;SAVE THE POINTER
CALL CEBACK ;BACK UP
POP P,A ;RESTORE THE POINTER
AOJA D,METAR1
METAR2: JUMPE B,CEKILL ;IF WE'RE AT EOL, JUST KILL IT
; HERE TO FIX THINGS UP AFTER METAD, METARB, OR ALTER MODE DELETE
M.FIX: PUSH P,A ;A HAS END OF WORD TO STUFF IN KILL BUFFER
MOVE B,CEBPTR ;B HAS START OF IT
MOVE D,[POINT 7,CEKBUF] ;POINT TO KILL BUFFER
CAMN A,B ;DOING ANYTHING?
JRST M.FIX3 ;NO, DON'T LOOP FOREVER
M.FIX2: ILDB C,B ;GET A CHARACTER OF DELETED STRING
IDPB C,D ;SAVE IT IN THE KILL BUFFER
CAME A,B ;SAVED ALL OF THE WORD YET?
JRST M.FIX2 ;NO, DO NEXT CHARACTER
SETZ C, ;GET A NULL BYTE
IDPB C,D ;TIE OFF THE KILL BUFFER
M.FIX3: POP P,B ;GET COPY OF DESTINATION POINTER
SKIPN CEDUMB ;EMACS OR SMART ALTER?
PSOUT ;YES, OVERWRITE THE SCREEN
CALL EEOLN ;CLEAN THINGS UP
MOVE A,CEBPTR ;GET CURRENT POINTER
M.FIX1: ILDB C,B ;GET FIRST CHARACTER
IDPB C,A ;SAVE IN NEW POSITION
JUMPN C,M.FIX1 ;DONE?
JRST CINST1 ;POSITION THE CURSOR
; SUBROUTINE TO RETURN NUMBER OF SPACES UNTIL START OF NEXT WORD
F.WORD: SETZ B, ;INITIALIZE COUNT
MOVE C,CEBPTR ;GET LOCAL COPY OF POINTER
ILDB A,C ;GET THIS CHARACTER
JUMPE A,[RET] ;END OF LINE, QUIT
CAIL A,"0"
CAILE A,"9"
SKIPA
JRST F.WRD2
CAIL A,"A"
CAILE A,"Z"
SKIPA
JRST F.WRD2
CAIL A,"a"
CAILE A,"z"
SKIPA
JRST F.WRD2
F.WRD1: ILDB A,C ;GET NEXT CHARACTER
AOS B ;UPDATE COUNT
JUMPE A,[RET] ;END OF LINE
CAIL A,"0"
CAILE A,"9"
SKIPA
JRST F.WRD2
CAIL A,"A"
CAILE A,"Z"
SKIPA
JRST F.WRD2
CAIL A,"a"
CAILE A,"z"
SKIPA
JRST F.WRD2
F.WRD2: ILDB A,C ;GET NEXT CHARACTER
AOS B ;INCREMENT COUNT
JUMPE A,[RET] ;END OF LINE
CAIL A,"0"
CAILE A,"9"
SKIPA
JRST F.WRD2
CAIL A,"A"
CAILE A,"Z"
SKIPA
JRST F.WRD2
CAIL A,"a"
CAILE A,"z"
SKIPA
JRST F.WRD2
RET ;YES, DONE.
; SUBROUTINE TO RETURN NUMBER OF SPACES UNTIL START OF PREVIOUS WORD
B.WORD: SETZ B, ;INITIALIZE COUNT
MOVE C,CEBPTR ;GET LOCAL COPY OF POINTER
MOVE D,CECPOS ;LOCAL COPY OF POSITION
JUMPE D,[RET] ;BEGINNING OF LINE, EXIT
ILDB A,C ;GET THIS CHARACTER
CAIL A,"0"
CAILE A,"9"
SKIPA
JRST B.WRD0
CAIL A,"A"
CAILE A,"Z"
SKIPA
JRST B.WRD0
CAIL A,"a"
CAILE A,"z"
SKIPA
JRST B.WRD0
JRST B.WRD1 ;NO, IN THE MIDDLE OF A WORD
B.WRD0: LDB A,CEBPTR ;GET WORD BEFORE THIS ONE
CAIL A,"0"
CAILE A,"9"
SKIPA
JRST B.WRD2
CAIL A,"A"
CAILE A,"Z"
SKIPA
JRST B.WRD2
CAIL A,"a"
CAILE A,"z"
SKIPA
JRST B.WRD2
; CONTINUED ON NEXT PAGE
B.WRD1: SETO A, ;BACKUP THE POINTER
ADJBP A,C
MOVE C,A
LDB A,C ;GET NEXT ONE
SOS D ;UPDATE COUNT
AOS B ;UPDATE THIS TOO
JUMPE D,[RET] ;CHECK FOR BEGINNING OF LINE
CAIL A,"0"
CAILE A,"9"
SKIPA
JRST B.WRD2
CAIL A,"A"
CAILE A,"Z"
SKIPA
JRST B.WRD2
CAIL A,"a"
CAILE A,"z"
SKIPA
JRST B.WRD2
JRST B.WRD1
B.WRD2: SETO A, ;BACKUP THE POINTER
ADJBP A,C
MOVE C,A
LDB A,C ;GET NEXT CHARACTER
SOS D ;UPDATE EVERYTHING
AOS B
JUMPE D,[RET] ;CHECK FOR BEGINNING OF LINE
CAIL A,"0"
CAILE A,"9"
SKIPA
JRST B.WRD2
CAIL A,"A"
CAILE A,"Z"
SKIPA
JRST B.WRD2
CAIL A,"a"
CAILE A,"z"
SKIPA
JRST B.WRD2
SOS B ;ADJUST IF NOT BEGINNING OF LINE
RET ;ALL DONE
; HERE TO STICK AN ESCAPE OR QUESTION MARK ON THE END OF THE COMMAND
METAES: SKIPA B,[.CHESC] ;STUFF ESCAPE WITH THE COMMAND
METAQU: MOVEI B,"?" ;STUFF ? WITH THE COMMAND
METAEQ: ILDB A,CEBPTR ;LOOK FOR THE END OF THE LINE
JUMPE A,METEQ1
JRST METAEQ ;TRY AGAIN
METEQ1: MOVEI C,.CHCNR ;PUT A ^R IN FIRST SO EVERYTHING
DPB C,CEBPTR ;IS ECHOED BY FIELD
IDPB B,CEBPTR ;NOW STUFF THE NEW CHARACTER
IDPB A,CEBPTR ;ADD A ZERO BYTE
JRST CEEX2
; HERE WHEN BUFFER ABOUT TO OVERFLOW. QUIT, INSTEAD OF MUNGING EXEC.
KABOOM: MOVEI A,.PRIIN
CFIBF ;CLEAR THE INPUT BUFFER
CALL CEBELL ;GONG!
TYPE <
?Buffer overflow, aborting command edit>
JRST CEQUIT ;ABORT EDIT
; WHEN DONE, PASS THE EDITED COMMAND TO THE EXEC TO USE.
; NOTE THAT FOR A NORMAL RETURN (I.E. JUST CR) WE CAN'T JUST STUFF A ^R
; AT THE END OF THE BUFFER AND LET FIELD DO ALL THE DIRTY WORK OF ECHOING
; THE COMMAND, BECAUSE THERE IS NO WAY TO MAKE IT PRINT OUT A CARRIAGE RETURN
; AT THE END!!! SIGH, THUS THIS HACK...
CEEXIT: ILDB A,CEBPTR ;FIRST FIND LAST CHARACTER IN LINE
JUMPN A,CEEXIT
SETO A,
ADJBP A,CEBPTR ;POINT TO LAST CHARACTER
LDB B,A
CAIN B,.CHESC ;IS THE LAST CHAR AN ESCAPE?
JRST [ MOVEM A,CEBPTR ;IF SO, THEN USE METAES TO EXIT
SETZ A, ;PUT A NULL IN A
JRST METEQ1 ]
SETOM NOPRMT ;DON'T PRINT PROMPT WHEN RSCANING BUFFER
HRROI A,CETSAV ;GET THE COMMAND WE'RE GOING TO EXECUTE
MOVEI B,LF ;PUT A LF AT THE END OF THE BUFFER
DPB B,CEBPTR
SETZ A, ;AND A NULL
IDPB A,CEBPTR
CEEX2: MOVEI A,.CTTRM
CFIBF ;CLEAR THE INPUT BUFFER
MOVE A,[POINT 7,CETSAV] ;POINT TO EDITED COMMAND
RSCAN ;PUT STUFF IN RSCAN BUFFER
ERJMP CEEX3
MOVEI A,.RSINI ;NOW GIVE TO THE EXEC TO USE
RSCAN
ERJMP CEEX3
CALL QUITR ;GO CLEAN UP
ETYPE <
>
RET
CEEX3: ETYPE <?RSCAN failure when trying to execute the new command>
SKIPA
CEQUIT: ETYPE <%_[Aborting]>
CALL QUITR ;DO THE CLEAN UP WORK
MOVEI B,CR
STI
ERJMP [ERROR <STI failure when trying to execute the new command>]
SETZM CEBPTR ;MAKE SURE THE NEXT COMMAND IS SAVED
RET
QUITR: MOVE Q1,CEFLAG
CAIN Q1,M.SED ;EDITOR IS SED ?
CALL VTEXIT ;YES - CLEAR APP KEYPAD MODE
MOVEI Q1,ETTYMD ;LOAD EXEC TTY MODES
CALL LTTYMD
MOVEI A,.CTTRM
MOVE B,CETTMD ;RESTORE MODE WORD
STPAR
SFMOD
MOVEI B,.MOXOF
SKIPE C,CEPEOP ;GET OLD SETTING OF PAUSE @ EOP
MTOPR ;AND SET IT
SETOM CEEOC ;SET EXITING FLAG
SETZM CEBPTR ;SAVE THIS COMMAND
RET
;BEGIN ADDITION - MAKE SURE TTY GETS FIXED UP ON ERROR
CEERET: MOVEI Q1, RERET ;PUT DEFAULT CLEANUP ROUTINE ADDRESS BACK
MOVEM Q1, CERET
MOVEI Q1, ETTYMD ;NORMAL EXEC TTY MODES
CALL LTTYMD ;FIX UP THE TTY
MOVEI A,.CTTRM ;RESTORE OLD STPAR PARAMETERS TOO
MOVE B,CETTMD ;GET JFN MODE WORD BACK
STPAR ;PUT BACK THE CORRECT MODES
JRST @CERET ;NOW GO DO DEFAULT CLEANUP
; ROUTINE TO REDISPLAY THE LINE
CEDISP: TYPE <
> ;GO TO A NEW LINE
CALL EEOLN ;JUST TO BE SURE
CALL CENUMB ;DO THE LINE NUMBER
HRROI A,CETSAV ;POINT TO COMMAND LINE
PSOUT ;WRITE IT OUT
JRST CINST1 ;POSITION THE CURSOR
;Routine to send a bell to the terminal
CEBELL: HRROI A,[BYTE (7) .CHBEL,0] ;SEND THE BELL
CALL CECCOC
RET
;Routine to set CCOC words, output a string, then reset the CCOC words
CECCOC: STKVAR <SVSTG,<SVCCOC,2>>
MOVEM A,SVSTG ;SAVE STRING POINTER
MOVE A,COJFN ;REDO THE CCOC
RFCOC
DMOVEM B,SVCCOC ;SAVE MODE
MOVE B,[525252,,525252] ;SEND ACTUAL CODE
MOVE C,B
SFCOC
MOVE B,SVSTG ;GET STRING POINTER BACK
SETZ C,
SOUT ;OUTPUT IT
DMOVE B,SVCCOC
SFCOC ;RESTORE MODE
RET
; ROUTINE TO BACK THE CURSOR UP ONE PLACE
CEBACK: MOVE A,COJFN ;GET THE TERMINAL TYPE
RFMOD ;GET MODE WORD
PUSH P,B ;SAVE IT
TXZ B,TT%DAM ;NO TRANSLATION
SFMOD
GTTYP
HRROI A,[ASCIZ //] ;ASSUME NORMAL TERMINAL
CAIE B,^D16 ;GET THE VT100 TYPES OUT OF THE WAY
CAIN B,^D33
HRROI A,[ASCIZ /[D/]
CAIE B,^D40
CAIN B,^D41
HRROI A,[ASCIZ /[D/] ;VT200
CAIN B,^D37 ;VT102
HRROI A,[ASCIZ /[D/]
CAIN B,^D27 ;BEEHIVES
HRROI A,[ASCIZ /D/]
CAIN B,^D44 ;DATAPOINTS
HRROI A,[ASCIZ //]
PSOUT
MOVE A,COJFN ;RESTORE MODE WORD
POP P,B ;GET OLD MODE
SFMOD ;DO IT
RET
; ROUTINE TO ERRASE ALL CHARACTERS TO THE END OF LINE
EEOLN: PUSH P,A ;SAVE THIS
PUSH P,B ;THIS TOO
MOVE A,COJFN ;CURRENT OUTPUT JFN
RFMOD ;GET MODE WORD
PUSH P,B ;SAVE IT
TXZ B,TT%DAM ;NO TRANSLATION
SFMOD
GTTYP ;GET TERMINAL TYPE
CAIG B,EOLNMX ;ALL WE KNOW ABOUT NOW
SKIPN A,EEOLTB(B) ;GET STRING TO DUMP
JRST EEOLN2 ;NONE - DO NOTHING
TLNN A,-1 ;STRING OR PNTR?
TLOA A,-1 ;PNTR TO TEXT
HRROI A,EEOLTB(B) ;STRING - POINT TO IT INSTEAD
PSOUT ;DUMP IT
EEOLN2: MOVE A,COJFN ;RESTORE MODE WORD
POP P,B ;GET OLD MODE
SFMOD ;DO IT
POP P,B ;RESTORE THIS
POP P,A ;THIS TOO
RET
; ERASE TO END OF LINE TABLE
EEOLTB: 0 ;0
0 ;1
0 ;2
0 ;3
0 ;4
0 ;5
0 ;6
0 ;7
0 ;8
0 ;9
BYTE (7)36,0 ;10 VT05
BYTE (7).CHESC,"K",0 ;11 VT50
0 ;12 LA30
0 ;13 GT40
0 ;14 LA36
BYTE (7) .CHESC,"K",0 ;15 VT52
BYTE(7).CHESC,"[","K",0 ;16 VT100
0 ;17 LA38
0 ;18 LA120
0 ;19
0 ;20
0 ;21
0 ;22
0 ;23
0 ;24
0 ;25
0 ;26
0 ;27
0 ;28
0 ;29
0 ;30
0 ;31
0 ;32
0 ;33
0 ;34
BYTE(7).CHESC,"[","K",0 ;35 VT125
BYTE(7).CHESC,"[","K",0 ;36 GIGI
BYTE(7).CHESC,"[","K",0 ;(37) VT102
BYTE(7).CHESC,"[","K",0 ;(38) H19
BYTE(7).CHESC,"[","K",0 ;(39) VT131
BYTE(7).CHESC,"[","K",0 ;(40) VT200
REPEAT ^D10,<0> ;(41-50) (RESERVED FOR CUSTOMER)
REPEAT ^D10,<0> ;(51-60) (RESERVED FOR DIGITAL)
EOLNMX== .-EEOLTB-1
;ROUTINE TO TYPE A HELP MESSAGE WITH EDITORS
CSHELP: HRROI B,[ASCIZ/HLP:EXEC-SED-KEYS.HLP/]
CALL CEDHLP
JRST CEDISP
CEHELP: HRROI B,[ASCIZ/HLP:EXEC-EMACS-KEYS.HLP/]
CALL CEDHLP
JRST CEDISP
CVHELP: HRROI B,[ASCIZ/HLP:EXEC-VMS-KEYS.HLP/]
CALL CEDHLP
JRST CEDISP
CAHELP: HRROI B,[ASCIZ/HLP:EXEC-ALTER-KEYS.HLP/]
CALL CEDHLP
JRST CETOP
CEDHLP: PUSH P,B
CALL BLANK1 ;CLEAR THE SCREEN
POP P,B
MOVX A,GJ%OLD+GJ%SHT+GJ%IFG ;OLD FILE ONLY, SHORT FORM
CALL GTJFS ;GET HANDLE ON HELP FILE
ERROR <No help available, the help file was not found.>
MOVEI Q1,CP%HEL ;SO "TYPE" LOGIC WILL KNOW IT'S US
MOVE A,JBUFP ;GET POINTER TO JFN CELL
HRRZM A,INIFH1
HRRZM A,INIFH2 ;COPY CODE NEEDS THIS
CALL TYPE1 ;FINISH COMMAND BY COPYING HELP FILE TO TERMINAL
RET
; COMMAND EDIT INTERRUPT ROUTINE
.CEPSI::SKIPN CLF ;AT COMMAND LEVEL?
DEBRK ;NO, DON'T DO THIS
SKIPE .P ;DO WE HAVE A SAVED STACK POINTER?
MOVE P,.P ;YES, RESTORE IT
CALL RLJFNS ;RELEASE PARSED JFN'S
MOVE A,[POINT 7,CBUF] ;LOOK AT THE COMMAND BUFFER
ILDB B,A ;GET THE NEXT CHARACTER
JUMPN B,.-1 ;KEEP LOOKING FOR A NULL
SETO C, ;FOUND IT
ADJBP C,A ;BACK UP ONE CHARACTER
MOVEI A,.PRIIN ;LOOK AT THE TERMINAL
SIBE ;ANYTHING THERE?
JRST [ MOVE A,C ;YES, ADD IT TO THE BUFFER
MOVE B,[RD%RIE+^D80]
SETZ C, ;NO PROMPT, QUIT WHEN TTY BUFFER IS EMPTY
RDTTY ;GET IT
ETYPE <%_%%Can not find rest of command, Continuing>
IDPB C,A ;ASCIZ THE STRING
JRST .+1 ] ;READY TO GO NOW
CALL CSAVE ;SAVE THE COMMAND IN PROGRESS
JFCL ;IGNORE THE ERROR
CALL CEPSI1 ;GO DO THE WORK
MOVE A,LEV1PC ;GET THE RETURN ADDRESS
HRRI A,CMDIN4 ;CHANGE IT
TXO A,PC%USR ;RETURN TO USER CODE
MOVEM A,LEV1PC ;RESTORE FIXED PC
DEBRK ;PARSE EDITED COMMAND
CEPSI1: CESTG ;ASSURE CONSISTENT TRVAR
SETZM CEDSEA ;INITIALIZE STUFF
CALL CEDITU ;GO TO THE EDITOR
RET
; "SET INTERRUPT-CHARACTER (FOR COMMAND EDITOR TO) CHAR" COMMAND
.SCEIC::NOISE (for command editor to)
STKVAR <ICHAR> ;CHARACTER TO INTERRUPT ON
MOVEI B,CEICLS ;POINT TO THE LIST
CALL FLDSKP ;GET THE CHARACTER
JRST [ ETYPE <%@?Character not available%_>
RET ]
HRRZ C,1(C) ;POINT TO THE STRING
LDB B,[POINT 7,(C),13] ;GET THE CHARACTER
TXZ B,1B29!1B30 ;MAKE IT A CONTROL CHARACTER
MOVEM B,ICHAR ;SAVE IT
NOISE (for command editor)
CONFIRM ;CONFIRM THE COMMAND
SKIPL A,CEPSIC ;GET THE OLD CHARACTER
DTI ;IF ONE WAS ASSIGNED THEN DEASSIGN IT
HRLZ A,ICHAR ;GET THE NEW ONE
HLRZM A,CEPSIC ;SAVE IT
HRRI A,CEDCHN ;SET THINGS UP ;CS4 use a symbol
ATI ;ASSIGN NEW INTERRUPT CHARACTER
RET ;DONE
.SNCEI::NOISE (for command editor)
CONFIRM ;COMFIRM "SET NO INTERRUPT-CHARACTER"
SKIPGE A,CEPSIC ;DO WE HAVE ONE?
RET ;NO, QUIT
DTI ;WE HAD ONE, DEASSIGN IT
SETOM CEPSIC ;SAY WE DON'T HAVE ONE
RET ;DONE
; COMMAND EDIT INTERRUPT CHARACTER LIST
CEICLS: FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^@.]>,,,Z1
Z1:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^A.]>,,,Z2
Z2:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^a.]>,,,Z3
Z3:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^B.]>,,,Z4
Z4:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^b.]>,,,Z5
Z5:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^D.]>,,,Z6
Z6:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^d.]>,,,Z7
Z7:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^G.]>,,,Z8
Z8:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^g.]>,,,Z9
Z9:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^K.]>,,,Z10
Z10:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^k.]>,,,Z11
Z11:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^N.]>,,,Z12
Z12:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^n.]>,,,Z13
Z13:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^P.]>,,,Z14
Z14:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^p.]>,,,Z15
Z15:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^Q.]>,,,Z16
Z16:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^q.]>,,,Z17
Z17:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^S.]>,,,Z18
Z18:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^s.]>,,,Z19
Z19:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^X.]>,,,Z20
Z20:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^x.]>,,,Z21
Z21:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^Y.]>,,,Z22
Z22:! FLDDB. .CMTOK,CM%SDH,<POINT 7,[ASCIZ .^y.]>,<Control character
(typed as a two-character sequence)>
.META:: NOISE <EXISTS ON TERMINAL>
CONFIRM
SETOM CEMETA
RET
.NOMET::NOISE <EXISTS ON TERMINAL>
CONFIRM
SETZM CEMETA
RET
.CESET::KEYWD $CESET ;POINT AT TABLE
0
JRST CERR
HRRZS P3 ;ONLY GET THE DISPATCH ADDRESS
JRST (P3) ;GO THERE
$CESET: TABLE
T HISTORY,,.SEHST ;SET EDIT HISTORY n (COMMAND EDITOR)
T INTERRUPT-CHARACTER,,.SCEIC ;SET INTERRUPT (COMMAND EDITOR)
T MODE,,.CEDMO ;SET EDIT MODE (COMMAND EDITOR)
TEND
;HERE FOR INFORMATION ABOUT COMMAND EDITOR
INFOCE::TYPE < SET EDIT MODE >
MOVE A,CEFLAG
CAIN A,M.EMCS ;EMACS MODE ?
TYPE <EMACS-STYLE-COMMANDS>
CAIN A,M.SED
TYPE <SED-STYLE-COMMANDS>
CAIN A,M.EDIT
TYPE <ALTER-STYLE-COMMANDS>
CAIN A,M.VMS
TYPE <VMS-STYLE-COMMANDS>
TYPE <
>
TYPE < SET > ; REPORT THE INTERRUPT STUFF
SKIPL A, CEPSIC ; ANY INTERRUPT CHARACTER SET?
IFSKP. ; NO,
TYPE <NO EDIT INTERRUPT-CHARACTER (FOR COMMAND EDITOR)
>
RET ; SAY SO, AND RETURN
ENDIF.
TYPE <EDIT INTERRUPT-CHARACTER (TO) ^>
ADDI A, 100 ; MAKE IT A REAL CHARACTER
PBOUT% ; AND OUTPUT IT
TYPE < (FOR COMMAND EDITOR)
>
RET
;THIS TELLS WHETHER TERMINAL META-KEY ENABLED - FOR "INFORMATION (ABOUT) TERMINAL"
IMETKY::MOVE A, TERMNL ; THIS TERMINAL?
CAIN A, .CTTRM ; IF NOT, SKIP THIS
SKIPN CEMETA ; META KEY ENABLED?
IFSKP.
TYPE < TERMINAL META-KEY
>
ENDIF.
RET ; ALL DONE
;"SET COMMAND-EDIT-MODE" , USED BY COMMAND EDITOR
.CEDMO::NOISE <TO>
KEYWD $CEDIT ;POINT AT EDITOR TABLE
0
JRST CERR
HRRZS P3 ;GET RID OF LEFT HALF
MOVEM P3,CEFLAG ;SET MODE
CAIN P3,M.VMS ;VMS MODE ?
JRST VMSDEF ;YES - ALLOW A DEFAULT MODE
RET
M.EMCS==0 ;EMACS MODE
M.EDIT==1 ;EDIT/SOS/ALTER MODE
M.SED==2 ;SED MODE
M.VMS==3 ;VMS MODE
$CEDIT: TABLE
T ALTER-STYLE-COMMANDS,ONEWRD,M.EDIT
T EMACS-STYLE-COMMANDS,ONEWRD,M.EMCS
T SED-STYLE-COMMANDS,ONEWRD,M.SED
T VMS-STYLE-COMMANDS,,M.VMS
TEND
;Dispatch table for selected editor type. Order is based on M.xxxx values
EDISP: XWD ECEINC,ECEDSP ;EMACS
XWD ACEINP,ACEDSP ;EDIT/SOS STYLE MODE
XWD SEDINP,SEDDSP ;SED MODE (USE SAME INPUT ROUTINE AS EMACS)
XWD ECEINC,VMSDSP ;VMS MODE (USE SAME INPUT ROUTINE AS EMACS)
CEDSPL==.-CEDISP
;HERE TO SET DEFAULT VMS INSERT/OVERSTRIKE MODE
VMSDEF: NOISE (WITH)
KEYWD $INSOV ;POINT AT MODE TABLE
T INSERT,ONEWRD,INSON ;DEFAULT IS INSERT MODE
JRST CERR
HRRZS P3 ;ONLY GET THE DISPATCH ADDRESS
JRST (P3) ;GO THERE
$INSOV: TABLE
T INSERT,ONEWRD,INSON ;DEFAULT IS INSERT MODE
T OVERSTRIKE,ONEWRD,OVRON ;OVERSTRIKE MODE
TEND
INSON: SETOM CEVMSD ;INSERT MODE
RET
OVRON: SETZM CEVMSD ;OVERSTRIKE MODE
RET
;HERE FOR SETTING UP COMMAND HISTORY
.SEHST::SKIPE SETNOF ; WAs "NO" SPECIFIED?
JRST .SEHS1 ; YES
DECX <Decimal number of commands to remember> ; GET NUMBER
CMERRX ; BAD INPUT
CAIG B, HSTMAX ; LARGER THAN MAX ALLOWED?
JUMPG B, .SEHS2 ; INPUT IS oK
MOVEI A, HSTMAX+1 ; GET MAX NUMBER
ETYPE <?Number must be larger than zero but smaller than %1Q>
RET
.SEHS1: SETZ B, ; SET NO HISTORY
.SEHS2: CONFIRM ; GET EOL
PUSH P, B ; SAVE NEW VALUE
SKIPN A, HSTCNT ; DO WE HAVE ANYTHING NOW?
JRST .SEHS4 ; NO, SO JUST GO ALLOCATE ANEW
MOVEM A, HSTNUM ; SAVE THIS NUMBER FOR LATER
.SEHS3: HLRZ C, HSTPTR ; GET ADDRESS OF PTR BLOCK
ADD C, HSTCNT ; LOOK AT EACH STRING
SUBI C, 1 ; BASE 0. OFFSET CORRECTLY
SKIPE A, (C) ; GET POINTER TO COMMAND STRING
CALL STREM ;RETURN IF NOT NULL
SOSE HSTCNT ; WORK UP THE LIST
JRST .SEHS3 ; UNTIL IT IS EXHAUSTED
MOVE A, HSTNUM ; GET NUMBER OF WORDS TO RETURN
HLRZ B, HSTPTR ; ADDRESS OF POINTER BLOCK
CALL RETBUF ; RETURN IT
.SEHS4: POP P, A ; GET NEW COUNT BACK
MOVEM A, HSTCNT ; AND SAVE IT
SKIPN A ; DON'T CALL ALLOCATION ROUTINE
JRST R ; SKIP THIS
CALL GTBUFX ; IF NON-ZERO, GET PERMANENT SPACE
HRLZM A, HSTPTR ; SAVE ADDRESS OF POINTER BLOCK
ADD A, HSTCNT ; POINT TO LAST ENTRY
HRRM A, HSTPTR ; AND SAVE IT
MOVN A, HSTCNT ; GET NUMBER OF WORDS TO CLEAR
HRLZS A ; MOVE TO LEFT HALF
HLR A, HSTPTR ; GET BASE ADDRESS BACK
SETZM (A) ; CLEAR ALL WORDS TO ZERO
AOBJN A, .-1 ; UNTIL DONE
SETZM HSTNUM ; ALWAYS RESET COMMAND COUNT
RET ; AND RETURN
;HERE TO SAVE THE COMMANDS FOR COMMAND HISTORY
CMDHST::CALL CSAVE ; SAVE COMMAND FOR COMMAND EDITOR
SKIPA ; COULDN'T - DON'T DO THIS, EITHER
SKIPN HSTCNT ; DOING HISTORY?
RET ; NO, SKIP THIS
LDB A, [POINT 7,CBUF,6] ; GET FIRST CHARACTER IN COMMAND BUFFER
AOS HSTNUM ; BUMP COMMAND COUNTER
HRROI A, CBUF ; GET POINTER TO COMMAND INPUT
CALL XBUFFS ; COPY IT TO PRV. PERMANENT FREE SPACE
HRRZ B, HSTPTR ; LOOK AT CURRENT SLOT
HLRZ C, HSTPTR ; GET BASE SLOT
ADD C, HSTCNT ; POINT ONE PLACE PAST
CAML B, C ; PAST END?
HLR B, HSTPTR ; GET ADDRESS OF BASE, THEN
HRRM B, HSTPTR ; AND SAVE IT
EXCH A, (B) ; SAVE POINTER TO COMMAND
SKIPE A ; ANYTHING THERE?
CALL STREM ; YES, RETURN IT
HRRZ B, HSTPTR ; GET BACK POINTER TO NEW COMMAND
MOVE A, (B) ; GET BYTE POINTER TO COMMAND
AOS HSTPTR ; POINT TO NEXT EMPTY SLOT
FDHST1: ILDB C,A ; GET A BYTE
JUMPE C, R ; FOUND NULL BEFORE CRLF - FINE.
CAIE C,.CHCRT ; LOOK FOR CR
CAIN D, .CHLFD ; OR A LF
CAIA ;
JRST FDHST1 ; TRY AGAIN
SETO C, ; BACK UP OVER IT
ADJBP C,A ;
SETZ A, ; AND DEPOSIT A NULL
IDPB A,C ; ON TOP OF IT
RET
; INFORMATION HISTORY
.INHST::MOVE A,HSTCNT ; GET NUMBER KEEPING
JUMPE A,[ERROR<No history>] ; SAY ERROR
ETYPE < History: %1Q%%_> ; OUTPUT IT
MOVNS A ; MAKE IT NEGATIVE
MOVSS A ; MOVE COUNT TO LH
HRR A,HSTPTR ; GET ADDRESS OF NEXT EMPTY SLOT
MOVE D,HSTNUM ; GET COMMAND COUNT
SUB D,HSTCNT ; SUBTRACT DISPLAY NUMBER
SKIPGE D ; IF NEGATIVE, MAKE ZERO
SETZ D, ;
.INHS1: HLRZ B,HSTPTR ; GET BASE ADDRESS OF BLOCK
ADD B,HSTCNT ; FIND END OF BLOCK
HRRZ C,A ; GET CURRENT PTR
CAML C,B ; PAST LAST SLOT?
HLR A,HSTPTR ; GET BASE ADDRESS THEN
SKIPN C,(A) ; GET A PTR
JRST .INHS2 ; CHECK NEXT ONE
AOS D ; INCR COMMAND COUNT
ETYPE < [%4Q] %3M%%_> ; OUTPUT COMMAND
.INHS2: AOBJN A,.INHS1 ; CDR THROUGH LIST
RET ; THEN RETURN
;HERE TO DO HISTORY COMMANDS
.REDO::PUSH P,[CMDIN4] ;FAKE RETURN ADDRESS
SKIPN HSTCNT ;ANY COMMANDS?
ERROR <No history> ;
MOVE A,P ;SAVE STACK PTR
TRVAR <COMNUM,SAVEP>
MOVEM A,SAVEP ;SO WE KNOW WHERE RETURN ADDR IS
MOVEI B,[FLDDB. .CMNUM,CM%SDH,5+5,<Decimal command number>,,[
FLDDB. .CMQST,CM%SDH,,<Quoted imbedded string>,,[
FLDBK. .CMFLD,,,<Command string>,,FLDMSK,]]]
CALL FLDSKP ;TRY TO PARSE THAT
CMERRX ;ERROR OR SOMETHING
LDB D,[331100,,(C)] ;GET FUNCTION CODE
CAIN D,.CMNUM ;GO HANDLE COMMAND NUMBER
JRST .DOHSN ;IF NUMBER ENTERED
CAIN D,.CMFLD ;WAS IT A FIELD
JRST .DOHSF ;GO EAT IT UP THEN
JRST .DOHSQ ;GO HANDLE QUOTED STRING
;HERE TO HANDLE COMMAND NUMBER
.DOHSN: MOVE A,B ;SAVE COMMAND NUMBER
.DOHN1: JUMPL A,[AOS A ;IF NEGATIVE, RELATIVE NUMBER
ADD A,HSTNUM ;MAKE IT ABSOLUTE
JRST .+1] ;AND CONTINUE
MOVE B,HSTNUM ;GET CURRENT COMMAND NUMBER
SUB B,HSTCNT ;GET SMALLEST COMMAND WE HAVE
SKIPGE B ;IF NEGATIVE, MAKE ONE
SETZ B, ;STILL HAVE THIS ONE THEN
AOS B ;BASE 1
CAMG A,HSTNUM ;SMALLER THAN LARGEST WE HAVE
CAMGE A,B ;AND LARGER THAN SMALLEST WE HAVE
ERROR <Command not found> ;TELL HIM WHY
SOS A ;BASE 0 THE COUNT
IDIV A,HSTCNT ;DIVIDE BY NUMBER OF COMMANDS
HLRZ A,HSTPTR ;GET BASE ADDRESS
ADD A,B ;GET PROPER OFFSET
MOVEM A,COMNUM ;SAVE COMMAND ADDRESS
JRST .DOHS2 ;GO PARSE FOR ARGS.
;HERE FOR AGAIN COMMAND
.AGAIN::PUSH P,[CMDIN4] ;FAKE RETURN ADDRESS
SKIPN HSTCNT ;ANY COMMANDS?
ERROR <No history> ;]
MOVE A,P ;SAVE STACK PTR
TRVAR <COMNUM,SAVEP>
MOVEM A,SAVEP ;SO WE KNOW WHERE RETURN ADDR IS
MOVE A,HSTNUM ;GET CURRENT COMMAND NUMBER
JRST .DOHN1 ;CALCULATE COMMAND ADDRESS
;HERE TO HANDLE STRING FIELD
.DOHSF: CALL DOHFCM ;LOOK UP COMMAND
ERROR <Command not found in list> ;COULDN'T FIND IT
MOVEM D,COMNUM ;SAVE NUMBER
JRST .DOHS2 ;JOIN OTHERS
;HERE TO HANDLE A QUOTED STRING
.DOHSQ: CALL DOHFIS ;LOOK UP IMBEDDED STRING IN COMMANDS
ERROR <Command not found in list> ;COULDN'T FIND IT
MOVEM D,COMNUM ;SAVE NUMBER
JRST .DOHS2 ;JOIN OTHERS
;HERE TO FINISH UP PARSE
.DOHS2: CONFIRM ;GET CRLF
MOVE A,COMNUM ;GET COMMAND NUMBER SPECIFIED
SKIPN B,(A) ;GET THE PTR ITSELF
ERROR <Command not found> ;NOTHING THERE. SAY SO
HRROI A,CBUF ;COPY IT TO COMMAND BUFFER
SETZ C, ;TILL NULL FOUND
SOUT%
MOVEI B, .CHCRT ;ADD CARRIAGE RETURN
IDPB B,A
MOVEI B,.CHLFD ;ADD LINE FEED
IDPB B,A ;]
SETZ B, ;NOW ADD NULL
IDPB B,A ;TIE IT OFF
HRROI A,CBUF ;GET COMMAND PTR
ETYPE < %1M> ;OUTPUT IT ALWAYS
MOVEM A,CMPTR ;SAVE FOR INPUT LATER
CALL BCOUNT ;COUNT CHARACTERS
ADDM B,CMINC ;KEEP COUNT IN HERE
MOVE A,SAVEP ;GET PTR TO RETURN LOC ON STACK
MOVEI B,CIN42 ;WHERE TO RETURN TO
MOVEM B,(A) ;STUFF IT SO WE RETURN THERE
RET ;GO DO IT
;HERE FOR RECALL - DISPLAYS THE COMMAND REQUESTED, AND WAITS FOR CONFIRM
.RECAL::PUSH P,[CMDIN4] ; FAKE RETURN ADDRESS
SKIPN HSTCNT ; ANY COMMANDS?
ERROR <No history> ;
MOVE A,P ; SAVE STACK PTR
TRVAR <COMNUM,SAVEP>
MOVEM A,SAVEP ; SO WE KNOW WHERE RETURN ADDR IS
MOVEI B,[FLDDB. .CMNUM,CM%SDH,5+5,<Decimal command number>,,[
FLDDB. .CMQST,CM%SDH,,<Quoted imbedded string>,,[
FLDBK. .CMFLD,,,<Command string>,,FLDMSK,]]]
CALL FLDSKP ; TRY TO PARSE THAT
CMERRX ; ERROR OR SOMETHING
LDB D,[331100,,(C)] ; GET FUNCTION CODE
CAIN D,.CMNUM ; GO HANDLE COMMAND NUMBER
JRST .REHSN ;IF NUMBER ENTERED
CAIN D,.CMFLD ; WAS IT A FIELD
JRST .REHSF ; GO EAT IT UP THEN
JRST .REHSQ ; GO HANDLE QUOTED STRING
;HERE TO HANDLE COMMAND NUMBER
.REHSN: MOVE A,B ; SAVE COMMAND NUMBER
.REHN1: JUMPL A,[AOS A ; IF NEGATIVE, RELATIVE NUMBER
ADD A,HSTNUM ; MAKE IT ABSOLUTE
JRST .+1] ; AND CONTINUE
MOVE B,HSTNUM ; GET CURRENT COMMAND NUMBER
SUB B,HSTCNT ; GET SMALLEST COMMAND WE HAVE
SKIPGE B ; IF NEGATIVE, MAKE ONE
SETZ B, ; STILL HAVE THIS ONE THEN
AOS B ; BASE 1
CAMG A,HSTNUM ; SMALLER THAN LARGEST WE HAVE
CAMGE A,B ; AND LARGER THAN SMALLEST WE HAVE
ERROR <Command not found> ; TELL HIM WHY
SOS A ; BASE 0 THE COUNT
IDIV A,HSTCNT ; DIVIDE BY NUMBER OF COMMANDS
HLRZ A,HSTPTR ; GET BASE ADDRESS
ADD A,B ; GET PROPER OFFSET
MOVEM A,COMNUM ; SAVE COMMAND ADDRESS
.REHS2: CONFIRM ; GET CRLF
MOVE A,COMNUM ; GET COMMAND NUMBER SPECIFIED
SKIPN B,(A) ; GET THE PTR ITSELF
ERROR <Command not found> ; NOTHING THERE. SAY SO
HRROI A,CBUF ; COPY IT TO COMMAND BUFFER
SETZ C, ; TILL NULL FOUND
SOUT%
SETZ B, ; NOW ADD NULL
IDPB B,A ; TIE IT OFF
HRROI A,CBUF ; GET COMMAND PTR
ETYPE < %1M> ; OUTPUT IT ALWAYS
MOVEM A,CMPTR ; SAVE FOR INPUT LATER
CALL BCOUNT ; COUNT CHARACTERS
ADDM B,CMINC ; KEEP COUNT IN HERE
MOVE A,SAVEP ; GET PTR TO RETURN LOC ON STACK
MOVEI B,CIN42 ; WHERE TO RETURN TO
MOVEM B,(A) ; STUFF IT SO WE RETURN THERE
RET ; GO DO IT
.REHSF: CALL DOHFCM ; LOOK UP COMMAND
ERROR <Command not found in list> ; COULDN'T FIND IT
MOVEM D,COMNUM ; SAVE NUMBER
JRST .REHS2 ; JOIN OTHERS
;HERE TO HANDLE A QUOTED STRING
.REHSQ: CALL DOHFIS ; LOOK UP IMBEDDED STRING IN COMMANDS
ERROR <Command not found in list> ; COULDN'T FIND IT
MOVEM D,COMNUM ; SAVE NUMBER
JRST .REHS2 ; JOIN OTHERS
;DOHFCM -- DO HISTORY FIND COMMAND
DOHFCM: HLRZ C,HSTPTR ;GET BASE ADDRESS
HRRZ D,HSTPTR ;GET CURRENT PTR
ADD C,HSTCNT ;SPECIAL FIRST CASE CHECK
CAML D,C ;PTR WITHIN RANGE?
HLRZ D,HSTPTR ;IF OVER RABLE, POINT TO FIRST
MOVE Q1,D ;SAVE CURRENT PTR
HLRZ C,HSTPTR ;GET BASE ADDR BACK
DOHFC1: SOS D ;BACKUP TO PREVIOUS COMMAND
CAMLE C,D ;IS PTR LESS THAN BASE?
JRST [ HLRZ D,HSTPTR ;GET CURRENT BASE ADDRESS
ADD D,HSTCNT ;GET TO END OF BLOCK
SOS D ;BACK UP TO LAST ENTRY
JRST .+1] ;CONTINUE ON
HRROI A,ATMBUF ;GET PTR TO INPUT STRING
SKIPN B,(D) ;GET PTR TO COMMAND
JRST DOHFC2 ;NOTHING, LOOK AT NEXT ONE
STCMP% ;COMPARE
SKIPE A ;TOTAL MATCH?
TXNE A,SC%SUB ;SUBSET MATCH?
RETSKP ;]
DOHFC2: CAMN D,Q1 ;HAVE WE LOOPED?
RET ;FAILURE RETURN
JRST DOHFC1 ;NO GOOD. LOOK AT NEXT
;DOHFIS -- DO HISTORY FIND IMBEDDED STRING
DOHFIS: HLRZ C,HSTPTR ;GET BASE ADDRESS
HRRZ D,HSTPTR ;GET CURRENT PTR
ADD C,HSTCNT ;SPECIAL FIRST CASE CHECK
CAML D,C ;PTR WITHIN RANGE?
HLRZ D,HSTPTR ;IF PAST TABLE, MOVE TO FIRST ENTRY
MOVE Q1,D ;SAVE CURRENT PTR
HLRZ C,HSTPTR ;GET BASE ADDR BACK
DOHFI1: SOS D ;BACKUP TO PREVIOUS COMMAND
CAMLE C,D ;IS PTR LESS THAN BASE?
JRST [ HLRZ D,HSTPTR ;GET CURRENT BASE ADDRESS
ADD D,HSTCNT ;GET TO END OF BLOCK
SOS D ;BACK UP TO LAST ENTRY
JRST .+1] ;CONTINUE ON
MOVE B,[POINT 7,ATMBUF] ;GET PTR TO INPUT PATTERN
SKIPN A,(D) ;GET PTR TO COMMAND STRING
JRST DOHFI2 ;NOTHING, LOOK AT NEXT ONE
CALL DOHFND ;DO PATTERN MATCH
SKIPA ;NOT FOUND
RETSKP ;SAY FOUND IT. ADDR OF COMMAND IN D
DOHFI2: CAMN D,Q1 ;HAVE WE LOOPED?
RET ;FAILURE RETURN
JRST DOHFI1 ;NO GOOD. LOOK AT NEXT
;DOHFND -- DO HISTORY FIND
;A/ PTR STRING TO SEARCH IN
;B/ PTR PATTERN TO FIND IN STRING
;RETURNS +1 NOT FOUND
; +2 A/ PTR TO START OF PATTERN IN STRING
DOHFND: JUMPE A,R ;RETURN IF STRING ZERO
JUMPE B,R ;RETURN IF PATTERN ZERO
PUSH P,C ;AC TO SAVE PLACE IN STRING
PUSH P,D ;AC WE USE TO POINT TO PATTERN
PUSH P,Q1 ;SAVE PLACES FOR CHARACTERS
PUSH P,Q2 ;
DOHFN1: MOVE C,A ;SAVE PTR INTO STRING
MOVE D,B ;GET NEW PTR TO PATTERN
DOHFN2: ILDB Q1,A ;GET A CHARACTER FORM STRING
ILDB Q2,D ;GET A CHARACTER FROM PATTERN
JUMPE Q2,[MOVE A,C ;RESTORE SAVED STRING POSITION
AOS -4(P) ;GOOD RETURN. MATCH FOUND
JRST DOHFN4] ;POP AND RETURN
JUMPE Q1,DOHFN4 ;END OF STRING?
CAMN Q1,Q2 ;CHARACTERS MATCH?
JRST DOHFN2 ;LOOP UNTIL MISMATCH
JRST DOHFN1 ;TRY PATTERN ON UPDATED STRING
DOHFN4: POP P,Q2 ;RESTORE ACS
POP P,Q1
POP P,D
POP P,C
RET
FLDMSK: BRMSK. FLDB0.,FLDB1.,FLDB2.,FLDB3.,</-!;.@\_$,*>
END