-
- global add_hla,div32_16,div32_r
- global ioiniml,ioini1l
- global intinit
- global bufinit
- global cpu_frq
-
- global fifolst
-
- extrn ?pmsg
- extrn msg.sm,msg.recv,hwl2phy
-
- include config.inc
- include z180reg.inc
-
-
-;--------------------------------------------------------------------
-; add a to hl
-;
-; return:
-; hl = hl + a
-; Flags undefined
-
- cseg ; (common. TODO: check for banked)
-
-add_hla:
- add a,l
- ld l,a
- ret nc
- inc h
- ret
-
-;--------------------------------------------------------------------
-; rounded div 32 by 16 bit
-;
-; HLDE: Dividend (x)
-; BC: Divisor (y)
-; return:
-; HLDE: Rounded Quotient (q)
-; BC: Remainder (r)
-
- cseg
-
-div32_r:
- push bc
- srl b ;y/2
- rr c
- add hl,bc ;low x + y/2
- pop bc
- jr nc,div_r1
- inc hl
-div_r1:
- ;fall thru
-
-;--------------------------------------------------------------------
-; Divide 32 bit by 16
-;
-; DEHL: Dividend (x)
-; BC: Divisor (y)
-;
-; return:
-; DEHL: Quotient
-; BC: Reminder
-
- cseg ; common area
-div32_16:
- exx ;low
- push de ;save alternate registers (de,bc)
- push bc
- exx ;high
- push hl ;lx
- push bc ;ly
- ld bc,0 ;bc = hy = 0
- ld h,b ;hl = hr = 0
- ld l,c
- ;de = x, hl = r
- exx ;low
- pop bc ;bc' = ly
- ex (sp),hl ;hl' = lx, save alternate hl
- ld de,0 ;de' = lr = 0
- ex de,hl ;de = x, hl = r
- exx ;high
- ld a,32 ;count
-;
-; start:
-; de: x (de: hx, de': lx)
-; bc: y (bc: hy, bc': ly)
-; hl: 0
-;
-div_lp: ;do
- exx ; low
- ex de,hl ; x
- add hl,hl ; x <<= 1
- exx ; high
- ex de,hl ; x
- adc hl,hl ; x <<= 1
- exx ; low
- ex de,hl ; r
- adc hl,hl ; r <<= 1
- exx ; high
- ex de,hl ; r
- adc hl,hl ; r <<= 1
- exx ; low
- inc de ; x/q += 1
- or a ;
- sbc hl,bc ;
- exx ; high
- sbc hl,bc ;
- jr nc,div_no_restore
- exx ; low
- dec de ;
- add hl,bc ; r += y
- exx ; high
- adc hl,bc ;
-
-div_no_restore: ;
- dec a ;
- jr nz,div_lp ;while (--count)
-
-; result:
-; de: q (de: hq, de': lq)
-; hl: r (hl: hr, hl': lr)
-
- exx ;low
- ex de,hl ;hl = lq, de = lr
-
- ex (sp),hl ;lq
- push de ;lr
- exx ;high
- pop bc ;bc = lr
- pop hl ;de = lq
-
- exx ;low
- pop bc ;restore alternate registers
- pop de
- exx ;high
- ret
-
-;----------------------------------------------------------------------
-
- ; output bytes to consecutive portaddresses
- ;
- ; hl: table with following structure:
- ; db n, port1, val1, val2,... valn
- ; db m, port1, val1, val2,... valm
- ; ...
- ; db 0 ; Terminate table
-
-
- cseg ; (common for now)
-
-ioiniml:
- push bc
- xor a
-ioml_lp:
- ld b,(hl)
- inc hl
- cp b
- jr z,ioml_e
-
- ld c,(hl)
- inc hl
- otimr
- jr ioml_lp
-ioml_e:
- pop bc
- ret
-
-;----------------------------------------------------------------------
-
- ; output bytes to ports
- ;
- ; hl: tables of port,value pairs:
- ; db n, port1,val1, port2,val2,... portn,valn
- ; ...
- ; db 0 ; Terminate table
-
- cseg ; (common for now)
-
-ioini1l:
- push bc
- jr io1_nxt
-io1_lp:
- ld c,(hl) ;port address
- inc hl
- otim
- jr nz,io1_lp
-io1_nxt:
- ld b,(hl) ;count
- inc hl
- inc b
- djnz io1_lp
-
- pop bc
- ret
-
-;----------------------------------------------------------------------
-
- dseg
-
-intinit:
- ld hl,ivtab ;
- ld a,h ;
- ld i,a ;
- out0 (il),l ;
- im 2
-
-; Let all vectors point to spurious int routines.
-
- ld de,sp.int0
- ld bc,sp.int.len
- ld a,9
-ivt_i1:
- ld (hl),e
- inc l
- ld (hl),d
- inc l
- ex de,hl
- add hl,bc
- ex de,hl
- dec a
- jr nz,ivt_i1
- ret
-
-
-;--------------------------------------------------------------------
-; Spurious interrupt handler
-
- cseg ; common area
-sp.int0:
- ld a,00h
- jr sp.i.1
-sp.int.len equ $-sp.int0
- ld a,01h
- jr sp.i.1
- ld a,02h
- jr sp.i.1
- ld a,03h
- jr sp.i.1
- ld a,04h
- jr sp.i.1
- ld a,05h
- jr sp.i.1
- ld a,06h
- jr sp.i.1
- ld a,07h
- jr sp.i.1
- ld a,08h
-sp.i.1:
-; out (80h),a
-
- add a,'0'
- ld (spi$nr),a
- ld hl,spi$msg
- call ?pmsg
-sp.i.2:
- halt
- jr sp.i.2
-
-spi$msg:
- db 13,10,'Spurious Int: '
-spi$nr: db '0'
- db 0
-
-;--------------------------------------------------------------------
-;
-; Get/compute CPU clock
-;
-; return:
-; hlde: CPU frequency (Hz)
-;
-
- dseg
-
-cpu_frq:
- ld hl,0
- ld d,h
- ld e,l
- call get_timer
- push de
- push hl
-
-; delay ~8ms @ 18.432MHz --> 147456 clock cycles
-; delay ~10ms @ 18.432MHz --> 184320 clock cycles
-;
-
-; ld hl,8192 ; 147456/18
- ld hl,10240 ; 184320/18
- ld de,1
- or a
-dly_lp:
- sbc hl,de ; 10
- jr nz,dly_lp ; 6/8 -> 18
-
- pop hl
- pop de
- call get_timer
-
- ld bc,10
- call div32_r
- ld b,h
- ld c,l
- ld de,00119h ;18432000/(2**16)
- ld hl,04000h ;18432000%(2**16)
-
- ld a,b
- or a
- jr nz,cpuf_div
- ld a,c
- cp 2
- jr c,cpuf_done
-cpuf_div:
- call div32_r
-cpuf_done:
- ret
-
-;--------------------------------------------------------------------
-
-get_timer:
- push de
- push hl
- ld hl,1*256 + 3 ; d = subcommand, e = command
- push hl
- ld hl,0
- add hl,sp
- ld b,6
- call msg.sm
-
- dec sp
- ld hl,0
- add hl,sp
- ld b,7 ; max receive message len
- call msg.recv
-
- pop bc
- inc sp
- pop hl
- pop de
- ret
-
-;--------------------------------------------------------------------
-
- cseg
-
-fifolst:
- rept 4
- dw 0
- db 0
- endm
-
-;--------------------------------------------------------------------
-
- dseg
-
-bufinit:
- ld c,a
- ld a,(ix+o.id)
- cp 4
- jr nc,bfi_doit2
-
- ld hl,fifolst
- ld e,a
- ld d,0
- add hl,de
- add hl,de
- add hl,de
-
- if 0
- ld e,(hl)
- inc hl
- ld d,(hl)
- dec hl
- ld a,e
- or d
- jr z,bfi_doit
-
-; TODO: address translation
- push de
- pop ix
- ret
- endif
-
-bfi_doit:
- push ix
- pop de
-; TODO: address translation
- ld (hl),e
- inc hl
- ld (hl),d
- ld a,(ix+o.id)
- or a
- jr nz,bfi_doit2
-
- ld hl,fifolst
- ld (040h),hl
- ld (040h+2),a
-
-bfi_doit2:
- ld (ix+o.in_idx),0 ;reset pointers
- ld (ix+o.out_idx),0
- ld (ix+o.mask),c ;reset "size"
-
- push ix ;get phys. address of fifo
- pop hl
- call hwl2phy
- ex de,hl
- ld c,a
- ld a,(ix+o.id) ;fifo id
- or a ;test if fifo 0
- jr nz,bfi_1
-
- out (AVRINT5),a
- ret
-
-bfi_1:
- ld hl,bfi_msg_end
- ld (hl),c
- dec hl
- ld (hl),d
- dec hl
- ld (hl),e
- dec hl
- ld (hl),a
- dec hl
- ld b,bfi_msg_len
- call msg.sm
- ret
-
-bfi_msg:
- db 0 ;function: 0
- db 0 ;subfunc: gets overwritten with buf id
- dw 0 ;physical
- db 0 ; address
-bfi_msg_len equ $ - bfi_msg
-bfi_msg_end equ $ - 1
-
-;----------------------------------------------------------------------
-
-
- end
+\r
+ public intinit\r
+ public cpu_frq\r
+ public get_tmr\r
+\r
+ extrn div32_r,pr.inln\r
+ extrn msg.sm,msg.recv,hwl2phy\r
+\r
+ maclib z180reg.inc\r
+ maclib config.inc\r
+\r
+\r
+;----------------------------------------------------------------------\r
+\r
+ dseg\r
+\r
+intinit:\r
+ ld hl,ivtab ;\r
+ ld a,h ;\r
+ ld i,a ;\r
+ out0 (il),l ;\r
+ im 2\r
+\r
+; Let all vectors point to spurious int routines.\r
+\r
+ ld de,sp.int0\r
+ ld bc,sp.int.len\r
+ ld a,9\r
+ivt_i1:\r
+ ld (hl),e\r
+ inc l\r
+ ld (hl),d\r
+ inc l\r
+ ex de,hl\r
+ add hl,bc\r
+ ex de,hl\r
+ dec a\r
+ jr nz,ivt_i1\r
+ ret\r
+\r
+\r
+;--------------------------------------------------------------------\r
+; Spurious interrupt handler\r
+\r
+ cseg ; common area\r
+sp.int0:\r
+ ld a,00h\r
+ jr sp.i.1\r
+sp.int.len equ $-sp.int0\r
+ ld a,01h\r
+ jr sp.i.1\r
+ ld a,02h\r
+ jr sp.i.1\r
+ ld a,03h\r
+ jr sp.i.1\r
+ ld a,04h\r
+ jr sp.i.1\r
+ ld a,05h\r
+ jr sp.i.1\r
+ ld a,06h\r
+ jr sp.i.1\r
+ ld a,07h\r
+ jr sp.i.1\r
+ ld a,08h\r
+sp.i.1:\r
+; out (80h),a\r
+\r
+ add a,'0'\r
+ ld (spi$nr),a\r
+ call pr.inln\r
+ db 13,10,'Spurious Int: '\r
+spi$nr: db '0'\r
+ db 0\r
+sp.i.2:\r
+ halt\r
+ jr sp.i.2\r
+\r
+;--------------------------------------------------------------------\r
+;\r
+; Get/compute CPU clock\r
+;\r
+; return:\r
+; hlde: CPU frequency (Hz)\r
+;\r
+\r
+ dseg\r
+\r
+cpu_frq:\r
+ ld hl,0\r
+ ld d,h\r
+ ld e,l\r
+ call get_tmr\r
+ push de\r
+ push hl\r
+\r
+; delay ~8ms @ 18.432MHz --> 147456 clock cycles\r
+; delay ~10ms @ 18.432MHz --> 184320 clock cycles\r
+;\r
+\r
+; ld hl,8192 ; 147456/18\r
+ ld hl,(10240-100)*5 ; 184320/18\r
+ ld de,1\r
+ or a\r
+dly_lp:\r
+ sbc hl,de ; 10\r
+ jr nz,dly_lp ; 6/8 -> 18 cycles\r
+\r
+ pop hl\r
+ pop de\r
+ call get_tmr\r
+\r
+ ld b,h\r
+ ld c,l\r
+ ld de,036EEh ;18432000/(2**16) * 50\r
+ ld hl,08000h ;18432000%(2**16) * 50\r
+\r
+ ld a,b\r
+ or a\r
+ jr nz,cpuf_div\r
+ ld a,c\r
+ cp 2\r
+ jr c,cpuf_done\r
+cpuf_div:\r
+ call div32_r\r
+cpuf_done:\r
+ ret\r
+\r
+;--------------------------------------------------------------------\r
+\r
+ dseg\r
+get_tmr:\r
+ push de\r
+ push hl\r
+ ld hl,1*256 + 3 ; h = subcommand, l = command\r
+ push hl\r
+ ld hl,0\r
+ add hl,sp\r
+ ld b,6\r
+ call msg.sm\r
+\r
+ dec sp\r
+ ld hl,0\r
+ add hl,sp\r
+ ld b,7 ; max receive message len\r
+ call msg.recv\r
+\r
+ pop bc\r
+ inc sp\r
+ pop hl\r
+ pop de\r
+ ret\r
+\r
+;----------------------------------------------------------------------\r
+\r
+ end\r