Hello,
It is possible to create variables in RAM (equivalent to global variables) to store the current source and destination addresses, in addition to a byte counter. However, the solution would be more general to make use of the stack to store these values.
The next issue is to "pass" the initial parameter values to the sub-routine. The Accumulator and H:X registers are available, however these will be insufficient for the current requirement. Therefore it will be necessary to "pre-load" some of the data to the stack, prior to the sub-routine call.
If the block size does not exceed 256 bytes, you might pass the block size within Acc, the destination address within H:X, and pre-load the source address. However, for a block size that may exceed 256 bytes you will need to pass three 16-bit values. For this case, one possibility is to pre-load the source and destination addresses, and to pass the block size within H:X.
The significance of pre-loading some of the data is that the stack pointer will require adjustment after the return from the sub-routine.
The following code snippet demonstrates the process. The code should be compatible with CW assembler.
; Memory copy sub-routine
; Copy block of memory from source location to destination location.
; Source address and destination address values are pre-loaded to
; the stack prior to the sub-routine call.
; On entry, H:X contains the number of bytes to be copied.
; On exit, Acc value is preserved.
; Stack frame structure (SP index)
SRC EQU 7 ; First pre-loaded value
DEST EQU 5 ; Second pre-loaded value
COUNT EQU 1 ; Byte count yet to be copied
MEMCOPY: cphx #0 ; Test for zero bytes to be copied
beq MC3 ; Exit if so
psha ; Save current value
pshx ; Save byte quantity to stack
pshh
MC1: ldhx SRC,sp ; Current source address
lda ,x ; Fetch byte value
ldhx DEST,sp ; Current destination address
sta ,x ; Write byte value
inc SRC,sp ; Increment source address
inc DEST,sp ; Increment destination address
ldhx COUNT,sp ; Byte counter
beq MC2 ; Exit if final byte copy done
dec COUNT,sp ; Decrement byte count
bra MC1 ; Loop always for next byte
MC2: ais #2 ; Adjust stack pointer
pula ; Restore previous value
MC3: rts
; Typical usage:
; aix #-4 ; Create space on stack
; ldhx #SRC_ADDR
; sthx 3,sp ; Pre-load to stack
; ldhx #DEST_ADDR
; sthx 1,sp ; Pre-load to stack
; ldhx #BLOCK_SIZE
; jsr MEMCOPY
; ais #4 ; Adjust stack pointer
Regards,
Mac