File: dos\lsysa.asm
1 ; LSYSA.ASM: assembler support routines for optimized L-System code
2 ; Nicholas Wilt, 11/13/91.
3 ; Updated to work with integer/FP code, 7/93.
4
5 ifdef ??version
6 masm51
7 quirks
8 endif
9
10 .MODEL MEDIUM,C
11
12 lsys_turtlestatei STRUC
13 counter DB ?
14 angle DB ?
15 reverse DB ?
16 stackoflow DB ?
17 maxangle DB ?
18 dmaxangle DB ?
19 curcolor DB ?
20 dummy DB ?
21 ssize DD ?
22 realangle DD ?
23 xpos DD ?
24 ypos DD ?
25 xmin DD ?
26 ymin DD ?
27 xmax DD ?
28 ymax DD ?
29 aspect DD ?
30 num DD ?
31 lsys_turtlestatei ENDS
32
33 EXTRN overflow:WORD
34 EXTRN boxy:DWORD
35
36 sins equ boxy
37 coss equ boxy + 200 ; 50 * 4 bytes
38
39 .CODE
40
41 DECANGLE MACRO
42 LOCAL @1
43 dec al
44 jge @1
45 mov al,[bx.dmaxangle]
46 @1: mov [bx.angle],al
47 ENDM
48
49 INCANGLE MACRO
50 LOCAL @1
51 inc al
52 cmp al,[bx.maxangle]
53 jne @1
54 xor ax,ax
55 @1: mov [bx.angle],al
56 ENDM
57
58 PUBLIC lsysi_doplus
59
60 lsysi_doplus PROC lsyscmd:ptr
61 mov bx,lsyscmd
62 mov al,[bx.angle]
63 cmp [bx.reverse],0
64 jnz PlusIncAngle
65 DECANGLE
66 ret
67 PlusIncAngle:
68 INCANGLE
69 ret
70 lsysi_doplus ENDP
71
72 PUBLIC lsysi_dominus
73
74 lsysi_dominus PROC lsyscmd:ptr
75 mov bx,lsyscmd ; Get pointer
76 mov al,[bx.angle]
77 cmp [bx.reverse],0
78 jnz MinusDecAngle
79 INCANGLE
80 ret
81 MinusDecAngle:
82 DECANGLE
83 ret
84 lsysi_dominus ENDP
85
86 PUBLIC lsysi_doplus_pow2
87
88 lsysi_doplus_pow2 PROC lsyscmd:ptr
89 mov bx,lsyscmd ; Get pointer
90 mov al,[bx.angle]
91 cmp [bx.reverse],0
92 jnz Plus2IncAngle
93 dec al
94 and al,[bx.dmaxangle]
95 mov [bx.angle],al
96 ret
97 Plus2IncAngle:
98 inc al
99 and al,[bx.dmaxangle]
100 mov [bx.angle],al
101 ret
102 lsysi_doplus_pow2 ENDP
103
104 PUBLIC lsysi_dominus_pow2
105
106 lsysi_dominus_pow2 PROC lsyscmd:ptr
107 mov bx,lsyscmd ; Get pointer
108 mov al,[bx.angle]
109 cmp [bx.reverse],0
110 jz Minus2IncAngle
111 dec al
112 and al,[bx.dmaxangle]
113 mov [bx.angle],al
114 ret
115 Minus2IncAngle:
116 inc al
117 and al,[bx.dmaxangle]
118 mov [bx.angle],al
119 ret
120 lsysi_dominus_pow2 ENDP
121
122 PUBLIC lsysi_dopipe_pow2
123
124 lsysi_dopipe_pow2 PROC lsyscmd:ptr
125 mov bx,lsyscmd ; Get pointer
126 xor ax,ax
127 mov al,[bx.maxangle]
128 shr ax,1
129 xor dx,dx
130 mov dl,[bx.angle]
131 add ax,dx
132 and al,[bx.dmaxangle]
133 mov [bx.angle],al
134 ret
135 lsysi_dopipe_pow2 ENDP
136
137 PUBLIC lsysi_dobang
138
139 lsysi_dobang PROC lsyscmd:ptr
140 mov bx,lsyscmd ; Get pointer
141 mov al,[bx.reverse] ; reverse = ! reverse;
142 dec al ; -1 if was 0; 0 if was 1
143 neg al ; 1 if was 0; 0 if was 1
144 mov [bx.reverse],al ;
145 ret
146 lsysi_dobang ENDP
147
148 ; Some 386-specific leaf functions go here.
149
150 .386
151
152 PUBLIC lsysi_doslash_386
153
154 lsysi_doslash_386 PROC lsyscmd:ptr
155 mov bx,lsyscmd ; Get pointer
156 mov eax,[bx.num]
157 cmp [bx.reverse],0
158 jnz DoSlashDec
159 add [bx.realangle],eax
160 ret
161 DoSlashDec:
162 sub [bx.realangle],eax
163 ret
164 lsysi_doslash_386 ENDP
165
166 PUBLIC lsysi_dobslash_386
167
168 lsysi_dobslash_386 PROC lsyscmd:ptr
169 mov bx,lsyscmd ; Get pointer
170 mov eax,[bx.num]
171 cmp [bx.reverse],0
172 jz DoBSlashDec
173 add [bx.realangle],eax
174 ret
175 DoBSlashDec:
176 sub [bx.realangle],eax
177 ret
178 lsysi_dobslash_386 ENDP
179
180 PUBLIC lsysi_doat_386
181
182 lsysi_doat_386 PROC lsyscmd:ptr ; not used, N:DWORD
183 mov bx,lsyscmd ; Get pointer
184 mov eax,[bx.ssize] ; Get size
185 imul [bx.num] ; Mul by n
186 shrd eax,edx,19
187 mov [bx.ssize],eax ; Save back
188 ret
189 lsysi_doat_386 ENDP
190
191 PUBLIC lsysi_dosizegf_386
192
193 lsysi_dosizegf_386 PROC USES SI,lsyscmd:ptr
194 mov si,lsyscmd ;
195 mov ecx,[si.ssize] ; Get size; we'll need it twice
movzx ebx,[si.angle]
ifndef ??version
mov eax,coss[ebx*4] ; eax <- coss[angle]
else
; TASM-only (this is slower but it should work)
shl bx,2
add bx,offset DGROUP:coss
mov eax,[ebx] ; eax <- coss[angle]
endif
imul ecx ; Mul by size
shrd eax,edx,29 ; eax <- multiply(size, coss[angle], 29)
add eax,[si.xpos] ;
jno nooverfl ; check for overflow
mov overflow,1 ; oops - flag the user later
nooverfl:
cmp eax,[si.xmax] ; If xpos <= [si.xmax,
jle GF1 ; jump
mov [si.xmax],eax ;
GF1: cmp eax,[si.xmin] ; If xpos >= [si.xmin
jge GF2 ; jump
mov [si.xmin],eax ;
GF2: mov [si.xpos],eax ; Save xpos
ifndef ??version
mov eax,sins[ebx*4] ; eax <- sins[angle]
else ; sins table is 200 bytes before coss
mov eax,[ebx-200] ; eax <- sins[angle]
endif
imul ecx ;
shrd eax,edx,29 ;
add eax,[si.ypos] ;
cmp eax,[si.ymax] ; If ypos <= [si.ymax,
jle GF3 ; jump
mov [si.ymax],eax ;
GF3: cmp eax,[si.ymin] ; If ypos >= [si.ymin
jge GF4 ; jump
mov [si.ymin],eax ;
GF4: mov [si.ypos],eax ;
ret
lsysi_dosizegf_386 ENDP
PUBLIC lsysi_dodrawg_386
lsysi_dodrawg_386 PROC USES SI,lsyscmd:ptr
mov si,lsyscmd ; Get pointer to structure
mov ecx,[si.ssize] ; Because we need it twice
movzx ebx,[si.angle]
ifndef ??version
mov eax,coss[ebx*4] ; eax <- coss[angle]
else
; TASM-only (this is slow but it should work)
shl bx,2
add bx,offset DGROUP:coss
mov eax,[ebx] ; eax <- coss[angle]
endif
imul ecx ;
shrd eax,edx,29 ;
add [si.xpos],eax ; xpos += size*coss[angle] >> 29
ifndef ??version
mov eax,sins[ebx*4] ; eax <- sins[angle]
else ; sins table is 200 bytes before coss
mov eax,[ebx-200] ; eax <- sins[angle]
endif
imul ecx ; ypos += size*sins[angle] >> 29
shrd eax,edx,29 ;
add [si.ypos],eax ;
ret ;
lsysi_dodrawg_386 ENDP
END