Trailing-Edge
-
PDP-10 Archives
-
scratch
-
10,7/unscsp/sos/sosalt.mac
There are 3 other files named sosalt.mac in the archive. Click here to see a list.
TITLE SOSALT - The ALTER Mode Family
; ------------------------------
; This file contains the processing for ALTER mode as follows:
; 1. The A command
; 2. Command dispatching
; 3. SETALT - Set up a line for altering
; 4. GNCH1 - Get an alter mode character
; 5. Alter mode command processing
; 6. The extend (X) command
;
SEARCH SOSTCS
$INIT
SUBTTL The X Command
$XPAND::SETOM XCMDF ; Flag we are doing an X command
JRST ALTER1 ; And do an alter
SUBTTL The A Command
; Here for the A command - Beginning of Alter Mode
$ALTER::SETZM XCMDF ; This is not an extend
; Join here for the X-command
ALTER1: SETOM PRVSIZ ; Fix count
SETZM SSW ; Clear suppress switch
PUSHJ P,GET2SD## ; Get the range
SKIPN XCMDF ; If X-command then
JRST ALTER2
CAIN C,";" ; Check for legal delimiter
JRST [PUSHJ P,SCAN ; Get number
TRNN FL,NUMF ; Is there a number
NERROR ILC ; No, quit
MOVE T2,INCR
MOVEM T2,TEMINC
JRST XCMD1] ; Join processing
CAIE C,"," ; Is there a switch or new increment
JRST ALTER2 ; No, check for end of line
PUSHJ P,SCAN## ; Get it
TRNN FL,NUMF ; Is there a number?
JRST XCMD2 ; No, look for switch
XCMD1: CAMN T1,LNZERO## ; Line zero?
NERROR ILC ; Is illegal
MOVEM T1,INCR ; Save increment
PUSHJ P,SCAN## ; Scan next
CAIE C,"," ; Still have a switch?
JRST ALTER2 ; No, so better be the end
PUSHJ P,SCAN## ; Scan the switch
XCMD2: MOVS T1,ACCUM ; to T1
CAIE T1,'S ' ; or ,S switch
NERROR ILC ; it's and error
SETOM SSW ; Else note suppress and continue
PUSHJ P,SCAN## ; To reach end of line
ALTER2: PUSHJ P,CKTRMF##
PUSHJ P,FINDLO## ; Get first line of range
TRZ FL,LINSN ; Not seen yet
CONT.
ALT1: PUSHJ P,ONMOV## ; Check for in range
JRST ALT2 ; No, finish up
TRO FL,LINSN ; We did see something
CAMN T1,PGMK ; Check for a page
JRST ALT3 ; Do not try to change this
MOVEM T1,CLN ; Now, in case we said altmode
MOVE T1,CPG ; Same for page
MOVEM T1,CPGL
SKIPE SSW ; If S-switch
TRO FL2,SUPN ; Do suppress thing
MOVEI T5,CPOPJ ; Assume alter command
SKIPE XCMDF ; True?
MOVEI T5,ALTELX ; First free command
PUSHJ P,ALTLIN## ; Do the Alter (or eXtend)
PJRST LEVINS## ; He said altmode
PUSHJ P,AINSED ; Go insert
ALT4: PUSHJ P,FINDN## ; Get the next line
JRST ALT1 ; Continue loop
ALT3: MOVE T2,CPG ; We are on a later page now
ADDI T2,1 ; Add fudge factor
MOVEM T2,CPGL ; Save as .
PUSHJ P,PGPRN## ; Print him a message
MOVE T1,LNZERO## ; Set to first? line
MOVEM T1,CLN ; For .
JRST ALT4 ; Continue past it
ALT2: TRNN FL,LINSN ; Was there anything there?
JRST [SKIPE XINSRT## ; Auto insert on X command?
SKIPN XCMDF ; X command?
NERROR NLN ; No, give error message
TRZ FL,CNTF ; Don't handle these here
JRST INSGO##] ; Yes, treat as an insertion
MOVE T1,CPG ; Get the current page
MOVEM T1,CPGL ; Save as .
SKIPE XINSRT## ; Auto insert on X command?
SKIPG XCMDF ; Go back to insert?
JRST COMND## ; No, next command
MOVE T1,CLN ; Current line
MOVEM T1,HILN ; Save for INSRTX
JRST INSRTX## ; Join insert routine
SUBTTL AINSED -- Insert Altered line into the buffer
;AINSED -- Insert Altered line into the Buffer
;
;Call with PNTR pointing to unaltered line in buffer and
;altered line in LIBUF. Checks to see if line was actually changed
;by doing a string compare. If it was, it inserts the new line in
;the buffer with INSED, and handles the decrement and test on SAVEN
;for auto-save.
AINSED: MOVE T1,NCNT ; Get new count
CAME T1,OCNT ; Is it the same?
JRST AINSD1 ; No, must update the line
MOVN T1,T1 ; Minus count
MOVSS T1 ; To left half
HRRI T1,LIBUF ; Point to Alter buffer
MOVEI T2,(PNTR) ; Point to line in edit buffer
HRLI T2,(POINT 36,) ; Make a word pointer
AINCMP: ILDB T3,T2 ; Word from the buffer
CAME T3,(T1) ; Compare with Altered line
JRST AINSD1 ; Different, go update line
AOBJN T1,AINCMP ; Loop over whole line
POPJ P, ; All same, therefore no changes
AINSD1: PUSHJ P,INSED## ; Update line in buffer
SKIPE SSAVEN ; Is save activated?
SOSLE SAVEN ; Yes, decrement count and check
POPJ P, ; No, just return
PUSH P,HILN ; Save current hiln
MOVE T1,CLN ; Get current line...
MOVEM T1,HILN ; And establish as hiln for auto-save
PUSHJ P,ASVCOD## ; Do the auto-save
POP P,HILN ; Restore hiln
POPJ P,
SUBTTL Command Dispatching for ALTER Mode
; Here to alter a line
$ATLIN::SKIPN T1,CRLFSW ; If not set
PJRST ALTLNX ; Just do the alter
MOVEM T1,SVCRLF ; Save, in case of errors
SETZM CRLFSW ; Clear
PUSHJ P,SETTTY## ; Re-set to zero
PUSHJ P,ALTLNX ; Do the alter
CAIA
AOS (P) ; If skip return
; Call ALTLNX if a user supplied procedure should be executed
; after SETALT has set things up
ALTLNX: PUSHJ P,SETALT ; Set up line for alteration
IFN %UAHPQ,<
PUSHJ P,HPQON## ;[UA WRS] Use HPQ for ALTER mode
>
PUSHJ P,(T5) ; Call user routine
$ATLN1:: ; Here if you don't want SETALT called
ALTLP2: TLZ FL,NEGF ; Turn off "-" seen flag
PUSHJ P,V52TPN ; Type line again
SETZM CHGLNF## ; Reset this flag
SETZB T2,DELBAK ; Reset 'deleting backward' flag
ALTLP: TRZ FL2,SUPN!ALTDUP ; Turn duplexing back off
PUSHJ P,GNCH1## ; Get on chr in ddt submode
TLNE CS,LETF_16 ; Check for letter
TRZ C,40 ; And convert to upper case
MOVSI T1,-ALTLG ; Get length of command table
;
ALTLP3: HRRZ T3,ALTAB(T1) ; Fetch an entry
TRZ T3,XNEGF!XAM ; Clear flags in right half
CAIE C,(T3) ; Check for character match
AOBJN T1,ALTLP3 ; No match, look at next
JUMPGE T1,ALTBEL ; Ring the bell if not found
MOVS T3,ALTAB(T1) ; Re-fetch entry (need flags)
TRNE FL,READOF ; Read-only?
TLNN T3,XAM ; and command modifies the file?
CAIA
JRST ALTBEL ; Yes, error
TLNN T3,XNEGF ; Minus sign permitted?
TLNN FL,NEGF ; No: is it set?
JRST ALTDSP ; Ok to execute command
ALTBEL: OUTCHR [7] ; Bong a gong
CLRBFI ; Clear type ahead
JRST ALTLP2 ; Try again
ALTDSP: PUSHJ P,(T3) ; Execute command
JRST ALTLP2 ; Reset repeat count and get new command
JRST ALTLP ; Skip return from digits no count reset
; Here to ring bell after a command detected error
ALTFS2: POP P,ALTCNT
ERARTN: POP P,ALTP
ER1RTN: POP P,(P) ; Clear junk off stack
ERRRTN: OUTCHR [7]
SETO T2, ; Flag meaning error
POPJ P, ; Then return
SUBTTL ALTER Mode Commands Table
; Flags
XNEGF==400000 ; Command may take a - sign
XAM==200000 ; Command modifies the line
DEFINE ACMNDS,<
I==0
REPEAT ^D10,<
X I+"0", ALTDG, XNEGF ;; Accumulate a number
I==I+1>
X " ", ALTSP##, XNEGF ;; Skip a character
X "H", ALTAMP, XNEGF!XAM ;; Amputate and insert
X ":", ALTXDL, XNEGF!XAM ;; Amputate
X "B", INSBLK, XAM ;; Insert blanks
X "C", ALTCN, XNEGF!XAM ;; Change some characters
X "D", ALTDL, XNEGF!XAM ;; Delete some characters
X "E", ALTEX, ;; Exit w/no print
X "F", ALTFS, XNEGF ;; Find a string
X "G", ALTGT, XNEGF ;; Find a string (rpos)
X "I", ALTIN, XAM ;; Insert text
X "J", AJOIN, XNEGF!XAM ;; Insert CRLF and join
X "K", ALTKL, XNEGF!XAM ;; Kill some characters
X "L", ALTLN, ;; List and continue
X "M", ALTAMD, XNEGF!XAM ;; Y followed by I
X "N", ALTNXL, XNEGF ;; Advance to next line
X "O", INSONE, XAM ;; Insert one character
X "P", APRINT, ;; Print and save pos
X "Q", ALTALT, ;; Quit while ahead
X "R", ALTRP, XNEGF!XAM ;; Replace some characters
X "S", ALTSR, XNEGF ;; Search for a character
X "T", ALTWX, XNEGF!XAM ;; Delete a word and i
X "W", ALTWD, XNEGF ;; Skips a word
X "X", ALTEOL,XNEGF!XAM ;; Extend the line
X "Y", ALTYK, XNEGF!XAM ;; Find string and delete
X "Z", ALTZNK, XNEGF!XAM ;; Delete words
X "^", ALTCHG, XNEGF!XAM ;; Invert case
X "V", ALTXCH, XNEGF!XAM ;; Invert case to EOL
X "/", ALTSL, XNEGF!XAM ;; Transpose 2 chars
X "\", ALTBSL, XNEGF!XAM ;; Transpose previous 2
X "-", ALTNEG, ;; Command goes left
X "#", ALTCHW, XNEGF!XAM ;; Like ^, but on words
X 42, ALTSIC, XNEGF!XAM ;; Search and invert case
X "!", ALTKI, XNEGF!XAM ;; K followed by I
X "+", INSNXT, XAM ;; Don't ask
X 73, INSCRF, XAM ;; Break the line
X "'", INSQT, XAM ;; Make ^<ch>
X "U"-100+200, ALTCU, ;; Restore and restart
X 11, ALTTAB##, XNEGF ;; Move to end of line
X 12, ALTFN, ;; Done with alter
X 15, CPOPJ1, ;; Ignore CR's
X 177, ALTBS, ;; Backspace in line
X "H"-100+200, ALTBS, ;; Backspace in line
X "R"-100+200, ALTCTR, ;; P up to current only
X "W"-100+200, ALTBSW ;; Backspace one word
>
; The commands table
DEFINE X(A,B,C),<XWD B,A!C>
ALTAB: ACMNDS
ALTLG==.-ALTAB
SUBTTL SETALT - Set Up a Line for ALTER
; Routine to set up a line for altering
SETALT: MOVEI T1,0 ; Be sure TTY TAB is off
PUSHJ P,SETTAB## ; (but remember old value)
PUSHJ P,LOADCL##
SALT1: MOVE ALTP,[POINT 7,LIBUF+1,13] ; Set up pointer
SETZM ALTCNT ; So far we are 0 chrs into line
HRRZM T1,OCNT ; And save it for insed
OFFECHO ; Turn off echo
TRZ FL2,RUBF!ALTDUP!RUBF2; Clear rubout and echoing flags
SETZM ALTFLG ; Nothing inserted so far
MOVE T1,LIBUF ; Print line number and tab
PUSHJ P,OUTSN## ; Sequence number
SETOM PRVSIZ ; Force typeout if on VT52
POPJ P,
; Macros for rubout control
DEFINE OFFRUB<
PUSHJ P,.OFFRB
>
.OFFRB: SKIPE DPYFLG
POPJ P,
TRZE FL2,RUBF2
OUTSTR [ASCIZ /\\/]
TRZE FL2,RUBF
OUTCHR ["\"]
POPJ P,
DEFINE ONRUB<
PUSHJ P,.ONRUB
>
.ONRUB: SKIPE DPYFLG
POPJ P,
TRZE FL2,RUBF2
OUTSTR [ASCII /\\/]
TRON FL2,RUBF
OUTCHR ["\"]
POPJ P,
SUBTTL The -, Space, Tab, X, ^ and V Commands
; The - command
ALTNEG: TLO FL,NEGF
JRST CPOPJ1##
; Here to accumulate digits
ALTDG: IMULI T2,^D10 ; Accumulate repeat count
ADDI T2,-"0"(C)
JRST CPOPJ1 ; Skip return so at not to 0 rpt. cnt.
; The tab and space commands
ALTBOL: PUSHJ P,SAVR## ; Save T3-T5
PUSHJ P,CSRPOS ; Compute number of wraps
PUSHJ P,FIXWPC## ; Account for multiple of LINEW
PJRST UPCRSR## ; And position
$ATTAB::SKIPE VT52FL
TLNN FL,NEGF ; -<TAB> on VT52?
CAIA
PJRST ALTLN ; Yes, use more efficient ALTLN routine
MOVSI T2,1 ; Large count
; ; Fall into space
$ALTSP::TLNE FL,NEGF ; Check backwards
PJRST ALTBS ; Yes: back space
OFFRUB
;
ALTSP2: LDB C,ALTP ; Get the chr we are pointing at
CAIN C,15 ; If return then as far as can go
PJRST FORCE##
TRNN FL2,SUPN ; Special hack for xtend
PUSHJ P,OCHR## ; Print it
IBP ALTP ; Advance pointer
AOS ALTCNT ; And count
SOJG T2,ALTSP2 ; Do correct number of times
PJRST FORCE## ; Dump it
; Here for the V command (change case to end of line)
ALTXCH: SKIPN NEWCMD ; SEE IF IN COMPATIBILY MODE
JRST CLTCHW ; YES--TREAT LIKE #
CLTXCH: MOVSI T2,1 ; Huge repeat count
;; PJRST ALTCHG ; Fall through to ^ command
; Here for the ^ command
ALTCHG: TRO FL2,ALTDUP ; Start duplexing again
TLNN FL,NEGF ; If going forward
JRST ALTCG0
PUSH P,T2 ; Save count
PUSHJ P,ALTBS ; Backspace
EXCH T2,(P) ; Restore count
SUB T2,(P) ; In case count was too large
ALTCG0: OFFRUB ; Terminate deletes and backspaces
ALTCG1: LDB C,ALTP ; Get character
CAIN C,15 ; Test for end of line
JRST ALTCG2 ; Yes, done
MOVE CS,CTBL(C) ; Get character's flag bits
TLNE CS,LETF_16 ; Test for a letter
TRC C,40 ; Yes, invert the case
DPB C,ALTP ; Put character back
PUSHJ P,OCHR ; Type character
IBP ALTP ; Incr byte pointer
AOS ALTCNT ; & character count
SOJG T2,ALTCG1 ; Decr count & repeat
ALTCG2: TLNE FL,NEGF ; If going backward
POP P,T2 ; Get garbage of the stack
PJRST FORCE ; Force typing out
; The X command
ALTELX: SETZ T2, ; Come here initially for the X command
TLZA FL,NEGF ; Clear negative flag
ALTEOL: SKIPE NEWCMD ; COMPATIBILITY MODE?
SKIPA ; NO
JRST CLTWX ; YES--TREAT LIKE T
CLTEOL: PUSH P,T2 ; SAVE POSSIBLE INCREMENT
PUSHJ P,ALTTAB## ; Go to end of line
POP P,T2 ; Restore increment
TLZ FL,NEGF
PJRST ALTIN ; And go merge with insert
SUBTTL The R and D Commands
; The R command
ALTRP: PUSHJ P,ALTDL ; Delete
PUSHJ P,V52TYP ; Type line so far
PJRST ALTINZ ; Then insert
; The D command
ALTXDL: MOVSI T2,1 ; Large repeat count
;
ALTDL: SETOM CHGLNF ; Note can change print size of line
TLNE FL,NEGF ; Backwards?
JRST ALTBDL ; Yes:
MOVEM ALTP,SVALTP ; Save current pointer posithon
ALTDL1: LDB C,ALTP ; Get current chr
CAIN C,15 ; At end of line?
JRST ALTDL5 ; Yes, go finish off
SKIPN EXPFLG ; Print only if non-expert
SKIPE VT52FL ; Or in fancy disply mode
CAIA
PUSHJ P,ALTDPN ; Yes: print char
IBP ALTP ; Advance pointer
SOJG T2,ALTDL1 ; Check count and continue
ALTDL5: SKIPN VT52FL ; If on a display
SKIPN DPYFLG ; Are we on a display?
JRST ALTDL6 ; No--skip extra blank stuff
MOVEI C," " ; Yes--put out one more...
PUSHJ P,OCHR ; Blank to delete last character
MOVE C,BACCHR## ; Then put out a backspace...
PUSHJ P,OCHR ; To puts us back at the right point
ALTDL6: PUSHJ P,FORCE ; Force output
ALTDL3: MOVE T3,SVALTP ; Get back pointer
ALTDL4: LDB C,ALTP ; Move line down
DPB C,T3
JUMPE C,ALTDL2 ; Done?
IBP ALTP ; Advance pointers
IBP T3
JRST ALTDL4
ALTDL2: MOVE ALTP,SVALTP ; Restore pointer again
POPJ P,
; THE H COMMAND (Amputate the line from here and insert)
ALTAMP: MOVSI T2,1 ; Huge count
PJRST ALTRP ; Now do replace
; The P and ^R commands
ALTCTR: SKIPN VT52FL ; Display?
PJRST RPRINT ; No standard function
V52RTP: SETOM PRVSIZ ; Force retype
PJRST V52TPP ; and do it
RPRINT: PUSH P,ALTCNT ; Save current count
PUSHJ P,ALTLNN ; Restart the line
PJRST APRNT1
APRINT: SKIPE VT52FL
PJRST V52RTP ; Do special thing for displays
PUSH P,ALTCNT ; Save current count
PUSHJ P,ALTLN ; Print rest of line and start over
APRNT1: POP P,T2 ; Get back count
JUMPN T2,ALTSP##
POPJ P,
; Here to print characters as they are deleted
ALTDPN: SKIPE DPYFLG ; On a display?
JRST DISDPN ; Do it right then
PUSH P,C
MOVEI C,"\"
TRNN FL2,RUBF2
PUSHJ P,OCHR
TRZE FL2,RUBF
PUSHJ P,OCHR
TRON FL2,RUBF2
PUSHJ P,OCHR
POP P,C
JRST OCHR
DISDPN: TLNN FL,NEGF ; Going backward?
JRST DSDPN2 ; No, then go forward
SETOM DELBAK ; Set 'deleting backward' flag
PUSHJ P,RUBAK## ; Backspace over the character
PJRST TYPSTR## ; Type eraser--returned in T1 by RUBAK##
;
DSDPN2: CAIG C," " ; Use blank to for non-printing chars
MOVEI C," " ; Map all special characters into a blank
PUSHJ P,OCHR ; Output deleted character
MOVE C,BACCHR## ; Code for backspace
PJRST OCHR ; Output and return
SUBTTL The I Command
; The I command -- text insertion
ALTINZ: TLZ FL,NEGF ; Commands join here to terminate with
; an I command. R, T, !, H and M.
SETZ T2, ; Clear increment
;
ALTIN: TRO FL2,ALTDUP ; Turn on duplexing
MOVEM T2,ALTINC ; Save in case he inserts a return
MOVEI T1,GNCH1##
ALTIN0: MOVEM T1,IGNCH## ; Set up routine to get characters
ALTIN1: PUSHJ P,@IGNCH## ; Get a character
CAIN C,233 ; Finish on altmode
POPJ P,
SETOM CHGLNF ; Can change print size of line
SETOM DELBAK ; Like deleting backward
CAIN C,15 ; Finish on CR
JRST ALTFNZ
CAIN C,12
JRST INSCR ; Go insert a CRLF
CAIN C,"U"-100+200 ; A ^U?
JRST ALTCU ; Abort this disaster
CAIE C,"H"-100+200 ; Is this a special delete char?
CAIN C,177 ; Check for backspace
JRST ALTIBS ; And delete chr to left
CAIN C,"R"-100+200 ; Did he type ^R?
JRST [PUSHJ P,RPRINT
JRST ALTIN1] ; Re-echo and loop for more
CAIN C,"W"-100+200 ; ^W?
JRST ALTIWS ; Wordspace backward
MOVE T3,ALTP ; Get set to shift things
PUSH P,ALTCNT ; Save this for later
LDB T1,T3 ; Get chr from line
ALTIN2: DPB C,T3 ; Shift line
JUMPE C,ALTIN3 ; Done
AOS ALTCNT ; Count it
ILDB C,T3
DPB T1,T3
JUMPE T1,ALTIN3 ; Done
AOS ALTCNT ; Count
ILDB T1,T3
JRST ALTIN2
ALTIN3: MOVE T2,ALTCNT ; See if overflow happened
CAIL T2,MXWPL*5
NERROR LTL ; Yes
POP P,ALTCNT ; Restore old count
IBP ALTP ; Advance pointer
AOS ALTCNT ; And count
ALTIN4: PUSHJ P,V52TPI ; Type if in VT52 mode
JRST ALTIN1 ; Go get more
; Here to insert a CRLF (i.e. a new line)
INSCR: OFFRUB
SETOM PRVSIZ ; Zap this, new line
SKIPE VT52FL ; Vt52?
XCT TMFCLN ; Clear to end of line
OCRLF
SKIPN T1,ALTINC ; Did he specify an increment?
SKIPA T3,INCR ; No, use standard
PUSHJ P,ASCON## ; Convert to ASCII
MOVE T1,T3 ; Find the new line number
MOVE T2,LIBUF ; Current one
PUSHJ P,ASCIAD## ; Add
PUSH P,T1 ; Save result
PUSHJ P,FINDN ; Get the next one
POP P,T2
CAMG T2,LIBUF ; Is there a war problem
JRST INCBAD ; Yes, we must try to compute one
JUMPE T1,INCOK ; End of file, any inc is ok
CAME T1,PGMK ; Also ok if a page mark
CAMGE T2,T1 ; Or in correct order
JRST INCOK
INCBAD: CAME T1,PGMK
SKIPN T1
MOVE T1,LNOVER## ; One over the top of the world
MOVEM T2,LIBUF2 ; Save in case nothing will work
MOVE T2,LIBUF ; Get current
PUSHJ P,ASCAV## ; Find average
CAME T2,LIBUF ; There may have only been a dif of 1
JRST INCOK ; All is well
RERROR ORDER ; Tell him
PUSHJ P,FINDB## ; Get back where we belong
PUSHJ P,RPRINT ; Type out line to current point
JRST ALTIN4 ; And continue insert
INCOK: MOVEM T2,LIBUF2 ; Save it
MOVEM T2,CLN ; And set as current line
PUSHJ P,FINDB ; Back up to where we belong
MOVE T1,[XWD LIBUF+1,LIBUF2+1]
BLT T1,LIBUF2+MXWPL+1; Save old buffer
PUSH P,ALTP ; Save pointer
MOVEI C,15
DPB C,ALTP ; And terminate this line
MOVEI C,12
IDPB C,ALTP
MOVEI C,0 ; Fill out line with nulls
AINSC2: TLNN ALTP,760000
JRST AINSC3
IDPB C,ALTP
JRST AINSC2
AINSC3: SUBI ALTP,LIBUF-1 ; Find count
HRRZM ALTP,NCNT
PUSHJ P,INSED ; Replace old line
PUSHJ P,FINDN ; Move up to next
SETZM OCNT ; This is a new line going in
MOVE T1,LIBUF2 ; Move line number over
CAMLE T1,HILN ; Is it smaller than HILN?
MOVEM T1,HILN ; No, make HILN consistent
MOVEM T1,LIBUF
SETZM LIBUF+1
MOVE T1,[XWD LIBUF+1,LIBUF+2]
BLT T1,LIBUF+MXWPL+1; Zero out rest
POP P,T2 ; Restore pointer to rest of line
MOVE ALTP,[POINT 7,LIBUF+1]; Dest pointer
ADD T2,[XWD 70000,MXWPL+3]; Adjust input pointer
MOVEI C,11 ; And set up the tab
MOVNEW: IDPB C,ALTP
CAIN C,12
JRST DONNEW ; Finished moving rest of line
ILDB C,T2 ; Pick up one
JRST MOVNEW
DONNEW: SUBI ALTP,LIBUF ; Get count
MOVEI ALTP,1(ALTP) ; Used to be - movei ac,1-libuf(ac)
MOVEM ALTP,NCNT
PUSH P,ALTP ; And save
PUSHJ P,INSED ; Insert
MOVE ALTP,[POINT 7,LIBUF+1,13]; Set up for alter
SETZM ALTCNT
POP P,OCNT ; Set for old count
MOVE T1,LIBUF
PUSHJ P,OUTSN##
SETOM ALTFLG ; We have inserted
JRST ALTIN4 ; And continue inserting
POPJ P,
; Here if he types a rubout in insert mode
ALTIBS: MOVEI T2,0 ; Set count to 0
MOVEM ALTP,SVALTP ; Save pointer
PUSHJ P,ALTBS ; Do a backspace
JUMPE T3,ALTIN1 ; If hit beginning of the line
EXCH ALTP,SVALTP ; Get back and save current
PUSHJ P,ALTDL3 ; Delete that chr
SKIPE DPYFLG ; On a display?
PUSHJ P,TYPSTR##
JRST ALTIN4 ; Get more
; Here on ^W in insert mode
ALTIWS: MOVEI T2,0 ; Set count to 0
TLO FL,NEGF ; Set negative flag
PUSHJ P,ALTZNK ; Backup
TLZ FL,NEGF ; Clear it now
JRST ALTIN4 ; Get next
; THE O COMMAND -- Insert a single character
INSONE: OFFRUB ; Issue pending backslashes
MOVEI T1,INSO1 ; Next entry when insert want a character
MOVEM T2,INOCNT## ; Rep count for insertion
SETOM V52SPF
PJRST ALTIN0 ; Start the insertion
;
INSO1: MOVEI T1,INSO2 ; Next entry
MOVEM T1,IGNCH ; Save it
PUSHJ P,AGNCH1## ; Read up next character
MOVEM C,INOCHR##
CAIE C,15 ; Don't duplex carriage return
CAIN C,12 ; or linefeed
POPJ P,
PJRST OCHR ; Duplex the character
;
INSO2: SOSG INOCNT ; Count satisfied?
JRST INSO3 ; Terminate
MOVE C,INOCHR ; Restore character to insert
CAIE C,12 ; Don't print a linefeed
PJRST OCHR ; Output it again
POPJ P, ; Return to insert routine
;
INSO3: MOVEI C,233 ; Termination character
SETZM V52SPF
PJRST FORCE
; The semicolon command -- insert a <CR> <LF> to break the current line
INSCRF: MOVEI C,12
PJRST INSCHR
; THE B COMMAND -- Insert one or more blanks (short for nO<blank>)
INSBLK: MOVEI C," " ; Blank character
INSCHR: MOVEM C,INOCHR ; Pass it for one character insert code
SETOM V52SPF ; Kill typeout by insert for awhile
SKIPN T2 ; Zero implies one
MOVEI T2,1 ; Adjust it
AOS T2 ; Fudge count
MOVEM T2,INOCNT ; Set up the count
MOVEI T1,INSO2 ; Address for character repetition
PJRST ALTIN0 ; Go insert the characters
; The + command -- duplicate the current character
INSNXT: OFFRUB
PUSHJ P,ALTBAK ; Peek at previous character
JUMPE T3,CPOPJ## ; If at beginning of line
MOVE C,T3 ; Character under cursor
IBP ALTP ; Reset pointer
CAIN C,15 ; If a null line
JRST ERRRTN ; This is an error
PJRST INSCHR ; Else output it
; Here for the ' command
INSQT: OFFRUB ; As usual
PUSHJ P,AGNCH1## ; Go get his character
CAIG C,100 ; Make sure it will be gt 0
JRST ERRRTN ; Nope, bong the gong
TRZ C,777640 ; Clear parity and convert to UC
SUBI C,100 ; Make it a control character
CAIE C,15 ; Bare carriage returns confuse SOS
CAIN C, 12 ; and so do linefeeds
JRST ERRRTN ; Bong the gong
JRST INSCHR ; Do, O, + and B thing
SUBTTL The F Command
; The F command
ALTFS: PUSHJ P,ALTFG ; Get search string
;
ALTFSR: PUSH P,T2
PUSH P,ALTP
PUSH P,ALTCNT
SETZM INOCNT
;
ALTFS1: LDB C,[POINT 7,AFSBUF##,6]; Break character for search
MOVEI T2,1
TLNE FL,NEGF ; Skip if going forward
PUSHJ P,[PUSH P,ALTP
AOS -1(P)
JRST ALTBC1]
PUSHJ P,ALTCS ; Look for instance of initial character
ADDM T2,INOCNT
CAIN T3,15 ; Give up if the search fails
JRST ALTFS2
JUMPE T3,ALTFS2 ; If search fails going backward
SKIPE T2 ; Don't space if zero
PUSHJ P,ALTSSP ; Space over to it
PUSHJ P,ALTCMP ; Is it the one we're looking for
JRST ALTFS1 ; No, try for another
POP P,ALTCNT ; Restore count
POP P,ALTP ; And pointer
SKIPE T2,INOCNT ; Get count
PUSHJ P,ALTSP## ; Space over that many
POP P,T2
SOJG T2,ALTFSR ; Do search specified number of times
POPJ P,
SUBTTL Subroutine to Read in a Search String
ALTFG: OFFRUB ; Terminate any rubouts or deletes
MOVEI T4,^D19 ; Max search string length
MOVE T3,[POINT 7,AFSBUF##-1,34]; Pointer to buffer
ALTG1: PUSHJ P,GNCH1## ; Get a character for search string
CAIN C,15 ; Is it <CR>
JRST ALTG2 ; Denotes string at eol
CAIN C,233 ; End of search string
JRST ALTG3 ; Yep
CAIN C,"U"-100+200 ; Negative acknowlege?
JRST ALTFG ; Take it again from the top
CAIE C,"H"-100+200 ; Yes, do we have a backspace?
CAIN C,177 ; Rubout?
JRST [CAMN T3,[POINT 7,AFSBUF-1,34]
JRST ALTG1
ADD T3,[POINT 0,0,28]
TLNE T3,(1B0)
SUB T3,[POINT 0,1,0]
AOJA T4,ALTG1]
TRZ C,200 ; Clear special bits for anything else
CAIL C,140 ; Skip if not lower case
TDZ C,AEXACF ; Conditionally convert to upper
IDPB C,T3 ; Save this character in sstr buffer
SOJG T4,ALTG1 ; Try for another
;
JRST ER1RTN ; The search string is too long
ALTG2: IDPB C,T3 ; Put <CR> in search string
PUSHJ P,GNCH1## ; Swallow the line feed
;
ALTG3: SETZ C, ; End of string marker
CAIE T4,^D19 ; If null string, T4 is still 19
IDPB C,T3 ; Mark it
POPJ P, ; Return
SUBTTL The G Command
ALTGT: MOVEI T1,ALTSP## ; Set up for spacing
MOVEM T1,ALTWPR## ; Leave it for indirect branch
ALTGTS: PUSHJ P,ALTFG ; Get string to search for
CAIN T2,0
MOVEI T2,1 ; Make positive
TLNN FL,NEGF ; Going backward
JRST ALTG1A ; If not
PUSH P,[ALTG1B]
PUSH P,T2
PUSH P,ALTP
PUSH P,ALTCNT ; Save state in case search fails
PUSHJ P,LFSBUF
MOVEM T2,INOCNT
PUSHJ P,ALTSSP ; Silent space over the string
JRST ALTFS1 ; Do the search
ALTG1A: TLO FL2,L2.SSI ; Allow G to skip F string
PUSHJ P,ALTFSR ; Do the search
ALTG1B: JUMPL T2,CPOPJ ; If search failed
PUSHJ P,LFSBUF ; Get length of search string
TLZ FL,NEGF ; Clear negative flag
JRST @ALTWPR## ; Process search string
; Routine to compute length of the search string (Returned in T2)
LFSBUF: MOVE T1,[POINT 7,AFSBUF]; Start of search string
SETZ T2, ; Initialize count
;
LFSBF1: ILDB C,T1 ; Get character from search string
JUMPE C,CPOPJ
AOJA T2,LFSBF1 ; Increment count
SUBTTL The Y and M Commands
; The y command
ALTYK: MOVEI T1,ALTDL ; Process is deletion
MOVEM T1,ALTWPR## ; Pass it
PJRST ALTGTS ; And do like G command
; The m command
ALTAMD: PUSHJ P,ALTYK ; First do a Y
JUMPL T2,CPOPJ## ; Just quit on error
PUSHJ P,V52TYP ; Now type the results
PJRST ALTINZ ; Then an insert
SUBTTL The Character-Search Commands: S, K, ! and "
; The ! command -- K followed by I
ALTKI: PUSHJ P,.ALTSR ; Get the count
JUMPLE T2,CPOPJ ; If nothing to do
PJRST ALTRP ; Else make like replace
; The S, K and " commands
ALTKL: PUSHJ P,.ALTSR ; Go do search thing
JUMPLE T2,CPOPJ ; If nothing to do
PJRST ALTDL ; Then go delete
ALTSIC: PUSHJ P,.ALTSR ; Search
JUMPLE T2,CPOPJ ; If nothing to do
PJRST ALTCHG ; and change case
ALTSR: PUSHJ P,.ALTSR ; Get the count
JUMPLE T2,CPOPJ ; If nothing to do
PJRST ALTSP## ; And then space over
.ALTSR: PUSHJ P,AGNCH1## ; Get character to search for
CAIN C,15 ; Carriage return is end of line
JRST .ALTSC ; Fake it
CAIL C,140 ; Lower case
TDZ C,AEXACF ; Map upper/lower if desired
PUSH P,ALTP
PUSH P,ALTCNT ; Save these
SETZM INOCNT ; Clear counter
MOVEM C,INOCHR ; Save targent character
;
.ALTS1: PUSH P,T2
MOVE C,INOCHR ; Restore character
PUSHJ P,ALTCS
CAIE T3,0 ; Off front end - skip
CAIN T3,15 ; or if reached end of line
JRST [OUTCHR [7] ; Type a bell
SETZM (P) ; Clear remaining count
JRST .ALTS2] ; And use what we have
ADDM T2,INOCNT ; Accumulate repitition count
PUSHJ P,ALTSSP ; Space over
.ALTS2: POP P,T2
SOJG T2,.ALTS1
POP P,ALTCNT ; Restore counter
POP P,ALTP ; and pointer
MOVE T2,INOCNT ; Restore count
TLNE FL,NEGF ; Backward?
SUBI T2,1 ; Go one less
POPJ P,
.ALTSC: PUSHJ P,GNCH1## ; Swallow line feed
MOVSI T2,1 ; Force end of line with huge count
POPJ P, ; And return
; Common search routine
ALTCS: MOVEI T2,1 ; Create a repeat count
TLNE FL,NEGF ; Backwards?
JRST ALTBCS ; Yes: search backwards
LDB T3,ALTP ; Chec to see if at end of line
CAIN T3,15
POPJ P,
MOVE T1,ALTP ; Get a copy of the pointer
TLNE FL2,L2.SSI ; Suppress?
MOVEI T2,0 ; Yes, clear space count
ALTCS1: TLZN FL2,L2.SSI ; Suppress incrementing?
IBP T1 ; No, increment pointer
LDB T3,T1 ; Get a character
CAIL T3,140 ; Lower case
TDZ T3,AEXACF ; Conditionally convert
CAIE T3,15 ; Done if end of line
CAMN T3,C ; Or a match
POPJ P,
AOJA T2,ALTCS1 ; Else keep count and keep looking
ALTCMP: MOVE T3,[POINT 7,AFSBUF##]; Pointer to alter search buf
MOVE T4,ALTP ; Copy of current pointer
LDB C,T4 ; Current source character
ALTCM1: CAIL C,140
TDZ C,AEXACF
ILDB T1,T3 ; Next target character
JUMPE T1,CPOPJ1 ; Done, it matched!
CAIL T1,140 ; Lower case?
TDZ T1,AEXACF## ; Conditionally fix
CAIE C,(T1) ; Do they match
POPJ P, ; No match this time
ILDB C,T4 ; Get next source character
JRST ALTCM1 ; And compare it too
SUBTTL Commands that Exit the Line: Q, ^U, E, <CR>, <LF> and N
; The Q command
ALTALT: OFFRUB
SKIPE VT52FL ; On a display?
PUSHJ P,[PUSHJ P,ALTBOL ; Position to front of line
XCT TMFCTE ; Clear rest of screen
PUSHJ P,SETALT ; Setup unmodified line
TLZ FL,NEGF ; And let ALTTAB go forward
PJRST ALTTAB##]
SKIPE ALTFLG
PUSHJ P,FINDN##
ONECHO
JRST T1POPJ##
; The N command--advance to next or previous line
ALTNXL: PUSH P,T2 ; Save count
PUSH P,[0] ; Save a zero as a flag
TLZE FL,NEGF ; Clear this before ALTFN
SETOM (P) ; Note that command is negative
PUSHJ P,[PUSHJ P,ALTFN] ; End this line. ALTFN prunes PDL.
JFCL ; Ignore skip return
PUSHJ P,AINSED ; Insert corrected line
SKIPE (P) ; Negative argument?
OUTSTR [ASCIZ/
/] ; Blank line, even if TTY NO BLANKS
ALTNX1: SKIPN (P) ; Forward?
PUSHJ P,FINDN ; Find next
SKIPE (P) ; Backward?
PUSHJ P,FINDB ; Find previous
JUMPE T1,ALTNLN ; If no next line
CAMN T1,PGMK ; Page mark?
JRST ALTNPG ; No next line
PUSHJ P,SETALT ; Setup next line for alter
POP P,T2 ; Get negative flag
SKIPE T2 ; Was NEGF set?
TLO FL,NEGF ; Yes, relight it in the flag register
POP P,T2 ; Restore the count
MOVE T1,LIBUF ; New line number
MOVEM T1,CLN ; Make this current now
; MOVEM T1,HILN ; Redefine top of range
MOVE T1,CPG ; Current page
MOVEM T1,CPGL ; Make it the current logical page
; MOVEM T1,HIPG ; ..and page at top of range
SOJG T2,ALTNXL
POPJ P, ; Continue with this stuff
ALTNLN: RERROR NLN
ALTNL0: SKIPN (P) ; Negative
PUSHJ P,FINDB ; Backup to previous
CAME T1,PGMK ; Is this a page mark?
JRST ALTNL1 ; No
MOVE T2,CPG ; Get the current page
SKIPE (P) ; Going backward?
AOS T2 ; Yes, off by one
PUSHJ P,PGPRN## ; Retype
JRST ALTNL0 ; Go look again
ALTNL1: ADJSP P,-1
POP P,T2
PJRST SETALT
ALTNPG: MOVE T2,CPG ; Current page
SKIPN (P) ; If negative
AOS T2 ; Do not adjust
PUSHJ P,PGPRN## ; Type it so he knows
JRST ALTNX1
; The CR command
ALTFNZ: PUSHJ P,GNCH1##
LDB C,ALTP ; Current character
CAIN C,15 ; End of line?
MOVMS XCMDF ; Indicate CR end
PJRST ALTFN
;
; Here if <LF> was typed without CR
;
ALTEX: SKIPN VT52FL ; On a display?
TRO FL2,SUPN ; No, E means suppress typeout
ALTFN: PUSHJ P,V52TPP ; Make sure display is okay.
SKIPE VT52FL ; On a display?
TRO FL2,SUPN ; Yes, suppress unecessary typeout
PUSHJ P,CSRPOS ; Get cursor position
PUSHJ P,FIXWPC## ; Fix wrap count for wrap waiting
MOVE T5,WRPCNT ; Save count of wraps
PUSHJ P,ALTTAB## ; Space to end of line
TRZ FL2,SUPN ; Clear suppress flag
SKIPN VT52FL ; VT52?
JRST ALTFNX ; No, line was just typed
PUSHJ P,PRNTSZ ; Get the print size of the line
PUSHJ P,FIXWPC## ; Fix wrap count for wrap waiting
SUB T5,WRPCNT ; Difference in line position
LFLUP: JUMPGE T5,ALTFNX ; If none
OUTCHR [12] ; Extra line feed
AOJA T5,LFLUP ; Keep checking
ALTFNX: PUSHJ P,ALTFNL ; Finish the line
JRST T1PPJ1## ; Prune PDL and give skip return
; Routine to finish up line currently being altered and setup NCNT
; for INSED.
ALTFNL: OCRLF
ONECHO ; Get out of non-duplex mode
ALTFN1: ILDB C,ALTP ; Look one chr over
CAIE C,12 ; This should be the line feed
NERROR ILFMT ; Something is wrong
MOVEI C,0 ; Zero remainder of line
ALTFN2: TLNN ALTP,760000 ; All done?
JRST ALTFN3 ; Yes
IDPB C,ALTP ; No, put in another 0
JRST ALTFN2
ALTFN3: SUBI ALTP,LIBUF-1 ; Get size of new line
HRRZM ALTP,NCNT ; And save for insed
POPJ P,
; The ^U command
ALTCU: SKIPE VT52FL
JRST [PUSHJ P,ALTBOL
XCT TMFCTE ; Clear rest of screen
SETOM PRVSIZ ; For retype of whole line
PJRST SETALT]
OFFRUB
OUTSTR [ASCIZ /^U
/]
PJRST SETALT ; Go restart line and forget edit so far
SUBTTL The \ and / commands
; THE / COMMAND -- Transpose the next two letters
; THE \ COMMAND (Same as -/)
ALTBSL: TLC FL,NEGF ; Complement neg flag and do / command
;
ALTSL: TLNE FL,NEGF ; Backward?
JRST ALTSLB ; Backup a couple
ALTSL1: LDB T1,ALTP ; Next character in buffer
MOVE T2,ALTP ; Save its position
ILDB C,ALTP ; and the next one after that
CAIE T1,15 ; Is it carriage return?
CAIN C,15 ; Same
JRST ALTSL2 ; Command not valid at end of line
CAIL C,40 ; Special?
CAIGE T1,40 ; (either one)
SETOM CHGLNF ; Yes, line size might change
OFFRUB
PUSHJ P,OCHR ; Output 2nd character
DPB C,T2 ; And make it the first
MOVE C,T1 ; Now for the second
PUSHJ P,OCHR ; Output it too
DPB C,ALTP ; Add first character to buffer
IBP ALTP ; And advance pointer
PUSHJ P,FORCE ; Make them visible
AOS ALTCNT
AOS ALTCNT ; Increment alter count by two
POPJ P, ; And return
;
ALTSLB: MOVEI T2,2 ; Count for backspace
PUSHJ P,ALTSP## ; Space back two
JRST ALTSL1 ; Join common processing
;
ALTSL2: MOVE ALTP,T2 ; Restore pointer
ADJSP P,-1 ; Pop junk off the PDL
JRST ALTBEL ; Signal error
SUBTTL The J command. Join to Next Line
; The J command
AJOIN: OFFRUB
SETOM PRVSIZ ; Zap this, new line configuration
TLNE FL,NEGF ; Backward?
JRST MJOIN ; This is special
AJOIN0: PUSH P,T2
PUSHJ P,FINDN ; Go see if next line is really there
CAME T1,PGMK
SKIPN T1
JRST [RERROR NNN
PUSHJ P,FINDB ; Refind the line
POP P,T2
JRST RPRINT]
PUSHJ P,GETLTH## ; Get line length, make sure it in core
PUSH P,T1 ; Save length for later
PUSHJ P,ALTTAB## ; Space to end of line
MOVEI T2,1(PNTR) ; Point past line number
HRLI T2,(POINT 7,0,6); Point to first character
MOVEI T3,MXWPL*5-6 ; Maximum length
SUB T3,ALTCNT ; Minus what we already have
PUSH P,ALTP ; Save pointer to this line
JOIN1: ILDB C,T2 ; Fetch a character
DPB C,ALTP ; Store the character in the line
IBP ALTP ; Advance the pointer
CAIN C,12 ; Line feed?
JRST JOIN2 ; Yes, end of line
SOJG T3,JOIN1 ; Loop to end of line
MOVE ALTP,(P) ; Restore ALTP
MOVEI C,15 ; Line feed
IDPB C,ALTP ; Store
MOVEI C,12 ; Line feed
IDPB C,ALTP ; Store
RERROR LTL ; Line too long
POP P,ALTP
PUSHJ P,FINDB
JOINER: POP P,T1
JOINR1: POP P,T2
PJRST RPRINT ; Re-type it
JOIN2: PUSHJ P,INSTRZ ; Add trailing zeros
POP P,ALTP ; Restore ALTP
PUSHJ P,FINDB ; And back to old line
POP P,T1 ; Restore line length
ADDM T1,OCNT ; Increase words to delete
PUSHJ P,INSJLN ; Insert the joined lines
POP P,T2 ; Restore remaining count
SOJG T2,AJOIN0 ; Join as many as he wants
PJRST V52TPN ; Then type line on VT52
SUBTTL The -J command -- Join to Previous Line
; Here for -J command.
MJOIN: PUSH P,T2
PUSHJ P,BUFLEN ; Get length of line
PUSH P,T1 ; Save word count
PUSHJ P,FINDB ; Find the previous line
CAME T1,PGMK
SKIPN T1
JRST [RERROR NLN ; No such line
CAMN PNTR,BUFFIR
PUSHJ P,FINDN
JRST JOINER]
PUSHJ P,GETLTH ; Get length of this one
MOVE T2,T1 ; Make a copy
ADD T2,(P) ; Compute sum
POP P,(P)
CAILE T2,MXWPL+1 ; See if it will fit
JRST [RERROR LTL
CAMN PNTR,BUFFIR
PUSHJ P,FINDN
JRST JOINR1]
ADDM T1,OCNT ; Increment count of words to delete
MOVSI T1,-MXWPL ; Max line length
SETZM LIBUF2(T1) ; Clear a word
AOBJN T1,.-1 ; Loop over whole buffer
SKIPE VT52FL ; On a display?
PUSHJ P,ALTBOL ; Go to beginning of the line
MOVE T4,[POINT 7,LIBUF2]
MOVE T2,[POINT 7,LIBUF+1,6] ; Point to data
;
MJOIN1: ILDB C,T2 ; Get a character from current line
IDPB C,T4 ; Stash in second line buffer
CAIE C,12 ; End yet?
JRST MJOIN1 ; No
PUSHJ P,LOADCL## ; Load that line
MOVE ALTP,[POINT 7,LIBUF+1,6] ; Point to that data
SETZM ALTCNT ; Set count at beginning
MJOIN3: ILDB C,ALTP ; Get a character
CAIN C,15 ; Is it end of text line
JRST MJOIN4 ; Yes
AOS T2,ALTCNT ; Increment count
JRST MJOIN3 ; Loop over whole line
MJOIN4: MOVE T3,[POINT 7,LIBUF2] ; Point to old line
MJOIN5: ILDB C,T3 ; Fetch a character
DPB C,ALTP ; Store this one next
IBP ALTP ; Then increment the pointer
CAIE C,12 ; End of line yet?
JRST MJOIN5 ; No, keep looking
PUSHJ P,INSTRZ ; Add trailing zeros
TLZ FL,NEGF ; Clear neg-flag
PUSHJ P,INSJLN ; Insert the line into the buffer
PUSHJ P,RPRINT
POP P,T2 ; Restore this
SOJG T2,MJOIN
POPJ P,
SUBTTL Support Routines for J and -J Commands
; Subroutine to compute the length of the line in LIBUF
;
BUFLEN: MOVE T2,[POINT 7,LIBUF+1,6] ; First character
MOVEI T1,7 ; Minimum length
BUFLN1: ILDB C,T2 ; Character
CAIE C,12 ; End of line?
AOJA T1,BUFLN1 ; Increment count and keep looking
ADDI T1,4 ; Round to whole words
IDIVI T1,5 ; Compute words required
POPJ P,
; Subroutine to install a joined line
; Call
; New line in LIBUF, OCNT setup with length of old lines
; Returns with OCNT set to old value of NCNT, line in buffer
;
INSJLN: PUSHJ P,BUFLEN ; Words in joined line
MOVEM T1,NCNT ; Insert that many
PUSHJ P,INSED ; Install the new line
MOVE T1,NCNT
MOVEM T1,OCNT ; Make that the old count
POPJ P,
; Routine to add trailing zeros to the last word in the line
; Call with ALTP setup pointing to first character after the LF
INSTRZ: MOVEI C,0 ; Get a zero
INSTR1: DPB C,ALTP ; Add one
TRNN ALTP,760000 ; At end of word?
POPJ P, ; Yes, done
IBP ALTP ; No, advance one character
JRST INSTR1 ; And clear next
SUBTTL The W Command -- Space Over by Words
; The W command
ALTBSW: TLC FL,NEGF ; Same as space only backward
ALTWD: MOVEI T1,ALTSP## ; Set spacing routine
;
.ALTWD: MOVEM T1,ALTWPR ; Process to perform for word stuff
OFFRUB
;
ALTWD1: PUSH P,ALTP ; Save pointer
TLNN FL,NEGF ; Going backward
TDZA T1,T1 ; Set T1 to zero and skip
SETO T1, ; Set T1 to -1
PUSH P,T1 ; Sum of characters seen in word skip
PUSH P,T2 ; Save count if any
;
ALTWD2: TLNE FL,NEGF ; If forward
JRST ALTWD3 ; If going backward
;
PUSHJ P,ALTWS ; Skip over word
JRST ALTWD4 ;
;
ALTWD3: PUSHJ P,ALTWBS ; Move to beginning of previous word
AOS -1(P) ; Fudge factor
;
ALTWD4: ANDI T2,-1 ; Clr flag in case
ADDM T2,-1(P) ; Tally spacing count
SOSLE (P) ; Count down number of words
JRST ALTWD2 ; Loop again if more to do
;
POP P,(P) ; Clear counter from stack
POP P,T2 ; Get length of words skipped
POP P,ALTP
PJRST @ALTWPR ; Do specified operation
; Routine to skip over next word
ALTWS: HRROI T2,0 ; Set flg and count
LDB T3,ALTP ; Get current character
JRST .+2 ; Skip increment
ALTWS1: ILDB T3,ALTP ; Get a character
CAIN T3,15 ; Done if end of line
ALTWS2: POPJ P, ; Quit
MOVE T3,CTBL(T3) ; Fetch character table entry
JUMPE T3,ALTWS4 ; Skip blanks etc...
ANDI T2,-1 ; Clr flag
JUMPG T3,ALTWS3 ; Skip letters & numbers
TRNN FL2,QSEPF ; Separators
TRNN T3,NSEPF ; Today
JRST IPOPJ ; Real break - quit!
ALTWS3: AOJA T2,ALTWS1 ; Keep count and continue
ALTWS4: JUMPL T2,ALTWS3 ; First blnks
AOS T2
ALTWS5: ILDB T3,ALTP
CAIE T3,15 ; Quit on CR
SKIPE CTBL(T3) ; Or first non-blank
POPJ P,
AOJA T2,ALTWS5
IPOPJ: TRNE T2,777777 ; Test count for zero
POPJ P, ; Non-zero: just return
IBP ALTP ; Increment alter pointer
AOJA T2,CPOPJ ; Increment count and return
SUBTTL Commands that Process by Words. T, Z, and #.
; The T command
ALTWX: SKIPN NEWCMD ; COPATIBILITY MODE?
JRST CLTEOL ; YES--TREAT LIKE X
CLTWX: PUSHJ P,ALTZNK ; Delete the words
PUSHJ P,V52TYP ; Fix line
PJRST ALTINZ ; Do insert
; THE Z COMMAND -- Zonk the next word
ALTZNK: MOVEI T1,ALTDL ; Processing is deleting
PJRST .ALTWD
; The # command; change case for words
ALTCHW: SKIPN NEWCMD ; COMPATIBILITY MODE?
JRST CLTXCH ; YES--TREAT LIKE V
CLTCHW: MOVEI T1,ALTCHG ; Processing is case change
PJRST .ALTWD ; Now go do it
SUBTTL The C Command
; The C command
ALTCN: OFFRUB
TLNN FL,NEGF ; Going forward?
JRST ALTCN2
PUSH P,T2 ; Save count
PUSHJ P,ALTSP## ; Backup
EXCH T2,(P)
SUB T2,(P)
POP P,T1
ALTCN2: LDB C,ALTP ; At end of line?
CAIN C,15
POPJ P, ; Yes, stop
CAIGE C," " ; Normal graphic character?
SETOM CHGLNF ; No, line size may change then
ALTCN1: PUSHJ P,AGNCH1## ; Get a character
CAIE C,177 ; Do not let him insert a rubout
CAIN C,12 ; Ignore carriage return
JRST ALTCN1
CAIE C,33 ; Stop on altmode and line feed
CAIN C,15
POPJ P,
CAIGE C," " ; Normal graphic character?
SETOM CHGLNF ; No, line size may change then
PUSHJ P,FOCHR## ; Duplex character
DPB C,ALTP ; Replace it
IBP ALTP ; Advance pointer
AOS ALTCNT ; And count
PUSHJ P,V52TPN ; Clean up the line
SETZM CHGLNF ; Clear flag if set
SOJG T2,ALTCN2 ; Continue
POPJ P,
SUBTTL Spacing Routines
; Subroutine to move alter pointer without changing display
; Call like ALTSP
ALTSSP: TLNE FL,NEGF ; Silent Space backward?
JRST ALTSBS ; Do silent back space then
ALTSS1: LDB C,ALTP ; Fetch a character
CAIN C,15 ; See if it is a CR
POPJ P, ; It is, so stop
IBP ALTP ; No, increment pointer
AOS ALTCNT ; and count
SOJG T2,ALTSS1 ; Loop until space request satisfied
POPJ P, ; Then return
; Here for silent space backward
ALTSBS: PUSHJ P,ALTBAK ; Backup
JUMPE T3,CPOPJ ; Stop if beginning of line
SOS ALTCNT ; Decrement counter
SOJG T2,ALTSBS ; Loop until request satisfied
POPJ P, ; Then return
; The backspace command
ALTBS: PUSHJ P,ALTBAK ; Get previous char
JUMPE T3,ALTCBS ; Jump if done
ONRUB
SOS ALTCNT ; Decrease count
MOVE C,T3
SKIPN DPYFLG ; Non display device?
PUSHJ P,OCHR
SKIPE DPYFLG ; On a display?
PUSHJ P,RUBAK## ; Backspace the real way
SOJG T2,ALTBS ; More, more
PJRST FORCE
ALTCBS: PUSHJ P,FORCE ; Finish buffer
SKIPN DPYFLG ; Just return if on display
JRST ALTCB1 ; Normal mode, output SN.
SETZ T1, ; Clear T1 to avoid ill mem ref
POPJ P,
PRNTSN: PUSHJ P,FORCE ; Finish print line
ALTCB1: OFFRUB ; No more rub
SKIPN VT52FL
OCRLF
SKIPE VT52FL
OUTCHR [15]
MOVE T1,LIBUF ; Also print seq num
PJRST OUTSN
; The L command
ALTLN: SKIPE VT52FL ; On a fancy display?
JRST [PUSHJ P,ALTBOL ; Position to front
JRST ALTLNN] ; Then re-type sequence number
MOVEI T2,1000 ; Finish printing the line
PUSHJ P,ALTSP##
ALTLNN: MOVE ALTP,[POINT 7,LIBUF+1,13]; Pointer to start
SETZM ALTCNT ; Reset count
PJRST PRNTSN ; And reprint line number
; Common routines to backup in a line
ALTBAK: CAMN ALTP,[POINT 7,LIBUF+1,13]
PJRST ALTRTZ ; Return zero if at beginning
ADD ALTP,[POINT 0,0,28]
TLNE ALTP,(<1B0>) ; Check word overflow
SUB ALTP,[POINT 0,1,0]
LDB T3,ALTP ; Get char
POPJ P,
;
ALTRTZ: MOVEI T3,0 ; Return 0
POPJ P,
SUBTTL Backward Deletion Routine
; Routine to do backwards deletion
ALTBDL: MOVEM ALTP,SVALTP ; Save pntr
ALTBD1: PUSHJ P,ALTBAK ; Back a char
JUMPE T3,ALTBD2 ; Done if no more
SOS ALTCNT ; Decrement count
MOVE C,T3 ; For printing
PUSHJ P,ALTDPN
SOJG T2,ALTBD1
ALTBD2: PUSHJ P,FORCE ; Force printing
PUSH P,ALTP ; Save new pntr
MOVE T3,SVALTP ; Get set to move line
ALTBD3: LDB C,T3
DPB C,ALTP ; Move char
JUMPE C,APOPJ ; Done if zero
IBP T3 ; Advance pntrs
IBP ALTP
JRST ALTBD3
;CSRPOS -- Routine to return the relative cursor position
;
;Call with
; PUSHJ P,CSRPOS
; <Return here with position in T4, wrap count in WRPCNT>
;Uses T1, T2, T4 and C
CSRPOS: MOVE T2,[POINT 7,LIBUF+1,6]; Initialize pointer a line start
LDB T4,PMTSZP## ; Get prompt length
SETZM WRPCNT## ; Zero the wraparound count
JSP T1,.+1 ; Set up T1 for later returns
RBK0: ILDB C,T2 ; Next character from buffer
CAME T2,ALTP ; Up to current position yet
JRST RBC## ; Compute length of this character
POPJ P, ; Return, size is in T4
; Routine to do backwards search
ALTBCS: PUSH P,ALTP ; Save pntr
ADDI T2,1 ; Advance pointer
PUSHJ P,ALTBAK ; Don't look at first character
ALTBC1: PUSHJ P,ALTBAK ; Prev char
JUMPE T3,APOPJ ; End of line
CAIL T3,140
TDZ T3,AEXACF
CAME T3,C ; Match?
AOJA T2,ALTBC1 ; No: count and continue
JRST APOPJ## ; Restore ALTP and return
; Routine to do a backward word search
ALTWBS: HRROI T2,0 ; Set flag and count
ALTWB1: PUSHJ P,ALTBAK ; Get the previous character
JUMPE T3,CPOPJ ; and return if at beginning of line
MOVE T3,CTBL(T3) ; Look up character in the char table
JUMPE T3,ALTWB3 ; Skip over spaces and so forth
ANDI T2,-1 ; and signal that we found something
JUMPG T3,ALTWB2 ; Skip letters and numbers
TRNN FL2,QSEPF ;
TRNN T3,NSEPF ; Seperator flag set?
POPJ P, ; Restore ALTP and return
ALTWB2: AOJA T2,ALTWB1 ; Increment character count and loop
ALTWB3: JUMPGE T2,CPOPJ ; If not first blanks
AOJA T2,ALTWB1 ; Continue looking
SUBTTL Support Routines for Fancy Display Version of ALTER Mode
; Routine to re-type line after a control-C
; Call with
; PUSHJ P,CCRTYP
; <Return here>
$CRTYP::
MOVEI T1,0 ; Be sure tabs are clear
PUSHJ P,SETTAB## ; ...
PUSHJ P,RPRINT ; Re-type the first part
SETOM PRVSIZ ; Force typeout
PJRST V52TPN ; Go retype the line without delay
; V52TYP -- Routine to retype the line currently being altered
;
; This routine checks VT52FL so it can be used even if this flag has
; not been selected. Ensures that the current screen image matches
; the internal line image. The refresh is not performed if there
; is a character waiting to be typed, or the specified refresh delay
; has not elapsed. (/REFDLY).
;
; Call V52TPN if the line should be refreshed immediately without
; waiting for REFDLY milliseconds.
V52TPI: SKIPE V52SPF## ; Suppressing intermediate typeout?
POPJ P, ; Yes, return
PUSHJ P,V52TYP ; Type the line again
SETZM CHGLNF ; Clear typeout flag
POPJ P, ; And return
V52TYP: SKIPE T1,REFDLY ; Does he want a delay (slow terminal)
HIBER T1, ; Yes wait for time or next character
JFCL ; No HIBER or no wait
V52TPN: SKIPLE T1,TSPEED ; GET USER TERMINAL SPEED
CAML T1,BAUD ; FAST ENOUGH FOR UPDATE?
CAIA ; YES
POPJ P, ; NO--DONT DO IT
V52TPP: SKPINC ; Is he ahead?
SKIPN VT52FL ; Or not on a VT52?
POPJ P, ; Yes, skip this stuff then
TRNE FL2,SUPN ; Suppressing?
POPJ P, ; Yes, no typeout
LDB C,ALTP ; Current character
CAIN C,15 ; End of line
SKIPN DELBAK ; and deleting backward
CAIA
PJRST SETPVS## ; Yes, line is okay. Update PRVSIZ.
PUSH P,FL ; Save flags
PUSH P,T2 ; and count
TLZ FL,NEGF ; Always type forward
CONT.
;
; Get the length of the new line it can be compared with the old
;
PUSHJ P,PRNSZC ; Get display length in characters
MOVE T4,T1 ; Save in T4
CAME T4,PRVSIZ## ; Same as last time?
JRST V52TP2 ; No
SKIPN CHGLNF ; Does this command change line size?
JRST V52TP4 ; No, just return after restoring AC's
;
; We must have done a insert, delete or change. Since the whole
; line is the same length, there must be a tab taking up the
; difference. Type all characters until we find a tab or EOL.
;
PUSH P,ALTP ; Save the pointer
CHKTB1: LDB C,ALTP ; Load next character
PUSHJ P,OCHR## ; No, type it
CAIE C,15 ; End of line
CAIN C,"I"-100 ; or tab
JRST CHKTB2 ; If yes
IBP ALTP ; Increment the pointer
JRST CHKTB1 ; And type till we find a tab
CHKTB2: PUSH P,T4 ; Save line size
PUSHJ P,CSRPOS ; Get cursor position
PUSHJ P,FIXWPC## ; Fix line wrap count
POP P,T4 ; Get T4 back
POP P,ALTP ; and the pointer
JRST V52TP6 ; Go retype the first part of the line
CONT.
; Here if the line size is different than it was last time
;
V52TP2: EXCH T4,PRVSIZ ; Get old size, save new
JUMPL T4,V52TP5 ; If explicit request to retype the line
SUB T4,PRVSIZ ; Compute difference
JUMPG T4,V52TP5 ; If new size smaller
LDB C,ALTP ; Look at current character
CAIN C,15 ; Is it a carriage return
JRST V52TP4 ; If line grew at EOL, screen still OK
V52TP5: PUSH P,ALTCNT ; Save count
PUSHJ P,ALTTAB## ; Print rest of the line
POP P,ALTCNT ; Restore the alter character count
MOVEI C," " ; Blank to use as eraser
SKIPG T4 ; Line shrank?
MOVEI T4,0 ; No
SKIPE T1,T4 ; Save difference
ERSLUP: PUSHJ P,OCHR ; Type a blank
SOJG T4,ERSLUP ; Over and over till done
ADD T1,PRVSIZ ; Get previous size
SUBI T1,1 ; End of line causes special problems
IDIV T1,LINEW ; Compute number of wraps
MOVEM T1,WRPCNT ; and set it up
V52TP6: PUSHJ P,FORCE## ; Force pending output
PUSHJ P,UPCRSR## ; Move cursor up if needed
PUSHJ P,RPRINT ; Reprint the first part of the line
V52TP4: POP P,T2 ; Restore the count
POP P,FL ; and the flags
POPJ P, ; Finally, return
;PRNSZC -- Get print size in characters
;
;Call
; PUSHJ P,PRNSZC
; <Return here with character count in T1>
;Uses T1, C
PRNSZC: PUSHJ P,SAVR## ; Preserve T3-T5
PUSH P,T2 ; Save T2
PUSHJ P,PRNTSZ ; Measure print size of line
MOVE T1,WRPCNT ; Get number of whole lines
IMUL T1,LINEW ; Times width of one line
ADD T1,T4 ; Plus characters on last line
JRST T2POPJ## ; Restore T2 and return
;PRNTSZ -- Get the print size of the current line
;
;Call
; PUSHJ P,PRNTSZ
; <Size in T4, line count in WRPCNT>
;Uses C, T1, T2, T4
PRNTSZ: SETZB T4,WRPCNT ; Size counter
MOVE T2,[POINT 7,LIBUF+1,6]
TLNE FL2,LNUMF ; Printing line numbers?
MOVEI T4,^D8 ; If yes, line number is 1 tab stop
CNTLUP: ILDB C,T2 ; Get a character
CAIN C,15 ; End of line?
POPJ P,
JSP T1,RBC## ; Size chacacter, return through T1
JRST CNTLUP ; Loop over whole line
END