Mon Oct 7 01:31:58 EDT 2013

Why You Should Never Develop for MSX

MSX memory system is flat out fucked. However, I've spent 3 hours now figuring it out and mapping it all down. So now I'll explain it plain and "simple", as loosely as I can apply those terms to this subject.

MSX memory is heavily bankswitch oriented. The Z80 memory space is divided into 4 segments of $4000 bytes. These are called Pages. Page 0 is $0000-$3FFF, Page 1 is $4000-$7FFF, etc. Whenever an access is made, the top 2 bits of the address are transformed by the value in PPI port A, also known as PSLOT, mapped to the Z80 at I/O address $A8. The Page accessed is a bit index into this register. Each Page has 2 bits per entry in the PSLOT table. bit0-1 is Page 0, bit2-3 is Page 1, etc. These values are the Page's Primary Slot.

From here, the Primary Slot is interrogated for it's SSLOT register. The SSLOT register can only be written to the Primary Slot that is mapped into Page 3, and is accessed via MMIO at $FFFF. Reading works as well as writing, but the data read is bitwise NOT'd, so you will need to flip it back with CPL or an XOR. Effectively doing this requires several switches of the Page banks in order to get the desired effect.

That's not even the start of the weirdness! The Page accessed is also a bit index into this register as well. Each Page has 2 bits per entry in each Primary Slot's SSLOT table. bit0-1 is Page 0, bit2-3 is Page 1, etc. These values are the Page's Primary Slot's Secondary Slot.

Confused yet? Well we're almost done. Now that we know the semantics behind Pages, the Primary Slots, and the Secondary Slots, we finally can figure out how to pick the device we're accessing. Let's define a notation though, to make this a bit easier: PSx[:Py[:SSz]], where PSx is Primary Slot x, Py is Page y, and SSz is Secondary Slot z. Not every device actually uses the Secondary Slot, and some devices are mapped across all 4 pages, in which case you can completely ignore them.

As for the actual mappings, they're actually machine dependent! For every machine, PS0:P0 always maps to the BIOS. Most machines with a BASIC ROM will have it at PS0:P1. Most machines will also have RAM located at least at PS3:P3:SS0. If your machine has more than 16KB, it will go down to PS3:P2:SS0, all the way down to PS3:P0:SS0. MSX2 Sub-ROM is usually mapped to PS3:P0:SS1. External devices are often at PS1 and PS2. Keep in mind these are not safe assumptions. Many machines do not adhere to these common practices. The only thing you can be 100% sure of is the location of the BIOS ROM. If you are running code after the BIOS, you can also be 100% sure that the high 8KB of Page 3 is mapped to RAM, but no more.

In an attempt to try to make this as absolutely clear as possible, I've made a little graphical representation that may serve better than this lengthy rant.

MSX Memory Architecture
Click for full size

Hopefully this serves you well, I think it makes everything a bit more clear in few words.


Posted by trap15 | Permanent link | Comments (0) | File under: reverse_engineering, msx

There are no comments.