DataMuseum.dk

Presents historical artifacts from the history of:

Christian Rovsing CR7, CR8 & CR16 CP/M

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Christian Rovsing CR7, CR8 & CR16 CP/M

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦795cde124⟧ TextFile

    Length: 5632 (0x1600)
    Types: TextFile
    Names: »MOVE.ASM«

Derivation

└─⟦b445f10af⟧ Bits:30004389 CP/M Plus Source files
    └─ ⟦this⟧ »MOVE.ASM« 

TextFile


	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»