/*
inner loops of ikpoly, polygon tiler for Ikonas
written in Gary Bishop's "gia2" language

Paul Heckbert	1983
*/

#include "ikpoly.h"
#include "tile.h"

extern int *bp,objtag,fcolor,y,avg,SD,SS,cm[],bug[];
extern int  LX, RX, LZ, RZ, LR, RR, LG, RG, LB, RB;
extern int DLX,DRX,DLZ,DRZ,DLR,DRR,DLG,DRG,DLB,DRB;
extern int  LU, RU, LV, RV, LD, RD, LSD, RSD, LSS, RSS;
extern int DLU,DRU,DLV,DRV,DLD,DRD,DLSD,DRSD,DLSS,DRSS;
extern texture,increm;

int FRAC,npixels,DSD,DSS;
register int t@r0,mode@r1,DX@r12;
register int yx,zyx,Z,DZ;

reserve r15;

scanxinit {				# INITIALIZATION FOR INNER LOOPS
   yx = SXT(LX+65535>>16);
   npixels = SXT(RX>>16)-yx+1;
   if (npixels<=0) goto bad;
   if ((DX = RX-LX)==0) goto bad;
   FRAC = (yx<<>16)-LX<<>16>>1;
   yx = fbyx(yx,y);			# left end
   zyx = ZADDR;				# saves 1 instr. in inner loops
   incrementalize(FRAC,LZ,RZ,Z,DZ)	# everybody interpolates Z
   Q = 0;
   return;

bad:
   Q = -1;				# bad scan line
}

facet {
   register int color,tag@r12;

   r14 = npixels; call mung_ldcnt;
   /* must be done after incrementalize, since div64 uses CNT */
   color = fcolor;
   tag = objtag;
   MAR = yx += zyx;
   Q = Z;				# Q will hold Z at times
   jmpcnt fdraw;

fdraw:					# FACETED SHADING
   pread; MDR = Z = SXT(Z>>16);		# read z-buffer
   t = BUS;
   t = SXT(t);
   MDR-t;
   Z = Q += DZ; if (ccneg) {
      MDR = tag | LOW MDR$		# the four bytes go 0,tag,zhi,zlo
      pwrite; MAR = yx-zyx;		# write z-buffer
      MDR = color$
      pwrite; MAR = yx += right; if (!cccntz) jmpcnt fdraw;
   }					# write image
   MAR = yx += right; if (!cccntz) jmpcnt fdraw;
}

gooro {
   register int V,DV, tag@r12;

   incrementalize(FRAC,LR,RR,V,DV)

   r14 = npixels; call mung_ldcnt;
   tag = objtag;
   MAR = yx += zyx;
   Q = Z;				# Q will hold Z at times
   if (mode&Indir) jmpcnt igdraw;
   else jmpcnt gdraw;

gdraw:					# GOURAUD SHADING
   pread; MDR = Z = SXT(Z>>16);		# read z-buffer
   t = BUS;
   t = SXT(t);
   MDR-t;
   Z = Q += DZ; if (ccneg) {
      MDR = tag | LOW MDR;
      t = V&0xff0000$
      pwrite; MAR = yx-zyx;		# write z-buffer
      MDR = Q = t | t>>8 | t>>16;
      Q = Z; pwrite;			# write image
   }
   V += DV;
   MAR = yx += right; if (!cccntz) jmpcnt gdraw;
   return;

igdraw:					# GOURAUD SHADING WITH INDIRECTION
   pread; MDR = Z = SXT(Z>>16);		# read z-buffer
   t = BUS;
   t = SXT(t);
   MDR-t;
   Z = Q += DZ; if (ccneg) {
      MDR = tag | LOW MDR$
      pwrite; MAR = yx-zyx; UDR = SPUDR;# write z-buffer
      MDR = cm[V>>16&0xff];
      MAR = yx-zyx;
      Q = Z; pwrite;			# write image
   }
   V += DV;
   MAR = yx += right; if (!cccntz) jmpcnt igdraw;
}

colerp {
   register int R,DR, G,DG, B,DB, tag@r12;

   incrementalize(FRAC,LR,RR,R,DR)
   incrementalize(FRAC,LG,RG,G,DG)
   incrementalize(FRAC,LB,RB,B,DB)

   r14 = npixels; call mung_ldcnt;
   tag = objtag;
   MAR = yx += zyx;
   Q = Z;				# Q will hold Z at times
   if (mode&Indir) jmpcnt icdraw;
   else jmpcnt cdraw;

cdraw:					# VERTEX COLOR INTERPOLATION
   pread; MDR = Z = SXT(Z>>16);		# read z-buffer
   t = BUS;
   t = SXT(t);
   MDR-t;
   Z = Q += DZ; if (ccneg) {
      MDR = tag | LOW MDR;
      Q = 0xff0000$
      pwrite; MAR = yx-zyx;		# write z-buffer
      MDR = B&Q;
      t = G&Q;
      MDR = Q = MDR | t>>8 | R>>16;
      Q = Z; pwrite;			# write image
   }
   R += DR;
   G += DG;
   B += DB;
   MAR = yx += right; if (!cccntz) jmpcnt cdraw;
   return;

icdraw:					# VERTEX COLOR INTERP. INDIRECTED
   pread; MDR = Z = SXT(Z>>16);		# read z-buffer
   t = BUS;
   t = SXT(t);
   MDR-t;
   Z = Q += DZ; if (ccneg) {
      MDR = tag | LOW MDR$
      pwrite; UDR = SPUDR;		# write z-buffer
      MDR  = cm[B>>16&0xff]&0xff0000; UDR = SPUDR;
      MDR |= cm[G>>16&0xff]&0x00ff00;
      MDR |= cm[R>>16&0xff]&0x0000ff;
      MAR = yx-zyx;
      Q = Z; pwrite;			# write image
   }
   R += DR;
   G += DG;
   B += DB;
   MAR = yx += right; if (!cccntz) jmpcnt icdraw;
}

texmap {
   register int U@r9,DU, V@r10,DV, D@r12,DD, tag,count;

   if (mode&Gooro) {
      incrementalize(FRAC,LSD,RSD,SD,DSD)
      incrementalize(FRAC,LSS,RSS,SS,DSS)
   }
   incrementalize(FRAC,LU,RU,U,DU)
   incrementalize(FRAC,LV,RV,V,DV)
   incrementalize(FRAC,LD,RD,D,DD)	# must be last; increm uses r12(=D)

   r14 = npixels; call mung_ldcnt;
   count = npixels;
   tag = objtag;
   MAR = yx += zyx;

tdraw:					# TEXTURE MAPPING (FACETED & GOURAUD)
   t = Z$
   pread; MDR = t = SXT(t>>16);		# read z-buffer
   t = BUS;
   t = SXT(t);
   MDR-t;
   Z += DZ; if (ccneg) {
      MDR = tag | LOW MDR$
      pwrite;				# write z-buffer
      call texture;
      MAR = yx-zyx$
      pwrite;				# write image
   }
   U += DU;
   V += DV;
   D += DD;
   if (mode&Gooro) {
      SD += DSD;
      SS += DSS;
   }
   MAR = yx += right;
   if (--count>0) goto tdraw;
}

mung_ldcnt {				# SET CNT REGISTER FROM r14
   register int cnt@r14;
   reserve r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12, r15;
   label place;

   MAR = MICRO+place<<1$
   read; MDR = BUS&HI | -cnt&LO $
   write;
place:
   CNT = 0;
}
