Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CPU mode select register - KEY0 #580

Merged
merged 5 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion src/CGB_Registers.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,13 +219,39 @@ ON/OFF pulses (length 10us ON, 17.5us OFF each) instead of a permanent
880us LED ON signal. Even though being generally CGB compatible, the GBA
does not include an infra-red port.

### FF4C — KEY0 (CGB Mode only): CPU mode select

This GBC-only register (which is not officially documented) is written only by the CGB boot ROM,
as it gets locked after the bootrom finish execution (by a write to the [BANK register](<#Monochrome models (DMG0, DMG, MGB)>)).

Once it is locked, the behavior of the system can't be changed without a reset (this behavior can be observed using [this test ROM](https://github.com/alloncm/MagenTests?tab=readme-ov-file#key0-cpu-mode-register-lock-after-boot)).

As a result of the above most of the behavior is not directly testable without hardware manipulation.
Even though we can't test its behavior directly we can inspect the disassembly of the CGB bootrom and infer the following:

{{#bits 8 >
"KEY0" 2:"DMG compatibility mode"
}}

- **DMG compatibility mode**: `0` = Disabled (full CGB mode, for regular CGB cartridges), `1` = Enabled (for DMG only cartridges)

#### PGB mode

:::tip Research needed

It has been speculated that setting bit 3 is related to a special mode called "PGB" for controlling the LCD externally.

This mode is not well researched nor documented yet, you are welcome to help [here!](https://github.com/gbdev/pandocs/issues/581)

:::

### FF6C — OPRI (CGB Mode only): Object priority mode

This register serves as a flag for which object priority mode to use. While
the DMG prioritizes objects by x-coordinate, the CGB prioritizes them by
location in OAM. This flag is set by the CGB bios after checking the game's CGB compatibility.

OPRI has an effect if a PGB value (`0xX8`, `0xXC`) is written to KEY0 but STOP hasn't been executed yet, and the write takes effect instantly.
OPRI has an effect if a [PGB](<#PGB mode>) value (`0xX8`, `0xXC`) is written to [KEY0](<#FF4C — KEY0 (CGB Mode only): CPU mode select>) but STOP hasn't been executed yet, and the write takes effect instantly.

:::warning TO BE VERIFIED

Expand Down
4 changes: 3 additions & 1 deletion src/Power_Up_Sequence.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ Then, like the monochrome boot ROMs, the header logo is checked *from the buffer
For unknown reasons, however, only the first half of the logo is checked, despite the full logo being present in the HRAM buffer.

Finally, the boot ROM fades all BG palettes to white, and sets the hardware to compatibility mode.
If [the CGB compatibility byte](<#0143 — CGB flag>) indicates CGB compatibility, the byte is written directly to `KEY0` ($FF4C), potentially enabling PGB mode; otherwise, $04 is written to `KEY0` (enabling DMG compatibility mode in the CPU), $01 is written to [`OPRI`](<#FF6C — OPRI (CGB Mode only): Object priority mode>) (enabling [DMG OBJ priority](<#Object Priority and Conflicts>)), and the [compatibility palettes](<#Compatibility palettes>) are written.
If [the CGB compatibility byte](<#0143 — CGB flag>) indicates CGB compatibility, the byte is written directly to [`KEY0`](<#FF4C — KEY0 (CGB Mode only): CPU mode select>), potentially [enabling "PGB mode"](<#PGB mode>);
otherwise, $04 is written to [`KEY0`](<#FF4C — KEY0 (CGB Mode only): CPU mode select>) (enabling DMG compatibility mode in the CPU),
$01 is written to [`OPRI`](<#FF6C — OPRI (CGB Mode only): Object priority mode>) (enabling [DMG OBJ priority](<#Object Priority and Conflicts>)), and the [compatibility palettes](<#Compatibility palettes>) are written.
Additionally, the DMG logo tilemap is written [if the compatibility requests it](<#Compatibility palettes>).

Like all other boot ROMs, the last thing the color boot ROMs do is hand off execution at the same time as they unmap themselves, though they write $11 instead of $01 or $FF.
Expand Down
9 changes: 1 addition & 8 deletions src/The_Cartridge_Header.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,7 @@ Value | Meaning
`$80` | The game supports CGB enhancements, but is backwards compatible with monochrome Game Boys
`$C0` | The game works on CGB only (the hardware ignores bit 6, so this really functions the same as `$80`)

Values with bit 7 and either bit 2 or 3 set will switch the Game Boy into a special non-CGB-mode called "PGB mode".

:::tip Research needed

The PGB mode is not well researched or documented yet.
Help is welcome!

:::
Setting bit 7 will trigger a write of this register value to [KEY0 register](<#FF4C — KEY0 (CGB Mode only): CPU mode select>) which sets the CPU mode.

## 0144–0145 — New licensee code

Expand Down
Loading