base:practical_memory_move_routines
no way to compare when less than two revisions
Differences
This shows you the differences between two versions of the page.
— | base:practical_memory_move_routines [2015-04-17 04:33] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Practical Memory Move Routines ====== | ||
+ | by Bruce Clark | ||
+ | |||
+ | (Info file taken from [[http:// | ||
+ | |||
+ | Here are some reasonably fast general-purpose routines for moving blocks of memory. You simply specify the address to move from, the address to move to, and the size of the block. When SIZE is zero, no bytes are moved. SIZEL and SIZEH do not need to be consecutive memory locations, or even on the zero page for that matter. These routines only take one additional cycle if SIZEL is not on the zero page. Likewise, they only take one additional cycle if SIZEH is not on the zero page. Note that this adds only to the total number of cycles, not to the number of cycles per byte, since neither SIZEL nor SIZEH is inside a loop anywhere. | ||
+ | |||
+ | These routines are intended to be both flexible and practical, without being excessively lengthy or excessively slow. To that end, they can be placed in ROM or in RAM. | ||
+ | |||
+ | There are three routines moving memory upward (i.e. to a higher address), each of which is tailored to a slightly different set of input parameters. | ||
+ | < | ||
+ | ; Move memory down | ||
+ | ; | ||
+ | ; FROM = source start address | ||
+ | ; TO = destination start address | ||
+ | ; SIZE = number of bytes to move | ||
+ | ; | ||
+ | MOVEDOWN LDY #0 | ||
+ | LDX SIZEH | ||
+ | BEQ MD2 | ||
+ | MD1 LDA (FROM),Y ; move a page at a time | ||
+ | STA (TO),Y | ||
+ | INY | ||
+ | BNE MD1 | ||
+ | INC FROM+1 | ||
+ | INC TO+1 | ||
+ | DEX | ||
+ | BNE MD1 | ||
+ | MD2 LDX SIZEL | ||
+ | BEQ MD4 | ||
+ | MD3 LDA (FROM),Y ; move the remaining bytes | ||
+ | STA (TO),Y | ||
+ | INY | ||
+ | DEX | ||
+ | BNE MD3 | ||
+ | MD4 RTS | ||
+ | |||
+ | ; Move memory up | ||
+ | ; | ||
+ | ; FROM = source start address | ||
+ | ; TO = destination start address | ||
+ | ; SIZE = number of bytes to move | ||
+ | ; | ||
+ | MOVEUP | ||
+ | | ||
+ | TXA | ||
+ | ADC FROM+1 | ||
+ | STA FROM+1 | ||
+ | CLC | ||
+ | TXA | ||
+ | ADC TO+1 | ||
+ | STA TO+1 | ||
+ | | ||
+ | LDY SIZEL | ||
+ | BEQ MU3 | ||
+ | | ||
+ | BEQ MU2 | ||
+ | MU1 LDA (FROM),Y | ||
+ | STA (TO),Y | ||
+ | DEY | ||
+ | BNE MU1 | ||
+ | MU2 LDA (FROM),Y ; handle Y = 0 separately | ||
+ | STA (TO),Y | ||
+ | MU3 DEY | ||
+ | DEC FROM+1 | ||
+ | DEC TO+1 | ||
+ | DEX | ||
+ | BNE MU1 | ||
+ | RTS | ||
+ | |||
+ | ; Move memory up | ||
+ | ; | ||
+ | ; FROM = 1 + source end address | ||
+ | ; TO = 1 + destination end address | ||
+ | ; SIZE = number of bytes to move | ||
+ | ; | ||
+ | MOVEUP | ||
+ | LDX SIZEH | ||
+ | BEQ MU3 | ||
+ | MU1 DEC FROM+1 | ||
+ | DEC TO+1 | ||
+ | MU2 LDA (FROM),Y ; move a page at a time | ||
+ | STA (TO),Y | ||
+ | DEY | ||
+ | BNE MU2 | ||
+ | LDA (FROM),Y ; handle Y = 0 separately | ||
+ | STA (TO),Y | ||
+ | DEY | ||
+ | DEX | ||
+ | BNE MU1 | ||
+ | MU3 LDX SIZEL | ||
+ | BEQ MU5 | ||
+ | DEC FROM+1 | ||
+ | DEC TO+1 | ||
+ | MU4 LDA (FROM),Y ; move the remaining bytes | ||
+ | STA (TO),Y | ||
+ | DEY | ||
+ | DEX | ||
+ | BNE MU4 | ||
+ | MU5 RTS | ||
+ | |||
+ | ; Move memory up | ||
+ | ; | ||
+ | ; FROM = source end address | ||
+ | ; TO = destination end address | ||
+ | ; SIZE = number of bytes to move | ||
+ | ; | ||
+ | MOVEUP | ||
+ | LDX SIZEH | ||
+ | BEQ MU3 | ||
+ | MU1 LDA (FROM),Y ; handle Y = 0 separately | ||
+ | STA (TO),Y | ||
+ | DEY | ||
+ | DEC FROM+1 | ||
+ | DEC TO+1 | ||
+ | MU2 LDA (FROM),Y ; move a page at a time | ||
+ | STA (TO),Y | ||
+ | DEY | ||
+ | BNE MU2 | ||
+ | DEX | ||
+ | BNE MU1 | ||
+ | MU3 LDX SIZEL | ||
+ | BEQ MU5 | ||
+ | LDA (FROM),Y ; handle Y = 0 separately | ||
+ | STA (TO),Y | ||
+ | DEY | ||
+ | DEX | ||
+ | BEQ MU5 | ||
+ | DEC FROM+1 | ||
+ | DEC TO+1 | ||
+ | MU4 LDA (FROM),Y ; move the remaining bytes | ||
+ | STA (TO),Y | ||
+ | DEY | ||
+ | DEX | ||
+ | BNE MU4 | ||
+ | MU5 RTS | ||
+ | </ | ||
+ | Even more speed can be gained by using self-modifying code, i.e. replacing the (ZeroPage), | ||
base/practical_memory_move_routines.txt · Last modified: 2015-04-17 04:33 by 127.0.0.1