Gameboy Camera Extraction Via Arduino
Follow this section to replicate this project quickly for your gameboy camera
Scroll to the bottom of this page, to see the js gameboy printer hex decoder
This project was to try and dump out all the images that I got from two gameboy cameras that I purchased off the internet.
For convenience and also considering that other people may want to construct their own extractor in an accessible manner, I opted to extract the images via the gameboy link cable to an arduino pretending to be a gameboy printer.
This is by no means a reverse engineering of the gameboy link protocol, as that has already been done. But rather it is just an implementation to allow for people with an arduino and a gameboy link cable to get their images out of their gameboy for archival purpose.
This is important, as the gameboy camera is battery backed up. If the battery dies, the images stored within it is lost forever.
What I hope to see in the future is a way to organise a way to retreive all the images from second hand gameboy cameras and display it online.
Project Source Code
If you are interested in replicating the project, then all the source code is placed in this repository:
- Github Repo: arduino-gameboy-printer-emulator
- Tutorial: Quick Start
Project Makeup
This projects consist of two parts:
- Arduino sketch emulating a gameboy printer to a computer via a serial link.
- Javascript gameboy printer hex stream rendering to image in browser.
- Part of the code is based on the gameboy tile decoder tutorial at http://www.huderlem.com/demos/gameboy2bpp.html
You can decode your own gameboy printer hex stream at the bottom of this page.
Images Extracted
For privacy reasons, I have not released all the images that I had extracted from the gameboy camera carts. But I would love to get back in touch with whomever originally took this image and hand over the images.
Hope you enjoy the images. I don't know when it was taken however.
Cart 1
- cart_one_A01.png
- cart_one_A02.png
- cart_one_A03.png - A girl and her mother?
- cart_one_A04.png - A woman
- cart_one_A05.png - Black Image
- cart_one_A06.png
- cart_one_A07.png
- cart_one_A08.png
- cart_one_A09.png
- cart_one_A10.png
- cart_one_A11.png
- cart_one_A12.png
- cart_one_A13.png - White Image
- cart_one_A14.png
- cart_one_A16.png
- cart_one_A17.png
- cart_one_A18.png - A girl hand signing V
- cart_one_A19.png - A toddler sticking out her tounge
- cart_one_A20.png - A pouting toddler
- cart_one_A21.png - A mother holding up her toddler?
- cart_one_A22.png - Same girl hand signing V elsewhere
- cart_one_A23.png
- cart_one_A24.png
- cart_one_A26.png
- cart_one_A27.png - A grandmother
- cart_one_A28.png - A guy and a girl
- cart_one_A29.png
- cart_one_A30.png
Cart 2
Not as many images in this cart
- cart_two_A01.png
- cart_two_A02 - A girl
- cart_two_A03 - A father?
- cart_two_A04 - A toddler? With various gameboy stickers.
- cart_two_A05 - Same as A04 but different sticker and expression
- cart_two_A06 - A older girl holding up a victory sign
Protocol In Summary
Full details in ./gbp_emulator/gameboy_printer_protocol.h
Packet
| BYTE POS : | 0 | 1 | 2 | 3 | 4 | 5 | 6 + X | 6 + X + 1 | 6 + X + 2 | 6 + X + 3 | 6 + X + 4 |
|---------------|-----------|-----------|-----------|-------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|
| SIZE | 2 Bytes | 1 Byte | 1 Byte | 1 Bytes | 1 Bytes | Variable | 2 Bytes | 1 Bytes | 1 Bytes |
| DESCRIPTION | SYNC_WORD | COMMAND | COMPRESSION | DATA_LENGTH(X) | Payload | CHECKSUM | DEVICEID | STATUS |
| GB TO PRINTER | 0x88 | 0x33 | See Below | See Below | Low Byte | High Byte | See Below | See Below | 0x00 | 0x00 |
| TO PRINTER | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x81 | See Below |
- Header is the Command, Compression and Data Length
- Command field may be either Initialize (0x01), Data (0x04), Print (0x02), or Inquiry (0x0F).
- Compression field is a compression indicator. No compression (0x00), Yes Compression (0x01)
- Payload byte count size depends on the value of the
DATA_LENGTH
field. - Checksum is 2 bytes of data representing the sum of the header + all data in the data portion of the packet
- Status byte is a bitfield byte indicating various status of the printer itself. (e.g. If it is still printing)
Timing
Below measurements was obtained via digilent ANALOG DISCOVERY
1.153ms
<--------------------------------------->
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
__ _ _ _ _ _ _ _ ___________ _ _ _ _ _ _ _ _
CLK: |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_|
DAT: ___XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX____________XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_
<--> <---------->
127.63 us 229.26 us
- Clock Frequency: 8kHz (127.63 us)
- Transmission Speed: 867 baud (1.153ms per 8bit symbol)
- Between Symbol Period: 229.26 us
Here below is the signal captured from the gameboy link cable, with nothing connected to the other side. I was doing this to just understand the general structure of the communication packet, based on existing documentation.
Resources
- https://github.com/gism/GBcamera-ImageSaver - Eventally found that someone else has already tackled the same project.
- However was not able to run this sketch, and his python did not run. So there may have been some code rot.
- Nevertheless I was able to get some ideas on using an ISR to capture the bits fast enough.
- http://gbdev.gg8.se/wiki/articles/Gameboy_Printer - Main gb documentation on gb protocol, great for the inital investigation.
- http://furrtek.free.fr/?a=gbprinter&i=2 - Previous guy who was able to print to a gameboy printer
- http://playground.arduino.cc/Main/Printf - printf in arduino
- https://www.mikrocontroller.net/attachment/34801/gb-printer.txt
- Backup if above link is dead here
- Most detailed writeup on the protocol I found online.
Findings
Some of the issues I am having with the current project is that there appears to be no flow control between the gameboy and the gameboy printer.
This means I had to increase the speed of the serial link between the arduino and the PC to 115200baud to keep up with the gameboy link speed.
Also I was not able to correctly decode the CRC.
Future
Some things I would certainly like to see improved upon, via other people improving on this project. Is...
- Get crc working -- given up. Not important
- Document the gameboy printer protocol so future hardware hackers can better understand the protocol
- Investigate if there is a way to force flow control -- edit: Nope
- Making the js decoder a lib in node.js so it can decode directy from the arduino
- Creating a proper pcb to make a cleaner gameboy to pc link cable.
Embedded JS Gameboy Printer Decoder
For your convenience, I have also included the decoder below. An example stream is also provided of a blank image.