Skip to content

Instantly share code, notes, and snippets.

@GOROman
Created August 22, 2026 07:19
Show Gist options
  • Select an option

  • Save GOROman/99b86c956938414ed733b15ea2c34568 to your computer and use it in GitHub Desktop.

Select an option

Save GOROman/99b86c956938414ed733b15ea2c34568 to your computer and use it in GitHub Desktop.
ModRetro Chromatic LCD・I/O・操作・通信・サウンド調査

ModRetro Chromatic: LCD / I/O・操作・通信・サウンド調査

調査対象

以下は公開ソースを静的に追跡した結果である。回路図や実機波形を使った電気的検証ではない。

全体像

Game Boy / Game Boy Color core
 ├─ LCD pixel stream ─→ color correction / frame blend / OSD
 │                      ├─→ ST7785 LCD interface
 │                      └─→ USB UVC 160x144/60fps
 ├─ stereo PCM ───────→ IIR + DC blocker
 │                      ├─→ TLV320 audio codec / speaker / headphones
 │                      └─→ USB UAC 2.0, 16-bit stereo, 44.1kHz
 ├─ joy P14/P15 ←────── physical buttons + ESP32 virtual buttons
 ├─ serial port ───────→ physical Game Boy link connector
 ├─ IR port ───────────→ IR receiver / LED
 └─ cartridge bus ─────→ physical 5V cartridge interface

ESP32 ←──115200bps UART──→ FPGA system monitor
  ├─ OSD/settings, brightness, palette, status
  ├─ physical button state readback
  └─ virtual button injection (command/address 0x09)

1. Game Boy Color対応

ChromaticはGBC対応である。FPGA統合層ではGame Boyコアの isGBC を常に 1 にしている。ブート処理後はCGB対応カートリッジならCGBモード、DMGソフトなら互換モードとして動作する構成である。

実装上確認できるCGB機能には次がある。

  • CPU倍速切替(KEY1、4 MHz / 8 MHz相当)
  • VRAM bank 0/1
  • WRAM bank
  • CGBカラー・パレット
  • HDMA
  • CGBのIRレジスタ
  • CGBシリアル高速モード

統合箇所: emu_system_top.v

2. LCDと映像経路

Game Boyコアからの入力

コアは次のLCDストリームを出す。

  • gb_lcd_data[14:0]: 15-bit RGB
  • gb_lcd_clkena: 有効画素
  • gb_lcd_mode: LCDモード。水平タイミングにも使用
  • gb_lcd_vsync: フレーム同期
  • gb_lcd_on: LCDオン/オフ状態

vid_system_top は160画素×144ラインのGame Boy映像を受け、15-bit RGBを各色6-bitへ展開する。

フレーム処理

  • 外部PSRAMを映像・OSD用メモリとして使用する。
  • 前フレームを読み、設定に応じてフレームブレンドを行う。
  • LCD向けとUSB UVC向けに別々のカラー補正を持つ。
  • ESP32が生成するOSD、バッテリー警告、タイマー、デバッグ表示を合成できる。
  • ST7785出力とのクロック差をラインバッファで吸収する。

映像処理: vid_system_top.sv

メモリ接続: top.v

ST7785 LCDインターフェース

起動時は LCD_SPI_CSX/SCLK/SDALCD_RESET を使ってST7785を初期化する。表示開始後は次の同期インターフェースを使う。

  • LCD_DOTCLK
  • LCD_HSYNC
  • LCD_VSYNC
  • LCD_ENABLE(DE)
  • LCD_DB[5:0]
  • LCD_PWM(バックライト)
  • LCD_TE入力

LCD_DB は18本のパラレルRGBではなく、6本へBlue / Green / Redを3位相で時分割している。ラインバッファは各Game Boyラインの160画素を取り込み、パネルタイミングへ合わせて読み出す。

パネル出力: ST7785_panel_master.v

初期化: ST7785_init.v

USB映像

LCDへ送るのと同系統の映像をUSB UVCへ分岐する。USBディスクリプタ上の映像形式は160×144、16-bit/pixel、60 fpsである。

定義: uvc_defs.v

注意: v18.8の HDMI_* ポートはGame Boy内部信号のデバッグ出力に割り当てられており、HDMI映像送信器ではない。

3. 操作入力

物理ボタン

A、B、上下左右、Start、Select、MenuはFPGAの専用GPIOへ直接入る。通常のゲーム入力はESP32を経由しない。

physical button
 → FPGA GPIO
 → button_debouncer
 → OSD/menu gating
 → opposite-direction filtering
 → Game Boy P14/P15 multiplex
 → joy_din[3:0]

Game BoyのJOYPは4本入力をP14/P15で多重化するため、FPGA側も joy_p54 に応じて次を返す。

  • 01: Start / Select / B / A
  • 10: Down / Up / Left / Right
  • 00: 両グループの論理積
  • 11: 全解放

実装: emu_system_top.v

ESP32からの仮想ボタン入力

ChromaticにはESP32からFPGAへボタンを注入する経路もある。FPGAの物理ボタンと MCU_buttons はORされる。

bit 入力
0 Start
1 Select
2 B
3 A
4 Up
5 Right
6 Left
7 Down
8 Menu

ESP32はUARTコマンドID 0x09 (kTxCmd_PokeButton) でビットマップを送る。FPGAではsystem-monitor address 9 を受信すると MCU_buttons <= rx_data[8:0] とする。

FPGA受信: system_monitor.sv

物理+仮想入力の合成: top.v

ESP32送信: fpga_tx.c

MCUには poke <hex bitmap> というコンソールコマンドもあり、「Chromaticがボタンを押した」状態を擬似生成できる。OSD表示中は物理ボタン状態がFPGAからESP32へ戻され、ESP32側のメニュー操作に使われる。

仮想入力実装: button.c

4. FPGAとESP32の通信

システム管理用通信は専用UARTで、設定は115200 bps、8 data bits、parityなし、1 stop bit、ハードウェアフロー制御なしである。

FPGA ESP32_MCU_D11 (TX) → ESP32 GPIO10 (RX)
FPGA ESP32_MCU_D12 (RX) ← ESP32 GPIO9  (TX)

V2パケットは概ね次の構造である。

0x8F | command/address | payload length | payload | CRC-8 SAE J1850

ESP32→FPGAには仮想ボタン、システム設定、明るさ、カラーパレット、バージョン要求などがある。FPGA→ESP32には物理ボタン、電池電圧、音量・ヘッドホン状態、PMIC状態、FPGAバージョン、ゲームパレット情報などがある。

FPGA UART: top.v

MCU UART設定: main.c

5. Game Boy通信機能

通信ケーブル

Game Boyコアのシリアルエンジンは物理 LINK_CLK, LINK_IN, LINK_OUT へ接続されている。内部クロック動作時だけ LINK_CLK を駆動し、外部クロック時はHi-Zにして相手側を受ける。したがってマスター/スレーブ双方のリンク動作を想定した回路である。

実装: emu_system_top.v

赤外線

IR_RXIR_LED はGame Boyコアへ直接接続されている。CGBのRPレジスタ(FF56)を通じた赤外線通信を実装できる構成である。

USB複合デバイス

FPGAはUSB側で次の機能をまとめた複合デバイスを実装する。

  • UVC: 160×144映像
  • UAC 2.0: 16-bit stereo、44.1 kHz
  • CDC/UART: ESP32コンソールへのブリッジ

USB CDCのDTR/RTSはESP32のEN/IO0にも接続され、ESP32ブートローダー制御に使われる。これはUSBゲームパッドを読むUSB Hostではなく、Chromatic自身がPCから見えるUSB Device実装である。

実装: usbuvcuart_top.v

6. カートリッジI/O

物理カートリッジへ次の信号を出している。

  • 16-bit address CART_A[15:0]
  • 8-bit bidirectional data CART_D[7:0]
  • CART_RD, CART_WR, CART_CS, CART_CLK, CART_RST
  • データバス方向制御 CART_DATA_DIR_E
  • 挿入検出 CART_DET

MBCは実カートリッジ側に存在するため、Chromatic FPGAはカートリッジバスサイクルを生成する。CGBのHDMAやDMA時もこの外部バスへアクセスする。

CART_AUDIN はトップポートには存在するが、調査対象のv18.8 RTL内では音声ミキサーへ接続されていない。

7. サウンド

Game Boy APUからアナログ出力まで

GB/GBC APU 16-bit L/R
 → audio_filter
    ├─ IIR filter
    └─ DC blocker
 → aud_system_top
 → serial audio (AUD_MCLK/BCLK/WCLK/DIN)
 → TLV320 codec
 → speaker / headphones

audio_filter はコア出力の安定化、IIR処理、DC除去を行う。aud_system_top はI2CでTLV320を初期化し、音量、ヘッドホン検出、PMIC状態をポーリングする。

ヘッドホン接続時はステレオ、非接続時は左右を加算したモノラルスピーカー用データへ切り替える。ソフトウェアmute、または音量閾値によるmuteもある。

フィルタ: audio_filter.v

コーデック出力: aud_system_top.v

同じフィルタ済みL/RはUSB UACにも入力される。USB定義は16-bit、2-channel、44.1 kHzである。

UAC定義: uac_defs.v

8. Tang Primer 20K移植への示唆

操作の最短移植は、Chromaticの MCU_buttons とP14/P15多重化をTang版へ移す方法である。

USB gamepad on Mac
 → host utility
 → Dock UART
 → 9-bit virtual button bitmap
 → Chromatic-compatible joy multiplexer
 → Game Boy core

この方式ならUSB HostコアをFPGAへ追加せず、現在のROMローダーUARTをROM転送後の操作チャネルとして再利用できる。将来スタンドアロン化する場合も、ESP32をBLE/USBゲームパッドからUARTへのブリッジとして置けば、Chromaticとほぼ同じ仮想入力経路を維持できる。

結論

  • Chromaticの通常操作は物理ボタン→FPGA直結である。
  • ESP32とは115200 bps UARTで双方向通信し、OSD管理に加えて仮想ボタン注入も可能である。
  • GBC対応は有効で、倍速、メモリバンク、HDMA、カラー、IR、シリアルを含む。
  • LCDはST7785をSPI初期化後、6-bit時分割RGB+同期信号で駆動する。
  • USBはUVC映像、UAC音声、CDC/UARTを持つDeviceであり、USB Hostゲームパッド入力ではない。
  • 音声はAPU→IIR/DC filter→TLV320とUSB UACへ分岐する。
  • Tang Primer 20KではESP32仮想入力方式を模倣するのが最短である。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment