English | 日本語
Real EBAZ4205 prototype playback; the ST7789 shows the live spectrum and channel activity. Image provenance.
RetroFM is a source-first FM player for the EBAZ4205 Zynq-7000 board. The ARM processing system handles storage, file parsing, sequencing, metadata, and the ST7789 display. The FPGA fabric schedules timestamped Yamaha register writes, mixes hardware FM and PCM, and produces stereo 1-bit delta-sigma audio.
Current status: the candidate source, host tests, RTL/build checks, and a packaged candidate have evidence in the workspace. Physical board playback, audio wiring, cold SD boot, and long-run acceptance are still open.
This public snapshot is source-only. It does not ship a bitstream, BOOT.BIN, ELF, local build products, or private music. The small files under testdata/generated are rights-cleared deterministic test fixtures, not a music release.
- MDX playback with optional same-basename PDX PCM.
- VGM and VGZ playback for the OPN/YM2203 path.
- An experimental, deliberately narrow OPNA/YM2608 VGM path.
- FAT32 /music scanning, SD boot packaging, metadata, volume persistence, auto-advance, looping, error screens, and an ST7789 UI.
- Five active-low PL buttons and stereo 1-bit delta-sigma outputs on H4.
- Host-testable parsers and player state separated from synthesizable RTL and the Xilinx standalone target.
flowchart LR
SD["FAT32 /music"] --> PS["ARM PS<br/>FatFs, parsers, sequencers, UI"]
PS -->|"timestamped OPM/OPN/OPNA writes"| FIFO["AXI event FIFO<br/>100 MHz deadlines"]
PS -->|"PDX / PCM frames"| PFIFO["PCM FIFO<br/>48 kHz"]
FIFO --> CORES["JT51 YM2151<br/>JT03 YM2203<br/>JT2608 OPNA"]
CORES --> MIX["FPGA mixer<br/>volume + mute ramp"]
PFIFO --> MIX
MIX --> SDM["Stereo 1-bit delta-sigma<br/>100 MHz PL plane"]
SDM --> H4["H4-4/P18 left<br/>H4-6/M19 right"]
The event scheduler, mixer, AXI front end, and delta-sigma modulators run from the 100 MHz PS FCLK. The JT51 path uses the exact 4 MHz YM2151 enable in the audited 80 MHz Yamaha-core domain. PCM is mixed at 48 kHz using the latest native core sample; this is a zero-order/latest-sample conversion rather than a band-limited resampler. See architecture.md.
| Input | Hardware path | Scope and current status |
|---|---|---|
| .mdx with optional .pdx | MXDRV/portable_mdx sequencing → timestamped writes → JT51 YM2151-compatible FPGA core; PDX remains the sampled PCM path | Implemented in the candidate source; board acceptance pending |
| One-chip .vgm / .vgz declaring YM2203 | ARM VGM iterator → JT03-compatible core from JT12/JT49 | Implemented; unsupported chips, clocks, and commands fail closed; board acceptance pending |
| One-chip .vgm / .vgz declaring YM2608 | Direct YM2608 port-0/port-1 writes → JT2608 wrapper; optional same-stem .pcm sidecar is uploaded before playback | Experimental candidate path; six FM lanes, SSG, and ADPCM-B sidecar are present; fixed rhythm-ROM/ADPCM-A audio is not implemented |
The OPNA path is intentionally narrow. It accepts timestamped direct-register writes and supported waits/end markers, uses a bounded 128 KiB sidecar store, and rejects unsupported or ambiguous streams rather than silently dropping commands. Do not infer support for arbitrary VGM commands, multi-chip files, the YM2608 fixed rhythm ROM, or ADPCM-A audio.
PMD/FMP, S98, multi-chip VGM, unsupported clock fields, unsupported commands, and malformed files are outside this source snapshot's playback scope.
Run these commands from the RetroFM directory:
.\test.ps1
.\verify.ps1
.\verify.ps1 -RouteVendor
.\verify.ps1 -ImplementFullDesigntest.ps1 configures and runs the host core tests and the public target-support tests. The MXDRV comparison test is added only when the separately fetched prototype dependency is present. verify.ps1 adds the Xilinx RTL suites; RouteVendor adds the slower vendor-core gate and ImplementFullDesign runs the complete PS/PL build.
The public verification path fetches only dependencies whose source terms are cleared for this repository:
.\fetch_dependencies.ps1
.\test.ps1
.\build.ps1The design targets xc7z010clg400-1, uses a 100 MHz PS FCLK, and does not use the adapter's standalone N18 clock. Vivado/Vitis, XSCT, and Bootgen 2024.2 are external AMD/Xilinx tools and are not redistributed here.
The current MDX target requires the optional portable_mdx/MXDRV/X68Sound prototype dependency. To create standalone firmware and a ready-to-copy SD directory for private evaluation, explicitly acknowledge that boundary:
.\fetch_dependencies.ps1 -IncludePrototypeMdx
.\build.ps1
.\packaging\build_firmware.ps1 -IncludePrototypeMdxThe final command generates build/vitis/sd/BOOT.BIN plus the SD directory.
That binary is private and non-redistributable until the portable_mdx terms are
resolved. Build output and proprietary Xilinx tools are intentionally not
committed to this public snapshot.
- Use an 8 GB or 16 GB microSDHC card for first bring-up; ordinary Class 4 or Class 10 media is sufficient.
- Create one MBR primary partition and format it FAT32. A 32 KiB allocation unit is a safe choice. Do not use exFAT or secondary/recovery partitions.
- Copy the contents of build/vitis/sd to the card root. Keep BOOT.BIN at the root and put playable files under /music.
- Keep optional PDX files beside their MDX files. OPNA sidecars use the same basename with the .pcm extension and are not standalone tracks.
- Set MIO5 to the verified SD-boot level before a power cycle. MIO4 is not a player button and should not be held during reset.
The player recursively scans /music to four directory levels. See hardware.md and packaging/README.md.
| Function | EBAZ4205 / adapter connection |
|---|---|
| Audio left | FPGA P18 → H4 pin 4 |
| Audio right | FPGA M19 → H4 pin 6 |
| Audio ground | H4 pin 2 |
| LCD | CS T20, D/C R18, reset N17, SCLK R19, MOSI P20 |
| Buttons | T19 previous, P19 play/pause, U20 next, U19 volume down, V20 volume up |
The output filter is one network per channel. The diagram shows the conservative
100 nF baseline:
FPGA output -- 220 ohm --+-- 10 uF series capacitor -- line input
|
100 nF
|
GND
With 220 ohm, 100 nF gives a nominal 7.23 kHz corner and the strongest RF
rejection, but it sounds dark. 47 nF gives approximately 15.39 kHz and is the
recommended first music-oriented replacement. 33 nF is a brighter
experimental choice only after oscilloscope checks. Do not use 10 nF as the
default single-pole filter because it passes substantially more sigma-delta RF
energy. See the full capacitor table and bench gates.
Connect the filtered output only to an active speaker or a line input rated at least 10 kohm; this is not a headphone or passive-speaker driver. Power off before changing the capacitor, verify H4 continuity, and confirm the selected contacts are not tied to 3.3 V or 5 V. After settling, measure less than 50 mV DC after the 10 uF capacitor. Use a high-impedance oscilloscope for overshoot and channel-isolation checks.
The ST7789 route constraints cover FPGA package routes only. Panel setup/hold, cable delay, ringing, voltage margin, and the audio connector still require bench measurements. Keep the bench record open until those measurements and listening tests exist.
The candidate evidence ledger is in STATUS.md. The current audit record reports 9/9 host CTest tests and 3/3 public target-support CTest tests, candidate RTL/build checks, and a routed/package candidate. Those results do not imply a board boot or audible output.
Known limitations:
- Physical H4 continuity, filtered audio, display, buttons, FAT32 cold boot, and 30-minute playback are not accepted yet.
- Standalone local ngspice evidence is unavailable; analog bench checks remain open.
- The OPNA path has no fixed rhythm-ROM/ADPCM-A audio and remains experimental.
- MDX PCM8 bank-select commands E0–E6, unknown commands, LZX-wrapped input, and zero-time/pathological loops are rejected explicitly.
- The public snapshot contains no prebuilt binary or music release.
The repository includes one reviewed real-hardware cover frame showing the ST7789 spectrum and channel display. Its source hash and deterministic crop are recorded in the media provenance note. It is presentation evidence, not a substitute for the open bench acceptance gates.
Future artifacts should be added only after their evidence is recorded:
- EBAZ4205 plus H4 adapter photograph.
- High-impedance scope capture of filtered left/right output.
- FAT32 card layout photograph.
- Architecture rendering based on the diagram above.
RetroFM Pocket is the companion software implementation for the M5Stack M5StickS3. It provides an ESP32-S3 reference for YM2203/OPN VGM/VGZ playback, YM2151/OPM MDX playback, optional PDX/ADPCM, and the title, spectrum, and channel-activity UI. Its source code is available on GitHub.
This EBAZ4205 project is a separate implementation that moves FM synthesis into FPGA hardware using JT51, JT03, and the experimental JT2608 path. RetroFM Pocket is not bundled as a dependency. Its source is MIT-licensed; see its LICENSE and dependency notices.
The combined RetroFM source is GPL-3.0-only; see LICENSE, COPYING, and THIRD_PARTY_NOTICES.md. Dependency revisions and their terms are pinned in third_party.lock.json.
The board integration follows the EBAZ4205 tutorial and adapter work by tomorrow56 / ThousanDIY. The PS preset and adapter materials are used under the upstream MIT notice.
The FPGA cores acknowledge Jose Tejada and contributors through JT51, JT12, and JT49. MDX sequencing retains the hardened mdxtools adaptation. The target's MXDRV path uses pinned portable_mdx sources and the original MXDRVg/MXDRV.X/X68Sound authors' work: the timer, command, register, PCM, and ADPCM paths remain, while software OPM output is compiled out and ordered writes are sent to JT51. The portable_mdx lock entry records unresolved prototype-distribution terms; do not treat them as cleared by this README.
Other retained notices cover miniz, M5Stack M5GFX, and the IPA font license. Read the shipped notices before redistributing a build or any test asset.
