.z80\r
\r
\r
- global mmuinit\r
- global bnk2log,bnk2phy,hwl2phy,phy2log\r
+ public mmuinit\r
+ public bnk2log,bnk2phy,hwl2phy,phy2log\r
+ public isv_sw\r
+ public b_ld_a,b_ld_hl,b_st_a,b_st_hl\r
\r
- include config.inc\r
- include z180reg.inc\r
+\r
+ extrn @cbnk\r
+ extrn ijphl\r
+\r
+\r
+ maclib z180reg.inc\r
+ maclib config.inc\r
\r
\r
;----------------------------------------------------------------------\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
+\r
+ if 0\r
+\r
_b0call:\r
push af\r
in0 a,(bbr)\r
ld sp,hl ;\r
ld hl,(b0_save_hl)\r
ret ;\r
+ else\r
+\r
+_b0call:\r
+ push af\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
+ endif\r
\r
b0_save_hl: dw 0\r
b0_save_de: dw 0\r
b0_save_af: dw 0\r
\r
\r
+;--------------------------------------------------------------------\r
+; Trampoline for interrupt routines in banked ram.\r
+; Switch stack pointer to "system" stack in top ram\r
+; Save bbr\r
+\r
+ cseg\r
+\r
+ if 0\r
+\r
+isv_sw: ;\r
+ ex (sp),hl ;save hl, 'return adr' in hl\r
+ push de ;\r
+ push af ;\r
+ ex de,hl ;'return address' in de\r
+\r
+ if 0\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
+ else\r
+ ld hl,0\r
+ add hl,sp\r
+ ld sp,istack\r
+ endif\r
+ push hl ;save user stack pointer\r
+ in0 h,(bbr) ;\r
+ push hl ;\r
+ xor a ;\r
+ out0 (bbr),a ;\r
+ ex de,hl ;\r
+ ld e,(hl) ;\r
+ inc hl ;\r
+ ld d,(hl) ;\r
+ ex de,hl ;\r
+ push bc ;\r
+ call ijphl ;\r
+\r
+ pop bc ;\r
+ pop hl ;\r
+ out0 (bbr),h ;\r
+ pop hl ;\r
+ ld sp,hl ;\r
+ pop af ;\r
+ pop de ;\r
+ pop hl ;\r
+ ei ;\r
+ ret ;\r
+\r
+ else\r
+\r
+isv_sw: ;\r
+ ex (sp),hl ;save hl, 'return adr' in hl\r
+\r
+ ld (i$stack),sp ;save user stack pointer\r
+ ld sp,i$stack\r
+ push de ;\r
+ push bc ;\r
+ push af ;\r
+ in0 a,(bbr) ;\r
+ push af ;\r
+ xor a ;\r
+ out0 (bbr),a ;\r
+ ld e,(hl) ;\r
+ inc hl ;\r
+ ld d,(hl) ;\r
+ ex de,hl ;\r
+ call ijphl ;\r
+\r
+ pop af ;\r
+ out0 (bbr),a ;\r
+ pop af ;\r
+ pop bc ;\r
+ pop de ;\r
+ ld sp,(i$stack) ;\r
+ pop hl ;\r
+ ei ;\r
+ ret ;\r
+\r
+ endif\r
+\r
+ public i$stack\r
+ rept 24\r
+ db '|'\r
+ endm\r
+i$stack:\r
+ dw 0\r
+\r
+ dseg\r
+\r
+;--------------------------------------------------------------------\r
+; Load byte/word from user ram\r
+;\r
+; de: src address in users bank\r
+; return\r
+; a: value (byte)\r
+; hl: value (word)\r
+\r
+b_ld_a:\r
+ push hl\r
+ or a ; clear carry == byte store\r
+ jr $+3\r
+b_ld_hl:\r
+ scf ; set carry == word store\r
+ push af ; save flag\r
+ push hl ; make space on stack\r
+\r
+ ld a,(@cbnk)\r
+ ld b,a ; b = src bank\r
+\r
+ ld hl,0\r
+ ld a,l\r
+ ld c,l ; c = dst bank (0)\r
+ add hl,sp ; hl = dst\r
+ adc a,1 ; a = count\r
+ ex de,hl\r
+ call dma_move\r
+ ex de,hl\r
+ pop hl\r
+ pop af\r
+ ret c\r
+ ld a,l\r
+ pop hl\r
+ ret\r
+\r
+;--------------------------------------------------------------------\r
+; Store byte/word to user ram\r
+;\r
+; de: dst address in users bank\r
+; a: value (byte)\r
+; hl: value (word)\r
+\r
+b_st_a:\r
+ push hl\r
+ ld l,a\r
+ or a ; clear carry == byte store\r
+ jr $+3\r
+b_st_hl:\r
+ scf ; set carry == word store\r
+ push af ; save flag\r
+ push hl ; put value on stack\r
+\r
+ ld a,(@cbnk) ;\r
+ ld c,a ; c = dst bank\r
+ ld a,0\r
+ ld l,a\r
+ ld h,a\r
+ ld b,a ; b = src bank (0)\r
+ add hl,sp ; hl = src\r
+ adc a,1 ; a = count\r
+\r
+ call dma_move\r
+\r
+ pop hl ; restore value\r
+ pop af ; carry\r
+ ret c\r
+ pop hl\r
+ ret\r
+\r
+;--------------------------------------------------------------------\r
+;\r
+; hl: src\r
+; de: dst\r
+; b: src bank\r
+; c: dst bank\r
+; a: count\r
+\r
+dma_move:\r
+ out0 (bcr0l),a ; setup DMA count\r
+ xor a\r
+ out0 (bcr0h),a\r
+\r
+ push hl\r
+ ld a,b\r
+ call bnk2phy\r
+ out0 (sar0l),l ; setup DMA src address\r
+ out0 (sar0h),h\r
+ out0 (sar0b),a\r
+\r
+ ld l,e\r
+ ld h,d\r
+ ld a,c\r
+ call bnk2phy\r
+ out0 (dar0l),l ; setup DMA dst address\r
+ out0 (dar0h),h\r
+ out0 (dar0b),a\r
+\r
+ ld a,M_MMOD ; DMA burst mode\r
+ out0 (dmode),a\r
+ ld a,M_DE0+M_NDWE1 ; enable DMA0\r
+ out0 (dstat),a ; move ...\r
+ pop hl\r
+ ret\r
+\r
\r
;====================================================================\r
\r
+ cseg\r
+\r
if 0\r
\r
;--------------------------------------------------------------------\r
endif\r
\r
\r
+ cseg\r
+ public bs$stack\r
+\r
+ rept bs$stack$size\r
+ db '|'\r
+ endm\r
+bs$stack:\r
+ dw 0\r
+\r
end\r