CAN'T LOCATE THAT FILE! SIG/ACCESS: XA WHICH SECTION ( 0 1 2 ): 1 USING SECTION 1 DATABASE. SIG/ACCESS: TYPE MX80.ASM PAGE 0 ; +-----------------------------------------+ ; | MX-80 PRINTER DRIVER | ; | GARY P. NOVOSIELSKI | ; +-----------------------------------------+ ; ; SOME USEFUL EQUATES: ; CTRL EQU ' '-1 ;CONTROL KEY MASK NULL EQU CTRL AND '@' ;SOME ASCII DEFINITIONS BS EQU CTRL AND 'H' ;BACKSPACE HT EQU CTRL AND 'I' ;HORIZONTAL TAB LF EQU CTRL AND 'J' ;LINE FEED VT EQU CTRL AND 'K' ;VERTICAL TAB FF EQU CTRL AND 'L' ;FORM FEED CR EQU CTRL AND 'M' ;CARRIAGE RETURN SO EQU CTRL AND 'N' ;SHIFT OUT DC4 EQU CTRL AND 'T' ;DEVICE CONTROL 4 ETB EQU CTRL AND 'W' ;END OF TEXT BLOCK CAN EQU CTRL AND 'X' ;CANCEL ESC EQU CTRL AND '[' ;ESCAPE DEL EQU 7FH ;DELETE ; ;INITIALIZATION STRING FOR PRINTER: INITS DB NULL OR 80H ;MAKE SURE NO ESC SEQUENCE ;IS IN PROGRESS. DB CAN ;CANCEL ANYTHING IN BUFFER. DB ESC,'D' ;START THE TABSET SEQUENCE. DB 8,16,24,32,40,48,56,64,72,80 DB 88,96,104,112,120 DB NULL ;END THE SEQUENCE. PTRINIT DB 0 ;INITIALIZATION FLAG PESCF DB 0 ;ESCAPE IN PROGRESS FLAG PTRCHAR DB 0 ;COLUMN COUNTER WIDEFLAG DB 0 ;DOUBLE WIDTH FLAG ; FALSE EQU 0 TRUE EQU NOT FALSE ; ;ENTRY TO THE SUBROUTINE IS MADE HERE: LPTOUT: ;ON ENTRY, CHARACTER TO BE PRINTED IS IN ;REGISTER C. ; LDA PTRINIT ;SEE IF INITIALIZATION ORA A ;IS REQURED. JNZ INITD ;JUMP IF NOT. LXI H,INITS ;POINT TO THE INIT STRING. INITP MOV B,M ;PUT THE CHAR IN B REGISTER CALL PROUT ;FOR THE OUTPUT ROUTINE. MOV A,B ;GET BACK THE CHARACTER. INX H ;POINT TO NEXT CHARACTER. ORA A ;IF WE JUST SENT A ZERO (NUL), ;WE'RE DONE, JNZ INITP ;ELSE DO SOME MORE. DCR A ;PUTS 0FFH IN THE A REG. STA PTRINIT ;STORE TRUE IN INIT FLAG ;SO WE DON'T INITIALIZE EVERY ;TIME. ;THE PRINTER HAS BEEN INITIALIZED. INITD MOV B,C ;GET CHARACTER TO BE PRINTED ;TO THE B REGISTER. MOV A,C ;COPY TO A. ANI 7FH ;BUT ONLY LOW SEVEN BITS. MOV C,A ;SAVE THE STRIPPED COPY IN C ;FOR COMPARISONS LATER. LDA PESCF ;SEE IF THE ESCAPE FLAG ORA A ;IS TRUE, INDICATING JNZ PESCSP ;WE ARE IN THE MIDDLE OF AN ;ESCAPE SEQUENCE. ;ELSE THIS IS NOT AN ESCAPE SEQUENCE. JUST A CHARACTER. MOV A,C ;GET STRIPPED COPY TO A CPI DEL ;IF ITS A DEL, RZ ;IGNORE IT AND RETURN. ; ; LXI H,PTRCHAR ;POINT TO THE CHARACTER COUNTER. ;FOR LATER. CPI ' ' ;CHECK IF THIS IS A PRINTING JNC PRTCHAR ;CHAR. IF SO PRINT IT. ;THIS IS A CONTROL CHARACTER. CHECK FOR SPECIAL CASES CPI BS ;BACKSPACE CHAR? JC PROUT ;ANYTHING LESS GOES OUT AS IS. JZ PBS ;IF EQUAL, PROCESS BACKSPACE. ; CPI HT ;TAB CHARACTER? JZ PPTAB ; IF SO, PROCESS IT. ; CPI SO ;DOUBLE WIDTH SET COMMAND? JC NEWLINE ;ANYTHING LESS MUST BE EITHER ;LF, VT, FF, OR CR. HANDLE IT. JZ SETWIDE ; IF EQUAL, SET THE FLAG. ; CPI DC4 ;DOUBLE WIDTH CLEAR COMMAND? JZ CLRWIDE ; IF SO, CLEAR THE FLAG. ; CPI ESC ;ESCAPE CHARACTER? JZ PESCP ;INITIATE ESCAPE SEQUENCE ;PROCESSING. ; CPI ETB ;SPECIAL CHARACTER ETB MEANS ;DUMP THE BUFFER BUT DON'T ;AFFECT PRINT POSITION. JZ PETBP ; CPI CAN ;CANCEL MEANS ERASE THE BUFFER. ;AND RESET COUNTER. JNZ PROUT ;NONE OF THE ABOVE. JUST SEND. NEWLINE: ;A CHARACTER HAS BEEN RECEIVED WHICH ;RESETS THE COLUMN COUNT. XRA A ;A CHEAP ZERO MOV M,A ;TO THE COUNTER STA WIDEFLAG ;AND THE DOUBLE WIDTH FLAG JMP PROUT ;SEND WHATEVER IT WAS FROM ;REGISTER B. ; PRTCHAR: ;A NORMAL PRINTING CHARACTER OR SPACE ;IS GOING OUT. INR M ;INCREMENT COLUMN COUNT ; LDA WIDEFLAG ;IF DOUBLE WIDTH ORA A ; IS OFF JZ PROUT ; PRINT IT. ; INR M ;ELSE INCREMENT A SECOND TIME ; FOR DOUBLE WIDTH. JMP PROUT ; AND THEN PRINT IT. ; PPTAB: ;PROCESS A TAB CHARACTER LDA WIDEFLAG ;IF DOUBLE WIDTH ORA A ; IS ON JNZ PROUT ; TAB CHARACTERS ARE IGNORED ; FOR SOME UNKNOWN REASON. ; MOV A,M ;ELSE GET THE OLD COLUMN COUNT, ADI 8 ; ADJUST TO NEXT ANI NOT 7 ; TAB STOP MOV M,A ; AND UPDATE THE COUNT. JMP PROUT ;SEND HT CHAR TO PRINTER. ; PESCP: ;AN ESCAPE CHARACTER HAS BEEN RECEIVED ;MAKE A NOTE THAT A SEQUENCE IS IN PROGRESS. MVI A,TRUE ;PUT ALL ONES STA PESCF ; IN THE ESCAPE FLAG ; JMP PROUT ;SEND ESC TO PRINTER. PESCSP: ; PROCESS THE NEXT CHARACTER OF AN ESCAPE SEQUENCE. CPI TRUE ;IF THE ESCAPE FLAG IS ALL ; ONES, WE JUST BEGAN, ; SO THIS MUST BE THE JZ SECOND ; SECOND BYTE. ;ELSE THIS IS THE THIRD BYTE OR MORE THIRD CPI 'A' ;IF THIS IS AN ESC A SEQUENCE JZ LAST ; OR CPI 'C' ; AN ESC C SEQUENCE, JZ LAST ; THE THIRD BYTE IS THE LAST. ;ELSE THIS SEQUENCE TERMINATES WITH A NUL. MOV A,C ;SEE IF THIS BYTE ORA A ; IS A NUL. JNZ PROUT ;IF NOT WE'RE STILL WITHIN THE ;SEQUENCE. LAST XRA A ;LAST ONE. END THE SEQUENCE ; BY... NEXT STA PESCF ; ...UPDATING THE FLAG. JMP PROUT ;SEND THE BYTE TO THE PRINTER SECOND: ;SECOND CHAR OF ESC SEQUENCE. SEE WHAT THE ID CHARACTER IS: CPI 'A' ;A THRU D ARE 3 OR MORE BYTES JC LAST ; OTHERS ARE JUST TWO CPI 'E' ; SO WE DON'T SAVE ANYTHING JNC LAST ; JUST PUT THEM OUT. ;FOR THE LONG ONES, WE SAVE THE JMP NEXT ;ID CHARACTER BY... ; SETWIDE: ;A CTRL-N HAS BEEN RECEIVED. STA WIDEFLAG ;SET THE SOFTWARE FLAG JMP PROUT ; AND THE HARDWARE ONE. ; CLRWIDE: ;A CTRL-T HAS BEEN RECEIVED. XRA A ;CLEAR STA WIDEFLAG ; THE SOFTWARE JMP PROUT ; AND HARDWARE FLAGS. PBS: ;PROCESS A BACKSPACE CHARACTER XRA A ;CLEAR THE STA WIDEFLAG ;DOUBLE WIDTH FLAG. MOV A,M ;GET THE COLUMN COUNTER. ORA A ;IF AT LEFT MARGIN, NO EFFECT. RZ ; SO FORGET IT. ;ELSE MOV D,M ;SAVE COUNT IN D DCR M ;BACKSPACE THE COUNT. MVI B,CR ;PRINT THE LINE SO FAR BY SEND- ; ING A CARRIAGE RETURN CALL PROUT ; TO THE PRINTER. ;NOW GET READY TO SEND SOME MVI B,' ' ; SPACES. PBS1: ;SPACE OVER TO WHERE WE BELONG. DCR D ;DONE YET? RZ ; LEAVE IF SO CALL PROUT ;ELSE PUT OUT A SPACE. JMP PBS1 ; UNTIL WE GET BACK TO WHERE ; WE ONCE BELONGED. ; PETBP: ;HANDLE THE ETB CHARACTER. DONE SAME AS BS ;EXCEPT ONE MORE SPACE IS SENT. INR M ;ONE MORE SPACE JMP PBS ;GO TO IT ; PROUT EQU $ ;THE PROUT ROUTINE MUST SEND THE CHARACTER ;IN THE B REGISTER TO THE PRINTER, AND ;RETURN ALL REGISTERS IN THEIR ORIGINAL ;CONDITION, EXCEPT FOR A AND FLAGS. ; ;THE FOLLOWING IS AN EXAMPLE. THE LINES ;BEGINNING WITH A "U" CONTAIN UNDEFINED PORT ;VALUES WHICH DEPEND ON THE USER'S INDIVIDUAL ;HARDWARE. ; IN STATUSPORT ANI BUSYMASK JNZ PROUT ;MAKE IT "JZ" IF THE FLAG ;BIT IS A "READY" ;RATHER THAN A "BUSY". MOV A,B OUT DATAPORT RET ; ; END SIG/ACCESS: ;RATHER THAN A "BUSY".