Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undocumented SGB Hardware quirk: Command packet bytes are buffered #509

Open
binarycounter opened this issue Nov 10, 2023 · 0 comments
Open
Labels
content Improvements or additions to documentation research

Comments

@binarycounter
Copy link
Member

binarycounter commented Nov 10, 2023

Hey, as discussed on discord, here's the issue:

The command packet buffer (at $7000 on the SNES side) is not written to immediately as bits come in (as I would expect). There is an internal 1 byte buffer that incoming transfers are written to. And only once 8 bits are transferred and that buffer is full, it gets written to $7000+. That means that if you transfer less than a byte, that data will never reach the buffer at $7000.

This quirk never comes up in official (or existing homebrew) software because the BIOS only reads the packet once the full 16 bytes are transferred and the "packet available" flag is set.

I am working on a SGB demo that jumps out of the BIOS and runs custom SNES code. Part of the demo has synchronised music playback between GB and SPC, with the GB being the part that dictates the speed. To save CPU time I was looking for the smallest possible amount of data i could transfer to indicate a new engine tick and tried just transferring the reset pulse and a single bit. This worked on Mesen2 and Higan, but not on hardware (PAL SNES 2/1/3, SGB1, EZFlash Jr cart). It only started working when I transfered a full byte.

To test this, I have created two test ROMs, one of which behaves differently on hardware, than it does on Higan and Mesen2 (both compiled from latest source).

The ROMs transfer a small program to SNES WRAM that continously reads $7000, left shifts it twice and writes it to the screen register.
The GB side then every few scanlines transfers a single bit, toggling between 1/0. On the 8bit version, this bit is then padded with 7 additional 0 bits.
If the transfer is successful, the SNES should start rapidly strobing the screen on and off every few scanlines. This only works on hardware, if the value is padded to 8 bits.

binarycounter added a commit to binarycounter/Mesen2 that referenced this issue Nov 11, 2023
@avivace avivace added content Improvements or additions to documentation research labels Dec 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
content Improvements or additions to documentation research
Projects
None yet
Development

No branches or pull requests

2 participants