]> cloudbase.mooo.com Git - z180-stamp-cpm3.git/blob - cbios/misc.180
divde and round
[z180-stamp-cpm3.git] / cbios / misc.180
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