Commit | Line | Data |
---|---|---|
893a268e WJ |
1 | ; Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved. |
2 | ; Distributed by Free Software Foundation, Inc. | |
3 | ; | |
4 | ; This file is part of Ghostscript. | |
5 | ; | |
6 | ; Ghostscript is distributed in the hope that it will be useful, but | |
7 | ; WITHOUT ANY WARRANTY. No author or distributor accepts responsibility | |
8 | ; to anyone for the consequences of using it or for whether it serves any | |
9 | ; particular purpose or works at all, unless he says so in writing. Refer | |
10 | ; to the Ghostscript General Public License for full details. | |
11 | ; | |
12 | ; Everyone is granted permission to copy, modify and redistribute | |
13 | ; Ghostscript, but only under the conditions described in the Ghostscript | |
14 | ; General Public License. A copy of this license is supposed to have been | |
15 | ; given to you along with Ghostscript so you can know your rights and | |
16 | ; responsibilities. It should be in a file named COPYING. Among other | |
17 | ; things, the copyright notice and this notice must be preserved on all | |
18 | ; copies. | |
19 | ||
20 | ; gdevegaasm.asm | |
21 | ; Assembly code for Ghostscript PC frame buffer driver | |
22 | ||
23 | gdevegaasm_TEXT SEGMENT BYTE PUBLIC 'CODE' | |
24 | ASSUME CS:gdevegaasm_TEXT | |
25 | ||
26 | ; Note: Turbo C uses si and di for register variables, so | |
27 | ; we have to preserve them. | |
28 | ||
29 | ; Normal entry and exit. Arguments are relative to bp. | |
30 | enterp macro | |
31 | push bp | |
32 | mov bp,sp | |
33 | x = 6 ; offset of arguments, | |
34 | ; large code model | |
35 | endm | |
36 | leavep macro | |
37 | pop bp | |
38 | endm | |
39 | ; Fast entry and exit, for procedures that don't use bx until | |
40 | ; they've fetched all their arguments. Arguments are relative to ss:bx. | |
41 | enterf macro | |
42 | mov bx,sp | |
43 | x = 4 ; offset of arguments, | |
44 | ; large code model | |
45 | endm | |
46 | leavef macro | |
47 | endm | |
48 | ||
49 | ; Fast call to VESA set-page routine. | |
50 | ; void vesa_call_set_page(void (*set_page_proc)(int), int page_no, int win_no) | |
51 | PUBLIC _vesa_call_set_page | |
52 | _vesa_call_set_page proc far | |
53 | enterf | |
54 | mov ax,4f05h | |
55 | mov dx,ss:[bx+x+4] ; page_no | |
56 | push ss:[bx+x+2] ; set_page_proc | |
57 | push ss:[bx+x] | |
58 | mov bx,ss:[bx+x+6] ; win_no | |
59 | ret | |
60 | _vesa_call_set_page endp | |
61 | ||
62 | ; Structure for operation parameters. | |
63 | ; Note that this structure is shared with C code. | |
64 | ; Not all parameters are used for every operation. | |
65 | ; typedef struct rop_params_s { | |
66 | p_dest equ 0 ; fb_ptr dest; /* pointer to frame buffer */ | |
67 | p_draster equ 4 ; int draster; /* raster of frame buffer */ | |
68 | p_src equ 6 ; byte far *src; /* pointer to source data */ | |
69 | p_sraster equ 10 ; int sraster; /* source raster */ | |
70 | p_width equ 12 ; int width; /* width in bytes */ | |
71 | p_height equ 14 ; int height; /* height in scan lines */ | |
72 | p_shift equ 16 ; int shift; /* amount to right shift source */ | |
73 | p_invert equ 18 ; int invert; /* 0 or -1 to invert source */ | |
74 | p_data equ 20 ; int data; /* data for fill */ | |
75 | ; } rop_params; | |
76 | ||
77 | ; void memsetcol(rop_params _ss *rop) | |
78 | ; { byte far *addr = rop->dest; | |
79 | ; int yc = rop->height; | |
80 | ; while ( yc-- ) | |
81 | ; { byte discard = *addr; | |
82 | ; *addr = rop->data; | |
83 | ; addr += rop->draster; | |
84 | ; } | |
85 | ; } | |
86 | PUBLIC _memsetcol | |
87 | _memsetcol proc far | |
88 | enterf | |
89 | push ds | |
90 | mov ax,ss | |
91 | mov ds,ax | |
92 | mov bx,[bx+x] ; rop | |
93 | mov cx,[bx].p_height | |
94 | jcxz msc0 ; height == 0 | |
95 | mov ax,[bx].p_data | |
96 | mov dx,[bx].p_draster | |
97 | lds bx,[bx].p_dest | |
98 | ; Unroll the loop -- two copies. | |
99 | inc cx ;round up to nearest word. cx>=2 now. | |
100 | shr cx,1 ;make byte count into word count. | |
101 | jnc msc2 ;if it had been odd, do a half word first. | |
102 | msc1: mov ah,[bx] | |
103 | mov [bx],al | |
104 | add bx,dx | |
105 | msc2: mov ah,[bx] | |
106 | mov [bx],al | |
107 | add bx,dx | |
108 | loop msc1 | |
109 | pop ds | |
110 | msc0: leavef | |
111 | ret | |
112 | _memsetcol ENDP | |
113 | ||
114 | ; void memsetrect(rop_params _ss *rop) | |
115 | ; { byte far *addr = rop->dest; | |
116 | ; int yc = rop->height; | |
117 | ; while ( yc-- ) | |
118 | ; { int cnt = rop->width; | |
119 | ; while ( cnt-- ) *addr++ = rop->data; | |
120 | ; addr += rop->drast - rop->width; | |
121 | ; } | |
122 | ; } | |
123 | PUBLIC _memsetrect | |
124 | _memsetrect proc far | |
125 | enterf | |
126 | push ds | |
127 | mov ax,ss | |
128 | mov ds,ax | |
129 | mov bx,[bx+x] ; rop | |
130 | mov cx,[bx].p_height | |
131 | jcxz msr0 ; height == 0 | |
132 | push si | |
133 | push di | |
134 | mov ax,[bx].p_data | |
135 | les di,[bx].p_dest | |
136 | cld | |
137 | mov dx,[bx].p_draster | |
138 | mov si,cx ; si = height | |
139 | mov cx,[bx].p_width | |
140 | sub dx,cx | |
141 | cmp cx,10 | |
142 | ja msrl ; large count, use fast loop | |
143 | ; Small count, rep stosb is faster. | |
144 | msrs: mov cx,[bx].p_width | |
145 | rep stosb | |
146 | add di,dx | |
147 | dec si ; count reps | |
148 | jnz msrs | |
149 | pop di | |
150 | pop si | |
151 | msr0: pop ds | |
152 | leavef | |
153 | ret | |
154 | ; Large count, loop by words rather than bytes. | |
155 | msrl: mov ah,al ;we may be storing words... | |
156 | msr1: mov cx,[bx].p_width | |
157 | test di,1 ;test for an even address | |
158 | je msr2 ;if even, we can store words. | |
159 | stosb ;otherwise we need to even it out. | |
160 | dec cx ;(cx is at least one here) | |
161 | msr2: shr cx,1 ;convert byte count into word count | |
162 | rep stosw ;store them puppies as fast as we can. | |
163 | jnc msr3 ;if an odd number, store it, too. | |
164 | stosb ;(no need to dec cx here). | |
165 | msr3: add di,dx | |
166 | dec si ; count reps | |
167 | jnz msr1 | |
168 | pop di | |
169 | pop si | |
170 | pop ds | |
171 | leavef | |
172 | ret | |
173 | _memsetrect ENDP | |
174 | ||
175 | ; void memrwcol(rop_params _ss *rop) | |
176 | ; { byte far *dp = rop->dest, *sp = rop->src; | |
177 | ; int yc = rop->height; | |
178 | ; int shift = rop->shift; | |
179 | ; while ( yc-- ) | |
180 | ; { byte discard = *dp; | |
181 | ; *dp = ((*sp >> shift) + (*sp << (8 - shift))) ^ rop->invert; | |
182 | ; dp += rop->draster, sp += rop->sraster; | |
183 | ; } | |
184 | ; } | |
185 | PUBLIC _memrwcol | |
186 | _memrwcol proc far | |
187 | enterp | |
188 | push ds | |
189 | mov ax,ss | |
190 | mov ds,ax | |
191 | mov bx,[bp+x] ; rop | |
192 | cmp word ptr [bx].p_height,0 | |
193 | jz short mrw0 | |
194 | push si | |
195 | push di | |
196 | ; Register usage: | |
197 | ; ds:si = sp, es:di = dp, bx = sraster, dx = draster, cl = shift, | |
198 | ; ch = invert, ah = low byte of yc. | |
199 | push [bx].p_height | |
200 | mov dx,[bx].p_draster | |
201 | mov ax,[bx].p_sraster | |
202 | mov cl,[bx].p_shift | |
203 | mov ch,[bx].p_invert | |
204 | les di,[bx].p_dest | |
205 | lds si,[bx].p_src | |
206 | mov bx,ax | |
207 | mov ah,[bp-8] ; low byte of yc | |
208 | test ah,ah | |
209 | jz mrw2 | |
210 | mrw1: mov al,[si] | |
211 | ror al,cl | |
212 | xor al,ch | |
213 | xchg es:[di],al | |
214 | add si,bx | |
215 | add di,dx | |
216 | dec ah | |
217 | jnz mrw1 | |
218 | mrw2: dec byte ptr [bp-7] ; high byte of yc | |
219 | jge mrw1 | |
220 | add sp,2 ; pop yc | |
221 | pop di | |
222 | pop si | |
223 | mrw0: pop ds | |
224 | leavep | |
225 | ret | |
226 | _memrwcol ENDP | |
227 | ||
228 | ; void memrwcol2(rop_params _ss *rop) | |
229 | ; { byte far *dp = rop->dest, *sp = rop->src; | |
230 | ; int yc = rop->height; | |
231 | ; int shift = rop->shift; | |
232 | ; while ( yc-- ) | |
233 | ; { byte discard = *dp; | |
234 | ; *dp = ((sp[1] >> shift) + (*sp << (8 - shift))) ^ rop->invert; | |
235 | ; dp += rop->draster, sp += rop->sraster; | |
236 | ; } | |
237 | ; } | |
238 | PUBLIC _memrwcol2 | |
239 | _memrwcol2 proc far | |
240 | enterp | |
241 | push ds | |
242 | mov ax,ss | |
243 | mov ds,ax | |
244 | mov bx,[bp+x] ; rop | |
245 | cmp word ptr [bx].p_height,0 | |
246 | jz short mrw20 | |
247 | push si | |
248 | push di | |
249 | ; Register usage: | |
250 | ; ds:si = sp, es:di = dp, bx = sraster, dx = draster, cl = shift, | |
251 | ; ch = invert. | |
252 | push [bx].p_height | |
253 | mov dx,[bx].p_draster | |
254 | mov ax,[bx].p_sraster | |
255 | mov cl,[bx].p_shift | |
256 | mov ch,[bx].p_invert | |
257 | les di,[bx].p_dest | |
258 | lds si,[bx].p_src | |
259 | mov bx,ax | |
260 | mrw21: mov ax,[si] ; bytes are in wrong order... | |
261 | ror ax,cl | |
262 | xor ah,ch ; ... so result is in ah | |
263 | xchg es:[di],ah | |
264 | add si,bx | |
265 | add di,dx | |
266 | dec word ptr [bp-8] ; yc | |
267 | jg mrw21 | |
268 | add sp,2 ; pop yc | |
269 | pop di | |
270 | pop si | |
271 | mrw20: pop ds | |
272 | leavep | |
273 | ret | |
274 | _memrwcol2 ENDP | |
275 | ||
276 | gdevegaasm_TEXT ENDS | |
277 | END |