-
Notifications
You must be signed in to change notification settings - Fork 32
Part 06 More MMU
Go Home
Now would be a good time to get the rest of the devices wired up to the MMU. Even if they don't do much, it would still be good to get that work out of the way. We have already wired up the boot ROM and the first 16KB chunk of cartridge ROM. The second 16KB chunk of cartridge ROM is switchable. As discussed on Memory Bank Controllers, each cartridge may have it's own controller in it that allows different chunks of memory to be swapped in. The simplest case is "None". This just means the game is small enough that it doesn't need more than 32KB of ROM, so the entire memory is available from 0x0000 to 0x7FFF.
Eventually, we will have to read each of these MBCs and implement them in the cartridge. ADD MORE DETAILS.
We need to create a GPU class and map these addresses to it. This contains RAM that the GPU will use to render. For us, we can just allocate an 8KB chunk of memory and ensure it can be read and written.
This is 8KB of RAM that is stored on the cartridge, often with a battery backup to allow for storing of high scores and saved games. The behavior of this will depend on the MBC used by the cartridge.
This is an 8KB chunk of working RAM that is provided by the MMU.
This is a strange thing. It is essentially a mirror of the memory at 0xC000 to 0xDDFF. It is rarely used, but should be expected to work. For example, if a request for 0xE123 is made, then the memory at 0xC123 should be returned by the MMU.
This is referred to as the Sprite Attribute Table. The GameBoy GPU can display up to 40 sprites either in 8x8 or in 8x16 pixels. Because of a limitation of hardware, only ten sprites can be displayed per scan line. See the link for more details.
These are unused and should fail if something is read or written to them.
This one byte is enough to read data from the gamepad!
We can choose to not implement this for now.
This isn't referenced in the specification at all!
Eventually, we'll have to wire up some logic here to provide timer logic via these addresses.
This isn't referenced in the specification at all!
This is used to control all of the sounds.
This controls various features of the LCD display. It can do things like turn it off.
These are unspecified.
This is referred to as high RAM (HRAM). It has some unique uses, but generally is is read/write capable. However, this is also where the stack lives. If you recall, during boot, the Stack Pointer (SP) was set to 0xFFFE. That points to the end of this HRAM. When the PUSH OpCode is called, it pushes the value to this SP location, then moves the SP up by one. Later, when a POP is done, the SP is moved down, and the value retrieved.
This is a special byte that is used to enable interrupts. Interrupts are a special feature on hardware to stop the processing of code, and immediate jump the execution (interrupt) to a special piece of code. For example, if you wanted to do something at the next VBlank (when the screen is done drawing), then you could enable the interrupt and it would trigger that piece of code.
That pretty much covers all the pieces. We need to make a set of classes for each of these components, and register them with the MMU so it can route the ReadByte and SetMemory requests to the correct device.