void polymap (float *x, float *y, float *z, char nv, Uchar tinta)
{
	if (nv==0) return;
	float tempXsize = XSIZE;
	float tempYsize = YSIZE;

	char  _flares = flares;
	float _uno = 1;

	char  culling = culling_needed;
	char  halfscan = halfscan_needed;

	Word   vr22;
	Dword  bndx;

	Word   i, sections;

	Dword  i_low_lim = -10000;
	Dword  i_hig_lim = +10000;

	Dword  u, v, min_y, max_y;
	Dword  x1, y1, x2, y2, ity, jty;

	float k1, k2, k3, k4;
	float hx, vx, ox, hy, vy, oy, hz, vz, oz, _x, _y, _z;
	float kx, rx, ry, rz, mx, my, mz, nx, ny, nz, xx, yy, zz;

	float midx, midy, midz;
	float trxf[4], tryf[4], trzf[4];

	#ifdef WINDOWS
	Udword min_xDW = min_x;
	Udword max_xDW = max_x;
	Udword min_yDW = min_y;
	Udword max_yDW = max_y;
	#endif
	
	// Polymap ha routines fatte per 4 vertici.
	// Se sono 3, l'ultimo va duplicato.

	if (nv==3) {
		x[3] = x[2];
		y[3] = y[2];
		z[3] = z[2];
	}

	// Rototraslazione dei vertici; i dati rimangono ancora 3d.

		asm	mov doflag, 0
		asm {// if (gamma)
	       #ifdef WINDOWS
	       mov eax, dword ptr _0
	       cmp eax, dword ptr gamma
	       #else
	       db 0x66; mov ax, word ptr _0
	       db 0x66; cmp ax, word ptr gamma
	       #endif
			jne t_axis
			jmp no_t_axis }
	t_axis: asm {   xor MAYBE_EDI, MAYBE_EDI
			xor MAYBE_ESI, MAYBE_ESI }
       _vertex: asm {
       		#ifdef WINDOWS
       		mov ebx, [z]
       		fld dword ptr [ebx+esi]
       		#else
       		les bx, dword ptr z
			fld dword ptr es:[bx+si]
			#endif
			fsub cam_z
			fst zz
			fmul opt_tsinbeta
			#ifdef WINDOWS
       		mov ebx, [x]
       		fld dword ptr [ebx+esi]
       		#else
       		les bx, dword ptr x
			fld dword ptr es:[bx+si]
			#endif
			fsub cam_x
			fst xx
			fmul opt_tcosbeta
			faddp
			#ifdef WINDOWS
			fstp dword ptr rxf[esi]
       		#else
       		fstp dword ptr rxf[si]
			#endif
			fld zz
			fmul opt_tcosbeta
			fld xx
			fmul opt_tsinbeta
			fsubp
			fst z2
			fmul opt_tcosalfa
			#ifdef WINDOWS
			mov ebx, [y]
			fld dword ptr [ebx+esi]
       		#else
       		les bx, dword ptr y
			fld dword ptr es:[bx+si]
			#endif
			fsub cam_y
			fst yy
			fmul opt_tsinalfa
			faddp
			#ifdef WINDOWS
       		fst dword ptr rzf[esi]
       		#else
       		fst dword ptr rzf[si]
			#endif
			fcomp uneg
			fstsw ax
			fld yy
			fmul opt_tcosalfa
			fld z2
			fmul opt_tsinalfa
			fsubp
			fst my
			fmul opt_tcosgamma
			#ifdef WINDOWS
       		fld dword ptr rxf[esi]
       		#else
       		fld dword ptr rxf[si]
			#endif
			fmul opt_tsingamma
			fsubp
			#ifdef WINDOWS
       		fstp dword ptr ryf[esi]
       		#else
       		fstp dword ptr ryf[si]
			#endif
			fld my
			fmul opt_tsingamma
			#ifdef WINDOWS
       		fld dword ptr rxf[esi]
       		#else
       		fld dword ptr rxf[si]
			#endif
			fmul opt_tcosgamma
			faddp
			#ifdef WINDOWS
       		fstp dword ptr rxf[esi]
       		#else
       		fstp dword ptr rxf[si]
			#endif
			sahf
			jb _rzf_min_uneg
			inc doflag
			mov byte ptr rwf[MAYBE_EDI], 1
			jmp _convert }
 _rzf_min_uneg: asm     mov byte ptr rwf[MAYBE_EDI], 0
      _convert: asm {   add MAYBE_ESI, 4
			inc MAYBE_EDI
			cmp MAYBE_EDI, 4
			je _end_convert
			jmp _vertex }
  _end_convert: asm	jmp end_convert
     no_t_axis: asm {   xor MAYBE_EDI, MAYBE_EDI
			xor MAYBE_ESI, MAYBE_ESI }
	vertex: asm {
			#ifdef WINDOWS
			mov ebx, [z]
			fld dword ptr [ebx+esi]
			#else
			les bx, dword ptr z
			fld dword ptr es:[bx+si]
			#endif
			fsub cam_z
			fst zz
			fmul opt_tsinbeta
			#ifdef WINDOWS
			mov ebx, [x]
			fld dword ptr [ebx+esi]
			#else
			les bx, dword ptr x
			fld dword ptr es:[bx+si]
			#endif
			fsub cam_x
			fst xx
			fmul opt_tcosbeta
			faddp
			#ifdef WINDOWS
			fstp dword ptr rxf[esi]
			#else
			fstp dword ptr rxf[si]
			#endif
			fld zz
			fmul opt_tcosbeta
			fld xx
			fmul opt_tsinbeta
			fsubp
			fst z2
			fmul opt_tcosalfa
			#ifdef WINDOWS
			mov ebx, [y]
			fld dword ptr [ebx+esi]
			#else
			les bx, dword ptr y
			fld dword ptr es:[bx+si]
			#endif
			fsub cam_y
			fst yy
			fmul opt_tsinalfa
			faddp
			fst dword ptr rzf[MAYBE_ESI]
			fcomp uneg
			fstsw ax
			fld yy
			fmul opt_tcosalfa
			fld z2
			fmul opt_tsinalfa
			fsubp
			fstp dword ptr ryf[MAYBE_ESI]
			sahf
			jb rzf_min_uneg
			inc doflag
			mov byte ptr rwf[MAYBE_EDI], 1
			jmp convert }
  rzf_min_uneg: asm     mov byte ptr rwf[MAYBE_EDI], 0
       convert: asm {   add MAYBE_ESI, 4
			inc MAYBE_EDI
			cmp MAYBE_EDI, 4
			je end_convert
			jmp vertex }

   end_convert: asm {// if (!doflag) return;
			cmp doflag, 0
			jne vectors }

		return;

	// Calcolo dei vettori di tracciamento del texture mapping.
	#ifdef WINDOWS
	int num;
	#endif
       vectors: if (nv == 3) {
			midx = (rxf[0] + rxf[1] + rxf[2]) * 0.3333333;
			midy = (ryf[0] + ryf[1] + ryf[2]) * 0.3333333;
			midz = (rzf[0] + rzf[1] + rzf[2]) * 0.3333333;
			for (vr = 0; vr < 3; vr++) {
				trxf[vr] = (rxf[vr] - midx) * x_antialias + midx;
				tryf[vr] = (ryf[vr] - midy) * y_antialias + midy;
				trzf[vr] = (rzf[vr] - midz) * z_antialias + midz;
			}
			#ifdef WINDOWS
			num = 2;
			_ESI = 8;
			#else
			_SI = 8;
			#endif
		}
		else {
			midx = (rxf[0] + rxf[1] + rxf[2] + rxf[3]) * 0.25;
			midy = (ryf[0] + ryf[1] + ryf[2] + ryf[3]) * 0.25;
			midz = (rzf[0] + rzf[1] + rzf[2] + rzf[3]) * 0.25;
			for (vr = 0; vr < 4; vr++) {
				trxf[vr] = (rxf[vr] - midx) * x_antialias + midx;
				tryf[vr] = (ryf[vr] - midy) * y_antialias + midy;
				trzf[vr] = (rzf[vr] - midz) * z_antialias + midz;
			}
			#ifdef WINDOWS
			num = 3;
			_ESI = 12;
			#else
			_SI = 12;
			#endif
		}
		/*#ifdef WINDOWS
		rx = trxf[0];
		mx = trxf[1]-rx;
		nx = rx - trxf[num];
		ry = tryf[0];
		my = tryf[1] - ry;
		ny = ry - tryf[num];
		rz = trzf[0];
		mz = trzf[1] - rz;
		nz = rz - trzf[num];
		#else*/
		asm {
			// rx = rxf[0];
			fld dword ptr trxf[0]
			fstp rx
		     //	mx = rxf[1] - rx;
			fld dword ptr trxf[4]
			fsub rx
			fstp mx
		     //	nx = rx - rxf[3];
			fld rx
			fsub dword ptr trxf[LOCALVAR MAYBE_ESI]	//[ebp+MAYBE_ESI] assembles to the result we want, but that's due to the bug which makes [MAYBE_ESI] assemble wrong...
			fstp nx
		     //	ry = ryf[0];
			fld dword ptr tryf[0]
			fstp ry
		     //	my = ryf[1] - ry;
			fld dword ptr tryf[4]
			fsub ry
			fstp my
		     //	ny = ry - ryf[3];
			fld ry
			fsub dword ptr tryf[LOCALVAR MAYBE_ESI]
			fstp ny
		     //	rz = rzf[0];
			fld dword ptr trzf[0]
			fstp rz
		     //	mz = rzf[1] - rz;
			fld dword ptr trzf[4]
			fsub rz
			fstp mz
		     //	nz = rz - rzf[3];
			fld rz
			fsub dword ptr trzf[LOCALVAR MAYBE_ESI]
			fstp nz }
		//#endif
		asm {// hx = (rx * mz - rz * mx) * YCOEFF;
			fld rx
			fmul mz
			fld rz
			fmul mx
			fsubp
			fmul YCOEFF
			fstp hx
		     // hy = (rx * nz - rz * nx) * YCOEFF;
			fld rx
			fmul nz
			fld rz
			fmul nx
			fsubp
			fmul YCOEFF
			fstp hy
		     // hz = (nx * mz - nz * mx) / dpp;
			fld nx
			fmul mz
			fld nz
			fmul mx
			fsubp
			fmul inv_dpp
			fstp hz
		     //	vx = (rz * my - ry * mz) * XCOEFF;
			fld rz
			fmul my
			fld ry
			fmul mz
			fsubp
			fmul XCOEFF
			fstp vx
		     //	vy = (rz * ny - ry * nz) * XCOEFF;
			fld rz
			fmul ny
			fld ry
			fmul nz
			fsubp
			fmul XCOEFF
			fstp vy
		     //	vz = (nz * my - ny * mz) / dpp;
			fld nz
			fmul my
			fld ny
			fmul mz
			fsubp
			fmul inv_dpp
			fstp vz
		     //	ox = (ry * mx - rx * my) * EMU_K;
			fld ry
			fmul mx
			fld rx
			fmul my
			fsubp
			fmul EMU_K
			fstp ox
		     //	oy = (ry * nx - rx * ny) * EMU_K;
			fld ry
			fmul nx
			fld rx
			fmul ny
			fsubp
			fmul EMU_K
			fstp oy
		     //	oz =  ny * mx - nx * my;
			fld ny
			fmul mx
			fld nx
			fmul my
			fsubp
			fstp oz }

	// Fast-load per poligoni completamente visibili.

		asm {// if (doflag==4) {
			cmp doflag, 4
			jne z_clipping
			xor MAYBE_ESI, MAYBE_ESI
			mov MAYBE_ECX, 4
			mov vr2, 4
			mov vr22, 8 }
	load:   asm {
			#ifdef WINDOWS
			mov eax, dword ptr rxf[esi]
			mov ebx, dword ptr ryf[esi]
			mov edx, dword ptr rzf[esi]
			mov dword ptr ultima_x[esi], eax
			mov dword ptr ultima_y[esi], ebx
			mov dword ptr ultima_z[esi], edx
			#else
			db 0x66; mov ax, word ptr rxf[si]
			db 0x66; mov bx, word ptr ryf[si]
			db 0x66; mov dx, word ptr rzf[si]
			db 0x66; mov word ptr ultima_x[si], ax
			db 0x66; mov word ptr ultima_y[si], bx
			db 0x66; mov word ptr ultima_z[si], dx
			#endif
			add MAYBE_ESI, 4
			dec MAYBE_ECX
			jnz load
			jmp to_2d }

	/* Conversione punti alle spalle dell'osservatore
	   rispetto al piano dello schermo. */

    z_clipping: asm {   mov vr, 0
			xor MAYBE_EDI, MAYBE_EDI
			mov dx, 4
			dec dx }
     the_for_1: asm {   MOVZX_MAYBE_ESI, vr
			cmp byte ptr rwf[MAYBE_ESI], 0
			je CONT1
			jmp bypass }
      CONT1:    asm {   mov ax, vr
			sub ax, 1
			jnc pvert1ok
			mov pvert, dx
			jmp pvert1no }
      pvert1ok: asm     mov pvert, ax
      pvert1no: asm {   mov ax, vr
			inc ax
			cmp ax, dx
			jbe nvert1ok
			mov nvert, 0
			jmp nvert1no }
      nvert1ok: asm     mov nvert, ax
      nvert1no: asm {   MOVZX_MAYBE_ESI, pvert
			cmp byte ptr rwf[MAYBE_ESI], 0
			je ctrl1
			jmp JMPR11 }
      ctrl1:    asm {   MOVZX_MAYBE_ESI, nvert
			cmp byte ptr rwf[MAYBE_ESI], 0
			jne JMPR11
			jmp STOP1 }
      JMPR11:   asm {   mov bx, vr
			shl bx, 2
			MOVZX_MAYBE_ESI, pvert
			mov al, byte ptr rwf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, nvert
			add al, byte ptr rwf[MAYBE_ESI]
			cmp al, 2
			je if11
			jmp else11 }
      if11:     asm {   shl pvert, 2
			shl nvert, 2
			MOVZX_MAYBE_ESI, bx
			fld dword ptr rzf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, pvert
			fcomp dword ptr rzf[MAYBE_ESI]
			fstsw ax
			sahf
			jne if12
			jmp else12 }
      if12:     asm {   fld dword ptr uneg
			fsub dword ptr rzf[MAYBE_ESI]
			fld dword ptr rzf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, bx
			fsubr dword ptr rzf[MAYBE_ESI]
			fdivp
			fst zk
			fld dword ptr rxf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, pvert
			fsub dword ptr rxf[MAYBE_ESI]
			fmulp
			fadd dword ptr rxf[MAYBE_ESI]
			fstp dword ptr ultima_x[MAYBE_EDI]
			fld zk
			MOVZX_MAYBE_ESI, bx
			fld dword ptr ryf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, pvert
			fsub dword ptr ryf[MAYBE_ESI]
			fmulp
			fadd dword ptr ryf[MAYBE_ESI]
			fstp dword ptr ultima_y[MAYBE_EDI]
			jmp JMPR12 }
      else12:   asm {   MOVZX_MAYBE_ESI, bx
			#ifdef WINDOWS
			mov eax, dword ptr rxf[esi]
			mov dword ptr ultima_x[edi], eax
			mov eax, dword ptr ryf[esi]
			mov dword ptr ultima_y[edi], eax
			#else
			db 0x66; mov ax, word ptr rxf[si]
			db 0x66; mov word ptr ultima_x[di], ax
			db 0x66; mov ax, word ptr ryf[si]
			db 0x66; mov word ptr ultima_y[di], ax
			#endif
			}
      JMPR12:   asm {
      		#ifdef WINDOWS
		  	mov eax, dword ptr uneg
		  	mov dword ptr ultima_z[edi], eax
			#else
		  	db 0x66; mov ax, word ptr uneg
			db 0x66; mov word ptr ultima_z[di], ax
			#endif
		  	MOVZX_MAYBE_ESI, bx
			fld dword ptr rzf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, nvert
			fcomp dword ptr rzf[MAYBE_ESI]
			fstsw ax
			sahf
			jne neq1
			jmp eq1 }
      neq1:     asm {   fld dword ptr uneg
			fsub dword ptr rzf[MAYBE_ESI]
			fld dword ptr rzf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, bx
			fsubr dword ptr rzf[MAYBE_ESI]
			fdivp
			fst zk
			fld dword ptr rxf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, nvert
			fsub dword ptr rxf[MAYBE_ESI]
			fmulp
			fadd dword ptr rxf[MAYBE_ESI]
			fstp dword ptr ultima_x[MAYBE_EDI+4]
			fld zk
			MOVZX_MAYBE_ESI, bx
			fld dword ptr ryf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, nvert
			fsub dword ptr ryf[MAYBE_ESI]
			fmulp
			fadd dword ptr ryf[MAYBE_ESI]
			fstp dword ptr ultima_y[MAYBE_EDI+4]
			jmp JMPR13 }
      eq1:      asm {   MOVZX_MAYBE_ESI, bx
			#ifdef WINDOWS
			mov eax, dword ptr rxf[esi]
			mov dword ptr ultima_x[edi+4], eax
			mov eax, dword ptr ryf[esi]
			mov dword ptr ultima_y[edi+4], eax }
      JMPR13:   asm {   mov eax, dword ptr uneg
			mov dword ptr ultima_z[edi+4], eax
			#else
			db 0x66; mov ax, word ptr rxf[si]
			db 0x66; mov word ptr ultima_x[di+4], ax
			db 0x66; mov ax, word ptr ryf[si]
			db 0x66; mov word ptr ultima_y[di+4], ax }
      JMPR13:   asm {   db 0x66; mov ax, word ptr uneg
			db 0x66; mov word ptr ultima_z[di+4], ax
			#endif
			add MAYBE_EDI, 8
			jmp STOP1 }
      else11:   asm {   MOVZX_MAYBE_ESI, pvert
			cmp byte ptr rwf[MAYBE_ESI], 0
			jne vpvert1
			mov ax, nvert
			mov vvert, ax
			jmp vnvert1 }
      vpvert1:  asm {   mov ax, pvert
			mov vvert, ax }
      vnvert1:  asm {   shl vvert, 2
			MOVZX_MAYBE_ESI, bx
			fld dword ptr rzf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, vvert
			fcomp dword ptr rzf[MAYBE_ESI]
			fstsw ax
			sahf
			jne neq2
			jmp eq2 }
      neq2:     asm {   fld dword ptr uneg
			fsub dword ptr rzf[MAYBE_ESI]
			fld dword ptr rzf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, bx
			fsubr dword ptr rzf[MAYBE_ESI]
			fdivp
			fst zk
			fld dword ptr rxf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, vvert
			fsub dword ptr rxf[MAYBE_ESI]
			fmulp
			fadd dword ptr rxf[MAYBE_ESI]
			fstp dword ptr ultima_x[MAYBE_EDI]
			fld zk
			MOVZX_MAYBE_ESI, bx
			fld dword ptr ryf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, vvert
			fsub dword ptr ryf[MAYBE_ESI]
			fmulp
			fadd dword ptr ryf[MAYBE_ESI]
			fstp dword ptr ultima_y[MAYBE_EDI]
			jmp JMPR14 }
      eq2:      asm {   MOVZX_MAYBE_ESI, bx
			#ifdef WINDOWS
		  	mov eax, dword ptr rxf[esi]
			mov dword ptr ultima_x[edi], eax
			mov eax, dword ptr ryf[esi]
			mov dword ptr ultima_y[edi], eax }
      JMPR14:   asm {   mov eax, dword ptr uneg
			mov dword ptr ultima_z[edi], eax
			add edi, 4
			jmp STOP1 }
      bypass:   asm {   shl esi, 2
			mov eax, dword ptr rxf[esi]
			mov dword ptr ultima_x[edi], eax
			mov eax, dword ptr ryf[esi]
			mov dword ptr ultima_y[edi], eax
			mov eax, dword ptr rzf[esi]
			mov dword ptr ultima_z[edi], eax
			#else
		  	db 0x66; mov ax, word ptr rxf[si]
			db 0x66; mov word ptr ultima_x[di], ax
			db 0x66; mov ax, word ptr ryf[si]
			db 0x66; mov word ptr ultima_y[di], ax }
      JMPR14:   asm {   db 0x66; mov ax, word ptr uneg
			db 0x66; mov word ptr ultima_z[di], ax
			add di, 4
			jmp STOP1 }
      bypass:   asm {   shl si, 2
			db 0x66; mov ax, word ptr rxf[si]
			db 0x66; mov word ptr ultima_x[di], ax
			db 0x66; mov ax, word ptr ryf[si]
			db 0x66; mov word ptr ultima_y[di], ax
			db 0x66; mov ax, word ptr rzf[si]
			db 0x66; mov word ptr ultima_z[di], ax
			#endif
		  	add MAYBE_EDI, 4 }
      STOP1:    asm {   inc vr
			mov ax, vr
			cmp ax, 4
			jnb cutting_end_1
			jmp the_for_1 }

 cutting_end_1: asm {   mov MAYBE_EAX, MAYBE_EDI
			shr MAYBE_EAX, 1
			mov vr22, ax
			shr MAYBE_EAX, 1
			mov vr2, ax }

			if (vr2<3) return;

	   // Queste sono le proiezioni prospettiche da 3d a 2d.
	   // Contemporaneamente, il ciclo ricerca il minimo ed il massimo
	   // verticale dell'estensione del poligono sullo schermo.

	 to_2d: asm {   
		 	#ifdef WINDOWS
		 	mov edx, dword ptr ubyl
			mov ebx, dword ptr lbyl
			#else
		 	db 0x66; mov dx, word ptr ubyl
			db 0x66; mov bx, word ptr lbyl
			#endif
		 	MOVZX_MAYBE_ESI, vr2
			dec MAYBE_ESI
			shl MAYBE_ESI, 2
			mov MAYBE_EDI, MAYBE_ESI
			add MAYBE_EDI, MAYBE_ESI }
     projector: asm {   fld dpp
			fdiv dword ptr ultima_z[MAYBE_ESI]
			fld st(0)
			fmul dword ptr ultima_x[MAYBE_ESI]
			fadd dword ptr x_centro_f
			fistp dword ptr mp[MAYBE_EDI]
			fmul dword ptr ultima_y[MAYBE_ESI]
			fadd dword ptr y_centro_f
			fistp dword ptr mp[MAYBE_EDI+4]
			#ifdef WINDOWS
			cmp dword ptr mp[edi+4], edx
			#else
			db 0x66; cmp word ptr mp[MAYBE_EDI+4], dx
			#endif
			jnl outr_3
			#ifdef WINDOWS
			mov edx, dword ptr mp[edi+4] }
     outr_3:	asm {	cmp dword ptr mp[edi+4], ebx
			jle outr_4
			mov ebx, dword ptr mp[edi+4] }
			#else
			db 0x66; mov dx, word ptr mp[MAYBE_EDI+4] }
     outr_3:	asm {	db 0x66; cmp word ptr mp[MAYBE_EDI+4], bx
			jle outr_4
			db 0x66; mov bx, word ptr mp[MAYBE_EDI+4] }
			#endif
     outr_4:	asm {	sub MAYBE_EDI, 8
			sub MAYBE_ESI, 4
			jnc projector
			#ifdef WINDOWS
			mov dword ptr max_y, ebx
			mov dword ptr min_y, edx
			#else
			db 0x66; mov word ptr max_y, bx
			db 0x66; mov word ptr min_y, dx
			#endif
			}
			
	// Eventuale esclusione di poligoni non visibili.

	asm {// if (min_y>uby) return;
       #ifdef WINDOWS
		mov eax, dword ptr min_y
       cmp eax, dword ptr ubyl
		jle ct1ok
	     // if (max_y<lby) return;
       mov eax, dword ptr max_y
       cmp eax, dword ptr lbyl
		#else
		db 0x66; mov ax, word ptr min_y
       db 0x66; cmp ax, word ptr ubyl
		jle ct1ok
	     // if (max_y<lby) return;
       db 0x66; mov ax, word ptr max_y
       db 0x66; cmp ax, word ptr lbyl
		#endif
		jnl ct1ok }

       return;

	// Normalizzazione dei limiti.

ct1ok:	asm {// if (min_y<lby) min_y = lby;
       #ifdef WINDOWS
		mov eax, dword ptr min_y
       cmp eax, dword ptr lbyl
		jnl step_1
       mov eax, dword ptr lbyl
       mov dword ptr min_y, eax }

step_1:	asm {// if (max_y>uby) max_y = uby;
       mov eax, dword ptr max_y
       cmp eax, dword ptr ubyl
		jle step_2
       mov eax, dword ptr ubyl
       mov dword ptr max_y, eax }

step_2:	asm {// if (min_y>max_y) return;
       mov eax, dword ptr min_y
       cmp eax, dword ptr max_y
		#else
		db 0x66; mov ax, word ptr min_y
       db 0x66; cmp ax, word ptr lbyl
		jnl step_1
       db 0x66; mov ax, word ptr lbyl
       db 0x66; mov word ptr min_y, ax }

step_1:	asm {// if (max_y>uby) max_y = uby;
       db 0x66; mov ax, word ptr max_y
       db 0x66; cmp ax, word ptr ubyl
		jle step_2
       db 0x66; mov ax, word ptr ubyl
       db 0x66; mov word ptr max_y, ax }

step_2:	asm {// if (min_y>max_y) return;
       db 0x66; mov ax, word ptr min_y
       db 0x66; cmp ax, word ptr max_y
		#endif
		jle ct2ok }

	return;

	// Inizializzazione costanti di ottimizzazione.

ct2ok:	asm {// k1 = vx * 16;
		fld  vx
		fmul _16
		fstp k1
	     //	k2 = vy * 16;
		fld  vy
		fmul _16
		fstp k2
	     //	k3 = vz * 16;
		fld  vz
		fmul _16
		fstp k3 }

	if (culling) {
		k1 *= 2;
		k2 *= 2;
		k3 *= 2;
	}

	// Inizializzazione delle matrici dei confini orizzontali.

	asm {// for (i=min_y; i<=max_y; i++)
		#ifdef WINDOWS
		xor edi, edi
		xor ecx, ecx
		//mov edi, dword ptr min_yDW
		//mov ecx, dword ptr max_yDW
		mov di, word ptr min_y
		mov cx, word ptr max_y
		mov eax, dword ptr lbxl
		mov ebx, dword ptr ubxl
		#else
		mov di, word ptr min_y
		mov cx, word ptr max_y
		db 0x66; mov ax, word ptr lbxl
		db 0x66; mov bx, word ptr ubxl
		#endif
		sub cx, di
		shl di, 1
		inc cx }
ol_init:asm {//	fpart[i] = lbxl;
		mov word ptr fpart[MAYBE_EDI], ax
	     // ipart[i] = ubxl;
		mov word ptr ipart[MAYBE_EDI], bx
		add di, 2
		dec cx
		jnz ol_init }
		/*sub MAYBE_ECX, MAYBE_EDI
		shl MAYBE_EDI, 1
		inc MAYBE_ECX }
ol_init:asm {//	fpart[i] = lbxl;
		mov word ptr fpart[MAYBE_EDI], ax
	     // ipart[i] = ubxl;
		mov word ptr ipart[MAYBE_EDI], bx
		add MAYBE_EDI, 2
		dec MAYBE_ECX
		jnz ol_init }
		*/

	// Calcolo confini orizzontali.

	asm {//	mp[vr22]   = mp[0];
	     // mp[vr22+1] = mp[1];
		MOVZX_MAYBE_EDI, vr22
		shl MAYBE_EDI, 2
       #ifdef WINDOWS
		mov eax, dword ptr mp[0]
	  	mov ebx, dword ptr mp[4]
	   	mov dword ptr mp[edi], eax
	   	mov dword ptr mp[edi+4], ebx
		#else
		db 0x66; mov ax, word ptr mp[0]
	  	db 0x66; mov bx, word ptr mp[4]
	   	db 0x66; mov word ptr mp[di], ax
	   	db 0x66; mov word ptr mp[di+4], bx
		#endif
	     // for (i = 0; i < vr22; i += 2)
		xor MAYBE_ESI, MAYBE_ESI
		shr vr22, 1 }
extfor: asm {//	y1 = mp[i+1];
	     //	y2 = mp[i+3];
	     //	x1 = mp[i];
	     //	x2 = mp[i+2];
       #ifdef WINDOWS
		mov ebx, dword ptr mp[esi+4]
       mov edx, dword ptr mp[esi+12]
       mov eax, dword ptr mp[esi]
       mov ecx, dword ptr mp[esi+8]
	     //	if (y2<y1)
       cmp edx, ebx
		jnl noex
       mov dword ptr x1, ecx
       mov dword ptr y1, edx
       mov dword ptr x2, eax
       mov dword ptr y2, ebx
		jmp exch }
  noex: asm {// niente scambio
       mov dword ptr x1, eax
       mov dword ptr y1, ebx
       mov dword ptr x2, ecx
       mov dword ptr y2, edx
	   #else
		db 0x66; mov bx, word ptr mp[si+4]
       db 0x66; mov dx, word ptr mp[si+12]
       db 0x66; mov ax, word ptr mp[si]
       db 0x66; mov cx, word ptr mp[si+8]
	     //	if (y2<y1)
       db 0x66; cmp dx, bx
		jnl noex
       db 0x66; mov word ptr x1, cx
       db 0x66; mov word ptr y1, dx
       db 0x66; mov word ptr x2, ax
       db 0x66; mov word ptr y2, bx
		jmp exch }
  noex: asm {// niente scambio
       db 0x66; mov word ptr x1, ax
       db 0x66; mov word ptr y1, bx
       db 0x66; mov word ptr x2, cx
       db 0x66; mov word ptr y2, dx
	   #endif
       }
  exch: asm {// scambio effettuato
	     // if (y2!=y1) [nessuno ha alterato i flags]
		jne ol
		jmp nool } // niente calcolo del bordo: il segmento non si sviluppa in altezza
    ol: asm {// kx = (float)(x2 - x1) / (float)(y2 - y1);
		fild x2
		fisub x1
		fild y2
		fisub y1
		fdivp
		fstp kx
	     // if (y1<lbyl)
       #ifdef WINDOWS
		mov eax, dword ptr y1
       cmp eax, dword ptr lbyl
	    #else
		db 0x66; mov ax, word ptr y1
       db 0x66; cmp ax, word ptr lbyl
		#endif
		jnl nocr
	     // ity = lbyl;
       	#ifdef WINDOWS
       	mov eax, dword ptr lbyl
      	mov dword ptr ity, eax
	    #else
       db 0x66; mov ax, word ptr lbyl
       db 0x66; mov word ptr ity, ax
		#endif
	     // x1 += (float)(lbyl-y1) * kx;
		fild x1
		fild lbyl
		fisub y1
		fmul kx
		faddp
		fistp x1
		jmp crct }
  nocr: asm {// ity = y1;
       #ifdef WINDOWS
	  mov eax, dword ptr y1
       mov dword ptr ity, eax }
  crct: asm {// if (y2>ubyl)
       mov eax, dword ptr y2
       cmp eax, dword ptr ubyl
		jng _nocr
	     // jty = ubyl;
       mov eax, dword ptr ubyl
       mov dword ptr jty, eax
		jmp _crct }
 _nocr: asm {// jty = y2;
       mov eax, dword ptr y2
       mov dword ptr jty, eax }
 _crct: asm {// bndx = x1;
		fild x1
	     // for (h=ity; h<=jty; h++)
       mov edi, dword ptr ity
        mov ecx, dword ptr jty
       cmp edi, ecx
		jnl noifor
       sub ecx, edi
		#else
	  db 0x66; mov ax, word ptr y1
       db 0x66; mov word ptr ity, ax }
  crct: asm {// if (y2>ubyl)
       db 0x66; mov ax, word ptr y2
       db 0x66; cmp ax, word ptr ubyl
		jng _nocr
	     // jty = ubyl;
       db 0x66; mov ax, word ptr ubyl
       db 0x66; mov word ptr jty, ax
		jmp _crct }
 _nocr: asm {// jty = y2;
       db 0x66; mov ax, word ptr y2
       db 0x66; mov word ptr jty, ax }
 _crct: asm {// bndx = x1;
		fild x1
	     // for (h=ity; h<=jty; h++)
       db 0x66; mov di, word ptr ity
       db 0x66; mov cx, word ptr jty
       db 0x66; cmp di, cx
		jnl noifor
       db 0x66; sub cx, di
		#endif
		shl MAYBE_EDI, 1
		inc MAYBE_ECX }
intfor: asm {// _EAX = bndx;
		fist bndx
		#ifdef WINDOWS
       	mov eax, dword ptr bndx
		cmp eax, dword ptr i_low_lim
		jnl ct01
		mov eax, dword ptr i_low_lim }
ct01:	asm {	cmp eax, dword ptr i_hig_lim
		jng ct02
		mov eax, dword ptr i_hig_lim
		#else
		db 0x66; mov ax, word ptr bndx
		db 0x66; cmp ax, word ptr i_low_lim
		jnl ct01
		db 0x66; mov ax, word ptr i_low_lim }
ct01:	asm {	db 0x66; cmp ax, word ptr i_hig_lim
		jng ct02
		db 0x66; mov ax, word ptr i_hig_lim
		#endif
		}
ct02:	asm {// if (bndx > fpart[h])
		cmp ax, word ptr fpart[MAYBE_EDI]
		jng ct1n
	     //	if (bndx < ubx)
		cmp ax, word ptr ubxl
		jnl ct2n
	     //	fpart[h] = bndx;
		mov word ptr fpart[MAYBE_EDI], ax
		jmp ct1n }
  ct2n: asm {// fpart[h] = ubx;
		mov dx, word ptr ubxl
		mov word ptr fpart[MAYBE_EDI], dx }
  ct1n: asm {// if (bndx < ipart[h])
		cmp ax, word ptr ipart[MAYBE_EDI]
		jnl ct3n
	     //	if (bndx > lbx)
		cmp ax, word ptr lbxl
		jng ct4n
	     //	ipart[h] = bndx;
		mov word ptr ipart[MAYBE_EDI], ax
		jmp ct3n }
  ct4n: asm {//	ipart[h] = lbx;
		mov dx, word ptr lbxl
		mov word ptr ipart[MAYBE_EDI], dx }
  ct3n: asm {// bndx += kx;
		fadd kx
		add MAYBE_EDI, 2
		dec MAYBE_ECX
		jnz intfor }
noifor:	
		#ifdef WINDOWS
		asm	fstp st(0)
		#else
		asm	fstp st
		#endif
  nool: asm {   add MAYBE_ESI, 8
		dec vr22
		jz  ol_end
		jmp extfor }

	// Pre-assegnamenti di lavoro.

ol_end:
	#ifdef WINDOWS
		//fs is txtr
		//es is adapted
		asm {
			mov esi, [adapted]
			mov al, tinta
			mov byte ptr [esi+0xFA00], al
			mov al, escrescenze
			mov byte ptr [esi+0xFA01], al
		}
	#else
	asm les dx, dword ptr txtr	// caricamento del segmento-texture
	asm mov ax, es			// .
	asm shr dx, 4			// .
	asm add ax, dx			// .
	asm db 0x8e, 0xe0		// mov fs, ax

	asm les ax, dword ptr adapted	// caricamento indirizzo area video
	asm mov al, tinta		// caricamento del primo colore
	asm mov es:[0xFA00], al		// .
	asm mov al, escrescenze		// caricamento primo colore bumps
	asm mov es:[0xFA01], al		// .
	#endif
	
	// Ciclo di tracciamento.

		     // for (i=min_y; i<=max_y; i++)
		asm     mov ax, word ptr min_y
		asm	mov i, ax
	 trace: asm {//	_z = oz + (hz * (i - y_centro)) + (vz * (ipart[i] - x_centro + 1));
			MOVZX_MAYBE_ESI, i
			shl MAYBE_ESI, 1
			fild word ptr ipart[MAYBE_ESI]
			fsub x_centro_f
			fadd uno
			fld st(0) // duplica (ipart[i] - x_centro + 1)
			fld st(0) // due volte, Š lo stesso per tre calcoli
			fmul vz
			fild i
			fsub y_centro_f
			fmul hz
			faddp
			fadd oz
			fst _z
		     //	k4 = 1 / _z;
			fdivr uno
			fstp k4
		     // _x = ox + (hx * (i - y_centro)) + (vx * (ipart[i] - x_centro + 1));
			fmul vx
			fild i
			fsub y_centro_f
			fmul hx
			faddp
			fadd ox
			fstp _x
		     // _y = oy + (hy * (i - y_centro)) + (vy * (ipart[i] - x_centro + 1));
			fmul vy
			fild i
			fsub y_centro_f
			fmul hy
			faddp
			fadd oy
			fstp _y
		     // u  = (_x * tempXsize) * k4; // Seq. stabile
		     //	v  = (_y * tempYsize) * k4; // Ma usare _control87
			fld _y
			fmul tempYsize
			fmul k4
			fld _x
			fmul tempXsize
			fmul k4
			fxch
			fistp v
			fistp u
		     //	sections = fpart[i] - ipart[i];	// Sequenza stabile.
		     //	_DI = i * 320 + ipart[i];       // Moltiplicazione per 320 in tabella.
		     // SI Š gi… caricato con I * 2.
			MOVZX_MAYBE_EDX, word ptr ipart[MAYBE_ESI]
			MOVZX_MAYBE_EAX, word ptr fpart[MAYBE_ESI]
			#ifdef WINDOWS
			mov edi, dword ptr riga[esi*2]
			#else
			mov di, word ptr riga[si]
			#endif
			sub MAYBE_EAX, MAYBE_EDX
			add MAYBE_EDI, MAYBE_EDX
			mov sections, ax
			#ifndef WINDOWS
			push ds
			push es
			pop  ds
//adapted is now ds too.
			#endif
			test culling, 1
			jz row
			jmp c_row }
	 // tracciamento di una scanline: versione ad alto dettaglio
	   row: asm {   cmp sections, 0
			jg  again
			jmp row_end }
	 again:	asm {	cmp sections, 16
			jg  complete
			mov ax, sections
			mov cl, al
			jmp unfinished }
      complete: asm 	mov cl, 16
    unfinished: asm {	sub sections, 16
			cmp cl, 0
			je  row
		     // x += k1;               // Sequenza stabile.
		     // y += k2;	       // Traduzione ASM ok.
		     // z += k3;               // Nessun ritardo grazie a FXCH.
		     // if (z) {               // !! Sequenza instabile.
		     //	k4 = 1 / z;	       // correzione da parte di "_control87"
		     //	u2 = (x * XSIZE) * k4; // Problema: le FISTP possono provocare
		     //	v2 = (y * YSIZE) * k4; // errori di dominio in virgola mobile.
			fld   _z	       // 1 cycle   stack: z
			fadd  k3               // 1 cycle   stack: z+k3
			fld   _x	       // 1 cycle   stack: x, z+k3
			fadd  k1               // 1 cycle   stack: x+k1, z+k3
			fxch                   // no time   stack: z+k3, x+k1
			fst   _z               // 2 cycles  stack: z+k3, x+k1
			fxch                   // no time   stack: x+k1, z+k3
			fst   _x               // 2 cycles  stack: x+k1, z+k3
			fxch                   // no time   stack: z+k3, x+k1
			fdivr _uno             // 39 cycles stack: k4, x+k1
			#ifdef WINDOWS
			mov eax, dword ptr u
			mov edx, dword ptr v
			#else
			db 0x66; mov ax, word ptr u     // while FPU is working,
	       	db 0x66; mov dx, word ptr v     // this group takes 0 cycles.
			#endif
			mov ch, _flares	       //
			#ifdef WINDOWS
			push ebp
			#else
			db 0x66; push bp                //This was just push bp before - but since we manipulate ebp later, we had better push the whole thing
			#endif
			fxch                   // no time   stack: x+k1, k4
			fmul  tempXsize        // 1 cycle   stack: x..., k4
			fld   _y               // 1 cycle   stack: y, x..., k4
			fadd  k2	       // 1 cycle   stack: y+k2, x..., k4
			fst   _y               // 3 cycles  stack: y+k2, x..., k4
			fmul  tempYsize        // 1 cycle   stack: y..., x..., k4
			fxch                   // no time   stack: x..., y..., k4
			fmul  st, st(2)        // 1 cycle   stack: u, y..., k4
			fxch                   // no time   stack: y..., u, k4
			fmul  st, st(2)        // 1 cycle   stack: v, u, k4
			fxch                   // no time   stack: u, v, k4
			fistp u                // 6 cycles  stack: v, k4
			fistp v                // 6 cycles  stack: k4
			#ifdef WINDOWS
			fstp st(0)
	       	mov esi, dword ptr v
			mov ebp, dword ptr u
			sub esi, edx
			sub ebp, eax
			sar esi, 4
			sar ebp, 4
			#else
			fstp st
	       	db 0x66; mov si, word ptr v
			db 0x66; mov bp, word ptr u
			db 0x66; sub si, dx
			db 0x66; sub bp, ax
			db 0x66; sar si, 4
			db 0x66; sar bp, 4
			#endif
			test ch, 15		// NORMALE = 0
			jz internal
			test ch, 1		// LUCIDO = 1
			jnz transp
			test ch, 2		// BRILLANTE = 2
			jnz bright
			test ch, 4		// TRASLUCIDO = 4
			jnz merger
			jmp bumper }		// BUMP MAPPING = 8
      internal:	asm {
		  	xor MAYBE_EBX, MAYBE_EBX
		  	mov bh, dh		// 1 (riempimento normale)
			inc MAYBE_EDI			// *
			mov bl, ah		// 1
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+0xFA00]
		  	add ch, byte ptr txtr[ebx]
			add eax, ebp		// *
			mov byte ptr [esi+edi+3], ch		// 1	//REMOVE4
		  	pop esi
			#else
		  	mov ch, ds:[0xFA00]	// *
			db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
			add MAYBE_EAX, MAYBE_EBP		// *
			mov [MAYBE_EDI+3], ch		// 1
			#endif
		  	add MAYBE_EDX, MAYBE_ESI		// *
			dec cl			// 1
			jnz internal  		// 7 cicli.
			jmp common }
      transp:  	asm {
		  	xor MAYBE_EBX, MAYBE_EBX
		  	mov bh, dh		// 1 (riempimento lucido)
			inc MAYBE_EDI			// *
			mov bl, ah		// 1
			#ifdef WINDOWS
		  	push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+edi+3]		// *	//REMOVE4
			add ch, byte ptr txtr[ebx]
		  	add eax, ebp		// *
			mov byte ptr [esi+edi+3], ch		// 1	//REMOVE4
			pop esi
		  	#else
		  	mov ch, [di+3]		// *
			db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
		  	add ax, bp		// *
			mov [di+3], ch		// 1
			#endif
			add MAYBE_EDX, MAYBE_ESI		// *
			dec cl			// 1
			jnz transp		// 7 cicli.
			jmp common }
      bright:  	asm {
		  	#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+edi+4]	//REMOVE4
		  	pop esi
		  	#else
		  	mov ch, [di+4]		// 1 (riempimento brillante)
			#endif
		  	mov bh, dh		// *
			inc MAYBE_EDI			// 1
			mov bl, ah		// *
			and ch, 0x3F		// 1
			add MAYBE_EAX, MAYBE_EBP		// *
			#ifdef WINDOWS
			add ch, byte ptr txtr[ebx]
			#else
		  	db 0x64, 0x02, 0x2F 	// 1+PFX (add ch, fs:[bx])
			#endif
		  	add MAYBE_EDX, MAYBE_ESI		// *
			cmp ch, 0x3E		// 1
			jbe antibloom		// * (antiblooming)
			mov ch, 0x3E }		// 1
      antibloom:asm {
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	and byte ptr [esi+edi+3], 0xC0	//REMOVE4
		  	or byte ptr [esi+edi+3], ch		//REMOVE4
		  	pop esi
		  	#else
		  	and byte ptr [di+3],0xC0// 1
			or  [di+3], ch		// 1
			#endif
		  	dec cl			// *
			jnz bright		// 1/0 (9-10 cicli.)
			jmp common }
      merger:  	asm {
		  	#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+edi+4]	//REMOVE4
		  	pop esi
		  	#else
		  	mov ch, [di+4]		// 1 (traslucido)
			#endif
		  	mov bh, dh		// *
			inc MAYBE_EDI			// 1
			mov bl, ah		// *
			and ch, 0x3F		// 1
			add MAYBE_EAX, MAYBE_EBP		// *
			#ifdef WINDOWS
			add ch, byte ptr txtr[ebx]
		  	push esi
		  	mov esi, [adapted]
		  	add ch, byte ptr [esi+0xFA00]
		  	pop esi
		  	#else
		  	db 0x64, 0x02, 0x2F 	// 1+PFX (add ch, fs:[bx])
			add ch, ds:[0xFA00]
			#endif
		  	add MAYBE_EDX, MAYBE_ESI		// *
			shr ch, 1		// 1
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	and byte ptr [esi+edi+3], 0xC0
		  	or byte ptr [esi+edi+3], ch
			pop esi
			#else
		  	and byte ptr [di+3],0xC0// 1
			or  [di+3], ch		// 1
			#endif
			dec cl			// *
			jnz merger		// 1 (9 cicli.)
			jmp common }
      bumper:  	asm {
		  	xor MAYBE_EBX, MAYBE_EBX
		  	mov bh, dh		// 1 (bump mapping)
			inc MAYBE_EDI			// *
			mov bl, ah		// 1
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+0xFA00]
			pop esi
		  	add ch, byte ptr txtr[ebx]
			#else
			mov ch, ds:[0xFA00]	// *
			db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
			#endif
			add MAYBE_EAX, MAYBE_EBP		// *
			#ifdef WINDOWS
			push esi
		  	mov byte ptr [esi+MAYBE_EDI+3], ch		// 1
			pop esi
		  	#else
			mov [di+3], ch
			#endif
			push MAYBE_EDI
			push cx
			and ch, 0x7
		}
		bmpm320:
		asm {
			sub MAYBE_EDI, 320
			dec ch
			jns bmpm320
			pop cx
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	sub ch, byte ptr [esi+0xFA00]
			add ch, byte ptr [esi+0xFA01]
			add ch, byte ptr txtr[ebx]
			mov byte ptr [esi+edi+640+3], ch
			pop esi
			#else
			sub ch, ds:[0xFA00]
			add ch, ds:[0xFA01]	// *
			db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
			mov byte ptr [di+640+3], ch
			#endif
			pop MAYBE_EDI
			add MAYBE_EDX, MAYBE_ESI		// *
			dec cl			// 1
			jnz bumper } 		// ? cicli.
	common:	asm {
			#ifdef WINDOWS
			pop ebp
			#else
			db 0x66; pop bp
			#endif
			jmp row }
	 // tracciamento di una scanline: versione a basso dettaglio
	 c_row: asm {   cmp sections, 0
			jg  c_again
			jmp row_end }
       c_again:	asm {	cmp sections, 32
			jg  c_complete
			mov ax, sections
			add ax, 2
			mov cl, al
			jmp c_unfinished }
    c_complete: asm  	mov cl, 32
  c_unfinished: asm {	sub sections, 32
			cmp cl, 2
			jl  c_row
			fld   _z	       // 1 cycle   stack: z
			fadd  k3               // 1 cycle   stack: z+k3
			fld   _x	       // 1 cycle   stack: x, z+k3
			fadd  k1               // 1 cycle   stack: x+k1, z+k3
			fxch                   // no time   stack: z+k3, x+k1
			fst   _z               // 2 cycles  stack: z+k3, x+k1
			fxch                   // no time   stack: x+k1, z+k3
			fst   _x               // 2 cycles  stack: x+k1, z+k3
			fxch                   // no time   stack: z+k3, x+k1
			fdivr _uno             // 39 cycles stack: k4, x+k1
	       	#ifdef WINDOWS
	       	mov eax, dword ptr u
	       	mov edx, dword ptr v
	       	#else
	       db 0x66; mov ax, word ptr u     // while FPU is working,
	       db 0x66; mov dx, word ptr v     // this group takes 0 cycles.
			#endif
			shr cl, 1	       //
			#ifdef WINDOWS
			push ebp
			#else
			db 0x66; push bp                //
			#endif
			mov ch, _flares	       //
			push MAYBE_EDI		       //
			fxch                   // no time   stack: x+k1, k4
			fmul  tempXsize        // 1 cycle   stack: x..., k4
			fld   _y               // 1 cycle   stack: y, x..., k4
			fadd  k2	       // 1 cycle   stack: y+k2, x..., k4
			fst   _y               // 3 cycles  stack: y+k2, x..., k4
			fmul  tempYsize        // 1 cycle   stack: y..., x..., k4
			fxch                   // no time   stack: x..., y..., k4
			fmul  st, st(2)        // 1 cycle   stack: u, y..., k4
			fxch                   // no time   stack: y..., u, k4
			fmul  st, st(2)        // 1 cycle   stack: v, u, k4
			fxch                   // no time   stack: u, v, k4
			fistp u                // 6 cycles  stack: v, k4
			fistp v                // 6 cycles  stack: k4
			#ifdef WINDOWS
	       	fstp st(0)
	       	mov esi, dword ptr v
	       	mov ebp, dword ptr u
	       	sub esi, edx
	       	sub ebp, eax
	       	sar esi, 4
	       	sar ebp, 4
	       	#else
			fstp st
	       	
	       db 0x66; mov si, word ptr v
	       db 0x66; mov bp, word ptr u
	       db 0x66; sub si, dx
	       db 0x66; sub bp, ax
	       db 0x66; sar si, 4
	       db 0x66; sar bp, 4
	       	#endif
			test ch, 15 		// NORMALE = 0
			jz c_internal
			test ch, 1		// LUCIDO = 1
			jnz c_transp
			test ch, 2		// BRILLANTE = 2
			jnz c_bright
			test ch, 4		// TRASLUCIDO = 4
			jnz c_merger
			jmp c_bumper }		// BUMP MAPPING = 8
    c_internal:	asm {
			xor MAYBE_EBX, MAYBE_EBX
			mov bh, dh		// 1 (riempimento normale)
			add MAYBE_EDI, 2		// *
			mov bl, ah		// 1
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+0xFA00]
			add ch, byte ptr txtr[ebx]
			pop esi
			#else
			mov ch, ds:[0xFA00]	// *
			db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
			#endif
			add MAYBE_EAX, MAYBE_EBP		// *
			#ifdef WINDOWS
			mov [edi+2], ch											//FIXME: Windows version crashes here. (SL)
			mov [edi+3], ch
			#else
			mov [di+2], ch		// 1
			mov [di+3], ch		// *
			#endif
			add MAYBE_EDX, MAYBE_ESI		// 1
			dec cl   		// *
			jnz c_internal  	// 1 (8 cicli).
			jmp c_common }
    c_transp:  	asm {
			xor MAYBE_EBX, MAYBE_EBX
			mov bh, dh		// 1 (riempimento lucido)
			add MAYBE_EDI, 2		// *
			mov bl, ah		// 1
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+edi+3]
			add ch, byte ptr txtr[ebx]
			pop esi
			#else
			mov ch, [di+3]		// *
			db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
			#endif
			add MAYBE_EAX, MAYBE_EBP		// *
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	mov byte ptr [esi+edi+2], ch
			mov byte ptr [esi+edi+3], ch
			pop esi
			#else
			mov [di+2], ch		// 1
			mov [di+3], ch		// *
			#endif
			add MAYBE_EDX, MAYBE_ESI		// 1
			dec cl   		// *
			jnz c_transp		// 1 (8 cicli).
			jmp c_common }
    c_bright:  	asm {
    		#ifdef WINDOWS
    		push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+edi+4]
    		pop esi
			#else
    		mov ch, [di+4]		// 1 (riempimento brillante)
    		#endif
			xor MAYBE_EBX, MAYBE_EBX
			mov bh, dh		// *
			add MAYBE_EDI, 2		// 1
			mov bl, ah		// *
			and ch, 0x3F		// 1
			add MAYBE_EAX, MAYBE_EBP		// *
			#ifdef WINDOWS
			add ch, byte ptr txtr[ebx]
			#else
			db 0x64, 0x02, 0x2F 	// 1+PFX (add ch, fs:[bx])
			#endif
			add MAYBE_EDX, MAYBE_ESI		// *
			cmp ch, 0x3E		// 1
			jbe c_antibloom		// * (antiblooming)
			mov ch, 0x3E }		// 1
    c_antibloom:asm {
//ds and es are still adapted, fs is still txtr
    		#ifdef WINDOWS
    		push esi
		  	mov esi, [adapted]
		  	and byte ptr [esi+edi+2], 0xC0
    		or ch, byte ptr [esi+edi+2]
    		dec cl
    		mov byte ptr [esi+edi+2], ch
    		mov byte ptr [esi+edi+3], ch
    		pop esi
			#else
    		and byte ptr [di+2],0xC0// 1
			or  ch, [di+2]		// 1
			dec cl    		// 1
			mov [di+2], ch		// *
			mov [di+3], ch		// 1
			#endif
			jnz c_bright		// 0 (11 cicli.)
			jmp c_common }
    c_merger:  	asm {
    		#ifdef WINDOWS
    		push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+edi+4]
			pop esi
    		#else
    		mov ch, [di+4]		// 1 (traslucido)
			#endif
			xor MAYBE_EBX, MAYBE_EBX
			mov bh, dh		// *
			add MAYBE_EDI, 2		// 1
			mov bl, ah		// *
			and ch, 0x3F		// 1
			add MAYBE_EAX, MAYBE_EBP		// *
			#ifdef WINDOWS
			add ch, byte ptr txtr[ebx]
			#else
			db 0x64, 0x02, 0x2F 	// 1+PFX (add ch, fs:[bx])
			add ch, ds:[0xFA00]
			#endif
			add MAYBE_EDX, MAYBE_ESI		// *
			shr ch, 1		// 1
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	and byte ptr [esi+edi+2],0xC0// *
			or  ch, byte ptr [esi+edi+2]		// 1
			dec cl   		// *
			mov byte ptr [esi+edi+2], ch		// 1
			mov byte ptr [esi+edi+3], ch		// *
			pop esi
			#else
			and byte ptr [di+2],0xC0// *
			or  ch, [di+2]		// 1
			dec cl   		// *
			mov [di+2], ch		// 1
			mov [di+3], ch		// *
			#endif
			jnz c_merger		// 1 (9 cicli.)
			jmp c_common }
      c_bumper: asm {
      		xor MAYBE_EBX, MAYBE_EBX
      		mov bh, dh		// 1 (bump mapping)
			add MAYBE_EDI, 2		// *
			mov bl, ah		// 1
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+0xFA00]	// *
			add ch, byte ptr txtr[ebx]
			add eax, ebp		// *
			mov byte ptr [esi+edi+2], ch		// 1
			mov byte ptr [esi+edi+3], ch		// 1
			pop esi
		  	push edi
			#else
			mov ch, ds:[0xFA00]	// *
			db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
			add ax, bp		// *
			
			mov [di+2], ch		// 1
			mov [di+3], ch		// 1
			push di
			#endif
			push cx
			and ch, 0x7 }
      c_bmpm320:asm {
      		sub MAYBE_EDI, 320
			dec ch
			jns c_bmpm320
			pop cx
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	sub ch, byte ptr [esi+0xFA00]
			add ch, byte ptr [esi+0xFA01]
			add ch, byte ptr txtr[ebx]
			mov byte ptr [esi+edi+640+2], ch
			pop esi
		  	pop edi
			#else
			sub ch, ds:[0xFA00]
			add ch, ds:[0xFA01]	// *
			db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
			mov byte ptr [di+640+2], ch
			mov byte ptr [di+640+3], ch
			pop di
			#endif
			add MAYBE_EDX, MAYBE_ESI		// *
			dec cl			// 1
			jnz c_bumper } 		// ? cicli.
      c_common:	asm {
      		#ifdef WINDOWS
      		pop edi
      		pop ebp
      		#else
      		pop MAYBE_EDI
			db 0x66; pop bp
			#endif
			add MAYBE_EDI, 32
			jmp c_row }
	// codice inter-scanline: fra una scanline e la successiva...
       row_end: asm {	test halfscan, 1
			jz do_singlescan
			inc i
			mov ax, word ptr max_y
			cmp ax, i
			#ifndef WINDOWS
			pop ds
			#endif
			jb trace_end
			MOVZX_MAYBE_ESI, i
			shl MAYBE_ESI, 1
			mov dx, word ptr ipart[MAYBE_ESI-2]
			mov ax, word ptr fpart[MAYBE_ESI-2]
			#ifdef WINDOWS
			mov edi, dword ptr riga[MAYBE_ESI*2]
			#else
			mov di, word ptr riga[MAYBE_ESI]
			push ds
			push es
			pop  ds
			#endif
			//and now ds is adapted again
			sub MAYBE_EAX, MAYBE_EDX
			jc do_singlescan
			jz do_singlescan
			add MAYBE_EDI, MAYBE_EDX }
     duplicate: asm {
     		#ifdef WINDOWS
     		push esi
		  	mov esi, [adapted]
		  	mov dl, byte ptr [esi+edi-316]
			mov byte ptr [esi+edi+4], dl
			mov byte ptr [esi+edi+324], dl
			pop esi
		 	#else
     		mov dl, [di-316]
			mov [di+4], dl
			mov [di+324], dl
			#endif
			inc MAYBE_EDI
			dec MAYBE_EAX
			jnz duplicate }
 do_singlescan:	asm {	inc i
			xor MAYBE_EAX, MAYBE_EAX
			mov ax, word ptr max_y
			cmp ax, i
			#ifndef WINDOWS
			pop ds
			#endif
			jb trace_end
			jmp trace }
     trace_end:      // Fine tracciamento.
			#ifdef WINDOWS
			0;
			#endif
}
