uXe wrote:
rvan wrote:

Good news.  But can the Arduino (or Teensy) access the RAM at 4.19 MHz, and when it is not providing the clock signal itself?  Clearly, we wouldn't have to read the RAM every single clock cycle, though.  Let's look more into whether the data stored in VRAM is in fact useful to us.

...it's SRAM (static) so it doesn't need to be clocked / refreshed the way DRAM (dynamic) does, here's a memory map:

I realize I wasn't entirely clear in what I was asking.  Rather, I was wondering whether the microcontroller would be able access the RAM while something else (i.e., the Game Boy), clocked at 4.19 MHz, was accessing it, as we would presumably have to access it between the Game Boy's read/writes.  It seems like the dual access SRAM solves this issue, though.

Other than the complexity of the RAM-snooping approach, my main concern is whether an Arduino/Teensy can in fact access the RAM as fast as the Game Boy updates it.  Does anyone have benchmarks for Arduino/Teensy RAM access?

Also, either bandwidth or processing power becomes a major issue here. We would either have to send all 8 kB of VRAM Data (+OAM etc.) every frame, or do enough processing on the microcontroller to work out which data we do need to send (which would amount to the MAP every frame and tile data + OAM when the tilebank is changed).  This is assuming whatever is running on the Game Boy is using sprites in a normal way.  The situation would be quite different for things like the Game Boy Camera and possibly LSDJ.

This does not seem the most viable approach for a computerless screen capture solution, which I am interested in in particular.

friendofmegaman wrote:

Any ideas how do we map the pins?

Pins marked A0-A12 on gameboy SRAM are mapped to either A0r-A12r or A0l-A12l

It seems like D0-D7 are mapped to IO0-IO7 (either r or l)

NOT OE also presented in both chips

This sounds right.  We would also connect the GB's /WR to the RAM's /R/Wx and /MOE to /OEx.  Incidentally, your image is of the DMG's system RAM rather than VRAM, but the two chips are the same type and the address and data buses are shared.  Also, uXe and ultramega are correct that we will need access to OAM, which is on the other SRAM.

friendofmegaman wrote:

So from the implementation POV we're gonna need several shift registers (e.g. 8x8), two dual RAM chips.

Why do we need shift registers here?  For accessing the two RAM chips from the microcontroller, can't we just invoke the relevant /CE line?

friendofmegaman wrote:

Now I'm beginning to doubt is this idea really worth it. It's too much work to do for just video out... on the other hand I at least can comprehend it unlike FPGA that I have absolutely no idea about.

Anyways I'd like to see how's rvan's idea with shift registers before doing something that hardcore.
Also Nitro's suggestion seems easier to implement, so we should not be hasty here.

Let's take a step back from everything here and think about what our overall aims for the project are, and what we can't achieve with an emulator or why we don't want to use an emulator.  Myself, I am interested in recording video (i.e., screen capture) from a DMG-01 with a device that is smaller than a SGB + SNES.

I am still going to try out my shift register idea and Nitro's idea next, when I find the time.

uXe wrote:

An Arduino Mega can directly address external SRAM as if it were internal:

Good news.  But can the Arduino (or Teensy) access the RAM at 4.19 MHz, and when it is not providing the clock signal itself?  Clearly, we wouldn't have to read the RAM every single clock cycle, though.  Let's look more into whether the data stored in VRAM is in fact useful to us.

friendofmegaman wrote:

I can also try to look at the DMG's actual clock signal with the DSO if need be.

I realized I could just do this on the board I'm using for testing without having to remove the crystal.  It's a sine wave.

DSO Trace of DMG CPU Clock.  Probe at X10 setting.

I'm fairly certain other waveforms should work, too:

LTC6930 Typical Output Waveform.  From the LTC6930 Datasheet.

friendofmegaman wrote:

Ok, my naive understanding that clock signal is just a square wave fell apart. The 0-1-0-1-... signal produced with 4M frequency and connected to where I would connect an LTC doesn't do the job.

I was quite certain a square wave would do fine (if not, I suspect Nitro knows what to do).  Looking at the data sheet for the LTC6930 (the chip in Kitsch-Bent's easy_CLK) would suggest a square wave works.  Perhaps your synthesis isn't working as expected at that speed?  I assume you are using an Arduino or Teensy.  If so, put up the code and I can test it with my DSO at some point.  I can also try to look at the DMG's actual clock signal with the DSO if need be.

rvan wrote:

I have also been experimenting with a 74HC595 and have so far got the hardware side set up correctly (as far as I can tell).  I'll aim to write code and test this over the weekend.

A brief update on this: I ended up having a hedge to cut this weekend so haven't had as much time as expected, but still plan to do this at some point.

CYBERP_NK wrote:

Is it just a plastic plate glued in place there?

I don't have a SNES to hand to confirm this, but I am reasonably certain this is the case.

I haven't tried this myself, but you could try soaking the part in isopropyl to loosen the adhesive on the circle before prying it off.  Masking may be a better bet though if you are good with the tape.

87

(1,206 replies, posted in Nintendo Handhelds)

RJL wrote:

I modified this Gameboy so that the clock speed is controlled by light!

Very impressive, and allows for lots of noisemaking possibilities.  I might make make a mod like this myself since I am a fan of Shitwave and Rez.  I assume you are using an LTC1799 with the LDR in place of the potentiometer?

A while ago I made a similar circuit (not a mod, since it is a separate device) which controls Nanoloop sync speed with an LDR (I can post code if anyone is interested), but controlling actual clock speed is much more exciting.

RJL wrote:

I'd love to post a pic,  but I don't know how... Can anybody tell me? <:(

[img=Alt Text]http://example.org/your_image.png[/img]
friendofmegaman wrote:

Why you need a shift register?

The serial side is connected to the DMG's D0 (pixel bit 0 output), the parallel side is connected to the Teensy.  This should mean that the Teensy needs to read data 8 times less frequently, while all 8 bits can be read from a single register (GPIOx_PDIR) in one go.  This  will eventually require two shift registers, one for each pixel bit, but I am testing with a single one first.

In the second of a series of long posts, I think I have caught up with current developments.

Jazzmarazz wrote:

I think I will try out my new Raspberry Pi since it has built in video outputs. No idea where start with programming taht thing though...

The two options with a Raspberry Pi are to write standalone ('bare metal') code, or use a hard RTOS.  I don't think an OS like Linux is really suitable for this project, due to various timing issues.

For the former approach, see http://www.cl.cam.ac.uk/projects/raspbe … orials/os/, which is apparently much recommended.  For RTOSs, I believe FreeRTOS may be a good option, although I haven't looked at it much myself.  See http://www.freertos.org/ in general and http://www.raspberrypi.org/forums/viewt … mp;t=22423 for the Raspberry Pi.

Jazzmarazz wrote:

all I can find are the cycles per assembly op-code.

Is this a straightforward calculation on the ARM?  Could you please post a link to the information you found?

friendofmegaman wrote:

However, Nitro's idea seems to be viable, but what I don't want to do is underclocking the boy to get video. I have a feeling that to implement it this way we gonna need to write some assembly code, because it must run the program normally and when signal arrives (and we can predict that) read the bits. So it should be fine grained to instruction-wise precision.

I think this is still the best approach short of using a faster board or FPGA.  Nitro seemed to suggest that the limited clock cycles wouldn't be an issue with this approach, and that the bottleneck would in fact be the data bandwidth of the USB Serial.  I do plan to benchmark this on the Teensy at some point (or see if someone else has done benchmarks), to see if we are actually close to Full Speed, in which case RLE would probably be viable, assuming that we have the clock cycles to do this too.

friendofmegaman wrote:

Aside from FPGA and SNES+SGB there's one more option that actually Craig from FlashingLEDs suggested - use a web cam, put it close to the screen and then on PC side extract the actual frame based on pixel colors.

I'm not in favor of this approach personally, although it does seem viable, so by all means try it if you're keen.

friendofmegaman wrote:

1. Having the recording device you can have nice big picture on PC. On emulator you'll need to upload your save file back and forth. It's a minor inconvenience, but I'd like to eliminate it
2. This also allows you to make *authentic* game reviews / let's plays
3. I find aesthetically more appealing to play on real hardware. Unfortunately GB LCD is shit and I wan't to fix that.

To be honest, it seems like a Super Game Boy would be a good solution here, although point two still stands, as a Super Game Boy is arguably less authentic due to the difference in clock speed.

Part of my motivation for being part of this project is to make a portable recording (not redisplay) solution which does not involve carrying around a SNES and a Super Game Boy.  I am aware that a Game Boy Advance with a TV Adapter is a reasonable solution, but I am also interested in the authenticity aspect, and would like to avoid the de-digitization and re-digitization of the signal necessary with this approach, assuming a digital recording medium (although this could admittedly be remedied with an amount of post-processing).

Jazzmarazz wrote:

Does anyone know what sort of data is stored in VRAM? Is it simply active sprites, windows, etc? or might it be something useful to us?

This is an interesting idea.  The question is can we read the VRAM fast enough?

friendofmegaman wrote:

Great! Thanks for sharing rvan. So it's time to move on to the next strategy. Which one is it going to be? I think we must try Nitro's idea. I think we shouldn't move from micro-controllers until we test every single way to do the job.

You're welcome.  I agree that we should try Nitro's plan.

I have also been experimenting with a 74HC595 and have so far got the hardware side set up correctly (as far as I can tell).  I'll aim to write code and test this over the weekend.

In the interest of completeness and good progress documentation, I have tested more or less all the code we have so far.  There was a chance this would raise some discrepancies in results which would potentially point to a wiring fault, but it seems that my results are generally as predicted and mostly in line with friendofmegaman's.

friendofmegaman's original Teensy code ("v1"):
My results match friendofmegaman's.  Here is an excerpt of a hex dump of the screen data.  This is an 'interesting' portion; most of the data is all zeros:

0015800: 0000 0000 0000 0000 2c00 0000 0000 0000  ........,.......
0015810: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0015820: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0015830: 0200 0000 0000 0000 0000 0000 0000 0000  ................
0015840: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0015850: 0000 0000 0000 0000 0200 0000 0000 0000  ................
0015860: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0015870: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0015880: 3000 0000 0000 0000 0000 0000 0000 0000  0...............
0015890: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00158a0: 0000 0000 0000 0000 2300 0000 0000 0000  ........#.......
00158b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00158c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00158d0: 4300 0000 0000 0000 0000 0000 0000 0000  C...............
00158e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00158f0: 0000 0000 0000 0000 0200 0000 0000 0000  ................

friendofmegaman's python serial dump code:
Works for me (I had to change the port setting), but sometimes hangs after 20 bufferfulls.

Here is a modified version, which prints the data as hex instead of saving it as a binary file.  I have found this useful for testing:

#!/usr/bin/python
#Author: friendofmegaman, rvan
#Print serial data as hexadecimal.

import serial

port = '/dev/ttyACM0'
speed = 115200
buflen = 100
ser = serial.Serial(port, speed)

try:
    j=0
    while True:
        data = ser.read(buflen)
        for i in data:
            print i.encode('hex'), "",
            j+=1
            if j==16:
                print
                j=0
except KeyboardInterrupt as e:
    print 'Shutting down'
    ser.close()

friendofmegaman's Python/Pylab frame display code:
Works, but is slow and CPU-intensive here, probably because PyLab is not designed with all points addressable (APA) graphics in mind.  I might work on a PyGame implementation which uses the data format (3 pixels per byte) which I defined above.  I have done APA graphics successfully in PyGame before.

my simple interrupt test program (i.e., clock pulse counting) (p. 3):
I get data like the following.  Under correct operation, I would expect constant 0xA0s (i.e, 160s).  The pattern shown in the data is repeating, i.e., a rise in values, followed by around three times as long of zeros.  I do now know why this is.

00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
00  00  00  00  00  00  00  0a  0a  0b  0a  15  15  15  15  16 
15  15  15  15  12  15  15  15  15  15  15  0a  0a  2b  2c  2d 
2e  2f  2f  2e  2f  2f  2e  2d  2c  2d  2c  2c  2d  26  27  00 
00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00 
0d  0d  0d  0e  0e  0e  0e  0e  0e  0e  0e  0e  0e  0e  0e  0e 
00  00  0b  00  00  00  00  00  00  00  00  00  00  00  00  00 
00  00  00  00  00  00  00  0a  0a  0a  0a  15  15  11  15  15 
15  15  16  15  15  15  15  15  15  15  15  0a  2b  2c  2c  2b 
2e  2f  2e  2e  2f  2e  2e  2d  2d  2c  2d  2c  28  26  27  26

Jazzmarazz's cleaned version of friendofmegaman's Teensy code ("v2"):
Unmodified, it does nothing.  If I explicitly declare the pins as inputs, it works as the original (see previous comments).  Nice clean code.  Jazzmarazz, if you're reading this, I'm curious whether there is a reason for using const ints rather than #defines for the pin numbering.  This version in theory introduces some function call overhead.  I don't know how much this would effect things.

Breadboard set up for testing friendofmegaman's code.

friendofmegaman's updated version of Jazzmarrazz's version ("v3):
Results are as for v2, above.  The note about declaring inputs applies here too.

friendofmegaman's clock pulse counting code:
My results match friendofmegaman's.  I do not know, however, what is causing the discrepancies in results between this code and my testing code.  Could someone shed some light on this?  It is quite possibly something trivial.

uXe's LED test v1 (interrupts):
The output is suprisingly consistent, but at a much slower rate.  The LED on pin 13 flickers, but this may be due to the dead time between lines.

DSO output. Channel 1 = GB clock; channel 2 = Teensy output.  Probes set to X10.

uXe's LED test v2 (no interrupts):
The output seems to be at the same rate as the input (as expected), but the pulse width is quite inconsistent, often too wide.

DSO output. Channel 1 = GB clock; channel 2 = Teensy output.  Probes set to X10.

General Notes:
The Teensy must sometimes be restarted (e.g., by removing and re-inserting the USB plug) after programming before it will do anything.  This confused me a couple of times when I forgot to do this and wondered why I wasn't seeing any serial data.

uXe wrote:

Again, the code you posted earlier is also doing a Serial.write on every HSYNC, and I can't help but think that is eating up a lot of cycles and again would suggest to maybe try storing those values in an array or something instead, and then Serial.write them out once you've collected a certain amount to see if that has any effect on the count?

I've tried this out just for completeness; here are the results:

n = 144
mean = 48.92
mode = 49
sd = 5.84

Clearly not right (as I expected); we would expect 160 every time if it were working as it should.

friendofmegaman wrote:

I though about deploying a logic analyzer. What they do (if understand it correctly) is record a sample to the memory (e.g. flash) and then you read it to PC. A good thing would be to know how to build one and use for real time data processing.

Does this mean that is is not possible to capture a continued data stream with a typical logic analyser?

friendofmegaman wrote:

Next - Nitro's suggestion to use uC as clock master. I don't understand how (in case of Teensy at least) it solves the issue of only 24 clocks available to do something with the data? 24 is an optimistic estimate.

This would probably require underclocking the Game Boy (unless using a faster microcontroller).  Obviously, this isn't ideal.  However, if the Game Boy is driven by a clock signal synthesised by the microcontroller, then pixels will arrive at a predictable cycle relative to the work loop, and can be read directly, with no need for polling or interrupts.  Has anyone (nitro, most likely) tried single-stepping the Game Boy's processor?  Being able to do so would aid in designing a solution using this approach.

friendofmegaman wrote:

Any other options?

I think the option of using SPI (probably dual SPI buses), as per Craig, is still feasible.  I also raised the idea of DMA on the Teensy, but I don't know whether this is feasible or not.  Here is a thread on the PJRC fora which might be relevant: http://forum.pjrc.com/threads/999-ARM-assember-code

For those interested, I have updated my post on the first page with a link to a thread on snesy's Gameboy Classic VGA-Adapter, in German.

Glitch Militia wrote:

Just a quick question; If you succeed, will you share it?

If this was directed at me, the answer is an unequivocal yes.  I am happy to share any of my work on this.  I don't, however, currently own a logic analyser.  I am planning on possibly buying an inexpensive one from China, but this would be a while in arriving.  First, I will do some research into APIs, as we would have to be able to access the data from the logic analyser directly.

uXe wrote:

I would be interested, yes. smile

Here it is:

//Author: rvan
/* A simple program to output pulses when a clock signal is received.  Pin 13
   is the LED pin, but we also attach a DSO probe here.  Currently this program
   DOES NOT produce the intended output, presumably because the ISR returns too
   slowly.
 */

#include <WProgram.h>

#define CLOCK_PIN 23
#define OUT_PIN 13

volatile bool have_clock = false;

unsigned int i;

void clock_ISR() {
    have_clock = true;
}

int main() {
    pinMode(CLOCK_PIN, INPUT);
    pinMode(OUT_PIN, OUTPUT);
    attachInterrupt(CLOCK_PIN, clock_ISR, RISING);

    for(;;) {
        if(have_clock) {
            digitalWrite(OUT_PIN, HIGH);
            i++; i--; i++; i--; //This creates a very short delay.
            digitalWrite(OUT_PIN, LOW);
            have_clock = false;
        }
    }
}
uXe wrote:

Again, the code you posted earlier is also doing a Serial.write on every HSYNC, and I can't help but think that is eating up a lot of cycles and again would suggest to maybe try storing those values in an array or something instead, and then Serial.write them out once you've collected a certain amount to see if that has any effect on the count?

Ah, I see what you mean; I thought you were simply talking about doing a serial write within the ISR or not.  I will try this out tonight.

uXe wrote:

I still think it is worth trying friendofmegaman's code without the Serial.write slowing down the interrupt to see what difference it makes, as I wrote earlier:

The code I posted earlier (p. 3), which only increments a variable in the ISR (serial is done in the work loop), demonstrates the same problem.  I also wrote an even simpler version which sends a pulse on an output pin when the clock ISR is called.  I compared the output signal with the clock signal using a DSO (which may not be entirely reliable for this application) and found that the ISR was not being triggered for most of the clock pulses.  I can post this code if you are interested.

The more I read about the Teensy 3.x, the more I feel that it is a poorly thought out development system, with a poor library which makes it unsuitable for this application, and likely for many of the tasks which the Freescale chip would be capable of.  Thankfully, it seems that most (if not all) of the issues lie with the libraries, rather than the board itself, and so can probably be avoided if we do not use the TeensyDuino libraries.

Knowing what I know now, I would have likely not chosen a Teensy for this project, and would recommend to anyone else wishing to get involved and buy hardware to consider other options (and perhaps suggest them here), rather than jumping in and buying a Teensy.  Nonetheless, I have a Teensy now, and so will persist with it and see how far we can get.  Also, the Teensy retains the advantage of being reasonably cheap.

Here is another thought, though: How feasible is it to forget the Teensy and simply use a logic analyser to capture the data, and process it on the PC using code not unlike friendofmegaman's original version (i.e, poll the signals)?  Craig of Flashing LEDs has more or less done this, but can it be done in realtime?

friendofmegaman wrote:
rvan wrote:

With my simple testing code (as follows) I think it was the ISR being called which took too many clock cycles (I recall reading 10 cycles of overhead somewhere).  Getting away from the Arduino code will hopefully reduce this.

Let us know the results, because in theory I don't see how this is faster. The Arduino sketch is merely a wrapper for what you've written. It puts contents of setup() to main() and the contents of loop() inside the  for(;;) loop in main. Of course I might be wrong smile

It's not the wrapper part of the Arduino environment which is the concern, but rather the Arduino/TeensyDuino library functions, which are known to be inefficient in some respects.  I suspect that using attachInterrupt may add additional complexity to the way in which interrupts are actually handled, which consumes unnecessary clock cycles.  This is just a guess, though.

friendofmegaman wrote:

There's one more concern though. What if a signal arrives while Teensy is handling the previous interrupt? This may me the reason why rvan's attempt didn't succeed. But I'd really like to see the code in order to avoid wasting time on re-doing something that has been done already.

Based on the simple sample program I wrote (see above), I think the issue is simply that the ISR is not being called every time it should, as the interrupting signal (Clock) is too fast; i.e., the ISR cannot be called and return within ~24 clock cycles.

friendofmegaman wrote:

Then you need to check the pseudonym for your serial devise where Teensy is. For *nix systems it should be something like /dev/tty.usbXXXX where XXXX is some string. I've no clue how it's addressed in Windows though.

Incedentally, mine is /dev/ttyACM0, not /dev/tty.usbXXXX, in case anyone else is looking for the right device.


friendofmegaman wrote:

Another question is has anybody benchmarked the USB serial speed of Teensy 3.1? According to this page: http://www.pjrc.com/teensy/usb_serial.html it is not very big and we need to keep data to transmit as small as possible as I'm trying to do by packing it into an unsigned char array.

The page you linked seems to be for the older Teensy boards, not Teensy 3.1.  The older boards are a different architecture, so this information isn't relevant to us.  While it may be worth benchmarking serial at some point, I do not suspect it will be a major issue, and think we should work on getting data into the Teensy, before we go into the particulars of how we get it out of the Teensy.

Jazzmarazz wrote:
rvan wrote:

I had a think about this, and I think the only foolproof way is to store only three pixels per byte and use the remaining two bits to store new line and/or new frame markers.  Another option would be to simply count pixels (assuming we always begin sending at the start of a frame) and hope we don't drop any bytes, but that is not as robust.

I like that, 3 pixels per byte and a 2-bit marker. Serial is sure fast enough to handle that.

I imagine the data scheme looking like this:

[hd][px][px][px]
Where hd is a two-bit header, and px is a two-bit pixel.
Pixels are encoded left to right, most significant to least significant.

Possible hd values are:
01    Beginning of line
10    Beginning of frame
11    Reserved

Since 160%3=1, we will have one byte at the end of the line which contains only one pixel.  We can probably simply ignore the other two pixel spaces in this byte, without not needing a special header here (note that this byte will directly precede the byte with a newline header).

friendofmegaman wrote:

Conjecture:

I'm missing bits because the CLOCK handler for the previous interrupt hasn't finished executing.

Yes.  I am quite certain now that this is the case.  I had figured that 24 cycles would be enough to set a variable within an ISR, but it seems like it is not.  My testing code (p. 3), and yours (p. 5) both point to this.

-----------------------------

Here is the original code I wrote using interrupts.  While this does not work on the Teensy (at least at present), I suspect that this strategy would work on a faster board.

/* Author: rvan
   Interrupt-based reading of pixel data from the DMG.

   This code currently DOES NOT WORK; we suspect this is because the ISRs
   (specifically clock_ISR()) are not returning fast enough.  Additionally, the
   code has been modified for clarity since last being tested, it is possible
   that some minor errors have been introduced.
 */

#include <WProgram.h>

#define CLOCK_PIN 23
#define HSYNC_PIN 22
#define VSYNC_PIN 21

unsigned int i;

volatile unsigned char new_pixel = 0;
volatile bool have_pixel = false;

unsigned char three_pixels = 0;
unsigned char num_pixels = 0;

volatile unsigned char place_in_line = 0;

unsigned char line[54];

void clock_ISR() {
    /* Read a pixel */

    //Do something here to wait for the pixel inputs to settle, if necessary.

    new_pixel = PIND;
    have_pixel = true;
}

void vsync_ISR() {
    /* The vsync_ISR() routine is NOT TESTED. */
    /* Note: It may be a bad idea to do serial transfer in the ISR, but we
       leave it here for now to eliminate checking more flags in the work loop.
     */
    /*
       Note also that the new frame and new line markers do not conform to the
       protocol described; in reality the remaining six bits would also contain
       pixel data.
     */
    Serial.write(B100000); //New frame.
}

void hsync_ISR() {
    Serial.write(B010000); //New line.
    place_in_line = 0;
}


int main() {
    DDRD = B00000000; //All pins as input.
    pinMode(CLOCK_PIN, INPUT);
    attachInterrupt(CLOCK_PIN, clock_ISR, FALLING);
    pinMode(HSYNC_PIN, INPUT);
    attachInterrupt(HSYNC_PIN, hsync_ISR, FALLING);
    pinMode(VSYNC_PIN, INPUT);
    attachInterrupt(VSYNC_PIN, vsync_ISR, FALLING);

    Serial.begin(1); //Always runs at Full Speed, the parameter is ignored.
    
    for(;;) {
        if(have_pixel) {
            //Shift the pixels he have two bits to the left, zero the two bits
            //where the new pixel goes,
            //and OR everything together.
            //We assume (for now) that the new pixel is in the two LSBs itself
            //and doesn't need shifting.
            three_pixels = (three_pixels << 2) | (new_pixel & 3); 
            have_pixel = false;
            num_pixels++;
            if(num_pixels == 3) {
                /* We store only 3 pixels. This is so we can use the remaining
                   two bits to show where a frame starts.
                 */
                //Add the pixel to the line.
                line[place_in_line++] = three_pixels;
                if(place_in_line == 40) {
                    //Send the line.
                    Serial.write(line, 40);
                    place_in_line = 0; //We shouldn't need this, as
                    //place_in_line is reset by the hsync ISR.
                }
                num_pixels = 0;
            }
        }
    }
}

Despite our lack of success so far, it seems like we are making progress, and at least coming to a better understanding of the hardware (and software) involved (I am, at least).

friendofmegaman wrote:

Also rvan, could you please share you code?

I will do so tonight, at which point I also hope to have caught up with this thread.

nitro2k01 wrote:

One of these days I'll give this a shot using a microcontroller as the clock master for the DMG. Should solve any and all timing problems.

This is a very interesting prospect; I think I will try this out quite soon (when I have time; not a lot over the next few days as I have a friend visiting).  Nice to see you're following along by the way, nitro.  On a side note, do you know how the Game Boy Camera behaves at low clock speeds?  I can confirm it works at half speed, but I am interested in how far it can be underclocked.