page 255 .z80 extrn ddtz,bpent extrn $stack extrn charini,?const,?conin extrn ?cono,?conos extrn romend global iobyte global isv_sw include config.inc if CPU_Z180 include z180reg.inc include z180.lib endif ;---------------------------------------------------------------------- cseg romstart equ $ org romstart+0 jp start iobyte: db 2 ; restart vectors rsti defl 1 rept 7 org 8*rsti + romstart jp bpent rsti defl rsti+1 endm ;---------------------------------------------------------------------- ; Config space ; org romstart+40h dw 0 db 0 if ROMSYS $crom: defb c$rom ; else db 0 ; endif INIWAITS defl CWAITIO if ROMSYS INIWAITS defl INIWAITS+CWAITROM endif ;---------------------------------------------------------------------- org romstart+50h start: jp cstart jp wstart jp ?const jp ?conin jp ?cono jp ?conos jp charini ;---------------------------------------------------------------------- hwini0: if CPU_Z180 db ;count db rcr,CREFSH ;configure DRAM refresh db dcntl,INIWAITS ;wait states db cbr,SYS$CBR db cbar,SYS$CBAR endif db 0 if CPU_Z180 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: db 0 endif cstart: if CPU_Z180 push af in0 a,(itc) ;Illegal opcode trap? jp m,??st01 ld a,i ;I register == 0 ? jr z,hw_reset ; yes, harware reset ??st01: ; TODO: SYS$CBR ld a,(syscbr) out0 (cbr),a pop af ;restore registers jp bpent ; hw_reset: di ;0058 ld a,CREFSH out0 (rcr),a ; configure DRAM refresh ld a,CWAITIO out0 (dcntl),a ; wait states ld a,M_NCD ;No Clock Divide out0 (ccr),a ; ld a,M_X2CM ;X2 Clock Multiplier ; out0 (cmr),a else di xor a ld (@cbnk),a endif ; check warm start mark ld ix,mark_55AA ; top of common area ld a,0aah ; cp (ix+000h) ; jr nz,kstart ; cp (ix+002h) ; jr nz,kstart ; cpl ; cp (ix+001h) ; jr nz,kstart ; cp (ix+003h) ; jr nz,kstart ; ld sp,$stack ; mark found, check jp z,wstart ; check ok, ; ram not ok, initialize -- kstart -- kstart: if CPU_Z180 ld a,SYS$CBR ;TODO: out0 (cbr),a ld a,SYS$CBAR out0 (cbar),a endif ld sp,$stack ;01e1 ; Clear RAM using DMA0 if CPU_Z180 if 0 ld hl,dmclrt ;load DMA registers call ioiniml 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? endif endif ld hl,055AAh ;set warm start mark ld (mark_55AA),hl ld (mark_55AA+2),hl ; -- wstart -- wstart: call sysram_init call ivtab_init if CPU_Z180 ; call prt0_init endif call msginit call charini if CPU_Z80 ld a,0 call selbnk endif ld a,INIDONEVAL ;tell others (CP/M) that hardware and fifos ld (INIDONE),a ; are allready initialized im 2 ei call ?const call ?const or a call nz,?conin if CPU_Z180 ld e,0 ;Sys$Bank else ; TODO: endif jp ddtz if CPU_Z180 ; TODO: SYS$CBR syscbr: db 0 endif ; ;---------------------------------------------------------------------- ; global bufinit 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 public fifolst fifolst : rept 4 dw 0 endm ;---------------------------------------------------------------------- extrn msg.sm extrn msginit,msg.sout extrn mtx.fifo,mrx.fifo extrn ff.init,co.fifo,ci.fifo fifoinit: if CPU_Z180 ret else ;CPU_Z180 call msginit ld hl,buffers ld b,buftablen bfi_1: ld a,(hl) inc hl ld (bufdat+0),a ld e,(hl) inc hl ld d,(hl) inc hl ex de,hl or a jr nz,bfi_2 ld a,(@cbnk) call bnk2phy ld (40h+0),hl ld (40h+2),a out (AVRINT5),a jr bfi_3 bfi_2: ld a,(@cbnk) call bnk2phy ld (bufdat+1),hl ld (bufdat+3),a ld hl,inimsg call msg.sout bfi_3: ex de,hl djnz bfi_1 ret endif ; ;---------------------------------------------------------------------- ; 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 ; if CPU_Z180 out0 (il),l ; endif ; 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 ;---------------------------------------------------------------------- ; Reload value for 10 ms Int. (0.1KHz): ; tc10ms = phi/prescale/0.1KHz = phi / (prescale/10) PRT_TC10MS equ 18432 / (PRT_PRE/10) if CPU_Z180 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 ioiniml 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: db 0 endif ; ;---------------------------------------------------------------------- ; if CPU_Z180 io.ini: if 0 push bc ld b,0 ;high byte port adress ioi_nxt: ld a,(hl) ;count inc hl or a jr z,ioi_e ld c,(hl) ;port address inc hl ioi_r: outi inc b ;outi decrements b dec a jr nz,ioi_r jr ioi_nxt ioi_e: pop bc ret else ;(if 1/0) push bc jr ioi_nxt ioi_l: ld c,(hl) ;port address inc hl inc c ioi_r: dec c ;otim increments c otim jr z,ioi_r ioi_nxt: ld b,(hl) ;count inc hl inc b ;stop if count == 0 djnz ioi_l pop bc ret endif ;(1/0) else io.ini: push bc jr ioi_nxt ioi_l: ld c,(hl) ;port address inc hl otir ioi_nxt: ld b,(hl) ;count inc hl inc b djnz ioi_l endif pop bc ret ;---------------------------------------------------------------------- if CPU_Z180 global ioiniml ioiniml: push bc xor a ioml_lp: ld b,(hl) inc hl cp b jr z,ioml_e ld c,(hl) inc hl otimr jr ioml_lp ioml_e: pop bc ret z endif io.ini.l: ; ;---------------------------------------------------------------------- ; if CPU_Z180 ;-------------------------------------------------------------------- ; Return the BBR value for the given bank number ; ; in a: Bank number ; out a: bbr value bnk2log: or a ; ret z ; Bank 0 is at physical address 0 push bc ; ld b,a ; ld c,CA ; mlt bc ; ld a,c ; add a,10h ; pop bc ; ret ; ;-------------------------------------------------------------- ;in hl: Log. Address ; a: Bank number ; ;out ahl: Phys. (linear) Address bnk2phy: call bnk2log ; 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) + (d<<8) + e ; ;out ahl: Phys. (linear) Address public hwl2phy 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 ; else ;CPU_Z180 ;---------------------------------------------------------------------- ; bnk2phy: sla h jr nc,b2p_1 ;A15=1 --> common ld a,3 b2p_1: srl a rr h ret endif ;-------------------------------------------------------------- ; ;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 ;'return address' in de ld hl,0 ; add hl,sp ; ld a,h ; cp 0f8h ; jr nc,isw_1 ;stack allready in top ram ld sp,$stack ; isw_1: push hl ;save user stack pointer 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) ; ; --------------------------------------------------------- if CPU_Z180 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 endif ; --------------------------------------------------------- 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 ; --------------------------------------------------------- if CPU_Z80 ; Get IFF2 ; This routine may not be loaded in page zero ; ; return Carry clear, if INTs are enabled. ; global getiff getiff: xor a ;clear accu and carry push af ;stack bottom := 00xxh pop af ld a,i ;P flag := IFF2 ret pe ;exit carry clear, if enabled dec sp dec sp ;has stack bottom been overwritten? pop af and a ;if not 00xxh, INTs were ret nz ;actually enabled scf ;Otherwise, they really are disabled ret ;---------------------------------------------------------------------- global selbnk ; a: bank (0..2) selbnk: push bc ld c,a call getiff push af ld a,c di ld (@cbnk),a ld a,5 out (SIOAC),a ld a,(mm_sio0) rla srl c rra out (SIOAC),a ld (mm_sio0),a ld a,5 out (SIOBC),a ld a,(mm_sio1) rla srl c rra out (SIOBC),a ld (mm_sio1),a pop af pop bc ret c ;INTs were disabled ei ret ;---------------------------------------------------------------------- ; c: bank (0..2) if 0 selbnk: ld a,(@cbnk) xor c and 3 ret z ;no change call getiff push af ld a,c di ld (@cbnk),a ld a,5 out (SIOAC),a ld a,(mm_sio0) rla srl c rra out (SIOAC),a ld (mm_sio0),a ld a,5 out (SIOBC),a ld a,(mm_sio1) rla srl c rra out (SIOBC),a ld (mm_sio1),a pop af ret nc ;INTs were disabled ei ret endif ;---------------------------------------------------------------------- if 0 ex af,af' push af ex af,af' rra jr nc,stbk1 ex af,af' ld a,5 out (SIOAC),a ld a,(mm_sio0) rla srl c rra out (SIOAC),a ld (mm_sio1),a ex af,af' stbk1: rra jr nc,stbk2 ex af,af' ld a,5 out (SIOBC),a ld a,(mm_sio1) rla srl c rra out (SIOBC),a ld (mm_sio1),a ex af,af' stbk2: endif global @cbnk global mm_sio0, mm_sio1 @cbnk: db 0 ; current bank (0..2) mm_sio0: ds 1 mm_sio1: ds 1 endif ;---------------------------------------------------------------------- curph defl $ .dephase sysrame: .phase curph tim_ms: db 0 tim_s: dw 0 .dephase ;----------------------------------------------------- cseg ;.phase 0ffc0h ;ivtab equ 0ffc0h ; 0ffc0h ;int vector table ;.dephase ;.phase 0fffah mark_55AA equ 0 - 2 - 4 ;2 byte for trap stack ;ds 4 ;.dephase end