jcs@crash.cts.com (John Schultz) (05/22/91)
Here's the latest verions of my dot, line, and polygon code. Redistribute and use at will, but leave the copyright notices in tact. Enjoy, John #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # p/demo.c # p/demo.h # p/draw3d.a # p/draw3d.h # p/fill.c # p/gdefs.i # p/makefile # p/readme # p/scanconvert.a # This archive created: Tue May 21 11:26:02 1991 export PATH; PATH=/bin:$PATH if test -f 'p/demo.c' then echo shar: will not over-write existing file "'p/demo.c'" else cat << \SHAR_EOF > 'p/demo.c' /* Demo.c Copyright ) 1991 John Schultz, All Rights Reserved Stripped from: Demo for AmigaWorld Expo, New York, April 5-7 1991 */ #include "draw3d.h" void main(void) { /* Add your code here */ } /* main */ /* end demo.c */ SHAR_EOF fi # end of overwriting check if test -f 'p/demo.h' then echo shar: will not over-write existing file "'p/demo.h'" else cat << \SHAR_EOF > 'p/demo.h' /* Demo.h Copyright ) 1991 John Schultz Demo for AmigaWorld Expo, New York, April 5-7 1991 */ #ifndef DEMOHEADER #define DEMOHEADER #include <exec/types.h> typedef struct shortpoint2d {short x,y;} shortpoint2d; typedef struct longpoint3d {long x,y,z;} longpoint3d; typedef struct defpoint3d {long x,y,z; /* rotated points */ long defx,defy,defz; /* definition points */ unsigned long gcycle;/* need to rotate? */ long pad; /* Make 32 bytes in size */ } defpoint3d; typedef struct drawoffset {unsigned short offset,bit,color;} drawoffset; typedef struct matrix {long a1,b1,c1,d1,e1,f1,g1,h1,i1;} matrix; typedef void (*animfunc)(long * data); /* anim function pointer */ typedef void (*motionfunc)(struct object * o); /* motion function pointer */ #define NUMDOTS 32 typedef struct dot { defpoint3d point; shortpoint2d dp; /* Drawpoint */ short color; } dot; typedef struct poly { matrix * pm; /* Parent object's matrix */ defpoint3d * vpoint[8]; defpoint3d shadow[8]; defpoint3d normal[2]; long planek,vis; shortpoint2d dp[8]; /* drawpoint */ animfunc companim; /* Compute animation */ long * animinfo; animfunc drawanim; /* Draw animation */ long * animdata; short basecolor,drawcolor; short vcount,colorrange; } poly; typedef struct object { matrix lm,sm; defpoint3d frame[8]; poly face[6]; /* Boxes, max */ short numface,numframe; defpoint3d icenter,rcenter; /* Imaginary and Real centers */ longpoint3d linvel,rotvel; /* Velocities */ longpoint3d linacl,rotacl; /* Accelerations */ longpoint3d stretch,straxis; /* For squash and stretch */ motionfunc motion; long mass; /* For Collisions */ } object; #define FBITS 14 #define FBITSONE (1<<FBITS) #define RBITS ((double)FBITSONE) #endif /* end demo.h */ SHAR_EOF fi # end of overwriting check if test -f 'p/draw3d.a' then echo shar: will not over-write existing file "'p/draw3d.a'" else cat << \SHAR_EOF > 'p/draw3d.a' ; Draw3d.a - 3D Drawing Routines ; Created 20-Oct-89 include "gdefs.i" section Draw3d,code xdef _drawpixel xdef _drawline xdef _fillline68k ; general purpose single call routine, using minimal registers. ; a1 = planeptr array, d0 = x, d1 = y, d2 = color _drawpixel: movem.l d6-d7/a2-a6,-(sp) move.w d1,d7 ; save y add.w d1,d1 ; *2 add.w d1,d1 ; *4 add.w d1,d7 ; *5 lsl.w #3,d7 ; *40 move.w d0,d6 ; save x lsr.w #3,d0 ; get x byte offset add.w d0,d7 ; x offset + y offset andi.w #7,d6 ; get x bit set not.b d6 ; invert bits (left to right) movea.l a0,a2 lea PLANESIZE(a2),a3 lea PLANESIZE(a3),a4 lea PLANESIZE(a4),a5 andi.w #15,d2 ; 0..15 color add.w d2,d2 ; add.w d2,d2 ; (4 byte entries) get table index lea colorjmptable(pc),a6 ; table base movea.l 0(a6,d2.w),a6 ; get jmp address jsr (a6) ; plot pixel movem.l (sp)+,d6-d7/a2-a6 rts cnop 0,4 _drawline: movem.l d2-d7/a2-a6,-(sp) movea.l a1,a2 lea PLANESIZE(a2),a3 lea PLANESIZE(a3),a4 lea PLANESIZE(a4),a5 andi.w #15,d7 ; 0..15 color add.w d7,d7 ; add.w d7,d7 ; (4 byte entries) get table index lea linejmptable(pc),a6 ; table base movea.l 0(a6,d7.w),a6 ; get jmp address move.w d0,d4 swap d4 clr.w d4 move.w d1,d5 swap d5 clr.w d5 sub.w d0,d2 move.w d2,d0 bpl.b sk1_vecd neg.w d0 sk1_vecd sub.w d1,d3 move.w d3,d1 bpl.b sk2_vecd neg.w d1 sk2_vecd cmp.w d0,d1 bgt.b y_biggerd tst.w d2 bmi.b sk3_vecd move.l #$10000,d6 bra.b sk4_vecd sk3_vecd move.l #$ffff0000,d6 sk4_vecd swap d3 clr.w d3 asr.l #2,d3 tst.w d0 beq.b divtrapd divs d0,d3 ext.l d3 asl.l #2,d3 move.l d3,d7 move.w d0,d2 bra.b sk7_vecd y_biggerd tst.w d3 bmi.b sk5_vecd move.l #$10000,d7 bra.b sk6_vecd sk5_vecd move.l #$ffff0000,d7 sk6_vecd swap d2 clr.w d2 asr.l #2,d2 tst.w d1 beq.b divtrapd divs d1,d2 ext.l d2 asl.l #2,d2 move.l d2,d6 move.w d1,d2 sk7_vecd sk8_vecd subq.w #1,d2 ; setup dbra move.l #$8000,a0 ; .5 to add to round up move.l #$8000,a1 ; " " jsr (a6) ; draw line divtrapd movem.l (sp)+,d2-d7/a2-a6 rts LINEPLOT macro lp0_vecd\@ move.l d4,d0 move.l d5,d1 add.l a0,d0 add.l a1,d1 swap d0 swap d1 move.w d1,d3 ; save y add.w d1,d1 ; *2 add.w d1,d1 ; *4 add.w d1,d3 ; *5 lsl.w #3,d3 ; *40 move.w d0,d1 ; save x lsr.w #3,d0 ; get x byte offset add.w d0,d3 ; x offset + y offset andi.w #7,d1 ; get x bit set not.b d1 ; invert bits (left to right) \1.b d1,0(a2,d3.w) \2.b d1,0(a3,d3.w) \3.b d1,0(a4,d3.w) \4.b d1,0(a5,d3.w) add.l d6,d4 add.l d7,d5 dbra d2,lp0_vecd\@ rts endm linecolor0: LINEPLOT bclr,bclr,bclr,bclr linecolor1: LINEPLOT bset,bclr,bclr,bclr linecolor2: LINEPLOT bclr,bset,bclr,bclr linecolor3: LINEPLOT bset,bset,bclr,bclr linecolor4: LINEPLOT bclr,bclr,bset,bclr linecolor5: LINEPLOT bset,bclr,bset,bclr linecolor6: LINEPLOT bclr,bset,bset,bclr linecolor7: LINEPLOT bset,bset,bset,bclr linecolor8: LINEPLOT bclr,bclr,bclr,bset linecolor9: LINEPLOT bset,bclr,bclr,bset linecolor10: LINEPLOT bclr,bset,bclr,bset linecolor11: LINEPLOT bset,bset,bclr,bset linecolor12: LINEPLOT bclr,bclr,bset,bset linecolor13: LINEPLOT bset,bclr,bset,bset linecolor14: LINEPLOT bclr,bset,bset,bset linecolor15: LINEPLOT bset,bset,bset,bset linejmptable: dc.l linecolor0 dc.l linecolor1 dc.l linecolor2 dc.l linecolor3 dc.l linecolor4 dc.l linecolor5 dc.l linecolor6 dc.l linecolor7 dc.l linecolor8 dc.l linecolor9 dc.l linecolor10 dc.l linecolor11 dc.l linecolor12 dc.l linecolor13 dc.l linecolor14 dc.l linecolor15 cnop 0,4 ; align for 020/030 speed. ; extern void __asm fillline68k(register __d0 short x, ; register __d1 short y, ; register __d2 short x2, ; register __d3 short y2, ; register __a0 short * table); _fillline68k: movem.l d2-d7,-(sp) cmp.w d1,d3 ; always draw top->bottom for accuracy bgt.b oky exg d1,d3 ; swap y's exg d0,d2 ; sway x's oky move.w d3,d6 add.w d6,d6 ; 2 byte entries move.w d2,0(a0,d6.w) ; save x in scan table move.w d1,d6 add.w d6,d6 ; 2 byte entries move.w d0,0(a0,d6.w) ; save x in scan table adda.w d6,a0 ; set up address to start of table move.w d0,d4 swap d4 clr.w d4 move.w d1,d5 swap d5 clr.w d5 sub.w d0,d2 move.w d2,d0 bpl.b sk1_vec neg.w d0 sk1_vec sub.w d1,d3 move.w d3,d1 bpl.b sk2_vec neg.w d1 sk2_vec cmp.w d0,d1 bgt.b y_bigger tst.w d2 bmi.b sk3_vec move.l #$10000,d6 bra.b sk4_vec sk3_vec move.l #$ffff0000,d6 sk4_vec swap d3 clr.w d3 asr.l #2,d3 tst.w d0 beq divtrap divs d0,d3 ext.l d3 asl.l #2,d3 move.l d3,d7 move.w d0,d2 bra.b sk7_vec y_bigger tst.w d3 bmi.b sk5_vec move.l #$10000,d7 bra.b sk6_vec sk5_vec move.l #$ffff0000,d7 sk6_vec swap d2 clr.w d2 asr.l #2,d2 tst.w d1 beq divtrap divs d1,d2 ext.l d2 asl.l #2,d2 move.l d2,d6 move.w d1,d2 sk7_vec ; subq.w #1,d2 ; set up dbra move.l #$8000,d3 ; .5 to add to round up move.w d1,a1 ; old y = current y move.l d4,d0 ; compute 2nd x point add.l d3,d0 swap d0 move.l d5,d1 ; compute 2nd y point add.l d3,d1 swap d1 lp0_vec cmp.w a1,d1 ; newy # oldy? beq.b ynochange ; no move.w d0,(a0)+ ynochange move.w d1,a1 add.l d6,d4 add.l d7,d5 move.l d4,d0 add.l d3,d0 swap d0 move.l d5,d1 add.l d3,d1 swap d1 sk8_vec dbra d2,lp0_vec divtrap movem.l (sp)+,d2-d7 rts cnop 0,4 ; jmp table routines for setting a pixel ; d6 = bit to set, a2-a5 = plane ptrs, d7.w = offset color0: ; %0000 bclr.b d6,0(a2,d7.w) bclr.b d6,0(a3,d7.w) bclr.b d6,0(a4,d7.w) bclr.b d6,0(a5,d7.w) rts color1: ; %0001 bset.b d6,0(a2,d7.w) bclr.b d6,0(a3,d7.w) bclr.b d6,0(a4,d7.w) bclr.b d6,0(a5,d7.w) rts color2: ; %0010 bclr.b d6,0(a2,d7.w) bset.b d6,0(a3,d7.w) bclr.b d6,0(a4,d7.w) bclr.b d6,0(a5,d7.w) rts color3: ; %0011 bset.b d6,0(a2,d7.w) bset.b d6,0(a3,d7.w) bclr.b d6,0(a4,d7.w) bclr.b d6,0(a5,d7.w) rts color4: ; %0100 bclr.b d6,0(a2,d7.w) bclr.b d6,0(a3,d7.w) bset.b d6,0(a4,d7.w) bclr.b d6,0(a5,d7.w) rts color5: ; %0101 bset.b d6,0(a2,d7.w) bclr.b d6,0(a3,d7.w) bset.b d6,0(a4,d7.w) bclr.b d6,0(a5,d7.w) rts color6: ; %0110 bclr.b d6,0(a2,d7.w) bset.b d6,0(a3,d7.w) bset.b d6,0(a4,d7.w) bclr.b d6,0(a5,d7.w) rts color7: ; %0111 bset.b d6,0(a2,d7.w) bset.b d6,0(a3,d7.w) bset.b d6,0(a4,d7.w) bclr.b d6,0(a5,d7.w) rts color8: ; %1000 bclr.b d6,0(a2,d7.w) bclr.b d6,0(a3,d7.w) bclr.b d6,0(a4,d7.w) bset.b d6,0(a5,d7.w) rts color9: ; %1001 bset.b d6,0(a2,d7.w) bclr.b d6,0(a3,d7.w) bclr.b d6,0(a4,d7.w) bset.b d6,0(a5,d7.w) rts color10: ; %1010 bclr.b d6,0(a2,d7.w) bset.b d6,0(a3,d7.w) bclr.b d6,0(a4,d7.w) bset.b d6,0(a5,d7.w) rts color11: ; %1011 bset.b d6,0(a2,d7.w) bset.b d6,0(a3,d7.w) bclr.b d6,0(a4,d7.w) bset.b d6,0(a5,d7.w) rts color12: ; %1100 bclr.b d6,0(a2,d7.w) bclr.b d6,0(a3,d7.w) bset.b d6,0(a4,d7.w) bset.b d6,0(a5,d7.w) rts color13: ; %1101 bset.b d6,0(a2,d7.w) bclr.b d6,0(a3,d7.w) bset.b d6,0(a4,d7.w) bset.b d6,0(a5,d7.w) rts color14: ; %1110 bclr.b d6,0(a2,d7.w) bset.b d6,0(a3,d7.w) bset.b d6,0(a4,d7.w) bset.b d6,0(a5,d7.w) rts color15: ; %1111 bset.b d6,0(a2,d7.w) bset.b d6,0(a3,d7.w) bset.b d6,0(a4,d7.w) bset.b d6,0(a5,d7.w) rts cnop 0,4 colorjmptable dc.l color0 dc.l color1 dc.l color2 dc.l color3 dc.l color4 dc.l color5 dc.l color6 dc.l color7 dc.l color8 dc.l color9 dc.l color10 dc.l color11 dc.l color12 dc.l color13 dc.l color14 dc.l color15 END SHAR_EOF fi # end of overwriting check if test -f 'p/draw3d.h' then echo shar: will not over-write existing file "'p/draw3d.h'" else cat << \SHAR_EOF > 'p/draw3d.h' /* Draw3d.h */ /* Created 9-May-90 */ /* From draw3d.a */ #ifndef DRAW3D #define DRAW3D #include <exec/types.h> #include <graphics/gfx.h> #define WIDTH 320 #define HEIGHT 200 #define DEPTH 4 #define ONEPLANE 0x100 /* One bitplane color (set color equal to) */ typedef struct shortpoint2d {short x,y;} shortpoint2d; extern void __asm drawpixel(register __a0 PLANEPTR p, register __d0 short x, register __d1 short y, register __d2 short color); extern void __asm drawline(register __a1 PLANEPTR p, register __d0 short x, register __d1 short y, register __d2 short x2, register __d3 short y2, register __d7 short color); extern void __asm fillline68k(register __d0 short x, register __d1 short y, register __d2 short x2, register __d3 short y2, register __a0 short * table); /* From scanconvert.a */ extern void __asm scanconvpix(register __a0 PLANEPTR p, register __a1 short * minx, register __a2 short * maxx, register __d0 short miny, register __d1 short maxy, register __d2 short color); /* One bitplane version */ extern void __asm scanconvpix1(register __a0 PLANEPTR p, register __a1 short * minx, register __a2 short * maxx, register __d0 short miny, register __d1 short maxy); /* From fill.c */ void drawpolyc(shortpoint2d * vp, PLANEPTR p, short count, short color); /* Will render into Plane p only if color == ONEPLANE */ #endif /* end Draw3d.h */ SHAR_EOF fi # end of overwriting check if test -f 'p/fill.c' then echo shar: will not over-write existing file "'p/fill.c'" else cat << \SHAR_EOF > 'p/fill.c' /* Copyright ) 1991 John Schultz All Rights Reserved */ /* fill.c, processor poly filler */ #include "draw3d.h" static short xmin[HEIGHT+1], xmax[HEIGHT+1]; static short * xt; void drawpolyc(shortpoint2d * vp, PLANEPTR p, short count, short color){ shortpoint2d * tmax, * tmin; shortpoint2d * tp, * tpn; shortpoint2d * last; long cmp; long orient; /* Get last point */ last = &vp[count-1]; /* Cross product to check for check for line case */ if (count > 3) { /* Use Newell method */ orient = 0; tp = vp; /* Point to first point */ while (1) { if (tp == last) tpn = vp; /* Set next pointer to first point */ else tpn = tp + 1; /* point to next. Compiler does: tp + sizeof(*tp) */ orient += (tp->x - tpn->x)*(tp->y + tpn->y); if (tpn == vp) break; /* Come full circle */ tp = tpn; /* go to next */ } /* while */ } else { /* Simple cross-product: triangle case */ orient = (vp[1].x - vp[0].x)*(vp[2].y - vp[0].y) - (vp[1].y - vp[0].y)*(vp[2].x - vp[0].x); } /* if count */ if (orient == 0L) { /* Collinear: draw a line */ /* Find two points that aren't equal */ cmp = *(long *)vp; /* First point */ tp = vp + 1; /* Point to next (Compiler does: vp + sizeof(*vp) */ while (1) { if ((cmp != (*(long *)tp)) || (tp == last)) break; tp++; } /* while */ if (color != ONEPLANE) drawline(p,vp->x,vp->y,tp->x,tp->y,(unsigned short)(color | 0xf00)); return; } /* if line case */ /* Find miny,maxy */ tmin = vp; /* Point at first */ tmax = vp; /* " " */ tp = vp + 1; /* Point to next (Compiler does: vp + sizeof(*vp) */ while (1) { if (tp->y < tmin->y) { tmin = tp; } else if (tp->y == tmin->y) { if (tp->x >= tmax->x) { tmin = tp; } /* if tp->x */ } /* if tp->y */ if (tp->y > tmax->y) { /* MaxY */ tmax = tp; } else if (tp->y == tmax->y) { if (tp->x < tmax->x) { /* Get maxY, minX */ tmax = tp; } /* if tp->x */ } /* if tmaxy */ if (tp == last) break; tp++; }; if (orient < 0) { /* Fill tables */ tp = tmin; /* Temp point starts at miny */ xt = xmin; /* Fill xmin table first */ while (1) { if (tp == last) tpn = vp; /* Set to first point */ else tpn = tp + 1; /* Next. Compiler does: tp + sizeof(*tp) */ fillline68k((short)tp->x,(short)tp->y,(short)tpn->x,(short)tpn->y,xt); if (tpn == tmin) break; /* Come full circle, quit */ if (tpn == tmax) xt = xmax; /* Fill max table */ tp = tpn; /* Go to next */ } /* while */ } else { /* Fill tables */ tp = tmin; /* Temp point starts at miny */ xt = xmax; /* Fill xmax table first */ while (1) { if (tp == last) tpn = vp; /* Set to first point */ else tpn = tp + 1; /* Next. Compiler does: tp + sizeof(*tp) */ fillline68k((short)tp->x,(short)tp->y,(short)tpn->x,(short)tpn->y,xt); if (tpn == tmin) break; /* Come full circle, quit */ if (tpn == tmax) xt = xmin; /* Fill min table */ tp = tpn; /* Go to next */ } /* while */ } /* if orient */ /* Draw polygon */ if (color== ONEPLANE) /* Draw only one bitplane */ scanconvpix1(p,xmin,xmax,(short)tmin->y,(short)tmax->y); else /* Draw all bitplanes */ scanconvpix(p,xmin,xmax,(short)tmin->y,(short)tmax->y,color); } /* drawpolyc */ /* end fill.c */ SHAR_EOF fi # end of overwriting check if test -f 'p/gdefs.i' then echo shar: will not over-write existing file "'p/gdefs.i'" else cat << \SHAR_EOF > 'p/gdefs.i' ; Graphics defs WIDTH equ 320 HEIGHT equ 200 DEPTH equ 4 PLANESIZE equ (((WIDTH*HEIGHT)+7)/8) ; end gdefs.i SHAR_EOF fi # end of overwriting check if test -f 'p/makefile' then echo shar: will not over-write existing file "'p/makefile'" else cat << \SHAR_EOF > 'p/makefile' FLAGS = -cusf -m3 -O demo: demo.o scanconvert.o fill.o draw3d.o blink from lib:c.o demo.o scanconvert.o fill.o draw3d.o to demo \ lib lib:lc.lib lib:amiga.lib SC SD ND demo.o: draw3d.h demo.c lc $(FLAGS) demo.c fill.o: draw3d.h fill.c lc $(FLAGS) fill.c draw3d.o: gdefs.i draw3d.a asm draw3d.a scanconvert.o: gdefs.i scanconvert.a asm scanconvert.a SHAR_EOF fi # end of overwriting check if test -f 'p/readme' then echo shar: will not over-write existing file "'p/readme'" else cat << \SHAR_EOF > 'p/readme' Here are my processor dot, line, and polygon routines. Any problems or questions mail them to me. Enjoy. John Schultz 5/21/91 jcs@crash.cts.com (If you are a graphics programmer developer with a product that can benefit from a 320x256 - 1280x1024 (1-8 bits per pixel, 24 bit palette) display, please contact Digital Micronics, Inc., at (619) 931-8554. DMI will soon have available a 60Mhz 34010 graphics coprocessor for the Amiga (Pending FCC)). These routines have been optimized for a 320x200x4 display. You must allocate memory for your bitmaps as one continuous block of memory. If you want to change the vertical size of the bitmap, change planesize accordingly (in gdefs.i). If you want to change the width, you'll have to modify all of the *40 (times forty) calculations (bytes per row). Changing to 80 bytes per row is simple (for 640 width). Other sizes and depths will require more work. All calls require a pointer to your first bitplane in your bitmap. For example: drawline(myRP->BitMap->Planes[0], etc) On a 68030 Amiga, especially an A3000 with 32bit chip ram, you'll find these routines to be much faster than the blitter (2-5 times faster than the ROM routines). Furthermore, you can still optimize the polygon routines even more... SHAR_EOF fi # end of overwriting check if test -f 'p/scanconvert.a' then echo shar: will not over-write existing file "'p/scanconvert.a'" else cat << \SHAR_EOF > 'p/scanconvert.a' ; scanconvert.a ; Created 14-March-90 ; Modified 17-May-90 ; Re-written with long word aligned writes: now up to twice as fast ; as using bfset/bfclr (bitfield instructions can hit up to 5 bytes, ; not long word aligned). ; Code is now 68000 compatible. section scanconvert,code include "gdefs.i" xdef _scanconvpix xdef _scanconvpix1 ; d0/d1 = miny,maxy. ; a0 = planeptr ; a1 = xmin table ; a2 = xmax table _scanconvpix1: movem.l d2-d7/a2-a6,-(sp) move.w d1,d7 ; get maxy. d0 = miny. sub.w d0,d7 ; compute yheight. +1 not necessary: using dbra. movea.l a1,a4 ; copy xminptr movea.l a2,a5 ; copy xmaxptr move.w d0,d6 ; copy miny add.w d6,d6 ; y index is 2 bytes, so *2 offset adda.w d6,a4 ; get to start postion minx adda.w d6,a5 ; get to start postion maxx move.w d0,d6 ; copy miny lsl.w #3,d6 ; *8 lsl.w #5,d0 ; *32 add.w d6,d0 ; *40 adda.w d0,a0 ; go to first scanline in bitmap movea.l a0,a1 ; setup for first pass moveq.l #40,d5 ; bytes per row, to be added each scanline ; d6 is free, d5 could be free, a3/a6 are free scanloop1 move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished1 move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a1 ; add x offset to scanline move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite ; check for single write ; single write and.l d2,d3 ; combine left and right masks or.l d3,(a1) ; write mask bra.b finished1 doublewrite or.l d2,(a1)+ ; write left mask subq.w #2,d1 ; subtract left and right writes bmi.b writeright ; don't do a multiwrite ; multiwrite moveq.l #-1,d2 ; $ffffffff multiloop move.l d2,(a1)+ ; write middle 1's dbra d1,multiloop writeright or.l d3,(a1) ; write right mask finished1 adda.w d5,a0 ; go to next scanline movea.l a0,a1 ; copy ptr to modify dbra d7,scanloop1 ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a6 rts ; d0/d1 = miny,maxy, d2 = color. ; a0 = planeptr ; a1 = xmin table ; a2 = xmax table _scanconvpix: movem.l d2-d7/a2-a5,-(sp) move.w d1,d7 ; get maxy. d0 = miny. sub.w d0,d7 ; compute yheight. +1 not necessary: using dbra. movea.l a1,a4 ; copy xminptr movea.l a2,a5 ; copy xmaxptr move.w d0,d6 ; copy miny add.w d6,d6 ; y index is 2 bytes, so *2 offset adda.w d6,a4 ; get to start postion minx adda.w d6,a5 ; get to start postion maxx move.w d0,d6 ; copy miny lsl.w #3,d6 ; *8 lsl.w #5,d0 ; *32 add.w d6,d0 ; *40 adda.w d0,a0 ; go to first scanline in bitmap move.l a0,d6 ; setup for first pass (d6 += 40 each pass) moveq.l #40,d5 ; bytes per row, to be added each scanline lea colorplanes(pc),a2 ; get colorplane table add.w d2,d2 add.w d2,d2 ; entries are 4 bytes long movea.l 0(a2,d2.w),a2 ; get color jsr address jmp (a2) ; do specific plane writes/clears ; end of scanconvpix COLOR0 macro color0: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks not.l d3 ; invert and.l d3,(a0) ; clear and.l d3,(a1) ; clear and.l d3,(a2) ; clear ; and.l d3,(a3) ; clear bra.b finished4\@ doublewrite4\@ not.l d2 ; invert and.l d2,(a0)+ ; write left mask and.l d2,(a1)+ ; write left mask and.l d2,(a2)+ ; write left mask ; and.l d2,(a3)+ ; write left mask subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite moveq.l #0,d2 ; zereos multiloop4\@ move.l d2,(a0)+ ; write middle 0's move.l d2,(a1)+ ; write middle 0's move.l d2,(a2)+ ; write middle 0's ; move.l d2,(a3)+ ; write middle 0's dbra d1,multiloop4\@ writeright4\@ not.l d3 and.l d3,(a0) ; write right mask and.l d3,(a1) ; write right mask and.l d3,(a2) ; write right mask ; and.l d3,(a3) ; write right mask finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR1 macro color1: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks or.l d3,(a0) ; set not.l d3 ; invert and.l d3,(a1) ; clear and.l d3,(a2) ; clear ; and.l d3,(a3) ; clear not.l d3 bra.b finished4\@ doublewrite4\@ or.l d2,(a0)+ ; set not.l d2 and.l d2,(a1)+ ; clear and.l d2,(a2)+ ; clear ; and.l d2,(a3)+ ; clear subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite\@ moveq.l #-1,d2 ; $ffffffff moveq.l #0,d4 ; zeroes multiloop4\@ move.l d2,(a0)+ ; set move.l d4,(a1)+ ; clear move.l d4,(a2)+ ; clear ; move.l d4,(a3)+ ; clear dbra d1,multiloop4\@ writeright4\@ or.l d3,(a0) ; set not.l d3 and.l d3,(a1) ; clear and.l d3,(a2) ; clear ; and.l d3,(a3) ; clear finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR2 macro color2: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks or.l d3,(a1) ; set not.l d3 ; invert and.l d3,(a0) ; clear and.l d3,(a2) ; clear ; and.l d3,(a3) ; clear bra.b finished4\@ doublewrite4\@ or.l d2,(a1)+ ; set not.l d2 and.l d2,(a0)+ ; clear and.l d2,(a2)+ ; clear ; and.l d2,(a3)+ ; clear subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite\@ moveq.l #-1,d2 ; $ffffffff moveq.l #0,d4 ; zeroes multiloop4\@ move.l d2,(a1)+ ; set move.l d4,(a0)+ ; clear move.l d4,(a2)+ ; clear ; move.l d4,(a3)+ ; clear dbra d1,multiloop4\@ writeright4\@ or.l d3,(a1) ; set not.l d3 ; invert and.l d3,(a0) ; clear and.l d3,(a2) ; clear ; and.l d3,(a3) ; clear finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR3 macro color3: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks ; or.l d3,(a0) ; set or.l d3,(a1) ; set not.l d3 ; invert ; and.l d3,(a2) ; clear ; and.l d3,(a3) ; clear bra.b finished4\@ doublewrite4\@ ; or.l d2,(a0)+ ; set or.l d2,(a1)+ ; set not.l d2 ; and.l d2,(a2)+ ; clear ; and.l d2,(a3)+ ; clear subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite\@ moveq.l #-1,d2 ; $ffffffff moveq.l #0,d4 ; zeroes multiloop4\@ ; move.l d2,(a0)+ ; set move.l d2,(a1)+ ; set ; move.l d4,(a2)+ ; clear ; move.l d4,(a3)+ ; clear dbra d1,multiloop4\@ writeright4\@ ; or.l d3,(a0) ; set or.l d3,(a1) ; set not.l d3 ; and.l d3,(a2) ; clear ; and.l d3,(a3) ; clear finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR4 macro color4: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks or.l d3,(a2) ; set not.l d3 ; invert and.l d3,(a0) ; clear ; and.l d3,(a1) ; clear ; and.l d3,(a3) ; clear bra.b finished4\@ doublewrite4\@ or.l d2,(a2)+ ; set not.l d2 and.l d2,(a0)+ ; clear ; and.l d2,(a1)+ ; clear ; and.l d2,(a3)+ ; clear subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite\@ moveq.l #-1,d2 ; $ffffffff moveq.l #0,d4 ; zeroes multiloop4\@ move.l d2,(a2)+ ; set move.l d4,(a0)+ ; clear ; move.l d4,(a1)+ ; clear ; move.l d4,(a3)+ ; clear dbra d1,multiloop4\@ writeright4\@ or.l d3,(a2) ; set not.l d3 ; invert and.l d3,(a0) ; clear ; and.l d3,(a1) ; clear ; and.l d3,(a3) ; clear finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR5 macro color5: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks or.l d3,(a0) ; set or.l d3,(a2) ; set not.l d3 ; invert and.l d3,(a1) ; clear and.l d3,(a3) ; clear bra.b finished4\@ doublewrite4\@ or.l d2,(a0)+ ; set or.l d2,(a2)+ ; set not.l d2 and.l d2,(a1)+ ; clear and.l d2,(a3)+ ; clear subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite\@ moveq.l #-1,d2 ; $ffffffff moveq.l #0,d4 ; zeroes multiloop4\@ move.l d2,(a0)+ ; set move.l d2,(a2)+ ; set move.l d4,(a1)+ ; clear move.l d4,(a3)+ ; clear dbra d1,multiloop4\@ writeright4\@ or.l d3,(a0) ; set or.l d3,(a2) ; set not.l d3 ; invert and.l d3,(a1) ; clear and.l d3,(a3) ; clear finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR6 macro color6: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks or.l d3,(a1) ; set or.l d3,(a2) ; set not.l d3 ; invert and.l d3,(a0) ; clear and.l d3,(a3) ; clear bra.b finished4\@ doublewrite4\@ or.l d2,(a1)+ ; set or.l d2,(a2)+ ; set not.l d2 and.l d2,(a0)+ ; clear and.l d2,(a3)+ ; clear subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite\@ moveq.l #-1,d2 ; $ffffffff moveq.l #0,d4 ; zeroes multiloop4\@ move.l d2,(a1)+ ; set move.l d2,(a2)+ ; set move.l d4,(a0)+ ; clear move.l d4,(a3)+ ; clear dbra d1,multiloop4\@ writeright4\@ or.l d3,(a1) ; set or.l d3,(a2) ; set not.l d3 ; invert and.l d3,(a0) ; clear and.l d3,(a3) ; clear finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR7 macro color7: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks or.l d3,(a0) ; set or.l d3,(a1) ; set or.l d3,(a2) ; set not.l d3 ; invert and.l d3,(a3) ; clear bra.b finished4\@ doublewrite4\@ or.l d2,(a0)+ ; set or.l d2,(a1)+ ; set or.l d2,(a2)+ ; set not.l d2 and.l d2,(a3)+ ; clear subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite\@ moveq.l #-1,d2 ; $ffffffff moveq.l #0,d4 ; zeroes multiloop4\@ move.l d2,(a0)+ ; set move.l d2,(a1)+ ; set move.l d2,(a2)+ ; set move.l d4,(a3)+ ; clear dbra d1,multiloop4\@ writeright4\@ or.l d3,(a0) ; set or.l d3,(a1) ; set or.l d3,(a2) ; set not.l d3 ; invert and.l d3,(a3) ; clear finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR8 macro color8: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks or.l d3,(a3) ; set not.l d3 ; invert and.l d3,(a0) ; clear and.l d3,(a1) ; clear and.l d3,(a2) ; clear bra.b finished4\@ doublewrite4\@ or.l d2,(a3)+ ; set not.l d2 and.l d2,(a0)+ ; clear and.l d2,(a1)+ ; clear and.l d2,(a2)+ ; clear subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite\@ moveq.l #-1,d2 ; $ffffffff moveq.l #0,d4 ; zeroes multiloop4\@ move.l d2,(a3)+ ; set move.l d4,(a0)+ ; clear move.l d4,(a1)+ ; clear move.l d4,(a2)+ ; clear dbra d1,multiloop4\@ writeright4\@ or.l d3,(a3) ; set not.l d3 ; invert and.l d3,(a0) ; clear and.l d3,(a1) ; clear and.l d3,(a2) ; clear finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR9 macro color9: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks or.l d3,(a0) ; set or.l d3,(a3) ; set not.l d3 ; invert and.l d3,(a1) ; clear and.l d3,(a2) ; clear bra.b finished4\@ doublewrite4\@ or.l d2,(a0)+ ; set or.l d2,(a3)+ ; set not.l d2 and.l d2,(a1)+ ; clear and.l d2,(a2)+ ; clear subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite\@ moveq.l #-1,d2 ; $ffffffff moveq.l #0,d4 ; zeroes multiloop4\@ move.l d2,(a0)+ ; set move.l d2,(a3)+ ; set move.l d4,(a1)+ ; clear move.l d4,(a2)+ ; clear dbra d1,multiloop4\@ writeright4\@ or.l d3,(a0) ; set or.l d3,(a3) ; set not.l d3 ; invert and.l d3,(a1) ; clear and.l d3,(a2) ; clear finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR10 macro color10: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks or.l d3,(a1) ; set or.l d3,(a3) ; set not.l d3 ; invert and.l d3,(a0) ; clear and.l d3,(a2) ; clear bra.b finished4\@ doublewrite4\@ or.l d2,(a1)+ ; set or.l d2,(a3)+ ; set not.l d2 and.l d2,(a0)+ ; clear and.l d2,(a2)+ ; clear subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite\@ moveq.l #-1,d2 ; $ffffffff moveq.l #0,d4 ; zeroes multiloop4\@ move.l d2,(a1)+ ; set move.l d2,(a3)+ ; set move.l d4,(a0)+ ; clear move.l d4,(a2)+ ; clear dbra d1,multiloop4\@ writeright4\@ or.l d3,(a1) ; set or.l d3,(a3) ; set not.l d3 ; invert and.l d3,(a0) ; clear and.l d3,(a2) ; clear finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR11 macro color11: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks or.l d3,(a0) ; set or.l d3,(a1) ; set or.l d3,(a3) ; set not.l d3 ; invert and.l d3,(a2) ; clear bra.b finished4\@ doublewrite4\@ or.l d2,(a0)+ ; set or.l d2,(a1)+ ; set or.l d2,(a3)+ ; set not.l d2 and.l d2,(a2)+ ; clear subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite\@ moveq.l #-1,d2 ; $ffffffff moveq.l #0,d4 ; zeroes multiloop4\@ move.l d2,(a0)+ ; set move.l d2,(a1)+ ; set move.l d2,(a3)+ ; set move.l d4,(a2)+ ; clear dbra d1,multiloop4\@ writeright4\@ or.l d3,(a0) ; set or.l d3,(a1) ; set or.l d3,(a3) ; set not.l d3 ; invert and.l d3,(a2) ; clear finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR12 macro color12: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks or.l d3,(a2) ; set or.l d3,(a3) ; set not.l d3 ; invert and.l d3,(a0) ; clear and.l d3,(a1) ; clear bra.b finished4\@ doublewrite4\@ or.l d2,(a2)+ ; set or.l d2,(a3)+ ; set not.l d2 and.l d2,(a0)+ ; clear and.l d2,(a1)+ ; clear subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite\@ moveq.l #-1,d2 ; $ffffffff moveq.l #0,d4 ; zeroes multiloop4\@ move.l d2,(a2)+ ; set move.l d2,(a3)+ ; set move.l d4,(a0)+ ; clear move.l d4,(a1)+ ; clear dbra d1,multiloop4\@ writeright4\@ or.l d3,(a2) ; set or.l d3,(a3) ; set not.l d3 ; invert and.l d3,(a0) ; clear and.l d3,(a1) ; clear finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR13 macro color13: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks or.l d3,(a0) ; set or.l d3,(a2) ; set or.l d3,(a3) ; set not.l d3 ; invert and.l d3,(a1) ; clear bra.b finished4\@ doublewrite4\@ or.l d2,(a0)+ ; set or.l d2,(a2)+ ; set or.l d2,(a3)+ ; set not.l d2 and.l d2,(a1)+ ; clear subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite\@ moveq.l #-1,d2 ; $ffffffff moveq.l #0,d4 ; zeroes multiloop4\@ move.l d2,(a0)+ ; set move.l d2,(a2)+ ; set move.l d2,(a3)+ ; set move.l d4,(a1)+ ; clear dbra d1,multiloop4\@ writeright4\@ or.l d3,(a0) ; set or.l d3,(a2) ; set or.l d3,(a3) ; set not.l d3 ; invert and.l d3,(a1) ; clear finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR14 macro color14: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks or.l d3,(a1) ; set or.l d3,(a2) ; set or.l d3,(a3) ; set not.l d3 ; invert and.l d3,(a0) ; clear bra.b finished4\@ doublewrite4\@ or.l d2,(a1)+ ; set or.l d2,(a2)+ ; set or.l d2,(a3)+ ; set not.l d2 and.l d2,(a0)+ ; clear subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite\@ moveq.l #-1,d2 ; $ffffffff moveq.l #0,d4 ; zeroes multiloop4\@ move.l d2,(a1)+ ; set move.l d2,(a2)+ ; set move.l d2,(a3)+ ; set move.l d4,(a0)+ ; clear dbra d1,multiloop4\@ writeright4\@ or.l d3,(a1) ; set or.l d3,(a2) ; set or.l d3,(a3) ; set not.l d3 ; invert and.l d3,(a0) ; clear finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR15 macro color15: scanloop4\@ move.w (a4)+,d0 ; get minx move.w (a5)+,d1 ; get maxx cmp.w d0,d1 ; error check bmi.b finished4\@ move.w d0,d4 ; copy minx lsr.w #5,d4 ; get first long word lsl.w #2,d4 ; *4 = number of bytes adda.w d4,a0 ; add x offset to scanline lea PLANESIZE(a0),a1 lea PLANESIZE(a1),a2 lea PLANESIZE(a2),a3 move.w d0,d4 ; copy minx moveq.l #-1,d2 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count lsr.l d4,d2 ; shift mask by d4 pixels move.w d1,d4 ; copy maxx moveq.l #-1,d3 ; start mask, $ffffffff andi.w #$1f,d4 ; minx mod 31 = shift count neg.w d4 ; - d4 add.w #31,d4 ; d4 = 31 - d4 lsl.l d4,d3 ; shift mask by d4 pixels lsr.w #5,d0 ; get start long word lsr.w #5,d1 ; get end long word sub.w d0,d1 ; get width in long words bne.b doublewrite4\@ ; check for single write ; single write and.l d2,d3 ; combine left and right masks or.l d3,(a0) ; set or.l d3,(a1) ; set or.l d3,(a2) ; set or.l d3,(a3) ; set bra.b finished4\@ doublewrite4\@ or.l d2,(a0)+ ; set or.l d2,(a1)+ ; set or.l d2,(a2)+ ; set or.l d2,(a3)+ ; set subq.w #2,d1 ; subtract left and right writes bmi.b writeright4\@ ; don't do a multiwrite ; multiwrite\@ moveq.l #-1,d2 ; $ffffffff multiloop4\@ move.l d2,(a0)+ ; set move.l d2,(a1)+ ; set move.l d2,(a2)+ ; set move.l d2,(a3)+ ; set dbra d1,multiloop4\@ writeright4\@ or.l d3,(a0) ; set or.l d3,(a1) ; set or.l d3,(a2) ; set or.l d3,(a3) ; set finished4\@ add.l d5,d6 ; go to next scanline movea.l d6,a0 ; copy ptr to modify dbra d7,scanloop4\@ ; d7 = yheight-1. movem.l (sp)+,d2-d7/a2-a5 rts endm COLOR0 COLOR1 COLOR2 COLOR3 COLOR4 COLOR5 COLOR6 COLOR7 COLOR8 COLOR9 COLOR10 COLOR11 COLOR12 COLOR13 COLOR14 COLOR15 CNOP 0,4 ; longword align for 020/030 speed colorplanes: dc.l color0 dc.l color1 dc.l color2 dc.l color3 dc.l color4 dc.l color5 dc.l color6 dc.l color7 dc.l color8 dc.l color9 dc.l color10 dc.l color11 dc.l color12 dc.l color13 dc.l color14 dc.l color15 END SHAR_EOF fi # end of overwriting check # End of shell archive exit 0