home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 2
/
crawlyvol2.bin
/
apps
/
dtp
/
pgsmodst
/
atariprt
/
slm804.s
< prev
next >
Wrap
Text File
|
1991-08-14
|
15KB
|
662 lines
.include "pdlequ.h"
*
* DEFINITIONS
*
dmadata equ $ffff8604 ; /* dma control and status register */
dmahigh equ $ffff8609 ; /* dma counter high */
dmamid equ $ffff860b ; /* dma counter mid */
dmalow equ $ffff860d ; /* dma counter low */
gpip equ $fffffa01 ; /* mfp general purpose i/o */
flock equ $43e ; /* dma lock semaphore */
_hz_200 equ $4ba ; /* 200 hz timer */
*
* SLM804 print driver
*
CR equ $d
LF equ $a
FF equ $c
ESC equ $1b
DC2 equ $12
.text
***************************************************************
***************************************************************
***************************************************************
dumbentry:
clr.l d0
rts
dc.l "PRNT"
dc.w 201
*
* distribute the calls to the appropriate routines
*
slm804: 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 #$8000+PRT+ASCENDING,device(a0)
prtok: moveq #1,d0
rrts: rts
rterr: moveq #0,d1
rts
*
* initialize the table of printer specific routines
*
p_init: clr.b pdl(a0) ;not a page description language driver
move.b #1,pmult(a0) ;automatically print mulitiple copies?
clr.b pman(a0) ;handle manual feed?
move.b #PRT_BW,ptype(a0) ;printer type?
*
* pminlft and pmaxw must be evenly divisible by 16
*
move.w pdensity(a0),d0
cmp.w #7,d0
bcs pint1
moveq #6,d0
pint1: lsl.w #1,d0
lea scl_tbl,a1
move.w 0(a1,d0.w),scale
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 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
lsl.w #1,d0
lea maxw_tbl,a1
move.l 0(a1,d0.w),pmaxw(a0) ;maximum # pixels across
lea maxh_tbl,a1
move.l 0(a1,d0.w),pmaxh(a0) ;maximum # pixels down
bra prtok
*
* going to begin printing a document
*
p_bgndoc:
bra prtok
*
* about to start printing of a page
*
p_bgnpage:
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 m_alloc(a0),a0
move.l #40000,d0
moveq #0,d1
jsr (a0)
beq rrts
move.l a0,p1handle
move.l table,a0
move.l m_alloc(a0),a0
move.l #40000,d0
moveq #0,d1
jsr (a0)
beq rrts
move.l a0,p2handle
move.l (a0),p2ptr
move.l p1handle,a0
move.l (a0),p1ptr
move.l table,a0
move.l pblockptr(a0),a1
move.l (a1),_page_image
move.l pblockw(a0),d0
move.w d0,width ;width in bytes
lsl.w #3,d0
move.w d0,wbits ;width in bits
move.l pblockh(a0),d0
move.w d0,height ;height
clr.l pblockh(a0)
move.w pcopies(a0),tcopy
block1: clr.l -(sp)
move.w #$20,-(sp) ;set supervisor mode
trap #1
addq.l #6,sp
move.l d0,stack
jsr _print_page
move.l stack,-(sp)
move.w #$20,-(sp) ;return to user mode
trap #1
addq.l #6,sp
subq.w #1,tcopy
bhi block1
move.l table,a1
move.l m_delete(a1),a1
move.l p1handle,a0
jsr (a1)
move.l table,a1
move.l m_delete(a1),a1
move.l p2handle,a0
jsr (a1)
bra prtok
*
* just finished describing current tile
*
p_endtile:
bra prtok
*
* just finished describing all tiles for this page
*
p_endpage:
bra prtok
*
* finished printing the document
*
p_enddoc:
bra prtok
***************************************************
*** original assumed 300x3180 ***
*** ***
***************************************************
*
_print_page:
move.l p1ptr,a0
move.w #9999,d0
pp1: clr.l (a0)+
dbf d0,pp1
move.l p2ptr,a0
move.w #9999,d0
pp2: clr.l (a0)+
dbf d0,pp2
*
*
*
lea dmadata,a0 ;
tas.b flock ; DMA channel currently in use?
bne rterr ; --> yes, don't use it right now
move.l #$e00000,cntrl
*
* INQUIRY - determine if the printer is happy, and what the controller # is
*
inquiry:
move.w #$198,2(a0) ;DMA select?
move.w #$88,2(a0) ;assert command signal
move.l #$12008a,d0 ;MODE SENSE command byte 0
or.l cntrl,d0
jsr writcmnd ;to controller number (cntrl)
bne badinq ;
move.l #$00008a,d0 ;command byte 1
jsr writcmnd ;
bne badinq
move.l #$00008a,d0 ;command byte 2
jsr writcmnd ;
bne badinq
move.l #$00008a,d0 ;command byte 3
jsr writcmnd ;
bne badinq
move.l #$00008a,d0 ;command byte 4
jsr writcmnd ;
bne badinq
move.l #$800082,d0 ;command byte 5
move.l d0,(a0) ;no acknowledge for byte 5
moveq.l #2,d1 ;~ 5 millisecond delay
add.l _hz_200,d1 ;NB MINIMUM DELAY IS 20 MICROSECONDS
indel: cmp.l _hz_200,d1 ;
bge indel ;
bsr getstatus ;status byte- is everybody in?
bne badinq
lea identlist,a3 ;the parade is about to begin...
bsr getstatus ;byte 0 - Device Type
bne badinq
move.b d0,(a3)+
bsr getstatus ;byte 1
bne badinq
move.b d0,(a3)+
bsr getstatus ;byte 2
bne badinq
move.b d0,(a3)+
bsr getstatus ;byte 3
bne badinq
move.b d0,(a3)+
bsr getstatus ;byte 4 - String Length
bne badinq
move.b d0,(a3)+
moveq #0,d7
move.b d0,d7
bra inidl2
inidl1: bsr getstatus ;get the next indentification list byte
bne badinq
move.b d0,(a3)+ ;save it in the table
inidl2: dbf d7,inidl1 ;loop ListLength times
lea identlist+5,a3
cmp.b #"P",(a3)+
bne badinq
cmp.b #"A",(a3)+
bne badinq
cmp.b #"G",(a3)+
bne badinq
cmp.b #"E",(a3)+
beq okinq
badinq: move.w #$80,2(a0)
sub.l #$200000,cntrl
bcc inquiry
bra prabrt
*
* MODE SENSE - get the current print parameters
*
okinq:
move.w #$198,2(a0) ;DMA select?
move.w #$88,2(a0) ;assert command signal
move.l #$1a008a,d0 ;MODE SENSE command byte 0
or.l cntrl,d0
jsr writcmnd ;to controller number n
bne prabrt ;
move.l #$00008a,d0 ;command byte 1
jsr writcmnd ;
bne prabrt ;
move.l #$00008a,d0 ;command byte 2
jsr writcmnd ;
bne prabrt ;
move.l #$00008a,d0 ;command byte 3
jsr writcmnd ;
bne prabrt ;
move.l #$00008a,d0 ;command byte 4
jsr writcmnd ;
bne prabrt ;
move.l #$000082,d0 ;command byte 5
move.l d0,(a0) ;no acknowledge for byte 5
moveq.l #2,d1 ;~ 5 millisecond delay
add.l _hz_200,d1 ;NB MINIMUM DELAY IS 20 MICROSECONDS
msdel: cmp.l _hz_200,d1 ;
bge msdel ;
bsr getstatus ;status byte- is everybody in?
lea paramlist,a3 ;the parade is about to begin...
bsr getstatus ;List Length- num of bytes to follow
move.b d0,(a3)+
moveq #0,d7
move.b d0,d7
bra gtpml2
gtpml1: bsr getstatus ;get the next parameter list byte
move.b d0,(a3)+ ;save it in the table
gtpml2: dbf d7,gtpml1 ;loop ListLength times
move.w #$80,2(a0)
move.b paramlist+3,owidth
move.b paramlist+4,owidth+1
move.w owidth,d0
lsr.w #3,d0
move.w d0,owidth
mulu #128,d0
move.l d0,olength
add.l #32,olength
divu #512,d0
addq.w #1,d0
swap d0
move.w #$112,d0
move.l d0,ocount
*
* setup the new parameters in paramlist to be sent
*
; move.b wbits,paramlist+3
; move.b wbits+1,paramlist+4
move.b height,paramlist+1
move.b height+1,paramlist+2
bclr #0,paramlist+9
move.l table,a1
tst.b pmanual(a1) ;handle manual feed?
beq notmanual
bset #0,paramlist+9 ;set manual feed bit
notmanual:
IF 0
*
* MODE SELECT - set the print parameters for the printer
*
move.w #$198,2(a0) ;DMA select?
move.w #$88,2(a0) ;assert command signal
move.l #$15008a,d0 ;MODE SELECT command byte 0
or.l cntrl,d0
jsr writcmnd ;to controller number n
bne prabrt ;
move.l #$00008a,d0 ;command byte 1
jsr writcmnd ;
bne prabrt ;
move.l #$00008a,d0 ;command byte 2
jsr writcmnd ;
bne prabrt ;
move.l #$00008a,d0 ;command byte 3
jsr writcmnd ;
bne prabrt ;
move.l #$00008a,d0 ;command byte 4
jsr writcmnd ;
bne prabrt ;
move.l #$00008a,d0 ;command byte 5 (was $8a, might be $80 or $82)
jsr writcmnd ;
bne prabrt ;
lea paramlist,a3 ;the parade is about to leave...
moveq #0,d7
move.b (a3)+,d7
move.w d7,d0
bra ptpml2
ptpml1: bsr putstatus ;put the next parameter list byte
bne prabrt ;
move.b (a3)+,d0 ;get next byte from the table
ptpml2: dbf d7,ptpml1 ;loop ListLength times
bsr putstatus
; swap d0
; move.w #$0082,d0 ;was 82-last byte in extended command
; move.l d0,(a0) ;no acknowledge for last byte
; moveq.l #2,d1 ;~ 5 millisecond delay
; add.l _hz_200,d1 ;NB MINIMUM DELAY IS 20 MICROSECONDS
;sedel: cmp.l _hz_200,d1 ;
; bge sedel ;
bsr getstatus ;status byte- is everybody in?
move.w #$80,2(a0)
ENDIF
*
* setup for first DMA cycle
*
move.w width,d0 ;copy width
lsr.w #1,d0
subq.w #1,d0
move.w d0,cpwdth
move.l _page_image,a2 ; /* load initial band base */
move.l p1ptr,a5
move.w #128,d4
cpd1: move.l a2,a3 ;don't want to advance on second row
move.l a5,a4
move.w cpwdth,d3
cpd2: move.w (a2)+,(a4)+
dbf d3,cpd2
add.w owidth,a5
; lea 300(a5),a5 ;skip white space (could precalc this)
dbf d4,cpd1
move.l a3,a2
*
* COMMAND PHASE
*
move.w #$198,2(a0) ;DMA select?
move.w #$88,2(a0) ;assert command signal
move.l #$0a008a,d0 ;PRINT command byte 0
or.l cntrl,d0
jsr writcmnd ;to controller number n
bne prabrt ;
move.l #$00008a,d0 ;command byte 1
jsr writcmnd ;
bne prabrt ;
move.l #$00008a,d0 ;command byte 2
jsr writcmnd ;
bne prabrt ;
move.l #$00008a,d0 ;command byte 3
jsr writcmnd ;
bne prabrt ;
move.l #$00008a,d0 ;command byte 4
jsr writcmnd ;
bne prabrt ;
move.l #$000082,d0 ;command byte 5
move.l d0,(a0) ;no acknowledge for byte 5
moveq.l #2,d1 ;~ 5 millisecond delay
add.l _hz_200,d1 ;NB MINIMUM DELAY IS 20 MICROSECONDS
codel: cmp.l _hz_200,d1 ;
bge codel ;
*
* DATA OUT PHASE
*
move.l p1ptr,d0
move.l d0,-(sp)
move.b 3(sp),dmalow ;initialize dma base address
move.b 2(sp),dmamid
move.b 1(sp),dmahigh
addq.l #4,sp
move.w #$192,2(a0) ;select sector count register
move.l ocount,(a0) ;write sector count, start dma
moveq #0,d7
move.w height,d7
add.w #127,d7
divu #128,d7
subq.w #1,d7
bra bottom
bdloop: add.l olength,d0 ;get final address to stop at
move.w sr,d1 ; /* save status register */
ori.w #$700,sr ; /* no interrupts, please */
move.l p2ptr,a5 ; swap p1ptr <-> p2ptr
move.l p1ptr,p2ptr
move.l a5,p1ptr
move.w #128,d4
cpd3: move.l a2,a3 ;don't want to advance on second row
move.l a5,a4
move.w cpwdth,d3
cpd4: move.w (a2)+,(a4)+
dbf d3,cpd4
add.w owidth,a5
; lea 300(a5),a5 ;skip white space (could precalc this)
dbf d4,cpd3
move.l a3,a2
bdwait: btst.b #5,gpip ;check for premature status phase
beq fuckoff ;stwait ;abort and get status byte
movep.w 7(a0),d2 ;get current DMA mid and low
cmp.w d2,d0 ;compare to final address
bne bdwait ;not there yet?
move.l p1ptr,d0
addq.l #2,d0 ;compensate for FIFO
move.l d0,-(sp)
move.b 3(sp),dmalow ;reinitialize DMA base address
move.b 2(sp),dmamid ;
move.b 1(sp),dmahigh ;
addq.l #4,sp ;
move.w #$92,2(a0) ;reset FIFO
move.w #$192,2(a0) ;
move.l ocount,(a0) ;reload sector count register
move.w d1,sr ;restore status register
bottom: dbra d7,bdloop ;more bands?
*
* STATUS PHASE
*
fuckoff:
stwait: btst.b #5,gpip ;wait for status byte
bne stwait ;
stbyte: move.w d1,sr ;restore status register
move.w #$8a,2(a0) ;select status register
move.w (a0),d0 ;read status byte
moveq.l #2,d1 ;~ 5 millisecond delay
add.l _hz_200,d1 ;NB MINIMUM DELAY IS 20 MICROSECONDS
stdel: cmp.l _hz_200,d1 ;
bge stdel ;
bra prexit ;return status byte
prabrt: moveq.l #-1,d0 ;return error flag
prexit: move.w #$80,2(a0)
sf flock ;unlock dma channel
rts ;
***************************************************
*** ***
***************************************************
getstatus:
moveq.l #100,d1 ;500 millisecond timeout
add.l _hz_200,d1 ;
gstime: btst.b #5,gpip ;
beq gsbyte ;command byte acknowledged
cmp.l _hz_200,d1 ;
bge gstime ;
moveq.l #-1,d1 ;timeout - set error flag
rts ;
gsbyte: move.w #$8a,2(a0) ;select status register
move.w (a0),d0 ;read status byte
moveq.l #2,d1 ;~ 5 millisecond delay
add.l _hz_200,d1 ;NB MINIMUM DELAY IS 20 MICROSECONDS
gsdel: cmp.l _hz_200,d1 ;
bge gsdel ;
moveq #0,d1
rts
***************************************************
*** ***
***************************************************
*
* WRITCMND
* Write command byte to DMA controller.
*
* Inputs: d0.L = Data/control words
* a0 = Pointer to DMA controller (ff8604)
* Outputs: EQ = Successful command write
* NE = Error occurred
* Modified: d1
*
putstatus:
swap d0
move.w #$8a,d0
writcmnd:
move.l d0,(a0) ;write command byte
moveq.l #2,d1 ;~ 5 millisecond delay
add.l _hz_200,d1 ;NB MINIMUM DELAY IS 20 MICROSECONDS
wrdel: cmp.l _hz_200,d1 ;
bge wrdel ;
moveq.l #40,d1 ;200 millisecond timeout
add.l _hz_200,d1 ;
writlp: btst.b #5,gpip ;
beq writok ;command byte acknowledged
cmp.l _hz_200,d1 ;
bge writlp ;
moveq.l #-1,d1 ;timeout - set error flag
writok: rts ;
***********************************
*** ***
***********************************
.data
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 prtok,p_ident
scl_tbl: dc.w 1,1,1,1,1,1,1
xdpi_tbl: dc.w 300,300,300,300,300,300,300
ydpi_tbl: dc.w 300,300,300,300,300,300,300
minl_tbl: dc.w 75,75,75,75,75,75,75
minr_tbl: dc.w 75,75,75,75,75,75,75
mint_tbl: dc.w 56,56,56,56,56,56,56
minb_tbl: dc.w 56,56,56,56,56,56,56
maxw_tbl: dc.l 2400,2400,2400,2400,2400,2400,2400
maxh_tbl: dc.l 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
driver: dc.b "Atari SLM804 v2.0.3-3",0
.bss
temp: ds.l 1
tcopy: ds.w 1
scale: ds.w 1
_page_image: ds.l 1
stack: ds.l 1
height: ds.w 1
width: ds.w 1
wbits: ds.w 1
owidth: ds.w 1
olength: ds.l 1
ocount: ds.l 1
table: ds.l 1
cpwdth: ds.w 1
cntrl: ds.l 1
paramlist: ds.b 50
identlist: ds.b 50
p1handle: ds.l 1
p1ptr: ds.l 1
p2handle: ds.l 1
p2ptr: ds.l 1
;
; 2.0.1 - added support for manual feed
; 2.0.2 - changed timing
; added support for variable length bitmaps
; removed 75,100,& 150 dpi options (they didn't do anything)