The DPC+ Driver is the ARM code that the Harmony/Melody runs in order to emulate a DPC+ coprocessor.
The 6507 in the Atari has no access to the driver.
While the driver is located in ROM, it is copied into RAM when the Harmony/Melody first powers up. This is because the code runs faster when located in RAM and the extra speed is required in order for the coprocessor emulation to keep up with the Atari.
When using custom ARM code, it must start in bank 0. While we'll be writing our custom ARM code in C, it is possible to write it using ARM assembly language.
The 6507 can select bank 0 by accessing memory location $FFF6*, though when using custom ARM code it's not recommended to also use bank 0 for 6507 code. If the ARM code is large enough, this same recommendation holds true for banks 1 thru 4.
If custom ARM code is greater than 4K, it will next fill up bank 1.
The 6507 can select bank 1 by accessing memory location $FFF7*.
If custom ARM code is greater than 8K, it will next fill up bank 2.
The 6507 can select bank 2 by accessing memory location $FFF8*.
If custom ARM code is greater than 12K, it will next fill up bank 3.
The 6507 can select bank 3 by accessing memory location $FFF9*.
If custom ARM code is greater than 16K, it will next fill up bank 4.
The 6507 can select bank 4 by accessing memory location $FFFA*.
Bank 5 is used for 6507 code. When a DPC+ cartridge is powered up, bank 5 will already be selected. If you've selected another bank then access $FFFB* to reselect bank 5.
When the Harmony/Melody is first powered on, the 4K of information in Display Data will be copied from ROM to RAM. This is required due to the speed boost the ARM gets when access RAM.
While the Atari cannot "bank in" the Display Data, it can indirectly access the RAM version via the Data Fetchers. This is how the custom C code will pass information to the 6507.
The Atari can also update the RAM version by using Data Writers. This is how the 6507 code will pass information to the custom C code.
The Atari's 6507 cannot access the original ROM version of Display Data, not even via the Data Fetchers. The ARM code does have access to it. The provides some space saving opportunities, which will be covered as part of this blog series.
When the Harmony/Melody is first powered on, the 1K of information in Frequency Data will be copied from ROM to RAM. Like before, this is required for speed boost.
The 6507 in the Atari has no access to the Frequency Data.
By default, when using custom ARM code the Frequency Data is reduced to just 512 bytes. The remaining 512 bytes are utilized as storage for the C Variable pool and the C Stack. This division can be changed.
The ARM CPU used in the Harmony/Melody is the ARM7TDMI-S LPC2103. It's specs are:
- 32 bit CPU
- 70 MHz
- 32 KB Flash (the "ROM")
- 8 KB SRAM (the "RAM")
MAM.2: Under certain conditions in MAM Mode2 code execution out of internal Flash can fail
The MAM block maximizes the performance of the ARM processor when it is running code in Flash memory. It includes three 128-bit buffers called the Prefetch Buffer, the Branch Trail Buffer and the data buffer. It can operate in 3 modes; Mode 0 (MAM off), Mode 1 (MAM partially enabled) and Mode 2 (MAM fully enabled).
Under certain conditions when the MAM is fully enabled (Mode 2) code execution from internal Flash can fail. The conditions under which the problem can occur is dependent on the code itself along with its positioning within the Flash memory.
If the above problem is encountered then Mode 2 should not be used. Instead, partially enable the MAM using Mode 1.
MAM is the Memory Accelerator Module, and is basically cache that's used to speed up execution time. Setting to mode 1 results in a drop in performance, but it's still way faster than the 6507.
The problem never showed up with the DPC+ driver because even though it starts out in Flash, it gets copied over to RAM in order to utilize the speed boost of the code running from SRAM.
cd-w posted a few blog entries back in 2009 and 2010:
They go over how the Harmony/Melody emulate a cartridge (including bankswitching support), the speed differences between SRAM vs Flash, and many other interesting bits of information. Go check them out, you'll be glad you did!
* due to the 6507's 8K addressing space, these locations are mirrored multiple times in memory. The mirrors are $1FFx, $3FFx, $5FFx, $7FFx, $9FFx, $BFFx and $DFFx. Any of the mirror addresses may be used. I think of them being located at $FFF6-FFFB due them being right before the RESET and IRQ vectors. The 6507 is a reduced package version of the 6502, which I first learned to program in the early 80s on my Vic 20. On a 6502 these vectors are, by definition, located at addresses $FFFC-FFFD and $FFFE-FFFF.