home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 514b.lha / line+fill / fill1 next >
Text File  |  1991-06-08  |  42KB  |  1,832 lines

  1. /* fill.c, a processor polygon filler */
  2. /* Copyright (c) 1990 John Schultz, All Rights Reserved */
  3.  
  4. /* This is the C interface to the assembly code that does most of the   */
  5. /* work. I haven't seen an algorithm of this type for filling polygons  */
  6. /* elsewhere, so I'd like to think my implementation of this table fill */
  7. /* algorithm is unique :-).The algorithm works by first finding out the */
  8. /* orientation of the polygon, then filling the tables from miny to    */
  9. /* maxy. This allows the table to be updated unconditionally, without */
  10. /* having to read the current values from the tables, compare, then  */
  11. /* write back to memory.                                            */
  12. /* The polygons are an array of drawpoints, and you don't need to  */
  13. /* close the polygons: a triangle will only have three points.    */
  14.  
  15. /* This code has been optimized for 320x200x4 bitmaps, which have */
  16. /* been allocated linearly (One 32,000 byte allocation as opposed */
  17. /* to four 8,000 byte allocations).                               */ 
  18.  
  19. /* To compile this code use: 
  20. /*   lc -O -cuf -v fill.c                                         */
  21. /*   asm scanconvert.a                                            */
  22. /* Link to your own code as appropriate.                          */
  23.  
  24. /* I am using Lattice 5.04, and get a CXERR: 26, Line: 0, if the  */
  25. /* optimizer is not used!                                         */
  26.  
  27. /* Look ma, no includes. */
  28.  
  29. typedef struct drawpoint {short dx,dy;} drawpoint;
  30.  
  31. #define MAXY 201                /* Bitmap max y + 1 */
  32.  
  33. short xmin[MAXY], xmax[MAXY]; /* Scanconverter tables */
  34.  
  35. short * xtable[] = {xmin,xmax}; /* For toggling between fill tables */
  36.  
  37. /* Prototypes */
  38.  
  39. extern void __asm drawline68k(register __a1 char * p, /* 1st Plane Ptr */
  40.                               register __d0 short x,
  41.                               register __d1 short y,
  42.                               register __d2 short x2,
  43.                               register __d3 short y2,
  44.                               register __d4 short color);
  45.  
  46. extern void __asm fillline68k(register __d0 short x,
  47.                               register __d1 short y,
  48.                               register __d2 short x2,
  49.                               register __d3 short y2,
  50.                               register __a0 short * table);
  51.  
  52. extern void __asm scanconvpix(register __a0 char * p, /* 1st Plane Ptr */
  53.                               register __a1 short * minx,
  54.                               register __a2 short * maxx,
  55.                               register __d0 short miny,
  56.                               register __d1 short maxy,
  57.                               register __d2 short color);
  58.  
  59. void drawpoly(drawpoint * dl, /* An array of drawpoints */
  60.               char * p,      /* 1st Plane Ptr          */
  61.               short cl,     /* Number of points       */
  62.               short color);
  63.  
  64. /* Code */
  65.  
  66. void drawpoly(drawpoint * dl, /* An array of drawpoints */
  67.               char * p,      /* 1st Plane Ptr          */
  68.               short cl,     /* Number of points       */
  69.               short color){
  70. short miny,maxy;
  71. short i,inext,index;
  72. short tminy,tmaxy;
  73. short j;
  74. long orient=0;
  75.  
  76. /* Find out if polygon is clockwise or counterclockwise */
  77.  
  78.   for (i=0; i < cl; i++) {        /* Use the Newell method */
  79.     if (i == (cl-1)) {
  80.       j = 0;
  81.     } else {
  82.       j = i+1;
  83.     }
  84.     orient += (dl[i].dx - dl[j].dx)*(dl[i].dy + dl[j].dy);
  85.   } /* for i */ 
  86.  
  87.   if (orient != 0) {    /* Check to see if we have a line or polygon */
  88.     index = (orient < 0) ? 0 : 1;
  89.  
  90. /* Find miny,maxy */
  91.     tminy = 199;
  92.     tmaxy = 0;
  93.     for (i=0; i < cl; i++) {
  94.       if (dl[i].dy < tminy) {miny = i; tminy = dl[i].dy;}
  95.       if (dl[i].dy > tmaxy) {maxy = i; tmaxy = dl[i].dy;}
  96.     } /* for i */
  97.  
  98. /* Fill tables */
  99.     i = miny; /* Start at top, fill to bottom, filling lines from top */
  100.     do {     /* to bottom for efficient assembly implementation.     */
  101.       inext = i + 1;
  102.       if (inext >= cl) inext = 0; /* Wrap around */
  103.       fillline68k(dl[i].dx,dl[i].dy,dl[inext].dx,dl[inext].dy,xtable[index]);
  104.       if (inext == maxy) index ^= 1; /* Toggle min/max to keep lines    */
  105.       i++;                          /* being filled from top to bottom */
  106.       if (i >= cl) i = 0; /* Wrap around */
  107.     } while (inext != miny); /* Come full circle, done */
  108.  
  109. /* Draw polygon */
  110.    scanconvpix(p,xmin,xmax,tminy,tmaxy,color);
  111.  
  112.   } else { /* Draw a line */
  113.  
  114. /* This test really only works for triangles */
  115.     if ((dl[0].dx == dl[1].dx) && (dl[0].dy == dl[1].dy))
  116.       drawline68k(p,dl[0].dx,dl[0].dy,dl[1].dx,dl[1].dy,color);
  117.     else
  118.       drawline68k(p,dl[0].dx,dl[0].dy,dl[2].dx,dl[2].dy,color);
  119.  
  120.   } /* if orient */
  121.  
  122. } /* end drawpoly */
  123.  
  124. /* end fill.c */
  125.     ------------------------------ 8< ------------------------------
  126. ; scanconvert.a
  127. ; Copyright (c) 1990 John Schultz, All Rights Reserved
  128.  
  129. ; Created 14-March-90
  130. ; Modified 17-May-90 
  131. ;   Re-written with long word aligned writes: now up to twice as fast
  132. ;   as using bfset/bfclr (bitfield instructions can hit up to 5 bytes,
  133. ;   not long word aligned).
  134. ;   Code is now 68000 compatible.
  135. ; Modified 8-June-90
  136. ;   Included filline68k, drawline68k in this file for Fill example.
  137. ;   Assembles to 3840 bytes using the Devpac 2.0 assembler.
  138.  
  139.     section    scanconvert,code
  140.  
  141.     xdef    _scanconvpix
  142.     xdef    _fillline68k
  143.     xdef    _drawline68k
  144.  
  145. ; This code has been optimized for 320x200x4 bitmaps, which have
  146. ; been allocated linearly (One 32,000 byte allocation as opposed
  147. ; to four 8,000 byte allocations). 
  148.  
  149.  
  150.  
  151. PLANESIZE    equ    8000    ; 320x200 bitplanes
  152. BYTESROW    equ    40    ; "               "
  153.  
  154. ;extern void __asm scanconvpix(register __a0 PLANEPTR p,
  155. ;                              register __a1 short * minx,
  156. ;                              register __a2 short * maxx,
  157. ;                              register __d0 short miny,
  158. ;                              register __d1 short maxy,
  159. ;                              register __d2 short color);
  160.  
  161. _scanconvpix:
  162.     movem.l    d2-d7/a2-a5,-(sp)
  163.  
  164.     move.w    d1,d7    ; get maxy. d0 = miny.
  165.     sub.w    d0,d7    ; compute yheight. +1 not necessary: using dbra.
  166.  
  167.     movea.l    a1,a4    ; copy xminptr
  168.     movea.l    a2,a5    ; copy xmaxptr
  169.  
  170.     move.w    d0,d6    ; copy miny
  171.     add.w    d6,d6    ; y index is 2 bytes, so *2 offset
  172.     adda.w    d6,a4    ; get to start postion minx
  173.     adda.w    d6,a5    ; get to start postion maxx
  174.  
  175.     move.w    d0,d6    ; copy miny
  176.     lsl.w    #3,d6    ; *8
  177.     lsl.w    #5,d0    ; *32
  178.     add.w    d6,d0    ; *40
  179.  
  180.     adda.w    d0,a0    ; go to first scanline in bitmap
  181.     move.l    a0,d6    ; setup for first pass (d6 += 40 each pass)
  182.  
  183.     moveq.l    #BYTESROW,d5    ; bytes per row, to be added each scanline
  184.  
  185.     lea    colorplanes(pc),a2    ; get colorplane table
  186.     add.w    d2,d2
  187.     add.w    d2,d2            ; entries are 4 bytes long
  188.     movea.l    0(a2,d2.w),a2        ; get color jsr address
  189.  
  190.     jmp    (a2)            ; do specific plane writes/clears
  191.  
  192. ; end of scanconvpix
  193.  
  194. ; Specific fill cases for 0-15 colors. Speed is of the essence, not
  195. ; code size :-). Each case is specifically optimized. Could be made
  196. ; shorter, but slower.
  197.  
  198. COLOR0    macro
  199.  
  200. color0:
  201.  
  202. scanloop4\@
  203.     move.w    (a4)+,d0    ; get minx
  204.     move.w    (a5)+,d1    ; get maxx
  205.  
  206.     cmp.w    d0,d1        ; error check
  207.     bmi.b    finished4\@
  208.  
  209.     move.w    d0,d4        ; copy minx
  210.     lsr.w    #5,d4        ; get first long word
  211.     lsl.w    #2,d4        ; *4 = number of bytes
  212.     adda.w    d4,a0        ; add x offset to scanline
  213.  
  214.     lea    PLANESIZE(a0),a1
  215.     lea    PLANESIZE(a1),a2
  216.     lea    PLANESIZE(a2),a3
  217.  
  218.     move.w    d0,d4        ; copy minx
  219.     moveq.l    #-1,d2        ; start mask, $ffffffff
  220.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  221.     lsr.l    d4,d2        ; shift mask by d4 pixels
  222.  
  223.     move.w    d1,d4        ; copy maxx
  224.     moveq.l    #-1,d3        ; start mask, $ffffffff
  225.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  226.     neg.w    d4        ; - d4
  227.     add.w    #31,d4        ; d4 = 31 - d4
  228.     lsl.l    d4,d3        ; shift mask by d4 pixels
  229.  
  230.     lsr.w    #5,d0        ; get start long word
  231.     lsr.w    #5,d1        ; get end   long word
  232.     sub.w    d0,d1        ; get width in long words
  233.     bne.b    doublewrite4\@    ; check for single write
  234. ; single write
  235.     and.l    d2,d3        ; combine left and right masks
  236.     not.l    d3        ; invert
  237.     and.l    d3,(a0)        ; clear
  238.     and.l    d3,(a1)        ; clear
  239.     and.l    d3,(a2)        ; clear
  240.     and.l    d3,(a3)        ; clear
  241.     bra.b    finished4\@
  242. doublewrite4\@
  243.     not.l    d2        ; invert
  244.     and.l    d2,(a0)+    ; write left mask
  245.     and.l    d2,(a1)+    ; write left mask
  246.     and.l    d2,(a2)+    ; write left mask
  247.     and.l    d2,(a3)+    ; write left mask
  248.     subq.w    #2,d1        ; subtract left and right writes
  249.     bmi.b    writeright4\@    ; don't do a multiwrite
  250. ; multiwrite
  251.     moveq.l    #0,d2        ; zereos
  252. multiloop4\@
  253.     move.l    d2,(a0)+    ; write middle 0's
  254.     move.l    d2,(a1)+    ; write middle 0's
  255.     move.l    d2,(a2)+    ; write middle 0's
  256.     move.l    d2,(a3)+    ; write middle 0's
  257.     dbra    d1,multiloop4\@
  258. writeright4\@
  259.     not.l    d3
  260.     and.l    d3,(a0)        ; write right mask
  261.     and.l    d3,(a1)        ; write right mask
  262.     and.l    d3,(a2)        ; write right mask
  263.     and.l    d3,(a3)        ; write right mask
  264. finished4\@
  265.     add.l    d5,d6        ; go to next scanline
  266.     movea.l    d6,a0        ; copy ptr to modify
  267.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  268.  
  269.     movem.l    (sp)+,d2-d7/a2-a5
  270.     rts
  271.  
  272.     endm
  273.  
  274. COLOR1    macro
  275.  
  276. color1:
  277.  
  278. scanloop4\@
  279.     move.w    (a4)+,d0    ; get minx
  280.     move.w    (a5)+,d1    ; get maxx
  281.  
  282.     cmp.w    d0,d1        ; error check
  283.     bmi.b    finished4\@
  284.  
  285.     move.w    d0,d4        ; copy minx
  286.     lsr.w    #5,d4        ; get first long word
  287.     lsl.w    #2,d4        ; *4 = number of bytes
  288.     adda.w    d4,a0        ; add x offset to scanline
  289.  
  290.     lea    PLANESIZE(a0),a1
  291.     lea    PLANESIZE(a1),a2
  292.     lea    PLANESIZE(a2),a3
  293.  
  294.     move.w    d0,d4        ; copy minx
  295.     moveq.l    #-1,d2        ; start mask, $ffffffff
  296.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  297.     lsr.l    d4,d2        ; shift mask by d4 pixels
  298.  
  299.     move.w    d1,d4        ; copy maxx
  300.     moveq.l    #-1,d3        ; start mask, $ffffffff
  301.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  302.     neg.w    d4        ; - d4
  303.     add.w    #31,d4        ; d4 = 31 - d4
  304.     lsl.l    d4,d3        ; shift mask by d4 pixels
  305.  
  306.     lsr.w    #5,d0        ; get start long word
  307.     lsr.w    #5,d1        ; get end   long word
  308.     sub.w    d0,d1        ; get width in long words
  309.     bne.b    doublewrite4\@    ; check for single write
  310. ; single write
  311.     and.l    d2,d3        ; combine left and right masks
  312.     or.l    d3,(a0)        ; set
  313.     not.l    d3        ; invert
  314.     and.l    d3,(a1)        ; clear
  315.     and.l    d3,(a2)        ; clear
  316.     and.l    d3,(a3)        ; clear
  317.     not.l    d3
  318.     bra.b    finished4\@
  319. doublewrite4\@
  320.     or.l    d2,(a0)+    ; set
  321.     not.l    d2
  322.     and.l    d2,(a1)+    ; clear
  323.     and.l    d2,(a2)+    ; clear
  324.     and.l    d2,(a3)+    ; clear
  325.     subq.w    #2,d1        ; subtract left and right writes
  326.     bmi.b    writeright4\@    ; don't do a multiwrite
  327. ; multiwrite\@
  328.     moveq.l    #-1,d2        ; $ffffffff
  329.     moveq.l    #0,d4        ; zeroes
  330. multiloop4\@
  331.     move.l    d2,(a0)+    ; set
  332.     move.l    d4,(a1)+    ; clear
  333.     move.l    d4,(a2)+    ; clear
  334.     move.l    d4,(a3)+    ; clear
  335.     dbra    d1,multiloop4\@
  336. writeright4\@
  337.     or.l    d3,(a0)        ; set
  338.     not.l    d3
  339.     and.l    d3,(a1)        ; clear
  340.     and.l    d3,(a2)        ; clear
  341.     and.l    d3,(a3)        ; clear
  342. finished4\@
  343.     add.l    d5,d6        ; go to next scanline
  344.     movea.l    d6,a0        ; copy ptr to modify
  345.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  346.  
  347.     movem.l    (sp)+,d2-d7/a2-a5
  348.     rts
  349.  
  350.     endm
  351.  
  352. COLOR2    macro
  353.  
  354. color2:
  355.  
  356. scanloop4\@
  357.     move.w    (a4)+,d0    ; get minx
  358.     move.w    (a5)+,d1    ; get maxx
  359.  
  360.     cmp.w    d0,d1        ; error check
  361.     bmi.b    finished4\@
  362.  
  363.     move.w    d0,d4        ; copy minx
  364.     lsr.w    #5,d4        ; get first long word
  365.     lsl.w    #2,d4        ; *4 = number of bytes
  366.     adda.w    d4,a0        ; add x offset to scanline
  367.  
  368.     lea    PLANESIZE(a0),a1
  369.     lea    PLANESIZE(a1),a2
  370.     lea    PLANESIZE(a2),a3
  371.  
  372.     move.w    d0,d4        ; copy minx
  373.     moveq.l    #-1,d2        ; start mask, $ffffffff
  374.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  375.     lsr.l    d4,d2        ; shift mask by d4 pixels
  376.  
  377.     move.w    d1,d4        ; copy maxx
  378.     moveq.l    #-1,d3        ; start mask, $ffffffff
  379.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  380.     neg.w    d4        ; - d4
  381.     add.w    #31,d4        ; d4 = 31 - d4
  382.     lsl.l    d4,d3        ; shift mask by d4 pixels
  383.  
  384.     lsr.w    #5,d0        ; get start long word
  385.     lsr.w    #5,d1        ; get end   long word
  386.     sub.w    d0,d1        ; get width in long words
  387.     bne.b    doublewrite4\@    ; check for single write
  388. ; single write
  389.     and.l    d2,d3        ; combine left and right masks
  390.     or.l    d3,(a1)        ; set
  391.     not.l    d3        ; invert
  392.     and.l    d3,(a0)        ; clear
  393.     and.l    d3,(a2)        ; clear
  394.     and.l    d3,(a3)        ; clear
  395.     bra.b    finished4\@
  396. doublewrite4\@
  397.     or.l    d2,(a1)+    ; set
  398.     not.l    d2
  399.     and.l    d2,(a0)+    ; clear
  400.     and.l    d2,(a2)+    ; clear
  401.     and.l    d2,(a3)+    ; clear
  402.     subq.w    #2,d1        ; subtract left and right writes
  403.     bmi.b    writeright4\@    ; don't do a multiwrite
  404. ; multiwrite\@
  405.     moveq.l    #-1,d2        ; $ffffffff
  406.     moveq.l    #0,d4        ; zeroes
  407. multiloop4\@
  408.     move.l    d2,(a1)+    ; set
  409.     move.l    d4,(a0)+    ; clear
  410.     move.l    d4,(a2)+    ; clear
  411.     move.l    d4,(a3)+    ; clear
  412.     dbra    d1,multiloop4\@
  413. writeright4\@
  414.     or.l    d3,(a1)        ; set
  415.     not.l    d3        ; invert
  416.     and.l    d3,(a0)        ; clear
  417.     and.l    d3,(a2)        ; clear
  418.     and.l    d3,(a3)        ; clear
  419. finished4\@
  420.     add.l    d5,d6        ; go to next scanline
  421.     movea.l    d6,a0        ; copy ptr to modify
  422.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  423.  
  424.     movem.l    (sp)+,d2-d7/a2-a5
  425.     rts
  426.  
  427.     endm
  428.  
  429. COLOR3    macro
  430.  
  431. color3:
  432.  
  433. scanloop4\@
  434.     move.w    (a4)+,d0    ; get minx
  435.     move.w    (a5)+,d1    ; get maxx
  436.  
  437.     cmp.w    d0,d1        ; error check
  438.     bmi.b    finished4\@
  439.  
  440.     move.w    d0,d4        ; copy minx
  441.     lsr.w    #5,d4        ; get first long word
  442.     lsl.w    #2,d4        ; *4 = number of bytes
  443.     adda.w    d4,a0        ; add x offset to scanline
  444.  
  445.     lea    PLANESIZE(a0),a1
  446.     lea    PLANESIZE(a1),a2
  447.     lea    PLANESIZE(a2),a3
  448.  
  449.     move.w    d0,d4        ; copy minx
  450.     moveq.l    #-1,d2        ; start mask, $ffffffff
  451.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  452.     lsr.l    d4,d2        ; shift mask by d4 pixels
  453.  
  454.     move.w    d1,d4        ; copy maxx
  455.     moveq.l    #-1,d3        ; start mask, $ffffffff
  456.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  457.     neg.w    d4        ; - d4
  458.     add.w    #31,d4        ; d4 = 31 - d4
  459.     lsl.l    d4,d3        ; shift mask by d4 pixels
  460.  
  461.     lsr.w    #5,d0        ; get start long word
  462.     lsr.w    #5,d1        ; get end   long word
  463.     sub.w    d0,d1        ; get width in long words
  464.     bne.b    doublewrite4\@    ; check for single write
  465. ; single write
  466.     and.l    d2,d3        ; combine left and right masks
  467.     or.l    d3,(a0)        ; set
  468.     or.l    d3,(a1)        ; set
  469.     not.l    d3        ; invert
  470.     and.l    d3,(a2)        ; clear
  471.     and.l    d3,(a3)        ; clear
  472.     bra.b    finished4\@
  473. doublewrite4\@
  474.     or.l    d2,(a0)+    ; set
  475.     or.l    d2,(a1)+    ; set
  476.     not.l    d2
  477.     and.l    d2,(a2)+    ; clear
  478.     and.l    d2,(a3)+    ; clear
  479.     subq.w    #2,d1        ; subtract left and right writes
  480.     bmi.b    writeright4\@    ; don't do a multiwrite
  481. ; multiwrite\@
  482.     moveq.l    #-1,d2        ; $ffffffff
  483.     moveq.l    #0,d4        ; zeroes
  484. multiloop4\@
  485.     move.l    d2,(a0)+    ; set
  486.     move.l    d2,(a1)+    ; set
  487.     move.l    d4,(a2)+    ; clear
  488.     move.l    d4,(a3)+    ; clear
  489.     dbra    d1,multiloop4\@
  490. writeright4\@
  491.     or.l    d3,(a0)        ; set
  492.     or.l    d3,(a1)        ; set
  493.     not.l    d3
  494.     and.l    d3,(a2)        ; clear
  495.     and.l    d3,(a3)        ; clear
  496. finished4\@
  497.     add.l    d5,d6        ; go to next scanline
  498.     movea.l    d6,a0        ; copy ptr to modify
  499.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  500.  
  501.     movem.l    (sp)+,d2-d7/a2-a5
  502.     rts
  503.  
  504.     endm
  505.  
  506. COLOR4    macro
  507.  
  508. color4:
  509.  
  510. scanloop4\@
  511.     move.w    (a4)+,d0    ; get minx
  512.     move.w    (a5)+,d1    ; get maxx
  513.  
  514.     cmp.w    d0,d1        ; error check
  515.     bmi.b    finished4\@
  516.  
  517.     move.w    d0,d4        ; copy minx
  518.     lsr.w    #5,d4        ; get first long word
  519.     lsl.w    #2,d4        ; *4 = number of bytes
  520.     adda.w    d4,a0        ; add x offset to scanline
  521.  
  522.     lea    PLANESIZE(a0),a1
  523.     lea    PLANESIZE(a1),a2
  524.     lea    PLANESIZE(a2),a3
  525.  
  526.     move.w    d0,d4        ; copy minx
  527.     moveq.l    #-1,d2        ; start mask, $ffffffff
  528.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  529.     lsr.l    d4,d2        ; shift mask by d4 pixels
  530.  
  531.     move.w    d1,d4        ; copy maxx
  532.     moveq.l    #-1,d3        ; start mask, $ffffffff
  533.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  534.     neg.w    d4        ; - d4
  535.     add.w    #31,d4        ; d4 = 31 - d4
  536.     lsl.l    d4,d3        ; shift mask by d4 pixels
  537.  
  538.     lsr.w    #5,d0        ; get start long word
  539.     lsr.w    #5,d1        ; get end   long word
  540.     sub.w    d0,d1        ; get width in long words
  541.     bne.b    doublewrite4\@    ; check for single write
  542. ; single write
  543.     and.l    d2,d3        ; combine left and right masks
  544.     or.l    d3,(a2)        ; set
  545.     not.l    d3        ; invert
  546.     and.l    d3,(a0)        ; clear
  547.     and.l    d3,(a1)        ; clear
  548.     and.l    d3,(a3)        ; clear
  549.     bra.b    finished4\@
  550. doublewrite4\@
  551.     or.l    d2,(a2)+    ; set
  552.     not.l    d2
  553.     and.l    d2,(a0)+    ; clear
  554.     and.l    d2,(a1)+    ; clear
  555.     and.l    d2,(a3)+    ; clear
  556.     subq.w    #2,d1        ; subtract left and right writes
  557.     bmi.b    writeright4\@    ; don't do a multiwrite
  558. ; multiwrite\@
  559.     moveq.l    #-1,d2        ; $ffffffff
  560.     moveq.l    #0,d4        ; zeroes
  561. multiloop4\@
  562.     move.l    d2,(a2)+    ; set
  563.     move.l    d4,(a0)+    ; clear
  564.     move.l    d4,(a1)+    ; clear
  565.     move.l    d4,(a3)+    ; clear
  566.     dbra    d1,multiloop4\@
  567. writeright4\@
  568.     or.l    d3,(a2)        ; set
  569.     not.l    d3        ; invert
  570.     and.l    d3,(a0)        ; clear
  571.     and.l    d3,(a1)        ; clear
  572.     and.l    d3,(a3)        ; clear
  573. finished4\@
  574.     add.l    d5,d6        ; go to next scanline
  575.     movea.l    d6,a0        ; copy ptr to modify
  576.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  577.  
  578.     movem.l    (sp)+,d2-d7/a2-a5
  579.     rts
  580.  
  581.     endm
  582.  
  583. COLOR5    macro
  584.  
  585. color5:
  586.  
  587. scanloop4\@
  588.     move.w    (a4)+,d0    ; get minx
  589.     move.w    (a5)+,d1    ; get maxx
  590.  
  591.     cmp.w    d0,d1        ; error check
  592.     bmi.b    finished4\@
  593.  
  594.     move.w    d0,d4        ; copy minx
  595.     lsr.w    #5,d4        ; get first long word
  596.     lsl.w    #2,d4        ; *4 = number of bytes
  597.     adda.w    d4,a0        ; add x offset to scanline
  598.  
  599.     lea    PLANESIZE(a0),a1
  600.     lea    PLANESIZE(a1),a2
  601.     lea    PLANESIZE(a2),a3
  602.  
  603.     move.w    d0,d4        ; copy minx
  604.     moveq.l    #-1,d2        ; start mask, $ffffffff
  605.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  606.     lsr.l    d4,d2        ; shift mask by d4 pixels
  607.  
  608.     move.w    d1,d4        ; copy maxx
  609.     moveq.l    #-1,d3        ; start mask, $ffffffff
  610.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  611.     neg.w    d4        ; - d4
  612.     add.w    #31,d4        ; d4 = 31 - d4
  613.     lsl.l    d4,d3        ; shift mask by d4 pixels
  614.  
  615.     lsr.w    #5,d0        ; get start long word
  616.     lsr.w    #5,d1        ; get end   long word
  617.     sub.w    d0,d1        ; get width in long words
  618.     bne.b    doublewrite4\@    ; check for single write
  619. ; single write
  620.     and.l    d2,d3        ; combine left and right masks
  621.     or.l    d3,(a0)        ; set
  622.     or.l    d3,(a2)        ; set
  623.     not.l    d3        ; invert
  624.     and.l    d3,(a1)        ; clear
  625.     and.l    d3,(a3)        ; clear
  626.     bra.b    finished4\@
  627. doublewrite4\@
  628.     or.l    d2,(a0)+    ; set
  629.     or.l    d2,(a2)+    ; set
  630.     not.l    d2
  631.     and.l    d2,(a1)+    ; clear
  632.     and.l    d2,(a3)+    ; clear
  633.     subq.w    #2,d1        ; subtract left and right writes
  634.     bmi.b    writeright4\@    ; don't do a multiwrite
  635. ; multiwrite\@
  636.     moveq.l    #-1,d2        ; $ffffffff
  637.     moveq.l    #0,d4        ; zeroes
  638. multiloop4\@
  639.     move.l    d2,(a0)+    ; set
  640.     move.l    d2,(a2)+    ; set
  641.     move.l    d4,(a1)+    ; clear
  642.     move.l    d4,(a3)+    ; clear
  643.     dbra    d1,multiloop4\@
  644. writeright4\@
  645.     or.l    d3,(a0)        ; set
  646.     or.l    d3,(a2)        ; set
  647.     not.l    d3        ; invert
  648.     and.l    d3,(a1)        ; clear
  649.     and.l    d3,(a3)        ; clear
  650. finished4\@
  651.     add.l    d5,d6        ; go to next scanline
  652.     movea.l    d6,a0        ; copy ptr to modify
  653.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  654.  
  655.     movem.l    (sp)+,d2-d7/a2-a5
  656.     rts
  657.  
  658.     endm
  659.  
  660. COLOR6    macro
  661.  
  662. color6:
  663.  
  664. scanloop4\@
  665.     move.w    (a4)+,d0    ; get minx
  666.     move.w    (a5)+,d1    ; get maxx
  667.  
  668.     cmp.w    d0,d1        ; error check
  669.     bmi.b    finished4\@
  670.  
  671.     move.w    d0,d4        ; copy minx
  672.     lsr.w    #5,d4        ; get first long word
  673.     lsl.w    #2,d4        ; *4 = number of bytes
  674.     adda.w    d4,a0        ; add x offset to scanline
  675.  
  676.     lea    PLANESIZE(a0),a1
  677.     lea    PLANESIZE(a1),a2
  678.     lea    PLANESIZE(a2),a3
  679.  
  680.     move.w    d0,d4        ; copy minx
  681.     moveq.l    #-1,d2        ; start mask, $ffffffff
  682.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  683.     lsr.l    d4,d2        ; shift mask by d4 pixels
  684.  
  685.     move.w    d1,d4        ; copy maxx
  686.     moveq.l    #-1,d3        ; start mask, $ffffffff
  687.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  688.     neg.w    d4        ; - d4
  689.     add.w    #31,d4        ; d4 = 31 - d4
  690.     lsl.l    d4,d3        ; shift mask by d4 pixels
  691.  
  692.     lsr.w    #5,d0        ; get start long word
  693.     lsr.w    #5,d1        ; get end   long word
  694.     sub.w    d0,d1        ; get width in long words
  695.     bne.b    doublewrite4\@    ; check for single write
  696. ; single write
  697.     and.l    d2,d3        ; combine left and right masks
  698.     or.l    d3,(a1)        ; set
  699.     or.l    d3,(a2)        ; set
  700.     not.l    d3        ; invert
  701.     and.l    d3,(a0)        ; clear
  702.     and.l    d3,(a3)        ; clear
  703.     bra.b    finished4\@
  704. doublewrite4\@
  705.     or.l    d2,(a1)+    ; set
  706.     or.l    d2,(a2)+    ; set
  707.     not.l    d2
  708.     and.l    d2,(a0)+    ; clear
  709.     and.l    d2,(a3)+    ; clear
  710.     subq.w    #2,d1        ; subtract left and right writes
  711.     bmi.b    writeright4\@    ; don't do a multiwrite
  712. ; multiwrite\@
  713.     moveq.l    #-1,d2        ; $ffffffff
  714.     moveq.l    #0,d4        ; zeroes
  715. multiloop4\@
  716.     move.l    d2,(a1)+    ; set
  717.     move.l    d2,(a2)+    ; set
  718.     move.l    d4,(a0)+    ; clear
  719.     move.l    d4,(a3)+    ; clear
  720.     dbra    d1,multiloop4\@
  721. writeright4\@
  722.     or.l    d3,(a1)        ; set
  723.     or.l    d3,(a2)        ; set
  724.     not.l    d3        ; invert
  725.     and.l    d3,(a0)        ; clear
  726.     and.l    d3,(a3)        ; clear
  727. finished4\@
  728.     add.l    d5,d6        ; go to next scanline
  729.     movea.l    d6,a0        ; copy ptr to modify
  730.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  731.  
  732.     movem.l    (sp)+,d2-d7/a2-a5
  733.     rts
  734.  
  735.     endm
  736.  
  737. COLOR7    macro
  738.  
  739. color7:
  740.  
  741. scanloop4\@
  742.     move.w    (a4)+,d0    ; get minx
  743.     move.w    (a5)+,d1    ; get maxx
  744.  
  745.     cmp.w    d0,d1        ; error check
  746.     bmi.b    finished4\@
  747.  
  748.     move.w    d0,d4        ; copy minx
  749.     lsr.w    #5,d4        ; get first long word
  750.     lsl.w    #2,d4        ; *4 = number of bytes
  751.     adda.w    d4,a0        ; add x offset to scanline
  752.  
  753.     lea    PLANESIZE(a0),a1
  754.     lea    PLANESIZE(a1),a2
  755.     lea    PLANESIZE(a2),a3
  756.  
  757.     move.w    d0,d4        ; copy minx
  758.     moveq.l    #-1,d2        ; start mask, $ffffffff
  759.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  760.     lsr.l    d4,d2        ; shift mask by d4 pixels
  761.  
  762.     move.w    d1,d4        ; copy maxx
  763.     moveq.l    #-1,d3        ; start mask, $ffffffff
  764.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  765.     neg.w    d4        ; - d4
  766.     add.w    #31,d4        ; d4 = 31 - d4
  767.     lsl.l    d4,d3        ; shift mask by d4 pixels
  768.  
  769.     lsr.w    #5,d0        ; get start long word
  770.     lsr.w    #5,d1        ; get end   long word
  771.     sub.w    d0,d1        ; get width in long words
  772.     bne.b    doublewrite4\@    ; check for single write
  773. ; single write
  774.     and.l    d2,d3        ; combine left and right masks
  775.     or.l    d3,(a0)        ; set
  776.     or.l    d3,(a1)        ; set
  777.     or.l    d3,(a2)        ; set
  778.     not.l    d3        ; invert
  779.     and.l    d3,(a3)        ; clear
  780.     bra.b    finished4\@
  781. doublewrite4\@
  782.     or.l    d2,(a0)+    ; set
  783.     or.l    d2,(a1)+    ; set
  784.     or.l    d2,(a2)+    ; set
  785.     not.l    d2
  786.     and.l    d2,(a3)+    ; clear
  787.     subq.w    #2,d1        ; subtract left and right writes
  788.     bmi.b    writeright4\@    ; don't do a multiwrite
  789. ; multiwrite\@
  790.     moveq.l    #-1,d2        ; $ffffffff
  791.     moveq.l    #0,d4        ; zeroes
  792. multiloop4\@
  793.     move.l    d2,(a0)+    ; set
  794.     move.l    d2,(a1)+    ; set
  795.     move.l    d2,(a2)+    ; set
  796.     move.l    d4,(a3)+    ; clear
  797.     dbra    d1,multiloop4\@
  798. writeright4\@
  799.     or.l    d3,(a0)        ; set
  800.     or.l    d3,(a1)        ; set
  801.     or.l    d3,(a2)        ; set
  802.     not.l    d3        ; invert
  803.     and.l    d3,(a3)        ; clear
  804. finished4\@
  805.     add.l    d5,d6        ; go to next scanline
  806.     movea.l    d6,a0        ; copy ptr to modify
  807.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  808.  
  809.     movem.l    (sp)+,d2-d7/a2-a5
  810.     rts
  811.  
  812.     endm
  813.  
  814. COLOR8    macro
  815.  
  816. color8:
  817.  
  818. scanloop4\@
  819.     move.w    (a4)+,d0    ; get minx
  820.     move.w    (a5)+,d1    ; get maxx
  821.  
  822.     cmp.w    d0,d1        ; error check
  823.     bmi.b    finished4\@
  824.  
  825.     move.w    d0,d4        ; copy minx
  826.     lsr.w    #5,d4        ; get first long word
  827.     lsl.w    #2,d4        ; *4 = number of bytes
  828.     adda.w    d4,a0        ; add x offset to scanline
  829.  
  830.     lea    PLANESIZE(a0),a1
  831.     lea    PLANESIZE(a1),a2
  832.     lea    PLANESIZE(a2),a3
  833.  
  834.     move.w    d0,d4        ; copy minx
  835.     moveq.l    #-1,d2        ; start mask, $ffffffff
  836.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  837.     lsr.l    d4,d2        ; shift mask by d4 pixels
  838.  
  839.     move.w    d1,d4        ; copy maxx
  840.     moveq.l    #-1,d3        ; start mask, $ffffffff
  841.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  842.     neg.w    d4        ; - d4
  843.     add.w    #31,d4        ; d4 = 31 - d4
  844.     lsl.l    d4,d3        ; shift mask by d4 pixels
  845.  
  846.     lsr.w    #5,d0        ; get start long word
  847.     lsr.w    #5,d1        ; get end   long word
  848.     sub.w    d0,d1        ; get width in long words
  849.     bne.b    doublewrite4\@    ; check for single write
  850. ; single write
  851.     and.l    d2,d3        ; combine left and right masks
  852.     or.l    d3,(a3)        ; set
  853.     not.l    d3        ; invert
  854.     and.l    d3,(a0)        ; clear
  855.     and.l    d3,(a1)        ; clear
  856.     and.l    d3,(a2)        ; clear
  857.     bra.b    finished4\@
  858. doublewrite4\@
  859.     or.l    d2,(a3)+    ; set
  860.     not.l    d2
  861.     and.l    d2,(a0)+    ; clear
  862.     and.l    d2,(a1)+    ; clear
  863.     and.l    d2,(a2)+    ; clear
  864.     subq.w    #2,d1        ; subtract left and right writes
  865.     bmi.b    writeright4\@    ; don't do a multiwrite
  866. ; multiwrite\@
  867.     moveq.l    #-1,d2        ; $ffffffff
  868.     moveq.l    #0,d4        ; zeroes
  869. multiloop4\@
  870.     move.l    d2,(a3)+    ; set
  871.     move.l    d4,(a0)+    ; clear
  872.     move.l    d4,(a1)+    ; clear
  873.     move.l    d4,(a2)+    ; clear
  874.     dbra    d1,multiloop4\@
  875. writeright4\@
  876.     or.l    d3,(a3)        ; set
  877.     not.l    d3        ; invert
  878.     and.l    d3,(a0)        ; clear
  879.     and.l    d3,(a1)        ; clear
  880.     and.l    d3,(a2)        ; clear
  881. finished4\@
  882.     add.l    d5,d6        ; go to next scanline
  883.     movea.l    d6,a0        ; copy ptr to modify
  884.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  885.  
  886.     movem.l    (sp)+,d2-d7/a2-a5
  887.     rts
  888.  
  889.     endm
  890.  
  891. COLOR9    macro
  892.  
  893. color9:
  894.  
  895. scanloop4\@
  896.     move.w    (a4)+,d0    ; get minx
  897.     move.w    (a5)+,d1    ; get maxx
  898.  
  899.     cmp.w    d0,d1        ; error check
  900.     bmi.b    finished4\@
  901.  
  902.     move.w    d0,d4        ; copy minx
  903.     lsr.w    #5,d4        ; get first long word
  904.     lsl.w    #2,d4        ; *4 = number of bytes
  905.     adda.w    d4,a0        ; add x offset to scanline
  906.  
  907.     lea    PLANESIZE(a0),a1
  908.     lea    PLANESIZE(a1),a2
  909.     lea    PLANESIZE(a2),a3
  910.  
  911.     move.w    d0,d4        ; copy minx
  912.     moveq.l    #-1,d2        ; start mask, $ffffffff
  913.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  914.     lsr.l    d4,d2        ; shift mask by d4 pixels
  915.  
  916.     move.w    d1,d4        ; copy maxx
  917.     moveq.l    #-1,d3        ; start mask, $ffffffff
  918.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  919.     neg.w    d4        ; - d4
  920.     add.w    #31,d4        ; d4 = 31 - d4
  921.     lsl.l    d4,d3        ; shift mask by d4 pixels
  922.  
  923.     lsr.w    #5,d0        ; get start long word
  924.     lsr.w    #5,d1        ; get end   long word
  925.     sub.w    d0,d1        ; get width in long words
  926.     bne.b    doublewrite4\@    ; check for single write
  927. ; single write
  928.     and.l    d2,d3        ; combine left and right masks
  929.     or.l    d3,(a0)        ; set
  930.     or.l    d3,(a3)        ; set
  931.     not.l    d3        ; invert
  932.     and.l    d3,(a1)        ; clear
  933.     and.l    d3,(a2)        ; clear
  934.     bra.b    finished4\@
  935. doublewrite4\@
  936.     or.l    d2,(a0)+    ; set
  937.     or.l    d2,(a3)+    ; set
  938.     not.l    d2
  939.     and.l    d2,(a1)+    ; clear
  940.     and.l    d2,(a2)+    ; clear
  941.     subq.w    #2,d1        ; subtract left and right writes
  942.     bmi.b    writeright4\@    ; don't do a multiwrite
  943. ; multiwrite\@
  944.     moveq.l    #-1,d2        ; $ffffffff
  945.     moveq.l    #0,d4        ; zeroes
  946. multiloop4\@
  947.     move.l    d2,(a0)+    ; set
  948.     move.l    d2,(a3)+    ; set
  949.     move.l    d4,(a1)+    ; clear
  950.     move.l    d4,(a2)+    ; clear
  951.     dbra    d1,multiloop4\@
  952. writeright4\@
  953.     or.l    d3,(a0)        ; set
  954.     or.l    d3,(a3)        ; set
  955.     not.l    d3        ; invert
  956.     and.l    d3,(a1)        ; clear
  957.     and.l    d3,(a2)        ; clear
  958. finished4\@
  959.     add.l    d5,d6        ; go to next scanline
  960.     movea.l    d6,a0        ; copy ptr to modify
  961.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  962.  
  963.     movem.l    (sp)+,d2-d7/a2-a5
  964.     rts
  965.  
  966.     endm
  967.  
  968. COLOR10    macro
  969.  
  970. color10:
  971.  
  972. scanloop4\@
  973.     move.w    (a4)+,d0    ; get minx
  974.     move.w    (a5)+,d1    ; get maxx
  975.  
  976.     cmp.w    d0,d1        ; error check
  977.     bmi.b    finished4\@
  978.  
  979.     move.w    d0,d4        ; copy minx
  980.     lsr.w    #5,d4        ; get first long word
  981.     lsl.w    #2,d4        ; *4 = number of bytes
  982.     adda.w    d4,a0        ; add x offset to scanline
  983.  
  984.     lea    PLANESIZE(a0),a1
  985.     lea    PLANESIZE(a1),a2
  986.     lea    PLANESIZE(a2),a3
  987.  
  988.     move.w    d0,d4        ; copy minx
  989.     moveq.l    #-1,d2        ; start mask, $ffffffff
  990.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  991.     lsr.l    d4,d2        ; shift mask by d4 pixels
  992.  
  993.     move.w    d1,d4        ; copy maxx
  994.     moveq.l    #-1,d3        ; start mask, $ffffffff
  995.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  996.     neg.w    d4        ; - d4
  997.     add.w    #31,d4        ; d4 = 31 - d4
  998.     lsl.l    d4,d3        ; shift mask by d4 pixels
  999.  
  1000.     lsr.w    #5,d0        ; get start long word
  1001.     lsr.w    #5,d1        ; get end   long word
  1002.     sub.w    d0,d1        ; get width in long words
  1003.     bne.b    doublewrite4\@    ; check for single write
  1004. ; single write
  1005.     and.l    d2,d3        ; combine left and right masks
  1006.     or.l    d3,(a1)        ; set
  1007.     or.l    d3,(a3)        ; set
  1008.     not.l    d3        ; invert
  1009.     and.l    d3,(a0)        ; clear
  1010.     and.l    d3,(a2)        ; clear
  1011.     bra.b    finished4\@
  1012. doublewrite4\@
  1013.     or.l    d2,(a1)+    ; set
  1014.     or.l    d2,(a3)+    ; set
  1015.     not.l    d2
  1016.     and.l    d2,(a0)+    ; clear
  1017.     and.l    d2,(a2)+    ; clear
  1018.     subq.w    #2,d1        ; subtract left and right writes
  1019.     bmi.b    writeright4\@    ; don't do a multiwrite
  1020. ; multiwrite\@
  1021.     moveq.l    #-1,d2        ; $ffffffff
  1022.     moveq.l    #0,d4        ; zeroes
  1023. multiloop4\@
  1024.     move.l    d2,(a1)+    ; set
  1025.     move.l    d2,(a3)+    ; set
  1026.     move.l    d4,(a0)+    ; clear
  1027.     move.l    d4,(a2)+    ; clear
  1028.     dbra    d1,multiloop4\@
  1029. writeright4\@
  1030.     or.l    d3,(a1)        ; set
  1031.     or.l    d3,(a3)        ; set
  1032.     not.l    d3        ; invert
  1033.     and.l    d3,(a0)        ; clear
  1034.     and.l    d3,(a2)        ; clear
  1035. finished4\@
  1036.     add.l    d5,d6        ; go to next scanline
  1037.     movea.l    d6,a0        ; copy ptr to modify
  1038.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  1039.  
  1040.     movem.l    (sp)+,d2-d7/a2-a5
  1041.     rts
  1042.  
  1043.     endm
  1044.  
  1045. COLOR11    macro
  1046.  
  1047. color11:
  1048.  
  1049. scanloop4\@
  1050.     move.w    (a4)+,d0    ; get minx
  1051.     move.w    (a5)+,d1    ; get maxx
  1052.  
  1053.     cmp.w    d0,d1        ; error check
  1054.     bmi.b    finished4\@
  1055.  
  1056.     move.w    d0,d4        ; copy minx
  1057.     lsr.w    #5,d4        ; get first long word
  1058.     lsl.w    #2,d4        ; *4 = number of bytes
  1059.     adda.w    d4,a0        ; add x offset to scanline
  1060.  
  1061.     lea    PLANESIZE(a0),a1
  1062.     lea    PLANESIZE(a1),a2
  1063.     lea    PLANESIZE(a2),a3
  1064.  
  1065.     move.w    d0,d4        ; copy minx
  1066.     moveq.l    #-1,d2        ; start mask, $ffffffff
  1067.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  1068.     lsr.l    d4,d2        ; shift mask by d4 pixels
  1069.  
  1070.     move.w    d1,d4        ; copy maxx
  1071.     moveq.l    #-1,d3        ; start mask, $ffffffff
  1072.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  1073.     neg.w    d4        ; - d4
  1074.     add.w    #31,d4        ; d4 = 31 - d4
  1075.     lsl.l    d4,d3        ; shift mask by d4 pixels
  1076.  
  1077.     lsr.w    #5,d0        ; get start long word
  1078.     lsr.w    #5,d1        ; get end   long word
  1079.     sub.w    d0,d1        ; get width in long words
  1080.     bne.b    doublewrite4\@    ; check for single write
  1081. ; single write
  1082.     and.l    d2,d3        ; combine left and right masks
  1083.     or.l    d3,(a0)        ; set
  1084.     or.l    d3,(a1)        ; set
  1085.     or.l    d3,(a3)        ; set
  1086.     not.l    d3        ; invert
  1087.     and.l    d3,(a2)        ; clear
  1088.     bra.b    finished4\@
  1089. doublewrite4\@
  1090.     or.l    d2,(a0)+    ; set
  1091.     or.l    d2,(a1)+    ; set
  1092.     or.l    d2,(a3)+    ; set
  1093.     not.l    d2
  1094.     and.l    d2,(a2)+    ; clear
  1095.     subq.w    #2,d1        ; subtract left and right writes
  1096.     bmi.b    writeright4\@    ; don't do a multiwrite
  1097. ; multiwrite\@
  1098.     moveq.l    #-1,d2        ; $ffffffff
  1099.     moveq.l    #0,d4        ; zeroes
  1100. multiloop4\@
  1101.     move.l    d2,(a0)+    ; set
  1102.     move.l    d2,(a1)+    ; set
  1103.     move.l    d2,(a3)+    ; set
  1104.     move.l    d4,(a2)+    ; clear
  1105.     dbra    d1,multiloop4\@
  1106. writeright4\@
  1107.     or.l    d3,(a0)        ; set
  1108.     or.l    d3,(a1)        ; set
  1109.     or.l    d3,(a3)        ; set
  1110.     not.l    d3        ; invert
  1111.     and.l    d3,(a2)        ; clear
  1112. finished4\@
  1113.     add.l    d5,d6        ; go to next scanline
  1114.     movea.l    d6,a0        ; copy ptr to modify
  1115.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  1116.  
  1117.     movem.l    (sp)+,d2-d7/a2-a5
  1118.     rts
  1119.  
  1120.     endm
  1121.  
  1122. COLOR12    macro
  1123.  
  1124. color12:
  1125.  
  1126. scanloop4\@
  1127.     move.w    (a4)+,d0    ; get minx
  1128.     move.w    (a5)+,d1    ; get maxx
  1129.  
  1130.     cmp.w    d0,d1        ; error check
  1131.     bmi.b    finished4\@
  1132.  
  1133.     move.w    d0,d4        ; copy minx
  1134.     lsr.w    #5,d4        ; get first long word
  1135.     lsl.w    #2,d4        ; *4 = number of bytes
  1136.     adda.w    d4,a0        ; add x offset to scanline
  1137.  
  1138.     lea    PLANESIZE(a0),a1
  1139.     lea    PLANESIZE(a1),a2
  1140.     lea    PLANESIZE(a2),a3
  1141.  
  1142.     move.w    d0,d4        ; copy minx
  1143.     moveq.l    #-1,d2        ; start mask, $ffffffff
  1144.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  1145.     lsr.l    d4,d2        ; shift mask by d4 pixels
  1146.  
  1147.     move.w    d1,d4        ; copy maxx
  1148.     moveq.l    #-1,d3        ; start mask, $ffffffff
  1149.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  1150.     neg.w    d4        ; - d4
  1151.     add.w    #31,d4        ; d4 = 31 - d4
  1152.     lsl.l    d4,d3        ; shift mask by d4 pixels
  1153.  
  1154.     lsr.w    #5,d0        ; get start long word
  1155.     lsr.w    #5,d1        ; get end   long word
  1156.     sub.w    d0,d1        ; get width in long words
  1157.     bne.b    doublewrite4\@    ; check for single write
  1158. ; single write
  1159.     and.l    d2,d3        ; combine left and right masks
  1160.     or.l    d3,(a2)        ; set
  1161.     or.l    d3,(a3)        ; set
  1162.     not.l    d3        ; invert
  1163.     and.l    d3,(a0)        ; clear
  1164.     and.l    d3,(a1)        ; clear
  1165.     bra.b    finished4\@
  1166. doublewrite4\@
  1167.     or.l    d2,(a2)+    ; set
  1168.     or.l    d2,(a3)+    ; set
  1169.     not.l    d2
  1170.     and.l    d2,(a0)+    ; clear
  1171.     and.l    d2,(a1)+    ; clear
  1172.     subq.w    #2,d1        ; subtract left and right writes
  1173.     bmi.b    writeright4\@    ; don't do a multiwrite
  1174. ; multiwrite\@
  1175.     moveq.l    #-1,d2        ; $ffffffff
  1176.     moveq.l    #0,d4        ; zeroes
  1177. multiloop4\@
  1178.     move.l    d2,(a2)+    ; set
  1179.     move.l    d2,(a3)+    ; set
  1180.     move.l    d4,(a0)+    ; clear
  1181.     move.l    d4,(a1)+    ; clear
  1182.     dbra    d1,multiloop4\@
  1183. writeright4\@
  1184.     or.l    d3,(a2)        ; set
  1185.     or.l    d3,(a3)        ; set
  1186.     not.l    d3        ; invert
  1187.     and.l    d3,(a0)        ; clear
  1188.     and.l    d3,(a1)        ; clear
  1189. finished4\@
  1190.     add.l    d5,d6        ; go to next scanline
  1191.     movea.l    d6,a0        ; copy ptr to modify
  1192.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  1193.  
  1194.     movem.l    (sp)+,d2-d7/a2-a5
  1195.     rts
  1196.  
  1197.     endm
  1198.  
  1199. COLOR13    macro
  1200.  
  1201. color13:
  1202.  
  1203. scanloop4\@
  1204.     move.w    (a4)+,d0    ; get minx
  1205.     move.w    (a5)+,d1    ; get maxx
  1206.  
  1207.     cmp.w    d0,d1        ; error check
  1208.     bmi.b    finished4\@
  1209.  
  1210.     move.w    d0,d4        ; copy minx
  1211.     lsr.w    #5,d4        ; get first long word
  1212.     lsl.w    #2,d4        ; *4 = number of bytes
  1213.     adda.w    d4,a0        ; add x offset to scanline
  1214.  
  1215.     lea    PLANESIZE(a0),a1
  1216.     lea    PLANESIZE(a1),a2
  1217.     lea    PLANESIZE(a2),a3
  1218.  
  1219.     move.w    d0,d4        ; copy minx
  1220.     moveq.l    #-1,d2        ; start mask, $ffffffff
  1221.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  1222.     lsr.l    d4,d2        ; shift mask by d4 pixels
  1223.  
  1224.     move.w    d1,d4        ; copy maxx
  1225.     moveq.l    #-1,d3        ; start mask, $ffffffff
  1226.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  1227.     neg.w    d4        ; - d4
  1228.     add.w    #31,d4        ; d4 = 31 - d4
  1229.     lsl.l    d4,d3        ; shift mask by d4 pixels
  1230.  
  1231.     lsr.w    #5,d0        ; get start long word
  1232.     lsr.w    #5,d1        ; get end   long word
  1233.     sub.w    d0,d1        ; get width in long words
  1234.     bne.b    doublewrite4\@    ; check for single write
  1235. ; single write
  1236.     and.l    d2,d3        ; combine left and right masks
  1237.     or.l    d3,(a0)        ; set
  1238.     or.l    d3,(a2)        ; set
  1239.     or.l    d3,(a3)        ; set
  1240.     not.l    d3        ; invert
  1241.     and.l    d3,(a1)        ; clear
  1242.     bra.b    finished4\@
  1243. doublewrite4\@
  1244.     or.l    d2,(a0)+    ; set
  1245.     or.l    d2,(a2)+    ; set
  1246.     or.l    d2,(a3)+    ; set
  1247.     not.l    d2
  1248.     and.l    d2,(a1)+    ; clear
  1249.     subq.w    #2,d1        ; subtract left and right writes
  1250.     bmi.b    writeright4\@    ; don't do a multiwrite
  1251. ; multiwrite\@
  1252.     moveq.l    #-1,d2        ; $ffffffff
  1253.     moveq.l    #0,d4        ; zeroes
  1254. multiloop4\@
  1255.     move.l    d2,(a0)+    ; set
  1256.     move.l    d2,(a2)+    ; set
  1257.     move.l    d2,(a3)+    ; set
  1258.     move.l    d4,(a1)+    ; clear
  1259.     dbra    d1,multiloop4\@
  1260. writeright4\@
  1261.     or.l    d3,(a0)        ; set
  1262.     or.l    d3,(a2)        ; set
  1263.     or.l    d3,(a3)        ; set
  1264.     not.l    d3        ; invert
  1265.     and.l    d3,(a1)        ; clear
  1266. finished4\@
  1267.     add.l    d5,d6        ; go to next scanline
  1268.     movea.l    d6,a0        ; copy ptr to modify
  1269.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  1270.  
  1271.     movem.l    (sp)+,d2-d7/a2-a5
  1272.     rts
  1273.  
  1274.     endm
  1275.  
  1276. COLOR14    macro
  1277.  
  1278. color14:
  1279.  
  1280. scanloop4\@
  1281.     move.w    (a4)+,d0    ; get minx
  1282.     move.w    (a5)+,d1    ; get maxx
  1283.  
  1284.     cmp.w    d0,d1        ; error check
  1285.     bmi.b    finished4\@
  1286.  
  1287.     move.w    d0,d4        ; copy minx
  1288.     lsr.w    #5,d4        ; get first long word
  1289.     lsl.w    #2,d4        ; *4 = number of bytes
  1290.     adda.w    d4,a0        ; add x offset to scanline
  1291.  
  1292.     lea    PLANESIZE(a0),a1
  1293.     lea    PLANESIZE(a1),a2
  1294.     lea    PLANESIZE(a2),a3
  1295.  
  1296.     move.w    d0,d4        ; copy minx
  1297.     moveq.l    #-1,d2        ; start mask, $ffffffff
  1298.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  1299.     lsr.l    d4,d2        ; shift mask by d4 pixels
  1300.  
  1301.     move.w    d1,d4        ; copy maxx
  1302.     moveq.l    #-1,d3        ; start mask, $ffffffff
  1303.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  1304.     neg.w    d4        ; - d4
  1305.     add.w    #31,d4        ; d4 = 31 - d4
  1306.     lsl.l    d4,d3        ; shift mask by d4 pixels
  1307.  
  1308.     lsr.w    #5,d0        ; get start long word
  1309.     lsr.w    #5,d1        ; get end   long word
  1310.     sub.w    d0,d1        ; get width in long words
  1311.     bne.b    doublewrite4\@    ; check for single write
  1312. ; single write
  1313.     and.l    d2,d3        ; combine left and right masks
  1314.     or.l    d3,(a1)        ; set
  1315.     or.l    d3,(a2)        ; set
  1316.     or.l    d3,(a3)        ; set
  1317.     not.l    d3        ; invert
  1318.     and.l    d3,(a0)        ; clear
  1319.     bra.b    finished4\@
  1320. doublewrite4\@
  1321.     or.l    d2,(a1)+    ; set
  1322.     or.l    d2,(a2)+    ; set
  1323.     or.l    d2,(a3)+    ; set
  1324.     not.l    d2
  1325.     and.l    d2,(a0)+    ; clear
  1326.     subq.w    #2,d1        ; subtract left and right writes
  1327.     bmi.b    writeright4\@    ; don't do a multiwrite
  1328. ; multiwrite\@
  1329.     moveq.l    #-1,d2        ; $ffffffff
  1330.     moveq.l    #0,d4        ; zeroes
  1331. multiloop4\@
  1332.     move.l    d2,(a1)+    ; set
  1333.     move.l    d2,(a2)+    ; set
  1334.     move.l    d2,(a3)+    ; set
  1335.     move.l    d4,(a0)+    ; clear
  1336.     dbra    d1,multiloop4\@
  1337. writeright4\@
  1338.     or.l    d3,(a1)        ; set
  1339.     or.l    d3,(a2)        ; set
  1340.     or.l    d3,(a3)        ; set
  1341.     not.l    d3        ; invert
  1342.     and.l    d3,(a0)        ; clear
  1343. finished4\@
  1344.     add.l    d5,d6        ; go to next scanline
  1345.     movea.l    d6,a0        ; copy ptr to modify
  1346.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  1347.  
  1348.     movem.l    (sp)+,d2-d7/a2-a5
  1349.     rts
  1350.  
  1351.     endm
  1352.  
  1353. COLOR15    macro
  1354.  
  1355. color15:
  1356.  
  1357. scanloop4\@
  1358.     move.w    (a4)+,d0    ; get minx
  1359.     move.w    (a5)+,d1    ; get maxx
  1360.  
  1361.     cmp.w    d0,d1        ; error check
  1362.     bmi.b    finished4\@
  1363.  
  1364.     move.w    d0,d4        ; copy minx
  1365.     lsr.w    #5,d4        ; get first long word
  1366.     lsl.w    #2,d4        ; *4 = number of bytes
  1367.     adda.w    d4,a0        ; add x offset to scanline
  1368.  
  1369.     lea    PLANESIZE(a0),a1
  1370.     lea    PLANESIZE(a1),a2
  1371.     lea    PLANESIZE(a2),a3
  1372.  
  1373.     move.w    d0,d4        ; copy minx
  1374.     moveq.l    #-1,d2        ; start mask, $ffffffff
  1375.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  1376.     lsr.l    d4,d2        ; shift mask by d4 pixels
  1377.  
  1378.     move.w    d1,d4        ; copy maxx
  1379.     moveq.l    #-1,d3        ; start mask, $ffffffff
  1380.     andi.w    #$1f,d4        ; minx mod 31 = shift count
  1381.     neg.w    d4        ; - d4
  1382.     add.w    #31,d4        ; d4 = 31 - d4
  1383.     lsl.l    d4,d3        ; shift mask by d4 pixels
  1384.  
  1385.     lsr.w    #5,d0        ; get start long word
  1386.     lsr.w    #5,d1        ; get end   long word
  1387.     sub.w    d0,d1        ; get width in long words
  1388.     bne.b    doublewrite4\@    ; check for single write
  1389. ; single write
  1390.     and.l    d2,d3        ; combine left and right masks
  1391.     or.l    d3,(a0)        ; set
  1392.     or.l    d3,(a1)        ; set
  1393.     or.l    d3,(a2)        ; set
  1394.     or.l    d3,(a3)        ; set
  1395.     bra.b    finished4\@
  1396. doublewrite4\@
  1397.     or.l    d2,(a0)+    ; set
  1398.     or.l    d2,(a1)+    ; set
  1399.     or.l    d2,(a2)+    ; set
  1400.     or.l    d2,(a3)+    ; set
  1401.     subq.w    #2,d1        ; subtract left and right writes
  1402.     bmi.b    writeright4\@    ; don't do a multiwrite
  1403. ; multiwrite\@
  1404.     moveq.l    #-1,d2        ; $ffffffff
  1405. multiloop4\@
  1406.     move.l    d2,(a0)+    ; set
  1407.     move.l    d2,(a1)+    ; set
  1408.     move.l    d2,(a2)+    ; set
  1409.     move.l    d2,(a3)+    ; set
  1410.     dbra    d1,multiloop4\@
  1411. writeright4\@
  1412.     or.l    d3,(a0)        ; set
  1413.     or.l    d3,(a1)        ; set
  1414.     or.l    d3,(a2)        ; set
  1415.     or.l    d3,(a3)        ; set
  1416. finished4\@
  1417.     add.l    d5,d6        ; go to next scanline
  1418.     movea.l    d6,a0        ; copy ptr to modify
  1419.     dbra    d7,scanloop4\@    ; d7 = yheight-1.
  1420.  
  1421.     movem.l    (sp)+,d2-d7/a2-a5
  1422.     rts
  1423.  
  1424.     endm
  1425.  
  1426. ; Expand the macros...
  1427.  
  1428.     COLOR0
  1429.     COLOR1
  1430.     COLOR2
  1431.     COLOR3
  1432.     COLOR4
  1433.     COLOR5
  1434.     COLOR6
  1435.     COLOR7
  1436.     COLOR8
  1437.     COLOR9
  1438.     COLOR10
  1439.     COLOR11
  1440.     COLOR12
  1441.     COLOR13
  1442.     COLOR14
  1443.     COLOR15
  1444.  
  1445.     CNOP    0,4    ; longword align for 020/030 speed
  1446.  
  1447. colorplanes:
  1448.     dc.l    color0
  1449.     dc.l    color1
  1450.     dc.l    color2
  1451.     dc.l    color3
  1452.     dc.l    color4
  1453.     dc.l    color5
  1454.     dc.l    color6
  1455.     dc.l    color7
  1456.     dc.l    color8
  1457.     dc.l    color9
  1458.     dc.l    color10
  1459.     dc.l    color11
  1460.     dc.l    color12
  1461.     dc.l    color13
  1462.     dc.l    color14
  1463.     dc.l    color15
  1464.  
  1465. ; A 68000 line drawer, originally from 68000 Assembly Language, by
  1466. ; Krantz and Stanley. Modified for the Amiga and the 320x200,
  1467. ; four bitplane case.
  1468.  
  1469. ;extern void __asm drawline68k(register __a1 PLANEPTR p,
  1470. ;                              register __d0 short x,
  1471. ;                              register __d1 short y,
  1472. ;                              register __d2 short x2,
  1473. ;                              register __d3 short y2,
  1474. ;                              register __d4 short color);
  1475.  
  1476. _drawline68k
  1477.     movem.l    d2-d7/a2-a6,-(sp)
  1478.  
  1479.     movea.l    a1,a2
  1480.     lea    PLANESIZE(a2),a3
  1481.     lea    PLANESIZE(a3),a4
  1482.     lea    PLANESIZE(a4),a5
  1483.  
  1484.     andi.w    #15,d4        ; 0..15 color
  1485.     add.w    d4,d4        ;
  1486.     add.w    d4,d4        ; (4 byte entries) get table index
  1487.     lea    linejmptable(pc),a6 ; table base
  1488.     movea.l    0(a6,d4.w),a6    ; get jmp address
  1489.  
  1490.  
  1491.     move.w    d0,d4
  1492.     swap    d4
  1493.     clr.w    d4
  1494.     move.w    d1,d5
  1495.     swap    d5
  1496.     clr.w    d5
  1497.  
  1498.     sub.w    d0,d2
  1499.     move.w    d2,d0
  1500.     bpl.b    sk1_vecd
  1501.     neg.w    d0
  1502. sk1_vecd
  1503.     sub.w    d1,d3
  1504.     move.w    d3,d1
  1505.     bpl.b    sk2_vecd
  1506.     neg.w    d1
  1507. sk2_vecd
  1508.     cmp.w    d0,d1
  1509.     bgt.b    y_biggerd
  1510.     tst.w    d2
  1511.     bmi.b    sk3_vecd
  1512.     move.l    #$10000,d6
  1513.     bra.b    sk4_vecd
  1514. sk3_vecd
  1515.     move.l    #$ffff0000,d6
  1516. sk4_vecd
  1517.     swap    d3
  1518.     clr.w    d3
  1519.     asr.l    #2,d3
  1520.     tst.w    d0
  1521.     beq    divtrapd
  1522.     divs    d0,d3
  1523.     ext.l    d3
  1524.     asl.l    #2,d3
  1525.     move.l    d3,d7
  1526.     move.w    d0,d2
  1527.     bra.b    sk7_vecd
  1528. y_biggerd
  1529.     tst.w    d3
  1530.     bmi.b    sk5_vecd
  1531.     move.l    #$10000,d7
  1532.     bra.b    sk6_vecd
  1533. sk5_vecd
  1534.     move.l    #$ffff0000,d7
  1535. sk6_vecd
  1536.     swap    d2
  1537.     clr.w    d2
  1538.     asr.l    #2,d2
  1539.     tst.w    d1
  1540.     beq    divtrapd
  1541.     divs    d1,d2
  1542.     ext.l    d2
  1543.     asl.l    #2,d2
  1544.     move.l    d2,d6
  1545.     move.w    d1,d2
  1546. sk7_vecd
  1547. sk8_vecd
  1548.     subq.w    #1,d2    ; setup dbra
  1549.  
  1550.     move.l    #$8000,a0    ; .5 to add to round up
  1551.     move.l    #$8000,a1    ; "                   "
  1552.  
  1553.     jsr    (a6)    ; draw line
  1554.  
  1555. divtrapd
  1556.     movem.l    (sp)+,d2-d7/a2-a6
  1557.     rts
  1558.  
  1559.  
  1560. LINEPLOT    macro
  1561. lp0_vecd\@
  1562.     move.l    d4,d0    ; fixed point arithmetic
  1563.     move.l    d5,d1
  1564.     add.l    a0,d0
  1565.     add.l    a1,d1
  1566.     swap    d0
  1567.     swap    d1
  1568.  
  1569.     move.w    d1,d3    ; save y
  1570.     add.w    d1,d1    ; *2
  1571.     add.w    d1,d1    ; *4
  1572.     add.w    d1,d3    ; *5
  1573.     lsl.w    #3,d3    ; *40
  1574.     move.w    d0,d1    ; save x
  1575.     lsr.w    #3,d0    ; get x byte offset
  1576.     add.w    d0,d3    ; x offset + y offset
  1577.     andi.w    #7,d1    ; get x bit set
  1578.     not.b    d1    ; invert bits (left to right)
  1579.  
  1580.         \1.b    d1,0(a2,d3.w)    
  1581.         \2.b    d1,0(a3,d3.w)    
  1582.         \3.b    d1,0(a4,d3.w)    
  1583.         \4.b    d1,0(a5,d3.w)    
  1584.  
  1585.     add.l    d6,d4
  1586.     add.l    d7,d5
  1587.     dbra    d2,lp0_vecd\@
  1588.     rts
  1589.     
  1590.     endm
  1591.  
  1592. linecolor0:
  1593.     LINEPLOT    bclr,bclr,bclr,bclr
  1594. linecolor1:
  1595.     LINEPLOT    bset,bclr,bclr,bclr
  1596. linecolor2:
  1597.     LINEPLOT    bclr,bset,bclr,bclr
  1598. linecolor3:
  1599.     LINEPLOT    bset,bset,bclr,bclr
  1600. linecolor4:
  1601.     LINEPLOT    bclr,bclr,bset,bclr
  1602. linecolor5:
  1603.     LINEPLOT    bset,bclr,bset,bclr
  1604. linecolor6:
  1605.     LINEPLOT    bclr,bset,bset,bclr
  1606. linecolor7:
  1607.     LINEPLOT    bset,bset,bset,bclr
  1608. linecolor8:
  1609.     LINEPLOT    bclr,bclr,bclr,bset
  1610. linecolor9:
  1611.     LINEPLOT    bset,bclr,bclr,bset
  1612. linecolor10:
  1613.     LINEPLOT    bclr,bset,bclr,bset
  1614. linecolor11:
  1615.     LINEPLOT    bset,bset,bclr,bset
  1616. linecolor12:
  1617.     LINEPLOT    bclr,bclr,bset,bset
  1618. linecolor13:
  1619.     LINEPLOT    bset,bclr,bset,bset
  1620. linecolor14:
  1621.     LINEPLOT    bclr,bset,bset,bset
  1622. linecolor15:
  1623.     LINEPLOT    bset,bset,bset,bset
  1624.  
  1625. linejmptable:
  1626.     dc.l    linecolor0
  1627.     dc.l    linecolor1
  1628.     dc.l    linecolor2
  1629.     dc.l    linecolor3
  1630.     dc.l    linecolor4
  1631.     dc.l    linecolor5
  1632.     dc.l    linecolor6
  1633.     dc.l    linecolor7
  1634.     dc.l    linecolor8
  1635.     dc.l    linecolor9
  1636.     dc.l    linecolor10
  1637.     dc.l    linecolor11
  1638.     dc.l    linecolor12
  1639.     dc.l    linecolor13
  1640.     dc.l    linecolor14
  1641.     dc.l    linecolor15
  1642.  
  1643. ;extern void __asm fillline68k(register __d0 short x,
  1644. ;                              register __d1 short y,
  1645. ;                              register __d2 short x2,
  1646. ;                              register __d3 short y2,
  1647. ;                              register __a0 short * table);
  1648.  
  1649. ; The line drawer modified...
  1650.  
  1651. _fillline68k:
  1652.     movem.l    d2-d7,-(sp)
  1653.  
  1654.     cmp.w    d1,d3        ; always draw top->bottom
  1655.     bgt.b    oky
  1656.     exg    d1,d3        ; swap y's
  1657.     exg    d0,d2        ; sway x's
  1658. oky
  1659.     move.w    d3,d6
  1660.     add.w    d6,d6        ; 2 byte entries
  1661.     move.w    d2,0(a0,d6.w)    ; save x in scan table
  1662.  
  1663.     move.w    d1,d6
  1664.     add.w    d6,d6        ; 2 byte entries
  1665.     move.w    d0,0(a0,d6.w)    ; save x in scan table
  1666.  
  1667.     adda.w    d6,a0        ; set up address to start of table
  1668.  
  1669.     move.w    d0,d4
  1670.     swap    d4
  1671.     clr.w    d4
  1672.     move.w    d1,d5
  1673.     swap    d5
  1674.     clr.w    d5
  1675.  
  1676.     sub.w    d0,d2
  1677.     move.w    d2,d0
  1678.     bpl.b    sk1_vec
  1679.     neg.w    d0
  1680. sk1_vec
  1681.     sub.w    d1,d3
  1682.     move.w    d3,d1
  1683.     bpl.b    sk2_vec
  1684.     neg.w    d1
  1685. sk2_vec
  1686.     cmp.w    d0,d1
  1687.     bgt.b    y_bigger
  1688.     tst.w    d2
  1689.     bmi.b    sk3_vec
  1690.     move.l    #$10000,d6
  1691.     bra.b    sk4_vec
  1692. sk3_vec
  1693.     move.l    #$ffff0000,d6
  1694. sk4_vec
  1695.     swap    d3
  1696.     clr.w    d3
  1697.     asr.l    #2,d3
  1698.     tst.w    d0
  1699.     beq    divtrap
  1700.     divs    d0,d3
  1701.     ext.l    d3
  1702.     asl.l    #2,d3
  1703.     move.l    d3,d7
  1704.     move.w    d0,d2
  1705.     bra.b    sk7_vec
  1706. y_bigger
  1707.     tst.w    d3
  1708.     bmi.b    sk5_vec
  1709.     move.l    #$10000,d7
  1710.     bra.b    sk6_vec
  1711. sk5_vec
  1712.     move.l    #$ffff0000,d7
  1713. sk6_vec
  1714.     swap    d2
  1715.     clr.w    d2
  1716.     asr.l    #2,d2
  1717.     tst.w    d1
  1718.     beq    divtrap
  1719.     divs    d1,d2
  1720.     ext.l    d2
  1721.     asl.l    #2,d2
  1722.     move.l    d2,d6
  1723.     move.w    d1,d2
  1724. sk7_vec
  1725. ;    subq.w    #1,d2        ; set up dbra
  1726.     move.l    #$8000,d3    ; .5 to add to round up
  1727.  
  1728.     move.w    d1,a1        ; old y = current y
  1729.  
  1730.     move.l    d4,d0        ; compute 2nd x point
  1731.     add.l    d3,d0
  1732.     swap    d0
  1733.     move.l    d5,d1        ; compute 2nd y point
  1734.     add.l    d3,d1
  1735.     swap    d1
  1736. lp0_vec
  1737.     cmp.w    a1,d1        ; newy # oldy?
  1738.     beq.b    ynochange    ; no
  1739.     move.w    d0,(a0)+    ; fastest possible write to memory.
  1740. ynochange            
  1741.     move.w    d1,a1
  1742.  
  1743.     add.l    d6,d4
  1744.     add.l    d7,d5
  1745.  
  1746.     move.l    d4,d0        ; fixed point arithmetic
  1747.     add.l    d3,d0
  1748.     swap    d0
  1749.     move.l    d5,d1
  1750.     add.l    d3,d1
  1751.     swap    d1
  1752. sk8_vec
  1753.     dbra    d2,lp0_vec
  1754. divtrap    
  1755.     movem.l    (sp)+,d2-d7
  1756.     rts
  1757.  
  1758.     END
  1759.  
  1760. ;   Here are a few subtle changes to improve performance of the processor
  1761. ; polygon fill code I posted earlier. Both changes are for the file
  1762. ; scanconvert.a. Also, my polygon fill code only works on convex polygons.
  1763. ; If the screen width is changed from 320 pixels, the line drawer's pixel
  1764. ; offset calculations will have to be rewritten to handle a non-40 bytes
  1765. ; per row case (The 80 bytes per row (640 pixels) case is trivial, just
  1766. ; change the lsl.w #3,d3 to lsl.w #4,d3). The polygon routines simply
  1767. ; require a changed define, and could be generalized so it could
  1768. ; handle screen width changes dynamically.
  1769. ;   In _drawline68k, change the code between sk8_vecd and the second
  1770. ; add.l to the below:
  1771. ; ; start _drawline changes
  1772. ; sk8_vecd
  1773. ;     subq.w    #1,d2    ; setup dbra
  1774. ;     move.l    #$8000,a0    ; .5 to add to round up
  1775. ;     move.w    #7,a1
  1776. ;     jsr    (a6)    ; draw line
  1777. ; divtrapd
  1778. ;     movem.l    (sp)+,d2-d7/a2-a6
  1779. ;     rts
  1780. ; LINEPLOT    macro
  1781. ; lp0_vecd\@
  1782. ;     move.l    d4,d0    ; fixed point arithmetic
  1783. ;     move.l    d5,d1
  1784. ;     add.l    a0,d0
  1785. ;     add.l    a0,d1
  1786. ; ; end of _drawline68k changes
  1787. ;   In _fillline68k, change everything from sk7_vec to sk8_vec to:
  1788. ; ; start _fillline68k changes
  1789. ; sk7_vec
  1790. ;     move.l    #$8000,d3    ; .5 to add to round up
  1791. ;     move.w    d1,a1        ; old y = current y
  1792. ; lp0_vec
  1793. ;     move.l    d4,d0        ; fixed point arithmetic
  1794. ;     add.l    d3,d0
  1795. ;     swap    d0
  1796. ;     move.l    d5,d1
  1797. ;     add.l    d3,d1
  1798. ;     swap    d1
  1799. ;     cmp.w    a1,d1        ; newy # oldy?
  1800. ;     beq.b    ynochange    ; no
  1801. ;     move.w    d0,(a0)+    ; fastest possible write to memory.
  1802. ; ynochange            
  1803. ;     move.w    d1,a1
  1804. ;     add.l    d6,d4
  1805. ;     add.l    d7,d5
  1806. ; sk8_vec
  1807. ; ; end of _filline68k changes
  1808.     ------------------------------ 8< ------------------------------
  1809. --
  1810. *** John Bickers, TAP, NZAmigaUG.        jbickers@templar.actrix.gen.nz ***
  1811. ***         "Endless variations, make it all seem new" - Devo.          ***
  1812.  
  1813.  
  1814.  
  1815.  
  1816.