]> cloudbase.mooo.com Git - z180-stamp-cpm3.git/commitdiff
ascii.180 interrupt driver for ASCI 0/1
authorLeo C <erbl259-lmu@yahoo.de>
Wed, 17 Jun 2015 05:45:20 +0000 (07:45 +0200)
committerLeo C <erbl259-lmu@yahoo.de>
Mon, 13 Jun 2016 16:21:20 +0000 (18:21 +0200)
cbios/Makefile
cbios/asci-cmn.180 [new file with mode: 0644]
cbios/ascii.180 [new file with mode: 0644]
cbios/ascip.180
cbios/boot.180
cbios/conbuf.180
cbios/fifo.180 [new file with mode: 0644]
cbios/gencpm.dat
cbios/misc.180
cbios/mm.180
cbios/time.180

index 0c41e939ffbcc2d94feb81dce58823cabfaf47a1..fafba284a5464d8573e0233b375713a7c806f16c 100644 (file)
@@ -1,8 +1,9 @@
 
 
 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
 
diff --git a/cbios/asci-cmn.180 b/cbios/asci-cmn.180
new file mode 100644 (file)
index 0000000..76ade5a
--- /dev/null
@@ -0,0 +1,113 @@
+
+       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
diff --git a/cbios/ascii.180 b/cbios/ascii.180
new file mode 100644 (file)
index 0000000..6bbf377
--- /dev/null
@@ -0,0 +1,312 @@
+       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
index 470c07e123c0ffc688217884c561cf29b8e06a8e..0d68fd4df887c4f69634e3406a0f1a00757633d7 100644 (file)
@@ -2,7 +2,6 @@
 \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
index fcf00ae4657185835053f987d4c05121079ed152..766277ff005f9bdc95bcde597ff8ab3889e64f07 100644 (file)
@@ -54,6 +54,7 @@ hwini_skip:
        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
@@ -68,7 +69,6 @@ hwini_skip:
        ld      (@aovec),hl\r
 \r
 \r
-       call    intinit                 ; setup interrupts and vectors\r
        call    prt0ini                 ; init timer\r
        ei\r
        ld      c,2\r
index 75741e0ebd50bdca7488a3097df5b6f5541e68d5..3c846dd1f2c876cf0be8a428bcfe9e7ff029aabb 100644 (file)
@@ -6,6 +6,7 @@
 ;\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
@@ -38,65 +39,33 @@ ff.init:
 \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
@@ -108,28 +77,10 @@ buf.full:
 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
diff --git a/cbios/fifo.180 b/cbios/fifo.180
new file mode 100644 (file)
index 0000000..341b5c7
--- /dev/null
@@ -0,0 +1,143 @@
+\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
index 408b8e8edb8cf27b3644bcfbd7562b28199944fa..874b2b16c0f6ffdbf3bdb7bb5b342ba6987eb27b 100644 (file)
@@ -4,7 +4,7 @@ PAGLEN   = 17
 BACKSPC  = N\r
 RUBOUT   = N\r
 BOOTDRV  = A\r
-MEMTOP   = FE\r
+MEMTOP   = FD\r
 BNKSWT   = Y\r
 COMBAS   = F0\r
 LERROR   = Y\r
@@ -155,4 +155,4 @@ OVLYDTAO = Y
 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
index 28c0123f3b2012c2490c9ae4fc863570545736b2..d39f63204ae85440c7dd9896bee30b4bf1938247 100644 (file)
-\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
index b4e6f61a3b0401f45099a7f1eb2bb3893419cbb1..9f90e0385f94593e49cd2db44132d8fcd0622cab 100644 (file)
-       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
index 2eb81239d3cee1effdd4987d0395587edcadad03..befd0ecf7f1309a690ad42680ffbb640dfe470bc 100644 (file)
-       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