Trailing-Edge
-
PDP-10 Archives
-
tops10_tools_bb-fp64b-sb
-
10,7/sed/sed1su.mac
There are 10 other files named sed1su.mac in the archive. Click here to see a list.
TITLE SED1SU - SED GENERAL UTILITY SUBROUTINES
SUBTTL A CHRISTOPHER HALL FECIT
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1979,1983.
SEARCH SEDSYM
SALL
IFN TOPS10,<
SEARCH UUOSYM
TWOSEG
RELOC 400000
>
IFE TOPS10,<
SEARCH MONSYM
>
;SUBROUTINE TO INITIALIZE CURSOR MOVEMENT PARAMETERS
;PUT CURSOR BACK INTO TEXT AND MARK STARTING POSITION
MARKUP::TRNE F,XCT!XBN ;DOING AN EXECUTE?
POPJ P, ;YES - NO DISPLAY, THEN
PUSH P,T1 ;SAVE CHARACTER TYPED BY USER
MOVE T1,[POINT 7,PARBUF]
CAME T1,PARPTR ;POINTING TO START OF PARAMETER BUFFER?
JRST [POP P,T1 ;NO - DON'T WANT TO ALLOW CURSOR MOVE
POP P, ;JUST IGNORE THIS COMMAND
TRZ F,CMV ;AND GET THE NEXT ONE
JRST LOOP]
SKIPN NEWMSG+1 ;IS /NOMESSAGE IN EFFECT?
JRST MARKU1 ;YES - DON'T TALK ABOUT CURSOR MOVEMENT
PUSHJ P,CMVBTM ;NO - GO TO START OF BOTTOM LINE
PUSHJ P,PROTON
MOVEI T1,[BYTE (7) 076," ","*","*","*"
ASCIZ / Parm defined by cursor movement ***/]
PUSHJ P,PUTSTG
PUSHJ P,PROTOF
MARKU1: PUSHJ P,POSCUR ;RE-POSITION THE CURSOR
POP P,T1 ;RESTORE USER'S CHARACTER
POPJ P,
;************************************************************************
;SUBROUTINE TO SQUEEZE ENTIRE NULL WORDS OUT OF THE BUFFER
;CALLED DURING EDITING, TO TAKE CARE OF MASSIVE DELETIONS
SQUEZW::MOVEI T0,SQZVAL ;RESET NUMBER OF COMMANDS TO LET GO BY
MOVEM T0,SQZCNT
TRNE F,RDO ;IS FILE READ-ONLY?
POPJ P, ;YES - DO NOTHING
PUSH P,T1 ;SAVE CURRENT COMMAND
IFE TOPS10,<
PUSH P,EN ;SAVE OLD END OF FILE
>
SKIPN (EN) ;IS END PTR POINTING TO A NULL WORD
SOJA EN,.-1 ;YES - BACK UP OVER IT
HRLI EN,010700 ;NO - POINT TO LAST BYTE OF NON-0 WORD
LDB T1,EN ;GET THAT BYTE
CAIE T1,0 ;IF NULL, O.K.
IBP EN ;ELSE SKIP TO NEXT BYTE (WHICH IS ZERO)
MOVEI T3,BUFFER ;GET TWO BUFFER POINTERS
MOVE T4,T3
HRRZ T2,DISPTR ;SET UP ADDRESS FROM DISPLAY PTR
CAIN T2,BUFFER-1
HRR T2,EN ;YES - SET UP END POINTER INSTEAD
SQUEW1: CAMN T3,T2 ;REACHED DISPLAY OR END POINTER?
JRST SQUEW2 ;YES - DO SOMETHING
SKIPN T1,(T3) ;GET A WORD - NULL?
AOJA T3,SQUEW1 ;YES - SKIP OVER IT
AOJ T3, ;NO - SAVE IT OFF
MOVEM T1,(T4)
AOJA T4,SQUEW1 ;AND GET ANOTHER ONE
SQUEW2: CAIE T2,(EN) ;FOUND DISPLAY POINTER?
JRST [HRRM T4,DISPTR ;YES - SAVE ITS NEW ADDRESS
HRR T2,EN
JRST SQUEW1] ;AND CONTINUE
MOVE T1,(EN) ;NO - SAVE LAST WORD OF BUFFER
MOVEM T1,(T4)
HRR EN,T4 ;POINT TO SQUEEZED-OUT END OF BUFFER
IFN TOPS10,<
MOVEI T1,2(EN) ;CLEAR FROM END OF FILE TO TOP OF CORE
HRLI T1,-1(T1)
MOVE T2,.JBREL
SETZM 1(EN)
BLT T1,(T2)
>
IFE TOPS10,<
MOVEI T1,2(EN) ;CLEAR FROM END OF FILE TO OLD END OF FILE
HRLI T1,-1(T1)
POP P,T2
SETZM 1(EN)
BLT T1,(T2)
>
TLO F,XPB!XPL!XPC ;POINTERS ARE NO LONGER VALID
POP P,T1 ;RESTORE CURRENT COMMAND
POPJ P, ;DONE
;************************************************************************
;SUBROUTINE CALLED ON EXIT TO REMOVE ALL NULLS
;AND TRAILING SPACES AND TABS FROM THE FILE
TRAILL::MOVE T4,[POINT 7,BUFFER]
MOVE PT,T4 ;SET UP SOURCE AND TARGET POINTERS
MOVE T3,DISPTR ;GET DISPLAY POINTER
SETZ T2, ;CLEAR POINTER TO TRAILING SPACES
ILDB T1,EN ;MAKE SURE LAST CHARACTER IS A NULL
JUMPE T1,TRAIL1 ;IF SO, O.K.
DPB T2,EN ;ELSE MAKE IT ONE
TRAIL1: CAMN T4,T3 ;REACHED DISPTR?
MOVEM PT,DISPTR ;YES - SAVE ADJUSTED POINTER
ILDB T1,T4 ;GET A CHARACTER
CAIG T1," " ;IS IT A CONTROL CHAR OR A SPACE?
JRST TRAILX ;YES - CHECK DEEPER
TRAIL2: SETZ T2, ;FORGET TRAILING SPACE POINTER
TRAIL3: IDPB T1,PT ;SAVE CHARACTER
JRST TRAIL1 ;AND GET ANOTHER
TRAILX: JUMPE T1,[CAME T4,EN ;IF NULL, AT END OF BUFFER?
JRST TRAIL1 ;NO - IGNORE THE NULL
MOVE EN,PT ;YES - SAVE ADJUSTED END POINTER
IDPB T1,EN ;MAKE SURE IT ENDS ON A NULL
IDPB T1,EN
POPJ P,]
CAIE T1," " ;IS IT A SPACE?
CAIN T1,11 ;IS IT A TAB?
JRST TRAILS ;YES - MARK CURRENT POSITION
JUMPE T2,TRAIL3 ;IF NO TRAILING SPACES, PROCEED
CAIE T1,15 ;ELSE IS CHARACTER A CR?
JRST TRAIL2 ;NO - SAVE THE CHARACTER
MOVE T0,T4 ;YES - GET CHARACTER AFTER CR
ILDB T0,T0
CAIN T0,12 ;IS IT A LINEFEED?
MOVE PT,T2 ;YES - BACK UP OVER THE TRAILING STUFF
JRST TRAIL2 ;AND GO SAVE THE CRLF
TRAILS: JUMPN T2,TRAIL3 ;IS POINTER ALREADY SAVED?
SKIPN TRLFLG ;NO - WANT TO STRIP TRAILING STUFF?
MOVE T2,PT ;YES - SAVE THE POINTER
JRST TRAIL3 ;AND LOOP
;************************************************************************
;SUBROUTINE TO LOOK UP THE FILE POINTED TO BY T2, FOR OUTPUT
;TOPS10 CALL: MOVEI T2,FILFIL; PUSHJ P,SETOUT
;TOPS20 CALL: HRROI T2,[ASCIZ /FILE/]; PUSHJ P,SETOUT
IFN TOPS10,<
SETOUT::MOVE T1,USRPPN ;SET UP USER'S PPN
MOVEM T1,3(T2)
OPEN 5,GENBLK ;OPEN A DUMP MODE OUTPUT FILE
HALT ;ON CHANNEL 5
SETOU1::ENTER 5,(T2)
HALT
HLLZS 1(T2)
SETZM 2(T2)
SETO T1,
POPJ P,
>
IFE TOPS10,<
SETOUT::MOVE T1,[GJ%SHT] ;IT COULDN'T BE MORE STRAIGHTFORWARD
GTJFN
JRST SETOU1
MOVE T2,[7B5+OF%WR]
OPENF
SETOU1: SETZ T1, ;ON FAILURE RETURN T1/ 0
POPJ P,
>
;SUBROUTINE TO LOOK UP THE FILE POINTED TO BY T2, FOR INPUT
;TOPS10 CALL: MOVEI T2,FILFIL; PUSHJ P,SETIN
;TOPS20 CALL: HRROI T2,[ASCIZ /FILE/]; PUSHJ P,SETIN
;RETURNS -FILE SIZE OR HANDLE IN T1 IF LOOKUP SUCCESSFUL, ELSE 0
;SETINP USES THE PPN IN THE BLOCK; SETIN USES THE USER'S PPN
;SETINL LOOKS ONLY IN THE USER'S LOGGED-IN AREA
IFN TOPS10,<
SETINL: MOVE T0,USRPPN ;SET UP USER'S LOGGED-IN PPN
JRST SETIN1 ;JUST LOOK IN THE LOGGED-IN AREA
SETINP::MOVE T0,3(T2) ;GET THE PPN FROM THE BLOCK
CAIA ; (CAN'T USE SKIPA WITH T0)
SETIN:: MOVE T0,USRPPN ;SET UP USER'S PPN
SETZB T1,3(T2) ;TRY PATHED DIR. FIRST; ASSUME FILE'S NOT THERE
OPEN 5,GENBLK ;OPEN A DUMP MODE INPUT FILE
POPJ P, ;ON CHANNEL 5
LOOKUP 5,(T2)
JRST SETIN1 ;NO SUCH FILE - TRY LOGIN DIRECTORY
SETIN2: MOVSI T1,'DSK' ;REPAIR THE OPEN BLOCK
MOVEM T1,GENBLK+1 ; IN CASE IT WAS CHANGED
HLLZS 1(T2)
SETZM 2(T2)
MOVE T1,3(T2) ;GET THE NEGATIVE FILE SIZE
MOVEM T0,3(T2) ;PUT THE PPN BACK IN
POPJ P,
SETIN1: HLLZS 1(T2) ;CLEAN UP LOOKUP BLOCK
SETZM 2(T2)
MOVEM T0,3(T2) ;LOOK IN LOGIN DIRECTORY
LOOKUP 5,(T2)
POPJ P, ;NO SUCH FILE - RETURN ZERO
JRST SETIN2 ;GOT IT - BACK TO FLOW
>
IFE TOPS10,<
SETINL: MOVEI T1,INIJFN ;LOOK IN USER'S LOGGED-IN DIRECTORY ONLY
JRST SETIN0
SETINP::
SETIN:: MOVE T0,T2 ;SAVE FILESPEC POINTER
MOVSI T1,(GJ%OLD+GJ%SHT)
GTJFN
SKIPA T1,[INIJFN] ;NOT FOUND - TRY USER'S PS:
JRST SETIN1 ;GOT IT - GO OPEN AND READ
MOVE T2,T0 ;GET FILESPEC POINTER BACK
SETIN0: SKIPE USRNAM ;(DON'T DO IT IF NO USER NAME)
GTJFN
JRST SETIN2 ;NO SUCH FILE - RETURN FAILURE
SETIN1: HRRZ T1,T1 ;CLEAR FLAGS OUT OF LH OF T1
MOVE T2,[7B5+OF%RD]
OPENF ;OPEN THE FILE
SETIN2: SETZ T1, ;FAILED - FLAG AS SUCH
POPJ P, ;RETURN SUCCESS OR FAILURE
>
IFN TOPS10,<
;SUBROUTINE TO DELETE A FILE. SPECS IN T2
SETDEL::MOVE T1,USRPPN ;SET UP USER'S PPN
MOVEM T1,3(T2)
OPEN 5,GENBLK ;OPEN A DUMP MODE INPUT FILE
HALT ;ON CHANNEL 5
LOOKUP 5,(T2)
CAIA ;NO FILE - DON'T DELETE IT
RENAME 5,DELFIL ;DELETE IT
JFCL
RELEAS 5, ;GET RID OF IT
POPJ P,
>
IFE TOPS10,<
;SUBROUTINE TO MAKE A TOPS20 FILE TEMPORARY. ENTER WITH JFN IN T1
SETTMP::HRLI T1,1 ;LIGHT TEMP BIT IN
MOVSI T2,(FB%TMP) ; 2ND WORD OF FILE DATA BLOCK
MOVSI T3,(FB%TMP)
CHFDB
CLOSF ;THEN CLOSE THE FILE
POPJ P,
POPJ P,
>
;************************************************************************
;SUBROUTINES TO MANIPULATE POINTERS
;SUBROUTINE TO BACK UP THE DISPLAY POINTER BY (T4) LINES
;STOPS, NATURALLY, IF IT HITS THE START OF BUFFER. IN THAT CASE, T4 HAS
;NUMBER OF LINES NOT BACKED UP, SO SUBTRACT T4 FROM THE DISTANCE YOU
;THINK YOU WENT TO GET THE ACTUAL DISTANCE
BAKDPT::MOVE PT,DISPTR ;GET POINTER TO START OF SCREEN
CAMN PT,[010700,,BUFFER-1] ;AT START OF BUFFER?
POPJ P, ;YES - NOTHING TO DO AT ALL
BAKDP1: ADD PT,[70000,,0] ;FUDGE A DECREMENT OF THE BUFFER POINTER
CAIGE PT,0
SUB PT,[430000,,1]
LDB T2,PT ;GET A CHARACTER
BAKDP2: CAIE T2,12 ;LINEFEED?
JRST BAKDP1 ;NO - IGNORE IT
CAMN PT,[010700,,BUFFER-1] ;AT START OF BUFFER?
JRST [MOVEM PT,DISPTR ;YES - POINT TO START OF BUFFER
SOJA T4,CPOPJ] ;ADJUST COUNT AND RETURN
ADD PT,[70000,,0] ;FUDGE A DECREMENT OF THE BUFFER POINTER
CAIGE PT,0
SUB PT,[430000,,1]
LDB T2,PT ;YES - PICK UP THE <CR>
CAIE T2,15 ;IS IT REALLY?
JRST BAKDP2 ;NO - IT'S NOT THE END OF THE LINE
SOJG T4,BAKDP1 ;YES - LOOP THROUGH DESIRED NUMBER OF ROWS
IBP PT ;SKIP OVER THAT LAST LINEFEED
MOVEM PT,DISPTR ;SAVE SET-UP DISPLAY POINTER
POPJ P, ;DONE
;SUBROUTINE TO ADVANCE DISPLAY POINTER BY (T4) LINES
;IF END OF FILE FOUND, SETS DISPTR TO LINROL LINES BEFORE END OF FILE
ADVDPT::MOVE PT,DISPTR ;GET DISPLAY POINTER
PUSHJ P,ADVLPT ;ADVANCE IT
MOVEM PT,DISPTR ;SAVE IT AGAIN
JUMPGE T4,CPOPJ ;IF NOT HIT END JUST RETURN
TRNE F,XCT ;EXECUTING?
JRST XCEERR ;YES - SAY FINISHED PREMATURELY
ADD T4,ROLLS ;ELSE FIND DISTANCE OF REAL ROLL
SUB T4,LINROL
SOJ T4,
MOVEM T4,ROLLS ;SAVE REAL ROLL
MOVE T4,LINROL ;BACK UP LINROL LINES
TLO F,FLG ;SET FLAG FOR RE-DISPLAY
JRST BAKDPT ;AND RETURN WITH THAT
;SUBROUTINE TO MAKE A POINTER TO THE CHARACTER WHERE THE CURSOR IS
;CANNOT USE T1, SINCE THERE MAY BE A LIVE CHARACTER THERE
;RETURNS CHARACTER POINTED TO BY CHRPTR, IN T3
;IF THAT CHARACTER IS A TAB, RETURNS PTR TO IT IN TABPTR
MAKCPT::TLZN F,XPC ;IS CHARACTER POINTER ALREADY GOOD?
JRST MAKCOK ;YES - CHECK FOR TAB (MAY COME BACK TO .+1)
MAKCK1::TLZE F,XPL ;IS LINE POINTER GOOD?
PUSHJ P,MAKLPT ;NO - MAKE IT FIRST
MAKCP0: MOVE T3,LINPTR ;GET LINE POINTER
MOVEM T3,CHRPTR ;SAVE AS STARTING CHARACTER POINTER
MOVE T2,CM ;GET COLUMN TO MOVE TO
ADD T2,SL ; (INCLUDING SLIDE OFFSET)
JUMPE T2,MAKCP3 ;IF ZERO, JUST CHECK FOR A TAB
MAKCP1: CAMN EN,CHRPTR ;AT END OF USEABLE BUFFER?
JRST MAKCR0 ;YES - ADD A FEW SPACES buggy if here
ILDB T3,CHRPTR ;GET A CHARACTER
JUMPE T3,MAKCP1 ;IGNORE IF NULL
CAIN T3,15 ;CARRIAGE RETURN?
JRST MAKCCR ;YES - NEED TO EXTEND LINE
MAKCP2: CAIN T3,11 ;TAB?
JRST MAKCTB ;YES - NEED TO USE THE RIGHT NUMBER OF SPACES
SOJG T2,MAKCP1 ;LOOP THROUGH DESIRED NUMBER OF COLUMNS
MAKCP3: MOVE T2,CHRPTR ;DONE - SEE WHAT CHARACTER IS POINTED TO
MAKCP4: CAMN T2,EN ;AT END OF BUFFER?
JRST [MOVEI T2,15 ;YES - NEED A FINAL <CR>
IDPB T2,EN
MOVEI T2,12
IDPB T2,EN
POPJ P,]
ILDB T3,T2
JUMPE T3,MAKCP4 ;SKIP, IF NULL
CAIE T3,11 ;IF IT'S A TAB, SET UP COUNTS AND RETURN
POPJ P, ;ELSE JUST RETURN
MOVEM T2,TABPTR ;SAVE POINTER TO TAB
MOVE T2,CM ;FIND NEGATIVE HOW LONG THIS TAB SHOULD BE
ADD T2,SL
ANDI T2,7
SUBI T2,10
SETZM TABSPC ;WANT NO SPACES TO LEFT OF TAB
MOVNM T2,TABSIZ ;SAVE LENGTH OF TAB
POPJ P, ;NOW RETURN
;HERE WHEN TAB FOUND. JUMP THE CORRECT NUMBER OF SPACES
;IF DESIRED POSITION IS WITHIN THE TAB, POINT TO START OF TAB
MAKCTB: MOVE T3,CM ;FIND NEGATIVE HOW LONG THIS TAB SHOULD BE
ADD T3,SL
SUB T3,T2
ANDI T3,7
SUBI T3,10
DPB T2,[POINT 3,TABSPC,35]
MOVNM T3,TABSIZ
ADD T2,T3 ;MOVE OVER THAT MANY POSITIONS
MOVEI T3,11 ;GET THE TAB BACK
JUMPG T2,MAKCP1 ;O.K. IF STILL MORE TO GO
JUMPE T2,MAKCP3 ;OR JUMP IF COUNTED OUT EXACTLY
MOVE T2,CHRPTR ;BACK POINTER UP BEFORE THE TAB
MOVEM T2,TABPTR
ADD T2,[70000,,0]
CAIGE T2,0
SUB T2,[430000,,1]
MOVEM T2,CHRPTR
POPJ P, ;AND THEN DONE
;HERE IS CHARACTER POINTER IS O.K. - RECALCULATE IF IT POINTS TO A TAB
MAKCOK: MOVE T2,CHRPTR ;DONE - SEE WHAT CHARACTER IS POINTED TO
MAKCK0: CAMN T2,EN ;AT END OF BUFFER?
JRST [MOVEI T2,15 ;YES - NEED A FINAL <CR>
IDPB T2,EN
MOVEI T2,12
IDPB T2,EN
JRST MAKCK1]
ILDB T3,T2
JUMPE T3,MAKCK0 ;SKIP, IF NULL
CAIN T3,15 ;GET A <CR>?
JRST [TLNN F,INS ;YES - WANT TO INSERT IF CURSOR OUT OF RANGE?
POPJ P, ;NO - RETURN FROM MAKCPT
JRST MAKCK1] ;YES - RE-CALC CURSOR POINTER
CAIE T3,11 ;TAB?
POPJ P, ;NO - RETURN FROM MAKCPT
JRST MAKCK1 ;ELSE RE-DO CHARACTER POINTER
;HERE IF END OF LINE FOUND, BUT NOT ENOUGH CHARACTERS
;IF FLAG INS IS SET, ADD SPACES TO THE LINE, THEN POINT BEYOND THEM
;ELSE JUST POINT TO THE <CR>
MAKCCR: MOVE T0,CHRPTR ;GET THE CHARACTER AFTER THE CARRIAGE RETURN
ILDB T0,T0
CAIE T0,12 ;IS IT A LINEFEED?
JRST MAKCP2 ;NO - TREAT LONE CR LINE ANY OTHER CHARACTER
MAKCR0: TLNN F,INS ;WANT TO EXTEND THE LINE?
JRST MAKCC1 ;NO - JUST RETURN POINTING TO <CR>
PUSH P,T1 ;SAVE CHARACTER TO BE EVENTUALLY ADDED
MOVSI T1,70000 ;MOVE POINTER BEHIND THE <CR>
ADD T1,CHRPTR
CAIGE T1,0
SUB T1,[430000,,1]
MOVEM T1,CHRPTR ;SAVE IT AGAIN
SKIPE INSTBS ;WANT TO TRY TO INSERT TABS?
JRST MAKCR2 ;NO - SKIP THE TAB STUFF
MOVE T1,CM ;YES - SEE IF ANY TABS CAN BE ADDED
TRZ T1,7
MOVN T1,T1
ADD T1,CM
CAML T1,T2 ;CAN THEY?
JRST MAKCR2 ;NO - JUST ADD SPACES
JUMPE T1,MAKCT0 ;NO SPACES IF END ON A TAB BOUNDARY
PUSH P,T2 ;ELSE ADD EXTRA SPACES FIRST
MOVEM T1,NUMCHR ;ADD (T2) SPACES (AND SOME NULLS) TO THE FILE
PUSHJ P,MAKSPC ;PUNCH A HOLE IN THE FILE
POP P,T2 ;GET TOTAL SPACES BACK
MAKCT0: MOVE T1,CM ;FIND POSITION OF LAST REAL CHARACTER
SUB T1,T2
TRNE T1,7 ;WAS IT AT A TAB STOP?
ADDI T2,7 ;NO - ADD ONE MORE TAB
LSH T2,-3 ;FIND NUMBER OF TABS TO ADD
MOVEM T2,NUMCHR ;SAVE IT
MOVEI T1,11 ;SET TO ADD TABS
MOVEM T1,CHARAC
PUSHJ P,MAKCHR ;ADD 'EM
POP P,T1 ;CLEAN UP
JRST MAKCP0 ;MAKE CURSOR POINTER RIGHT; DONE
MAKCR2: MOVEM T2,NUMCHR ;ADD (T2) SPACES (AND SOME NULLS) TO THE FILE
PUSHJ P,MAKSPC ;PUNCH A HOLE IN THE FILE
POP P,T1
JRST MAKCP0 ;MAKE CURSOR POINTER RIGHT
MAKCC1: MOVSI T2,70000 ;BACK THE CHARACTER POINTER ONE NOTCH
ADD T2,CHRPTR
CAIGE T2,0
SUB T2,[430000,,1]
MOVEM T2,CHRPTR
POPJ P,
;SUBROUTINE TO MAKE A POINTER TO THE START OF THE LINE THE CURSOR IS ON
;CANNOT USE T1, SINCE THERE MAY BE A LIVE CHARACTER THERE
MAKLPT::MOVE PT,DISPTR ;GET POINTER TO START OF SCREEN
MOVEM PT,LINPTR ;SAVE IT AS INITIAL LINE POINTER
SKIPN T4,RW ;GET ROW TO MOVE TO - ZERO?
POPJ P, ;YES - DONE
PUSHJ P,ADVLPT ;NO - ADVANCE THE POINTER
JUMPL T4,MAKLP2 ;ADD LINES IF AT END OF FILE
MOVEM PT,LINPTR ;SAVE THE CORRECT LINE POINTER
MOVE T3,PT ;GET FRAGGABLE POINTER
MAKLP0: CAMN T3,EN ;AT END OF BUFFER?
JRST ADDCR ;YES - NEED TO ADD A <CRLF> AT END
ILDB T2,T3 ;NO - FIND A NON-NULL CHARACTER
JUMPE T2,MAKLP0
POPJ P, ;GOT ONE - O.K.
;HERE IF END OF BUFFER FOUND, BUT NOT ENOUGH <CR>S
;IF THE INS FLAG IS SET, ADD THE DESIRED <CR>S TO BUFFER, PLUS SOME NULLS
;THEN POINT BEYOND THE <CR>S
;IF INS NOT SET, POINT TO LAST <CR>
MAKLP2: TLNN F,INS ;WANT TO INSERT STUFF?
JRST MAKLP3 ;NO - JUST POINT TO LAST <CR>
MOVEI T3,15 ;NO - SAVE OFF <CRLF>S
MOVEI T2,12
IDPB T3,EN
IDPB T2,EN
AOJL T4,.-2 ;UNTIL GOT ENOUGH
MOVEM EN,LINPTR ;SAVE AS POINTER TO DESIRED LINE
IDPB T3,EN ;AND A FINAL <CR>
IDPB T2,EN
SETZ T3,
IDPB T3,EN
POPJ P,
MAKLP3: ADD PT,[70000,,0] ;BACK THE LINE POINTER ONE NOTCH
CAIGE PT,0
SUB PT,[430000,,1]
LDB T0,PT ;LOOK FOR A <CR>
CAIE T0,15 ;IS IT?
JRST MAKLP3 ;NO - LOOP
ADD PT,[70000,,0] ;BACK UP BEFORE THE <CR>
CAIGE PT,0
SUB PT,[430000,,1]
MOVEM PT,LINPTR ;SAVE LINE POINTER
TLO F,XPL!XPC ;BUT SAY IT'S INVALID
POPJ P, ;AND RETURN
CCREOL::MOVE T1,PT ;MAKE SURE THE FILE ENDS WITH A CRLF
CCREL1: ILDB T2,T1 ;GET A CHARACTER
CAMN T1,EN ;REACHED END OF THE FILE?
JRST ADDCR ;YES - PUT IN A CARRIAGE RETURN AND RETURN
JUMPE T2,CCREL1 ;NO - LOOP UNTIL END OR NON-NULL CHARACTER
POPJ P, ;END OF FILE IS NOW O.K.
ADDCR:: MOVEI T2,15 ;END BUFFER WITH A <CRLF>
IDPB T2,EN ; AND A NULL
MOVEI T2,12
IDPB T2,EN
SETZ T2,
IDPB T2,EN
POPJ P,
;SUBROUTINE TO SET UP THE POINTER TO THE LAST LINE ON THE SCREEN
;WORKS WITH LINPTR IF IT'S VALID (BEING CLOSER); ELSE USES DISPTR
;RETURNS BOTTOM POINTER BOTH IN PT AND BOTPTR
;RETURNS 0 IF LAST LINE IS BEYOND END OF BUFFER, HENCE NOTHING TO DISPLAY
; (ALSO, IF ZERO, FENCE SHOULD BE ON SCREEN)
MAKBPT::MOVE T4,LPP.1 ;GET DISTANCE OF BOTTOM LINE FROM TOP LINE
TLNE F,XPL ;IS LINE POINTER VALID?
JRST MAKBP0 ;NO - USE DISPLAY POINTER
MOVE PT,LINPTR ;YES - USE IT
SUB T4,RW ;AND WORK A FEW LINES LESS
JUMPN T4,MAKBP1 ;ALREADY AT BOTTOM LINE. WADDAYA KNOW.
JRST MAKBP2
MAKBP0: MOVE PT,DISPTR ;GET THE DISPLAY POINTER
MAKBP1: PUSHJ P,ADVLPT ;ADVANCE THE POINTER
CAIGE T4,0 ;BEYOND END OF FILE?
SETZ PT, ;YES - NO POINTER, THEN
MAKBP2: MOVEM PT,BOTPTR ;SAVE POINTER (OR NON-POINTER)
POPJ P,
;SUBROUTINE TO ADVANCE THE POINTER IN PT (T4) LINES
;T4 IS RETURNED WITH NEGATIVE NUMBER OF LINES NOT FOUND (0 IF ALL FOUND)
ADVLPT::CAMN EN,PT ;AT END OF USEABLE BUFFER?
JRST [MOVN T4,T4 ;NO - RETURN NEGATIVE # LINES NOT FOUND
POPJ P,] ;AND RETURN
ILDB T2,PT ;GET A CHARACTER
ADVLP1: CAIE T2,15 ;CARRIAGE RETURN?
JRST ADVLPT ;NO - IGNORE IT
ILDB T2,PT ;YES - PICK UP THE <LF>
CAIE T2,12 ;IS IT REALLY?
JRST ADVLP1 ;NO - IT'S NOT THE END OF THE LINE
SOJG T4,ADVLPT ;YES - LOOP THROUGH DESIRED NUMBER OF ROWS
POPJ P, ;DONE
;************************************************************************
;SUBROUTINE FIND IF THERE ARE ANY TABS FROM THE CURSOR TO THE END
;OF THE LINE, OR IF THE LINE WILL GO OFF THE RIGHT OF THE SCREEN
;ASSUMES CHRPTR IS VALID; FRAGS T1, T2
;CALL WITH T4/ NUMBER OF SPACES THAT WILL BE ADDED TO THE LINE
;RETURNS +1 IF LINE IS TOO LONG OR A TAB IS FOUND, ELSE +2
;WITH T1/ POSITION OF LAST CHARACTER
FNDEOL::MOVE T1,CM ;GET POSITION OF STARTING CHARACTER
MOVE T2,CHRPTR ;GET THE POINTER TO THE FIRST CHARACTER
FNDEO1: CAMLE T1,CPL(TM) ;AT 80TH COLUMN?
POPJ P, ;YES - DONE NOW
ILDB T0,T2 ;NO - GET A CHARACTER
FNDEO2: JUMPE T0,.-1 ;SKIP IT IF NULL
CAIN T0,11 ;TAB?
JRST FNDEOT ;YES - HANDLE SPECIALLY
CAIE T0,15 ;END OF LINE?
AOJA T1,FNDEO1 ;NO - KEEP LOOKING
ILDB T0,T2 ;YES - GET THE NEXT CHARACTER
CAIE T0,12 ;IS IT A LINEFEED?
AOJA T1,FNDEO2 ;NO - COUNT THE CR AND CHECK THE LF FURTHER
AOS (P) ;YES - GIVE SKIP RETURN
POPJ P,
FNDEOT: TRO T1,3 ;GOT A TAB - TAB OVER
AOJA T1,CPOPJ ;AND RETURN
;************************************************************************
;SUBROUTINE TO OVERWRITE (T4) REAL CHARACTERS (NOT NULLS) WITH NULLS
;AT (PT), WHICH IS FRAGGED
;STOPS WHEN COUNTED OUT, OR AT END OF LINE
;SAVES CHARACTERS NULLED OUT IN DELBUF (UP TO 5*32 CHARACTERS)
WRTNUL::MOVEM T4,WRTNUM ;SAVE NUMBER OF CHARS TO NULL
MOVNI T1,5*40 ;INIT NUMBER OF CHARACTERS IN DELETE BUFFER
MOVEM T1,DELCNT
SETZ T1, ;GET A NULL
MOVE T3,[POINT 7,DELBUF] ;POINT TO START OF DELETE BUFFER
ILDB T2,PT ;GET FIRST CHARACTER
JUMPE T2,[CAME PT,EN ;IF NULL, REACHED END OF BUFFER?
JRST .-1 ;NO - JUST IGNORE THE NULL
JRST WRTNLE] ;YES - RETURN NOW
CAIE T2,11 ;IS IT A TAB?
JRST WRTNL2 ;NO - CONTINUE
AOSG DELCNT ;YES - COUNT IT - COUNTED OUT?
IDPB T2,T3 ;NO - SAVE THE TAB IN THE DELETE BUFFER
MOVE T2,TABSPC ;FIND -NUMBER OF SPACES RIGHT OF CURSOR
SUB T2,TABSIZ
ADD T4,T2 ;COUNT OFF THAT MANY SPACES FROM DELETE
DPB T1,PT ;NULL OUT THE TAB
JUMPLE T4,WRTNT1 ;JUMP IF DONE (START AND END IN THE SAME TAB)
SKIPE NUMCHR ;START WITHIN THE TAB?
PUSHJ P,WRTNLS ;YES - CHANGE THE TAB IN THE BUFFER TO SPACES
WRTNL1: ILDB T2,PT ;GET A CHARACTER
CAMN PT,EN ;AT END OF BUFFER?
JRST WRTNLE ;YES - GO HOME EARLY
JUMPE T2,WRTNL1 ;IGNORE IF NULL
CAIN T2,11 ;IS IT A TAB?
JRST WRTNTB ;YES - SEE HOW LONG THE TAB IS
WRTNL2: CAIN T2,15 ;IS IT A <CR>?
JRST WRTNLC ;YES - DONE, IF FOLLOWED BY <LF>
WRTNL3: AOSG DELCNT ;ELSE COUNT IT - COUNTED OUT?
IDPB T2,T3 ;NO - SAVE THE DELETED CHARACTER
DPB T1,PT ;OVERWRITE IT WITH A NULL
SOJG T4,WRTNL1 ;AND COUNT IT - LOOP IF NOT DONE
WRTNLE: IDPB T1,T3 ;END DELETE BUFFER WITH A NULL
MOVEI T1,5*40 ;ADJUST COUNT OF CHARACTERS DELETED
MOVEI T2,5*40
ADDB T1,DELCNT
CAIL T1,5*40 ;DID BUFFER OVERFLOW?
MOVEM T2,DELCNT ;YES - SET TO THE MAXIMUM
POPJ P, ;NO - DONE
WRTNLC: MOVE T0,PT ;GET SCRATCH BUFFER POINTER
ILDB T2,T0 ;GET NEXT CHARACTER
CAIE T2,12 ;<LF>?
JRST WRTNL3 ;NO - <CR>'S JUST ANOTHER CHARACTER
JRST WRTNLE ;YES - GO FINISH OFF
WRTNTB: AOSG DELCNT ;ELSE COUNT IT - COUNTED OUT?
IDPB T2,T3 ;NO - SAVE THE TAB
MOVE T2,CM ;GET STARTING COLUMN POSITION
ADD T2,WRTNUM ;PLUS LENGTH OF DELETE
SUB T2,T4 ;LESS NUMBER TO GO, GIVES PRESENT POSITION
ANDI T2,7 ;FIND NEGATIVE SIZE OF TAB
SUBI T2,10
ADD T4,T2 ;COUNT OFF THAT MANY SPACES FROM DELETE
DPB T1,PT ;NULL OUT THE TAB
JUMPG T4,WRTNL1 ;CONTINUE, IF STILL MORE TO GO
WRTNT1: JUMPE T4,WRTNLE ;LEAVE TAB IF ENDED AT THE END OF IT
MOVN T4,T4 ;ELSE ADD SOME SPACES FOR THIS TAB, TOO
ADDM T4,NUMCHR
ADD T2,T4 ;FIND NUMBER OF SPACES THIS TAB REPRESENTS
PUSHJ P,WRTNLS ;CHANGE THE TAB IN THE BUFFER TO SPACES
SETZ T4, ;SAY NOTHING WAS LEFT OVER
JRST WRTNLE ;AND GO FINISH UP
WRTNLS: MOVEI T0," " ;REPLACE TAB WITH -(T2) SPACES
DPB T0,T3 ;COVER TAB WITH A SPACE
AOJE T2,CPOPJ ;DONE IF ONLY ONE SPACE WANTED
AOSG DELCNT ;ELSE COUNT EACH SPACE - COUNTED OUT?
IDPB T0,T3 ;NO - SAVE THE SPACE
AOJG T2,.-2
POPJ P, ;DONE
;************************************************************************
;SUBROUTINE TO CALCULATE RW AND LINPTR, GIVEN CHRPTR AND DISPTR
CALCRW::MOVE PT,DISPTR ;START FROM START OF SCREEN
MOVEM PT,LINPTR ;SAVE (TENTATIVE) LINE POINTER
SETZ RW, ;CLEAR ROW NUMBER
CALRW1: CAMN PT,CHRPTR ;AT DESIRED POSITION?
POPJ P, ;YES - DONE
ILDB T1,PT ;NO - GET CHARACTER
CALRW2: CAIE T1,15 ;<CR>?
JRST CALRW1 ;NO - SKIP IT
CAMN PT,CHRPTR ;YES - AT DESIRED POSITION?
POPJ P, ;YES - DONE
ILDB T1,PT ;NO - GET NEXT CHARACTER
CAIE T1,12 ;<LF>?
JRST CALRW2 ;NO - SKIP IT
MOVEM PT,LINPTR ;SAVE (TENTATIVE) LINE POINTER
AOJA RW,CALRW1 ;YES - COUNT LINE AND LOOP
;SUBROUTINE TO CALCULATE THE NUMBER OF LINES AND PAGES, AND TOTAL LINES
;SINCE THE START OF THE FILE
FINDRW::SETZB T3,SAVEAC ;CLEAR PAGE NUMBER AND TOTAL LINES
CAIA ;SKIP SUMMING THE FIRST TIME
FNDRW0: ADDM RW,SAVEAC ;ADD UP TOTAL LINES PASSED OVER
SETZ RW, ;CLEAR ROW NUMBER
FNDRW1: CAMN PT,CHRPTR ;AT DESIRED POSITION?
JRST [ADDM RW,SAVEAC ;YES - ADD IN LINES FROM LAST PAGE
POPJ P,] ;DONE
ILDB T1,PT ;NO - GET CHARACTER
FNDRW2: CAIN T1,14 ;FORMFEED?
AOJA T3,FNDRW0 ;YES - BUMP PAGES AND ZERO LINES
CAIE T1,15 ;<CR>?
JRST FNDRW1 ;NO - SKIP IT
ILDB T1,PT ;YES - GET NEXT CHARACTER
CAIE T1,12 ;<LF>?
JRST FNDRW2 ;NO - SKIP IT
AOJA RW,FNDRW1 ;YES - COUNT LINE AND LOOP
;SUBROUTINE TO CALCULATE CM, GIVEN CHRPTR, AND LINPTR IN PT
;(ALTERNATE ENTRY: CALCML - PUTS LINPTR INTO PT)
;IF CM IS BEYOND SCREEN LIMITS, DOES A SLIDE TO PUT IT WITHIN LIMITS
;NORMAL RETURN IF SLIDE, ELSE SKIP RETURN
CALCML::MOVE PT,LINPTR ;GET POINTER TO START OF LINE
CALCCM::SETZ CM, ;CLEAR COLUMN NUMBER
CALCM1: CAMN PT,CHRPTR ;AT CHARACTER POSITION?
JRST CALCCD ;YES - DONE
ILDB T1,PT ;NO - GET CHARACTER
JUMPE T1,CALCM1 ;IGNORE IF NULL
CAIN T1,11 ;TAB?
TRO CM,7 ;YES - COUNT IT
AOJA CM,CALCM1 ;COUNT CHARACTER AND LOOP
CALCCD: SUB CM,SL ;ACCOUNT FOR THE SLIDE
CAMGE CM,CPL(TM) ;OFF THE RIGHT SIDE?
JRST CALCD1 ;NO - CHECK LEFT
MOVE T1,CM ;YES - SLIDE A BIT TO SHOW THE MATCH
MOVE T2,CPL(TM)
IDIVI T2,3
LSH T2,1
SUB T1,T2
ADD SL,T1
SUB CM,T1
POPJ P, ;GIVE NON-SKIP RETURN
CALCD1: JUMPGE CM,CPOPJ1 ;OFF THE LEFT SIDE (IF NO, SKIP RETURN)?
ADD SL,CM ;YES - MOVE LEFT SO KEY IS ON SCREEN
SETZ CM,
POPJ P, ;GIVE NON-SKIP RETURN
;************************************************************************
;SUBROUTINES TO FILL WITH SPACES OR NULLS (OR CONTENTS OF CHARAC)
;ENTER WITH NUMCHR/ NUMBER OF CHARACTERS TO INSERT
; CHRPTR/ PLACE TO START INSERTING THEM (PRESERVED)
;IF ENTER AT MAKCHR, SET UP CHARACTER IN CHARAC
;ON RETURN, CHRPTR WILL POINT TO THE START OF THE STUFF ADDED,
; T4 POINTS TO THE FIRST CHARACTER AFTER THE NEW STUFF
; MAKPTR POINTS TO LAST REAL CHARACTER ADDED
;NOTE: THIS IS THE only PLACE WHERE THINGS ARE INSERTED INTO THE BUFFER
;AN ADDRESS CAN BE STORED IN ADJWRD (ADDRESS - NOT A POINTER). IF THE
;FILE WORD AT THAT ADDRESS IS MOVED THE ADDRESS WILL BE ADJUSTED SO IT
;STILL POINTS TO THE WORD. THE CALLER MUST CLEAR ADJWRD WHEN THIS ROUTINE
;RETURNS.
;IF ADJWRD IS ZERO HERE AND THE BOTTOM POINTER IS VALID, IT IS ADJUSTED.
;IF ADJWRD IS NON-ZERO BOTPTR IS MARKED INVALID.
MAKSPC::MOVEI T1," " ;GET A SPACE
MOVEM T1,CHARAC ;SAVE AS THE FILL CHARACTER
JRST MAKCHR ;GO PUT THEM IN
MAKNUL::SETZM CHARAC ;SET TO FILL WITH NULLS
MAKCHR::SKIPN T3,NUMCHR ;GET COUNT OF CHARACTERS TO PUT IN - ANY?
POPJ P, ;NO - JUST RETURN
IDIVI T3,5 ;CONVERT IT TO COUNT OF WORDS
CAIE T4,0 ;ANY EXCESS?
AOJ T3, ;YES - ROUND UP TO NEXT FULL WORD
MOVEM T3,NUMWDS ;SAVE NUMBER OF WORDS TO ADD
HRRZ T4,CHRPTR ;GET ADDRESS OF START OF INSERT
HRRZ T1,BOTPTR ;GET THE ADDRESS OF THE BOTTOM POINTER
SKIPE ADJWRD ;DID THE USER GIVE AN ADDRESS TO ADJUST?
TLO F,XPB ;YES - THEN THE BOTTOM LINE PTR IS INVALID
TLNN F,XPB ;IS THE BOTTOM LINE POINTER INVALID?
MOVEM T1,ADJWRD ;NO - SAVE IT FOR ADJUSTING
SKIPN @ADJWRD ;ARE THE CONTENTS OF THAT WORD ZERO
HRROS @ADJWRD ;YES - MAKE THE WORD -1,,0
;FIRST SEE IF THERE ARE ENOUGH NULL WORDS RIGHT WHERE THE CURSOR IS
;IF SO, JUST GO AND WRITE THEM
SKIPE (T4) ;IS THE FIRST WORD NULL?
JRST MAKCH0 ;NO - GO LOOK AND SQUEEZE
MOVEI T1,010700 ;YES - POINT CHRPTR BEFORE START OF THAT WORD
HRLM T1,CHRPTR
SOS CHRPTR
MAKCHL: SKIPE (T4) ;COUNT CONSECUTIVE NULLS AT START: GOT ONE?
JRST MAKCH0 ;NO - GO LOOK AND SQUEEZE
SOJLE T3,MAKCL1 ;YES - JUMP IF FOUND ENOUGH
AOJA T4,MAKCHL ;ELSE LOOK FOR MORE
MAKCL1: CAIL T4,(EN) ;MOVED BEYOND END OF BUFFER?
HRRI EN,1(T4) ;YES - EXTEND END BY THAT PLUS ONE WORD
JRST MAKCH4 ;GO PUT DATA IN
;HERE IF NOT ENOUGH NULLS WORDS AT CURSOR. LOOK (NOBYTE) WORDS AHEAD AND
;SHUFFLE THOSE UP TO THE TOP
MAKCH0: MOVEI T2,NOBYTE ;GET # OF WORDS TO LOOK AHEAD FOR NULLS
MAKCH1: CAIN T4,(EN) ;AT END OF BUFFER?
AOJ EN, ;YES - EXTEND BUFFER A WORD
SKIPN (T4) ;IS THIS WORD NULL?
AOJA T4,MKCH1A ;YES - COUNT IT AND LOOP
AOJ T4, ;NO - POINT TO NEXT WORD
SOJGE T2,MAKCH1 ;AND LOOP, IF NOT LOOKED FAR ENOUGH
;HERE IF NOT ENOUGH NULLS FOUND IN RANGE - SHUFFLE REST OF FILE DOWN
;IF ANY NULLS HAVE BEEN FOUND, LEAVE THEM ALONE
HRRZ T3,EN ;GET ADDRESS OF END OF FILE
ADD EN,NUMWDS ;EXTEND FILE BY THAT AMOUNT
HRRZ T4,EN ;GET ADDRESS OF NEW END OF FILE
HRRZ T2,CHRPTR ;GET ADDRESS OF LAST WORD TO MOVE
CAMLE T2,ADJWRD ;NEED TO ADJUST THE ADJUSTABLE WORD?
JRST MAKADD ;NO - SKIP THIS
MOVE T1,T4 ;YES - FIND DISTANCE THE WORD WILL MOVE
SUB T1,T3
ADDM T1,ADJWRD ;ADJUST THE WORD FORWARD BY THAT AMOUNT
MAKADD: MOVE T1,(T3) ;GET A WORD
MOVEM T1,(T4) ;SAVE IT
SOJ T4,
CAME T3,T2 ;BACK TO START?
SOJA T3,MAKADD ;NO - KEEP GOING
AOJA T4,MAKCH4 ;YES - PUT STUFF IN THAT NEW GAP
;HERE FROM MAKCH1, WHEN A WORD OF NULLS IS FOUND
MKCH1A: SOJGE T3,MAKCH1 ;GOT A NULL - LOOP IF NOT ENOUGH
SOJ T4, ;ELSE ADJUST WORD POINTER AND EXIT THIS LOOP
;NOW SQUEEZE ALL THE NULL WORDS UP TO THE LOCATION OF THE FILE POINTER
MAKCH2: HRRZ T2,CHRPTR ;GET ADDRESS OF LAST WORD TO SHUFFLE
MOVE T3,T4 ;POINT TO END OF SHUFFLE
MAKCH3: CAMGE T3,T2 ;AT STARTING WORD?
AOJA T4,MAKCH4 ;YES - DONE SHUFFLING BYTES
SKIPN T1,(T3) ;GET A WORD - NULL
SOJA T3,MAKCH3 ;YES - DON'T SHUFFLE
MOVEM T1,(T4) ;NO - SAVE FARTHER DOWN
CAMN T3,ADJWRD ;IS THIS THE WORD THAT NEEDS ADJUSTING?
HRRM T4,ADJWRD ;YES - ADJUST IT
SOJ T4,
SOJA T3,MAKCH3 ;DE-BUMP BOTH POINTERS AND LOOP
;NOW WRITE THE DESIRED STUFF INTO THE OPENED-UP AREA
MAKCH4: TLNE F,XPB ;GOT AN ADJUSTED BOTTOM POINTER?
JRST MAKCH5 ;NO - SKIP THIS
SETZ T1, ;YES - SAVE THE ADJUSTED ADDRESS WITH THE PTR
EXCH T1,ADJWRD
HRRM T1,BOTPTR
MAKCH5: MOVE T1,@ADJWRD ;GET THE WORD AT THE POINTER
CAMN T1,[-1,,0] ;IS IT -1,,0?
SETZM @ADJWRD ;YES - IT SHOULD BE ZERO, SO MAKE IT SO
HLL T4,CHRPTR ;GET POINTER TO FIRST CHAR AFTER INSERT
MOVEM T4,NUMNUL ;SAVE IT FOR LATER
MOVE T4,CHRPTR ;POINT TO START OF INSERTED STUFF
MOVE T3,NUMCHR ;GET THE NUMBER OF CHARACTERS TO WRITE
TLZE F,WRH ;WANT TO READ FROM THE PICK OR CLOSE BUFFER?
JRST MAKPTP ;YES - HANDLE SEPARATELY
MOVE T1,CHARAC ;NO - GET THE CHARACTER TO PUT IN
IDPB T1,T4 ;PUT THE CHARACTER IN
SOJG T3,.-1 ;LOOP <NOCH> TIMES
;PAD OUT THE REMAINDER OF THE LAST WORD WITH NULLS; THEN RETURN
MAKPT1: MOVEM T4,MAKPTR ;SAVE POINTER TO LAST REAL THING ADDED
SETZ T1, ;GET A NULL
MAKPT2: CAMN T4,NUMNUL ;REACHED GOOD STUFF?
POPJ P, ;YES - DONE
IDPB T1,T4 ;NO - PUT THE NULL IN
JRST MAKPT2 ;AND LOOP THROUGH THE DESIRED NUMBER
;HERE TO WRITE FROM THE PICK OR CLOSE BUFFER INTO THE OPENED-UP SPACE
MAKPTP: SKIPN PUTJFN ;WANT TO READ FROM DISK?
JRST MAKPT0+1 ;NO - DON'T INITIALIZE
PUSHJ P,MAKPB0 ;YES - INITIALIZE
MAKPT0: PUSHJ P,MAKPTB ;SET UP A PIECE IN THE BUFFER
MOVE PT,PUTPTR
MAKPPT: ILDB T1,PT ;GET CHARACTER FROM THE PICK BUFFER
MAKPP0: IDPB T1,T4 ;SAVE IT IN THE FILE BUFFER
CAIN T1,15 ;<CR>?
SOJG T3,MAKPP1 ;YES - SEE IF END OF LINE
SOJG T3,MAKPPT ;LOOP <NOCH> TIMES
SKIPG MAKCNT ;GOT MORE TO READ FROM BUFFER?
JRST MAKPT1 ;NO - PUT ENDING NULLS IN, IF ANY
JRST MAKPT0 ;YES - GET AND PUT IT
MAKPP1: ILDB T1,PT ;PICK UP LINEFEED
CAIN T1,12 ;IS IT REALLY?
AOS MAKLNS ;YES - BUMP COUNT OF LINES FOUND
JRST MAKPP0 ;CONTINUE
;SUBROUTINE FOR WHEN READING FROM DISK: READ NEXT BUFFERFUL OF TEXT
;AND SET UP COUNTS. WHEN LAST BUFFERFUL HAS BEEN READ, CLOSE DISK FILE
MAKPB0::MOVE PT,PUTPTR ;SAVE POINTER TO THE PROPER BUFFER
MOVEM PT,PTMPTR
MOVEM T3,MAKCNT ;SAVE COUNT OF CHARACTERS TO ADD
IFN TOPS10,<
HRLI PT,-PCBSIZ ;MAKE IOWD PCBSIZ,(PICK/CLOSE BUFFER)
MOVEM PT,PUTCCL
>
POPJ P,
MAKPTB:
IFE TOPS10,<
MOVE T1,PUTJFN ;GET BUFFER JFN
>
MOVE T2,PTMPTR ;GET POINTER TO THE RIGHT BUFFER
MOVEM T2,PUTPTR ;SAVE IT
MOVNI T3,PCBSIZ*5 ;DECREASE CHAR COUNT BY ONE BUFFERFUL
ADDM T3,MAKCNT ;UNLESS THERE'S NOT THAT MUCH OUT THERE
SKIPGE MAKCNT ;GOT SOMETHING LEFT FOR NEXT TIME?
JRST [SUB T3,MAKCNT ;NO - READ ONLY A PARTIAL BUFFER
IFN TOPS10,<
MOVE T1,T3 ;SET UP I/O WORDCOUNT FOR FINAL READ
IDIVI T1,5
SOJ T1,
HRLM T1,PUTCCL
>
SETZM MAKCNT ;CLEAR COUNT TO INDICATE FINISHED-NESS
SETZM PUTJFN ;CLEAR BUFFER JFN
JRST .+1]
IFN TOPS10,<
INPUT 5,PUTCCL ;READ THE BUFFERFUL
>
IFE TOPS10,<
PUSH P,T3
SIN ;READ THE BUFFERFUL
POP P,T3
>
MOVN T3,T3 ;MAKE COUNT POSITIVE
SKIPE PUTJFN ;TIME TO CLOSE THE BUFFER FILE?
POPJ P, ;NO - JUST PROCESS THE BUFFER
IFN TOPS10,<
RELEAS 5, ;YES
>
IFE TOPS10,<
CLOSF ;YES
HALTF
>
POPJ P,
;************************************************************************
;SUBROUTINES FOR WHEN THE USER WANTS TO DO SOMETHING IN THE MIDDLE OF A TAB
;CHANGE THE TAB TO SPACES, RE-ADJUST CURSOR POSITION, AND DRIVE ON
;CALL WITH T1/POINTER TO THE TAB
RPLTAB::SKIPN TABSPC ;SITTING AT START OF TAB?
POPJ P, ;YES - DON'T BUST THE TAB THIS TIME
MOVE T1,TABSIZ ;ELSE GET SIZE OF TAB
MOVEM T1,NUMCHR ;SAVE AS NUMBER OF CHARACTERS TO MAKE
SETZ T1, ;NULL OUT THE TAB
IDPB T1,T2
PUSHJ P,MAKSPC ;ADD THOSE SPACES
TLO F,XPC
JRST MAKCPT ;RE-MAKE CURSOR POINTER AND RETURN
;************************************************************************
;PEEL ROUTINES - THESE CONVERT A PART OF THE PARAMETER BUFFER TO
;A NUMBER (PEEL.1), OR MOVE A FILE SPEC TO ITS OWN SPEC-IAL AREA (PELS.1)
;CAN ENTER IN ONE OF THREE SITUATIONS:
;ENTER, PARAMETER
;ENTER, NO PARAMETER PARPTR UNCHANGED; GET TOKEN (OR SPECIAL)
;ENTER, CURSOR MOVE CMV SET; TWO PARMS SET UP
;CAN RETURN IN ONE OF THREE SITUATIONS:
;NO ENTER TYPED ENT FLAG IS NOT SET
;ENTER, BUT NO PARAMETER TYPED ENT SET; T1/0
;ENTER AND PARAMETER TYPED ENT SET; T1/NON-0
;SUBROUTINE TO READ A DECIMAL NUMBER FROM BUFFER. RETURN IS IN PARG1
;RETURNS T1/0 IF PARM NULL; ELSE -1
PEEL.1::SETZB T1,PARG2 ;CLEAR PARM SET BY CURSOR MOVE
TRNE F,CMV ;WAS PARM DEFINED USING CURSOR MOVEMENT?
JRST PEEL.M ;YES - THAT'S A WHOLE NUTHER STORY
MOVE T4,[POINT 7,PARBUF]
CAMN T4,PARPTR ;ENTER-NO PARM TYPED?
JRST PEEL.C ;YES - MAY WANT TO COUNT UP A TOKEN
IDPB T1,PARPTR ;MAKE SURE PARAMETER ENDS WITH A NULL
SETZB T1,T3 ;CLEAR FLAG AND RETURN VALUE
PEEL1:: ILDB T2,T4 ;GET A CHARACTER
JUMPE T2,PEEL3 ;DONE IF NULL
CAIN T2,177 ;DELIMITER CHARACTER?
JRST PEEL2 ;YES - END OR IGNORE
SETO T1, ;ELSE INDICATE A NON-NULL PARAMETER
SUBI T2,60 ;CONVERT TO OCTAL
CAIL T2,12 ;IS IT REALLY A NUMBER?
JRST PGTERR ;NO - GIVE ERROR MESSAGE
JUMPL T2,PGTERR
IMULI T3,12 ;YES - SHIFT TARGET
ADD T3,T2 ;ADD IN NEW DIGIT
JRST PEEL1 ;GET SOME MORE
PEEL2: CAIE DO,$SUBST ;GOT DELIMITER - IS THIS SUBSTITUTE COMMAND?
JRST PEEL1 ;NO - JUST IGNORE IT (ELSE FINISH OFF)
PEEL3: JUMPE T1,CPOPJ ;IF NULL PARM FOUND, JUST RETURN
MOVEM T3,PARG1 ;SAVE PARM
POPJ P, ;DONE
PGTERR: MOVEI T1,[ASCIZ /#####Argument must be numeric/]
JRST ERROR
;HERE IF PARAMETER WAS MADE USING CURSOR MOVEMENT
;SET PARG1 TO ROWS MOVED AND PARG2 TO COLUMNS
;CALLER SHOULD RESTORE MARK AT (RW,CM), THEN GET (RW,CM) FROM (SAVPOS,+1)
PEEL.M: DMOVEM RW,SAVEAC ;SAVE ENDING POSITION
SUB RW,SAVPOS ;FIND DIFFERENCE IN ROW
MOVE T2,RW ;GET ACTUAL DIFFERENCE
MOVMM RW,PARG1 ;SAVE MAGNITUDE OF DIFFERENCE
JUMPGE RW,[MOVE RW,SAVPOS ;IF POSITIVE GO FROM STARTING POSITION
JRST PEL.M1] ;NOW CHECK COLUMN
MOVE RW,SAVEAC ;IF NEGATIVE GO FROM ENDING POSITION
EXCH RW,SAVPOS
TLO F,XPL!XPC ;RE-DO ROW AND COLUMN POINTERS
PEL.M1: SUB CM,SAVPOS+1 ;FIND DIFFERENCE IN COLUMN
CAIE DO,$INSLN ;OPEN-
CAIN DO,$DELLN ; OR CLOSE-LINES COMMAND?
JRST PEL.M4 ;YES - HANDLE SPECIALLY
CAIE DO,$CASE ;SAME WITH THE CASE
CAIN DO,$PICK ; AND PICK COMMANDS
JRST PEL.M4 ;YES - DON'T ADJUST COLUMN
PEL.M2: MOVMM CM,PARG2 ;SAVE MAGNITUDE OF DIFFERENCE
JUMPL CM,PEL.M5 ;JUMP IF NEGATIVE
MOVE CM,SAVPOS+1 ;IF POSITIVE GO FROM STARTING POSITION
PEL.M3: MOVE T1,SAVCPT ;RE-SET ORIGINAL CHARACTER POINTER
CAME T1,CHRPTR ;HAS IT CHANGED ANY (W-WISE TABS)?
TLO F,XPL!XPC ;YES - RE-DO IT
POPJ P, ;AND LET CALLER WORRY ABOUT IT
PEL.M4: JUMPE T2,PEL.M2 ;IF NO ROW CHANGE, DO IT THE OLD WAY
MOVEM CM,PARG2 ;ELSE USE ACTUAL COLUMN DIFFERENCE
JUMPG T2,PEL.M3-1 ;CONTINUE, IF ROW CHANGE POSITIVE
MOVNM CM,PARG2 ;NEGATIVE - SAVE NEGATIVE DIFFERENCE
PEL.M5: MOVE CM,SAVEAC+1 ;NEGATIVE - GO FROM ENDING POSITION
EXCH CM,SAVPOS+1
TLO F,XPC ;RE-DO COLUMN POINTER
JRST PEL.M3 ;NOW FINISH OFF
;SUBROUTINE TO COUNT THE SIZE OF THE CURRENT FILE TOKEN
PEEL.C: CAIE DO,$RLFWL ;IS IT A ROLL LINES COMMAND?
CAIN DO,$RLBKL
POPJ P, ;YES - SPECIAL NON-TOKEN CASE
CAIE DO,$GOTO ;IS IT A PERCENT COMMAND
CAIN DO,$EXEC ; OR AN EXECUTE COMMAND?
POPJ P, ;YES - ANOTHER NON-TOKEN CASE
CAIN DO,$JUSTI ;HOW ABOUT JUSTIFY?
POPJ P, ;YES - LIKEWISE
PUSHJ P,MAKCPT ;MAKE POINTER TO CURSOR LOCATION
MOVE PT,CHRPTR ;GET CURSOR POINTER
SETZ T2, ;CLEAR COUNT
CAIN DO,$SETCT ;IS IT A SET-COUNTER EXECUTE CONSTRUCT?
JRST PEL.CN ;YES - READ THE NUMBER AT THE CURSOR POSITION
PEL.C1: ILDB T1,PT ;GET CHARACTER FROM THE BUFFER
JUMPE T1,.-1 ;IGNORE IF NULL
CAIGE T1,"0" ;TOO SMALL FOR A NUMBER?
AOJA T2,PEL.C3 ;YES - END OF TOKEN
CAIG T1,"9" ;IS IT A NUMBER?
AOJA T2,PEL.C1 ;YES - GOOD
ANDI T1,137 ;CONVERT LOWER CASE TO UPPER
CAIL T1,"A" ;GOT A LETTER (IN EITHER CASE)?
CAILE T1,"Z"
AOJA T2,PEL.C3 ;NOT A LETTER - END OF TOKEN
AOJA T2,PEL.C1 ;LETTER - GO GET ANOTHER ONE
;HERE TO READ A NUMBER FROM FILE AS THE TOKEN
PEL.CN: ILDB T1,PT ;GET CHARACTER FROM THE BUFFER
JUMPE T1,.-1 ;IGNORE IF NULL
CAIL T1,"0" ;IS IT A NUMBER?
CAILE T1,"9"
JRST PEL.C3 ;NO - END OF TOKEN
SUBI T1,"0" ;YES - CONVERT TO A DIGIT
IMULI T2,^D10 ;SHIFT OVER WHAT'S THERE ALREADY
ADD T2,T1 ;ADD IN THE NEW DIGIT
JRST PEL.CN ;AND GO GET MORE
;DONE - SAVE THE TOKEN VALUE AND RETURN
PEL.C3: MOVEM T2,PARG1 ;SAVE SIZE OF TOKEN
CAIN DO,$PICK ;DOING A PICK?
SETZ T1, ;YES - CLEAR GOT-AN-ARG FLAG
POPJ P, ;DONE
;SUBROUTINE TO PEEL OFF A STRING (FOR SEARCHES, SET-FILE, PUT)
;CALL WITH T3/ ASCII POINTER TO STRING SAVE AREA
;RETURNS T1/LENGTH OF STRING
PELS.1::TRZE F,CMV ;GOT A CURSOR MOVEMENT PARAMETER?
JRST PELS.M ;YES - HANDLE IT
SETZ T1, ;CLEAR GOT-A-PARM FLAG
MOVE T4,[POINT 7,PARBUF]
CAMN T4,PARPTR ;ENTER-NO PARM TYPED?
JRST PEEL.T ;YES - MAY WANT TO PICK UP A TOKEN
IDPB T1,PARPTR ;MAKE SURE PARAMETER ENDS WITH A NULL
ILDB T2,T4 ;GET THE FIRST CHARACTER
JUMPN T2,PELS2A ;IF NULL, JUST ENTER WAS TYPED
POPJ P, ;SO JUST RETURN
PELST2::ILDB T2,T4 ;GET A CHARACTER
PELS2A: CAIN T2,177 ;DELIMITER CHARACTER?
JRST PELST3 ;YES - IGNORE IT OR END
IDPB T2,T3 ;SAVE IT WHEREVER USER WANTS
JUMPE T2,CPOPJ ;DONE, IF NULL
AOJA T1,PELST2 ;ELSE COUNT CHARACTER AND LOOP
PELST3: CAIE DO,$SUBST ;GOT DELIMITER - IS THIS SUBSTITUTE COMMAND?
JRST PELST2 ;NO - JUST IGNORE IT
SETZ T0, ;YES - END STRING WITH A NULL
IDPB T0,T3
POPJ P, ;DONE
;HERE TO PEEL A CURSOR MOVEMENT STRING
;CALLER SHOULD RESTORE MARK AT (RW,CM), THEN GET (RW,CM) FROM (SAVPOS,+1)
PELS.M::CAME CM,SAVPOS+1 ;ONLY LEGAL IF NOT ON THE SAME COLUMN,
CAME RW,SAVPOS ; BUT ON THE SAME LINE - O.K.?
JRST CMVERR ;NO - ILLEGAL
PUSH P,T3 ;SAVE POINTER TO PLACE TO SAVE STRING
MOVE T1,CM ;GET LENGTH OF STRING TO PICK UP
SUB T1,SAVPOS+1 ;(MAKCPT PRESERVES ONLY T1)
CAIL T1,0 ;IS COUNT NEGATIVE?
MOVE CM,SAVPOS+1 ;NO - GET ORIGINAL POSITION BACK
TLO F,XPC ;ALWAYS RE-DO CHARACTER POINTER
PUSHJ P,MAKCPT ;RE-DO IT, ALREADY
POP P,T3
JUMPGE T1,PELSM1 ;IS THE COUNT NEGATIVE?
TLO F,XPC ;YES - GET THE CORRECT STARTING COLUMN
MOVE CM,SAVPOS+1
PELSM1: MOVM T4,T1 ;SET UP SIZE OF PICK
MOVE PT,CHRPTR ;GET THAT POINTER
PUSHJ P,SPCBUF ;PICK UP THE STRING FROM THE BUFFER
MOVE T1,SPCCNT ;GET COUNT OF CHARACTERS PICKED
SETZ T2, ;END PARAMETER WITH A NULL
IDPB T2,T3
POPJ P, ;DONE
;SUBROUTINE TO PEEL OFF A TOKEN FROM THE FILE.
;THE TOKEN IS DEFINED AS EXTENDING FROM THE CURSOR LOCATION TO THE
;NEXT NON-ALPHANUMERIC CHARACTER
;TOKEN IS STORED AT AREA POINTED TO BY T3
PEEL.T: CAIN DO,$PUT ;GOT A PUT COMMAND?
POPJ P, ;YES - DON'T READ TOKEN
MOVEM T3,PARPTR ;SAVE SAVE POINTER
PUSHJ P,MAKCPT ;MAKE POINTER TO CURSOR LOCATION
MOVE T3,[POINT 7,PARBUF]
EXCH T3,PARPTR ;RESTORE SAVE POINTER
SETZ T1, ;CLEAR LENGTH OF TOKEN
CAIN DO,$SETFI ;IS COMMAND A SETFIL?
JRST PEEL.F ;YES - GET A FILESPEC-FLAVORED TOKEN
MOVE PT,CHRPTR ;GET CURSOR POINTER
PEL.T2: ILDB T2,PT ;GET CHARACTER FROM THE BUFFER
JUMPE T2,.-1 ;IGNORE IF NULL
CAIGE T2,"0" ;TOO SMALL FOR A NUMBER?
JRST PEL.T3 ;YES - END OF TOKEN
CAIG T2,"9" ;IS IT A NUMBER?
JRST PEL.T1 ;YES - GOOD
MOVE T0,T2 ;CONVERT LOWER CASE TO UPPER
ANDI T0,137
CAIL T0,"A" ;GOT A LETTER (IN EITHER CASE)?
CAILE T0,"Z"
JRST PEL.T3 ;NOT A LETTER - END OF TOKEN
PEL.T1: IDPB T2,T3 ;SAVE CHARACTER IN CALLER'S BUFFER
IDPB T2,PARPTR ;SAVE CHARACTER IN PARAMETER BUFFER
AOJA T1,PEL.T2 ;COUNT IT AND GET ANOTHER ONE
;SUBROUTINE TO PEEL OFF A FILESPEC STRING.
;CALL WITH T3/ ASCII POINTER TO STRING SAVE AREA
;RETURNS T1/LENGTH OF STRING
PELS.F::TRZE F,CMV ;GOT A CURSOR MOVEMENT PARAMETER?
JRST PELS.M ;YES - HANDLE IT
MOVE T4,[POINT 7,PARBUF]
CAMN T4,PARPTR ;ENTER-NO-PARM TYPED?
JRST PEEL.T ;YES - MAY WANT TO PICK UP A TOKEN
SETZB T1,FILSPC ;CLEAR GOT-AN-ARG FLAG
IFN TOPS10,<
MOVE T2,[FILSPC,,FILSPC+1]
BLT T2,FILSPC+13 ;CLEAR OUT PREVIOUS FILE SPECS
>
IDPB T1,PARPTR
ILDB T2,T4 ;GET THE FIRST CHARACTER
JUMPN T2,PELSF1 ;IF NULL, JUST ENTER WAS TYPED
POPJ P, ;SO JUST RETURN
PELSF0: ILDB T2,T4 ;GET A CHARACTER
PELSF1: CAIN T2,"=" ;WANT TO CREATE A FILE?
JRST [TRO F,CRE ;YES - FLAG AS SUCH
JRST PELSF0] ;AND GET ANOTHER CHARACTER
CAIN T2,"@" ;WANT TO USE THE FILES GIVEN IN THIS FILE?
JRST [TRO F,IND ;YES - FLAG AS SUCH
JRST PELSF0] ;AND GET ANOTHER CHARACTER
IDPB T2,T3 ;SAVE IT WHEREVER USER WANTS
JUMPE T2,CPOPJ ;DONE, IF NULL
AOJA T1,PELSF0 ;ELSE COUNT CHARACTER AND LOOP
;SUBROUTINE TO PEEL OFF A FILESPEC TOKEN FROM THE FILE.
;10: TOKEN INCLUDES ALL LETTERS AND NUMBERS, PLUS ":.["
; IF "[" IS FOUND ONLY OCTAL NUMBERS AND ",]" ARE LEGAL
;20: TOKEN INCLUDES ALL LETTERS AND NUMBERS, PLUS ":.<>-"
;BOTH: OTHER CHARACTERS, OR MORE THAN 64 OF THESE, END THE TOKEN
PEEL.F: SKIPE MFLPTR ;WORKING WITH AN INDIRECT FILE?
JRST SETMFB ;YES - BACK UP A FILE
SETZM FILSPC ;CLEAR FILSPEC BLOCK
IFN TOPS10,<
MOVE T2,[FILSPC,,FILSPC+1]
BLT T2,FILSPC+13 ;CLEAR OUT PREVIOUS FILE SPECS
>
MOVE PT,CHRPTR ;GET CURSOR POINTER
MOVEI T0,100 ;SAVE AT MOST 64 CHARACTERS
PEL.F1: ILDB T2,PT ;GET CHARACTER FROM THE BUFFER
JUMPE T2,.-1 ;IGNORE IF NULL
CAIL T2,"a" ;LOWER CASE?
SUBI T2,40 ;YES - CONVERT TO UPPER
CAIE T2,"." ;DOT,
CAIN T2,":" ; OR COLON?
JRST PEL.F3 ;YES - CONTINUE
IFN TOPS10,<
CAIN T2,"[" ;OPEN BRACKET?
AOJA T1,PEL.F2 ;YES - CONTINUE IN PPN MODE
>
IFE TOPS10,<
CAIE T2,74 ;OPEN
CAIN T2,76 ; OR CLOSE BRACKET?
JRST PEL.F3 ;YES - CONTINUE
CAIN T2,"-" ;DASH?
JRST PEL.F3 ;YES - CONTINUE
>
CAIGE T2,"0" ;NUMERIC?
JRST PEL.T3 ;NO - END OF TOKEN
CAIG T2,"9" ;NUMERIC?
JRST PEL.F3 ;YES - CONTINUE
CAIGE T2,"A" ;ALPHABETIC?
JRST PEL.T3 ;NO - END OF TOKEN
CAIG T2,"Z" ;ALPHABETIC?
PEL.F3: SOJLE T0,PEL.T3 ;YES - DONE IF COUNTED OUT
IDPB T2,T3 ;SAVE CHARACTER IN CALLER'S BUFFER
IDPB T2,PARPTR ;SAVE CHARACTER IN PARAMETER BUFFER
AOJA T1,PEL.F1 ;COUNT IT AND GET MORE
PEL.T3: SETZ T2, ;END BUFFER WITH A NULL
IDPB T2,T3
IDPB T2,PARPTR
POPJ P, ;DONE (LENGTH IS RETURNED IN T1)
IFN TOPS10,<
PEL.F2: IDPB T2,T3 ;SAVE CHARACTER IN CALLER'S BUFFER
IDPB T2,PARPTR ;SAVE CHARACTER IN PARAMETER BUFFER
ILDB T2,PT ;GET CHARACTER FROM THE BUFFER
JUMPE T2,.-1 ;IGNORE IF NULL
CAIN T2,"," ;COMMA?
JRST PEL.F4 ;YES - CONTINUE
CAIN T2,"]" ;CLOSE BRACKET?
JRST PEL.F3 ;YES - CONTINUE IN NON-PPN MODE
CAIGE T2,"0" ;NUMERIC?
JRST PEL.T3 ;NO - END OF TOKEN
IFN FTSFD,<
CAIG T2,"9" ;NUMERIC?
JRST PEL.F4 ;YES - O.K.
ANDI T2,137 ;CONVERT LOWER CASE TO UPPER
CAIGE T2,"A" ;ALPHABETIC?
JRST PEL.T3 ;NO - END OF TOKEN
CAIG T2,"Z" ;ALPHABETIC?
>
IFE FTSFD,<
CAIG T2,"7" ;OCTAL NUMERIC?
>
PEL.F4: SOJLE T0,PEL.T2 ;YES - DONE IF COUNTED OUT
AOJA T1,PEL.F2 ;COUNT IT AND GET MORE
> ;END IFN TOPS10
CMVERR: SKIPA T1,[[ASCIZ /######Stay on the same line/]]
CMXERR::MOVEI T1,[ASCIZ /###Can't mix characters and moves/]
MOVE RW,SAVPOS ;RESTORE SAVED POSITION
MOVE CM,SAVPOS+1
JRST ERROR
;************************************************************************
;INITIALIZING SUBROUTINES
;SUBROUTINE TO RESCAN USER'S RUN LINE TO SEE IF HE TYPED "R EDIT;FILESPECS"
;LOOKS FOR AN "E", SKIPS TO NEXT SPACE OR ";", ASSUMES THE REST IS SPECS
;MOVE SPACES TO PARM BUFFER AND SET FLAG SO THEY WILL BE PARSED
IFN TOPS10,<
RSCANL::RESCAN ;GO TO START OF RUN LINE
SETZM RSCANF
RSCAN0: INCHRS T1 ;IS THERE A CHARACTER WAITING?
JRST RSCANR ;NO - DONE
CAIN T1,"E" ;BEGINNING OF EDITOR NAME?
JRST RSCAN1 ;NO - KEEP LOOKING
CAIE T1,"e" ;BEGINNING OF EDITOR NAME?
JRST RSCAN0 ;NO - KEEP LOOKING
RSCAN1: INCHRS T1 ;YES - SKIP CHARACTERS
JRST RSCANR ;UNTIL END OF LINE,
CAIN T1,"/" ;IF A SLASH IS FOUND
JRST RSCA1B ; JUMP INTO THE GOOD STUFF
CAIE T1," " ;IF A SPACE
CAIN T1,";" ; OR SEMICOLON IS FOUND
JRST RSCA1A ; START THE GOOD STUFF
JRST RSCAN1 ;ELSE KEEP SKIPPING
RSCA1A: INCHRS T1 ;GET FIRST FILE CHARACTER
JRST RSCAN3 ;DONE IF NOTHING WAITING
CAIN T1," " ;SKIP ANY LEADING SPACES
JRST RSCA1A
RSCA1B: MOVE T0,[POINT 7,CLSBUF] ;POINT TO START OF CLOSE BUFFER
MOVEM T0,PARPTR
CAIE T1,12 ;END OF LINE?
CAIN T1,15
JRST RSCAN3 ;YES - SET UP NO FILE
SETOM RSCANF ;NO - SET ENTER-PARAMETER FLAG
JRST RSCA2A ;GO SAVE THE FILE NAME
RSCAN2: INCHRS T1 ;YES - SAVE FROM HERE ON AS A PARAMETER
JRST RSCAN3 ;DONE IF NOTHING LEFT
RSCA2A: CAIE T1,12 ;END OF LINE?
CAIN T1,15
JRST RSCAN3 ;YES - CLEAN BUFFER OUT AND RETURN
IDPB T1,PARPTR ;ELSE SAVE THE CHARACTER
JRST RSCAN2 ;AND GET ANOTHER ONE
RSCANR: CLRBFI ;JUST CLEAR INPUT BUFFER AND RETURN
POPJ P,
RSCAN3: CLRBFI
SETZ T0, ;END BUFFER WITH A NULL
IDPB T0,PARPTR
>
IFE TOPS10,<
RSCANL::MOVE T1,[POINT 7,CLSBUF]
MOVEM T1,PARPTR ;POINT TO START OF CLOSE BUFFER
SETZB T1,RSCANF ;SET TO RE-READ RUN LINE
SETZM SAVEAC+10 ;CLEAR GOT-AN-OUTPUT-FILE FLAG
IFE FTDDT,<
RSCAN
>
POPJ P, ;IF THERE'S A PROBLEM, FORGET IT
RSCNL1: PBIN ;GET THE FIRST CHARACTER
CAIE T1," " ;SKIP LEADING SPACES
CAIN T1,11 ;AND TABS
JRST RSCNL1
CAIE T1,"C" ;GOT THE "CREATE" COMMAND
CAIN T1,"c"
TRO F,CRE ;YES - FLAG AS SUCH
CAIE T1,"P" ;GOT THE "PERUSE" COMMAND?
CAIN T1,"p"
SETOM GREFLG ;YES - SET THE GLOBAL READ-ONLY FLAG
CAIA ;SKIP THE FIRST PBIN AND FLOW
RSCAN0: PBIN ;GET A CHARACTER
CAIN T1,12 ;END OF LINE?
POPJ P, ;YES - RETURN
CAIN T1,"E" ;BEGINNING OF EDITOR NAME?
JRST RSCAN1 ;YES - SKIP TO A SPACE
CAIE T1,"e" ;BEGINNING?
JRST RSCAN0 ;NO - KEEP LOOKING
RSCAN1: PBIN ;GET A CHARACTER
CAIN T1,12 ;END OF LINE?
JRST RSCN30 ;YES - COPY SWITCHES, IF ANY; DONE
CAIN T1,"/" ;DOES THE LINE START WITH SWITCHES?
JRST RSCN1S ;YES - SAVE 'EM OFF
CAIE T1," " ;GOT A SPACE YET?
JRST RSCAN1 ;NO - KEEP SKIPPING
RSCN1A: PBIN ;GET THE FIRST FILESPEC CHARACTER
CAIN T1,12 ;END OF LINE?
JRST RSCN30 ;YES - COPY SWITCHES, IF ANY; DONE
CAIN T1," " ;SKIP ANY LEADING SPACES
JRST RSCN1A
CAIE T1,15 ;DON'T SET FLAG IF END OF THE LINE
SETOM RSCANF ;GOT LIVE CHAR - SAY FILESPECS HAVE BEEN FOUND
CAIN T1,"/" ;DOES THE LINE START WITH SWITCHES?
JRST RSCN1S ;YES - SAVE 'EM OFF
JRST RSCN2A ;AND GO SET UP THE SPECS
RSCAN2: PBIN ;GET A FILESPEC CHARACTER
CAIN T1,12 ;END OF LINE?
JRST RSCAN3 ;YES - FINISH OFF
RSCN2A: CAIN T1," " ;GOT A SPACE?
JRST RSCN2O ;YES - GOT SWITCHES OR START OF OUTPUT FILE
CAIE T1,15 ;IGNORE CARRIAGE RETURNS
IDPB T1,PARPTR ;ELSE SAVE THE CHARACTER
JRST RSCAN2 ;NO - GET ANOTHER CHARACTER
;HERE IF FOUND A SPACE WHILE SAVING THE FILESPECS. MAY HAVE AN OUTPUT FILE.
;IGNORE NOISE IN PARENS, SKIP COMMENTS, IF ANY
RSCN2O: PBIN
CAIN T1,12 ;END OF LINE?
JRST RSCAN3 ;YES - GO FINISH OFF
CAIE T1," " ;SKIP LEADING SPACES,
CAIN T1,15 ; AND A CARRIAGE RETURN
JRST RSCN2O
CAIN T1,"/" ;START OF SWITCHES?
JRST RSCN2A ;YES - GO BACK UP TO FILESPEC LOOP
CAIN T1,"(" ;START OF NOISE?
JRST RSCN2N ;YES - GO SKIP THE NOISE
CAIE T1,"!" ;START OF A COMMENT?
CAIN T1,";"
JRST RSCN2S ;YES - SKIP THE REST OF THE LINE
MOVE T4,[ASCII ?/OUT:?]
SKIPE SAVEAC+10 ;NO - ALREADY HAD AN OUTPUT SPEC?
JRST RSCN2E ;YES - ERROR
SETOM SAVEAC+10 ;NO - THERE'S ONE NOW
LSHC T3,7 ;SET UP AN /OUTPUT: SWITCH
IDPB T3,PARPTR
JUMPN T4,.-2
JRST RSCN2A ;OUTPUT THE OUTPUT FILESPEC
RSCN2E: MOVEI T1,.PRIIN ;CLEAR THE INPUT BUFFER
CFIBF
HRROI T1,[ASCIZ /#More than one output filespec given/]
JRST ERROR
;HERE TO SKIP THE REST OF A LINE IF A COMMENT IS FOUND
RSCN2S: MOVEI T1,.PRIIN ;CLEAR THE INPUT BUFFER
CFIBF
JRST RSCAN3 ;AND GO FINISH OFF
;HERE TO SKIP NOISE, IF "(" IS FOUND
RSCN2N: PBIN ;GET A NOISE CHARACTER
CAIN T1,")" ;END OF THE NOISE?
JRST RSCN2O ;YES - PROCEED WITH THE GOOD STUFF
CAIN T1,12 ;END OF LINE?
JRST RSCAN3 ;YES - GO FINISH OFF
JRST RSCN2N ;NO - SKIP THE CHARACTER
;HERE WHEN DONE - COPY ANY SWITCHES TO AFTER THE FILESPEC
RSCN30: TRNN F,FLG ;WERE ANY SWITCHES SEEN?
POPJ P, ;NO - DONE
RSCAN3: TRZE F,FLG ;GOT SOME SWITCHES THAT NEED COPYING?
PUSHJ P,RSCNSW ;YES - COPY THEM
SETZ T0, ;END BUFFER WITH A NULL
IDPB T0,PARPTR
>
TLZ F,SMF ;CLEAR SAME-FILE FLAG (FROM REDTMP)
MOVE PT,[POINT 7,CLSBUF] ;NOW LOOK OVER SPECS AGAIN
RSCAN4: ILDB T1,PT ;SEE IF THERE ARE ANY SWITCHES
JUMPE T1,CPOPJ ;IF END OF BUFFER, DONE
CAIE T1,"/" ;ELSE GOT START OF SWITCHES?
JRST RSCAN4 ;NO - KEEP LOOKING
DPB T0,PT ;YES - NULL OUT THE FIRST SLASH
CAMN PT,[350700,,CLSBUF] ;SWITCHES ONLY; NO FILESPECS?
SETZM RSCANF ;YES - PRETEND USER DIDN'T TYPE ANYTHING
JRST SWHMNY ;GO HANDLE THE SWITCHES AND RETURN
IFE TOPS10,<
RSCN1S: MOVE T4,[POINT 7,PARBUF] ;STORE SWITCHES IN PARBUF FOR NOW
TROA F,FLG ;AND NOTE THAT THEY'RE THERE
RSCNS2: PBIN ;GET A SWITCH CHARACTER
CAIE T1," " ;SPACE,
CAIN T1,15 ; OR CARRIAGE RETURN?
JRST RSCNS3 ;YES - END OF SWITCHES
CAIN T1,12 ;LINEFEED?
JRST RSCNS3 ;YES - END OF SWITCHES
IDPB T1,T4 ;SAVE IT IN THE STAGING AREA
JRST RSCNS2 ;AND GET MORE
RSCNS3: SETZ T0, ;END SWITCHES WITH A NULL
IDPB T0,T4
CAIN T1,12 ;END WITH A LINEFEED?
JRST RSCAN3 ;YES - END OF THE LINE
JRST RSCN1A ;PROCESS THE REST OF THE COMMAND LINE
;SUBROUTINE TO COPY SWITCHES FROM PARBUF TO COMMAND STRING IN CLSBUF
RSCNSW: MOVE T4,[POINT 7,PARBUF]
ILDB T1,T4 ;MOVE THE SWITCHES
IDPB T1,PARPTR ;FROM PARBUF TO CLSBUF
JUMPN T1,.-2 ;UNTIL A NULL IS FOUND,
POPJ P, ;THEN RETURN
>
;HERE ON ENTRY TO TRANSFER RESCANNED SPECS TO PARM BUFFER
SETSCN::MOVE T1,[POINT 7,PARBUF]
MOVE T2,[POINT 7,CLSBUF]
ILDB T0,T2 ;GET A CHARACTER FROM THE CLOSE BUFFER
IDPB T0,T1 ;SAVE IT IN THE PARAMETER BUFFER
JUMPN T0,.-2 ;LOOP UNTIL A NULL IS FOUND
MOVEM T1,PARPTR ;SAVE PARAMETER POINTER
MOVEI DO,$SETFI ;PRETEND A SET-FILE COMMAND WAS TYPED
IFN TOPS10,<
IFN FTSFD,<
MOVE T1,[FILSPC,,OLDSPC] ;COPY CURRENT SPECS INTO OLD SPECS
BLT T1,OLDSPC+SPCSIZ-1
MOVEI T1,SFDLVL ;SET UP DEFAULT PATH AS CURRENT ONE
SETSFD: MOVE T2,DEFPTH+2(T1)
MOVEM T2,FILPTH+2(T1)
SOJGE T1,SETSFD
JRST SETFLC ;GO DO THAT SET-FILE
>
IFE FTSFD,<
JRST SETFLS ;SET TO THE FILE; PRESERVE READ-ONLY FLAG
>>
IFE TOPS10,<
JRST SETFLS
>
;REDEDT - SUBROUTINE TO READ TMPCOR
;THIS ROUTINE WAS STOLEN FROM TECO AND MODIFIED FOR USE BY SED
;
; PUSHJ P,REDEDT ;READS EDT TMPCOR
; NO TMPCOR AVAILABLE ;NO EDT TMPCOR AVAILABLE
; TMPCOR AVAILABLE ;TMPCOR HAS BEEN READ AND FILSPEC IN THE BUFFER
;
REDEDT::DMOVE T2,[XWD 'EDT',0 ;SETUP TO READ EDT TMPCOR
IOWD 400,PIKBUF+PCBSIZ-400]
MOVE T1,[.TCRDF,,T2] ;POINT TO THE TMPCOR UUO ARG
TMPCOR T1, ;READ AND DELETE FILE EDT
POPJ P, ;NO FILE EDT OR NO TMPCOR UUO
MOVE T6,[POINT 7,PIKBUF+PCBSIZ-400] ;GET START OF BUFFER AREA
IBP T6 ;SKIP LINED "S"
MOVE PT,[POINT 7,CLSBUF] ;WHERE TO STORE OUR FILE SPECS
MOVEI T2,"=" ;FLAG NO EQUALS SIGN SEEN
SETZ T3, ;AND SET UP A NUL
;LOOP BACK HERE ON EACH NEW CHARACTER IN THE TMP FILE
EDTLOP: ILDB T1,T6 ;INPUT THE FILE NAME & EXT
CAMN T1,T2 ;FIRST EQUALS SIGN SEEN?
JRST EDTEQL ;YES
CAIE T1,15 ;CR?
CAIN T1,"}" ;OLD ALT?
JRST EDTNUL ;THEN PROCESS THE END OF THE SEQUENCE
JUMPE T1,EDTLOP ;THROW AWAY NULLS
IDPB T1,PT ;ELSE STORE CHAR
JRST EDTLOP ;AND LOOP FOR ALL CHARS
;HERE ON THE FIRST "=" IN THE COMMAND STRING
EDTEQL: IDPB T3,PT ;MAKE SURE IT ENDS IN A NUL
HRRZ T1,.JBFF ;FIRST FREE LOCATION
ADDI T1,400 ;WE'LL NEED 401 WORDS
CAMG T1,.JBREL ;DO WE CURRENTLY HAVE THE MEMORY?
JRST EDTEQ1 ;YES, SO WE DON'T NEED TO DO THE UUO
CORE T1, ;LET IT GROW
JRST GAKERR ;GAD ZOOKS!
EDTEQ1: MOVE T1,[ASCII |/OUT:|] ;SO, "=" MEANS THAT WE HAVE THE OUTPUT
MOVEM T1,@.JBFF ;SAVE THE /OUT SWITCH
HRLI T1,CLSBUF ;MAKE A BLT POINTER
HRR T1,.JBFF
AOS T1 ;CLSBUF,,BUFFER+1
MOVE T2,.JBFF ;WHERE TO END THE BLT
ADDI T2,400 ;BUFFER+400
BLT T1,(T2) ;MOVE IT
MOVE PT,[POINT 7,CLSBUF] ;START THE BUFFER ALL OVER
SETO T2, ;PREVENT FINDING LATER EQUALS
JRST EDTLOP ;AND LOOP BACK FOR NEXT CHAR
;HERE ON A NUL (END OF COMMAND). SEE IF IT WAS MAKE OR TECO
EDTNUL: CAIG T1,15 ;WAS BREAK A CRLF?
JRST EDTNU1 ;YES
SKIPGE T2 ;IF WE'VE SEEN AN "="
JRST EDTNU0 ;THEN WE DON'T NEED TO CREATE THE FIRST FILE
MOVEI T4,"=" ;ADD AN "=" TO THE COMMAND LINE
IDPB T4,PT ;WHICH MEANS CREATE THIS FILE
EDTNU0: MOVEI T4,"/" ;NOW ADD "/WR"
IDPB T4,PT
MOVEI T4,"W"
IDPB T4,PT
MOVEI T4,"R"
IDPB T4,PT
EDTNU1: MOVE T6,.JBFF ;POINT TO THE STORED BUFFER
SKIPGE T2 ;IF WE'VE SEEN AN "=" THEN TRANSFER THE
;FILESPEC INCLUDING THE NUL, IF NOT JUST
;COPY A NUL
EDTOUT: ILDB T3,T6 ;GET A BYTE THAT HAS BEEN SAVED AWAY
IDPB T3,PT ;PUT A BYTE INTO THE COMMAND BUFFER
JUMPN T3,EDTOUT ;LOOP UNTIL WE COPY A NUL
SETOM RSCANF ;WE GOT THIS INFO FROM A SCAN
TRZ F,RDO ;WE MAY WANT TO WRITE THIS FILE
AOS (P) ;SKIP RETURN
POPJ P, ;RETURN
;HERE TO READ nnnSED.TMP, IF ANY, AND SET UP THE FILE STATUS THERE
;IF NONE, SETS UP FOR THE DEFAULT "WELCOME TO SED" MESSAGE
REDTMP::HRROI T2,SEDFIL
IFN TOPS10,<
IFN FTTMPC,<
MOVE T1,[1,,TMPBLK] ;TRY TO READ STATS FROM TMPCOR
TMPCOR T1,
CAIA ;FAILED - GET THEM OFF DISK
JRST REDT0A ;O.K. - GO PROCESS THEM
>
MOVE T0,SEDFIL+3 ;GET THE PPN
>
PUSHJ P,SETIN ;GO FIND THE TEMPORARY FILE
JUMPE T1,CPOPJ ;IF NONE, JUST RETURN
REDTM0::
IFN TOPS10,<
MOVEM T0,SEDFIL+3 ;PUT THE RIGHT PPN BACK AGAIN
MOVEI T1,-400
HRLM T1,SEDCCL ;SET UP SIZE OF FILE
INPUT 5,SEDCCL ;READ STATUS INTO PICK BUFFER
RELEAS 5,
REDT0A:
>
IFE TOPS10,<
MOVE T2,[POINT 7,PIKBUF+PCBSIZ-400]
SETZ T3, ;READ THE FILE INTO THE PICK BUFFER
SIN
CLOSF ;CLOSE THE FILE
HALTF
>
SETZB T2,INDFLG
MOVE PT,[POINT 7,PIKBUF+PCBSIZ-400]
MOVE T4,[POINT 7,FILSPC]
MOVEM T4,MFLPT1 ;SAVE POINTER TO 1ST SPEC
PUSHJ P,TMPGET ;READ ACTIVE SPECS INTO ACTIVE AREA
JUMPE T1,REDTM1 ;IS THERE ANOTHER LINE (WITH ALTERNATE SPECS)?
MOVE PT,MFLPTR ;YES - GET SPEC POINTER BACK
MOVEM PT,MFLPT0 ;SAVE IT AS PTR TO 2ND SPEC
MOVE T4,[POINT 7,OLDSPC]
PUSHJ P,TMPGET ;READ ALTERNATE SPECS INTO OLD AREA
REDTM1: CAIGE T1,"0" ;IS THERE AN ALPHANUMERIC ON THE NEXT LINE?
SETZM MFLPTR ;NO - FORGET THE POINTER
SETZM DISPTR ;CLEAR POINTERS
SETZM SAVEDP ; TO NOTE THAT PARSING MUST BE DONE
TLO F,XPL!XPC!XPB ;SAY NO POINTERS ARE VALID
IFE TOPS10,<
MOVE T4,[POINT 7,OLDSPC]
MOVE PT,[POINT 7,SAVEXP+1]
PUSHJ P,UNPEXT ;SET UP THE ALTERNATE FILE'S EXTENSION
PUSHJ P,UNPEX0 ;AND THAT OF THE CURRENT FILE; FALL INTO
>
;SUBROUTINE TO SEE IF FILE AND ALTERNATE ARE THE SAME
;SETS FLAG SMF IF FILES ARE THE SAME, ELSE CLEARS SMF
SAMFIL::TLZ F,SMF ;ASSUME FILES AREN'T THE SAME
IFE TOPS10,<
SKIPN SAVEAC+12 ;IF USER GAVE VN # FILES CAN'T BE THE SAME
>
SKIPE OUTFLG ;CHANGING THE NAME OF THE NEW FILE?
POPJ P, ;YES - FILES AREN'T THE SAME
MOVE T3,[POINT 7,FILSPC]
MOVE T4,[POINT 7,OLDSPC]
SAMFL1: ILDB T1,T3 ;SEE IF BOTH FILE SPECS ARE THE SAME
ILDB T2,T4
CAIN T1,"/" ;TREAT START OF SWITCHES
SETZ T1, ; LIKE END OF SPECS
CAIN T2,"/"
SETZ T2,
CAME T1,T2 ;ARE SPECS THE SAME SO FAR?
POPJ P, ;NO - DONE
JUMPN T1,SAMFL1 ;ELSE LOOP THROUGH ENTIRE STRING
TLO F,SMF ;FILES ARE THE SAME IF CONTROL GETS HERE
POPJ P, ;DONE
;SUBROUTINE TO READ A FILESPEC FROM (PT) AND SAVE IN (T4). EXPECTS T2/0
;RETURNS FIRST CHARACTER OF NEXT LINE IN T1
TMPGET::TDZ T0,T0 ;CLEAR "GOT /FD" FLAG
TMPGT1: ILDB T1,PT ;GET FIRST CHARACTER
CAIE T1,11 ;TAB OR
CAIN T1," " ; SPACE?
JRST TMPGT1 ;YES - IGNORE IT
CAIE T1,";" ;IS THE ENTIRE LINE A COMMENT?
CAIN T1,"!"
JRST TMPGTI ;YES - IGNORE THE WHOLE LINE
CAIE T1,15 ;BLANK LINE?
JRST TMPGT3 ;NO - CONTINUE
ILDB T1,PT ;YES - SKIP THE LINEFEED, TOO
JRST TMPGT1 ;AND CHECK NEXT LINE
TMPGT2: ILDB T1,PT ;READ SPECS INTO ACTIVE OR ALTERNATE AREA
JUMPE T1,TMPGT4 ;IF NULL, GO FINISH OFF
CAIN T1,15 ;GOT A CARRIAGE RETURN?
JRST TMPGT4 ;YES - FINISH OFF
TMPGT3: CAIN T1,"/" ;GOT THE /FD SWITCH, MAYBE?
PUSHJ P,TMPGTS ;MAYBE - CHECK IT OUT
CAIE T1,"!" ;GOT END OF SPECS?
CAIN T1,";"
JRST TMPGTT ;YES - SAY LINE ENDS HERE
CAIN T1,11 ;GOT A TAB?
JRST TMPGTT ;YES - SAY LINE ENDS HERE
IDPB T1,T4 ;NO - SAVE CHARACTER
JRST TMPGT2 ;AND GET ANOTHER
TMPGTT: ILDB T1,PT ;FOUND TAB - SKIP UNTIL CR
CAIE T1,15
JUMPN T1,TMPGTT ;(A NULL CAN END IT, TOO)
TMPGT4: JUMPN T0,TMPGTE ;IF GOT /FD, O.K.
EXCH T4,TY ;ELSE SET IT UP NOW
MOVE T1,[ASCII ?/FD:0?]
PUSHJ P,PUTSQ1
EXCH T4,TY
TMPGTE: IDPB T2,T4 ;PUT NULL AT END OF STRING
ILDB T1,PT ;SKIP OVER THE LINEFEED
MOVEM PT,MFLPTR ;SAVE POINTER TO (MAYBE) NEW SPECS
TMGEE1: ILDB T1,PT ;PICK UP FIRST CHARACTER OF NEXT LINE
CAIE T1,11 ;TAB OR
CAIN T1," " ; SPACE?
JRST TMGEE1 ;YES - IGNORE IT
POPJ P, ;GIVE IT BACK TO CALLER
TMPGTS: IDPB T1,T4 ;SAVE THE SLASH
ILDB T1,PT ;GET NEXT CHARACTER
CAIE T1,"F" ;FILE SWITCH?
POPJ P, ;NO - CONTINUE
IDPB T1,T4 ;YES - SAVE IT
ILDB T1,PT ;GET NEXT CHARACTER
CAIN T1,"D" ;STILL FILE SWITCH?
AOJ T0, ;YES - SET FLAG
POPJ P, ;RETURN EITHER WAY
TMPGTI: ILDB T1,PT ;SKIP UNTIL A LINEFEED
CAIE T1,12
JRST TMPGTI
JRST TMPGT1 ;THEN READ THE NEXT LINE
;SUBROUTINE TO MOVE PRE-SET FILE STATUS INFORMATION INTO THE ACTIVE PLACES
;PNTSTT CAN BE CALLED TO SET UP POINTERS TO START OF FILE (PERCEN, NEWFIL)
PRESET::HRRZ T2,PREDP ;GET ADDRESS OF DISPLAY POINTER
CAIL T2,(EN) ;DOES IT POINT BEYOND END OF FILE?
JRST PNTSTT ;YES - POINT TO START OF FILE
TLO F,XPL!XPC!XPB ;NO - NO POINTERS ARE GOOD
HRRZ RW,PRERW ;GET PRE-SET ROW
HLRZ CM,PRERW ;AND COLUMN
MOVE SL,PRESL ;AND SLIDE
SETZ T2, ;GET AND ZERO DISPLAY POINTER
EXCH T2,PREDP
MOVEM T2,DISPTR
POPJ P,
PNTSTT::MOVE T2,[010700,,BUFFER-1]
MOVEM T2,DISPTR ;POINT TO START OF FILE
MOVEM T2,LINPTR
MOVEM T2,CHRPTR
SETZB RW,CM
SETZ SL,
TLZ F,XPC!XPL ;LINE AND CHARACTER POINTERS ARE O.K.
TLO F,XPB ;BUT BOTTOM POINTER IS BAD
POPJ P,
;****************************************************************
;SUBROUTINE TO READ THE INIT FILE AND SET UP THE SWITCHES THEREIN
;LOOKS FOR THE FOLLOWING: SED.INI (SED.INIT ON TOPS20) IN PATHED DIRECTORY;
;DITTO, LOGIN DIRECTORY; SWITCH.INI IN PATHED; DITTO LOGIN
;(SED.INIT DOESN'T NEED TO HAVE "SED/" AT THE START OF EVERY LINE)
REDSWH::SETOM INIFLG ;ASSUME SED.INIT WILL BE FOUND
HRROI T2,INIFIL ;FIND SED.INIT ON CONNECTED DIRECTORY
PUSHJ P,SETIN ; OR LOGIN DIRECTORY
JUMPN T1,REDSW0 ;IF O.K. GO READ IT IN
HRROI T2,SWHFIL ;ELSE LOOK FOR SWITCH.INI
PUSHJ P,SETINL ; IN THE LOGGED-IN DIRECTORY ONLY
JUMPE T1,CPOPJ ;NOT FOUND - JUST RETURN
SETZM INIFLG ;FLAG THE FILE AS SWITCH.INI
IFN TOPS10,<
REDSW0: HRRI T1,PIKBUF-1 ;READ THE FILE INTO THE PICK BUFFER
MOVEM T1,PIKCCL
INPUT 5,PIKCCL
RELEAS 5,
MOVEI T1,-PCBSIZ ;SET PROPER PICK SIZE BACK UP
HRLM T1,PIKCCL
>
IFE TOPS10,<
REDSW0: MOVE T2,[POINT 7,PIKBUF]
SETZ T3,
SIN ;READ THE FILE INTO THE PICK BUFFER
CLOSF ;CLOSE THE FILE
HALTF
>
MOVE PT,[POINT 7,PIKBUF]
REDSW1: PUSHJ P,REDCHR ;GET 1ST CHARACTER OF A LINE
JUMPE T1,REDSWE ;IF NULL, CLEAR OUT PICK BUFFER AND RETURN
JUMPL T1,REDSWS ;IF A COMMENT LINE, SKIP IT
SKIPE INIFLG ;READING SED.INIT?
JRST REDSW3 ;YES - MAYBE THERE'S NO "SED"
CAIN T1," " ;IGNORE SPACES
JRST REDSW1
CAIE T1,"S" ;START OF "SED"?
JRST REDSWS ;NO - SKIP THE LINE
PUSHJ P,REDCHR ;YES - GET THE "E"
CAIE T1,"E" ;IS IT?
JRST REDSWS ;NO - SKIP THE LINE
PUSHJ P,REDCHR ;YES - GET THE "D"
CAIE T1,"D" ;IS IT?
JRST REDSWS ;NO - SKIP THE LINE
REDSW2: ILDB T1,PT ;YES - LOOK FOR THE "/"
REDSW3: JUMPE T1,REDSWE ;IF NULL CLEAR OUT PICK BUFFER AND RETURN
CAIN T1,12 ;AT END OF LINE?
JRST REDSW1 ;YES - TRY OUT THE NEXT LINE
CAIE T1,"/" ;GOT A SLASH?
JRST REDSW2 ;NO - KEEP LOOKING
PUSHJ P,SWHMNY ;YES - HANDLE ALL THE SWITCHES
JRST REDSW1 ;SEE IF THERE'S ANOTHER LINE
REDSWS: ILDB T1,PT ;SKIP REST OF LINE - GET CHARACTER
JUMPE T1,REDSWE ;IF AT END OF FILE, FINISH OFF
CAIE T1,12 ;GOT A LINEFEED?
JRST REDSWS ;NO - LOOP
JRST REDSW1 ;YES - CHECK NEXT LINE
REDSWE: MOVEI T1,XBFNUM-1 ;MAKE SURE NULL EXECUTE BUFFER'S STILL ACTIVE
MOVEM T1,XCTACW
SETZM PIKBUF ;END OF FILE - CLEAR OUT PICK BUFFER
MOVE T1,[PIKBUF,,PIKBUF+1]
HRLI PT,(BLT T1,) ;TO END OF STUFF THAT'S JUST BEEN PROCESSED
XCT PT
POPJ P, ;RETURN FROM SWITCH.INI PROCESSING
REDCHR: ILDB T1,PT ;GET NEXT CHARACTER
CAIE T1,";" ;START OF A COMMENT?
CAIN T1,"!"
SETO T1, ;YES - SET TO SKIP IT
CAIL T1,"a" ;LOWER CASE?
SUBI T1,40 ;YES - CONVERT TO UPPER
POPJ P, ;RETURN
;************************************************************************
IFE TOPS10,<
IFN FTECHO,<
;SUBROUTINES TO PLAY GAMES WITH THE TERMINAL:
;BRKALL - BREAK ON ALL CHARACTERS
;BRKNPT - BREAK ON NON-PRINTING CHARACTERS
;EKOALL - NO ECHO AND BREAK ON ALL CHARACTERS
;EKONPT - ECHO PRINTING, AND BREAK ON NON-PRINTING, CHARACTERS
;ALL ROUTINES USE T1, T2, T3
EKOALL::SKIPN EKOFLG ;ALREADY ECHOING ALL?
POPJ P, ;YES - NOTHING TO DO
SETZM EKOFLG ;NO - SAY ECHOING ALL NOW
MOVEI T1,.PRIIN
MOVE T2,SMDSAV ;GET SED'S MODE WORD
TRZ T2,4000 ;MAKE NOTHING ECHO
SFMOD ;SET IT AND FALL TO SET THE BREAK SET
BRKALL::SKIPN BRKFLG ;ALREADY BREAK ON EVERYTHING?
POPJ P, ;YES - NOTHING TO DO
SETZM BRKFLG ;NO - SAY BREAK ON EVERYTHING NOW
MOVEI T3,[EXP 4,-1,-1,-1,-1] ;BREAK ON EVERYTHING
BRKSET::MOVEI T1,.PRIOU
MOVEI T2,.MOSBM
MTOPR
POPJ P,
EKONPT::TRNN F,IMD ;IN INSERT MODE,
SKIPGE EKOFLG ; OR ALREADY ECHOING NON-PRINTING?
POPJ P, ;EITHER - NOTHING TO DO
SETOM EKOFLG ;NOT BOTH - SAY ECHOING NPT NOW
MOVEI T1,.PRIIN
MOVE T2,SMDSAV ;RESTORE SED'S MODE WORD - TURN ECHO ON
SFMOD ;FALL TO SET UP THE BREAK SET AND RETURN
BRKNPT::TRNN F,IMD ;IN INSERT MODE?
SKIPGE BRKFLG ; OR ALREADY BREAK ON NON-PRINTING?
POPJ P, ;EITHER - NOTHING TO DO
SETOM BRKFLG ;NOT BOTH - SAY BREAK ON NPT NOW
MOVEI T3,[EXP 4,-1,0,0,20] ;NO - BREAK ONLY ON CONTROL CHARACTERS
JRST BRKSET ;GO SET THE BREAK MASK
>>
;************************************************************************
;HERE (ERROR:) TO CLEAR SCREEN, OUTPUT AN ERROR MESSAGE, REWRITE SCREEN,
;AND GO GET ANOTHER COMMAND. THE COMMAND THAT CAUSED THE ERROR IS IGNORED
;THIS ROUTINE CAN BE CALLED FROM ANY LEVEL SINCE IT RESETS THE P-D STACK
ALPERR::TLNE F,ERF ;JUST HAD AN ERROR?
JRST RDOERR ;YES - SKIP THIS
PUSHJ P,MAKCPT ;NO - MAKE SURE THE CHARACTER POINTER IS O.K.
PUSHJ P,DISLIN ;AND REPAIR THE FRAGGED LINE
RDOERR::MOVEI T1,[ASCIZ /######File cannot be modified/]
ERROR:: TLNE TM,JRC ;NO - RESTORING A JOURNAL?
JRST ERRORZ ;YES - JUST CONTINUE PROCESSING
TLOE F,ERF ;JUST HAD AN ERROR?
JRST ERRORX ;YES - DON'T OUTPUT THIS ONE, THEN
TRZN F,XCT!XBN ;EXECUTING?
TLZA F,FLG ;NO - CLEAR XCT AND FLG
TLO F,FLG ;YES - CLEAR XCT AND SET FLG
PUSHJ P,ERRDSP ;ELSE DISPLAY THE ERROR MESSAGE
TRNN F,GFL ;GOT A FILE TO EDIT?
JRST ERRORY ;NO - DISPLAY CHEERY MESSAGE
TLNN TM,SLW ;SLOW TERMINAL?
PUSHJ P,DISPLL ;NO - REWRITE THE SCREEN
PUSHJ P,ERASPM ;IF ENTER TYPED CLEAN LINE UP
ERRORX: PUSHJ P,POSCUR
ERRORZ: MOVE P,[IOWD STKSIZ,STACK] ;CLEAN UP THE STACK
TLZ F,FLG!ENT ;STOP DOING COMMANDS; CLEAR ENTER MODE
JRST LOOP ;AND GET ANOTHER COMMAND
ERRORY: MOVE P,[IOWD STKSIZ,STACK] ;CLEAN UP THE STACK
TLZ F,FLG!ENT ;STOP DOING COMMANDS; CLEAR ENTER MODE
SKIPE STTFLG ;INITIALIZING?
JRST INIERR ;YES - FINISH THE INITIALIZATION
JRST REDNO ;NO - GO DISPLAY CHEERY MESSAGE
;HERE TO HANDLE ERRORS FROM SETTING FILES. THEY ARE SPECIAL SINCE SED CAN'T
;JUST REDISPLAY THE SCREEN - THERE MIGHT NOT BE A FILE TO REDISPLAY
;ACTION: RESTORE CURRENT AND ALTERNATE SPECS
;IF GFL DO A NORMAL ERROR, ELSE GET CURRENT FILE OR CHEERY MESSAGE
STFERR::MOVS T2,[FILSPC,,OLDSPC] ;RESTORE THE CURRENT SPECS
BLT T2,FILSPC+SPCSIZ-1
HLRZ CM,SAVERW ;GET ROW AND COLUMN BACK
HRRZ RW,SAVERW
MOVE T2,SAVEDP ;GET DISPLAY POINTER
MOVEM T2,DISPTR
MOVE SL,SAVESL ;SET UP SLIDE
MOVS T2,[OLDSPC,,SVASPC] ;AND THE OLD SPECS AND POINTERS
BLT T2,OLDSPC+SPCSIZ+2
IFN TOPS10,<
IFE FTSFD,<
MOVE T2,FILFIL+3 ;RESTORE THE PPN
MOVEM T2,FILPPN
>>
TLO F,XPC!XPL!XPB ;NO POINTERS ARE VALID
SETOM GOPRCT ;IF USER GAVE A /G: SWITCH CANCEL IT
SETZM OUTFLG ;DITTO AN /OUT: SWITCH
SKIPE PT,MFLPTR ;GOT ANOTHER SPEC IN STAT.TMP FILE?
JRST [PUSH P,T1 ;YES - SAVE ERROR MESSAGE
PUSHJ P,SETMFE ;READ NEW SPECS INTO OLDSPC
POP P,T1 ;GET ERROR MESSAGE BACK
JRST .+1] ;AND CONTINUE
STFER1::TRNE F,GFL ;GOT A FILE TO REDISPLAY?
JRST ERROR ;YES - OUTPUT THE ERROR NORMALLY
TLZ F,FLG ;NO - TURN OFF ERROR ROUTINE'S EXECUTE FLAG
PUSHJ P,ERRDSP ;OUTPUT THE MESSAGE
SKIPN FILSPC ;ARE THERE ANY OTHER FILESPECS?
JRST REDNO ;NO - GO SET UP CHEERY MESSAGE
SKIPE DISPTR ;YES - NEED TO PARSE SPECS?
JRST SETFL1 ;NO - GO TRY THE OTHER FILE
PUSHJ P,PARSEF ;YES - DO SO
SETZM SVASPC ;CLEAR OUT THE SAVED SPECS
MOVE T2,[SVASPC,,SVASPC+1]
BLT T2,SVASPC+SPCSIZ+2
JRST SETFL1 ;GO TRY THE OTHER FILE
;SUBROUTINE TO OUTPUT THE ERROR MESSAGE IN (T1)
ERRDSP::PUSH P,T1 ;SAVE MESSAGE ADDRESS
TLNE TM,SLW ;GOT A SLOW TERMINAL?
JRST ERRDSW ;YES - OUTPUT ONLY ON FIRST LINE
SKIPN STTFLG ;INITIALIZING?
PUSHJ P,CLRALL ;NO - MOVE HOME AND CLEAR THE SCREEN
MOVEI T1,STARS ;PUT UP UPPER STARS
PUSHJ P,PUTSTG
POP P,T1
PUSHJ P,PUTSTX
MOVEI T1,STARS ;PUT UP LOWER STARS
PUSHJ P,PUTSTG
PUSHJ P,PUTTYP ;OUTPUT THE MESSAGE
SNOOZE ^D1500 ;SLEEP A BIT
TLZ F,FLG ;CLEAR (EXECUTE) FLAG
POPJ P, ;DONE
;IF TERMINAL IS SLOW (SLW FLAG) PUT ERROR MESSAGE ON BOTTOM LINE
ERRDSW: PUSHJ P,CBOTOM ;GO TO BOTTOM LINE
MOVEI T1,7 ;BEEP ONCE
IDPB T1,TY
PUSHJ P,PROTON ;TURN PROTECTION ON
POP P,T1 ;RESTORE MESSAGE ADDRESS
PUSHJ P,PUTSTX ;OUTPUT MESSAGE
MOVEI T1," " ;FOLLOW THE MESSAGE WITH A SPACE
IDPB T1,TY
PUSHJ P,PROTOF ;TURN PROTECTION OFF AGAIN
PUSHJ P,PUTTYP ;OUTPUT THE MESSAGE
TLNE TM,NEL ;CAN BOTTOM LINE STAY FRAGGED?
JRST ERRDW1 ;YES - NO DELAY THEN
SNOOZE ^D1000 ;SLEEP A BIT
ERRDW1: TLZE F,FLG ;EXECUTING?
JRST DISPLL ;YES - RE-DISPLAY THE SCREEN AND RETURN
TLO F,FBL ;SAY BOTTOM LINE WILL BE FRAGGED
TLNN TM,NEL ;NO - CAN BOTTOM LINE REMAIN FRAGGED,
TLNE F,ENT ; OR HAS ENTER BEEN TYPED?
POPJ P, ;ANY OF THESE - DONE
SKIPE DISPTR ;IS THERE A CURRENT FILE
TRNN F,GFL ; (DITTO)?
POPJ P, ;NO - DONE
JRST FIXBLN ;YES - REPAIR THE BOTTOM LINE AND RETURN
;************************************************************************
;TOPS10 ROUTINE TO INITIALIZE PSI INTERRUPTS FOR KSYS
IFN TOPS10,<
PSIKSY::SKIPE KSYVEC+.PSVNP ;ALREADY INIT'D FOR KSYS PSI?
POPJ P, ;YES, JUST RETURN
XMOVEI T1,KSYINT ;GET KSYS INTERRUPT ROUTINE ADDRESS
MOVEM T1,KSYVEC+.PSVNP ;SAVE IN INTERRUPT VECTOR
MOVEI T1,KSYVEC ;GET VECTOR ADDRESS
PIINI. T1, ;TELL MONITOR VECTOR ADDRESS
POPJ P, ;OH WELL, WE TRIED
MOVE T1,[EXP PS.FON+PS.FAC+[
EXP .PCKSY
EXP 0
EXP 0]] ;GET ARG BLOCK TO ENABLE FOR KSYS INTERRUPTS
PISYS. T1, ;TELL THE MONITOR
TRN ;WHO USES KSYS ANYWAY?
POPJ P, ;RETURN
;************************************************************************
;TOPS10 ROUTINE TO HANDLE KSYS PSI INTERRUPTS
KSYINT: SKIPN KSYVEC+.PSVIS ;A VALID KSYS TIME
DEBRK. ;NO, JUST RETURN
MOVEM T1,KSYSAV ;SAVE AN AC
MOVE T1,KSYVEC+.PSVIS ;GET KSYS VALUE
CAIG T1,KSYMIN ;TIME FOR A WARNING?
SETOM KSYFLG ;YES, FLAG IT
MOVE T1,KSYSAV ;RESTORE AC
DEBRK. ;RETURN FROM INTERRUPT
HALT .
;************************************************************************
;TOPS10 ROUTINE TO WARN OF AN IMPENDING KSYS
KSYWRN::SETZM KSYFLG ;CLEAR WARNING FLAG
PUSHJ P,CBOTOM ;POSITION TO BOTTOM LINE
PUSHJ P,PROTON ;TURN ON PROTECTION
PUSHJ P,PUTTYP ;MAKE SURE TERMINAL KNOWS
SKIPG T1,KSYVEC+.PSVIS ;GET TIME TILL KSYS
JRST KSYW.1 ;MUST BE OVER OR PRE-7.03 COUNTDOWN BUG
PUSH P,T1 ;SAVE MINUTES TILL KSYS
MOVEI T1,[ASCIZ\ Timesharing will end in \] ;GET INITIAL TEXT
PUSHJ P,PUTSTG ;DUMP IT
MOVE T1,(P) ;GET MINUTES
PUSHJ P,PUTNUM ;DUMP IT
MOVEI T1,[ASCIZ\ minute\] ;GET ENDING TEXT
PUSHJ P,PUTSTG ;DUMP IT
POP P,T1 ;GET TIME BACK
SOJE T1,SWHNPE ;IF JUST 1, WE'RE DONE...
MOVEI T1,[ASCIZ\s\] ;...OTHERWISE WE MUST BE CORRECT
PUSHJ P,PUTSTC
JRST SWHNPE ;GO CLEAN UP AND RETURN (BUM SOME CODE)
;HERE IF TIMESHARING IS OVER
KSYW.1: AOSE T1 ;IS IT -1, TIMESHARING OVER?
POPJ P, ;NOPE, JUST RETURN
MOVEI T1,[ASCIZ\ Timesharing is over!\] ;YES, GET TEXT!
PUSHJ P,PUTSTG ;DUMP IT
JRST SWHNPE ;HOPE IT'S NOT TO LATE
;************************************************************************
;TOPS10 ROUTINE TO INPUT A CHAR. CHAR IS RETURNED IN T1.
GETCHR::INCHRS T1 ;CHARACTER WAITING?
TRNA ;NO
POPJ P, ;YES, RETURN WITH IT IN T1
MOVSI T1,(HB.RTC+HB.RTL) ;GET HIBER BITS
HIBER T1, ;WAIT FOR INPUT (OR PSI)
HALT . ;SHOULDN'T HAPPEN
SKIPE KSYFLG ;IMPENDING KSYS?
PUSHJ P,KSYWRN ;YES, TELL USER
JRST GETCHR ;SEE IF A CHARACTER IS AVAILABLE
;************************************************************************
;TOPS10 INTERRUPT ROUTINE TO EXPAND CORE BY 1K
GETAK:: PUSH P,T1 ;SAVE AN AC
HRRZ T1,.JBREL ;FIND CURRENT LIMIT
ADDI T1,1000 ;PLUS ONE K
CORE T1, ;EXPAND
JRST GAKERR ;OOPS (PROBABLY RAN OUT)
POP P,T1 ;RESTORE AC
JRST 2,@.JBTPC ;RETURN FROM THE INTERRUPT
;HERE ON A FATAL CORE GRAB, PROBABLY A ILL MEM REF
;IF THIS HAPPENS, IT'S A BUG, BUT JUST TRY TO ISOLATE IT
GAKERR::MOVE P,[IOWD STKSIZ,STACK] ;CLEAN UP THE STACK
MOVEI T1,[ASCIZ /####Fatal error - save and exit/]
PUSHJ P,ERRDSP ;DISPLAY THE ERROR
JRST EEXIT ;SAVE FILE AND EXIT
>
END