1/
2// d_copy.s
3// x86 assembly-language screen copying code.
4//
5
6#include "qasm.h"
7
8	.data
9
10LCopyWidth:		.long	0
11LBlockSrcStep:	.long	0
12LBlockDestStep:	.long	0
13LSrcDelta:		.long	0
14LDestDelta:		.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)
25C(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
59LRowLoop:
60	movb	$1,%al
61
62LPlaneLoop:
63	outb	%al,%dx
64	movb	$2,%ah
65
66	pushl	%esi
67	pushl	%edi
68LRowSetLoop:
69	movl	LCopyWidth,%ecx
70LColumnLoop:
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)
117C(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
133LLRowLoop:
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
148