Quake-2

Quake 2 GPL Source Release
Log | Files | Refs

d_copy.s (2561B)


      1 /
      2 // d_copy.s
      3 // x86 assembly-language screen copying code.
      4 //
      5 
      6 #include "qasm.h"
      7 
      8 	.data
      9 
     10 LCopyWidth:		.long	0
     11 LBlockSrcStep:	.long	0
     12 LBlockDestStep:	.long	0
     13 LSrcDelta:		.long	0
     14 LDestDelta:		.long	0
     15 
     16 #define bufptr	4+16
     17 
     18 // copies 16 rows per plane at a pop; idea is that 16*512 = 8k, and since
     19 // no Mode X mode is wider than 360, all the data should fit in the cache for
     20 // the passes for the next 3 planes
     21 
     22 	.text
     23 
     24 .globl C(VGA_UpdatePlanarScreen)
     25 C(VGA_UpdatePlanarScreen):
     26 	pushl	%ebp				// preserve caller's stack frame
     27 	pushl	%edi
     28 	pushl	%esi				// preserve register variables
     29 	pushl	%ebx
     30 
     31 	movl	C(VGA_bufferrowbytes),%eax
     32 	shll	$1,%eax
     33 	movl	%eax,LBlockSrcStep
     34 	movl	C(VGA_rowbytes),%eax
     35 	shll	$1,%eax
     36 	movl	%eax,LBlockDestStep
     37 
     38 	movl	$0x3C4,%edx
     39 	movb	$2,%al
     40 	outb	%al,%dx		// point the SC to the Map Mask
     41 	incl	%edx
     42 
     43 	movl	bufptr(%esp),%esi
     44 	movl	C(VGA_pagebase),%edi
     45 	movl	C(VGA_height),%ebp
     46 	shrl	$1,%ebp
     47 
     48 	movl	C(VGA_width),%ecx
     49 	movl	C(VGA_bufferrowbytes),%eax
     50 	subl	%ecx,%eax
     51 	movl	%eax,LSrcDelta
     52 	movl	C(VGA_rowbytes),%eax
     53 	shll	$2,%eax
     54 	subl	%ecx,%eax
     55 	movl	%eax,LDestDelta
     56 	shrl	$4,%ecx
     57 	movl	%ecx,LCopyWidth
     58 
     59 LRowLoop:
     60 	movb	$1,%al
     61 
     62 LPlaneLoop:
     63 	outb	%al,%dx
     64 	movb	$2,%ah
     65 
     66 	pushl	%esi
     67 	pushl	%edi
     68 LRowSetLoop:
     69 	movl	LCopyWidth,%ecx
     70 LColumnLoop:
     71 	movb	12(%esi),%bh
     72 	movb	8(%esi),%bl
     73 	shll	$16,%ebx
     74 	movb	4(%esi),%bh
     75 	movb	(%esi),%bl
     76 	movl	%ebx,(%edi)
     77 	addl	$16,%esi
     78 	addl	$4,%edi
     79 	decl	%ecx
     80 	jnz		LColumnLoop
     81 
     82 	addl	LDestDelta,%edi
     83 	addl	LSrcDelta,%esi
     84 	decb	%ah
     85 	jnz		LRowSetLoop
     86 
     87 	popl	%edi
     88 	popl	%esi
     89 	incl	%esi
     90 
     91 	shlb	$1,%al
     92 	cmpb	$16,%al
     93 	jnz		LPlaneLoop
     94 
     95 	subl	$4,%esi
     96 	addl	LBlockSrcStep,%esi
     97 	addl	LBlockDestStep,%edi
     98 	decl	%ebp
     99 	jnz		LRowLoop
    100 
    101 	popl	%ebx				// restore register variables
    102 	popl	%esi
    103 	popl	%edi
    104 	popl	%ebp				// restore the caller's stack frame
    105 
    106 	ret
    107 
    108 
    109 #define srcptr			4+16
    110 #define destptr			8+16
    111 #define width			12+16
    112 #define height			16+16
    113 #define srcrowbytes		20+16
    114 #define destrowbytes	24+16
    115 
    116 .globl C(VGA_UpdateLinearScreen)
    117 C(VGA_UpdateLinearScreen):
    118 	pushl	%ebp				// preserve caller's stack frame
    119 	pushl	%edi
    120 	pushl	%esi				// preserve register variables
    121 	pushl	%ebx
    122 
    123 	cld
    124 	movl	srcptr(%esp),%esi
    125 	movl	destptr(%esp),%edi
    126 	movl	width(%esp),%ebx
    127 	movl	srcrowbytes(%esp),%eax
    128 	subl	%ebx,%eax
    129 	movl	destrowbytes(%esp),%edx
    130 	subl	%ebx,%edx
    131 	shrl	$2,%ebx
    132 	movl	height(%esp),%ebp
    133 LLRowLoop:
    134 	movl	%ebx,%ecx
    135 	rep/movsl	(%esi),(%edi)
    136 	addl	%eax,%esi
    137 	addl	%edx,%edi
    138 	decl	%ebp
    139 	jnz		LLRowLoop
    140 
    141 	popl	%ebx				// restore register variables
    142 	popl	%esi
    143 	popl	%edi
    144 	popl	%ebp				// restore the caller's stack frame
    145 
    146 	ret
    147