From f4d5b4febbffab80cb06bd18564d4c326756fad7 Mon Sep 17 00:00:00 2001 From: Leo C Date: Wed, 2 Jul 2014 14:33:22 +0200 Subject: Rename dir Z180 --> z180 --- z180/r3init.180 | 875 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 875 insertions(+) create mode 100644 z180/r3init.180 (limited to 'z180/r3init.180') diff --git a/z180/r3init.180 b/z180/r3init.180 new file mode 100644 index 0000000..83bdbe5 --- /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 + -- cgit v1.2.3