Gameboy Memory MAP

Home CPU Memory Routines


The gameboy has access to only 8192 bytes of working RAM (i.e. the variables in the game, the list of ennemies ect...) and 8192 bytes of Video RAM.

This may sound like a lot... generally knowing that a byte holds just 1 comma-less value between 0 and 255 (or between -128 and 127, depending on what you do with it), but then wait. Say we have 256 colors (which, seeing how many ugly GIF's the internet is cluttered with, who have just exactly this number of pixels) we could just generate a grid with colors (Some would say an image... depends on what you are painting on) 128*64 cells large. The Gameboy, as being a device with 160*144 pixels, clearly hasn't got enough with that.

To still render 160*144 pixel large picture, the Gameboy pulls out a few tricks.

First of all, did you ever wonder why the old big Gameboy could only display 4 different shades of gray? (look very closely... you will see. Unless you have messed-up with the contrast!) It is because he has just stored 4 pixels in 1 byte!

Indeed, a lot of old systems only stored a On & Off image of your favorite character. Like this:

12864 32 16 8 4 2 1 Total
X X X #14
X X X X X #145
X X X X X X X #223
X X X X X X #138
X X X X #212
X X X X #46
X X #10
X X #10

Here, the bytes are made by summing up the numbers on the top which are lit as pixels. Or, said more mathematically, we do look at the first pixel, add 1 to the number if it is lit, then multiply the number by 2 and shift the picture 1 pixel to the left. The Gameboy does the inverse to reconstruct the image.

So, we have just encoded a 8*8 pixel image in just 8 bytes instead of 64 bytes. But 1 pixel in this image can only be eighter fully lit or fully dark! To resolve this problem, the Gameboy desided to store 1 row in 2 bytes.

If the same pixel is Off in both bytes, then the pixel is White (or green). If it is On on both bytes, it is Black. But if it is On on the first byte and Off on the second, it is dark green and if it Off on the first byte and On on the second one it is light green.

Green X Dark Green
Light Green X Black
X X

The Gameboy stores 384 pairs of 8*8 images like that, 16 bytes per image, in a table 6072 bytes large.

There is another trick that the Gameboy uses everywhere.

Say we want to write "Hello World". We could just assign the value representing those 3 "l"s to one of the numeric values of a byte. Then, we write this byte, and then the next byte the numeric value of "o".

This way, we don't have to store every single "l" as 8 bytes for a picture, but only as 1 byte of a char.

The Gameboy stores 2 such char maps, 1 byte per char, for the background, 32 bytes long by 32 bytes large (i.e. 1024 bytes accross per page of text). Of course, it reads left to right, mapping each value to a shape in the shape map.

And if we load in the whole alphabet, we can start writing words!

As you might guess, this table is 32*8=256 pixels long by 256 pixels large. This is to large for the screen of the Gameboy, so it is clipped; however the game may scroll it with some registers

0000-7FFF
Cartridge ROM

In cartridge, fixed at bank 00
In cartridge, switchable bank number

8000-9FFF
Video RAM

Can be used for Sprites and Background.

8xx0 M M M M M M M M RW MSB of line 0
8xx1 L L L L L L L L RW LSB of line 0
8xx2 M M M M M M M M RW MSB of line 1
8xx3 L L L L L L L L RW LSB of line 1
8xx4 M M M M M M M M RW MSB of line 2
8xx5 L L L L L L L L RW LSB of line 2
8xx6 M M M M M M M M RW MSB of line 3
8xx7 L L L L L L L L RW LSB of line 3
8xx8 M M M M M M M M RW MSB of line 4
8xx9 L L L L L L L L RW LSB of line 4
8xxA M M M M M M M M RW MSB of line 5
8xxB L L L L L L L L RW LSB of line 5
8xxC M M M M M M M M RW MSB of line 6
8xxD L L L L L L L L RW LSB of line 6
8xxE M M M M M M M M RW MSB of line 7
8xxF L L L L L L L L RW LSB of line 7

The tile number is stored in a unsigned byte xx (0 to 255)

Can be used for Window and Background.

9xx0 M M M M M M M M RW MSB of line 0
9xx1 L L L L L L L L RW LSB of line 0
9xx2 M M M M M M M M RW MSB of line 1
9xx3 L L L L L L L L RW LSB of line 1
9xx4 M M M M M M M M RW MSB of line 2
9xx5 L L L L L L L L RW LSB of line 2
9xx6 M M M M M M M M RW MSB of line 3
9xx7 L L L L L L L L RW LSB of line 3
9xx8 M M M M M M M M RW MSB of line 4
9xx9 L L L L L L L L RW LSB of line 4
9xxA M M M M M M M M RW MSB of line 5
9xxB L L L L L L L L RW LSB of line 5
9xxC M M M M M M M M RW MSB of line 6
9xxD L L L L L L L L RW LSB of line 6
9xxE M M M M M M M M RW MSB of line 7
9xxF L L L L L L L L RW LSB of line 7

The tile number is stored in a signed byte xx (-128 to 127)

Can be used for Window and Background.

32 Rows of 32 Bytes each.

D D D D D D D D RW Number of Tile

BG Map Attributes in VRAM bank 1 (CGB)

P P P RW BG Palette number
B RW Tile VRAM Bank number
H RW Horizontal Flip
V RW Vertical Flip
P RW BG/OAM Priority

Can be used for Window and Background.

32 Rows of 32 Bytes each.

D D D D D D D D RW Number of Tile

BG Map Attributes in VRAM bank 1 (CGB)

P P P RW BG Palette number
B RW Tile VRAM Bank number
H RW Horizontal Flip
V RW Vertical Flip
P RW BG/OAM Priority

C000-DFFF
General Purpose RAM

In cartridge, switchable bank, if any
Switchable bank 1-7 in CGB Mode

FE00-FE9F
Sprite Attribute Table

40 Sprites, organised in groups of 4 bytes

+0 D D D D D D D D RW Y Position (Y-16)
+1 D D D D D D D D RW X Position (X-8)
+2 D D D D D D D D RW Tile Number (00-FF)
+3 P P P RW CGB Palette number
+3 B RW CGB Tile VRAM-Bank
+3 P RW DMG Palette number
+3 H RW Horizontal Flip
+3 V RW Vertical Flip
+3 P RW OAM/BG Priority

FEA0-FEFF
Not Usable

FF00-FF02
I/O registers

0 R P1F_0
1 R P1F_1
2 R P1F_2
3 R P1F_3
4 W P1F_4
5 W P1F_5
dddddddd RW Data
C RW Clock Source
S RW CGB Clock Speed
T RW Transfer Start

FF04-FF0F
Timer

Incremented at rate of 16384Hz

dddddddd RW Data

Incremented by clock frequency specified by TAC register.
When the value overflows will be reset to the value specified in TMA

dddddddd RW Data

When TIMA overflows, this data will be loaded


dddddddd RW Data
S S RW Timer Speed
P RW Timer Start/Stop
dddddddd RW Data

FF10-FF3F
Sound

S S S RW Sweep Shift
D RW Sweep Increase/Decrease
T T T RW Sweep Time
L L L L L L RW Sound Length
D D RW Sound Duty
S S S RW Nbr of Enveloppe Sweep
D RW Enveloppe Up/Down
V V V V RW Initial Value
F F F F F F F F W Frequency
F F F W Frequency
C W C/C Select
I W Initialize
L L L L L L RW Sound Length
D D RW Sound Duty
S S S RW Nbr of Enveloppe Sweep
D RW Enveloppe Up/Down
V V V V RW Initial Value
F F F F F F F F W Frequency
F F F W Frequency
C W C/C Select
I W Initialize
I RW On/Off
D D D D D D D D RW Sound Length
V V RW Volume
F F F F F F F F W Frequency
F F F W Frequency
C W C/C Select
I W Initialize
D D D D D RW Sound Length
S S S RW Nbr of Enveloppe Sweep
D RW Enveloppe Up/Down
V V V V RW Initial Value
D D D RW Divide Ratio of Freq
S RW Polynomial Counter Step
F F F F RW Freq of Polynomial Cntr
C W C/C Select
I W Initialize
V V V RW SO1 Output Volume
I RW SO1 On/Off
V V V RW SO2 Output Volume
I RW SO2 On/Off
L RW Output Sound 1 to SO1
L RW Output Sound 2 to SO1
L RW Output Sound 3 to SO1
L RW Output Sound 4 to SO1
L RW Output Sound 1 to SO2
L RW Output Sound 2 to SO2
L RW Output Sound 3 to SO2
L RW Output Sound 4 to SO2
L RW Sound 1 On/Off
L RW Sound 2 On/Off
L RW Sound 3 On/Off
L RW Sound 4 On/Off
L RW All Channels On/Off
V V V V RW Sample 1 Volume
V V V V RW Sample 2 Volume

FF40-FF4B
LCD registers

B RW Background On/Off
O RW Object On/Off
S RW Object Size
A A RW Background Address
W RW Window On/Off
A RW Window Address
L RW LCD On/Off
M M RW OAM/VRAM Lock
C RW Coincidence Flag
H RW Mode 00 (HBlank)
V RW Mode 01 (VBlank)
M RW Mode 10
L RW LYCEQULY Coincidence
Y Y Y Y Y Y Y Y RW Vertical Scroll Value
X X X X X X X X RW Horizontal Scroll Value
D D D D D D D D R Current line rendering

If between 144 and 153, then the LCD is in VBlank

D D D D D D D D RW Vertical Compare
A A A A A A A A RW Source (xx00-xx9F)

Since the CPU can only access HRAM
during DMA transfer, you must copy
a small routine to it

 ld  (0FF46h),a ;start DMA transfer
 ld  a,28h      ;delay...
wait:           ;total 5x40 cycles, approx 200ms
 dec a          ;1 cycle
 jr  nz,wait    ;4 cycles
0 0 RW Shade for Color 0
1 1 RW Shade for Color 1
2 2 RW Shade for Color 2
3 3 RW Shade for Color 3
1 1 RW Shade for Color 1
2 2 RW Shade for Color 2
3 3 RW Shade for Color 3
1 1 RW Shade for Color 1
2 2 RW Shade for Color 2
3 3 RW Shade for Color 3
Y Y Y Y Y Y Y Y RW Window Y Position
X X X X X X X X RW Window X Position

FF4D-FF70
Color Gameboy Registers

P RW Prepare Speed Switch
S R Current Speed
B RW CGB VRAM Bank (0/1)
A A A A A A A A RW Source Address (High)
A A A A RW Source Address (Low)

May be located at 0000-7FF0 or A000-DFF0
The lower 4 bits of the address is ignored

A A A A A RW Destination Address (High)

The upper 3 bits of the address are ignored
The destination is always in VRAM.

A A A A RW Destination Address (Low)

May be located at 8000-9FF0
The lower 4 bits of the address is ignored

L L L L L L L RW Transfer Length
(divided by 10h, minus 1)
M W HBlank DMA mode
C R DMA complete

Without HBlank DMA, transfers everything,
halting the program


With HBlank DMA, transfers 16 bytes
during each H-Blank from LY=0 to 143


It takes 8 normal-speed cycles to transfer 16 bytes

L RW Write LED On/Off
S R Read Signal On/Off
R R R Read Enable (C0=enable)

The address in the Background Palette Memory.
Read/Write through BGPD


B RW Byte Number (Low/High)
E E RW Shade Number (0/1/2/3)
P P P RW Palette Number (0:7)
I RW Auto-Increment

Read/Write data to the Background Palette Memory
Addressed through BCPS


Data is organized as 2 bytes per palette entry

(low) R R R R R RW Red Value
(low)G G G RW Green Value (low)
(high) G G RW Green Value (high)
(high) B B B B B RW Blue Value

Values 10-1F appear as very bright...
the medium and darker shades are at 00-0F
In the AGB the reverse is true;
00-0F are dark and 10-1F are medium and light

The address in the Object Palette Memory.
Read/Write through OCPD


B RW Byte Number (Low/High)
E E RW Shade Number (0/1/2/3)
P P P RW Palette Number (0:7)
I RW Auto-Increment

Read/Write data to the Object Palette Memory
Addressed through OCPS


Data is organized as 2 bytes per palette entry

(low) R R R R R RW Red Value
(low)G G G RW Green Value (low)
(high) G G RW Green Value (high)
(high) B B B B B RW Blue Value

Values 10-1F appear as very bright...
the medium and darker shades are at 00-0F
In the AGB the reverse is true;
00-0F are dark and 10-1F are medium and light

In CGB, Bank 1-7 can be selected
into the address space at D000-DFFF


B B B RW WRAM Bank

Writing 0 loads bank 1 instead of 0

FF80-FFFF
High RAM

V RW VBlank Interrupt
L RW LCDC Interrupt
T RW Timer Overflow
I RW Serial I/O Transfert Done
O RW HiLo (Pad) Transition