friendofmegaman wrote:
Alley Beach wrote:

a pi wouldnt work?
I have a beaglebone and an XMOS pcb i can donate if you think you can make it happen on one of those

It probably would, but until we know why exactly a 96MHz microcontroller cannot handle LCD data it's just trial and error sad
Thanks for an offer though smile

I would actually be quite keen to try things out on a BeagleBone, one reason being that a board like this would allow for some interesting video out possibilities (such as with the DVI Cape), but as friendofmegaman says, this should by rights be doable on a Teensy (although I haven't gone and computed clock cycles thoroughly).  And I suppose friendofmegaman gets first dibs on hardware.

Jazzmarazz wrote:

I have another project using one of the Teensy's so once mine arrive, I'll jump in to this mess.

Great to hear you're on board.

Jazzmarazz wrote:

2. Pins default to input, so your for pinMode for-loop is unnecessary.

I just tested this on the Teensy, and this seems to not be the case.  This is possibly different from Arduinos.  Explicitly declaring pins makes for more readable code, too.

Jazzmarazz wrote:

Hm...there has to be a better way of separating the frames. Chances are that the new separator could still become mixed with data. Slimmer, but still not 100% mix-proof.

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.

Kitsch-Bent has them:

http://store.kitsch-bent.com/product/re … nt-screens

friendofmegaman wrote:

Nice. Where are we losing the clocks then... I mean, 96Mhz, how much time it takes to read data and send it to PC...

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.

#include <WProgram.h>

#define CLOCK_PIN 23
#define HSYNC_PIN 21

volatile char clk_cnt = 0;
volatile bool got_hsync = false;

void ISR_clock() {
    clk_cnt++;
}

void ISR_hsync() {
    got_hsync = true;
}

int main() {
    Serial.begin(1); //Always runs at Full Speed.
    pinMode(CLOCK_PIN, INPUT);
    attachInterrupt(CLOCK_PIN, ISR_clock, RISING);
    pinMode(HSYNC_PIN, INPUT);
    attachInterrupt(HSYNC_PIN, ISR_hsync, RISING);
    
    for(;;) {
        if(got_hsync) {
            got_hsync = false;
            Serial.write(clk_cnt);
            clk_cnt=0;
        }
    }
}
Alley Beach wrote:

a pi wouldnt work?
I have a beaglebone and an XMOS pcb i can donate if you think you can make it happen on one of those

If any of these have two SPI buses, I am quite sure it would be doable (at least with the Raspberry Pi or BeagleBone; I'm not familiar with the XMOS).  Even without, the extra clock speed would probably make things magically work, at least when not running an OS (or if using an RTOS and a low-level API).  I would like to eventually have this running on something quite small, though (not that a BeagleBone / Raspberry Pi is that big).

At least at first glance, this seems like almost exactly what I've been hoping for, thank you.  It is for a Windows system, but should be easily adaptable.

I wired up my board today and tried out my code.  I was getting bogus data, so I took a step back and connected Clock and HSync to two interrupts and wrote a simple program which counted the number of clock pulses between interrupts.  I was getting inconsistent numbers around 50 or less, whereas I would have expected a solid 160.  It seems that the Teensy simply isn't fast enough (i.e, calling the ISRs uses up too many clock cycles), at least when using TeensyDuino.  I was running at 96 MHz.

I think the best option at this point is to try writing some code which doesn't use the Arduino libraries.

Edit: I just had another look at Craig's NintendOscope page.  His XMega in fact only runs at 32 MHz, but he uses SPI.  It's probably worth trying SPI on the Teensy, even though Craig uses two SPI buses (one for each data bit) and the Teensy has (as far as I know) only one.

Edit again: Another option might be to use DMA to get the data into the teensy.

Good work so far, friendofmegaman.

I've started writing some Teensy code which uses interrupts, and hope to have my DMG wired up tomorrow.  I'll also test your code on my setup once the hardware side is ready.

friendofmegaman wrote:

Edges can be detected as clock==0 && clock_prev==1 (for rising edge) the other way around would be for the falling edge.

This suggests you're planning to sample the clock.  I think it would be more robust to use an interrupt.

friendofmegaman wrote:

3. And then I'm hoping to be able to make a frame inside the microcontroller this way we'll save on bandwidth (which is not that relevant of course if we have 12 MBps) ...

Given that the dead time in terms of LCD data is at the end of the line, rather than the end of the frame, it might be more feasible to send the data one line at a time.  Also note that USB Full Speed is 12 Mbps not 12 MBps.

friendofmegaman wrote:

I'd go with a one dimensional array holding a frame as an unfolded matrix.

If you're using a Teensy 3.1 I wouldn't worry about doing this unless it makes the execution more efficient (I'm not sure whether it will), as there is 64 kB of RAM (this is assuming you do store whole frames).

friendofmegaman wrote:

On the PC side I'm thinking of using (at least kick start with) pyGame - an SDL binding for python. Looks cross-platform enough for me. PySerial can be used to grab data from USB.

This is a good choice.  I've worked with Pygame before.

Good stuff.  I changed the envelope to F4 and the notes down to the third octave and now I have some crunchy bass.

I read this thread with great interest as I am working on a similar project myself.  I am interested in recording video directly from the Game Boy, rather than streaming it to a PC. I hope to eventually build a portable solution that isn't tethered to a computer.  Nonetheless, my first step will likely be to read the data with a Teensy 3.1 and send it to a computer over USB so that I can capture and analyse some frames (this saves me buying a logic analyser).

I think the Teensy is a good choice as it is cost-effective (especially compared to Arduinos) and reasonably fast.  I'd like to avoid FPGAs if possible, simply because I've never worked with them before and it looks as though the learning curve is quite steep. Nonetheless, it seems like if we use the same chip our projects could share some code, which I would be happy to do, although this may be slow going due to my work commitments.  What follows are a few thoughts I've had so far which might help you out.

[Edit, 2014-04-26: To anyone reading this thread from the start: The Teensy 3.1 is proving to be a less suitable board than I had anticipated, and so I would no longer recommend it for this application without reservations.  See pp. 5-6.]

The basic idea of connecting a Teensy would be to put the clock signal on an interrupt and use port manipulation to read the two data lines (as Jazzmarazz suggests).  It may be desirable to also use interrupts for VSync and HSync.

I initially suspected that the effective framerate of the Game Boy would be lower than the refresh rate, but having done some investigation it seems that this is not the case.  This means that we do need to be able to handle around 60 fps if we don't want to drop frames.

The Game Boy's LCD receives data at 4.19 MHz (the Game Boy's CPU clock).  The screen resolution is 160x144 px with a bit depth of 2 bpp (as you point out), and the VSync is 59.73 Hz.  This means that while we need to capture the data at 4.19 MHz, we only need to transmit it at around 2.75 Mbps if we send the raw data.  The Teensy apparently transmits serial data at USB Full Speed (12 Mbps) (although I have not tested to see if it can maintain these speeds), so this is well within spec.  Since the clock speed is fast relative to the resolution and refresh rate, it means there must be some dead time in between pixels (about a third of the time is spent actually transmitting pixels).  This time seems to occur at the end of each line and lasts about 78 µs, giving the microcontroller time to do other processing.

The Game Boy LCD is driven with 5V logic.  It is worth noting that only the Teensy 3.1 has 5V tolerant inputs; the Teensy 3.0 does not (I don't know about the older ones), meaning that you would need to add a voltage divider (although this is trivial).  Also, on the subject of voltage, as Craig of Flashing LEDs points out, "be careful of the -30V DC contrast signal," which can be found on the LCD connector.

You mentioned making a device which uses the same protocol as webcams.  USB Webcams are USB Video Class Devices, the specification is here: http://www.usb.org/developers/devclass_ … ss_1_5.zip, but it would be a lot of work to implement this on a microcontroller.  I think that writing a (userspace) driver would be a much better option, but if you really want a device that doesn't need custom drivers, you could output a video signal and then feed it into a USB video capture card (although there would be some loss in quality with this approach).

Anyhow, for reference, here are some links to the relevant research (which you have no doubt seen, but will be of interest to others reading this thread).  Possibly more to come.

Gameboy VGA Adapter (Rival-Corp) [archive]
http://web.archive.org/web/201206110330 … adapter-2/

Intercepting the Gameboy LCD (Flashing LEDs)
http://flashingleds.wordpress.com/2010/ … meboy-lcd/

NintendOscope (Flashing LEDs)
http://flashingleds.wordpress.com/2011/ … endoscope/

Gameboy Classic VGA-Adapter (snesy)
http://circuit-board.de/forum/index.php … A-Adapter/ [German]

Sabrepulse wrote:

2. pulling one of open emu's proprietary save state's out, renaming it to LSDJ.sav and loading it onto the cart (bc y'never know)

A save state is different from a save file, but it may turn out that this file is in fact a standard VBA save state, which would mean you could load it up in a regular instance of VBA and then make a save file that you can put onto the cart.  If not, try poking around in the file, there may be a VBA save state (or a normal Game Boy save file) hiding in there, possibly compressed (although VBA compresses its save states anyway) or with an extra header.

This looks interesting.  It seems that you write your code in a domain-specific language which is implemented in Ruby and gets translated to C and then compiled for the NES with cc65. I'm not sure how much actual Ruby code you can use inside the domain-specific language.

I managed to install Burn without trouble (after installing Ruby 1.9.1 alongside Ruby 1.8.7), and had a go at compiling the examples. Both hello_world and shooting compile and run fine, play_with_music compiles but does nothing. Burn produces C with syntax errors for sprite_sample. I'll let you know if I can get the C to compile. Edit: Fixing the syntax errors gets the C to compile. It shows the start screen and plays the music when run, but I don't see any sprites. It looks like a bunch of code from main.rb isn't even ending up in the C.

Nonetheless this looks promising. It would be great to have some lower-level access to NES audio in the domain-specific language.

This article, linked from the Burn Readme, might be interesting for those that haven't already seen it:
http://shiru.untergrund.net/articles/pr … s_in_c.htm

107

(43 replies, posted in General Discussion)

Great site.  I found some cool music I didn't know about (and also some I did).  I like the background image too.