Files
Arquivotheca.SunOS-4.1.4/usr.etc/gp/pp/vector.pp.u
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

754 lines
31 KiB
Plaintext

| "@(#)vector.pp.u 1.1 94/10/31 SMI"
| Copyright 1985 by Sun Microsystems, Inc.
| vector: Mimics the action of cg2_vec.c
| Please refer to cg2_vec.c and follow along.
#define pkptr r[25] /* used only in GP+ */
#define options r[24]
#define clip r[23]
#define reflect r[22]
#define ropmode r[21]
#define offsety r[20]
#define offsetx r[19]
#define sizey r[18]
#define sizex r[17]
#define clipptr r[16]
#define temp0 r[4]
#define x0 r[15]
#define y0 r[14]
#define x1 r[13]
#define y1 r[12]
#define dx r[11]
#define dy r[10]
#define hierr r[9] /* Double precision for early init error calculations. Not needed later. */
#define err r[8]
#define startx r[7]
#define starty r[6]
#define count r[5]
#define zbdc r[4] /* holds status of zbuffering and depth cueing */
#define addrlo r[0]
#define addrhi r[1]
#define nosetup 3
#define zbuf 1 /* these used only in GP+ */
#define dcue 0
#define pick 0
| Vector can be called from the pixrect level (0 has been stuffed into options field), or it can
| be called from the xfline level, where we have solid, width 1 vectors. In this case, a 0 has
| been loaded into r[24] for the first vector, but this register is not touched after that.
vector: ; SavePts->scrmemp; ; |
movw d, x0; fifo1->am; cjp, f1e .; |
movw d, y; am->scrmem; ; scrmp + |
movw d, y0; fifo1->am; cjp, f1e .; |
movw d, y; am->scrmem; ; scrmp + |
movw d, x1; fifo1->am; cjp, f1e .; |
movw d, y; am->scrmem; ; scrmp + |
rsubw d, x0, dx; ; ; | dx
movw d, y1; fifo1->am; cjp, f1e .; |
movw d, y; am->scrmem; ; |
#ifndef GPPLUS
rsubw d, y0, dy; ; ; | dy
#else GPPLUS
rsubw d, y0, dy; VecAtts->scrmemp; ; | dy. NEW (scrmemp load)
#endif
movw d, op; fifo1->am; cjp, f1e .; |
norw,s d, op, clip; 0xfffe->am; ; | (PIX_DONTCLIP == 1) => (clip == 0).
#ifndef GPPLUS
movw d, color; fifo1->am; cjp, f1e .; |
vec6: rolw 11, op, acc; ; ; | color in op?
#else GPPLUS
| Here we test if we are drawing z-buffered vectors, & if so, we yank the relevant z values from the fifo. It is
| important we do this here, as we loop through the rest of the code for each rectangle.
testw (d); scrmem->am; ; | NEW
movw d, color; fifo1->am; cjp, f1e .; |
vec6: rolw 11, op, acc; ; cjs,~zer vec3fetch; | color in op? Fetch z components if 3d vecs NEW
#endif GPPLUS
andw,s d, acc, acc; 0x7ff->am; ; |
sr0w op, op; ; cjp, zer vop0; | op >>= 1.
movw acc, color; ; ; |
vop0: andw d, op, op; 0xf->am; ; |
| PIXOP_NEEDS_DST (op<<1)= (op^(op<<1)) & 0xa
movw op, acc; ; ; |
sl0w acc, acc; ; ; |
xorw op, acc, acc; ClipList->scrmemp; ; | Get ready to get clipping rectangle.
movw d, clipptr; ClipList->am; ; |
andw,s d, acc, acc; 0xa->am; ; |
#ifndef GPPLUS
movw 0, nodst; ; cjp, ~zer vtr; |
#else GPPLUS
movw 0, nodst; ; cjp, ~zer ptvtr; |
#endif GPPLUS
incw 0, nodst; ; ; |
#ifdef GPPLUS
ptvtr: btstw,s pick,options; Pickmaybe->scrmemp; ; | test if picking is on
movw 0,y; am->scrmem; ; | Set pickmaybe (used for 3d) to zero
movw clipptr,y; am->scrmemp; cjp,~zer pkvtr; | reload scrmemp
#endif GPPLUS
| code will return to vtr (through vreset) after each clip rectangle.
vtr: testw (clip); ; ; | If no clipping, return from end of module (vreset)
movw,s d, offsetx; scrmem->am; cjp, zer vtrnclip; scrmp + | Transform screen coords to pixrect relative.
subw d, x0, x0; ; crtn, neg; | Neg == end of clip list.
subw d, x1, x1; ; ; |
movw d, offsety; scrmem->am; ; scrmp + |
subw d, y0, y0; ; ; |
subw d, y1, y1; ; ; |
movw d, sizex; scrmem->am; ; scrmp + |
movw d, sizey; scrmem->am; ; scrmp + |
#ifndef GPPLUS
add2nw 2, clipptr, clipptr; ; cjp, go vtrstat; |
vtrnclip: movw 0, offsetx; ; ; |
movw 0, offsety; ; ; |
movw d, sizex; SWidth->am; ; |
#else GPPLUS
vtrpk: add2nw 2, clipptr, clipptr; ; cjs, go vtrstat; |
vreset: testw (clip); SavePts->scrmemp; ; |
movw d, x0; scrmem->am; crtn, zer; scrmp + | if no clipping we are done.
movw d, y0; scrmem->am; ; scrmp + |
movw d, x1; scrmem->am; ; scrmp + |
rsubw d, x0, dx; ; ; |
movw d, y1; scrmem->am; ; scrmp + |
rsubw d, y0, dy; ; ; |
movw clipptr, y; am->scrmemp; cjp, go vtr; |
vtrnclip: movw d, sizex; SWidth->am; ; |
#endif GPPLUS
movw d, sizey; SHeight->am; ; |
#ifdef GPPLUS
movw 0, offsetx; ; ; |
movw 0, offsety; ; cjs,go vtrstat; |
; ; cjp,go vreset;
#endif GPPLUS
vtrstat: movw d, acc; vstreg->am; ; | Clear vme status register.
#ifdef GPPLUS
| Here we test for z-buffered and/or depth cued vectors. In this case, we don't special case short, horizontal
| or vertical vectors. We set up a register here (which lasts until our first multiply), which holds the status
| of these attributes.
; VecAtts->scrmemp; ; |
testw (d); scrmem->am; ; | test if zbuffering or depth cueing enabled
movw d,zbdc; ; cjp, ~zer vnshrt; | initialize gp+ register
#endif GPPLUS
| Handle vectors of length 1 or 2 by drawing endpoints. Check first for short vector.
incw,s dx, acc; =vnshrt->brreg; ; | Compare absolute value dx with 1.
| Incw takes care of dx == -1. Thus we compare with 2.
rsubw,s d, acc, y; 2->am; cjp, neg; | vector is not short.
incw,s dy, acc; ; cjp, neg; |
rsubw,s d, acc, y; 2->am; cjp, neg; |
btstw,s nosetup,options; =vropset1->brreg; cjp, neg; |
testw (nodst); ; cjp, ~zer vsdraw; | Jump if no rasterop setup nec.
movw GPVWord,y; ; cjp, ~vir .; |
IMM; am->vctlreg; cjs, go vropseta; | Set up rasterop chips.
vsropdone: romw 8, color, acc, 0xff00; ; ; | instruction completes on next cycle.
IMM; FBAllRopPrimeSrc1->vloareg; ; | vhiareg unchanged.
movw acc, y; am->vwdreg; cjp, ~vir .; vmewr |
vsdraw: ; ; cjp, ~vir .; | must set rop chips after short.
movw,s x0, acc; VByte->vctlreg; ; |
subw,s sizex, acc, y; ; cjp, neg vschk2; | if (pos0.x >= size.x) check 2nd endpoint.
movw,s y0, acc; ; cjp, ~neg vschk2; |
subw,s sizey, acc, y; ; cjp, neg vschk2; | if (pos0.y >= size.y)
movw offsety, acc; ; cjp, ~neg vschk2; | first endpt clipped out.
addw y0, acc, Multiplier; ; cjs, go MulSWid; | cg2_roppixel (dmd, pos0.x, pos0.y)
movw offsetx, acc; ; ; |
addw x0, acc, acc; ; cjs, go vcompvme; |
movw color, y; am->vwdreg; cjp, ~vir .; vmewr |
vschk2: movw dx, acc; ; ; |
orw,s dy,acc,y; ; ; |
#ifndef GPPLUS
vschk2a: movw,s x1, acc; ; cjp, zer vreset; |
subw,s sizex, acc, y; ; cjp, neg vreset; | if (pos1.x >= size.x)2nd endpt clipped.
movw,s y1, acc; ; cjp, ~neg vreset; |
subw,s sizey, acc, y; ; cjp, neg vreset; | if (pos1.y >= size.y)2nd endpt clipped.
movw offsety, acc; ; cjp, ~neg vreset; |
#else GPPLUS
vschk2a: movw,s x1, acc; ; crtn, zer; |
subw,s sizex, acc, y; ; crtn, neg; | if (pos1.x >= size.x)2nd endpt clipped.
movw,s y1, acc; ; crtn, ~neg; |
subw,s sizey, acc, y; ; crtn, neg; | if (pos1.y >= size.y)2nd endpt clipped.
movw offsety, acc; ; crtn, ~neg; |
#endif GPPLUS
addw y1, acc, Multiplier; ; cjs, go MulSWid; | cg2_roppixel (dmd, pos1.x, pos1.y)
movw offsetx, acc; ; ; |
addw x1, acc, acc; ; cjs, go vcompvme; |
movw color, y; am->vwdreg; cjp, ~vir .; vmewr |
#ifndef GPPLUS
; ; cjp, go vreset; |
#else GPPLUS
; ; crtn, go; |
#endif GPPLUS
| Not a short vector. Force vector to have increasing x.
| Limits number of octants to 4.
vnshrt: testw (dx); ; ; | Test dx.
movw 0, reflect; ; cjp, ~neg vnoswap; | reflect= 0.
movw x0, acc; ; ; |
movw x1, x0; ; ; | Swap x.
movw acc, x1; ; ; |
movw y0, acc; ; ; | Swap y.
movw y1, y0; ; ; |
movw acc, y1; ; ; |
negw dx, dx; ; ; | dx= -dx.
negw dy, dy; ; ; | dy= -dy.
| Clipper works with y positive going. If needed, reflect
| vector around the centerline. Remember this in the reflect
| variable so it can be undone later.
vnoswap:testw (dy); ; ; |
testw (y1); ; cjp, ~neg vbound; | Set y1 cc for vbound
negw dy, dy; ; ; |
subw d, sizey, acc; 1->am; ; | size.y-1
subw y0, acc, y0; ; ; | pos0.y= (size.y-1) - pos0.y.
subw,s y1, acc, y1; ; ; | pos1.y= (size.y-1) - pos1.y.
addw d, reflect, reflect;2->am; ; | reflect += 2
| Bounds check for vector ending before rectangle or starting after.
#ifndef GPPLUS
vbound: testw (x1); ; cjp, neg vreset; | if (pos1.y < 0 || pos1.x < 0)
movw x0, acc; ; cjp, neg vreset; |
#else GPPLUS
vbound: testw (x1); ; crtn, neg; | if (pos1.y < 0 || pos1.x < 0)
movw x0, acc; ; crtn, neg; |
#endif GPPLUS
subw,s sizex, acc, y; ; ; | || pos0.x >= size.x
#ifndef GPPLUS
movw y0, acc; ; cjp, ~neg vreset; |
#else GPPLUS
movw y0, acc; ; crtn, ~neg; |
#endif GPPLUS
subw,s sizey, acc, y; ; ; | || pos0.y >= size.y
| If vector horizontal use fast algorithm.
#ifndef GPPLUS
vhor: testw (dy); ; cjp, ~neg vreset; |
#else GPPLUS
vhor: testw (dy); ; crtn, ~neg; |
#endif GPPLUS
movw,s dx, acc; ; cjp, ~zer vvert; | Set cc for vert test.
#ifdef GPPLUS
testw (zbdc); ; ; | check if drawing zb or dc vectors
movw,s dx, acc; ; cjp, ~zer vdxdy; | don't special case if true
#endif GPPLUS
movw FBCont,y; am->vhiareg; cjp, ~vir .; | Wait till vctlreg ready.
; GPVWord->vctlreg; ; |
; RRValues->scrmemp; ; |
subw,s d, op, y; scrmem->am; ; |
movw op, y; am->scrmem; cjp, zer vhpatt0; scrmp + |
; FBAllRopRegOp->vloareg;; | vhiareg unchanged.
movw op, y; am->vwdreg; cjp, ~vir .; vmewr | cg2_setfunction (..., op).
vhpatt0: ; FBAllRopRegPatt->vloareg; ; | vhiareg unch.
movw,s d, y; scrmem->am; ; |
movw 0, y; am->scrmem; cjp, zer vhpatt1; scrmp + |
movw 0, y; am->vwdreg; cjp, ~vir .; vmewr |
vhpatt1: testw (x0); am->am; ; | if (pos0.x >= 0)
movw sizex, acc; ; cjp, ~neg vhx1; |
movw 0, x0; am->am; ; | pos0.x= 0
vhx1: rsubw,s x1, acc, y; ; ; | if (pos1.x >= size.x)
decw acc; ; cjp, neg vhdx; | pos1.x= size.x - 1
movw acc, x1; ; cjp, go vhdx1; |
vhdx: movw x1, acc; ; ; |
vhdx1: subw d, x1, dx; ; ; | dx= pos1.x - pos0.x
movw d, r[0]; scrmem->am; ; |
addw offsetx, acc, acc; FBAllRopRegMask2->vloareg;; | cg2_prd_skew (dmd, pos1.x). vhiareg unchanged.
andw d, acc, count; 0xf->am; ; | count= cg2_prd_skew
addw d, count, acc; RMaskTable->am; ; | rmasktable [count]
movw acc, y; am->scrmemp; ; |
subw,s d, r[0], y ; scrmem->am; ; |
movw x0, acc; ; cjp, zer vhm1; |
movw d, r[0]; scrmem->am; ; |
; RRValm2->scrmemp; ; |
movw r[0], y; am->scrmem; ; |
movw r[0], y; am->vwdreg; cjp, ~vir .; vmewr |
vhm1: addw offsetx, acc, acc; FBAllRopRegMask1->vloareg; ; | cg2_prd_skew (dmd, pos0.x) vhiareg unchanged.
andw d, acc, count; 0xf->am; ; | count= cg2_prd_skew
addw d, count, acc; LMaskTable->am; ; |
movw acc, y; am->scrmemp; ; |
movw d, r[0]; scrmem->am; ; |
; RRValm1->scrmemp; ; |
subw,s d, r[0], y; scrmem->am; ; |
movw r[0], y; am->scrmem; cjp, zer vhrm; scrmp + |
movw r[0], y; am->vwdreg; cjp, ~vir .; vmewr |
vhrm: testw (nodst); PRRWRD->am; ; |
movw d, ropmode; ; cjp, ~zer vhropmode; | if (nodst) ropmode= PRRWRD
movw d, ropmode; PWRWRD->am; ; | else ropmode= PWRWRD
vhropmode:movw d, acc; PWRWRD->am; ; |
; ; cjs, go vropmode; |
movw dx, acc; ; ; | count= (dx+count)>>4. (>>4 == <<12).
addw count, acc, count; 0xfff->am; ; |
rolw 12, count, count; FBAllRopRegWidth->vloareg;; | vhiareg unchanged. mask off high bits of rotate.
andw d, count, count; ; ; |
subw,s d, count, y; scrmem->am; ; |
movw count, y; am->scrmem; cjp, zer vhcnt; scrmp + |
movw count, y; am->vwdreg; cjp, ~vir .; vmewr | 1st 1/2 cg2_setwidth (..., count, count).
vhcnt: ; FBAllRopRegOpCnt->vloareg; ; | vhiareg unchanged.
subw,s d, count, y; scrmem->am; ; |
movw count, y; am->scrmem; cjp, zer vhsh; scrmp + |
movw count, y; am->vwdreg; cjp, ~vir .; vmewr | 2nd 1/2 cg2_setwidth (..., count, count).
vhsh: ; FBAllRopRegShift->vloareg; ; | vhiareg unchanged.
sub2nw,s 8, d, y; scrmem->am; ; |
mov2nw 8, y; am->scrmem; cjp, zer vhsrc2a; scrmp + |
mov2nw 8, y; am->vwdreg; cjp, ~vir .; vmewr | cg2_setshift (..., 0, 1).
vhsrc2a: movw color, acc; ; ; |
romw 8, color, acc, 0xff00;; ; | instruction completes on next cycle.
IMM; FBAllRopPrimeSrc2->vloareg;; | vhiareg unchanged.
movw acc, y; am->vwdreg; cjp, ~vir .; vmewr |
movw offsety, acc; ; ; |
addw y0, acc, Multiplier;; cjs, go MulSWWid; | cg2_ropword (dmd, 0, pos0.x, pos0.x)
movw offsetx, acc; ; ; |
addw x0, acc, x0; ; ; |
rolw 13, x0, acc; ; ; | cg2_ropword: (x>>4)*(sizeof(short))
andw d, acc, acc; 0x1fff->am; ; | a5_adr= cg2_ropword
addw addrlo, acc, addrlo;am->vloareg; ; |
addcw d, FBHi, acc; RopFB->am; ; |
addw addrhi, acc, addrhi;am->vhiareg; ; |
| switch (d5_count) unwrapped. nodst part separated out.
vhcolor:testw (nodst); ; ; |
movw count, y; am->brreg; cjp, ~zer vhnodst; |
; ; push, go; |
movw color, y; am->vwdreg; cjp, ~vir .; vmewr | value written is immaterial.
; ; ; varegs +|
; ; rfct; varegs +|
#ifndef GPPLUS
bclrw nosetup,options; ; cjp, go vreset; | Must setup rop chips after hor.
#else GPPLUS
bclrw nosetup,options; ; crtn, go; | Must setup rop chips after hor.
#endif GPPLUS
vhnodst:subw,s d, count, y; 2->am; ; |
testw (count); ; cjp, ~neg vh2; |
movw color, y; am->vwdreg; cjp, ~vir .; vmewr |
#ifndef GPPLUS
bclrw nosetup,options; ; cjp, zer vreset; varegs +| Must setup rop chips after hor.
#else GPPLUS
bclrw nosetup,options; ; crtn, zer; varegs +| Must setup rop chips after hor.
#endif GPPLUS
; ; ; varegs +|
; ; cjp, ~vir .; vmewr |
#ifndef GPPLUS
; ; cjp, go vreset; |
#else GPPLUS
; ; crtn, go; |
#endif GPPLUS
vh2: movw FBCont, y; am->vhiareg; ; |
mov2nw 1, acc; FBAllRopRegWidth->vloareg; ; |
; RRValWid->scrmemp; ; |
sub2nw,s 1, d, y; scrmem->am; ; |
mov2nw 1, y; am->scrmem; cjp, zer vhcnt1; scrmp + |
movw acc, y; am->vwdreg; cjp, ~vir .; vmewr | 1st 1/2 cg2_setwidth (..., 2, 2).
vhcnt1: ; FBAllRopRegOpCnt->vloareg; ; | vhiareg unchanged.
sub2nw,s 1, d, y; scrmem->am; ; |
mov2nw 1, y; am->scrmem; cjp, zer vhcol0; scrmp + |
vhcount1:movw acc, y; am->vwdreg; cjp, ~vir vhcount1; vmewr | 2nd 1/2 cg2_setwidth (..., 2, 2).
vhcol0: movw addrlo, y; am->vloareg; ; |
movw addrhi, y; am->vhiareg; ; |
vhcol1: movw color, y; am->vwdreg; cjp, ~vir vhcol1; vmewr | *(a5_adr)++= d3_color (value is immaterial)
; ; ; varegs +|
; ; ; varegs +|
vhcol2:; ; cjp, ~vir vhcol2; vmewr | *(a5_adr)++= d3_color (value is immaterial)
subw,s d, count, count; 3->am; ; varegs +| count less 3 so "fastloop" right num
; ; cjp, neg vhvmewr3; varegs +|
movw ropmode, acc; ; cjs, go vropmode; |
addw,s d, addrlo, addrlo;4->am; ; | Sync addrlo with vme addr counter.
movw addrlo, y; am->vloareg; cjp, ~cry vhncry1; |
incw addrhi, addrhi; ; ; | Sync addrhi with vme addr counter.
vhncry1:movw count, y; am->brreg; ; | Get ready to load counter.
movw addrhi, y; am->vhiareg; push, go; |
movw color, y; am->vwdreg; cjp, ~vir .; vmewr | (value is immaterial)
; ; ; varegs +|
; PWRWRD->am; rfct; varegs +|
movw d, acc; ; cjs, go vropmode; |
sl0w count, temp0; ; ; |
addw,s d, temp0, acc; 2->am; ; |
addw,s addrlo, acc, addrlo;am->vloareg; cjp, ~cry vhvmewr2; |
incw addrhi, y; ; ; |
vhvmewr2:movw addrhi, y; am->vhiareg; cjp, ~cry vhvmewr3; |
incw addrhi, y; am->vhiareg; ; |
vhvmewr3: movw 0, y; am->vwdreg; cjp, ~vir .; vmewr | (value is immaterial)
#ifndef GPPLUS
bclrw nosetup,options; ; cjp, go vreset; |
#else GPPLUS
bclrw nosetup,options; ; crtn, go; |
#endif GPPLUS
| If vector is vertical use fast algorithm.
#ifndef GPPLUS
vvert: btstw,s nosetup,options; ; cjp, ~zer vdxdy; | Jump if dx != 0 (cc set earlier).
#else GPPLUS
vvert: testw (zbdc); ; cjp,~zer vdxdy; | check if drawing zb or dc vectors
btstw,s nosetup,options; ; cjp,~zer vdxdy; | don't special case if true
#endif GPPLUS
; ; cjp, ~zer vvclip; | Jump if no rasterop chip setup nec.
; ; cjs, go vropset; | Set up rasterop chips.
vvropdone: romw 8, color, acc, 0xff00; ; ; | instruction completes on next cycle.
IMM; FBAllRopPrimeSrc1->vloareg;; | vhiareg unchanged.
movw acc, y; am->vwdreg; cjp, ~vir .; vmewr |
vvclip: testw (y0); ; ; | Test (pos0.y < 0)
movw y1, acc; ; cjp, ~neg vvclip1; |
movw 0, y0; ; ; | if (pos0.y < 0) pos0.y= 0.
vvclip1: subw,s sizey, acc, y; 1->am; ; | if (pos1.y >= size.y)
subw d, sizey, acc; ; cjp, neg vvclip2; | pos1.y= size.y - 1.
movw acc, y1; ; cjp, go vvclip3; |
vvclip2:movw y1, acc; ; ; |
vvclip3: subw y0, acc, dy; =vvnorefl->brreg; ; | dy= pos1.y - pos0.y
andw,s d, reflect, y; 2->am; ; | if (reflect & 2)
subw d, sizey, acc; 1->am; cjp, zer; | size.y - 1
subw y1, acc, y0; ; ; | pos0.y= size.y - 1 - pos1.y.
vvnorefl:movw offsety, acc; ; cjp, ~vir vvnorefl; |
addw y0, acc, Multiplier;; cjs, go MulSWid; | cg2_roppixel (dmd, pos0.x, pos0.y)
movw offsetx, acc; VByte->vctlreg; ; |
addw x0, acc, acc; ; cjs, go vcompvme; | cg2_roppixel
movw dy, y; am->brreg; ; | Prepare to load counter.
movw d, acc; SWidth->am; ; | SWidth= cg2_linebytes.
movw 0, y; am->am; push, go; | Push loop, ld cntr.
vvvmewr:movw color, y; am->vwdreg; cjp, ~vir vvvmewr; vmewr | cg2_vertln ().
addw addrlo, acc, addrlo;am->vloareg; ; |
addcw d, addrhi, addrhi;am->vhiareg; rfct; |
#ifndef GPPLUS
; ; cjp, go vreset; |
#else GPPLUS
; ; crtn, go; |
#endif GPPLUS
| One more reflection. Note that dx in acc from horizontal test.
#ifndef GPPLUS
vdxdy: subw,s dy, acc, y; ; ; |
#else GPPLUS
vdxdy: movw d,pkptr; =vclipdraw->am; ;
vvdxdy: subw,s dy, acc, y; ; ; |
#endif GPPLUS
movw x0, acc; ; cjp, ~neg viniterr; | if (dx < dy) swap (x0, y0)
movw y0, x0; ; ; |
movw acc, y0; ; ; |
movw x1, acc; ; ; | Swap (x1, y1)
movw y1, x1; ; ; |
movw acc, y1; ; ; |
movw dy, dx; ; ; | dy = dx
subw y0, acc, dy; ; ; | Recompute dy (saves a cycle).
movw sizex, acc; ; ; | Swap (size.x, size.y).
movw sizey, sizex; ; ; |
movw acc, sizey; ; ; | Swap complete.
incw reflect, reflect; ; ; | reflect += 1.
viniterr:sr0w dx, err; ; ; | initerror= -(dx >> 1).
negw,s err, err; ; ; |
compw 0, hierr; ; cjp, ~cry vierr1; |
incw hierr, hierr; ; ; |
vierr1: movw,s x0, startx; ; ; | start= pos0.
movw y0, starty; ; ; |
negw startx, Mulcand; ; cjp, ~neg vadvy; | initerr += -start.x * dy.
movw dy, Multiplier; ; cjs, go multiply; | pr_product
movw HiRslt, acc; ; ; | double precision add.
movw LoRslt, y; am->am; ; |
addw d, err, err; ; ; |
addcw hierr, acc, hierr;; ; |
movw 0, startx; ; ; | start.x= 0.
decw dx, temp0; am->am; ; | count= (initerr + (dx-1)) / dx.
addw d, err, DLow; ; ; | double precision add.
addcw d, hierr, DHigh; 0->am; ; |
movw dx, Dvsr; ; cjs, go divlong; |
movw QLow, count; ; ; |
movw starty, acc; ; ; |
addw count, acc, starty;; ; | start.y += count.
movw count, Mulcand; ; ; | initerr -= count * dx.
movw dx, Multiplier; ; cjs, go multiply; | pr_product
movw HiRslt, y; am->am; ; |
movw LoRslt, acc; ; ; |
rsubw err, acc, err; ; ; |
subcw d, hierr, hierr; ; ; |
vadvy: movw starty, acc; ; ; |
subw,s sizey, acc, y; ; ; | if (start.y >= size.y)
#ifndef GPPLUS
movw,s starty, Multiplier; ; cjp, ~neg vreset; | if (start.y < 0)...
#else GPPLUS
movw,s starty, Multiplier; ; crtn, ~neg; | if (start.y < 0)...
#endif GPPLUS
movw x1, acc; ; cjp, ~neg vcliprt; | initerr += start.y * dx.
movw dx, Mulcand; ; cjs, go multiply; | pr_product
movw LoRslt, acc; ; ; | double precision add.
movw HiRslt, y; am->am; ; |
addw err, acc, err; ; ; |
addcw d, hierr, hierr; ; ; |
vadvy1: movw 0, starty; ; ; | start.y= 0.
movw dy, acc; ; ; |
subw,s dx, acc, acc; ; ; | count= ((dy-dx)-initerr) / dy.
movw 0, y; am->am; cjp, ~neg vadvy1a; | d and acc (low) form (dy-dx).
compw 0, y; am->am; ; |
vadvy1a:subw err, acc, DLow; ; ; | double precision subtract.
rsubcw d, hierr, DHigh; ; ; |
movw dy, Dvsr; ; cjs, go divlong; |
movw QLow, count; am->am; ; |
addw d, startx, startx; ; ; | start.x += count.
movw dy, Mulcand; ; ; | initerr += count * dy.
movw count, Multiplier; ; cjs, go multiply; | pr_product
movw LoRslt, acc; ; ; | double precision add.
movw HiRslt, y; am->am; ; |
addw err, acc, err; ; ; |
addcw d, hierr, hierr; ; ; |
vadvy3: movw startx, acc; ; ; |
subw,s sizex, acc, y; ; ; | if (startx >= size.x)...
#ifndef GPPLUS
movw x1, acc; ; cjp, ~neg vreset; |
#else GPPLUS
movw x1, acc; ; crtn, ~neg; |
#endif GPPLUS
vcliprt: subw,s sizex, acc, y; 1->am; ; | if (pos1.x >= size.x)...
subw d, sizex, acc; ; cjp, neg vlasty; | pos1.x= size.x - 1.
movw acc, x1; ; ; |
subw x0, acc, Mulcand; ; ; | (size.x-1) - pos0.x
movw dy, Multiplier; ; cjs, go multiply; | pr_product (..., dy).
sr0w dx, temp0; am->am; ; | acc= (dx - dx>>1 - 1). temp0 is junk.
subw d, dx, acc; ; ; |
decw acc; ; ; | dx > 0 so that acc >= 0, and high acc = 0.
addw LoRslt, acc, DLow; ; ; | double precision add: prod + (dx - dx>>1 - 1).
addcw d, HiRslt, DHigh; 0->am; ; |
vcliprt2:movw dx, Dvsr; ; cjs, go divlong; | / dx
movw y0, acc; ; ; |
addw QLow, acc, y1; ; ; | pos1.y= pos0.y + (...) / dx.
vlasty: movw y1, acc; ; ; |
subw,s sizey, acc, y; ; ; | if (pos1.y >= size.y)...
decw sizey, ropmode; am->am; cjp, neg vclipdone; | pos1.y= size.y - 1. ropmode junk reg for am->am.
movw d, y1; ; ; |
rsubw d, y0, Mulcand; ; ; | (size.y-1) - pos0.y
movw dx, Multiplier; ; cjs, go multiply; | pr_product (..., dx).
sr0w dx, temp0; am->am; ; | dx>>1. temp0 junk (can't use acc).
addw d, LoRslt, DLow; ; ; | + (dx>>1). double precision add.
addcw d, HiRslt, DHigh; 0->am; ; |
vlasty0:movw dy, Dvsr; ; cjs, go divlong; | / dy.
movw x0, acc; ; ; |
addw QLow, acc, x1; ; ; | pos1.x= pos0.x + (...) / dy.
#ifndef GPPLUS
vclipdone: btstw,s nosetup,options; ; ; |
movw x1, acc; =vropset1->brreg; ; | Test if rop chips need setup.
#else GPPLUS
vclipdone: movw pkptr,y; am->brreg; ; | resulting vector will be drawn
btstw,s nosetup,options; ; cjp,go; | continue or return to pick routine
vclipdraw: movw x1, acc; =vropset1->brreg; ; | Test if rop chips need setup.
#endif GPPLUS
subw startx, acc, count; ; cjp, ~zer vcolor; | count= pos1.x-start.x. Jump if chips rop chips ok.
#ifdef GPPLUS
; VecAtts->scrmemp; ; |
testw (d); scrmem->am; ldct v3dummy; | test if z buffering enabled
testw (nodst); ; jsrp,zer vropseta; | call subroutine if z buf disabled
#else
testw (nodst); ; cjs, go vropseta; | Set up rasterop chips.
#endif GPPLUS
vropdone: romw 8, color, acc, 0xff00; ; ; | instruction completes on next cycle.
IMM; FBAllRopPrimeSrc1->vloareg;; | vhiareg unchanged.
movw acc, y; am->vwdreg; cjp, ~vir .; vmewr |
vcolor: movw color, y; am->vwdreg; cjp, ~vir .; | load vwdreg for bresenham loop but don't write.
btstw,s 0, reflect; VByte->vctlreg; ; | if (reflect & 1), 3d returns to here
vcdumret: btstw,s 1, reflect; ; cjp, zer vmajx; | if (reflect & 2)
movw sizex, acc; ; cjp, zer vmajy; |
decw acc; ; ; |
subw startx, acc, startx;; ; | start.x= ((size.x-1) - start.x).
vmajy: movw offsety, acc; ; ; |
addw startx, acc, Multiplier;; cjs, go MulSWid; | cg2_roppixel (..., start.x).
movw offsetx, acc; ; ; |
addw starty, acc, acc; ; cjs, go vcompvme; | cg2_roppixel (..., start.y, ...).
| Bump error so that test in octant is as if it were done after adding dy.
#ifdef GPPLUS
| Test for Z buffered lines. If necessary, we will have to advance the z values based on
| our clipping results.
; VecAtts->scrmemp; ; |
testw (d); scrmem->am; ; | NEW, CHECK NEXT LINE !!!
; ; cjs,~zer vec3yjmap; | haven't reflected back y, jump if z buffering is on NEW
#endif GPPLUS
subw d, err, acc; 1->am; ; |
addw dy, acc, acc; ; ; | We can only directly test err >= 0 not err > 0.
movw dy, r[3]; am->am; ; |
rsubw d, dx, r[4]; ; ; |
#ifndef GPPLUS
movw count, r[2]; ; ; |
movw reflect, y; am->am; ; |
movw d, r[5]; ; cjs, go octant; |
; ; cjp, go vreset; |
#else GPPLUS
movw count, r[2]; VecAtts->scrmemp; ; |
testw (d); scrmem->am; ; | test if zbuf, depth cueing or both on
movw reflect, y; am->am; ldct zbdcjmap; |
movw d,r[5]; ; jrp,zer octant; | octant if off, z buff octant if on
#endif GPPLUS
vmajx: movw sizey, acc; ; cjp, zer vmajx1; |
decw acc; ; ; |
subw starty, acc, starty;; ; | start.x= ((size.x-1) - start.x).
vmajx1: movw offsety, acc; ; ; |
addw starty, acc, Multiplier;; cjs, go MulSWid; | cg2_roppixel (..., start.x).
movw offsetx, acc; ; ; |
addw startx, acc, acc; ; cjs, go vcompvme; | cg2_roppixel (..., start.y, ...).
#ifdef GPPLUS
| Test for Z buffered lines. If necessary, we will have to advance the z values based on
| our clipping results.
; VecAtts->scrmemp; ; |
testw (d); scrmem->am; ; | NEW
; ; cjs,~zer vec3xjmap; | jump if z buffering is on NEW
#endif GPPLUS
subw d, err, acc; 1->am; ; | Subtract 2 from error.
addw dy, acc, acc; ; ; | We can only directly test err >= 0 not err > 0.
movw dy, r[3]; am->am; ; |
rsubw d, dx, r[4]; ; ; |
#ifndef GPPLUS
| Bump error so that test in octant is as if it were done after adding dy.
movw count, r[2]; ; ; |
movw reflect, y; am->am; ; |
movw d, r[5]; ; cjs, go octant; |
#else GPPLUS
movw count, r[2]; VecAtts->scrmemp; ; |
testw (d); scrmem->am; ; | test if zbuf, depth cueing or both on
movw reflect, y; am->am; ldct zbdcjmap; |
movw d,r[5]; ; jrp,zer octant; | octant if off, z buff octant if on
#endif GPPLUS
#ifndef GPPLUS
vreset: testw (clip); SavePts->scrmemp; ; |
movw d, x0; scrmem->am; crtn, zer; scrmp + | if no clipping we are done.
movw d, y0; scrmem->am; ; scrmp + |
movw d, x1; scrmem->am; ; scrmp + |
rsubw d, x0, dx; ; ; |
movw d, y1; scrmem->am; ; scrmp + |
rsubw d, y0, dy; ; ; |
movw clipptr, y; am->scrmemp; cjp, go vtr; |
#endif GPPLUS
#ifdef GPPLUS
| vec3fetch grabs the z0hi,z0lo,z1hi,z1lo,dzhi, and dzlo components from the fifo, and stores them in scrmem, in a location
| with the same function as SavePts has in the vector code.
vec3fetch:
movw ZSavePts,y; ; ; | load scrmemp with address for z parameters
IMM; am->scrmemp; ldct 9; | will loop 6 times
; fifo1->am; cjp,f1e .; | z0hi,z0lo,z1hi,z1lo,dzhi,dzlo,chi,clo,dchi,dclo
movw d,y; am->scrmem; rpct .-1; scrmp+ |
; ; crtn,go; |
zbdcjmap:
btstw,s zbuf,d; scrmem->am; ; |
; ; cjp,zer dcjmap; |
zbjmap: ; ; jmap zboctant; | zbuffer, depth cue code resides on 2nd bank
dcjmap: ; ; jmap dcoctant; |
zbquit_pp: ; ; crtn,go; |
vec3xjmap:
; ; jmap vec3majx; | 3d vector clipping code is on other bank
vec3yjmap:
; ; jmap vec3majy; | 3d vector clipping code is on other bank
v3quit_pp: ; ; crtn,go; |
v3dummy: ; ; cjp,~vir .; |
btstw,s 0,reflect; VByte->vctlreg; ; |
; ; cjpp,go vcdumret; |
#endif GPPLUS
| Vropset does the rasterop chip initialization for single pixel fb accesses. It is called by all but
| the horizontal case for the vector code, and is called in all cases by the textured vector code.
| We return from here with the color in the accumulator. Note also that the code for vropmode has
| been folded in here to save 2 cycles.
vropset: testw (nodst); =vropset1->brreg; ; |
vropseta: movw d, acc; SWWPIX->am; cjp, zer; | if PIXOP_NEEDS_DST (op<<1)
movw d, acc; SRWPIX->am; ; |
vropset1: rolw 3, acc, acc; FBStatus->vloareg; ; | Rotate is 3 bits.
movw FBCont, y; am->vhiareg; cjp, ~vir .; | wait until vme interface idle
; GPVWord->vctlreg; ; |
vropset2: ; ; cjp, ~vir .; vmerd | read status word.
movw d, r[2]; vrdreg->am; cjp, ~vir .; |
andw d, r[2], r[2]; 0xffc7->am; ; | 0x38 is mask to cover 3 bits.
orw r[2], acc, r[2]; am->vwdreg; cjp, ~vir .; vmewr | write status word.
bsetw nosetup,options; RRValues->scrmemp; ; |
subw,s d, op, y; scrmem->am; ; |
movw op, y; am->scrmem; cjp, zer vrpatt; scrmp + |
; FBAllRopRegOp->vloareg;; |
movw op, y; am->vwdreg; cjp, ~vir .; vmewr | cg2_setfunction (..., op).
vrpatt: ; FBAllRopRegPatt->vloareg; ; | vhiareg unch. Acc used 2 cycles later
testw (d); scrmem->am; ; |
movw 0, y; am->scrmem; cjp, zer vrmask2; scrmp + |
movw 0, y; am->vwdreg; cjp, ~vir .; vmewr |
vrmask2: ; FBAllRopRegMask2->vloareg; ; | vhiareg unchanged.
testw (d); scrmem->am; ; |
movw 0, y; am->scrmem; cjp, zer vrmask1; scrmp + |
movw 0, y; am->vwdreg; cjp, ~vir .; vmewr |
vrmask1: ; FBAllRopRegMask1->vloareg; ; | vhiareg unchanged.
testw (d); scrmem->am; ; |
movw 0, y; am->scrmem; cjp, zer vrwidth; scrmp + |
movw 0, y; am->vwdreg; cjp, ~vir .; vmewr |
vrwidth: ; FBAllRopRegWidth->vloareg; ; | vhiareg unchanged.
testw (d); scrmem->am; ; |
movw 0, y; am->scrmem; cjp, zer vropcnt; scrmp + |
movw 0, y; am->vwdreg; cjp, ~vir .; vmewr | half of cg2_setwidth (..., 0, 0).
vropcnt: ; FBAllRopRegOpCnt->vloareg; ; | vhiareg unchanged.
testw (d); scrmem->am; ; |
movw 0, y; am->scrmem; cjp, zer vrshft; scrmp + |
movw 0, y; am->vwdreg; cjp, ~vir .; vmewr | other half of cg2_setwidth (..., 0, 0).
vrshft: ; FBAllRopRegShift->vloareg; ; | vhiareg unchanged.
sub2nw,s 8, d, y; scrmem->am; ; |
mov2nw 8, y; am->scrmem; cjp, zer vrret; scrmp + |
mov2nw 8, y; am->vwdreg; cjp, ~vir .; vmewr | cg2_setshift (..., 0, 1).
vrret: movw color,acc; ; crtn, go; |
| vropmode subroutine: fb->status.reg.ropmode= acc. Uses r[2]. Assumes that high 13 bits of acc are zero.
| Assumes that the vme control word has been set to Word Mode (GPVWord->vctlreg).
vropmode: rolw 3, acc, acc; FBStatus->vloareg; ; | Rotate is 3 bits.
movw FBCont, y; am->vhiareg; ; |
; ; cjp, ~vir .; vmerd | read status word.
movw d, r[2]; vrdreg->am; cjp, ~vir .; |
andw d, r[2], r[2]; 0xffc7->am; ; | 0x38 is mask to cover 3 bits.
orw r[2], acc, r[2]; am->vwdreg; cjp, ~vir .; vmewr | write status word.
; ; crtn, go; |
| vcompvme: completes vme address calculation: addr + acc + FBHi + RopFB.
| Input: addrlo low address.
| addrhi high address.
| acc value such as x to be added in.
| Uses no other registers.
| Output: addrlo low address.
| addrhi high address.
| vloareg
| vhiareg
vcompvme:addw,s addrlo, acc, addrlo;am->vloareg;; |
vcompv: addw d, FBHi, acc; RopFB->am; ; |
addw addrhi, acc, addrhi;am->vhiareg; crtn, ~cry; |
incw addrhi, addrhi; am->vhiareg; crtn, go; |
#undef options
#undef clip
#undef reflect
#undef offsetx
#undef offsety
#undef ropmode
#undef x0
#undef y0
#undef x1
#undef y1
#undef dx
#undef dy
#undef hierr
#undef err
#undef starty
#undef startx
#undef sizey
#undef sizex
#undef count
#undef addrlo
#undef addrhi
#undef clipptr
#undef pkptr
#undef temp0
#undef nosetup
#undef zbuf
#undef dcue
#undef pick