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