Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5131 | clevermous | 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 |