diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 30c8349c..9336f63c 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -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 diff --git a/Source/ver.inc b/Source/ver.inc index fd73e28a..d6117e2a 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -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" diff --git a/Source/ver.lib b/Source/ver.lib index c16db76f..e13f6c1b 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -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