Once or twice a year on HN, I find myself reading a post and thinking "this is a complete and utter waste of time, this person has spent so much time and effort on something so meaningless that they could have spent on something else", and yet despite that thought, absolutely loving it.
I advise using pen and paper lists of ideas, somewhere visible! Whenever I have my eyes wandering from a screen, I pick it up and start working on a couple of ideas.
If you like this kind of thing you should take a look at the suckerpinch channel on YouTube. The technical complexity and amount of effort spent on some of his projects is quite unbelievable, with no practical use other than displaying the crazy things you can do with computing.
Particularly Reverse Emulating the NES and Harder Drives are good examples of this.
May favourite suckerpinch is the Uppestcase and Lowestcase letter video.
I like that he takes something familiar - and goes sideways with it such that you could have thought of that, but probably wouldn't have "explored that space" mentally.
It really is impressive! Like, sure - maybe many of us could learn these skills and are technically capable of doing something like this - but how many of us would have such a creative idea and then actually dedicate what must be hundreds if not thousands of hours to making it happen.
They explain very early on the purpose of it. As someone who's worked in events for years and worked with Nintendo on their own such official devices, this is niche but absolutely useful.
I am always pleasantly amazed and surprised when I see something truly odd, in a hyperbolic example, like "We have implemented a complete gravitational model of the solar system on a commodore 64" or "Custom cartridge created for NES/Famicom for advanced protein folding simulations" or "Reverse engineering a Chumby to add a 100 gigabit ethernet interface"
Agreed! I, probably like many HN readers, tend to over-optimize every part of my life. But life is more than optimization for an output — sometimes the purpose is just the pure joy and fun of doing it. Projects like this are a great reminder.
I'm surprised that it apparently works so well (most of the time, for many games) without knowing the state of inputs, just relying on conditional branching. I would have expected a lot of code to just manipulate registers based on inputs and use those to send different PPU commands.
I wonder if you could achieve 100% parity (and audio) without modification of the console by doing all the emulation in the capture card. Send some pre-built ROM to the console which just reads inputs, sends them back to the "cartridge" and then reads back video output from the emulator.
Edit: Ah I see the video stream cartridge runs at 20fps, but gameboy games can run up to 60fps. I suppose that wouldn't work for the original purpose of streaming tournaments.
Regarding the chip just being a duplicate destination of the inputs, I wonder how many games are deterministic enough for this to be possible. I feel like a lot of effort put into modern multiplayer games is ensuring determinism where if you capture the set of user inputs, it's guaranteed to be replayed into the same game, but that perviously a lot of race conditions or randoms() would make that not true.
if i remember correctly, the rng on tetris on the gameboy is terrible, and is quite predictable. https://tetrisconcept.net/threads/randomizer-theory.512/page... has some more info about it. Im not familiar with with how some of the prng algorithms are seeded, but maybe on tetris, the hardware responsible is part of the cartridge and then can be intercepted. just a thought tho
I would be very surprised if the Gameboy, like practically any 8 bit CPU of that era, had any dedicated instructions or hardware for RNG.
So it's a software RNG, and the user input is pretty much the only "random" thing coming in from outside. This is very common for games. It still is: Games like Civilization often let you specify the seed to initialize their software RNG with, so you or someone else can replay the exact same game.
> I'm surprised that it apparently works so well (most of the time, for many games)
I worked on a Game Boy related project recently and, similar to you, was surprised at how heavily the Game Boy uses the cartridge ROM. If I remember correctly, it makes on the order of thousands of requests to the ROM per frame.
That's to be expected though: That's just the actual game code itself being executed! The code is not copied from the cartridge into RAM (that would just be a gigantic waste of RAM), the Gameboy directly executes it from the ROM in the cartridge.
So every single instruction being executed, you will see on that bus. And every instruction hopefully serves to either build up the current frame, or do game logic for later on.
Well... might be true 99% of the time, but it's not a safe assumption.
Nothing stopping a developer temporally copying code out of ROM to minimise bank switches or because they want to implement an algorithm with self-modifying code.
But that isn't actually a problem for this approach, because the CPU still puts the address on the cartridge bus even when it's accessing internal RAM, and you can still monitor which addresses it accesses to tell which way it's branching, even when executing from RAM.
On Gameboy copying some code to RAM is essentially required if you want to use sprites, because the fastest way to update the sprite attributes (so called OAM) is to use DMA. And during OAM DMA the CPU cannot access anything else than a internal 128 byte RAM, so the DMA trigger + delay loop procedure must be copied and executed there.
Likely true. You still do see every instruction executing on the bus if I’m not mistaken, and the overwhelming majority will still execute directly from the cartridge ROM I assume. (Happy to be proven wrong, but I imagine the code for addressing OAM is still a small fraction of what’s executing.)
With a better chip this should be totally doable. It would achieve the desired result of being able to play on your hardware of choice (the original gameboy), but at the expense of it not being a "true" gameboy hardware ran game, but rather an entirely emulated game.
Maybe I'm misreading the article but it sounds like even when just copying data from cartridge to vram there isn't enough time to get 60fps, no matter how fast your emulator hardware is.
However, I guess that is a problem for arbitrary video where you have to be able to completely swap out the tile map on each frame (actually 2x/frame). For a GB game you could only swap the tiles/sprites that have actually updated and send over info what to redraw.
So potentially possible I guess? Someone should do the instruction count / bus bandwidth math.
No, it's just that he used a codec that has much more bit depth than he needed on the output end to make it a regular webcam. He says himself that if he used a custom codec then it would be fine but would require software support on the receiving computer.
For games with really tight timing, it might be tricky, but worst case you could trigger on vsync, read the inputs, write them to the cartridge, the cartridge bank swaps to the real code, with the read inputs to load an immediate value without any further modifications. Then go back to the interception code when the original code is looking for vsync again.
Maybe some games don't have time for that, but I'd guess most do. If you have execution bandwidth for that, you probably have execution bandwidth for straight line code that only does the PPU per frame work, because the emulator did all the cpu work and ran ahead (hopefully)... Of course, when PPU work happens midframe, timing gets real important and that may be tricky.
I've always wanted a debug cartridge with modern design and features ... I imagined something very much like this but with additional serial and video outputs:
- video passthrough (like this one, obviously)
- serial console debug output (framerate ? CPU ? sprite count ?)
- secondary video output of sprites - perhaps with a palette of all sprites and an array of sprites actually on-screen ?
- tertiary video output ???
I make no claim that any of the above would actually be useful.
I'm thinking about this as a development tool from an alternative timeline that never existed here ... and specifically, a standalone development tool that doesn't require a PC tied to it with a SCSI cable like the SN Systems and (other carts) did.
You don't really achieve any more for debugging with this than you would inspecting memory values on an emulator though, you're not actually inspecting memory on the real hardware - any bugs that are only reproducible on the real hardware would cause this to desync because it's just an emulator running side by side with the real hardware.
This has a couple advantages over an emulator though. Debugging a game in an emulator has the disadvantage that the emulator may not be 100% accurate to original hardware, so if the behavior you're trying to debug is the result of an unknown or undocumented hardware quirk, it may not be reproducible in an emulator. This was extremely common during the early days of NES emulation -- many homebrew games created during this time period are not playable on original hardware or modern emulators, because they relied on behaviors that were implemented inaccurately in early emulators.
You're much less likely to be in this situation today, because (as you said) modern emulators are very accurate. But this is only because people spend enormous amounts of time reverse-engineering the original hardware and running test cases to find the weird quirks and obscure corner cases. For these investigations, some kind of debug cartridge could be invaluable.
Another reason for debugging on original hardware is simple convenience. Speedrunners usually prefer original hardware (or FPGA recreations) because emulators introduce input latency (which is very noticeable and makes a huge difference for high-level players). I speedrun Super Metroid for the SNES, and I often load the game into a debugging emulator to investigate strange behaviors or glitches. It's kind of annoying to have to switch from my nice FPGA setup that I use most of the time, to my laggy computer emulator that I use when I want to investigate something. But the community has already developed hardware and software that supports reading and writing the console's memory in realtime over USB, and this functionality is available on the most widely-used flashcarts. Adding support for simple breakpoints and a hex memory editor/disassembler would be a fun and relatively straightforward software project, and a nice quality-of-life improvement, so it's something I'm hoping to work on when I have the time.
Can you send me an email? (See my profile on HN) I’ll be working on an SNES related project soon that touches on speed running and would like to ask you more about your setup.
What a wonderful piece of work! From the description it's possible to imagine a series of showstoppers, each followed by an epiphany that allowed the work to continue one more step. And I'm sure there are more stories not shared.
Truly inspiring!
Probably the most interesting thing for me is that they used the rp2040 and based their pcb design off of the minimal design example kicad files from the 'Hardware design with RP2040' pdf released by the pi foundation here: https://datasheets.raspberrypi.com/rp2040/hardware-design-wi... - (side note, it is so cool that they produce documentation of this quality) - I was just reading through this yesterday and was wondering how feasible it was to build on their example. I am excited to get into PCB design and this gives me hope that I can make some cool things. If anyone has any suggestions or advice on getting into this sort of thing please let me know!
I’d use kicad and start with a simpler example to get used to the workflow. Also have the pcb produced and assemble the pcb with components yourself. This will give you tons of insights for your next designs. Oh yeah another kool example would be to convert a through hole design to surface mount (and have it fully assembled eventually, maybe first batch should be hand assembled for debugging purposes).
> This together with the overhead of emulating an 8-bit CPU on a 32-bit CPU made it necessary to overclock the rp2040 from its default 125 MHz5 to 225 MHz. The rp2040 can usually handle this without any problems, but still I would love to see if someone can improve the efficiency of my code to dial this back a bit.
It wasn't clear to me if this was because of the code, or because of the environment.
For the latter it helps to have a dedicated chip doing the emulation, without being burdened by a multitasking OS that rudely interrupts you at all times. Does not have to be an FPGA implementing the Gameboy CPU, could also be a normal boring CPU that dedicatedly does the emulation (it has to be fast enough, but >200MHz seems overkill).
Alternatively, maybe proper use of realtime threads helps already.
I've been thinking that there oughta be a human-sized cartridge for data in general. Current SD-cards are flimsy, and it's just getting worse. The Minidisc/Gameboy cartridge/MiniCD form factor was something that was tangible but not oversized. It could go in your drawer and not be lost. You could write something informative on it.
I loved the 3.5 floppies too. Maybe the Star Trek TOS "book-tape" was the right idea all along. Wonder if the in-universe people were clueless where the "tape" part of the name came from?
Well, I'd like it to be a standard size I could stack. Maybe I'm just nostalgic but I pine for the days where I had a shelf full of self-burnt CD's. Shame they're so prone to bit rot.
Speaking as a connoisseur of Game Boy (I write gameboyessentials.com) I have to say this is a very interesting project, since it allows video out, sort of, without modifying the device. Congratulations.
As long as the image data is coming from the cartridge and the instructions are obviously moving data that originated from the cart to video RAM or registers (I don’t know anything about the game boy). M with something like the GB camera, latency is less of a concern though, so the cartridge could probably interrupt the camera periodically to read video memory.
this is so cool. As a former electrical engineer (now I just write APIs) I really appreciate everything here and miss working with PCBs terribly! I don't have any ideas for what to make though, although it would be something along the lines of what you did.
I have an unrelated question. I was never very good at the physical hardware part of things (i.e. enclosures, plastic, etc), and I noticed for example in the video you appeared to be "sinking" a little screw nut into plastic. What is this process and how did you learn how to do it? If anyone can ELI5 because I'm a total newb at this.
"A few months ago a Tetris enthusiast got in touch with me about this problem: An online Tetris tournament during which the contestants stream their gameplay."
I don't see how an online Tetris tournament during which the contestants stream their gameplay is a problem.
I know what they're saying, it's just worded strangely. The actual problem is that didn't know how to stream the game, but that's actually not a problem either; they just wanted to stream their game, which is a desire.
> Have a look at the first vsync interrupt of “The Legend of Zelda - A Link to the Past” on the original Game Boy:
I think this should be "Links Awakening".
Side note, something like this could _almost_ be used to implement multiplayer gaming for things like multi-world randomizers (see https://www.youtube.com/watch?v=2VJ21rQ4L2U for an example on SNES).
Relatedly, Linus Tech Tips has a recent video https://youtu.be/4YpRJtvFmP8 about a 3DS dev kit they got their hands on, in that video they also mention that there is a similar device for the DS that was used to capture video for live e-sports tournaments.
I would love to see a possibility to record / dump the whole datastream as such in a file. This way it would be possible to improve the video emulation afterwards and it would be a gold mine for emulator developers analysing these dumps to fix bugs and understand the process of data transfer.
Wouldn't it be easier to send the bus data to the PC and run the emulator there?
Or would sending the custom data via USB be a problem without a custom driver or something?
That said though, emulating it on the pi is way more impressive.
That sounds like a hard hard real-time [1] problem, one that I would be very scared of trying to implement over USB to a PC. Especially if that PC runs a ordinary non-real-time operating system.
Sure, USB and a typical desktop-class CPU are easily fast enough to handle the bandwidth requirements, but I don't think you could safely uphold the latency requirements in order for the emulation to run well. There I said it, now some crazy h4cK3r can prove me wrong, and everyone wins! :)
It seems like they were attempting to leverage existing USB camera drivers and viewers. That would allow writing the output once on the device and it being consumable on anything that can use a USB webcam. M
I wonder if it would have been eaiser to make a cartridge that lets you use the gameboy controls as a controller instead? This is still really neat of course but maybe that would have saved the emulator step.
That would add some amount of possible lag - generally running an emulator on a PC will introduce some frames of latency. This doesn't introduce any latency except for spectators, for whom it doesn't matter.
I don't see why it'd have to add lag or require an emulator? I was thinking more a SNES controller adapter where the Game Boy sends it's button presses out the link port similar to the GBA and it's GCN adapter. Then you could just use a modded SGB or SGB2 to display on TV. Perhaps there's no way to make that work however.
That would be really neat - but would still display slower than the built in screen on the GB. Even assuming your adapter somehow adds zero latency, TVs add at least a frame of latency.
curious if it's possible to make a generic version of this that somehow interprets the voltage of the LCD and can stream anything without actually seeing, so to speak.
It's possible but requires more hardware hacking. The only accessible port on an unmodified Game Boy is the cartridge slot, which doesn't carry the video signal. The point of this article is to use an unmodified console, which means you can only access what can be seen from the cartridge slot, which is activity on the memory/IO bus, and so this project recreates the video from that.
To do what you propose, you'd have to open it up and add hardware hooked in to the connection that goes to the LCD. Someone's probably done that somewhere; it's a different scope than the project here.
Now you made me think horrible thoughts: What if the signals to the LCD happen to be AC coupled into the cartridge pins enough that you can filter them out and reconstruct the image from it, at least with some level of fidelity.
Probably not though. For starters, the interface to the LCD is most likely parallel, and you have to be really lucky for them to be discernible over unintentional coupling.
For example, it could still work if the individual digital signals have slightly different phase and amplitude, in which case what you get from the cartridge pins is "just" quadrature amplitude modulated multiplexing of all pins. And you'd need some high quality test equipment to sample that...
This is probably my favourite link this year.