summaryrefslogtreecommitdiff
path: root/Z180/r3init.180
diff options
context:
space:
mode:
Diffstat (limited to 'Z180/r3init.180')
-rw-r--r--Z180/r3init.180875
1 files changed, 875 insertions, 0 deletions
diff --git a/Z180/r3init.180 b/Z180/r3init.180
new file mode 100644
index 0000000..c99b624
--- /dev/null
+++ b/Z180/r3init.180
@@ -0,0 +1,875 @@
+ page 255
+ .z80
+
+ extrn ddtz,bpent
+ extrn $stack
+ extrn $coninit,$cists,$ci
+
+ extrn romend
+
+
+ global isv_sw
+
+ include config.inc
+ include z180reg.inc
+ include z180.lib
+
+CR equ 0dh
+
+
+
+;----------------------------------------------------------------------
+
+ cseg
+
+ jp start
+
+; restart vectors
+
+rsti defl 1
+ rept 7
+ db 0, 0, 0, 0, 0
+ jp bpent
+rsti defl rsti+1
+ endm
+
+;----------------------------------------------------------------------
+
+ if ROMSYS
+$crom: defb c$rom ;
+ else
+ db 0 ;
+ endif
+
+dmclrt: ;clear ram per dma
+ db dmct_e-dmclrt-2 ;
+ db sar0l ;first port
+ dw nullbyte ;src (fixed)
+nullbyte:
+ db 000h ;src
+ dw romend ;dst (inc), start after "rom" code
+ db 00h ;dst
+ dw 0-romend ;count (64k)
+dmct_e:
+
+
+INIWAITS defl CWAITIO
+ if ROMSYS
+INIWAITS defl INIWAITS+CWAITROM
+ endif
+
+hwini0:
+ db 3 ;count
+ db rcr,CREFSH ;configure DRAM refresh
+ db dcntl,INIWAITS ;wait states
+ db cbar,SYS$CBAR
+
+;----------------------------------------------------------------------
+
+start:
+ push af ;003c
+ in0 a,(itc) ;003d Illegal opcode trap?
+ jp p,??st01 ;0040
+ pop af ;0043
+ jp bpent ;0044 yes, handle
+
+??st01:
+ ld a,i ;0047 I register == 0 ?
+ jr z,??st02 ;004b yes, harware reset
+ pop af ;004d
+ jp bpent ;004e no, allready set up
+
+??st02:
+ di ;0058
+ ld a,CREFSH
+ out0 (rcr),a ; configure DRAM refresh
+ ld a,CWAITIO
+ out0 (dcntl),a ; wait states
+
+; search warm start mark
+
+ ld ix,mark_55AA ;00b8 ; top of common area
+ ld a,SYS$CBAR ;
+ out0 (cbar),a ;
+ ld a,071h ;00bc
+ ex af,af' ;00be ;for cbr = 0x70 downto 0x40
+swsm_l:
+ ex af,af' ;00bf
+ dec a ;00c0
+ cp 03fh ;00c1
+ jr z,kstart ;00c3 ; break (mark not found)
+ out0 (cbr),a ;00c5
+ ex af,af' ;00c8
+ ld a,0aah ;00c9
+ cp (ix+000h) ;00cb
+ jr nz,swsm_l ;00ce
+ cp (ix+002h) ;00d0
+ jr nz,swsm_l ;00d3
+ cpl ;00d5
+ cp (ix+001h) ;00d6
+ jr nz,swsm_l ;00d9
+ cp (ix+003h) ;00db
+ jr nz,swsm_l ;00de
+ ld sp,$stack ;00e0 mark found, check
+ call checkcrc_alv ;00e3
+ jp z,wstart ;00e6 check ok,
+
+;
+; ram not ok, initialize -- kstart --
+
+kstart:
+
+ ld a,088h ;00e9 0000-7fff: common 0
+ out0 (cbar),a ;00eb 8000-ffff: common 1
+ ld ix,08000h ;00f3
+ ld a,0 ;00f1 start at 008000 (2. phys. 32k block)
+??f_0:
+ out0 (cbr),a ;00f9
+
+ ld (ix+0),a ;0103
+ cpl
+ ld (ix+1),a ;0103
+ cpl
+ add a,8 ;010a next 'bank'
+ cp 078h ;010c stop at 078000
+ jr nz,??f_0 ;010e
+
+ ld de,8000h ;0114 first block not tested, but mark as ok
+ ld a,0 ;00f1 start at 008000 (2. phys. 32k block)
+??cp_0:
+ out0 (cbr),a ;011c
+ ld c,a
+ xor (ix+0)
+ ld b,a
+ ld a,c
+ cpl
+ xor (ix+1)
+ or b
+ jr nz,??cp_1
+ scf
+??cp_1:
+ rr d
+ rr e
+ ld a,c
+ add a,8
+ cp 078h ; stop at 078000
+ jr nz,??cp_0
+
+;
+; ram test found 1 or more error free blocks (32k)
+;
+
+ramok:
+ ld a,SYS$CBAR ;01c8
+ out0 (cbar),a ;01ca
+ ld h,d
+ ld l,e
+ ld c,070h ;01ce highest block
+ ld b,15 ;01d0
+??sr_1:
+ add hl,hl
+ jr c,alloc ;01d4 highest "error free" block
+ ld a,c ;01d6
+ sub 008h ;01d7
+ ld c,a ;01d9
+ djnz ??sr_1 ;01da
+
+ slp ;01dc should never be reached
+
+alloc:
+ out0 (cbr),c ;01de
+ ld sp,$stack ;01e1
+
+; Clear RAM using DMA0
+
+ ld hl,dmclrt ;load DMA registers
+ call io.ini.m
+ ld a,0cbh ;01ef dst +1, src fixed, burst
+ out0 (dmode),a ;01f1
+
+ ld b,512/64
+ ld a,062h ;01f4 enable dma0,
+??cl_1:
+ out0 (dstat),a ;01f9 clear (up to) 64k
+ djnz ??cl_1 ; end of RAM?
+
+; Init bank manager
+
+ ld hl,banktabsys ;020f
+ ld (hl),c ; Common area
+ inc hl ;0213
+ ld (hl),c ; System work area
+ inc hl ;0215 Point to bank 0 entry
+ ld b,BANKS ;0216
+l0218h:
+ ld (hl),0ffh ;0218 Mark all banks as unassigned
+ inc hl ;021a
+ djnz l0218h ;021b
+
+ ld hl,memalv ;
+ ld b,8 ; 8*4k ie. first 32k
+??a_0:
+ ld (hl),0e0h ; mark as sys ("rom"/monitor)
+ inc hl
+ djnz ??a_0
+
+ rr d ; shift out bit for block 0
+ rr e ;
+ ld c,15 ;022c 15*32k remaining blocks
+l022eh:
+ ld a,0feh ; 0xfe == block with error(s)
+ rr d ;
+ rr e
+ adc a,0 ; ==> 0xff : block ok
+ ld b,32/4 ; 32k == 8 * 4k
+l0236h:
+ ld (hl),a ;
+ inc hl ;
+ djnz l0236h ;
+ dec c ;
+ jr nz,l022eh ;next 32k block
+
+ ld hl,memalv+0ch ;memalv+0ch
+ ld a,(banktabsys) ;
+ call add_hl_a
+ ld b,3 ;
+l024ah:
+ ld (hl),0ech ;alloc system ram
+ inc hl ;
+ djnz l024ah ;
+ ld (hl),0efh ;alloc common
+ call gencrc_alv
+
+ ld hl,0000h ;bank #
+ ld bc,0f0fh ; size (?) (4k blocks)
+ xor a ;
+ call sub_0420h ;alloc mem for bank 0
+ ld c,l ;
+ or a ;
+ call z,sub_04b5h ;
+
+ ld hl,0101h ;
+ ld bc,0f0fh ;
+ xor a ;
+ call sub_0420h ;
+ ld c,l ;
+ or a ;
+ call z,sub_04b5h ;
+
+ ld hl,055AAh ;set warm start mark
+ ld (mark_55AA),hl ;
+ ld (mark_55AA+2),hl;
+
+;
+; crc ok -- wstart --
+;
+wstart:
+ call sysram_init ;027f
+ call ivtab_init
+
+ call prt0_init
+
+
+ call bufferinit
+
+
+ call $coninit
+
+
+
+
+ im 2 ;?030e
+ ei ;0282
+
+ call $cists ;0284
+ call $cists ;0287
+ or a ;028a
+ call nz,$ci ;028d
+
+ ld a,(banktab) ;
+ ld e,a ;
+ jp ddtz ;0290
+
+
+;
+;----------------------------------------------------------------------
+;
+
+ extrn msginit,msg.sout,msg_fifo
+ extrn tx.buf,rx.buf
+
+
+;TODO: Make a ringbuffer module.
+
+ global buf.init
+
+buf.init:
+ ld (ix+o.in_idx),0
+ ld (ix+o.out_idx),0
+ ld (ix+o.mask),a
+ ret
+
+;----------------------------------------------------------------------
+
+bufferinit:
+ call msginit
+
+ ld hl,buffers
+ ld bc,0300h
+bfi_1:
+ ld e,(hl)
+ inc hl
+ ld d,(hl)
+ inc hl
+ push hl
+ in0 a,cbr
+ call log2phys
+ ld (bufdat+1),hl
+ ld (bufdat+3),a
+ ld a,c
+ ld (bufdat+0),a
+ ld hl,inimsg
+ call msg.sout
+ pop hl
+ inc c
+ djnz bfi_1
+ ret
+
+ rept 20
+ db 0
+ endm
+
+buffers:
+ dw msg_fifo
+ dw tx.buf
+ dw rx.buf
+
+inimsg:
+ db inimsg_e - $ -2
+ db PMSG
+ db 81h
+ db inimsg_e - $ -1
+ db 0
+bufdat:
+ db 0
+ dw 0
+ db 0
+inimsg_e
+
+;
+;----------------------------------------------------------------------
+;
+
+sysram_init:
+ ld hl,sysramw
+ ld de,topcodsys
+ ld bc,sysrame-sysramw
+ ldir
+
+ ret
+
+;----------------------------------------------------------------------
+
+ivtab_init:
+ ld hl,ivtab ;
+ ld a,h ;
+ ld i,a ;
+ out0 (il),l ;
+
+; Let all vectors point to spurious int routines.
+
+ ld d,high sp.int0
+ ld a,low sp.int0
+ ld b,9
+ivt_i1:
+ ld (hl),a
+ inc l
+ ld (hl),d
+ inc l
+ add a,sp.int.len
+ djnz ivt_i1
+ ret
+
+
+prt0_init:
+ ld a,i
+ ld h,a
+ in0 a,(il)
+ and 0E0h
+ or IV$PRT0
+ ld l,a
+ ld (hl),low iprt0
+ inc hl
+ ld (hl),high iprt0
+ ld hl,prt0itab
+ call io.ini.m
+ ret
+
+prt0itab:
+ db prt0it_e-prt0itab-2
+ db tmdr0l
+ dw PRT_TC10MS
+ dw PRT_TC10MS
+ db M_TIE0+M_TDE0 ;enable timer 0 interrupt and down count.
+prt0it_e:
+
+;
+;----------------------------------------------------------------------
+;
+
+io.ini:
+ push bc
+ ld b,0 ;high byte port adress
+ ld a,(hl) ;count
+ inc hl
+ioi_1:
+ ld c,(hl) ;port address
+ inc hl
+ outi
+ inc b ;outi decrements b
+ dec a
+ jr nz,ioi_1
+ pop bc
+ ret
+
+io.ini.m:
+ push bc
+ ld b,(hl)
+ inc hl
+ ld c,(hl)
+ inc hl
+ otimr
+ pop bc
+ ret
+
+io.ini.l:
+;
+
+;----------------------------------------------------------------------
+;
+
+; compute crc
+; hl: start adr
+; bc: len
+; bc returns crc val
+
+do_crc16:
+ ld de,0FFFFh
+crc1:
+ ld a,(hl)
+ xor e
+ ld e,a
+ rrca
+ rrca
+ rrca
+ rrca
+ and 0Fh
+ xor e
+ ld e,a
+ rrca
+ rrca
+ rrca
+ push af
+ and 1Fh
+ xor d
+ ld d,a
+ pop af
+ push af
+ rrca
+ and 0F0h
+ xor d
+ ld d,a
+ pop af
+ and 0E0h
+ xor e
+ ld e,d
+ ld d,a
+ cpi
+ jp pe,crc1
+ or e ;z-flag
+ ret
+
+
+gencrc_alv:
+ push hl ;03f6
+ push de ;03f7
+ push bc
+ push af ;03f8
+ ld hl,banktabsys ;03f9
+ ld bc,crc_len ;03fc
+ call do_crc16 ;03ff
+ ld (hl),e
+ inc hl
+ ld (hl),d
+ pop af ;0406
+ pop bc
+ pop de ;0407
+ pop hl ;0408
+ ret ;0409
+
+checkcrc_alv:
+ push hl ;040a
+ push de
+ push bc ;040b
+ ld hl,banktabsys ;040d
+ ld bc,crc_len+2 ;0410
+ call do_crc16 ;0413
+ pop bc ;041d
+ pop de
+ pop hl ;041e
+ ret ;041f
+
+;
+; alloc
+;
+; h: max bank #
+; l: min bank #
+; b: max size
+; c: min size
+;
+; ret:
+; a: 0 == ok
+; 1 ==
+; 2 == no bank # in requested range
+; ff == crc error
+;
+
+sub_0420h:
+ call checkcrc_alv ;0420
+ jr nz,l049ch ;0424 crc error, tables corrupt
+
+ call sub_049dh ;0427 bank # in req. range available?
+ jr c,l0499h ;042a
+ push ix ;042c
+ push iy ;042e
+ push de ;0430
+ push hl ;0431
+ push bc ;0432
+ ld c,b ;0433
+ ld b,alv_len+1 ;0434
+ ld d,0 ;0436
+ ld hl,memalv-1 ;0438
+ jr l0441h ;043b
+
+; find free blocks
+
+l043dh:
+ ld a,(hl) ;043d
+ inc a ;043e free blocks are marked 0ffh
+ jr z,l0446h ;043f
+l0441h:
+ inc hl ;0441
+ djnz l043dh ;0442
+ jr l0464h ;0444
+l0446h:
+ push hl ;0446
+ pop ix ;0447 free blocks start here
+ ld e,000h ;0449
+ jr l0451h ;044b
+l044dh: ; count free blocks
+ ld a,(hl) ;044d
+ inc a ;044e
+ jr nz,l0457h ;044f
+l0451h:
+ inc e ;0451
+ inc hl ;0452
+ djnz l044dh ;0453
+ jr l0464h ;0455
+
+; end of free blocks run.
+
+l0457h:
+ ld a,d ;0457
+ cp e ;0458 nr of blocks >= requested ?
+ jr nc,l0441h ;0459
+
+ ld d,e ;045b
+ push ix ;045c
+ pop iy ;045e
+ ld a,d ;0460
+ cp c ;0461
+ jr c,l0441h ;0462
+l0464h:
+ pop bc ;0464
+ ld a,d ;0465
+ cp b ;0466
+ jr c,l046ch ;0467
+ ld d,b ;0469
+ jr l0471h ;046a
+l046ch:
+ cp c ;046c
+ jr nc,l0471h ;046d
+ ld d,000h ;046f
+l0471h:
+ ld a,d ;0471
+ push iy ;0472
+ pop hl ;0474
+ ld de,memalv ;0475
+ or a ;0478
+ sbc hl,de ;0479
+ ld b,l ;047b
+ ld c,a ;047c
+ pop hl ;047d
+l047eh:
+ or a ;047e
+ jr z,l0489h ;047f
+ ld (iy+0),l ;0481
+ inc iy ;0484
+ dec a ;0486
+ jr l047eh ;0487
+l0489h:
+ pop de ;0489
+ pop iy ;048a
+ pop ix ;048c
+ call gencrc_alv ;048e
+ ld a,c ;0491
+ or a ;0492
+ ld a,000h ;0493
+ ret nz ;0495
+ or 001h ;0496
+ ret ;0498
+
+l0499h:
+ ld a,2 ;0499
+l049ch:
+ or a
+ ret ;049c
+
+
+; search a free bank number in range
+; h: max #
+; l: min #
+; ret:
+; l: bank number available
+; nc, if found, bank nr. in l
+; cy, if none found
+
+sub_049dh:
+ push de ;049d
+ push bc ;049e
+ ex de,hl ;049f
+ dec e ;04a0
+l04a1h:
+ inc e ;04a1 test next #
+ ld a,d ;04a2
+ cp e ;04a3
+ jr c,l04b1h ;04a4
+ ld a,e ;04a6
+ ld hl,memalv ;04a7
+ ld bc,alv_len ;04aa
+ cpir ;04ad bank# allready allocated?
+ jr z,l04a1h ;04af if yes, search for next
+l04b1h:
+ ex de,hl ;04b1
+ pop bc ;04b2
+ pop de ;04b3
+ ret ;04b4
+
+
+sub_04b5h:
+ ld a,l ;04b5
+ cp 012h ;04b6
+ ccf ;04b8
+ ret c ;04b9
+ push hl ;04ba
+ ld hl,banktab ;04bb
+ call add_hl_a
+ ld (hl),b ;04c3
+ call gencrc_alv ;04c4
+ pop hl ;04c7
+ or a ;04c8 clear carry
+ ret ;04c9
+
+
+;--------------------------------------------------------------
+;
+; de: Log. Address
+; a: Bank number
+;
+;out ahl: Phys. (linear) Address
+
+
+bnk2phys:
+ push hl
+ ld hl,banktab
+ call add_hl_a
+ ld a,(hl)
+ pop hl
+
+ ; fall thru
+;--------------------------------------------------------------
+;
+; de: Log. Address
+; a: Bank (bbr)
+;
+; OP: ahl = (a<<12) + (d<<8) + e
+;
+;out ehl: Phys. (linear) Address
+
+
+log2phys:
+ push bc ;
+ ld c,a ;
+ ld b,16 ;
+ mlt bc ;bc = a<<4
+ ld l,d ;
+ ld h,0 ;
+ add hl,bc ;bc + d == a<<4 + d
+ ld a,h ;
+ ld h,l ;
+ ld l,e ;
+ pop bc ;
+ ret ;
+
+
+;--------------------------------------------------------------
+;
+;return:
+; hl = hl + a
+; Flags undefined
+;
+
+add_hl_a:
+ add a,l
+ ld l,a
+ ret nc
+ inc h
+ ret
+
+; ---------------------------------------------------------
+
+sysramw:
+
+ .phase isvsw_loc
+topcodsys:
+
+; Trampoline for interrupt routines in banked ram.
+; Switch stack pointer to "system" stack in top ram
+; Save cbar
+
+isv_sw: ;
+ ex (sp),hl ; save hl, return adr in hl
+ push de ;
+ push af ;
+ ex de,hl ;
+ ld hl,0 ;
+ add hl,sp ;
+ ld a,h ;
+ cp 0f8h ;
+ jr nc,isw_1 ;
+ ld sp,$stack ;
+isw_1:
+ push hl ;
+ in0 h,(cbar) ;
+ push hl ;
+ ld a,SYS$CBAR ;
+ out0 (cbar),a ;
+ ex de,hl ;
+ ld e,(hl) ;
+ inc hl ;
+ ld d,(hl) ;
+ ex de,hl ;
+ push bc ;
+ call jphl ;
+
+ pop bc ;
+ pop hl ;
+ out0 (cbar),h ;
+ pop hl ;
+ ld sp,hl ;
+ pop af ;
+ pop de ;
+ pop hl ;
+ ei ;
+ ret ;
+jphl:
+ jp (hl) ;
+
+; ---------------------------------------------------------
+
+iprt0:
+ push af
+ push hl
+ in0 a,(tcr)
+ in0 a,(tmdr0l)
+ in0 a,(tmdr0h)
+ ld a,(tim_ms)
+ inc a
+ cp 100
+ jr nz,iprt_1
+ xor a
+ ld hl,(tim_s)
+ inc hl
+ ld (tim_s),hl
+iprt_1:
+ ld (tim_ms),a
+ pop hl
+ pop af
+ ei
+ ret
+
+; ---------------------------------------------------------
+
+sp.int0:
+ ld a,0d0h
+ jr sp.i.1
+sp.int.len equ $-sp.int0
+ ld a,0d1h
+ jr sp.i.1
+ ld a,0d2h
+ jr sp.i.1
+ ld a,0d3h
+ jr sp.i.1
+ ld a,0d4h
+ jr sp.i.1
+ ld a,0d5h
+ jr sp.i.1
+ ld a,0d6h
+ jr sp.i.1
+ ld a,0d7h
+ jr sp.i.1
+ ld a,0d8h
+sp.i.1:
+; out (80h),a
+ halt
+
+curph defl $
+ .dephase
+sysrame:
+ .phase curph
+tim_ms: db 0
+tim_s: dw 0
+ .dephase
+
+;-----------------------------------------------------
+
+ dseg
+
+ ds 1
+banktabsys:
+ ds 1 ;0c001h
+ ds 1 ;0c002h
+banktab:
+ ds BANKS ;0c003h
+memalv:
+ ds 512/4 ;Number of 4k blocks
+alv_len equ $-memalv
+crc_len equ $-banktabsys
+
+crc_memalv:
+ ds 2 ;
+
+ cseg
+
+ ;.phase 0ffc0h
+;ivtab equ 0ffc0h ; 0ffc0h ;int vector table
+ ;.dephase
+
+ ;.phase 0fffch
+mark_55AA equ 0fffch
+ ;ds 4 ; 0fffch
+ ;.dephase
+
+
+ end
+