; ------------------------------------------------------------- ; 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 SPINIT - INITIALIZATION / .IDENT /V01.01/ .NLIST BEX ; This program performs initialization for the spooler package. ; It is executed only once (at spooler startup) after which the ; area is turned into the SP input buffer; as such, it can not ; be less than 512 (decimal) bytes in size. ; ------------------------------------------------------------- ; Author: GA ; Edit History: ; GA 28-APR-80 CKSIZ doesn't correctly size scratch file. ; GA 23-AUG-80 Create scratch file if not found. .PAGE ; ----- Macros and other definitions -------------------------- .GLOBL START,TIMERON .IIF NDF MMG$T, MMG$T=0 ;** Assume we're not mapped.** .MACRO DEVICE NAME,SIZE,TYPE ;Macro to define spooled device. .RAD50 %'NAME% .WORD TYPE,0 .BLKW 3 .WORD SIZE,0 .ENDM .MCALL .LOOKUP, .QSET, .PURGE, .PRINT, .EXIT, .ENTER ;GA2+ .MCALL .RCTRLO. .GVAL, .DSTAT, .WRITW, .PROTECT .IF NE MMG$T .MCALL .CRRG, .CRAW, .RDBBK, .RDBDF, .WDBBK .RDBDF ;Define XM mnemonics. APR = 7 ;Use APR 7. WINOFF = 0 ;Offset into region to start window. .ENDC $BUSY == 100000 ;Device is busy. $CRPND == 040000 ;Completion processing is due for the device. $HOLD == 020000 ;Output is to be held. $NEXT == 010000 ;Move the the start of the next file. $LAST == 004000 ;Move to the beginning of the last file. $KILL == 002000 ;Kill all output to the device. SDCESZ == 000020 ;16 bytes per SDCTAB entry. D.STAT == 000002 ;Offset to SDCTAB device status. B.USED == 000004 ;Offset to SDCTAB used blocks count (var). B.HEAD == 000006 ;Offset to SDCTAB header block (var). B.TAIL == 000010 ;Offset to SDCTAB tailer block (var). B.BEG == 000012 ;Offset to SDCTAB begin block (con). B.END == 000014 ;Offset to SDCTAB end block (con). D.BLK == 000016 ;Offset to SDCTAB output block number. SYSOP = 000372 ;Offset to RT-11 SYSOP. MMGT$ = 000002 ;XM bit in SYSOP. SP$BNR == 000002 ;Buffer number register offset from CSR. SP$DEV == 000005 ;Device number register offset from CSR. SP$WCR == 000006 ;Word count register offset from CSR. SP$BPR == 000010 ;Buffer pointer register offset from CSR. LAST == 000010 ;Move to start of last file listed bit in CSR. NEXT == 000020 ;Move to start of next file bit in CSR. SHOW == 000040 ;Show status of spooler bit in pseudo CSR. INTEN == 000100 ;Fake interrupt enable bit in the CSR. SOFTPG == 000200 ;Software page control and length bit in CSR. ENDPGS == 002000 ;Set end page count bit in pseudo CSR. KILL == 010000 ;Set kill device output 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. .PAGE ; *************************************************************** ; * The user modifies this code to generate a tailored spooler. * ; *************************************************************** SP$VEC == 000360 ;Spooler vector address. SP$CSR == SP$VEC+4 ;Spooler command status register. ; To change the vector and command status register addresses, ; the above global equate for SP$VEC may be changed to any un- ; used 8 word block in the range 060 to 377. Note that the ; corresponding change must also be made in the SP handler. ; ------------------------------------------------------------- .PSECT PURE ; ------------------------------------------------------------- ; The DEVICE macro is used to define entries in the spooled ; device control table (i.e. installs a device in the spooling ; system). It takes 3 arguments; NAME, SIZE and TYPE. ; NAME specifies the device's handler name. For example, ; specifes handler device LP:. ; SIZE specifies the number of blocks to allocate to the device ; from the scratch file. The total number of blocks for all ; devices cannot exceed the size of the scratch file. ; TYPE defines the configuration setup for the device and uses ; the control bits defined above. ; EXAMPLES: ; 1. Two line printers LP and LS, each gets 400 blocks in the ; scratch file (which must be at least 800. blocks. ; SDCTAB:: DEVICE ,400.,0 ; DEVICE ,400.,0 ; 2. A line printer LP only, the standard default setup. SDCTAB:: DEVICE ,400.,0 NUMDEV==.-SDCTAB/SDCESZ ;Number of devices in the table. ; ------------------------------------------------------------- ; Normally, the spooler scratch file is SY:SPOOL.SYS. The user ; may change the following specification if he or she (note non ; male chauvenist pig attitude) requires the scratch file to be ; on an alternate device or under a different name. Note that ; the scratch file is considered to be a system file and hence, ; is subject to the same restrictions (i.e. cannot be moved in ; a squash (squeeze?) operation etc). SPLFIL: .RAD50 /SY SPOOL SYS/ ;Define spooler scratch file. .PAGE ; ----- Parameter and data area ----------------------------------- .PSECT PURE AREA: .WORD 0,0,0,0,0 ;EMT request block. JUNK: .BLKW 2 ;A couple of scratch locations. SCRTSIZ:.WORD 0 ;Size of scratch file (working). ;GA2+ QEROOM: .BLKW NUMDEV*10.+30. ;Room for more queue elements. .IF NE MMG$T WADR: .WDBBK APR,256.*NUMDEV/32.,0,WINOFF,256.*NUMDEV/32.,WS.MAP WNRID = WADR+W.NRID ;Address of region ID word. RGADR: .RDBBK 256.*NUMDEV/32. .ENDC .PAGE ; ----- Entry point ----------------------------------------------- .PSECT SPOOL SPINIT::.RCTRLO ;Just in case we need to report an error. MOV #AREA,R2 ;R2 => EMT request block (always). .IF EQ MMG$T MOV #START,@#46 ;Tell RT where to swap the USR when its FB. .GVAL R2,#SYSOP ;Is this XM monitor? BIT #MMGT$,R0 BEQ 1$ ;No, then carry on. .PRINT #ITSXM ;Yes, then tell the dummy and abort. .EXIT .ENDC 1$: .QSET #QEROOM,#NUMDEV+3 ;Allocate more queue elements. .IF NE MMG$T MMGTON: CMP #SPINIT+512.,#20000 ;Is the transfer buffer in the BLO 1$ ;area mapped by APR 1? CMP #SPINIT,#37776 BHI 1$ ;No, carry on. .PRINT #APRRNG ;Yes, then despite that I feel really .EXIT ;bad about it, abort the human. 1$: .CRRG R2,#RGADR ;Allocate a region in extended memory. BCC 2$ ;Did we get it? .PRINT #NOMEM ;No, report the fact .EXIT ;and abort. 2$: MOV RGADR,WNRID ;Map the region to our window. .CRAW R2,#WADR ;Creat the window. BCC 3$ ;Did it map up? .PRINT #CANTMAP ;Nope, then we have problems. .EXIT ;Abort exit. .ENDC 3$: ;Fall through to next block. ; ----- Protect the vector addresses for the pseudo registers ----- PROTECT:.PROTECT R2,#SP$CSR ;Protect the pseudo CSR location. BCS 1$ ;Error if we didn't get it. .PROTECT R2,#SP$CSR+4 ;Meme choise! BCS 1$ .PROTECT R2,#SP$CSR+8. BCC 2$ 1$: .PRINT #VINUSE ;Cannot protect so tell and exit. .EXIT 2$: ;Now for something different. .PAGE ; ----- Determine the size of the scratch file -------------------- ;GA2+ FINDSZ: MOV #NUMDEV,R1 ;R1 = number of devices in the system. ;GA2+ MOV #SDCTAB,R3 ;R3 = spooled device control table. ;GA2+ CLR R4 ;R4 = number of blocks required. ;GA2+ 1$: ADD B.END(R3),R4 ;Add up the requirements for each device.GA2+ ADD #SDCESZ,R3 ;Move to next SDCTAB entry. ;GA2+ DEC R1 ;All done? ;GA2+ BGT 1$ ;No, continue. ;GA2+ MOV R4,SCRTSIZ ;Save the file size for later. ;GA2+ ; ----- Lookup the spooler scratch file---------------------------- SFLOOK: .DSTAT R2,#SPLFIL ;Is the device in the system? BCC 3$ .PRINT #NOSFDEV ;Nope, then cannot spool. .EXIT 3$: TST 4(R2) ;Is the handler loaded? BNE 4$ .PRINT #NOSFHND ;Nope, tisk tisk! .EXIT ;Abort the amateur user. 4$: .PURGE #10 ;Clear out the channel (never hurts). .LOOKUP R2,#10,#SPLFIL ;Lookup the spooler scratch file. BCC 6$ ;Found ok? 5$: .ENTER R2,#10,#SPLFIL,SCRTSIZ ;Nope, then create it. ;GA2+ BCC 6$ ;Could we enter it? ;GA2+ .PRINT #NOSFIL ;Nope, tell him and abort. .EXIT 6$: ;Fall through to the next block. ; ----- Verify that the scratch file is big enough ---------------- CKSIZ: DEC SCRTSIZ ;Convert number of blocks to block number.GA2+ .WRITW R2,#10,#SPINIT,#256.,SCRTSIZ ;Try to write to the highest.GA2+ BCC 1$ ;Carry on if successful. .PRINT #TOOSMALL ;Must be using floppies! .EXIT 1$: ;Fall through. ; ----- Reset the spooled device control table -------------------- RS.SDC: MOV #NUMDEV,R1 ;R1 = number of devices in the system. MOV #SDCTAB,R3 ;R3 => spooled device control table entry. CLR R4 ;R4 = block number. 1$: CLR B.USED(R3) ;Clear the used block count. MOV R4,B.HEAD(R3) ;Initialize header block number. MOV R4,B.TAIL(R3) ;TAIL = HEAD initially. MOV R4,B.BEG(R3) ;Set lowest useable block for this device. ADD B.END(R3),R4 ;Move to starting block for next device. MOV R4,B.END(R3) ;Set ending block number for this device. DEC B.END(R3) ;Highest(this device)=Lowest(next device)-1. ADD #SDCESZ,R3 ;Move to the start of the next entry. DEC R1 ;All device entries initialized? BGT 1$ ;No, continue. Yes, fall through .PAGE ; ----- Lookup the spooled devices -------------------------------- DEVLK: MOV #NUMDEV,R1 ;Get the number of devices to lookup. MOV #SDCTAB,R3 ;R3 = index into SDCTAB. CLR R4 ;R4 = I/O channel for device. CLR JUNK+2 ;word 2=0 for non file structured lookup. 1$: MOV (R3),JUNK ;Move device name to word 1 for lookup. 2$: .DSTAT R2,#JUNK ;Is the device in the system? BCC 3$ .PRINT #NOSDDEV ;Nope, then cannot spool. .EXIT 3$: TST 4(R2) ;Is the handler loaded? BNE 4$ .PRINT #NOSDDEV ;Nope, tisk tisk! .EXIT ;Abort the amateur user. 4$: .PURGE R4 ;Clear out the channel (never hurts). .LOOKUP R2,R4,#JUNK ;Lookup the spooled device. DEC R1 ;All devices looked up? BEQ 5$ ;Yes, go carry on. ADD #SDCESZ,R3 ;No, move to next entry. INC R4 ;Select next I/O channel. INCB DEVNUM ;Increment device number in messages. BR 1$ ;Go do next device. 5$: ;Fall through to next block. ; ----- Initialize the pseudo control registers ------------------ MOV #SP$CSR,R3 ;R3 => CSR. CLR (R3) ;Clear the CSR. ; ----- Turn on timed task scheduling ---------------------------- TURNON: CALL TIMERON ;Start scheduling checks of INTEN. RETURN ;Were all done so return. .PAGE ; ----- Messages -------------------------------------------------- .IF NE MMG$T NOMEM: .ASCIZ 'SPOOL-F-Cannot get required extended memory.' CANTMAP:.ASCIZ 'SPOOL-F-Cannot map window to extended region.' APRRNG: .ASCIZ 'SPOOL-F-SP buffer in area mapped by APR 1.' .ENDC .IF EQ MMG$T ITSXM: .ASCIZ 'SPOOL-F-SPOOL not generated for XM monitor.' .ENDC NOSFDEV:.ASCIZ 'SPOOL-F-Device for scratch file non-existant.' NOSFHND:.ASCIZ 'SPOOL-F-Scratch file device handler not loaded.' NOSFIL: .ASCIZ 'SPOOL-F-Cannot .ENTER scratch file.' NOSDDEV:.ASCII 'SPOOL-F-Spooled device number ' DEVNUM: .ASCIZ '0 non existant or not loaded.' TOOSMALL:.ASCIZ 'SPOOL-F-Scratch file is too small.' VINUSE: .ASCIZ 'SPOOL-F-Cannot protect pseudo registers.' .EVEN ; ----- Buffers --------------------------------------------------- .IF EQ MMG$T DEVBUF == . ;Device output buffers are here in FB. .REPT NUMDEV .BLKW 256. .ENDR .ENDC .IF NE MMG$T DEVBUF == APR*4096.*2 ;Device output buffers are here in XM. .ENDC .END