home *** CD-ROM | disk | FTP | other *** search
- ;
- ; TITLE BI-DIRECTIONAL DIABLO PRINTER DRIVER
- ; FILENAME BIDI.LIB
- ; AUTHOR Robert A. Van Valzah 9/30/79
- ; LAST REVISOR R.A.V. 11/10/79
- ; REASON byte squeezing
- ;
- ;
- ; plan of attack:
- ; ===============
- ; characters come in one at a time and are stored into
- ; a buffer until a line feed comes in. at this point,
- ; the line in the buffer is analized and a decision is
- ; made to print it forward or backward so as to mininmize
- ; the head movement.
- ;
- ; the gory details:
- ; =================
- ; characters which are printable are just stored in the
- ; buffer. blanks, on the other hand, are accumulated
- ; and the number of blanks to move is stored with a bias
- ; of 80h. the first byte of the buffer is an exception:
- ; it is initialized to 0h and is used to accumulate the
- ; number of spaces between the left margin and the first
- ; printable character (this is the location leolpos).
- ; the position of the rightmost printable character is
- ; keep track of as characters come in the location reolpos.
- ;
- ; as the head is moved across the page, its position is
- ; recorded in hpos. this information is used in
- ; conjunction with leolpos and reolpos to determine if
- ; printing forward or backward will cause the shortest
- ; printhead movement. if the printhead is currently to
- ; the left of the centerpoint of the line, then it is
- ; shortest to move to the left end and start printing.
- ; otherwise, it is shortest to move to the right end
- ; and print backward. if the printhead is exactly at
- ; the midpoint, the line is printed backward so as to
- ; leave the printhead as close to the left margin
- ; as possible.
- ;
- ;
- ; port i/o number equates
- ;
- base equ 0f4h
- datal equ base
- datah equ base+1
- cmand equ base+2
- stats equ base
- ;
- ; print formatting equates
- ;
- ncols equ 120 ;max number of cols/line (must be <=126)
- ;
- ; command bits
- ;
- restr equ 1 ;restore carriage
- chstb equ 2 ;character strobe
- xstb equ 4 ;carriage strobe
- ystb equ 8 ;paper feed strobe
- selpr equ 10h ;select printer
- selry equ 20h ;select ready
- rblft equ 40h ;ribbon lift
- ;
- ; status bits
- ;
- chrdy equ 8 ;character ready
- xrdy equ 10h ;carriage ready
- yrdy equ 20h ;paper feed ready
- ;
- ;
- ; print character in reg c
- ;
- print:
- mov a,c ;get char to print to reg a
- ani 7fh ;strip parity
- mov c,a
- lhld nbufad ;and pointer to next buffer address
- cpi 13 ;test for special characters
- rz ;ignore carriage return
- cpi 10
- jz plf ;line feed
- cpi 12
- jz pff ;form feed
- inr m ;assume a space
- cpi ' '
- rz ;was a space, all done
- dcr m ;un-do assumption
- rc ;was some other control char, ignore
- ;must be a printable character
- mov a,l ;see if buffer is about overflow
- cpi low(buf+ncols-2)
- rz
- cpi low(buf) ;see if this is first character
- mov a,m ;get amt to move before printing
- jz gotamt ;jump if first character
- cpi 81h
- jz noblank ;no blanks between last & this char
- sui 80h ;subtract flag value
- gotamt: ;amount to move in reg a
- inx h ;move over number of blanks
- db 11h ;lxi trick to skip following mvi a
- noblank:
- mvi a,1 ;like one blank between character
- mov m,c ;store the character comming in
- inx h ;point to next buffer location
- mvi m,81h ;init to one blank to next char
- shld nbufad ;update buffer pointer
- lxi h,reolpos ;update right end of line position
- add m
- mov m,a
- ret
- ;
- ; print line feed
- ;
- plf:
- mov a,l ;see if nbufad = buf
- cpi low(buf) ;if = then blank line
- jz lfend ;=, so don't print anything
- lda leolpos ;get left end of line position
- mov b,a ;save it in reg b
- lda reolpos ;get right end of line position
- add b ;add leolpos to reolpos
- rar ;divide by two to find midpoint
- mov b,a ;save line center point in reg b
- lda hpos ;get current head position
- sub b ;hpos-(leolpos+reolpos)/2
- jc forward ;middle > hpos
- ;
- ; print the buffer backward
- ;
- backward:
- mvi a,80h ;put end of buffer marker at left end
- sta buf
- lda reolpos ;get absolute position of right eol
- lxi h,hpos ;compute amount to move to get there
- sub m ;reolpos-hpos
- lhld nbufad ;get right most character to print
- dcx h
- bkwd1:
- ;signed distance to move is now in reg a
- call movprt ;move as needed and print a character
- dcx h ;point to movement amount
- mov a,m ;amount to move to reg a
- sui 80h ;test for eob mark
- jz lfend ;hit end of line
- dcx h ;assume this is a movement
- cma ;two's comp for leftward movement
- inr a
- jnc bkwd1 ;it was, reg a has amount to move
- inx h ;it wasn't, fix buffer pointer
- mvi a,0ffh ;move one space to the left
- jmp bkwd1
- ;
- ; print buffer forwards
- ;
- forward:
- mvi m,80h ;put in eob mark (also ignores trailing blanks)
- lxi h,buf ;pointer into buffer
- mov a,m ;absolute pos of leftmost char to reg a
- inx h ;point to first printable character
- push h ;save buffer pointer
- lxi h,hpos ;compute amount to move to get to leolpos
- sub m ;leolpos-hpos
- pop h ;restore buffer pointer
- fwd1:
- ;signed distance to move is now in reg a
- call movprt ;move and print a character
- inx h ;point to next character
- mov a,m ;get it
- sui 80h ;test for end of line
- jz lfend ;hit end of line
- inx h ;point to character
- jnc fwd1 ;was a movement, reg a has distance
- dcx h ;was a character, backup pointer
- mvi a,1 ;and set amount to move to 1
- jmp fwd1 ;go print next character
- ;
- ; common finish up routine for print line feed
- ;
- lfend:
- lxi h,lfstodo ;add one to line feeds to do before
- inr m ;printing next line
- jmp init1 ;reset pointers
- ;
- ; print a form feed
- ;
- pff:
- lda lpp ;get lines per page
- lxi h,lonp ;subtract lines printed on this page
- sub m ;leaving lines left on this page
- sta lfstodo ;which is the number of lfs to do
- ret
- ;
- ; move the number of character positions in reg a (taken as a
- ; signed number, + to the right, - to the left) and
- ; print the character pointed to by reg hl.
- ;
- movprt:
- mov c,m ;get character to print
- push h ;save while printing
- mov e,a ;save amount to move in reg e
- movr:
- in stats ;wait for all movement to stop
- ani chrdy+xrdy+yrdy
- jnz movr
- lxi h,hpos ;update the head position byte
- mov a,e
- add m ;add amount we are moving
- mov m,a
- mvi b,xstb ;ready x strobe for movstb
- lda chwid ;load up character muliplicaton factor
- call movstb ;send necessary x movement
- lda lpp ;lines per page to reg b
- mov b,a
- lxi h,lfstodo ;number of pending line feeds
- mov a,m ;skip movement if zero
- ora a
- jz noymov ;no y movement
- mov e,a ;movement to reg e for movstb
- mvi m,0 ;there will be none to do now
- lxi h,lonp ;keep track of line on page
- add m
- mov m,a
- sub b ;see if started new page
- jc samepage ;nope
- mov m,a ;yes - take lonp mod lpp
- samepage:
- lda linhgt ;load up line multiplicaton factor
- mvi b,ystb ;ready y strobe for movstb
- call movstb ;send necessary y movement
- noymov:
- mov e,c ;send character
- mvi b,chstb ;send character strobe
- mvi a,1 ;dummy multiplication factor
- call movstb
- pop h
- ret
- ;
- ; move the signed amount in reg e using value in reg a as
- ; a mulitplication factor to get the number of increments
- ; then send strobe in reg b.
- ;
- movstb:
- push psw ;save multiplication factor
- mov a,e ;form a 16 bit amount to move in reg de
- ral ;sign of movement into carry
- sbb a ;generate sign extention
- mov d,a ;16-bit signed movement now in reg de
- pop psw ;get multiplication factor
- lxi h,0 ;initialize product
- mulbyw: ;multiply
- dad d
- dcr a
- jnz mulbyw ;keep multiplying
- mov a,h ;is this leftward movement?
- ora a
- jp posmov ;no - distance is ok
- xra a ;yes - negate distance
- sub l ;reg a = 0 - low order
- mov l,a ;which is low order compliment
- sbb h ;now subtract out high order and
- sub l ;subtract out excess low order
- ;complimented distance now in reg a and reg l
- ori 4 ;and set negative motion bit
- posmov:
- cma ;high order data is active low
- out datah ;send high order data
- mov a,l ;get low order data
- cma ;it too is active low
- out datal ;send low order data
- ;fall thru to strobe
- ;
- ; pulse strobe in reg b
- ;
- strobe:
- xra a ;delay a while for data set-up time
- dlay:
- dcr a
- jnz dlay
- mvi a,0ffh-selpr-rblft-selry
- push psw ;save bits which are allways high
- sub b ;lower appropriate strobe bit
- out cmand ;send strobe bit low
- pop psw ;and send it high
- out cmand
- ret
- ;
- ; init for printing
- ;
- init:
- mvi b,restr ;pulse restore line to
- call strobe ;reset printer
- xra a ;set software head position to zero
- sta hpos
- sta lonp ;reset line counter to top of page
- sta lfstodo ;zero out number of line feeds to do
- init1: ;empty buffer entry point
- xra a ;reset right end of line position
- sta reolpos
- lxi h,buf ;next buffer address pointer
- shld nbufad
- mov m,a ;inits left end of line position
- ret
- ;
- ;
- ; ram parameter area
- ;
- linhgt db 8 ;line height in increments
- chwid db 6 ;character width in increments
- lpp db 66 ;lines per page
- ;
- ; ram areas
- ;
- lonp ds 1 ;current line on page, 0 = first line
- lfstodo ds 1 ;line feeds to do before printing
- hpos ds 1
- reolpos ds 1
- nbufad ds 2
- buf:
- leolpos: ;address of byte containing left eol
- ds 1
- lmostch: ;address of left most character
- ds ncols
- ;
- end
-
-