fachat wrote:
I am looking for a fast way to copy a variable amount of data between two banks (basically like a file read or write) on the 65816.
I am not sure I fully understand how the DBR works, but as I read it, consecutive reads/writes would all go to the same bank, except if I change the DBR in between, right?
To the maximum extent possible, I avoid messing with
DB, since it can only be loaded and saved via the stack. Basically, your two options for mass-copying data are long indirect addressing or use of the block-copy instructions that are unique to the 65C816.
In native mode, the
MVN and
MVP instructions will copy up to 64KB chunks of memory, either intra- or inter-bank. Use
MVN when the source and destination addresses are in the same bank and the destination address is lower than the source address, or when the destination is in a different bank than the source. Use
MVP when the source and destination addresses are in the same bank and the destination address is higher than the source address. Both instructions will copy at the rate of one byte per seven clock cycles, which is much faster than achievable by rolling your own with indirect addressing.
Note that
MVN and
MVP are interruptible instructions, so your interrupt handlers must preserve the accumulator and index registers, as well as
DB. Also,
DB should be pushed before executing
MVN or
MVP and subsequently pulled afterward, since as Gordon noted,
DB is clobbered during the copy procedure.
Quote:
So the fastest thing I came up with was basically a long read (3-byte address, indexed) followed by a long write (3-byte address, indexed), using self-modifying code to update the read and write addresses appropriately... right?
If you want to "manually" copy you should use long indirect indexed addressing, which is notated in compliant assemblers as
[<dp>],y.
<dp> refers to three consecutive locations on direct page in which an address is set in customary little-endian format—
<dp>+2 is the bank. With the index registers set to 16 bits, you can copy up to 64KB without having to touch the direct page pointers. Unlike copying with
MVN and
MVP, this method can overlap bank boundaries, hence treating the 65C816's address space as linear.
Quote:
Would this work in emulation mode too? (i.e. are the long indexed addressing modes available, and not truncated to bank 0)?
MVN and
MVP will work in emulation mode, but are all-but-useless due to the inability to set the registers to 16 bits in emulation mode. Long indirect addressing will work in emulation mode, but not as efficiently, since you would have to adjust your pointers for every 256 bytes copied—you wouldn't be able to use a 16-bit index as you can in native mode. Frankly, you should avoid emulation mode, as it substantially negates the many advantages of using the 65C816.