0,0 → 1,783 |
/* |
Copyright (C) 1996-1997 Id Software, Inc. |
|
This program is free software; you can redistribute it and/or |
modify it under the terms of the GNU General Public License |
as published by the Free Software Foundation; either version 2 |
of the License, or (at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
See the GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|
*/ |
// |
// surf8.s |
// x86 assembly-language 8 bpp surface block drawing code. |
// |
|
#include "asm_i386.h" |
#include "quakeasm.h" |
#include "asm_draw.h" |
|
#if id386 |
|
.data |
|
sb_v: .long 0 |
|
.text |
|
.align 4 |
.globl C(R_Surf8Start) |
C(R_Surf8Start): |
|
//---------------------------------------------------------------------- |
// Surface block drawer for mip level 0 |
//---------------------------------------------------------------------- |
|
.align 4 |
.globl C(R_DrawSurfaceBlock8_mip0) |
C(R_DrawSurfaceBlock8_mip0): |
pushl %ebp // preserve caller's stack frame |
pushl %edi |
pushl %esi // preserve register variables |
pushl %ebx |
|
// for (v=0 ; v<numvblocks ; v++) |
// { |
movl C(r_lightptr),%ebx |
movl C(r_numvblocks),%eax |
|
movl %eax,sb_v |
movl C(prowdestbase),%edi |
|
movl C(pbasesource),%esi |
|
Lv_loop_mip0: |
|
// lightleft = lightptr[0]; |
// lightright = lightptr[1]; |
// lightdelta = (lightleft - lightright) & 0xFFFFF; |
movl (%ebx),%eax // lightleft |
movl 4(%ebx),%edx // lightright |
|
movl %eax,%ebp |
movl C(r_lightwidth),%ecx |
|
movl %edx,C(lightright) |
subl %edx,%ebp |
|
andl $0xFFFFF,%ebp |
leal (%ebx,%ecx,4),%ebx |
|
// lightptr += lightwidth; |
movl %ebx,C(r_lightptr) |
|
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift; |
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift; |
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) | |
// 0xF0000000; |
movl 4(%ebx),%ecx // lightptr[1] |
movl (%ebx),%ebx // lightptr[0] |
|
subl %eax,%ebx |
subl %edx,%ecx |
|
sarl $4,%ecx |
orl $0xF0000000,%ebp |
|
sarl $4,%ebx |
movl %ecx,C(lightrightstep) |
|
subl %ecx,%ebx |
andl $0xFFFFF,%ebx |
|
orl $0xF0000000,%ebx |
subl %ecx,%ecx // high word must be 0 in loop for addressing |
|
movl %ebx,C(lightdeltastep) |
subl %ebx,%ebx // high word must be 0 in loop for addressing |
|
Lblockloop8_mip0: |
movl %ebp,C(lightdelta) |
movb 14(%esi),%cl |
|
sarl $4,%ebp |
movb %dh,%bh |
|
movb 15(%esi),%bl |
addl %ebp,%edx |
|
movb %dh,%ch |
addl %ebp,%edx |
|
movb 0x12345678(%ebx),%ah |
LBPatch0: |
movb 13(%esi),%bl |
|
movb 0x12345678(%ecx),%al |
LBPatch1: |
movb 12(%esi),%cl |
|
movb %dh,%bh |
addl %ebp,%edx |
|
rorl $16,%eax |
movb %dh,%ch |
|
addl %ebp,%edx |
movb 0x12345678(%ebx),%ah |
LBPatch2: |
|
movb 11(%esi),%bl |
movb 0x12345678(%ecx),%al |
LBPatch3: |
|
movb 10(%esi),%cl |
movl %eax,12(%edi) |
|
movb %dh,%bh |
addl %ebp,%edx |
|
movb %dh,%ch |
addl %ebp,%edx |
|
movb 0x12345678(%ebx),%ah |
LBPatch4: |
movb 9(%esi),%bl |
|
movb 0x12345678(%ecx),%al |
LBPatch5: |
movb 8(%esi),%cl |
|
movb %dh,%bh |
addl %ebp,%edx |
|
rorl $16,%eax |
movb %dh,%ch |
|
addl %ebp,%edx |
movb 0x12345678(%ebx),%ah |
LBPatch6: |
|
movb 7(%esi),%bl |
movb 0x12345678(%ecx),%al |
LBPatch7: |
|
movb 6(%esi),%cl |
movl %eax,8(%edi) |
|
movb %dh,%bh |
addl %ebp,%edx |
|
movb %dh,%ch |
addl %ebp,%edx |
|
movb 0x12345678(%ebx),%ah |
LBPatch8: |
movb 5(%esi),%bl |
|
movb 0x12345678(%ecx),%al |
LBPatch9: |
movb 4(%esi),%cl |
|
movb %dh,%bh |
addl %ebp,%edx |
|
rorl $16,%eax |
movb %dh,%ch |
|
addl %ebp,%edx |
movb 0x12345678(%ebx),%ah |
LBPatch10: |
|
movb 3(%esi),%bl |
movb 0x12345678(%ecx),%al |
LBPatch11: |
|
movb 2(%esi),%cl |
movl %eax,4(%edi) |
|
movb %dh,%bh |
addl %ebp,%edx |
|
movb %dh,%ch |
addl %ebp,%edx |
|
movb 0x12345678(%ebx),%ah |
LBPatch12: |
movb 1(%esi),%bl |
|
movb 0x12345678(%ecx),%al |
LBPatch13: |
movb (%esi),%cl |
|
movb %dh,%bh |
addl %ebp,%edx |
|
rorl $16,%eax |
movb %dh,%ch |
|
movb 0x12345678(%ebx),%ah |
LBPatch14: |
movl C(lightright),%edx |
|
movb 0x12345678(%ecx),%al |
LBPatch15: |
movl C(lightdelta),%ebp |
|
movl %eax,(%edi) |
|
addl C(sourcetstep),%esi |
addl C(surfrowbytes),%edi |
|
addl C(lightrightstep),%edx |
addl C(lightdeltastep),%ebp |
|
movl %edx,C(lightright) |
jc Lblockloop8_mip0 |
|
// if (pbasesource >= r_sourcemax) |
// pbasesource -= stepback; |
|
cmpl C(r_sourcemax),%esi |
jb LSkip_mip0 |
subl C(r_stepback),%esi |
LSkip_mip0: |
|
movl C(r_lightptr),%ebx |
decl sb_v |
|
jnz Lv_loop_mip0 |
|
popl %ebx // restore register variables |
popl %esi |
popl %edi |
popl %ebp // restore the caller's stack frame |
ret |
|
|
//---------------------------------------------------------------------- |
// Surface block drawer for mip level 1 |
//---------------------------------------------------------------------- |
|
.align 4 |
.globl C(R_DrawSurfaceBlock8_mip1) |
C(R_DrawSurfaceBlock8_mip1): |
pushl %ebp // preserve caller's stack frame |
pushl %edi |
pushl %esi // preserve register variables |
pushl %ebx |
|
// for (v=0 ; v<numvblocks ; v++) |
// { |
movl C(r_lightptr),%ebx |
movl C(r_numvblocks),%eax |
|
movl %eax,sb_v |
movl C(prowdestbase),%edi |
|
movl C(pbasesource),%esi |
|
Lv_loop_mip1: |
|
// lightleft = lightptr[0]; |
// lightright = lightptr[1]; |
// lightdelta = (lightleft - lightright) & 0xFFFFF; |
movl (%ebx),%eax // lightleft |
movl 4(%ebx),%edx // lightright |
|
movl %eax,%ebp |
movl C(r_lightwidth),%ecx |
|
movl %edx,C(lightright) |
subl %edx,%ebp |
|
andl $0xFFFFF,%ebp |
leal (%ebx,%ecx,4),%ebx |
|
// lightptr += lightwidth; |
movl %ebx,C(r_lightptr) |
|
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift; |
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift; |
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) | |
// 0xF0000000; |
movl 4(%ebx),%ecx // lightptr[1] |
movl (%ebx),%ebx // lightptr[0] |
|
subl %eax,%ebx |
subl %edx,%ecx |
|
sarl $3,%ecx |
orl $0x70000000,%ebp |
|
sarl $3,%ebx |
movl %ecx,C(lightrightstep) |
|
subl %ecx,%ebx |
andl $0xFFFFF,%ebx |
|
orl $0xF0000000,%ebx |
subl %ecx,%ecx // high word must be 0 in loop for addressing |
|
movl %ebx,C(lightdeltastep) |
subl %ebx,%ebx // high word must be 0 in loop for addressing |
|
Lblockloop8_mip1: |
movl %ebp,C(lightdelta) |
movb 6(%esi),%cl |
|
sarl $3,%ebp |
movb %dh,%bh |
|
movb 7(%esi),%bl |
addl %ebp,%edx |
|
movb %dh,%ch |
addl %ebp,%edx |
|
movb 0x12345678(%ebx),%ah |
LBPatch22: |
movb 5(%esi),%bl |
|
movb 0x12345678(%ecx),%al |
LBPatch23: |
movb 4(%esi),%cl |
|
movb %dh,%bh |
addl %ebp,%edx |
|
rorl $16,%eax |
movb %dh,%ch |
|
addl %ebp,%edx |
movb 0x12345678(%ebx),%ah |
LBPatch24: |
|
movb 3(%esi),%bl |
movb 0x12345678(%ecx),%al |
LBPatch25: |
|
movb 2(%esi),%cl |
movl %eax,4(%edi) |
|
movb %dh,%bh |
addl %ebp,%edx |
|
movb %dh,%ch |
addl %ebp,%edx |
|
movb 0x12345678(%ebx),%ah |
LBPatch26: |
movb 1(%esi),%bl |
|
movb 0x12345678(%ecx),%al |
LBPatch27: |
movb (%esi),%cl |
|
movb %dh,%bh |
addl %ebp,%edx |
|
rorl $16,%eax |
movb %dh,%ch |
|
movb 0x12345678(%ebx),%ah |
LBPatch28: |
movl C(lightright),%edx |
|
movb 0x12345678(%ecx),%al |
LBPatch29: |
movl C(lightdelta),%ebp |
|
movl %eax,(%edi) |
movl C(sourcetstep),%eax |
|
addl %eax,%esi |
movl C(surfrowbytes),%eax |
|
addl %eax,%edi |
movl C(lightrightstep),%eax |
|
addl %eax,%edx |
movl C(lightdeltastep),%eax |
|
addl %eax,%ebp |
movl %edx,C(lightright) |
|
jc Lblockloop8_mip1 |
|
// if (pbasesource >= r_sourcemax) |
// pbasesource -= stepback; |
|
cmpl C(r_sourcemax),%esi |
jb LSkip_mip1 |
subl C(r_stepback),%esi |
LSkip_mip1: |
|
movl C(r_lightptr),%ebx |
decl sb_v |
|
jnz Lv_loop_mip1 |
|
popl %ebx // restore register variables |
popl %esi |
popl %edi |
popl %ebp // restore the caller's stack frame |
ret |
|
|
//---------------------------------------------------------------------- |
// Surface block drawer for mip level 2 |
//---------------------------------------------------------------------- |
|
.align 4 |
.globl C(R_DrawSurfaceBlock8_mip2) |
C(R_DrawSurfaceBlock8_mip2): |
pushl %ebp // preserve caller's stack frame |
pushl %edi |
pushl %esi // preserve register variables |
pushl %ebx |
|
// for (v=0 ; v<numvblocks ; v++) |
// { |
movl C(r_lightptr),%ebx |
movl C(r_numvblocks),%eax |
|
movl %eax,sb_v |
movl C(prowdestbase),%edi |
|
movl C(pbasesource),%esi |
|
Lv_loop_mip2: |
|
// lightleft = lightptr[0]; |
// lightright = lightptr[1]; |
// lightdelta = (lightleft - lightright) & 0xFFFFF; |
movl (%ebx),%eax // lightleft |
movl 4(%ebx),%edx // lightright |
|
movl %eax,%ebp |
movl C(r_lightwidth),%ecx |
|
movl %edx,C(lightright) |
subl %edx,%ebp |
|
andl $0xFFFFF,%ebp |
leal (%ebx,%ecx,4),%ebx |
|
// lightptr += lightwidth; |
movl %ebx,C(r_lightptr) |
|
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift; |
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift; |
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) | |
// 0xF0000000; |
movl 4(%ebx),%ecx // lightptr[1] |
movl (%ebx),%ebx // lightptr[0] |
|
subl %eax,%ebx |
subl %edx,%ecx |
|
sarl $2,%ecx |
orl $0x30000000,%ebp |
|
sarl $2,%ebx |
movl %ecx,C(lightrightstep) |
|
subl %ecx,%ebx |
|
andl $0xFFFFF,%ebx |
|
orl $0xF0000000,%ebx |
subl %ecx,%ecx // high word must be 0 in loop for addressing |
|
movl %ebx,C(lightdeltastep) |
subl %ebx,%ebx // high word must be 0 in loop for addressing |
|
Lblockloop8_mip2: |
movl %ebp,C(lightdelta) |
movb 2(%esi),%cl |
|
sarl $2,%ebp |
movb %dh,%bh |
|
movb 3(%esi),%bl |
addl %ebp,%edx |
|
movb %dh,%ch |
addl %ebp,%edx |
|
movb 0x12345678(%ebx),%ah |
LBPatch18: |
movb 1(%esi),%bl |
|
movb 0x12345678(%ecx),%al |
LBPatch19: |
movb (%esi),%cl |
|
movb %dh,%bh |
addl %ebp,%edx |
|
rorl $16,%eax |
movb %dh,%ch |
|
movb 0x12345678(%ebx),%ah |
LBPatch20: |
movl C(lightright),%edx |
|
movb 0x12345678(%ecx),%al |
LBPatch21: |
movl C(lightdelta),%ebp |
|
movl %eax,(%edi) |
movl C(sourcetstep),%eax |
|
addl %eax,%esi |
movl C(surfrowbytes),%eax |
|
addl %eax,%edi |
movl C(lightrightstep),%eax |
|
addl %eax,%edx |
movl C(lightdeltastep),%eax |
|
addl %eax,%ebp |
movl %edx,C(lightright) |
|
jc Lblockloop8_mip2 |
|
// if (pbasesource >= r_sourcemax) |
// pbasesource -= stepback; |
|
cmpl C(r_sourcemax),%esi |
jb LSkip_mip2 |
subl C(r_stepback),%esi |
LSkip_mip2: |
|
movl C(r_lightptr),%ebx |
decl sb_v |
|
jnz Lv_loop_mip2 |
|
popl %ebx // restore register variables |
popl %esi |
popl %edi |
popl %ebp // restore the caller's stack frame |
ret |
|
|
//---------------------------------------------------------------------- |
// Surface block drawer for mip level 3 |
//---------------------------------------------------------------------- |
|
.align 4 |
.globl C(R_DrawSurfaceBlock8_mip3) |
C(R_DrawSurfaceBlock8_mip3): |
pushl %ebp // preserve caller's stack frame |
pushl %edi |
pushl %esi // preserve register variables |
pushl %ebx |
|
// for (v=0 ; v<numvblocks ; v++) |
// { |
movl C(r_lightptr),%ebx |
movl C(r_numvblocks),%eax |
|
movl %eax,sb_v |
movl C(prowdestbase),%edi |
|
movl C(pbasesource),%esi |
|
Lv_loop_mip3: |
|
// lightleft = lightptr[0]; |
// lightright = lightptr[1]; |
// lightdelta = (lightleft - lightright) & 0xFFFFF; |
movl (%ebx),%eax // lightleft |
movl 4(%ebx),%edx // lightright |
|
movl %eax,%ebp |
movl C(r_lightwidth),%ecx |
|
movl %edx,C(lightright) |
subl %edx,%ebp |
|
andl $0xFFFFF,%ebp |
leal (%ebx,%ecx,4),%ebx |
|
movl %ebp,C(lightdelta) |
// lightptr += lightwidth; |
movl %ebx,C(r_lightptr) |
|
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift; |
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift; |
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) | |
// 0xF0000000; |
movl 4(%ebx),%ecx // lightptr[1] |
movl (%ebx),%ebx // lightptr[0] |
|
subl %eax,%ebx |
subl %edx,%ecx |
|
sarl $1,%ecx |
|
sarl $1,%ebx |
movl %ecx,C(lightrightstep) |
|
subl %ecx,%ebx |
andl $0xFFFFF,%ebx |
|
sarl $1,%ebp |
orl $0xF0000000,%ebx |
|
movl %ebx,C(lightdeltastep) |
subl %ebx,%ebx // high word must be 0 in loop for addressing |
|
movb 1(%esi),%bl |
subl %ecx,%ecx // high word must be 0 in loop for addressing |
|
movb %dh,%bh |
movb (%esi),%cl |
|
addl %ebp,%edx |
movb %dh,%ch |
|
movb 0x12345678(%ebx),%al |
LBPatch16: |
movl C(lightright),%edx |
|
movb %al,1(%edi) |
movb 0x12345678(%ecx),%al |
LBPatch17: |
|
movb %al,(%edi) |
movl C(sourcetstep),%eax |
|
addl %eax,%esi |
movl C(surfrowbytes),%eax |
|
addl %eax,%edi |
movl C(lightdeltastep),%eax |
|
movl C(lightdelta),%ebp |
movb (%esi),%cl |
|
addl %eax,%ebp |
movl C(lightrightstep),%eax |
|
sarl $1,%ebp |
addl %eax,%edx |
|
movb %dh,%bh |
movb 1(%esi),%bl |
|
addl %ebp,%edx |
movb %dh,%ch |
|
movb 0x12345678(%ebx),%al |
LBPatch30: |
movl C(sourcetstep),%edx |
|
movb %al,1(%edi) |
movb 0x12345678(%ecx),%al |
LBPatch31: |
|
movb %al,(%edi) |
movl C(surfrowbytes),%ebp |
|
addl %edx,%esi |
addl %ebp,%edi |
|
// if (pbasesource >= r_sourcemax) |
// pbasesource -= stepback; |
|
cmpl C(r_sourcemax),%esi |
jb LSkip_mip3 |
subl C(r_stepback),%esi |
LSkip_mip3: |
|
movl C(r_lightptr),%ebx |
decl sb_v |
|
jnz Lv_loop_mip3 |
|
popl %ebx // restore register variables |
popl %esi |
popl %edi |
popl %ebp // restore the caller's stack frame |
ret |
|
|
.globl C(R_Surf8End) |
C(R_Surf8End): |
|
//---------------------------------------------------------------------- |
// Code patching routines |
//---------------------------------------------------------------------- |
.data |
|
.align 4 |
LPatchTable8: |
.long LBPatch0-4 |
.long LBPatch1-4 |
.long LBPatch2-4 |
.long LBPatch3-4 |
.long LBPatch4-4 |
.long LBPatch5-4 |
.long LBPatch6-4 |
.long LBPatch7-4 |
.long LBPatch8-4 |
.long LBPatch9-4 |
.long LBPatch10-4 |
.long LBPatch11-4 |
.long LBPatch12-4 |
.long LBPatch13-4 |
.long LBPatch14-4 |
.long LBPatch15-4 |
.long LBPatch16-4 |
.long LBPatch17-4 |
.long LBPatch18-4 |
.long LBPatch19-4 |
.long LBPatch20-4 |
.long LBPatch21-4 |
.long LBPatch22-4 |
.long LBPatch23-4 |
.long LBPatch24-4 |
.long LBPatch25-4 |
.long LBPatch26-4 |
.long LBPatch27-4 |
.long LBPatch28-4 |
.long LBPatch29-4 |
.long LBPatch30-4 |
.long LBPatch31-4 |
|
.text |
|
.align 4 |
.globl C(R_Surf8Patch) |
C(R_Surf8Patch): |
pushl %ebx |
|
movl C(colormap),%eax |
movl $LPatchTable8,%ebx |
movl $32,%ecx |
LPatchLoop8: |
movl (%ebx),%edx |
addl $4,%ebx |
movl %eax,(%edx) |
decl %ecx |
jnz LPatchLoop8 |
|
popl %ebx |
|
ret |
|
#endif // id386 |