.Title ALVCL CL-Controlled TSX I/O .Psect Alvin,Gbl,Con .Ident /LVL51C/ .Mcall .Spfun, $Alvin .GLOBL CLOUT, CLIN ; Internal Globals .Globl BufSpace ; External Globals $Alvin ;+ ;;********************************************************************** ;; Last Modified: 16-Sep-85 DVJensen - AlvRT converted to AlvCL ;; for TSX CL device support. ;; This version is not reentrant due to the use of local EMT storage ;; and storage for the CLcount's. ;; This version presumes all flow control will be handled by TSX-Plus. ;; As such, it will not transmit the NEXTOUT character as used in Alvin. ;; The PARITY control as used in Alvin is also not implemented. It is ;; presumed that parity will be controlled by the hardware using TSX+. ;; ;;********************************************************************** ; CLORSZ = 32. ; Size of the TSX CL output ring buffer(s), as in TSGEN. ; ;;********************************************************************** ;; CLOUT ;; Alvin subroutine to process output to a CL controlled port. ;; This pseudo-device handler is the routine entered when ;; output is initiated via Alvin SEND to a TSX CL controlled ;; device. ALVUPD will also invoke this routine whenever ;; a CL controled device is found to be incomplete. ;; ;; The first version cannot find out ;; what the actual size of the TSX CL output ring buffer is. As ;; such, the size is presumed here to be the definition of ;; CLORSZ as used in the TSGEN (see above). In sending to CL from an ;; Alvin ring buffer, one maybe two linear strings will be sent in a ;; non-blocking fashion; the second will occur if more will be ;; accepted after the Alvin ring has sent upto the end of the ring, ;; at which point it will send as much as will yet be accepted at the ;; start of the ring. ;; ;; Expects calls of the form: JSR PC,CLout ;; with the device descriptor address in Register 2 ;; and the buffer descriptor address in Register 4 ;- CLout:: Mov R0,-(SP) Mov R1,-(SP) Mov R3,-(SP) Bit #BrkReq,(R2) ; Has output termination been requested? Beq CLOgo ; No, branch to output. ; ; Here an .Spfun 202 could be used to transmit a break. The break must be ; stopped after a period of time. A Twait would have to be used followed by ; another .Spfun 202. I don't think it would be a problem to do this here, ; although its good to keep in mind that this is a pseudo-device handler ; that should not take inordinate amounts of time. ; Mov (R4),Bout(R4) ; Truncate what's left in the buffer. Br CLOdone ;; CLOgo: .Spfun #Area,Lunit(R2),#262,#CLcount,#1,#0 ; Get CL count. Mov #CLORSZ,R0 ; Get the size of the CL buffer. Sub CLcount,R0 ; Subtract the current # of chars. Ble ClOexit ; If zero or negative, no room, exit. Mov (R4),R3 ; Get the INPUT POINTER. MOV BOUT(R4),R1 ; Get the OUTPUT POINTER local. Cmp R1,R3 ; In the ring, is Output before Input ptr? Blo CLOall ; Yes, then can send it all in one burst. ; Beq is case where static string is output. ; (Typically Input = Output = Buffer empty.) Mov Bend(R4),R3 ; Can send upto the end of the ring. Inc R3 ; (add one for inclusive region) CLOall: Sub R1,R3 ; This is the byte count of a linear string. Cmp R3,R0 ; Will the CL silo accept this much? Blos CLOsend ; Yes, branch Mov R0,R3 ; No, only send what will be accepted. CLOsend: ; JSR PC,PARIT ; Not DOing PARITY AS SPECIFIED IN DEVICE DESC. ; .Spfun #Area,Lunit(R2),#263,Bout(R4),R3,#0 ; Transmit to CL silo. Add R3,R1 ; Calculate the new output pointer - ; add the number of chars transmitted. Cmp R1,Bend(R4) ; Need to wrap? Blos CLOcheck ; No, branch Mov Bstart(R4),R1 ; Yes, wrap. This is the case where Mov R1,Bout(R4) ; there may still be more which will fit. Cmp R1,(R4) ; Check if done, though. Beq CLOdone ; Yes, done. Br CLOGO ; Go for it once more (can't happen twice). CLOcheck: Mov R1,Bout(R4) ; Update the output pointer. Cmp R1,(R4) ; Is the output ptr = input ptr? Bne CLOexit ; No, then just exit. CLODONE: BIS #COMPLETE!IGNORE,(R2) ; Mark logical device as COMPLETE. BIC #SEIZED,(R2) ; Release the device. CLOexit: Mov (SP)+,R3 Mov (SP)+,R1 MOV (SP)+,R0 ;RESTORE WORK REGISTERS RTS PC ;AND RETURN ;;*************************** Area: .Blkw 6 ; EMT work area for .Spfun CLcount: .Word 0 ; CL character count return location. ;+ ;;********************************************************************** ;; CLIN ;; Alvin pseudo device handler for TSX-Plus CL input. ;; Input from TSX-Plus CL is via .Spfun 203 which a read with byte ;; count. The available number of characters is always checked first ;; with the .Spfun 261 to accomplish non-blocking input. The charcters ;; are transfered from CL to a standard Alvin ring buffer. ;; ;; Currently CLIN provides only for transfer and does not check for ;; activation characters (ala RTTIN using CLTSTR's). ;; ;; Expects calls of the form: JSR PC,CLin ;; with the device control block address in Register 2 ;; and with the buffer descriptor address in Register 4 . ;- CLin:: Mov R0,-(Sp) Mov R1,-(Sp) Mov R3,-(Sp) CLinAgain: Jsr Pc,BufSpace ; Check what room there is in the buffer. Mov R0,R3 ; Save the byte count of room available. Beq CLIexit ; If zero, then no room - exit. .Spfun #Area,Lunit(R2),#261,#CLcount,#1,#0 ; Get CL count. Mov CLcount,R1 ; Get it local. Beq CLIexit ; If zero, then nothing to do. ;::**** Cmp (R4),Bout(R4) ; Is the available space all linear? Blo CLIread ; Yes, then correct count is in R3? Mov Bend(R4),R0 ; First linear string extends to the end Sub (R4),R0 ; starting at the input pointer Inc R0 ; plus one for the inclusive pointer. Cmp R0,R3 ; Can the last position be used? Bhi CLIread ; No, branch; the output pointer is at start. Mov R0,R3 ; Otherwise fill to end of buffer first time. CLIread: Cmp R1,R3 ; Is there enough input to fill the space? Bhis CLIgo ; Yes, receive only what fits. Mov R1,R3 ; No, receive only what is available. CLIgo: .Spfun #Area,Lunit(R2),#203,(R4),R3,#0 ; Transmit from CL silo. Mov (R4),R0 ; Get the input pointer local. Add R3,R0 ; Update input pinter for chars added. Cmp R0,Bend(R4) ; Does the pointer need to wrap? Blos CliUpd ; No, branch. Mov BStart(R4),(R4); Yes, wrap to the start of the buffer. Br CLINagain ; Branch to see if more will fit at the start. ; (This will be the second pass, only two are possible.) CliUpd: Mov R0,(R4) ; Update the buffer descriptor input pointer. CLIexit: Clrb @(R4) ; RT convention - End of buffer is null byte. Mov (Sp)+,R3 ; for Alvin, Buf Input Ptr = Next available Mov (Sp)+,R1 ; location to store. Mov (Sp)+,R0 ; Input Pointer = Output Pointer = Empty. Rts Pc ; Return. ;;********************************************************************** .end