Jump to content
  • entries
  • comments
  • views

DPC+ARM - Part 6, DPC+ Cartridge Layout




NOTE: This blog series is obsolete.  Head on over to the Harmony/Melody Club where you'll find information on the new Linaro compiler and the new CDFJ coprocessor/bankswitch scheme that has many improvements over DPC+.


DPC+ Driver


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.


Bank 0


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.


Bank 1


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*.


Bank 2


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*.


Bank 3


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*.



Bank 4


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


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.


Display Data


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.


Frequency Data


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")

There is a bug in the CPU that can crash your program, which caused all sorts of development problems in Stay Frosty 2 and Frantic before we found this out. The errata sheet has this to say:



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.


Further Reading


cd-w posted a few blog entries back in 2009 and 2010:


Perfect Harmony


Harmony Memory


More Harmony


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.

  • Like 1


Recommended Comments

Putting the banking hotspots at the highest addresses possible makes for easier coding as programs typically grow from low addresses to high addresses. Also, because the interrupt vectors are at the highest addresses, that chunk of memory is already "used", so reserving a few more addresses for hotspots leaves the maximum number of address chunks available.


Hmm... using the interrupt vector addresses as hotspots could be useful as it would auto-initialize which bank the program starts in.

Link to comment

That makes sense.

I do like the ZP hotspots better, like Tigervision's 3F, as they don't waste any of the ROM. Additionally, each trigger of a bankswitch uses 1 byte less ROM and 1 less cycle of CPU time.

supercat's X07 bankswitch format, used for Stella's Stocking, has a slick feature that lets you do a bankswitch without wasting any cycles, but the feature only works in the last 2 banks. He needed that ability in order to bankswitch during the kernel for his music playing menu. He posted a little bit about it here.

Link to comment

Finally had some free time last night and was able to finish the code for Part 7. I still need to add comments and write up the blog entry, so it's not ready to be posted yet - but at least some progress has been made!

Link to comment

Thanks for informing us about the MAM bug! I ran into this last night and would have probably spent several days debugging it had I not read about it here.

Link to comment
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...