feat(bios): support sound and serial register reset
This commit is contained in:
parent
cb2772cef8
commit
d6a47a3e12
14 changed files with 278 additions and 47 deletions
49
docs/hardware/audio.md
Normal file
49
docs/hardware/audio.md
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# Sound initialization subset
|
||||
|
||||
Sound synthesis and host audio output are not implemented.
|
||||
The core now models disabled sound-register state so firmware can perform a functional sound reset.
|
||||
This is not a silent-audio compatibility mode. Enabling sound returns an explicit diagnostic.
|
||||
|
||||
## Supported state
|
||||
|
||||
| Address | Behavior |
|
||||
| --- | --- |
|
||||
| `0x04000060..0x04000081` | Programmable sound generator (PSG) registers remain zero; writes have no effect while master sound is disabled |
|
||||
| `0x04000082` (`SOUNDCNT_H`) | Retains mixing/routing/timer configuration with readback mask `0x770f` |
|
||||
| `0x04000084` (`SOUNDCNT_X`) | Reads zero; status flags are read-only; a write setting bit 7 fails |
|
||||
| `0x04000088` (`SOUNDBIAS`) | Retains bias/resolution configuration with mask `0xc3fe`; no analog output is generated |
|
||||
| `0x04000090..0x0400009f` | Read/write wave RAM in the CPU-accessible inactive bank |
|
||||
|
||||
Unused mapped bytes through `0x0400008b` read zero and ignore writes.
|
||||
The FIFO reset strobes in `SOUNDCNT_H` do not latch. No FIFO data can be queued in this subset.
|
||||
FIFO addresses and the remaining sound-region holes stay unmapped.
|
||||
All sound configuration starts at zero in raw memory. RegisterRamReset bit 6 sets the functional bias default to `0x0200`.
|
||||
|
||||
With master sound disabled, `SOUND3CNT_L` stays zero. The CPU accesses wave bank 1.
|
||||
Bank 0 cannot be selected or played and remains zero. Disabling master sound does not erase wave RAM.
|
||||
The BIOS reset explicitly clears the accessible wave RAM through ordinary stores.
|
||||
Future bank switching and channel playback need a complete sound engine, not a larger register array.
|
||||
|
||||
## Diagnostics and atomicity
|
||||
|
||||
A write setting `SOUNDCNT_X` bit 7 returns `MemoryError::UnsupportedIo`, including the address, byte value, and operation.
|
||||
Status bits and unused bits alone do not enable sound.
|
||||
Validation occurs before any bytes in the access are written.
|
||||
Block stores validate every register value before committing earlier writes. Failed CPU and DMA steps remain retryable.
|
||||
|
||||
Original tests cover disabled-register writes, masks, byte lanes, wave retention, and BIOS reset selection.
|
||||
They also check rejected sound activation through byte/word accesses, ARM block stores, and DMA without partial state changes.
|
||||
|
||||
## Remaining work
|
||||
|
||||
Implement channel clocks, length/envelope/sweep state, wave banking, FIFO consumption, timer-triggered sound DMA, and mixing.
|
||||
Add a host-independent sample interface before connecting a desktop audio backend.
|
||||
Do not acknowledge active sound requests without implementing their device behavior.
|
||||
|
||||
## References
|
||||
|
||||
- [GBATEK sound control registers](https://problemkaputt.de/gbatek-gba-sound-control-registers.htm): disabled PSG behavior, master enable, masks, FIFO reset strobes, and bias.
|
||||
- [GBATEK](https://mgba-emu.github.io/gbatek/): channel 3 wave-bank access and register layout.
|
||||
- [mGBA BIOS service implementation at 3a5e34be](https://github.com/mgba-emu/mgba/blob/3a5e34be33dc7f8f707e5bc9db69e8a430046f21/src/gba/bios.c): functional reset defaults. No upstream implementation was copied.
|
||||
|
||||
Reset values are source-backed. Exact Nintendo firmware ordering, timing, and analog behavior are not established.
|
||||
|
|
@ -40,7 +40,7 @@ Supported software interrupt services:
|
|||
| Number | Service | Behavior |
|
||||
| --- | --- | --- |
|
||||
| `0x00` | SoftReset | Clear BIOS work RAM and reset CPU registers/stacks; restart in ROM or RAM without returning |
|
||||
| `0x01` | RegisterRamReset | r0 selects RAM and supported I/O resets; force blank; reject serial/sound flags |
|
||||
| `0x01` | RegisterRamReset | r0 selects RAM and supported I/O resets, including disabled sound and disconnected serial state |
|
||||
| `0x02` | Halt | Wait for `IE & IF`; preserve IME and caller registers |
|
||||
| `0x03` | Stop | Freeze system clocks until an enabled live keypad condition wakes the system; preserve caller state |
|
||||
| `0x04` | IntrWait | `r0`: discard old selected flags when nonzero; `r1`: flags to wait for |
|
||||
|
|
@ -215,21 +215,26 @@ Supported flags can be combined:
|
|||
| 2 | Clear palette RAM: `0x05000000..0x050003ff` |
|
||||
| 3 | Clear all 96 KiB of video RAM: `0x06000000..0x06017fff` |
|
||||
| 4 | Clear sprite attribute memory (OAM): `0x07000000..0x070003ff` |
|
||||
| 5 | Serial reset: unsupported |
|
||||
| 6 | Sound reset: unsupported |
|
||||
| 5 | Reset supported idle serial state and select general-purpose inputs |
|
||||
| 6 | Reset disabled sound state, mixing control, bias, and accessible wave RAM |
|
||||
| 7 | Reset supported display, DMA, timer, and interrupt registers as described below |
|
||||
|
||||
**Unsupported flags:** any request containing bit 5 or 6 reaches `bios::INVALID_ARGUMENT_TRAP`.
|
||||
Validation occurs before forced blank or RAM/I/O reset writes, but after the common SWI stack save.
|
||||
This includes the common all-devices request `r0=0xff`; it is not silently treated as a successful full reset.
|
||||
Serial and audio devices remain unimplemented. The firmware's unconditional serial-data side effect is not reproduced.
|
||||
All low-byte flag combinations, including `r0=0xff`, are accepted within the supported device subset.
|
||||
This is not full audio or serial support. [Sound activation](audio.md) and [serial transfers](serial.md) still fail explicitly.
|
||||
The firmware always clears the low halfword of SIODATA32, even when bit 5 is clear; its upper halfword is preserved.
|
||||
|
||||
Every supported request first writes `DISPCNT=0x0080`, including requests with no selected flags.
|
||||
This forces a white screen and clears other display-control bits.
|
||||
RAM clears then run in bit order, using ordinary word stores.
|
||||
Zeroed OAM contains regular sprites at the origin, not disabled sprites; software must configure them before enabling objects.
|
||||
|
||||
Bit 7 runs after the selected RAM clears:
|
||||
After the RAM clears, bit 5 clears SIOCNT and SIODATA8, writes RCNT=0x8000, and clears supported Joybus reset registers.
|
||||
Disconnected general-purpose inputs read high, so RCNT reads back as 0x800f.
|
||||
Bit 6 writes SOUNDCNT_X=0, SOUNDCNT_H=0, and SOUNDBIAS=0x0200, then clears the accessible wave RAM bank.
|
||||
Disabled PSG registers remain zero. The other wave bank cannot be enabled in the current subset and remains zero.
|
||||
Reset does not produce audio, fabricate serial transfers, or bypass normal bus accesses.
|
||||
|
||||
Bit 7 runs after the selected RAM and sound/serial resets:
|
||||
|
||||
- Disable IME.
|
||||
- Disable all four DMA channels, then zero their source, destination, count, and control registers.
|
||||
|
|
@ -244,7 +249,7 @@ Read-only display status and VCOUNT continue to reflect the advancing display cl
|
|||
GREENSWAP, KEYINPUT/button state, KEYCNT, POSTFLG, and BIOS IRQ communication words are not reset.
|
||||
Bit 7 covers only the listed registers. A later matching input sample can request keypad IRQ again after IF acknowledgement.
|
||||
|
||||
Without bit 7, device configuration remains unchanged except for DISPCNT.
|
||||
Without their corresponding reset flags, device configuration remains unchanged except for DISPCNT and the SIODATA32 low halfword.
|
||||
IRQ delivery stays CPU-masked during the call. The service restores the caller's mask on return.
|
||||
Timers and DMA continue until their reset writes, if selected; this service does not stop clocks or replace frame-capture history.
|
||||
Pending IRQs remain pending without bit 7 and can be delivered after return.
|
||||
|
|
@ -504,5 +509,5 @@ Unsupported SWIs, unsupported exception vectors, and null/misaligned IRQ callbac
|
|||
The CPU reports `CpuError::UnsupportedInstruction` with `bios::UNSUPPORTED_TRAP`, rather than silently treating a service as a no-op.
|
||||
Invalid arithmetic/decompression arguments use the same CPU error type with the distinct `bios::INVALID_ARGUMENT_TRAP` instruction.
|
||||
Prior boot/service steps remain committed on failure.
|
||||
RegisterRamReset serial/sound flags, HardReset, and serial/Game Pak STOP wake-up remain unimplemented.
|
||||
Active sound, serial transfers, HardReset, and serial/Game Pak STOP wake-up remain unimplemented.
|
||||
This subset is not sufficient for Pokémon Emerald compatibility.
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ Cartridge writes, save devices, and cartridge peripherals remain unsupported.
|
|||
Both modes call `bios::boot` with the loaded bytes.
|
||||
The [original BIOS replacement](bios.md) executes its minimal boot before entering `0x08000000` in ARM System mode.
|
||||
There is no command-line option for external BIOS files.
|
||||
Unsupported services remain diagnostics. In particular, RegisterRamReset sound/serial flags, including `r0=0xff`, still fail.
|
||||
Unsupported services remain diagnostics. RegisterRamReset now accepts sound/serial reset flags, including `r0=0xff`, within the initialization subset.
|
||||
Active sound and serial transfers still fail with device-specific diagnostics; accepting reset does not establish game compatibility.
|
||||
|
||||
## Terminal execution limits and results
|
||||
|
||||
|
|
|
|||
43
docs/hardware/serial.md
Normal file
43
docs/hardware/serial.md
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# Disconnected serial initialization subset
|
||||
|
||||
The core supports idle normal-mode data registers and disconnected general-purpose pins.
|
||||
It does not support link transfers, multiplayer, UART, Joybus communication, or external serial interrupts.
|
||||
Unsupported activity remains diagnostic rather than reporting a fabricated completion.
|
||||
|
||||
## Registers
|
||||
|
||||
- `SIODATA32` at `0x04000120` is a four-byte latch in the supported normal-mode subset.
|
||||
- `SIODATA8` at `0x0400012a` retains its low byte; its upper byte reads zero.
|
||||
- `SIOCNT` at `0x04000128` retains normal 8/32-bit mode, IRQ configuration, clock selection, and the output-data bit.
|
||||
The retained mask is `0x500b`. The disconnected serial input is high, except when a general-purpose output drives it low.
|
||||
Transfer-start bit 7 and multiplayer/UART mode bit 13 return explicit errors.
|
||||
- `RCNT` at `0x04000134` retains general-purpose mode, output latches, and pin directions with mask `0x80ff`.
|
||||
In general-purpose mode, each input reads high through its pull-up. Each output reads its output latch.
|
||||
`RCNT=0x8000` therefore reads back as `0x800f`, not `0x8000`.
|
||||
Joybus mode and GPIO interrupt enable return errors. Normal-mode low-byte pin readback remains unmapped rather than guessed.
|
||||
- `JOYCNT` permits clearing already-empty status flags. Joybus interrupt enable is unsupported.
|
||||
- `JOY_RECV` and `JOY_TRANS` permit only zero writes and zero readback for reset initialization.
|
||||
Nonzero writes return an explicit error. Joybus status and data-transfer side effects are not implemented.
|
||||
|
||||
GPIO means general-purpose input/output. UART means universal asynchronous receiver/transmitter.
|
||||
No external serial device is connected. Elapsed cycles alone do not change serial data or generate an IRQ.
|
||||
Configuration that hardware accepts in other modes can still be rejected by this intentionally limited subset.
|
||||
|
||||
## BIOS reset
|
||||
|
||||
RegisterRamReset always clears the low halfword of SIODATA32, even without bit 5.
|
||||
The upper halfword remains unchanged in this functional subset.
|
||||
With bit 5 selected, the firmware clears SIOCNT and SIODATA8, selects general-purpose inputs, and clears the supported Joybus reset registers.
|
||||
It uses ordinary ARM bus stores, not a host-side reset bypass.
|
||||
|
||||
Original tests cover independent byte lanes, input pull-ups, output directions, reset flag selection, and explicit unsupported operations.
|
||||
Whole-access and block-store validation prevent a rejected control value from committing preceding bytes or registers.
|
||||
|
||||
## References
|
||||
|
||||
- [GBATEK reset functions](https://problemkaputt.de/gbatek-bios-reset-functions.htm): reset flags, general-purpose selection, and the unconditional SIODATA32 side effect.
|
||||
- [GBATEK normal serial mode](https://problemkaputt.de/gbatek-sio-normal-mode.htm): data widths, input status, and control bits.
|
||||
- [GBATEK](https://mgba-emu.github.io/gbatek/): general-purpose pin directions and internal pull-ups.
|
||||
- [mGBA BIOS implementation at 3a5e34be](https://github.com/mgba-emu/mgba/blob/3a5e34be33dc7f8f707e5bc9db69e8a430046f21/src/gba/bios.c): functional serial reset defaults, not copied source.
|
||||
|
||||
Exact firmware write ordering and hardware pin timing remain unverified.
|
||||
Loading…
Add table
Add a link
Reference in a new issue