**********************************************************************
*
*  TRANSFER.ASM for an Amiga printer driver for the Hewlett Packard DeskJet
*
*                    Copywrite © 1989 Creative Focus
*
*   This software is freely redistributable, as long as all code,
*   comments, and documentation are included unaltered, and no other
*   conditions are imposed on its redistribution.
*
*   THIS SOFTWARE IS PROVIDED "AS IS," AND NO GUARANTEE IS MADE OF ITS
*   FITNESS FOR ANY PURPOSE.  CREATIVE FOCUS MAY NOT BE HELD ACCOUNTABLE
*   FOR ANY DAMAGE, REAL OR IMAGINED, RESULTING FROM ITS USE OR MISUSE.
*
*                           Creative Focus
*                           Dr. Gerald Hull
*                           12 White Street
*                           Binghamton, New York  13901
*
*                           (607) 648-4082
*                           BIX:  ghull
*                           PLINK:  DRJERRY
*
***********************************************************************

      nolist
      include "exec/types.i"
      include "devices/prtgfx.i"
      include "devices/prtbase.i"
      include "intuition/preferences.i"
      list

      xref  _PD

      xdef  _Transfer

PI    equr     a0       * -> PrtInfo structure
CI    equr     a1       * -> colorEntry structure
SXP   equr     a2       * -> ScaleX array
PT    equr     a3       * -> output buffer
DM    equr     a4       * -> dither matrix
FP    equr     a5       * frame pointer
SP    equr     a7       * stack pointer

X     equr     d0       * starting x position
SVN   equr     d1       * constant 7
SX    equr     d2       * scaling factor
WI    equr     d3       * graphic row width
DV    equr     d4       * dither value (also Y offset)
BL    equr     d5       * black intensity of pixel
BIT   equr     d6       * bit that needs to be set
OFF   equr     d7       * outbuf offset for setting bit

REGS  reg      d2-d7/a2-a4

*  input parameter offsets

PINFO equ      8        * -> PrtInfo
Y     equ     14        * graphic row number
PTR   equ     16        * -> output buffer


_Transfer
      link     FP,#0                * allocate frame
      movem.l  REGS,-(SP)           * save registers
      movea.l  PINFO(FP),PI         * get PrtInfo pointer
      movea.l  PTR(FP),PT           * get outbuf pointer
      move.w   pi_xpos(PI),X        * get x position
      movea.l  pi_ColorInt(PI),CI   * get color intensity data
      movea.l  pi_ScaleX(PI),SXP    * get scale array pointer
      move.w   pi_width(PI),WI      * get row width
      subq.w   #1,WI                * decrement for DBRA
      move.w   pi_threshold(PI),DV  * get dither value
      moveq    #7,SVN               * register is faster
      tst.w    DV                   * if zero
      beq.s    DITH                 *    dither
      eori.b   #15,DV               * else invert
WID1  move.l   (CI)+,BL             * black intensity data in low byte
CNT1  move.w   (SXP)+,SX            * increment scale pointer
      cmp.b    DV,BL                * dark enough to print?
      ble.s    END1                 *    nope
      subq.w   #1,SX                * yup; prep for DBRA
SCL1  move.w   X,OFF                * x position of dot
      lsr.w    #3,OFF               * div by 8 for byte number
      move.w   X,BIT                * again x position
      and.w    SVN,BIT              * modulo 8
      eor.w    SVN,BIT              * invert for BSET
      bset.b   BIT,0(PT,OFF.w)      * set bit in outbuf
      addq.w   #1,X                 * increment x position
      dbra     SX,SCL1              * repeat for scaling factor
      bra.s    FIN1                 * jump to DBRA (x already incr)
END1  add.w    SX,X                 * increment x position by scale
FIN1  dbra     WI,WID1              * repeat for row width
      bra.s    DUN                  * then get ready to leave

DITH  movea.l  pi_dmatrix(PI),DM    * get dither matrix pointer
      move.w   Y(FP),DV             * get row number
      andi.w   #3,DV                * modulo 4 
      lsl.w    #2,DV                * times 4
      adda.w   DV,DM                * adjust DM
WID2  move.l   (CI)+,BL             * black intensity value in low byte
CNT2  move.w   (SXP)+,SX            * get scaling factor
      subq.w   #1,SX                * prep for DBRA
SCL2  move.w   X,DV                 * get x position
      andi.w   #3,DV                * modulo 4 also
      cmp.b    0(DM,DV.w),BL        * dark enough?
      ble.s    END2                 *    nope
      move.w   X,DV                 * yup; get x position again
      lsr.w    #3,DV                * div by 8
      move.w   X,BIT                * and again
      and.w    SVN,BIT              * modulo 8
      eor.w    SVN,BIT              * invert for BSET
      bset.b   BIT,0(PT,DV.w)       * set bit in outbuf
END2  addq.w   #1,X                 * increment x dot position
      dbra     SX,SCL2              * repeat for scaling factor
      dbra     WI,WID2              * repeat for row width

DUN   movem.l  (SP)+,REGS           * restore registers
      unlk     FP                   * deallocate frame
      rts                           * return to Render

      end
