$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