]>
Commit | Line | Data |
---|---|---|
1 | ||
2 | global add_hla,div32_16,div32_r | |
3 | global ioiniml,ioini1l | |
4 | global intinit | |
5 | global bufinit | |
6 | global cpu_frq | |
7 | ||
8 | global fifolst | |
9 | ||
10 | extrn ?pmsg | |
11 | extrn msg.sm,msg.recv,hwl2phy | |
12 | ||
13 | include config.inc | |
14 | include z180reg.inc | |
15 | ||
16 | ||
17 | ;-------------------------------------------------------------------- | |
18 | ; add a to hl | |
19 | ; | |
20 | ; return: | |
21 | ; hl = hl + a | |
22 | ; Flags undefined | |
23 | ||
24 | cseg ; (common. TODO: check for banked) | |
25 | ||
26 | add_hla: | |
27 | add a,l | |
28 | ld l,a | |
29 | ret nc | |
30 | inc h | |
31 | ret | |
32 | ||
33 | ;-------------------------------------------------------------------- | |
34 | ; rounded div 32 by 16 bit | |
35 | ; | |
36 | ; HLDE: Dividend (x) | |
37 | ; BC: Divisor (y) | |
38 | ; return: | |
39 | ; HLDE: Rounded Quotient (q) | |
40 | ; BC: Remainder (r) | |
41 | ||
42 | cseg | |
43 | ||
44 | div32_r: | |
45 | push bc | |
46 | srl b ;y/2 | |
47 | rr c | |
48 | add hl,bc ;low x + y/2 | |
49 | pop bc | |
50 | jr nc,div_r1 | |
51 | inc hl | |
52 | div_r1: | |
53 | ;fall thru | |
54 | ||
55 | ;-------------------------------------------------------------------- | |
56 | ; Divide 32 bit by 16 | |
57 | ; | |
58 | ; DEHL: Dividend (x) | |
59 | ; BC: Divisor (y) | |
60 | ; | |
61 | ; return: | |
62 | ; DEHL: Quotient | |
63 | ; BC: Reminder | |
64 | ||
65 | cseg ; common area | |
66 | div32_16: | |
67 | exx ;low | |
68 | push de ;save alternate registers (de,bc) | |
69 | push bc | |
70 | exx ;high | |
71 | push hl ;lx | |
72 | push bc ;ly | |
73 | ld bc,0 ;bc = hy = 0 | |
74 | ld h,b ;hl = hr = 0 | |
75 | ld l,c | |
76 | ;de = x, hl = r | |
77 | exx ;low | |
78 | pop bc ;bc' = ly | |
79 | ex (sp),hl ;hl' = lx, save alternate hl | |
80 | ld de,0 ;de' = lr = 0 | |
81 | ex de,hl ;de = x, hl = r | |
82 | exx ;high | |
83 | ld a,32 ;count | |
84 | ; | |
85 | ; start: | |
86 | ; de: x (de: hx, de': lx) | |
87 | ; bc: y (bc: hy, bc': ly) | |
88 | ; hl: 0 | |
89 | ; | |
90 | div_lp: ;do | |
91 | exx ; low | |
92 | ex de,hl ; x | |
93 | add hl,hl ; x <<= 1 | |
94 | exx ; high | |
95 | ex de,hl ; x | |
96 | adc hl,hl ; x <<= 1 | |
97 | exx ; low | |
98 | ex de,hl ; r | |
99 | adc hl,hl ; r <<= 1 | |
100 | exx ; high | |
101 | ex de,hl ; r | |
102 | adc hl,hl ; r <<= 1 | |
103 | exx ; low | |
104 | inc de ; x/q += 1 | |
105 | or a ; | |
106 | sbc hl,bc ; | |
107 | exx ; high | |
108 | sbc hl,bc ; | |
109 | jr nc,div_no_restore | |
110 | exx ; low | |
111 | dec de ; | |
112 | add hl,bc ; r += y | |
113 | exx ; high | |
114 | adc hl,bc ; | |
115 | ||
116 | div_no_restore: ; | |
117 | dec a ; | |
118 | jr nz,div_lp ;while (--count) | |
119 | ||
120 | ; result: | |
121 | ; de: q (de: hq, de': lq) | |
122 | ; hl: r (hl: hr, hl': lr) | |
123 | ||
124 | exx ;low | |
125 | ex de,hl ;hl = lq, de = lr | |
126 | ||
127 | ex (sp),hl ;lq | |
128 | push de ;lr | |
129 | exx ;high | |
130 | pop bc ;bc = lr | |
131 | pop hl ;de = lq | |
132 | ||
133 | exx ;low | |
134 | pop bc ;restore alternate registers | |
135 | pop de | |
136 | exx ;high | |
137 | ret | |
138 | ||
139 | ;---------------------------------------------------------------------- | |
140 | ||
141 | ; output bytes to consecutive portaddresses | |
142 | ; | |
143 | ; hl: table with following structure: | |
144 | ; db n, port1, val1, val2,... valn | |
145 | ; db m, port1, val1, val2,... valm | |
146 | ; ... | |
147 | ; db 0 ; Terminate table | |
148 | ||
149 | ||
150 | cseg ; (common for now) | |
151 | ||
152 | ioiniml: | |
153 | push bc | |
154 | xor a | |
155 | ioml_lp: | |
156 | ld b,(hl) | |
157 | inc hl | |
158 | cp b | |
159 | jr z,ioml_e | |
160 | ||
161 | ld c,(hl) | |
162 | inc hl | |
163 | otimr | |
164 | jr ioml_lp | |
165 | ioml_e: | |
166 | pop bc | |
167 | ret | |
168 | ||
169 | ;---------------------------------------------------------------------- | |
170 | ||
171 | ; output bytes to ports | |
172 | ; | |
173 | ; hl: tables of port,value pairs: | |
174 | ; db n, port1,val1, port2,val2,... portn,valn | |
175 | ; ... | |
176 | ; db 0 ; Terminate table | |
177 | ||
178 | cseg ; (common for now) | |
179 | ||
180 | ioini1l: | |
181 | push bc | |
182 | jr io1_nxt | |
183 | io1_lp: | |
184 | ld c,(hl) ;port address | |
185 | inc hl | |
186 | otim | |
187 | jr nz,io1_lp | |
188 | io1_nxt: | |
189 | ld b,(hl) ;count | |
190 | inc hl | |
191 | inc b | |
192 | djnz io1_lp | |
193 | ||
194 | pop bc | |
195 | ret | |
196 | ||
197 | ;---------------------------------------------------------------------- | |
198 | ||
199 | dseg | |
200 | ||
201 | intinit: | |
202 | ld hl,ivtab ; | |
203 | ld a,h ; | |
204 | ld i,a ; | |
205 | out0 (il),l ; | |
206 | im 2 | |
207 | ||
208 | ; Let all vectors point to spurious int routines. | |
209 | ||
210 | ld de,sp.int0 | |
211 | ld bc,sp.int.len | |
212 | ld a,9 | |
213 | ivt_i1: | |
214 | ld (hl),e | |
215 | inc l | |
216 | ld (hl),d | |
217 | inc l | |
218 | ex de,hl | |
219 | add hl,bc | |
220 | ex de,hl | |
221 | dec a | |
222 | jr nz,ivt_i1 | |
223 | ret | |
224 | ||
225 | ||
226 | ;-------------------------------------------------------------------- | |
227 | ; Spurious interrupt handler | |
228 | ||
229 | cseg ; common area | |
230 | sp.int0: | |
231 | ld a,00h | |
232 | jr sp.i.1 | |
233 | sp.int.len equ $-sp.int0 | |
234 | ld a,01h | |
235 | jr sp.i.1 | |
236 | ld a,02h | |
237 | jr sp.i.1 | |
238 | ld a,03h | |
239 | jr sp.i.1 | |
240 | ld a,04h | |
241 | jr sp.i.1 | |
242 | ld a,05h | |
243 | jr sp.i.1 | |
244 | ld a,06h | |
245 | jr sp.i.1 | |
246 | ld a,07h | |
247 | jr sp.i.1 | |
248 | ld a,08h | |
249 | sp.i.1: | |
250 | ; out (80h),a | |
251 | ||
252 | add a,'0' | |
253 | ld (spi$nr),a | |
254 | ld hl,spi$msg | |
255 | call ?pmsg | |
256 | sp.i.2: | |
257 | halt | |
258 | jr sp.i.2 | |
259 | ||
260 | spi$msg: | |
261 | db 13,10,'Spurious Int: ' | |
262 | spi$nr: db '0' | |
263 | db 0 | |
264 | ||
265 | ;-------------------------------------------------------------------- | |
266 | ; | |
267 | ; Get/compute CPU clock | |
268 | ; | |
269 | ; return: | |
270 | ; hlde: CPU frequency (Hz) | |
271 | ; | |
272 | ||
273 | dseg | |
274 | ||
275 | cpu_frq: | |
276 | ld hl,0 | |
277 | ld d,h | |
278 | ld e,l | |
279 | call get_timer | |
280 | push de | |
281 | push hl | |
282 | ||
283 | ; delay ~8ms @ 18.432MHz --> 147456 clock cycles | |
284 | ; delay ~10ms @ 18.432MHz --> 184320 clock cycles | |
285 | ; | |
286 | ||
287 | ; ld hl,8192 ; 147456/18 | |
288 | ld hl,10240 ; 184320/18 | |
289 | ld de,1 | |
290 | or a | |
291 | dly_lp: | |
292 | sbc hl,de ; 10 | |
293 | jr nz,dly_lp ; 6/8 -> 18 | |
294 | ||
295 | pop hl | |
296 | pop de | |
297 | call get_timer | |
298 | ||
299 | ld bc,10 | |
300 | call div32_r | |
301 | ld b,h | |
302 | ld c,l | |
303 | ld de,00119h ;18432000/(2**16) | |
304 | ld hl,04000h ;18432000%(2**16) | |
305 | ||
306 | ld a,b | |
307 | or a | |
308 | jr nz,cpuf_div | |
309 | ld a,c | |
310 | cp 2 | |
311 | jr c,cpuf_done | |
312 | cpuf_div: | |
313 | call div32_r | |
314 | cpuf_done: | |
315 | ret | |
316 | ||
317 | ;-------------------------------------------------------------------- | |
318 | ||
319 | get_timer: | |
320 | push de | |
321 | push hl | |
322 | ld hl,1*256 + 3 ; d = subcommand, e = command | |
323 | push hl | |
324 | ld hl,0 | |
325 | add hl,sp | |
326 | ld b,6 | |
327 | call msg.sm | |
328 | ||
329 | dec sp | |
330 | ld hl,0 | |
331 | add hl,sp | |
332 | ld b,7 ; max receive message len | |
333 | call msg.recv | |
334 | ||
335 | pop bc | |
336 | inc sp | |
337 | pop hl | |
338 | pop de | |
339 | ret | |
340 | ||
341 | ;-------------------------------------------------------------------- | |
342 | ||
343 | cseg | |
344 | ||
345 | fifolst: | |
346 | rept 4 | |
347 | dw 0 | |
348 | db 0 | |
349 | endm | |
350 | ||
351 | ;-------------------------------------------------------------------- | |
352 | ||
353 | dseg | |
354 | ||
355 | bufinit: | |
356 | ld c,a | |
357 | ld a,(ix+o.id) | |
358 | cp 4 | |
359 | jr nc,bfi_doit2 | |
360 | ||
361 | ld hl,fifolst | |
362 | ld e,a | |
363 | ld d,0 | |
364 | add hl,de | |
365 | add hl,de | |
366 | add hl,de | |
367 | ||
368 | if 0 | |
369 | ld e,(hl) | |
370 | inc hl | |
371 | ld d,(hl) | |
372 | dec hl | |
373 | ld a,e | |
374 | or d | |
375 | jr z,bfi_doit | |
376 | ||
377 | ; TODO: address translation | |
378 | push de | |
379 | pop ix | |
380 | ret | |
381 | endif | |
382 | ||
383 | bfi_doit: | |
384 | push ix | |
385 | pop de | |
386 | ; TODO: address translation | |
387 | ld (hl),e | |
388 | inc hl | |
389 | ld (hl),d | |
390 | ld a,(ix+o.id) | |
391 | or a | |
392 | jr nz,bfi_doit2 | |
393 | ||
394 | ld hl,fifolst | |
395 | ld (040h),hl | |
396 | ld (040h+2),a | |
397 | ||
398 | bfi_doit2: | |
399 | ld (ix+o.in_idx),0 ;reset pointers | |
400 | ld (ix+o.out_idx),0 | |
401 | ld (ix+o.mask),c ;reset "size" | |
402 | ||
403 | push ix ;get phys. address of fifo | |
404 | pop hl | |
405 | call hwl2phy | |
406 | ex de,hl | |
407 | ld c,a | |
408 | ld a,(ix+o.id) ;fifo id | |
409 | or a ;test if fifo 0 | |
410 | jr nz,bfi_1 | |
411 | ||
412 | out (AVRINT5),a | |
413 | ret | |
414 | ||
415 | bfi_1: | |
416 | ld hl,bfi_msg_end | |
417 | ld (hl),c | |
418 | dec hl | |
419 | ld (hl),d | |
420 | dec hl | |
421 | ld (hl),e | |
422 | dec hl | |
423 | ld (hl),a | |
424 | dec hl | |
425 | ld b,bfi_msg_len | |
426 | call msg.sm | |
427 | ret | |
428 | ||
429 | bfi_msg: | |
430 | db 0 ;function: 0 | |
431 | db 0 ;subfunc: gets overwritten with buf id | |
432 | dw 0 ;physical | |
433 | db 0 ; address | |
434 | bfi_msg_len equ $ - bfi_msg | |
435 | bfi_msg_end equ $ - 1 | |
436 | ||
437 | ;---------------------------------------------------------------------- | |
438 | ||
439 | ||
440 | end |