|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 5632 (0x1600) Types: TextFile Names: »MOVE.ASM«
└─⟦b445f10af⟧ Bits:30004389 CP/M Plus Source files └─ ⟦this⟧ »MOVE.ASM«
TITLE 'BANK AND MOVE MODULE FOR CP/M 3.0 BIOS - DATE:831024' PAGE 43 ;************************************************************************ ;* THE MOVE MODULE PERFORM MEMORY TO MEMORY BLOCK TRANSFER * ;************************************************************************ EXTRN ?BNKSL EXTRN @CBNK PUBLIC ?MOVE ; PUBLIC ?XMOVE ; PUBLIC ?BANK ; PUBLIC MA3MIR ; if crtype eq cr7 PUBLIC BUFFER endif MACLIB Z80 MACLIB PORTS ;************************************************************************ ;* MEMORY TO MEMORY MOVE * ;* * ;* INPUT : <BC> = BYTE COUNT * ;* <DE> = START SOURCE ADDRESS * ;* <HL> = START DESTINATION ADDRESS * ;* * ;* OUTPUT: DE,HL POINTS TO NEXT BYTES AFTER MOVE * ;* * ;************************************************************************ CSEG ;ALL IS IN COMMON MEMORY if (crtype eq cr7) ?MOVE: MOV A,B ;TEST IF BYTE COUNT <>0 ORA C ; JZ XM$RESET ; LDA XM$FLAG ; CPI 0FFH ;TEST IF EXTENDED MOVE IS REQUIRED JNZ NO$X$MOV ; SDED S$ADDR ;SAVE SOURCE ADDR SHLD D$ADDR ;SAVE DEST ADDR MOV A,B ANI 1 ORA C MOV L,C MOV H,B JZ MOVE1 MOV A,B ANI 1 MOV H,A SHLD C$BUF$SIZE MOV A,B ANI 0FEH INR A INR A MOV H,A MVI L,0 MOVE1: SHLD C$COUNT ;SAVE BYTE COUNT LDA @CBNK ;GET CURRENT BANK PUSH PSW ; AND SAVE IT MOVE$MORE: LDA S$BANK CALL ?BNKSL ;SELECT SOURCE BANK LBCD C$BUF$SIZE ;BYTE COUNT LXI H,BUFFER ;DESTINATION LDED S$ADDR ;SOURCE CALL DMAMOVE ;MOVE DATA TO BUFFER SDED S$ADDR LDA D$BANK CALL ?BNKSL ;SELECT DESTINATION BANK LBCD C$BUF$SIZE ;BYTE COUNT LHLD D$ADDR ;DESTINATION LXI D,BUFFER ;SOURCE CALL DMAMOVE ;MOVE DATA FROM BUFFER SHLD D$ADDR ;SAVE NEW ADDRESS LXI H,200H ;SET BUFFER SIZE TO MAX VALUE SHLD C$BUF$SIZE ; LBCD C$COUNT ;GET BYTE COUNT DCR B ;DECREMENT MSB OF COUNT DCR B SBCD C$COUNT ;SAVE NEW COUNT MOV A,B ORA A JZ MOVE$END JMP MOVE$MORE MOVE$END: POP PSW CALL ?BNKSL ;RESELECT CURRENT BANK XM$RESET: XRA A ; STA XM$FLAG ;RESET FLAG RET ; NO$X$MOV: CALL DMAMOVE RET C$BUF$SIZE: DW 200H S$ADDR: DW 0 D$ADDR: DW 0 C$COUNT: DW 0 BUFFER: DS 200H else ?MOVE: LDA XM$FLAG ; CPI 0FFH ;TEST IF EXTENDED MOVE IS REQUIRED JZ MOV1 ; PUSH B ; LDA @CBNK ;IF NOT USE CURRENT BANK AS MOV B,A ; DESTINATION MOV C,A ; AND SOURCE CALL ?XMOVE ; POP B ; MOV1: MOV A,B ;TEST IF BYTE COUNT <>0 ORA C ; JZ XM$RESET ; CALL DMAMOVE XM$RESET: XRA A ; STA XM$FLAG ;RESET FLAG RET ; endif ;---------------------------------------------------------------------------- DMAMOVE: XCHG ;SWAP SOURCE AND DESTINATION OUT P$DMA$TOGGLE ;RESET BYTE POINTER FLIP-FLOP IN DMA DCX B ;DMA HAS A FUNNY WAY TO COUNT BYTES MOV A,C ;GET LSB OF BYTE COUNT OUT P$DMA$CNT0 ;OUT TO SOURCE CH. MOV A,B ;GET MSB OUT P$DMA$CNT0 ; OUT P$DMA$TOGGLE ;MAKE SHURE IT IS CORRECT STATE MOV A,C ;GET LSB OF BYTE COUNT OUT P$DMA$CNT1 ;OUT TO DESTINATION CH. MOV A,B ;GET MSB OUT P$DMA$CNT1 ; OUT P$DMA$TOGGLE ;IT'S THE SAME PROBLEM AGAIN MOV A,L ;GET LSB OF SOURCE BUFFER ADDRESS OUT P$DMA$ADR0 ;OUT TO SOURCE CH. MOV A,H ;GET MSB OUT P$DMA$ADR0 ; OUT P$DMA$TOGGLE ;ONCE AGAIN MOV A,E ;GET LSB OF DESTINATION BUFFER ADDRESS OUT P$DMA$ADR1 ;OUT TO DESTINATION CH. MOV A,D ;GET MSB OUT P$DMA$ADR1 ; IN P$DMA$STAT ;MIGHT BE SOME GARBAGE IN THERE MVI A,04H ;VALUE TO SEND SOFTWARE DMA REQUEST TO OUT P$DMA$REQ ;CHANNEL 0 DMAWAIT: IN P$DMA$STAT ;GET CONTROLLER STATUS ANI 02H ;TEST IF FUNCTION COMPLETE JZ DMAWAIT ;MUST FINISH UP SOME TIME INX B ; DAD B ;MAKE REG <DE> AND <HL> POINT XCHG ;AT NEXT BYTE AFTER MOVE DAD B ; RET ;************************************************************************ ;* SET BANKS FOR EXTENDED MOVE * ;* * ;* IF ?XMOVE HAS BEEN CALLED SINCE THE LAST CALL TO ?MOVE,AN * ;* INTERBANK MOVE MUST BE PERFORMED. * ;* * ;* INPUT : <B> = DESTINATION BANK * ;* <C> = SOURCE BANK * ;* * ;* OUTPUT: BC,DE,HL ARE UNCHANGED * ;* * ;************************************************************************ ?XMOVE: MVI A,0FFH STA XM$FLAG PUSH B ; MOV A,C ;GET SOURCE BANK STA S$BANK CALL BANK$CHECK ; MOV C,A ; MOV A,B ;GET DESTINATION BANK STA D$BANK ; CALL BANK$CHECK if (crtype eq CR8) RLCR A ;ROTATE INTO PROPER DESTINATION RLCR A ; RLCR A ; RLCR A ; ADD C ; OUT P$BANK$DMA ;SET DMA BANKS endif POP B ; RET ; XM$FLAG: DB 0 S$BANK: DB 0 D$BANK: DB 0 PAGE ;************************************************************************ ;* SELECT BANK * ;* * ;* CALLED PRIOR TO READ AND WRITE * ;* * ;* INPUT : <A> = BANK NUMBER * ;* * ;* OUTPUT: ALL REGISTERS ARE UNCHANGED * ;* * ;************************************************************************ ?BANK: PUSH B ; PUSH PSW CALL BANK$CHECK ;CHECK IF BANK 0 OR 1 MOV C,A ; DI LDA MA3MIR ; ANI 0F0H ;MASK OUT FLOPPY CONTROLLER BITS ORA C ; STA MA3MIR ;UPDATE MAP REG. MIRROR OUT P$MAP3 ;SELECT PROCESSOR BANK EI POP PSW ;RESTORE REG POP B ; RET ; MA3MIR DB 0 ; ;======================================================================== BANK$CHECK: CPI 1 ; JZ BANK1 ;BANK 1 <=> PAGE 0 (Z80 RAM) MVI A,1 ;BANK 0 <=> PAGE 1 (8088 RAM) RET ; BANK1: XRA A RET END «eof»