 include "pdlequ.h"
 
*
* IFF File printer
*


 SECTION printer,CODE,PUBLIC
************************************

dumbentry:
	clr.l	d0
	rts

	dc.l	"PRNT"
	dc.w	200



****************************************************
* distribute the calls to the appropriate routines *
****************************************************
fx80:	move.l	a0,table
	lsl.w	#2,d0
	lea	prntbl,a1
	move.l	0(a1,d0.w),a1
	jmp	(a1)


*********************************************************
* identify who I am, and set up who I like to speak to. *
*********************************************************
p_ident:
	move.l	#driver,pdrvrnm(a0)	;pointer to string for driver name
	move.w	#DISK+ASCENDING,device(a0)
prtok:	moveq	#1,d0
	rts


******************************************************
* initialize the table of printer specific routines  *
******************************************************
p_init:	clr.b	pdl(a0)			;no page description language
	clr.b	pmult(a0)		;automatically print mulitiple copies?
	clr.b	pman(a0)		;handle manual feed?
        
        lea     colortag1,a1
        lea     colortag2,a2
        move.l  prtspcl(a0),a3
        
pint01: tst.b   (a1)
        beq     colr
        
        move.b  (a3),d0
        cmp.b   (a1),d0
        beq     pint02
        
        cmp.b   (a2),d0
        bne     bw
        
pint02: addq.l  #1,a1
        addq.l  #1,a2
        addq.l  #1,a3        
        bra     pint01
        
bw:	move.b	#PRT_BW,ptype(a0)	;b&w iff file
        bclr    #0,flag
        bra     pint03
        
colr:   move.b  #PRT_CMYK,ptype(a0)     ;16 color iff file
	bset    #0,flag
        
pint03: move.l	sendout(a0),send+2	;self-modifing code, tisk, tisk!

*
* pminlft and pmaxw must be evenly divisible by 16
* this is the part that should be worked out
*

	move.w	pdensity(a0),d0
	cmp.w	#7,d0
	bcs	pint1
	moveq	#6,d0
pint1:	lsl.w	#1,d0

	lea	xdpi_tbl,a1
	move.w	0(a1,d0.w),pxdpi(a0)	;x resolution
	lea	ydpi_tbl,a1
	move.w	0(a1,d0.w),pydpi(a0)	;y resolution
	lea	minl_tbl,a1
	move.w	0(a1,d0.w),pminlft(a0)	;pixels from the left
        lea	minr_tbl,a1
	move.w	0(a1,d0.w),pminrht(a0)	;pixels from the right
	lea	maxw_tbl,a1
	move.w	0(a1,d0.w),pmaxw(a0)	;maximum # pixels across
        lea	maxh_tbl,a1
	move.l	0(a1,d0.w),pmaxh(a0)	;maximum # pixels down
	lea	mint_tbl,a1
	move.w	0(a1,d0.w),pmintop(a0)	;pixels down from top
	lea	minb_tbl,a1
	move.w	0(a1,d0.w),pminbot(a0)	;pixels up from bottom
	lea	xover_tbl,a1
	move.w	0(a1,d0.w),pxover(a0)	;percentage of x overlap of dots
	lea	yover_tbl,a1
	move.w	0(a1,d0.w),pyover(a0)	;percentage of y overlap of dots
	lea	rowht_tbl,a1
	move.w	0(a1,d0.w),prowht(a0)	;rows height modula
	move.w	0(a1,d0.w),rowht
	lea	rows_tbl,a1
	move.w	0(a1,d0.w),rows
        
        lea     pagexres,a1             ;iff source page X for BMHD
        move.w  0(a1,d0.w),xpage
        lea     pageyres,a1             ;iff source page Y for BMHD
        move.w  0(a1,d0.w),ypage
	
        lea	grmode_tbl,a1           ;CAMG data
	move.w	0(a1,d0.w),grmode
	bra	prtok


**************************************
* going to begin printing a document *
**************************************
p_bgndoc:
        clr.l   cbuf
	bra	prtok


**************************************
* about to start printing of a page  *
**************************************
p_bgnpage:
        move.l  table,a0

        move.l  PPageWidth(a0),d0
        move.l  d0,d1
        addq.l  #7,d1
        lsr.l   #3,d1
        btst    #0,d1
        beq     bp0
        addq.l  #1,d1    
bp0:    move.l  d0,iffx
        move.l  PPageHeight(a0),iffy
        
        tst.l   cbuf
        bne     bp1
        
        clr.l   d1
        clr.l   d2
        move.l  iffx,d0
        lsl.l   #1,d0
        move.l  m_alloc(a0),a0
        jsr     (a0)
        beq     bp1
        move.l  a0,cbuf

bp1:    mulu    iffy+2,d1
        btst    #0,flag         ;is it color or b&w (1=color)
        beq     bpage1          ;b&w
        
        lsl.l   #2,d1           ;multiply by 4
        
bpage1: move.l  d1,bodylen
        clr.l   d1

        btst    #0,flag         ;is it color or b&w?
        bne     form1           
        add.l   #66,d1          ;for b&w        
        bra     form2
        
form1:  add.l   #108,d1         ;for color 
form2:  move.l  d1,formlen
        
        lea     form,a0         ;output FORM
        bsr     sendline
        
        move.b  formlen,d0      ;length of form
        bsr     send
        move.b  formlen+1,d0
        bsr     send        
        move.b  formlen+2,d0
        bsr     send
        move.b  formlen+3,d0
        bsr     send

        lea     ilbm,a0         ;output ILBM 
        bsr     sendline
        
        lea     bmhd,a0         ;output BMHD chunk
        bsr     sendline
        
        move.b  #0,d0           ;length of chunk (always 20)
        bsr     send 
        move.b  #0,d0
        bsr     send        
        move.b  #0,d0
        bsr     send
        move.b  #20,d0
        bsr     send

        move.b  iffx+2,d0       ;xres
        bsr     send
        move.b  iffx+3,d0
        bsr     send
                
        move.b  iffy+2,d0       ;yres
        bsr     send
        move.b  iffy+3,d0
        bsr     send
        
        move.b  #0,d0           ;x location
        bsr     send
        move.b  #0,d0
        bsr     send        
        
        move.b  #0,d0           ;y location
        bsr     send
        move.b  #0,d0
        bsr     send
        
        btst    #0,flag         ;is it color or b&w?
        bne     bmhd1           ;1=color, 0=b&w
        
        move.b  #1,d0           ;bitplanes in b&w image = 1
        bra     bmhd2
bmhd1:  move.b  #4,d0           ;bitplanes in color image = 4
bmhd2:  bsr     send
        
        move.b  #0,d0           ;masking        (0=none)
        bsr     send
        
        move.b  #1,d0           ;compression    (1=Run Lenght compressed)
        tst.l   cbuf            ;is the compression buffer available?
        bne     bmhd3           ;yes, so use it
        move.b  #0,d0           ;no, so don't use it
bmhd3:  bsr     send
        
        move.b  #0,d0           ;pad byte
        bsr     send
        
        move.b  #0,d0           ;transparent color
        bsr     send
        move.b  #0,d0
        bsr     send        
        
        move.b  #10,d0          ;xaspect
        bsr     send
        
        move.b  #11,d0          ;yaspect
        bsr     send
        
        move.b  xpage,d0        ;x source page size
        bsr     send
        move.b  xpage+1,d0
        bsr     send
                
        move.b  ypage,d0        ;y source page size
        bsr     send
        move.b  ypage+1,d0
        bsr     send
        
        
        lea     cmap,a0 ;output CMAP chunk
        bsr     sendline
        
        btst    #0,flag         ;is it a color or b&w picture?
        bne     color1
    
        move.b  #0,d0           ;length
        bsr     send
        move.b  #0,d0
        bsr     send        
        move.b  #0,d0
        bsr     send
        move.b  #6,d0
        bsr     send            

        move.b  #255,d0         ;white - red
        bsr     send
        move.b  #255,d0         ;white - green
        bsr     send        
        move.b  #255,d0         ;white - blue
        bsr     send
        
        move.b  #0,d0           ;black - red
        bsr     send
        move.b  #0,d0           ;black - green
        bsr     send        
        move.b  #0,d0           ;black - blue
        bsr     send
        
        bra     camg1    

color1: move.b  #0,d0           ;length
        bsr     send
        move.b  #0,d0
        bsr     send        
        move.b  #0,d0
        bsr     send
        move.b  #48,d0
        bsr     send
        
        move.w  #47,d1
        lea     colormap,a0

cmap1:  move.b  (a0)+,d0         ;send out color palette data
        move.l  a0,-(sp)
        move.w  d1,-(sp)
        bsr     send
        move.w  (sp)+,d1
        move.l  (sp)+,a0
        dbf     d1,cmap1
        
camg1:  lea     camg,a0         ;output a CAMG chunk
        bsr     sendline
         
        move.b  #0,d0           ;length
        bsr     send
        move.b  #0,d0
        bsr     send        
        move.b  #0,d0
        bsr     send
        move.b  #4,d0
        bsr     send 
        
        move.b  #0,d0           ;data
        bsr     send
        move.b  #0,d0
        bsr     send        
        move.b  grmode,d0
        bsr     send
        move.b  grmode+1,d0
        bsr     send       

body1:  lea     body,a0 ;output BODY chunk header
        bsr     sendline
        
        move.b  bodylen,d0           ;length of body
        bsr     send 
        move.b  bodylen+1,d0
        bsr     send        
        move.b  bodylen+2,d0
        bsr     send
        move.b  bodylen+3,d0
        bsr     send
        clr.l   bodylen

	bra	prtok


******************************************
* about to print a new tile for the page *
******************************************
p_bgntile:
	bra	prtok


********************************
* print a block to the printer *
********************************
p_block:
	move.l	table,a0
	move.l	pblockw(a0),width
        move.l  pblockplane(a0),pplane
	move.l	pblockptr(a0),a1
	move.l	(a1),a1
	add.l	pblockoff(a0),a1
	move.l	a1,v_base       ;do the first plane (yellow)

        move.l  width,d1                ;width = width of whole page
	move.l	v_base,a0
        tst.l   cbuf
        beq     putln1
        clr.l   clen
        clr.l   ulen
        move.l  d1,d0
        bsr     compit
        move.l  d0,d1
        move.l  d0,width
        move.l  cbuf,a0
        move.l  (a0),a0
        
putln1:	move.b	(a0)+,d0
	move.l	a0,-(sp)
	move.l	d1,-(sp)
	bsr	send
	move.l	(sp)+,d1
	move.l	(sp)+,a0
	subq.l	#1,d1
	bne	putln1
        
        move.l  bodylen,d0
        add.l   width,d0
        move.l  d0,bodylen
        
        btst    #0,width
        beq     ptln11
        move.b  #0,d0           ;make sure to end on a word
        bsr     send
        addq.l  #1,bodylen
        
ptln11: btst    #0,flag         ;is it color?
        beq     putln5          ;no - only 1 bitplane so exit
        
        move.l  v_base,a0
        move.l  pplane,d0
        add.l   d0,a0           ;move to the magenta plane
        tst.l   cbuf
        beq     putln2
        clr.l   clen
        clr.l   ulen
        move.l	table,a1
	move.l	pblockw(a1),d0
        move.l  d0,width
        bsr     compit
        move.l  d0,width
        move.l  cbuf,a0
        move.l  (a0),a0
        
        move.l  width,d1                ;width = width of whole page
putln2:	move.b	(a0)+,d0
	move.l	a0,-(sp)
	move.l	d1,-(sp)
	bsr	send
	move.l	(sp)+,d1
	move.l	(sp)+,a0
	subq.l	#1,d1
	bne	putln2
        
        move.l  bodylen,d0
        add.l   width,d0
        move.l  d0,bodylen
        
        btst    #0,width
        beq     ptln30
        move.b  #0,d0           ;make sure to end on a word
        bsr     send  
        addq.l  #1,bodylen

ptln30: move.l  v_base,a0
        move.l  pplane,d0
        add.l   d0,a0           ;move to the cyan plane
        add.l   d0,a0
        
        tst.l   cbuf
        beq     putln3
        clr.l   clen
        clr.l   ulen
        move.l	table,a1
	move.l	pblockw(a1),d0
        move.l  d0,width        
        bsr     compit
        move.l  d0,width
        move.l  cbuf,a0
        move.l  (a0),a0
        
        move.l  width,d1                ;width = width of whole page
putln3:	move.b	(a0)+,d0
	move.l	a0,-(sp)
	move.l	d1,-(sp)
	bsr	send
	move.l	(sp)+,d1
	move.l	(sp)+,a0
	subq.l	#1,d1
	bne	putln3
        
        move.l  bodylen,d0
        add.l   width,d0
        move.l  d0,bodylen
        
        btst    #0,width
        beq     ptln40
        move.b  #0,d0           ;make sure to end on a word
        bsr     send
        addq.l  #1,bodylen
        
ptln40: move.l  v_base,a0
        move.l  pplane,d0
        add.l   d0,a0           ;move to the black plane
        add.l   d0,a0
        add.l   d0,a0
        tst.l   cbuf
        beq     putln4
        clr.l   clen
        clr.l   ulen
        move.l	table,a1
	move.l	pblockw(a1),d0
        move.l  d0,width
        bsr     compit
        move.l  d0,width
        move.l  cbuf,a0
        move.l  (a0),a0
        
        move.l  width,d1                ;width = width of whole page
putln4:	move.b	(a0)+,d0
	move.l	a0,-(sp)
	move.l	d1,-(sp)
	bsr	send
	move.l	(sp)+,d1
	move.l	(sp)+,a0
	subq.l	#1,d1
	bne	putln4
        
        move.l  bodylen,d0
        add.l   width,d0
        move.l  d0,bodylen
        
        btst    #0,width
        beq     putln5
        move.b  #0,d0           ;make sure to end on a word
        bsr     send
        addq.l  #1,bodylen
                
putln5:	bra	prtok
       

*****************************************  
* just finished describing current tile *
*****************************************
p_endtile:
        bra     prtok


****************************************************
* just finished describing all tiles for this page *
****************************************************
p_endpage:
        tst.l   cbuf
        beq     ep0
        
        move.l  table,a1
        move.l  m_delete(a1),a1
        move.l  cbuf,a0
        jsr     (a1)
        clr.l   cbuf
        
ep0:    btst    #0,flag         ;is this a color file?
        bne     ep1             ;yes
        
        move.l  bodylen,d0
        add.l   #66,d0
        move.l  #66,bodyseek
        move.l  d0,formlen
        bra     ep2
        
ep1:    move.l  bodylen,d0
        add.l   #108,d0
        move.l  #108,bodyseek
        move.l  d0,formlen
        
ep2:    move.l  table,a0
        move.l  pfseek(a0),a0
        move.l  #4,d0
        jsr     (a0)
        
        move.b  formlen,d0      ;length of form
        bsr     send
        move.b  formlen+1,d0
        bsr     send        
        move.b  formlen+2,d0
        bsr     send
        move.b  formlen+3,d0
        bsr     send
        
        move.l  table,a0
        move.l  pfseek(a0),a0
        move.l  bodyseek,d0
        addq.l  #4,d0
        jsr     (a0)
        
        move.b  bodylen,d0      ;length of body
        bsr     send
        move.b  bodylen+1,d0
        bsr     send        
        move.b  bodylen+2,d0
        bsr     send
        move.b  bodylen+3,d0
        bsr     send
        
        bra	prtok


************************************
* finished printing the document   *
************************************
p_enddoc:
	bra	prtok


***************************
* user stopped printing   *
***************************
p_break:
	bra	p_endtile


***************************************************
***	these are the send routines for the	***
***	dot matrix driver.			***
***************************************************
sendline:
	move.b	(a0)+,d0
	beq	prtok
	move.l	a0,-(sp)
	bsr	send
	move.l	(sp)+,a0
	bra	sendline

        
***********************************
***                             ***
***********************************
send:	jmp	$ffffff         ;address is modified to be send(a0)
                                ;by init code.

************************************************
**   compress the data going to the file      **
************************************************
compit:
        move.l  cbuf,a2         ;get address of compression buffer
        move.l  (a2),a2
        clr.l   d1              ;zero out the length counter
        clr.l   d3              ;zero out the total length counter
        
cmpt2:  subq.l  #1,d0           ;am I out of data yet? (exit when d0 = -1)
        bmi     cmpt3           ;yes
        
        move.b  (a0)+,d2        ;get a byte from the input data
        cmp.b   (a0),d2         ;check the prev byte against the next byte
        beq     crun            ;if equal do compressed run
        
        ;uncompressed run
urun:   bsr     crun1           ;check for compressed run needing output
        lea     ubuf,a3         ;stuff uncompressed byte into ubuf
        move.l  ulen,d4
        move.b  d2,0(a3,d4.l)
        addq.l  #1,ulen
        cmp.l   #128,ulen       ;have I filled the ubuf?
        bcs     cmpt2           ;no, so keep going
        bsr     urun1           ;yes, so output the ubuf
        btst    #31,d0          ;did I finish a row?
        beq     cmpt2           ;no, so get another
        bra     cmpt3           ;get out
        
        ;mini-subroutine to output the ubuf
urun1:  tst.l   ulen            ;any data to output?
        beq     urun3           ;no, so exit
        move.l  ulen,d4         ;output coded length of uncompressed run
        subq.l  #1,d4
        move.b  d4,(a2)+
        lea     ubuf,a3         ;output uncompressed run bytes
urun2:  move.b  (a3)+,(a2)+
        dbf     d4,urun2
        addq.l  #1,d3           ;add 1 for length code to total length
        add.l   ulen,d3         ;add in for the bytes output to total length
        clr.l   ulen            ;reset string length for next urun
urun3:  rts

crun:   bsr     urun1           ;output ubuf if any data is there
        move.b  d2,cchar        ;save compressed data byte
        addq.l  #1,clen         ;add 1 to the length
        cmp.l   #128,clen       ;have i done the max count yet?
        bcs     cmpt2           ;no, so keep checking
        bsr     crun1           ;output compressed codes
        btst    #31,d0          ;did I finish a row?
        beq     cmpt2           ;no, so get another
        bra     cmpt3           ;get out

        ;mini-subroutine to output compressed stuff
crun1:  tst.l   clen
        beq     crun2
        move.l  clen,d4
        subq.l  #1,d4           ;output compressed data
        neg.b   d4
        move.b  d4,(a2)+        ;output the code for a $FF run
        move.b  cchar,(a2)+     ;output the compressed data
        addq.l  #2,d3           ;add two to the total length counter
        clr.l   clen            ;reset the compressed length
crun2:  rts
        
        
cmpt3:  bsr     urun1           ;output ubuf if any data is there
        bsr     crun1           ;output compression code if any
        move.l  d3,d0
        rts
                                


***********************************
***********************************
***********************************
 SECTION printer,DATA,PUBLIC

prntbl:	dc.l	prtok,prtok,prtok,prtok,p_init
	dc.l	p_bgndoc,p_bgnpage,p_bgntile
	dc.l	p_block
	dc.l	p_endtile,p_endpage,p_enddoc
	dc.l	p_break,p_ident

xdpi_tbl:       dc.w    65,75,100,150,200,200,300
ydpi_tbl:       dc.w    55,75,100,150,100,200,300
minl_tbl:	dc.w	0,0,0,0,0,0,0
minr_tbl:	dc.w	0,0,0,0,0,0,0
;maxw_tbl:	dc.w	640,864,1088,1536,1712,1712,2560
maxw_tbl:	dc.w	0,0,0,0,0,0,0
maxh_tbl:       dc.w    0,0,0,0,0,0,0
mint_tbl:	dc.w	0,0,0,0,0,0,0
minb_tbl:	dc.w	0,0,0,0,0,0,0
xover_tbl:	dc.w	0,0,0,0,0,0,0
yover_tbl:	dc.w	0,0,0,0,0,0,0
rowht_tbl:	dc.w	1,1,1,1,1,1,1
rows_tbl:	dc.w	1,1,1,1,1,1,1

pagexres:       dc.w    640,640,640,640,640,640,640
pageyres:       dc.w    400,400,400,400,200,400,400

grmode_tbl:	dc.w	$8004,$8004,$8004,$8004,$8000,$8004,$8004

cchar:          dc.b    0,0

driver:		dc.b	"IFF File v2.1.0",0

colortag1:      dc.b    "COLOR",0
colortag2:      dc.b    "color",0

form:           dc.b    "FORM",0
ilbm:           dc.b    "ILBM",0
bmhd:           dc.b    "BMHD",0
camg:           dc.b    "CAMG",0
cmap:           dc.b    "CMAP",0
clut:           dc.b    "CLUT",0
body:           dc.b    "BODY",0

colormap:       dc.b    255,255,255     ;white
                dc.b    0,255,255       ;cyan
                dc.b    255,0,255       ;magenta
                dc.b    0,0,255         ;blue
                dc.b    255,255,0       ;yellow
                dc.b    0,255,0         ;green
                dc.b    255,0,0         ;red
                dc.b    0,0,0           ;black
                dc.b    0,0,0           ;black-white (grey - actually black)
                dc.b    0,128,128       ;black-cyan
                dc.b    128,0,128       ;black-magenta
                dc.b    0,0,128         ;black-blue
                dc.b    128,128,0       ;black-yellow
                dc.b    0,128,0         ;black-green
                dc.b    128,0,0         ;black-red
                dc.b    0,0,0           ;black-black
                

 SECTION printer,BSS,PUBLIC
table:		ds.l	1
twidth:		ds.w	1
pixel:		ds.w	1
v_base:		ds.l	1
lineptr:	ds.l	1
width:		ds.l	1
count:		ds.w	1
grmode:		ds.w	1
rows:		ds.w	1
rowht:		ds.w	1
iffx:           ds.l    1
iffy:           ds.l    1
xpage:          ds.w    1
ypage:          ds.w    1
formlen:        ds.l    1
bodylen:        ds.l    1
flag:           ds.w    1
pplane:         ds.l    1
ulen:           ds.l    1
clen:           ds.l    1
cbuf:           ds.l    1
bodyseek:       ds.l    1
ubuf:           ds.b    130


********************************** changes *****************************
;
;       version 2.1.0
;       
;       - added support for compressed IFF files
;
;       - fixed a bug in determining the Width and Height of the area to print
;         (it wasn't using the most reliable values from PageStream)
;       
;       version 2.0.1   (uploaded 9/25/90)
;
;       - bug fix that caused bad iff's on res 1,2,4,7.
;         the form and body len values did not include the extra byte
;         needed for odd length rows.
;
;       - bug fix that caused all b&w iff outputs to be bad - wrong value
;         added to form len for all other chunks.
;
;       - now outputs a CAMG chunk for B&W pictures
;
;       - option 5 (200x100) now produces a 640x200 iff file.
;         (before it was a 640x400 iff file)
;
;
;       version 2.0.0
;
;       - initial release
