386BSD 0.1 development
[unix-history] / usr / othersrc / public / ghostscript-2.4.1 / gdevegaa.asm
CommitLineData
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
23gdevegaasm_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.
30enterp macro
31 push bp
32 mov bp,sp
33 x = 6 ; offset of arguments,
34 ; large code model
35 endm
36leavep 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.
41enterf macro
42 mov bx,sp
43 x = 4 ; offset of arguments,
44 ; large code model
45 endm
46leavef 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 {
66p_dest equ 0 ; fb_ptr dest; /* pointer to frame buffer */
67p_draster equ 4 ; int draster; /* raster of frame buffer */
68p_src equ 6 ; byte far *src; /* pointer to source data */
69p_sraster equ 10 ; int sraster; /* source raster */
70p_width equ 12 ; int width; /* width in bytes */
71p_height equ 14 ; int height; /* height in scan lines */
72p_shift equ 16 ; int shift; /* amount to right shift source */
73p_invert equ 18 ; int invert; /* 0 or -1 to invert source */
74p_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.
102msc1: mov ah,[bx]
103 mov [bx],al
104 add bx,dx
105msc2: mov ah,[bx]
106 mov [bx],al
107 add bx,dx
108 loop msc1
109 pop ds
110msc0: 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.
144msrs: 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
151msr0: pop ds
152 leavef
153 ret
154; Large count, loop by words rather than bytes.
155msrl: mov ah,al ;we may be storing words...
156msr1: 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)
161msr2: 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).
165msr3: 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
210mrw1: 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
218mrw2: dec byte ptr [bp-7] ; high byte of yc
219 jge mrw1
220 add sp,2 ; pop yc
221 pop di
222 pop si
223mrw0: 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
260mrw21: 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
271mrw20: pop ds
272 leavep
273 ret
274_memrwcol2 ENDP
275
276gdevegaasm_TEXT ENDS
277 END