title 'Bank & Move Module for the Modular CP/M 3 BIOS' ; CP/M-80 Version 3 -- Modular BIOS ; Bank and Move Module for Z180-Stamp ; Initial version 1.0 ; Compile with M80, slr180, or compatible public ?move,?xmove,?bank extrn bnk2log,bnk2phy extrn @cbnk maclib z180reg.inc maclib config.inc cseg ; must be in common memory ?xmove: if banked ld (src$bnk),bc ; c -> src$bnk, b -> dst$bnk endif ret ?move: ex de,hl ; we are passed source in DE and dest in HL if banked ld a,(src$bnk) ; contains 0FEh if normal block move cp 0FEh jr nz,inter_bank_move endif ldir ; use Z80 block move instruction ex de,hl ; need next address in same regs ret ; select bank in A ?bank: if banked call bnk2log out0 (bbr),a endif ret if banked inter_bank_move: ; source in HL, dest in DE, count in BC if 1 ; works with new memory map out0 (bcr0l),c ; setup DMA count out0 (bcr0h),b push hl push de ld a,(src$bnk) call bnk2phy out0 (sar0l),l ; setup DMA src address out0 (sar0h),h out0 (sar0b),a ex de,hl ld a,(dst$bnk) call bnk2phy out0 (dar0l),l ; setup DMA dst address out0 (dar0h),h out0 (dar0b),a ld a,M_MMOD ; DMA burst mode out0 (dmode),a ld a,M_DE0+M_NDWE1 ; enable DMA0 out0 (dstat),a ; move the block pop de pop hl add hl,bc ; src must point past end block ex de,hl add hl,bc ; and so must dst ld bc,0 ld a,0FEh ld (src$bnk),a ret ; return with src in DE, dst in HL, count = 0 else ; inefficient fall back ld (tmp$sp),sp ld sp,tmp$stk ex af,af' ; push af mv$blk: ld a,(src$bnk) ; call ?bank ld a,(hl) ex af,af' ; ld a,(dst$bnk) call ?bank ex af,af' ; ld (de),a inc de cpi jp pe,mv$blk ld a,(@cbnk) call ?bank ld a,0FEh ld (src$bnk),a ex de,hl pop af ex af,af' ; ld sp,(tmp$sp) ret ds 16 tmp$stk: tmp$sp: ds 2 endif src$bnk: db 0FEh dst$bnk: db 0FEh endif ;banked end