mirror of
https://github.com/wwarthen/RomWBW.git
synced 2026-02-06 14:11:48 -06:00
Improve Z280 DMA Memory Copy
The Z280 interbank memory copy uses DMA and did not properly handle scenarios where the source or destination memory range crossed over the banked/common memory boundary. It added a bunch of code, but it is fixed now. This seems to be required by CP/M 3.
This commit is contained in:
@@ -561,7 +561,7 @@ HBX_MMA .DB 0 ; TEMPORARY STORAGE FOR REG A
|
||||
HBX_BNKCPY:
|
||||
#IF (MEMMGR == MM_Z280)
|
||||
.DB $ED,$71 ; SC
|
||||
.DW Z280_BNKCPY ; SC PARAMETER
|
||||
.DW Z280_BNKCPYX ; SC PARAMETER
|
||||
RET
|
||||
#ELSE
|
||||
#IF (CPUFAM == CPU_Z280)
|
||||
@@ -2600,6 +2600,71 @@ HB_WDZ:
|
||||
INITSYS3:
|
||||
CALL PRTSUM ; PRINT UNIT/DEVICE SUMMARY TABLE
|
||||
;
|
||||
#IF 0
|
||||
CALL NEWLINE
|
||||
CALL NEWLINE
|
||||
CALL NEWLINE
|
||||
|
||||
; SRC & DEST BELOW BND
|
||||
CALL NEWLINE
|
||||
LD HL,$4000
|
||||
LD DE,$5000
|
||||
LD BC,$3000
|
||||
CALL NEWLINE
|
||||
CALL REGDMP
|
||||
CALL Z280_BNKCPYX
|
||||
|
||||
; SRC & DEST ABOVE BND
|
||||
CALL NEWLINE
|
||||
LD HL,$8000
|
||||
LD DE,$9000
|
||||
LD BC,$1000
|
||||
CALL NEWLINE
|
||||
CALL REGDMP
|
||||
CALL Z280_BNKCPYX
|
||||
|
||||
; SRC CROSSOVER
|
||||
CALL NEWLINE
|
||||
LD HL,$7000
|
||||
LD DE,$9000
|
||||
LD BC,$2000
|
||||
CALL NEWLINE
|
||||
CALL REGDMP
|
||||
CALL Z280_BNKCPYX
|
||||
|
||||
; DEST CROSSOVER
|
||||
CALL NEWLINE
|
||||
LD HL,$9000
|
||||
LD DE,$7000
|
||||
LD BC,$2000
|
||||
CALL NEWLINE
|
||||
CALL REGDMP
|
||||
CALL Z280_BNKCPYX
|
||||
|
||||
; DOUBLE CROSSOVER
|
||||
CALL NEWLINE
|
||||
LD HL,$7800
|
||||
LD DE,$7000
|
||||
LD BC,$2000
|
||||
CALL NEWLINE
|
||||
CALL REGDMP
|
||||
CALL Z280_BNKCPYX
|
||||
|
||||
; DOUBLE CROSSOVER SINGLE BYTES
|
||||
CALL NEWLINE
|
||||
LD HL,$7FFE
|
||||
LD DE,$7FFF
|
||||
LD BC,$0500
|
||||
CALL NEWLINE
|
||||
CALL REGDMP
|
||||
CALL Z280_BNKCPYX
|
||||
|
||||
CALL NEWLINE
|
||||
CALL NEWLINE
|
||||
CALL NEWLINE
|
||||
;
|
||||
#ENDIF
|
||||
;
|
||||
INITSYS4:
|
||||
;
|
||||
#IF (MEMMGR == MM_Z280)
|
||||
@@ -5209,8 +5274,115 @@ Z280_BNKSEL_LEN .EQU $ - Z280_BNKSEL
|
||||
;
|
||||
; Z280 BANK COPY (CALLED FROM PROXY)
|
||||
;
|
||||
; USE Z280 PHYSICAL MEMORY DMA COPY TO PERFORM AN INTERBANK COPY.
|
||||
; COPY FROM (HB_SRCBNK):(HL) TO (HB_DSTBNK):(DE) FOR BC BYTES. BOTH
|
||||
; HB_SRCBNK AND HB_DSTBNK MUST BE INITIALIZED PRIOR TO CALLING THIS
|
||||
; ROUTINE.
|
||||
;
|
||||
; ADDRESSES ARE TRANSLATED FROM LOGICAL (Z80) TO PHYSICAL (Z280) TO
|
||||
; SETUP THE DMA COPY PARAMETERS. IF THE SOURCE OR DESTINATION RANGE
|
||||
; CROSSES OVER THE BANKED/COMMON BOUNDARY AT $8000, THEN SPECIAL STEPS
|
||||
; MUST BE TAKEN BECAUSE THE BANKED AND COMMON AEAS ARE PROBABLY NOT
|
||||
; SEQUENTIALLY LOCATED IN PHYSICAL MEMORY. TWO ENTRY POINTS ARE
|
||||
; PROVIDED. Z280_BNKCPY IS MUCH FASTER, BUT DOES NOT ACCOUNT FOR THE
|
||||
; COPY RANGES CROSSING OVER THE BANKED/COMMON BOUNDARY (WORKS GREAT
|
||||
; FOR ANY COPY KNOWN TO STAY WITHIN IT'S OWN AREA). Z280_BNKCPYX
|
||||
; WILL HANDLE COPIES WHERE THE SOURCE AND/OR DESTINATION RANGES
|
||||
; CROSS OVER THE BANKED/COMMON MEMORY BOUNDARY. IT DOES THIS BY
|
||||
; BREAKING UP THE COPY REQUESTS INTO MULTIPLE REQUESTS THAT ALL FIT
|
||||
; WITHIN A SINGLE BANKED/COMMON MEMORY SEGMENT AND CALLING Z280_BNKCPY
|
||||
; ITERATIVELY UNTIL THE COPY IS COMPLETE.
|
||||
;
|
||||
; THERE IS ESSENTIALLY NO PROTECTION FOR CALLING THESE ROUTINES WITH
|
||||
; INVALID PARAMETERS. FOR EXAMPLE, A REQUEST TO COPY $2000 BYTES
|
||||
; STARTING AT $F000 EXCEEDS THE SIZE OF THE Z80 MEMORY SPACES AND
|
||||
; RESULTS IN UNDEFINED BEHAVIOR.
|
||||
;
|
||||
; THE COPY IS ALWAYS DONE FROM START TO END. IF THE SOURCE AND
|
||||
; DESTINATION RANGES OVERLAP, THEN YOU MUST TAKE THIS INTO ACCOUNT.
|
||||
;
|
||||
; THE ROUTINE FUNCTIONS LOGICALLY LIKE THE Z80 LDIR INSTRUCTION. ON
|
||||
; RETURN THE SOURCE (HL) AND DESTINATION (DE) REGISTERS WILL BE LEFT
|
||||
; POINTING TO THE NEXT BYTE THAT WOULD BE COPIED IF THE COPY ROUTINE
|
||||
; CONTINUED. BC WILL BE 0. AF IS UNDEFINED.
|
||||
;
|
||||
#IF (MEMMGR == MM_Z280)
|
||||
;
|
||||
; ADJUST THE LENGTH OF THE COPY SUCH THAT BOTH THE SOURCE AND
|
||||
; DESTINATION RANGES DO NOT CROSS OVER THE BANKED/COMMON MEMORY
|
||||
; BOUNDARY. CALL Z280_BNKCPY TO DO AS MANY ITERATIONS AS NEEDED TO
|
||||
; COMPLETE THE COPY.
|
||||
;
|
||||
;
|
||||
Z280_BNKCPYX:
|
||||
LD (Z280_BNKCPY_LEN),BC ; SAVE LENGTH
|
||||
;
|
||||
CALL Z280_BNKCPY_XOVER ; ADJUST FOR XOVER AS NEEDED
|
||||
EX DE,HL ; SWAP SOURCE/DEST
|
||||
CALL Z280_BNKCPY_XOVER ; ADJUST FOR XOVER AS NEEDED
|
||||
EX DE,HL ; SWAP BACK
|
||||
;
|
||||
; DO THE WORK, SAVE THE LEN OF THIS ITERATION
|
||||
PUSH BC ; SAVE ITER LENGTH
|
||||
CALL Z280_BNKCPY ; DO THE WORK
|
||||
;
|
||||
;;; *DEBUG* SIMULATE CALL TO Z280_BNKCPY
|
||||
;;CALL NEWLINE
|
||||
;;CALL REGDMP ; *DEBUG*
|
||||
;;ADD HL,BC ; INCREMENT SRC ADR BY COUNT
|
||||
;;EX DE,HL ; SWAP
|
||||
;;ADD HL,BC ; INCREMENT DST ADR BY COUNT
|
||||
;;EX DE,HL ; SWAP BACK
|
||||
;;LD BC,0 ; COUNT IS NOW ZERO
|
||||
;;; END *DEBUG*
|
||||
;
|
||||
POP BC ; RECOVER ITER LENGTH
|
||||
;
|
||||
; ACCUNT FOR WORK ACTUALLY PERFORMED
|
||||
PUSH HL ; SAVE SOURCE ADR
|
||||
LD HL,(Z280_BNKCPY_LEN) ; GET PENDING LENGTH
|
||||
OR A ; CLEAR CARRY
|
||||
SBC HL,BC ; SUBTRACT WHAT WE DID
|
||||
PUSH HL ; MOVE NEW PENDING LEN
|
||||
POP BC ; TO BC
|
||||
POP HL ; RECOVER SOURCE ADR
|
||||
;
|
||||
; SEE IF WE NEED TO ITERATE
|
||||
LD A,B ; IS LENGTH
|
||||
OR C ; ... NOW ZERO?
|
||||
RET Z ; IF SO, ALL DONE
|
||||
JR Z280_BNKCPYX ; ELSE ITERATE UNTIL DONE
|
||||
;
|
||||
Z280_BNKCPY_LEN .DW 0 ; TEMP STORAGE FOR BC
|
||||
;
|
||||
Z280_BNKCPY_XOVER:
|
||||
; DETECT XOVER IN RANGE AND ADJUST COPY LEN IF SO
|
||||
; HL=START, BC=LEN
|
||||
; BC IS REDUCED AS NEEDED TO AVOID XOVER
|
||||
BIT 7,H ; START ABOVE 32K?
|
||||
RET NZ ; YES, NO XOVER
|
||||
PUSH HL ; SAVE START ADR
|
||||
ADD HL,BC ; ADD COPY LEN
|
||||
DEC HL ; CONVERT TO "LAST" BYTE OF RANGE
|
||||
BIT 7,H ; ABOVE 32K?
|
||||
POP HL ; RESTORE HL
|
||||
RET Z ; IF NOT, NO XOVER
|
||||
;
|
||||
; START IS BELOW 32K, END IS OVER 32K, XOVER IN SOURCE!
|
||||
; REDUCE LENGTH TO AVOID IT
|
||||
; COMPUTE (32K - START) FOR NEW LEN
|
||||
PUSH DE ; SAVE DEST (DE)
|
||||
PUSH HL ; SAVE START (HL)
|
||||
LD DE,$8000
|
||||
EX DE,HL ; DE=START, HL=32K
|
||||
OR A ; CLEAR CARRY
|
||||
SBC HL,DE ; HL = NEW LEN
|
||||
PUSH HL ; MOVE NEW LEN
|
||||
POP BC ; ... TO BC
|
||||
POP HL ; RECOVER START
|
||||
POP DE ; RECOVER DEST
|
||||
RET ; RETURN
|
||||
;
|
||||
Z280_BNKCPY:
|
||||
; Z280 MEMORY TO MEMORY DMA
|
||||
; USE FLOW THROUGH MODE
|
||||
@@ -5324,6 +5496,7 @@ Z2DMAADR2:
|
||||
INC C ; BUMP TO NEXT REG
|
||||
;
|
||||
RET
|
||||
;
|
||||
#ENDIF
|
||||
;
|
||||
; Z280 SYSCALL VECTOR ENTRY POINT. TAKES STACK PARAMETER AS A BRANCH
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
#DEFINE RMN 1
|
||||
#DEFINE RUP 1
|
||||
#DEFINE RTP 0
|
||||
#DEFINE BIOSVER "3.1.1-pre.155"
|
||||
#DEFINE BIOSVER "3.1.1-pre.156"
|
||||
|
||||
@@ -3,5 +3,5 @@ rmn equ 1
|
||||
rup equ 1
|
||||
rtp equ 0
|
||||
biosver macro
|
||||
db "3.1.1-pre.155"
|
||||
db "3.1.1-pre.156"
|
||||
endm
|
||||
|
||||
Reference in New Issue
Block a user