title 'bank & move module for CP/M3 linked BIOS' ; use M80 to assemble true equ -1 false equ 0 banked equ true ; banked version .z80 entry ?move,?xmove,?bank if banked entry ?bank0,?rbank,?trans,@xsp,@xmvst external @cbnk endif cseg ?move: if banked ld a,(@xmvst) ; get xmove status and a ; set flags endif ex de,hl ; we are passed source in DE and dest in HL if banked jr nz,ibnk ; interbank transfer endif ldir ; use Z80 block move instruction ex de,hl ; need next addresses in same regs ret if banked ibnk: ; interbank transfer xor a ; clear a ld (@xmvst),a ; reset xmove status ld (@xsp),sp ; switch stack ld sp,@xsp ld a,(xmvsou) ; source bank call ?bank ; set bank push de ; keep destination push bc ; keep length ld de,ibuff ; buffer in common memory ldir ; copy to buffer ld a,(xmvdes) ; destination bank call ?bank ; set bank pop bc ; get length ex (sp),hl ; dest in hl, end of source in stack ex de,hl ; destination in de ld hl,ibuff ; buffer in common memory ldir ; copy from buffer ex de,hl ; end of destination in hl pop de ; end of source in de ld a,(@cbnk) ; bank we started with call ?bank ; restore bank ld sp,(@xsp) ; restore stack ret ?bank: out (0feh),a ; switch board and a ; to get flags ld a,0 ; clear a jr nz,zero ; disk contr on for bank zero inc a ; set a to 1 zero: out (40h),a ; switch disk controller ret ?bank0: ; get bank 0 pop hl ; get return address ld (@xsp),sp ; store stack pointer ld sp,@xsp ; use temporary stack in common memory push af xor a ; a=0 call ?bank ; set bank pop af jp (hl) ; return ?rbank: ; restore bank pop hl ; get return address push af ld a,(@cbnk) ; get last bank call ?bank ; set bank pop af ld sp,(@xsp) ; restore stack pointer jp (hl) ; return ?trans: ; transfer a series of 128 byte blocks ; from one bank to another ; a = number of blocks ; b = destination bank ; c = source bank ; de = source initial location ; hl = destination initial location and a ; check a non-zero ret z ex de,hl ; source in hl, destination in de ld (xtrsou),bc ; remember bc ld (@xsp),sp ; set up stack in common memory ld sp,@xsp ld b,a ; number of blocks tloop: push bc ; keep block count ld a,(xtrsou) ; source bank call ?bank push de ; destination on stack ld de,ibuff ; 128 byte buffer ld bc,128 ldir ; copy to common memory ld a,(xtrdes) ; destination bank call ?bank ex (sp),hl ; source on stack, destination in hl ex de,hl ; destination in de ld hl,ibuff ; 128 byte buffer ld bc,128 ldir ; copy from common memory pop hl ; source on hl pop bc ; get back block count djnz tloop ; loop ex de,hl ; to conform to DR's convention ld a,(@cbnk) ; restore bank call ?bank ld sp,(@xsp) ; restore stack ret ds 16 ; temporary stack @xsp: ds 2 ; temporary storage for sp xmvsou: ds 1 ; source bank xmvdes: ds 1 ; destination bank @xmvst: db 0 ; xmove status (0ffh for interbank mv) xtrsou: ds 1 ; source bank used by transfer xtrdes: ds 1 ; destination bank used by transfer ibuff: ds 128 ; buffer for interbank move dseg ?xmove: ; setup interbank move ld (xmvsou),bc ; load source & destination banks ld a,0ffh ld (@xmvst),a ; xmove status ret else ?bank: ; dummy routines for unbanked system ?xmove: ret endif end