title 'BGPRINT.ASM - printer character-conversion driver 6/16/85' ;-----------------------------------------------------------------------; ; Copyright (c) 1985 by: ; ; ; ; Plu*Perfect Systems ; ; Box 1494 ; ; Idyllwild Ca 94249 ; ; ; ; Licensed users of The Backgrounder are granted permission to use ; ; this program for non-commercial purposes provided copyright ; ; notices are retained intact. ; ; ; ; Please send a copy of improved versions to Plu*Perfect Systems. ; ;-----------------------------------------------------------------------; ; vers equ 1$1 ;veriosn 1.1 2/18/86 -- added optional pause method for buffered ; parallel printers ;version 1.0 1/13/86 -- first production version ; changed string substitution from single character ; to prefix character followed by another, prefix ; character quotes itself ; Also added check parameters to data structure so ; that config program can check space requirements ; ;version 0.4 6/16/85 -- initial release ; BGPRINT is a resident semi-permanent module for The Backgrounder ; that intercepts the bios LIST function. ; ; If the character sent to LIST is the PAUSE character it sounds an ; alarm and waits for the operator to react by: ; Turning the parallel printer off-line, or ; Pressing a key for a serial printer. ; ; If the character appears in the table of special characters, it ; discards the character and sends the special printer string for that ; character. ; ; All other characters are sent to the printer without change. ; ; Z80 code ; Addresses coded 'ADDRESS' are patched by the loader ; ; RMAC BGPRINT ; LINK BGPRINT[OP] ; maclib z80 maclib bgprint cseg ; ; PARAMETERS FOR THE MODULE LOADER ; org 0h ;labels for address relative ;convenience to 0000h ; wxwbadd: dw xwbadd-100h wbboot: dw xbboot-100h wconstat: dw xconst-100h wconin: dw xconin-100h wconot: dw xconot-100h wlst1: dw xlst1-100h wlst2: dw xlst2-100h wlsts1: dw xlsts1-100h wlsts2: dw xlsts2-100h wxlist: dw xlist-100h wxblst: dw xblist-100h wxdata: dw xdata-100h wstrtbl: dw strtbl-100h wstrngs: dw strngs-100h PAGE org 100h ; ; The module code, which will be relocated to run in high memory. ; ;--------------------------------*****----------------------------------; ; ; ; Standard header structure for Plu*Perfect Systems ; ; resident system extension module ; ; ; xstart: jmp ADDRESS ;bdos entry address ; xwboot$entry: jmp xwboot ;warm-boot trap ; xremove$entry: jmp xremove ;remove this module ; xwboot$addr: dw ADDRESS ;addr of bios warm-boot jmp vector ; xprotect$addr: dw xstart ;lowest protected address in this module; xname$addr: dw xname ;addr of nul/hi-bit terminated name ; u$wboot: jmp ADDRESS ;upper$wboot or ccp entry ; ; ;--------------------------------*****----------------------------------; ; The warm-boot trap for this module. ; xwboot: lhld xwboot$addr ;always restore 0001 shld 0001h inx h ;point at addr in biosjmp to warmboot lxi d,xwboot$entry ;if it points at us, mov a,e cmp m jrnz xwb1 inx h mov a,d cmp m jrnz xwb1 lhld xprotect$addr ;...(re)install our protect address shld 0006h xwb1: lda 4 ;in case this is the top module, mov c,a ;get logged drive/user jr u$wboot ;jump to next warm-boot addr in chain ;or to ccp entry if top module ; ; ; Remove the bios patches for this module, restoring the BIOS ; (and anything else that was patched) to its load-time state. ; xremove: xbboot equ $+1 lxi h,ADDRESS ;restore former warmboot addr xwbadd equ $+1 shld ADDRESS lhld xlst1 ;get list addr xblist equ $+1 shld ADDRESS ;restore bios jmp vector list address stc ;flag action done for REMOVE utility ret ; ; ; DATA AREA. For this module, the data are moved here by the ; loader so that they can be changed by patching without reassembly. ; ;parameters for checking maxcnt: db MAXCHR ;for checking by loader maxspc: dw MAXSTRS ;for checking by loader xdata equ $ pmethod: ds 1 ;method of parallel pause pausch: ds 1 ;the pause character prefch: ds 1 ;prefix character chrcnt: ds 1 ;count of special characters ;actual string area chrtbl: ds MAXCHR ;the special characters strtbl: ds 2*MAXCHR ;their string addresses strngs: ds MAXSTRS ;the strings ;each string is: length,char1,...,charn ; ; ; The bios LIST function performed by this module. ; xlist: lxi h,pausch ;is pause character active? mov a,m ora a ;NULL means pause is disabled mov a,c ;put list char in A jrz scan ;no cmp m ;is it the pause character? jrnz scan ;no ; LSTMASK equ 1100$0000b LPTMASK equ 1000$0000b ; ; Notify operator with bells that printer is paused. ; ; For a parallel printer, ring until printer is switched off line. ; optionally use serial method for parallel printers with buffers ; where busy line reflects state of buffer, rather than printer ; ; For a serial printer, ring until a keypress is detected. ; (Because the UART is buffered, we can't detect the printer ; busy/offline until another character is sent. If there ; is a do-nothing character for your printer, it could be ; repeatedly sent, with delays, until the printer is switched ; off line.) paus1: call rings lda iobyte ;which type of printer? ani LSTMASK xri LPTMASK jrnz serial lda pmethod ;for parallel have optional method ora a jrnz serial ;use serial method anyway xlsts1 equ $+1 ;liststat call ADDRESS ;for parallel printer, ora a ; continue ringing jrnz paus3 ;until operator makes it not ready xlsts2 equ $+1 ;liststat paus2: call ADDRESS ;now wait for ready to be restored ora a jrz paus2 ret ;and then return ; xconst equ $+1 ;constat serial: call ADDRESS ;for serial printer ora a ; continue ringing until keypress xconin equ $+1 ;conin jnz ADDRESS ;flush the keypress and return ;to LIST caller paus3: call wait ;interval between rings jr paus1 ; ; ; Scan the special-character table for a match ; If found, send its string to printer. Else send entering character. ; scan: preflag equ $ + 1 mvi a,0 ;flag for previous char ora a ;test inx h ;point to prefix character jrnz scan0 ;now check if it is the prefix character mov a,c cmp m ;do comparison jrnz go$list ;no action mvi a,0FFH sta preflag ;set flag ret ;swallow character ;always zero prefix flag scan0: xra a sta preflag ;clear prefix flag inx h ;->chrcnt mov b,m ;set count (+1) mov e,b ;save total count jr s0bot s0: inx h ;->chrtbl mov a,m cmp c jrz sfound s0bot: djnz s0 go$list: ;alternate exit point xlst1 equ $+1 ;list patch point jmp ADDRESS ;char not in table, so print it ;and return there to LIST caller ; sfound: mov a,e ; dcr a ;adjust for chrcnt being +1 sub b ; a = index of found char add a ;2x lxi h,strtbl ;index into address table add l mov l,a jrnc s1 inr h s1: mov a,m ;get string pointer from table inx h mov h,m mov l,a mov b,m ;str length inr b ;test for nul length jr sbot sloop: inx h mov c,m ;get char from string push b push h xlst2 equ $+1 ;list call ADDRESS ;send it to printer pop h pop b sbot: djnz sloop ret ;return to LIST caller ; ; ; ring RNGTIMES and return ; rings: mvi b, RNGTIMES r0: mvi c, CCOUNT*MHZ push b mvi c,BELL xconot equ $+1 ;conout call ADDRESS pop b call delay djnz r0 ret ; wait: mvi c,3*CCOUNT*MHZ ;silent for 3x the delay ; ; do C loops delay: lxi h,HLCOUNT d2: dcx h ;delay loops mov a,h ora l jrnz d2 dcr c jrnz delay ret ; ; Name of this module, hi-bit terminated xname: db 'BGPRINT v ',(vers/10) + '0','.', (vers mod 10) +'0' +80h ; end