SRC := bioskrnl.180 boot.180 chario.180 drvtbl.180
-SRC += move.180 time.180 mm.180 misc.180 utils.180
-SRC += msgbuf.180 conbuf.180 ascip.180 sdio.180 cfio.180
+SRC += move.180 time.180 mm.180 misc.180 utils.180 fifo.180
+SRC += msgbuf.180 conbuf.180 ascii.180 asci-cmn.180
+SRC += sdio.180 cfio.180
SRC += scb.180
ALLSRC := $(SRC) ldrbios.180
--- /dev/null
+
+ public as_init
+
+ extrn ioiniml
+ extrn f_cpu,add_hla,div32_r
+ extrn @ctbl
+
+ include config.inc
+ include z180reg.inc
+
+
+;--------------------------------------------------------------
+; TC = (f PHI /(2*baudrate*Clock_mode)) - 2
+;
+; Clock_mode == 16
+; TC = (f PHI / (32 * baudrate)) - 2
+;
+; br150 = baudrate/150
+; TC = (f PHI / (32 * 150 * br150)) - 2
+; TC = (f PHI / (32 * 150 * br150)) - 2
+
+
+;--------------------------------------------------------------
+; Init Serial I/O for console input and output (ASCI1)
+;
+; b: device number (0..15)
+; c: asci channel number (0/1)
+
+ dseg
+as_init:
+ ld hl,initab0
+ dec c
+ jr nz,$+5
+ ld hl,initab1
+
+ push hl
+ ld c,8 ;
+ mlt bc ;
+ ld hl,@ctbl+7 ;get baudrate index
+ add hl,bc ;
+ ld a,(hl)
+ and 0fh
+ add a,a ;get factor
+ ld hl,bd150_tab
+ call add_hla
+ ld c,(hl)
+ inc hl
+ ld b,(hl)
+ ld hl,(f_cpu)
+ ld de,(f_cpu+2)
+ call div32_r
+ ld bc,32*150
+ call div32_r
+ ld de,2
+ or a
+ sbc hl,de
+ jr nc,as_ini_1
+ ld hl,0
+as_ini_1:
+ ld b,h
+ ld c,l
+ pop de
+ ld hl,init_br_off
+ add hl,de
+ ld (hl),c
+ inc hl
+ ld (hl),b
+ ex de,hl
+ jp ioiniml
+
+
+bd150_tab:
+; factor index baudrate orig. cp/m
+ dw 19200/150 ; 0 19200 -
+ dw 28800/150 ; 1 28800 50
+ dw 38400/150 ; 2 38400 75
+ dw 57600/150 ; 3 57600 110
+ dw 11520/15 ; 4 115200 134.5
+ dw 150/150 ; 5 150
+ dw 300/150 ; 6 300
+ dw 600/150 ; 7 600
+ dw 1200/150 ; 8 1200
+ dw 1800/150 ; 9 1800
+ dw 2400/150 ;10 2400
+ dw 3600/150 ;11 3600
+ dw 4800/150 ;12 4800
+ dw 7200/150 ;13 7200
+ dw 9600/150 ;14 9600
+ dw 19200/150 ;15 19200
+
+
+
+
+initab0:
+ db 1,stat0,0 ;Disable rx/tx interrupts
+ ;Enable baud rate generator
+ db 1,asext0,M_BRGMOD+M_DCD0DIS+M_CTS0DIS
+ db 2,astc0l
+init_br_off equ $ - initab0
+ dw 28
+ db 1,cntlb0,M_MPBT ;No MP Mode, X16
+ db 1,cntla0,M_RE+M_TE+M_MOD2 ;Rx/Tx enable, 8N1
+ db 0
+
+initab1:
+ db 1,stat1,0 ;Disable rx/tx ints, disable CTS1
+ db 1,asext1,M_BRGMOD ;Enable baud rate generator
+ db 2,astc1l,low 3, high 3
+ db 1,cntlb1,M_MPBT ;No MP Mode, X16
+ db 1,cntla1,M_RE+M_TE+M_MOD2 ;Rx/Tx enable, 8N1
+ db 0
+
+ end
--- /dev/null
+ page 200\r
+\r
+; Interrupt drivers for ASCI0 and ASCI1\r
+\r
+ global as0init\r
+ global as0ista,as0inp\r
+ global as0osta,as0out\r
+ global as1init\r
+ global as1ista,as1inp\r
+ global as1osta,as1out\r
+\r
+ extrn as_init\r
+ extrn ff_empty,ff_get,ff_full,ff_put\r
+ extrn bufinit\r
+ extrn isv_sw\r
+\r
+\r
+\r
+ include config.inc\r
+ include z180reg.inc\r
+\r
+\r
+\r
+;-----------------------------------------------------\r
+\r
+ dseg\r
+\r
+ mkbuf s0.rx_id, s0.inbuf, s0.rx_len\r
+ mkbuf s0.tx_id, s0.outbuf,s0.tx_len\r
+ mkbuf s1.rx_id, s1.inbuf, s1.rx_len\r
+ mkbuf s1.tx_id, s1.outbuf, s1.tx_len\r
+\r
+\r
+\r
+ dseg\r
+\r
+;--------------------------------------------------------------\r
+; Init Serial I/O for input and output (ASCI 0/1)\r
+;\r
+; b: device number\r
+;\r
+\r
+\r
+;ser.init:\r
+; ld a,i\r
+; push af ;save IFF\r
+; di\r
+;---\r
+; pop af\r
+; ret po\r
+; ei\r
+; ret ;\r
+\r
+as0init:\r
+ xor a ;\r
+ out0 (stat0),a ;Disable rx/tx interrupts\r
+ ld c,0 ;asci channel number\r
+ call as_init\r
+ ld hl,rtxisvjmp0 ;rx/tx int vector\r
+ ld (ivtab + IV$ASCI0),hl ;\r
+\r
+ ld ix,s0.inbuf\r
+ call bufinit\r
+ ld ix,s0.outbuf\r
+ call bufinit\r
+ ld a,M_RIE\r
+ out0 (stat0),a ;Enable rx interrupts\r
+ ret\r
+\r
+as1init:\r
+ xor a ;\r
+ out0 (stat1),a ;Disable rx/tx interrupts\r
+ ld c,1 ;asci channel number\r
+ call as_init\r
+\r
+ ld hl,rtxisvjmp1 ;rx/tx int vector\r
+ ld (ivtab + IV$ASCI1),hl ;\r
+\r
+ push ix\r
+ ld ix,s1.inbuf\r
+ call bufinit\r
+ ld ix,s1.outbuf\r
+ call bufinit\r
+ pop ix\r
+ ld a,M_RIE\r
+ out0 (stat1),a ;Enable rx interrupts\r
+ ret\r
+\r
+\r
+ cseg\r
+rtxisvjmp0:\r
+ call isv_sw\r
+ dw rxtxi0\r
+rtxisvjmp1:\r
+ call isv_sw\r
+ dw rxtxi1\r
+\r
+;--------------------------------------------------------------\r
+\r
+ dseg\r
+as0ista:\r
+ push ix\r
+ ld ix,s0.inbuf ;\r
+ call ff_empty\r
+ pop ix\r
+ ret\r
+\r
+;--------------------------------------------------------------\r
+\r
+as1ista:\r
+ push ix\r
+ ld ix,s1.inbuf ;\r
+ call ff_empty\r
+ pop ix\r
+ ret\r
+\r
+;--------------------------------------------------------------\r
+; Get an input character\r
+\r
+as0inp:\r
+ push ix\r
+ ld ix,s0.inbuf ;\r
+ call ff_get\r
+ pop ix\r
+ ret\r
+\r
+;--------------------------------------------------------------\r
+; Get an input character\r
+\r
+as1inp:\r
+ push ix\r
+ ld ix,s1.inbuf ;\r
+ call ff_get\r
+ pop ix\r
+ ret\r
+\r
+;--------------------------------------------------------------\r
+; Output status\r
+\r
+as0osta:\r
+ push ix\r
+ ld ix,s0.outbuf ;\r
+ call ff_full\r
+ pop ix\r
+ ret\r
+\r
+;--------------------------------------------------------------\r
+; Output status\r
+\r
+as1osta:\r
+ push ix\r
+ ld ix,s1.outbuf ;\r
+ call ff_full\r
+ pop ix\r
+ ret\r
+\r
+;--------------------------------------------------------------\r
+; put character in c in buffer\r
+; destroys hl, bc\r
+; returns output char in a\r
+\r
+as0out:\r
+ push ix ;\r
+ ld ix,s0.outbuf ;\r
+ call ff_put\r
+ di ;\r
+ in0 c,(stat0) ;\r
+ set TIE,c ;\r
+ out0 (stat0),c ;\r
+ ei ;\r
+ pop ix ;\r
+ ret\r
+\r
+;--------------------------------------------------------------\r
+; put character in c in buffer\r
+; destroys hl, bc\r
+; returns output char in a\r
+\r
+as1out:\r
+ push ix ;\r
+ ld ix,s1.outbuf ;\r
+ call ff_put\r
+ di ;\r
+ in0 c,(stat1) ;\r
+ set TIE,c ;\r
+ out0 (stat1),c ;\r
+ ei ;\r
+ pop ix ;\r
+ ret\r
+\r
+\r
+;------------------------------------------\r
+; ASCI 1 Transmit/Receive interupt routines\r
+\r
+ dseg\r
+rxtxi0:\r
+ in0 e,(stat0) ;receive flag set? 5\r
+ jp p,txisv0 ;\r
+\r
+ in0 d,(rdr0) ;todo: break detection 9\r
+ bit FE,e ;framing error?\r
+ jr nz,?0ri_1\r
+\r
+ push ix\r
+ ld ix,s0.inbuf ;\r
+ ld hl,s0.inbuf ;\r
+ ld c,(ix+o.in_idx) ;\r
+ ld b,0\r
+ add hl,bc\r
+ ld (hl),d\r
+\r
+ ld a,c ;\r
+ inc a\r
+ and (ix+o.mask)\r
+ cp (ix+o.out_idx) ;\r
+ jr z,$+5 ;skip if buffer is full\r
+ ld (ix+o.in_idx),a\r
+ pop ix\r
+?0ri_1:\r
+ in0 a,(cntla0) ; 1\r
+ res EFR,a ;\r
+ out0 (cntla0),a ; 1\r
+ ret\r
+\r
+txisv0:\r
+ push ix\r
+ ld ix,s0.outbuf ;\r
+\r
+ ld a,(ix+o.out_idx) ;\r
+ cp (ix+o.in_idx) ;if index.in == index.out\r
+ jr z,?0ti_2 ; buffer empty\r
+\r
+ ld hl,s0.outbuf ;\r
+ ld c,a\r
+ ld b,0\r
+ add hl,bc\r
+ ld l,(hl)\r
+ out0 (tdr0),l ; 7\r
+\r
+ inc a\r
+ and (ix+o.mask)\r
+ ld (ix+o.out_idx),a\r
+ jr ?0ti_3\r
+?0ti_2:\r
+ res TIE,e ;disable tx-int\r
+ out0 (stat0),e ; 5\r
+?0ti_3:\r
+ pop ix\r
+ ret\r
+\r
+;------------------------------------------\r
+; ASCI 1 Transmit/Receive interupt routines\r
+\r
+ dseg\r
+rxtxi1:\r
+ in0 e,(stat1) ;receive flag set? 5\r
+ jp p,txisv1 ;\r
+\r
+ in0 d,(rdr1) ;todo: break detection 9\r
+ bit FE,e ;framing error?\r
+ jr nz,??ri_1\r
+\r
+ push ix\r
+ ld ix,s1.inbuf ;\r
+ ld hl,s1.inbuf ;\r
+ ld c,(ix+o.in_idx) ;\r
+ ld b,0\r
+ add hl,bc\r
+ ld (hl),d\r
+\r
+ ld a,c ;\r
+ inc a\r
+ and (ix+o.mask)\r
+ cp (ix+o.out_idx) ;\r
+ jr z,$+5 ;skip if buffer is full\r
+ ld (ix+o.in_idx),a\r
+ pop ix\r
+??ri_1:\r
+ in0 a,(cntla1) ; 1\r
+ res EFR,a ;\r
+ out0 (cntla1),a ; 1\r
+ ret\r
+\r
+txisv1:\r
+ push ix\r
+ ld ix,s1.outbuf ;\r
+\r
+ ld a,(ix+o.out_idx) ;\r
+ cp (ix+o.in_idx) ;if index.in == index.out\r
+ jr z,??ti_2 ; buffer empty\r
+\r
+ ld hl,s1.outbuf ;\r
+ ld c,a\r
+ ld b,0\r
+ add hl,bc\r
+ ld l,(hl)\r
+ out0 (tdr1),l ; 7\r
+\r
+ inc a\r
+ and (ix+o.mask)\r
+ ld (ix+o.out_idx),a\r
+ jr ??ti_3\r
+??ti_2:\r
+ res TIE,e ;disable tx-int\r
+ out0 (stat1),e ; 5\r
+??ti_3:\r
+ pop ix\r
+ ret\r
+\r
+\r
+\r
+ end\r
\r
; Simple polling drivers for ASCI0 and ASCI1\r
\r
- extrn ioiniml\r
\r
global as0init\r
global as0ista,as0inp\r
global as1ista,as1inp\r
global as1osta,as1out\r
\r
+ extrn as_init\r
\r
- extrn f_cpu,add_hla,div32_r\r
- extrn @ctbl\r
\r
include config.inc\r
include z180reg.inc\r
\r
+ dseg\r
\r
;--------------------------------------------------------------\r
-; TC = (f PHI /(2*baudrate*Clock_mode)) - 2\r
+; Init Serial I/O for input and output (ASCI 0/1)\r
;\r
-; Clock_mode == 16\r
-; TC = (f PHI / (32 * baudrate)) - 2\r
+; b: device number\r
;\r
-; br150 = baudrate/150\r
-; TC = (f PHI / (32 * 150 * br150)) - 2\r
-; TC = (f PHI / (32 * 150 * br150)) - 2\r
\r
\r
-;\r
-; Init Serial I/O for console input and output (ASCI1)\r
-;\r
-\r
- dseg\r
-\r
as0init:\r
- ld hl,initab0\r
- jr as_init\r
+ ld c,0 ;asci channel number\r
+ jp as_init\r
+\r
as1init:\r
- ld hl,initab1\r
-as_init:\r
- push hl\r
-\r
- ld c,8 ;\r
- mlt bc ;\r
- ld hl,@ctbl+7 ;get baudrate index\r
- add hl,bc ;\r
- ld a,(hl)\r
- and 0fh\r
- add a,a ;get factor\r
- ld hl,bd150_tab\r
- call add_hla\r
- ld c,(hl)\r
- inc hl\r
- ld b,(hl)\r
- ld hl,(f_cpu)\r
- ld de,(f_cpu+2)\r
- call div32_r\r
- ld bc,32*150\r
- call div32_r\r
- ld de,2\r
- or a\r
- sbc hl,de\r
- jr nc,as_ini_1\r
- ld hl,0\r
-as_ini_1:\r
- ld b,h\r
- ld c,l\r
- pop de\r
- ld hl,init_br_off\r
- add hl,de\r
- ld (hl),c\r
- inc hl\r
- ld (hl),b\r
- ex de,hl\r
- jp ioiniml\r
-\r
-\r
-bd150_tab:\r
-; factor index baudrate orig. cp/m\r
- dw 19200/150 ; 0 19200 -\r
- dw 28800/150 ; 1 28800 50\r
- dw 38400/150 ; 2 38400 75\r
- dw 57600/150 ; 3 57600 110\r
- dw 11520/15 ; 4 115200 134.5\r
- dw 150/150 ; 5 150\r
- dw 300/150 ; 6 300\r
- dw 600/150 ; 7 600\r
- dw 1200/150 ; 8 1200\r
- dw 1800/150 ; 9 1800\r
- dw 2400/150 ;10 2400\r
- dw 3600/150 ;11 3600\r
- dw 4800/150 ;12 4800\r
- dw 7200/150 ;13 7200\r
- dw 9600/150 ;14 9600\r
- dw 19200/150 ;15 19200\r
-\r
-\r
-\r
-\r
-initab0:\r
- db 1,stat0,0 ;Disable rx/tx interrupts\r
- ;Enable baud rate generator\r
- db 1,asext0,M_BRGMOD+M_DCD0DIS+M_CTS0DIS\r
- db 2,astc0l\r
-init_br_off equ $ - initab0\r
- dw 28\r
- db 1,cntlb0,M_MPBT ;No MP Mode, X16\r
- db 1,cntla0,M_RE+M_TE+M_MOD2 ;Rx/Tx enable, 8N1\r
- db 0\r
-\r
-initab1:\r
- db 1,stat1,0 ;Disable rx/tx ints, disable CTS1\r
- db 1,asext1,M_BRGMOD ;Enable baud rate generator\r
- db 2,astc1l,low 3, high 3\r
- db 1,cntlb1,M_MPBT ;No MP Mode, X16\r
- db 1,cntla1,M_RE+M_TE+M_MOD2 ;Rx/Tx enable, 8N1\r
- db 0\r
+ ld c,1 ;asci channel number\r
+ jp as_init\r
\r
\r
;--------------------------------------------------------------\r
\r
- dseg\r
-\r
as0ista:\r
in0 a,(stat0)\r
and M_RDRF\r
call cpu_frq\r
ld (f_cpu),hl\r
ld (f_cpu+2),de\r
+ call intinit ; setup interrupts and vectors\r
ret\r
\r
?init:\r
ld (@aovec),hl\r
\r
\r
- call intinit ; setup interrupts and vectors\r
call prt0ini ; init timer\r
ei\r
ld c,2\r
;\r
global ff.init,ff.in,ff.ist,ff.out,ff.ost\r
\r
+ extrn ff_empty,ff_get,ff_full,ff_put\r
extrn bufinit,fifolst\r
\r
include config.inc\r
\r
;--------------------------------------------------------------\r
; Input status\r
-; buffer is empty, if output index and input index are the same\r
\r
dseg\r
ff.ist:\r
push ix\r
ld ix,(fifolst+ici) ;\r
-\r
-buf.empty:\r
- ld a,(ix+o.in_idx) ;\r
- sub (ix+o.out_idx) ;\r
+ call ff_empty\r
pop ix\r
- ret z\r
- or 0ffh\r
ret\r
\r
-\r
;--------------------------------------------------------------\r
-; Output status\r
-; buffer is full, if output index is one behind input index\r
+; Get an input character \r
\r
ff.in:\r
push ix\r
ld ix,(fifolst+ici) ;\r
-\r
-buf.get:\r
- push ix\r
- pop hl\r
- ld c,(ix+o.out_idx) ;\r
- ld b,0\r
- add hl,bc\r
- ld a,c\r
-bg.wait:\r
- cp (ix+o.in_idx) ;\r
- jr z,bg.wait\r
- ld b,(hl)\r
- ld a,c ;\r
- inc a\r
- and (ix+o.mask)\r
- ld (ix+o.out_idx),a\r
- ld a,b\r
+ call ff_get\r
pop ix\r
ret\r
\r
;--------------------------------------------------------------\r
; Output status\r
-; buffer is full, if output index is one behind input index\r
\r
ff.ost:\r
push ix\r
ld ix,(fifolst+ico) ;\r
-\r
-buf.full:\r
- ld a,(ix+o.in_idx) ;\r
- inc a\r
- and (ix+o.mask)\r
- sub (ix+o.out_idx) ;\r
+ call ff_full\r
pop ix\r
- ret z\r
- or 0ffh\r
ret\r
\r
\r
ff.out:\r
push ix ;\r
ld ix,(fifolst+ico) ;\r
-buf.put:\r
- push ix ;\r
- pop hl ; get buffer start address\r
-\r
- ld a,c ;\r
- ld c,(ix+o.in_idx) ; add input index\r
- ld b,0 ;\r
- add hl,bc ;\r
- ld (hl),a ; one place is allways free\r
- ld b,a ;\r
-\r
- ld a,c ; bump input index\r
- inc a ;\r
- and (ix+o.mask) ;\r
-bp.wait: ; do\r
- cp (ix+o.out_idx) ;\r
- jr z,bp.wait ; while new input idx == ouput idx\r
- ld (ix+o.in_idx),a ;\r
-\r
+ call ff_put\r
out (AVRINT6),a ; tell monitor\r
- ld a,b ;\r
pop ix ;\r
- ret ;\r
+ ret\r
\r
end\r
+\r
--- /dev/null
+\r
+ public bufinit\r
+ public ff_empty,ff_get,ff_full,ff_put\r
+\r
+ public fifolst\r
+\r
+ extrn msg.sm,hwl2phy\r
+\r
+ include config.inc\r
+ include z180reg.inc\r
+\r
+\r
+;--------------------------------------------------------------------\r
+\r
+ dseg\r
+\r
+fifolst:\r
+ rept 4\r
+ dw 0\r
+ endm\r
+\r
+;--------------------------------------------------------------------\r
+\r
+ dseg\r
+\r
+bufinit:\r
+ ld (ix+o.in_idx),0 ;reset pointers (empty fifo)\r
+ ld (ix+o.out_idx),0\r
+ ld a,(ix+o.id)\r
+ ld hl,fifolst\r
+ ld e,a\r
+ ld d,0\r
+ add hl,de\r
+ add hl,de\r
+ push ix\r
+ pop de\r
+ cp 4\r
+ jr nc,bfi_skip\r
+\r
+ ld (hl),e\r
+ inc hl\r
+ ld (hl),d\r
+\r
+bfi_skip:\r
+ ex de,hl\r
+ call hwl2phy ;get phys. address of fifo\r
+ ld c,a\r
+ ld a,(ix+o.id) ;fifo id\r
+ or a ;test if fifo 0\r
+ ret z\r
+\r
+ cp 4\r
+ ret nc\r
+\r
+; TODO: move to better place\r
+\r
+ ld b,a\r
+ push bc ;c: bank-addr, b: ignored\r
+ push hl ;address\r
+ ld c,0\r
+ push bc ;c: function, b:subf\r
+ ld b,5\r
+ ld h,c\r
+ ld l,c\r
+ add hl,sp\r
+ call msg.sm\r
+ pop hl\r
+ pop hl\r
+ pop hl\r
+ ret\r
+\r
+;--------------------------------------------------------------\r
+; Check if characters in fifo\r
+; Fifo is empty, if output index and input index are the same\r
+\r
+ff_empty:\r
+ ld a,(ix+o.in_idx) ;\r
+ sub (ix+o.out_idx) ;\r
+ ret z\r
+ or 0ffh\r
+ ret\r
+\r
+;--------------------------------------------------------------\r
+\r
+ff_get:\r
+ push ix\r
+ pop hl\r
+ ld c,(ix+o.out_idx) ;\r
+ ld b,0\r
+ add hl,bc\r
+ ld a,c\r
+bg.wait:\r
+ cp (ix+o.in_idx) ;\r
+ jr z,bg.wait\r
+ ld b,(hl)\r
+ ld a,c ;\r
+ inc a\r
+ and (ix+o.mask)\r
+ ld (ix+o.out_idx),a\r
+ ld a,b\r
+ ret\r
+\r
+;--------------------------------------------------------------\r
+; Check if room in fifo\r
+; buffer is full, if output index is one behind input index\r
+\r
+ff_full:\r
+ ld a,(ix+o.in_idx) ;\r
+ inc a\r
+ and (ix+o.mask)\r
+ sub (ix+o.out_idx) ;\r
+ ret z\r
+ or 0ffh\r
+ ret\r
+\r
+\r
+;--------------------------------------------------------------\r
+; put character in c in buffer\r
+; destroys hl, bc\r
+; returns output char in a\r
+\r
+ff_put:\r
+ push ix ;\r
+ pop hl ; get buffer start address\r
+\r
+ ld a,c ;\r
+ ld c,(ix+o.in_idx) ; add input index\r
+ ld b,0 ;\r
+ add hl,bc ;\r
+ ld (hl),a ; one place is allways free\r
+ ld b,a ;\r
+\r
+ ld a,c ; bump input index\r
+ inc a ;\r
+ and (ix+o.mask) ;\r
+bp.wait: ; do\r
+ cp (ix+o.out_idx) ;\r
+ jr z,bp.wait ; while new input idx == ouput idx\r
+ ld (ix+o.in_idx),a ;\r
+ ld a,b ;\r
+ ret ;\r
+\r
+ end\r
BACKSPC = N\r
RUBOUT = N\r
BOOTDRV = A\r
-MEMTOP = FE\r
+MEMTOP = FD\r
BNKSWT = Y\r
COMBAS = F0\r
LERROR = Y\r
OVLYDTAP = Y\r
CRDATAF = N\r
DBLALV = Y\r
-\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a
\ No newline at end of file
+\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\r
-\r
- public intinit\r
- public bufinit\r
- public cpu_frq\r
- public get_tmr\r
-\r
- public fifolst\r
-\r
- extrn div32_r,?pmsg\r
- extrn msg.sm,msg.recv,hwl2phy\r
-\r
- include config.inc\r
- include z180reg.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
- ld hl,spi$msg\r
- call ?pmsg\r
-sp.i.2:\r
- halt\r
- jr sp.i.2\r
-\r
-spi$msg:\r
- db 13,10,'Spurious Int: '\r
-spi$nr: db '0'\r
- db 0\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
- dseg\r
-\r
-fifolst:\r
- rept 4\r
- dw 0\r
- endm\r
-\r
-;--------------------------------------------------------------------\r
-\r
- dseg\r
-\r
-bufinit:\r
- ld (ix+o.in_idx),0 ;reset pointers (empty fifo)\r
- ld (ix+o.out_idx),0\r
- ld a,(ix+o.id)\r
- ld hl,fifolst\r
- ld e,a\r
- ld d,0\r
- add hl,de\r
- add hl,de\r
- push ix\r
- pop de\r
- cp 4\r
- jr nc,bfi_skip\r
-\r
- ld (hl),e\r
- inc hl\r
- ld (hl),d\r
-\r
-bfi_skip:\r
- ex de,hl\r
- call hwl2phy ;get phys. address of fifo\r
- ld c,a\r
- ld a,(ix+o.id) ;fifo id\r
- or a ;test if fifo 0\r
- ret z\r
-\r
- ld b,a\r
- push bc ;c: bank-addr, b: ignored\r
- push hl ;address\r
- ld c,0\r
- push bc ;c: function, b:subf\r
- ld b,5\r
- ld h,c\r
- ld l,c\r
- add hl,sp\r
- call msg.sm\r
- pop hl\r
- pop hl\r
- pop hl\r
- ret\r
-\r
-;----------------------------------------------------------------------\r
-\r
-\r
- end\r
+
+ public intinit
+ public bufinit
+ public cpu_frq
+ public get_tmr
+
+ public fifolst
+
+ extrn div32_r,?pmsg
+ extrn msg.sm,msg.recv,hwl2phy
+
+ include config.inc
+ include z180reg.inc
+
+
+;----------------------------------------------------------------------
+
+ 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_tmr
+ 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-100)*5 ; 184320/18
+ ld de,1
+ or a
+dly_lp:
+ sbc hl,de ; 10
+ jr nz,dly_lp ; 6/8 -> 18 cycles
+
+ pop hl
+ pop de
+ call get_tmr
+
+ ld b,h
+ ld c,l
+ ld de,036EEh ;18432000/(2**16) * 50
+ ld hl,08000h ;18432000%(2**16) * 50
+
+ 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
+
+;--------------------------------------------------------------------
+
+ dseg
+get_tmr:
+ push de
+ push hl
+ ld hl,1*256 + 3 ; h = subcommand, l = 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
+
+;--------------------------------------------------------------------
+
+ dseg
+
+fifolst:
+ rept 4
+ dw 0
+ endm
+
+;--------------------------------------------------------------------
+
+ dseg
+
+bufinit:
+ ld (ix+o.in_idx),0 ;reset pointers (empty fifo)
+ ld (ix+o.out_idx),0
+ ld a,(ix+o.id)
+ ld hl,fifolst
+ ld e,a
+ ld d,0
+ add hl,de
+ add hl,de
+ push ix
+ pop de
+ cp 4
+ jr nc,bfi_skip
+
+ ld (hl),e
+ inc hl
+ ld (hl),d
+
+bfi_skip:
+ ex de,hl
+ call hwl2phy ;get phys. address of fifo
+ ld c,a
+ ld a,(ix+o.id) ;fifo id
+ or a ;test if fifo 0
+ ret z
+
+ ld b,a
+ push bc ;c: bank-addr, b: ignored
+ push hl ;address
+ ld c,0
+ push bc ;c: function, b:subf
+ ld b,5
+ ld h,c
+ ld l,c
+ add hl,sp
+ call msg.sm
+ pop hl
+ pop hl
+ pop hl
+ ret
+
+;----------------------------------------------------------------------
+
+
+ end
- page 255\r
- .z80\r
-\r
-\r
- global mmuinit\r
- global bnk2log,bnk2phy,hwl2phy,phy2log\r
-\r
- include config.inc\r
- include z180reg.inc\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Memory Map 1:\r
-;\r
-; Common CAStart .. 0FFFF\r
-; Bank 0 00000 .. CAStart-1\r
-; Bank 1 10000 ..\r
-; Bank 2\r
-;\r
-; Memory Map 2:\r
-;\r
-; Common 18000 .. 1BFFF BANK1\r
-;\r
-; Bank 0 00000 .. 0BFFF 0\r
-; Bank 1 0C000 .. 17FFF 1*BNK_SIZE\r
-; Bank 2 1C000 .. 27FFF 2*BNK_SIZE + CMN_SIZE\r
-; Bank 3 28000 .. 33FFF 3*BNK_SIZE + CMN_SIZE\r
-; Bank n n*BNK_SIZE + (n < 2) ? 0 : CMN_SIZE\r
-;\r
-;----------------------------------------------------------------------\r
-\r
- cseg\r
-\r
-mmuinit:\r
- ld a,USR$CBAR\r
- out0 (cbar),a\r
- ret\r
-\r
-;--------------------------------------------------------------------\r
-; Return the BBR value for the given bank number\r
-;\r
-; in a: Bank number\r
-; out a: bbr value\r
-\r
- if 0 ; Memory Map 1\r
-\r
-bnk2log:\r
- or a ;\r
- ret z ; Bank 0 is at physical address 0\r
-\r
- dec a ;\r
- push bc ;\r
- ld c,a ;\r
- ld b,BNK_SIZE ;\r
- mlt bc ; bank size * bank number\r
- ld a,c ;\r
- add a,10h ; add bank0 + common\r
- pop bc ;\r
- ret ;\r
-\r
- else ; Memory Map 2\r
-\r
-bnk2log:\r
- or a\r
- ret z ; Bank 0 is at physical address 0\r
-\r
- push bc\r
- ld c,a ;\r
- ld b,BNK_SIZE ;\r
- mlt bc ; bank size * bank number\r
- cp 2 ;\r
- ld a,c ;\r
- pop bc\r
- ret c\r
- add a,CMN_SIZE\r
- ret\r
-\r
- endif\r
-\r
- if 0 ; table version\r
-\r
- push hl\r
- ld hl,bnk_table ;\r
- add a,l ;\r
- ld l,a ;\r
- jr nc,$+3 ;\r
- inc h ;\r
- ld a,(hl) ;\r
- pop hl\r
- ret\r
-\r
- endif\r
-\r
-;--------------------------------------------------------------\r
-\r
-;in hl: Log. Address\r
-; a: Bank number\r
-;\r
-;out ahl: Phys. (linear) Address\r
-\r
-\r
-bnk2phy:\r
- push bc\r
- ld c,a\r
- ld a,h\r
- and a,0f0h\r
- cp CA*16\r
- ld a,c\r
- pop bc\r
- jr c,b2p_banked\r
- ; address is in common\r
- if 0 ; Memory Map 1\r
- ld a,0 ; base is 0\r
- else ; Memory Map 2\r
- ld a,1 ; same as bank1\r
- endif\r
-\r
-b2p_banked:\r
- call bnk2log ; get address base\r
-\r
- ; fall thru\r
-\r
-;--------------------------------------------------------------\r
-;\r
-; hl: Log. Address\r
-; a: Bank base (bbr)\r
-;\r
-; 2 0 0\r
-; 0 6 8 0\r
-; hl hhhhhhhhllllllll\r
-; a + bbbbbbbb\r
-;\r
-; OP: ahl = (a<<12) + (h<<8) + l\r
-;\r
-;out ahl: Phys. (linear) Address\r
-\r
-log2phy:\r
- push bc ;\r
-l2p_i:\r
- ld c,a ;\r
- ld b,16 ;\r
- mlt bc ; bc = a<<4\r
- ld a,c ;\r
- add a,h ;\r
- ld h,a ;\r
- ld a,b ;\r
- adc a,0 ;\r
- pop bc ;\r
- ret ;\r
-\r
-;--------------------------------------------------------------\r
-;\r
-; hl: Log. Address\r
-;\r
-;\r
-; OP: ahl = (bankbase<<12) + (h<<8) + l\r
-;\r
-;out ahl: Phys. (linear) Address\r
-\r
-\r
-hwl2phy:\r
- push bc ;\r
- in0 c,(cbar) ;\r
- ld a,h ;\r
- or 00fh ; log. addr in common1?\r
- cp c\r
- jr c,hlp_1\r
-\r
- in0 a,(cbr) ; yes, cbr is address base\r
- jr hl2p_x\r
-hlp_1:\r
- ld b,16 ; log. address in baked area?\r
- mlt bc\r
- ld a,h\r
- cp c\r
- jr c,hlp_2\r
- in0 a,(bbr) ; yes, bbr is address base\r
- jr hl2p_x\r
-hlp_2:\r
- xor a ; common1\r
-hl2p_x:\r
- jr nz,l2p_i\r
-\r
- pop bc ; bank part is 0, no translation\r
- ret ;\r
-\r
-\r
-;--------------------------------------------------------------\r
-; return logical bank 0 address for given physical address.\r
-;\r
-; in: ahl: pyhsical addres (20 bit)\r
-; out hl: logical address.\r
-; logical address is in bank 0 or common, no bank number returned\r
-;\r
-\r
-phy2log:\r
- or a\r
- ret z\r
-\r
- push bc\r
- push hl\r
- ld l,h\r
- ld h,0\r
- ld bc,-16*SYS$CBR\r
- add hl,bc\r
- ld h,l\r
- pop bc\r
- ld l,c\r
- pop bc\r
- ret\r
-\r
-;--------------------------------------------------------------\r
-; Trampoline for routines in banked ram.\r
-; Switch stack pointer to "system" stack in top ram\r
-; Save cbar\r
-;\r
- extrn bs$stack\r
-\r
- cseg ; common!\r
-\r
- public _b0call\r
-_b0call:\r
- push af\r
- in0 a,(bbr)\r
- jr nz,b0c_doit\r
- pop af\r
-\r
- ex (sp),hl ;16\r
- push de\r
- ld e,(hl)\r
- inc hl\r
- ld d,(hl)\r
- inc hl\r
- ld (b0c_fast_go),de\r
- pop de\r
- ex (sp),hl ;16\r
-b0c_fast_go equ $+1\r
- jp 0\r
-\r
-b0c_doit:\r
- ld (b0_save_hl),hl\r
- ld (b0_save_de),de\r
- pop hl\r
- ld (b0_save_af),hl\r
-\r
- pop de ;get ptr to 'function address' in de\r
- ld hl,2\r
- add hl,de\r
- push hl ;put return address on stack\r
-\r
- if 0 ; link80\r
-\r
- ld hl,0\r
- add hl,sp ;\r
- ld a,h\r
- cp high (bs$stack-bs$stack$size) ;link80 can't process this\r
- jr nc,$ + 5 ;skip if stack allready in common bios ram\r
-\r
- else\r
-\r
- ld hl,bs$stack-bs$stack$size\r
- ld a,h\r
- dec a\r
- ld hl,0\r
- add hl,sp ;\r
- cp h\r
- jr c,$ + 5 ;skip if stack allready in common bios ram\r
- endif\r
- ld sp,bs$stack ;\r
-\r
- push hl ;save user stack pointer\r
-\r
- in0 h,(bbr) ;\r
- push hl ;\r
- ld hl,b0c_ret\r
- push hl\r
- xor a\r
- out0 (bbr),a ;\r
- ex de,hl ;ptr\r
- ld e,(hl) ;get 'function address'\r
- inc hl ;\r
- ld d,(hl) ;\r
- push de ;put on (switched) stack\r
-\r
- ld hl,(b0_save_af) ;get back users registers\r
- push hl\r
- pop af\r
- ld de,(b0_save_de)\r
- ld hl,(b0_save_hl)\r
- ret ;go to function\r
-b0c_ret:\r
- ld (b0_save_hl),hl\r
-\r
- pop hl ;\r
- out0 (bbr),h ;\r
- pop hl ;\r
- ld sp,hl ;\r
- ld hl,(b0_save_hl)\r
- ret ;\r
-\r
-\r
-b0_save_hl: dw 0\r
-b0_save_de: dw 0\r
-b0_save_af: dw 0\r
-\r
-\r
-\r
-;====================================================================\r
-\r
- if 0\r
-\r
-;--------------------------------------------------------------------\r
-; Return the BBR value for the given bank number\r
-\r
-bnk2bbr:\r
- or a ; 4\r
- ret z ; 5/10 | 11 14\r
-\r
- push bc ;11 | 11\r
- ld b,a ; 4\r
- ld c,CA ; 6\r
- mlt bc ;17 >45\r
- ld a,c ; 4\r
- add a,10h ; 6\r
- pop bc ; 9 | 10\r
- ret ; 9 | 10 76\r
-\r
- push ix ;2 / 14 | 15\r
- ld ix,bnktbl ;4 / 12 | 14\r
- ld ($+3+2),a ;3 / 15 | 19\r
- ld a,(ix+0) ;3 / 14 | 19\r
- pop ix ;2 / 12 | 14\r
- ret ;1 / 9 | 10 15 / 76|91\r
-\r
- push hl ;1 / 11 | 11\r
- ld hl,bnktbl ;3 / 9 | 10\r
- add a,l ;1 / 4 | 4\r
- ld l,a ;1 / 4 | 4\r
- ld a,0 ;1 / 6 | 7\r
- adc a,h ;1 / 4 | 4\r
- ld h,a ;1 / 4 | 4\r
- ld a,(hl) ;1 / 6 | 7\r
- pop hl ;1 / 9 | 10\r
- ret ;1 / 9 | 10 12 / 66|71\r
-\r
- push hl ;1 / 11 | 11\r
- add a,low bnktbl ;2 / 6 | 7\r
- ld l,a ;1 / 4 | 4\r
- ld a,0 ;1 / 6 | 7\r
- adc a,high bnktbl ;2 / 6 | 7\r
- ld h,a ;1 / 4 | 4\r
- ld a,(hl) ;1 / 6 | 7\r
- pop hl ;1 / 9 | 10\r
- ret ;1 / 9 | 10 11 / 61|67\r
-\r
- endif\r
-\r
-\r
- end\r
+ page 255
+ .z80
+
+
+ public mmuinit
+ public bnk2log,bnk2phy,hwl2phy,phy2log
+ public isv_sw
+
+ include config.inc
+ include z180reg.inc
+
+
+;----------------------------------------------------------------------
+; Memory Map 1:
+;
+; Common CAStart .. 0FFFF
+; Bank 0 00000 .. CAStart-1
+; Bank 1 10000 ..
+; Bank 2
+;
+; Memory Map 2:
+;
+; Common 18000 .. 1BFFF BANK1
+;
+; Bank 0 00000 .. 0BFFF 0
+; Bank 1 0C000 .. 17FFF 1*BNK_SIZE
+; Bank 2 1C000 .. 27FFF 2*BNK_SIZE + CMN_SIZE
+; Bank 3 28000 .. 33FFF 3*BNK_SIZE + CMN_SIZE
+; Bank n n*BNK_SIZE + (n < 2) ? 0 : CMN_SIZE
+;
+;----------------------------------------------------------------------
+
+ cseg
+
+mmuinit:
+ ld a,USR$CBAR
+ out0 (cbar),a
+ ret
+
+;--------------------------------------------------------------------
+; Return the BBR value for the given bank number
+;
+; in a: Bank number
+; out a: bbr value
+
+ if 0 ; Memory Map 1
+
+bnk2log:
+ or a ;
+ ret z ; Bank 0 is at physical address 0
+
+ dec a ;
+ push bc ;
+ ld c,a ;
+ ld b,BNK_SIZE ;
+ mlt bc ; bank size * bank number
+ ld a,c ;
+ add a,10h ; add bank0 + common
+ pop bc ;
+ ret ;
+
+ else ; Memory Map 2
+
+bnk2log:
+ or a
+ ret z ; Bank 0 is at physical address 0
+
+ push bc
+ ld c,a ;
+ ld b,BNK_SIZE ;
+ mlt bc ; bank size * bank number
+ cp 2 ;
+ ld a,c ;
+ pop bc
+ ret c
+ add a,CMN_SIZE
+ ret
+
+ endif
+
+ if 0 ; table version
+
+ push hl
+ ld hl,bnk_table ;
+ add a,l ;
+ ld l,a ;
+ jr nc,$+3 ;
+ inc h ;
+ ld a,(hl) ;
+ pop hl
+ ret
+
+ endif
+
+;--------------------------------------------------------------
+
+;in hl: Log. Address
+; a: Bank number
+;
+;out ahl: Phys. (linear) Address
+
+
+bnk2phy:
+ push bc
+ ld c,a
+ ld a,h
+ and a,0f0h
+ cp CA*16
+ ld a,c
+ pop bc
+ jr c,b2p_banked
+ ; address is in common
+ if 0 ; Memory Map 1
+ ld a,0 ; base is 0
+ else ; Memory Map 2
+ ld a,1 ; same as bank1
+ endif
+
+b2p_banked:
+ call bnk2log ; get address base
+
+ ; fall thru
+
+;--------------------------------------------------------------
+;
+; hl: Log. Address
+; a: Bank base (bbr)
+;
+; 2 0 0
+; 0 6 8 0
+; hl hhhhhhhhllllllll
+; a + bbbbbbbb
+;
+; OP: ahl = (a<<12) + (h<<8) + l
+;
+;out ahl: Phys. (linear) Address
+
+log2phy:
+ push bc ;
+l2p_i:
+ ld c,a ;
+ ld b,16 ;
+ mlt bc ; bc = a<<4
+ ld a,c ;
+ add a,h ;
+ ld h,a ;
+ ld a,b ;
+ adc a,0 ;
+ pop bc ;
+ ret ;
+
+;--------------------------------------------------------------
+;
+; hl: Log. Address
+;
+;
+; OP: ahl = (bankbase<<12) + (h<<8) + l
+;
+;out ahl: Phys. (linear) Address
+
+
+hwl2phy:
+ push bc ;
+ in0 c,(cbar) ;
+ ld a,h ;
+ or 00fh ; log. addr in common1?
+ cp c
+ jr c,hlp_1
+
+ in0 a,(cbr) ; yes, cbr is address base
+ jr hl2p_x
+hlp_1:
+ ld b,16 ; log. address in baked area?
+ mlt bc
+ ld a,h
+ cp c
+ jr c,hlp_2
+ in0 a,(bbr) ; yes, bbr is address base
+ jr hl2p_x
+hlp_2:
+ xor a ; common1
+hl2p_x:
+ jr nz,l2p_i
+
+ pop bc ; bank part is 0, no translation
+ ret ;
+
+
+;--------------------------------------------------------------
+; return logical bank 0 address for given physical address.
+;
+; in: ahl: pyhsical addres (20 bit)
+; out hl: logical address.
+; logical address is in bank 0 or common, no bank number returned
+;
+
+phy2log:
+ or a
+ ret z
+
+ push bc
+ push hl
+ ld l,h
+ ld h,0
+ ld bc,-16*SYS$CBR
+ add hl,bc
+ ld h,l
+ pop bc
+ ld l,c
+ pop bc
+ ret
+
+;--------------------------------------------------------------
+; Trampoline for routines in banked ram.
+; Switch stack pointer to "system" stack in top ram
+; Save cbar
+;
+ extrn bs$stack
+
+ cseg ; common!
+
+ public _b0call
+_b0call:
+ push af
+ in0 a,(bbr)
+ jr nz,b0c_doit
+ pop af
+
+ ex (sp),hl ;16
+ push de
+ ld e,(hl)
+ inc hl
+ ld d,(hl)
+ inc hl
+ ld (b0c_fast_go),de
+ pop de
+ ex (sp),hl ;16
+b0c_fast_go equ $+1
+ jp 0
+
+b0c_doit:
+ ld (b0_save_hl),hl
+ ld (b0_save_de),de
+ pop hl
+ ld (b0_save_af),hl
+
+ pop de ;get ptr to 'function address' in de
+ ld hl,2
+ add hl,de
+ push hl ;put return address on stack
+
+ if 0 ; link80
+
+ ld hl,0
+ add hl,sp ;
+ ld a,h
+ cp high (bs$stack-bs$stack$size) ;link80 can't process this
+ jr nc,$ + 5 ;skip if stack allready in common bios ram
+
+ else
+
+ ld hl,bs$stack-bs$stack$size
+ ld a,h
+ dec a
+ ld hl,0
+ add hl,sp ;
+ cp h
+ jr c,$ + 5 ;skip if stack allready in common bios ram
+ endif
+ ld sp,bs$stack ;
+
+ push hl ;save user stack pointer
+
+ in0 h,(bbr) ;
+ push hl ;
+ ld hl,b0c_ret
+ push hl
+ xor a
+ out0 (bbr),a ;
+ ex de,hl ;ptr
+ ld e,(hl) ;get 'function address'
+ inc hl ;
+ ld d,(hl) ;
+ push de ;put on (switched) stack
+
+ ld hl,(b0_save_af) ;get back users registers
+ push hl
+ pop af
+ ld de,(b0_save_de)
+ ld hl,(b0_save_hl)
+ ret ;go to function
+b0c_ret:
+ ld (b0_save_hl),hl
+
+ pop hl ;
+ out0 (bbr),h ;
+ pop hl ;
+ ld sp,hl ;
+ ld hl,(b0_save_hl)
+ ret ;
+
+
+b0_save_hl: dw 0
+b0_save_de: dw 0
+b0_save_af: dw 0
+
+
+;--------------------------------------------------------------------
+; Trampoline for interrupt routines in banked ram.
+; Switch stack pointer to "system" stack in top ram
+; Save bbr
+
+ cseg
+isv_sw: ;
+ ex (sp),hl ;save hl, 'return adr' in hl
+ push de ;
+ push af ;
+ ex de,hl ;'return address' in de
+
+ if 0
+ if 0 ; link80
+
+ ld hl,0
+ add hl,sp ;
+ ld a,h
+ cp high (bs$stack-bs$stack$size) ;link80 can't process this
+ jr nc,$ + 5 ;skip if stack allready in common bios ram
+
+ else
+
+ ld hl,bs$stack-bs$stack$size
+ ld a,h
+ dec a
+ ld hl,0
+ add hl,sp ;
+ cp h
+ jr c,$ + 5 ;skip if stack allready in common bios ram
+ endif
+ ld sp,bs$stack ;
+ else
+ ld hl,0
+ add hl,sp
+ ld sp,istack
+ endif
+ push hl ;save user stack pointer
+ in0 h,(bbr) ;
+ push hl ;
+ xor a ;
+ out0 (bbr),a ;
+ ex de,hl ;
+ ld e,(hl) ;
+ inc hl ;
+ ld d,(hl) ;
+ ex de,hl ;
+ push bc ;
+ call jphl ;
+
+ pop bc ;
+ pop hl ;
+ out0 (bbr),h ;
+ pop hl ;
+ ld sp,hl ;
+ pop af ;
+ pop de ;
+ pop hl ;
+ ei ;
+ ret ;
+jphl:
+ jp (hl) ;
+
+
+ ds 24
+istack:
+
+;====================================================================
+
+ if 0
+
+;--------------------------------------------------------------------
+; Return the BBR value for the given bank number
+
+bnk2bbr:
+ or a ; 4
+ ret z ; 5/10 | 11 14
+
+ push bc ;11 | 11
+ ld b,a ; 4
+ ld c,CA ; 6
+ mlt bc ;17 >45
+ ld a,c ; 4
+ add a,10h ; 6
+ pop bc ; 9 | 10
+ ret ; 9 | 10 76
+
+ push ix ;2 / 14 | 15
+ ld ix,bnktbl ;4 / 12 | 14
+ ld ($+3+2),a ;3 / 15 | 19
+ ld a,(ix+0) ;3 / 14 | 19
+ pop ix ;2 / 12 | 14
+ ret ;1 / 9 | 10 15 / 76|91
+
+ push hl ;1 / 11 | 11
+ ld hl,bnktbl ;3 / 9 | 10
+ add a,l ;1 / 4 | 4
+ ld l,a ;1 / 4 | 4
+ ld a,0 ;1 / 6 | 7
+ adc a,h ;1 / 4 | 4
+ ld h,a ;1 / 4 | 4
+ ld a,(hl) ;1 / 6 | 7
+ pop hl ;1 / 9 | 10
+ ret ;1 / 9 | 10 12 / 66|71
+
+ push hl ;1 / 11 | 11
+ add a,low bnktbl ;2 / 6 | 7
+ ld l,a ;1 / 4 | 4
+ ld a,0 ;1 / 6 | 7
+ adc a,high bnktbl ;2 / 6 | 7
+ ld h,a ;1 / 4 | 4
+ ld a,(hl) ;1 / 6 | 7
+ pop hl ;1 / 9 | 10
+ ret ;1 / 9 | 10 11 / 61|67
+
+ endif
+
+
+ end
- title 'Time module for the Modular CP/M 3 BIOS'\r
-\r
- public ?time, gs_rtc\r
- public prt0ini\r
- public gtimer,gstimer\r
-\r
- extrn @date,@hour,@min,@sec\r
- extrn f_cpu\r
- extrn ioiniml,div32_16\r
- extrn msg.sm,msg.recv\r
- extrn _b0call\r
-\r
- include config.inc\r
- include z180reg.inc\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; c == 00h: get time\r
-; c == ffh: set time\r
-\r
- cseg ; time must be done from resident memory\r
-?time:\r
- inc c ;zero if ff\r
- ld c,3\r
- jr z,time_set\r
-\r
- ld a,(time_to)\r
- or a\r
- ret nz\r
-\r
- dec c\r
-time_set:\r
- b0call gs_rtc\r
- ld a,0ffh\r
- ld (time_to),a\r
- ret\r
-\r
-;----------------------------------------------------------------------\r
-; c = 2: get time\r
-; c = 3: set time\r
-\r
- dseg\r
-gs_rtc:\r
-\r
- push hl\r
- push de\r
-\r
- ld hl,(@date)\r
- ld a,(@hour)\r
- ld d,a\r
- ld a,(@min)\r
- ld e,a\r
- ld a,(@sec)\r
- ld b,a ;b = sec, c = subcommand\r
- push hl ;2\r
- push de ;4\r
- push bc ;6\r
- ld hl,3 * 256 + 0 ;h = command, l = 0\r
- push hl ;8\r
-\r
- ld h,l ;hl = 0\r
- add hl,sp\r
- push hl\r
- inc hl ;7\r
-\r
- ld b,7\r
- call msg.sm\r
-\r
- pop hl ;8\r
- ld b,8 ; max receive message len\r
- call msg.recv\r
-\r
- pop hl ;len/command (discard)\r
- pop bc ;subc/sec\r
- pop de\r
- pop hl\r
- ld a,b\r
- ld (@sec),a\r
- ld a,e\r
- ld (@min),a\r
- ld a,d\r
- ld (@hour),a\r
- ld (@date),hl\r
-\r
- pop de\r
- pop hl\r
- ret\r
-\r
-;----------------------------------------------------------------------\r
-\r
-;uint32_t get_timer(uint32_t base)\r
-;{\r
-; uint32_t ret;\r
-; ATOMIC_BLOCK(ATOMIC_FORCEON)\r
-; {\r
-; ret = timestamp;\r
-; }\r
-; return ret - base;\r
-;}\r
-\r
- dseg ; called from banked only\r
-gstimer:\r
- push de\r
- ex de,hl\r
- ld hl,(uptime)\r
- or a\r
- sbc hl,de\r
- pop de\r
- ret\r
-\r
-;----------------------------------------------------------------------\r
-\r
-gtimer:\r
- push bc\r
- ld b,h\r
- ld c,l\r
- or a\r
- di\r
- ld hl,(uptime)\r
- sbc hl,bc\r
- push hl\r
- ei\r
- ld hl,(uptime+2)\r
- sbc hl,de\r
- ex de,hl\r
- pop hl\r
- pop bc\r
- ret\r
-\r
-;----------------------------------------------------------------------\r
-; intit timer interrupt\r
-\r
- dseg\r
-\r
-prt0ini:\r
- in0 a,(tcr)\r
- push af\r
- and ~(M_TIE0+M_TDE0) ;stop timer 0\r
- out0 (tcr),a\r
-\r
- ld a,i\r
- ld h,a\r
- in0 a,(il)\r
- and 0E0h\r
- or IV$PRT0\r
- ld l,a\r
- ld de,isvprt0\r
- ld (hl),e\r
- inc hl\r
- ld (hl),d\r
-\r
- ld hl,(f_cpu)\r
- ld de,(f_cpu+2)\r
- ld bc,PRT_PRE * 800 ;1/800 s == 1,25 ms interrupt rate\r
- call div32_16\r
-\r
- out0 (tmdr0l),l\r
- out0 (tmdr0h),h\r
- out0 (rldr0l),l\r
- out0 (rldr0h),h\r
- pop af\r
- or (M_TIE0+M_TDE0)\r
- out0 (tcr),a\r
- ret\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; timer interrupt\r
-;\r
-; 1,25 ms clock tick\r
-\r
-\r
- cseg ;common!\r
-isvprt0:\r
- push af\r
- in0 a,(tcr) ;reset TIF0 flag\r
- in0 a,(tmdr0l)\r
- in0 a,(tmdr0h)\r
-\r
- push hl ;11\r
- ld hl,uptime ; 9\r
- inc (hl) ;10\r
- jr nz,iprt_1 ;6/8 38\r
- inc hl ; 4\r
- inc (hl) ;10\r
- jr nz,iprt_1 ;6/8 58\r
- inc hl ; 4\r
- inc (hl) ;10\r
- jr nz,iprt_1 ;6/8\r
- inc hl ; 4\r
- inc (hl) ;10\r
-iprt_1:\r
- pop hl ; 9\r
- ld a,(time_to)\r
- sub a,1\r
- jr c,iprt_0\r
- ld (time_to),a\r
-iprt_0:\r
- pop af\r
- ei\r
- ret\r
-\r
-uptime:\r
- dw 0,0\r
-time_to:\r
- db 0\r
-\r
- end\r
+ title 'Time module for the Modular CP/M 3 BIOS'
+
+ public ?time, gs_rtc
+ public prt0ini
+ public gtimer,gstimer
+
+ extrn @date,@hour,@min,@sec
+ extrn f_cpu
+ extrn ioiniml,div32_16
+ extrn msg.sm,msg.recv
+ extrn _b0call
+
+ include config.inc
+ include z180reg.inc
+
+
+;----------------------------------------------------------------------
+; c == 00h: get time
+; c == ffh: set time
+
+ cseg ; time must be done from resident memory
+?time:
+ inc c ;zero if ff
+ ld c,3
+ jr z,time_set
+
+ ld a,(time_to)
+ or a
+ ret nz
+
+ dec c
+time_set:
+ b0call gs_rtc
+ ld a,0ffh
+ ld (time_to),a
+ ret
+
+;----------------------------------------------------------------------
+; c = 2: get time
+; c = 3: set time
+
+ dseg
+gs_rtc:
+
+ push hl
+ push de
+
+ ld hl,(@date)
+ ld a,(@hour)
+ ld d,a
+ ld a,(@min)
+ ld e,a
+ ld a,(@sec)
+ ld b,a ;b = sec, c = subcommand
+ push hl ;2
+ push de ;4
+ push bc ;6
+ ld hl,3 * 256 + 0 ;h = command, l = 0
+ push hl ;8
+
+ ld h,l ;hl = 0
+ add hl,sp
+ push hl
+ inc hl ;7
+
+ ld b,7
+ call msg.sm
+
+ pop hl ;8
+ ld b,8 ; max receive message len
+ call msg.recv
+
+ pop hl ;len/command (discard)
+ pop bc ;subc/sec
+ pop de
+ pop hl
+ ld a,b
+ ld (@sec),a
+ ld a,e
+ ld (@min),a
+ ld a,d
+ ld (@hour),a
+ ld (@date),hl
+
+ pop de
+ pop hl
+ ret
+
+;----------------------------------------------------------------------
+
+;uint32_t get_timer(uint32_t base)
+;{
+; uint32_t ret;
+; ATOMIC_BLOCK(ATOMIC_FORCEON)
+; {
+; ret = timestamp;
+; }
+; return ret - base;
+;}
+
+ dseg ; called from banked only
+gstimer:
+ push de
+ ex de,hl
+ ld hl,(uptime)
+ or a
+ sbc hl,de
+ pop de
+ ret
+
+;----------------------------------------------------------------------
+
+gtimer:
+ push bc
+ ld b,h
+ ld c,l
+ or a
+ di
+ ld hl,(uptime)
+ sbc hl,bc
+ push hl
+ ei
+ ld hl,(uptime+2)
+ sbc hl,de
+ ex de,hl
+ pop hl
+ pop bc
+ ret
+
+;----------------------------------------------------------------------
+; intit timer interrupt
+
+ dseg
+
+prt0ini:
+ in0 a,(tcr)
+ push af
+ and ~(M_TIE0+M_TDE0) ;stop timer 0
+ out0 (tcr),a
+
+ ld a,i
+ ld h,a
+ in0 a,(il)
+ and 0E0h
+ or IV$PRT0
+ ld l,a
+ ld de,isvprt0
+ ld (hl),e
+ inc hl
+ ld (hl),d
+
+ ld hl,(f_cpu)
+ ld de,(f_cpu+2)
+ ld bc,PRT_PRE * 800 ;1/800 s == 1,25 ms interrupt rate
+ call div32_16
+
+ out0 (tmdr0l),l
+ out0 (tmdr0h),h
+ out0 (rldr0l),l
+ out0 (rldr0h),h
+ pop af
+ or (M_TIE0+M_TDE0)
+ out0 (tcr),a
+ ret
+
+
+;----------------------------------------------------------------------
+; timer interrupt
+;
+; 1,25 ms clock tick
+
+
+ cseg ;common!
+isvprt0: ;
+ push af ; 11
+ in0 a,(tcr) ;reset TIF0 flag 12
+ in0 a,(tmdr0l) ; 12
+ in0 a,(tmdr0h) ; 12
+ ;
+
+ push hl ;11
+ ld hl,uptime ; 9
+ inc (hl) ; 10 77
+ jr nz,iprt_1 ; 6/8 -2
+ inc hl ; 4
+ inc (hl) ; 10 14
+ jr nz,iprt_1 ; 6/8
+ inc hl ; 4
+ inc (hl) ;10
+ jr nz,iprt_1 ;6/8
+ inc hl ; 4
+ inc (hl) ;10
+iprt_1: ; 85 138
+ pop hl ; 9
+ ld a,(time_to) ; 12
+ sub a,1 ; 6 112
+ jr c,iprt_0 ; 6/8
+ ld (time_to),a ; 13
+iprt_0: ; 120 178
+ pop af ; 9
+ ei ; 3
+ ret ; 9 141 199
+ ; +intack 18 159 217
+
+uptime:
+ dw 0,0
+time_to:
+ db 0
+
+ end