home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Vectronix 2
/
VECTRONIX2.iso
/
FILES_01
/
HP_550C.LZH
/
DJ550DEP.S
< prev
next >
Wrap
Text File
|
1994-06-27
|
47KB
|
1,639 lines
*************************************************************************
* *
* HP_DJ550.S *
* Modifié par Thierry Rodolfo 24/03/1994 *
*************************************************************************
*************************************************************************
* *
* This module contains the HP PaintJet dependent portion of *
* the assembler code for printer output. *
* *
* This code has been brought up-to-date with the printer driver *
* source received 5/31/85. *
* J. Shillington, Bell Northern Research *
* *
* Modifications made by Theresa Estrada 4/10/91 Atari Corp. *
* *
*************************************************************************
.text
*************************************************************************
* *
* Locally Defined Procedures and Variables *
* *
*************************************************************************
.globl _set_vars * Initial setup of printer driver vars
.globl _getlstat
.globl concat * convert x-y coordinates to buffer offsets
.globl _enter_gr * enter graphics mode
.globl _adv_form * perform a form feed
.globl _scan_out * print contents of the rasterizing buffer
.globl _exit_gr * exit graphics mode
.globl _alphaout * print alphanumeric text
.globl _init_p * initialize printer output routines
.globl _dinit_p * de-initialize printer output routines
.globl printer_out * output a string to printer
.globl pout * output a character to printer
.globl _abort * abort flag
.globl _handle
.globl _com_port
.globl _sendbuff * Send addr of buffer to app (STUB)
.globl _num_planes
.globl _num_colors
.globl _PAL_RGB
.globl _MAP_COL
.globl byte_out * temporarily global for debugging only
.globl lastplane
* .globl _COLOR_TAB
.globl PLANE_COLORS
.page
*************************************************************************
* *
* Externally Defined Labels *
* *
*************************************************************************
.xref _YS_MIN
.xref _YS_MAX
.xref _YW_MAX
.xref graph_plane
.xref slice_cnt
.xref _vmu
.xref _curalpha
.xref _reqalpha
.xref print_wires
.xref slice_width
.xref scan_line_offset
.xref slice_offset
.xref bytes_line
.xref bytes_per_scan
.xref _A_SLICE
.xref _INTIN
.xref _CONTRL
.xref _PTSIN
* Driver structure variables TE 6/5/91
.xref NPLANES
.xref PAGESIZE
.xref XRES
.xref YRES
.xref PGSZ_TAB
.xref _drvr_qulty
.xref _newbuff_ad * TE 7/18/91
.xref _TOPMRGN * TE 8/10/92
.xref _LFTMRGN
.xref _BOTMRGN
.xref _RHTMRGN
.xref TOPMRGN2 * TE 8/17/92
.xref LFTMRGN2
.xref BOTMRGN2
.xref RHTMRGN2
************************************************************************
*
* Added 3/11/87 CS Configurable variables
*
.xref xresmx
.xref yresmx
.xref xsize
.xref ysize
.xref num_planes
.xref num_colors
*
.xref def_sl_cnt
.xref def_sl_sz
.xref def_plane_sz
*
.xref drast_sz
.xref dlist_sz
.xref min_free
.xref max_list
.xref max_rast
*
.xref _A_PAGE
.xref _G_PAGE
.xref _G_SLICE
*
.page
*************************************************************************
* *
* Local Constants *
* *
*************************************************************************
CR .equ $0D * carriage return
ESC .equ $1B * escape character
FORM_FEED .equ $0C * form feed
LF .equ $0A * line feed
ALPHA_ESCAPE .equ $12 * alphanumeric attribute escape character
_set_vars:
move.l #0,_newbuff_ad * Ignore memory driver variable
move.l _CONTRL,a0
tst.w 2(a0)
beq use_defaults
move.l _PTSIN,a0
move.w (a0)+,xresmx * Get x resolution
move.w (a0)+,yresmx
bra no_defs
use_defaults:
move.w PAGESIZE,d0 * index into PGSZ_TAB for first dpi available
cmp.w #4,d0 * use user-defined xres & yres?
beq set_xyres * yes
get_sz:
lea.l PGSZ_TAB,a1 * table for pg. sz. values according to dpi
move.w NPLANES,d1
cmp.w #4,d1 * 4 planes? (means use next dpi)
bne first_dpi * no
next_dpi:
adda.l #16,a1 * yes - advance to next set of dpi values
first_dpi:
move.w PAGESIZE,d0 * for offset into pgsz_tab
mulu.w #4,d0 * 2xwords+2ywords=4xywords=2longs
adda.l d0,a1 * advance correct offset into pgsz_tab
move.w (a1)+,xresmx
move.w (a1)+,yresmx
bra no_defs
set_xyres:
move.w XRES,xresmx
move.w YRES,yresmx
no_defs:
lea _DEV_TAB,a0 * Address of device table
move.w xresmx,(a0)+ * and put in xresmx and yresmx
move.w yresmx,(a0)+
move.w NPLANES,d0
cmp.w #4,d0
blt fewplanes
move.w #85,xsize * pixel size in microns for 4 planes 90dpi
move.w #85,ysize
move.w TOPMRGN2,d0
move.w d0,_TOPMRGN
move.w BOTMRGN2,d0
move.w d0,_BOTMRGN
move.w LFTMRGN2,d0
move.w d0,_LFTMRGN
move.w RHTMRGN2,d0
move.w d0,_RHTMRGN
bra store_pixsz
fewplanes: * pixel size in microns for 1-3 planes 180dpi
move.w #85,xsize
move.w #85,ysize
store_pixsz:
tst.w (a0)+ * Get ready to set
move.w xsize,(a0)+ * Xsize and
move.w ysize,(a0) * Ysize
move.w NPLANES,num_planes * Number of planes
move.w num_planes,_num_planes * copy for C portion of code
move.w num_planes,d0 * index into COLOR_TAB
lea.l PLANE_COLORS,a1 * table for # of colors according to # of planes
subq.w #1,d0 * for dbra
find_color:
move.w (a1)+,num_colors
dbra d0,find_color
move.w num_colors,_num_colors * copy for C portion of code
adda.l #18,a0 * set ptr in DEV_TAB
move.w num_colors,(a0) * store color variable
move.w xresmx,d0 * bytes_line = (xresmx+7)/8
addq.w #7,d0
ext.l d0
divs #8,d0
addq #1,d0
and.w #$FFFE,d0 * Assure even bytes
move.w d0,bytes_line
*
move.w #1,print_wires * 1 line per print pass
move.w #1,slice_width * # of lines per slice
*
move.w slice_width,d0 * slice_offset = slice_width*bytes_line
muls bytes_line,d0
move.w d0,slice_offset
*
move.w bytes_line,d0 * scan_line_offset = bytes_line
move.w d0,scan_line_offset
*
move.w bytes_line,d0 * bytes_per_scan = slice_width*bytes_line
muls slice_width,d0
move.w d0,bytes_per_scan
*
move.w #2,def_sl_cnt * default number of slices
*
move.w slice_width,d0 * def_sl_sz = def_sl_cnt*slice_width
muls def_sl_cnt,d0
move.w d0,def_sl_sz
*
move.w bytes_per_scan,d0 *def_plane_sz=def_sl_cnt*bytes_per_scan
muls def_sl_cnt,d0
move.l d0,def_plane_sz
*
muls num_planes,d0
move.l d0,drast_sz * FOUR PLANES FOR SIXTEEN COLORS - TE
*
move.l #$400,dlist_sz * Internal display list buffer size
move.l #$8000,min_free * Minimum amount of free memory left
move.l #$8000,max_list * Maximum display list buffer size
*
move.w yresmx,d0 * max_rast=(yresmx+1)*
addq.w #1,d0
muls num_planes,d0 * num_planes*bytes_line
muls bytes_line,d0
move.l d0,max_rast
*
move.w #63,_A_PAGE * # of alpha text lines per page(10.5 in)
move.w #24,_A_SLICE * alpha text height in pixels
*
move.w yresmx,d0 * _G_PAGE = (yresmx+1)/slice_width
addq.w #1,d0
ext.l d0
divs slice_width,d0
move.w d0,_G_PAGE
*
move.w slice_width,_G_SLICE
move.w #0,d0
*
rts
_sendbuff:
rts
_getlstat:
move.w #0,d0 * Stub in dot matrix printers
rts
.page
*************************************************************************
* *
* CONCAT *
* *
* This routine converts x and y-coordinates into a physical *
* offset to a word in the rasterizing buffer and an index to *
* the desired bit within that word. *
* *
* Inputs: *
* d0.w = x-coordinate *
* d1.w = y-coordinate *
* *
* Outputs: *
* d0.w = word index (x mod 16) *
* d1.l = physical offset -- (y * bytes_line) *
* + (x & $FFF0) >> 3 *
* *
* Registers Modified: None *
* *
*************************************************************************
*
* Save the registers that get clobbered and convert the y-coordinate
* to an offset to the start of the desired scan row.
*
concat:
move.w d2,-(a7) * save the register that gets clobbered
* sub.w _TOPMRGN,d1 * NOT NEEDED CUZ YS_MIN IS ADJUSTED ACCORDINGLY
sub.w _LFTMRGN,d0
sub.w _YS_MIN,d1 * normalize the y-coordinate to start of slice
mulu bytes_line,d1 * compute offset to start of scan row
*
* Compute the bit offset into the desired word, save it, and remove
* these bits from the x-coordinate.
*
move.w d0,d2 * save a copy of the x-coordinate
andi.w #$0F,d0 * convert it to bit offset into word
sub.w d0,d2 * clear bits for offset into word
*
* Convert the adjusted x-coordinate to a word offset into the current
* scan line by dividing it by 8. Compute the total offset into the
* buffer and restore the clobbered registers before returning.
*
asr.w #3,d2 * convert result to word offset
ext.l d2 * convert word offset to long word
add.l d2,d1 * compute total offset into buffer
move.w (a7)+,d2 * restore the clobbered register
rts
_init_p:
jsr _set_vars
rts
_dinit_p:
rts
*************************************************************************
* *
* printer_out *
* *
* This routine outputs a string of characters to the printer *
* buffer. The first byte in the string is a signed count of *
* the number of characters. *
* *
* Inputs: *
* a0 - address of string to print *
* *
* Registers Modified: d0, d1, a0 *
* *
*************************************************************************
*
* If something has gone wrong with the printer then abort the
* print job.
*
printer_out:
movem.l d0-d7/a0-a6,-(sp)
tst.w _abort * check the abort flag
bne end_ptr_out * it's non-zero so bail out
*
* Get the length of the string.
*
moveq.l #0,d1
move.b (a0)+,d1 * get the count
cmp.b #1,d1
beq end_ptr_out * nothing to xmit if the count is 0
moveq.l #0,d0 * clear for bios call
*
* Loop buffering the characters.
*
ptrout1:
move.l a0,-(sp)
move.l d1,-(sp)
move.w _handle,-(sp)
move.w #$40,-(sp)
trap #1
adda.w #12,sp
* move.b (a0)+,chr_ad1
* movem.l d0-d1/a0,-(sp)
* move.w chr_ad,-(sp)
* move.w #0, -(sp) * Ici fonction Bconout
* move.w #3, -(sp) * Sortie d'un car. sur
* trap #13 * 0=Centronics 1=R232 5=ecran
* adda.w #6,a7
* movem.l (sp)+,d0-d1/a0
* dbra d1,ptrout1
end_ptr_out:
movem.l (sp)+,d0-d7/a0-a6
rts
.page
*************************************************************************
* *
* pout *
* *
* This routine outputs a single character to the printer *
* port. *
* *
* Inputs: *
* d0 - character to print *
* *
* Registers Modified: d0 *
* *
*************************************************************************
*
* If something has gone wrong with the printer then abort the
* print job.
*
pout:
movem.l d0-d7/a0-a6,-(sp)
poutb:
tst.w _abort * check the abort flag
bne.w pout2 * it's non-zero so bail out
move.b d0, chr_ad
pea chr_ad
move.l #1,-(sp)
move.w _handle,-(sp)
move.w #$40,-(sp) * setup for gemdos write call
trap #1
adda.l #12,sp
pout2:
movem.l (sp)+,d0-d7/a0-a6
rts
.page
*************************************************************************
* *
* INIT_DEV *
* *
* This routine initializes the printer. It is a no-op for *
* the Epson printer. *
* *
* Inputs: None *
* *
* Outputs: None *
* *
* Registers Modified: None *
* *
*************************************************************************
.page
*************************************************************************
* *
* DINI_DEV *
* *
* This routine de-initializes the printer. It is a no-op for *
* the Epson printer. *
* *
* Inputs: None *
* *
* Outputs: None *
* *
* Registers Modified: None *
* *
*************************************************************************
.page
*************************************************************************
* *
* ENTER_GR *
* *
* This routine is used to put the printer into graphics mode *
* and to set the desired defaults. For the HP paintjet the *
* defaults include: page width, dpi, number of planes, *
* color palette, cursor position, and transmission mode. *
* *
* Inputs: None *
* *
* Outputs: None *
* *
* Registers Modified: None *
* *
*************************************************************************
_enter_gr:
lea width,a0
jsr printer_out
lea low_dpi,a0 * default = 90 dpi (planes=4)
jsr printer_out
move.w NPLANES,d1
cmp.w #4,d1 * max. # of planes?
bne highdpi * no - so use 180 dpi
bra send_numplanes * yes - 90 dpi already set above
highdpi:
tst.w _drvr_qulty * draft_mode?
beq send_numplanes * yes - lower dpi already set above
lea high_dpi,a0 * no - use high dpi for final mode
jsr printer_out
send_numplanes:
lea escape_r,a0 * 1st part
jsr printer_out
moveq #0,d0
move.w NPLANES,d0 * # 4 of planes on force 4 plans
jsr convert_itoa * 2nd part
move.b #'U',d0 * 3rd part
jsr pout
clr.l d1
clr.l d0
* lea _COLOR_TAB,a1
color_palette:
cont_scan:
lea enter_graph,a0 * start raster graphics
jsr printer_out
lea transmit_mode,a0 * transmission mode (compression)
jsr printer_out
rts
.page
*************************************************************************
* *
* ADV_FORM *
* *
* This routine advances the printer to the start of the next *
* form. *
* *
* Inputs: None *
* *
* Outputs: *
* vmu - reset to 0 *
* *
* Registers Modified: d0 *
* *
*************************************************************************
_adv_form:
moveq #FORM_FEED,d0 * get form feed control code
jsr pout * stuff it into printer transmit buffer
clr.w _vmu * reset the vertical motion unit counter
rts
.page
*************************************************************************
* *
* EXIT_GR *
* *
* This routine takes the printer out of the graphics mode. *
* *
* Inputs: None *
* *
* Outputs: None *
* *
* Registers Modified: a0 *
* *
*************************************************************************
_exit_gr:
lea end_graph,a0 * send end graphics sequence
jsr printer_out
rts
.page
*************************************************************************
* *
* CONVERT_ITOA *
* *
* Inputs: d0 *
* *
* Outputs: ascii value sent to printer *
* *
* Registers Modified: d0, d1, a7 *
* *
*************************************************************************
convert_itoa:
movem.l d0-d1,-(a7) * save registers
clr.l d1 * loop cntr
next_digit:
divu #10,d0 * divide by base 10
swap d0
add.b #"0",d0 * convert to ascii
move.b d0,-(a7) * store on stack
addq.b #1,d1
clr.w d0 * clear what will be high word
swap d0
tst.w d0
bne next_digit
subq.b #1,d1 * for dbra
ascii_value:
move.b (a7)+,d0
jsr pout
dbra d1,ascii_value
movem.l (a7)+,d0-d1 * restore registers
rts
.page
*************************************************************************
* *
* SCAN_OUT *
* *
* Scan the contents of the rasterizing buffer. Discard any *
* trailing blanks. If there is any data to send to the *
* printer then convert it to printer dependent format, and *
* send it. *
* *
* Inputs: None *
* *
* Outputs: None *
* *
* Registers Modified: d0, d1, d2, a0, a1, a2 *
* *
*************************************************************************
*
* Save the registers that get clobbered and determine how many
* slices of graphic data are in the rasterizing buffer.
*
_scan_out:
movem.l d1-d7/a3-a6,-(a7) * save the registers used by C
move.w _YW_MAX,d7 * get upper limit of window
cmp.w _YS_MAX,d7 * does this slice extend beyond the window?
blt calc_cnt * yes - determine how many slices to print
move.w slice_cnt,d7 * nope - get # of slices in buffer
bra scan_parms
calc_cnt:
sub.w _YS_MIN,d7 * get # of scans - 1 in buffer
move.w slice_width,d6 * get # of scans in a slice
add.w d6,d7 * add it to # of scans - 1 for rounding
ext.l d7 * make result a 32-bit quantity
divs d6,d7 * compute # of slices to draw
*
* Get the address of the rasterizing buffer, initalize some additional
* parameters, and loop drawing slices of the buffer's contents to
* the necessary planes.
*
scan_parms:
movea.l graph_plane,a2 * get address of rasterizing buffer
movea.w bytes_line,a6 * get length of a single scan line
move.w scan_line_offset,a5 * get length of two scan lines
subq.w #1,d7 * convert # of slices to loop counter
*
* Analyse and output data for each color, one scan line at a time.
*
moveq.l #1,d1 * initialize plane counter
clr.b lastplane
move.l a2,plane_top * Point to 1st plane, this slice
scan_next_slice:
jsr back_scan * eliminate trailing blanks in the line
tst.w d3 * any non-blank bytes left?
bmi no_data * no
jsr byte_out * yes - print data for current color index
tst.b lastplane * last color plane?
bne check_qulty_mode
addq.w #1,d1 * no - increment plane counter
cmp.w num_planes,d1 * last color plane?
bne next_plane * no
st lastplane * yes-set variable for special escape seq.
bra next_plane
no_data:
lea empty_plane,a0 * no data for this color plane
tst.b lastplane * last color plane?
beq not_last * no
lea last_empty,a0 * yes - requires special escape seq.
not_last:
jsr printer_out
addq.w #1,d1 * increment plane counter
cmp.w num_planes,d1 * last color plane?
bmi next_plane * no - continue with next plane
bgt check_qulty_mode
st lastplane * no - one more plane to go so set variable
next_plane:
adda.l plane_sz,a2 * advance ptr to next plane
bra scan_next_slice * scan same slice in next plane
*
* Skip every other line for draft mode.
*
check_qulty_mode:
tst.w _drvr_qulty * final mode?
bne setup_next_scan_line * yes - so go on and print every line
* * no-so skip next line only if in low dpi
move.w NPLANES,d1
cmp.w #4,d1 * max. # of planes? (AND draft mode)
beq setup_next_scan_line * yes - so go on and print every line
* * no - (180dpi & draft mode) so skip line
movea.l plane_top,a2 * restore top of plane
adda.w slice_offset,a2 * advance pointer to next slice
move.l a2,plane_top * Point to 1st plane at new slice
move.w #1,d1 * initialize plane cntr for next slice
clr.b lastplane
dbra d7,setup_next_scan_line * print every other line
bra done * no more lines to process
* Advance the rasterizing buffer pointer to the start of the
* next slice and loop until all the slices are drawn.
*
setup_next_scan_line:
movea.l plane_top,a2 * restore top of plane
adda.w slice_offset,a2 * advance pointer to next slice
move.l a2,plane_top * Point to 1st plane at new slice
move.w #1,d1 * initialize plane cntr for next slice
clr.b lastplane
dbra d7,scan_next_slice * loop until all slices drawn
done:
movem.l (a7)+,d1-d7/a3-a6 * restore all registers used by C
rts
.page
*************************************************************************
* *
* BACK_SCAN *
* *
* This routine determines the number of non-blank bytes in *
* the next 8 even or odd numbered scan lines. Trailing *
* blanks are discarded before the data is sent to the printer. *
* *
* Inputs: *
* a2.l - address of start of first scan line to check *
* a5.w - offset to next even/odd scan line *
* a6.w - # of bytes in a scan line *
* *
* Outputs: *
* d3.w - # of non-blank bytes in each scan line *
* *
* Registers Modified: d3, d4, a3, a4 *
* *
*************************************************************************
*
* Set up the loop counter for examining a single scan and initialize
* the master buffer pointer to the last byte in the first scan.
*
back_scan:
move.w bytes_line,d3 * get # of bytes in a scan line
subq.w #1,d3 * adjust for dbra loop
movea.l a2,a3 * get start address of scan line
adda.w a6,a3 * bump pointer to end of scan line
*
* Set up the loop counter for the number of scan lines to check,
* get a temporary copy of the master pointer for checking the current
* column of bytes, and bump the master pointer to the previous column.
*
check_next_column:
subq.w #1,a3 * bump master pointer to next column
nxt_byte:
tst.b (a3) * is current byte non-blank?
bne found_non_blank * yes - done
dbra d3,check_next_column * loop until all columns are checked
found_non_blank:
rts
.page
*************************************************************************
* *
* BYTE_OUT *
* *
* This routine extracts the data from the 8 even/odd scans *
* of a slice and sends it to the printer. *
* *
* Inputs: *
* d3.w - # of bytes -1 to print *
* a3.l - address of start of first scan line in slice *
* a5.w - offset to next even/odd scan line *
* *
* Outputs: None *
* *
* Registers Modified: d0, d1, d2, a0, a3 *
* *
*************************************************************************
* d1.w - loop counter
* d2.w - total count for bytes in row to send
* d3.w - # bytes in row to print (computed by back_scan routine)
* d4.w - temp variable for bytes_line
* d6.b - count for no. of similar bytes in block (same)
* a3.l - current byte
* a4.l - next byte
*
* Determine the number of columns of graphic data to send and prepare
* the printer to receive them.
*
byte_out:
movem.l d1-d7/a2-a6,-(sp)
clr.l d7
move.w _drvr_qulty,d7 * store quality mode
move.w NPLANES,d1
cmp.w #4,d1 * max. # of planes?
bne initialization * no
* yes - so now check quality mode
tst.w _drvr_qulty * draft mode? (AND 4 planes)
bne initialization * no
move.w #1,d0 * change mode to final if already in low dpi
move.w d0,_drvr_qulty * and user requested draft mode
initialization:
clr.l d2 * next=0
clr.l d5 * total=0
clr.l d4 * counter=0
clr.l d6 * same=0
move.w d3,d4 * use temp variable
movea.l a2,a3 * get ptr to start of 1st row of data
addq.l #1,a3 * advance ptr
movea.l a3,a4 * store next ptr
movea.l a2,a3 * get ptr to start of 1st row of data
* special case - one byte row
tst.w d4 * does row have only one byte?
beq end1 * yes - account for 1 data byte & 1 cnt byte
subq.w #1,d4 * no: 2 bytes = 1 comparison
tst.w _drvr_qulty
bne next1
* testing
addq.w #1,d4
* subq.w #1,d4 * no: 2bytes= 1comparison (draft=> 4bytes=1comp)
move.b (a3)+,d1 * d1 = first byte
* Get every other bit of first byte
clr.l d0 * clear out work register
add.b d1,d1 * shift out bit 7 of data byte
addx.b d0,d0 * shift into bit 0 of work register
add.b d1,d1 * shift out bit 5
add.b d1,d1
addx.b d0,d0
add.b d1,d1 * shift out bit 3
add.b d1,d1
addx.b d0,d0
add.b d1,d1 * shift out bit 1
add.b d1,d1
addx.b d0,d0
* Get every other bit of second byte
subq.w #1,d4 * decrement raster loop counter
tst.w d4 * ended on odd byte?
bge not_odd1
move.b d0,d1 * set to d1 in case there is no 2nd byte
rol.b #4,d1 * make last nibble blank(2nd byte blank)
blt end1 * yes
not_odd1:
move.b (a3)+,d1 * d1 = second byte
add.b d1,d1 * shift out bit 7 of data byte
addx.b d0,d0 * shift into bit 0 of work register
add.b d1,d1 * shift out bit 5
add.b d1,d1
addx.b d0,d0
add.b d1,d1 * shift out bit 3
add.b d1,d1
addx.b d0,d0
add.b d1,d1 * shift out bit 1
add.b d1,d1
addx.b d0,d0
* move.b d0,d1 * d1 = combined byte to output
move.b d0,d2 * d2 = combined byte to output
subq.w #1,d4 * decrement raster loop counter
tst.w d4
blt end1
next1_mask:
move.b d2,d1 * curr = next
move.b (a3)+,d2 * d2 = first byte
* Get every other bit of first byte
clr.l d0 * clear out work register
add.b d2,d2 * shift out bit 7 of data byte
addx.b d0,d0 * shift into bit 0 of work register
add.b d2,d2 * shift out bit 5
add.b d2,d2
addx.b d0,d0
add.b d2,d2 * shift out bit 3
add.b d2,d2
addx.b d0,d0
add.b d2,d2 * shift out bit 1
add.b d2,d2
addx.b d0,d0
* Get every other bit of second byte
subq.w #1,d4 * decrement raster loop counter
tst.w d4
bge even1_byte
move.b d0,d2 * set to d2 in case there is no 2nd byte
rol.b #4,d2 * make last nibble blank(2nd byte blank)
bra next1_dft * yes
even1_byte:
move.b (a3)+,d2 * d2 = second byte
add.b d2,d2 * shift out bit 7 of data byte
addx.b d0,d0 * shift into bit 0 of work register
add.b d2,d2 * shift out bit 5
add.b d2,d2
addx.b d0,d0
add.b d2,d2 * shift out bit 3
add.b d2,d2
addx.b d0,d0
add.b d2,d2 * shift out bit 1
add.b d2,d2
addx.b d0,d0
move.b d0,d2 * d2 = combined byte to output
next1_dft:
cmp.b d1,d2
bne dif1
tst.b d6
bgt same1
bra sim_blk1
* first pass - analyse row of data
next1:
cmpm.b (a3)+,(a4)+ * compare consecutive bytes
bne dif1 * dealing w/ dissimilar consecutive bytes
tst.b d6
bgt same1 * if same>0 continue within similar block
sim_blk1: * else if same=0 begin similar block
addq.b #1,d6 * same++
total: addq.w #2,d5 * 1 for byte cnt & 1 for data byte
bra cont1
same1:
cmpi.b #127,d6 * maximum transfer reached?
bge lg_same1 * yes
addq.b #1,d6 * no - same++
bra cont1 * continue to next byte
lg_same1:
clr.b d6 * same=0; initialize variable to begin new block
bra sim_blk1 * require new block
dif1: * transition from old block to new block
tst.b d6
beq total * new dissimilar block encountered
clr.b d6 * transition from similar to dissimilar block
cont1: tst.w _drvr_qulty
bne cont1_fnl
tst.w d4
blt dft_1backup
dbra d4, next1_mask * next = new
bra dft_1backup
cont1_fnl:
dbra d4,next1 * compare next pair of bytes
bra fnl_1backup
dft_1backup:
cmp.b d1,d2
beq sameblk1
bra end1
fnl_1backup:
* back up and account for last byte
subq.l #1,a3 * move pointer back by one
subq.l #1,a4 * move pointer back by one
cmpm.b (a3)+,(a4)+
beq sameblk1 * last 2 bytes are same
bra end1 * last 2 bytes are different
sameblk1:
cmpi.b #127,d6 * maximum transfer reached?
bge end1 * yes
bra done1 * don't increment d6 cuz cnt must be one fewer
end1:
addq.w #2,d5 * new block for last byte
done1:
lea send_cnt,a0 * send next part of transfer sequence
jsr printer_out
move.l d5,d0 * get total cnt that needs to be sent in ascii
jsr convert_itoa
* send 3rd part of trnsfr sequence
move.b #'V',d0 * trnsfr seq. for color plane
tst.b lastplane * last plane?
beq out * no
move.b #'W',d0 * yes - trnsfr seq. for last color plane
out: jsr pout
* second pass to send out data
* initialization
clr.l d2 * next=0
clr.l d4 * counter=0
clr.l d6 * same=0; reset variable for second pass
move.w d3,d4 * use temp variable
movea.l a2,a3 * get ptr to start of 1st row of data
addq.l #1,a3 * advance ptr
movea.l a3,a4 * next ptr
movea.l a2,a3 * current ptr
tst.w d4 * does row have only one byte?
bne manybytes
* special case - one byte row
tst.w _drvr_qulty
bne fnl_onebyte
dft_onebyte:
* move.b (a3),d1
move.b (a3),d2
bra end2
fnl_onebyte:
* addq.l #1,a3
bra end2
manybytes:
subq.w #1,d4 * i.e. 2 bytes = 1 comparison
tst.w _drvr_qulty
bne next2
* testing
addq.w #1,d4
* subq.w #1,d4 * no: 2bytes= 1comparison (draft=> 4bytes=1comp)
move.b (a3)+,d1 * d1 = first byte
* Get every other bit of first byte
clr.l d0 * clear out work register
add.b d1,d1 * shift out bit 7 of data byte
addx.b d0,d0 * shift into bit 0 of work register
add.b d1,d1 * shift out bit 5
add.b d1,d1
addx.b d0,d0
add.b d1,d1 * shift out bit 3
add.b d1,d1
addx.b d0,d0
add.b d1,d1 * shift out bit 1
add.b d1,d1
addx.b d0,d0
* Get every other bit of second byte
subq.w #1,d4 * decrement raster loop counter
tst.w d4
bge not_odd2
move.b d0,d1 * set to d1 in case there is no 2nd byte
rol.b #4,d1 * make last nibble blank(2nd byte blank)
blt end2 * yes
not_odd2:
move.b (a3)+,d1 * d1 = second byte
add.b d1,d1 * shift out bit 7 of data byte
addx.b d0,d0 * shift into bit 0 of work register
add.b d1,d1 * shift out bit 5
add.b d1,d1
addx.b d0,d0
add.b d1,d1 * shift out bit 3
add.b d1,d1
addx.b d0,d0
add.b d1,d1 * shift out bit 1
add.b d1,d1
addx.b d0,d0
* move.b d0,d1 * d1 = combined byte to output
move.b d0,d2 * d2 = combined byte to output
subq.l #1,d4
tst.w d4
blt end2
next2_mask:
move.b d2,d1
move.b (a3)+,d2 * d2 = first byte
* Get every other bit of first byte
clr.l d0 * clear out work register
add.b d2,d2 * shift out bit 7 of data byte
addx.b d0,d0 * shift into bit 0 of work register
add.b d2,d2 * shift out bit 5
add.b d2,d2
addx.b d0,d0
add.b d2,d2 * shift out bit 3
add.b d2,d2
addx.b d0,d0
add.b d2,d2 * shift out bit 1
add.b d2,d2
addx.b d0,d0
* Get every other bit of second byte
subq.w #1,d4 * decrement raster loop counter
tst.w d4 * ended on odd byte?
bge even2_byte
move.b d0,d2 * set to d2 in case there is no 2nd byte
rol.b #4,d2 * make last nibble blank(2nd byte blank)
bra next2_dft * yes
even2_byte:
move.b (a3)+,d2 * d2 = second byte
add.b d2,d2 * shift out bit 7 of data byte
addx.b d0,d0 * shift into bit 0 of work register
add.b d2,d2 * shift out bit 5
add.b d2,d2
addx.b d0,d0
add.b d2,d2 * shift out bit 3
add.b d2,d2
addx.b d0,d0
add.b d2,d2 * shift out bit 1
add.b d2,d2
addx.b d0,d0
move.b d0,d2 * d2 = combined byte to output
next2_dft:
cmp.b d1,d2
bne dif2
tst.b d6
bgt same2
bra sim_blk2
next2:
cmpm.b (a3)+,(a4)+ * compare consecutive bytes
bne dif2 * dealing w/ dissimilar consecutive bytes
tst.b d6 * same=?
bgt same2 * same>0; continue within similar block
sim_blk2:
addq.b #1,d6 * same==0; begin similar block; same++
bra cont2
same2:
cmpi.b #127,d6 * maximum transfer reached?
bge lg_same2 * yes
addq.b #1,d6 * no - same++
bra cont2 * continue to next byte
lg_same2:
subq.b #1,d6 * byte always printed at least once
move.b d6,d0 * send repeat count to printer
jsr pout
tst.w _drvr_qulty
bne sendbyte_fnl
move.b d1,d0
jsr pout
sendbyte_fnl:
move.b (a3),d0 * get repeated data byte to output
jsr pout
clr.b d6 * same=0; reset variable for new block
bra sim_blk2 * require new block
dif2: * transition from old block to new block
tst.b d6
beq no_prev_blk
move.b d6,d0 * send repeat count to printer
jsr pout
tst.w _drvr_qulty
bne dif2_fnl
move.b d1,d0
jsr pout
clr.b d6
bra cont2
dif2_fnl:
subq.l #1,a3 * move current ptr back
move.b (a3),d0 * get repeated data byte to output
jsr pout
addq.l #1,a3 * restore current ptr
clr.b d6 * same=0; clear var for next block
bra cont2
no_prev_blk:
clr.b d0 * else if same=0 send one dissimilar data byte
jsr pout
tst.w _drvr_qulty
bne fnl_no_prev_blk
move.b d1,d0
jsr pout
clr.b d6
bra cont2
fnl_no_prev_blk:
subq.l #1,a3 * move current ptr back
move.b (a3),d0 * get data byte to output
jsr pout
addq.l #1,a3 * restore current ptr
clr.b d6 * same=0; clear var for next block
bra cont2
cont2: tst.w _drvr_qulty
bne cont2_fnl
tst.w d4
blt dft_2backup
dbra d4, next2_mask * next = new
bra dft_2backup
cont2_fnl:
dbra d4,next2 * compare next pair of bytes
bra fnl_2backup
dft_2backup:
cmp.b d1,d2
beq sameblk2
bra last_byte
fnl_2backup:
* back up and account for last byte
subq.l #1,a3 * move pointer back by one
subq.l #1,a4 * move pointer back by one
cmpm.b (a3)+,(a4)+
beq sameblk2
bra last_byte * else send dissimilar block
sameblk2:
cmpi.b #127,d6 * maximum transfer reached?
bge done2 * yes
end2:
tst.b d6 * check if there exists a prev block to send
beq last_byte
move.b d6,d0
jsr pout * send repeat count to printer
tst.w _drvr_qulty
bne end2_fnl
move.b d2,d0
jsr pout
bra end_byte_out
end2_fnl:
subq.l #1,a3 * move current ptr back
move.b (a3),d0 * get repeated data byte to output
jsr pout
addq.l #1,a3 * restore current ptr
bra end_byte_out * done with second pass of one row
last_byte:
clr.b d0 * zero cnt means one data byte
jsr pout
tst.w _drvr_qulty
bne fnl_last_byte:
move.b d2,d0
jsr pout
bra end_byte_out
fnl_last_byte:
move.b (a3),d0 * get data byte to output
jsr pout
bra end_byte_out * done with second pass of one row
done2: * send maximum transfer of 127 bytes
subq.b #1,d6 * byte always printed at least once
move.b d6,d0 * send repeat count to printer
jsr pout
tst.w _drvr_qulty
bne done2_fnl
move.b d1,d0
jsr pout
bra end2
done2_fnl:
move.b (a3),d0 * get repeated data byte to output
jsr pout
bra end2 * print last byte (byte #128)
end_byte_out: * done with second pass of one row
move.w d7,_drvr_qulty * restore value if changed above
movem.l (sp)+,d1-d7/a2-a6
rts
.page
*************************************************************************
* *
* ALPHAOUT *
* *
* This routine prints alphanumeric text. It also handles *
* escape sequences for setting/clearing alphanumeric text *
* attributes. The accepted escape sequences are: *
* DC2 0 - begin bold *
* DC2 1 - end bold *
* DC2 2 - begin italic *
* DC2 3 - end italic *
* DC2 4 - begin underline *
* DC2 5 - end underline *
* *
* Inputs: *
* INTIN - alphanumeric text string *
* CONTRL[3] - # of characters in the text string *
* *
* Outputs: None *
* *
* Registers Modified: d0, d1, d2, a0, a1, a2 *
* *
*************************************************************************
*
* Before printing the alphanumeric text we must do the following
* tasks.
* 1) Ensure that the output will occur on a character line.
* 2) Ensure that alphanumeric attributes are properly set.
* 3) Set up the pointer and counter for for the character loop.
*
_alphaout:
movem.l d3-d5/a3,-(a7) * save the registers used by C
jsr vmu_sync * align the paper to a printer character line
jsr alphaenv * make sure that attributes are set correctly
movea.l _CONTRL,a0 * get address of CONTRL array
move.w 6(a0),d2 * get the # of characters to print
subq.w #1,d2 * convert it to a loop counter
movea.l _INTIN,a2 * get address of character string
*
* Check the next two characters in the string to determine if they form
* an attribute escape sequence. A valid escape sequence starts with a
* DC2 and is terminated with an ASCII 0 through 5.
*
alpha_loop:
move.w (a2)+,d0 * get the next character
cmpi.b #ALPHA_ESCAPE,d0 * do we have an escape sequence?
bne not_escape * nope
tst.w d2 * is this the last character?
beq not_escape * yes - no escape sequence
move.w (a2),d1 * get the next character
subi.b #'0',d1 * ASCII 0 or greater?
bmi not_escape * nope
cmpi.b #5,d1 * ASCII 5 or less?
bgt not_escape * nope
*
* We have found an attribute escape sequence. Update the requested
* attributes flags and send the appropriate escape sequence to the
* printer.
*
subq.w #1,d2 * decrement the character count for the DC2
addq.w #2,a2 * bump the pointer to the next character
lsr.w #1,d1 * convert attribute code to bit index
bcs clr_bit * branch if code was odd
bset.b d1,_reqalpha * set bit if code was even
bra set_att * send escape sequence to printer
clr_bit:
bclr.b d1,_reqalpha * clear bit if code was odd
set_att:
jsr alphaenv * send the escape sequence to the printer
bra next_alpha_loop * test if done with string yet
*
* If the current character is a line feed then add the number
* of steps in an alphanumeric character to the vmu count.
*
not_escape:
jsr pout * send the character to the printer
* If the current character is a form feed or line then reset the vmu count.
cmpi.b #LF,d0 * current character a line feed?
bne vme_check_ff * nope
move.w _A_SLICE,d1 * yes - get height of alpha text in pixels
add.w d1,_vmu * add # of scans in character to count
bra next_alpha_loop * test if done with string yet
vme_check_ff:
cmpi.b #FORM_FEED,d0 * current character a form feed?
bne next_alpha_loop * nope
clr.w _vmu * yes - reset the count
*
* Send the current character to the printer and loop until done with
* the character string.
*
next_alpha_loop:
dbra d2,alpha_loop * loop until done with character string
movem.l (a7)+,d3-d5/a3 * restore the registers used by C
rts
.page
*************************************************************************
* *
* VMU_SYNC *
* *
* This routine will advance the paper so that alphanumeric *
* text is aligned to printer character lines. *
* *
* Inputs: None *
* *
* Outputs: None *
* *
* Registers Modified: d0, d1, a0 *
* *
*************************************************************************
*
* Determine whether the paper is aligned to a printer character
* line. If not then determine the number of vertical motion units
* to advance the paper, align it, and update the vmu count.
*
vmu_sync:
moveq.l #0, d0
move.w _vmu, d0 * get the current vmu count
move.w _A_SLICE, d1 * get the number of pixels in a character
divs d1, d0 * get vmu count modulo # of pixels in character
swap d0 * get the remainder
cmp.w #0, d0 * if there is no remainder we
beq vs_out * we are currently aligned
sub.w d0, d1 * compute add'l # of vmu units needed
add.w d1, _vmu * adjust vmu to next line
* The d1 register now contains the number of pixels to be advanced. However,
* the Epson command uses 1/216 inch increments. For high resolution, the
* number of pixels needs to be multiplied by 1.5. For low resolution, the
* number of pixels needs to be multiplied by 3.
* move.w d1, d0 * get a copy of the amount
* asr.w #1, d0 * divide it by 2
* add.w d0, d1 * multiply amount by 1.5 to get # of steps
move.b d1,slf_cnt * store # of printer steps in escape sequence
lea sized_lf,a0 * advance paper the desired # of steps
jsr printer_out
vs_out:
rts
.page
*************************************************************************
* *
* ALPHAENV *
* *
* This routine compares the requested alphanumeric text *
* attributes with the current values. If they are different *
* the current attributes are updated and the appropriate *
* escape sequences are sent to the printer. *
* *
* Inputs: *
* reqalpha - requested attributes for alphanumeric text *
* curalpha - current attributes for alphanumeric text *
* *
* Outputs: *
* curalpha - updated with new attributes *
* *
* Registers Modified: d0, d3, d4, d5, a0, a3 *
* *
*************************************************************************
*
* Determine if there has been any change in the attributes for
* alphanumeric text. If not then do nothing.
*
alphaenv:
move.b _curalpha,d3 * get the current attributes
move.b _reqalpha,d4 * get the requested attributes
eor.b d4,d3 * any change?
beq end_alfaenv * nope - just go away
*
* At least one of the attributes has changed. Initialize the
* pointer and counter needed to determine which escape sequence(s)
* must be sent to the printer.
*
moveq.l #2,d5 * get the loop counter (only 3 attributes)
lea.l com_add,a3 * get the address of the table
*
* Loop checking the current attribute to see if it has changed. If it
* has then send an escape sequence to the printer to set/clear the
* attribute.
*
alfaenv_loop:
asr.b #1,d3 * has the current attribute changed?
beq next_alfaenv_loop * nope
clr.w d0 * yes - preset table index to set attribute
asr.b #1,d4 * get state for the current attribute
roxl.w #2,d0 * turn it into an offset of 0 or 2
move.w 0(a3,d0.w),d0 * get the offset to the escape sequence
lea com_add(pc,d0.w),a0 * get address of the escape sequence
jsr printer_out * send it to the printer
next_alfaenv_loop:
addq.w #4,a3 * update the pointer into the table
dbra d5,alfaenv_loop * loop until all attributes checked
end_alfaenv:
rts
*************************************************************************
* *
* Address offset table for escape sequences used to set/clear *
* alphanumeric text attributes *
* *
*************************************************************************
com_add dc.w end_bold-com_add * end bold attribute
dc.w begin_bold-com_add * begin bold attribute
dc.w end_italic-com_add * end italic attribute
dc.w begin_italic-com_add * begin italic attribute
dc.w end_under-com_add * end underscore attribute
dc.w begin_under-com_add * begin underscore attribute
*************************************************************************
* *
* Printer Escape Sequences for Alphanumeric Text Attributes *
* *
*************************************************************************
end_bold dc.b 2,ESC,'F'
begin_bold dc.b 2,ESC,'E'
end_italic dc.b 2,ESC,'5'
begin_italic dc.b 2,ESC,'4'
end_under dc.b 3,ESC,'-','0'
begin_under dc.b 3,ESC,'-','1'
.page
*************************************************************************
* *
* Local Variable Definitions *
* *
*************************************************************************
* Default RGB values for color pallette
PLANE_COLORS
dc.w 2 * 2 colors = 1 plane
dc.w 4 * 4 colors = 2 planes
dc.w 8 * 8 colors = 3 planes
dc.w 16 * 16 colors = 4 planes
.data
_MAP_COL
dc.w 0 * white
dc.w 1 * black
dc.w 12 * red
dc.w 10 * green
dc.w 6 * blue
dc.w 2 * cyan
dc.w 8 * yellow
dc.w 4 * magenta
dc.w 3 * white
dc.w 5 * black
dc.w 7 * light red
dc.w 9 * light green
dc.w 11 * light blue
dc.w 13 * light cyan
dc.w 14 * light yellow
dc.w 15 * light magenta
_PAL_RGB
dc.w 1000,1000,1000
dc.w 0,0,0
dc.w 1000,0,0
dc.w 0,1000,0
dc.w 0,0,1000
dc.w 0,1000,1000
dc.w 1000,1000,0
dc.w 1000,0,1000
dc.w 0,0,0
dc.w 0,0,0
dc.w 0,0,0
dc.w 0,0,0
dc.w 0,0,0
dc.w 0,0,0
dc.w 0,0,0
dc.w 0,0,0
*
* Enter High Resolution 300 DPI Graphics Mode
*
enter_graph dc.b 5,ESC,'*','r','0','A' * start raster graphics
*
* Initialisation de l'imprimante!
*
width dc.b 13,ESC,'E',ESC,38,108,50,54,65,ESC,38,108,48,76
*
* Low DPI = 150 dpi used for NPLANES = 4 or draft mode
*
low_dpi dc.b 12,ESC,'*','t','3','0','0','R',ESC,'*','o','1','Q'
*
* High DPI = 300 dpi used for NPLANES = 1,2 or 3
*
high_dpi dc.b 12,ESC,'*','t','3','0','0','R',ESC,'*','o','1','Q'
*
* First part of escape sequence for number of planes to process
*
escape_r dc.b 4,ESC,'*','r','-'
*
* Part of escape sequence for color palette customizing.
* Ca sert plus a rien.
* rgb_escape dc.b 1,' '
*
* Transmission Mode - unencoded or 'run-length' encoded data
*
transmit_mode dc.b 5,ESC,'*','b','1','M' * run-length encoded
*
* Send empty plane escape sequence
*
empty_plane dc.b 5,ESC,'*','b','0','V'
*
* Send empty plane escape sequence for last available color
*
last_empty dc.b 5,ESC,'*','b','0','W'
*
* Part of necessary transfer sequence for compression method #2
*
send_cnt dc.b 3,ESC,'*','b'
*
* End Graphics Mode
*
end_graph dc.b 5,ESC,'*','r','b','C' * end raster graphics
*
* Copy of ptr to current slice of the first plane in scan_out
*
plane_top ds.l 1
*
* Variable for checking if current plane is the last in multi-plane seq.
*
lastplane ds.b 1
*
* Printer Spacing Command
*
sized_lf dc.b 3,ESC,'J'
slf_cnt ds.b 1
_abort dc.w 0 * abort flag
_handle dc.w 0 * handle returned from open of aux port
chr_ad dc.b 0 * byte to hold character
chr_ad1 dc.b 0 * second byte
*
* Copy of num_colors to be used by 'C' routine
*
_num_colors dc.w 1
*
* Copy of num_planes to be used by 'C' routine
*
_num_planes dc.w 1
.end