--- /dev/null
+;; NASM note: this file abuses the section directives in such a way that\r
+;; NASM 0.98.37 broke when this was compiled with:\r
+;; nasm -o tmap.o -f elf -DLINUX tmap.nas\r
+\r
+;;-----------------------------------------------------------------------------\r
+;;\r
+;; $Id$\r
+;;\r
+;; Copyright (C) 1998-2000 by DooM Legacy Team.\r
+;;\r
+;; This program is free software; you can redistribute it and/or\r
+;; modify it under the terms of the GNU General Public License\r
+;; as published by the Free Software Foundation; either version 2\r
+;; of the License, or (at your option) any later version.\r
+;;\r
+;; This program is distributed in the hope that it will be useful,\r
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+;; GNU General Public License for more details.\r
+;;\r
+;;\r
+;; $Log$
+;; Revision 1.1 2003/09/08 22:59:45 hpa
+;; More test files...
+;;\r
+;; Revision 1.10 2001/02/24 13:35:21 bpereira\r
+;; no message\r
+;;\r
+;; Revision 1.9 2001/02/10 15:24:19 hurdler\r
+;; Apply Rob's patch for Linux version\r
+;;\r
+;; Revision 1.8 2000/11/12 09:48:15 bpereira\r
+;; no message\r
+;;\r
+;; Revision 1.7 2000/11/06 20:52:16 bpereira\r
+;; no message\r
+;;\r
+;; Revision 1.6 2000/11/03 11:48:40 hurdler\r
+;; Fix compiling problem under win32 with 3D-Floors and FragglScript (to verify!)\r
+;;\r
+;; Revision 1.5 2000/11/03 03:27:17 stroggonmeth\r
+;; Again with the bug fixing...\r
+;;\r
+;; Revision 1.4 2000/11/02 17:50:10 stroggonmeth\r
+;; Big 3Dfloors & FraggleScript commit!!\r
+;;\r
+;; Revision 1.3 2000/04/24 20:24:38 bpereira\r
+;; no message\r
+;;\r
+;; Revision 1.2 2000/02/27 00:42:11 hurdler\r
+;; fix CR+LF problem\r
+;;\r
+;; Revision 1.1.1.1 2000/02/22 20:32:32 hurdler\r
+;; Initial import into CVS (v1.29 pr3)\r
+;;\r
+;;\r
+;; DESCRIPTION:\r
+;; assembler optimised rendering code for software mode\r
+;; draw floor spans, and wall columns.\r
+;;\r
+;;-----------------------------------------------------------------------------\r
+\r
+\r
+[BITS 32]\r
+\r
+%ifdef LINUX\r
+%macro cextern 1\r
+[extern %1]\r
+%endmacro\r
+\r
+%macro cglobal 1\r
+[global %1]\r
+%endmacro\r
+\r
+%define CODE_SEG .rwtext\r
+%else\r
+%macro cextern 1\r
+%define %1 _%1\r
+[extern %1]\r
+%endmacro\r
+\r
+%macro cglobal 1\r
+%define %1 _%1\r
+[global %1]\r
+%endmacro\r
+\r
+%define CODE_SEG .text \r
+%endif\r
+\r
+\r
+;; externs\r
+;; columns\r
+cextern dc_x\r
+cextern dc_yl\r
+cextern dc_yh\r
+cextern ylookup\r
+cextern columnofs\r
+cextern dc_source\r
+cextern dc_texturemid\r
+cextern dc_iscale\r
+cextern centery\r
+cextern dc_colormap\r
+cextern dc_transmap\r
+cextern colormaps\r
+\r
+;; spans\r
+cextern ds_x1\r
+cextern ds_x2\r
+cextern ds_y\r
+cextern ds_xfrac\r
+cextern ds_yfrac\r
+cextern ds_xstep\r
+cextern ds_ystep\r
+cextern ds_source\r
+cextern ds_colormap\r
+;cextern ds_textureheight\r
+\r
+; polygon edge rasterizer\r
+cextern prastertab\r
+\r
+\r
+;;----------------------------------------------------------------------\r
+;;\r
+;; R_DrawColumn\r
+;;\r
+;; New optimised version 10-01-1998 by D.Fabrice and P.Boris\r
+;; TO DO: optimise it much farther... should take at most 3 cycles/pix\r
+;; once it's fixed, add code to patch the offsets so that it\r
+;; works in every screen width.\r
+;;\r
+;;----------------------------------------------------------------------\r
+\r
+[SECTION .data]\r
+\r
+;;.align 4\r
+loopcount dd 0\r
+pixelcount dd 0\r
+tystep dd 0\r
+\r
+[SECTION CODE_SEG write exec]\r
+\r
+;----------------------------------------------------------------------------\r
+;fixed_t FixedMul (fixed_t a, fixed_t b)\r
+;----------------------------------------------------------------------------\r
+cglobal FixedMul\r
+; align 16\r
+FixedMul:\r
+ mov eax,[esp+4]\r
+ imul dword [esp+8]\r
+ shrd eax,edx,16\r
+ ret\r
+\r
+;----------------------------------------------------------------------------\r
+;fixed_t FixedDiv2 (fixed_t a, fixed_t b);\r
+;----------------------------------------------------------------------------\r
+cglobal FixedDiv2\r
+; align 16\r
+FixedDiv2:\r
+ mov eax,[esp+4]\r
+ mov edx,eax ;; these two instructions allow the next\r
+ sar edx,31 ;; two to pair, on the Pentium processor.\r
+ shld edx,eax,16\r
+ sal eax,16\r
+ idiv dword [esp+8]\r
+ ret\r
+\r
+;----------------------------------------------------------------------------\r
+; void ASM_PatchRowBytes (int rowbytes);\r
+;----------------------------------------------------------------------------\r
+cglobal ASM_PatchRowBytes\r
+; align 16\r
+ASM_PatchRowBytes:\r
+ mov eax,[esp+4]\r
+ mov [p1+2],eax\r
+ mov [p2+2],eax\r
+ mov [p3+2],eax\r
+ mov [p4+2],eax\r
+ mov [p5+2],eax\r
+ mov [p6+2],eax\r
+ mov [p7+2],eax\r
+ mov [p8+2],eax\r
+ mov [p9+2],eax\r
+ mov [pa+2],eax\r
+ mov [pb+2],eax\r
+ mov [pc+2],eax\r
+ mov [pd+2],eax\r
+ mov [pe+2],eax\r
+ mov [pf+2],eax\r
+ mov [pg+2],eax\r
+ mov [ph+2],eax\r
+ mov [pi+2],eax\r
+ mov [pj+2],eax\r
+ mov [pk+2],eax\r
+ mov [pl+2],eax\r
+ mov [pm+2],eax\r
+ mov [pn+2],eax\r
+ mov [po+2],eax\r
+ mov [pp+2],eax\r
+ mov [pq+2],eax\r
+ add eax,eax\r
+ mov [q1+2],eax\r
+ mov [q2+2],eax\r
+ mov [q3+2],eax\r
+ mov [q4+2],eax\r
+ mov [q5+2],eax\r
+ mov [q6+2],eax\r
+ mov [q7+2],eax\r
+ mov [q8+2],eax\r
+ ret\r
+\r
+\r
+;----------------------------------------------------------------------------\r
+; 8bpp column drawer\r
+;----------------------------------------------------------------------------\r
+\r
+cglobal R_DrawColumn_8\r
+; align 16\r
+R_DrawColumn_8:\r
+ push ebp ;; preserve caller's stack frame pointer\r
+ push esi ;; preserve register variables\r
+ push edi\r
+ push ebx\r
+;;\r
+;; dest = ylookup[dc_yl] + columnofs[dc_x];\r
+;;\r
+ mov ebp,[dc_yl]\r
+ mov ebx,ebp\r
+ mov edi,[ylookup+ebx*4]\r
+ mov ebx,[dc_x]\r
+ add edi,[columnofs+ebx*4] ;; edi = dest\r
+;;\r
+;; pixelcount = yh - yl + 1\r
+;;\r
+ mov eax,[dc_yh]\r
+ inc eax\r
+ sub eax,ebp ;; pixel count\r
+ mov [pixelcount],eax ;; save for final pixel\r
+ jle near vdone ;; nothing to scale\r
+;;\r
+;; frac = dc_texturemid - (centery-dc_yl)*fracstep;\r
+;;\r
+ mov ecx,[dc_iscale] ;; fracstep\r
+ mov eax,[centery]\r
+ sub eax,ebp\r
+ imul eax,ecx\r
+ mov edx,[dc_texturemid]\r
+ sub edx,eax\r
+ mov ebx,edx\r
+ shr ebx,16 ;; frac int.\r
+ and ebx,0x7f\r
+ shl edx,16 ;; y frac up\r
+\r
+ mov ebp,ecx\r
+ shl ebp,16 ;; fracstep f. up\r
+ shr ecx,16 ;; fracstep i. ->cl\r
+ and cl,0x7f\r
+ mov esi,[dc_source]\r
+;;\r
+;; lets rock :) !\r
+;;\r
+ mov eax,[pixelcount]\r
+ mov dh,al\r
+ shr eax,2\r
+ mov ch,al ;; quad count\r
+ mov eax,[dc_colormap]\r
+ test dh,0x3\r
+ je near v4quadloop\r
+;;\r
+;; do un-even pixel\r
+;;\r
+ test dh,0x1\r
+ je two_uneven\r
+\r
+ mov al,[esi+ebx] ;; prep un-even loops\r
+ add edx,ebp ;; ypos f += ystep f\r
+ adc bl,cl ;; ypos i += ystep i\r
+ mov dl,[eax] ;; colormap texel\r
+ and bl,0x7f ;; mask 0-127 texture index\r
+ mov [edi],dl ;; output pixel\r
+p1: add edi,0x12345678\r
+;;\r
+;; do two non-quad-aligned pixels\r
+;;\r
+two_uneven:\r
+ test dh,0x2\r
+ je f3\r
+\r
+ mov al,[esi+ebx] ;; fetch source texel\r
+ add edx,ebp ;; ypos f += ystep f\r
+ adc bl,cl ;; ypos i += ystep i\r
+ mov dl,[eax] ;; colormap texel\r
+ and bl,0x7f ;; mask 0-127 texture index\r
+ mov [edi],dl ;; output pixel\r
+ mov al,[esi+ebx]\r
+ add edx,ebp ;; fetch source texel\r
+ adc bl,cl ;; ypos f += ystep f\r
+ mov dl,[eax] ;; ypos i += ystep i\r
+ and bl,0x7f ;; colormap texel\r
+p2: add edi,0x12345678 ;; mask 0-127 texture index\r
+ mov [edi],dl\r
+p3: add edi,0x12345678 ;; output pixel\r
+;;\r
+;; test if there was at least 4 pixels\r
+;;\r
+f3:\r
+ test ch,0xff ;; test quad count\r
+ je near vdone\r
+;;\r
+;; ebp : ystep frac. upper 16 bits\r
+;; edx : y frac. upper 16 bits\r
+;; ebx : y i. lower 7 bits, masked for index\r
+;; ecx : ch = counter, cl = y step i.\r
+;; eax : colormap aligned 256\r
+;; esi : source texture column\r
+;; edi : dest screen\r
+;;\r
+v4quadloop:\r
+ mov dh,0x7f ;; prep mask\r
+align 4\r
+vquadloop:\r
+ mov al,[esi+ebx] ;; prep loop\r
+ add edx,ebp ;; ypos f += ystep f\r
+ adc bl,cl ;; ypos i += ystep i\r
+ mov dl,[eax] ;; colormap texel\r
+ mov [edi],dl ;; output pixel\r
+ and bl,0x7f ;; mask 0-127 texture index\r
+\r
+ mov al,[esi+ebx] ;; fetch source texel\r
+ add edx,ebp\r
+ adc bl,cl\r
+p4: add edi,0x12345678\r
+ mov dl,[eax]\r
+ and bl,0x7f\r
+ mov [edi],dl\r
+\r
+ mov al,[esi+ebx] ;; fetch source texel\r
+ add edx,ebp\r
+ adc bl,cl\r
+p5: add edi,0x12345678\r
+ mov dl,[eax]\r
+ and bl,0x7f\r
+ mov [edi],dl\r
+\r
+ mov al,[esi+ebx] ;; fetch source texel\r
+ add edx,ebp\r
+ adc bl,cl\r
+p6: add edi,0x12345678\r
+ mov dl,[eax]\r
+ and bl,0x7f\r
+ mov [edi],dl\r
+\r
+p7: add edi,0x12345678\r
+\r
+ dec ch\r
+ jne vquadloop\r
+\r
+vdone:\r
+ pop ebx ;; restore register variables\r
+ pop edi\r
+ pop esi\r
+ pop ebp ;; restore caller's stack frame pointer\r
+ ret\r
+\r
+;;----------------------------------------------------------------------\r
+;;13-02-98:\r
+;; R_DrawSkyColumn : same as R_DrawColumn but:\r
+;;\r
+;; - wrap around 256 instead of 127.\r
+;; this is needed because we have a higher texture for mouselook,\r
+;; we need at least 200 lines for the sky.\r
+;;\r
+;; NOTE: the sky should never wrap, so it could use a faster method.\r
+;; for the moment, we'll still use a wrapping method...\r
+;;\r
+;; IT S JUST A QUICK CUT N PASTE, WAS NOT OPTIMISED AS IT SHOULD BE !!!\r
+;;\r
+;;----------------------------------------------------------------------\r
+\r
+cglobal R_DrawSkyColumn_8\r
+; align 16\r
+R_DrawSkyColumn_8:\r
+ push ebp\r
+ push esi\r
+ push edi\r
+ push ebx\r
+;;\r
+;; dest = ylookup[dc_yl] + columnofs[dc_x];\r
+;;\r
+ mov ebp,[dc_yl]\r
+ mov ebx,ebp\r
+ mov edi,[ylookup+ebx*4]\r
+ mov ebx,[dc_x]\r
+ add edi,[columnofs+ebx*4] ;; edi = dest\r
+;;\r
+;; pixelcount = yh - yl + 1\r
+;;\r
+ mov eax,[dc_yh]\r
+ inc eax\r
+ sub eax,ebp ;; pixel count\r
+ mov [pixelcount],eax ;; save for final pixel\r
+ jle near vskydone ;; nothing to scale\r
+;;\r
+;; frac = dc_texturemid - (centery-dc_yl)*fracstep;\r
+;;\r
+ mov ecx,[dc_iscale] ;; fracstep\r
+ mov eax,[centery]\r
+ sub eax,ebp\r
+ imul eax,ecx\r
+ mov edx,[dc_texturemid]\r
+ sub edx,eax\r
+ mov ebx,edx\r
+ shr ebx,16 ;; frac int.\r
+ and ebx,0xff\r
+ shl edx,16 ;; y frac up\r
+ mov ebp,ecx\r
+ shl ebp,16 ;; fracstep f. up\r
+ shr ecx,16 ;; fracstep i. ->cl\r
+ mov esi,[dc_source]\r
+;;\r
+;; lets rock :) !\r
+;;\r
+ mov eax,[pixelcount]\r
+ mov dh,al\r
+ shr eax,0x2\r
+ mov ch,al ;; quad count\r
+ mov eax,[dc_colormap]\r
+ test dh,0x3\r
+ je vskyquadloop\r
+;;\r
+;; do un-even pixel\r
+;;\r
+ test dh,0x1\r
+ je f2\r
+ mov al,[esi+ebx] ;; prep un-even loops\r
+ add edx,ebp ;; ypos f += ystep f\r
+ adc bl,cl ;; ypos i += ystep i\r
+ mov dl,[eax] ;; colormap texel\r
+ mov [edi],dl ;; output pixel\r
+p8: add edi,0x12345678\r
+;;\r
+;; do two non-quad-aligned pixels\r
+;;\r
+f2: test dh,0x2\r
+ je skyf3\r
+\r
+ mov al,[esi+ebx] ;; fetch source texel\r
+ add edx,ebp ;; ypos f += ystep f\r
+ adc bl,cl ;; ypos i += ystep i\r
+ mov dl,[eax] ;; colormap texel\r
+ mov [edi],dl ;; output pixel\r
+\r
+ mov al,[esi+ebx] ;; fetch source texel\r
+ add edx,ebp ;; ypos f += ystep f\r
+ adc bl,cl ;; ypos i += ystep i\r
+ mov dl,[eax] ;; colormap texel\r
+p9: add edi,0x12345678\r
+ mov [edi],dl ;; output pixel\r
+\r
+pa: add edi,0x12345678\r
+;;\r
+;; test if there was at least 4 pixels\r
+;;\r
+skyf3: test ch,0xff ;; test quad count\r
+ je vskydone\r
+;;\r
+;; ebp : ystep frac. upper 24 bits\r
+;; edx : y frac. upper 24 bits\r
+;; ebx : y i. lower 7 bits, masked for index\r
+;; ecx : ch = counter, cl = y step i.\r
+;; eax : colormap aligned 256\r
+;; esi : source texture column\r
+;; edi : dest screen\r
+;;\r
+align 4\r
+vskyquadloop:\r
+ mov al,[esi+ebx] ;; prep loop\r
+ add edx,ebp ;; ypos f += ystep f\r
+ mov dl,[eax] ;; colormap texel\r
+ adc bl,cl ;; ypos i += ystep i\r
+ mov [edi],dl ;; output pixel\r
+\r
+ mov al,[esi+ebx] ;; fetch source texel\r
+ add edx,ebp\r
+ adc bl,cl\r
+pb: add edi,0x12345678\r
+ mov dl,[eax]\r
+ mov [edi],dl\r
+\r
+ mov al,[esi+ebx] ;; fetch source texel\r
+ add edx,ebp\r
+ adc bl,cl\r
+pc: add edi,0x12345678\r
+ mov dl,[eax]\r
+ mov [edi],dl\r
+\r
+ mov al,[esi+ebx] ;; fetch source texel\r
+ add edx,ebp\r
+ adc bl,cl\r
+pd: add edi,0x12345678\r
+ mov dl,[eax]\r
+ mov [edi],dl\r
+\r
+pe: add edi,0x12345678\r
+\r
+ dec ch\r
+ jne vskyquadloop\r
+vskydone:\r
+ pop ebx\r
+ pop edi\r
+ pop esi\r
+ pop ebp\r
+ ret\r
+\r
+\r
+;;----------------------------------------------------------------------\r
+;; R_DrawTranslucentColumn_8\r
+;;\r
+;; Vertical column texture drawer, with transparency. Replaces Doom2's\r
+;; 'fuzz' effect, which was not so beautiful.\r
+;; Transparency is always impressive in some way, don't know why...\r
+;;----------------------------------------------------------------------\r
+\r
+cglobal R_DrawTranslucentColumn_8\r
+R_DrawTranslucentColumn_8:\r
+ push ebp ;; preserve caller's stack frame pointer\r
+ push esi ;; preserve register variables\r
+ push edi\r
+ push ebx\r
+;;\r
+;; dest = ylookup[dc_yl] + columnofs[dc_x];\r
+;;\r
+ mov ebp,[dc_yl]\r
+ mov ebx,ebp\r
+ mov edi,[ylookup+ebx*4]\r
+ mov ebx,[dc_x]\r
+ add edi,[columnofs+ebx*4] ;; edi = dest\r
+;;\r
+;; pixelcount = yh - yl + 1\r
+;;\r
+ mov eax,[dc_yh]\r
+ inc eax\r
+ sub eax,ebp ;; pixel count\r
+ mov [pixelcount],eax ;; save for final pixel\r
+ jle near vtdone ;; nothing to scale\r
+;;\r
+;; frac = dc_texturemid - (centery-dc_yl)*fracstep;\r
+;;\r
+ mov ecx,[dc_iscale] ;; fracstep\r
+ mov eax,[centery]\r
+ sub eax,ebp\r
+ imul eax,ecx\r
+ mov edx,[dc_texturemid]\r
+ sub edx,eax\r
+ mov ebx,edx\r
+\r
+ shr ebx,16 ;; frac int.\r
+ and ebx,0x7f\r
+ shl edx,16 ;; y frac up\r
+\r
+ mov ebp,ecx\r
+ shl ebp,16 ;; fracstep f. up\r
+ shr ecx,16 ;; fracstep i. ->cl\r
+ and cl,0x7f\r
+ push cx\r
+ mov ecx,edx\r
+ pop cx\r
+ mov edx,[dc_colormap]\r
+ mov esi,[dc_source]\r
+;;\r
+;; lets rock :) !\r
+;;\r
+ mov eax,[pixelcount]\r
+ shr eax,0x2\r
+ test byte [pixelcount],0x3\r
+ mov ch,al ;; quad count\r
+ mov eax,[dc_transmap]\r
+ je vt4quadloop\r
+;;\r
+;; do un-even pixel\r
+;;\r
+ test byte [pixelcount],0x1\r
+ je trf2\r
+\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ add ecx,ebp\r
+ adc bl,cl\r
+ mov al,[edi] ;; fetch dest : index into colormap\r
+ and bl,0x7f\r
+ mov dl,[eax]\r
+ mov dl,[edx]\r
+ mov [edi],dl\r
+pf: add edi,0x12345678\r
+;;\r
+;; do two non-quad-aligned pixels\r
+;;\r
+trf2: test byte [pixelcount],0x2\r
+ je trf3\r
+\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ add ecx,ebp\r
+ adc bl,cl\r
+ mov al,[edi] ;; fetch dest : index into colormap\r
+ and bl,0x7f\r
+ mov dl,[eax]\r
+ mov dl,[edx]\r
+ mov [edi],dl\r
+pg: add edi,0x12345678\r
+\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ add ecx,ebp\r
+ adc bl,cl\r
+ mov al,[edi] ;; fetch dest : index into colormap\r
+ and bl,0x7f\r
+ mov dl,[eax]\r
+ mov dl,[edx]\r
+ mov [edi],dl\r
+ph: add edi,0x12345678\r
+;;\r
+;; test if there was at least 4 pixels\r
+;;\r
+trf3: test ch,0xff ;; test quad count\r
+ je near vtdone\r
+\r
+;;\r
+;; ebp : ystep frac. upper 24 bits\r
+;; edx : y frac. upper 24 bits\r
+;; ebx : y i. lower 7 bits, masked for index\r
+;; ecx : ch = counter, cl = y step i.\r
+;; eax : colormap aligned 256\r
+;; esi : source texture column\r
+;; edi : dest screen\r
+;;\r
+vt4quadloop:\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ mov [tystep],ebp\r
+pi: add edi,0x12345678\r
+ mov al,[edi] ;; fetch dest : index into colormap\r
+pj: sub edi,0x12345678\r
+ mov ebp,edi\r
+pk: sub edi,0x12345678\r
+ jmp short inloop\r
+align 4\r
+vtquadloop:\r
+ add ecx,[tystep]\r
+ adc bl,cl\r
+q1: add ebp,0x23456789\r
+ and bl,0x7f\r
+ mov dl,[eax]\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ mov dl,[edx]\r
+ mov [edi],dl\r
+ mov al,[ebp] ;; fetch dest : index into colormap\r
+inloop:\r
+ add ecx,[tystep]\r
+ adc bl,cl\r
+q2: add edi,0x23456789\r
+ and bl,0x7f\r
+ mov dl,[eax]\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ mov dl,[edx]\r
+ mov [ebp+0x0],dl\r
+ mov al,[edi] ;; fetch dest : index into colormap\r
+\r
+ add ecx,[tystep]\r
+ adc bl,cl\r
+q3: add ebp,0x23456789\r
+ and bl,0x7f\r
+ mov dl,[eax]\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ mov dl,[edx]\r
+ mov [edi],dl\r
+ mov al,[ebp] ;; fetch dest : index into colormap\r
+\r
+ add ecx,[tystep]\r
+ adc bl,cl\r
+q4: add edi,0x23456789\r
+ and bl,0x7f\r
+ mov dl,[eax]\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ mov dl,[edx]\r
+ mov [ebp],dl\r
+ mov al,[edi] ;; fetch dest : index into colormap\r
+\r
+ dec ch\r
+ jne vtquadloop\r
+vtdone:\r
+ pop ebx\r
+ pop edi\r
+ pop esi\r
+ pop ebp\r
+ ret\r
+\r
+\r
+;;----------------------------------------------------------------------\r
+;; R_DrawShadeColumn\r
+;;\r
+;; for smoke..etc.. test.\r
+;;----------------------------------------------------------------------\r
+cglobal R_DrawShadeColumn_8\r
+R_DrawShadeColumn_8:\r
+ push ebp ;; preserve caller's stack frame pointer\r
+ push esi ;; preserve register variables\r
+ push edi\r
+ push ebx\r
+\r
+;;\r
+;; dest = ylookup[dc_yl] + columnofs[dc_x];\r
+;;\r
+ mov ebp,[dc_yl]\r
+ mov ebx,ebp\r
+ mov edi,[ylookup+ebx*4]\r
+ mov ebx,[dc_x]\r
+ add edi,[columnofs+ebx*4] ;; edi = dest\r
+;;\r
+;; pixelcount = yh - yl + 1\r
+;;\r
+ mov eax,[dc_yh]\r
+ inc eax\r
+ sub eax,ebp ;; pixel count\r
+ mov [pixelcount],eax ;; save for final pixel\r
+ jle near shdone ;; nothing to scale\r
+;;\r
+;; frac = dc_texturemid - (centery-dc_yl)*fracstep;\r
+;;\r
+ mov ecx,[dc_iscale] ;; fracstep\r
+ mov eax,[centery]\r
+ sub eax,ebp\r
+ imul eax,ecx\r
+ mov edx,[dc_texturemid]\r
+ sub edx,eax\r
+ mov ebx,edx\r
+ shr ebx,16 ;; frac int.\r
+ and ebx,byte +0x7f\r
+ shl edx,16 ;; y frac up\r
+\r
+ mov ebp,ecx\r
+ shl ebp,16 ;; fracstep f. up\r
+ shr ecx,16 ;; fracstep i. ->cl\r
+ and cl,0x7f\r
+\r
+ mov esi,[dc_source]\r
+;;\r
+;; lets rock :) !\r
+;;\r
+ mov eax,[pixelcount]\r
+ mov dh,al\r
+ shr eax,2\r
+ mov ch,al ;; quad count\r
+ mov eax,[colormaps]\r
+ test dh,3\r
+ je sh4quadloop\r
+;;\r
+;; do un-even pixel\r
+;;\r
+ test dh,0x1\r
+ je shf2\r
+\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ add edx,ebp\r
+ adc bl,cl\r
+ mov al,[edi] ;; fetch dest : index into colormap\r
+ and bl,0x7f\r
+ mov dl,[eax]\r
+ mov [edi],dl\r
+pl: add edi,0x12345678\r
+;;\r
+;; do two non-quad-aligned pixels\r
+;;\r
+shf2:\r
+ test dh,0x2\r
+ je shf3\r
+\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ add edx,ebp\r
+ adc bl,cl\r
+ mov al,[edi] ;; fetch dest : index into colormap\r
+ and bl,0x7f\r
+ mov dl,[eax]\r
+ mov [edi],dl\r
+pm: add edi,0x12345678\r
+\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ add edx,ebp\r
+ adc bl,cl\r
+ mov al,[edi] ;; fetch dest : index into colormap\r
+ and bl,0x7f\r
+ mov dl,[eax]\r
+ mov [edi],dl\r
+pn: add edi,0x12345678\r
+;;\r
+;; test if there was at least 4 pixels\r
+;;\r
+shf3:\r
+ test ch,0xff ;; test quad count\r
+ je near shdone\r
+\r
+;;\r
+;; ebp : ystep frac. upper 24 bits\r
+;; edx : y frac. upper 24 bits\r
+;; ebx : y i. lower 7 bits, masked for index\r
+;; ecx : ch = counter, cl = y step i.\r
+;; eax : colormap aligned 256\r
+;; esi : source texture column\r
+;; edi : dest screen\r
+;;\r
+sh4quadloop:\r
+ mov dh,0x7f ;; prep mask\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ mov [tystep],ebp\r
+po: add edi,0x12345678\r
+ mov al,[edi] ;; fetch dest : index into colormap\r
+pp: sub edi,0x12345678\r
+ mov ebp,edi\r
+pq: sub edi,0x12345678\r
+ jmp short shinloop\r
+\r
+align 4\r
+shquadloop:\r
+ add edx,[tystep]\r
+ adc bl,cl\r
+ and bl,dh\r
+q5: add ebp,0x12345678\r
+ mov dl,[eax]\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ mov [edi],dl\r
+ mov al,[ebp] ;; fetch dest : index into colormap\r
+shinloop:\r
+ add edx,[tystep]\r
+ adc bl,cl\r
+ and bl,dh\r
+q6: add edi,0x12345678\r
+ mov dl,[eax]\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ mov [ebp],dl\r
+ mov al,[edi] ;; fetch dest : index into colormap\r
+\r
+ add edx,[tystep]\r
+ adc bl,cl\r
+ and bl,dh\r
+q7: add ebp,0x12345678\r
+ mov dl,[eax]\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ mov [edi],dl\r
+ mov al,[ebp] ;; fetch dest : index into colormap\r
+\r
+ add edx,[tystep]\r
+ adc bl,cl\r
+ and bl,dh\r
+q8: add edi,0x12345678\r
+ mov dl,[eax]\r
+ mov ah,[esi+ebx] ;; fetch texel : colormap number\r
+ mov [ebp],dl\r
+ mov al,[edi] ;; fetch dest : index into colormap\r
+\r
+ dec ch\r
+ jne shquadloop\r
+\r
+shdone:\r
+ pop ebx ;; restore register variables\r
+ pop edi\r
+ pop esi\r
+ pop ebp ;; restore caller's stack frame pointer\r
+ ret\r
+\r
+\r
+\r
+;;----------------------------------------------------------------------\r
+;;\r
+;; R_DrawSpan\r
+;;\r
+;; Horizontal texture mapping\r
+;;\r
+;;----------------------------------------------------------------------\r
+\r
+\r
+[SECTION .data]\r
+\r
+oldcolormap dd 0\r
+\r
+[SECTION CODE_SEG write exec]\r
+\r
+cglobal R_DrawSpan_8\r
+R_DrawSpan_8:\r
+ push ebp ;; preserve caller's stack frame pointer\r
+ push esi ;; preserve register variables\r
+ push edi\r
+ push ebx\r
+;;\r
+;; initilise registers\r
+;;\r
+ \r
+ mov edx, [ds_xfrac]\r
+ mov eax, [ds_ystep]\r
+ ror edx, 14\r
+ ror eax, 15\r
+ mov bl, dl\r
+ mov ecx, [ds_xstep]\r
+ mov dh, al\r
+ mov ax, 1\r
+ mov [tystep], eax\r
+\r
+\r
+ mov eax, [ds_yfrac]\r
+ ror ecx, 13\r
+ ror eax, 16\r
+ mov dl, cl\r
+ mov bh, al\r
+ xor cx, cx\r
+ and ebx, 0x3fff\r
+ mov [pixelcount],ecx\r
+\r
+ mov ecx, [ds_x2]\r
+ mov edi, [ds_y]\r
+ mov esi, [ds_x1]\r
+ mov edi, [ylookup+edi*4]\r
+ mov ebp, ebx\r
+ add edi, [columnofs+esi*4]\r
+ sub esi, ecx ;; pixel count\r
+ shr ebp, 2\r
+ mov ecx, [ds_colormap]\r
+ mov ax, si\r
+ mov esi, [ds_source]\r
+ sar ax,1\r
+ jnc near .midloop ;; check parity\r
+\r
+; summary\r
+; edx = high16bit xfrac[0..13], ah=ystep[16..24] al=xtep[14..21]\r
+; ebx = high16bit =0, bh=yfrac[16..24], bl=xfrac[14..21] \r
+; ecx = colormap table cl=0 (colormap is aligned 8 bits)\r
+; eax = high16bit yfrac[0..15], dx = count\r
+; esi = flat texture source\r
+; edi = screeen buffer destination\r
+; ebp = work register\r
+; pixelcount = high16bit xstep[0..13] rest to 0\r
+; tystep = high16bit ystep[0..15] low 16 bit = 2 (increment of count)\r
+\r
+align 4\r
+.loop\r
+ add eax, [tystep]\r
+ mov cl, [esi+ebp]\r
+ adc bh, dh\r
+ mov cl, [ecx]\r
+ and bh, 0x3f \r
+ mov [edi], cl\r
+ mov ebp, ebx \r
+ inc edi\r
+ shr ebp, 2\r
+\r
+.midloop:\r
+ add edx, [pixelcount]\r
+ mov cl, [esi+ebp]\r
+ adc bl, dl\r
+ mov cl, [ecx]\r
+ mov ebp, ebx \r
+ mov [edi], cl\r
+ inc edi\r
+ shr ebp, 2\r
+\r
+ test eax, 0xffff\r
+ jnz near .loop\r
+\r
+.hdone: pop ebx ;; restore register variables\r
+ pop edi\r
+ pop esi\r
+ pop ebp ;; restore caller's stack frame pointer\r
+ ret\r
+\r
+\r
+[SECTION .data]\r
+\r
+obelix dd 0\r
+etaussi dd 0\r
+\r
+[SECTION .text]\r
+\r
+cglobal R_DrawSpan_8_old\r
+R_DrawSpan_8_old:\r
+ push ebp ;; preserve caller's stack frame pointer\r
+ push esi ;; preserve register variables\r
+ push edi\r
+ push ebx\r
+;;\r
+;; find loop count\r
+;;\r
+ mov eax,[ds_x2]\r
+ inc eax\r
+ sub eax,[ds_x1] ;; pixel count\r
+ mov [pixelcount],eax ;; save for final pixel\r
+ js near .hdone ;; nothing to scale\r
+ shr eax,0x1 ;; double pixel count\r
+ mov [loopcount],eax\r
+;;\r
+;; build composite position\r
+;;\r
+ mov ebp,[ds_xfrac]\r
+ shl ebp,10\r
+ and ebp,0xffff0000\r
+ mov eax,[ds_yfrac]\r
+ shr eax,6\r
+ and eax,0xffff\r
+ mov edi,[ds_y]\r
+ or ebp,eax\r
+\r
+ mov esi,[ds_source]\r
+;;\r
+;; calculate screen dest\r
+;;\r
+ mov edi,[ylookup+edi*4]\r
+ mov eax,[ds_x1]\r
+ add edi,[columnofs+eax*4]\r
+;;\r
+;; build composite step\r
+;;\r
+ mov ebx,[ds_xstep]\r
+ shl ebx,10\r
+ and ebx,0xffff0000\r
+ mov eax,[ds_ystep]\r
+ shr eax,6\r
+ and eax,0xffff\r
+ or ebx,eax\r
+\r
+ mov [obelix],ebx\r
+ mov [etaussi],esi\r
+\r
+;; %eax aligned colormap\r
+;; %ebx aligned colormap\r
+;; %ecx,%edx scratch\r
+;; %esi virtual source\r
+;; %edi moving destination pointer\r
+;; %ebp frac\r
+\r
+ mov eax,[ds_colormap]\r
+ mov ecx,ebp\r
+ add ebp,ebx ;; advance frac pointer\r
+ shr cx,10\r
+ rol ecx,6\r
+ and ecx,4095 ;; finish calculation for third pixel\r
+ mov edx,ebp\r
+ shr dx,10\r
+ rol edx,6\r
+ add ebp,ebx ;; advance frac pointer\r
+ and edx,4095 ;; finish calculation for fourth pixel\r
+ mov ebx,eax\r
+ mov al,[esi+ecx] ;; get first pixel\r
+ mov bl,[esi+edx] ;; get second pixel\r
+\r
+ test dword [pixelcount],0xfffffffe\r
+\r
+ mov dl,[eax] ;; color translate first pixel\r
+\r
+;; movw $0xf0f0,%dx ;;see visplanes start\r
+\r
+ je .hchecklast\r
+\r
+ mov dh,[ebx] ;; color translate second pixel\r
+ mov esi,[loopcount]\r
+align 4\r
+.hdoubleloop:\r
+ mov ecx,ebp\r
+ shr cx,10\r
+ rol ecx,6\r
+ add ebp,[obelix] ;; advance frac pointer\r
+ mov [edi],dx ;; write first pixel\r
+ and ecx,4095 ;; finish calculation for third pixel\r
+ mov edx,ebp\r
+ shr dx,10\r
+ rol edx,6\r
+ add ecx,[etaussi]\r
+ and edx,4095 ;; finish calculation for fourth pixel\r
+ mov al,[ecx] ;; get third pixel\r
+ add ebp,[obelix] ;; advance frac pointer\r
+ add edx,[etaussi]\r
+ mov bl,[edx] ;; get fourth pixel\r
+ mov dl,[eax] ;; color translate third pixel\r
+ add edi,byte +0x2 ;; advance to third pixel destination\r
+ dec esi ;; done with loop?\r
+ mov dh,[ebx] ;; color translate fourth pixel\r
+ jne .hdoubleloop\r
+;; check for final pixel\r
+.hchecklast:\r
+ test dword [pixelcount],0x1\r
+ je .hdone\r
+ mov [edi],dl ;; write final pixel\r
+.hdone: pop ebx ;; restore register variables\r
+ pop edi\r
+ pop esi\r
+ pop ebp ;; restore caller's stack frame pointer\r
+ ret\r
+\r
+\r
+;; ========================================================================\r
+;; Rasterization des segments d'un polyg\93ne textur\82 de mani\8are LINEAIRE.\r
+;; Il s'agit donc d'interpoler les coordonn\82es aux bords de la texture en\r
+;; m\88me temps que les abscisses minx/maxx pour chaque ligne.\r
+;; L'argument 'dir' indique quels bords de la texture sont interpolés:\r
+;; 0 : segments associ\82s aux bord SUPERIEUR et INFERIEUR ( TY constant )\r
+;; 1 : segments associ\82s aux bord GAUCHE et DROITE ( TX constant )\r
+;; ========================================================================\r
+;;\r
+;; void rasterize_segment_tex( LONG x1, LONG y1, LONG x2, LONG y2, LONG tv1, LONG tv2, LONG tc, LONG dir );\r
+;; ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 ARG7 ARG8\r
+;;\r
+;; Pour dir = 0, (tv1,tv2) = (tX1,tX2), tc = tY, en effet TY est constant.\r
+;;\r
+;; Pour dir = 1, (tv1,tv2) = (tY1,tY2), tc = tX, en effet TX est constant.\r
+;;\r
+;;\r
+;; Uses: extern struct rastery *_rastertab;\r
+;;\r
+\r
+[SECTION CODE_SEG write exec]\r
+\r
+MINX EQU 0\r
+MAXX EQU 4\r
+TX1 EQU 8\r
+TY1 EQU 12\r
+TX2 EQU 16\r
+TY2 EQU 20\r
+RASTERY_SIZEOF EQU 24\r
+\r
+cglobal rasterize_segment_tex\r
+rasterize_segment_tex:\r
+ push ebp\r
+ mov ebp,esp\r
+\r
+ sub esp,byte +0x8 ;; alloue les variables locales\r
+\r
+ push ebx\r
+ push esi\r
+ push edi\r
+ o16 mov ax,es\r
+ push eax\r
+\r
+;; #define DX [ebp-4]\r
+;; #define TD [ebp-8]\r
+\r
+ mov eax,[ebp+0xc] ;; y1\r
+ mov ebx,[ebp+0x14] ;; y2\r
+ cmp ebx,eax\r
+ je near .L_finished ;; special (y1==y2) segment horizontal, exit!\r
+\r
+ jg near .L_rasterize_right\r
+\r
+;;rasterize_left: ;; on rasterize un segment \85 la GAUCHE du polyg\93ne\r
+\r
+ mov ecx,eax\r
+ sub ecx,ebx\r
+ inc ecx ;; y1-y2+1\r
+\r
+ mov eax,RASTERY_SIZEOF\r
+ mul ebx ;; * y2\r
+ mov esi,[prastertab]\r
+ add esi,eax ;; point into rastertab[y2]\r
+\r
+ mov eax,[ebp+0x8] ;; ARG1\r
+ sub eax,[ebp+0x10] ;; ARG3\r
+ shl eax,0x10 ;; ((x1-x2)<<PRE) ...\r
+ cdq\r
+ idiv ecx ;; dx = ... / (y1-y2+1)\r
+ mov [ebp-0x4],eax ;; DX\r
+\r
+ mov eax,[ebp+0x18] ;; ARG5\r
+ sub eax,[ebp+0x1c] ;; ARG6\r
+ shl eax,0x10\r
+ cdq\r
+ idiv ecx ;; tdx =((tx1-tx2)<<PRE) / (y1-y2+1)\r
+ mov [ebp-0x8],eax ;; idem tdy =((ty1-ty2)<<PRE) / (y1-y2+1)\r
+\r
+ mov eax,[ebp+0x10] ;; ARG3\r
+ shl eax,0x10 ;; x = x2<<PRE\r
+\r
+ mov ebx,[ebp+0x1c] ;; ARG6\r
+ shl ebx,0x10 ;; tx = tx2<<PRE d0\r
+ ;; ty = ty2<<PRE d1\r
+ mov edx,[ebp+0x20] ;; ARG7\r
+ shl edx,0x10 ;; ty = ty<<PRE d0\r
+ ;; tx = tx<<PRE d1\r
+ push ebp\r
+ mov edi,[ebp-0x4] ;; DX\r
+ cmp dword [ebp+0x24],byte +0x0 ;; ARG8 direction ?\r
+\r
+ mov ebp,[ebp-0x8] ;; TD\r
+ je .L_rleft_h_loop\r
+;;\r
+;; TY varie, TX est constant\r
+;;\r
+.L_rleft_v_loop:\r
+ mov [esi+MINX],eax ;; rastertab[y].minx = x\r
+ add ebx,ebp\r
+ mov [esi+TX1],edx ;; .tx1 = tx\r
+ add eax,edi\r
+ mov [esi+TY1],ebx ;; .ty1 = ty\r
+\r
+ ;;addl DX, %eax // x += dx\r
+ ;;addl TD, %ebx // ty += tdy\r
+\r
+ add esi,RASTERY_SIZEOF ;; next raster line into rastertab[]\r
+ dec ecx\r
+ jne .L_rleft_v_loop\r
+ pop ebp\r
+ jmp .L_finished\r
+;;\r
+;; TX varie, TY est constant\r
+;;\r
+.L_rleft_h_loop:\r
+ mov [esi+MINX],eax ;; rastertab[y].minx = x\r
+ add eax,edi\r
+ mov [esi+TX1],ebx ;; .tx1 = tx\r
+ add ebx,ebp\r
+ mov [esi+TY1],edx ;; .ty1 = ty\r
+\r
+ ;;addl DX, %eax // x += dx\r
+ ;;addl TD, %ebx // tx += tdx\r
+\r
+ add esi,RASTERY_SIZEOF ;; next raster line into rastertab[]\r
+ dec ecx\r
+ jne .L_rleft_h_loop\r
+ pop ebp\r
+ jmp .L_finished\r
+;;\r
+;; on rasterize un segment \85 la DROITE du polyg\93ne\r
+;;\r
+.L_rasterize_right:\r
+ mov ecx,ebx\r
+ sub ecx,eax\r
+ inc ecx ;; y2-y1+1\r
+\r
+ mov ebx,RASTERY_SIZEOF\r
+ mul ebx ;; * y1\r
+ mov esi,[prastertab]\r
+ add esi,eax ;; point into rastertab[y1]\r
+\r
+ mov eax,[ebp+0x10] ;; ARG3\r
+ sub eax,[ebp+0x8] ;; ARG1\r
+ shl eax,0x10 ;; ((x2-x1)<<PRE) ...\r
+ cdq\r
+ idiv ecx ;; dx = ... / (y2-y1+1)\r
+ mov [ebp-0x4],eax ;; DX\r
+\r
+ mov eax,[ebp+0x1c] ;; ARG6\r
+ sub eax,[ebp+0x18] ;; ARG5\r
+ shl eax,0x10\r
+ cdq\r
+ idiv ecx ;; tdx =((tx2-tx1)<<PRE) / (y2-y1+1)\r
+ mov [ebp-0x8],eax ;; idem tdy =((ty2-ty1)<<PRE) / (y2-y1+1)\r
+\r
+ mov eax,[ebp+0x8] ;; ARG1\r
+ shl eax,0x10 ;; x = x1<<PRE\r
+\r
+ mov ebx,[ebp+0x18] ;; ARG5\r
+ shl ebx,0x10 ;; tx = tx1<<PRE d0\r
+ ;; ty = ty1<<PRE d1\r
+ mov edx,[ebp+0x20] ;; ARG7\r
+ shl edx,0x10 ;; ty = ty<<PRE d0\r
+ ;; tx = tx<<PRE d1\r
+ push ebp\r
+ mov edi,[ebp-0x4] ;; DX\r
+\r
+ cmp dword [ebp+0x24], 0 ;; direction ?\r
+\r
+ mov ebp,[ebp-0x8] ;; TD\r
+ je .L_rright_h_loop\r
+;;\r
+;; TY varie, TX est constant\r
+;;\r
+.L_rright_v_loop:\r
+\r
+ mov [esi+MAXX],eax ;; rastertab[y].maxx = x\r
+ add ebx,ebp\r
+ mov [esi+TX2],edx ;; .tx2 = tx\r
+ add eax,edi\r
+ mov [esi+TY2],ebx ;; .ty2 = ty\r
+\r
+ ;;addl DX, %eax // x += dx\r
+ ;;addl TD, %ebx // ty += tdy\r
+\r
+ add esi,RASTERY_SIZEOF\r
+ dec ecx\r
+ jne .L_rright_v_loop\r
+\r
+ pop ebp\r
+\r
+ jmp short .L_finished\r
+;;\r
+;; TX varie, TY est constant\r
+;;\r
+.L_rright_h_loop:\r
+ mov [esi+MAXX],eax ;; rastertab[y].maxx = x\r
+ add eax,edi\r
+ mov [esi+TX2],ebx ;; .tx2 = tx\r
+ add ebx,ebp\r
+ mov [esi+TY2],edx ;; .ty2 = ty\r
+\r
+ ;;addl DX, %eax // x += dx\r
+ ;;addl TD, %ebx // tx += tdx\r
+\r
+ add esi,RASTERY_SIZEOF\r
+ dec ecx\r
+ jne .L_rright_h_loop\r
+\r
+ pop ebp\r
+\r
+.L_finished:\r
+ pop eax\r
+ o16 mov es,ax\r
+ pop edi\r
+ pop esi\r
+ pop ebx\r
+\r
+ mov esp,ebp\r
+ pop ebp\r
+ ret\r
+\r
+\r
+;;; this version can draw 64x64 tiles, but they would have to be arranged 4 per row,\r
+;; so that the stride from one line to the next is 256\r
+;;\r
+;; .data\r
+;;xstep dd 0\r
+;;ystep dd 0\r
+;;texwidth dd 64 ;; texture width\r
+;; .text\r
+;; this code is kept in case we add high-detail floor textures for example (256x256)\r
+; align 16\r
+;_R_DrawSpan_8:\r
+; push ebp ;; preserve caller's stack frame pointer\r
+; push esi ;; preserve register variables\r
+; push edi\r
+; push ebx\r
+;;\r
+;; find loop count\r
+;;\r
+; mov eax,[ds_x2]\r
+; inc eax\r
+; sub eax,[ds_x1] ;; pixel count\r
+; mov [pixelcount],eax ;; save for final pixel\r
+; js near .hdone ;; nothing to scale\r
+;;\r
+;; calculate screen dest\r
+;;\r
+; mov edi,[ds_y]\r
+; mov edi,[ylookup+edi*4]\r
+; mov eax,[ds_x1]\r
+; add edi,[columnofs+eax*4]\r
+;;\r
+;; prepare registers for inner loop\r
+;;\r
+; xor eax,eax\r
+; mov edx,[ds_xfrac]\r
+; ror edx,16\r
+; mov al,dl\r
+; mov ecx,[ds_yfrac]\r
+; ror ecx,16\r
+; mov ah,cl\r
+;\r
+; mov ebx,[ds_xstep]\r
+; ror ebx,16\r
+; mov ch,bl\r
+; and ebx,0xffff0000\r
+; mov [xstep],ebx\r
+; mov ebx,[ds_ystep]\r
+; ror ebx,16\r
+; mov dh,bl\r
+; and ebx,0xffff0000\r
+; mov [ystep],ebx\r
+;\r
+; mov esi,[ds_source]\r
+;\r
+;;; %eax Yi,Xi in %ah,%al\r
+;;; %ebx aligned colormap\r
+;;; %ecx Yfrac upper, dXi in %ch, %cl is counter (upto 1024pels, =4x256)\r
+;;; %edx Xfrac upper, dYi in %dh, %dl receives mapped pixels from (ebx)\r
+;;; ystep dYfrac, add to %ecx, low word is 0\r
+;;; xstep dXfrac, add to %edx, low word is 0\r
+;;; %ebp temporary register serves as offset like %eax\r
+;;; %esi virtual source\r
+;;; %edi moving destination pointer\r
+;\r
+; mov ebx,[pixelcount]\r
+; shr ebx,0x2 ;; 4 pixels per loop\r
+; test bl,0xff\r
+; je near .hchecklast\r
+; mov cl,bl\r
+;\r
+; mov ebx,[dc_colormap]\r
+;;;\r
+;;; prepare loop with first pixel\r
+;;;\r
+; add ecx,[ystep] ;;pr\82a1\r
+; adc ah,dh\r
+; add edx,[xstep]\r
+; adc al,ch\r
+; and eax,0x3f3f\r
+; mov bl,[esi+eax] ;;pr\82b1\r
+; mov dl,[ebx] ;;pr\82c1\r
+;\r
+; add ecx,[ystep] ;;a2\r
+; adc ah,dh\r
+;\r
+;.hdoubleloop:\r
+; mov [edi+1],dl\r
+; add edx,[xstep]\r
+; adc al,ch\r
+; add edi,byte +0x2\r
+; mov ebp,eax\r
+; add ecx,[ystep]\r
+; adc ah,dh\r
+; and ebp,0x3f3f\r
+; add edx,[xstep]\r
+; mov bl,[esi+ebp]\r
+; adc al,ch\r
+; mov dl,[ebx]\r
+; and eax,0x3f3f\r
+; mov [edi],dl\r
+; mov bl,[esi+eax]\r
+; add ecx,[ystep]\r
+; adc ah,dh\r
+; add edx,[xstep]\r
+; adc al,ch\r
+; mov dl,[ebx]\r
+; mov ebp,eax\r
+; mov [edi+1],dl\r
+; and ebp,0x3f3f\r
+; add ecx,[ystep]\r
+; adc ah,dh\r
+; mov bl,[esi+ebp]\r
+; add edi,byte +0x2\r
+; add edx,[xstep]\r
+; adc al,ch\r
+; mov dl,[ebx]\r
+; and eax,0x3f3f\r
+; mov [edi],dl\r
+; mov bl,[esi+eax]\r
+; add ecx,[ystep]\r
+; adc ah,dh\r
+; mov dl,[ebx]\r
+; dec cl\r
+; jne near .hdoubleloop\r
+;;; check for final pixel\r
+;.hchecklast:\r
+;;; to do\r
+;.hdone:\r
+; pop ebx\r
+; pop edi\r
+; pop esi\r
+; pop ebp\r
+; ret\r