;
; SYSLIB Module Name:  SMOVE
; Author:  Richard Conn
; SYSLIB Version Number:  2.0
; Module Version Number:  1.0
; Module Entry Points:
;	HMOVB		HMOVBC		MOVEB		MOVEBC
; Module External References:
;	None
;

;
;  SMOVEB.MAC -- SYSLIB MODULE
;
;  ENTRY POINTS --
;	EXT	MOVEB		-- MOVE BYTES PTED TO BY HL TO
;				   LOCATION PTED TO BY DE FOR B BYTES
;	EXT	MOVEBC		-- MOVE BYTES PTED TO BY HL TO
;				   LOCATION PTED TO BY DE FOR BC BYTES
;
;  NO REGISTERS ARE TO BE AFFECTED
;
;	EXT	HMOVB		-- LIKE MOVEB, BUT HL AND DE PT TO BYTE AFTER
;				   LAST BYTE MOVED WHEN DONE
;	EXT	HMOVBC		-- LIKE MOVEBC, BUT HL AND DE PT TO BYTE AFTER
;				   LAST BYTE MOVED WHEN DONE
;

;
;  SUPPORTING MACROS --
;
PUTRG	MACRO		; SAVE ALL REGS
	PUSH	PSW
	PUSH	B
	PUSH	D
	PUSH	H
	ENDM

GETRG	MACRO		; RESTORE ALL REGS
	POP	H
	POP	D
	POP	B
	POP	PSW
	ENDM

;
;  HMOVB AND HMOVBC ROUTINES --
;
HMOVB::
	CALL	MOVEB	; DO THE MOVE
	PUSH	B	; SAVE BC
	MOV	C,B	; BC=B
	MVI	B,0
	DAD	B	; HL PTS TO BYTE AFTER LAST BYTE MOVED
	XCHG
	DAD	B	; DE PTS TO BYTE AFTER LAST BYTE MOVED
	XCHG
	POP	B	; GET BC
	RET

HMOVBC::
	CALL	MOVEBC	; DO THE MOVE
	PUSH	B	; SAVE BC
	DAD	B	; HL PTS TO BYTE AFTER LAST BYTE MOVED
	XCHG
	DAD	B	; DE PTS TO BYTE AFTER LAST BYTE MOVED
	XCHG
	POP	B	; GET BC
	RET

;
;  MOVEB AND MOVEBC ROUTINES --
;
MOVEB::
	PUSH	B	; SAVE BC
	MOV	C,B	; C=B
	MVI	B,0	; B=0
	CALL	MOVEBC	; USE MOVEBC
	POP	B	; RESTORE BC
	RET

MOVEBC::
	PUTRG		; SAVE ALL REGS

;  DETERMINE IF HL < DE; IF SO, MOVE BACK TO FRONT; OTHERWISE, FRONT TO BACK
	MOV	A,H	; HL<DE?
	CMP	D
	JC	MOVER	; MOVE BACK-TO-FRONT
	JNZ	MOVEF	; MOVE FRONT-TO-BACK IF HL>DE
	MOV	A,L	; HL<DE?
	CMP	E
	JC	MOVER	; MOVE BACK-TO-FRONT

;  MOVE FRONT-TO-BACK
MOVEF:
	MOV	A,M	; GET BYTE
	STAX	D	; PUT BYTE
	INX	H	; PT TO NEXT
	INX	D
	DCX	B	; COUNT DOWN
	MOV	A,B	; DONE?
	ORA	C
	JNZ	MOVEF

;  DONE WITH PROGRAM
DONE:
	GETRG		; RESTORE ALL REGS
	RET

;  MOVE BACK-TO-FRONT
MOVER:
;  POINT TO END OF BUFFERS
	DCX	B	; DECR COUNT BY 1
	DAD	B	; PT TO END OF BUFFERS
	XCHG
	DAD	B
	XCHG
	INX	B	; CORRECT BYTE COUNT
;  PERFORM MOVE
MOVERL:
	MOV	A,M	; GET BYTE
	STAX	D	; PUT BYTE
	DCX	H	; PT TO NEXT
	DCX	D
	DCX	B	; COUNT DOWN
	MOV	A,B	; DONE?
	ORA	C
	JNZ	MOVERL
	JMP	DONE

	END
