$DEBUG

BLOCK_MOVES SEGMENT CODE

EXTRN DATA(SRC_POINTER, DST_POINTER, BLOCK_LENGTH)
PUBLIC BLOCK_MOVE_TYPE_1, BLOCK_MOVE_TYPE_2, BLOCK_MOVE_TYPE_3

; Type 1: Blocks begin on page boundaries, and max block length is 255 bytes.
;
; Type 2: Blocks begin anywhere, and max block length is 256 bytes. 
;
; Type 3: Blocks begin anywhere, and max block length > 256 bytes.


RSEG BLOCK_MOVES


;***************************************************************************;
;                                                                           ;
;                          BLOCK_MOVE_TYPE_n
;
;    MOVES BLOCK OF DATA FROM XRAM AT SRC_POINTER TO XRAM AT DST_POINTER
;
;  New users of MCS-51 products are sometimes disappointed that the MCS-51
;  architecture only has one 16-bit data pointer.  This can be a disadvantage
;  when you have to do XRAM-to-XRAM block moves.  Herein are three routines
;  that minimize the time required to do those moves.
;
;   INPUTS: SRC_POINTER    2 bytes in externally defined DATA
;              (low byte at SRC_POINTER, high byte at SRC_POINTER+1)
;
;           DST_POINTER    2 bytes in externally defined DATA
;              (low byte at DST_POINTER, high byte at DST_POINTER+1)
;
;           BLOCK_LENGTH   For TYPE_1 and TYPE_2:
;                                     1 byte in externally defined DATA
;                          For TYPE_3: 2 bytes in externally defined DATA
;
;   BLOCK_MOVE_TYPE_1:
;
;      Blocks begin on page boundaries, and max block length is 255 bytes.
;      Execution time is about 9 usec/byte at 12MHz.
;
;   BLOCK_MOVE_TYPE_2:
;
;      Blocks begin anywhere, and max block length is 256 bytes.  If the
;      block length is 256 bytes, BLOCK_LENGTH should contain 0.  Execution
;      time is about 11 usecs/byte.
;
;   BLOCK_MOVE_TYPE_3:
;
;      Blocks begin anywhere, and max block length > 256 bytes.  BLOCK_LENGTH
;      is 2 bytes, low byte at BLOCK_LENGTH, high byte at BLOCK_LENGTH+1.
;      Execution time is about 11 usecs/byte.
;    
;
;   OUTPUTS: none
;  
;
;   VARIABLES AND REGISTERS MODIFIED:
;
;            BLOCK_LENGTH
;            ACC, PSW, DPTR, P2, R0, R1
;
;                                                                           ;
;***************************************************************************;



BLOCK_MOVE_TYPE_1:
;
;  Blocks begin on page boundaries, and max block length is 255 bytes.

;                                     execution     code
;                                        time      length
	MOV	DPL,SRC_POINTER		; 2           3
	MOV	DPH,SRC_POINTER+1	; 2           3
	MOV	R0,DST_POINTER		; 2           2
	MOV	P2,DST_POINTER+1	; 2           3
	SJMP	BLOCK_MOVE1		; 2           2

AGN1:	INC	DPTR			; 2           1
	INC	R0			; 1           1

BLOCK_MOVE1:
	MOVX	A,@DPTR			; 2           1
	MOVX	@R0,A			; 2           1
	DJNZ	BLOCK_LENGTH,AGN1	; 2           3
;                                    -------        ----
;                  Setup:            10 usec         20 bytes
;                  1st move:          6 usec
;                  subsequent moves:  9 usec
;                                    --
;                 total for N bytes: 7 + 9*N usec
;                 total for 200 bytes: 1807 usec
	RET



BLOCK_MOVE_TYPE_2:
;
;  Blocks begin anywhere, and max block length is 256 bytes. 
;
;                                     execution     code
;                                        time      length
	MOV	DPL,SRC_POINTER		; 2           3
	MOV	DPH,SRC_POINTER+1	; 2           3
	MOV	R0,DST_POINTER		; 2           2
	MOV	P2,DST_POINTER+1	; 2           3
	CLR	A			; 1           1
	CLR	C			; 1           1
	SUBB	A,R0			; 1           1
	MOV	R1,A			; 1           1
	SJMP	BLOCK_MOVE2		; 2           2

AGN2:	INC	DPTR			; 2           1
	INC	R0			; 1           1
	DJNZ	R1,BLOCK_MOVE2		; 2           2
	INC	P2			; 1           2
BLOCK_MOVE2:
	MOVX	A,@DPTR			; 2           1
	MOVX	@R0,A			; 2           1
	DJNZ	BLOCK_LENGTH,AGN2	; 2           3
;                                    -------        ----
;                  Setup:            14 usec         28 bytes
;                  1st move:          6 usec
;                  subsequent moves: 11 usec (12 if dst page turns)
;                                    --
;                 total for N bytes: 9 + 11*N usec
;                               (10 + 11*N if dst block crosses page boundary)
;                 total for 200 bytes: either 2209 or 2210 usec, depending on
;                                   whether dst block crosses a page boundary
	RET


BLOCK_MOVE_TYPE_3:
;
;  Blocks begin anywhere, and max block length > 255 bytes.

;                                     execution     code
;                                        time      length
	MOV	DPL,SRC_POINTER		; 2           3
	MOV	DPH,SRC_POINTER+1	; 2           3
	MOV	R0,DST_POINTER		; 2           2
	MOV	P2,DST_POINTER+1	; 2           3
	INC	BLOCK_LENGTH+1		; 1           2
	CLR	A			; 1           1
	CLR	C			; 1           1
	SUBB	A,R0			; 1           1
	MOV	R1,A			; 1           1
	SJMP	BLOCK_MOVE3		; 2           2

AGN3:	INC	DPTR			; 2           1
	INC	R0			; 1           1
	DJNZ	R1,BLOCK_MOVE3		; 2           2
	INC	P2			; 1           2
BLOCK_MOVE3:
	MOVX	A,@DPTR			; 2           1
	MOVX	@R0,A			; 2           1
	DJNZ	BLOCK_LENGTH,AGN3	; 2           3
	DJNZ	BLOCK_LENGTH+1,AGN3	; 2           3
;                                    -------        ----
;                  Setup:            14 usec         31 bytes
;                  1st move:          6 usec
;                  subsequent moves: 11 usec (+ 1 if dst page turns)
;                           (+ 2 each time BLOCK_LENGTH low byte decs to 0)
;                                    --
;                 total for N bytes: 9 + 11*N usec
;                       (10 + 11*N if dst block crosses one page boundary)
;                 total for 200 bytes: 2209 usec
	RET

END
                                                                                                   