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