
	nosyms
	mname HWIA_UTILS

	src     MODULE HWIA_UTILS;
	src     import SCSI_DEFS;
	src     export
	src     procedure hwiAXfer(var XferBlock:XferBlockType; PtrScsiChip:PtrScsiChipType);
	src     END;

	def     HWIA_UTILS_HWIAXFER
	def     HWIA_UTILS_HWIA_UTILS
	def     HWIA_UTILS__BASE

regScsiChip                     equ     a4
intsOffset                      equ     9
sstsOffset                      equ     13
dataOffset                      equ     21
BitFIFOEmpty                    equ     0
BitFIFOFull                     equ     1

regXferBlock                    equ     a3
XferPhaseOffset                 equ     0
XferRetryCountOffset            equ     2
XferSavedDataPointerOffset      equ     4
XferSavedDataLengthOffset       equ     8
XferDMACountOffset              equ     12
XferBufPtrOffset                equ     16
XferBufLenOffset                equ     20
XferDoDMAOffset                 equ     24

regBufPtr                       equ     a2
regChipData                     equ     a1
regChipSsts                     equ     a0
regBufLen                       equ     d2

HWIA_UTILS__BASE              equ *
HWIA_UTILS_HWIAXFER           equ *
*******************************************************************
* set up registers
* predecrement regBufLen to compensate for dbra termination on -1.
* if the register is < 0, then 0 or negative length, do nothing in
* this case.
*******************************************************************
		move.l  8(sp),regXferBlock
		move.l  4(sp),regScsiChip
		lea     dataOffset(regScsiChip),regChipData
		lea     sstsOffset(regScsiChip),regChipSsts
		move.l  XferBufPtrOffset(regXferBlock),regBufPtr
		move.l  XferBufLenOffset(regXferBlock),regBufLen
		subq.l  #1,regBufLen
		blt.s   exit_restore

*******************************************************************
* determine if this is an inbound or outbound transfer
*******************************************************************
		cmpi.w  #1,XferPhaseOffset(regXferBlock)
		bne.w   outbound_xfer

inbound_xfer    equ     *
*******************************************************************
*  while (there is room in the buffer)
*       if fifo not empty
*               input data
*       else fifo is empty
*               wait for an interrupt or fifo not empty
*               on interrupt exit
*******************************************************************
check_fifo_empty equ    *
		btst    #BitFIFOEmpty,(regChipSsts)
		bne.s   fifo_empty
		move.b  (regChipData),(regBufPtr)+
		dbra    regBufLen,check_fifo_empty
		clr.w   regBufLen               ; dbra only works on 16 bits
		subq.l  #1,regBufLen            ; check for > 16 bit transfer
		bgt.s   check_fifo_empty
		bra.s   exit_restore
fifo_empty      equ     *
		tst.b   intsOffset(regScsiChip)
		beq.s   check_fifo_empty
		bra.s   exit_restore

outbound_xfer   equ *
*******************************************************************
*  while (there is data in the buffer)
*       if fifo not full
*               output data
*       else fifo is full
*               wait for an interrupt or fifo not full
*               on interrupt exit
*  wait for fifo to empty or an interrupt to occur
*******************************************************************
check_fifo_full equ     *
		btst    #BitFIFOFull,(regChipSsts)
		bne.s   fifo_full
		move.b  (regBufPtr)+,(regChipData)
		dbra    regBufLen,check_fifo_full
		clr.w   regBufLen               ; dbra only works on 16 bits
		subq.l  #1,regBufLen            ; check for > 16 bit transfer
		bgt.s   check_fifo_full
wait_fifo_empty equ     *
		btst    #BitFIFOEmpty,(regChipSsts)
		bne.s   exit_restore
		tst.b   intsOffset(regScsiChip)
		beq.s   wait_fifo_empty
		bra.s   exit_restore
fifo_full       equ     *
		tst.b   intsOffset(regScsiChip)
		beq.s   check_fifo_full
*               bra.s   exit_restore

exit_restore    equ *
*******************************************************************
*  restore registers into the XferBlock.  Add 1 to regBufLen
*  to get the true final count.  This compensates for dbra
*  terminating on -1.
*******************************************************************
		move.l  regBufPtr,XferBufPtrOffset(regXferBlock)
		addq.l  #1,regBufLen
		move.l  regBufLen,XferBufLenOffset(regXferBlock)

*******************************************************************
*  restore stack and go back to caller
*******************************************************************
		move.l  (sp)+,a0
		addq.w  #8,sp
		jmp     (a0)




HWIA_UTILS_HWIA_UTILS         equ *
	rts

	END
