.TITLE P2SERV Printer Server (ALVIN V5.1) .PSECT P2SERV,GBL,CON .MCALL $Alv51, .TWait, $List, $SkipList, .SCCA ;;********************************************************************** ;; ALVIN 7-01-77 BY DVJENSEN, AMES LAB COMPUTER SERVICES 50011 ;; VERSION ;; 28-JAN-82 5.0 - REVISED ALVIN NUCLEUS ;; 5-Aug-82 - CSG Printer Server implementation ;; 26-Feb-83 - Single printer dedicated server. ;; 20-Apr-83 - Update for P300 printer back online. ;; 12-Jul-83 - P1 Server removed as separate Psect. ;; 13-Jul-83 - P2 Server implemented - two serial print streams ;; input (CSG TSX & VAX) to one printer. ;; 13-Sep-84 5.1 - Conversion to run as a forground task on Micro-11. ;; - Support for the Serial Line Printer interface. ;; 18-Sep-84 - Added call to AlvUpd to force console print out. ;; - Added .TWait (in forground) to allow BG some time. ;; 21-Sep-84 - Support for second input print stream added. ;; 25-Oct-84 - Continued. ;; 31-Oct-85 - Revised for Unstall invoked by AlvUpdate. ;; - SLEEP timer technique changed so AlvUpdate is invoked ;; more frequently. ;; 7-May-86 - Added keyboard control options: ;; ^C or ^Z will Xoff the streams and disable all ;; devices except the console. (^U & ^D also) ;; Carriage Return will restart the server. ;; Once disabled, a ^C will abort the server. ;; Keyboard control options will only be detected after a ;; print job has completed or while the server is inactive. ;; The Server cannot be aborted or unloaded until the device ;; interrupts are disabled. ;; ;;**************** ;; Alvin Globals ;; .GLOBL ALVIN, ALVINIT, ALVEXIT, ALVMSG .GLOBL STACKP, LDEVICE .GLOBL BUFSPACE, BUFCOUNT .GLOBL CONSKB, CONSLT .Globl P1IN, P1OUT, PRINTout, Printin, P2in, P2out .GLOBL SEND, RECEIVE, RESETBUF, AlvEnable, AlvDisable .Globl Alvupdate ;;**************** .GLOBL P1BUFF,P2BUFF ;;********************************************************************** $Alv51 ;;********************************************************************** ;;; Logical unit numbers - must match position in device table: Keyb=0 List=1 PRT1IN=2 ;TSX input stream. PRT1OUT=3 P300Flow=4 PRINT=5 ;Actual printer. Prt2In=6 ;Vax input stream Prt2Out=7 ;; STARTMARGIN=4. ;Number of characters which must be in buffer before ; the printer will be activated on this buffer. ;; Startmargin is now set per input stream in the INSTREAMS table below. ;;********************************************************************** ALVIN: PSERVER:: ; Printer server entry point. MOV SP,STACKP ; Save where the stack is. JSR PC,ALVINIT ; Initialize all devices in the table. $List ,PMsg ; Identify the print server. JSR R5,RECEIVE ; Prepare to receive input .WORD PRT1IN ; Reset the buffer for PRT1IN logical unit .WORD P1BUFF ; Buffer descriptor for Print 1 input. NOP ; It will not be busy. JSR R5,RECEIVE ; Prepare to receive input .WORD PRT2IN ; Reset the buffer. .WORD P2BUFF ; Buffer descriptor for Print 2 input. NOP ; It will not be busy. JSR R5,RECEIVE ; Prepare to receive input .WORD P300Flow ; on the Printer's Flow control input. .WORD DumBD ; Buffer descriptor is a Dummy (not used). NOP ; It will not be busy. TurnOn: Jsr R5,SEND ; Make sure print streams in are Xon'ed .Word PRT1OUT!STRING ; TSX printer .Word XONSTRING ; One Xon to go, please. Nop ; It won't be busy Jsr R5,SEND .Word PRT2OUT!STRING ; VAX printer .Word XONSTRING ; One Xon to go, please. Nop ; It won't be busy ;; Clr Active ; Indicate that the server is active. ConsRead: Jsr Pc,Console ; Enable console input. ; Detect Control-C to stop the server (Xoff ; and disable the ports). (^Z, ^U & ^D also) ; Carriage return will reactivate the server. ;; ;; ***** Main Loop ****** FINDACTIVE: Jsr Pc,Sleep ; Wait, then look what there is to do. Bit #Complete!BrkReq,Conskb ; Is there a user request? Bne UserRequest Jmp ChkStreams ; No, check if there is printer work. UserRequest: Bit #BrkReq!Cancel,Conskb ; Is this a request to terminate? Beq ChkRestart ; No, branch Tst Active ; Yes, but is it currently active? Beq Off1 ; Yes is active, so can disable it. $SkipList Br ConsRead ; Nothing to do, restart console. Off1: Jsr R5,SEND ; Make sure print streams in are Xoff'ed .Word PRT1OUT!STRING ; TSX printer .Word XoffSTRING ; One Xoff to go, please. Br Off1 ; Loop until this is sent. Off2: Jsr R5,SEND ; Make sure print streams in are Xoff'ed .Word PRT2OUT!STRING ; VAX printer. .Word XoffSTRING ; One Xoff to go, please. Br Off2 ; Loop until this is sent. ;; Mov R0,R2 ; Send returns the device desc adr in R0. OffWait: Jsr Pc,Alvupd ; Make sure it gets sent. Tst (R2) ; Wait until the last Xoff is actually out. Bpl OffWait Jsr Pc,AlvExit ; Disable all devices in the device table. Mov #-1,Active ; Mark the server as inactive. Clr R3 ; Unit 0. Jsr Pc,AlvEna ; Re-enable the console keyboard. Inc R3 ; Unit 1. Jsr Pc,AlvEna ; Re-enable the console display. .SCCA #Area,#0 ; Can allow a Control-C Abort now. $SkipList $List < Use Ctrl-C to abort.> Jmp ConsRead ;; ChkRestart: Tst Active ; Is the server currently active. Bmi Restart ; No, restart the server. $SkipList Jmp TurnOn Restart: Clr R3 ; Select unit 0. Jsr Pc,AlvDisable ; Disable it so .SCCA will go back into effect ; when unit zero is again enabled. Jmp PServer ;;******************************** ;; Activation of a print stream: ;(For more printers, process a stack of buffers.) ChkStreams: Mov #InStreams,R5 ;Get the Input print stream(s) desc address. Mov (R5),R1 ;Get the address of the first entry in the table FindP: Cmp R1,2(R5) ; Is this the end of the table? Blo Findit ; No, check out this stream. Jmp FindActive ; Yes, try again Findit: Mov (R1),R2 ; Get an input print stream device descriptor. MOV BDadr(R2),R4 ; Get the buffer descriptor JSR PC,BUFCOUNT ;Count input characters CMP R0,2(R1) ;Is there enough in the buffer to start printing? Bhis GoPrint ;Yes, start sending this buffer to the printer. Add 4(R5),R1 ;Increment to the next entry in the stream table. Br FindP ;Check this one now. GOPRINT: JSR R5,SEND ;Startup the printer .WORD PRINT .WORD 0 ;Buffer descriptor is in register 4 BR GOPRINT ;Loop to activate if not done MOV R0,R3 ;Save the address of the printer device desc. LPWAIT: BIT #COMPLETE,(R3) ;Has the printer completed emptying buf? BNE Endelay ;Yes, branch to delay a bit before new print. Jsr Pc,Sleep ;Sleep for a while - Pserve takes care of itself. Br LPWAIT ;Carry on. Endelay: Mov 4(R1),R3 ;Get the Sleep delay count to wait. Beq Done ;If zero, proceed to find another busy stream. Delay: Jsr Pc,Sleep ;Wait a second. Jsr Pc,Bufcount ;Did anything else come in the mean time? Tst R0 Bne GoPrint Dec R3 ;Count down the defined delay. Bne Delay ;Loop until zero. Done: Jmp FindActive ;Print delay expired - Go look for another. ;;**************************************************************************** ;; Sleep - Subroutine to wait for a while. Allows the background to do some ;; processing. In fact, Pserve will sleep most of the time. It is ;; almost totaly interrupt driven. Only the selection of the next ;; stream to schedule to the printer and flow reactivation requires ;; normal level service. ;; ;; Expects calls of the form: Jsr Pc,Sleep ;; Sleep: AlvIdle:: ; Let this be Alvin's Idler routine. .TWait #Area,#Ticks ; Wait. (Use the $Twait macro if this needs ; to run under the SJ monitor.) Jsr Pc,AlvUpd ; try to reactivate after sleeping, also. Rts PC Area: .Word 0,0 ; EMT arguement block. Ticks: .Word 0,6. ; Wait one tenth of a second. ;;**************************************************************************** ;; Subroutine to enable console input. Console: JSR R5,RECEIVE ; Prepare to receive input .WORD Reset!KeyB ; from the console keyboard. .WORD Keyin ; Local buffer descriptor. NOP ; (It will not be busy.) Rts Pc ;;*************************************************************************** ;; Input print stream structure - defines which devices are input print ;; streams: InStream: .Word Strm ;First entry .Word Strmend ;End address of the stream table. .Word 6 ;Size (in bytes) of an entry. ;; Strm: .Word P1in ;Device descriptor of TSX input stream. .Word 4 ;Number of bytes which must be buffered before ; the device will be eligible for printing. .Word 50. ; Number of .1 seconds the stream must go inactive ; before another input stream will be printed. ;; .Word P2in ;Device descriptor of VAX input stream. .Word 16. ;Number of bytes which must be buffered to act. .Word 20. ;.1 Seconds idle before new stream will be queued. Strmend=.-2 ;;********************************************************************** ;; STACKP: .WORD 1000 ; Base address of the stack. Active: .Word -1 ; Initialized to inactive. ;; ;;********************************************************************** ;; String Descriptors ;;**************************** XONSTRING: .WORD XON1 ; Xon static string descriptor .WORD XON1 ;;**************************** XOFFSTRING: .WORD XOFF1 ; Xoff static string descriptor .WORD XOFF1 XOFF1: .BYTE XOFF XON1: .BYTE XON .even ;;**************************** ;; BUFFER DESCRIPTORS ;; P1BUFFER: .WORD BUF1 ; INPUT POINTER - TSX-Plus print stream. .WORD BUF1 ; OUTPUT POINTER .WORD BUF1 ; STARTING ADDRESS OF BUFFER .WORD BUF1END ; ENDING ADDRESS OF BUFFER ;; P2BUFFER: .WORD BUF2 ; VAX print stream. .WORD BUF2 .WORD BUF2 .Word Buf2End ;; KeyIn: .WORD BUFkey ; Keyboard input buffer. .WORD BUFkey .WORD BUFKey .Word BufKend ;; DumBD: .Word DumWD ; A Dummy Buffer descriptor. .Word DumWD .Word DumWD .Word DumWD+1 DumWD: .Word 0 ;; ;; The buffer sizes are quite adjustable. The smaller they are, the more ;; frequent that Xoff/Xon will have to used to idle the flow. Internally ;; the margin is set at 1/8 of the buffer size as the point as which flow ;; must be idled or restarted. ;; BufKey:: .Blkw 20. ; Small keyboard input buffer. Bufkend==.-1 BUF1:: .Blkw 256. ; Buffer 1 start. BUF1END==.-1 ; Buffer 1 end. BUF2:: .Blkw 256. ; Buffer 2 start. BUF2END==.-1 ; Buffer 2 end. ;; ;;********************************************************************** ;; ;; Server initialization message. ;; PMSG: .WORD INTRO1 ;TOP .WORD INTRO3 ;BOTTOM ;; INTRO1: .BYTE CR,LF .ASCII '** P2Server **' .BYTE CR,LF .ASCII 'Version 5.1c - 2->1 Foreground Print Server. ' ; .BYTE CR,LF,LF ; .ASCII 'Two input print streams to one printer.' ; .Byte CR,LF ; .ASCII '(The keyboard only accepts cancel (^C) and continue (Cr) )' ;INTRO4: .BYTE CR,LF INTRO3: .BYTE Cr,LF .EVEN ;;**************************************************************************** .End Pserve