]> 4ch.mooo.com Git - 16.git/blob - 16/xlib/xline.asm
code miraculously works on real hardware
[16.git] / 16 / xlib / xline.asm
1 ;-----------------------------------------------------------------------\r
2 ; MODULE XLINE\r
3 ;\r
4 ; Line drawing functions.\r
5 ;\r
6 ; Compile with Tasm.\r
7 ; C callable.\r
8 ;\r
9 ;\r
10 ; ****** XLIB - Mode X graphics library                ****************\r
11 ; ******                                               ****************\r
12 ; ****** Written By Themie Gouthas                     ****************\r
13 ;\r
14 ; egg@dstos3.dsto.gov.au\r
15 ; teg@bart.dsto.gov.au\r
16 ;-----------------------------------------------------------------------\r
17 include xlib.inc\r
18 include xline.inc\r
19 \r
20         .code\r
21 \r
22 \r
23 ModeXAddr       macro\r
24         mov     cl,bl\r
25         push    dx\r
26         mov     dx,[_ScrnLogicalByteWidth]\r
27         mul     dx\r
28         pop     dx\r
29         shr     bx,1\r
30         shr     bx,1\r
31         add     bx,ax\r
32         add     bx,[bp+14]\r
33         and     cl,3\r
34         endm\r
35 \r
36 \r
37 ;-----------------------------------------------------------------------\r
38 ; _x_line\r
39 ;\r
40 ; Line drawing function for all MODE X 256 Color resolutions\r
41 ; Based on code from "PC and PS/2 Video Systems" by Richard Wilton.\r
42 ;\r
43 ; Compile with Tasm.\r
44 ; C callable.\r
45 ;\r
46 \r
47 _x_line         proc\r
48 ;ARG     x1:word,y1:word,x2:word,y2:word,Color:word,PgOffs:word\r
49 LOCAL   vertincr:word,incr1:word,incr2:word,routine:word=LocalStk\r
50         push    bp              ; Set up stack frame\r
51         mov     bp,sp\r
52         sub     sp,LocalStk\r
53         push    si\r
54         push    di\r
55 \r
56         mov     ax,0a000h\r
57         mov     es,ax\r
58 \r
59         mov     dx,SC_INDEX     ; setup for plane mask access\r
60 \r
61 ; check for vertical line\r
62 \r
63         mov     si,[_ScrnLogicalByteWidth]\r
64         mov     cx,[bp+8]\r
65         sub     cx,[bp+4]\r
66         jz      VertLine\r
67 \r
68 ; force x1 < x2\r
69 \r
70         jns     L01\r
71 \r
72         neg     cx\r
73 \r
74         mov     bx,[bp+8]\r
75         xchg    bx,[bp+4]\r
76         mov     [bp+8],bx\r
77 \r
78         mov     bx,[bp+10]\r
79         xchg    bx,[bp+6]\r
80         mov     [bp+10],bx\r
81 \r
82 ; calc dy = abs(y2 - y1)\r
83 \r
84 L01:\r
85         mov     bx,[bp+10]\r
86         sub     bx,[bp+6]\r
87         jnz     short skip\r
88         jmp     HorizLine\r
89 skip:           jns     L03\r
90 \r
91         neg     bx\r
92         neg     si\r
93 \r
94 ; select appropriate routine for slope of line\r
95 \r
96 L03:\r
97         mov     [vertincr],si\r
98         mov     [routine],offset LoSlopeLine\r
99         cmp     bx,cx\r
100         jle     L04\r
101         mov     [routine],offset HiSlopeLine\r
102         xchg    bx,cx\r
103 \r
104 ; calc initial decision variable and increments\r
105 \r
106 L04:\r
107         shl     bx,1\r
108         mov     [incr1],bx\r
109         sub     bx,cx\r
110         mov     si,bx\r
111         sub     bx,cx\r
112         mov     [incr2],bx\r
113 \r
114 ; calc first pixel address\r
115 \r
116         push    cx\r
117         mov     ax,[bp+6]\r
118         mov     bx,[bp+4]\r
119         ModeXAddr\r
120         mov     di,bx\r
121         mov     al,1\r
122         shl     al,cl\r
123         mov     ah,al           ; duplicate nybble\r
124         shl     al,1\r
125         shl     al,1\r
126         shl     al,1\r
127         shl     al,1\r
128         add     ah,al\r
129         mov     bl,ah\r
130         pop     cx\r
131         inc     cx\r
132         jmp     [routine]\r
133 \r
134 ; routine for verticle lines\r
135 \r
136 VertLine:\r
137         mov     ax,[bp+6]\r
138         mov     bx,[bp+10]\r
139         mov     cx,bx\r
140         sub     cx,ax\r
141         jge     L31\r
142         neg     cx\r
143         mov     ax,bx\r
144 \r
145 L31:\r
146         inc     cx\r
147         mov     bx,[bp+4]\r
148         push    cx\r
149         ModeXAddr\r
150 \r
151         mov     ah,1\r
152         shl     ah,cl\r
153         mov     al,MAP_MASK\r
154         out     dx,ax\r
155         pop     cx\r
156         mov     ax, word ptr [bp+12]\r
157 \r
158 ; draw the line\r
159 \r
160 L32:\r
161         mov     es:[bx],al\r
162         add     bx,si\r
163         loop    L32\r
164         jmp     Lexit\r
165 \r
166 ; routine for horizontal line\r
167 \r
168 HorizLine:\r
169         push    ds\r
170 \r
171         mov     ax,[bp+6]\r
172         mov     bx,[bp+4]\r
173         ModeXAddr\r
174 \r
175         mov     di,bx     ; set dl = first byte mask\r
176         mov     dl,00fh\r
177         shl     dl,cl\r
178 \r
179         mov     cx,[bp+8] ; set dh = last byte mask\r
180         and     cl,3\r
181         mov     dh,00eh\r
182         shl     dh,cl\r
183         not     dh\r
184 \r
185 ; determine byte offset of first and last pixel in line\r
186 \r
187         mov     ax,[bp+8]\r
188         mov     bx,[bp+4]\r
189 \r
190         shr     ax,1     ; set ax = last byte column\r
191         shr     bx,1    ; set bx = first byte column\r
192         shr     ax,1     ; set ax = last byte column\r
193         shr     bx,1    ; set bx = first byte column\r
194         mov     cx,ax    ; cx = ax - bx\r
195         sub     cx,bx\r
196 \r
197         mov     ax,dx    ; mov end byte masks to ax\r
198         mov     dx,SC_INDEX ; setup dx for VGA outs\r
199         mov     bx, [bp+12]\r
200 \r
201 ; set pixels in leftmost byte of line\r
202 \r
203         or      cx,cx      ; is start and end pt in same byte\r
204         jnz     L42        ; no !\r
205         and     ah,al      ; combine start and end masks\r
206         jmp     short L44\r
207 \r
208 L42:            push    ax\r
209         mov     ah,al\r
210         mov     al,MAP_MASK\r
211         out     dx,ax\r
212         mov     al,bl\r
213         stosb\r
214         dec     cx\r
215 \r
216 ; draw remainder of the line\r
217 \r
218 L43:\r
219         mov     ah,0Fh\r
220         mov     al,MAP_MASK\r
221         out     dx,ax\r
222         mov     al,bl\r
223         rep     stosb\r
224         pop     ax\r
225 \r
226 ; set pixels in rightmost byte of line\r
227 \r
228 L44:\r
229         mov     al,MAP_MASK\r
230         out     dx, ax\r
231         mov     byte ptr es:[di],bl\r
232         pop     ds\r
233         jmp     short Lexit\r
234 \r
235 \r
236 ; routine for dy >= dx (slope <= 1)\r
237 \r
238 LoSlopeLine:\r
239         mov     al,MAP_MASK\r
240         mov     bh,byte ptr [bp+12]\r
241 L10:\r
242         mov     ah,bl\r
243 \r
244 L11:\r
245         or      ah,bl\r
246         rol     bl,1\r
247         jc      L14\r
248 \r
249 ; bit mask not shifted out\r
250 \r
251         or      si,si\r
252         jns     L12\r
253         add     si,[incr1]\r
254         loop    L11\r
255 \r
256         out     dx,ax\r
257         mov     es:[di],bh\r
258         jmp     short Lexit\r
259 \r
260 L12:\r
261         add     si,[incr2]\r
262         out     dx,ax\r
263         mov     es:[di],bh\r
264         add     di,[vertincr]\r
265         loop    L10\r
266         jmp     short Lexit\r
267 \r
268 ; bit mask shifted out\r
269 \r
270 L14:            out     dx,ax\r
271         mov     es:[di],bh\r
272         inc     di\r
273         or      si,si\r
274         jns     L15\r
275         add     si,[incr1]\r
276         loop    L10\r
277         jmp     short Lexit\r
278 \r
279 L15:\r
280         add     si,[incr2]\r
281         add     di,[vertincr]\r
282         loop    L10\r
283         jmp     short Lexit\r
284 \r
285 ; routine for dy > dx (slope > 1)\r
286 \r
287 HiSlopeLine:\r
288         mov     bx,[vertincr]\r
289         mov     al,MAP_MASK\r
290 L21:            out     dx,ax\r
291         push    ax\r
292         mov     ax,[bp+12]\r
293         mov     es:[di],al\r
294         pop     ax\r
295         add     di,bx\r
296 \r
297 L22:\r
298         or      si,si\r
299         jns     L23\r
300 \r
301         add     si,[incr1]\r
302         loop    L21\r
303         jmp     short Lexit\r
304 \r
305 L23:\r
306         add     si,[incr2]\r
307         rol     ah,1\r
308         adc     di,0\r
309 lx21:   loop    L21\r
310 \r
311 ; return to caller\r
312 \r
313 Lexit:\r
314         pop     di\r
315         pop     si\r
316         mov     sp,bp\r
317         pop     bp\r
318         ret\r
319 \r
320 _x_line endp\r
321 \r
322 end\r