Skip to content

[WIP] Add custom DVD commands for homebrew app functionality#6

Closed
Copilot wants to merge 1 commit into
mainfrom
copilot/add-custom-dvd-commands
Closed

[WIP] Add custom DVD commands for homebrew app functionality#6
Copilot wants to merge 1 commit into
mainfrom
copilot/add-custom-dvd-commands

Conversation

Copilot AI commented Apr 4, 2026

Copy link
Copy Markdown

Thanks for asking me to work on this. I will get started on it and keep this PR's description up to date as I form a plan and make progress.

Original prompt

Overview

Add new custom DVD commands (under the existing 0xF4 command prefix in dvd.c) that allow a homebrew app running on the GameCube to:

  1. Switch PicoLoader out of passthrough mode back into ODE mode so the homebrew app can communicate with the Pico.
  2. Query the current firmware version (already partially exists as command 0xF4 0x00, but should be verified/enhanced).
  3. Update the firmware itself (the code region in flash).
  4. Update the payload areas individually — the HEADER region and the PAYLOAD region as defined in memmap_data.ld.

Current Architecture

Flash Memory Layout (from memmap_data.ld)

  • FLASH (firmware code): Starts at ORIGIN(FLASH), length 128KB (PICO_FLASH_SIZE_BYTES = 131072 in CMakeLists.txt)
  • HEADER region: ORIGIN(FLASH) + LENGTH(FLASH) + ALIGN(66k, 4k) - 66k, length 66KB — contains gbi.hdr and iso.hdr
  • PAYLOAD region: Starts right after HEADER, length 2048k - LENGTH(FLASH) - LENGTH(HEADER) — contains the DOL/ISO payload

Existing Custom Commands (dvd.cdvd_request_custom())

  • 0xF4 0x00 — Device info: returns 32-byte buffer with magic 0x0D15E45E, major version, minor version
  • 0xF4 0x01 — Reboot into USB bootloader (reset_usb_boot)

How DVD Commands Work

The GameCube sends 12-byte command packets via the DVD interface. The first byte is the command ID. For custom command 0xF4, byte req[1] is the sub-command. The remaining bytes req[2..11] are available for parameters. The Pico responds using dvd_drv_send() to send data back, or dvd_drv_set_error() to signal errors.

Passthrough Mode

When PicoLoader enters passthrough mode (via dvd_drv_enable_passthrough() in dvd_drv.c), it disables the PIO state machines for recv/send, enables the passthrough SM, and forwards all signals between the GameCube and the physical DVD drive. The PIO IRQs and GPIO IRQs are disabled. To exit passthrough mode, the Pico's PIO state machines need to be re-initialized.

Required Changes

1. Exit Passthrough Mode Command (0xF4 0x02)

Add a new function dvd_drv_disable_passthrough() in dvd_drv.c/dvd_drv.h that reverses what dvd_drv_enable_passthrough() does:

  • Stops the passthrough state machine (PIO_PASSTHROUGH_SM)
  • Re-enables the recv, send, and dir state machines
  • Restores GPIO functions and pin directions for data pins
  • Re-enables the GPIO IRQs and PIO IRQs
  • Restores the pin_gc_dstrb back to PIO function (from GPCK)
  • Resets the pin_dvd_dir, pin_gc_cover, pin_dvd_reset overrides back to their ODE-mode states

However, the homebrew app cannot send a custom DVD command while in passthrough mode because the PicoLoader is not intercepting commands — the physical drive is. So the mechanism needs to work differently:

Approach: Sniff for a magic command sequence while in passthrough mode.

While in passthrough mode, the PicoLoader should passively monitor the DVD bus (since data lines are visible even in passthrough mode) for a specific magic "wake-up" command sequence. When it detects this sequence, it exits passthrough mode and re-enters ODE mode.

Implementation approach:

  • In dvd_drv.c, when entering passthrough mode, set up a GPIO IRQ or use a DMA-based sniffer on the pin_hstrb line to capture incoming bytes on the data bus
  • Monitor for a specific magic sequence (e.g., the custom command 0xF4 0x02 followed by a magic value like 0x50 0x49 0x43 0x4F = "PICO")
  • When the magic sequence is detected, call dvd_drv_disable_passthrough() to exit passthrough mode
  • Since the drive will likely return an error for the unknown command, the homebrew app can then retry the command once PicoLoader is in ODE mode and get a proper response
  • Add a state variable (e.g., static bool passthrough_active) so other parts of the code know the current mode

In dvd.c, add the 0xF4 0x02 sub-command handler:

  • When received in ODE mode, respond with a success acknowledgment (e.g., send back a 4-byte status)
  • The homebrew app flow: send the magic command → PicoLoader exits passthrough → re-send command → get success response

2. Firmware Version Query Enhancement (0xF4 0x00)

The existing device info command already returns version info. Enhance it to also include:

  • Flash capacity (flash_capacity from dvd.c)
  • The flash offsets of the HEADER and PAYLOAD regions (so the homebrew app knows where to write)
  • The sizes of the HEADER and PAYLOAD regions
  • A flags byte indicating current state (e.g., bit 0 = passthrough available, bit 1 = drive detected)

Update the device_info response buffer to include this information in the existing 32-byte response:

Offset 0x00-0x03: Magic (0x0D, 0x15, 0xE4, 0x5E)
Offset 0x04: PROGRAM_VERSION_MAJOR
Offset 0x05: PROGRAM_VERSION_MINOR
Offset 0x06: Flags byte (bit 0 = drive present, etc.)
Offset 0x07: Reserved
Offset 0x08-0x0B: Flash capacity (big-endian uint32)
Offset 0x0C-0x0F: Header region flash offset (big-endian uint32, rel...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

@silverstee1 silverstee1 closed this Apr 4, 2026
@silverstee1 silverstee1 deleted the copilot/add-custom-dvd-commands branch April 4, 2026 14:28
Copilot AI requested a review from silverstee1 April 4, 2026 14:28
Copilot stopped work on behalf of silverstee1 due to an error April 4, 2026 14:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants