]>
Commit | Line | Data |
---|---|---|
1 | ;.area DATA | |
2 | .area OSEG (OVR,DATA) | |
3 | ;.area DATA | |
4 | notes: .ds 16 ; 0x00 .. 0x0f | |
5 | i0: .ds 1 ; 0x10 | |
6 | i1: .ds 1 ; 0x11 | |
7 | i2: .ds 1 ; 0x12 | |
8 | n: .ds 1 ; 0x13 | |
9 | .even ; make next two bytes word-aligned | |
10 | zero: .ds 1 ; 0x14 | |
11 | tmp_1: .ds 1 ; 0x15 | |
12 | tmp_hi: .ds 1 ; 0x16 | |
13 | tmp_lo: .ds 1 ; 0x17 | |
14 | pwm: .ds 1 ; 0x18 | |
15 | .area SSEG | |
16 | .even ; SP must be aligned? (sdcc does it) | |
17 | stack: .ds 1 | |
18 | ||
19 | ; aliases for memory locations: | |
20 | notes_ix = tmp_1 | |
21 | t = tmp_1 | |
22 | mul2 = tmp_hi | |
23 | mul1 = tmp_lo | |
24 | mod3hi = tmp_hi | |
25 | mod3lo = tmp_lo | |
26 | ||
27 | ; cycle count (worst-case) | |
28 | ; mod3: 28 | |
29 | ; g: 81 | |
30 | ; sample: 115 + 4*g + 2*mod3 = 495 | |
31 | ||
32 | ||
33 | .area CSEG (CODE,ABS) | |
34 | ;.area HOME | |
35 | ;.area HEADER (ABS) | |
36 | .org 0x0000 | |
37 | ;TODO: 0x0000 must be NOP for autocalib routine | |
38 | ;TODO: move some init stuff here (space for 15 instr.) | |
39 | GOTO init | |
40 | ||
41 | ;.area HOME | |
42 | ;.area HEADER (ABS) | |
43 | .org 0x0020 | |
44 | GOTO sample | |
45 | ||
46 | ;.area CODE | |
47 | ||
48 | mod3: | |
49 | MOV a, mod3hi | |
50 | ADD mod3lo, a ; mod3lo = hi+lo | |
51 | MOV a, #0 | |
52 | ADDC a ; mod3hi, 1bit | |
53 | SWAP a | |
54 | MOV mod3hi, a | |
55 | ||
56 | MOV a, mod3lo | |
57 | SWAP a | |
58 | AND a, #0xf ; (mod3lo>>4) | |
59 | XCH mod3lo ; a=mod3lo, mod3lo=mod3lo>>4 | |
60 | AND a, #0xF ; a=mod3lo&0xf, mod3lo=mod3lo>>4 | |
61 | ADD a, mod3lo ; (mod3lo & 0xF) | |
62 | ADD a, mod3hi | |
63 | MOV mod3lo, a | |
64 | ||
65 | AND a, #0x3 ; a = (mod3lo & 0x3) | |
66 | SR mod3lo | |
67 | SR mod3lo ; (mod3lo >> 2) | |
68 | ADD a, mod3lo | |
69 | MOV mod3lo, a | |
70 | ||
71 | AND a, #0x3 ; a = (mod3lo & 0x3) | |
72 | SR mod3lo | |
73 | SR mod3lo ; (mod3lo >> 2) | |
74 | ADD a, mod3lo | |
75 | ||
76 | SUB a, #3 | |
77 | T0SN f, c | |
78 | ADD a, #3 | |
79 | RET | |
80 | ||
81 | g: | |
82 | ; notes_ix_hi = always 0 | |
83 | AND a, #0x7 | |
84 | MOV notes_ix, a | |
85 | ; test i2 & 3: | |
86 | MOV a, i2 | |
87 | AND a, #3 | |
88 | T0SN f, z | |
89 | SET1 notes_ix, #3 | |
90 | IDXM a, notes_ix | |
91 | ||
92 | MOV t, a | |
93 | CLEAR mul2 | |
94 | CLEAR mul1 | |
95 | ; note: LSB of result (mul0) is not needed for our purposes | |
96 | ;;1/8: | |
97 | SR t | |
98 | T1SN f, c | |
99 | GOTO skip1 | |
100 | MOV a, i0 | |
101 | ADD mul1, a | |
102 | MOV a, i1 | |
103 | ADDC mul2, a | |
104 | skip1: SR mul2 | |
105 | SRC mul1 | |
106 | ;;2/8: | |
107 | SR t | |
108 | skip2: SR mul2 | |
109 | SRC mul1 | |
110 | ;;3/8: | |
111 | SR t | |
112 | T1SN f, c | |
113 | GOTO skip3 | |
114 | MOV a, i0 | |
115 | ADD mul1, a | |
116 | MOV a, i1 | |
117 | ADDC mul2, a | |
118 | skip3: SR mul2 | |
119 | SRC mul1 | |
120 | ;;4/8: | |
121 | SR t | |
122 | T1SN f, c | |
123 | GOTO skip4 | |
124 | MOV a, i0 | |
125 | ADD mul1, a | |
126 | MOV a, i1 | |
127 | ADDC mul2, a | |
128 | skip4: SR mul2 | |
129 | SRC mul1 | |
130 | ;;5/8: | |
131 | SR t | |
132 | T1SN f, c | |
133 | GOTO skip5 | |
134 | MOV a, i0 | |
135 | ADD mul1, a | |
136 | MOV a, i1 | |
137 | ADDC mul2, a | |
138 | skip5: SR mul2 | |
139 | SRC mul1 | |
140 | ;;6/8: | |
141 | SR t | |
142 | T1SN f, c | |
143 | GOTO skip6 | |
144 | MOV a, i0 | |
145 | ADD mul1, a | |
146 | skip6: | |
147 | SRC mul1 | |
148 | ;;7/8: | |
149 | SR t | |
150 | T1SN f, c | |
151 | GOTO skip7 | |
152 | MOV a, i0 | |
153 | ADD mul1, a | |
154 | skip7: | |
155 | SRC mul1 | |
156 | ;;8/8: | |
157 | SR t | |
158 | T1SN f, c | |
159 | GOTO skip8 | |
160 | MOV a, i0 | |
161 | ADD mul1, a | |
162 | skip8: | |
163 | SRC mul1 | |
164 | ||
165 | MOV a, mul1 | |
166 | RET | |
167 | ||
168 | init: | |
169 | ; AUTO_INIT_SYSCLOCK() -- 4mhz | |
170 | ; AUTO_CALIBRATE_SYSCLOCK() -- move away w/ goto | |
171 | ; ??: setup fuses (romlocation 0x3ff) | |
172 | ; setup SP (&= 0xfe) | |
173 | ; setup timer2, timer16 | |
174 | CLEAR i0 | |
175 | CLEAR i1 | |
176 | CLEAR i2 | |
177 | ||
178 | ;rom is not mmapped; must load into ram first | |
179 | MOV a, #0x84 | |
180 | MOV notes+0x0, a | |
181 | MOV notes+0x5, a | |
182 | MOV a, #0x9d | |
183 | MOV notes+0x1, a | |
184 | MOV notes+0x4, a | |
185 | MOV a, #0xb0 | |
186 | MOV notes+0x2, a | |
187 | MOV notes+0xA, a | |
188 | MOV a, #0x69 | |
189 | MOV notes+0x3, a | |
190 | MOV notes+0x6, a | |
191 | MOV notes+0xB, a | |
192 | MOV notes+0xE, a | |
193 | MOV a, #0x58 | |
194 | MOV notes+0x7, a | |
195 | MOV notes+0xF, a | |
196 | MOV a, #0x75 | |
197 | MOV notes+0x8, a | |
198 | MOV notes+0xD, a | |
199 | MOV a, #0x8c | |
200 | MOV notes+0x9, a | |
201 | MOV notes+0xC, a | |
202 | ||
203 | ;TODO: setup mcu, timer16, ... | |
204 | ;TODO: freepdk calibration routine | |
205 | ||
206 | loop: | |
207 | ;TODO: test i2==0x78 to enter halt() | |
208 | ;TODO: stopsys | |
209 | GOTO loop | |
210 | ||
211 | sample: | |
212 | ;TODO: send pwm data to timer2 | |
213 | ||
214 | MOV a, i2; "mov mem,mem" | |
215 | MOV n, a; does not exist | |
216 | SL n | |
217 | SL n | |
218 | MOV a, i1 | |
219 | SWAP a | |
220 | AND a, #0xf | |
221 | SR a | |
222 | SR a | |
223 | OR n, a | |
224 | ||
225 | MOV a, n | |
226 | CALL g | |
227 | SWAP a | |
228 | AND a, #0x1 | |
229 | MOV pwm, a | |
230 | ||
231 | MOV a, i2 | |
232 | SL a | |
233 | SL a | |
234 | SL a | |
235 | MOV tmp_1, a ; fresh tmp_1: | |
236 | MOV a, i1 | |
237 | SWAP a | |
238 | AND a, #0xf | |
239 | SR a | |
240 | OR a, tmp_1 ; tmp_1 done. | |
241 | XOR a, n | |
242 | CALL g | |
243 | SR a | |
244 | AND a, i2 | |
245 | SR a | |
246 | AND a, #3 | |
247 | ADD pwm, a | |
248 | ||
249 | MOV a, i2 | |
250 | MOV mod3hi, a | |
251 | SR mod3hi | |
252 | SR mod3hi | |
253 | SR mod3hi | |
254 | SWAP a | |
255 | AND a, #0xf0 | |
256 | SL a | |
257 | MOV mod3lo, a | |
258 | MOV a, i1 | |
259 | SR a | |
260 | SR a | |
261 | SR a | |
262 | OR mod3lo, a | |
263 | CALL mod3 | |
264 | ADD a, n | |
265 | CALL g | |
266 | SR a | |
267 | SR a | |
268 | MOV tmp_1, a ; a saved in tmp_1; fresh a | |
269 | MOV a, i2 | |
270 | ; shift-divide by six | |
271 | ; note: i2 is max 0x78; so a will <= 20. (breaks vor values >=128) | |
272 | SR a | |
273 | ADD a, i2 | |
274 | SR a | |
275 | SR a | |
276 | ADD a, i2 | |
277 | SR a | |
278 | SR a | |
279 | ADD a, i2 | |
280 | SR a | |
281 | SR a | |
282 | SR a | |
283 | ; end divide by six | |
284 | AND a, tmp_1 ; a restored from tmp_1 | |
285 | AND a, #3 | |
286 | ADD pwm, a | |
287 | ||
288 | MOV a, i2 | |
289 | MOV mod3hi, a | |
290 | SR mod3hi | |
291 | SR mod3hi | |
292 | SWAP a | |
293 | AND a, #0xf0 | |
294 | SL a | |
295 | SL a | |
296 | MOV mod3lo, a | |
297 | MOV a, i1 | |
298 | SR a | |
299 | SR a | |
300 | OR mod3lo, a | |
301 | CALL mod3 | |
302 | SUB a, n | |
303 | SUB a, #8 | |
304 | NEG a | |
305 | CALL g | |
306 | SR a | |
307 | MOV tmp_1, a ; a saved in tmp_1; fresh a | |
308 | MOV a, i2 | |
309 | ; shift-divide by ten | |
310 | ; note: i2 is max 0x78; so a will <= 12. | |
311 | INC i2 | |
312 | SR a | |
313 | ADD a, i2 | |
314 | SR a | |
315 | SR a | |
316 | SR a | |
317 | ADD a, i2 | |
318 | SR a | |
319 | ADD a, i2 | |
320 | SWAP a | |
321 | DEC i2 | |
322 | ; end divide by ten | |
323 | AND a, tmp_1 ; a restored from tmp_1 | |
324 | AND a, #3 | |
325 | ADD pwm, a | |
326 | ||
327 | MOV a, pwm | |
328 | SWAP a | |
329 | ; next sample is now ready. | |
330 | ||
331 | INC i0 | |
332 | ADDC i1 | |
333 | ADDC i2 | |
334 | ||
335 | RETI |