ASMSchool - Lesson 5
This lesson will introduce you to the hardware built into this incredible little machine.
Now that you know a little on how to make the CPU work for you and do your evil bidding,
you need to learn just what you can manipulate and how. We will start out learning the
MONOCHROME GameBoy (DMG) first. Why??? Because, a GameBoy Color is nothing more than
a regular monochrome GameBoy with a few tricks added to display color. One step at a time. =)
Since the cpu has a 16-bit address bus, a total of 64Kbytes of direct address space is
available to the cpu at any given time. This 64K is carved up into areas that are for specific
things, such as cartridge access, video ram, i/o registers, stack space, etc. It'd be a good
idea to take a look at the memory map lesson (15) for a graphical representation of the
entire address space.
The lower 32K ($0000-$7FFF) is used for accessing cartridge rom. A gameboy cartridge is
basically carved up into 16K pieces, called BANKS, with the first 16K bank of cartridge space being addressable
at the first 16K of the address space ($0000-$3FFF). This first 16K bank is called the HOME BANK.
This piece of the cartridge is ALWAYS accessed from this area. This is where most of your
game's code will be placed, since it's always available. This first 16K also holds the HEADER of a GameBoy game, located at $0100.
The header is basically an ID tag for a game. The rest of the cartridge
banks can be "paged" into the address space from area $4000-$7FFF. This area
is called paged because you can change. NOTE, only ONE bank of the cartridge is visible
in the paged space at any given time. To change which bank is visible, you need to tell the
hardware what bank to change it to. This is pretty easy and will be detailed later.
The address space from $8000-$9FFF is video ram (VRAM). This area of memory isn't a plain linear
collection of bytes that represent pixels on the LCD, rather this memory area contains
building blocks that the LCD controller builds each screen with. Each of these 8x8 pixel
blocks is called a TILE. The VRAM contains two major sections, one section for tiles,
and another section for a MAP. The map area is a 32x32 byte array (1024 bytes) that makes
up the Background Map, or BGMAP for short. The way the LCD draws a screen is this: it
takes the byte value in the map area, and gets the corressponding tile from the tile set,
and draws the 8x8 tile where it got the map byte from. Easy right? Here's a little picture
to help you visualize it.
Why on earth would anybody make something so complicated? Why not have plain old directly
addressable screen pixels? Well, there's three good reasons I can think of: 1) When the
GameBoy was designed back in the late 80's, ram wasn't cheap, nor small. Directly addressable
pixels would require almost 46Kbytes of video ram, compared to the 8K that the GameBoy's tile-based
video has. 2) 46K of video ram would take up 72% of the CPU's limited addressing space.
3) Lets see how fun it is to draw 1.3 MILLION pixels per second (23040 pixels on the LCD X 60
frames per second) while using nothing more than a 1MHz 8-bit CPU... about as fun a picking
your nose with barbed wire.not fun. In fact, just about ALL non-3D game systems use
tile-based rendering to take a load off the CPU. With the GameBoy's LCD, all you do is
load up a set of tiles (4K for a whole set of 256 tiles) and a map (1K) and voila, you
have a whole screen that draws itself based on your map and tiles. Of course, there are
other details like turning the LCD on, setting the BG palette, and such. We will come to
those. Patience grasshopper....
The next area of the address space is RAM. All your goodies get stored here, eg: variables.
There are two ram areas, both 8K. The first area ($A000-$BFFF) is mapped to CARTRIDGE RAM, if the cartridge
HAS any ram on it. Not a requirement, but handy to have, espescially if battery backed.
If there is no ram on the cartridge, this address space is pretty NULL and VOID. So make
sure you either have ram there if you're going to use it, or don't use it if you don't have
any cart ram.
The second area is INTERNAL WORK RAM or WRAM ($C000-$DFFF). This is where most runtime variables will be
located, as opposed to variables you want to store (character stats, save games, etc) which
go on the cart ram.
This next area of the address space is wasted. $E000-$FDFF. It's defined as a mirror of the
contents of $C000-$DDFF, but it is STRONGLY advised that you NOT use this area for anything. 'Nuff said.
Our next piece of address space is OAM, or Object Attribute Memory, more commonly known
as Sprite RAM. This little area is from $FE00 to $FE9F (160 bytes). This 160-byte table
is where our "little man" characters come from. Anything moving on the screen that isn't
drawn on the BG is a sprite. The GameBoy can have a maximum of 40 sprites at any given time.
Each one of these sprites is defined by 4 bytes in OAM, hence the 160 byte long OAM (4x40).
So where do the graphics for our sprites come from? Tile ram, just like BG tiles. In fact,
the exact same tile set. Sprites can be displayed in 2 modes, 8x8 pixels and 8x16 pixels.
Note that this mode applies to ALL the sprites in OAM, so if you tell the LCD that you want
8x16 sprites, ALL of your sprites will be 8x16. Make a good note of that. (what??? you're NOT keeping notes???)
$FEA0-$FEFF is unusable address space. Just a small useless chunk left over. Don't expect
there to be ram here, there isn't... (shouldn't be). Nintendo would rather you left it alone. 'Nuff said.
$FF00-$FFFE is what we like to call the ZERO PAGE. 127 bytes of pure bliss. The lower 64 bytes
is memory-mapped I/O. Almost every single byte in this area is a special hardware control
register that controls everything on the GB. The upper 63 bytes (yes 63, to $FFFE) is High RAM,
or HRAM. It's a special area for many nice uses. The GB's CPU has a few instructions to access data
anywhere in it's address space. You should remember the LD (load) instruction from the first
few lessons. An instruction to load a byte from address $2000 into register A would be written as:
This instruction is THREE BYTES LONG, consisting of the "LD A" command byte and the $00 and $20 bytes for
the address. There is a special LD instruction for the ZERO PAGE called LDH (load high). LDH takes only an 8-bit
value as a parameter, rather than a whole 16-bit address. This makes the instruction only 2 bytes long, since
the upper part of the address is ASSUMED to be $FFxx. So a LDH A,$80 would load the byte located
at $FF80 into A... and do it one cycle FASTER than a regular load. Could be used very handily
for variables needed in loops to keep the loop fast as possible. (You ARE taking notes, AREN'T YOU?)
And the VERY last byte of address space on a GameBoy is $FFFF. This byte is another memory-mapped I/O
register, it was just put here, for some reason.
Well, there is the whole address space on the GB and how it's broken down. Next lesson will introduce you
to some of the tools that many GB programmers like to use, including Tile Designers, Map Builders, Graphics convertors, Assemblers, Compilers, etc.