/
MATH.INC
222 lines (184 loc) · 3.85 KB
/
MATH.INC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
; -*- text -*-
;MATH-Library
;fuer den WiNiFe-Compiler
;cdw by 'The Atari Team' 2019
;
.LOCAL
; HINT: Genau drauf achten, das immer x das hoeherwertige Byte nimmt
; SGN vorzeichen x * 256 + y := SGN(@REG1)
@SGN
@SGN_I
LDY #2
LDA (@HEAP_PTR),Y ; get high value
BMI ?SGNNEGATIV
STA @REG+1
DEY
LDA (@HEAP_PTR),Y ; get low value
ORA @REG+1
BEQ ?SGNZERO
LDY #1 ;positiv
LDX #0
RTS
?SGNNEGATIV
LDY #255 ;negativ
LDX #255
RTS
?SGNZERO
LDY #0 ;zero
LDX #0
RTS
; Vorzeichen entfernen, immer positiv
@ABS
@ABS_I
LDY #2
LDA (@HEAP_PTR),Y ; get high value
BPL ?ABSPOSITIV
STA @REG+1
DEY
LDA (@HEAP_PTR),Y
STA @REG
jmp @NEG_INNER
; SEC ;Ensure carry is set
; LDA #0 ;Load constant zero
; SBC @REG+0 ;... subtract the least significant byte
; TAY ;... and store the result
; LDA #0 ;Load constant zero again
; SBC @REG+1 ;... subtract the most significant byte
; TAX ;... and store the result
; RTS
?ABSPOSITIV
TAX
DEY
LDA (@HEAP_PTR),Y
TAY
RTS
; MIN a,b
@MIN
@MIN_II
LDY #2
LDA (@HEAP_PTR),Y ; wert holen
STA @ERG+1
DEY
LDA (@HEAP_PTR),Y
STA @ERG
; (x*256+y) ist der Wert im Heap
LDY #4
LDA (@HEAP_PTR),Y ; wert holen
TAX
DEY
LDA (@HEAP_PTR),Y
TAY
; Bedingung (a>b)
CPY @ERG
TXA
SBC @ERG+1
BVC ?VC1112
EOR #$80
?VC1112
BMI ?A_GT_B2
?MIN_FALSE
LDY @ERG
LDX @ERG+1
RTS
?A_GT_B2
?MIN_TRUE
; LDY @REG
; LDX @REG+1
RTS
; MAX a,b
@MAX
@MAX_II
LDY #2
LDA (@HEAP_PTR),Y ; wert holen
STA @ERG+1
DEY
LDA (@HEAP_PTR),Y
STA @ERG
; (x*256+y) ist der Wert im Heap
LDY #4
LDA (@HEAP_PTR),Y ; wert holen
TAX
DEY
LDA (@HEAP_PTR),Y
TAY
; (x*256+y) ist der Wert im Heap
; STY @REG
; STX @REG+1
; Bedingung (a>b)
CPY @ERG
TXA
SBC @ERG+1
BVC ?VC111
EOR #$80
?VC111
BMI ?A_GT_B
?MAX_FALSE
; LDY @REG
; LDX @REG+1
RTS
?A_GT_B
?MAX_TRUE
LDY @ERG
LDX @ERG+1
RTS
; Negiert ein gegebenes Word
; ist das gleiche wie (x*256+y) := (x*256+y) * -1 nur schneller
@NEG
@NEG_I
LDY #2
LDA (@HEAP_PTR),Y ; wert holen
STA @REG+1
DEY
LDA (@HEAP_PTR),Y
STA @REG
; 16 bit Binary Negation
@NEG_INNER
SEC ;Ensure carry is set
LDA #0 ;Load constant zero
SBC @REG+0 ;... subtract the least significant byte
TAY ;... and store the result
LDA #0 ;Load constant zero again
SBC @REG+1 ;... subtract the most significant byte
TAX ;... and store the result
RTS
; Convertiert vorzeichenrichtig ein Byte zu einem Word
; Der Compiler koennte es leisten, ist mir aber zu kompliziert
; Beim Ausfuehren weiss das Programm nichts mehr von byte oder word
; kostet hier 19 Takte + 28 Takte (init)
@TOWORD
@TOWORD_I
LDY #1 ;2
LDA (@HEAP_PTR),Y ;5 wert holen (ein Byte)
BMI ?NEGATIV ;2 (positiv, no jump)
TAY ;2
LDX #0 ;2
RTS ;6
?NEGATIV
TAY ;2 + 1 (branch)
LDX #$FF ;2
RTS ;6
; liefert 1, wenn das uebergebene ungerade ist
@ODD
@ODD_I
LDY #1
LDA (@HEAP_PTR),Y ; wert holen (ein Byte)
AND #~00000001
BNE ?TRUE
JMP ?FALSE
; liefert 1, wenn das uebergebene gerade ist
@EVEN
@EVEN_I
LDY #1
LDA (@HEAP_PTR),Y ; wert holen (ein Byte)
AND #~00000001
BNE ?FALSE
; BEQ ?TRUE
?TRUE
LDY #1
LDX #0
RTS
?FALSE
LDY #0
LDX #0
RTS
; TODO: Potenzieren würde 2 Parameter erfordern, wird nicht unterstuetzt. Aber x*x kann jeder selbst tippen