;******************************************************** ;* * ;* BI-DIRECTIONAL PRINTING DRIVER * ;* FOR DIABLO 1620 OR SIMILAR * ;* DAISYWHEEL PRINTER * ;* * ;******************************************************** ; ; VERSION: 1.00 ; ; DATE: 03/Mar/1980 ; ; HISTORY: Modified for CP/M use ; from PTDOS program ; originally published by PROTEUS ; ; Modifications by: ; Bill Bolton ; Software Tools ; P.O. Box 80, ; Newport Beach, ; NSW, 2106, ; Australia ; NULL EQU 000H ;ASCII NULL DEL EQU 07FH ;ASCII DELETE CR EQU 00DH ;ASCII CARRIAGE RETURN LF EQU 00AH ;ASCII LINE FEED FF EQU 00CH ;ASCII FORM FEED ESC EQU 01BH ;ASCII ESCAPE HTAB EQU 009H ;ASCII HORIZONTAL TAB SPACE EQU 020H ;ASCII ' ' BACKSP EQU 008H ;ASCII BACKSPACE ACK EQU 006H ;ASCII ACKNOWLEDGE ETX EQU 003H ;ASCII END OF TEXT STPORT EQU 003H ;HORIZON 1ST SERIAL STATUS DPORT EQU STPORT-1 ;HORIZON 1ST SERIAL DATA OUTMASK EQU 001H ;OUTPUT STATUS MASK INMASK EQU 002H ;INPUT STATUS MASK COUNT EQU 150 ;DIABLO BUFFER LENGTH ; ORG 0F200H ;Or wherever suits ; PROCESS: MOV A,C CPI CR ;CARRIAGE RETURN ? JZ PRINT ;YES, PRINT OUT THE BUFFER CPI LF ;LINE FEED ? JZ PUTC ;YES, SEND IT CPI FF ;FORM FEED ? JZ PUTC ;YES, SEND IT CPI DEL ;DELETE ? RZ ;YES, IGNORE IT CPI NULL ;NULL ? RZ ;IGNORE IT ; PRO2: LDA EOLINE ;INCREMENT END OF LINE INR A STA EOLINE LHLD TXTPT ;GET TEXT POINTER MOV M,C ;CHARACTER WAS IN C INX H ;BUMP POINTER MVI M,0 ;BUFFER END MARK IS 0 SHLD TXTPT ;STORE POINTER RET ; ;* This routine strips leading and lagging blanks from ;* the buffer before sending the buffer out to the printer. ; ;* Strip the leading blanks ; PRINT: LXI H,BUFFER+1 ;POINT TO 1ST CHARACTER POSITION MVI D,0 ;BLANKS COUNTER MVI A,SPACE ;BLANK FOR COMPARISION P1: CMP M ;BLANK ? JNZ P2 ;NO, STOP COUNTING INR D INX H JMP P1 ; P2: DCX H ;POINT TO CHAR-1 MVI M,0 ;PUT IN A MARKER MOV A,D ;GET BLANK COUNT STA BOLINE ;AND SAVE IT ; ;* Strip the lagging blanks ; LHLD TXTPT ;POINT TO BUFFER END MARK LDA EOLINE ;GET CHARACTER COUNT MOV D,A MVI A,SPACE ;GET A SPACE ; P3: DCX H DCR D ;BLANK COUNTER CMP M ;IS IT A SPACE ? JZ P3 ;YES, KEEP COUNTING ; P4: INX H ;NO, BACK UP THE POINTER MVI M,0 ;STORE END MARKER MOV A,D STA EOLINE ;STORE NEW COUNT SHLD TXTPT ;STORE NEW BUFER END ; ;* Calculate the most efficient direction to print ;* (logic seeking). ; DRCTN: LDA HDPOS ;GET PRINT HEAD POSITION PUSH PSW ;SAVE IT LXI H,BOLINE ;POINT TO BEGINNING OF LINE SUB M ;FIND THE DIFFERENCE CM ABSVAL ;TAKE THE ABSOLUTE VALUE MOV B,A ;SAVE IT IN B INX H ;GET THE END OF LINE POP PSW ;GET HEAD POSITION SUB M ;FIND THE DIFFERENCE CM ABSVAL ;TAKE THE ABSOLUTE VALUE SUB B ;COMPARE DISTANCE TO BOL AND EOL JP MFWRD ;IF PLUS FORWARD IS FASTER ; ;* Print backwards ; MBWRD: MVI D,'6' ;DIABLO BACKWARD PRINT CODE LDA EOLINE ;GET END OF LINE CALL ALIGN ;PROCESS THE DATA LDA BOLINE ;POSITION OF 1ST BUFFER CHARACTER ORA A ;IS IT THE ZERO POSITION JZ MB2 ;YES, CANT TAB LEFT OF MARGIN DCR A ; MB2: STA HDPOS ;UPDATE HEAD POSITION LXI D,-1 LHLD TXTPT ;POINT TO END OF BUFFER JMP PRLINE ;PRINT THE BUFFER ; ;* Print forwards ; MFWRD: MVI D,'5' ;DIABLO FORWARD PRINT CODE LDA BOLINE ;GET BEGINNING OF LINE CALL ALIGN LDA EOLINE ;GET LAST CHARACTER POSITION INR A STA HDPOS ;SAVE NEW HEAD POSITION LXI H,BUFFER ;POINT TO BUFFER START LDA BOLINE ;COMPUTE POSITION OF 1ST NON BLANK MVI D,0 MOV E,A DAD D LXI D,1 ;SET UP TO READ BUFFER FORWARD ; ;* Print the buffer ; PRLINE: DAD D ;BUMP HL MOV A,M ;MOVE CHARACTER IN BUFFER TO A ORA A ;END OF BUFFER ? JZ CLRBUF ;YES, GO CLEAN UP CALL PUTC ;PRINT THE CHARACTER JMP PRLINE ; ;* Align the Print Head to the correct position ;* to start printing ; ;* NOTE: The diablo 1610/1620 can only do an ;* "absolute tab" to the first 126 character ;* positions. ; ;* D = Direction of printing ;* A = BOLINE or EOLINE ; ALIGN: MOV E,A ;SAVE BOLINE/EOLINE MVI A,ESC ;GET "COMMAND" CODE CALL PUTC ;SEND IT MOV A,D ;GET THE DIRECTION CODE CALL PUTC ;SEND IT ; MVI A,ESC ;GET "COMMAND" CODE CALL PUTC ;SEND IT MVI A,HTAB ;GET ABSOLUTE TAB CODE CALL PUTC ;SEND IT MOV A,E ;GET LOCATION TO TAB TO ADI 1 ;ADD TO SATISFY DIABLO JMP PUTC ;SEND IT AND RETURN ; CLRBUF: LXI H,BUFFER+1 ;CLEAR BUFFER SHLD TXTPT XRA A STA EOLINE ;RESET COUNTERS STA BOLINE STA BUFFER+1 RET ; ABSVAL: CMA ;TAKE THE ABSOLUTE VALUE INR A RET ; PUTC: MOV C,A CALL OUTPUT ;SEND THE CHARACTER CPI ESC ;WAS IT AN ESCAPE? JZ ESCSEQ ;YES, NEEDS SPECIAL TREATMENT LDA OUTCNT ;CHARS SENT SINCE O/P COUNT RESET DCR A STORE: STA OUTCNT ;SAVE UPDATED COUNT RNZ ;NO, RETURN MVI A,COUNT ;SET COUNT STA OUTCNT MVI C,ETX ;YES, GET ETX CALL OUTPUT ;SEND IT ACKLOOP: CALL INPUT ;GET CHARACTER FROM PRINTER CPI ACK ;DIABLO SENDS ACK WHEN IT GETS ETX ;FROM ITS CHARACTER BUFFER JNZ ACKLOOP ;NOT FOUND, KEEP LOOKING RET ; ESCSEQ: LDA OUTCNT ;GET OUTPUT COUNT ADI 2 ;MAKE SURE NEXT TWO CHARS, JMP STORE ;GET SENT BEFORE ETX ; OUTPUT: IN STPORT ;1ST SERIAL PORT ANI OUTMASK JZ OUTPUT MOV A,C OUT DPORT RET ; INPUT: IN STPORT ANI INMASK JZ INPUT IN DPORT ANI 07FH RET ; ; HDPOS DB 0 ;CURRENT HEAD POSITION BOLINE DB 0 ;BEGINNING OF LINE POINTER EOLINE DB 0 ;END OF LINE POINTER TXTPT DW BUFFER+1 ;BUFFER POINTER OUTCNT DB COUNT ;CHARACTERS SENT TO PRINTER ; BUFFER DW 0000H DS 160 ;CHARACTER BUFFER ; END PROCESS