Difference between revisions of "Gameboy VGA adapter"

From Hackerspace ACKspace
Jump to: navigation, search
m (set project picture)
 
(7 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
{{Project
 
{{Project
|State=Active
+
|State=Completed
|Members=Prodigity
+
|Members=Prodigity, Danny Witberg
 
|Description=Adding VGA output to a gameboy classic
 
|Description=Adding VGA output to a gameboy classic
}}  
+
|Picture=FPGAscreen.jpg
 
+
}}
 
[[Image:VGA.png|center|300x150px|Temporary VGAmeboy logo]]  
 
[[Image:VGA.png|center|300x150px|Temporary VGAmeboy logo]]  
  
Line 15: Line 15:
 
Nowadays the gameboy has been replaced by far more advanced (read: battery-slurping) handheld devices and as such, many people have one lying around collecting dust.<br>  
 
Nowadays the gameboy has been replaced by far more advanced (read: battery-slurping) handheld devices and as such, many people have one lying around collecting dust.<br>  
  
As some of you might remember, the biggest problem with the gameboy classic was the unlit screen which caused any form of sunlight to render the screen into a useless plastic mirror.<br>  
+
As some of you might remember, the biggest problem with the gameboy classic was the lack of backlighting which caused any form of unwanted lighting to render the screen into a useless plastic mirror.<br>  
  
 
REJOICE! For I have decided to add VGA output to the gameboy so you can play on 21" screens! (TAKE&nbsp;THAT&nbsp;SUN!) No more visibility problems! (Yes you can add LEDs to the back of the screen, stop being so boring&nbsp;:P).  
 
REJOICE! For I have decided to add VGA output to the gameboy so you can play on 21" screens! (TAKE&nbsp;THAT&nbsp;SUN!) No more visibility problems! (Yes you can add LEDs to the back of the screen, stop being so boring&nbsp;:P).  
Line 39: Line 39:
 
The resolution of 160x144 however poses a problem, no such VGA resolution exists and as such we will be forced to pick a different resolution and do some pixel juggling.<br>  
 
The resolution of 160x144 however poses a problem, no such VGA resolution exists and as such we will be forced to pick a different resolution and do some pixel juggling.<br>  
  
The solution? We will use double buffering and a different resolution.<br>  
+
The solution? We will use <strike>double</strike> buffering and a different resolution.<br>  
 
 
  
 +
<br>
  
= Calculations =
+
= Calculations =
  
<u>Double buffer</u><br>  
+
<strike><u>Double</u></strike><u>buffer</u><br>  
  
To determine the size of our buffers we simply take the resolution of the gameboy screen and multiply the amount of horizontal pixels with the vertical pixels (160x144 = 23040).<br>  
+
To determine the size of our buffer<strike>s</strike> we simply take the resolution of the gameboy screen and multiply the amount of horizontal pixels with the vertical pixels and the bpp (160x144x2 = 46080).<br>  
  
The 23040 bits translate roughly to 3 kilobyte.<br>  
+
The 46080 bits translate roughly to 6 kilobyte.<br>  
 
 
Since we are dealing with 2 bits per pixel, we need 2 buffers per frame, which adds up to 4 buffers in total.
 
  
 
<br>  
 
<br>  
Line 69: Line 67:
 
<u>VESA&nbsp;signal 768x576</u> [http://tinyvga.com/vga-timing/768x576@60Hz source]<br>  
 
<u>VESA&nbsp;signal 768x576</u> [http://tinyvga.com/vga-timing/768x576@60Hz source]<br>  
  
<b>General timing</b>
+
'''General timing'''
  
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! Screen refresh rate
+
! Screen refresh rate  
 
| 60 Hz
 
| 60 Hz
 
|-
 
|-
! Vertical refresh
+
! Vertical refresh  
 
| 35.819672131148 kHz
 
| 35.819672131148 kHz
 
|-
 
|-
! Pixel freq.
+
! Pixel freq.  
 
| 34.96 MHz
 
| 34.96 MHz
 
|}
 
|}
  
<b>Horizontal timing (line)</b>
+
<strike>To 'convert' 160 pixels to 768 we simply adjust the pixel clock: 34.96 MHz / 768 pixels = x MHz / 160 pixels x = 160 pixels * (34.96 MHz / 768 pixels) = 7.283 MHz So if we use a pixel clock of 7.283 MHz, the 160 pixels will stretch themselves over a width of 768 pixels.</strike>
<br>Polarity of horizontal sync pulse is negative.
 
  
{| class="wikitable"
+
I've cheated, I stole some pixels from the back &amp; front porch and made the horizontal resolution 160*5 and the vertical resolution 144*4 (800x576)
|-
+
 
! Scanline part
+
= Implementation  =
! Pixels
+
 
! Time [µs]
+
All of this converting takes place inside an Altera Cyclone II FPGA. This is a fairly cheap FPGA with integrated free configurable memory, and embedded multipliers. <strike>Also, a PLL which we can use to convert the 4MHz pixelclock to a more VGA-like frequency</strike>. The design of the VGA adapter is made using VHDL.
|-
+
 
|Visible area
+
The VGA interface is made using a 3 bit R-2R DAC ladder, for each one of the R, G and B values. Hsync and Vsync are connected directly to the VGA out of the FPGA.<strike>Not having the gameboy connected yet</strike>, we are using a static picture (from an actual Gameboy) which resides in the framebuffer of our design. Some results so far:
|768
+
 
|21.967963386728
+
[[Image:FPGAVGA.jpg|300px|FPGAVGA.jpg]]
|-
+
 
|Front porch
+
= Results =
|24
 
|0.68649885583524
 
|-
 
|Sync pulse
 
|80
 
|2.2883295194508
 
|-
 
|Back porch
 
|104
 
|2.974828375286
 
|-
 
|Whole line
 
|976
 
|27.9176201373
 
|}
 
  
<b>Vertical timing (frame)</b>
+
GREAT&nbsp;SUCCES!
<br>Polarity of vertical sync pulse is positive.
 
  
{| class="wikitable"
+
[[Image:VGAbeamer.jpg|400x300px|Awesome.]]
|-
 
! Frame part
 
! Lines
 
! Time [ms]
 
|-
 
|Visible area
 
|576
 
|16.080549199085
 
|-
 
|Front porch
 
|1
 
|0.0279176201373
 
|-
 
|Sync pulse
 
|3
 
|0.083752860411899
 
|-
 
|Back porch
 
|17
 
|0.4745995423341
 
|-
 
|Whole frame
 
|597
 
|16.666819221968
 
|}
 
  
To 'convert' 160 pixels to 768 we simply adjust the pixel clock:
+
to be updated..
34.96 MHz / 768 pixels = x MHz / 160 pixels
 
x = 160 pixels * (34.96 MHz / 768 pixels) =  7.283 MHz
 
So if we use a pixel clock of 7.283 MHz, the 160 pixels will stretch themselves over a width of 768 pixels.
 

Latest revision as of 21:58, 3 November 2015

Project: Gameboy VGA adapter
Featured:
State Completed
Members Prodigity, Danny Witberg
GitHub No GitHub project defined. Add your project here.
Description Adding VGA output to a gameboy classic
Picture
FPGAscreen.jpg
Temporary VGAmeboy logo

Introduction

The gameboy classic is a handheld video game device which invokes a feeling of nostalgia into the hearts of many gamers (and non-gamers!).

In total nearly 120 million of these devices have been sold around the world and have delivered uncountable hours of fun (and frustration.. "DAMN YOU MARIO!" heh anyone? :P).

Nowadays the gameboy has been replaced by far more advanced (read: battery-slurping) handheld devices and as such, many people have one lying around collecting dust.

As some of you might remember, the biggest problem with the gameboy classic was the lack of backlighting which caused any form of unwanted lighting to render the screen into a useless plastic mirror.

REJOICE! For I have decided to add VGA output to the gameboy so you can play on 21" screens! (TAKE THAT SUN!) No more visibility problems! (Yes you can add LEDs to the back of the screen, stop being so boring :P).

Before we get down and dirty, you'll need to be sure that you understand the terms used on this page; VGA terminology.


The gameboy

Gameboy specs:

  • Resolution: 160 x 144
  • Refresh rate: 59.7Hz
  • Horizontal Sync: 9.2KHz
  • Bits per pixel: 2 (Black, Dark grey, Light grey or White)
  • Pixel Clock: 4MHz


As you can see we are presented with a refresh rate of 59.7Hz which nearly matches the standard VGA refresh rate. (Most likely close enough, only testing will tell)

The resolution of 160x144 however poses a problem, no such VGA resolution exists and as such we will be forced to pick a different resolution and do some pixel juggling.

The solution? We will use double buffering and a different resolution.


Calculations

Doublebuffer

To determine the size of our buffers we simply take the resolution of the gameboy screen and multiply the amount of horizontal pixels with the vertical pixels and the bpp (160x144x2 = 46080).

The 46080 bits translate roughly to 6 kilobyte.


Resolution

Multiplying horizontal pixels by a float is only a matter of altering the pixel clock.

Multiplying vertical pixels by a float however is difficult as this has to be done with a digital solution.

As such we prefer to use a resolution whose vertical pixels are a multiple of 144. (Any integer)

There so happens to be a resolution which adheres to this: 768x576


VESA signal 768x576 source

General timing

Screen refresh rate 60 Hz
Vertical refresh 35.819672131148 kHz
Pixel freq. 34.96 MHz

To 'convert' 160 pixels to 768 we simply adjust the pixel clock: 34.96 MHz / 768 pixels = x MHz / 160 pixels x = 160 pixels * (34.96 MHz / 768 pixels) = 7.283 MHz So if we use a pixel clock of 7.283 MHz, the 160 pixels will stretch themselves over a width of 768 pixels.

I've cheated, I stole some pixels from the back & front porch and made the horizontal resolution 160*5 and the vertical resolution 144*4 (800x576)

Implementation

All of this converting takes place inside an Altera Cyclone II FPGA. This is a fairly cheap FPGA with integrated free configurable memory, and embedded multipliers. Also, a PLL which we can use to convert the 4MHz pixelclock to a more VGA-like frequency. The design of the VGA adapter is made using VHDL.

The VGA interface is made using a 3 bit R-2R DAC ladder, for each one of the R, G and B values. Hsync and Vsync are connected directly to the VGA out of the FPGA.Not having the gameboy connected yet, we are using a static picture (from an actual Gameboy) which resides in the framebuffer of our design. Some results so far:

FPGAVGA.jpg

Results

GREAT SUCCES!

Awesome.

to be updated..