home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / DSHJ2 / HAFTONE.S < prev    next >
Encoding:
Text File  |  2001-02-10  |  19.3 KB  |  964 lines

  1.  
  2.         .globl    _haftone
  3.  
  4.  
  5. _haftone:
  6.  
  7. *    Scale a 16 color ST format image and transform to monochrome
  8. *    domain using luminance value of pixels as input to a dither matrix.
  9. *
  10. *
  11. *   iN:    sp+4    pointer to 28 byte image structure
  12. *
  13. *        +00    Source Memory Form base address
  14. *        +04    width of memory form (in bytes)
  15. *        +06    Xmin of source rectangle to be scaled and halftoned
  16. *        +08    Ymin
  17. *        +10    Width  (in pixels)
  18. *        +12    Height (in pixels)
  19. *
  20. *        +14    Destination Memory Form base address
  21. *        +18    width of memory form (in bytes)
  22. *        +20    Xmin of destination rectangle
  23. *        +22    Ymin
  24. *        +24    Width
  25. *        +26    Height
  26. *
  27. *    sp+8    pointer to 16 consecutive words of color information
  28. *
  29. *            each color word is in ST format:
  30. *
  31. *            RED <10:8>  GREEN <6:4>  BLUE <2:0>
  32.  
  33.     move.l    4(sp),a1    ; a5 -> image structure
  34.     move.l    8(sp),a0    ; a0 -> color LUT values
  35.     movem.l d3-d7/a3-a5,-(sp)
  36.     move.l    a1,a5
  37.     lea    halfbuf,a1    ; a1 -> target area for dither matricies
  38.     bsr    makehalf    ; build the dither data
  39.  
  40.     clr.w    d0        ; select appropriate scaling subroutine
  41.     move.w    SRC_WD(a5),d1
  42.     sub.w    DST_WD(a5),d1
  43.     addx.w    d0,d0
  44.     move.w    SRC_HT(a5),d1
  45.     sub.w    DST_HT(a5),d1
  46.     roxl.w    #3,d0
  47.     move.l    halftbl(pc,d0.w),a0    
  48.     jmp    (a0)
  49.  
  50. halftbl:
  51.  
  52.     dc.l    half400        ; Dst Wd =< Src Wd   Dst Ht =< Src Ht   
  53.     dc.l    half401        ; Dst Wd =< Src Wd   Dst Ht  > Src Ht   
  54.     dc.l    half410        ; Dst Wd  > Src Wd   Dst Ht =< Src Ht   
  55.     dc.l    half411        ; Dst Wd  > Src Wd   Dst Ht  > Src Ht   
  56.  
  57.  
  58.  
  59. WS        set    -28
  60.  
  61. HAF_BASE    set    -28
  62. HAF_RCTR    set    -24
  63. SRC_ADDR    set    -22
  64. SRC_X1ST    set    -18
  65. SRC_SCNT    set    -16
  66. DST_HCTR    set    -14
  67. DST_ADDR    set    -12
  68. DST_X1ST    set    -08
  69. DDA_XINI    set    -06
  70. DDA_YACC    set    -04
  71. DDA_YINC    set    -02
  72.  
  73. half400:
  74.  
  75. *    Scale Down in X and Y
  76. *
  77. *  iN:
  78. *    a1    pointer to initialized halftone table area
  79. *    a5    pointer to parameter structure
  80.  
  81.     link    a6,#WS            ; a6 -> temporary workspace
  82.  
  83.     move.l    a1,a2
  84.     move.l    a1,HAF_BASE(a6)
  85.     clr.w    HAF_RCTR(a6)
  86.  
  87.     move.l    SRC_BASE(a5),a0
  88.     move.w    SRC_YMIN(a5),d0
  89.     mulu    SRC_NXLN(a5),d0
  90.     add.l    d0,a0
  91.     move.w    SRC_XMIN(a5),d0
  92.     move.w    d0,d1
  93.     and.w    #$FFF0,d0
  94.     lsr.w    #1,d0
  95.     add.w    d0,a0
  96.     move.l    a0,SRC_ADDR(a6)        ; src starting address
  97.     moveq.l    #15,d2
  98.     and.w    d2,d1
  99.     move.w    d1,SRC_SCNT(a6)        ; src shift count for 1st word
  100.     eor.w    d2,d1
  101.     move.w    d1,SRC_X1ST(a6)        ; src pixel counter for 1st word
  102.  
  103.     move.l    DST_BASE(a5),a1
  104.     move.w    DST_YMIN(a5),d1
  105.     mulu    DST_NXLN(a5),d1
  106.     add.l    d1,a1
  107.     move.w    DST_XMIN(a5),d1
  108.     move.w    d1,d0
  109.     lsr.w    #4,d1
  110.     add.w    d1,d1
  111.     add.w    d1,a1
  112.     move.l    a1,DST_ADDR(a6)
  113.     not.w    d0
  114.     and.w    d2,d0
  115.     move.w    d0,DST_X1ST(a6)
  116.  
  117.     move.w    DST_HT(a5),d0
  118.     move.w    d0,d1
  119.     subq.w    #1,d1
  120.     move.w    d1,DST_HCTR(a6)
  121.  
  122.     swap    d0
  123.     clr.w    d0
  124.     divu    SRC_HT(a5),d0
  125.     bvc.s    .1
  126.  
  127.     swap    d0
  128.     move.w    #$FFFF,d0
  129.  
  130. .1:    move.w    d0,DDA_YINC(a6)
  131.     swap    d0
  132.     move.w    d0,DDA_YACC(a6)
  133.  
  134.     move.w    DST_WD(a5),d0
  135.     swap    d0
  136.     clr.w    d0
  137.     divu    SRC_WD(a5),d0
  138.     bvc.s    .2
  139.  
  140.     swap    d0
  141.     move.w    #$FFFF,d0
  142.  
  143. .2:    move.w    d0,a3            ; a3 <- X DDA accumulator
  144.     swap    d0
  145.     move.w    d0,DDA_XINI(a5)
  146.  
  147.     move.w    SRC_NXLN(a5),d0
  148.     bra    .70
  149.  
  150.  
  151. .10:    add.w    a3,d4        ; advance the SRC DDA accumulator
  152.     bcs.s    .15        ; fetch pixel if DDA rollover
  153.  
  154.     add.l    d0,d0        ; otherwise skip the pixel
  155.     add.l    d1,d1
  156.     dbra    d2,.10        ; check for SRC word fault
  157.  
  158.     moveq.l    #15,d2        ; d2 <- src pixel counter for next word
  159.     move.l    (a0)+,d0    ; reload source pixel cache with 
  160.     move.l    (a0)+,d1    ; the next 16 pixels
  161.     bra.s    .10
  162.  
  163.  
  164. .15:    clr.w    d7        ; isolate next logical pixel
  165.     add.w    d1,d1
  166.     addx.w    d7,d7
  167.     swap    d1
  168.     add.w    d1,d1
  169.     addx.w    d7,d7
  170.     swap    d1
  171.     add.w    d0,d0
  172.     addx.w    d7,d7
  173.     swap    d0
  174.     add.w    d0,d0
  175.     roxl.w    #2,d7        ; d7 <- offset into relevant dither matrix 
  176.     swap    d0
  177.     dbra    d2,.20        ; check for SRC word fault 
  178.  
  179.     moveq.l    #15,d2        ; d2 <- src pixel counter for next word
  180.     move.l    (a0)+,d0    ; reload source pixel cache with 
  181.     move.l    (a0)+,d1    ; the next 16 pixels
  182.  
  183. .20:    move.w    (a2,d7.w),d7    ; d7 <- dither data: is pixel on or off at X
  184.  
  185. .30:    btst.l    d3,d7        ; given luminance, does dst pix get set ?
  186.     beq.s    .40
  187.  
  188.     bset.l    d3,d5
  189.  
  190. .40:    dbra    d3,.50        ; destination word fault ?
  191.  
  192.     moveq.l    #15,d3        ; d3 <- hi bit of dst halftone cache word
  193.     or.w    d5,(a1)+    ; OR halftone cache into dst
  194.     clr.w    d5        ; reinit dst buffer
  195.  
  196. .50:    dbra    d6,.10        ; d6 <- destination pixels remaining
  197.  
  198.     or.w    d5,(a1)        ; flush dst buffer
  199.  
  200.     move.l    SRC_ADDR(a6),a0
  201.     move.l    DST_ADDR(a6),a1
  202.     add.w    DST_NXLN(a5),a1    ; a1 -> first word of next dst line
  203.     move.l    a1,DST_ADDR(a6)
  204.  
  205.     move.l    HAF_BASE(a6),a2
  206.     move.w    HAF_RCTR(a6),d7
  207.     add.w    #$0020,d7
  208.     and.w    #$00E0,d7
  209.     add.w    d7,a2        ; a2 -> halftone dither matrix array for line n
  210.     move.w    d7,HAF_RCTR(a6)
  211.  
  212.     move.w    SRC_NXLN(a5),d0
  213.     add.w    d0,a0
  214.  
  215. .70:    move.w    DDA_YINC(a6),d1
  216.     move.w    DDA_YACC(a6),d2
  217.  
  218. .80:    add.w    d1,d2
  219.     bcs.s    .90
  220.     add.w    d0,a0
  221.     bra.s    .80    
  222.  
  223. .90:    move.w    d2,DDA_YACC(a6)
  224.     move.l    a0,SRC_ADDR(a6)
  225.  
  226.     move.w    SRC_SCNT(a6),d2    ; load src pixel cache and
  227.     move.l    (a0)+,d0    ; adjust registers so that the bits
  228.     move.l    (a0)+,d1    ; of the first pixel are in positions
  229.     lsl.l    d2,d0        ; 15 and 31 of each register
  230.     lsl.l    d2,d1
  231.  
  232.     move.w    SRC_X1ST(a6),d2    ; d2 <- src pixel pointer
  233.     move.w    DST_X1ST(a6),d3    ; d3 <- dst pixel pointer
  234.     move.w    DDA_XINI(a6),d4    ; d4 <- reinited DDA X accumulator
  235.     clr.w    d5        ; clear dst pixel buffer
  236.     move.w    DST_WD(a5),d6
  237.     subq.w    #1,d6        ; d6 <- src pixel counter
  238.  
  239.     subq.w    #1,DST_HCTR(a6)
  240.     bcc    .10
  241.  
  242.     unlk    a6
  243.     movem.l (sp)+,d3-d7/a3-a5
  244.     rts
  245.  
  246.  
  247.  
  248.  
  249. WS        set    -28
  250.  
  251. HAF_BASE    set    -28
  252. HAF_RCTR    set    -24
  253. SRC_ADDR    set    -22
  254. SRC_X1ST    set    -18
  255. SRC_SCNT    set    -16
  256. SRC_HCTR    set    -14
  257. DST_ADDR    set    -12
  258. DST_X1ST    set    -08
  259. DDA_XINI    set    -06
  260. DDA_YACC    set    -04
  261. DDA_YINC    set    -02
  262.  
  263. half401:
  264.  
  265. *    Scale Down in X
  266. *    Scale Up in Y
  267. *
  268. *  iN:
  269. *    a1    pointer to initialized halftone table area
  270. *    a5    pointer to parameter structure
  271.  
  272.     link    a6,#WS            ; a6 -> temporary workspace
  273.  
  274.     move.l    a1,a2
  275.     move.l    a1,HAF_BASE(a6)
  276.     clr.w    HAF_RCTR(a6)
  277.  
  278.     move.l    SRC_BASE(a5),a0
  279.     move.w    SRC_YMIN(a5),d0
  280.     mulu    SRC_NXLN(a5),d0
  281.     add.l    d0,a0
  282.     move.w    SRC_XMIN(a5),d0
  283.     move.w    d0,d1
  284.     and.w    #$FFF0,d0
  285.     lsr.w    #1,d0
  286.     add.w    d0,a0
  287.     move.l    a0,SRC_ADDR(a6)        ; src starting address
  288.     moveq.l    #15,d2
  289.     and.w    d2,d1
  290.     move.w    d1,SRC_SCNT(a6)        ; src shift count for 1st word
  291.     eor.w    d2,d1
  292.     move.w    d1,SRC_X1ST(a6)        ; src pixel counter for 1st word
  293.  
  294.     move.l    DST_BASE(a5),a1
  295.     move.w    DST_YMIN(a5),d1
  296.     mulu    DST_NXLN(a5),d1
  297.     add.l    d1,a1
  298.     move.w    DST_XMIN(a5),d1
  299.     move.w    d1,d0
  300.     lsr.w    #4,d1
  301.     add.w    d1,d1
  302.     add.w    d1,a1
  303.     move.l    a1,DST_ADDR(a6)
  304.     not.w    d0
  305.     and.w    d2,d0
  306.     move.w    d0,DST_X1ST(a6)
  307.  
  308.     move.w    SRC_HT(a5),d0
  309.     move.w    d0,d1
  310.     subq.w    #1,d1
  311.     move.w    d1,SRC_HCTR(a6)
  312.  
  313.     swap    d0
  314.     clr.w    d0
  315.     divu    DST_HT(a5),d0
  316.     bvc.s    .1
  317.  
  318.     swap    d0
  319.     move.w    #$FFFF,d0
  320.  
  321. .1:    move.w    d0,DDA_YINC(a6)
  322.     swap    d0
  323.     move.w    d0,DDA_YACC(a6)
  324.  
  325.     move.w    DST_WD(a5),d0
  326.     swap    d0
  327.     clr.w    d0
  328.     divu    SRC_WD(a5),d0
  329.     bvc.s    .2
  330.  
  331.     swap    d0
  332.     move.w    #$FFFF,d0
  333.  
  334. .2:    move.w    d0,a3            ; a3 <- X DDA accumulator
  335.     swap    d0
  336.     move.w    d0,DDA_XINI(a5)
  337.  
  338.     bra    .70
  339.  
  340.  
  341. .10:    add.w    a3,d4        ; advance the SRC DDA accumulator
  342.     bcs.s    .15        ; fetch pixel if DDA rollover
  343.  
  344.     add.l    d0,d0        ; otherwise skip the pixel
  345.     add.l    d1,d1
  346.     dbra    d2,.10        ; check for SRC word fault
  347.  
  348.     moveq.l    #15,d2        ; d2 <- src pixel counter for next word
  349.     move.l    (a0)+,d0    ; reload source pixel cache with 
  350.     move.l    (a0)+,d1    ; the next 16 pixels
  351.     bra.s    .10
  352.  
  353.  
  354. .15:    clr.w    d7        ; isolate next logical pixel
  355.     add.w    d1,d1
  356.     addx.w    d7,d7
  357.     swap    d1
  358.     add.w    d1,d1
  359.     addx.w    d7,d7
  360.     swap    d1
  361.     add.w    d0,d0
  362.     addx.w    d7,d7
  363.     swap    d0
  364.     add.w    d0,d0
  365.     roxl.w    #2,d7        ; d7 <- offset into relevant dither matrix 
  366.     swap    d0
  367.     dbra    d2,.20        ; check for SRC word fault 
  368.  
  369.     moveq.l    #15,d2        ; d2 <- src pixel counter for next word
  370.     move.l    (a0)+,d0    ; reload source pixel cache with 
  371.     move.l    (a0)+,d1    ; the next 16 pixels
  372.  
  373. .20:    move.w    (a2,d7.w),d7    ; d7 <- dither data: is pixel on or off at X
  374.  
  375. .30:    btst.l    d3,d7        ; given luminance, does dst pix get set ?
  376.     beq.s    .40
  377.  
  378.     bset.l    d3,d5
  379.  
  380. .40:    dbra    d3,.50        ; destination word fault ?
  381.  
  382.     moveq.l    #15,d3        ; d3 <- hi bit of dst halftone cache word
  383.     or.w    d5,(a1)+    ; OR halftone cache into dst
  384.     clr.w    d5        ; reinit dst buffer
  385.  
  386. .50:    dbra    d6,.10        ; d6 <- destination pixels remaining
  387.  
  388.     or.w    d5,(a1)        ; flush dst buffer
  389.  
  390.     move.l    SRC_ADDR(a6),a0
  391.     move.l    DST_ADDR(a6),a1
  392.  
  393.     move.w    DDA_YINC(a6),d0
  394.     add.w    d0,DDA_YACC(a6)
  395.     bcc.s    .60
  396.  
  397.     add.w    SRC_NXLN(a5),a0    ; a0 -> first word of next src line
  398.     move.l    a0,SRC_ADDR(a6)
  399.     
  400.     subq.w    #1,SRC_HCTR(a6)
  401.     bcc.s    .60
  402.  
  403.     unlk    a6
  404.     movem.l (sp)+,d3-d7/a3-a5
  405.     rts
  406.  
  407. .60:    add.w    DST_NXLN(a5),a1    ; a1 -> first word of next dst line
  408.     move.l    a1,DST_ADDR(a6)
  409.  
  410.     move.l    HAF_BASE(a6),a2
  411.     move.w    HAF_RCTR(a6),d7
  412.     add.w    #$0020,d7
  413.     and.w    #$00E0,d7
  414.     add.w    d7,a2        ; a2 -> halftone dither matrix array for line n
  415.     move.w    d7,HAF_RCTR(a6)
  416.  
  417. .70:    move.w    SRC_SCNT(a6),d2    ; load src pixel cache and
  418.     move.l    (a0)+,d0    ; adjust registers so that the bits
  419.     move.l    (a0)+,d1    ; of the first pixel are in positions
  420.     lsl.l    d2,d0        ; 15 and 31 of each register
  421.     lsl.l    d2,d1
  422.  
  423.     move.w    SRC_X1ST(a6),d2    ; d2 <- src pixel pointer
  424.     move.w    DST_X1ST(a6),d3    ; d3 <- dst pixel pointer
  425.     move.w    DDA_XINI(a6),d4    ; d4 <- reinited DDA accumulator
  426.     clr.w    d5        ; clear dst pixel buffer
  427.     move.w    DST_WD(a5),d6
  428.     subq.w    #1,d6        ; d6 <- dst pixel counter
  429.     bra    .10
  430.  
  431.  
  432.  
  433.  
  434. WS        set    -28
  435.  
  436. HAF_BASE    set    -28
  437. HAF_RCTR    set    -24
  438. SRC_ADDR    set    -22
  439. SRC_X1ST    set    -18
  440. SRC_SCNT    set    -16
  441. DST_HCTR    set    -14
  442. DST_ADDR    set    -12
  443. DST_X1ST    set    -08
  444. DDA_XINI    set    -06
  445. DDA_YACC    set    -04
  446. DDA_YINC    set    -02
  447.  
  448.  
  449. half410:
  450.  
  451. *    Scale Up in X
  452. *    Scale Down in Y
  453. *
  454. *  iN:
  455. *    a1    pointer to initialized halftone table area
  456. *    a5    pointer to parameter structure
  457.  
  458.     link    a6,#WS            ; a6 -> temporary workspace
  459.  
  460.     move.l    a1,a2
  461.     move.l    a1,HAF_BASE(a6)
  462.     clr.w    HAF_RCTR(a6)
  463.  
  464.     move.l    SRC_BASE(a5),a0
  465.     move.w    SRC_YMIN(a5),d0
  466.     mulu    SRC_NXLN(a5),d0
  467.     add.l    d0,a0
  468.     move.w    SRC_XMIN(a5),d0
  469.     move.w    d0,d1
  470.     and.w    #$FFF0,d0
  471.     lsr.w    #1,d0
  472.     add.w    d0,a0
  473.     move.l    a0,SRC_ADDR(a6)        ; src starting address
  474.     moveq.l    #15,d2
  475.     and.w    d2,d1
  476.     move.w    d1,SRC_SCNT(a6)        ; src shift count for 1st word
  477.     eor.w    d2,d1
  478.     move.w    d1,SRC_X1ST(a6)        ; src pixel counter for 1st word
  479.  
  480.     move.l    DST_BASE(a5),a1
  481.     move.w    DST_YMIN(a5),d1
  482.     mulu    DST_NXLN(a5),d1
  483.     add.l    d1,a1
  484.     move.w    DST_XMIN(a5),d1
  485.     move.w    d1,d0
  486.     lsr.w    #4,d1
  487.     add.w    d1,d1
  488.     add.w    d1,a1
  489.     move.l    a1,DST_ADDR(a6)
  490.     not.w    d0
  491.     and.w    d2,d0
  492.     move.w    d0,DST_X1ST(a6)
  493.  
  494.     move.w    DST_HT(a5),d0
  495.     move.w    d0,DST_HCTR(a6)
  496.  
  497.     swap    d0
  498.     clr.w    d0
  499.     divu    SRC_HT(a5),d0
  500.     bvc.s    .1
  501.  
  502.     swap    d0
  503.     move.w    #$FFFF,d0
  504.  
  505. .1:    move.w    d0,DDA_YINC(a6)
  506.     swap    d0
  507.     move.w    d0,DDA_YACC(a6)
  508.  
  509.     move.w    SRC_WD(a5),d0
  510.     swap    d0
  511.     clr.w    d0
  512.     divu    DST_WD(a5),d0
  513.     bvc.s    .2
  514.  
  515.     swap    d0
  516.     move.w    #$FFFF,d0
  517.  
  518. .2:    move.w    d0,a3            ; a3 <- Xinc
  519.     swap    d0
  520.     move.w    d0,DDA_XINI(a5)
  521.  
  522.     move.w    SRC_NXLN(a5),d0
  523.     bra.s    .70
  524.  
  525.  
  526. .10:    clr.w    d7            ; isolate next logical pixel
  527.     add.w    d1,d1
  528.     addx.w    d7,d7
  529.     swap    d1
  530.     add.w    d1,d1
  531.     addx.w    d7,d7
  532.     swap    d1
  533.     add.w    d0,d0
  534.     addx.w    d7,d7
  535.     swap    d0
  536.     add.w    d0,d0
  537.     roxl.w    #2,d7        ; d7 <- offset into relevant dither matrix 
  538.     swap    d0
  539.     dbra    d2,.20        ; does next pixel cause source word fault ?
  540.  
  541.     moveq.l    #15,d2        ; d2 <- src pixel counter for next word
  542.     move.l    (a0)+,d0    ; reload source pixel cache with 
  543.     move.l    (a0)+,d1    ; the next 16 pixels
  544.  
  545. .20:    move.w    (a2,d7.w),d7    ; d7 <- dither data: is pixel on or off at X
  546.  
  547. .30:    btst.l    d3,d7        ; given luminance, does dst pix get set ?
  548.     beq.s    .40
  549.  
  550.     bset.l    d3,d5
  551.  
  552. .40:    dbra    d3,.50        ; destination word fault ?
  553.  
  554.     moveq.l    #15,d3        ; d3 <- hi bit of dst halftone cache word
  555.     or.w    d5,(a1)+    ; OR halftone cache into dst
  556.     clr.w    d5        ; reinit dst buffer
  557.  
  558. .50:    add.w    a3,d4        ; source DDA rollover ?
  559.     bcc.s    .30        ; if not, process next dst pixel.
  560.  
  561.     dbra    d6,.10        ; d5 <- source pixels remaining
  562.  
  563.     or.w    d5,(a1)        ; flush dst buffer
  564.  
  565.  
  566.     move.l    SRC_ADDR(a6),a0
  567.     move.l    DST_ADDR(a6),a1
  568.     add.w    DST_NXLN(a5),a1    ; a1 -> first word of next dst line
  569.     move.l    a1,DST_ADDR(a6)
  570.  
  571.     move.l    HAF_BASE(a6),a2
  572.     move.w    HAF_RCTR(a6),d7
  573.     add.w    #$0020,d7
  574.     and.w    #$00E0,d7
  575.     add.w    d7,a2        ; a2 -> halftone dither matrix array for line n
  576.     move.w    d7,HAF_RCTR(a6)
  577.  
  578.     move.w    SRC_NXLN(a5),d0
  579.     add.w    d0,a0
  580.  
  581. .70:    move.w    DDA_YINC(a6),d1
  582.     move.w    DDA_YACC(a6),d2
  583.  
  584. .80:    add.w    d1,d2
  585.     bcs.s    .90
  586.     add.w    d0,a0
  587.     bra.s    .80    
  588.  
  589. .90:    move.w    d2,DDA_YACC(a6)
  590.     move.l    a0,SRC_ADDR(a6)
  591.  
  592.     move.w    SRC_SCNT(a6),d2    ; load src pixel cache and
  593.     move.l    (a0)+,d0    ; adjust registers so that the bits
  594.     move.l    (a0)+,d1    ; of the first pixel are in positions
  595.     lsl.l    d2,d0        ; 15 and 31 of each register
  596.     lsl.l    d2,d1
  597.  
  598.     move.w    SRC_X1ST(a6),d2    ; d2 <- src pixel pointer
  599.     move.w    DST_X1ST(a6),d3    ; d3 <- dst pixel pointer
  600.     move.w    DDA_XINI(a6),d4    ; d4 <- reinited DDA X accumulator
  601.     clr.w    d5        ; clear dst pixel buffer
  602.     move.w    SRC_WD(a5),d6
  603.     subq.w    #1,d6        ; d6 <- src pixel counter
  604.  
  605.     subq.w    #1,DST_HCTR(a6)
  606.     bcc    .10
  607.  
  608.     unlk    a6
  609.     movem.l (sp)+,d3-d7/a3-a5
  610.     rts
  611.  
  612.  
  613.  
  614.  
  615. WS        set    -28
  616.  
  617. HAF_BASE    set    -28
  618. HAF_RCTR    set    -24
  619. SRC_ADDR    set    -22
  620. SRC_X1ST    set    -18
  621. SRC_SCNT    set    -16
  622. SRC_HCTR    set    -14
  623. DST_ADDR    set    -12
  624. DST_X1ST    set    -08
  625. DDA_XINI    set    -06
  626. DDA_YACC    set    -04
  627. DDA_YINC    set    -02
  628.  
  629.  
  630. half411:
  631.  
  632. *  iN:
  633. *    a1    pointer to initialized halftone table area
  634. *    a5    pointer to parameter structure
  635.  
  636.     link    a6,#WS            ; a6 -> temporary workspace
  637.  
  638.     move.l    a1,a2
  639.     move.l    a1,HAF_BASE(a6)
  640.     clr.w    HAF_RCTR(a6)
  641.  
  642.     move.l    SRC_BASE(a5),a0
  643.     move.w    SRC_YMIN(a5),d0
  644.     mulu    SRC_NXLN(a5),d0
  645.     add.l    d0,a0
  646.     move.w    SRC_XMIN(a5),d0
  647.     move.w    d0,d1
  648.     and.w    #$FFF0,d0
  649.     lsr.w    #1,d0
  650.     add.w    d0,a0
  651.     move.l    a0,SRC_ADDR(a6)        ; src starting address
  652.     moveq.l    #15,d2
  653.     and.w    d2,d1
  654.     move.w    d1,SRC_SCNT(a6)        ; src shift count for 1st word
  655.     eor.w    d2,d1
  656.     move.w    d1,SRC_X1ST(a6)        ; src pixel counter for 1st word
  657.  
  658.     move.l    DST_BASE(a5),a1
  659.     move.w    DST_YMIN(a5),d1
  660.     mulu    DST_NXLN(a5),d1
  661.     add.l    d1,a1
  662.     move.w    DST_XMIN(a5),d1
  663.     move.w    d1,d0
  664.     lsr.w    #4,d1
  665.     add.w    d1,d1
  666.     add.w    d1,a1
  667.     move.l    a1,DST_ADDR(a6)
  668.     not.w    d0
  669.     and.w    d2,d0
  670.     move.w    d0,DST_X1ST(a6)
  671.  
  672.     move.w    SRC_HT(a5),d0
  673.     move.w    d0,d1
  674.     subq.w    #1,d1
  675.     move.w    d1,SRC_HCTR(a6)
  676.     swap    d0
  677.     clr.w    d0
  678.     divu    DST_HT(a5),d0
  679.     bvc.s    .1
  680.  
  681.     swap    d0
  682.     move.w    #$FFFF,d0
  683.  
  684. .1:    move.w    d0,DDA_YINC(a6)
  685.     swap    d0
  686.     move.w    d0,DDA_YACC(a6)
  687.  
  688.     move.w    SRC_WD(a5),d0
  689.     swap    d0
  690.     clr.w    d0
  691.     divu    DST_WD(a5),d0
  692.     bvc.s    .2
  693.  
  694.     swap    d0
  695.     move.w    #$FFFF,d0
  696.  
  697. .2:    move.w    d0,a3        ; a3 <- Xinc
  698.     swap    d0
  699.     move.w    d0,DDA_XINI(a5)
  700.  
  701.     bra    .70
  702.  
  703.  
  704. .10:    clr.w    d7        ; isolate next logical pixel
  705.     add.w    d1,d1
  706.     addx.w    d7,d7
  707.     swap    d1
  708.     add.w    d1,d1
  709.     addx.w    d7,d7
  710.     swap    d1
  711.     add.w    d0,d0
  712.     addx.w    d7,d7
  713.     swap    d0
  714.     add.w    d0,d0
  715.     roxl.w    #2,d7        ; d7 <- offset into relevant dither matrix 
  716.     swap    d0
  717.     dbra    d2,.20        ; does next pixel cause source word fault ?
  718.  
  719.     moveq.l    #15,d2        ; d2 <- src pixel counter for next word
  720.     move.l    (a0)+,d0    ; reload source pixel cache with 
  721.     move.l    (a0)+,d1    ; the next 16 pixels
  722.  
  723. .20:    move.w    (a2,d7.w),d7    ; d7 <- dither data: is pixel on or off at X
  724.  
  725. .30:    btst.l    d3,d7        ; given luminance, does dst pix get set ?
  726.     beq.s    .40
  727.  
  728.     bset.l    d3,d5
  729.  
  730. .40:    dbra    d3,.50        ; destination word fault ?
  731.  
  732.     moveq.l    #15,d3        ; d3 <- hi bit of dst halftone cache word
  733.     or.w    d5,(a1)+    ; OR halftone cache into dst
  734.     clr.w    d5        ; reinit dst buffer
  735.  
  736. .50:    add.w    a3,d4        ; source DDA rollover ?
  737.     bcc    .30        ; if not, process next dst pixel.
  738.  
  739.     dbra    d6,.10        ; d5 <- source pixels remaining
  740.  
  741.     or.w    d5,(a1)        ; flush dst buffer
  742.  
  743.     move.l    SRC_ADDR(a6),a0
  744.     move.l    DST_ADDR(a6),a1
  745.  
  746.     move.w    DDA_YINC(a6),d0
  747.     add.w    d0,DDA_YACC(a6)
  748.     bcc.s    .60
  749.  
  750.     add.w    SRC_NXLN(a5),a0    ; a0 -> first word of next src line
  751.     move.l    a0,SRC_ADDR(a6)
  752.  
  753.     subq.w    #1,SRC_HCTR(a6)
  754.     bcc.s    .60
  755.  
  756.     unlk    a6
  757.     movem.l (sp)+,d3-d7/a3-a5
  758.     rts
  759.  
  760.  
  761. .60:    add.w    DST_NXLN(a5),a1    ; a1 -> first word of next dst line
  762.     move.l    a1,DST_ADDR(a6)
  763.  
  764.     move.l    HAF_BASE(a6),a2
  765.     move.w    HAF_RCTR(a6),d7
  766.     add.w    #$0020,d7
  767.     and.w    #$00E0,d7
  768.     add.w    d7,a2        ; a2 -> halftone dither matrix array for line n
  769.     move.w    d7,HAF_RCTR(a6)
  770.  
  771. .70:    move.w    SRC_SCNT(a6),d2    ; load src pixel cache and
  772.     move.l    (a0)+,d0    ; adjust registers so that the bits
  773.     move.l    (a0)+,d1    ; of the first pixel are in positions
  774.     lsl.l    d2,d0        ; 15 and 31 of each register
  775.     lsl.l    d2,d1
  776.  
  777.     move.w    SRC_X1ST(a6),d2    ; d2 <- src pixel pointer
  778.     move.w    DST_X1ST(a6),d3    ; d3 <- dst pixel pointer
  779.     move.w    DDA_XINI(a6),d4    ; d4 <- reinited DDA accumulator
  780.     clr.w    d5        ; clear dst pixel buffer
  781.     move.w    SRC_WD(a5),d6
  782.     subq.w    #1,d6        ; d6 <- src pixel counter
  783.     
  784.     bra    .10
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791. makehalf:
  792.  
  793. *  iN:
  794. *    a0    points to 16 words of RGB data
  795. *    a1    points to 256 byte area for halftone tables
  796.  
  797.     move.w    #15,d4
  798.  
  799. .0:    move.w    (a0)+,d0
  800.     bsr    getlum
  801.     mulu    #33,d2
  802.     swap    d2
  803.     lsl.w    #2,d2
  804.     lea    dither(pc,d2.w),a2
  805.  
  806.     moveq.l    #3,d1
  807.  
  808. .1:    move.b    (a2)+,d0
  809.     move.b    d0,000(a1)
  810.     move.b    d0,001(a1)
  811.     ror.b    #4,d0
  812.     move.b    d0,128(a1)
  813.     move.b    d0,129(a1)
  814.     add.w    #32,a1
  815.     dbra    d1,.1
  816.  
  817.     sub.w    #126,a1
  818.     dbra    d4,.0
  819.  
  820.     sub.w    #32,a1
  821.     rts
  822.  
  823.  
  824. dither:
  825.  
  826. *      T h E   d I t H e R   m A t R i X
  827. *
  828. *
  829. *    12  09  05  14  16  25  20  18
  830. *
  831. *    04  00  01  11  23  28  29  27
  832. *
  833. *    10  03  02  06  26  31  30  21
  834. *
  835. *    13  07  08  15  17  22  24  19
  836. *
  837. *    16  25  20  18  12  09  05  14
  838. *
  839. *    23  28  29  27  04  00  01  11
  840. *
  841. *    26  31  30  21  10  03  02  06
  842. *
  843. *    17  22  24  19  13  07  08  15
  844.  
  845. d00:    dc.b    $FF,$FF,$FF,$FF
  846. d01:    dc.b    $FF,$FF,$FB,$FF
  847. d02:    dc.b    $FF,$FF,$F9,$FF
  848. d03:    dc.b    $FF,$FD,$F9,$FF
  849. d04:    dc.b    $FF,$F9,$F9,$FF
  850. d05:    dc.b    $FF,$F8,$F9,$FF
  851. d06:    dc.b    $FF,$F8,$F1,$FF
  852. d07:    dc.b    $FB,$F8,$F1,$FF
  853. d08:    dc.b    $FB,$F8,$F1,$FD
  854. d09:    dc.b    $FB,$F0,$F1,$FD
  855. d10:    dc.b    $FB,$F0,$F1,$F9
  856. d11:    dc.b    $FB,$F0,$F0,$F9
  857. d12:    dc.b    $F9,$F0,$F0,$F9
  858. d13:    dc.b    $F9,$F0,$F0,$F8
  859. d14:    dc.b    $F8,$F0,$F0,$F8
  860. d15:    dc.b    $F8,$F0,$F0,$F0
  861. d16:    dc.b    $F0,$F0,$F0,$F0
  862. d17:    dc.b    $F0,$F0,$F0,$E0
  863. d18:    dc.b    $E0,$F0,$F0,$E0
  864. d19:    dc.b    $E0,$F0,$F0,$60
  865. d20:    dc.b    $60,$F0,$F0,$60
  866. d21:    dc.b    $60,$E0,$F0,$60
  867. d22:    dc.b    $60,$E0,$70,$60
  868. d23:    dc.b    $20,$E0,$70,$60
  869. d24:    dc.b    $20,$E0,$70,$40
  870. d25:    dc.b    $20,$E0,$70,$00
  871. d26:    dc.b    $20,$E0,$60,$00
  872. d27:    dc.b    $00,$E0,$60,$00
  873. d28:    dc.b    $00,$60,$60,$00
  874. d29:    dc.b    $00,$60,$20,$00
  875. d30:    dc.b    $00,$60,$00,$00
  876. d31:    dc.b    $00,$40,$00,$00
  877. d32:    dc.b    $00,$00,$00,$00
  878.  
  879.  
  880. getlum:
  881.  
  882. *  iN:
  883. *    d0    color        RED[10:08] GREEN[06:04] BLUE[02:00]
  884. * ouT:
  885. *    d2    luminance    BLACK:0000 WHITE:FFFF
  886.  
  887.  
  888.     moveq.l    #$0E,d3
  889.     move.w    d0,d1
  890.     lsl.w    #1,d1
  891.     and.w    d3,d1
  892.     move.w    b11(pc,d1.w),d2
  893.     move.w    d0,d1
  894.     lsr.w    #3,d1
  895.     and.w    d3,d1
  896.     add.w    g59(pc,d1.w),d2
  897.     lsr.w    #7,d0
  898.     and.w    d3,d0
  899.     add.w    r30(pc,d0.w),d2
  900.     bcc.s    .1
  901.  
  902.     subx.w    d2,d2        
  903.  
  904. .1:
  905.     rts
  906.  
  907.  
  908.  
  909. r30:    dc.w                        0
  910.     dc.w    (($10000/7)*(($10000*30)/100))/$10000
  911.     dc.w    (($20000/7)*(($10000*30)/100))/$10000
  912.     dc.w    (($30000/7)*(($10000*30)/100))/$10000
  913.     dc.w    (($40000/7)*(($10000*30)/100))/$10000
  914.     dc.w    (($50000/7)*(($10000*30)/100))/$10000
  915.     dc.w    (($60000/7)*(($10000*30)/100))/$10000
  916.     dc.w                  ($10000*30)/100
  917.  
  918.  
  919. g59:    dc.w                        0
  920.     dc.w    (($10000/7)*(($10000*59)/100))/$10000
  921.     dc.w    (($20000/7)*(($10000*59)/100))/$10000
  922.     dc.w    (($30000/7)*(($10000*59)/100))/$10000
  923.     dc.w    (($40000/7)*(($10000*59)/100))/$10000
  924.     dc.w    (($50000/7)*(($10000*59)/100))/$10000
  925.     dc.w    (($60000/7)*(($10000*59)/100))/$10000
  926.     dc.w                  ($10000*59)/100
  927.  
  928.  
  929. b11:    dc.w                        0
  930.     dc.w    (($10000/7)*(($10000*11)/100))/$10000
  931.     dc.w    (($20000/7)*(($10000*11)/100))/$10000
  932.     dc.w    (($30000/7)*(($10000*11)/100))/$10000
  933.     dc.w    (($40000/7)*(($10000*11)/100))/$10000
  934.     dc.w    (($50000/7)*(($10000*11)/100))/$10000
  935.     dc.w    (($60000/7)*(($10000*11)/100))/$10000
  936.     dc.w                  ($10000*11)/100
  937.  
  938.  
  939.         .bss
  940.  
  941. *    Halftone Dither Table Buffer
  942.  
  943. halfbuf:    ds.b    256
  944.  
  945.  
  946. *    Parameter Block Structure
  947.  
  948.         .abs
  949.  
  950. SRC_BASE:    ds.l    1
  951. SRC_NXLN:    ds.w    1
  952. SRC_XMIN:    ds.w    1
  953. SRC_YMIN:    ds.w    1
  954. SRC_WD:        ds.w    1
  955. SRC_HT:        ds.w    1
  956. DST_BASE:    ds.l    1
  957. DST_NXLN:    ds.w    1
  958. DST_XMIN:    ds.w    1
  959. DST_YMIN:    ds.w    1
  960. DST_WD:        ds.w    1
  961. DST_HT:        ds.w    1
  962.  
  963.  
  964.