Skip to content

Conversation

@tihmstar
Copy link

@tihmstar tihmstar commented Mar 1, 2024

Add a physical link cable port to support communication with real gameboy

Demo: https://infosec.exchange/@tihmstar/112021022361046810

@deltabeard
Copy link

Thanks for your work! My only question is why the existing serial functions in peanut-gb were removed? Like gb_init_serial and gb_serial_*. Do they not work as expected?

@tihmstar
Copy link
Author

tihmstar commented Mar 4, 2024

The existing serial function are incompatible with a physical link cable. They were ment for connecting 2 emulators.
Because they are unused and to avoid confusion, i removed them. There is no technical reason for removing them other than to avoid confusion. You can also keep both methods and either link to an emulator, or to a physical gameboy.
Though you'd probably need to add a little more cleanup code etc, which i was too lazy to do.

Now the reason why that implementation can't be used for a real link cable.
The gameboy speaks SPI. So in every clock cycle you receive a bit and send a bit simultaniously. There is no way to first send, then receive (or the other way around). It needs to happen simultaneously on the bus.
For connecting 2 emulators, you (ususally) can't have true simultaneous processing (levaing multicores aside). There it makes sense to split the transfer into send and receive functions. The order in which they are called doesn't really matter.
On top of that, you can slow down two emulators for synchronisation (mGBA does that), while with a real gameboy you need to make sure your gameboy keeps up fast enough.

For the physical link cable i implemented 2 PIO statemachines. Master is easy, because you provide the clock yourself. Thus on an abstraction layer you can say you "call a function" with what you want to send, and it returns the received data.
(It's actually a realy interrupt, but it doesn't really matter).
Slave is more tricky, because the remote gameboy can pull at any time and you need to provide data no matter what. Additionally, at the end of the transfer you need to trigger an interrupt (inside the gameboy).
I'm not exactly sure what happens in cases where the remote gameboy pulls twice before the local gameboy had a chance to put new data there. It probably makes sense to return the same data as the remote gameboy sent in the previous iteration. Not sure i implemented this correctly.

@L-28
Copy link

L-28 commented Apr 9, 2025

Are there plans to merge this? Would be a fantastic feature.

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.

3 participants