Sad timing sounds

A project log for Dreamdrive - Dreamcast Edition

Dreamcast ODE using Dual RP2040 MUCs

kaili-hillKaili Hill 04/14/2023 at 18:550 Comments

I spent time writing my own docs based on the “GDROM Sega Packet Interface Specifications” pdf I was able to find. I discovered an issue with the command table that translated the CS0, CS1, A0, A1, A2, READ, WRITE lines into a register address (and either reading or writing data to them) the CS0 and CS1 columns should be reversed.

I figured it out experimentally and on accident when I hooked up the logic analyzer to see what kind of timing I had to work with. The decoded lines didn’t make sense. I cross checked the ICE40 fpga project verilog code and saw that the commands also had the CS lines flipped. So likely an issue with the PDF transcription or some other small detail I might have overlooked. 

I was able to get some basic code up to read the control lines via MCU2 and send them to MCU1. Knowing the timings that I need to hit, I’ll need to reconsider some wiring and code decisions. 

ATA Function Select and timings

On the falling edge of READ or WRITE, the data on the bus pins is valid. On a READ the data is latched on the rising edge. 

The read and write lines are low for sometime between 60-300ns and that timing will depend on which PIO transfer mode is in use. The lower bound of 60ns is pulled more from the ATA spec and the 300ns upper bound is what I found experimentally. 

More research is needed to see if other PIO transfer modes will be supported and thus tighter timings. 


My internal name for the mcu interconnect I named Dreamlink. Sounded fun. 
it sends 4 bits of data and waits for an ACK from the receiver before sending 4 more bits for a total of 16bits per transmission. 

.program inter_mcu_tx
.define rx_ack 22
.side_set 1 opt ;; pin 24
    ;; side set is applied at the START of an instruction
    out pins, 4         side 0; Shift out 4 bits at a time
    nop                 side 1 [3]
    wait 1 gpio rx_ack  side 0; wait for rx to sample

;; Push 16 bits of data into rx fifo
.program inter_mcu_rx
.define tx_ack 24
.side_set 1 opt ;; pin 22
    wait 0 gpio tx_ack  side 1
    wait 1 gpio tx_ack  side 0
    in pins, 4          side 0
    nop                 side 1

My communication overhead also leaves a lot to be desired. 2 bytes to start transmission, 1 byte command, 2 bytes data length, then data. That’s just too much data to send for the kind of speed I need to hit. It currently takes 96 cycles to send the control line data from mcu2 to mcu1. Then I have to decode it into the proper registers/commands and it’s just too slow. 

I also only have one way comes set up. The control lines used for the ack and clock don’t change direction. I think I might be better off moving to a two line solution and using the other 4 gpio to move some of the timing critical lines from mcu2 to mcu1. Probably read, write, intrq, and dmack or dmarq. 

There should be at least one more gpio I can access (25) on the pico and get access to all those control lines.  Then mcu2 will just be responsible for serializing CS0, CS1, A0, A1, and A2 to mcu1. And those pins can be sampled before the falling edge of read or write as there is some time that’s allotted in the ATA spec for them to stabilize. From what I see, they are stable enough before read/write goes low. That should give mcu1 a little more time to decode and prepare to access the data pins and either read or write the register/data.