File: dos\lsysaf.asm
1 ; LSYSAF.ASM: assembler support routines for optimized L-System code
2 ; (floating-point version)
3 ; Nicholas Wilt, 7/93.
4
5 .MODEL MEDIUM,C
6
7 lsys_turtlestatef STRUC
8 counter DB ?
9 angle DB ?
10 reverse DB ?
11 stackoflow DB ?
12 maxangle DB ?
13 dmaxangle DB ?
14 curcolor DB ?
15 dummy DB ?
16 ssize DT ?
17 realangle DT ?
18 xpos DT ?
19 ypos DT ?
20 xmin DT ?
21 ymin DT ?
22 xmax DT ?
23 ymax DT ?
24 aspect DT ?
25 num DD ?
26 lsys_turtlestatef ENDS
27
28 EXTRN overflow:WORD
29 EXTRN draw_line:FAR
30 EXTRN FPUsincos:FAR
31 EXTRN cpu:WORD
32
33 EXTRN boxy:TBYTE
34
35 sins_f equ boxy
36 coss_f equ boxy + 500 ; 50 * 10 bytes
37
38 .CODE
39
40 DECANGLE MACRO
41 LOCAL @1
42 dec al
43 jge @1
44 mov al,[bx.dmaxangle]
45 @1: mov [bx.angle],al
46 ENDM
47
48 INCANGLE MACRO
49 LOCAL @1
50 inc al
51 cmp al,[bx.maxangle]
52 jne @1
53 xor ax,ax
54 @1: mov [bx.angle],al
55 ENDM
56
57 PUBLIC lsysf_doplus
58
59 lsysf_doplus PROC lsyscmd:ptr
60 mov bx,lsyscmd
61 mov al,[bx.angle]
62 cmp [bx.reverse],0
63 jnz PlusIncAngle
64 DECANGLE
65 ret
66 PlusIncAngle:
67 INCANGLE
68 ret
69 lsysf_doplus ENDP
70
71 PUBLIC lsysf_dominus
72
73 lsysf_dominus PROC lsyscmd:ptr
74 mov bx,lsyscmd ; Get pointer
75 mov al,[bx.angle]
76 cmp [bx.reverse],0
77 jnz MinusDecAngle
78 INCANGLE
79 ret
80 MinusDecAngle:
81 DECANGLE
82 ret
83 lsysf_dominus ENDP
84
85 PUBLIC lsysf_doplus_pow2
86
87 lsysf_doplus_pow2 PROC lsyscmd:ptr
88 mov bx,lsyscmd ; Get pointer
89 mov al,[bx.angle]
90 cmp [bx.reverse],0
91 jnz Plus2IncAngle
92 dec al
93 and al,[bx.dmaxangle]
94 mov [bx.angle],al
95 ret
96 Plus2IncAngle:
97 inc al
98 and al,[bx.dmaxangle]
99 mov [bx.angle],al
100 ret
101 lsysf_doplus_pow2 ENDP
102
103 PUBLIC lsysf_dominus_pow2
104
105 lsysf_dominus_pow2 PROC lsyscmd:ptr
106 mov bx,lsyscmd ; Get pointer
107 mov al,[bx.angle]
108 cmp [bx.reverse],0
109 jz Minus2IncAngle
110 dec al
111 and al,[bx.dmaxangle]
112 mov [bx.angle],al
113 ret
114 Minus2IncAngle:
115 inc al
116 and al,[bx.dmaxangle]
117 mov [bx.angle],al
118 ret
119 lsysf_dominus_pow2 ENDP
120
121 PUBLIC lsysf_dopipe_pow2
122
123 lsysf_dopipe_pow2 PROC lsyscmd:ptr
124 mov bx,lsyscmd ; Get pointer
125 xor ax,ax
126 mov al,[bx.maxangle]
127 shr ax,1
128 xor dx,dx
129 mov dl,[bx.angle]
130 add ax,dx
131 and al,[bx.dmaxangle]
132 mov [bx.angle],al
133 ret
134 lsysf_dopipe_pow2 ENDP
135
136 PUBLIC lsysf_dobang
137
138 lsysf_dobang PROC lsyscmd:ptr
139 mov bx,lsyscmd ; Get pointer
140 mov al,[bx.reverse] ; reverse = ! reverse;
141 dec al ; -1 if was 0; 0 if was 1
142 neg al ; 1 if was 0; 0 if was 1
143 mov [bx.reverse],al ;
144 ret
145 lsysf_dobang ENDP
146
147 PUBLIC lsysf_doat
148
149 lsysf_doat PROC lsyscmd:ptr
150 mov bx,lsyscmd ; Get pointer
151 fld tbyte ptr [bx.num] ; Get N.
152 ; FPU stk: N xpos ypos size aspect
153 fmulp st(3),st ; Multiply size by it.
154 ret
155 lsysf_doat ENDP
156
157 .386
158
159 LSYS_SINCOS MACRO OFFS
160 LOCAL UseSinCos, Done
161
162 cmp cpu,386 ; If CPU >= 386, we can use fsincos.
163 jge UseSinCos ;
164
165 ; Otherwise we use FPUsincos.
166
167 sub sp,50+24 ; Save enough room for entire state
168 ; plus parameter to sin or cos
169 fstp tbyte ptr [bp-OFFS-10] ; Save state
170 fstp tbyte ptr [bp-OFFS-20] ;
171 fstp tbyte ptr [bp-OFFS-30] ;
172 fstp tbyte ptr [bp-OFFS-40] ;
173 fld st ; realangle remains on FPU stack
174 fstp tbyte ptr [bp-OFFS-50] ;
175 fstp qword ptr [bp-OFFS-50-8] ; Store as parameter to FPUsincos
176
177 lea ax,[bp-OFFS-50-16] ; Push pointer to cosine
178 push ax ;
179 lea ax,[bp-OFFS-50-24] ; Push pointer to sine
180 push ax ;
181 lea ax,[bp-OFFS-50-8] ; Push pointer to parameter
182 push ax ;
183 call FPUsincos ; Call it.
184
185 add sp,6 ; Restore stack
186
187 fld tbyte ptr [bp-OFFS-50] ; Restore state
188 fld tbyte ptr [bp-OFFS-40] ;
189 fld tbyte ptr [bp-OFFS-30] ;
190 fld tbyte ptr [bp-OFFS-20] ;
191 fld tbyte ptr [bp-OFFS-10] ;
192 fld qword ptr [bp-OFFS-50-24] ; Get sine
193 fld qword ptr [bp-OFFS-50-16] ; Get cosine
194
195 add sp,50+24 ; Restore stack
196
197 jmp short Done ;
198 UseSinCos:
199 fld st(4) ; Get angle
200 fsincos ; c s xpos ypos size aspect realangle
201 Done:
202 ENDM
203
204 PUBLIC lsysf_dosizedm
205
206 lsysf_dosizedm PROC lsyscmd:ptr
207 LSYS_SINCOS 0 ; Get sine and cosine of angle.
208 mov bx,lsyscmd ; Get pointer to structure
209 fmul st,st(5) ; c*aspect s xpos ypos size aspect
210 fmul st,st(4) ; c*size*aspect s xpos ypos size aspect
211 faddp st(2),st ; s xpos ypos size aspect
212 fmul st,st(3) ; s*size xpos ypos size aspect
213 faddp st(2),st ; xpos ypos size aspect
214
215 push ax ; Allocate a local for FP status word
216
217 fld [bx.xmin] ; Compare xpos to xmin
218 fcomp ;
219 fstsw [bp-2] ; Store status word
220 mov ax,[bp-2] ;
221 sahf ;
222 jb SizeDM1 ; Jump if ST > xmin
223 fld st ;
224 fstp [bx.xmin] ;
225 jmp short SizeDM2 ;
226 SizeDM1:
227 fld [bx.xmax] ; Compare to xmax
228 fcomp ;
229 fstsw [bp-2] ; Store status word
230 mov ax,[bp-2] ;
231 sahf ;
232 ja SizeDM2 ; Jump if ST < xmax
233 fld st ;
234 fstp [bx.xmax] ;
235 SizeDM2:
236 fxch ; Swap xpos and ypos
237 fld [bx.ymin] ; Compare ypos to ymin
238 fcomp ;
239 fstsw [bp-2] ; Store status word
240 mov ax,[bp-2] ;
241 sahf ;
242 jb SizeDM3 ; Jump if ST > ymin
243 fld st ;
244 fstp [bx.ymin] ;
245 jmp short SizeDM4 ;
246 SizeDM3:
247 fld [bx.ymax] ; Compare ypos to ymax
248 fcomp ;
249 fstsw [bp-2] ;
250 mov ax,[bp-2] ;
251 sahf ;
252 ja SizeDM4 ;
253 fld st ;
254 fstp [bx.ymax] ;
255 SizeDM4:
256 fxch ; Swap xpos and ypos back
257 pop ax ; Deallocate local for FPU status word
258
259 ret ; Done.
260 lsysf_dosizedm ENDP
261
262 PUBLIC lsysf_dosizegf
263
264 lsysf_dosizegf PROC USES SI,lsyscmd:ptr
265 mov si,lsyscmd ;
266 xor bx,bx ; BX <- angle * sizeof(long double)
267 mov bl,[si.angle] ;
268 shl bx,1 ;
269 mov ax,bx ;
270 shl ax,1 ;
271 shl ax,1 ;
272 add bx,ax ;
273 fld st(2) ; size xpos ypos size aspect
274 fld coss_f[bx] ; size*cmd->coss[cmd->angle]
275 fmul ;
276 faddp st(1),st ; xpos ypos size aspect
277 fld st(2) ; size xpos ypos size aspect
278 fld sins_f[bx] ; size*cmd->sins[cmd->angle]
279 fmul ;
280 faddp st(2),st ; xpos ypos size aspect
281
282 push ax ; Allocate a local for FPU status word
283
284 fld [si.xmin] ; Compare xpos to xmin
285 fcomp ;
286 fstsw [bp-4] ; Store status word
287 mov ax,[bp-4] ;
288 sahf ;
289 jb SizeGF1 ; Jump if ST > xmin
290 fld st ;
291 fstp [si.xmin] ;
292 jmp short SizeGF2 ;
293 SizeGF1:
294 fld [si.xmax] ; Compare to xmax
295 fcomp ;
296 fstsw [bp-4] ; Store status word
297 mov ax,[bp-4] ;
298 sahf ;
299 ja SizeGF2 ; Jump if ST < xmax
300 fld st ;
301 fstp [si.xmax] ;
302 SizeGF2:
303 fxch ; Swap xpos and ypos
304 fld [si.ymin] ; Compare ypos to ymin
305 fcomp ;
306 fstsw [bp-4] ; Store status word
307 mov ax,[bp-4] ;
308 sahf ;
309 jb SizeGF3 ; Jump if ST > ymin
310 fld st ;
311 fstp [si.ymin] ;
312 jmp short SizeGF4 ;
313 SizeGF3:
314 fld [si.ymax] ; Compare ypos to ymax
315 fcomp ;
316 fstsw [bp-4] ;
317 mov ax,[bp-4] ;
318 sahf ;
319 ja SizeGF4 ;
320 fld st ;
321 fstp [si.ymax] ;
322 SizeGF4:
323 fxch ; Swap xpos and ypos back
324 pop ax ; Deallocate local for FPU status word
325 ret
326 lsysf_dosizegf ENDP
327
328 PUBLIC lsysf_dodrawg
329
330 lsysf_dodrawg PROC USES SI,lsyscmd:ptr
331 mov si,lsyscmd ; Get pointer to structure
332 xor bx,bx ; Get angle offset
333 mov bl,[si.angle] ;
334 mov al,10 ;
335 mul bl ;
336 xchg ax,bx ;
337 fld coss_f[bx] ; xpos += cmd->size * cmd->coss[cmd->angle]
338 fmul st,st(3) ;
339 fadd ;
340 fld sins_f[bx] ; ypos += cmd->size * cmd->sins[cmd->angle]
341 fmul st,st(3) ;
342 faddp st(2),st ;
343 ret ;
344 lsysf_dodrawg ENDP
345
346 PUBLIC lsysf_dodrawd
347
348 lsysf_dodrawd PROC lsyscmd:PTR
349 mov bx,lsyscmd ; Get pointer to structure
350 xor ax,ax ; Push last parm to draw_line
351 mov al,[bx.curcolor]
352 push ax ;
353 sub sp,8 ; Allocate the rest of draw_line's parms
fist word ptr [bp-10] ; Store xpos
fxch ; Store ypos
fist word ptr [bp-8] ;
fxch ;
LSYS_SINCOS 10 ; c s xpos ypos size aspect
fmul st,st(5) ; c*aspect s xpos ypos size aspect
fmul st,st(4) ; size*c*aspect s xpos ypos size aspect
faddp st(2),st ; s xpos ypos size aspect
fmul st,st(3) ; s*size xpos ypos size aspect
faddp st(2),st ; xpos ypos size aspect
fist word ptr [bp-6] ; Store xpos
fxch ; Store ypos
fist word ptr [bp-4] ;
fxch ;
call far ptr draw_line ;
add sp,10 ; Remove parameters
ret ;
lsysf_dodrawd ENDP
PUBLIC lsysf_dodrawm
lsysf_dodrawm PROC lsyscmd:ptr
mov bx,lsyscmd ; Get pointer to structure, to quiet warning
LSYS_SINCOS 0 ;
fmul st,st(5) ; c*aspect s xpos ypos size aspect
fmul st,st(4) ; size*c*aspect s xpos ypos size aspect
faddp st(2),st ; s xpos ypos size aspect
fmul st,st(3) ; s*size xpos ypos size aspect
faddp st(2),st ; xpos ypos size aspect
ret ;
lsysf_dodrawm ENDP
PUBLIC lsysf_dodrawf
lsysf_dodrawf PROC USES SI, lsyscmd:ptr
mov si,lsyscmd ; Get pointer to structure
xor ax,ax ; Push curcolor for draw_line
mov al,[si.curcolor] ;
push ax ;
sub sp,8 ; Allocate the rest of the draw_line call
fist word ptr [bp-12] ; Store xpos in draw_line parms
fxch ; Store ypos in draw_line parms
fist word ptr [bp-10] ;
fxch ;
xor bx,bx ; BX <- offset into cos/sin arrays
mov bl,[si.angle] ;
mov al,10 ;
mul bl ;
xchg ax,bx ;
fld st(2) ; xpos += size*cmd->coss[cmd->angle]
fld coss_f[bx] ;
fmul
fadd ;
fist word ptr [bp-8] ; Store new xpos in draw_line parms
fld st(2) ; ypos += size*cmd->sins[cmd->angle]
fld sins_f[bx] ;
fmul ;
faddp st(2),st ;
fxch ; Store new ypos in draw_line parms
fist word ptr [bp-6] ;
fxch ;
call far ptr draw_line ; Call the line-drawing routine
add sp,10 ; Deallocate the stuff we pushed
ret ;
lsysf_dodrawf ENDP
PUBLIC lsysf_doslash
lsysf_doslash PROC lsyscmd:ptr
mov bx,lsyscmd ; Get pointer
fld tbyte ptr [bx.num]
cmp [bx.reverse],0
jnz DoSlashDec
faddp st(5),st
ret
DoSlashDec:
fsubp st(5),st
ret
lsysf_doslash ENDP
PUBLIC lsysf_dobslash
lsysf_dobslash PROC lsyscmd:ptr
mov bx,lsyscmd ; Get pointer
fld tbyte ptr [bx.num]
cmp [bx.reverse],0
jz DoBSlashDec
faddp st(5),st
ret
DoBSlashDec:
fsubp st(5),st
ret
lsysf_dobslash ENDP
PUBLIC lsys_prepfpu
lsys_prepfpu PROC lsyscmd:ptr
mov bx,lsyscmd ; Get pointer to structure
fld [bx.realangle] ; Load: xpos ypos size aspect realangle
fld [bx.aspect] ;
fld [bx.ssize] ;
fld [bx.ypos] ;
fld [bx.xpos] ;
ret ; Return.
lsys_prepfpu ENDP
PUBLIC lsys_donefpu
lsys_donefpu PROC lsyscmd:ptr
mov bx,lsyscmd ; Get pointer to structure
fstp [bx.xpos] ; Save: xpos ypos size aspect realangle
fstp [bx.ypos] ;
fstp [bx.ssize] ;
fstp [bx.aspect] ;
fstp [bx.realangle] ;
ret
lsys_donefpu ENDP
END