add cycle count and some comments
[Chiptunes-pms150c.git] / bsv.S
CommitLineData
ec2152ea
TG
1;.area DATA
2.area OSEG (OVR,DATA)
3;.area DATA
4notes: .ds 16 ; 0x00 .. 0x0f
5i0: .ds 1 ; 0x10
6i1: .ds 1 ; 0x11
7i2: .ds 1 ; 0x12
8n: .ds 1 ; 0x13
9.even ; make next two bytes word-aligned
10zero: .ds 1 ; 0x14
11tmp_1: .ds 1 ; 0x15
12tmp_hi: .ds 1 ; 0x16
13tmp_lo: .ds 1 ; 0x17
14pwm: .ds 1 ; 0x18
15.area SSEG
c8495413 16.even ; SP must be aligned? (sdcc does it)
ec2152ea
TG
17stack: .ds 1
18
19; aliases for memory locations:
20notes_ix = tmp_1
21t = tmp_1
22mul2 = tmp_hi
23mul1 = tmp_lo
24mod3hi = tmp_hi
25mod3lo = tmp_lo
26
c8495413
TG
27; cycle count (worst-case)
28; mod3: 28
29; g: 81
30; sample: 115 + 4*g + 2*mod3 = 495
ec2152ea
TG
31
32
33.area CSEG (CODE,ABS)
34;.area HOME
35;.area HEADER (ABS)
36.org 0x0000
c8495413 37 ;TODO: 0x0000 must be NOP for autocalib routine
ec2152ea
TG
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
48mod3:
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
81g:
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
168init:
c8495413
TG
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
ec2152ea
TG
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
206loop:
207 ;TODO: test i2==0x78 to enter halt()
208 ;TODO: stopsys
209 GOTO loop
210
211sample:
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
Imprint / Impressum