; ------------------------------------------------------------- ; TRANSPARENT OUTPUT SPOOLER FOR RT-11 V04 .ENABL LC ; This software is the property of the Government of Canada. ; It may be freely used by any person or agency provided that ; such use is not for gain or reward except as authorized ; by her Majesty or her designated representative. ; Support for this program may be obtained from: ; National Defence Headquarters ; Ottawa Ontario Canada ; K1A 0K4 ; Attn: Mr.Greg.L.Adams ; DACS 2-2-4 ; Phone: (613) 993-9624 ; The department reserves the right to withdraw support without ; notice and does not assume responsibility for the correct ; operation of this software. ; ------------------------------------------------------------- .TITLE SP - SPOOLER HANDLER / .IDENT /V01.00/ ; ------------------------------------------------------------- ; MACROS AND DEFINITIONS .MCALL .DRDEF .DRDEF SP,50,WONLY$,0,364,360 ;THIS IS A SUPER DELUX MACRO ANTON! LAST = 000010 ;Move to start of last file listed bit in CSR. NEXT = 000020 ;Move to start of next file to be listed bit in CSR. SHOW = 000040 ;Show status of spooler bit in pseudo CSR. INTEN = 000100 ;Fake interrupt enable bit in the SP pseudo CSR. SOFTPG = 000200 ;Set software page control and length bit in CSR. ENDPGS = 002000 ;Set end page count bit in psuedo CSR. KILL = 010000 ;Kill all output to unit bit in CSR. OFF = 020000 ;Set spooler unit off bit in CSR. ON = 040000 ;Set spooler unit on bit in CSR. ERROR = 100000 ;Error bit in pseudo CSR. SP$BNR = 000002 ;Spooler pseudo block number register. SP$WCR = 000006 ;Spooler pseudo word count register offset. SP$BPR = 000010 ;Spooler pseudo buffer pointer register offset. KPAR1 = 172342 ;Kernel PAR 1 address. .PAGE ; ------------------------------------------------------------- ; SET OPTIONS .DRSET UNIT,7,S.UNIT, .DRSET HOLD,ON,S.HOLD, .DRSET SHOW,SHOW,S.BIT .DRSET NEXT,NEXT,S.BIT .DRSET LAST,LAST,S.BIT .DRSET KILL,KILL,S.BIT .DRSET ENDPGS,3,S.ENDP, ; ------------------------------------------------------------- ; SET CODE S.UNIT: CMP R0,R3 ;Is unit number too big? BGT 1$ ;Yes, take error exit. BIS R0,@SPSCSR ;No, set unit number bits in CSR. 1$: CMP R3,R0 ;Set carry bit as appropriate. RTS PC S.HOLD: MOV #OFF,R3 ;SET SP NOHOLD entry so use on bit. S.BIT: BIS R3,@(PC)+ ;Set the appropriate CSR bit. SPSCSR: .WORD SP$CSR CLR R3 ;Clear the carry bit. RTS PC ;Return. S.ENDP: CMP R0,R3 ;Is the value legal? BGT 1$ ;No, go exit. SWAB R0 ;Yes, so shift to appropriate bits. BIS R0,@SPSCSR ;Set them. SWAB R0 ;Restore R0. BIS #ENDPGS,@SPSCSR ;Flag the new end pages count. 1$: CMP R3,R0 ;Set carry bit. RTS PC ;Return to RT-11. .PAGE ; ------------------------------------------------------------- ; DRIVER ENTRY .DRBEG SP ;Setup handler header. MOV SPCQE,R4 ;Get pointer to queue element. TST Q$WCNT(R4) ;A seek only? BEQ SPEXIT ;Yes, then exit now. CLR (PC)+ ;Clear the block segmentation count. BLKSC: .WORD 0 MOV SPCSR,R5 ;Get a pointer to pseudo control regs. BIS #INTEN,(R5)+ ;Then request a fake interrupt. MOV (R4)+,(R5)+ ;Copy block and job numbers because MOV (R4)+,(R5)+ ;the spooler will need it later. RTS PC ;Return for later continuation. ; -------------------------------------------------------------- ; INTERRUPT SERVICE .DRAST SP,4,SPEXIT ;Let the macro set it up. MOV SPCQE,R4 ;Get pointer to the queue element. MOV SPCSR,R5 ;Get pointer to the fake CSR. .IF NE MMG$T MOV @#KPAR1,-(SP) ;Save kernal PAR 1 if we're mapped MOV Q$PAR(R4),@#KPAR1 ;and remap to user's buffer. .ENDC TST (R5) ;Was our request ok? BMI SPERR ;No, take error exit. CLR SP$WCR(R5) ;Clear the spoolers wordcount. ADD BLKSC,SP$BNR(R5) ;Add count for split-up xfers. 1$: MOV @Q$BUFF(R4),@SP$BPR(R5) ;Send a word to SPOOL's buffer. ADD #2,SP$BPR(R5) ;Increment the buffer pointers. ADD #2,Q$BUFF(R4) .IF NE MMG$T CMP Q$BUFF(R4),#40000 ;Has buffer address overflowed? BLO 2$ ;No, then continue. SUB #20000,Q$BUFF(R4) ;Yes, then select next page. ADD #200,Q$PAR(R4) .ENDC 2$: INC SP$WCR(R5) ;Count the word for the spooler. INC Q$WCNT(R4) ;All data output? BEQ SPDONE ;Yes, then go exit. CMP SP$WCR(R5),#256. ;Is spooler buffer full? BNE 1$ ;No, then copy some more data. INC BLKSC ;Yes, then inc the segmentation count. .IF NE MMG$T MOV (SP)+,@#KPAR1 ;Restore default kernel mapping. .ENDC RTS PC ;RTI via RT. ; ------------------------------------------------------------------- .PAGE ; ------------------------------------------------------------------- ; ERROR AND NORMAL EXITS SPERR: BIS #HDERR$,@-(R4) ;Report the user's error. SPDONE: .IF NE MMG$T MOV (SP)+,@#KPAR1 ;Restore default kernel mapping .ENDC SPEXIT: BIC #INTEN,@SPCSR ;Yes, disable any more interrupts. BIC #ERROR,@(PC)+ ;Clear errors. SPCSR: .WORD SP$CSR ;Pointer to pseudo spooler CSR. .DRFIN SP ;Take output done exit. ; ------------------------------------------------------------------- ; HANDLER TERMINATION .DREND SP .END