Hotdry.
systems-engineering

RP2040 PIO 状态机精确仿真 ZX Spectrum/Amiga 卡带协议:时序波形生成参数

基于 RP2040 PIO 状态机,给出 ZX Spectrum/Amiga 卡带协议的 bit-banging 实现、时序参数与 PIO 配置要点。

RP2040 的 PIO(可编程 I/O)子系统是复古计算机卡带仿真领域的强大工具,特别是针对 ZX Spectrum 和 Amiga 等机的磁带加载协议。这些协议依赖精确的波形时序,如 ZX Spectrum 的 pilot tone(约 806μs 高 / 低脉冲)和数据位(0 位约 1333μs,1 位约 667μs),传统 CPU bit-banging 难以维持纳秒级精度,而 PIO 状态机(State Machine, SM)可独立运行,达到系统时钟(133MHz)级别的确定性执行。

PIO 的核心在于 2 个 PIO 块,每个块 4 个 SM,共 8 个 SM,每个 SM 执行共享 32 条指令的 PIO 汇编程序。SM 配备 OSR(输出移位寄存器)、ISR(输入移位寄存器)、X/Y Scratch 寄存器、双向 FIFO(TX/RX),以及 DMA/IRQ 接口,支持 FIFO 与 CPU/DMA 无缝数据流。指令集仅 9 种:JMP、WAIT、IN、OUT、PUSH、PULL、MOV、IRQ、SET,支持 [delay] 槽(0~31 周期)和 side-set(并行设置最多 5 引脚)。例如,SET pins, 1 [10] 可精确生成 10 周期高脉冲,结合 clkdiv(16.8 定点分频)调整 SM 频率,实现 μs 级波形。

针对 ZX Spectrum 卡带(EAR 端口,3.5mm 单声道音频,~1200-4000Hz),协议分 pilot(2168 脉冲对齐)、sync1(806μs 高 + 1606μs 低)、sync2(668μs 高 + 1606μs 低)、数据位(pilot 后边沿对齐,0: 1333μs 高 + 1333μs 低;1: 667μs 高 + 1333μs 低)。Amiga 类似,但 FAST/SLOW 模式下时序不同(pilot 240μs/480μs)。PIO 优势:一个 SM 生成时钟 / 数据波形,另一个处理数据流(DMA 从 SD 卡读取 .tap/.tzx 文件),CPU 仅监控。

工程实现中,先用 pioasm 汇编 .pio 文件生成 .h(如 maxduino.pio)。典型 PIO 程序:

.program cassette_tx
loop:
    pull block      ; 从 TX FIFO 拉 32 位数据块
    mov osr, ~x     ; 反转位序(MSB 先)
bitloop:
    jmp x-- bitloop ; X 递减至 0
    out pins, 1     ; 输出 LSB 到 OUT pins(bit-bang)
    set pins, 1 [pilot_delay]  ; 高脉冲,延迟 pilot_delay 周期
    set pins, 0 [sync_delay]   ; 低脉冲
    jmp !osre bitloop ; OSR 空时拉新数据

配置 SM:pio_sm_config c = cassette_tx_program_get_default_config (offset); sm_config_set_out_pins (&c, ear_pin, 1); sm_config_set_clkdiv (&c, div); pio_sm_init (pio0, sm0, offset, &c); pio_sm_set_enabled (pio0, sm0, true)。关键参数:

  • SM 频率:sysclk /clkdiv,目标~1MHz(ZX pilot ~1.2kHz,周期~833 cycles)。133MHz / 133 = 1MHz,精确匹配 μs 级:pilot 高 806μs → 806 cycles,高 clkdiv=165(133MHz/165≈806kHz)。
  • 延迟槽:[n] = n / SM_freq(μs)。pilot 高:n = 806μs * SM_freq;数据 0 高:n=667μs * freq。
  • FIFO 阈值:autopull=true, pull_thresh=8,确保流式无中断。
  • Side-set:sideset_count=1, sideset pins for EAR(GPx),指令侧带 set。
  • DMA 链:DMA0 从 SD → PIO TX FIFO,IRQ 同步多 SM(一 SM 波形,一 SM 校验)。

落地清单:

  1. 硬件:RP2040 板(如 Pico),3.5mm JACK(GP0 EAR OUT),SD 卡槽(SPI GP1-4),复古机 EAR IN。
  2. 固件:CMake 添加 pio_add_program (pio0 cassette_tx.pio),UF2 刷入。SD 加载 .tap 文件,解析块头(pilot/sync/data len)。
  3. 参数表(133MHz sysclk):
协议 元素 高 (μs) 低 (μs) clkdiv 高 delay 低 delay
ZX Pilot 高 / 低 806 806 165 133 133
ZX Data0 高 / 低 1333 1333 200 267 267
ZX Data1 高 / 低 667 1333 200 133 267
Amiga SLOW Pilot 240 240 278 67 67
  1. 监控 / 回滚:UART 日志 SM IRQ(rx_fifo () 检查溢出),示波器验波形(±5% 时序容忍)。风险:时钟漂移→动态 clkdiv 校准;长 tape(>10min)→DMA 优先级高,避免 CPU 饥饿。
  2. 优化:多 SM 并行(SM0 pilot/sync,SM1 data),JOIN_TX FIFO 双倍缓冲。

实际项目如 MaxDuino 使用 PIO 精确仿真多协议,支持 ZX/Amiga/MSX 等,加载速度达原生 100%。相比 CPU 轮询,PIO 零 jitter,功耗低(空闲 <1mA)。

资料来源:

  • RP2040 数据手册 PIO 章节。
  • ZX Spectrum 卡带格式规范(WOS)。
  • MaxDuino 项目(retrogamecoders 评测)。
查看归档