Trailing-Edge
-
PDP-10 Archives
-
tops20_version7_0_tools_tape_clock_tape
-
tools/sed/sed1cm.mac
There are 10 other files named sed1cm.mac in the archive. Click here to see a list.
TITLE SED1CM - GENERAL SED FILE-CHANGING COMMANDS
SUBTTL A CHRISTOPHER HALL FECIT
SEARCH SEDSYM
SALL
IFN TOPS10,<
SEARCH UUOSYM
TWOSEG
RELOC 400000
>
IFE TOPS10,<
SEARCH MONSYM
>
;HERE ON LINEFEED, WHICH ERASES THE LINE THAT THE CURSOR GOES TO
;NOTE: this command is obsolete; replaced by ERASE-LINE
LNFPAR::TLNN TM,LSD ;IS LINEFEED REALLY A CURSOR DOWN?
JRST KILPAR ;NO - DELETE ENTIRE PARAMETER
MOVEI DO,$CURDN ;YES - DO A DOWN INSTEAD
JRST DWNARG
KILPAR::MOVE T1,[POINT 7,PARBUF] ;POINT TO START OF PARAMETER BUFFER
MOVEM T1,PARPTR
TRZN F,CMV ;CLEAR CURSOR MOVE FLAG - ON?
JRST ENTERM ;NO - CLEAR BOTTOM LINE, PROMPT, AND LOOP
DMOVE RW,SAVPOS ;YES - RESTORE SAVED POSITION
JRST ENTERM ;NOW CLEAR, PROMPT, AND LOOP
LNFEED::TLNE TM,LSD ;IS LINEFEED REALLY A CURSOR DOWN?
JRST [MOVEI DO,$CURDN;YES - DO A DOWN INSTEAD
JRST DOWN]
TRNE F,RDO ;IS FILE READ-ONLY?
JRST RDOERR ;YES - COMMAND IS ILLEGAL
SOS ISVCNT ;DECREMENT INCREMENTAL SAVE COUNTER
TLO F,CHG ;SAY FILE HAS BEEN MODIFIED
CAMN RW,LPP.1 ;AT BOTTOM OF SCREEN?
JRST LNFERR ;YES - ILLEGAL
AOJ RW, ;MOVE TO NEXT ROW
MOVEI T1,15 ;MOVE TO START OF LINE
IDPB T1,TY
PUSHJ P,CDOWN ;MOVE DOWN ONE
PUSHJ P,CLRLNA ;ERASE THE ENTIRE LINE
PUSHJ P,POSCUR
TLZ F,XPL!PCM ;SAY LINE POINTER IS BE GOOD; KILL MARK
PUSHJ P,MAKLPT ;AND MAKE IT (IN LINPTR AND PT)
SETZ T2, ;GET A NULL
LNFED1: ILDB T1,PT ;GET A CHARACTER
CAIN T1,15 ;CARRIAGE RETURN?
JRST LNFED3 ;YES - CHECK FOR END OF LINE
LNFED2: DPB T2,PT ;ELSE NULL OUT THE CHARACTER
JRST LNFED1 ;AND GET ANOTHER
LNFED3: PUSHJ P,ISCRLF ;IS IT REALLY A CRLF?
JRST LNFED2 ;NO - JUST NULL OUT THE <CR>
TLO F,XPC ;SAY CHARACTER POINTER IS BAD
JRST LOOP ;DONE
LNFERR: MOVEI T1,[ASCIZ /#Can't erase last line of display/]
JRST ERROR
;HERE TO ERASE ALL CHARACTERS FROM THE CURSOR TO THE END OF THE LINE
;ENTER ERASE-LINE ERASES PARAMETER (KILPAR)
ERASLN::TRNE F,RDO ;IS FILE READ-ONLY?
JRST RDOERR ;YES - COMMAND IS ILLEGAL
MOVEI T1,^D1000 ;SET TO CLOSE A LOT OF SPACES
JRST CLSNP0 ;LET CLOSE-SPACES HANDLE IT
;**********************************************************************
;HERE TO MOVE TO THE BEGINNING OF THE LINE, UNLESS CURSOR IS AT BEGINNING,
;IN WHICH CASE IT MOVES TO THE END
LINARG::TRON F,CMV ;ALREADY DOING CURSOR MOVEMENT?
PUSHJ P,MARKUP ;NO - PUT CURSOR BACK IN TEXT
LINE:: TDZN CM,CM ;MOVE TO THE BEGINNING - ALREADY THERE?
JRST LINEND ;YES - MOVE TO END INSTEAD
TLO F,XPC ;CHARACTER POINTER IS BAD
JRST DISCUR ;DISPLAY THE CURSOR AND LOOP
LINEND::TLO F,XPC!XPL ;CHARACTER AND LINE POINTERS ARE BAD
AOJA RW,WBTAB ;GO DO A WORDWISE BACKTAB FROM NEXT LINE
;**********************************************************************
;HERE ON ENTER-CONTROL-CHARACTER COMMAND. SET FLAG SO IF NEXT
;CHARACTER IS ASCII IT WILL BE MADE A CONTROL CHARACTER
;(ELSE THERE IS NO EFFECT)
ENTCCH::TLO F,CCH ;SET THAT OL' FLAG
IFE TOPS10,<
IFN FTECHO,<
PUSHJ P,EKOALL ;BREAK ON NEXT CHARACTER AND DON'T ECHO IT
>>
JRST LOOP ;THAT'S ALL
;**********************************************************************
;HERE ON INSERT MODE TOGGLE COMMAND. SET FLAG SO CHARACTERS TYPED
;WILL BE INSERTED AT CURSOR POSITION, AND NOT REPLACE THE EXISTING CHARACTER
;TYPING THE COMMAND AGAIN REVERSES THIS EFFECT
INSMOD::TRC F,IMD ;TOGGLE THE INSERT MODE FLAG
TRNE F,XCT!XBN ;EXECUTING?
JRST LOOP ;YES - DONE NOW
IFE TOPS10,<
IFN FTECHO,<
PUSHJ P,INSBP2 ;TURN ECHO ON OR OFF DEPENDING ON MODE
>>
TLNE TM,BEP ;WANT TO BEEP INSTEAD OF WORKING WITH MESSAGE?
JRST INSBEP ;YES - GO DO SO
PUSHJ P,FIXBLN ;NO - REPAIR THE BOTTOM LINE
PUSHJ P,POSCUR ;REPOSITION THE CURSOR
JRST LOOP ;AND LOOP
INSBEP: TRNE F,IMD ;NOW IN INSERT MODE?
JRST INSBP1 ;NO - BEEP ONCE
TYPCHI 207 ;BEEP ONCE
SNOOZE ^D0400 ;WAIT A WHILE
INSBP1: TYPCHI 207 ;BEEP AGAIN
JRST LOOP
IFE TOPS10,<
IFN FTECHO,<
INSBP2: TRNN F,IMD ;IN INSERT MODE?
JRST EKONPT ;NO - BREAK ON NON-PRINTING CHARACTERS
JRST EKOALL ;NO - NO ECHO; BREAK ON ALL CHARACTERS
>>
;**********************************************************************
;SAVE-THE-FILE COMMAND
SAVEIT::TRNN F,RDO ;IS FILE READ-ONLY,
TLNN F,CHG ; OR UNMODIFIED?
JRST SAVITX ;YES - DON'T TRY TO SAVE IT
PUSHJ P,INCSAV ;SAVE THE FILE
JRST LOOP ;THAT'S ALL
SAVITX: MOVEI T1,[ASCIZ /####File not changed - not saved/]
JRST ERROR
;SUBROUTINE TO DO AN INCREMENTAL SAVE
INCSAV::DMOVE T1,ISVNUM ;RESET COMMAND INCREMENTAL SAVE COUNT
DMOVEM T1,ISVCNT ;AND TYPEIN INCREMENTAL SAVE COUNT
MOVEI T1,SQZVAL ;RESET # OF COMMANDS TO SKIP BETWEEN SQUEEZES
MOVEM T1,SQZCNT
TRNN F,RDO ;IS FILE READ-ONLY?
TLNN F,CHG ;NO - HAS IT BEEN MODIFIED?
POPJ P, ;READ-ONLY OR NOT MODIFIED - DON'T SAVE FILE
MOVEI T1,[ASCIZ /SAVING FILE - WAIT/]
PUSHJ P,PUTBTM ;PUT MESSAGE ON BOTTOM LINE
PUSHJ P,PROTOF
PUSHJ P,PUTTYP
IFN TOPS10,<
MOVEI PT,FILBLK ;POINT TO NAME OF CURRENT FILE
>
MOVEI T4,FILSPC
SKIPE INJFN ;IS THERE A JFN?
PUSHJ P,SAVFLC ;YES - SAVE THE FILE
IFN FTJOUR,<
TLNE TM,JRW ;WRITING A JOURNAL?
PUSHJ P,JRNSTT ;YES - START UP A NEW ONE
>
IFN TOPS10,<
TLO F,XPL!XPC ;LINE AND CHARACTER PTRS ARE NOW BAD
PUSHJ P,FIXBLN ;REPAIR THE BOTTOM LINE
JRST POSCUR ;RE-POSITION THE CURSOR AND RETURN
>
IFE TOPS10,<
TRO F,GFL ;NOTE THAT FILE IS EXISTS
TLO DO,500000 ;TELL SET-FILE THAT INCSAV CALLED IT
POP P, ;KILL CALL TO INCSAV
JRST SETFL1 ;CONNECT TO THE FILE AGAIN; GET NEW COMMAND
>
;**********************************************************************
;HERE TO ADD BLANK LINES TO THE BUFFER
OPENLN::TRNE F,RDO ;IS FILE READ-ONLY?
JRST RDOERR ;YES - COMMAND IS ILLEGAL
MOVE T4,ADDLNS ;GET LAST TIME'S NOMINAL
TLNN F,ENT ;IS THERE A PARAMETER TYPED?
JRST OPLNPM ;NO - USE THE ONE ALREADY SET UP
MOVEM T4,PARG1
PUSHJ P,PEEL.1 ;READ NEW PARM, IF ANY
MOVE T4,PARG1 ;GET LINES TO ADD
MOVEM T4,ADDLNS ;SAVE AS NEW NOMINAL
TRNE F,CMV ;CURSOR MOVEMENT?
JRST [MOVE T1,PARG2 ;YES - GET SPACES TO OPEN, TOO
ADD T1,SAVPOS+1 ;COUNT SPACES FROM LEFT MARGIN
ADD T1,SL
MOVEM T1,ADDLSP
JRST OPLNP0]
SETZM ADDLSP ;IF NO CURSOR MOVE, CLEAR EXTRA SPACES
OPLNP0: PUSHJ P,ERASPM ;RESET ENTER MODE
TLNE TM,XCI ;INITIALIZING FOR AN EXECUTE?
JRST LOOP ;YES - DONE NOW
OPLNPM::JUMPLE T4,CLSLNE ;DONE, IF OPENING ZERO LINES
SOS ISVCNT ;DECREMENT INCREMENTAL SAVE COUNTER
TLZ F,PCM ;CANCEL THE PICK-CLOSE MARK, IF ANY
PUSHJ P,MAKCPT ;RE-MAKE CURSOR POSITION
CAIN T3,11 ;IS CHARACTER AT CURSOR A TAB?
PUSHJ P,RPLTAB ;YES - REPLACE IT WITH SPACES
MOVE T4,ADDLNS ;GET LINES TO ADD
LSH T4,1 ;MULTIPLY COUNT BY 2, FOR <CR><LF>
MOVEM T4,NUMCHR ;GO ADD THAT MANY <LF>S
MOVEI T1,12 ; (CHANGE HALF OF 'EM TO <CR>S LATER)
MOVEM T1,CHARAC
PUSHJ P,MAKCHR
TLO F,XPB!CHG ;SAY BOTTOM POINTER BAD; FILE MODIFIED
MOVEI T1,15 ;NOW CHANGE HALF THE <LF>S TO <CR>S
MOVE PT,CHRPTR ;GET POINTER TO CURSOR POSITION
MOVE T4,ADDLNS ;AND NUMBER OF LINES TO ADD
IDPB T1,PT ;SET UP A NEW LINE
IBP PT
SOJG T4,.-2 ;LOOP UNTIL ALL LINES SET UP
SKIPG T4,ADDLSP ;NOW GOT SOME SPACES TO ADD?
JRST OPNLD0 ;NO - JUST RE-DISPLAY
MOVEM T4,NUMCHR
EXCH PT,CHRPTR
PUSH P,PT
PUSHJ P,MAKSPC ;ADD THE SPACES
POP P,PT ;RESTORE THE REAL CHARACTER POINTER
EXCH PT,CHRPTR
OPNLD0: MOVE T4,ADDLNS ;GET SIZE OF OPEN
;@@ bug here - ADDLSP shouldn't be reset below
TRNN F,RST ;WANT TO RESTORE THE NOMINAL PARAMETERS?
JRST OPNLDA ;NO - SKIP THIS
MOVEI T1,1
MOVEM T1,ADDLNS ;YES - SET BACK TO ONE LINE
SETZM ADDLSP ; AND NO SPACES
OPNLDA: PUSHJ P,OPENLD ;OPEN UP THE SCREEN **MAY NOT RETURN**
JUMPN CM,OPNLDX ;JUMP IF STARTING WITHIN A LINE
SKIPN ADDLSP ;WERE SPACES ADDED TOO?
JRST OPLDX1 ;NO - JUST POSITION AND LOOP
PUSHJ P,CDOWN ;ELSE MOVE DOWN
OPNLDX: PUSHJ P,DISONE ;RE-DO THAT LINE
OPLDX1: PUSHJ P,FIXBLW ;PUT MESSAGES, IF ANY, ON THE BOTTOM LINE
JRST DISCUR ;RE-POSITION CURSOR AND LOOP
;SUBROUTINE TO OPEN (T4) LINES ON THE SCREEN (USED BY OPENLN, PUT)
;NOTE: WILL NOT RETURN IF REST OF SCREEN MUST BE DISPLAYED (JRSTS TO LOOP)
;IF INSERT IS LONGER THAN LINES BELOW THE CURSOR,
; IF TERMINAL CAN CLEAR TO EOP, DO THE CLEAR (RETURN IF PUT, ELSE LOOP)
; ELSE DISPLAY THE ENTIRE SCREEN (LOOP)
;ELSE IF INSERT FITS WITHIN THE SCREEN
; IF TERMINAL CAN INSERT LINES, INSERT THEM (RETURN)
; ELSE IF CURSOR IS HOME AND TERMINAL CAN ROLL DOWN, ROLL DOWN (RETURN)
; ELSE DISPLAY FROM CURSOR TO END OF SCREEN (LOOP)
OPENLD::MOVE T1,LPP(TM) ;FIND NUMBER OF LINES BELOW CURSOR
SUB T1,RW
CAMG T1,T4 ;ADDING MORE THAN THAT?
JRST OPNLD2 ;YES - KILL THE RETURN
SKIPN T3,ILN(TM) ;CAN TERMINAL OPEN ITS OWN LINES?
JRST OPNLDR ;NO - GO REDISPLAY FROM HERE DOWN
PUSHJ P,POSCUR ;YES - POSITION THE CURSOR
TLZ F,FBL ;BOTTOM LINE WILL BE IN GOOD SHAPE
JUMPE CM,OPLD1A ;WITHIN A LINE?
PUSHJ P,CLRLNR ;YES - CLEAR TO END OF LINE
MOVEI T1,15 ;DROP TO START OF NEXT LINE
IDPB T1,TY
OPNLD1: PUSHJ P,CDOWN
OPLD1A: MOVE T1,T3 ;OPEN UP ONE LINE
PUSHJ P,PUTSEQ
SOJG T4,OPNLD1 ;LOOP THROUGH ALL LINES
POPJ P, ;DONE
OPNLD2: SKIPN CPG(TM) ;IS THERE A SEQUENCE FOR CLEAR-TO-EOP?
JRST DISALL ;NO - GO DISPLAY ENTIRE SCREENFUL
PUSHJ P,POSCUR ;YES - REPOSITION THE CURSOR
PUSHJ P,CLEARP ;CLEAR TO END OF SCREEN
CAIN DO,$PUT ;GOT A PUT COMMAND?
POPJ P, ;YES - RETURN TO PUT THE BUFFER
POP P, ;NO - KILL RETURN TO CALLER
PUSHJ P,PUTTYP ;OUTPUT ALL THIS
JRST LOOP ;AND GET A NEW COMMAND
OPNLDR: JUMPN RW,OPLDR1 ;IF NOT HOME JUST DO DISPLAY
JUMPN CM,OPLDR1
SKIPE RLD(TM) ;NO ROLL DOWN SEQUENCE,
CAML T4,LPP(TM) ; OR INSERTING LONGER THAN SCREEN SIZE?
JRST OPLDR1 ;YES - DISPLAY ANYWAY
PUSHJ P,CHOME ;HOME THE CURSOR
PUSHJ P,ROLLDN ;ROLL AND CLEAR A LINE
SOJG T4,.-1 ;DO THE PHYSICAL ROLL OF THE SCREEN
POPJ P, ;DONE
OPLDR1: POP P, ;DISPLAY FROM HERE DOWN AND LOOP
JRST DISDWN
;HERE TO REMOVE LINES FROM THE BUFFER (NULL THEM OVER, REALLY)
CLOSLN::TRNE F,RDO ;IS FILE READ-ONLY?
JRST RDOERR ;YES - COMMAND IS ILLEGAL
MOVE T4,ADDLNS ;SET UP LAST TIME'S NOMINAL
TLNN F,ENT ;IS THERE A PARAMETER TYPED?
JRST CLLNPM ;NO - USE THE ONE ALREADY SET UP
MOVEM T4,PARG1
PUSHJ P,PEEL.1 ;READ NEW PARM, IF ANY
MOVE T4,PARG1 ;GET SPACES TO ADD
MOVEM T4,ADDLNS ;SAVE AS NEW NOMINAL
TRNE F,CMV ;CURSOR MOVEMENT?
JRST [MOVE T1,PARG2 ;YES - GET SPACES TO CLOSE, TOO
ADD T1,SAVPOS+1 ;COUNT SPACES FROM LEFT MARGIN
ADD T1,SL
CAIN T4,0 ;CLOSING ZERO LINES?
MOVE T1,PARG2 ;YES - COUNT ONLY SPACES PASSED OVER
MOVEM T1,ADDLSP ;SAVE NUMBER OF SPACES TO CLOSE
JRST CLOSL1] ;(SKIP THE SETZ)
SETZM ADDLSP ;IF NO CURSOR MOVE, CLEAR EXTRA SPACES
CLOSL1: PUSHJ P,ERASPM ;ERASE PARAMETER
TLNE TM,XCI ;INITIALIZING FOR AN EXECUTE?
JRST LOOP ;YES - DONE NOW
CLLNPM::DMOVE T1,ADDLNS ;MOVE NOMINALS TO FRAGGABLE AREA
DMOVEM T1,ADDLNX
SOS ISVCNT ;DECREMENT INCREMENTAL SAVE COUNTER
TLNE F,PCM ;HAS A MARK BEEN MADE?
JRST CLSMRK ;YES - DO THINGS DIFFERENTLY
JUMPG T4,CLSLN0 ;IF CLOSING SOME LINES, CONTINUE
SKIPN ADDLSX ;IF ZERO LINES, GOT ZERO SPACES TOO?
JRST CLSLNE ;YES - NOTHING TO DO
CLSLN0: MOVEM T4,ROLLS ;SAVE NUMBER OF LINES FOR ROLLING AT END
TLO F,INS!XPB!CHG ;LET LINE BE EXTENDED; BOTPTR BAD; FILE MOD'D
PUSHJ P,MAKCPT ;RE-MAKE CURSOR POSITION
TLZ F,INS
CAIN T3,11 ;IS CHARACTER AT CURSOR A TAB?
PUSHJ P,RPLTAB ;YES - REPLACE WITH SPACES BEFORE CURSOR
MOVE PT,CHRPTR ;GET CURRENT CURSOR POSITION
PUSHJ P,CLSGPT ;SET UP THE POINTER INTO THE DELETE BUFFER
SETZ T2, ;GET A NULL
SKIPN T4,ADDLNX ;GET NUMBER OF LINES TO CLOSE - ANY?
JRST CLSLN3 ;NO - JUST GO CLOSE SPACES
CLSLN1: CAMN EN,PT ;AT END OF USEABLE BUFFER?
JRST CLOSEN ;YES - DO END OF BUFFER-Y THINGS
ILDB T1,PT ;GET A CHARACTER
JUMPE T1,CLSLN1 ;IF NULL, GET ANOTHER ONE
DPB T2,PT ;REPLACE IT WITH A NULL
CLSLN2: CAMN T3,[010700,,CLSBUF+PCBSIZ-1]
PUSHJ P,CLSOVF ;IF ABOUT TO OVERFLOW, STORE ON DISK
IDPB T1,T3 ;SAVE CHARACTER IN THE CLOSE BUFFER
AOS CLSCNT ;BUMP COUNT
CAIE T1,15 ;CARRIAGE RETURN?
JRST CLSLN1 ;NO - DRIVE ON
ILDB T1,PT ;YES - PICK UP THE <LF>
DPB T2,PT ;REPLACE IT WITH A NULL
CAIE T1,12 ;IS IT REALLY A LINEFEED?
JRST CLSLN2 ;NO - IT'S NOT THE END OF THE LINE
SOJG T4,CLSLN2 ;YES - LOOP THROUGH DESIRED NUMBER OF ROWS
CAMN T3,[010700,,CLSBUF+PCBSIZ-1]
PUSHJ P,CLSOVF ;IF ABOUT TO OVERFLOW, STORE ON DISK
IDPB T1,T3 ;SAVE THE LINEFEED IN THE CLOSE BUFFER
AOS CLSCNT ;BUMP COUNT FOR <LF>
CLSLN3: SKIPLE T4,ADDLSX ;GOT SOME SPACES TO CLOSE TOO?
PUSHJ P,CLLSPS ;YES - DO THEM
CLSLN4: TRNE F,RST ;WANT TO RESTORE THE NOMINAL PARAMETERS?
PUSHJ P,CLLRST ;YES - DO SO
MOVEM T3,CLAFLG ;SAVE THE ENDING POINTER
SETZ T1, ;END THE BUFFER WITH A NULL
IDPB T1,T3
TRNE F,COV ;HAS BUFFER OVERFLOWED?
PUSHJ P,CLSLST ;YES - WRITE OUT THE LAST PIECE
PUSHJ P,CCREOL ;MAKE SURE THE FILE ENDS WITH A CRLF
SOSG SQZCNT ;TIME TO DO A SQUEEZE?
PUSHJ P,SQUEZW ;YES - REMOVE ALL NULL WORDS
TLZE F,PCM ;WAS THERE A MARK?
JRST DISALL ;YES - RE-DISPLAY THE SCREEN AND LOOP
SKIPN ADDLNX ;REALLY CLOSE ANY LINES?
JRST CLSLNL ;NO - JUST SPACES - RE-DO ONE LINE
SKIPN T3,DLN(TM) ;CAN TERMINAL DO ITS OWN CLOSE?
JRST CLSLNR ;NO - DISPLAY ALL FROM HERE DOWN
MOVE T4,LPP(TM) ;YES - GET NUMBER OF LINES PER PAGE
SUB T4,RW ;LESS CURRENT POSITION
SUB T4,ADDLNX ;LESS SIZE OF DELETE, GIVES LINES LEFT
JUMPL T4,DISDWN ;IF NONE (BIG DELETE), JUST RE-DISPLAY
TLNE F,FNC!FBL ;GOT FENCE OR FRAGGED BOTTOM LINE?
PUSHJ P,CBOTOM ;YES - ERASE IT
MOVE T4,RW ;MOVE TO START OF THE LINE THE CURSOR IS ON
PUSHJ P,POSLIN
MOVE T2,ADDLNX ;GET SIZE OF DELETE
TLNE F,FNC!FBL ;IS BOTTOM LINE O.K.?
AOS ROLLS ;NO - REWRITE ONE MORE LINE
MOVE T1,T3 ;GET CODE TO CLOSE LINES
PUSHJ P,PUTSEQ ;CLOSE A LINE
SOJG T2,.-2 ;LOOP THROUGH ALL LINES
SKIPN ADDLSX
JUMPE CM,CLSLN5 ;JUMP IF AT START OF A LINE
MOVE PT,LINPTR
PUSHJ P,DISONE ;ELSE DISPLAY SINGLE CLOSED-UP LINE
CLSLN5: MOVE T4,LPP(TM) ;GET LINE NUMBER OF START OF REWRITE
SUB T4,ADDLNX
TLNE F,FBL ;IS BOTTOM LINE O.K.?
SOJ T4, ;NO - RE-DO IT, TOO
MOVEM T4,SAVEAC ;SET IT UP IN T4 AND SAVEAC
PUSHJ P,ROLFW1 ;AND REWRITE FROM THERE DOWN
JRST LOOP
CLSLNL: PUSHJ P,DISLIN ;DISPLAY REST OF LINE CURSOR IS ON
JRST DISCUR ;RESTORE CURSOR AND LOOP
CLSLNR: JUMPN RW,DISDWN ;IF NOT HOME JUST DO DISPLAY
JUMPN CM,DISDWN
SKIPN ADDLSX ;DELETED ANY SPACES,
SKIPN RUP(TM) ; OR NO ROLL UP SEQUENCE?
JRST DISDWN ;YES - DISPLAY ANYWAY
MOVE T4,ADDLNX ;GET NUMBER OF LINES DELETED
CAML T4,LPP(TM) ;LONGER THAN SCREEN SIZE?
JRST DISDWN ;YES - DISPLAY ANYWAY
PUSHJ P,ROLFW0 ;NO - DISPLAY BY DOING A ROLL (AT LAST)
JRST LOOP ;DONE
;HERE IF END OF BUFFER REACHED DURING THE CLOSE
CLOSEN: MOVEM T3,CLAFLG ;SAVE POINTER TO END OF CLOSE BUFFER
TRNE F,RST ;WANT TO RESTORE THE NOMINAL PARAMETERS?
PUSHJ P,CLLRST ;YES - DO SO
MOVE PT,CHRPTR ;GET POINTER TO FIRST DELETED CHARACTER
IBP PT ;PLUS A CHARACTER
MOVE EN,PT ;SAVE AS NEW END OF BUFFER
CAIN SL,0 ;DID CLOSE START AT START OF A LINE?
CAIE CM,0
PUSHJ P,ADDCR ;NO - PUT A <CRLF> AFTER THAT PARTIAL LINE
TRNE F,COV ;HAS BUFFER OVERFLOWED?
PUSHJ P,CLSLST ;YES - WRITE OUT THE LAST PIECE
PUSHJ P,POSCUR ;PUT CURSOR WHERE IT BELONGS
SKIPN CPG(TM) ;CAN TERMINAL CLEAR TO END OF SCREEN?
JRST DISALL ;NO - RE-DISPLAY THE ENTIRE SCREEN
PUSHJ P,FIXBLC ;YES - CLEAR AND PUT UP THE FENCE
JRST DISCUR ;RE-POSITION THE CURSOR AND GET A NEW COMMAND
;SUBROUTINE TO WRITE OUT THE LAST PIECE OF THE CLOSE BUFFER
CLSLST: SETZ T1, ;MAKE SURE LAST WORD OF BUFFER IS NULLED
IDPB T1,T3
IDPB T1,T3
IDPB T1,T3
IDPB T1,T3
IDPB T1,T3
IFN TOPS10,<
HRRZ T1,CLAFLG ;GET ADDRESS OF THE LAST BUFFER WORD USED
MOVNI T1,CLSBUF(T1) ;FIND -NUMBER OF WORDS IN THIS LAST PIECE
HRLM T1,CLSCCL ;SET TO OUTPUT THAT MANY WORDS
>
PUSHJ P,CLSOV0 ;YES - WRITE OUT THE LAST PIECE
IFN TOPS10,<
MOVNI T1,PCBSIZ ;RESTORE FULL BUFFER SIZE
HRLM T1,CLSCCL ; TO CHANNEL COMMAND
>
JRST CLSOVE ;CLOSE THE DISK FILE AND RETURN
;HERE TO RESTORE INSERT-DELETE LINES NOMINALS (MAYBE), RE-SET CURSOR, AND LOOP
CLSLNE: TRNE F,RST ;WANT TO RESTORE THE NOMINAL PARAMETERS?
PUSHJ P,CLLRST ;YES - DO SO
JRST DISCUR ;RE-POSITION AND LOOP
CLLRST: MOVEI T1,1 ;RESTORE THE INSERT/DELETE-LINE NOMINALS:
MOVEM T1,ADDLNS ;SET BACK TO ONE LINE
SETZM ADDLSP ; AND NO SPACES
POPJ P, ;DONE
;SUBROUTINE FOR WHEN USER WANTS TO CLOSE SOME SPACES AFTER CLOSING LINES
;(WHICH HE'S INDICATED BY USING CURSOR MOVEMENT)
CLLSPS: TLO F,FLG ;SET TO NULL THE CHARACTERS AS THEY ARE FOUND
MOVE T2,CLSCNT ;GET NUMBER OF SPACES CLOSED
PUSHJ P,SPCBFZ ;NULL OUT (T4)S WORTH OF CHARACTERS
TLZ F,FLG ;CLEAR NULLING FLAG
MOVE T1,SPCCNT ;GET COUNT OF CHARACTERS
ADDM T1,CLSCNT ;ADD TO TOTAL COUNT
POPJ P, ;FINISH OFF
;HERE IF MARK WAS MADE - CLOSE FROM STARTING CHARACTER TO CURRENT POSITION
;note: does nothing about starting or ending in a tab
CLSMRK: PUSHJ P,MAKCPT ;RE-MAKE CURSOR POSITION
TLO F,CHG ;SAY FILE IS CHANGED
PUSHJ P,MRKSET ;SET UP TO USE THE MARK
SETZM ADDLNX ;CLEAR LINES TO ADD (RE-COMPUTE BELOW)
PUSHJ P,CLSGPT ;SET UP THE POINTER INTO THE DELETE BUFFER
SETZB T2,T4 ;CLEAR CHARACTER COUNT AND GET A NULL
CLSMK1: CAMN PT,MRKPTR ;AT END OF THE CLOSE?
JRST CLSMKE ;YES - FINISH OFF
CAMN T3,[010700,,CLSBUF+PCBSIZ-1]
PUSHJ P,CLSOVF ;WRITE TO DISK ON CLOSE BUFFER OVERFLOW
ILDB T1,PT ;GET A CHARACTER
JUMPE T1,CLSMK1 ;SKIP, IF NULL
IDPB T1,T3 ;SAVE IT IN THE CLOSE BUFFER
DPB T4,PT ;NULL OUT THE CHARACTER IN THE FILE
CAIN T1,11 ;TAB?
OR T2,[7,,0] ;YES - COUNT ITS LENGTH IN SPACES
CAIN T1,15 ;END OF A LINE?
PUSHJ P,ISCRLF ;MAYBE - GOT A CRLF PAIR?
AOBJP T2,CLSMK1 ;NOT CRLF - COUNT CR AS JUST ANOTHER CHARACTER
HRRO T2,T2 ;YES - CLEAR NUMBER OF SPACES (AFTER LF FOUND)
AOS ADDLNX ;BUMP NUMBER OF LINES
AOJA T2,CLSMK1 ;AND CONTINUE
CLSMKE: HLRZM T2,ADDLSX ; AND SPACES TO ADD
HRRZ T2,T2 ;ISOLATE COUNT OF CHARACTERS CLOSED
ADDM T2,CLSCNT ;ADD IT TO THE CURRENT COUNT
MOVE T1,ADDLNX ;SAVE NUMBER OF LINES
MOVEM T1,ROLLS ; FOR ROLLING AT END
JRST CLSLN4 ;FINISH OFF
;SUBROUTINE TO SET UP FOR A MARKED PICK OR DELETE-LINES
MRKSET::MOVE T4,MRKPTR ;GET THE STARTING DISPLAY POINTER
CAMN T4,DISPTR ;HAS DISPLAY POINTER CHANGED DURING MARKING?
TLZ F,PCM ;NO - CLEAR MARK FLAG (TO HELP DISPLAYING)
MOVE T2,CHRPTR ;GET POINTER TO ENDING POSITION
MOVEM T2,MRKPTR ;SAVE IT AS POINTER TO END OF REGION
MOVE PT,MRCPTR ;GET POINTER TO STARTING POSITION
MOVE T3,PT ; SHIFT BYTE COUNT INTO LOW-ORDER BITS
ROTC T2,6 ; (NOW A SIMPLE COMPARE TELLS WHICH IS LARGER)
MOVE T0,T2 ;PUT AC T2 IN A SAFE PLACE
CAMGE T0,T3 ;GOING FORWARDS?
JRST MRKST1 ;NO - FINISH OFF DIFFERENTLY
PUSHJ P,PUSMKS ;YES - STACK THE ENDING DISPLAY POINTER
MOVEM T4,DISPTR ;MOVE BACK TO THE STARTING DISPLAY POINTER
DMOVE RW,SVPMRK ;AND THE STARTING ROW AND COLUMN
DMOVE T0,MRLPTR ;SET UP STARTING LINE AND CURSOR POINTERS
DMOVEM T0,LINPTR
POPJ P, ;DONE
MRKST1: EXCH T4,DISPTR ;BACKWARDS - STACK THE ENDING DISPLAY POINTER
PUSHJ P,PUSMKS
MOVEM T4,DISPTR ;PUT BACK THE STARTING DISPLAY POINTER
EXCH PT,MRKPTR ;SWAP START AND END POINTERS
POPJ P, ;DONE
;SUBROUTINE TO SET UP T3/PTR TO CLOSE BUFFER. CLEARS THE CHARACTER
;COUNT IFF THE PREVIOUS COMMAND WAS NOT A DELETE-LINES.
;ELSE APPENDS TO THE PREVIOUSLY-DELETED STUFF.
;ALSO, IF BUFFER HAS OVERFLOWED, RE-OPENS DISK FILE FOR APPENDING
;SAVES T1; USES T2, T3
CLSGPT: SKIPN T3,CLAFLG ;GET CLOSE-APPEND POINTER - ANY?
SKIPA T3,[POINT 7,CLSBUF] ;NO - POINT TO START OF BUFFER
CAMN T3,[POINT 7,CLSBUF] ;YES - POINTING TO START OF BUFFER?
JRST CLSGPS ;YES - CLEAR COUNT AND RETURN
TRNN F,COV ;NO - HAS DELETE BUFFER OVERFLOWED?
POPJ P, ;NO - DONE
HRROI T2,CLSFIL ;YES - OPEN THE FILE FOR APPENDING
IFN TOPS10,<
MOVEM T1,SAVEAC ;SAVE AC T1
PUSHJ P,SETIN ;OPEN IT FOR INPUT
HLRO T3,T1 ;SAVE NEGATIVE FILE SIZE
PUSHJ P,SETOU1 ;OPEN FOR OUTPUT, TOO
MOVN T1,T3 ;GET POSITIVE FILE SIZE
LSHC T1,-7 ;MAKE IT A BLOCK NUMBER
TLNN T2,774000 ;END EXACTLY ON A BLOCK BOUNDARY?
AOJA T1,CLSGPB ;YES - DON'T NEED TO READ ANYTHING
AOJ T1, ;NO - READ LAST BLOCK OF FILE
USETI 5,(T1)
INPUT 5,CLACCL ;READ IT
USETO 5,(T1) ;PREPARE TO WRITE THE LAST BLOCK, TOO
MOVN T3,T3 ;GET NUMBER OF FULL WORDS IN THE FILE
ANDI T3,177
ADD T3,[POINT 7,CLSBUF-1] ;MAKE IT A POINTER
ILDB T1,T3 ;MAKE IT POINT AFTER THE DATA
JUMPN T1,.-1
ADD T3,[70000,,0] ;BACK UP BEFORE THE NULL
CAIGE T3,0
SUB T3,[430000,,1]
MOVE T1,SAVEAC ;RESTORE AC T1
>
IFE TOPS10,<
MOVEM T1,CLSJFN ;SAVE T1
MOVE T1,[GJ%SHT] ;OPEN THE PICK BUFFER FOR APPENDING
GTJFN
HALTF
MOVE T2,[7B5+OF%APP]
OPENF
HALTF
EXCH T1,CLSJFN ;RESTORE T1 AND SAVE JFN
MOVE T3,[POINT 7,CLSBUF] ;POINT TO START OF BUFFER
>
POPJ P, ;DONE
CLSGPS: TRZ F,COV ;SAY DELETE BUFFER HASN'T OVERFLOWED (SO FAR)
SETZM CLSCNT ;CLEAR COUNT OF CHARACTERS DELETED
POPJ P, ;DONE
IFN TOPS10,<
CLSGPB: MOVE T3,[POINT 7,CLSBUF] ;POINT TO START OF BUFFER
POPJ P, ;DONE
>
;SUBROUTINE TO FIND (T4) REAL CHARACTERS (NOT NULLS) AT (PT), WHICH IS FRAGGED
;AND PUT THEM IN THE AREA POINTED TO BY T3
;IF FLG IS SET, NULLS THE CHARACTER IN THE FILE BUFFER; ELSE LEAVES IT ALONE
;STOPS WHEN COUNTED OUT. IF END OF LINE REACHED, PADS WITH SPACES
;RETURNS COUNT OF CHARACTERS MOVED IN SPCCNT
;NOTE: PICK OR CLOSE BUFFER can't OVERFLOW WHILE IN THIS ROUTINE, AS LONG AS
;BUFFER SIZE IS LARGER THAN ONE SCREENFUL (80*20/5 = 320 WORDS)
;THAT'S BECAUSE THIS IS REACHED FROM A CURSOR MOVE COMMAND, AND CURSOR MOVE
;CAN'T ENCOMPASS MORE THAN A SCREENFUL.
;WELL, ALMOST: REAL LONG LINES can OVERFLOW. SO BEWARE OF, SAY, OBJECT FILES
SPCBFZ: SETZM SAVEAC ;CLEAR STARTING COLUMN NUMBER
CAIN T2,0 ;PICKED NOTHING SO FAR?
SPCBUF::MOVEM CM,SAVEAC ;RIGHT - SAVE COLUMN POSITION INSTEAD
MOVEM T4,WRTNUM ;SAVE NUMBER OF CHARS TO NULL
SETZM SPCCNT ;CLEAR COUNT OF CHARACTERS MOVED
SETZB T1,NUMCHR ;GET A NULL; CLEAR # SPACES TO ADD
SPCBF1: CAMN PT,EN ;AT END OF BUFFER?
JRST SPCBF4 ;YES - PUT IN SOME SPACES AND FINISH UP
ILDB T2,PT ;NO - GET A CHARACTER
JUMPE T2,SPCBF1 ;IGNORE IF NULL
CAIN T2,15 ;IS IT A <CR>?
PUSHJ P,ISCRLF ;YES - GOT A CRLF?
AOSA SPCCNT ;NO - BUMP COUNT OF CHARACTERS
JRST SPCBF4 ;YES - FINISH OFF AND RETURN
TLNE F,FLG ;ELSE WANT TO NULL IT OUT?
DPB T1,PT ;YES - ZAP
CAIN T2,11 ;IS IT A TAB?
JRST SPCBTB ;YES - SEE HOW LONG THE TAB IS
IDPB T2,T3 ;NO - SAVE CHARACTER IN THE DESIRED BUFFER
SOJG T4,SPCBF1 ;AND COUNT IT - GOT ENOUGH?
SPCBEN: SKIPE NUMCHR ;GOT ANY SPACES TO ADD,
TLZN F,FLG ;REALLY WANT TO ADD THEM?
POPJ P, ;NO - JUST RETURN
JRST MAKSPC ;YES - ADD THEM AND RETURN
SPCBF4: ADDM T4,SPCCNT ;DONE - COUNT THE EXTRA SPACES
MOVEI T1," " ;PAD OUT WITH SPACES:
IDPB T1,T3 ;SAVE SPACES UNTIL COUNTED OUT
SOJG T4,.-1
POPJ P, ;DONE FOR KEEPS
SPCBTB: MOVE T0,WRTNUM ;GET LENGTH OF DELETE
ADD T0,SAVEAC ; PLUS STARTING CURSOR POSITION
SUB T0,T4 ; LESS NUMBER TO GO, GIVES PRESENT POSITION
ANDI T0,7 ;FIND NEGATIVE SIZE OF TAB
SUBI T0,10
ADD T4,T0 ;COUNT OFF THAT MANY SPACES FROM DELETE
JUMPG T4,[IDPB T2,T3 ;IF STILL MORE TO GO, SAVE TAB
JRST SPCBF1];AND CONTINUE
SOS SPCCNT ;REMOVE TAB FROM COUNT OF CHARACTERS
MOVN T1,T4 ;GET COUNT OF SPACES TO ADD TO FILE
ADDM T1,NUMCHR
SUB T4,T0 ;GET COUNT OF SPACES TO ADD TO BUFFER
MOVEI T1," " ;AND SAVE OFF THOSE SPACES
IDPB T1,T3
AOS SPCCNT ;BUMP COUNT OF CHARACTERS
SOJG T4,.-2
JRST SPCBEN ;AND FINISH UP
;SUBROUTINE FOR OVERFLOW OF CLOSE BUFFER - SAVE ON DISK; SET COV FLAG
CLSOVF: PUSH P,T1 ;SAVE LIVE CHARACTER
SETZ T1, ;STORE A NULL AT END OF CLOSE BUFFER
IDPB T1,T3
TROE F,COV ;SET CLOSE OVERFLOW FLAG - ALREADY SET?
JRST CLSOV1 ;YES - FILE ALREADY OPEN
PUSH P,T2 ;SAVE AN AC
HRROI T2,CLSFIL
IFN TOPS10,<
PUSHJ P,SETDEL ;DELETE OLD .TMP FILE
>
PUSHJ P,SETOUT ;SET UP THE DELETE BUFFER FILE
MOVEM T1,CLSJFN
JRST CLSOV2
CLSOV0: PUSH P,T1 ;SAVE AN AC
CLSOV1: PUSH P,T2 ;SAVE AN AC
IFN TOPS10,<
CLSOV2: OUTPUT 5,CLSCCL ;WRITE OUT THE CLOSE BUFFER
>
IFE TOPS10,<
MOVE T1,CLSJFN
CLSOV2: HRROI T2,CLSBUF ;WRITE OUT THE CLOSE BUFFER
SETZ T3,
SOUT
>
MOVE T3,[POINT 7,CLSBUF] ;START THE BUFFER AFRESH
POP P,T2 ;RESTORE ACS
POP P,T1 ;RESTORE ACS
POPJ P, ;CONTINUE
IFN TOPS10,<
CLSOVE: CLOSE 5,
RELEAS 5, ;FINISH OFF THE FILE
POPJ P, ;DONE
>
IFE TOPS10,<
CLSOVE: MOVE T1,CLSJFN ;GET FILE HANDLE
JRST SETTMP ;MAKE IT TEMPORARY, CLOSE IT, AND RETURN
>
;**********************************************************************
;HERE TO ADD SPACES TO THE BUFFER
OPENSP::MOVE T4,ADDSPC ;SET UP LAST TIME'S NOMINAL
MOVEM T4,PARG1 ;AS DEFAULT FOR THIS TIME
PUSHJ P,PEEL.1 ;READ NEW PARM, IF ANY
MOVE T4,PARG1 ;GET SPACES TO ADD
TRNE F,CMV ;DOING CURSOR MOVEMENT?
PUSHJ P,SPSCUR ;YES - HANDLE THINGS A LITTLE DIFFERENTLY
MOVEM T4,ADDSPC ;SAVE NEW NOMINAL
PUSHJ P,ERASPM ;ERASE PARAMETER
TLNE TM,XCI ;INITIALIZING FOR AN EXECUTE?
JRST LOOP ;YES - DONE NOW
OPSNPM::TRNE F,RDO ;IS FILE READ-ONLY?
JRST RDOERR ;YES - COMMAND IS ILLEGAL
SOS ISVCNT ;DECREMENT INCREMENTAL SAVE COUNTER
SKIPG T1,ADDSPC ;SET UP LAST TIME'S NOMINAL
JRST OPNSPE ;DONE, IF NOTHING TO ADD
TLOA F,CHG!INS ;SAY FILE HAS BEEN MODIFIED
OPSNP1: TLO F,INS ;LET LINE BE EXTENDED IF NECESSARY
PUSHJ P,MAKCPT ;RE-MAKE CURSOR POSITION
TLZ F,INS!PCM
MOVEM T1,NUMCHR ;ADD THE RIGHT NUMBER OF SPACES
CAIE T3,11 ;IS CHARACTER AT CURSOR A TAB?
JRST OPNSP1 ;NO - CONTINUE
MOVE T1,TABSIZ ;YES - CONVERT THE TAB TO SPACES
ADDM T1,NUMCHR
SETZ T1, ;AND NULL OUT THE TAB
DPB T1,TABPTR
SKIPN TABSPC ;POINTING TO START OF TAB?
TLO F,XPC ;NO - CHARACTER POINTER IS BAD
OPNSP1: PUSHJ P,MAKSPC ;GO ADD THE SPACES
MOVE T4,ADDSPC ;GET NUMBER OF SPACES TO ADD
IFN FTIMD,<
SKIPN IMO(TM) ;DOES TERMINAL HAVE INSERT MODE?
>
SKIPE ISP(TM) ;CAN TERMINAL OPEN SPACES ON ITS OWN?
PUSHJ P,OPNSPI ;YES - LET IT (SKIP RETURNS)
PUSHJ P,DISLIN ;NO - REWRITE REST OF LINE CURSOR IS ON
SOSGE ADDSLN ;WANT TO WORK WITH OTHER LINES?
JRST OPNSPE ;NO - GO FINISH UP
TLO F,XPC!XPL ;YES - RE-MAKE SOME POINTERS
MOVE T1,ADDSPC ;GET SIZE OF INSERT
AOJA RW,OPSNP1 ;AND DO THE SAME WITH THE NEXT LINE
OPNSPE: MOVEI T1,1
TRNE F,RST ;WANT TO RESTORE THE NOMINAL PARAMETER?
MOVEM T1,ADDSPC ;YES - SET IT BACK TO 1
JRST DISCUR ;RE-POSITION THE CURSOR AND LOOP
;SUBROUTINES TO USE THE TERMINAL HARDWARE TO INSERT OR DELETE SPACES
;ENTER WITH T4/ NUMBER OF TIMES TO OUTPUT (T3)
;NORMAL RETURN: LINE HAS TABS, MUST BE RE-DISPLAYED
;SKIP RETURN: LINE HAS BEEN HANDLED; NO FURTHER ACTION NECESSARY
CLSSPI: PUSHJ P,FNDEOL ;SEE IF THERE ARE ANY TABS FROM HERE TO EOL
POPJ P, ;EITHER - GO RE-DISPLAY ENTIRE LINE
ADD T1,ADDSPC ;NEITHER - WAS ORIGINAL LINE TOO LONG?
CAMLE T1,CPL(TM)
POPJ P, ;YES - RE-DISPLAY IT ANYWAY
AOS (P) ;NO - SET UP FOR SKIP RETURN
PUSHJ P,POSCUR ;POINT TO THE RIGHT POSITION
MOVE T1,T3 ;GET CODE TO DO THE CLOSE
PUSHJ P,PUTSEQ ;CLOSE ONE SPACE
SOJG T4,.-2 ;LOOP THROUGH ALL SPACES
JRST PUTTYP ;OUTPUT THE BUFFER AND SKIP RETURN
OPNSPI::PUSHJ P,FNDEOL ;SEE IF THERE ARE ANY TABS FROM HERE TO EOL
POPJ P, ;YES - RE-DISPLAY THE REMAINDER OF THE LINE
AOS (P) ;SET UP FOR SKIP RETURN
PUSHJ P,POSCUR ;MOVE TO THE RIGHT POSITION
IFN FTIMD,<
SKIPE IMO(TM) ;DOES THE TERMINAL HAVE INSERT MODE?
JRST OPNSII ;YES - INSERT THE HOLE, THEN
>
MOVE T1,T3 ;GET CODE TO DO THE OPEN
PUSHJ P,PUTSEQ ;OPEN ONE SPACE
SOJG T4,.-2 ;LOOP THROUGH ALL SPACES
JRST PUTTYP ;OUTPUT THE BUFFER AND SKIP RETURN
IFN FTIMD,<
OPNSII: PUSHJ P,IMODON ;TURN ON INSERT MODE
MOVEI T1," " ;GET THE SPACE TO TYPE IN
IDPB T1,TY
SOJG T4,.-1 ;OUTPUT ALL THE SPACES
PUSHJ P,IMODOF ;TURN OFF INSERT MODE
JRST PUTTYP ;OUTPUT THE BUFFER AND SKIP RETURN
>
;HERE TO DELETE THE PREVIOUS CHARACTER FROM THE BUFFER
DELCHR::TRNE F,RDO ;IS FILE READ-ONLY?
JRST RDOERR ;YES - COMMAND IS ILLEGAL
JUMPE CM,LOOP ;DO NOTHING IF AT START OF LINE
SOS ISVCNT ;DECREMENT INCREMENTAL SAVE COUNTER
PUSHJ P,MAKCPT ;RE-MAKE THE CURSOR POINTER
MOVEM CM,SAVEAC ;SAVE THE CURRENT COLUMN POSITION
CAIN T3,15 ;IS THE CURSOR AT OR BEYOND END OF THE LINE?
PUSHJ P,ERSWDL ;YES - FIRST POSITION TO END OF LINE
CAME CM,SAVEAC ;WAS THE CURSOR BEYOND THE END OF THE LINE?
JRST LOOP ;YES - IT MOVED TO THE END; DONE
TLO F,CHG ;NO - SAY THE FILE HAS BEEN MODIFIED
TLZ F,PCM ;CANCEL THE PICK-CLOSE MARK, IF ANY
MOVE PT,CHRPTR ;GET CHARACTER POINTER
MOVEM PT,SAVEAC ;STORE IT IN A SAFE PLACE
JRST DELCH2 ;JUMP INTO THE LOOP
DELCH1: ADD PT,[70000,,0] ;BACK IT UP A NOTCH
CAIGE PT,0
SUB PT,[430000,,1]
DELCH2: LDB T1,PT ;GET THE PREVIOUS CHARACTER
JUMPE T1,DELCH1 ;SKIP OVER IT IF NULL
MOVEI T4,1 ;SET LENGTH OF DELETE TO 1
MOVEM T4,DELCNT ;SET SIZE OF DELETE BUFFER TO 1, TOO
MOVE T2,T1 ;KEEP THE CHARACTER IN T2
ROT T1,-7 ;LEFT JUSTIFY THE CHARACTER
MOVEM T1,DELBUF ;SAVE IT IN THE DELETE BUFFER
CAIN T3,11 ;IS THE CHARACTER UNDER THE CURSOR A TAB?
JRST DELCHT ;YES - HANDLE SPECIALLY
DPB T1,PT ;NULL OUT THE LIVE CHARACTER
CAIE T2,11 ;WAS A TAB DELETED?
SOJA CM,CLSNP3 ;NO - CORRECT THE DISPLAY AND LOOP
PUSHJ P,CALCML ;YES - POSITION TO THE CHARACTER BEFORE THE TAB
JRST CLSLNL
JRST CLSLNL ;RE-DISPLAY THE REST OF THE LINE; LOOP
;HERE WHEN THE CHARACTER UNDER THE CURSOR IS A TAB. FIND THE POSITION
;OF THE PREVIOUS CHARACTER. IF THE CURSOR IS NEXT TO IT, DELETE IT;
;IF THE CURSOR IS WITHIN THE TAB, DELETE THE TAB
;PT/ DPB POINTER TO PREVIOUS CHARACTER; SAVEAC/ DPB POINTER TO TAB
DELCHT: MOVEM CM,SAVEAC+1 ;SAVE CURSOR POSITION
PUSHJ P,CALCML ;POSITION TO THE CHARACTER BEFORE THE TAB
TDZA T4,T4
SETZ T4, ;GET A NULL
CAMN CM,SAVEAC+1 ;IS THE CURSOR NEXT TO THE CHARACTER?
JRST DELCT1 ;YES - DELETE THE CHARACTER
IDPB T4,SAVEAC ;NO - DELETE THE TAB
MOVSI T1,(BYTE (7) 11)
MOVEM T1,DELBUF ;NOTE THAT THE DELETED CHARACTER WAS THE TAB
JRST CLSLNL ;RE-DISPLAY THE REST OF THE LINE AND LOOP
DELCT1: DPB T4,PT ;DELETE THE CHARACTER
SOJA CM,CLSNP3 ;FINISH UP THE DISPLAY AND LOOP
;HERE TO REMOVE CHARACTERS FROM THE BUFFER
CLOSSP::TRNE F,RDO ;IS FILE READ-ONLY?
JRST RDOERR ;YES - COMMAND IS ILLEGAL
TLNN F,ENT ;IS THERE A PARAMETER TYPED?
JRST CLSNPM ;NO - USE THE ONE ALREADY SET UP
MOVE T4,ADDSPC ;SET UP LAST TIME'S NOMINAL
MOVEM T4,PARG1
CLSSP1: PUSHJ P,PEEL.1 ;READ NEW PARM, IF ANY
MOVE T4,PARG1 ;GET SPACES TO DELETE
TRNE F,CMV ;DOING CURSOR MOVEMENT?
PUSHJ P,SPSCUR ;YES - HANDLE THINGS A LITTLE DIFFERENTLY
MOVEM T4,ADDSPC ;SAVE NEW NOMINAL
PUSHJ P,ERASPM ;ERASE PARAMETER
TRZ F,CMV ;CLEAR CURSOR MOVE FLAG (IF COMING FROM ERASWD)
TLNE TM,XCI ;INITIALIZING FOR AN EXECUTE?
JRST LOOP ;YES - DONE NOW
CLSNPM::SKIPG T1,ADDSPC ;GOT ANYTHING TO DELETE?
JRST CLOSP1 ;NO - DONE
CLSNP0: SOS ISVCNT ;YES - DECREMENT INCREMENTAL SAVE COUNTER
TLZ F,PCM ;CANCEL THE PICK-CLOSE MARK, IF ANY
MOVEM T1,ADDSPS ;SET UP THE VALUE
TLO F,CHG ;SAY FILE IS MODIFIED
CLSNP1: PUSHJ P,MAKCPT ;RE-MAKE CHARACTER POINTER
SETZM NUMCHR ;ASSUME A TAB WON'T BE BROKEN
CAIE T3,11 ;IS CHARACTER AT CURSOR A TAB?
JRST CLSNP2 ;NO - CONTINUE
MOVE T1,TABSPC ;YES - ADD SPACES TO LEFT OF TAB, AFTER CLOSE
MOVEM T1,NUMCHR
CLSNP2: MOVE PT,CHRPTR
MOVE T4,ADDSPS ;GET NUMBER OF SPACES TO CLOSE
PUSHJ P,WRTNUL ;NULL OUT THAT MANY CHARACTERS
MOVEM T4,WRTNUM ;SAVE SIZE OF LEFTOVER, IF IT'S SHORT
SKIPE NUMCHR ;WANT TO ADD SPACES FOR A BROKEN TAB?
PUSHJ P,MAKSPC ;YES - DO IT
MOVE T4,ADDSPS ;GET NUMBER OF SPACES TO CLOSE
SUB T4,WRTNUM ;MINUS UNNEEDED OVERAGE
SKIPE WRTNUM ;DELETE PAST THE END OF THE LINE?
JRST CLSN2A ;YES - JUST CLEAR TO END OF LINE IF POSSIBLE
CLSNP3: SKIPE T3,DSP(TM) ;CAN TERMINAL CLOSE SPACES ON ITS OWN?
PUSHJ P,CLSSPI ;YES - LET IT (SKIP RETURNS)
PUSHJ P,CLOSP0 ;NO - REWRITE THE LINE CURSOR IS ON
CLSNP4: SOSGE ADDSLN ;WANT TO DO IT WITH ANOTHER LINE?
JRST CLOSP1 ;NO - JUST GET ANOTHER COMMAND
TLO F,XPC!XPL ;YES - RE-MAKE SOME POINTERS
AOJA RW,CLSNP1 ;AND DO THE SAME WITH THE NEXT LINE
CLSN2A: SKIPN CLN(TM) ;CAN TERMINAL CLEAR TO END OF LINE?
JRST CLSNP3 ;NO - DO IT SOME OTHER WAY
PUSHJ P,POSCUR ;YES - RE-POSITION THE CURSOR
MOVE T1,CLN(TM) ;CLEAR TO END OF LINE
PUSHJ P,PUTSEQ
JRST CLSNP4 ;AND FINISH OFF
CLOSP0: SKIPE NUMCHR ;STARTED WITH A TAB?
PUSHJ P,MAKCK1 ;YES - MAKE SURE THE CURSOR POINTER IS RIGHT
JRST DISLIN ;RE-WRITE REST OF LINE THE CURSOR IS ON; RETURN
CLOSP1: SOSG SQZCNT ;TIME TO DO A SQUEEZE?
PUSHJ P,SQUEZW ;YES - REMOVE ALL NULL WORDS
JRST OPNSPE ;FINISH UP AND GET ANOTHER COMMAND
;HERE FOR CURSOR MOVE OPENSP OR CLOSSP - COUNT LINES AND SPACES
SPSCUR: MOVEM T4,ADDSLN ;SAVE LINES TO WORK WITH
SKIPN T4,PARG2 ;GET NUMBER OF SPACES - ANY?
MOVE T4,ADDSPC ;NO - USE CURRENT NOMINAL
POPJ P,
;**********************************************************************
;HERE TO TAKE LINES FROM THE BUFFER AND PUT THEM IN THE PICK BUFFER
PICK:: MOVE T4,PICKLN ;SET UP LAST TIME'S NOMINAL
MOVEM T4,PARG1
PUSHJ P,PEEL.1 ;READ NEW PARM, IF ANY
MOVE T4,PARG1 ;GET LINES TO PICK
JUMPE T1,[SETZM PICKLN ;IF GOT A TOKEN, READ ZERO lINES
MOVEM T4,PICKSP ;AND GIVEN NUMBER OF SPACES
JRST PICK0] ;CONTINUE
MOVEM T4,PICKLN ;SAVE AS NEW NOMINAL
TRNE F,CMV ;CURSOR MOVEMENT?
JRST [MOVE T1,PARG2 ;YES - GET SPACES TO PICK, TOO
MOVEM T1,PICKSP ;IF NO LINES, COUNT SPACES FROM CURSOR
JUMPE T4,PICK0
ADD T1,SAVPOS+1 ;IF SOME LINES, COUNT FROM LEFT MARGIN
ADD T1,SL
MOVEM T1,PICKSP
JRST PICK0]
SETZM PICKSP ;IF NO CURSOR MOVE, CLEAR EXTRA SPACES
PICK0: PUSHJ P,ERASPM ;ERASE PARAMETER
TLNE TM,XCI ;INITIALIZING FOR AN EXECUTE?
JRST LOOP ;YES - DONE NOW
PIKNPM::PUSHJ P,MAKCPT ;RE-MAKE CURSOR POINTER
TLNE F,PCM ;HAS A MARK BEEN MADE?
JRST PIKMRK ;YES - DO THINGS DIFFERENTLY
MOVE T1,T3 ;SAVE CHARACTER AT CURSOR
MOVE PT,CHRPTR ;GET CURRENT CURSOR POSITION
PUSHJ P,PIKGPT ;SET UP THE POINTER TO THE PICK BUFFER
SETZ T2, ;CLEAR COUNT (IN CASE THERE AREN'T ANY LINES)
SKIPG T4,PICKLN ;GET NUMBER OF LINES TO PICK - ANY?
JRST PICK3 ;NO - SEE IF WANT TO PICK SPACES
CAIE T1,11 ;GOT A TAB AT THE CURSOR?
JRST PICK1A ;NO - SKIP THIS
MOVE T2,PT ;GET CURSOR PTR AGAIN FOR SCRATCH
ILDB T1,T2 ;GET CHARACTER CURSOR POINTS TO
CAIE T1,11 ;FOUND THE TAB?
JRST .-2 ;NO - KEEP LOOKING
SKIPG TABSPC ;YES - AT BEGINNING OF TAB?
JRST PICK1A ;YES - DON'T TOUCH THE TAB, THEN
MOVE PT,T2 ;WITHIN - POINT AFTER TAB
MOVE T2,TABSIZ ;GET TAB'S SIZE TO RIGHT OF CURSOR
SUB T2,TABSPC
MOVEM T2,SAVEAC ;SAVE COUNT FOR A WHILE
MOVEI T1," " ;PUT SOME SPACES IN THE PICK BUFFER
IDPB T1,T3
SOJG T2,.-1
SKIPA T2,SAVEAC ;RESTORE COUNT OF SPACES PUT IN AND SKIP
PICK1A: SETZ T2, ;CLEAR COUNT OF CHARACTERS PICKED
PICK1: CAMN EN,PT ;AT END OF USEABLE BUFFER?
JRST PIKPAD ;YES - PAD IN THE REMAINING <CRLF>S
CAMN T3,[010700,,PIKBUF+PCBSIZ-1]
PUSHJ P,PIKOVF ;WRITE TO DISK ON PICK BUFFER OVERFLOW
ILDB T1,PT ;GET A CHARACTER
JUMPE T1,PICK1 ;SKIP, IF NULL
IDPB T1,T3 ;SAVE IT IN THE PICK BUFFER
CAIE T1,15 ;CARRIAGE RETURN?
AOJA T2,PICK1 ;NO - IGNORE IT
CAMN T3,[010700,,PIKBUF+PCBSIZ-1]
PUSHJ P,PIKOVF ;WRITE TO DISK ON PICK BUFFER OVERFLOW
ILDB T1,PT ;YES - PICK UP THE <LF>
IDPB T1,T3 ;SAVE IT IN THE PICK BUFFER
ADDI T2,2 ;COUNT IT
CAIE T1,12 ;IS IT REALLY?
JRST PICK1 ;NO - IT'S NOT THE END OF THE LINE
SOJG T4,PICK1 ;YES - LOOP THROUGH DESIRED NUMBER OF LINES
PICK3: ADDM T2,PIKCNT ;SAVE COUNT OF CHARACTERS PICKED
SKIPLE T4,PICKSP ;DONE WITH LINES - GOT ANY SPACES?
PUSHJ P,PIKSPS ;YES - PICK THEM, TOO
PICK4: SKIPE APPFLG ;APPENDING?
MOVEM T3,APPFLG ;YES - SAVE THE LATEST POINTER
SETZ T1, ;DONE - END PICK BUFFER WITH A NULL
IDPB T1,T3
IFN TOPS10,<
IDPB T1,T3 ;CLEAR OUT ENTIRE LAST WORD
IDPB T1,T3
IDPB T1,T3
IDPB T1,T3
>
HRRZ T3,T3 ;GET BUFFER ENDING ADDRESS
CAIL T3,PIKBUF+PCBSIZ-400
SETOM INDFLG ;IF PICK IS LARGE SAY TAIL OF BUFFER FRAGGED
TRNN F,POV ;HAS BUFFER OVERFLOWED?
JRST PICK5 ;NO - FINISH OFF
SETOM INDFLG ;YES - TAIL OF BUFFER IS FRAGGED
IFN TOPS10,<
MOVNI T1,-PIKBUF(T3) ;SET RH T1 = - [(T3) - PIKBUF]
HRLM T1,PIKCCL ;SET TO OUTPUT THAT MANY WORDS
>
PUSHJ P,PIKOV1 ;WRITE OUT THE LAST PIECE
IFN TOPS10,<
MOVNI T1,PCBSIZ ;RESTORE FULL BUFFER SIZE
HRLM T1,PIKCCL ; TO CHANNEL COMMAND
>
PUSHJ P,PIKOVE ;CLOSE THE DISK FILE
PICK5: TRNN F,RST ;WANT TO RESTORE THE NOMINAL PARAMETERS?
JRST PICK6 ;NO - SKIP THIS
MOVEI T1,1
MOVEM T1,PICKLN ;YES - SET BACK TO ONE LINE
SETZM PICKSP ; AND NO SPACES
PICK6: TLZE F,PCM ;WAS THERE A MARK?
PUSHJ P,DISPLL ;YES - RE-DISPLAY THE SCREEN
PUSHJ P,POSCUR ;RE-POSITION THE CURSOR
JRST LOOP ;AND GET ANOTHER COMMAND
;SUBROUTINE TO SET UP T3/PICK POINTER. CLEARS THE CHARACTER COUNT IFF
;THE POINTER POINTS TO THE START OF THE BUFFER AND POV IS NOT SET
;ALSO, IF BUFFER HAS OVERFLOWED, RE-OPENS DISK FILE FOR APPENDING
;SAVES T1; USES T2
PIKGPT: SKIPN T3,APPFLG ;GET APPEND POINTER - ANY?
SKIPA T3,[POINT 7,PIKBUF] ;NO - POINT TO START OF BUFFER
CAMN T3,[POINT 7,PIKBUF] ;YES - POINTING TO START OF BUFFER?
JRST PIKGPS ;YES - CLEAR COUNT AND RETURN
TRNN F,POV ;NO - HAS PICK BUFFER OVERFLOWED?
POPJ P, ;NO - DONE
HRROI T2,PIKFIL ;YES - OPEN THE FILE FOR APPENDING
IFN TOPS10,<
MOVEM T1,SAVEAC ;SAVE AC T1
PUSHJ P,SETIN ;OPEN IT FOR INPUT
HLRO T3,T1 ;SAVE NEGATIVE FILE SIZE
PUSHJ P,SETOU1 ;OPEN FOR OUTPUT, TOO
MOVN T1,T3 ;GET POSITIVE FILE SIZE
LSHC T1,-7 ;MAKE IT A BLOCK NUMBER
TLNN T2,774000 ;END EXACTLY ON A BLOCK BOUNDARY?
AOJA T1,PIKGPB ;YES - DON'T NEED TO READ ANYTHING
AOJ T1, ;NO - READ LAST BLOCK OF FILE
USETI 5,(T1)
INPUT 5,PKACCL ;READ IT
USETO 5,(T1) ;PREPARE TO WRITE THE LAST BLOCK, TOO
MOVN T3,T3 ;GET NUMBER OF FULL WORDS IN THE FILE
ANDI T3,177
ADD T3,[POINT 7,PIKBUF-1] ;MAKE IT A POINTER
ILDB T1,T3 ;MAKE IT POINT AFTER THE DATA
JUMPN T1,.-1
ADD T3,[70000,,0] ;BACK UP BEFORE THE NULL
CAIGE T3,0
SUB T3,[430000,,1]
MOVE T1,SAVEAC ;RESTORE AC T1
>
IFE TOPS10,<
MOVEM T1,PIKJFN ;SAVE T1
MOVE T1,[GJ%SHT] ;OPEN THE PICK BUFFER FOR APPENDING
GTJFN
HALTF
MOVE T2,[7B5+OF%APP]
OPENF
HALTF
EXCH T1,PIKJFN ;RESTORE T1 AND SAVE JFN
MOVE T3,[POINT 7,PIKBUF] ;POINT TO START OF BUFFER
>
POPJ P, ;DONE
PIKGPS: TRZ F,POV ;SAY PICK BUFFER HASN'T OVERFLOWED (SO FAR)
SETZM PIKCNT ;CLEAR COUNT OF CHARACTERS PICKED
POPJ P, ;DONE
IFN TOPS10,<
PIKGPB: MOVE T3,[POINT 7,PIKBUF] ;POINT TO START OF BUFFER
POPJ P, ;DONE
>
;HERE IF PICK EXTENDS BEYOND FILE, TO PAD OUT WITH EXTRA <CR>S
;(IE, YOU ALWAYS GET THE NUMBER OF LINES YOU ASK FOR)
PIKPAD: CAMN T3,[010700,,PIKBUF+PCBSIZ-1]
PUSHJ P,PIKOVF ;WRITE TO DISK ON PICK BUFFER OVERFLOW
MOVEI T1,15 ;THEN SAVE A CARRIAGE RETURN
IDPB T1,T3
CAMN T3,[010700,,PIKBUF+PCBSIZ-1]
PUSHJ P,PIKOVF ;WRITE TO DISK ON PICK BUFFER OVERFLOW
MOVEI T1,12 ;THEN SAVE A LINEFEED
IDPB T1,T3
ADDI T2,2 ;COUNT THE <CRLF>
SOJG T4,PIKPAD ;CONTINUE THROUGH ALL LEFTOVER LINES
JRST PICK3 ;THEN FINISH OFF
;HERE TO PICK (T4) EXTRA SPACES AFTER THE LINES
PIKSPS: TLZ F,FLG ;DON'T NULL OUT THE PICKED CHARACTERS
PUSHJ P,SPCBFZ ;PICK (T4)S WORTH OF CHARACTERS AND RETURN
MOVE T1,SPCCNT ;GET COUNT OF CHARACTERS
ADDM T1,PIKCNT ;ADD TO TOTAL COUNT
POPJ P, ;DONE
;HERE IF MARK WAS MADE - PICK FROM STARTING CHARACTER TO (MRKPTR)
;note: does nothing about starting or ending in a tab
PIKMRK: PUSHJ P,MRKSET ;SET UP TO USE THE MARK
PUSHJ P,PIKGPT ;SET UP THE POINTER TO THE PICK BUFFER
SETZB T2,T4 ;CLEAR COUNT OF CHARACTERS; GET A NULL
PIKMK1: CAMN PT,MRKPTR ;AT END OF THE PICK?
JRST PIKMKE ;YES - FINISH OFF
CAMN T3,[010700,,PIKBUF+PCBSIZ-1]
PUSHJ P,PIKOVF ;WRITE TO DISK ON PICK BUFFER OVERFLOW
ILDB T1,PT ;GET A CHARACTER
JUMPE T1,PIKMK1 ;SKIP, IF NULL
IDPB T1,T3 ;SAVE IT IN THE PICK BUFFER
AOJA T2,PIKMK1 ;COUNT CHARACTER AND LOOP
PIKMKE: ADDM T2,PIKCNT ;SAVE COUNT OF CHARACTERS PICKED
TLNN F,PCM ;WANT TO RE-DISPLAY THE SCREEN?
PUSHJ P,MRKRES ;NO - REPAIR THE SCREEN AS IT IS
JRST PICK4 ;GO FINISH OFF, EITHER WAY
;SUBROUTINE FOR OVERFLOW OF PICK BUFFER - SAVE ON DISK; SET POV FLAG
;USES T1, T2; RESETS T3
PIKOVF: SETZ T1, ;SAVE A NULL AT END OF PICK BUFFER
IDPB T1,T3
TROE F,POV ;SET PICK OVERFLOW FLAG - ALREADY SET?
JRST PIKOV1 ;YES - FILE ALREADY OPEN
PUSH P,T2 ;SAVE AN AC
HRROI T2,PIKFIL
IFN TOPS10,<
PUSHJ P,SETDEL ;DELETE OLD .TMP FILE
>
PUSHJ P,SETOUT ;SET UP THE PICK OUTPUT FILE
MOVEM T1,PIKJFN
JRST PIKOV2
PIKOV1: PUSH P,T2 ;SAVE AN AC
IFN TOPS10,<
PIKOV2: OUTPUT 5,PIKCCL ;WRITE OUT THE PICK BUFFER
>
IFE TOPS10,<
MOVE T1,PIKJFN
PIKOV2: HRROI T2,PIKBUF ;WRITE OUT THE PICK BUFFER
SETZ T3,
SOUT
>
MOVE T3,[010700,,PIKBUF-1] ;START THE BUFFER AFRESH
POP P,T2 ;RESTORE AC
POPJ P, ;CONTINUE
IFN TOPS10,<
PIKOVE: CLOSE 5,
RELEAS 5, ;FINISH OFF THE FILE
POPJ P, ;DONE
>
IFE TOPS10,<
PIKOVE: MOVE T1,PIKJFN ;GET FILE HANDLE
JRST SETTMP ;MAKE IT TEMPORARY, CLOSE IT, AND RETURN
>
;**********************************************************************
;HERE TO PUT THE CONTENTS OF THE PICK BUFFER INTO THE BUFFER
;HERE, SPECIFICALLY, TO DO AN IN-LINE PUT: PUT TEXT IN THE MIDDLE OF A LINE
PUT:: TRNE F,RDO ;IS FILE READ-ONLY?
JRST RDOERR ;YES - COMMAND IS ILLEGAL
SOS ISVCNT ;DECREMENT INCREMENTAL SAVE COUNTER
SETZM PIKJFN ;ASSUME NOT READING FROM DISK
TLO F,INS ;LET LINE BE EXTENDED IF NECESSARY
PUSHJ P,MAKCPT ;RE-MAKE CURSOR POSITION
TLZ F,INS!PCM
CAIN T3,11 ;IS CHARACTER AT CURSOR A TAB?
PUSHJ P,RPLTAB ;YES - REPLACE IT WITH SPACES
MOVE T3,[010700,,PIKBUF-1]
MOVEM T3,PUTPTR ;ASSUME WILL READ FROM PUT BUFFER
TLNN F,ENT ;IS THERE A PARAMETER TYPED?
JRST PUTNPM ;NO - USE THE PICK BUFFER
PUSHJ P,PELS.1 ;GET STRING TO PUT, IF ANY
JUMPE T1,PUTCLS ;IF ENTER-PUT TYPED GO USE THE CLOSE BFR
TRZ F,POV ;IF IMMEDIATE, BUFFER CAN'T OVERFLOW
SETZM APPFLG ; AND APPENDING MUST BE TURNED OFF
MOVEM T1,PIKCNT ;SAVE SIZE OF STRING
MOVEM T1,NUMCHR ;SAVE AS NUMBER OF CHARACTERS TO ADD
PUSHJ P,ERASPM ;CLEAN THE SCREEN UP
TLNE TM,XCI ;INITIALIZING FOR AN EXECUTE?
JRST LOOP ;YES - DONE NOW
TLO F,CHG!WRH ;SET TO READ FROM THE PICK BUFFER
PUSHJ P,MAKCPT ;RE-MAKE CURSOR POSITION, IF CURSOR MVMT USED
SKIPN T1,PIKCNT ;GET COUNT OF CHARACTERS PICKED - ANY?
JRST PUTERR ;NO - ERROR
PUSHJ P,MAKCHR ;YES - GO PUT THEM IN
;HERE FOR AN IN-LINE PUT (IE, NO <CRLF>S IN THE BUFFER)
PUT0: TLZE F,XPL ;IS LINE POINTER O.K.?
PUSHJ P,MAKLPT ;NO - RE-MAKE IT
MOVE T4,NUMCHR ;GET DISTANCE TO OPEN
IFN FTIMD,<
SKIPN IMO(TM) ;DOES THE TERMINAL HAVE INSERT MODE?
>
SKIPE ISP(TM) ;CAN TERMINAL OPEN SPACES ON ITS OWN?
PUSHJ P,OPNSPI ;YES - OPEN UP THE LINE (SKIP RETURN)
JRST PUT0D ;NO - REWRITE THE LINE CURSOR IS ON
PUSHJ P,POSCUR ;GET BACK TO START OF NEWLY-OPENED SPACE
AOS T1,PUTPTR ;WRITE PICK OR CLOSE BUFFER THERE
PUSHJ P,PUTSTS
CAME RW,LPP.1 ;PUTTING ON BOTTOM LINE?
JRST DISCUR ;NO - RE-DISPLAY THE CURSOR AND LOOP
TLZE F,FNC ;YES - IS FENCE UP?
PUSHJ P,CLRLNA ;YES - ERASE IT
JRST DISCUR ;THEN RE-DISPLAY THE CURSOR AND LOOP
PUT0D: PUSHJ P,DISLIN ;TERMINAL CAN'T HELP - RE-DO REST OF LINE
CAMN RW,LPP.1 ;PUTTING ON BOTTOM LINE?
TLZ F,FNC ;YES - IF FENCE WAS UP, IT AIN'T NO MO
JRST DISCUR ;RE-POSITION CURSOR AND RETURN
;HERE TO PUT OLD CONTENTS OF PICK BUFFER
PUTNPM::SKIPN T1,PIKCNT ;GET COUNT OF CHARACTERS PICKED - ANY?
JRST PUTERR ;NO - ERROR
MOVEM T1,NUMCHR ;SAVE AS NUMBER OF CHARACTERS TO ADD
SOS ISVCNT ;DECREMENT INCREMENTAL SAVE COUNTER
TLO F,CHG!WRH ;SET TO READ FROM THE PICK BUFFER
TRNN F,POV ;WANT TO READ OFF DISK?
JRST PUTNP2 ;NO - READ FROM BUFFER
HRROI T2,PIKFIL
PUSHJ P,SETIN ;YES - SET FILE UP
MOVEM T1,PUTJFN ;SAVE JFN FOR MAKSPC
PUTNP2: SETZM MAKLNS ;CLEAR NUMBER OF <CRLF>S IN BUFFER
PUSHJ P,MAKCHR ;PUT THE BUFFER
SKIPN T4,MAKLNS ;ARE THERE <CRLF>S IN THE PICK BUFFER?
JRST PUT0 ;NO - JUST REWRITE ONE LINE
TLO F,XPB ;YES - BOTTOM POINTER IS BAD
PUSHJ P,OPENLD ;OPEN UP, SOMEHOW **NOTE: MAY NOT RETURN**
PUSHJ P,POSCUR ;POSITION TO START OF PUT
MOVE T4,MAKLNS ;GET NUMBER OF LINES TO DISPLAY
JUMPN CM,PUTNP3 ;JUMP IF NOT AT START OF A COLUMN
LDB T1,MAKPTR ;GET LAST CHARACTER PUT
CAIE T1,12 ;END OF LINE?
PUTNP3: AOJ T4, ;DO ONE MORE LINE IF START OR END W/IN LINE
MOVE T1,LPP(TM) ;FIND NUMBER OF LINES BELOW CURSOR
SUB T1,RW
CAMG T1,T4 ;IS PUT LONGER THAN THAT?
MOVE T4,T1 ;YES - DISPLAY ONLY WHAT WILL FIT
MOVE PT,CHRPTR ;DISPLAY FROM CURSOR POSITION
PUSHJ P,DISPLY
; TLZN F,FNC ;WAS THE FENCE ON THE SCREEN?
; JRST DISCUR ;NO - RE-POSITION CURSOR AND LOOP
PUSHJ P,FIXBLW ;YES - RESTORE IT IF IT'S STILL THERE
JRST DISCUR ;RE-POSITION CURSOR AND LOOP
;HERE TO PUT THE CONTENTS OF THE CLOSE BUFFER
PUTCLS: MOVE T1,[010700,,CLSBUF-1]
MOVEM T1,PUTPTR ;SET TO READ FROM CLOSE BUFFER
PUSHJ P,ERASPM ;ERASE PARAMETER
TLO F,CHG!WRH ;SET TO READ FROM THE CLOSE BUFFER
TRNN F,COV ;WANT TO READ OFF DISK?
JRST PUTCS1 ;NO - READ FROM BUFFER
HRROI T2,CLSFIL
PUSHJ P,SETIN ;YES - SET FILE UP
MOVEM T1,PUTJFN ;SAVE JFN FOR MAKSPC
PUTCS1: SKIPG T1,CLSCNT ;GET COUNT OF CHARS IN BUFFER - ANY?
JRST PUCERR ;NO - ERROR
MOVEM T1,NUMCHR ;YES - SAVE AS NUMBER OF CHARACTERS TO ADD
JRST PUTNP2 ;GO PUT THEM IN
PUCERR: MOVEI T1,[ASCIZ /#######Close buffer is empty/]
JRST ERROR
PUTERR: MOVEI T1,[ASCIZ /########Put buffer is empty/]
JRST ERROR
;**********************************************************************
;HERE TO INSERT A REAL TAB IN THE FILE - SAME AS IF USER TYPED E-C-C I
REALTB::MOVEI T1,11 ;GET A TAB
SETO DO, ;NOTE THAT A COMMAND IS ACTIVE
JRST ALPNU1 ;TREAT IT LIKE E-C-C I
;**********************************************************************
;HERE TO MARK POSITION FOR PICK OR CLOSE-LINES. THE NEXT SUCH COMMAND
;WILL TAKE TEXT FROM THE MARK TO THE CURSOR POSITION.
MARK:: PUSHJ P,MAKCPT ;GET A CORRECT CURSOR POINTER
DMOVE T1,LINPTR ;SAVE LINE AND CURSOR POINTER FOR LATER
DMOVEM T1,MRLPTR
MOVE T1,DISPTR ;SAVE CURRENT DISPLAY POINTER
MOVEM T1,MRKPTR
TLO F,PCM ;SET MARK FLAG
DMOVEM RW,SVPMRK ;SAVE STARTING POSITION
PUSHJ P,MRKCUR ;MARK THE CURSOR POSITION
MOVEM T3,SVPMRK+2 ;SAVE THE CHARACTER MARKED
PUSHJ P,POSCUR ;RE-POSITION AND OUTPUT
JRST LOOP ;THAT'S ALL
;HERE ON ENTER MARK, WHICH CANCELS THE MARK
MRKARG::TLZN F,PCM ;CANCEL THE MARK - GOT ONE?
JRST TBCLRX ;NO - REPAIR SCREEN AND GO HOME
DMOVE T1,MRLPTR ;RESTORE CURSOR AND LINE POINTERS
DMOVEM T1,LINPTR
MOVE T1,MRKPTR ;RESTORE THE OLD DISPLAY POINTER
EXCH T1,DISPTR
CAMN T1,DISPTR ;HAS DISPLAY POINTER CHANGED?
JRST MRKAG0 ;NO - REPAIR THE SCREEN AS IT IS
DMOVE RW,SVPMRK ;YES - RESTORE SAVED ROW AND COLUMN
TLZ F,ENT!XPL!XPC ;CANCEL THE ENTER; SAY CUR, LINE PTRS ARE GOOD
TLO F,XPB ;BUT BOTTOM POINTER IS NOT
JRST DISALL ;RE-DISPLAY THE SCREEN AND LOOP
MRKAG0: PUSHJ P,ERASPM ;FIX UP THE SCREEN
DMOVE RW,SVPMRK ;RESTORE SAVED ROW AND COLUMN
PUSHJ P,MRKAG1 ;DE-BLIP THE MARK
JRST LOOP ;RE-POSITION AND LOOP
MRKAG1: MOVE T1,SVPMRK+2 ;GET CHARACTER MARKED
MOVEM T1,CHRCUR
JRST RESTPM+2 ;DE-BLIP THE MARK AND RETURN
MRKRES: EXCH RW,SVPMRK ;DE-BLIP THE MARK AT THE STARTING POINT
EXCH CM,SVPMRK+1
PUSHJ P,MRKAG1
DMOVE RW,SVPMRK ;GET THE REAL POSITION BACK
POPJ P, ;DONE
;**********************************************************************
;HERE TO CHANGE THE CASE OF STUFF AT THE CURSOR. IF THE SWITCH
;/RAISE IS ON THE LETTER WILL BECOME UPPER; IF /NORAISE, LOWER
CHGCAS::TRNE F,RDO ;IS FILE READ-ONLY?
JRST RDOERR ;YES - COMMAND IS ILLEGAL
MOVE T4,CASSPS ;GET LAST TIME'S NOMINAL
TLNN F,ENT ;IS THERE A PARAMETER TYPED?
JRST CASNPM ;NO - USE THE ONE ALREADY SET UP
MOVEM T4,PARG1
PUSHJ P,PEEL.1 ;READ NEW PARM, IF ANY
MOVE T4,PARG1 ;GET COUNT OF CHARACTERS
TRNE F,CMV ;CURSOR MOVEMENT?
JRST [MOVEM T4,CASLNS ;YES - SAVE LINES TO WORK WITH
MOVE T4,PARG2 ;GET REAL SPACES TO WORK WITH
SKIPN CASLNS ;GOT ANY LINES?
JRST CASNP0 ;NO - USE SPACES AS IS
ADD T4,SAVPOS+1 ;YES - COUNT THEM FROM LEFT MARGIN
ADD T4,SL
JRST CASNP0]
SETZM CASLNS ;IF NO CURSOR MOVE, CLEAR EXTRA LINES
CASNP0: MOVEM T4,CASSPS ;SAVE SPACE COUNT AS NEW NOMINAL
PUSHJ P,ERASPM ;RESET ENTER MODE
PUSHJ P,POSCUR ;RE-POSITION THE CURSOR
TLNE TM,XCI ;INITIALIZING FOR AN EXECUTE?
JRST LOOP ;YES - DONE NOW
CASNPM::SKIPE T1,CASLNS ;GET LINES TO WORK WITH
MOVEI T4,^D1000 ;SET TO DO ENTIRE LINE
JUMPLE T4,DISCUR ;DONE IF GOT ZERO SPACES
MOVEM T1,CASLIN ;ELSE SAVE LINES IN A FRAGGABLE PLACE
SOS ISVCNT ;DECREMENT INCREMENTAL SAVE COUNTER
MOVEM T4,SAVEAC ;SAVE SPACE COUNT
PUSHJ P,MAKCPT ;GET A GOOD CHARACTER POINTER
MOVE T4,SAVEAC ;GET SPACE COUNT BACK
TLO F,CHG ;SAY FILE HAS BEEN CHANGED
SKIPN INVFLG ;WANT TO INVERT THE CASE?
JRST CASINV ;YES - GO DO IT
SKIPE UPCFLG ;NO - WANT LOWER CASE?
JRST CASUC0 ;NO - MAKE IT UPPER CASE
;HERE TO CHANGE LOWER CASE TO UPPER
MOVEI PT,CASLC2 ;YES - SET UP LC RETURN ADDRESS
CASLC1: ILDB T1,CHRPTR ;GET THE NEXT CHARACTER FROM THE FILE
JUMPE T1,CASENB ;IF NULL CHECK FOR END OF BUFFER
CAIL T1,"a" ;IS CHARACTER LOWER CASE?
CAILE T1,"z"
JRST CASSKP ;NO - JUST SKIP OVER IT
HRRZI T1,-40(T1) ;YES - CONVERT TO UPPER
PUSHJ P,CASSAV ;STORE AND OUTPUT THE CHANGED CHARACTER
CASLC2: SOJG T4,CASLC1 ;HANDLE THE NEXT CHARACTER
TLZ F,LFF ;CLEAR RETURN-FROM-CURSOR-MOVE FLAG
CASEND: TRNN F,RST ;WANT TO RESTORE THE NOMINAL PARAMETER?
JRST DISCUR ;NO - POSITION CURSOR; DONE
MOVEI T1,1
MOVEM T1,CASSPS ;YES - SET IT BACK TO ONE CHARACTER
SETZM CASLNS ; AND NO LINES
JRST DISCUR ;POSITION CURSOR; DONE
;HERE TO CHANGE UPPER CASE TO LOWER
CASUC0: MOVEI PT,CASUC2 ;GET UPPER CASE RETURN ADDRESS
CASUC1: ILDB T1,CHRPTR ;GET NEXT CHARACTER FROM THE FILE
JUMPE T1,CASENB ;IF NULL CHECK FOR END OF BUFFER
CAIL T1,"A" ;IS CHARACTER UPPER CASE?
CAILE T1,"Z"
JRST CASSKP ;NO - JUST SKIP OVER IT
MOVEI T1,40(T1) ;YES - CONVERT TO LOWER
PUSHJ P,CASSAV ;SAVE AND OUTPUT THE CHARACTER
CASUC2: SOJG T4,CASUC1 ;HANDLE THE NEXT CHARACTER
CASUC3: TLZ F,LFF ;CLEAR RETURN-FROM-CURSOR-MOVE FLAG
JRST CASEND ;DONE; GO FINISH UP
;HERE TO INVERT THE CASE: UPPER GOES TO LOWER AND VICE VERSA
CASINV: MOVEI PT,CASIV2 ;GET INVERT CASE RETURN ADDRESS
CASIV1: ILDB T1,CHRPTR ;GET NEXT CHARACTER FROM THE FILE
JUMPE T1,CASENB ;IF NULL CHECK FOR END OF BUFFER
CAIGE T1,"A" ;IS CHARACTER UPPER CASE?
JRST CASSKP ;NO - JUST SKIP OVER IT
CAILE T1,"Z"
JRST CASIVL ;NO - CHECK FOR LOWER CASE
MOVEI T1,40(T1) ;YES - CONVERT TO LOWER
CASIL1: PUSHJ P,CASSAV ;SAVE AND OUTPUT THE CHARACTER
CASIV2: SOJG T4,CASIV1 ;HANDLE THE NEXT CHARACTER
CASIV3: TLZ F,LFF ;CLEAR RETURN-FROM-CURSOR-MOVE FLAG
JRST CASEND ;DONE; GO FINISH UP
CASIVL: CAIL T1,"a" ;IS CHARACTER LOWER CASE?
CAILE T1,"z"
JRST CASSKP ;NO - JUST SKIP OVER IT
HRRZI T1,-40(T1) ;YES - CONVERT TO UPPER
JRST CASIL1 ;AND CONTINUE
CASENB: CAMN EN,CHRPTR ;FOUND A NULL - AT END OF BUFFER?
JRST CASIV3 ;YES - QUIT NOW
AOJA T4,@PT ;NO - LOOP
CASSAV: DPB T1,CHRPTR ;SAVE IT OVER THE OTHER ONE
JUMPL CM,CASSV1 ;DONE IF OFF THE LEFT OF THE SCREEN
TRNN F,XCT ;EXECUTING,
CAML CM,CPL.1 ; OR OFF THE RIGHT SIDE?
JRST CASSV1 ;YES - NO ECHO
MOVEM T1,SAVEAC ;NO - SAVE CHARACTER TO ECHO
TLZE F,LFF ;ALREADY POSITIONED?
PUSHJ P,POSCUR ;NO - POSITION, ALREADY
MOVE T1,SAVEAC ;GET CHARACTER BACK
TYPCHA ;AND OUTPUT IT
CASSV1: AOJA CM,CPOPJ ;ADJUST COLUMN POSITION AND RETURN
CASSKP: CAIN T1,15 ;END OF LINE?
JRST CASSKC ;MAYBE - CHECK IT OUT
JUMPL CM,CASSK2 ;NO DISPLAY IF OFF THE LEFT OF THE SCREEN
CAML CM,CPL.1 ;OFF THE RIGHT SIDE?
AOJA CM,@PT ;YES - NO DISPLAY EITHER
CAIN T1,11 ;TAB?
JRST CASSKT ;YES - FIX COLUMN POSITION AND CHARACTER COUNT
CASSK1: TLO F,LFF ;FLAG THAT CURSOR HAS MOVED
CASSK2: AOJA CM,@PT ;AND CONTINUE
CASSKT: ADD T4,CM ;GOT A TAB - SUBTRACT ITS LENGTH FROM THE COUNT
TRO CM,7 ;MOVE OVER TO TAB BOUNDARY
SUB T4,CM ;COMPLETE THE SUBTRACTION
JRST CASSK1 ;BACK TO THE FLOW
CASSKC: MOVE T2,CHRPTR ;GET CHARACTER AFTER THE CARRIAGE RETURN
ILDB T1,T2
CAIE T1,12 ;IS IT A LINEFEED?
JRST CASSK1 ;NO - JUST SKIP OVER THE CR
MOVEM T2,CHRPTR ;YES - DON'T COUNT IT AS A CHARACTER
MOVN CM,SL ;MOVE TO THE NEXT LINE
AOJ RW,
CAML RW,LPP(TM) ;WORKING ON BOTTOM LINE?
PUSHJ P,CASROL ;YES - ROLL DOWN A LINE
TLO F,XPL!XPC!LFF ;LINE AND CHARACTER POINTERS ARE INVALID
SOSGE T1,CASLIN ;GOT MORE LINES TO DO?
JRST CASUC3 ;NO - DONE
MOVEI T4,^D1000 ;SET TO DO ONE MORE LINE
JUMPN T1,@PT ;JUMP IS THIS IS NOT THE LAST LINE
SKIPE T4,CASSPS ;ELSE GET NUMBER OF SPACES IN LAST LINE - ANY?
AOJA T4,@PT ;YES - GO DO LAST LINE
JRST CASUC3 ;NO - DONE
CASROL: MOVEI T4,1 ;ROLL UP ONE LINE
MOVEM T4,ROLLS
PUSH P,PT
PUSHJ P,ROLFW ;GO DO THE ACTUAL ROLLING
POP P,PT
POPJ P,
;**********************************************************************
;HERE TO DELETE THE FIRST CHARACTER FROM THE PARAMETER BUFFER
DELFIR::SETZ T1, ;END PARAMETER BUFFER WITH A NULL
MOVE T2,PARPTR
IDPB T1,T2
CAMN T2,[POINT 7,PARBUF,6]
JRST LOOP ;NOTHING TO DO IF NOTHING IN BUFFER
MOVE PT,[POINT 7,PARBUF] ;ELSE POINT TO START OF THE BUFFER
MOVE T4,PT ;POINT TO FIRST AND SECOND CHARACTERS
IBP PT
DELFR1: ILDB T1,PT ;GET A CHARACTER
IDPB T1,T4 ;SAVE IT IN THE PREVIOUS POSITION
JUMPN T1,DELFR1 ;LOOP UNTIL NULL
PUSHJ P,ENTRMK ;MAKE THE MARK ON THE BOTTOM LINE
JRST RECAL1 ;GO TO RECALL CODE TO FINISH UP
;**********************************************************************
;ERASE THE PREVIOUS WORD
ERASWD::TRNE F,RDO ;IS FILE READ-ONLY?
JRST RDOERR ;YES - COMMAND IS ILLEGAL
SOS ISVCNT ;DECREMENT INCREMENTAL SAVE COUNTER
TLO F,XPC ;FORCE RE-MAKE OF CHARACTER POINTER
PUSHJ P,MAKCPT ;RE-MAKE IT
CAIN T3,15 ;IS THE CURSOR AT OR BEYOND END OF THE LINE?
PUSHJ P,ERSWDL ;YES - POSITION TO END OF LINE
MOVE PT,CHRPTR ;GET CHARACTER POINTER
JUMPE CM,ERAWDE ;IF AT LEFT MARGIN MOVE TO END OF LINE
ERAWD0: DMOVEM RW,SAVPOS ;SAVE CURRENT POSITION
TLO F,CHG!XPC ;SAY CHARACTER POINTER BAD; FILE MODIFIED
TLZ F,PCM!FLG ;CANCEL THE PICK-CLOSE MARK, IF ANY
IBP PT ;MAKE THE BYTE POINTER RIGHT FOR DECREMENTING
ERAWD1: PUSHJ P,ERAGET ;GET NEXT-MOST-RECENT CHARACTER
CAIN T1,12 ;LINEFEED?
JRST [PUSHJ P,ERAGET ;YES - GET (MAYBE) THE CARRIAGE RETURN
CAIE T1,15 ;IS IT?
SOJA CM,ERAWD3 ;NO - TREAT JUST LIKE A NORMAL CHARACTER
JRST ERAWDB] ;YES - END OF THE ERASE
CAIN T1,11 ;TAB?
TLOA F,FLG ;YES - SET FLAG, COUNT IT AND LOOP
CAIN T1," " ;SPACE?
SOJA CM,ERAWD1 ;YES - MOVE OVER IT
IFN TOPS10,<
CAIGE T1,"0" ;NUMERIC?
JRST ERAWDA ;NO - KEEP CHECKING
CAIG T1,"9"
SOJA CM,ERAWD2 ;YES - PHASE TWO
ERAWDA: CAIL T1,"A" ;ALPHABETIC?
CAILE T1,"Z"
SOJA CM,ERAWDX ;NO - STOP ON THE SPECIAL CHARACTER
>
SOJ CM,
ERAWD2: PUSHJ P,ERAGET ;GET NEXT-MOST-RECENT CHARACTER
ERAWD3: CAIGE T1,"0" ;NUMERIC?
JRST ERAWD4 ;NO - KEEP CHECKING
CAIG T1,"9"
SOJA CM,ERAWD2 ;YES - MOVE OVER IT
ERAWD4: CAIGE T1,"A" ;ALPHABETIC?
JRST ERAWDX ;NO - STOP HERE
CAIG T1,"Z"
SOJA CM,ERAWD2 ;YES - MOVE OVER IT
ERAWDX: CAIGE CM,0 ;BACK TO THE START OF THE LINE?
SETZ CM, ;YES
TLZE F,FLG ;WERE ANY TABS FOUND?
PUSHJ P,ERAWDT ;YES - CM MUST BE MADE RIGHT
ERAWX1: TRO F,CMV ;PRETEND ALL THIS WAS CURSOR MOVEMENT
MOVEI DO,$DELSP ;AND THAT DELETE-SPACES WAS TYPED
EXCH RW,SAVPOS ;SWAP CURRENT AND STARTING POSITIONS
EXCH CM,SAVPOS+1
PUSHJ P,PEEL.1 ;READ NEW PARM, IF ANY
MOVE T4,PARG1 ;GET SPACES TO DELETE
PUSHJ P,SPSCUR ;YES - HANDLE THINGS A LITTLE DIFFERENTLY
TRZ F,CMV ;CLEAR CURSOR MOVE FLAG (IF COMING FROM ERASWD)
SKIPN T1,T4 ;PUT SPACES TO DELETE IN THE RIGHT AC - ANY?
JRST DISCUR ;NO - DONE
JRST CLSNP0 ;GO DO THE CLOSE-SPACES
ERAWDB: SETZ CM, ;MOVE TO THE BEGINNING OF THE LINE
TLZ F,FLG ;DON'T CARE IF A TAB WAS FOUND
JRST ERAWX1 ;GO FINISH OFF
ERAWDT: MOVE T4,CHRPTR ;GET OLD CHARACTER POINTER
MOVEM PT,CHRPTR ;SAVE POINTER TO ENDING CHARACTER
TLO F,XPC!XPL
PUSHJ P,CALCML ;FIND WHERE CM REALLY IS
JFCL
MOVEM T4,CHRPTR ;RESTORE OLD POINTER
POPJ P, ;DONE
;HERE IF STARTING AT OR BEYOND THE END OF A LINE
;POSITION TO THE END OF THE LINE, THEN ERASE THE WORD
;(CALLED ALSO BY DELCHR)
ERSWDL: PUSHJ P,CALCML ;CALCULATE PROPER VALUE OF CM
JRST POSCUR ;DON'T CARE IF THERE'S A SLIDE
JRST POSCUR ;POSITION THE CURSOR AND RETURN
;HERE IF STARTING AT START OF LINE - DELETE LAST WORD OF PREVIOUS LINE
ERAWDE: SOJL RW,ERAWE2 ;MOVE UP A ROW - JUMP IF AT TOP
PUSHJ P,ERAGET ;BACK THE CHARACTER POINTER UP
PUSHJ P,ERAGET
MOVEM PT,CHRPTR
PUSHJ P,MAKLPT ;GET THE POINTER TO THAT ROW (IN LINPTR AND PT)
PUSHJ P,CALCCM ;FIND CHARACTER POSITION
JRST ERAWD0
JRST ERAWD0
ERAWE2: SETZB RW,CM ;IF USER STARTED AT HOME
JRST DISCUR ;LEAVE HIM THERE
;SUBROUTINE TO GET THE NEXT-LATEST FILE CHARACTER
ERAGET: ADD PT,[70000,,0] ;GET NEXT-MOST-RECENT CHARACTER
CAIGE PT,0
SUB PT,[430000,,1]
LDB T1,PT
JUMPE T1,ERAGET ;SKIP IF NULL
CAIL T1,"a" ;LOWER CASE (MAYBE)?
SUBI T1,40 ;YES - CONVERT TO (MAYBE) UPPER
POPJ P, ;DONE
;**********************************************************************
;RECOVER COMMAND - PUT THE CONTENTS OF THE DELETE BUFFER BACK IN THE FILE
RECOVR::PUSHJ P,ERASPM ;CLEAN UP ENTER MODE
TLO F,INS!CHG ;LET LINE BE EXTENDED IF NECESSARY
PUSHJ P,MAKCPT ;MAKE SURE THE CURSOR POINTER IS RIGHT
TLZ F,INS!PCM
SKIPN T4,DELCNT ;GET SIZE OF THE DELETE BUFFER - ANY?
JRST DISCUR ;NO - NOTHING TO DO
CAIN T4,1 ;WANT TO PUT IN ONE CHARACTER?
JRST RECOV1 ;YES - HANDLE SPECIALLY
MOVEM T4,NUMCHR ;SAVE NUMBER OF CHARACTERS TO ADD
MOVE T1,[010700,,DELBUF-1]
MOVEM T1,PUTPTR ;SET TO READ FROM DELETE BUFFER
TLO F,WRH ;SET USE-BUFFER FLAG FOR MAKCHR
JRST PUTNP2 ;GO PUT THEM IN
;HERE TO RECOVER ONE CHARACTER - SIMULATE INSERT-MODE TYPE-IN
RECOV1: LDB T1,[350700,,DELBUF] ;GET THE CHARACTER TO INSERT
JRST ALPIMD ;INSERT THE CHARACTER; DONE
;**********************************************************************
;HERE FOR THE SUBSTITUTE COMMAND - SEARCH FOR THE SEARCH KEY, REPLACE IT
;WITH THE SUBSTITUTE STRING; LOOP THE GIVEN NUMBER OF TIMES
SUBSTI::TRZE F,CMV ;DID USER USE CURSOR MOVEMENT?
JRST SUMERR ;YES - ILLEGAL
SETZB T1,SUBNUM ;END BUFFER WITH A NULL
IDPB T1,PARPTR
MOVE T4,[POINT 7,PARBUF] ;GET POINTER TO PARAMETER BUFFER
SUBST0: SETZB T1,T3 ;CLEAR THINGS FOR PEEL ROUTINES
ILDB T2,T4 ;GET FIRST CHARACTER OF PARAMETER
CAIL T2,"a" ;LOWER CASE?
SUBI T2,40 ;MAYBE - CONVERT TO UPPER
CAIN T2,"S" ;SET UP THE SEARCH KEY?
JRST SUBSRC ;YES - DO IT
CAIN T2,"R" ;SET UP THE SUBSTITUTE STRING?
JRST SUBSUB ;YES - DO IT
;HERE TO SET UP A NUMBER OF ITERATIONS
PUSHJ P,PEEL1+1 ;READ (HOPEFULLY) A NUMBER
JUMPE T1,SUMERR ;ERROR IF TOKEN
SKIPG T1,PARG1 ;ELSE GET NUMBER OF ITERATIONS - ANY?
JRST SUNERR ;NO - ERROR
MOVEM T1,SUBCNT ;YES - SAVE AS NEW NOMINAL
MOVEM T1,SUBNUM ;AND NOTE THAT IT'S NEW
CAIE T2,177 ;END WITH A DELIMITER?
JRST SUBDUN ;NO - FINISH UP
JRST SUBST0 ;YES - FIND WHAT'S NEXT
;HERE TO SET UP THE SUBSTITUTE KEY AS THE SEARCH KEY (SUBSRC)
; OR THE SUBSTITUTE STRING (SUBSUB)
;ENTER WITH T4/ POINTER TO START OF KEY IN PARBUF
SUBSRC: MOVE T2,[SRCKEY,,SROKEY]
BLT T2,SROKEY+7 ;SAVE CURRENT KEY AS PREVIOUS ONE
MOVE T3,[POINT 7,SRCKEY]
PUSHJ P,PELST2 ;GET SEARCH KEY
MOVEM T1,SRCKLN ;SAVE ITS LENGTH
CAIE T2,177 ;END WITH A DELIMITER?
JRST SUBDUN ;NO - FINISH UP
JRST SUBST0 ;YES - FIND WHAT'S NEXT
SUBSUB: MOVE T3,[POINT 7,SUBSTG]
PUSHJ P,PELST2 ;GET SUBSTITUTE STRING
MOVEM T1,SUBSLN ;SAVE ITS LENGTH
MOVE T1,CM ;SAVE THE REAL CURSOR POSITION
SETZ CM, ;SEE HOW LONG THE STRING IS
PUSHJ P,SUBCB0 ;(TO SEE IF THERE ARE ANY TABS IN IT)
EXCH T1,CM ;RESTORE THE REAL POSITION
CAME T1,SUBSLN ;ARE THERE TABS?
MOVNS SUBSLN ;YES - INDICATE WITH A NEGATIVE LENGTH
CAIN T2,177 ;END WITH A DELIMITER?
JRST SUBST0 ;YES - FIND WHAT'S NEXT (ELSE FALL TO FINISH)
;HERE TO FINISH WITH PARAMETERS - DO COMMAND ONLY IF ITERATIONS WERE GIVEN
SUBDUN: PUSHJ P,ERASPM ;ERASE THE PARAMETER FROM THE SCREEN
TLNN TM,XCI ;INITIALIZING FOR AN EXECUTE?
SKIPN SUBNUM ;NO - WAS A NUMBER OF ITERATIONS GIVEN?
JRST LOOP ;NO INIT, NO NUMBER - DONE
;HERE TO DO THE SUBSTITUTE FROM THE PARAMETERS SET UP ABOVE
SUBNPM::TRNE F,RDO ;IS FILE READ-ONLY?
JRST RDOERR ;YES - COMMAND IS ILLEGAL
SKIPG T1,SUBCNT ;WANT TO DO ANY SUBSTITUTES?
JRST SUNERR ;NO - ERROR (SHOULDN'T HAPPEN)
MOVEM T1,SUBNUM ;YES - SAVE DECREMENTABLE NUMBER TO DO
MOVEI T2,1
TRNE F,RST ;WANT TO RESTORE THE NOMINAL PARAMETER?
MOVEM T2,SUBCNT ;YES - SET IT BACK TO ONE
SETZM SAVEAC+1 ;CLEAR BOTTOM-LINE MESSAGE FLAG
TLZ F,PCM ;CANCEL THE PICK-CLOSE MARK, IF ANY
TLO F,CHG ;SAY FILE HAS CHANGED
MOVEM F,SAVEAC+10 ;SAVE OLD SETTING OF XCT FLAG
SUBNP0: PUSHJ P,SRFNPM ;SEARCH FOR THE KEY
MOVE T4,SRCKLN ;NULL IT OUT
SETZ T2,
MOVE PT,CHRPTR
SUBNP1: ILDB T1,PT ;GET A CHARACTER
JUMPE T1,SUBNP1 ;IGNORE IF NULL
DPB T2,PT ;ELSE NULL IT OUT
CAIN T1,15 ;WAS IT A CARRIAGE RETURN?
TLO F,FLG ;YES - REMEMBER THAT FACT
SOJG T4,SUBNP1 ;LOOP THROUGH ALL CHARACTERS
SKIPN T4,SUBSLN ;GET SIZE OF THE SUBSTITUTE STRING - ANY?
JRST SUBNP2 ;NO - NOTHING TO DO
MOVMM T4,NUMCHR ;SAVE NUMBER OF CHARACTERS TO ADD
MOVE T1,[010700,,SUBSTG-1]
MOVEM T1,PUTPTR ;SET TO READ FROM SUBSTITUTE BUFFER
TLO F,WRH ;SET USE-BUFFER FLAG FOR MAKCHR
PUSHJ P,MAKCHR ;PUT THE STUFF IN
SUBNP2: TLO F,XPC ;MARK CURSOR POINTER AS INVALID
SKIPE SAVEAC+1 ;WAS DISPLAY POINTER MOVED DURING LAST SEARCH?
TROA F,XCT ;YES - PRETEND EXECUTING TO TURN OFF DISPLAY
PUSHJ P,DISLIN ;NO - DISPLAY THE CHANGE THAT WAS MADE
MOVE T1,CM ;SAVE OLD CURSOR POSITION
PUSHJ P,SUBCTB ;MOVE CURSOR TO LAST CHARACTER OF SUB. STRING
SOSG SUBNUM ;GOT MORE TO DO?
JRST SUBNP3 ;NO - DONE
TLZN F,FLG ;YES - TOOK OUT A CARRIAGE RETURN?
SOJA CM,SUBNP0 ;NO - JUST LOOP
PUSHJ P,CCREOL ;YES - IF AT END OF FILE PUT THE CR BACK
JUMPE T2,SUBNP3 ;DONE IF IT WAS END OF FILE
SOJA CM,SUBNP0 ;ELSE LOOP
SUBNP3: EXCH T1,SAVEAC+10 ;NO - GET SAVED FLAGS AND SAVE OLD POSITION
TRNN T1,XCT ;WAS AN EXECUTE IN PROGRESS?
TRZ F,XCT ;NO - CLEAR EXECUTE FLAG
SKIPE SAVEAC+1 ;MOVE OFF THE SCREEN?
SOJA CM,DISALL ;YES - REWRITE THE SCREEN AND RETURN
SOJA CM,DISCUR ;NO - MAKE CURSOR POSITION RIGHT AND LOOP
;SUBROUTINE TO COUNT THE LENGTH OF THE SUBSTITUE STRING. USES SUBSLN
;IF IT'S POSITIVE; IF NEGATIVE, THERE ARE TABS IN THE STRING, SO THE
;COUNT MUST BE MADE FOR EACH SUBSTITUTE.
;UPDATES CM; USES T0, T3; PRESERVES T1, T2
SUBCTB: SKIPG T3,SUBSLN ;ANY TABS IN THE STRING?
JRST SUBCB0 ;YES - GO COUNT THEM THE HARD WAY
ADD CM,T3 ;NO - ADVANCE THE CURSOR OVER THE STRING
POPJ P, ;DONE
SUBCB0: MOVE T3,[POINT 7,SUBSTG] ;GET POINTER TO THE SUBSTITUTE STRING
SUBCB1: ILDB T0,T3 ;GET A CHARACTER OF THE STRING
JUMPE T0,CPOPJ ;DONE IF NULL
CAIN T0,11 ;TAB?
TRO CM,7 ;YES - MOVE TO THE NEXT TAB STOP
AOJA CM,SUBCB1 ;ELSE COUNT IT AND GET ANOTHER ONE
SUNERR: SKIPA T1,[[ASCIZ /######Can't do 0 iterations/]]
SUMERR::MOVEI T1,[ASCIZ /#####Cursor movement is illegal/]
JRST ERROR
;**********************************************************************
;HERE TO JUSTIFY LINES OF TEXT BETWEEN /LM: AND /RM:.
;WITH A PARAGRAPH INDENT OF /PIND: AND A PREFIX STRING OF /JPRE:
;IF /FILL IS SET, ALIGNS THE RIGHT MARGIN; /NOFILL LEAVES IT RAGGED
JUSTIF::TRNE F,RDO ;IS FILE READ-ONLY?
JRST RDOERR ;YES - COMMAND IS ILLEGAL
SETZ T1, ;END PARAMETER BUFFER WITH A NULL
IDPB T1,PARPTR
MOVE PT,[POINT 7,PARBUF]
PUSHJ P,SWHLUR ;READ PARAMETER CHARACTER
CAIN T1,"C" ;WANT TO CENTER THIS LINE?
JRST JUSCEN ;YES - GO DO IT
MOVE T4,JUSLNS ;GET LAST TIME'S NOMINAL
TLNN F,ENT ;IS THERE A PARAMETER TYPED?
JRST JUSNPM ;NO - USE THE ONE ALREADY SET UP
MOVEM T4,PARG1
PUSHJ P,PEEL.1 ;READ NEW PARAMETER, IF ANY
MOVE T4,PARG1 ;GET NUMBER OF LINES TO JUSTIFY
MOVEM T4,JUSLNS ;SAVE IT AS THE NEW NOMINAL
JUMPE T1,[SETOM SAVEAC+2 ;IF TOKEN, FLAG IT SO
MOVEI T4,1000 ;AND SET NUMBER OF LINES BIG
JRST JUSTI1] ;BACK TO THE FLOW
SETZM SAVEAC+2 ;CLEAR TOKEN FLAG
JUSTI1: PUSHJ P,ERASPM ;RESET ENTER MODE
TLNE TM,XCI ;INITIALIZING FOR AN EXECUTE?
JRST LOOP ;YES - DONE NOW
MOVEI T1,1
TRNE F,RST ;WANT TO RESTORE THE NOMINAL PARAMETER?
MOVEM T1,JUSLNS ;YES - SET IT BACK TO ONE
JUSNPM::JUMPE T4,DISCUR ;NOTHING TO DO IF ZERO LINES
MOVEM T4,SAVEAC+1 ;ELSE SAVE FRAGGABLE COUNT
MOVEM T4,SAVEAC+6 ;SAVE ALSO FOR DISPLAYING AT END
SOS ISVCNT ;DECREMENT INCREMENTAL SAVE COUNTER
SETZ CM, ;MOVE THE CURSOR TO THE START OF THE LINE
TLO F,XPC ;FORCE POINTER TO BE RE-MADE
PUSHJ P,MAKCPT ;GET A GOOD CHARACTER POINTER
MOVE PT,CHRPTR ;POINT TO THE START OF THE TEXT
TLZ F,FLG ;CLEAR AND PARAGRAPH FLAG
TLO F,PCM!CHG ;SET SPACER FLAG SO LEADING SPACERS ARE SKIPPED
MOVEI T3," " ;GET A SPACE
;PASS 1: LOOK THROUGH THE ENTIRE RANGE. CHANGE CRLF'S TO A SPACE; CHANGE
;MULTIPLE TABS, SPACES, AND CRLF'S TO A SINGLE SPACE. IF END OF A PARAGRAPH
;(TWO CRLF'S OR CRLF-SPACERS), IS FOUND, LEAVE ONE CRLF TO MARK IT.
;FLG == CRLF FOUND; SPACERS OR CRLF IS START OF A NEW PARAGRAPH
;PCM == SPACE FOUND; NULL ANY OTHERS
;SET UP POINTER TO END OF RANGE. CHECK FOR END OF FILE HERE;
;IGNORE IT IN PASS 2
;TOKEN JUSTIFY: SET FLAG; END PASS 1 ON FIRST END OF PARAGRAPH
;SAVEAC+0: POINTER TO PLACE TO PUT A CRLF BACK IN
; +1: FRAGGABLE JUSLNS
; +2: -1 == TOKEN PARAMETER, ELSE ZERO
; ...
; +6: JUSLNS AGAIN (USED BY JUSDPY)
PUSHJ P,JUSSTR ;STRIP THE LEADING STRING OFF THE FIRST LINE
JUSTP1: SETZB T4,T0 ;GET A NULL FOR NULLING; CLEAR SPACE POINTER
JUSP1A: ILDB T1,PT ;GET A CHARACTER
CAIG T1," " ;SPECIAL CHARACTER?
JRST JUS1A3 ;MAYBE - CHECK FURTHER
JUS1A2: TLZ F,FLG!PCM ;OTHER CHARACTER - CLEAR CRLF AND SPACER FLAGS
JRST JUSTP1 ;COUNT IT AND DO SOME MORE
JUS1A3: CAMN PT,EN ;REACHED THE END OF THE FILE?
JRST JUSP2T ;YES - END OF PASS 1
JUMPE T1,JUSP1A ;IGNORE NULLS
CAIE T1," " ;SPACE,
CAIN T1,11 ; OR TAB?
JRST JUS1SP ;YES - DO SPACER STUFF
CAIE T1,15 ;CARRIAGE RETURN?
JRST JUS1A2 ;NO - SKIP THE NORMAL CHARACTER
;YES - FALL TO CHECK FOR LINEFEED
;HERE WHEN A CARRIAGE RETURN IS FOUND. IF NOT FOLLOWED BY A LINEFEED, IT'S
;JUST ANOTHER CHARACTER. OTHERWISE COUNT ANOTHER LINE OF THE RANGE (DONE IF
;COUNTED OUT). SET CRLF AND SPACER FLAGS (FLG, PCM); CHANGE THE CRLF TO
;SPACE, NULL; SAVE POINTER TO THE FORMER CRLF IN CASE OF END OF PARAGRAPH
MOVE T2,PT ;GET POINTER TO THE CR
ILDB T1,PT ;GET THE NEXT CHARACTER
JUMPE T1,.-1 ;IGNORE NULLS
CAIE T1,12 ;IS IT A CRLF?
JRST JUS1A2 ;NO - TREAT LONE CR LIKE A NORMAL CHARACTER
TLOE F,FLG ;YES - SET CRLF FLAG - ALREADY SET?
JRST JUS1C4 ;YES - IT'S END OF PARAGRAPH - LEAVE THE CRLF
MOVEM T2,SAVEAC ;NO - SAVE THE POINTER TO THE FORMER CRLF
TLNE F,PCM ;IS THE SPACER FLAG SET?
JRST JUS1C1 ;YES - SKIP THIS
DPB T3,T2 ;NO - COVER THE CR WITH A SPACE
MOVE T0,T2 ;SAVE THE POINTER TO THE SPACE
JRST JUS1C2 ;SKIP THE OTHER DPB AND CONTINUE
JUS1C1: DPB T4,T2 ;YES - COVER THE CR WITH A NULL
JUS1C2: DPB T4,PT ;AND COVER THE LF WITH A NULL
JUS1C3: TLO F,PCM ;SET THE SPACER FLAG
SOSG SAVEAC+1 ;DECREMENT COUNT OF LINES - DONE?
JRST JUSTP2 ;YES - IT'S TIME FOR PASS 2
PUSHJ P,JUSSTR ;NO - STRIP THE HEADER STRING FROM NEXT LINE
JRST JUSP1A ;AND CONTINUE WITH PASS 1
;HERE ON THE END OF A PARAGRAPH. IF A TOKEN PARAMETER WAS GIVEN, END PASS 1.
JUS1C4: JUMPE T0,JUS1C5 ;IS THERE A SPACE TO NULL OUT?
DPB T4,T0 ;YES - DO SO
SETZ T0, ;CLEAR POINTER TO SPACE
JUS1C5: SKIPE SAVEAC+2 ;END OF PARAGRAPH - WAS IT A TOKEN PARM?
JRST JUSP2T ;YES - DONE WITH PASS 1
SKIPN SAVEAC ;NO - GOT END OF PARAGRAPH ALREADY?
JRST JUS1C1 ;YES - NULL OVER THE WHOLE CRLF
SETZM SAVEAC ;NO - NOTE THAT EOP'S CRLF IS ALREADY THERE
JRST JUS1C3 ;AND CONTINUE
;SUBROUTINE CALLED AT THE START OF EACH LINE
;REMOVES THE HEADER STRING, IF IT'S PRESENT, FROM THE LINE.
;IF IT'S NOT PRESENT, NO SWEAT.
JUSSTR: HRRZ T4,JSHCNT ;WANT TO REMOVE ANYTHING?
JUMPE T4,CPOPJ ;NO - NOTHING TO DO
PUSH P,T2 ;SAVE A WORK AC
PUSH P,PT ;AND THE POINTER TO THE START OF THE LINE
MOVE T3,[POINT 7,JUSHED] ;POINT TO THE START OF THE STRING
JUSTR1: ILDB T1,PT ;GET THE NEXT CHARACTER
JUMPE T1,.-1 ;SKIP IT IF NULL
ILDB T2,T3 ;AND THE NEXT CHARACTER OF THE STRING
CAME T2,T1 ;STILL MATCHING?
JRST JUSTRX ;NO - DON'T STRIP
SOJG T4,JUSTR1 ;YES - LOOP THROUGH THE ENTIRE STRING
POP P,PT ;IT ALL MATCHES - POINT BACK TO START
HRRZ T3,JSHCNT ;GET THE LENGTH OF THE STRING
JUSTR2: ILDB T1,PT ;NULL OUT THE STRING - GET NEXT CHARACTER
JUMPE T1,.-1 ;SKIP IT IF NULL
DPB T4,PT ;ELSE NULL IT OUT,
SOJG T3,JUSTR2 ;COUNT IT AND LOOP
JUSTR3: MOVEI T3," " ;RESTORE THE SAVED AC
POP P,T2 ;RESTORE THE WORK AC
POPJ P, ;DONE
JUSTRX: POP P,PT ;RESTORE ALL THE INTERESTING ACS
SETZ T4, ;PUT A NULL BACK IN T4
JRST JUSTR3 ;DONE
;HERE IF A SPACE IS FOUND IN PASS 1. SET THE SPACER FLAG (PCM). IF IT WAS
;SET NULL OUT THE SPACE. IF THE CRLF FLAG (FLG) IS ON IT'S THE END OF A
;PARAGRAPH. CHANGE A TAB TO A SPACE.
JUS1SP: TLOE F,PCM ;MARK THE SPACER - ALREADY GOT ONE?
JRST JUS1S1 ;YES - NULL THIS ONE OUT
CAIN T1,11 ;NO - IS THE CHARACTER A TAB?
DPB T3,PT ;YES - CHANGE IT TO A SPACE
MOVE T0,PT ;SAVE THE POINTER TO THE SPACE
JRST JUSP1A ;AND CONTINUE WITH PASS 1
JUS1S1: DPB T4,PT ;NULL OUT THIS SPACER
TLNE F,FLG ;IS THIS THE END OF A PARAGRAPH?
SKIPN T2,SAVEAC ;YES - GET PTR TO FORMER CRLF - ALREADY DONE?
JRST JUSP1A ;NO OR DONE - GO CONTINUE WITH PASS 1
JUMPE T0,JUS1S2 ;IS THERE A SPACE TO NULL?
DPB T4,T0 ;YES - DO SO
JUS1S2: MOVEI T1,15 ;PUT A CRLF BACK IN TO MARK END OF PARAGRAPH
DPB T1,T2
MOVEI T1,12
IDPB T1,T2
SETZM SAVEAC ;NOTE THAT THIS PARAGRAPH HAS BEEN MARKED
JRST JUSTP1 ;CONTINUE WITH PASS 1
;HERE FOR PASS 2. PT/ END OF THE REGION, DO/ # CHARS IN RANGE.
;NOW THERE IS ONLY ONE SPACE BETWEEN EACH WORD AND A CRLF MARKS THE
;END OF A PARAGRAPH
;CARVE OFF FULL WORDS UNTIL LINE COUNT IS SATISFIED, THEN INDENT, JUSTIFY,
;AND ADD A CRLF AT THE END (BUT DON'T JUSTIFY IF IT'S THE END OF THE
;PARAGRAPH).
;SAVEAC+0: POINTER TO START OF CURRENT LINE
; +1: POINTER TO THE PLACE TO SAVE THE LINE
; +2: NUMBER OF WORDS IN THIS LINE
; +3: POINTER TO END OF REGION
; +4: INDENT FOR THIS LINE
; +5: NUMBER OF LINES IN REGION AFTER JUSTIFY
; +6: NUMBER OF LINES IN REGION BEFORE JUSTIFY (USED BY JUSDPY)
; +7: NUMBER OF CHARACTERS UP TO THE LATEST WORD
JUSP2T: MOVN T1,SAVEAC+1 ;HERE FROM A TOKEN PARAMETER:
AOJ T1, ;FIND NUMBER OF LINES IN REGION
ADDB T1,SAVEAC+6 ;SAVE FOR THE DISPLAY ROUTINE
TRNN F,RST ;WANT TO RESTORE THE NOMINAL PARAMETER?
MOVEM T1,JUSLNS ;NO - SAVE LINE COUNT FOR NEXT TIME
JUSTP2: TLZ F,PCM ;CLEAN UP FROM PASS 1
TLO F,FLG ;TURN PARAGRAPH FLAG ON
MOVEM PT,SAVEAC+3 ;SAVE POINTER TO END OF REGION
HRRZM PT,ADJWRD ;SAVE IT ALSO FOR ADJUSTING
MOVE T1,LMARGN ;FIND HOW MANY NULLS TO ADD:
ADD T1,PARIND ;GET THE LEFT MARGIN PLUS THE INDENT
ADDI T1,^D20 ; PLUS 20 SPACES PER LINE
IMUL T1,SAVEAC+6 ; TIMES THE NUMBER OF LINES IN THE RANGE
MOVEM T1,NUMCHR ;GIVES NUMBER OF NULLS NEEDED (AT MOST)
PUSHJ P,MAKNUL ;PUNCH A HOLE IN THE FILE
SETZ T1, ;CLEAR AND GET ADJUSTED END-OF-REGION ADDRESS
EXCH T1,ADJWRD
HRRM T1,SAVEAC+3 ;SAVE IN THE E-O-R POINTER
MOVE T1,CHRPTR ;GET POINTER TO START OF NULLS
MOVEM T1,LINPTR ;IT'S THE START OF THE FIRST LINE, TOO
MOVEM T1,SAVEAC+1 ;AND START OF THE JUSTIFIED TEXT
MOVE PT,T4 ;GET POINTER TO START OF UNJUSTIFIED TEXT
SETZB T4,SAVEAC+5 ;CLEAR COUNT OF ENDING LINES
JUSP2S: MOVE T3,RMARGN ;GET COUNT OF CHARACTERS THIS LINE
MOVE T2,LMARGN ;FIND THE INDENTATION
TLNE F,FLG ;DID A PARAGRAPH JUST START?
ADD T2,PARIND ;YES - ADD PARAGRAPH INDENT, TOO
CAIGE T2,0 ;GOT A NEGATIVE TOTAL INDENT?
SETZ T2, ;YES - FORCE IT TO ZERO
MOVEM T2,SAVEAC+4 ;SAVE THIS LINE'S INDENT
SUB T3,T2 ;AND SUBTRACT IT FROM NUMBER OF CHARS WANTED
HLRZ T1,JSHCNT ;SUBTRACT THE LENGTH OF HEADER, TOO
SUB T3,T1
SETZB T0,SAVEAC+2 ;CLEAR COUNTS OF CHARS AND WORDS THIS LINE
MOVEM PT,SAVEAC ;SAVE POINTER TO START OF THIS LINE
JUSP2A: CAMN PT,SAVEAC+3 ;REACHED THE END OF THE REGION?
JRST JUS2ND ;YES - FINISH OFF AND DISPLAY
ILDB T1,PT ;NO - GET A CHARACTER
CAIG T1," " ;SPACE OR LESS?
JRST JUS2CK ;YES - CHECK FURTHER
JUSP2B: TLZ F,FLG ;SAY IT'S NO LONGER THE END OF A PARAGRAPH
SOJGE T3,JUSP2A ;COUNT THE CHARACTER - LOOP IF NOT END OF LINE
;HERE WHEN COUNTED OUT TO END OF LINE - DO THE JUSTIFICATION
;FLG == THE END OF THE PARAGRAPH
;PCM == THE END OF THE REGION
JUS2EL: JUMPN T0,JUS2E0 ;WAS A SPACE FOUND IN THE LINE?
MOVE T0,PT ;NO - SET TO WRAP THE LINE AROUND
TDZA T3,T3 ;REMEMBER THAT LINE WRAPPED
JUS2E0: SETO T3, ;NOTE THAT LINE DIDN'T WRAP
MOVE PT,SAVEAC ;GET POINTER TO THE START OF THE LINE
MOVE T2,SAVEAC+1 ;AND POINTER TO THE PLACE TO STORE THE LINE
PUSHJ P,JUSINS ;INDENT THE LINE
MOVEI DO,-1 ;GET DEFAULT NUMBER OF WORDS (BIG)
SETZ T1, ;GET DEFAULT SPACES PER WORD (ONE)
SKIPE FLLFLG ;USE DEFAULT IF NOT FILLING
TLNE F,FLG!PCM ;OR IF END OF PARAGRAPH OR REGION
JRST JUS2ES
JUMPE T3,JUS2ES ;OR IF LINE WRAPPED AROUND
SKIPG T1,SAVEAC+7 ;GET THE NUMBER OF EXTRA SPACES TO ADD - ANY?
JRST JUS2ES ;NO - NOTHING TO ADJUST
SOS SAVEAC+2 ;WORD COUNT WAS ONE TOO LARGE
MOVE DO,T2 ;STORE POINTER FOR EXCHANGING BELOW
IDIV T1,SAVEAC+2 ;OVER NUMBER OF WORDS, GIVES SPACES PER LINE
EXCH DO,T2 ;GET # OF WORDS WHICH GET EXTRA SPACE
JUMPE DO,[MOVEI DO,-1 ;IF GOT EXACTLY ENOUGH SPACES
JRST JUS2ES] ;DO THE SAME THING FOR EVERY WORD
TLCN F,LFF ;FLIP ODD/EVEN LINE FLAG - EVEN?
AOJA T1,JUS2ES ;YES - ADD IN THE EXTRA SPACE AND CONTINUE
MOVN DO,DO
ADD DO,SAVEAC+2 ;GET # OF WORDS WHICH GET NORMAL SPACING
JUS2ES: MOVEM T1,SAVEAC+2 ;SAVE NUMBER OF SPACES - 1 BETWEEN WORDS
JUS2E1: ILDB T1,PT ;GET A CHARACTER
CAMN PT,T0 ;AT THE END OF THE LINE?
JRST JUS2E2 ;YES - FINISH THE LINE AND LOOP
JUMPE T1,JUS2E1 ;NO - IGNORE IT IF NULL
DPB T4,PT ;ELSE NULL OUT THE SOURCE CHARACTER
CAIN T1," " ;END OF A WORD?
PUSHJ P,JUS3SP ;YES - ADD THE RIGHT AMOUNT OF SPACE
IDPB T1,T2 ;NO - SAVE THE CHARACTER
JRST JUS2E1 ;AND GET ANOTHER ONE
JUS2E2: CAIE T3,0 ;DID THE LINE WRAP AROUND?
DPB T4,PT ;NO - NULL OUT THE SOURCE CHARACTER
PUSHJ P,JUSEOL ;END THE LINE WITH A CRLF
TLNE F,FLG ;IS THIS THE END OF A PARAGRAPH?
PUSHJ P,JUSEOL ;YES - THROW OUT ANOTHER CRLF
MOVEM T2,SAVEAC+1 ;SAVE THE STORAGE POINTER
JUMPE T3,JUS2E4 ;IF PREVIOUS LINE WRAPPED, DON'T LOSE LAST CHAR
TLNN F,PCM ;DONE WITH THE ENTIRE RANGE?
JUS2E3: CAMN PT,SAVEAC+3 ;NO - SEE IF THE REGION ENDS HERE
JRST JUSDPY ;IT DOES - GO DISPLAY
ILDB T1,PT ;CHECK ALL THE NULLS AT THE END OF THE LINE
JUMPE T1,JUS2E3
JUS2E4: ADD PT,[70000,,0] ;BACK UP BEHIND THE REAL CHARACTER AGAIN
JUMPGE PT,JUSP2S
SUB PT,[430000,,1]
JRST JUSP2S ;THEN GO DO THE NEXT LINE
;HERE WHEN END OF REGION IS REACHED - SET FLAG TO SAY SO AND
;GO FINISH OFF THE LAST LINE. THEN DISPLAY; DONE
JUS2ND: TLO F,PCM ;NOTE THAT THIS IS THE LAST LINE
TLNN F,FLG ;JUST ENDED A PARAGRAPH?
JRST JUS2EL ;NO - FINISH THE LAST LINE; DONE
JRST JUSDPY ;YES - GO DISPLAY THE RESULT
;HERE WHEN A SPACE IS FOUND DURING PASS 2. BUMP COUNT OF WORDS
;AND SAVE POINTER TO THE SPACE
JUS2SP: AOS SAVEAC+2 ;BUMP COUNT OF WORDS ON THIS LINE
MOVE T0,PT ;SAVE POINTER TO THE SPACE
MOVEM T3,SAVEAC+7 ;SAVE CHARACTER COUNT UP TO THIS WORD
JRST JUSP2B ;COUNT THE CHARACTER AND LOOP
;HERE IF CHARACTER IS SPACE OR LESS - HANDLE SOME CHARACTERS SPECIALLY
JUS2CK: JUMPE T1,JUSP2A ;IGNORE NULLS
CAIN T1," " ;SPACE?
JRST JUS2SP ;YES - COUNT AND SAVE POINTER
CAIE T1,15 ;CARRIAGE RETURN?
JRST JUSP2B ;NO - TREAT IT NORMALLY
MOVE T2,PT ;YES - CHECK FOR CRLF - GET A FRAGGABLE POINTER
ILDB T1,T2 ;SEE IF A LF FOLLOWS THE CR
CAIE T1,12 ;DOES IT?
JRST JUSP2B ;NO - TREAT THE CR LINE A NORMAL CHARACTER
DPB T4,T2 ;YES - NULL OVER THE LINEFEED
TLNE F,FLG ;JUST HAD A CRLF?
JRST JU2CK1 ;YES - JUST NULL THIS ONE OVER
MOVE T0,PT ;SET POINTER TO LATEST SPACE TO HERE
TLO F,FLG ;NOTE THAT IT'S THE END OF THE PARAGRAPH
JRST JUS2EL ;SO GO END IT, ALREADY
JU2CK1: DPB T4,PT ;NULL OUT THE CR
MOVE PT,T2 ;SKIP OVER THE CRLF
JRST JUSP2A ;AND CONTINUE
;HERE WHEN A SPACE IS FOUND WHILE COPYING THE LINE
;PUT IN THE RIGHT NUMBER OF SPACES
JUS3SP: SKIPN T4,SAVEAC+2 ;GET NUMBER OF EXTRA SPACES TO ADD - ANY?
JRST JUS3S1 ;NO - DON'T PUT ANY IN
IDPB T1,T2 ;SAVE A SPACE
SOJG T4,.-1 ;LOOP TO SAVE ALL THE SPACES
JUS3S1: SOJG DO,CPOPJ ;DONE IF NO ADJUSTMENTS ARE NEEDED
TLNE F,LFF ;ELSE ON AN EVEN LINE?
SOSA SAVEAC+2 ;NO - DE-BUMP NUMBER OF SPACES TO ADD
AOS SAVEAC+2 ;YES - BUMP NUMBER OF SPACES TO ADD
MOVEI DO,-1 ;SET WORD-COUNT BIG NOW
POPJ P, ;DONE
;HERE WHEN DONE - DELETE OLD TEXT FROM DISPLAY AND INSERT JUSTIFIED TEXT
;SAVEAC+6/ LINES IN OLD TEXT; SAVEAC+5/ LINES IN NEW TEXT
JUSDPY: PUSHJ P,POSCUR ;MAKE SURE THE CURSOR IS IN THE RIGHT PLACE
MOVEI DO,$JUSTI ;RESTORE THE COMMAND NAME
TLO F,XPB ;SAY BOTTOM POINTER IS BAD
TLZ F,FLG!PCM!LFF ;AND CLEAR THE FLAGS JUSTIFY USED
MOVE T4,LPP(TM) ;GET NUMBER OF LINES REMAINING ON SCREEN
SUB T4,RW
CAMLE T4,SAVEAC+5 ;WILL THE RE-DISPLAY FIT IN THE SCREEN
SKIPN CLN(TM) ;YES - CAN THE TERMINAL CLEAR TO END OF LINE?
JRST DISDWN ;NEITHER - JUST DISPLAY TO END OF SCREEN
CAMGE T4,SAVEAC+6 ;START WITH MORE LINES THAN WERE ON THE SCREEN?
JRST DISDWN ;YES - JUST DISPLAY TO END OF SCREEN
MOVE T4,SAVEAC+6 ;FIND CHANGE IN LINES BEFORE AND AFTER
SUB T4,SAVEAC+5
JUMPE T4,JUSDP2 ;IF NO CHANGE, DON'T INSERT OR DELETE ANY
JUMPL T4,JUSDP1 ;JUMP IF LINES INCREASED
SKIPN DLN(TM) ;ELSE DELETE LINES - CAN THE TERMINAL DO IT?
JRST DISDWN ;NO - JUST DISPLAY FROM HERE DOWN
EXCH T4,T2 ;YES - PUT NUMBER OF LINES IN THE RIGHT PLACE
TLNE F,FNC ;IS THE FENCE UP?
PUSHJ P,JUSFNE ;YES - REMOVE IT
JUSDP0: MOVE T1,DLN(TM) ;GET SEQUENCE TO DELETE LINES
PUSHJ P,PUTSEQ ;DELETE THE EXCESS LINES
SOJG T2,JUSDP0
EXCH T4,T2 ;PUT T2 AND T4 IN THE RIGHT PLACES
JRST JUSDP2 ;NOW GO CLEAR OUT AND REWRITE THE REGION
JUSDP1: MOVN T4,T4 ;# LINES INCREASED - MAKE COUNT POSITIVE
JSDP1A: SKIPN T1,ILN(TM) ;INSERT LINES - CAN THE TERMINAL DO IT?
JRST DISDWN ;NO - JUST DISPLAY FROM HERE DOWN
PUSHJ P,PUTSEQ ;INSERT THE NEEDED LINES
SOJG T4,JSDP1A
TLZE F,FNC ;WAS THE FENCE ON THE SCREEN BEFORE?
PUSHJ P,FIXBLW ;YES - PUT IT BACK IF IT'S STILL THERE
PUSHJ P,POSCUR ;RE-POSITION THE CURSOR
JUSDP2: MOVEI T1,15 ;MAKE SURE CURSOR IS AT START OF LINE
IDPB T1,TY
MOVE T4,SAVEAC+5 ;GET COUNT OF LINES TO CLEAR
JUSDP3: MOVE T1,CLN(TM) ;GET THE LINE-CLEARING SEQUENCE
PUSHJ P,PUTSEQ ;CLEAR OUT A LINE
PUSHJ P,CDOWN ;MOVE DOWN A LINE
SOJG T4,JUSDP3 ;LOOP THROUGH ALL THE LINES
PUSHJ P,POSCUR ;POSITION TO THE START OF THE REGION
MOVE T4,SAVEAC+5 ;GET NUMBER OF LINES TO DISPLAY
MOVE PT,LINPTR ;AND POINTER TO START OF FIRST LINE
PUSHJ P,DISPLY ;DISPLAY THEM LINES
MOVE T4,SAVEAC+6 ;FIND CHANGE IN LINES BEFORE AND AFTER
SUB T4,SAVEAC+5
JUMPLE T4,DISCUR ;DONE, UNLESS LINES WERE DELETED
MOVEM T4,ROLLS
MOVN T4,T4
ADD T4,LPP(TM) ;GET LINE NUMBER OF START OF REWRITE
MOVEM T4,SAVEAC
PUSHJ P,ROLFW1 ;REPAIR THE BOTTOM OF THE SCREEN
JRST LOOP ;DONE
;SUBROUTINES TO ERASE THE FENCE AND TO PUT IT BACK IF IT'S THERE
JUSFNE: PUSHJ P,CBOTOM ;ERASE THE FENCE FROM THE BOTTOM LINE
JRST POSCUR ;RE-POSITION THE CURSOR AND RETURN
;SUBROUTINE TO INSERT A CRLF IN THE NEW TEXT AND COUNT ANOTHER LINE
JUSEOL: MOVEI T1,15 ;END THE LINE WITH A CRLF
IDPB T1,T2
MOVEI T1,12
IDPB T1,T2
AOS SAVEAC+5 ;BUMP COUNT OF ENDING LINES
POPJ P, ;DONE
;SUBROUTINE TO ADD THE HEADER STRING, IF ANY, TO THE START OF THE LINE.
;IT THEN ADDS TABS AND/OR SPACES TO START THE LINE AT THE LEFT MARGIN
;CALL WITH T2/ PTR TO TEXT; RETURNS T4/ 0. USES T1
JUSINS: HRRZ T4,JSHCNT ;GOT A HEADER STRING TO INSERT?
JUMPE T4,JUSIN0 ;NO - SKIP THIS
MOVE DO,[POINT 7,JUSHED] ;YES - GET POINTER TO THE STRING
JUSINL: ILDB T1,DO ;GET A CHARACTER
IDPB T1,T2 ;SAVE IT
SOJG T4,JUSINL ;LOOP THROUGH ALL CHARACTERS
JUSIN0: SKIPG T4,SAVEAC+4 ;FIND THE NUMBER OF SPACES TO INSERT - ANY?
POPJ P, ;NO - DONE
CAIL T4,10 ;GOT ROOM FOR A TAB?
SKIPE INSTBS ;YES - WANT TO INSERT TABS IF POSSIBLE?
JRST JUSIN2 ;NO ROOM OR NO TAB - DO IT ALL IN SPACES
MOVEI T1,11 ;ELSE ADD AS MANY TABS AS POSSIBLE
JUSIN1: CAIGE T4,10 ;GOT ROOM FOR ANOTHER TAB?
JRST JUSIN2 ;NO - FINISH OFF WITH SPACES
IDPB T1,T2 ;YES - SAVE IT
SUBI T4,10 ;COUNT THE TAB
JRST JUSIN1 ;AND TRY FOR ONE MORE
JUSIN2: JUMPE T4,CPOPJ ;DONE IF COUNTED OUT
MOVEI T1," " ;ELSE GET A SPACE FOR SAVING
IDPB T1,T2 ;SAVE SPACES
SOJG T4,.-1 ;UNTIL COUNTED OUT
POPJ P, ;DONE
;HERE TO CENTER THE LINE THE CURSOR IS ON BETWEEN /LM: AND /RM:
;(THE CURSOR CAN BE ANYWHERE IN THE LINE; IT ENDS UP AT THE BEGINNING)
JUSCEN: PUSHJ P,ERASPM ;REPAIR THE SCREEN FROM THE PARAMETER
PUSHJ P,MAKLPT ;GET A GOOD LINE POINTER
MOVE PT,LINPTR ;GET THE POINTER TO THE START OF THE LINE
MOVEM PT,CHRPTR ;MOVE THE CURSOR TO THE START
SETZB T4,CM ;CLEAR THE COUNTER; MOVE TO COLUMN ZERO
MOVEI T3," " ;GET A SPACE TO COPY OVER TABS
TLZA F,XPC ;SAY THE CHARACTER POINTER IS O.K.
;NOW SEE HOW LONG THE LINE IS, WHILE NULLING OUT LEADING AND TRAILING
;SPACES AND TABS
JUSCN1: DPB T4,PT ;NULL OUT THE SPACER
ILDB T1,PT ;GET THE NEXT CHARACTER
JUMPE T1,.-1 ;IGNORE NULLS
CAIE T1," " ;SPACE,
CAIN T1,11 ; OR TAB?
JRST JUSCN1 ;YES - NULL IT OUT AND KEEP LOOKING
JRST JUSC2A ;NO - JUMP INTO THE COUNTING LOOP
JUSCN2: ILDB T1,PT ;SEE HOW LONG THE LINE IS - GET A CHARACTER
JUMPE T1,JUSCN2 ;IGNORE NULLS
JUSC2A: CAIN T1,11 ;TAB?
DPB T3,PT ;YES - CHANGE IT TO A SPACE
CAIE T1,15 ;CARRIAGE RETURN?
AOJA T4,JUSCN2 ;NO - COUNT THE CHARACTER AND LOOP
PUSHJ P,ISCRLF ;YES - IS IT A CRLF PAIR?
AOJA T4,JUSCN2 ;NO - COUNT THE CR AND CONTINUE LOOKING
SETZ T3, ;YES - STRIP TRAILING SPACES/TABS - GET A NULL
JUSCN3: ADD PT,[70000,,0] ;BACK UP A CHARACTER
CAIGE PT,0
SUB PT,[430000,,1]
LDB T1,PT ;GET THE PREVIOUS CHARACTER
JUMPE T1,JUSCN3 ;SKIP IT IF NULL
CAIE T1," " ;SPACE?
JRST JUSCN4 ;NO - PROCEED WITH CENTERING
DPB T3,PT ;YES - NULL IT OUT
SOJA T4,JUSCN3 ;UN-COUNT IT AND CHECK THE NEXT ONE
JUSCN4: SUB T4,RMARGN ;YES - SEE HOW MUCH SPACE TO ADD
ADD T4,LMARGN
ASH T4,-1 ;(NOW T4/ NEGATIVE SPACE TO ADD)
JUMPGE T4,JUSCN5 ;IF LINE IS TOO LONG, JUST RE-DISPLAY IT
MOVNM T4,NUMCHR ;ELSE SAVE (POSITIVE) NUMBER OF SPACES TO ADD
PUSHJ P,MAKSPC ;PUT THEM IN
JUSCN5: PUSHJ P,DISONL ;RE-DISPLAY THE LINE
JRST DISCUR ;RE-POSITION THE CURSOR AND GET A NEW COMMAND
END