aboutsummaryrefslogtreecommitdiffstats
path: root/QW/client/surf8.s
diff options
context:
space:
mode:
Diffstat (limited to 'QW/client/surf8.s')
-rw-r--r--QW/client/surf8.s783
1 files changed, 783 insertions, 0 deletions
diff --git a/QW/client/surf8.s b/QW/client/surf8.s
new file mode 100644
index 0000000..a079f1d
--- /dev/null
+++ b/QW/client/surf8.s
@@ -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