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