; ; Printer Filter - will watch for print sequences and convert ; them into new sequences ; ; Setup so that an NEC P5XL will more closely emulate an Epson ; FX-80 or JX-80. Note that a P5XL is Epson LQ compatible ; ; This program installs itself as a TSR and monitors int 17h which ; is the bios printer support. If the requested operation is an ; output byte for printer LPT1, the program is activated. ; ; The printer control codes are intercepted as follows: ; ; ESC % (select ROM/Downloaded Character set) is ignored. ; ; ESC & (define download character set) is ignored. ; ; ESC m (can not remember why I did this - had a program ; that required it) is ignored. ; ; ESC A (set line spacing in n/72nds of an inch) - converted ; to setting in n/180ths of an inch by using the ; formula n * 5 / 2. ; ; ESC 3 (set line spacing in n/216ths of an inch) - converted ; to setting in n/180ths of an inch by using the ; formula n * 5 / 6. ; ; For both the spacing setting conversions, they can not be exact in ; all cases. If n is odd in ESC A, the error is 1/360th of an inch ; per line. In the ESC 3 case, the max error is 5/1080 of an inch per ; line - .306 in per 66 lines. ; ; If you really have an NEC P5 and are sure of what is being sent ; to it, the following changes will make the emulation more exact: ; ; Change the labeled lines as shown here ; ; esca: mov esc_seq,1 ; ; esc3: mov esc_seq,3 ; ; out_cd: mov al,1ch ;get FS ; ; This uses an P5 mode to output in 360ths of an inch but is limited ; to a max line spacing of 255/360 (approx .711 in). This should be ; okay for most graphics related software - but I had one package ; (SAMNA Word III) that was trying to set spacing to 1 inch and had ; problems. For ESC A, the result is exact. For ESC 3, the possible ; error is reduced to a max of 2/1080 of an inch per line or .122 in. ; ; Installation ; ; Assemble and create com file as follows: (you can use the copy ; of prnfiltr.com with this archive if no changes are needed). ; ; masm prnfiltr; ; link prnfiltr; ; exe2bin prnfiltr ; del prnfiltr.exe ; ren prnfiltr.bin prnfiltr.com ; ; Add prnfiltr as a line in your autoexec.bat file ; ; Comments ; ; This program produced by: ; ; Tom Frank ; 6474 Skyward Ct. ; Columbia, Md 21045 ; ; I can be reached on either of these two local BBS systems. ; ; Computer Connection (202) 547-2008 ; Baltimore Washington PC Exchange (301) 381-6411 ; or ; Compuserve 73200,1162. ; ; Comments or enhancements are welcome. I wrote this originally ; so that my P5XL would work properly with several graphics / ; word processors which did not support it directly. As always, ; use at your own risk. ; code_seg segment assume cs:code_seg, ds:code_seg org 100h first: jmp load_it ; data storage esc_seq db 0 ;non-zero if doing replacement last_esc db 0 ;non-zero if last char was ESC skip_cnt dw 0 ;non-zero-count of chars to ignore lc_set db 0 ;non-zero if in download char set command dwn_c1 db 0 ;1st char in download sequence five db 5 ;for mpy twelve db 0Ch ;for mpy ; symbolic equates old_int equ 60h routine proc far push ds push cs pop ds cmp dl,0 ;lpt 1? jne std_int ;no-do std code cmp ah,0 ;output byte function? jne std_int ;no test lc_set,0ffh ;in download? jz go_on_1 ;no jmp download ;yes go_on_1: test skip_cnt,0ffh ;skipping chars? jz go_on_2 ;no jmp skip_chars ;yes go_on_2: test esc_seq,0ffh ;doing an esc sequence? jnz do_seq ;yes test last_esc,0ffh ;last char an escape? jz see_esc ;no - see if this one is ; last char was an escape - is this something we need to do? mov last_esc,0 ;reset escape seen flag cmp al,41h ;is the char 'A'? je esca ;yes cmp al,33h ;is it '3'? je esc3 ;yes cmp al,6Dh ;is the char 'm'? je escm ;yes cmp al,26h ;is the char '&' je esc_and ;yes cmp al,25h ;is the char '%'? je esc_perc ; not a sequence we change - output an escape and then this char push ax mov al,1bh ;get an escape int old_int mov dx,0 pop ax int old_int leave: pop ds iret std_int: int old_int jmp leave see_esc: cmp al,1bh ;is char ESC? je see_esc1 ;yes jmp chk_csub ;no-check for char substitution see_esc1: mov last_esc,0ffh ;yes-set flag jmp leave esca: mov esc_seq,2 ;get divisor-set flag jmp leave esc3: mov esc_seq,6 jmp leave escm: mov esc_seq,0ffh jmp leave esc_and: mov lc_set,1 ;set saying just starting jmp leave esc_perc: mov skip_cnt,2 ;skip next 2 chars jmp leave do_seq: push ax ;save argumet to sequence mov al,esc_seq ;get sequence code cmp al,0ffh ;special one to skip? je skip_it ;yes out_cd: mov al,1bh ;get ESC int old_int mov dx,0 mov ah,0 mov al,33h ;get '3' int old_int pop ax ;get arg back mul five ;times multiplier div esc_seq ;divide by argument ;result is in 180ths of an inch mov dx,0 mov ah,0 int old_int mov esc_seq,0 jmp leave skip_it: pop ax mov esc_seq,0 jmp leave skip_chars: dec skip_cnt ;reduce count by 1 jmp leave download: cmp lc_set,1 ;only seen ESC & so far? jne down_1 ;no-seen more mov lc_set,2 ;yes-prepare for 1st char id jmp leave down_1: cmp lc_set,2 ;is this the 1st char? jne down_2 ;no mov dwn_c1,al ;yes-save it mov lc_set,3 ;say looking for 2nd char jmp leave down_2: sub al,dwn_c1 ;get #chars to define inc al ;normalize it mul twelve ;times chars to skip mov skip_cnt,ax ;save as chars to skip mov lc_set,0 ;clear download seq flag jmp leave chk_csub: cmp al,7Fh ja chk_1 ;jump if user defined jmp std_int ;no-just output it chk_1: cmp al,0B2h ;do we want to sub it? jne chk_2 ;no mov al,0DAh jmp std_int chk_2: cmp al,0B5h ;do we want to sub it? jne chk_3 ;no mov al,0C4h jmp std_int chk_3: cmp al,0B0h ;do we want to sub it? jne chk_4 ;no mov al,0C0h jmp std_int chk_4: cmp al,0B1h ;do we want to sub it? jne chk_5 ;no mov al,0B3h jmp std_int chk_5: cmp al,0B4h ;do we want to sub it? jne chk_6 ;no mov al,0D9h jmp std_int chk_6: cmp al,0B7h ;do we want to sub it? jne chk_7 ;no mov al,0BFh jmp std_int chk_7: cmp al,0B3h ;do we want to sub it? jne chk_8 ;no mov al,0C3h jmp std_int chk_8: cmp al,0B6h ;do we want to sub it? jne chk_9 ;no mov al,0C1h jmp std_int chk_9: cmp al,0B8h ;do we want to sub it? jne chk_A ;no mov al,0B4h jmp std_int chk_A: cmp al,0B9h ;do we want to sub it? jne chk_B ;no mov al,0C2h jmp std_int chk_B: cmp al,0BAh ;do we want to sub it? jne chk_C ;no mov al,0C5h jmp std_int chk_C: jmp std_int routine endp load_it proc near mov ah,35h ;get int vector mov al,17h ;bios printer spt int 21h push es pop ds ;get segment mov dx,bx ;get offset mov ah,25h ;set int vector mov al,old_int ;for old as this one int 21h push cs pop ds ;get our address mov dx,offset routine mov ah,25h mov al,17h int 21h mov dx,offset load_it int 27h load_it endp code_seg ends end first