quake2forge/ref_soft/r_surf8.asm
2001-12-22 04:27:19 +00:00

771 lines
15 KiB
NASM

.386P
.model FLAT
;
; surf8.s
; x86 assembly-language 8 bpp surface block drawing code.
;
include qasm.inc
if id386
_DATA SEGMENT
sb_v dd 0
_DATA ENDS
_TEXT SEGMENT
align 4
public _R_Surf8Start
_R_Surf8Start:
;----------------------------------------------------------------------
; Surface block drawer for mip level 0
;----------------------------------------------------------------------
align 4
public _R_DrawSurfaceBlock8_mip0
_R_DrawSurfaceBlock8_mip0:
push ebp ; preserve caller's stack frame
push edi
push esi ; preserve register variables
push ebx
; for (v=0 ; v<numvblocks ; v++)
; {
mov ebx,ds:dword ptr[_r_lightptr]
mov eax,ds:dword ptr[_r_numvblocks]
mov ds:dword ptr[sb_v],eax
mov edi,ds:dword ptr[_prowdestbase]
mov esi,ds:dword ptr[_pbasesource]
Lv_loop_mip0:
; lightleft = lightptr[0];
; lightright = lightptr[1];
; lightdelta = (lightleft - lightright) & 0xFFFFF;
mov eax,ds:dword ptr[ebx] ; lightleft
mov edx,ds:dword ptr[4+ebx] ; lightright
mov ebp,eax
mov ecx,ds:dword ptr[_r_lightwidth]
mov ds:dword ptr[_lightright],edx
sub ebp,edx
and ebp,0FFFFFh
lea ebx,ds:dword ptr[ebx+ecx*4]
; lightptr += lightwidth;
mov ds:dword ptr[_r_lightptr],ebx
; lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
; lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
; lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
; 0xF0000000;
mov ecx,ds:dword ptr[4+ebx] ; lightptr[1]
mov ebx,ds:dword ptr[ebx] ; lightptr[0]
sub ebx,eax
sub ecx,edx
sar ecx,4
or ebp,0F0000000h
sar ebx,4
mov ds:dword ptr[_lightrightstep],ecx
sub ebx,ecx
and ebx,0FFFFFh
or ebx,0F0000000h
sub ecx,ecx ; high word must be 0 in loop for addressing
mov ds:dword ptr[_lightdeltastep],ebx
sub ebx,ebx ; high word must be 0 in loop for addressing
Lblockloop8_mip0:
mov ds:dword ptr[_lightdelta],ebp
mov cl,ds:byte ptr[14+esi]
sar ebp,4
mov bh,dh
mov bl,ds:byte ptr[15+esi]
add edx,ebp
mov ch,dh
add edx,ebp
mov ah,ds:byte ptr[12345678h+ebx]
LBPatch0:
mov bl,ds:byte ptr[13+esi]
mov al,ds:byte ptr[12345678h+ecx]
LBPatch1:
mov cl,ds:byte ptr[12+esi]
mov bh,dh
add edx,ebp
ror eax,16
mov ch,dh
add edx,ebp
mov ah,ds:byte ptr[12345678h+ebx]
LBPatch2:
mov bl,ds:byte ptr[11+esi]
mov al,ds:byte ptr[12345678h+ecx]
LBPatch3:
mov cl,ds:byte ptr[10+esi]
mov ds:dword ptr[12+edi],eax
mov bh,dh
add edx,ebp
mov ch,dh
add edx,ebp
mov ah,ds:byte ptr[12345678h+ebx]
LBPatch4:
mov bl,ds:byte ptr[9+esi]
mov al,ds:byte ptr[12345678h+ecx]
LBPatch5:
mov cl,ds:byte ptr[8+esi]
mov bh,dh
add edx,ebp
ror eax,16
mov ch,dh
add edx,ebp
mov ah,ds:byte ptr[12345678h+ebx]
LBPatch6:
mov bl,ds:byte ptr[7+esi]
mov al,ds:byte ptr[12345678h+ecx]
LBPatch7:
mov cl,ds:byte ptr[6+esi]
mov ds:dword ptr[8+edi],eax
mov bh,dh
add edx,ebp
mov ch,dh
add edx,ebp
mov ah,ds:byte ptr[12345678h+ebx]
LBPatch8:
mov bl,ds:byte ptr[5+esi]
mov al,ds:byte ptr[12345678h+ecx]
LBPatch9:
mov cl,ds:byte ptr[4+esi]
mov bh,dh
add edx,ebp
ror eax,16
mov ch,dh
add edx,ebp
mov ah,ds:byte ptr[12345678h+ebx]
LBPatch10:
mov bl,ds:byte ptr[3+esi]
mov al,ds:byte ptr[12345678h+ecx]
LBPatch11:
mov cl,ds:byte ptr[2+esi]
mov ds:dword ptr[4+edi],eax
mov bh,dh
add edx,ebp
mov ch,dh
add edx,ebp
mov ah,ds:byte ptr[12345678h+ebx]
LBPatch12:
mov bl,ds:byte ptr[1+esi]
mov al,ds:byte ptr[12345678h+ecx]
LBPatch13:
mov cl,ds:byte ptr[esi]
mov bh,dh
add edx,ebp
ror eax,16
mov ch,dh
mov ah,ds:byte ptr[12345678h+ebx]
LBPatch14:
mov edx,ds:dword ptr[_lightright]
mov al,ds:byte ptr[12345678h+ecx]
LBPatch15:
mov ebp,ds:dword ptr[_lightdelta]
mov ds:dword ptr[edi],eax
add esi,ds:dword ptr[_sourcetstep]
add edi,ds:dword ptr[_surfrowbytes]
add edx,ds:dword ptr[_lightrightstep]
add ebp,ds:dword ptr[_lightdeltastep]
mov ds:dword ptr[_lightright],edx
jc Lblockloop8_mip0
; if (pbasesource >= r_sourcemax)
; pbasesource -= stepback;
cmp esi,ds:dword ptr[_r_sourcemax]
jb LSkip_mip0
sub esi,ds:dword ptr[_r_stepback]
LSkip_mip0:
mov ebx,ds:dword ptr[_r_lightptr]
dec ds:dword ptr[sb_v]
jnz Lv_loop_mip0
pop ebx ; restore register variables
pop esi
pop edi
pop ebp ; restore the caller's stack frame
ret
;----------------------------------------------------------------------
; Surface block drawer for mip level 1
;----------------------------------------------------------------------
align 4
public _R_DrawSurfaceBlock8_mip1
_R_DrawSurfaceBlock8_mip1:
push ebp ; preserve caller's stack frame
push edi
push esi ; preserve register variables
push ebx
; for (v=0 ; v<numvblocks ; v++)
; {
mov ebx,ds:dword ptr[_r_lightptr]
mov eax,ds:dword ptr[_r_numvblocks]
mov ds:dword ptr[sb_v],eax
mov edi,ds:dword ptr[_prowdestbase]
mov esi,ds:dword ptr[_pbasesource]
Lv_loop_mip1:
; lightleft = lightptr[0];
; lightright = lightptr[1];
; lightdelta = (lightleft - lightright) & 0xFFFFF;
mov eax,ds:dword ptr[ebx] ; lightleft
mov edx,ds:dword ptr[4+ebx] ; lightright
mov ebp,eax
mov ecx,ds:dword ptr[_r_lightwidth]
mov ds:dword ptr[_lightright],edx
sub ebp,edx
and ebp,0FFFFFh
lea ebx,ds:dword ptr[ebx+ecx*4]
; lightptr += lightwidth;
mov ds:dword ptr[_r_lightptr],ebx
; lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
; lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
; lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
; 0xF0000000;
mov ecx,ds:dword ptr[4+ebx] ; lightptr[1]
mov ebx,ds:dword ptr[ebx] ; lightptr[0]
sub ebx,eax
sub ecx,edx
sar ecx,3
or ebp,070000000h
sar ebx,3
mov ds:dword ptr[_lightrightstep],ecx
sub ebx,ecx
and ebx,0FFFFFh
or ebx,0F0000000h
sub ecx,ecx ; high word must be 0 in loop for addressing
mov ds:dword ptr[_lightdeltastep],ebx
sub ebx,ebx ; high word must be 0 in loop for addressing
Lblockloop8_mip1:
mov ds:dword ptr[_lightdelta],ebp
mov cl,ds:byte ptr[6+esi]
sar ebp,3
mov bh,dh
mov bl,ds:byte ptr[7+esi]
add edx,ebp
mov ch,dh
add edx,ebp
mov ah,ds:byte ptr[12345678h+ebx]
LBPatch22:
mov bl,ds:byte ptr[5+esi]
mov al,ds:byte ptr[12345678h+ecx]
LBPatch23:
mov cl,ds:byte ptr[4+esi]
mov bh,dh
add edx,ebp
ror eax,16
mov ch,dh
add edx,ebp
mov ah,ds:byte ptr[12345678h+ebx]
LBPatch24:
mov bl,ds:byte ptr[3+esi]
mov al,ds:byte ptr[12345678h+ecx]
LBPatch25:
mov cl,ds:byte ptr[2+esi]
mov ds:dword ptr[4+edi],eax
mov bh,dh
add edx,ebp
mov ch,dh
add edx,ebp
mov ah,ds:byte ptr[12345678h+ebx]
LBPatch26:
mov bl,ds:byte ptr[1+esi]
mov al,ds:byte ptr[12345678h+ecx]
LBPatch27:
mov cl,ds:byte ptr[esi]
mov bh,dh
add edx,ebp
ror eax,16
mov ch,dh
mov ah,ds:byte ptr[12345678h+ebx]
LBPatch28:
mov edx,ds:dword ptr[_lightright]
mov al,ds:byte ptr[12345678h+ecx]
LBPatch29:
mov ebp,ds:dword ptr[_lightdelta]
mov ds:dword ptr[edi],eax
mov eax,ds:dword ptr[_sourcetstep]
add esi,eax
mov eax,ds:dword ptr[_surfrowbytes]
add edi,eax
mov eax,ds:dword ptr[_lightrightstep]
add edx,eax
mov eax,ds:dword ptr[_lightdeltastep]
add ebp,eax
mov ds:dword ptr[_lightright],edx
jc Lblockloop8_mip1
; if (pbasesource >= r_sourcemax)
; pbasesource -= stepback;
cmp esi,ds:dword ptr[_r_sourcemax]
jb LSkip_mip1
sub esi,ds:dword ptr[_r_stepback]
LSkip_mip1:
mov ebx,ds:dword ptr[_r_lightptr]
dec ds:dword ptr[sb_v]
jnz Lv_loop_mip1
pop ebx ; restore register variables
pop esi
pop edi
pop ebp ; restore the caller's stack frame
ret
;----------------------------------------------------------------------
; Surface block drawer for mip level 2
;----------------------------------------------------------------------
align 4
public _R_DrawSurfaceBlock8_mip2
_R_DrawSurfaceBlock8_mip2:
push ebp ; preserve caller's stack frame
push edi
push esi ; preserve register variables
push ebx
; for (v=0 ; v<numvblocks ; v++)
; {
mov ebx,ds:dword ptr[_r_lightptr]
mov eax,ds:dword ptr[_r_numvblocks]
mov ds:dword ptr[sb_v],eax
mov edi,ds:dword ptr[_prowdestbase]
mov esi,ds:dword ptr[_pbasesource]
Lv_loop_mip2:
; lightleft = lightptr[0];
; lightright = lightptr[1];
; lightdelta = (lightleft - lightright) & 0xFFFFF;
mov eax,ds:dword ptr[ebx] ; lightleft
mov edx,ds:dword ptr[4+ebx] ; lightright
mov ebp,eax
mov ecx,ds:dword ptr[_r_lightwidth]
mov ds:dword ptr[_lightright],edx
sub ebp,edx
and ebp,0FFFFFh
lea ebx,ds:dword ptr[ebx+ecx*4]
; lightptr += lightwidth;
mov ds:dword ptr[_r_lightptr],ebx
; lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
; lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
; lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
; 0xF0000000;
mov ecx,ds:dword ptr[4+ebx] ; lightptr[1]
mov ebx,ds:dword ptr[ebx] ; lightptr[0]
sub ebx,eax
sub ecx,edx
sar ecx,2
or ebp,030000000h
sar ebx,2
mov ds:dword ptr[_lightrightstep],ecx
sub ebx,ecx
and ebx,0FFFFFh
or ebx,0F0000000h
sub ecx,ecx ; high word must be 0 in loop for addressing
mov ds:dword ptr[_lightdeltastep],ebx
sub ebx,ebx ; high word must be 0 in loop for addressing
Lblockloop8_mip2:
mov ds:dword ptr[_lightdelta],ebp
mov cl,ds:byte ptr[2+esi]
sar ebp,2
mov bh,dh
mov bl,ds:byte ptr[3+esi]
add edx,ebp
mov ch,dh
add edx,ebp
mov ah,ds:byte ptr[12345678h+ebx]
LBPatch18:
mov bl,ds:byte ptr[1+esi]
mov al,ds:byte ptr[12345678h+ecx]
LBPatch19:
mov cl,ds:byte ptr[esi]
mov bh,dh
add edx,ebp
ror eax,16
mov ch,dh
mov ah,ds:byte ptr[12345678h+ebx]
LBPatch20:
mov edx,ds:dword ptr[_lightright]
mov al,ds:byte ptr[12345678h+ecx]
LBPatch21:
mov ebp,ds:dword ptr[_lightdelta]
mov ds:dword ptr[edi],eax
mov eax,ds:dword ptr[_sourcetstep]
add esi,eax
mov eax,ds:dword ptr[_surfrowbytes]
add edi,eax
mov eax,ds:dword ptr[_lightrightstep]
add edx,eax
mov eax,ds:dword ptr[_lightdeltastep]
add ebp,eax
mov ds:dword ptr[_lightright],edx
jc Lblockloop8_mip2
; if (pbasesource >= r_sourcemax)
; pbasesource -= stepback;
cmp esi,ds:dword ptr[_r_sourcemax]
jb LSkip_mip2
sub esi,ds:dword ptr[_r_stepback]
LSkip_mip2:
mov ebx,ds:dword ptr[_r_lightptr]
dec ds:dword ptr[sb_v]
jnz Lv_loop_mip2
pop ebx ; restore register variables
pop esi
pop edi
pop ebp ; restore the caller's stack frame
ret
;----------------------------------------------------------------------
; Surface block drawer for mip level 3
;----------------------------------------------------------------------
align 4
public _R_DrawSurfaceBlock8_mip3
_R_DrawSurfaceBlock8_mip3:
push ebp ; preserve caller's stack frame
push edi
push esi ; preserve register variables
push ebx
; for (v=0 ; v<numvblocks ; v++)
; {
mov ebx,ds:dword ptr[_r_lightptr]
mov eax,ds:dword ptr[_r_numvblocks]
mov ds:dword ptr[sb_v],eax
mov edi,ds:dword ptr[_prowdestbase]
mov esi,ds:dword ptr[_pbasesource]
Lv_loop_mip3:
; lightleft = lightptr[0];
; lightright = lightptr[1];
; lightdelta = (lightleft - lightright) & 0xFFFFF;
mov eax,ds:dword ptr[ebx] ; lightleft
mov edx,ds:dword ptr[4+ebx] ; lightright
mov ebp,eax
mov ecx,ds:dword ptr[_r_lightwidth]
mov ds:dword ptr[_lightright],edx
sub ebp,edx
and ebp,0FFFFFh
lea ebx,ds:dword ptr[ebx+ecx*4]
mov ds:dword ptr[_lightdelta],ebp
; lightptr += lightwidth;
mov ds:dword ptr[_r_lightptr],ebx
; lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
; lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
; lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
; 0xF0000000;
mov ecx,ds:dword ptr[4+ebx] ; lightptr[1]
mov ebx,ds:dword ptr[ebx] ; lightptr[0]
sub ebx,eax
sub ecx,edx
sar ecx,1
sar ebx,1
mov ds:dword ptr[_lightrightstep],ecx
sub ebx,ecx
and ebx,0FFFFFh
sar ebp,1
or ebx,0F0000000h
mov ds:dword ptr[_lightdeltastep],ebx
sub ebx,ebx ; high word must be 0 in loop for addressing
mov bl,ds:byte ptr[1+esi]
sub ecx,ecx ; high word must be 0 in loop for addressing
mov bh,dh
mov cl,ds:byte ptr[esi]
add edx,ebp
mov ch,dh
mov al,ds:byte ptr[12345678h+ebx]
LBPatch16:
mov edx,ds:dword ptr[_lightright]
mov ds:byte ptr[1+edi],al
mov al,ds:byte ptr[12345678h+ecx]
LBPatch17:
mov ds:byte ptr[edi],al
mov eax,ds:dword ptr[_sourcetstep]
add esi,eax
mov eax,ds:dword ptr[_surfrowbytes]
add edi,eax
mov eax,ds:dword ptr[_lightdeltastep]
mov ebp,ds:dword ptr[_lightdelta]
mov cl,ds:byte ptr[esi]
add ebp,eax
mov eax,ds:dword ptr[_lightrightstep]
sar ebp,1
add edx,eax
mov bh,dh
mov bl,ds:byte ptr[1+esi]
add edx,ebp
mov ch,dh
mov al,ds:byte ptr[12345678h+ebx]
LBPatch30:
mov edx,ds:dword ptr[_sourcetstep]
mov ds:byte ptr[1+edi],al
mov al,ds:byte ptr[12345678h+ecx]
LBPatch31:
mov ds:byte ptr[edi],al
mov ebp,ds:dword ptr[_surfrowbytes]
add esi,edx
add edi,ebp
; if (pbasesource >= r_sourcemax)
; pbasesource -= stepback;
cmp esi,ds:dword ptr[_r_sourcemax]
jb LSkip_mip3
sub esi,ds:dword ptr[_r_stepback]
LSkip_mip3:
mov ebx,ds:dword ptr[_r_lightptr]
dec ds:dword ptr[sb_v]
jnz Lv_loop_mip3
pop ebx ; restore register variables
pop esi
pop edi
pop ebp ; restore the caller's stack frame
ret
public _R_Surf8End
_R_Surf8End:
;----------------------------------------------------------------------
; Code patching routines
;----------------------------------------------------------------------
_TEXT ENDS
_DATA SEGMENT
align 4
LPatchTable8:
dd LBPatch0-4
dd LBPatch1-4
dd LBPatch2-4
dd LBPatch3-4
dd LBPatch4-4
dd LBPatch5-4
dd LBPatch6-4
dd LBPatch7-4
dd LBPatch8-4
dd LBPatch9-4
dd LBPatch10-4
dd LBPatch11-4
dd LBPatch12-4
dd LBPatch13-4
dd LBPatch14-4
dd LBPatch15-4
dd LBPatch16-4
dd LBPatch17-4
dd LBPatch18-4
dd LBPatch19-4
dd LBPatch20-4
dd LBPatch21-4
dd LBPatch22-4
dd LBPatch23-4
dd LBPatch24-4
dd LBPatch25-4
dd LBPatch26-4
dd LBPatch27-4
dd LBPatch28-4
dd LBPatch29-4
dd LBPatch30-4
dd LBPatch31-4
_DATA ENDS
_TEXT SEGMENT
align 4
public _R_Surf8Patch
_R_Surf8Patch:
push ebx
mov eax,ds:dword ptr[_colormap]
mov ebx,offset LPatchTable8
mov ecx,32
LPatchLoop8:
mov edx,ds:dword ptr[ebx]
add ebx,4
mov ds:dword ptr[edx],eax
dec ecx
jnz LPatchLoop8
pop ebx
ret
_TEXT ENDS
endif ;id386
END