Trailing-Edge
-
PDP-10 Archives
-
decuslib20-03
-
decus/20-0081/vtslve.mac
There is 1 other file named vtslve.mac in the archive. Click here to see a list.
TITLE VTSLVE -- SLAVE PART OF VTTAM SYSTEM
SUBTTL SLAVE STORAGE AND CONSTANTS
;TONY LAUCK 1 JUL 71
;A COPY OF VTSLVE RUNS FOR EACH VT05 TERMINAL CONNECTED TO VTTAM.
;THE TERMINAL IS DETERMINED BY ASSIGNING THE LOGICAL NAME "VTTERM".
;WHEN VTSLVE IS STARTED, IT ASKS FOR A NUMBER. THIS IS A DECIMAL
;NUMBER WHICH BECOMES THE NUMBER OF THE TERMINAL AS REFERENCED BY
;THE MASTER JOB.
;ACCUMULATORS
F=0 ;FLAGS
A=1 ;G.P. AC'S
B=2
C=3
D=C+1
T=5 ;TEMPS
T1=T+1
;VARIABLES USED IN DUMPING CORE TO CRT
LL=7 ;LINES LEFT ON SCREEN
CL=10 ;CHARACTERS LEFT ON CURRENT LINE
SL=11 ;COUNT OF QUEUED LINES FOR TRAILING LINE SUPPR.
SC=12 ;COUNT OF QUEUED CHARS FOR TRAILING BLANK SUPPR.
TT=13 ;VTTAM TERMINAL NUMBER OF THIS JOB
W=14 ;AC HOLDING WAKE UUO ENABLE BITS
H=15 ;CURSOR POSITION HORIZ. 0 TO N
V=16 ;CURSOR POSITION VERT. 0 TO M
P=17 ;PUSH DOWN POINTER
;FLAGS IN ACCUMULATOR F
;L.H.
WINPF=1B0 ;1 IF SLAVE WAITING FOR SHARED INPUT BUFFER
PDLEN=20 ;SIZE OF PUSH DOWN LIST
SCRCOL=^D72 ;COLUMNS PER LINE OF VT05
SCRLIN=^D20 ;LINES PER SCREEN OF VT05
INTERN SCRCOL,SCRLIN ;FORCE THESE TO MATCH HISEG AND MASTER
SCRCHR=SCRCOL*SCRLIN ;CHARACTERS PER SCREEN
SCRWDS=<SCRCHR+5>/6 ;WORDS PER SCREEN (DISPLAY-6)
;SPECIAL VT05 CHARACTERS
;THESE MUST AGREE WITH SPCTAB.
CH.FIL=1 ;FILLER CHARACTER
CH.HOM=35 ;HOME UP
CH.EOL=36 ;ERASE TO END OF LINE
CH.EOF=37 ;ERASE TO END OF SCREEN
;HIGH SEGMENT LOCATIONS USED BY MASTER AND SLAVE FOR COMMUNICATION
EXTERN JOBTAB ;TABLE INDEXED BY TERMINAL #
; GIVING SLAVE MONITOR JOB #
EXTERN MAXTRM ;MAX NUMBER OF VTTAM TERMINALS
EXTERN STDAY ;DATE SYSTEM STARTED OR STOPPED
EXTERN STTIME ;STARTING TIME MASTER BEGAN OR STOPPED
;START IF POS, STOP IF NEG.
EXTERN MJOBN ;JOB NUMBER OF MASTER
EXTERN SINFLG ;0 IF INPUT BUFFER FREE
;ELSE TERM NO WHICH FILLED IT
EXTERN SINBF ;SHARED INPUT BUFFER
EXTERN SOUTRM ;0 IF OUTPUT BUFFER EMPTY
; ELSE TERMINAL NUMBER OF DATA IN
; SOUTBF
EXTERN SOUMOD ;TYPE OF OUTPUT REQUEST
;-1 ERASE SCREEN, 0 FULL SCREEN, ELSE
; WRITE LINE
EXTERN SOUTBF ;SHARED OUTPUT BUFFER
EXTERN QREQ ;CRITICAL SECTION SYNC COUNT
EXTERN QBITS ;SLAVE SYNC REQUEST BIT-TABLE
EXTERN AVLINP ;ASSIGNMENT WORD FOR SHARED INPUT BUFFER
EXTERN QININP ;PUTTER FOR QUEUE FOR INPUT BUFFER
EXTERN QBFINP ;QUEUE AREA FOR INPUT BUFFER
EXTERN QSTINP ;BYTE POINTER TO FIRST INPUT BUFFER
; QUEUE ENTRY
EXTERN QFNINP ;BYTE POINTER TO LAST INPUT BUFFER
; QUEUE ENTRY
;MONITOR STUFF
EXTERN JOBFF
PTYCNF=22 ;GETTAB ITEM FOR PTY DATA WORD
CNFTBL=11 ;GETTAB TABLE FOR PTY DATA WORD
SPECLM=500 ;SPECIAL TTY DATA MODE
;USED WITH CRT TO CAUSE FULL CHAR SET
;AND TRUE ECHOING OF INPUT CHARACTERS
LINBIT=1B11 ;INPUT AVAILABLE LINE MODE BIT FOR GETLCH
CQBIT=1B16 ;^Q BIT FOR GETLCH, SETLCH TTCALL'S
WAKPRJ=1B17 ;WAKE UUO ENABLED FOR PROJECT MATCH (HIBER UUO)
WAKLN=1B13 ;WAKE UP ON TTY LINE MODE ACTIVITY (HIBER UUO)
OPDEF PJRST [JRST] ;PUSHJ POPJ CONVENTION
;SOFTWARE CHANNELS
VTCHN=1 ;VT05 I/O
;LOW SEGMENT STORAGE AREA
LOWZER: ;FIRST WORD TO ZERO IN INITIALIZAION
SAVFF: BLOCK 1 ;JOBFF SAVED HERE FOR BUFFER RECLAIMATION
VTIBF: BLOCK 3 ;CRT INPUT BUFFER HEADER
VTOBF: BLOCK 3 ;CRT OUTPUT BUFFER HEADER
TTYNUM: BLOCK 1 ;MONITOR TTY NO. OF VT05 SAVED HERE
PDL: BLOCK PDLEN ;PUSH DOWN LIST
QJOBN: BLOCK 1 ;OUR JOB NUMBER SAVED HERE
QWORD: BLOCK 1 ;WORD POINTER TO OUR QBIT ENTRY
QMASK: BLOCK 1 ;BIT MASK TO OUR QBIT ENTRY
;VT05 SCREEN IMAGE NORMALLY A COPY OF DATA ON CRT
SCREEN: BLOCK SCRWDS
;HOLD BUFFER FOR SCREEN IMAGE
;USED WHEN ESC RECEIVED AND SHARED INPUT BUFFER IS FULL
HOLD: BLOCK SCRWDS
HIZER=.-1 ;HIGHEST LOCATION TO ZERO ON INITIALIZATION
SUBTTL SLAVE ONCE ONLY CODE
;HERE ON STARTUP OF SLAVE JOB.
;USER MUST HAVE ASSIGNED DEVICE VTTERM TO THE VT05.
;USER MUST THEN TYPE IN DECIMAL TERMINAL NUMBER
;TO COMPLETE MAPPING OF MONITOR TTY NUMBER TO VTTAM NUMBER.
SGO: RESET
MOVEI T,SEGBLK ;GET SHARED SEGMENT
GETSEG T,
HALT . ;COULDN'T GET SEGMENT
MOVEI T,0 ;UNLOCK HISEG FOR WRITING
SETUWP T,
HALT . ;CAN'T UNLOCK HISEG
SETZM LOWZER ;ZERO SLAVE LOW CORE
MOVE T,[XWD LOWZER,LOWZER+1]
BLT T,HIZER
MOVEI 0,0 ;ZERO THE AC'S
MOVEI 17,1
BLT 17,17
MOVE P,[IOWD PDLEN,PDL] ;SET UP PUSH DOWN POINTER
MOVE T,JOBFF ;SAVE JOBFF FOR BUFFER RECLAIMATION
MOVEM T,SAVFF
PUSHJ P,TTYINI ;INIT THE VT05
PUSHJ P,GTT ;GET VTTAM UNIT NO. FROM OPERATOR
JRST SRESTB ;GO TO RESTART CODE
;CONTROL BLOCK FOR USE BY GETSEG UUO
SEGBLK: SIXBIT /DSK/ ;GETSEG DEVICE
SIXBIT /VTTAM/ ;FILE
SIXBIT /SHR/ ;EXT
0
0 ;PPN
0
;SUBROUTINE TO GET VTTAM TERMINAL NUMBER FROM CONTROLLING TTY.
;CALLED ONCE ONLY WHEN SLAVE JOB IS STARTED.
;USER TYPES A DECIMAL NUMBER <CR> IN RESPONSE TO "*".
;VTTAM ACCEPTS THE NUMBER AND RESPONDS WITH "!".
GTT: OUTSTR [ASCIZ /*/] ;PROMPT USER
MOVEI TT,0 ;ZERO NUMBER
;LOOP HERE TO CONVERT A DIGIT
GTT1: INCHWL T ;GET A CHARACTER
CAIL T,"0" ;CHECK FOR DIGIT
CAILE T,"9"
JRST GTT2 ;IF NO MORE DIGITS
IMULI TT,^D10 ; ELSE MULTIPLY BY 10
ADDI TT,-"0"(T) ; ADD IN DIGIT
JRST GTT1 ; AND LOOP FOR MORE
;HERE WHEN NON-DIGIT RECEIVED. LOOP HERE TO GOBBLE UNTIL <LF> SEEN.
GTT2: INCHWL T ;GOBBLE CHARACTER
CAIE T,12 ;IS IT LF?
JRST GTT2 ;GOBBLE IF NOT
JUMPLE TT,GTT3 ;CHECK LEGAILITY OF NUMBER
CAILE TT,MAXTRM
JRST GTT3 ;BAD
OUTSTR [ASCIZ /!/] ;TELL OPERATOR WHEN HAPPY
POPJ P, ;RETURN WITH TT SET UP
;HERE WHEN NUMBER HAS OVERFLOWED, OR IS TOO LARGE FOR JOBTAB
GTT3: OUTSTR [ASCIZ /?
/] ;TELL OPERATOR HE LOST
JRST GTT ;LET HIM TRY AGAIN
SUBTTL SLAVE RESTART CODE
;HERE ON VTCLSE (OR IMPLIED CLOSE ON VTOPEN).
;OUTPUT THE CLOSE MESSAGE AND GO TO IDLE STATE.
SRESTA: MOVE P,[IOWD PDLEN,PDL] ;RESET PDL TO TOP LEVEL
PUSHJ P,CMSG ;GIVE CLOSE MESSAGE
;HERE ON INITIAL START UP, OR ON CLOSE AFTER MESSAGE SENT OUT.
;WAIT FOR MASTER TO START UP.
SRESTB: SETZM JOBTAB(TT) ;TELL MASTER WE ARE IDLE
; IN CASE HE IS WAITING FOR IT
PUSHJ P,MWAKE ;WAKE HIM IF HE IS AROUND AND ASLEEP
PUSHJ P,UQINIT ;SET UP HIBERNATE WAKE ENABLES
;LOOP HERE WAITING FOR MASTER TO START UP.
SRESB1: SKIPLE STTIME ;IS MASTER UP?
JRST SRESTC ;YES
HIBER W, ;NO, HIBERNATE
HALT . ;HIBER UUO FAILED
JRST SRESB1 ;AWOKE. NOW SEE IF MASTER IS UP
;HERE ON STARTUP OR RESTART WHEN WE SAW MASTER WAS UP.
;THERE IS A RACE CONDITION BETWEEN SLAVE START-UP AND MASTER SHUT-DOWN.
SRESTC: MOVE T,QJOBN ;TELL MASTER OUR JOB NUMBER AND THEREBY
MOVEM T,JOBTAB(TT) ; WARN HIM WE ARE COMING UP.
SKIPG STTIME ;CHECK FOR "STARE-DOWN" CASE
JRST SRESTB ; IF WE LOST THE RACE, GO BACK TO IDLE
PUSHJ P,MWAKE ; ELSE WAKE MASTER
PUSHJ P,UQINIT ; SET UP OUR Q RESOURCE STUFF
PUSHJ P,OMSG ; SEND OUR OPEN MESSAGE
JRST SLOOP ; GO TO SLAVE MAIN LOOP
;SUBROUTINES TO SEND OPEN AND CLOSE MESSAGES TO VT05
;THESE INCLUDE TIME, DATE, TERMINAL NUMBER, VTTAM NUMBER, AND
;MONITOR JOB NUMBER.
;CALLED ON OPEN OR CLOSE FOR ALL TERMINALS.
;HERE TO OUTPUT OPEN MESSAGE.
OMSG: PUSHJ P,BLANK ;BLANK SCREEN IMAGE IN CORE
PUSHJ P,INLMES ;OPEN MESSAGE
ASCIZ /VTTAM OPENED AT /
JRST OCMSG ;TO COMMON CODE
;HERE TO OUTPUT CLOSE MESSAGE
CMSG: PUSHJ P,BLANK ;BLANK SCREEN IMAGE IN CORE
PUSHJ P,INLMES ;CLOSE MESSAGE
ASCIZ /VTTAM CLOSED AT /
;COMMON MESSAGE CODE
OCMSG: MOVM C,STTIME ;-TIME ON CLOSE
IDIV C,[^D60*^D60*^D1000] ;HOURS
PUSHJ P,OUT2D
MOVEI A,":"
PUSHJ P,OUTC
MOVE C,D ;MINUTES
IDIVI C,^D60*^D1000
PUSHJ P,OUT2D
MOVEI A,":" ;:
PUSHJ P,OUTC
MOVE C,D ;SECONDS
IDIVI C,^D1000
PUSHJ P,OUT2D
PUSHJ P,INLMES
ASCIZ / ON /
MOVE C,STDAY ;DATE
IDIVI C,^D12*^D31 ;COMPUTE YEAR
ADDI C,^D64
PUSH P,C ;SAVE YEAR
MOVEI C,^D31+1(D) ;MONTH (GET BACK TO 1 ORIGIN)
IDIVI C,^D31
PUSHJ P,OUT2D
MOVE C,D ;DAY
PUSHJ P,OUT2S
POP P,C ;YEAR
PUSHJ P,OUT2S
MOVEI V,3 ;GO DOWN 3 LINES
MOVEI H,0
PUSHJ P,INLMES ;DEVICE
ASCIZ /DEVICE: /
PUSHJ P,TTYNO ;GET PHYSICAL DEVICE NAME TO D
MOVE C,[POINT 6,D] ;1 WORD SIXBIT OUTPUT FROM D
MOVEI CL,6
SIXTYL: ILDB A,C
PUSHJ P,OUTC6
SOJG CL,SIXTYL
PUSHJ P,INLMES ;TERMINAL NUMBER
ASCIZ / VTTAM NO: /
MOVE C,TT
PUSHJ P,DECOUT
PUSHJ P,INLMES ;JOB NUMBER
ASCIZ / JOB NO: /
MOVE C,QJOBN
PUSHJ P,DECOUT
PUSHJ P,HOMEUP ;HOME UP
PUSHJ P,DUMP ;WRITE SCREEN IMAGE
PUSHJ P,FLUSH ;FLUSH ANY TYPE-AHEAD
PJRST HOMEUP ;HOME UP AND RETURN
;SUBROUTINE TO OUTPUT A SLASH PLUS 2 DECIMAL DIGITS
OUT2S: MOVEI A,"/" ;DO SLASH
PUSHJ P,OUTC
;AND FALL INTO OUT2D
;SUBROUTINE TO OUTPUT 2 DECIMAL DIGITS
OUT2D: PUSH P,D ;SAVE D
IDIVI C,^D10 ;GET 2 DIGITS
MOVEI A,"0"(C) ;OUTPUT HI-ORDER
PUSHJ P,OUTC
MOVEI A,"0"(D) ;OUTPUT LOW-ORDER
POP P,D ; RESTORE D
PJRST OUTC ; AND RETURN
;SUBROUTINE TO OUTPUT IN-LINE ASCIZ MESSAGE
INLMES: POP P,D ;GET CALL ADDRESS
HRLI D,(POINT 7,) ;MAKE IT A BYTE POINTER
;LOOP HERE TO OUTPUT A CHARACTER
INLME1: ILDB A,D ;GET CHAR
JUMPE A,1(D) ;RETURN IF NULL
PUSHJ P,OUTC ;ELSE OUTPUT IT
JRST INLME1 ; AND LOOP
;THE STANDARD RADIX 10. TYPER
DECOUT: IDIVI C,^D10 ;DIVIDE BY TEN
HRLM D,(P) ;SAVE REMAINDER
SKIPE C ;ALL DIGITS FORMED?
PUSHJ P,DECOUT ;NO, SO RECURR
HLRZ C,(P) ;YES, UNWIND
MOVEI A,"0"(C) ;MAKE IT A DIGIT
PJRST OUTC ;OUTPUT IT AND RETURN UP A LEVEL
SUBTTL SLAVE MAIN LOOP
;LOOP HERE IN SLAVE LOOKING FOR WORK.
;HERE TO CHECK ALL POSSIBLE WORK THE SLAVE JOB DOES, DO IT IF NECESSARY,
;OR HIBERNATE IF NOT.
;NOTE: THE HIBERN ROUTINE WORRIES ABOUT SHUT-DOWN'S AND RESTARTS.
SLOOP: TLNE F,(WINPF) ;WERE WE WAITING FOR AN INPUT BUFFER?
PUSHJ P,TRYINP ;YES. TRY TO GET IT.
JRST SLOOP1 ;CHECK OTHER WORK
JRST WON ;GOT BUFFER, GO USE IT
;HERE IN SLAVE LOOP WHEN INPUT BUFFER WAS BUSY, OR NOT NEEDED.
SLOOP1: PUSHJ P,CHKINP ;CHECK FOR VT05 INPUT
JRST SINPUT ; YES, GO HANDLE IT
; NO, KEEP LOOKING FOR OTHER WORK.
;NOW CHECK FOR OUTPUT REQUEST BY MASTER
CAMN TT,SOUTRM ;IS OUTPUT BUFFER FULL OF STUFF FOR US?
JRST OUTPRO ;IF SO, GO HANDLE IT
;NO
;HERE WHEN SLAVE HAS CHECKED FOR WORK AND FOUND NONE TO DO.
PUSHJ P,HIBERN ;CHECK FOR RESTARTS/SHUTDOWNS AND HIBERN
JRST SRESTA ;GO TO RESTART CODE
JRST SLOOP ;GO BACK TO SLAVE LOOP
SUBTTL SLAVE INPUT EDITING
;HERE WHEN SLAVE LOOP DETERMINED THERE ARE CHARACTERS IN THE VT05
; INPUT BUFFER. ALL CHARACTERS ARE PROCESSED, UPDATING SCREEN IMAGE
; IN CORE, EXCEPT FOR CHARACTERS THAT RESULT IN SPECIAL ACTION.
SINPUT: IN VTCHN, ;READ BUFFER
JRST SINPU1 ;OK
HALT . ;IMPOSSIBLE TTY FILE STATUS
;HERE TO PROCESS EACH CHARACTER IN THE INPUT BUFFER, OR RETURN
; TO SLAVE LOOP IF NONE ARE LEFT.
SINPU1: SOSGE VTIBF+2 ;COUNT BUFFERED CHARACTERS
JRST SLOOP ;IF NONE, GO BACK TO SLAVE LOOP
ILDB A,VTIBF+1 ;GET CHARACTER
JUMPE A,SINPU1 ;IGNORE NULLS
CAIN A,177 ;MAKE RUBOUT'S 0
MOVEI A,0
CAIGE A,40 ;IS IT A SPECIAL CHARACTER?
JRST SINP2 ; YES
PUSHJ P,OUTC ; NO, STORE GRAPHIC CHARACTER
JRST SINPU1 ;AND GO BACK FOR MORE
;HERE TO PROCESS A SPECIAL (CONTROL) CHARACTER RECEIVED
SINP2: XCT SPCTAB(A) ;DO FUNCTION
;INSTRUCTION, PUSHJ, OR JRST
JRST SINPU1 ;IF WE GET BACK HERE, GO BACK FOR MORE
;SPECIAL CHARACTER TABLE FOR INPUT PROCESSING
;THIS TABLE IS INDEXED BY CONTROL CHARACTER CODE (RUBOUT=0)
;ITS ENTRIES ARE XCT'ED TO CAUSE THE NECESSARY ACTION.
SPCTAB: JRST REWRIT ; RUBOUT REWRITE SCREEN
JRST ILLCH ; ^A ILLEGAL
JRST ILLCH ; ^B ILLEGAL
JRST RECCO ; ^C TURN OF ^O, ILLEGAL
JRST ILLCH ; ^D ILLEGAL
JRST ILLCH ; ^E WRU ILLEGAL
JRST ILLCH ; ^F ILLEGAL
JRST ILLCH ; ^G BEL ILLEGAL
PUSHJ P,CURLFT ; ^H BACKSPACE CURSOR LEFT, IF
; NOT AT LEFT MARGIN
JRST ILLCH ; ^I TAB ILLEGAL
PUSHJ P,LINFD ; ^J LINE FEED DOWN ONE, OR SCROLL
PUSHJ P,CURDWN ; ^K CURSOR DOWN DOWN ONE, IF NOT AT
; LAST LINE
JRST ILLCH ; ^L ILLEGAL
MOVEI H,0 ; ^M RETURN GO TO LEFT MARGIN
JRST ILLCH ; ^N ILLEGAL
JRST RECCO ; ^O TURN OFF ^O, ILLEGAL
JRST ILLCH ; ^P ILLEGAL
JRST RECCQ ; ^Q XON TURN OFF TAPE MODE,
; ILLEGAL
JRST ILLCH ; ^R ILLEGAL
JRST ILLCH ; ^S XOFF ILLEGAL
JRST ILLCH ; ^T ILLEGAL
JRST ILLCH ; ^U ILLEGAL
JRST ILLCH ; ^V ILLEGAL
JRST ILLCH ; ^W ILLEGAL
PUSHJ P,NXTPOS ; ^X CURSOR RIGHT RIGHT IF NOT AT
; RIGHT MARGIN
PUSHJ P,CURLFT ; ^Y CURSOR LEFT LEFT IF NOT AT
; LEFT MARGIN
PUSHJ P,CURUP ; ^Z CURSOR UP UP IF NOT AT TOP LINE
JRST RESC ; ^[ ESC ENTER TRANSACTION
JRST ILLCH ; ^\ HOME DOWN ILLEGAL
SETZB H,V ; ^] HOME UP GO TO TOP LEFT
PUSHJ P,REOL ; ^^ ERASE EOL ERASE TO END OF LINE
PUSHJ P,REOF ; ^_ ERASE EOF ERASE TO END OF SCREEN
;HERE ON RECEIPT OF LINE FEED
LINFD: CAIGE V,SCRLIN-1 ;ARE WE ON LAST LINE OF SCREEN?
AOJA V,CPOPJ ;IF NOT, COUNT V AND RETURN
; ELSE FALL INTO SCROLL
;SUBROUINE TO SIMULATE SCROLLING.
;LINES 2 THROUGH M REPLACE 1 THROUGH M-1 AND LINE M
; IS BLANKED.
LINWDS==SCRCOL/6 ;WORDS PER LINE
IFN <SCRCOL-<6*LINWDS>>,
<PRINTX NUMBER OF COLUMNS IS NOT A MULTIPLE OF 6>
SCROLL: MOVE T,[XWD SCREEN+LINWDS, SCREEN] ;BLT DOWN ONE LINE
BLT T,SCREEN+SCRWDS-LINWDS-1
SETZM SCREEN+SCRWDS-LINWDS ;BLANK LAST LINE
MOVE T,[XWD SCREEN+SCRWDS-LINWDS,SCREEN+SCRWDS-LINWDS+1]
BLT T,SCREEN+SCRWDS-1
POPJ P, ;RETURN
;HERE ON RECEIPT OF CURSOR DOWN
CURDWN: CAIGE V,SCRLIN-1 ;ARE WE ON BOTTOM LINE?
ADDI V,1 ;IF NOT, ADD 1 TO V
POPJ P, ;RETURN
;HERE ON RECEIPT OF CURSOR UP
CURUP: JUMPE V,CPOPJ ;RETURN IF ON TOP LINE
SOJA V,CPOPJ ; ELSE SUBTRACT ONE FROM V
; AND RETURN
;HERE ON RECEIPT OF CURSOR LEFT
CURLFT: JUMPE H,CPOPJ ;RETURN IF AT LEFT MARGIN
SOJA H,CPOPJ ; ELSE SUBTRACT 1 FROM H
; AND RETURN
;HERE ON RECEPT OF XON (CONTROL Q)
RECCQ: PUSHJ P,OFFCQ ;TURN OFF SCNSER PAPER TAPE MODE
JRST ILLCH ; AND HANDLE AS ILLEGAL CHAR
;HERE ON RECEIPT OF A ^O OR ^C CHARACTER
RECCO: PUSHJ P,TTYINI ;TURN OFF CONTROL O MODE
;FALL INTO ILLCH
;HERE ON RECEIPT OF AN ILLEGAL INPUT CHARACTER.
;RING BELL AND REWRITE USER'S SCREEN.
ILLCH: MOVEI T,7 ;BEL
PUSHJ P,VTOUTC ;SEND IT
JRST REWRIT ;REWRITE SCREEN FROM CORE
;HERE ON RECEIPT OF AN ERASE END OF LINE (EOL) CHARACTER
REOL: PUSHJ P,MAKPTR ;MAKE BYTE POINTER
MOVEI A,0 ;GET SIXBIT BLANK
DPB A,B ;STORE IT AT CURRENT POSITION
HRREI T,-<SCRCOL-1>(H) ; T = H - (SCRCOL-1)
AOJG T,CPOPJ ;COUNT ONE JUST CLEARED,
; RETURN IF DONE
;LOOP HERE TO CLEAR CHARACTERS IN LINE IMAGE
REOL1: IDPB A,B ;CLEAR NEXT ONE
AOJLE T,REOL1 ;COUNT. LOOP IF MORE
POPJ P, ; ELSE RETURN
;HERE ON ERASE EOF CHARACTER
REOF: PUSHJ P,MAKPTR ;GET BYTE POINTER TO CURRENT POS
MOVEI A,0 ;GET A SIXBIT BLANK
;LOOP HERE CHECKING FOR BYTE POINTER AT 1ST BYTE OF A WORD
REOF1: TLC B,360000 ;TEST POSITION FIELD FOR 36
TLCN B,360000
JRST REOF2 ;IF 36, DONE
DPB A,B ; ELSE BLANK THIS ONE
IBP B ;GO TO NEXT BYTE
JRST REOF1 ;AND LOOP
;HERE WHEN ANY PARTIAL WORD HAS BEEN BLANKED
REOF2: HRRZ B,B ;GET ADDRESS OF 1ST FULL WORD
; TO BLANK
CAIGE B,SCREEN+SCRWDS ;BEYOND END ALREADY?
SETZM (B) ;IF NOT, ZERO 1ST WORD LEFT
CAIL B,SCREEN+SCRWDS-1 ;MORE THAN 1 WORD TO ZERO?
POPJ P, ;IF NOT, RETURN
HRLI B,1(B) ;ELSE BLT ZEROS TO REST
MOVS B,B
BLT B,SCREEN+SCRWDS-1
POPJ P, ;RETURN
SUBTTL SLAVE TRANSACTION PROCESSING
;HERE WHEN ESC RECIEVED.
;NOTE: CALLED BY JRST, NOT PUSHJ FOR CONDITIONAL RETURN.
RESC: TLNN F,(WINPF) ;WAS A PREVIOUS TRANSACTION HELD UP?
CAMN TT,SINFLG ; OR ARE WE ALREADY WAITING ON MASTER?
JRST ILLCH ;IF SO, ESC IS ILLEGAL
PUSHJ P,HOMEUP ;ACKNOWLEDGE OK RECEIPT WITH HOME UP
PUSHJ P,TRYINP ;TRY TO GET BUFFER RESOURCE
JRST RESC1 ;JUMP IF FAILED
MOVE T,[XWD SCREEN,SINBF] ;WON. COPY TO SHARED INPUT BUF
BLT T,SINBF+SCRWDS-1
SETOM AVLINP ;PASS THE BUFFER TO THE MASTER
MOVEM TT,SINFLG ;TELL MASTER OUR NUMBER
PUSHJ P,MWAKE ;WAKE MASTER
JRST SINPU1 ;GO BACK FOR MORE INPUT CHARACTERS
;HERE ON ESC WHEN NO PREVIOUS ENTRY FOR US, BUT BUFFER WAS BUSY
RESC1: MOVE T,[XWD SCREEN,HOLD] ;COPY SCREEN TO HOLD
BLT T,HOLD+SCRWDS-1
JRST SINPU1 ;GO BACK FOR MORE CHARACTERS
;HERE WHEN WE GOT SHARED INPUT BUFFER AFTER A WAIT
WON: MOVE T,[XWD HOLD,SINBF] ;COPY HOLD TO SHARED BUFFER
BLT T,SINBF+SCRWDS-1
SETOM AVLINP ;PASS THE BUFFER TO THE MASTER
MOVEM TT,SINFLG ;TELL MASTER OUR NUMBER
PUSHJ P,MWAKE ;WAKE MASTER
JRST SLOOP ;GO BACK TO SLAVE LOOP
SUBTTL SLAVE OUTPUT PROCESSING
;HERE WHEN AN OUTPUT REQUEST BY THE MASTER WAS SEEN BY SLAVE
OUTPRO: SKIPGE T,SOUMOD ;CHECK MODE OF OUTPUT REQUEST
JRST OUTPR2 ;-1 MEANS ERASE SCREEN
JUMPG T,OUTPR1 ;.GT. 0 MEANS LINE MODE
;ZERO MEANS WHOLE SCREEN
;HERE TO PROCESS WRITE SCREEN CALL
PUSHJ P,CPYSCR ;COPY SOUTBF TO SCREEN
PUSHJ P,OUTWAK ;FREE SHARED OUTPUT BUFFER & WAKE MASTER
;HERE ALSO ON INPUT TO REWRITE ENTIRE SCREEN
REWRIT: PUSHJ P,HOMEUP ;HOME UP CURSOR
PUSHJ P,DUMP ;DUMP SCREEN BUFFER TO VT05 TERMINAL
JRST OUTPR3 ;DO FINAL STUFF
;HERE ON WRLIN CALL
OUTPR1: PUSHJ P,CPYLIN ;COPY 1 LINE TO SCREEN
PUSHJ P,OUTWAK ;FREE SHARED OUTPUT BUFFER & WAKE MASTER
PUSHJ P,HOME ;HOME UP CURSOR, BUT SAVE V
PUSHJ P,LINDMP ;DUMP LINE V TO VT05
JRST OUTPR3 ;DO FINAL STUFF
;HERE TO PROCESS ERSCR CALL.
OUTPR2: PUSHJ P,OUTWAK ;FREE SHARED OUTPUT BUFFER & WAKE MASTER
PUSHJ P,HOMEUP ;HOME UP
PUSHJ P,EREOF ;CLEAR SCREEN
PUSHJ P,BLANK ;CLEAR SCREEN IMAGE IN CORE
;HERE ON ALL OUTPUT CALLS TO FINISH UP
;HERE ALSO ON COMPLETION OF REWRITING SCREEN ON INPUT
OUTPR3: PUSHJ P,FLUSH ;FLUSH INPUT STREAM TYPE-AHEADS
PUSHJ P,HOMEUP ;GIVE CURSOR BACK TO USER AT TOP
JRST SLOOP ;GO TO SLAVE'S MAIN LOOP
SUBTTL MISCELANEOUS SLAVE ROUTINES TO UPDATE SCREEN IMAGE
;SUBROUTINE TO COPY 1ST LINE IN SOUTBF TO SCREEN
;THE LINE NUMBER (1 ORIGIN) IS IN T
CPYLIN: MOVEI V,-1(T) ;GET V (0 ORIGIN)
MOVEI H,0 ;START OF LINE
MOVE D,[POINT 6,SOUTBF] ;SET UP POINTER TO SHARED
; OUTPUT BUFFER
MOVEI C,SCRCOL-1 ;SET UP COUNT
ILDB A,D ;DO 1ST MOVE AS SPECIAL CASE
PUSHJ P,OUTC6 ;STOW IT AND FORM BYTE POINTER
;LOOP HERE TO COPY 2ND THROUGH LAST CHARACTER OF LINE
CPYLI1: ILDB A,D ;GET CHARACTER FROM SOUTBF
IDPB A,B ;STOW CHAR IN SCREEN
SOJG C,CPYLI1 ;COUNT AND LOOP UNTIL DONE
POPJ P, ;RETURN
;SUBROUTINE TO COPY ALL OF SOUTBF TO SCREEN
CPYSCR: MOVE T,[XWD SOUTBF,SCREEN] ;FORM BLT POINTER
BLT T,SCREEN+SCRWDS-1 ;COPY IT
POPJ P, ;RETURN
;SUBROUTINE TO PUT AN ASCII CHARACTER IN A INTO BUFFER THEN
;ADVANCE TO NEXT POSITION, THEREBY SIMULATING ACTION OF VT05.
OUTC: CAIL A,140 ;MAKE IT UPPER CASE
SUBI A,40
SUBI A,40 ;MAKE IT SIXBIT
;FALL INTO OUTC6
;SUBROUTINE TO PUT A SIXBIT CHARACTER IN A INTO BUFFER THEN
;ADVANCE TO NEXT POSITION, THEREBY SIMULATING ACTION OF VT05.
OUTC6: PUSHJ P,MAKPTR ;GET A BYTE POINTER BASED ON H AND V
DPB A,B ;STORE CHARACTER
;FALL INTO NXTPOS
;SUBROUTINE TO ADVANCE CURSOR COUNTERS TO NEXT CHARACTER OF A LINE
NXTPOS: CAIGE H,SCRCOL-1 ;AT END OF LINE?
ADDI H,1 ;IF NOT, GO TO NEXT COLUMN
POPJ P, ;RETURN
;SUBROUTINE TO FORM A 6 BIT ILDB BYTE POINTER TO START OF LINE V.
LINPTR: SETOM H ;SET H = -1 SO ILDB GETS 1ST CHAR
;FALL INTO MAKPTR
;SUBROUTINE TO FORM A 6 BIT BYTE POINTER TO SCREEN (H,V)
MAKPTR: MOVE T,V ;COMPUTE T = V*SCRCOL + H + 6
IMULI T,SCRCOL
ADDI T,6(H) ;ADD 6 IN TO ENSURE T POSITIVE
IDIVI T,6 ;DIVIDE T BY 6 TO GET WORD, POSITION
MOVE B,PTRTAB(T1) ;GET APPROPRIATE POINTER WORD
ADD B,T ;ADD IN WORD OFFSET
POPJ P, ;RETURN
;TABLE OF BYTE POINTERS TO SCREEN BASED ON POSITION OF BYTE IN A WORD
JJ==5
PTRTAB: REPEAT 6, < POINT 6,SCREEN-1,JJ
JJ==JJ+6 >
;SUBROUTINE TO BLANK SCREEN BUFFER AND RESET CURSOR COUNTERS
BLANK: SETZM SCREEN ;ZERO SCREEN
MOVE T,[XWD SCREEN,SCREEN+1]
BLT T,SCREEN+SCRWDS-1
SETZB H,V ;RESET CURSOR COUNTER
POPJ P, ;RETURN
SUBTTL VT05 I/O ROUTINES
;SUBROUTINE TO INITIALIZE STATE OF THE TERMINAL
;CALLED ON START UP AND UPON RECEIPT OF ^O
;THIS CODE INITS TTY, TURNS OFF ^O AND CLEARS INPUT BUFFER
TTYINI: MOVE T,SAVFF ;RESTORE JOBFF TO REUSE BUFFERS
MOVEM T,JOBFF
INIT VTCHN,SPECLM ;INIT TERMINAL IN F.C.S. TRUE ECHO MODE
SIXBIT /VTTERM/
XWD VTOBF,VTIBF
JRST TTYIN1 ;INIT FAILED
PUSHJ P,TTYNO ;GET AND SAVE MONITOR TTY NO.
INBUF VTCHN,2 ;SET UP BUFFERS
OUTBUF VTCHN,2
PUSHJ P,FILL1 ;SEND A FILL TO TURN OFF ^O
PUSHJ P,VTOUTC ;FORCE IT OUT
;FALL INTO FLUSH
;SUBROUTINE TO FLUSH TERMINAL INPUT BUFFER OF ANY CHARACTERS
;NOT READ YET.
;CALLED INITIALLY AND WHEN NECESSARY TO SYNCHRONIZE TYPE-AHEAD.
;*** TEMPORARILY THE TERMINAL MUST BE THE CONTROLLING TTY ***
;*** CHANGE THIS WHEN SCNSER FIXED ***
FLUSH: CLRBFI ;CLEAR CONTROLLING TTY AND HOPE ITS THE ONE
POPJ P, ;RETURN
;HERE WHEN INIT OF DEVICE VTTERM FAILED.
TTYIN1: OUTSTR [ASCIZ /? NO DEVICE VTTERM/ ] ;TELL OPER HE LOST
EXIT ;RETURN TO MONITOR
;SUBROUTINE TO TURN OFF PAPER TAPE MODE
;CALLED WHEN ^Q RECEIVED
;*** TEMPORARILY THE TERMINAL MUST BE THE CONTROLLING TTY ***
;*** CHANGE THIS WHEN SCNSER FIXED ***
OFFCQ: MOVE A,TTYNUM ;MONITOR TTY NO
GETLCH A ;GET CURRENT CHARACTERISTICS
TLZ A,(CQBIT) ;TURN OFF ^Q BIT IN A
SETLCH A ;SET THE CHARACTERISTICS
POPJ P, ;RETURN
;SUBROUTINE TO CHECK IF THERE IS DATA TO INPUT FROM THE VT05.
;THE CHECK IS MADE IN LINE MODE.
;CALL PUSHJ P,CHKINP
; RETURN IF INPUT
; RETURN IF NO INPUT
CHKINP: MOVE A,TTYNUM ;MONITOR TTY NUMBER OF VT05
GETLCH A ;GET LINE CHARACTERISTICS
TLNN A,(LINBIT) ;HAS A LINE BEEN TYPED?
AOS (P) ;NO, SET UP SKIP
POPJ P, ;RETURN
;SUBROUTINE TO GET THE MONITOR TTY NUMBER OF VT05 TERMINAL
; AND STORE IT IN TTYNUM.
;THIS ROUTINE ALSO LEAVES THE PHYSICAL DEVICE NAME IN D.
;THIS KLUDGERY WILL DISAPPEAR IF SCNSER BECOMES REASONABLE
TTYNO: MOVEI D,VTCHN ;SOFTWARE CHANNEL
DEVNAM D, ;MAP IT TO PHYSICAL DEVICE NAME
HALT . ;DEVNAM FAILED
CAMN D,[SIXBIT /CTY/] ;IS IT THE CTY?
JRST TTYNO3 ;IF CTY, DO SPECIAL CASE
MOVE B,[POINT 6,D,17] ;NO, GET BYTE POINTER TO XXX
MOVEI C,3 ;SET LOOP COUNT = 3 CHARACTERS
MOVEI A,0 ;CLEAR ACCUMULATOR
;LOOP HERE TO CONVERT "TTYXXX" FROM SIXBIT OCTAL TO A BINARY NUMBER
TTYNO1: ILDB T,B ;GET NEXT SIXBIT OCTAL DIGIT
CAIL T,"0"-40 ;CHECK IT
CAILE T,"7"-40
JRST TTYNO2 ;IF NOT A DIGIT, RETURN
LSH A,3 ;IF A DIGIT, MULTIPLY BY 8
ADDI A,-<"0"-40>(T) ;ADD IN DIGIT
SOJG C,TTYNO1 ;LOOP UNLESS SEEN 3
;(BACK) HERE TO STORE TTYNUM AND RETURN
TTYNO2: MOVEM A,TTYNUM ;STORE TTYNUM
POPJ P, ;RETURN
;HERE FOR SPECIAL CASE OF CTY
TTYNO3: MOVE A,[XWD PTYCNF,CNFTBL] ;GETTAB ARGUMENTS
GETTAB A, ;GET MONITOR PTY DATA
HALT . ;GETTAB FAILED
HLRZ A,A ;LEFT HALF IS NUMBER OF FIRST PTY
SOJA A,TTYNO2 ;RETURN 1 LESS AS CTY LINE NUMBER
;MACRO FOR STANDARD SINGLE CHARACTER BUFFERED MODE OUTPUT
;AN OPEN SUBROUTINE IS USED WHERE USEFUL TO SAVE CPU
;TIME IN DUMP ROUTINE.
DEFINE VTOUTM (AC),
< SOSG VTOBF+2 ;COUNT BUFFER. SPACE?
PUSHJ P,VOUTUU ;IF NEED MORE SPACE
IDPB AC,VTOBF+1 ;STOW CHARACTER >
;SUBROUTINE TO OUTPUT CARRIAGE RETURN, LINE FEED TO VT05
CRLF: MOVEI T,15 ;CR
PUSHJ P,VTOUTC ;SEND IT
;FALL INTO LF
;SUBROUTINE TO OUTPUT LINE FEED TO VT05.
LF: MOVEI T,12 ;LF
;FALL INTO VTOUTC
;SUBROUTINE TO OUTPUT A CHARACTER FROM ACCUMULATOR T TO VT05
VTOUTC: VTOUTM T, ;DO THE STANDARD STUFF
POPJ P, ;RETURN
;SUBROUTINE TO HOME UP CURSOR AND RESET OUR CURSOR COUNTERS.
HOMEUP: SETZB H,V ;RESET OUR CURSOR COUNTERS
;FALL INTO HOME
;SUBROUTINE TO POSITION VT05 TO HOME.
HOME: MOVEI T,CH.HOM ;GET A HOME-UP CHARACTER
PUSHJ P,VTOUTC ;OUTPUT IT
;FALL INTO VOUTUU TO FORCE IT OUT
;SUBROUTINE TO DO AN OUTPUT UUO TO VT05
VOUTUU: OUT VTCHN, ;OUT UUO
POPJ P, ;RETURN IF OK
HALT . ;OUT UUO FAILED
;SUBROUTINE TO ERASE REST OF SCREEN (EOF)
EREOF: MOVEI T,CH.EOF ;PICK UP ERASE EOF CHARACTER
JRST EREOX ;GO SEND IT
;SUBROUTINE TO ERASE REST OF LINE (EOL)
EREOL: MOVEI T,CH.EOL ;PICK UP ERASE EOL CHARACTER
;HERE ON BOTH EREOF AND EREOL
EREOX: PUSHJ P,VTOUTC ;OUTPUT CHARACTER
;FALL INTO FILL 4
;SUBROUTINES TO OUTPUT 4, 2, OR 1 FILLER CHARACTERS
FILL4: PUSHJ P,FILL2 ;CALL FILL2, THEN FALL INTO FILL2
FILL2: PUSHJ P,FILL1 ;CALL FILL1 THEN FALL INTO FILL1
FILL1: MOVEI T,CH.FILL ;PICK UP A FILLER CHARACTER
PJRST VTOUTC ;SEND IT AND RETURN
;SUBROUTINE TO DUMP THE CONTENTS OF SCREEN TO THE VT05.
;CALLED WHEN CURSOR IS AT TOP LEFT.
;UPON RETURN, CURSOR POSITION IS UNDEFINED.
;THIS ROUTINE MINIMIZES I/O BY SUPPRESSING TRAILING BLANKS ON EACH
;LINE, AND BY SUPPRESSING ANY BLANK LINES AT THE
;BOTTOM OF THE SCREEN.
;THIS ROUTINE IS OPTIMIZED TO REDUCE CPU TIME.
DUMP: MOVEI LL,SCRLIN ;INITIALIZE COUNT OF LINES LEFT
MOVE B,[POINT 6,SCREEN] ;BYTE POINTER TO SCREEN
MOVEI D," " ;ASCII BLANK
MOVEI SL,0 ;CLEAR COUNT OF QUEUED BLANK LINES
;HERE WHEN PREVIOUS LINES (IF ANY) ARE PROCESSED.
;START PROCESSING NEW LINE.
DUMP1: MOVEI SC,0 ;CLEAR COUNT OF QUEUED SPACES
MOVEI CL,SCRCOL ;INITIALIZE COLUMNS LEFT TO PROCESS
;LOOP THROUGH HERE SCANNING FOR FIRST NON-BLANK CHARACTER.
DUMP2: ILDB A,B ;GET NEXT CHARACTER IN LINE
JUMPE A,DUMP9 ;QUEUE IT IF IT IS BLANK
;HERE WHEN FIRST NON-BLANK CHARACTER OF A LINE HAS BEEN FOUND
DUMP3: JUMPG SL,DUMP8 ;IF THERE ARE QUEUED BLANK LINES,
; EXPAND THEM
;HERE WHEN ALL PREVIOUSLY QUEUED BLANK LINES HAVE BEEN EXPANDED.
;LOOP THROUGH HERE ON EACH NON-BLANK CHARACTER OF A LINE.
DUMP4: JUMPG SC,DUMP10 ;IF THERE ARE QUEUED BLANKS,
; EXPAND ONE
;HERE WHEN NO BLANKS ARE QUEUED AND THERE IS A NON-BLANK CHARACTER
DUMP5: ADDI A,40 ;CONVERT FROM SIXBIT TO ASCII
VTOUTM A, ;SEND IT TO THE VT05
;LOOP HERE TO SCAN NEXT CHARACTER IN A LINE
DUMP6: SOJLE CL,DUMP11 ;COUNT LAST CHAR JUST DONE.
; JUMP IF LINE IS DONE
ILDB A,B ;GET NEXT CHARACTER IN THE LINE
JUMPN A,DUMP4 ;IF NOT BLANK, LOOP BACK TO PROCESS IT
AOJA SC,DUMP6 ;IF BLANK, QUEUE IT AND SCAN NEXT CHAR
;HERE WHEN FIRST NON-BLANK CHARACTER OF A LINE WAS FOUND AND
; PREVIOUSLY BLANK LINES WERE QUEUED.
;THIS CODE EXPANDS ONE OF THOSE QUEUED LINES.
DUMP8: PUSHJ P,EREOL ;ERASE EOL
PUSHJ P,CRLF ;OUTPUT CR LF
SOJA SL,DUMP3 ;GO BACK FOR NEXT
;HERE WHEN A LEADING BLANK WAS FOUND IN SCANNING A LINE
DUMP9: ADDI SC,1 ;QUEUE THE BLANK
SOJG CL,DUMP2 ;COUNT AND LOOP FOR NEXT ONE,
; IF NOT AT END OF LINE
ADDI SL,1 ;END OF LINE. ALL BLANKS. QUEUE LINE.
SOJG LL,DUMP1 ;COUNT LINES LEFT AND GO BACK IF MORE
PJRST EREOF ; ELSE DONE. ERASE REST OF SCREEN
;HERE WHEN A NON-BLANK CHARACTER WAS FOUND
; AND THERE ARE SPACES TO EXPAND.
DUMP10: VTOUTM D, ;OUTPUT ONE BLANK
SOJA SC,DUMP4 ;DEQUEUE IT AND GO BACK FOR NEXT ONE
;HERE WHEN COMPLETE NON-BLANK LINE HAS BEEN SCANNED
DUMP11: JUMPE SC,DUMP12 ;TEST FOR QUEUED (TRAILING) BLANKS
PUSHJ P,EREOL ;IF SO, ERASE END OF LINE
;HERE WHEN A COMPLETE NON-BLANK LINE HAS BEEN PROCESSED,
DUMP12: SOJLE LL,DUMP13 ;COUNT LINES DONE. JUMP IF FINISHED.
PUSHJ P,CRLF ;NOT DONE YET. OUTPUT CRLF.
JRST DUMP1 ;AND GO SCAN NEXT LINE
;HERE WHEN ALL LINES HAVE BEEN PROCESSED
DUMP13: JUMPE SL,CPOPJ ;IF NO QUEUED BLANK LINES, RETURN
PJRST EREOF ; ELSE ERASE EOF AND RETURN
;SUBROUTINE TO POSITION THE CURSOR TO LINE V AND DUMP LINE V TO VT05.
;CALLED WHEN CURSOR IS AT TOP LEFT. UPON RETURN, CURSOR IS UNDEFINED.
;TRAILING BLANKS ARE SUPPRESSED TO SAVE I/O TIME.
LINDMP: SKIPE CL,V ;GET COUNT OF LINES TO SKIP. IS IT 0?
;LOOP HERE OUTPUTTING LINE FEEDS TO GET CURSOR TO LINE V.
LINDM1: PUSHJ P,LF ;SEND A LINE FEED (IF V NON-ZERO)
SOJG CL,LINDM1 ;COUNT IT, AND LOOP IF MORE NEEDED
;HERE WHEN CURSOR POSITIONED TO START OF LINE V.
PUSHJ P,LINPTR ;GET ILDB POINTER TO START OF LINE V
MOVEI D," " ;PICK UP AN ASCII BLANK
MOVEI SC,0 ;CLEAR COUNT OF QUEUED LINES.
MOVEI CL,SCRCOL ;INITIALIZE COUNT OF CHARS LEFT
;LOOP HERE SCANNING EACH CHARACTER IN LINE V.
LINDM2: ILDB T,B ;GET NEXT CHARACTER
JUMPE T,LINDM5 ;IF BLANK, GO QUEUE IT
;(LOOP) HERE WHEN A NON-BLANK CHARACTER SEEN.
LINDM3: JUMPG SC,LINDM6 ;IF ANY QUEUED BLANKS, UNWIND ONE
;HERE WHEN NON-BLANK CHARACTER SEEN AND NO QUEUED BLANKS ARE LEFT.
ADDI T,40 ;CONVERT SIXBIT TO ASCII
PUSHJ P,VTOUTC ;SEND THE CHARACTER
;HERE WHEN A CHARACTER HAS BEEN PROCESSED.
LINDM4: SOJG CL,LINDM2 ;IF MORE, GO DO THEM
JUMPE SC,CPOPJ ;IF NO QUEUED BLANKS, JUST RETURN
PJRST EREOL ; ELSE ERASE END OF LINE AND RETURN
;HERE WHEN A BLANK WAS SEEN.
LINDM5: AOJA SC,LINDM4 ;QUEUE IT AND GO ON
;HERE WHEN A NON-BLANK CHARACTER WAS SEEN AND THERE ARE QUEUED BLANKS.
LINDM6: VTOUTM D, ;SEND A BLANK
SOJA SC,LINDM3 ;COUNT IT DOWN, AND SEE IF MORE LEFT
SUBTTL SYNCRONIZATION AND QUEUING
;SUBROUTINES TO SYNCHRONIZE CRITICAL (SHORT) NON-REENTRANT SECTIONS.
;THESE ROUTINES MAY BE CALLED BY ANY JOB SHARING THE HIGH-SEGMENT.
;THE INTENTION IS TO USE THESE ROUTINES TO INTERLOCK ONLY A FEW
;INSTRUCTIONS OF A HIGHER LEVEL QUEUEING SYSTEM, IN MUCH THE MANNER
;THE MONITOR OCCASIONALLY USES CONO PI,PIOFF.
;THE QUEUING DISCIPLINE DEPENDS ONLY ON JOB NUMBER.
;IF THERE IS A CONFLICT THE LOSER(S) ARE BLOCKED, AND AWOKEN
;ACCORDING TO THE ABOVE DISCIPLINE.
;CAUTION: THIS CODE FAILS ON MULTI-PROCESSOR SYSTEMS USING DRUM-SPLIT!
;SUBROUTINE TO GET Q RESOURCE, WAITING IF NECESSARY.
GETQ: MOVE T,QMASK ;SET OUR REQUEST BIT
IORM T,@QWORD
AOSN QREQ ;TRY AND GRAB THE INTERLOCK
ANDCAM T,@QWORD ;WON, SO CLEAR REQUEST BIT
;LOOP THRU HERE WHILE WAITING FOR Q RESOURCE
GETQ1: TDNN T,@QWORD ;HAS OUR REQUEST BIT BEEN CLEARED?
POPJ P, ;YES, RETURN
PUSHJ P,HIBERN ;NO, WAIT UNTIL AWOKEN
JRST SRESTA ;ON A RESTART GO START OVER
JRST GETQ1 ;OK, CHECK FOR SPURIOUS WAKES
;SUBROUTINE TO RELEASE Q RESOURCE, WAKING UP A WAITER, IF THERE IS ONE.
RELQ: SOSGE QREQ ;COUNT DOWN USE INTERLOCK
POPJ P, ;-1 MEANS NO WAITERS, RETURN
MOVEI C,3 ;SET TO SCAN ALL QBITS WORDS
;LOOP THRU HERE TO SCAN QBITS LOOKING FOR A 1 BIT
RELQ1: SKIPE T,QBITS(C) ;SEE IF WORD IS ZERO
JFFO T,RELQ2 ;NO, SO FIND FIRST ONE BIT
SOJGE C,RELQ1 ;YES, TRY NEXT WORD UNLESS LAST
HALT . ;SHOULD NEVER HAPPEN
;HERE WHEN A WAITER HAS BEEN FOUND.
RELQ2: MOVN T1,T1 ;CLEAR HIS REQUEST BIT
MOVSI T,400000
LSH T,(T1)
ANDCAM T,QBITS(C)
IMULI C,^D36 ;GET HIS JOB NUMBER
SUB C,T1
WAKE C, ;AWAKEN HIM
HALT . ;WAKE SHOULD NEVER FAIL
POPJ P, ;RETURN
;SUBROUTINE TO TRY FOR INPUT BUFFER RESOURCE.
;NON-SKIP RETURN IF BUSY, WITH WINPF SET.
;SKIP RETURN IF ASSIGNED, WITH WINPF CLEARED.
;IF WINPF WAS SET WHEN CALLED, THIS ROUTINE ASSUMES REQUEST ALREADY
;WAS QUEUED UP AND MERELY CHECKS FOR SATISFACTION.
TRYINP: TLNE F,(WINPF) ;IS THIS THE FIRST TRY?
JRST TRYIN1 ;NO, SO SKIP MAKING QUEUE ENTRY
PUSHJ P,GETQ ;YES. SYNCHRONIZE
MOVE T1,QJOBN ;GET OUR JOB NUMBER
SKIPE T,AVLINP ;IS INPUT BUFFER FREE
CAMN T,T1 ; OR ASSIGNED TO ME?
JRST TRYIN3 ;YES
IDPB T1,QININP ;NO, ENTER QUEUE
MOVE T,QSTINP ;SET QININP TO START IF AT END
MOVE T1,QFNINP
CAMN T1,QININP
MOVEM T,QININP
PUSHJ P,RELQ ;END OF CRITICAL SECTION
JRST TRYIN2 ;SET WAIT FLAG AND GIVE LOSE RETURN
;HERE WHEN TRIED BEFORE AND LOST
TRYIN1: MOVE T,QJOBN ;IS INPUT BUFFER MINE YET?
CAMN T,AVLINP
JRST TRYIN4 ;YES, WIN
;HERE TO SET WAITING FLAG AND GIVE LOSE (NON-SKIP) RETURN
TRYIN2: TLO F,(WINPF) ;SET WAITING FLAG
POPJ P, ;RETURN
;HERE ON SUCCESSFUL FIRST TRY TO RESERVE THE RESOURCE
TRYIN3: MOVEM T1,AVLINP ;ASSIGN INPUT BUFFER RESOURCE TO ME
PUSHJ P,RELQ ;END OF CRITICAL SECTION
;HERE WHEN RESOURCE SUCCESFULLY OBTAINED
TRYIN4: TLZ F,(WINPF) ;CLEAR WAITING FLAG
JRST CPOPJ1 ;SKIP RETURN
;SUBROUTINE TO INITIALIZE EACH JOB'S QUEUE DATA
UQINIT: PJOB T, ;GET JOB NUMBER
MOVEM T,QJOBN ;SAVE IT
WAKE T, ;WAKE OURSELF UP
HALT . ;WAKE SHOULD NEVER FAIL
IDIVI T,^D36 ;GET WORD AND BIT FOR THIS NUMBER
ADDI T,QBITS
MOVEM T,QWORD ;SAVE WORD ADDRESS
MOVN T1,T1
MOVSI T,400000
LSH T,(T1)
MOVEM T,QMASK ;BIT MASK
ANDCAM T,@QWORD ;CLEAR JOB'S REQUEST BIT
TLZ F,(WINPF) ;CLEAR FLAGS
MOVSI W,(WAKPRJ!WAKLN) ;SET UP HIBERNATE WAKE ENABLES
HIBER W, ;WAKE UP SAME PROJECT OR TTY LINE MODE
HALT . ;HIBER UUO FAILED
POPJ P, ;RETURN
;SUBROUTINE TO HIBERNATE UNTIL AWOKEN.
;ACCUMULATOR W MUST BE SET UP WITH ENABLE MASK.
;CALL PUSHJ P,HIBERN
; ERROR RETURN
; NORMAL RETURN
;THE NORMAL RETURN IS TAKEN UNLESS A VTCLSE IS PENDING.
HIBERN: SKIPG STTIME ;IS A CLOSE PENDING?
POPJ P, ;IF SO, NO-SKIP RETURN
HIBER W, ;HIBERNATE
HALT . ;HIBER UUO FAILED
SKIPLE STTIME ;CHECK AGAIN FOR A CLOSE
AOS (P) ;SET UP SKIP RETURN IF NO CLOSE PENDING
POPJ P, ;RETURN
;SUBROUTINE TO FREE SHARED OUTPUT BUFFER AND WAKE MASTER JOB.
OUTWAK: SETZM SOUTRM ;FREE SHARED OUTPUT BUFFER
;FALL INTO MWAKE
;SUBROUTINE TO AWAKEN MASTER JOB
;CALLED BY SLAVE WHENEVER SERVICE IS NEEDED FROM THE MASTER.
;NOTE, MWAKE MUST BE CALLED AFTER THE COMMAND TO THE MASTER HAS BEEN
; SET UP.
MWAKE: MOVE T,MJOBN ;MASTER JOB NUMBER
WAKE T,
JFCL ;IGNORE FAILURE. MASTER MAY BE GONE
POPJ P, ;RETURN
SUBTTL COMMON SUBROUTINE RETURNS
CPOPJ1: AOSA (P) ;SKIP RETURN
TPOPJ: POP P,T ;RESTORE T AND RETURN
CPOPJ: POPJ P, ;RETURN
LIT
END SGO