.NLIST TTM ; RT-11 OVERLAPPED LINE PRINTER HANDLER (LP/LS 11) ; DEC-11-XXXXX-Y-ZZ ; ; ; ; ; ; ; ; ; ; ; COPYRIGHT (C) 1976 BY DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSSETTS ; ; ; ; ; ; ; ; ; ; 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 DIGITAL. ; ; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE ; WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A ; COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. ; ; DIGITAL EQUIPMENT CORPORATION ASSUMES NO RESPONSIBILITY ; FOR THE USE OR RELIABILITY OF ITS SOFTWARE ON EQUIPMENT ; WHICH IS NOT SUPPLIED BY DIGITAL. ; ; ; ; ; ; ; ; ; ; ; ; ; .TITLE LQ HANDLER - OVERLAPPED LP DRIVER ; H.J. R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 ; LINE PRINTER CONTROL REGISTERS (STANDARD UNIBUS LOCATIONS) ; DEFAULT CONTROL REGISTER DEFINITIONS .IIF NDF LPCSR, LPCSR = 177514 .IIF NDF LPDB, LPDB = 177516 .IIF NDF LPVEC, LPVEC = 200 ; CONSTANTS FOR MONITOR COMMUNICATION HDERR = 1 ;HARD ERROR BIT MONLOW = 54 ;BASE ADDR OF MONITOR OFFSET = 270 ;POINTER TO Q MANAGER COMP ENTRY PR7 = 340 PR4 = 200 ; ASCII CONSTANTS CR = 15 LF = 12 FF = 14 HT = 11 BLANK = 40 LPIE = 100 COLSIZ = 132. ;132 COLS BUFNUM = 30. ;NUMBER OF INTERNAL BUFFERS ; THE INTERFACE TO THE MONITOR 'SET' COMMAND .ASECT . = 400 .WORD 30. ;MINIMUM WIDTH .RAD50 /WIDTH / .WORD /2+40000 ;NO 'NO' OPTION, NUMBER REQUIRED BEQ IGNORE-CROPT+. ;NO CR => NOP CROPT .RAD50 /CR / .WORD /2+100000 ;ALLOW 'NO' BR BLKCOP-FFOPT+. ;NO FORM0 => NOP FFOPT .RAD50 /FORM0 / .WORD /2+100000 ;ALLOW 'NO' ; NEEDS SUPPORT IN HANDLER, SEE LATER COMMENT ; BMI LPERR-ERROPT+. ;NO HANG BY GOING TO ERROR ; .RAD50 /HANG / ; .WORD /2+100000 ;ALLOW 'NO' .WORD 40 ;FOR NO LC, CONVERT LC TO UC .RAD50 /LC / .WORD /2+100000 BNE IGNORE-CTROPT+. ;IGNORE CTRL CHAR IF NOCTRL .RAD50 /CTRL / .BYTE /2 ;ALLOW 'NO' .BYTE 200 .WORD LPIE ;KILL LP OPTION .RAD50 /QUIET / .BYTE /2 .BYTE 0 0 ;END OF LIST O.WIDTH:MOV R0,COLCNT ;NEW WIDTH TO 2 CONSTANTS MOV R0,RSTC+2 CMP R0,R3 ;ERROR IF < 30. RTS PC O.CR: MOV (PC)+,R3 ;NO 'NO', SO SET TO DO CR BEQ RSTC-CROPT+. MOV R3,CROPT ;SET CR OPTION RTS PC O.FORM0:MOV (PC)+,R3 ;SET TO DO FORMFEEDS ON BLOCK 0 BNE BLKCOP-FFOPT+. MOV R3,FFOPT RTS PC ; ;O.HANG:MOV (PC)+,R3 ;SET TO HANG ; BMI RET-ERROPT+. ; MOV R3,ERROPT ; RTS PC O.LC: CLR R3 ;FOR 'LC', LEAVE LOWER CASE STUFF ALONE NOP MOV R3,LCOPT RTS PC O.CTRL: MOV (PC)+,R3 ;SET TO PASS ALL NON-PRINTING CHAR BNE LPRNT-CTROPT+. MOV R3,CTROPT RTS PC LPSTOP: BIC R3,@LPCSRP ;DISABLE LP INTERRUPTS RTS PC .CSECT LQ ; LOAD POINT LOADPT: .WORD LPVEC ;ADDR OF INTERRUPT VECTOR .WORD LPINT-. ;OFFSET TO INTERRUPT SERVICE .WORD PR7 ;PRIORITY 7 LPLQE: .WORD 0 ;POINTER TO LAST Q ENTRY LPCQE: .WORD 0 ;POINTER TO CURRENT Q ENTRY ; ENTRY POINT HALT MOV LPCQE,R4 ;R4 POINTS TO CURRENT Q ENTRY TST 6(R4) ;MAKE SURE THIS IS A WRITE REQUEST BPL LPERR ;A READ REQUEST IS ILLEGAL BIT #LPIE,@LPCSRP ;ARE WE CURRENTLY ACTIVE? BNE RET ;BRANCH IF YES CLR CURPTR ;CLEAN UP IN CASE OF ABORT CLR PRINTB ;ABORT ALL ACTIVE BUFFERS MOV #1,R3 ;FIRST BUFFER NUMBER CLR TABFLG ;CLEAN UP TAB STUFF MOV R3,TABCNT ;RESET TAB POSITIONS MOV #COLSIZ,COLCNT ;FORM FEED BETTER BE FIRST CHARACTER MOVB R3,FREEB ;RECREATE FREE BUFFER LIST MOV #BUFNUM,R0 ;NUMBER OF BUFFERS TO RELINK BR 2$ 1$: MOVB R3,@R2 ;PUT IN NEXT LINK NUMBER 2$: JSR PC,GETADR ;GET ABSOLUTE ADDRESS OF NEXT BUFFER CLR @R2 ;ASSUME END OF LIST INC R3 ;NEXT BUFFER NUMBER DEC R0 ;AT END OF BUFFERS? BNE 1$ ;BRANCH IF NOT RET: INC QEPEND ;INDICATE QUEUE ELEMENT AVAILABLE BIS #LPIE,@LPCSRP ;CAUSE AN INTERRUPT, STARTING TRANSFER ; ABORT ENTRY RTS PC ; INTERRUPT ENTRY LPINT: JSR R5,@INTEN ;INTO SYSTEM STATE .WORD ^C&PR7 MOV R3,-(SP) ;SAVE SOME REGS MOV R2,-(SP) MOV LPCQE,R4 ;R4 -> CURRENT QUEUE ELEMENT TST @(PC)+ ;ERROR CONDITION? LPCSRP: .WORD LPCSR ;LINE PRINTER STATUS REGISTER ; SHOULD PUT IN CODE TO RETURN ERROR IF Q ELEMENT AVAILABLE BMI LPBUFT ;BRANCH IF ERROR LPNEXT: TSTB @LPCSRP ;READY FOR ANOTHER CHAR YET? BPL LPBUFT ;BRANCH IF LP NOT READY TO TAKE A CHAR ; GET CHAR FOR PRINTING ASLB (PC)+ ;TAB IN PROGRESS? TABFLG: .WORD 0 BNE TAB ;BRANCH IF DOING TAB IGNORE: TST (PC)+ ;ARE WE IN MIDDLE OF BUFFER? CURPTR: .WORD 0 ;CURRENT POINTER INTO A BUFFER BNE GTCHAR ;BRANCH IF YES TO JUST PICK UP CHAR MOVB PRINTB,R3 ;GET LINK POINTER TO NEXT BUFFER BEQ LPEND ;NO MORE BUFFERS TO PRINT- ;NOTE INITIALIZE TAKES THIS PATH! MOVB R3,(PC)+ ;SAVE FOR LATER, SHORTCUT FOR RELINK CURBUF: .WORD 0 ;BUFFER NUMBER CHARACTERS CURRENTLY IN JSR PC,GETADR ;FORM ABSOLUTE POINTER TO BUFFER IN R2 MOV R2,(PC)+ ;AGAIN, SHORTCUT FOR RELINK CURBEG: .WORD 0 ;ABSOLUTE ADDRESS OF ACTIVE BUFFER MOVB (R2)+,PRINTB ;UNLINK FROM NEXT TO PRINT CHAIN MOV R2,CURPTR ;POINT TO FORM FEED FLAG GTCHAR: MOVB @CURPTR,R5 ;GET NEXT CHAR BPL 1$ ;BRANCH IF JUST NORMAL CHAR COMB R5 ;THIS CHAR WAS END OF THIS BUF LOAD! MOVB FREEB,@CURBEG ;PUT BUFFER BACK INTO FREE LIST MOVB CURBUF,FREEB MOV #-1,CURPTR ;FORCE CURPTR TO 0, CAUSES A NEW BUFFER ;TO GET USED NEXT TIME 1$: INC CURPTR ;BUMP CURPTR TO NEXT CHAR CMPB R5,#40 ;PRINTING CHAR? BLO CHRTST ;NO-GO TEST FOR SPECIAL CHAR. CMPB #140,R5 ;LOWER CASE? BHIS PCHAR ;NO SUB (PC)+,R5 ;YES, CONVERT IF DESIRED LCOPT: 40 PCHAR: DEC (PC)+ ;ANY ROOM LEFT ON LINE? COLCNT: .WORD COLSIZ ;# OF PRINTER COLUMNS LEFT BLT IGNORE ;NO MORE ROOM ON LINE,DON'T PRINT CHAR ASLB (PC)+ ;UPDATE TAB COUNT TABCNT: .WORD 1 BEQ RSTTAB ;RESET TAB LPRNT: MOVB R5,@(PC)+ ;PRINT THE CHAR LPDBP: .WORD LPDB ;POINTER TO LP DATA BUFFER BR LPNEXT ;TRY FOR NEXT CHAR CHRTST: CMPB R5,#HT ;IS CHAR A TAB? BEQ TABSET ;YES-RESET TAB CMPB R5,#LF ;IS IT LF? BEQ RSTC ;YES-RESTORE COLUMN COUNT CMPB R5,#CR ;IS IT CR? CROPT: BEQ RSTC ;PRINT UNLESS MODIFIED TSTB R5 ;IS IT A NULL? BEQ IGNORE ;NEVER PRINT NULLS CMPB R5,#FF ;IS IT A FF? CTROPT: BNE IGNORE ;IGNORE NON-PRINT CHARS UNLESS MODIFIED RSTC: MOV #COLSIZ,COLCNT ;RE-INITIALIZE COLUMN COUNTER RSTTAB: MOV #1,TABCNT ;RESET TAB COUNTER BR LPRNT ;PRINT THE CHAR TABSET: MOV TABCNT,TABFLG ;SET UP TAB TAB: MOV #BLANK,R5 ;PRINT SPACES BR PCHAR LPERR: BIS #HDERR,@-(R4) ;SET HARD ERROR BIT BR LPEXIT ;WATCH OUT FOR STACK! LPEND: BIC #LPIE,@LPCSRP ;DISABLE LP INTERRUPT LPBUFT: MOVB (PC)+,R3 ;IS A BUFFER AVAILABLE? FREEB: .WORD 0 ;START OF FREE BUFFER CHAIN BEQ RETURN ;BRANCH IF NOT TST (PC)+ ;ARE WE WORKING ON A REQUEST? QEPEND: .WORD 0 ;QUEUE ELEMENT PENDING FLAG BEQ RETURN ;BRANCH IF NOT, NOTHING TO DO MOV R3,-(SP) ;SAVE BUF NUM FOR LATER JSR PC,GETADR ;GET ABSOLUTE POINTER TO BUFFER HEAD MOV R2,R5 ;KEEP IN R5 MOVB @R5,FREEB ;REMOVE BUFFER FROM FREE LIST MOV #BUFNUM+1,R3 ;INIT HACK TO FIND END OF PRINTB CHAIN ;PRINTB MUST OCCUR AT END OF BUFFERS 1$: JSR PC,GETADR MOVB @R2,R3 ;AT END OF LIST YET? BNE 1$ ;BRANCH IF NOT MOVB (SP)+,@R2 ;LINK NEW BUFFER IN AT END CLR (R5)+ ;CLEAR CHAIN POINTER AND FF FLAG TST @R4 ;IS THIS A WRITE TO BLOCK 0? FFOPT: BNE BLKCOP ;BRANCH IF NOT MOVB #FF,-1(R5) ;SET FORM FEED FLAG INC @R4 ;MAKE SURE IT DOESN'T OCCUR AGAIN ;FOR THIS REQUEST BLKCOP: BIS #LPIE,@LPCSRP ;ENABLE INTERRUPTS, A BUFFER EXISTS MOV #256.,R3 ;BUFFERS ARE A MAXIMUM OF 256 WORDS CMP (R4)+,(R4)+ ;POINT TO DATA POINTER MOV (R4)+,R2 ;GET DATA POINTER 1$: MOV (R2)+,@R5 ;COPYT A WORD BIC #100200,(R5)+ ;MAKE SURE ONLY 7-BIT CODE INC @R4 ;INCREMENT WORD COUNT BEQ FREEQE ;REQUEST DONE- CLEAN UP DEC R3 ;KEEP BUFFERS TO 256 WORDS BNE 1$ ;BRANCH FOR MORE DATA COMB -(R5) ;FLAG END OF BUFFER MOV R2,-(R4) ;RESAVE NEW DATA POINTER RETURN: MOV (SP)+,R2 ;RESTORE SOME REGS MOV (SP)+,R3 RTS PC ;RETURN FREEQE: CLR QEPEND ;CLEAR Q ELEMENT PENDING FLAG COMB -(R5) ;FLAG END OF DATA IN BUFFER ; OPERATION COMPLETE MOV (SP)+,R2 ;RESTORE EXTRA REGS MOV (SP)+,R3 LPEXIT: MOV PC,R4 ADD #LPCQE-.,R4 ;ADDR OF CQE IN R3 MOV @#MONLOW,R5 JMP @OFFSET(R5) ;JUMP TO Q MANAGER GETADR: MOV R3,R2 ;COPY BUF NUMBER SWAB R2 ;*256 ADD R3,R2 ;*257 ASL R2 ;INTO BYTES ADD PC,R2 ;MAKE ABSOLUTE ADD #BUF-.-514.,R2 ;ADJUST, ACCOUNT FOR 1 ORIGIN RTS PC ;RETURN BUF: .REPT BUFNUM ;ALLOCATE THE BUFFERS .BLKW 257. .ENDR PRINTB: .WORD 0 ;START OF NEXT TO PRINT CHAIN ;MUST BE AT END OF BUFFERS!!! INTEN: .WORD 0 LPSIZE = .-LOADPT .END