.TITLE SPOL11.145 .SBTTL COPYRIGHT ; ;COPYRIGHT (C) 1975 ;DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ;THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ;ON A SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY WITH ;THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS ;SOFTWARE, OR ANY OTHER COPIES THEREOF, MAY NOT BE PRO- ;VIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON ;EXCEPT FOR USE ON SUCH SYSTEM AND TO ONE WHO AGREES TO ;THESE LICENSE TERMS. TITLE TO AND OWNERSHIP OF THE ;SOFTWARE SHALL AT ALL TIMES REMAIN IN DEC. ; ;THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO CHANGE ;WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A COM- ;MITMENT BY DIGITAL EQUIPMENT CORPORATION. ; ;DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY ;OF ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC. ; ; ; .SBTTL LEGEND ; EDIT=145. ; #085 SK UPDATE TO PERMIT RESTART AFTER "RESTORE# ; 086 SR TAKE OUT CD CONDITIONAL ; 087 SR EQUATE FOR ACCURATE SPOOLER SIZE ; 088 SK 16-OCT-73 FLUSH BUG FIX-WAIT FOR OUTPUT ; TASK TO BE IDLE BEFORE SETTING SWITCHES ; POINTERS ; 089 SR CLEANUP ; 090 SK 17-OCT-73 BUG FIX IN END-GET FA FROM TCB ; RATHER THAN COMPUTE IT TO PREVENT ; ODD/EVEN BYTE PROBLEM ; 092 SK 3-DEC-73 GENERAL FIX UP ; 093 SK 10-DEC-73 CHANGE @SEND11 TCB FORMAT. SEND TASK CODEE ; # OF THE TASK TO RETURN CONTROL TO IN WORD0 ; 094 SK 17-DEC-73 B-E-B-E-B-E BUG FIX. STORE FA SENT IN BEGIN ; TCB IN TCBDIS ; 095 SK 10-JAN-74 REMOVE HALT FROM GETBUF/GETRKT/XXCALL & ; XXINT ROUTINES. FOR GETBUF & GETRKT REPLACE ; BY WAIT. ; 096 SK 11-JAN-74 CDINT: EOD CARD/BUFFER FULL CONFLICT BUG FIX ; PROTECT FINDBK,GETBUF,GETRKT ROUTINES ; 097 SCR 1-FEB-74 REDUCE TO LP,PL, 8 BUFF'S FOR FIELD ; 098 SK 14-FEB-74 CD MULTIPLE DECK BUG FIX ; 099 SK 18-FEB-74 CD EMPTY BUG FIX ; 100 SK 21-FEB-74 E. 099 CLEANUP ; 101 SK 25-FEB-74 E. 101 CLEANUP ; 102 SK 26-FEB-74 E. 101 CLEANUP ; 103 SK 28-FEB-74 SPOOLER FULL PROBLEM FIX ATTEMPT ; + DISK FAILURE HANDLING (IOPS 20) ; 104 SK 1-MAR-74 REFINE DISK FAILURE ERROR REPORT ; 115 26-JUN-74 DE-IMPLEMENT ALL EXCEPT BEGIN AND END ; PRINT BLOCK NUMBER + ADD ERROR REPORT ; FOR REV SETTING OF NOT EQUAL TO "1" ; 116-119........... ; BR,SK,SR......... ; 8-JUL-74 FIXED 2 END-OF-SPOOLER BUGS ; FIXED ERROR 400 TO OCCUR ONLY ON ; REAL ERROR ; FIXED EXTRA RKTCDS TO BE CREATED ; WITH EXTRA BUFFERS FOR THREE DEVICES ; 120 BR 9-JUL-74 CHANGED CDCALL LOCKOUT PRIORITY ; FROM 6 TO 5 ; FIXED BAD FIX ON ERROR 400 BUG ; 121 SK 10-JUL-74 FIX PDP-15 CTL 'C'/IOPSUC 15 PROBLEM ; 122 SK 14-JUL-74 CLEANUP+FIX 2 CONSECUTIVE .CLOSE PROBLEM ; 123 SK 31-JUL-74 FIX .CLOSE PL PROBLEM. ; 124 SK 1-AUG-74 FIX MULTIPLE SEQUENTIAL EOF PROBLEM ; 125 SK 2-AUG-74 EDIT #124 CLEANUP ; IN LP & PL ; 126 BR 11-DEC-74 REMOVE MAP/TABLE SAVE JUNK ; 127 BR 12-DEC-74 ADD SPOOLER SIZE TO FRONT ; 128 BR 16-DEC-74 ADD STARTING OFFSET TO WORD 1 ; 129 BR 22-DEC-74 FIX COND. ASM PARAM TO DELETE LISTING ; ADD UNIT SELECTION FEATURE ; 130 BR/SK 23-31 DEC FIX CTL'C'.IOPSUC15 LP PROBLEMS ; 131 " " " ; 132 SK 2-JAN-75 EDIT 129,130,131 CLEANUP ; 133 SCR 2-JAN-75 SPEED FINDDISKBLOCK ROUTINE ; 135 SCR 2-JAN-75 MAKE FROM 133, CLEANUP ; 136,7 SCR 2-JAN-75 DEBUG FINDBK ROUTINE ; 138 BLR 6-JAN-75 DELAY END/FIXUP IOPSUC 20 ; 139 SCR 6-JAN-75 FIX:>1SPOOLER WAITING ON FULLDSK ; 140 BR 10-JAN-75 CLEAN UP OUT OF BLOCKS CONDITION. ; 141 GAR 20-JUN-75 FIX SO THAT THE SPOLLER DOESN'T ; CAUSE THE PDP-11 TO TRAP AT LOC. 10 ; WHEN THE SPOOLER IS TURNED OFF ; AND IS IMPROPERLY CONFIGURED. ; (CODE DONE BY BR.) ; 142 MJH 20-AUG-75 DISCLAIMER ; 143 03-OCT-75 (RCHM-SCR) FIX LP EOF. ; 144 08-OCT-75 (SCR) 1 DEV. BUFFERS TO 6; FIX 577 ERROR BYTE ; 145 BR 9-NOV-75 FIX EOF BUG ; ; SPOL11 ; ;THIS IS THE SPOOLER FOR THE UC15 SYSTEM. IT RUNS UNDER ;PIREX ON THE PDP-11. IT IS ALMOST ENTIRELY INDEPENDENT OF THE ;SOFTWARE ENVIORNMENT ON THE MASTER PROCESSOR(PDP-15). ;SPOL11 IS CURRENTLY CONTROLLED BY SPOL15 RUNNING UNDER ;DOS-15. THE FOLLOWING DIRECTIVES, WHICH CAN BE ISSUED TO ;SPOL11 PERFORM THE INDICATED FUNCTIONS: ; ; DIR. CODE. FUN. ; ; B:BEGIN 0 START SPOOLING OF I/O ; E:END 4 END SPOOLING ; ; ; A MAXIMUM OF 32(5BITS) DIRECTIVES & 8(3BITS) SUB_DIRECTIVES UNDER ; EACH DIRECTIVE IS POSSIBLE ; ;THE SPOOLER SUPPORTS THE FOLLOWING DEVICES: ; LP: LINE PRINTER ; CD: CARD READER ; LT: XY PLOTTER ; ; .SBTTL ASSEMBLY PARAMETERS ; ; CONDITIONAL ASSEMBLY, $LP, $CD, $PL, FOR LINEPRINTER ; FOR LP USE 40000 ; FOR PL USE 10000 ; FOR CD USE 20000 ; ; CARD READER, AND XY PLOTTER, RESPECTIVELY DEVSPP=0 DEVCNT=0 .IFDF $LP DEVCNT=DEVCNT+1 DEVSPP=DEVSPP!$LP .ENDC .IFDF $CD DEVCNT=DEVCNT+1 DEVSPP=DEVSPP!$CD .ENDC .IFDF $PL DEVCNT=DEVCNT+1 DEVSPP=DEVSPP!$PL .ENDC ; ; ; ; .SBTTL SYMBOLIC EQUATES .ENABL ABS .LIST ME ; ;GENERAL PURPOSE REGISTERS ; R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 R6=%6 R7=%7 PC=R7 SP=R6 PS=177776 SW=177570 AC=177302 MQ=177304 SC=177310 CKCREG=177546 ; ;INSTRUCTION MNEMONICS ; RETURN=207 ;RTS PC ; ;INDEX CONSTANTS ; ; ERROR BYTES FOR SPOOLER FOR SPECIFIC DEVICES ; LPSPER=4*6+5 ;4 IS LP DEV CODE CDSPER=5*6+5 PLSPER=6*6+5 ; SPOLSZ=SPEND-SPBEG/2 ;SPOOLER SIZE IN WORDS (EDIT #087) ; ; ; EQUATE FOR DIFFERENCE IN ADDR. IN TABLE FOR PL-LP PLTEOF=30 ;PL ENTRY IN TABLE CDTEOF=14 ;CD - TCODE=2 ;INDEX TO TASK CODE FCODE=6 ; - FUNCTION CODE SBN =10 ; - START BLOCK NUMBER NBK =12 ; - NUMBER OF SPOOL BLOCKS UNIT=16 ;UNIT TO SPOOL ON (BR-126) TCBDSA=12 ; - START ADDRESS DTCODE=26 ; - CALLING DEVICE TASK CODE TWD0=774 ; - TRAILER WORD 0 (WORD 376) IN BUFER TWD1=776 ; - 1 7 CBN=2 ;TABLE OFFSET FOR A TASK ENTRY CRP=4 NBN=6 LSB=10 LFB=12 ; ;POINTERS TO LOCATIONS IN PIREX ; MEMSIZ=40 ;11'S LOCAL MEMORY SIZE SEND11=1002 ;LOC. CONTAINING RETURN ADDRESS ON ;COMPLETION OF A REQUEST CURTSK=1004 ;CURRENT TASKS ATL POINTER POL.LH=1006 ;POOL LISTHEAD LISTHD=1010 ;BYSTEM LIST HEAD R.SAVE=1012 ;SAVE REG ROUTINE R.REST=1014 ;RESTORE REG ROUTINE DEQU=1022 ;DEQUE NEXT REQUEST ROUTINE MOVEN=1020 ;MOVE NODE ROUTINE SEND15=1024 ;SEND INT. TO 15 EMPTY=1026 ;EMPTY TASKS DEQUE ATLNP=1030 ;ATL NODE POINTER TABLE SPOLSW=1046 ;SPOOLER SWITCHES ;BIT 0-7 DEVICE BUSY IDLE SWITCH ;'0' IF IDLE & '1' IF BUSY ; BIT 0 LP ; 1 CD ; 2 PL ; BITS 3-7 UNUSED ;BITS 8-15 SPOOLER STATE/FUNCTION SWITCHES ; BIT 12=1 DESPOOLER ENABLED ; 13=1 SPOOLING ENABLED ; 14=1 SPOOLING+DESPOOLING ; ENABLED ; 15=1 SPOOLER CONNECTED TO PIREX RTURN=1036 ;RETURN INST ADRESS DEVST=1050 ;DEVICE ERROR STATUS TABLE DEVSPL=1064 CLTABL=1052 ;CLOCK TABLE SPOOLER ENTRY DEQU1=1054 ;SET TASK IN WAIT STATE ROUTINE TEVADD=1060 ;TABLE OF TASK START ADDRESSES CTLCT=1066 ;PDP-15 CTL 'C' RUNNING COUNTER SPUNIT=1070 ;PIREX COPY OF UNIT TO SPOOL ON (BR-126) ; ;LITERALS ; WRITEF=2 ;RK FUNCTION CODE READF=4 ; - RKCOD=2 ;RK TASK CODE UNDER PIREX SDCOD=1 ;SD - LPCOD=4 ;LP - CDCOD=5 ;CD - PLCOD=6 ;PL - SPCOD=7 ;SP - FLTCOD=7 ;FLUSH DIR. TASK CODE(FOR SPOOLER) ; IOPS15=15 ;SPOOLER FULL ERROR CODE IOPS20=20 ;DISK HARDWARE FAILURE ERROR CODE IOPS55=55 ;NO BUFFERS AVAILABLE IOPS77=77 ;TASK NOT SUPPORTED ERROR CODE ; CDSIZE=124 ;CARD SIZE(80 COLOUMS=120+HEADER=4) ; LVL5=240 ;LEVEL 5 PS SETTING LVL6=300 ; 6 LVL7=340 ; 7 ; LP1=142061 ;LINE PRINTER UNIT #1 CD1=030461 ;CARD READER UNIT #1 LT1=142461 ;XY PLOTTER UNIT #1 ; CDEOD=104611 ;END OF DECK CARD CODE ; TABLBN=1773 ;DISK HOME BLOCK NUMBER FOR TABLE BTMPBN=1774 ; - BITMAP ; ; ******* BEGSW=170000 ;PIREX SPOLSW SETTING FOR 'B' CONTSW=40005 ; - - 'C' HALTSW=40000 ; - - 'H' CDTIME=200 ;CARD READER EMPTY TIMER REQUEST ; .IFDF EAE EAESTK=6 .ENDC .IFNDF EAE EAESTK=0 .ENDC ; .SBTTL MACROS ; ;GET ADDRESS OF REG. 'A' IN REG. 'B' .MACRO ADR A,B MOV PC,B ADD #A-.,B .ENDM ; ; ;RESERVE A BLOCK OF ZEROED CORE .MACRO .BLOCK N .NLIST .REPT N .WORD 0 .ENDR .LIST .ENDM ; ;CALL SUBROUTINE .MACRO CALL ROUTIN JSR PC,ROUTIN .ENDM ; ;PUSH ARGUMENT IN STACK .MACRO PUSH ARG MOV ARG,-(SP) .ENDM ; ;POP ARGUMENT OF STACK .MACRO POP ARG MOV (SP)+,ARG .ENDM ; ;INHIBIT INTERRUPTS .MACRO .INH PUSH @#PS BIS #LVL7,@#PS .ENDM ; ;ENABLE INTERRUPTS .MACRO .ENA POP @#PS .ENDM ; ;EXIT FROM TASK IN STATE 'S' .MACRO SEXIT S IOT .BYTE 0,S .ENDM ; ;ISSUE A TASK REQUEST .MACRO IREQ MOV #100000,R4 IOT .BYTE 1,0 .ENDM ; ;RK TCB TEMPLATES .MACRO TCBRK SPCOD ;0. API LVL & TRAP ADD. 1600+RKCOD ;2. NO. INT. + RK TASK + RETURN @SEND11 0 ;4. REV 0 ;6. BLOCK # 100000 ;10. DONT RELOCATE ADD. 0 ;12. FA 0 ;14. WC 0 ;16. UNIT # (13-15) + FUN. (1-3) .BLOCK 3 ;20.,22.,24. DISK STATUR 0 ;26. REQ. DEV. CODE .ENDM ; .MACRO TCBDK A A: 0 ;0. API LVL & TRAP ADD. 600+RKCOD ;2. NO INT. + RK TASK 0 ;4. REV 0 ;6. BLOCK # 100000 ;10. DONT RELOC. ADD. 0 ;12. FA 0 ;14. WC 0 ;16. UNIT + FUN. .BLOCK 3 ;20,22,24. DISK STATUS .ENDM ; ; .SBTTL SPOOLER DISPATCHER SPBEG=. .WORD SPEND-SPBEG/2 ;SIZE OF SPOOLER (BR-127) .WORD SPST ;STARTING BYTE OFFSET (BR-128) .BLOCK 8.+EAESTK*6-2 ;(BR-128) .WORD DUM DUM: .WORD 0 .WORD 0 SPST: MOV SPST-2,R0 ;GET TCP ADDRESS IN R0 MOV #100000,SPST-4 ;FAKE 11'S REQ. TO PREVENT GETTING KILLED ;THIS IS TO PREVENT STACK BLOW UP THRO' ;CTL 'C'S FROM PDP-15 MOV @#CTLCT,SDCTSV ;SAVE CURRENT CTL 'C' COUNT FOR LATER CLEANUP TST ONCEFL ;HAS THIS CODE ALREADY BEEN DONE? BNE 20$ ;YES -- DON'T DO IT AGAIN MOV #DEVSPP,@#DEVSPL ;SET UP DEVICE SPOOLED WORD ADR SPBEG,R1 ;INITALIZE ADDRESSES (PIC CODE) ADR ADRTBL,R2 MOV #-ADTCNT,R3 10$: ADD R1,(R2)+ ;CALCULATE ADDRESSES DEC R3 BNE 10$ ;LOOP UNTIL ALL FINISHED MOV BUFLAD,R2 ;SET UP BUFFERS 15$: ADD R1,(R2)+ ;SET UP POINTERS GOING BACKWARDS THRU Q ADD R1,@R2 MOV -(R2),R2 CMP R2,BUFLAD ;HEAD OF BUFFER? BNE 15$ ;NO -- TRY AGAIN 20$: CMPB #SPCOD+200,TCODE(R0) ;SPOOLER REQUEST? BEQ Z1$ MOV PC,R1 ADD #DISP1-.,R1 ; GET DEVICE DISPATCH TABLE IN R1 CLR R2 ; CMPB #LPCOD,TCODE(R0) ;LP REQUEST? BEQ Z2$ ; TST (R2)+ CMPB #CDCOD,TCODE(R0) ;NO. CD REQUEST? BEQ Z2$ ; TST (R2)+ CMPB #PLCOD,TCODE(R0) ;NO. PL REQUEST? BEQ Z2$ ; ;UNRECOGNISED TASK REQUEST REPORT. ; ERROR: MOV @#DEVST,R1 ADD #SPCOD*3*2+4,R1 MOVB #IOPS77,(R1) CALL DEQREQ ; Z1$: MOV PC,R1 ;SPOOLER REQUEST ;GET SPOOLER DISPTACH ADD #DISP0-.,R1 ;TABLE IN #3 MOVB FCODE(R0),R2 ;GET FUN. CODE BIC #177740,R2 Z2$: ADD R1,R2 ;ADD FUN. CODE TO R1 ADD (R2),R1 ;BUILD DISPATCH JUMP X JMP (R1) ;BRANCH TO APPROPRIATE ROUTINE ; ;SPOOLER DIRECTIVE DISPATCH TABLE DISP0: BEGIN -DISP0 ;BEGIN: CODE=0 ERROR -DISP0 ;ERROR: CODE=2 END -DISP0 ;END: CODE=4 ERROR -DISP0 ;ERROR: CODE=6 ERROR -DISP0 ;ERROR: CODE=10 ERROR -DISP0 ;ERROR: CODE=12 ERROR -DISP0 ;ERROR: CODE=14 ; ;DEVICE REQUEST -DISPATCH TABLE DISP1: LPCALL -DISP1 ;LP: LINE PRINTER CDCALL -DISP1 ;CD: CARD READER PLCALL -DISP1 ;PL: XY PLOTTER ; .SBTTL BEGIN DIRECTIVE ; ;THIS ROUTINE STARTS ALL SPOOLING OPERATIONS. SWITCHES, CONTROL REGISTERS ;ETC. ARE SET . THE BUFFER POOL, TCB POINTERS, BITMAP, TABLE ETC. ARE ;SET UP;BITMAP & TABLE ARE SAVED ON DISK(FOR BACKUP OPERATIONS). EACH ;INDIVIDUAL SPOOLED TASK IS THEN INITIALIZED & STARTED UP IF NECESSARY ; ; BEGIN: MOV PC,R1 ;GET ADDRESS OF DEVINT IN R1 ADD #DEVINT-.,R1 MOV @#SEND11,R2 MOV R1,SPCOD*2(R2) ;SET SEND11 ADDRESS IN PIREX MOV 14(R0),TCBDSA+TCBDIS ; INITIALIZE ALL SWITCHES MOV #1,CBTPTR ;START BIT MAP SEARCH MOV ASPLFU,R1 ;##139##SETUP TASK CODE STACK FOR FINDBK MOV R1,TCDINI ;##139##WHEN MORE THAN ONE GUY FINDS OUT MOV R1,TCDPNT ;##139##THERE ARE NO BLOCKS ;SET CONTROL REGS. MOV PC,R1 ;GET ADD. OF DUM IN R1 ADD #DUM-.,R1 PUSH R1 ;SAVE ON STACK POP -(R1) ; SET SPOOLER CONTROL REG.!! ;SETUP BUFFER POOL ;INITIALIZE RK TCB POINTERS MOV RKCAD,R1 ;GET RKTCBP ADD. IN R1 MOV PC,R2 ;GET TCBR01 ADD. IN R2 ADD #TCBST-.,R2 MOV #TCBCT,R3 ;SETUP TCBCT TCB'S 2$: MOV R2,(R1)+ ;SET TCBRK1 POINTER ADD #30,R2 ;BUMP R2 TO TCBRK2 DEC R3 BNE 2$ ;INITIALIZE BITMAP PUSH NBK(R0) ;GET SIZE OF SPOOLER AREA NUMBER ASR (SP) ;COMPUTE SIZE OF BIT MAP ASR (SP) ;SIZE=NUMBK/8+2 ASR (SP) BIC #1,(SP) ;GET EVEN NUMBER MOV BTMPAD,CWDPTR ;RESET CWDPTR MOV BTMPAD,R1 ;(BR_112. TEMP FIX) ADD (SP)+,R1 ;ADD OFFSET TO END MOV R1,BTMPED ;SET UP BTMPED MOV STBKNA,R1 ;GET ADDRESS OF STBKNM-4 IS R1 MOV SBN(R0),(R1)+ ;SET STARTING LOCK # MOV NBK(R0),(R1)+ ;SET NUMBER OF BLOCKS MOV UNIT(R0),@#SPUNIT ;TELL PIREX SPOOLING UNIT (BR-126) MOV UNIT(R0),UNITSP ;COPY INTO LOCAL MEM. (BR-126) SWAB UNITSP ;SET UP FOR TCB USE (BR-126) MOV #BTMPSZ,R2 ;GET BIT MAP SIZE IN R2 MOV R1,R3 4$: CLR (R3)+ DEC R2 BNE 4$ ;INITIALIZE TABLE MOV TABLAD,R1 ;GET ADDRESS OF TABLE IN R1,R3,R1 MOV R1,R3 MOV #TABLSZ,R2 ;GET TABLE SIZE IN R2 3$: MOV #-1,(R3)+ DEC R2 BNE 3$ MOV #LP1,(R1) ;SET LP1(DED) IN TABLE MOV #CD1,CDTEOF(R1) ;SET CD1 (DED) IN TABLE MOV #LT1,PLTEOF(R1) ;SET PL1 (DED) IN TABLE ;SET SPOOLER SWITCHES 1$: CLR @#SPOLSW ;RESET SPOOLER SWITCHES BIS #BEGSW,@#SPOLSW ;SET SPOOLER ENABLED AND RUNNING ; ;ALL SPOOLED TASKS HAVE TO BE INITIALISED. OPERATIONS LIKE SETTING ;& RESETTING SWITCHES, SETTING UP POINTERS, BUFFERS, STARTING UP ;TASK ETC. HAVE TO BE DONE AS INDICATED FOR EACH TASK ; .IFDF $CD BIS #2,@#SPOLSW ;SET CD ON ONLY IF PRESENT ;INITIALIZE CD SPOOLER/DESPOOLER TASK CLRB CDONCE MOV #1000,CDONCE+1 MOV @#LISTHD,R2 ;GET ADDRESS OF LISTHD IN R2 ADD #CDCOD*4,R2 ;CLEAR CD DEQUE TASK CODE=5 CALL EMPTD MOV @R1,NBN+TABLE+CDTEOF MOVB #1,CDCNTI ;INITIALIZE CDCNTI CLRB CDBMS ;RESET CDBMS CLRB CDBFS MOV R1,CDCBIP CMP (R1)+,(R1)+ MOV R1,CDWDIP ADD #CDSIZE,CDWDIP ;BUMP TO NEXT CARD MOV R1,R5 ;SAVE BUFFER ADDRESS ON DTA H CALL STUPCT ;SET UP TCB TO READ A CARD .ENDC .IFDF $LP ;INITIALIZE LP SPOOLER/DESPOOLER TASK CLRB LPONCE MOV #1000,LPONCE+1 MOV @#LISTHD,R2 ;GET ADDRESS OF LISTHD IN R2 ADD #LPCOD*4,R2 ;CLEAR LP DEQUE: TASK CODE=4 CALL EMPTD ;SET NBN=CBN FOR START UP MOV @R1,NBN+TABLE MOV R1,LPCBCP CMP (R1)+,(R1)+ MOV R1,LPWDCP CLRB LPBMS .ENDC .IFDF $PL ;INITIALIZE PL SPOOLER/DESPOOLER TASK CLRB PLONCE MOV #1000,PLONCE+1 MOV @#LISTHD,R2 ;GET ADDRESS OF LISTHD IN R2 ADD #PLCOD*4,R2 ;CLEAR PL DEQUE: TASK CODE=6 CALL EMPTD MOV @R1,NBN+TABLE+PLTEOF MOV R1,PLCBCP ;SET PLCBCP CMP (R1)+,(R1)+ MOV R1,PLWDCP ;SET PLWDCP CLRB PLBMS ;RESET PLBMS .ENDC ;ALL DONE DEQUE NEXT REQUEST CALL DEQREQ ; ;EMPTY TASK DEQUE EMPTD: .INH ;INHIBIT INTERRUPTS MOV #EMPTY,R1 ;EMPTY TASKS DEQUE JSR PC,@(R1)+ .ENA ;ENABLE INTERRUPTS CALL FINDBK MOV R1,-(SP) CALL GETBUF POP (R1) RETURN .SBTTL END ; ;THIS ROUTINE SHUTS DOWN ALL SPOOLING OPERATIONS. THE TIMER REQUEST ;IS CANCELLED, SOFTWARE INTERRUPTS ARE IGNORED AND THE SPOL11 TASK ;IS DISCONNECTED FROM PIREX ; ; END: BIS #LVL7,@#PS ;PROTECT ROUTINE (BR-138) MOV @#CLTABL,R1 ;NULL SPOOLER TIMER REQUEST CLR SPST-4 ;ENABLE STOP ALL I/O CLR @#DEVSPL ;CLEAR DEVICED SPOOLED SWITCH CLR SPCOD*4(R1) CLR @#SPOLSW ;RESET SPOOLER SWITCH BIC #LVL7,@#PS ;UNPROTECT TO ALLOW INTS. TO RUN DOWN (BR-138) MOV #20,R5 ;ALLOW 20 INTERRUPTS (CLOCK OR DEVICE) (BR-138) 1$: WAIT ;WAIT FOR THEM (BR-138) DEC R5 ;COUNT 20 INTS. (BR-138) BNE 1$ ;BRANCH IF NOT 20 (BR-138) BIS #LVL7,@#PS ;INHIBIT INT. MOV @#TEVADD,R1 ;FIND THE ENTRY ADDRESS .IFDF $LP MOV LPCOD*2(R1),R2 ;FIND TASK ADDRESS CALL STPTSK ;STOP THE TASK .ENDC .IFDF $CD MOV CDCOD*2(R1),R2 ;STOP THE CARD READER TASK CALL STPTSK ;STOP THE TASK .ENDC .IFDF $PL MOV PLCOD*2(R1),R2 ;STOP THE PLOTTER TASK CALL STPTSK .ENDC MOV #RTURN,R1 ;GET RETURN INST. ADD IN R1 MOV @#SEND11,R2 MOV (R1),SPCOD*2(R2) ;SHUT OFF SEND11 CMP FCODE(R0),#4 ;SEE IF THIS WAS "END" OR IOPSUC 20 (BR-138) BNE 2$ ;BRANCH IF IOPSUC 20 (BR-138) MOV #1,R1 ;TELL SPOL15 DONE MOV #SEND15,R2 JSR PC,@(R2)+ 2$: ADR TCBDIS,R5 ;SET FA IREQ ;SEND REQUEST ; STPTSK: TST R2 ;(GAR-141) IS TASK IN EXISTENCE? BEQ 1$ ;(GAR-141) BRANCH IF NOT. TST -4(R2) ;PDP-11 REQUEST? BPL 1$ ;NO -- IGNORE MOV -(R2),R3 ;YES -- TEST FOR SPOLLER REQUEST? CMPB #SPCOD,@R3 BNE 1$ CLR @R2 CLR -(R2) ;STOP TASK (CLEAR TCB ADR CLR @-2(R2) ;STOP DEVICE FROM INTERRUPTING 1$: RETURN ; ; .SBTTL DEQUE NEXT REQUEST ; ;THIS ROUTINE CHECKS TO SEE IF THERE ARE ANY MORE REQUESTS IN THE ;'TRL'. IT HAS 3 ENTRY POINTS: ; DEQRQO PROCESS NEXT REQUEST IF ANY ; DEQRQ ABOVE+TELL CALLER DONE ; DEQREQ ABOVE+INDICATE GOOD COMPLETION ; DEQREQ: BIS #LVL7,@#PS ;INHIBIT INT. MOV #1,R1 ;TELL CALLER ALL DONE DEQRQ: MOV #SEND15,R2 CMP @#CTLCT,SDCTSV ;ANY CTL 'C'S FROM PDP-15?? BNE DEQRQ0 JSR PC,@(R2)+ ;NO. DEQRQ0: TST (SP)+ ;THROW AWAY PC!!!! BIS #LVL7,@#PS MOV SPSTAD,R1 MOV R1,R3 CLR -(R1) ;CLEAR BUSY FLAG CLR -(R1) MOV @#LISTHD,R1 ;GET ADDRESS OF SYSTEM LISTAD IN R1 ADD #SPCOD*4,R1 ;ADD OFFSET TO TASK LISTHEAD MOV @#DEQU,R2 ;DEQUE REQUEST JMP (R2) ; .SBTTL UTILITY ROUTINES .IFDF $CD ; ;SET UP TCB TO READ A CARD FROM CD ;CALLING SEQUENCE: MOV BUFAD,R5 ; CALL STUPCT ; STUPCT: MOV PC,R1 ;GET ADDRESS OF TCBCD IN R1 ADD #TCBCD-.,R1 BR STUCOM ;ENTER COMMON ROUTNINE .ENDC .IFDF $LP ; ;SET UP TCB TO WRITE A LINE ON LP ;CALLING SEQUENCE: MOV BUFAD,R5 ; CALL STUPLT ; STUPLT: MOV PC,R1 ;GET ADDRESS OF TCBLP IN R1 & R5 ADD #TCBLP-.,R1 BR STUCOM .ENDC .IFDF $PL ; ;SET UP TCB TO WRITE A LINE ON PL ;CALLING SEQUENCE: MOV BUFAD,R5 ; CALL STUPPT ; STUPPT: MOV PC,R1 ;GET ADDRESS OF TCBPL IN R1 & R5 ADD #TCBPL-.,R1 .ENDC STUCOM: MOV R5,10(R1) MOV R1,R5 CLR 4(R1) ;RESET REV IREQ ;SEND RETURN ; ;SET UP DISK TCB TO READ A BLOCK WITH NO INTERRUPTS & RETURN ADDRESS ; CALLING SEQUENCE: ADR BUFF,R4 ; ADR -.CBN,R3 ; ADR TCBDK-,R2 ; CALL STUPDT ; STUPDT: MOV R2,R5 ;SAVE TCBP IN R5 CMP (R2)+,(R2)+ ;BUMP TO REV CLR (R2)+ ;RESET REV MOV (R3),(R2)+ ;SET BLOCK # TST (R2)+ MOV R4,(R2)+ ;SET BUFAD MOV #-400,(R2)+ ;SET WC MOV #READF,(R2)+ ADD UNITSP,-2(R2) ;ADD UNIT NUMBER (BR-126) IREQ RETURN ; WAITBK: PUSH @#PS CLRB @#PS WAIT POP @#PS RETURN ; ; .SBTTL FIND A FREE BLOCK ON DISK ; ;FIND A FREE BLOCK ON DISK ;CALLING SEQUENCE: CALL FINDBK ; FREE BLOCK # IF ANY RETURNED ON STACK ; IF NOT SET UP TO HALT CURRENT OPERATION & RETURN ; REGS USED R1, R2, R3 FINDBK: .INH ; ; < > < > < > < > < > < > < > < > < > < > START OF EDIT #133 ; MOV CWDPTR,R1 ;ADDR OF BIT MAP WORD LAST USED MOV CBTPTR,R2 ;LAST BIT USED BMI 1$ ;MINUS, NO BITS LEFT IN WORD ASL R2 ;START SEARCH WITH NEXT BIT UP ADD (R1),R2 ;THIS SETS NEXT ZERO BIT IN WORD! BCC 6$ ;IF NO CARRY, A BIT WAS FOUND AND SET 1$: TST (R1)+ ;BUMP R1 TO POINT TO NEXT WORD CLR R3 ;##135##FLAG FOR PASS 1;CWDPTR TO END MOV #-1,R2 ;COMPARE TO SEE IF WORD OF BITS ALL USED 2$: CMP (R1)+,R2 ;DOES WORD HAVE ANY FREE BITS BNE 3$ ;EITHER IT DOES, OR WE RAN OFF END CMP (R1)+,R2 BNE 3$ CMP (R1)+,R2 ;LEAVE THESE SPREAD OUT TO SPEED LOOP BNE 3$ ;SINCE WE ARE LEVEL 7, AND BR'S THAT BR CMP (R1)+,R2 ;ARE SLOWER!!! BNE 3$ CMP (R1)+,R2 BEQ 2$ ;WORD ALL FULL, KEEP LOOPING ; < > < > < > < > < > < > < > < > < > < > START OF EDIT #135 3$: TST R3 ;SEE IF PASS 1 OR PASS 2 BNE 4$ ;NON0, GO FIELD PASS 2 CMP BTMPED,R1 ;SEE IF RAN OFF END OF MAP BHIS 7$ ;NO, SO WE'VE FOUND A FREE BIT MOV CWDPTR,R3 ;OFF END, INIT PASS 2, HERE'S FLAG CLR (R3) ;CLEAR BEGINNING WORD TO STOP PASS 2 MOV BTMPAD,R1 ;START PASS 2 AT TOP OF MAP BR 2$ ;GO TO SCAN LOOP ; 4$: COM (R3) ;PASS 2, TURN BEGINNING WORD BACK TO -1 CMP R1,R3 ;DID WE GET TO BEGINNING WORD BHI 55$ ;YES, NO BITS, SET UP FOR 'ERROR' ; 7$: MOV -(R1),R2 ;BACK UP TO GET COPY OF MAP WORD ; < > < > < > < > < > < > < > < > < > < > END OF EDIT #135 MOV R1,CWDPTR ;SAVE FIND POSITION FOR NEXT TIME CALLED INC R2 ;SETS FIRST ZERO BIT IN WORD!! 6$: BIC (R1),R2 ;CLEAR ALL REST,LEAVING BIT FOR OUR BLOK BIS R2,(R1) ;SET BIT IN MAP MOV R2,CBTPTR ;REMEMBER BIT FOR NEXT TIME SUB BTMPAD,R1 ;BYTE INDEX FOR FOUND BLOCK # TSTB R2 ;IS BIT IN LOW HALF OF WORD BNE 8$ ;YUP, NO CHANGE INC R1 ;IN HIGH HALF, INC BYTE COUNT 8$: ASL R1 ;NIBBLE (4 BIT) INDEX FOR FIND BIT #170360,R2 ;IS BIT IN HIGH NIBBLE OF BYTE BEQ 9$ ;NO, NOCHANGE INC R1 ;YES, SO INCR NIBBLE COUNT 9$: ASL R1 ;CRUMB (2 BIT) INDEX FOR FOUND BLOCK BIT #146314,R2 ; IS BIT IN HIGH CRUMB OF MIBBLE BEQ 10$ ;NO, NO CHANGE INC R1 ;YES, SO INCR CRUMB COUNT 10$: ASL R1 ;NOW HAVE BIT COUNT FOR BLOCK BIT #125252,R2 ;IS BIT IN HIGH BIT OF CRUMP BEQ 11$ ;NO, NO CHANGE INC R1 ;YES, SO ADD ONE 11$: ADD STBKNM,R1 ;AND FINALLY ADD #OF FIRST MAPPED BLOCK ; ; < > < > < > < > < > < > < > < > < > < > END OF EDIT #133 ; ;THE FOLLOWING PIECE OF CODE CHECKS TO SEE IF THE CURRENT BLOCK TO BE ;ALLOCATED TO THE CURRENT SPOOLING TASK EQUALS THE CBN OF THIS ;DESPOOLING TASK;IF THIS IS TRUE, THEN THE 'SPOOLER IS DECLARED FLOODED' ;THIS HAPPENS ONLY ON A WRAP AROUND(ENTIRE SPOOLER AREA IS TREATED AS A ;RING BUFFER)WHEN SPOOLING OPERATIONS ARE WAY AHEAD OF DESPOOLING OPERATIONS ; ; ;*****NOTE: AS NEW TASKS ARE ADDED NEW CODE HAS TO BE ADDED***** ;********** SIMILAR TO THE CODE FOR EXISTING TASKS************** ; MOVB 2(R0),R2 ;GET CURRENT TASK CODE CMPB #LPCOD,R2 ;LP? BEQ 21$ CMPB #CDCOD+200,R2 ;NO. CD? BEQ 22$ CMPB #PLCOD,R2 ;NO. PL? BNE 26$ MOV TABPLC,R2 ;YES BR 30$ 21$: MOV TABPCB,R2 BR 30$ ; 22$: MOV TABCDC,R2 30$: CMP R1,(R2) BEQ 5$ 26$: POP @#PS ;DEBUG;UNPROTECT ;RETURN WITH BLOCK # ON STACK RETURN ; ;SORRY NO BLOCK FREE?? SETUP TO HALT CURRENT OPERATION ; < > < > < > < > < > < > < > < > < > < > START OF EDIT #135 55$: MOV AFNDBK,R3 ;ADDR 'FINDBK' ; ENTER WHEN NO BLOCK POP R2 ;STACK NOW /ENTER PS/CALL PC/ PUSH R3 ;MAKE IT /ENTER PS/ADDR FINDBK/CALL PC PUSH R2 ;AND HOPE IT FALLS THRU 5 OK ; < > < > < > < > < > < > < > < > < > < > END OF EDIT #135 5$: MOV (SP),R2 ;DEBUG;GET OLD PS;BR HERE 1 BLK LEFT MOV 2(SP),(SP) ;DEBUG;SET UP PC MOV R2,2(SP) ;DEBUG;SET PS PUSH R0 PUSH R1 PUSH R2 PUSH R3 PUSH R4 PUSH R5 MOV @#CTLCT,SDCTSV ;SAVE CURRENT COUNT OF PDP-11 CTL 'C'S MOV @#CURTSK,R2 MOVB 6(R2),R1 ;##139##GET TASK CODE MOVB R1,SPLFUL ;##139##USE AS FULL FLAG BIC #177417,R1 ;##139##KEEP ONLY TASK CODE ASR R1 ;##139##MAKE CODE INTO WORD INDEX ASR R1 ;##139## MOV #4,R3 ;START TO COMPUTE TASKS DEVST LOCATION (BR-140) ADD R1,R3 ;CONTINUE DEVST STUFF (BR-140) ASR R1 ;##139## CONTINUE TASK CODE INDEX COMPUTATION ADD R1,R3 ;BACK TO DEVST COMPUT. R3=6*TASK CODE (BR-140) ADD @#DEVST,R3 ;FINISH DEVST COMPUT. (BR-140) MOVB #IOPS15,(R3) ;MOVE IOPS 15 INTO DEVST TABLE (BR-140) DEC TCDPNT ;##139##PUSH TASK CODE*2 ONTO BYTE STACK MOVB R1,@TCDPNT ;##139## ADD @#TEVADD,R1 ;##139##KEEP BECAUSE IT WAS THERE MOV (R1),R1 ;##139##DON'T THINK NECESSARY TST -(R1) ;##139##MAKES IT A PDP-11 REQ. MOV #100000,-(R1) ;##139##WITH HIGH BIT OF HIGH ADDR WORD MOV @#DEQU1,R1 ;SET TASK IN WAIT STATE & EXIT JMP (R1) ; ; CWDPTR: 0 ;CURRENT WORD POINTER CBTPTR: 1 ;CURRENT BIT POINTER ; ;##139##KEEP EDIT 139 IN THIS ORDER TCDINI: 0 ;##139##INIT'ED TO POINT TO SPLFUL! TCDPNT: 0 ;##139##ALSO INIT'ED TO POINT AT SPLFUL .WORD 0,0,0,0 ;##139##STACK TASK CODES THRU TCDPNT SPLFUL: .BYTE 0 ;##139##SPOOLER FULL FLAG FRBKCT: .BYTE 0 ;##139##FREE BLOCK COUNT SDCTSV: 0 ;PDP-15 CTL 'C'S COUNT SAVE ; ; .SBTTL FREE BLOCK ON DISK ; ;CALLING SEQUENCE: CALL FREEBK ; BLOCK # IN R4 ; REGS USED R1,R2,R3 ; FREEBK: SUB STBKNM,R4 ;DEDUCT STARTING BLOCK # CLR R2 ;RESET WORD OFFSET COUNTES BR 1$ 2$: TST (R2)+ ;COMPUT WORD OFFSET IN BITMAP 1$: SUB #16.,R4 BGE 2$ ;DONE? ADD #16.,R4 ;RESTORE BIT OFFSET MOV #1,R3 ;RESET BIT POINTERS 4$: TST R4 ;SET BIT POINTER CORRESPONDING TO OFFSET BEQ 3$ DEC R4 ASL R3 BR 4$ 3$: MOV BTMPAD,R1 ;GET ADDR OF START OF BITMAP ADD R2,R1 ;ADD WORD OFFSET BIC R3,(R1) ;CLEAR BIT FREE BLOCK!! ;SPOOL FLOODED? TSTB SPLFUL BEQ 8$ ; 5$: INCB FRBKCT CMPB #5,FRBKCT ;5 FREE BLOCKS? BNE 8$ ; 6$: .INH ;##139##EXPAND RANGE OF .INH SLIGHTLY CLR SPLFUL ;##139##CLEAR FRBKCT AND SPLFUL BIS #20000,@#SPOLSW ;##139##ENABLE SPOOLING MOV TCDPNT,R2 ;##139##FETCH TASKS WHO ARE WAITING 9$: MOVB (R2)+,R3 ;##139##WORD INDEX OF WAITING TASK ADD @#ATLNP,R3 ;##139##ADDED TO ADDR OF LIST OF ATL NOD MOV (R3),R3 ;##139##ADDR OF A WAITING NODE BIC #17,6(R3) ;##139##SET TASK TO RUNNABLE CMP TCDINI,R2 ;##139##CHECK FOR MORE TO DO BNE 9$ ;##139##MORE MOV R2,TCDPNT ;##139##RESET POINTER FOR NEXT TIME .ENA ;DEBUG 8$: RETURN ; .SBTTL GETPUT/CHNBUF/STUPRT ; ;THIS ROUTINE SETS UP FOR DISK BLOCK TRANSFERS(IN/OUT) ; ;CALLING SEQUENCE (SP-10) DEVICE CODE ; (SP-6) DISK FUNCT WRITE (2)/READ (4) ; (SP-4) BUFFER ADDRESS ; (SP-2) BLOCK # ; (SP) RETURN ADDRESS ; CALL GETPUT ; REGS USED R4 GETPUT: MOV 2(SP),(R4)+ ;SET BLOCK # IS TCB TST (R4)+ ;STEP PAST MSB-FA MOV 4(SP),(R4)+ ;SET BUFFER ADDRESS IN TCB MOV #-400,(R4)+ ;SET WC IN TCB MOV 6(SP),(R4)+ ;SET DISK FUNCT IN TCB ADD UNITSP,-(R4) ;ADD IN UNIT NUMBER ADD #10,R4 ;BUMP TO END OF R3 MOV 10(SP),(R4) ;SET DEVICE CODE IREQ ;SEND DISK REQUEST RETURN UNITSP: .WORD 3400 ;UNIT TO SPOOL ON - INITIALIZED TO 7 - ;TO PREVENT ACCIDENTIAL USE - SINCE THERE ;IS A LOW PROBABILITY OF A 8 DRIVE UC15 ;IN ANY CASE SPOL15 SETS THIS TO A VAILD ;NUMBER UPON STARTUP (BEGIN) (BR-126) .SBTTL GETBUF/GIVBUF ; ;CALLING SEQUENCE: CALL GETBUF ; BUFFER ADDRESS RETURNED IN R1 ; REGS USED R1, R2, R3 GETBUF: PUSH @#PS 2$: BIS #LVL7,@#PS MOV BUFLAD,R1 CMP R1,(R1) ;BUFFER: LEFT? BEQ 1$ MOV R1,R3 ;YES ??? MOV (R1),R1 ;GET FOR PTR OF BAFLHD IN R1 PUSH R1 ;SAVE ON 1 TACK MOV (R1),R2 ;GET TO PTR OF BUF IN R2 CMP (R1)+,(R2)+ ;BUMP TO BACK USED PTR. MOV (R1),(R2) ;SET BACK UP TO OF NEXT BUT TO BUFLHD MOV -(R1),(R3) ;SET TO PTR OF BUFLHD POP R1 ;GET BUFAD IN R1 & POP STACK CLR (R1) ;RESET HEADER WORDS FOR DEBUGGING CLR 2(R1) .ENA RETURN ; ; ******TEMPORARY FIX FOR RUNNING OUT OF BUFFERS******* ; EDIT #092 ; 1$: MOV @#DEVST,R1 ;SET ERROR CODE IN PIREX TABLE ADD #SPCOD*3*2+4,R1 MOVB #IOPS55,(R1) CLRB @#PS WAIT ;TIME OUT BR 2$ ; ;CALLING SEQUENCE: R3 BUFAD ; CALL GIVBUF ; REGS USE R1, R2, R3 GIVBUF: .INH MOV BUFLAD,R1 CMP R1,(R1) ;BUFFER POOL EMPTY? BEQ 1$ MOV R1,R2 ;COPY R1 INTO R2 TST (R2)+ ;BUMP R2 TO BACK. PTR. OF BUFLHD MOV @(R2),(R3)+ ;SET FOR. PTR. OF N.BUF=FOR. PTR. OF ;LAST BUF. IN CHAIN & BUMP TO BACK. PTR. ;OF N.BUFF MOV (R2),(R3) ;SET BACK. PTR. OF N.BUFF=BACK. PTR. OF ;BUFLHD TST -(R3) ;POINT R3 BACK TO FOR. PTR. OF N.BUFF MOV R3,@(R2) ;SET FOR. PTR. OF LAST BUF. IN CHAIN MOV R3,(R2) ;SET BACK. PTR. OF BUFLHD BR 2$ 1$: MOV R1,(R3)+ ;SET FOR. PTR. IN BUFF. MOV R1,(R3) ;SET BACK. PTR. IN BUF TST -(R3) ;POINT TO WD0 IN BUF. MOV R3,(R1)+ ;SET FOR. PTR. OF BUFLHD MOV R3,(R1) ;SET BACK. PTR. IN BUFLHD 2$: .ENA RETURN .SBTTL RK TCB SETUP ROUTINES ; ; ***NOTE*** ; ;A POOL OF DISK TCB'S(ONE FOR EACH BUFFER) IS KEPT TO ENABLE CONTINUOUS ;DISK BLOCK TRANSFERS. EACH TCB HAS A CORRESPONDING BIT WHICH IS SET IF ;BUSY, RESET IF IDLE. A POINTER TO EACH TCB IS KEPT IN A TABLE BELOW. ; RKTCBS: 0 ;TCB BUSY/IDLE SWITCH. MAXM. OF 16 TCB RKTCBP=. ;POINTERS TO TCB .IFEQ DEVCNT-1 .REPT DEVCNT*4+2 ;(SCR-144)1 DEV. EXTRA BUFFER .WORD 0 .ENDR .ENDC .IFNE DEVCNT-1 .REPT DEVCNT*4 .WORD 0 .ENDR .ENDC ; ;GET A DISK TCB FROM POOL ;CALLING SEQUENCE: CALL GETRKT ; ADD. OF TCB RET. IN R4 ; REGS. USED R1,R4,R5 GETRKT: PUSH @#PS 6$: BIS #LVL7,@#PS MOV #1,R5 ;START OF SEARCH 1$: BIT R5,RKTCBS ;FREE TCB? BEQ 2$ ASL R5 ;TRY NEXT TCB CMP #TCBLIM,R5 ;TCB'S LEFT? BEQ 3$ BR 1$ ;YES. 2$: BIS R5,RKTCBS ;FREE TCB. SET BUSY SW CLR -(SP) ;COMPUTE TCB ADD. 4$: ROR R5 BEQ 5$ ADD #2,(SP) ;BUMP OFFSET BR 4$ 5$: MOV RKCAD,R4 ;GET ADD. OF TCB IN R4 ADD (SP)+,R4 MOV (R4),R4 MOV R4,R5 ;SAVE IN R5 FOR IREQ CMP (R4)+,(R4)+ ;BUMP R4 TO REV CLR (R4)+ ;RESET REV & BUMP TO BLOCK # .ENA RETURN ; ; ******TEMPORARY FIX FOR RUNNING OUT OF TCB'S******* ; EDIT #092 ; 3$: MOV @#DEVST,R1 ;SET ERROR CODE ADD #SPCOD*3*2+4,R1 MOV #IOPS55,(R1) CLRB @#PS WAIT BR 6$ ; ; ;GIVE BACK TCB ;CALLING SEQUENCE: TCB ADD. IN R4 ; CALL GIVRKT ; REGS. USED R1,R4,R5 GIVRKT: .INH MOV #1,-(SP) MOV RKCAD,R1 2$: MOV (R1)+,R5 ;GET ADD. OF NEXT TCB CMP R5,R4 ;ADD. MATCH? BEQ 1$ ASL (SP) BR 2$ ;YES. ; 1$: BIC (SP)+,RKTCBS ;SET TCB IDLE SW .ENA RETURN ; ; .SBTTL TASK SOFTWARE INTERRUPT DISPATCHER ; ;SEND15 IN PIREX TRANSFERS CONTROL TO DEVINT BY A "CALL @SEND11(-COD*2)" ;IF REQUESTED IN TCB. THIS IS DONE BY A CODE OF '3' IN BYTE-3 ;OF TCB. SPOOLER SETS THE ADDRESS OF DEVINT IN SEND11 WHEN STARTED ; ; ; DEVINT: CMP #1,4(R0) ;GOOD COMPLETION?? BNE 5$ ;BRANCH IF NO CMPB #RKCOD+200,TCODE(R0) ;RK REQ.? BEQ RKINT CMPB #LPCOD+200,TCODE(R0) ;LP REQ? BEQ 2$ CMPB #CDCOD+200,TCODE(R0) ;CD REQ? BEQ 3$ JMP PLINT ; ; 2$: JMP LPINT ; 3$: JMP CDINT ; ; ; 5$: RETURN ; .SBTTL RK INTERRUPT SERVICE ; ;DISK REQUEST WAS MADE ON BEHALF OF A SPOOLED DEVICE: ??? FIND OUT ;WHAT HAS TO BE DONE NEXT ; RKINT: TST 20(R0) ;DISK HARDWARE FAILURE? BMI 3$ CMPB #WRITEF,16(R0) ;WRITE FUNCT? BEQ 1$ MOV 6(R0),R4 ;NO. READ GET BLOCK # IN R4 CALL FREEBK ;FREE BLOCK CMPB #LPCOD,DTCODE(R0) ;FOR LP DEV? BEQ 10$ CMPB #CDCOD,DTCODE(R0) ;NO. CD DEV.? BEQ 20$ CMPB #PLCOD,DTCODE(R0) ;NO. PL DEV.? BEQ 30$ ;ASSUME SPOOLER REQUEST JMP DONE ; 1$: JMP WRITE ; ; ; ;THIS IMPLEMENTATION DOES NOT RECOVER FROM DISK FAILURE. ;USER IS INTIMATED OF THIS CONDITION -IOPS 20- AND THE SPOOLER GOES INTO A HALT ;STATE. THIS IS TO PERMIT USER TO RECOVER,IF POSSIBLE FROM THIS CONDITION. ; 3$: BIS #LVL7,@#PS ;SHUT OFF THE WORLD MOV @#DEVST,R1 ;SET ERROR IN PIREX TABLE ADD #SPCOD*3*2+4,R1 MOVB #IOPS20,(R1) MOV 6(R0),-(R1) ;SET BLOCK NUMBER IN TABLE CLR R0 ;SETUP CALL FOR "END" (BR-138) JMP END ;CALL END ROUTINE (BR-138) .IFNDF $LP 10$: MOV @#DEVST,R1 ;SET ERROR CODE MOVB #IOPS77,LPSPER(R1) RETURN .ENDC .IFDF $LP ; ;READ REQUEST WAS MADE FOR LP. 10$: MOV TABLAD,R3 ;CBN=LFB? CMP 6(R0),LFB(R3) BNE 13$ MOV #-1,LFB(R3) ;YES. SET LFB=-1 13$: CLRB LPBMD DECB LPBUFS ;DECREMENT LPBUFS CMPB #1,LPONCE ;LPONCE=1? BNE DONE ;BRANCH IF NO MOV LPCZAD,R2 ;YES. START UP LP 11$: CALL 12$ INCB LPONCE ;SET ONCE ONLY COMPLETE SW. BIT #40000,@#SPOLSW ;SHUT DOWN? BEQ DONE MOV @R2,R5 ;SAVE BUFAD ON STACK CALL STUPLT ;NO SET LP TCB BIS #1,@#SPOLSW ;SET LP BUSY SW BR DONE ;EXIT .ENDC ; ;SECTIONS 12 USED FOR LP AND PL ; ; 12$: MOV 6(R0),CBN(R3) ;SET CBN IN TABLE PUSH 12(R0) ;SAVE FA ON STACK MOV @SP,(R2)+ ;SET LPCBIP MOV #4,(R2) ;SET LPWDIP ADD @SP,(R2) ;COMPUTE LPWDIP ADD #TWD1,(SP) ;BUMP TO LINK A NBN MOV @(SP)+,NBN(R3) ;SET NBN IN TABLE MOV #4,CRP(R3) ;SET CRP IN TABLE RETURN .IFNDF $CD 20$: MOV @#DEVST,R1 MOVB #IOPS77,CDSPER(R1) ;REPORT TASK NOT SUPPORTED RETURN .ENDC .IFDF $CD ;READ REQUEST WAS MADE FOR CD 20$: MOV TABCDT,R3 ;CBN=LFB? CMP 6(R0),LFB(R3) BNE 21$ MOV #-1,LFB(R3) ;YES. SET LFB=-1 21$: CLRB CDBMD DECB CDBUFS CMPB #1,CDONCE ;CDONCE=1? BNE DONE MOV CDCBAD,R2 CALL 12$ INCB CDONCE ;YES. SET ONCE ONLY PROCESS COMPLETE SW. BR DONE ;EXIT .ENDC ;READ REQUEST WAS MADE FOR A PLOTTER .IFNDF $PL 30$: MOV @#DEVST,R1 MOVB #IOPS77,PLSPER(R1) ;REPORT TASK NOT SUPPORTED RETURN .ENDC .IFDF $PL ;READ REQUEST WAS MADE FOR PL. 30$: MOV TABPLA,R3 ;CBN=LFB? CMP 6(R0),LFB(R3) BNE 33$ MOV #-1,LFB(R3) ;YES. SET LFB=-1 33$: CLRB PLBMD DECB PLBUFS ;DECREMENT PLBUFS CMPB #1,PLONCE ;PLONCE=1? BNE DONE ;BRANCH IF NO MOV PLCIAD,R2 ;YES. START UP PL 31$: CALL 12$ INCB PLONCE BIT #40000,@#SPOLSW ;SHUT DOWN? BEQ DONE MOV @R2,R5 ;SAVE BUFAD ON STACK CALL STUPPT ;NO SET PL TCB BIS #4,@#SPOLSW ;SET PL BUSY SW ; .ENDC ;ALL DONE; CHECK REV, RESOTRE REGS & EXIT DONE: MOV R0,R4 ;RETURN TCB CALL GIVRKT RETURN ; ; ;DISK WRITE REQUEST WAS MADE FOR A SPOOLED DEVICE ; WRITE: MOV 12(R0),R1 ;GET BUFFER ADDRESS IN R1 MOV R1,R3 CLR (R1)+ ;RESET HWDS CLR (R1) CALL GIVBUF CMPB #PLCOD,DTCODE(R0) ;REQ MADE FOR PL DEV? BEQ 43$ CMPB #CDCOD,DTCODE(R0) ;REQ MADE FOR CD DEV? BEQ 42$ .IFNDF $LP 41$: MOV @#DEVST,R1 MOVB #IOPS77,LPSPER(R1) ;REPORT TASK NOT SUPPORTED RETURN .ENDC .IFDF $LP ;WRITE REQUEST MADE FOR LP 41$: MOV LPBMSA,R1 ;RESET LPBMSA CLRB (R1) MOV TABLAD,R5 MOV 6(R0),LSB(R5) ;SET LSB IN TABLE MOV LPONAD,R3 ;GET ADD OF LPBMS IN R3 TSTB (R3) ;FIRST TIME THROUGH?? BNE DONE INCB (R3)+ ;YES. SET SW. INCB (R3) ;SET LPBMD CALL GETBUF ;GET A BUFFER PUSH #LPCOD ;SETUP FOR GETPUT SAVE DEV CODE .ENDC 44$: PUSH #READF ;SAVE DISK FUN. PUSH R1 ;SAVE BUFFER ADD PUSH NBN(R5) ;SAVE BLOCK # CALL GETRKT ;GET A RK TCB CALL GETPUT ;GET BLOCK ADD #10,SP ;CLEAN STACK BR DONE ;CHECK REV & EXIT .IFNDF $CD 42$: MOV @#DEVST,R1 MOVB #IOPS77,CDSPER(R1) ;REPORT TASK NOT SUPPORTED RETURN .ENDC .IFDF $CD ;WRITE REQUEST MADE FOR CD 42$: MOV CDBMSA,R1 ;SET CDBMD CLRB (R1) MOV TABCDT,R5 MOV 6(R0),LSB(R5) ;SET LSB IN TABLE MOV CDONAD,R4 ;YES. CDONCE=0? TSTB (R4) BNE DONE INCB (R4) ;SET CDONCE INCB 1(R4) ;SET CDBMS CALL GETBUF ;GET A BUFFER MOV R1,7(R4) ;SET CDOBCP CALL GETBUF PUSH #CDCOD ;SAVE DEV.CODE FOR GETPUT BR 44$ ;ISSUE READ REQUEST .ENDC .IFNDF $PL 43$: MOV @#DEVST,R1 MOVB #IOPS77,PLSPER(R1) ;REPORT TASK NOT SUPPORTED RETURN .ENDC .IFDF $PL ;WRITE REQUEST MADE FOR PL 43$: MOV PLBMSA,R1 ;RESET PLBMSA CLRB (R1) MOV TABPLA,R5 MOV 6(R0),LSB(R5) ;SET LSB IN TABLE MOV PLONAD,R3 ;GET ADD OF PLBMS IN R3 TSTB (R3) ;FIRST TIME THROUGH?? BNE DONE INCB (R3)+ ;YES. SET SW. INCB (R3) ;SET PLBMD CALL GETBUF ;GET A BUFFER PUSH #PLCOD ;SETUP FOR GETPUT SAVE DEV CODE BR 44$ .ENDC ; ; .SBTTL SPOOLED TASKS ; ;UNDER THE CURRENT IMPLEMENTATION, SPOOLED TASKS BASICALLY CONSIST OF A ;"CALL SERVICE ROUTINE" & A "INTERRUPT SERVICE ROUTINE" BESIDES THE ;OTHER SUPPORTING ROUTINES. THE 'CALL SEVICE ROUTINE' IS THE SPOOLER FOR ;OUTPUT TASKS(LP) AND DESPOOLER FOR INPUT TASKS(CD). CONVERSELY THE 'INTERRUPT ;SERVICE ROUTINE' IS THE DESPOOLER FOR OUTPUT TASKS(LP) & THE SPOOLER FOR ;INPUT TASKS(CD). ;IN GENERAL THE SPOOLER ROUTINE COPIES THE RECORD OF DATA RECEIVED, INTO ;THE CURRENT BUFFER & INDICSTES COMPLETION OF REQUEST TO CALLER. WHEN ;THE BUFFER IS FULL IT WRITES IT OUT ON THE NEXT AVAILABLE FREE BLOCK ;ON THE DISK. IT ALSO GETS A NEW BUFFER TO COPY THE NEXT RECORD. THE ONLY ;RECORD OF SPOOLED DATA MAINTAINED ARE THE LFB & LSB ENTRIES IN THE TABLE ;OTHER THAN THE FORWARD LINK IN EACH SPOOLED DATA BLOCK, CURRENT WORD ;POINTER, CURRENT BUFFER POINTER & NEXT BUFFER POINTER. THE LAST BLOCK IN ;A SPOOLED DATA FILE HAS A BACKWARD LINK WHICH EITHER POINTS TO THE LAST ;BLOCK OF THE PREVIOUS SPOOLED DATA FILE OR = TO '-1' IF NONE PRESENT. ;THERE CAN BE ONE OR MORE RECORDS IN A BLOCK. THE MAXM. SIZE OF A ;RECORD IS 252 WORDS. ;THE DESPOOLER ROUTINE UNPACKS THE BLOCKED DATA INTO RECORDS & SENDS ;IT TO THE CALLER OR DRIVER TASK. TO SPEED UP THIS PROCESS THE DESPOOLER ;ROUTINES ARE DOUBLE BUFFERED. BESIDES THE CURRENT WORD POINTER, CURRENT ;BUFFER POINTER & NEXT BUFFER POINTER THE ONLY OTHER INFORMATION MAINTAINED ;ARE THE CBN, CRP & NBN ENTRIES IN THE TABLE. DESPOOLING OPERATIONS ARE ;TERMINATED WHEN CBN=LSB AND THE TASK IDLE SWITCH IS SET. A RECORD WITH ;'0' AS THE FIRST WORD INDICATES THE ABSENCE OF ANY MORE RECORDS IN THAT ;BLOCK. ; ; CBN CURRENT BLOCK NUMBER ; CRP CURRENT RECORD POINTER ; NBN NEXT BLOCK NUMBER ; LFB LAST FILE BLOCK(NUMBER) ; LSB LAST SPOOLED BLOCK(NUMBER) ; .SBTTL LP INTERRUPT SERVICE ; ;THIS ROUTINE HANDLES COMPLETION OF I/O SOFTWARE INTERRUPT FROM THE ;DRIVER TASK IN PIREX. IT DESPOOLS THE SPOOLED DATA ONTO THE LP. ; .IFDF $LP LPDUMI: .BYTE 0 ;UNUSED LPONCE: .BYTE 0 ;ONCE ONLY SW LPBMD: .BYTE 0 ;BLOCK IN MOTION SW LPBUFS: .BYTE 0 ;EMPTY BUFFER COUNT LPCBIP: 0 ;CURRENT BUFFER POINTER LPWDIP: 0 ;CURRENT WORD POINTER LPOBIP: 0 ;NEXT BUFFER POINTER .ENDC ; ; .IFNDF $LP LPINT: MOV @#DEVST,R1 MOVB #IOPS77,LPSPER(R1) ;REPORT TASK NOT SUPPORTED RETURN .ENDC .IFDF $LP ; LPINT: MOV TABCRT,R1 BIS #LVL5,@#PS ;INHIBIT DISK INTERRUPTS CMP #-1,(R1) ;ANY MORE TO DO? BNE 1$ 11$: MOV LPONAD,R3 ;GET C(LPCBIP) IN R3 CLRB (R3)+ ;RESET SW.'S CLRB (R3)+ ;BUMP TO LPBUFS INCB (R3)+ ;RELEASE BUFF. MOV (R3),R3 CALL GIVBUF ;GIVE BACK BUFFER 2$: BIC #1,@#SPOLSW ;NO. SET LP IDLE SW 50$: RETURN 1$: TST (R1) ;YES. BLOCK IN MOTION? BNE 3$ 15$: MOV LPCPAD,R4 ;SK-124 YES. GET ADD OF LLPCPADBIP IN R2 MOV (R4),R3 ;RELEASE BUFFER CALL GIVBUF INCB -(R4) 10$: TSTB -1(R4) ;BLOCK READ IN? BEQ 4$ CALL WAITBK BR 10$ 4$: MOV TABCRT,R1 ;DEBUG MOV TABLE+NBN,TABLE+CBN ;SET CBN=NBN MOV #4,TABLE+CRP ;SET CRP MOV PC,R3 ;GET LPOBIP ADD. IN R3 ADD #LPOBIP-.,R3 MOV (R3),R4 ;GET C(LPOBIP) IN R3 & BUMP TO TWD1 MOV TWD1(R4),TABLE+NBN ;SET LP.NBN MOV LPCPAD,R2 ;GET ADD. OF LLPCPADBIP IN R2 MOV (R3),(R2)+ ;SET LPCBIP MOV (R3),(R2) ;SET LPWDIP ADD #4,(R2) BR 5$ ;SEND WRITE REQ IF NOT SHUT DOWN 3$: MOV LPCWAD,R2 ;GET ADD OF LPWDIP IN R2 MOV @(R2),-(SP) ADD #5,(SP) ;EVEN BYTE COUNT BIC #177401,(SP) ADD (SP),(R1) ;BUMP CRP ADD (SP)+,(R2) ;BUMP LPWDIP 5$: BIT #40000,@#SPOLSW ;SHUT DOWN? BEQ 2$ BIT #1,@#SPOLSW ;SHUT LP? BEQ 2$ BIT #10000,@#SPOLSW ;SHUT DESPOOLER BEQ 2$ TST @(R2) ;FIRST RECORD A .CLOSE? BNE 13$ CMP -2(R1),4(R1) ;ANY MORE DATA? BNE 14$ CALL 12$ ;NO. SET TABLE ENTRIES BR 11$ ;RESET SWITCHES & EXIT 14$: MOV LPONAD,R2 ;DEBUG;SK-124 GET LPBUFS ADRRESS ADD #2,R2 ;DEBUG;SK-124 CMPB #1,(R2) ;DEBUG;SK-124 ONE FREE BUFFER? BNE 15$ ;SK-124 TSTB -1(R2) ;DEBUG;SK-124 YES. BLOCK IN MOTION? BNE 15$ ;SK-124 CALL 9$ ;SK-124 NO. GET NEXT BLOCK BR 15$ ;SK-124 RELEASE BUFFER & WAIT FOR BLOCK TO COME IIN ; ; 13$: MOV @R2,R5 ;NO. SAVE BUFF ADD ON STACK CALL STUPLT ;SET UP TCB TO UNTI A LINE MOV TABCRT,R1 MOV (R2),R4 ;CHECK FOR BUFFER EMPTY MOV @(R2),-(SP) ;GET BYTE COUNT ADD #5,(SP) ;EVEN BYTE COUNT BIC #177401,(SP) ADD (SP)+,R4 ;BUMP R4 TO POINT TO PT WORD OF NEXT MOV PC,R2 ;NO. GET ADD OF LPBUFS IN R2 ADD #LPBUFS-.,R2 TST (R4) ;LAST RECORD? BEQ 6$ CMP #-1,(R4) BEQ 6$ CMPB #1,(R2) ;LPBUFS=1 BNE 50$ TSTB -(R2) ;YES. BLOCK IN NEXT? BNE 50$ CMP -2(R1),4(R1) ;NO. MORE TO DOE (CBN=LSB) BEQ 50$ CALL 9$ ;SK-124 GET NEXT BLOCK RETURN ;RETURN TO CALLER (BR-145) ; ; ;BUFFER EMPTY; TEST IF MORE BLOCK TO DO? 6$: CMP -2(R1),4(R1) ;MORE TO DO? (CBN=LSB) BEQ 7$ CLR (R1) ;SK-124 SET CRP=0 CMPB #1,(R2) ;LPBUFS=1? BNE 8$ TSTB -(R2) ;BLOCK IN TRANSIT? BNE 8$ ;SK-124 CALL 9$ ;SK-124 GET NEXT BLOCK 8$: RETURN ;RETURN TO CALLER (BR-145) ;NO MORE BLOCKS TO DO 7$: CALL 12$ ;SET TABLE ENTRIES RETURN ;RETURN TO CALLER (BR-145) ; ; ;GET NEXT BLOCK 9$: PUSH R1 PUSH R2 CALL GETBUF ;YES. GET BUFFER & READ NEXT BLOCK MOV R1,R4 ;SAVE BUFAD IN R4 POP R2 POP R1 MOV R4,LPOBIP ;SET LPOBIP INCB (R2) ;SET LPBMS SW MOV #LPCOD,R3 ;GET DEV.CODE IN R3. FOR GETBLK MOV R1,R2 ;GET LP.CRP ADD. IN R2 CALL GETBLK ;GET BLOCK FROM DISK RETURN ;SK-124 ; 12$: MOV #-1,@R1 ;SET CRP=-1 MOV #-1,6(R1) ;SET LFB=-1 RETURN ; .ENDC .SBTTL LP CALL SERVICE ; ;THIS ROUTINE SERVICES CALLS TO OUTPUT DATA ONTO THE LP. IT SPOOLS THE ;DATA SENT BY THE CALLER ONTO THE DISK. ; .IFDF $LP LPDUMC: .BYTE 0 ;UNUSED LPBMS: .BYTE 0 ;BLOCK IN MOTION SW LPCBCP: 0 ;CURRENT BUFFER POINTER LPWDCP: 0 ;CURRENT WORD POINTER LPOBCP: 0 ;NEXT BUFF POINTER(DUMMY) .ENDC ; ; .IFNDF $LP LPCALL: MOV @#DEVST,R1 MOVB #IOPS77,LPSPER(R1) ;(SCR-144)REPORT TASK NOT SUPPORTED CALL DEQREQ .ENDC .IFDF $LP LPCALL: CMP -(R1),-(R1) ;POINT R1 TO LPWDCP BIT #20000,@#SPOLSW ;SHUT SPOOLER? BEQ 10$ PUSH R1 ;SAVE R1. NO MOV (R1),R1 ;GET CONTENTS OF LPWDCP IN R1,R4 MOV R1,R4 MOV 10(R0),R3 ;GET CALLER BUF. ADD. IN R3 ASL R3 ;RELOCATE ADD. ADD @#MEMSIZ,R3 MOVB (R3),R2 ;GET BYTE COUNT FROM BUFFER IN R2 ADD #5,R2 ;ADD HWD BYTE COUNT + EVEN BYTE COUNT BIC #177401,R2 ADD R2,R1 ;BUMP LPWDCP BY THE SIZE OF NEXT RECD. MOV (SP),R5 ;GET LPWDCP ADD. IN R4 PUSH -(R5) ;POINT TO LPCBCP & SAVE CONT. OF LPCBCP ON STACK ASR R2 ;CONVERT TO WORD COUNT SUB (SP)+,R1 ;COMPUTE SPACE REM. CMP #770,R1 ;SPACE LEFT? BLT 4$ CALL COPBUF ;COPY CALLER BUFFER POP R4 ;TEMP SAVE R1 IN R2 CALL 6$ ;CHECK FOR .CLOSE BR 8$ ;NO ; 10$: MOV #-600,4(R0) ;SPOOLER SHUT DOWN. REPORT PUSH R1 ;DUMMY JMP DEQRQ ;LAST RECORD WAS NOT A .CLOSE 8$: MOV LPCBAD,R1 ;POINT R1 TO LPCBCP (BR-145) MOV R1,R2 ;SAVE IN R2 TST (R1)+ ;BUMP R1 LPWDCP MOV (R1),R1 ;GET CURRENT WORD ADD. IN R1 SUB (R2),R1 ;GET REMAINNING # OF WORDS CMP #770,R1 ;SPACE LEFT? BGT 2$ 9$: MOV PC,R1 ;GET ADD. OF LPWDCP IN R1 ADD #LPWDCP-.,R1 CLR @(R1) ;NO. PUT BUFFER ON DISK CALL FINDBK ;GET DISK BLOCK # PUSH R1 ;SAVE BLOCK # ON STACK MOV LPCBCP,R2 ;GET C(LPCBIP) IN R2 MOV (SP),TWD1(R2) ;SAVE BLOCK # IN TWD1 MOV #LPCOD,R3 ;GET LP.DEV CODE IN R3 MOV LPBMSA,R1 ;SET LPBMSA INCB (R1) CALL PUTBLK ;PUT BUFF. ON DISK MOV LPCBAD,R4 ;GET ADD. OF LLPCBADBCP IN R3&R4 3$: CALL GETBUF ;GET A NEW BUF MOV R1,(R4)+ ;SET LPCBCP=BUFAD POP (R1) ;SET BLOCK # IN HWD0 OF NEW BUFF. ADD #4,R1 ;BUMP R2 TO WORD 2 OF BUF MOV R1,(R4) ;SET LPWDCP 2$: CALL DEQREQ ;DEQUE REQUEST & EXIT IN WAIT STATE 4$: POP R1 ;RESTORE ADD. OF CURRENT WORD IN R1 PUSH R3 ;SAVE R3,R2 PUSH R2 CLR @(R1) ;SET BUFF. END SW CALL FINDBK ;GET DISK BLOCK # PUSH R1 ;SAVE BLOCK # CALL GETBUF ;GET A BUFF. MOV (SP),(R1) ;SET BLOCK # IN HWD0 OF NEW BUFF. MOV LPCBAD,R4 ;GET ADD. OF LLPCBADBCP IN R4 PUSH (R4) PUSH (R4) ;SAVE CONT. OF LPCBCP ADD #TWD1,(SP) ;BUMP TO TWD1 MOV 4(SP),@(SP)+ ;SET LINK IN OLD BUFF. MOV R1,(R4)+ ;SET LPCBCP & BUMP TO LPWDCP ADD #4,R1 ;POINT TO WORD 2 IN BUFF. PUSH R4 ;SAVE LPWDCP ADD. ON STACK MOV R1,(R4) ;SET LPWDCP MOV R1,R4 ;GET CONT. OF LPWDCP MOV 6(SP),R2 ;RESTORE R3,R2 MOV 10(SP),R3 CALL COPBUF ;COPY CALLER BUFFER POP R4 ;SAVE LPWDCP ADD. IN R4 POP R2 ;CONT. OF LPCBCP ON STACK TOP??? MOV #LPCOD,R3 ;GET DEV.CODE IN R3. FOR PUTBLK ADD #6,SP ;CLEAN STACK PUSH R4 ;SAVE R5 MOV LPBMSA,R1 ;SET LPBMSA INCB (R1) CALL PUTBLK ;PUT BUFF. ON DISK POP R4 ;TEMP SAVE R1 CALL 6$ ;CHECK FOR .CLOSE BR 2$ 6$: MOV R4,R1 ;SAVE R4 MOV (R1),R4 ;GET C(LPWDCP) IN R4 CMP #104001,-6(R4) ;TEST FOR EOF (.CLOSE) (BR-145) BNE 7$ ;BRANCH IF NOT EOF (BR-145) MOV R1,R4 ;RESTORE R4 ADR TABLE+LFB,R2 ;GET LP.LFB ADD. IN R2 MOV LPCBAD,R1 PUSH (R2) ;SAVE OLD LFB MOV @(R1),(R2) ;SET LFB IN TABLE MOV (R1),R1 POP 2(R1) ;SET OLD LFB IN BUFFER MOV #-1,TWD0(R1) ;SET EOF CODE IN BUFFER TST (SP)+ ;RETURN TO 9 (NOT SUB RETURN) BR 9$ 7$: RETURN ; .ENDC COPBUF: CMP SDCTSV,@#CTLCT ;DEBUG BNE 1$ MOV (R3)+,(R4)+ ;COPY CALLER BUFFER DEC R2 BNE COPBUF MOV R4,@2(SP) 1$: RETURN ; .SBTTL PL INTERRUPT SERVICE ; ;THIS ROUTINE HANDLES COMPLETION OF I/O SOFTWARE INTERRUPT FROM THE ;DRIVER TASK IN PIREX. IT DESPOOLS THE SPOOLED DATA ONTO THE XY PLOTTER. ; .IFDF $PL PLDUMI: .BYTE 0 ;UNUSED PLONCE: .BYTE 0 ;ONCE ONLY SW PLBMD: .BYTE 0 ;BLOCK IN MOTION SW PLBUFS: .BYTE 0 ;EMPTY BUFFER COUNT PLCBIP: 0 ;CURRENT BUFFER POINTER PLWDIP: 0 ;CURRENT WORD POINTER PLOBIP: 0 ;NEXT BUFFER POINTER .ENDC ; ; .IFNDF $PL PLINT: MOV @#DEVST,R1 MOVB #IOPS77,PLSPER(R1) ;REPORT TASK NOT SUPPORTED RETURN .ENDC .IFDF $PL ; PLINT: MOV TABPDT,R1 BIS #LVL5,@#PS ;INHIBIT DISK INT. CMP #-1,(R1) ;ANY MORE TO DO? BNE 1$ 11$: MOV PLONAD,R3 ;GET C(PLCBIP) IN R3 CLRB (R3)+ ;RESET SW.'S CLRB (R3)+ ;BUMP TO PLBUFS INCB (R3)+ ;RELEASE BUFF. MOV (R3),R3 CALL GIVBUF ;GIVE BACK BUFFER 2$: BIC #4,@#SPOLSW ;NO. SET PL IDLE SW 50$: RETURN 1$: TST (R1) ;YES. BLOCK IN MOTION? BNE 3$ 15$: MOV PLCIAD,R4 ;SK-124 YES. GET ADD OF PLCBIP IN R2 MOV (R4),R3 ;RELEASE BUFFER CALL GIVBUF INCB -(R4) 10$: TSTB -1(R4) ;BLOCK READ IN? BEQ 4$ CALL WAITBK ;NO BR 10$ 4$: MOV TABPDT,R2 MOV 2(R2),-2(R2) ;SET CBN=NBN MOV #4,(R2) ;SET CRP MOV PLOIAD,R3 ;GET PLOBIP ADD. IN R3 MOV (R3),R4 ;GET C(PLOBIP) IN R3 & BUMP TO TWD1 MOV TWD1(R4),2(R2) ;SET PL.NBN MOV R2,R1 ;SAVE PL.CRP ADD. IN R1 MOV PLCIAD,R2 ;GET ADD. OF PLCBIP IN R2 MOV (R3),(R2)+ ;SET PLCBIP MOV (R3),(R2) ;SET PLWDIP ADD #4,(R2) BR 5$ ;SEND WRITE REQ IF NOT SHUT DOWN 3$: MOV PLWDAD,R2 ;GET ADD OF PLWDIP IN R2 MOV @(R2),-(SP) ADD #5,(SP) ;EVEN BYTE COUNT BIC #177401,(SP) ADD (SP),(R1) ;BUMP CRP ADD (SP)+,(R2) ;BUMP LPWDIP 5$: BIT #40000,@#SPOLSW ;SHUT DOWN? BEQ 2$ BIT #4,@#SPOLSW ;SHUT PL? BEQ 2$ BIT #10000,@#SPOLSW ;SHUT DESPOOLER BEQ 2$ TST @(R2) ;LAST RECORS? BNE 13$ CMP -2(R1),4(R1) ;YES. ANY MORE DATA? BNE 14$ CALL 12$ ;NO. SET TABLE ENTRIES BR 11$ 14$: MOV PLONAD,R2 ;SK-124 GET PLBUFS ADDRESS ADD #2,R2 ;SK-124 CMPB #1,(R2) ;SK-124 ONE FREE BUFFER? BNE 15$ ;SK-124 TSTB -1(R2) ;SK-124 YES. BLOCK IN MOTION BNE 15$ ;SK-124 CALL 9$ ;SK-124 NO. GET NEXT BLOCK BR 15$ ;SK-124 WAIT FOR BLOCK TO COME IN ; 13$: MOV @R2,R5 ;NO. SAVE BUFF ADD ON STACK CALL STUPPT ;SET UP TCB TO UNTI A LINE MOV PC,R1 ;GET PL.CRP ADD. IN R1 ADD #TABLE+PLTEOF-.+4,R1 MOV (R2),R4 ;CHECK FOR BUFFER EMPTY MOV @(R2),-(SP) ;GET BYTE COUNT ADD #5,(SP) ;EVEN BYTE COUNT BIC #177401,(SP) ADD (SP)+,R4 ;BUMP R4 TO POINT TO PT WORD OF NEXT MOV PC,R2 ;NO. GET ADD OF PLBUFS IN R2 ADD #PLBUFS-.,R2 TST (R4) ;LAST RECORD? BEQ 6$ CMP #-1,(R4) BEQ 6$ CMPB #1,(R2) ;PLBUFS=1 BNE 50$ TSTB -(R2) ;YES. BLOCK IN NEXT? BNE 50$ CMP -2(R1),4(R1) ;NO. MORE TO DOE (CBN=LSB) BEQ 50$ CALL 9$ ;SK-124 GET NEXT BLOCK BR 50$ ;SK-124 ; ;BUFFER EMPTY; TEST IF MORE BLOCK TO DO? 6$: CMP -2(R1),4(R1) ;MORE TO DO? (CBN=LSB) BEQ 7$ CLR (R1) ;SET CRP=0 CMPB #1,(R2) ;PLBUFS=1? BNE 8$ TSTB -(R2) ;BLOCK IN TRANSIT? BNE 8$ ;SK-124 CALL 9$ 8$: JMP 50$ ;SK-125 ;NO MORE BLOCKS TO DO 7$: CALL 12$ ;SET TABLE ENTRIES BR 8$ ; ; ;GET NEXT BLOCK FROM DISK. 9$: PUSH R1 PUSH R2 CALL GETBUF ;YES. GET BUFFER & READ NEXT BLOCK MOV R1,R4 ;SAVE BUFAD IN R4 POP R2 POP R1 MOV PLOIAD,R3 ;GET ADD. OF PLOBIP IN R3 MOV R4,(R3) ;SET PLOBIP INCB (R2) ;SET PLBMS SW MOV #PLCOD,R3 ;GET DEV.CODE IN R3. FOR GETBLK MOV R1,R2 ;GET PL.CRP ADD. IN R2 CALL GETBLK ;GET BLOCK FROM DISK RETURN ;SK-124 ; 12$: MOV #-1,@R1 ;SET CRP=-1 MOV #-1,6(R1) ;SET LFB=-1 RETURN ; .ENDC ; .SBTTL PL CALL SERVICE ; ;THIS ROUTINE SRVICES CALLS TO OUTPUT DATA ONTO THE XY PLOTTER. IT ;SPOOLS THE DATA SENT BY THE CALLER ONTO THE DISK. ; .IFDF $PL PLDUMC: .BYTE 0 ;UNUSED PLBMS: .BYTE 0 ;BLOCK IN MOTION SW PLCBCP: 0 ;CURRENT BUFFER POINTER PLWDCP: 0 ;CURRENT WORD POINTER PLOBCP: 0 ;NEXT BUFF POINTER(DUMMY) .ENDC ; ; .IFNDF $PL PLCALL: MOV @#DEVST,R1 MOVB #IOPS77,PLSPER(R1) ;(SCR-144)REPORT TASK NOT SUPPORTED CALL DEQREQ .ENDC .IFDF $PL PLCALL: CMP -(R1),-(R1) ;POINT R1 TO PLWDCP BIT #20000,@#SPOLSW ;SHUT SPOOLER? BEQ 10$ PUSH R1 ;SAVE R1. NO MOV (R1),R1 ;GET CONTENTS OF PLWDCP IN R1,R4 MOV R1,R4 MOV 10(R0),R3 ;GET CALLER BUF. ADD. IN R3 ASL R3 ;RELOCATE ADD. ADD @#MEMSIZ,R3 MOVB (R3),R2 ;GET BYTE COUNT FROM BUFFER IN R2 ADD #5,R2 ;ADD HWD BYTE COUNT + EVEN BYTE COUNT BIC #177401,R2 ADD R2,R1 ;BUMP PLWDCP BY THE SIZE OF NEXT RECD. MOV (SP),R5 ;GET PLWDCP ADD. IN R4 PUSH -(R5) ;POINT TO PLCBCP & SAVE CONT. OF PLCBCP ON STACK ASR R2 ;CONVERT TO WORD COUNT SUB (SP)+,R1 ;COMPUTE SPACE REM. CMP #770,R1 ;SPACE LEFT? BLT 4$ CALL COPBUF ;COPY CALLER BUFFER POP R4 ;TEMP SAVE R1 IN R2 CALL 6$ ;CHECK FOR .CLOSE BCC 8$ ;NO BR 9$ ;YES ; 10$: MOV #-600,4(R0) ;SPOOLER SHUT DOWN. REPORT PUSH R1 ;DUMMY JMP DEQRQ ;LAST RECORD WAS NOT A .CLOSE 8$: MOV PLCBAD,R1 ;POINT R1 TO PLCBCP (BR-145) MOV R1,R2 ;SAVE IN R2 TST (R1)+ ;BUMP R1 PLWDCP MOV (R1),R1 ;GET CURRENT WORD ADD. IN R1 SUB (R2),R1 ;GET REMAINNING # OF WORDS CMP #770,R1 ;SPACE LEFT? BGT 2$ 9$: MOV PC,R1 ;GET ADD. OF PLWDCP IN R1 ADD #PLWDCP-.,R1 CLR @(R1) ;NO. PUT BUFFER ON DISK CALL FINDBK ;GET DISK BLOCK # PUSH R1 ;SAVE BLOCK # ON STACK MOV PLCBCP,R2 ;GET C(PLCBIP) IN R2 MOV (SP),TWD1(R2) ;SAVE BLOCK # IN TWD1 MOV #PLCOD,R3 ;GET PL.DEV CODE IN R3 MOV PLBMSA,R1 ;SET PLBMSA INCB (R1) CALL PUTBLK ;PUT BUFF. ON DISK MOV PLCBAD,R4 ;GET ADD. OF PLCBCP IN R3&R4 3$: CALL GETBUF ;GET A NEW BUF MOV R1,(R4)+ ;SET PLCBCP=BUFAD POP (R1) ;SET BLOCK # IN HWD0 OF NEW BUFF. ADD #4,R1 ;BUMP R2 TO WORD 2 OF BUF MOV R1,(R4) ;SET PLWDCP 2$: CALL DEQREQ ;DEQUE REQUEST & EXIT IN WAIT STATE 4$: POP R1 ;RESTORE ADD. OF CURRENT WORD IN R1 PUSH R3 ;SAVE R3,R2 PUSH R2 CLR @(R1) ;SET BUFF. END SW CALL FINDBK ;GET DISK BLOCK # PUSH R1 ;SAVE BLOCK # CALL GETBUF ;GET A BUFF. MOV (SP),(R1) ;SET BLOCK # IN HWD0 OF NEW BUFF. MOV PLCBAD,R4 ;GET ADD. OF PLCBCP IN R4 PUSH (R4) PUSH (R4) ;SAVE CONT. OF PLCBCP ADD #TWD1,(SP) ;BUMP TO TWD1 MOV 4(SP),@(SP)+ ;SET LINK IN OLD BUFF. MOV R1,(R4)+ ;SET PLCBCP & BUMP TO PLWDCP ADD #4,R1 ;POINT TO WORD 2 IN BUFF. PUSH R4 ;SAVE PLWDCP ADD. ON STACK MOV R1,(R4) ;SET PLWDCP MOV R1,R4 ;GET CONT. OF PLWDCP MOV 6(SP),R2 ;RESTORE R3,R2 MOV 10(SP),R3 CALL COPBUF ;COPY CALLER BUFFER POP R4 ;SAVE PLWDCP ADD. IN R4 POP R2 ;CONT. OF PLCBCP ON STACK TOP??? MOV #PLCOD,R3 ;GET DEV.CODE IN R3. FOR PUTBLK ADD #6,SP ;CLEAN STACK PUSH R4 ;SAVE R5 MOV PLBMSA,R1 ;SET PLBMS INCB (R1) CALL PUTBLK ;PUT BUFF. ON DISK POP R4 ;TEMP SAVE R1 CALL 6$ ;CHECK FOR .CLOSE BCC 2$ BR 9$ ;YES 6$: MOV R4,R1 ;SAVE R4 MOV 10(R0),R4 ;EOF TEST. RECOMPUTE BUFFER HEADER ASL R4 ADD @#MEMSIZ,R4 ;NOW HAVE ADDR OF BUFFER TST (R4) ;IF MINUS, IS EOF BPL 7$ ;NOT NEG, BRANCH OUT TO END MOV R1,R4 ;RESTORE R4 ADR TABLE+PLTEOF+LFB,R2 ;GET PL.LFB ADD. IN R2 MOV PLCBAD,R1 PUSH (R2) ;SAVE OLD LFB MOV @(R1),(R2) ;SET LFB IN TABLE MOV (R1),R1 POP 2(R1) ;SET OLD LFB IN BUFFER MOV #-1,TWD0(R1) ;SET EOF CODE IN BUFFER SEC 7$: RETURN ; .ENDC .SBTTL CD INTERRUPT SERVICE ; ;THIS ROUTINE HANDLES THE COMPLETION OF I/O SOFTWARE INTERRUPT FROM ;THE DRIVER TASK IN PIREX. IT SPOOLS THE CARDS ONTO THE DISK. ; .IFDF $CD CDDUMI: .BYTE 0 ;UNUSED CDBMS: .BYTE 0 ;BLOCK IN MOTION SW CDCNTI: .BYTE 0 ;CARD COUNT CDBFS: .BYTE 0 ;BUFFER FULL SW CDCBIP: 0 ;CURRENT BUFFER POINTER CDWDIP: 0 ;CURRENT WORD POINTER CDOBIP: 0 ;NEXT BUFFER POINTER .ENDC .IFNDF $CD CDINT: MOV @#DEVST,R1 MOVB #IOPS77,CDSPER(R1) ;REPORT TASK NOT SUPPORTED RETURN .ENDC .IFDF $CD ; ; CDINT: BIT #40000,@#SPOLSW ;SHUT DOWN? BEQ 1$ MOV CDINTA,R1 BIT #2,@#SPOLSW ;SHUT CD? BEQ 1$ BIT #20000,@#SPOLSW ;SHUT SPOOLING? BEQ 1$ MOV -4(R1),R2 ;POINT TO 1ST WORD IN RECORD SUB #120,R2 ;POINT TO WORD 1 CMP #CDEOD,(R2) ;EOD CARD? BEQ 2$ TSTB -7(R1) ;NO. CDBFS=0? BNE 3$ 4$: MOV -4(R1),R5 ;YES. SAVE BUFAD CALL STUPCT ;SET UP TCB MOV CDINTA,R1 ;RESTORE ADD. OF CDINTA IN R1 ADD #124,-4(R1) ;BUMP CDWDIP INCB -10(R1) ;INCREMENT CARD COUNT TSTB -7(R1) ;CDBFS=0? BNE 5$ CMPB #6,-10(R1) ;CDCNTI=5? BNE 7$ INCB -7(R1) ;SET BUFFER FULL SW. 7$: RETURN ; 1$: BIC #2,@#SPOLSW BR 7$ ; ; 5$: CLRB -7(R1) ;RESET CDBFS INCB -11(R1) ;SET CDBMS MOV #CDCOD,R3 ;SET UP FOR PUTBLK POP R2 CALL PUTBLK BR 7$ ; 8$: TST (SP)+ ;PRUNE STACK 3$: PUSH -6(R1) ;SAVE BUFAD ADD #TWD1,(SP) BR 6$ ; 2$: CMP -(R2),-(R2) ;SET BUFEND SW MOV #-1,@R2 ADR TABLE+CDTEOF+LFB,R2 ;SET LFB IN TAABLE PUSH -6(R1) MOV (R2),R1 ;SAVE OLD LFB MOV @(SP),(R2) ADD #2,(SP) ;BUMP TO HWD1 MOV R1,@(SP) ;SET LFB IN BUFFER HWD1 ADD #772,(SP) ;BUMP TO TWD0 MOV #-1,@(SP) ;SET EOD CODE IN BUFF. ADD #2,(SP) ;BUMP TO TWD1 MOV CDINTA,R1 6$: CLRB -10(R1) INCB -7(R1) ;NO. SET IT CALL FINDBK ;GET A BLOCK ON DISK MOV R1,@(SP)+ ;SET BLOCK # IN OLD BUFF. PUSH R1 ;SAVE BLOCK # CALL GETBUF ;GET A BUFF. POP (R1) ;SET BLOCK # IN HWD0 OF NEW BUFF. MOV CDCPAD,R2 ;SAVE CDCPAD & SET NEW VALUE PUSH (R2) MOV R1,(R2)+ MOV R1,(R2) ;SET CDWDIP ADD #4,(R2) MOV CDINTA,R1 BR 4$ ; .ENDC ; .SBTTL CD CALL SERVICE ; ;THIS ROUTINE SERVICES CALLS TO READ A CARD. IT DESPOOLS THE SPOOLED ;DATA CARDS. DISK INTERRUPTS ARE INHIBITED WHEN THIS ROUTINE IS ;EXECUTED. ; .IFDF $CD CDCNTC: .BYTE 0 ;CARD COUNT CDONCE: .BYTE 0 ;ONCE ONLY SW CDBMD: .BYTE 0 ;BLOCK IN MOTION SW CDBUFS: .BYTE 0 ;EMPTY BUFFER COUNT CDCBCP: 0 ;CURRENT BUFFER POINTER CDWDCP: 0 ;CURRENT WORD POINTER CDOBCP: 0 ;NEXT BUFFER POINTER .ENDC ; .IFNDF $CD CDCALL: MOV @#DEVST,R1 MOVB #IOPS77,CDSPER(R1) ;(SCR-144)REPORT TASK NOT SUPPORTED CALL DEQREQ .ENDC .IFDF $CD CDCALL: MOV TABDCT,R2 ;CD.CRP=-1? BIT #10000,@#SPOLSW ;DESPOOLER ENABLED? BEQ 2$ BIS #LVL5,@#PS ;YES. INHIBIT DISK INT.(BR-120) CMP #-1,(R2) BEQ 1$ TST (R2) ;CRP=0? BEQ 11$ 4$: MOV -4(R1),R4 ;NO. GET C(CDWDCP) IN R4 MOV 10(R0),R3 ;GET CALLER BUFF. ADD ASL R3 ;RELOC. ADD. ADD @#MEMSIZ,R3 MOV #CDSIZE/2,R5 ;COPY A CARD INTO CALLERS BUFF. CMP #-1,(R4) ;FIRST CARD EOD? BNE 3$ TSTB -10(R1) ;EOD CARD. NEXT BLOCK IN? BNE 11$ ;BRANCH IF BLOCK COMING TSTB -7(R1) ;NO. BLOCK ALREADY IN? BEQ 11$ ;BRANCH IF YES CMP -2(R2),4(R2) ;NO. MORE BLOCKS ON DISK? BEQ 17$ ;BRANCH IF NO CALL 15$ ;YES. GET BLOCK MOV CDCAAD,R1 BR 11$ 3$: MOV (R4)+,(R3)+ DEC R5 BNE 3$ MOV R4,-4(R1) ;DONE. SET CDWDCP ADD #CDSIZE,(R2) ;BUMP CRP IN TABLE MOV -4(R1),R4 ;MORE CARDS IN BUFFER? CMP #-1,(R4) BEQ 5$ INCB -12(R1) ;FIRST COUNT CARD GIVEN CMPB #6,-12(R1) BEQ 5$ CMPB #1,-7(R1) ;CDBUFS=1? BNE 6$ TSTB -10(R1) ;YES. CDBMS=0? BNE 6$ MOV TABDCT,R2 ;RESTORE ADD. OF CD.CRP IN R2 CMP -2(R2),4(R2) ;YES. MORE CARDS ON DISK? BEQ 6$ 14$: CALL 15$ ;GET BLOCK 6$: CALL DEQREQ ;EXIT ; ; 2$: MOV #-700,R1 ;DESPOOLER DISABLED. REPORT CALL DEQRQ ; ;NO CARDS ON DISK. SET CODE IN TABLE & SAVE THE REQUEST NODE ; 1$: BIT #134400,@#177160 ;CHECK IF REAL ERROR (BR-120) BEQ 25$ ;NOT A REAL ERROR (BR-119) MOV @#DEVST,R1 ;SET ERROR CODE IN PIREX TABLE ADD #CDCOD*3*2+5,R1 MOVB #1,(R1) 25$: MOV RESTAD,R1 ;SETUP FOR REINSERTING REQUEST AFTER 1 SEC. MOV @#CLTABL,R2 MOV #CDTIME,CDCOD*4(R2) ;1000/60 SEC INTERVAL MOV R1,CDCOD*4+2(R2) ;GOTO RESTRQ ON TIMER RUNOUT MOV SPSTAD,R3 ;SAVE TCBP MOV -(R3),-(R1) MOV -(R3),-(R1) CALL DEQRQ0 ; 11$: MOV TABDCT,R2 9$: TSTB -10(R1) ;CDBMS=0? BEQ 10$ CALL WAITBK BR 9$ 10$: CALL 12$ ;UPDATE POINTERS MOV CDCAAD,R1 ;RESTORE R1 BR 4$ ; ;PROCESSING NEW BUFFER. MUST UPDATE POINTERS 5$: CLRB -12(R1) ;RESET CDCNTC MOV TABDCT,R2 ;CBN=LSB? CMP 4(R2),-2(R2) BEQ 7$ CLR (R2) ;SET CRP=0 FOR NOW TSTB -10(R1) ;BLOCK READ IN. CDBMS=0? BNE 6$ TSTB -7(R1) ;NEXT BLOCK READ IN? BNE 14$ ;GET BLOCK IF NO CALL 12$ ;YES. UPDATE POINTERS BR 6$ ; 7$: CALL 16$ BR 6$ ; 17$: CALL 16$ BR 1$ ; ; 12$: MOV R1,R3 MOV -6(R3),R4 ;GET OLD BUFAD IN R4 MOV -2(R3),-6(R3) ;YES. SET CDCBCP=CDOBCP MOV -2(R3),-4(R3) ;SET CDWDCP MOV #4,(R2) ;SET CRP IN TABLE ADD @R2,-4(R3) MOV 2(R2),-2(R2) ;SET CBN=NBN PUSH -2(R3) ;SET CD.NBN IN TABLE ADD #TWD1,(SP) MOV @(SP)+,2(R2) INCB -7(R3) ;RELEASE CURRENT BUFFER MOV CDOBAD,R1 ;SET CDOBAD MOV R4,(R1) MOV R4,R1 ;RESET HWDS IN BUFF. CLR (R1)+ CLR (R1) CMP -2(R2),4(R2) ;NBN SPOOLED? BEQ 24$ ;BRANCH TO GET BLOCK IF YES 13$: INCB -10(R3) ;SET CDBMS MOV #CDCOD,R3 ;GET BLOCK FROM DISK CALL GETBLK 24$: RETURN ; 15$: INCB -10(R1) ;YES. SET CDBMS MOV #CDCOD,R3 ;GET CD.DEV.CODE IN R3 MOV CDOBCP,R4 ;GET BUFF. ADD. IN R4 CALL GETBLK ;GET BLOCK FROM DISK RETURN ; 16$: MOV CDCBAD,R1 ;RETURN BUFFER MOV (R1),R3 CLR (R1) CALL GIVBUF MOV CDOBAD,R1 MOV (R1),R3 CLR (R1) CALL GIVBUF MOVB #2,CDBUFS MOV #-1,6+TABLE+CDTEOF+CRP ;SET LFB=-1 MOV #-1,TABLE+CDTEOF+CRP CLRB CDBUFS-2 ;RESET CDONCE RETURN .ENDC ; .SBTTL PUTBLK/GETBLK/RESTRQ ; ;THIS ROUTINE READS A BLOCK FROM DISK INTO CORE. A SOFTWARE INTERRUPT ;IS ISSUED WHEN THIS OPERATION IS COMPLETED. ; ;CALLING SEQUENCE: MOV #-COD,R3 ; ADR BUFAD,R4 ; ADR -.CRP,R2 ; CALL GETBLK ; GETBLK: PUSH R3 ;SAVE DEV CODE PUSH #READF ;SAVE DISK FUNCT PUSH R4 ;SAVE BUFF ADD PUSH 2(R2) ;SAVE BLOCK #(NBN) CALL GETRKT ;GET RK TCB BR GETCOM ; ;THIS ROUTINE WRITES A BLOCK ONTO DISK FROM CORE. A SOFTWARE INTERRUPT ;IS ISSUED WHEN THIS OPERATION IS COMPLETED ; ;CALLING SEQUENCE: MOV #-COD,R3 ; ADR BUFAD,R2 ; CALL PUTBLK ; PUTBLK: CALL GETRKT ;GET A TCB PUSH R3 ;SAVE CALLING DEV CODE PUSH #WRITEF ;SAVE DISK FUN. PUSH R2 ;SAVE BUFFER ADD PUSH (R2) ;SAVE BLOCK # GETCOM: CALL GETPUT ;PUT BUFFER ON DISK ADD #10,SP ;CLEAN UP STACK RETURN ; ;THE FOLLOWING ROUTINE IS USED BY THE 'CD CALL SERVICE ROUTINE' WHEN THERE ;ARE NO CARDS IN THE SPOOLER. IT SAVES THE TCBP INFO & SETS UP A TIMER ;REQUEST. WHEN THE TIMER RUNS OUT IT RECHECKS TO SEE IF ANY CARDS ARE ;PRESENT. IF NOT IT RESTARTS THE TIMER. IF CARDS ARE PRESENT IT PROCESSES THE ;READ REQUEST. ; ;THIS ROUTINE REINSERTS THE REQUEST PRESENT IN 'RESTRQ-2' INTO THE SPOOLER TRL ;ON GAINING CONTROL FROM TIMER RUNOUT ; .IFDF $CD .BLOCK 2 RESTRQ: MOV CDONAD,R1 ;CHECK IF CD ON? CMPB #2,(R1) BNE 1$ MOV SPSTAD,R1 ;IS SPOOLER BUSY? MOV RESTAD,R0 .INH TST -2(R1) BNE 4$ MOV -(R0),-(R1) ;NO. SET STATUS TO RUN. SAVE TCBP MOV -(R0),-(R1) CLR (R0)+ CLR (R0)+ CMP (R1)+,(R1)+ MOV R1,-12(R1) ;SETUP PC ON STACK CLR -10(R1) ;SET PS ON STACK MOV @#ATLNP,R3 MOV SPCOD*2(R3),R2 ;GET ATL NODE ADDRESS BIC #17,6(R2) ;SET STATUS TO RUN SUB #26,R1 ;SET SP IN ATL NODE MOV R1,4(R2) BR 3$ 4$: MOV @#LISTHD,R1 ;GET LISTHD ADD. IN R1 MOV SPCOD*4+2(R1),R1 MOV @#POL.LH,R2 ;GET POL.LH ADD. IN R2 MOV (R2),R5 ;YES. GET ADD. OF NODE MOV -(R0),6(R5) MOV -(R0),4(R5) CLR (R0)+ ;RESET SAVED TCBP IN 'RESTRQ-2/4' CLR (R0)+ ;DELETE NODE FROM POOL MOV (R5),R2 MOV R2,@2(R5) ;SET FORWARD POINTER MOV 2(R5),2(R2) ;SET BACKWARD POINTER ;PUT NODE IN SPOOLER DEQUE MOV @(R1),(R5) ;SET FORWARD POINTER OF NODE MOV (R1),2(R5) ;SET BACKWARD POINTER MOV R5,@(R1) ;SET FORWARD POINTER OF LAST NODE MOV R5,(R1) ;SET BACKWARD POINTER OF LISTHEAD 3$: .ENA RETURN ; 1$: MOV @#CLTABL,R2 ;SETUP TIMER MOV #CDTIME,CDCOD*4(R2) RETURN ; .ENDC ; ; .SBTTL ADDRESS TABLE ; ADRTBL: RKCAD: .WORD RKTCBP .IFDF $LP LPONAD: .WORD LPONCE .ENDC TABPLA: .WORD TABLE+PLTEOF .IFDF $PL PLONAD: .WORD PLONCE .ENDC BTMPAD: .WORD BTMPST STBKNA: .WORD STBKNM TABLAD: .WORD TABLE TABPCB: .WORD TABLE+CBN TABPLC: .WORD TABLE+PLTEOF+CBN TABCDC: .WORD TABLE+CDTEOF+CBN TCBK1A: .WORD TCBDK1 .IFDF $CD CDCPAD: .WORD CDCBIP CDCBAD: .WORD CDCBCP .ENDC .IFDF $LP LPCBAD: .WORD LPCBCP LPCWAD: .WORD LPWDIP .ENDC .IFDF $PL PLCBAD: .WORD PLCBCP PLWDAD: .WORD PLWDIP .ENDC TCBK3A: .WORD TCBDK3 AFNDBK: .WORD FINDBK ASPLFU: .WORD SPLFUL ;##139## BUFLAD: .WORD BUFLHD .IFDF $LP LPCPAD: LPCZAD: .WORD LPCBIP LPBMSA: .WORD LPBMS .ENDC TABCDT: .WORD TABLE+CDTEOF TABCRT: .WORD TABLE+CRP TABPDT: .WORD TABLE+PLTEOF+CRP .IFDF $PL PLCIAD: .WORD PLCBIP PLOIAD: .WORD PLOBIP PLBMSA: .WORD PLBMS .ENDC .IFDF $CD CDBMSA: .WORD CDBMS CDINTA: .WORD CDINT .ENDC TABDCT: .WORD TABLE+CDTEOF+CRP CDCAAD: .WORD CDCALL SPSTAD: .WORD SPST .IFDF $CD CDOBAD: .WORD CDOBCP RESTAD: .WORD RESTRQ CDONAD: .WORD CDONCE .ENDC ONCEFL: .WORD 0 ADTCNT=ADRTBL-./2 ; ; .SBTTL BITMAP & TABLE ; BITMAP: .BLOCK 14 ;SPOOLER ID INFO STBKNM: .WORD 0 ;SPOOLER AREA FBN .WORD 0 ;SPOOLER AREA SIZE BTMPST: .BLOCK 362 ;##133##START OF BIT MAP BTMPSZ=.-BTMPST/2 BTMPED: 0 ;POINTER TO END+2 OF BIT MAP ; .BLOCK 4 ;HWD'S TABLE: .BLOCK 44 ;3 DEVICES * 14(8) WORDS EACH TABLSZ=.-TABLE/2 ; ; TABLE ENTRIES ARE AS FOLLOWS FOR EACH TASK: ; DEVCOD/CBN/CRP/NBN/LSB/LFB ; 0/2/4/6/10/12 ; .SBTTL TCB TEMPLATES ; ;DISK READ/WRITE TCB WITH ONLY SETTING OF EV TCBDK TCBDK1 TCBDK TCBDK3 TCBDK TCBDK4 TCBDK TCBDK5 ;DISK READ/WRITE TCB'S FOR SPOOLED DEVS. TCBST=. .IFEQ DEVCNT-1 .REPT DEVCNT*4+2 ;(SCR-144)1 DEV. EXTRA BUFFER TCBRK .ENDR .ENDC .IFNE DEVCNT-1 .REPT DEVCNT*4 TCBRK .ENDR .ENDC TCBEN=. TCBCT=TCBEN-TCBST/30 TCBLIM=1 .REPT TCBCT TCBLIM=2*TCBLIM .ENDR ; .IFDF $LP ;LP WRITE TCB WITH RETURN ADDRESS & SET EV TCBLP: SPCOD ;0. API LVL & TRAP ADDRESS 1600+LPCOD ;2. NO INT. + LP TASK + RETURN @SEND11 0 ;4. REV 100000 ;6. DONT RELOCATE ADDRESS 0 ;10. FA 2 ;12. SINGLE LINE/MULTI LINE SW 0 ;14. LP STATUS .ENDC .IFDF $PL ; ; ;PL WRITE TCB WITH RETURN ADDR AND SET EV ; TCBPL: SPCOD ;0. API LVL. & TRAP ADDRESS 1600+PLCOD ;2. NO INT. + PL TASK + RETURN @SEND11 0 ;4. RETURN EVENT VARIABLE 100000 ;6. DON'T RELOCATE ADDRESS 0 ;10. FA .ENDC .IFDF $CD ; ;CD READ TCB WITH RETURN ADDRESS & SET EV TCBCD: SPCOD ;0. API LVL & TRAP ADDRESS 1600+CDCOD ;2. NO INT. + CD TASK + RETURN @SEND11 0 ;4. REV 100000 ;6. DONT RELOCATE ADDRESS 0 ;10. FA 0 ;12. UNIT # .ENDC ; ;DISCONNECT SPOOLER TCB TCBDIS: 0 ;0 API LVL + TRAP ADD. 600+SDCOD ;2. SD TASK + NO INT. 0 ;4. REV SPCOD ;6. SPOOLER TASK CODE 100000 ;10. DONT RELOC. ADD. 0 ;12. FA (SET UP) 0 ;14. SPOLSZ*2 ;16. SPOOLER SIZE ; .SBTTL BUFFER POOL ; BUFLHD: .WORD BUF1 ;BUFFER LIST HEAD .WORD BUF8 BUF1: .WORD .+1000 .WORD BUFLHD .BLOCK 376 .IFEQ DEVCNT-1 .REPT DEVCNT*4 ;(SCR-144)1 DEV. EXTRA BUFFER .WORD .+1000 .WORD .-1002 .BLOCK 376 .ENDR .ENDC .IFNE DEVCNT-1 .REPT DEVCNT*4-2 .WORD .+1000 .WORD .-1000 .BLOCK 376 .ENDR .ENDC BUF8: .WORD BUFLHD .WORD .-1002 .BLOCK 376 ; SPEND: .END ;