Programming for the Game Boy

Status
Not open for further replies.

Aran Falcord

Junior Member
Mar 16, 2012
2
0
0
Hey there!

I'm studying electronic engineering and I think I know enough about assembler language and CPU architectures to start fiddling with my old stuff a bit (which is not much, but I want to get practical).

There's a perfectly working Game Boy laying around here, which I would like to work with. I have a document with the instructions, datapath, memory maps and so forth but to be honest I'm a little lost on how to start.

I'm at a curious situation of "okay, I know how this thing works, now what?". What kinds of software/hardware would you use? How does one load his own programs into such an archaic machine? Are there custom flash cartridges or do I need to rewire the thing to somehow access the RAM directly?

Thank you!
 
Last edited:

imagoon

Diamond Member
Feb 19, 2003
5,199
0
0
You write code, and load it on the a flash cartridge. You will likely never find a dev gameboy to work with so you won't be able to attach to the device for debugging. Some of the emulators out there can do that though and you may have better luck using those.

Like this:

http://devkits.handheldmuseum.com/GB_Wideboy.htm
 
Last edited:

exdeath

Lifer
Jan 29, 2004
13,679
10
81
I'd recommended Gameboy Advance instead. The 32 bit ARM7 core and standard 15/16bit RGBA formats are much friendlier to work with, and the emulator Visual Boy Advance is a fully featured debugger which allows viewing all graphics, registers, memory, code, stepping and tracing, etc to test and verify correct operation before you waste time flashing to hardware.

The original GB architecture is pretty "hacked" and limited and won't be as nice to follow for someone learning. You'll be spending more time trying to figure out strange and irrelevant graphics formats, etc, rather than learning how to code.

The basic idea though is you assemble some code, put the binary in the cartridge at the location that cooresponds to the devices RESET address, and it runs your code. You'll need to get intimate with the specialized display hardware (tiles and screen maps and palettes rather than pixels) in order to see results (in VBA you can view BG tiles/OAMs/VRAM to verify you are loading them correctly while troubleshooting, etc). Code and data are all stored together in the flat linear address space of the ROM cart. RAM is only used for variables, arrays, lists, stack/heap, etc.

Your first program will only be a few instructions. Something like setting a display mode, enabling a BG, and changing the default BG color in the palette to set the screen to another color so that you can see the effect and know your program is running correctly.

If you are interested in GBA, I have some old demo sources I can dig up that are pretty well documented. Can't be any help on original GB however.
 
Last edited:

Aran Falcord

Junior Member
Mar 16, 2012
2
0
0
Thank you guys for the great answers.

I'd recommended Gameboy Advance instead. The 32 bit ARM7 core and standard 15/16bit RGBA formats are much friendlier to work with, and the emulator Visual Boy Advance is a fully featured debugger which allows viewing all graphics, registers, memory, code, stepping and tracing, etc to test and verify correct operation before you waste time flashing to hardware.

The original GB architecture is pretty "hacked" and limited and won't be as nice to follow for someone learning. You'll be spending more time trying to figure out strange and irrelevant graphics formats, etc, rather than learning how to code.

The basic idea though is you assemble some code, put the binary in the cartridge at the location that cooresponds to the devices RESET address, and it runs your code. You'll need to get intimate with the specialized display hardware (tiles and screen maps and palettes rather than pixels) in order to see results (in VBA you can view BG tiles/OAMs/VRAM to verify you are loading them correctly while troubleshooting, etc). Code and data are all stored together in the flat linear address space of the ROM cart. RAM is only used for variables, arrays, lists, stack/heap, etc.

Your first program will only be a few instructions. Something like setting a display mode, enabling a BG, and changing the default BG color in the palette to set the screen to another color so that you can see the effect and know your program is running correctly.

If you are interested in GBA, I have some old demo sources I can dig up that are pretty well documented. Can't be any help on original GB however.

That sounds like solid advice. Thanks! I also have a functioning GBA somewhere around here so I might as well do that.

I would love to have those sources. Let's hope I can find documentation on the GBA processor as good as what I have for the original Game Boy. Thank you!
 

exdeath

Lifer
Jan 29, 2004
13,679
10
81
This one is my first encounter with both ARM and GBA. I had fun abusing the hell out of conditional moves.

The only hardware interfacing to GBA is address 0x04000000 (r0) to set the display mode, 0x04000006 (r0+6) to get the current scanline being displayed, and 0x05000000 to change palette entry 0.

The concept of copper bars is to have horizontal colored bars moving up and down the screen blending together when they overlap. The trick for "real" copper bars is that the only means you have of generating the picture is only by changing the BG color (palette 0) per scan line. No actual drawing is taking place at all.

I used a gradient table to compute the intensity along the thickness of the bars to give the bars a nice shaded rounded look.


Code:
; ---------------------------------------------------------------------------------
;
;	'copper bars' for GBA
;	by exdeath
;	with goldroad ARM 1.7
@arm

; r2  = current row we are processing (scanline)
; r3  = current color for the scanline
; r4  = position of a bar
; r6  = red bar position
; r7  = green bar position
; r8  = blue bar position
; r9  = red bar velocity
; r10 = green bar velocity
; r11 = blue bar velocity
; r12 = pointer to table with an intensity gradient

@textarea	0x08000000

;-------------------------------------------------------------
;	entry point
	
;	b	agb_main

;	gba header

;@dup	dcb 0xba,0x0

.agb_main:

;	init display mode

	ldr r0,=#0x04000000
	ldr r1,=#0x4
	str r1,[r0]

; 	init vars
	mov 	r6,  #0x28	
	mov 	r7,  #0x28
	mov 	r8,  #0x28
	mov 	r9,  #0x1
	mov 	r10, #0x2
	mov 	r11, #0x3
	ldr	r12, =#table
	and	r13, r13, #0x0	

.while:	
	and	r2, r2, #0x0


;	make sure we are on the right row

.wait:				
	ldrh	r1, [r0,#0x6]
	cmp	r1, r2
	bne 	.wait

;	calculate bar contributions

	sub	r4, r2, r6	; red bar
	cmns	r4, #0x7
	movlt	r4, #0x7
	cmps	r4, #0x7
	movgt	r4, #0x7
	add	r4, r12, r4
	ldrb	r3, [r4,#0x7]	
	sub	r4, r2, r7	; green bar
	cmns	r4, #0x7
	movlt	r4, #0x7
	cmps	r4, #0x7
	movgt	r4, #0x7
	add	r4, r12, r4
	ldrb	r1, [r4,#0x7]	
	mov	r1, r1, lsl #0x5
	orr	r3, r3, r1
	sub	r4, r2, r8	; blue bar
	cmns	r4, #0x7
	movlt	r4, #0x7
	cmps	r4, #0x7
	movgt	r4, #0x7
	add	r4, r12, r4
	ldrb	r1, [r4,#0x7]	
	mov	r1, r1, lsl #0xA
	orr	r3, r3, r1

; 	write pixel color into palette

	mov	r1, #0x05000000
	strh	r3, [r1]

;	end of .for

	add	r2, r2, #0x1
	cmp	r2, #0xA0
	blt	.wait
	
	add	r13, r13, #0x1
	cmp	r13, #0x2	; cheap way to synch to 30 fps
	blt	.while
	and	r13, r13, #0x0


;	update positions

	add 	r6, r6, r9	; red bar
	cmp	r6, #0x78
	rsbgt	r9, r9, #0x0
	cmp	r6, #0x28
	rsblt	r9, r9, #0x0
	add 	r7, r7, r10	; green bar
	cmp	r7, #0x78
	rsbgt	r10, r10, #0x0
	cmp	r7, #0x28
	rsblt	r10, r10, #0x0
	add 	r8, r8, r11	; blue bar
	cmp	r8, #0x78
	rsbgt	r11, r11, #0x0
	cmp	r8, #0x28
	rsblt	r11, r11, #0x0
	
	b 	.while

.table:
@DCB 0x0, 0x3, 0xA, 0x10, 0x15, 00x19, 0x1D, 0x1F, 0x1D, 0x19, 0x15, 0x10, 0xA, 0x3, 0x0

Programming documents and tools:

http://ric.san.free.fr/_donnees/Nintendo Gba Manual V1.1.pdf

http://www.cs.rit.edu/~tjh8300/CowBite/CowBiteSpec.htm

http://vba.ngemu.com/

http://www.gbadev.org/

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0234b/i1010871.html
 
Last edited:

exdeath

Lifer
Jan 29, 2004
13,679
10
81
Realize that might be a bit complex to swallow, so I made a simple ROM just now that just sets BG colors to confirm you have an active working program that is assembled and .org'ed correctly in the GBA's address space.

Code:
@arm
@textarea	0x08000000

.agb_main:

;	init display mode

	ldr r0,=#0x04000000
	ldr r1,=#0x00000004
	str r1,[r0]

; 	Write new 15 bit RGB color value to BG color 0 to change screen color
;       which defaults to color 0
;	Format is 16 bits xbbbbbgggggrrrrr 
;       eg 0x7C00 = max blue, 0x03E0 = max green, 0x001F = max red
;	storing only lower half of register r3 for 16 bit write

	ldr	r0, =#0x05000000
	ldr	r1, =#0x000003E0		; bg color 0 = 03E0 = pure green
	strh	r1, [r0]

;	Put CPU in endless loop to avoid crashing from random garbage
;       in memory beyond this ROM
;	There is actually a way to sleep or halt until VSYNC interrupt 
;       because this loop will kill battery life in a real GBA

.loop:
	b 	.loop

Assembled with Goldroad ARM 1.7 into a .gba file and verified on Visual Boy Advance.

This assembles to (little endian)

Code:
14009FE5
14109FE5
0010A0E4
10009FE5
10109FE5
B010C0E0
FEFFFFEA
00000004
04000000
00000005
E0030000

VBA disassembly :

Code:
08000000 E59F0014 ldr r0, [$0800001C]
08000004 E59F1014 ldr r1, [$08000020]
08000008 E4A01000 str r1, [r0]
0800000C E59F0010 ldr r0, [$08000024]
08000010 E59F1010 ldr r1, [$08000028]
08000014 E0C010B0 strh r1, [r0]
08000018 EAFFFFFE b $08000018
0800001C 04000000 <constant immediate>
08000020 00000004 <constant immediate>
08000024 05000000 <constant immediate>
08000028 000003E0 <constant immediate>
0800002C and beyond = uninitialized random garbage and ROM "infinite mirrors"

On a flash cart, random garbage is likely to be all 0000 or FFFF due to erased unused flash.

The loading of constants via relative addressing for immediate data is common with RISC architectures, as the instructions sizes are fixed (32 bits here).

In the above

08000000 is the start of ROM address space in the GBA, and application entry point
04000000 is the display enable and mode select register for GBA graphics hardware
00000004 is just selecting display mode 4 defined by GBA graphics hardware
05000000 is address of a 512 entry palette of 16 bits each (total 1K) for GBA graphics hardware

This is painting the screen by changing palette entry 0, no tiles or playfield maps are being written. It's about the simplest way of getting started and verifying the program is running correctly on real hardware.

This works in VBA emulator but should also work on real hardware via blind luck. There are specific quirks and protocols on real hardware such as certain addresses only allowing 16 or 32 bit r/w without locking up the system, using NOPS to wait 1-2 cycles for hardware to recover after display mode changes or using DMA before you attempt to write to hardware regs again, only updating palettes and display memory during VBLANK, etc that can throw a wrench into your ROM working on real hardware. GBA also doesn't have cache, so things like using DMA halt the CPU 2 clocks after you activate a DMA until the DMA completes, etc. And I don't remember if GBA used branch delay slots or if it matters with unconditional branches.

I have some others that load graphics and sprites and do HDMA special effects, but they are hard to follow because the graphics have already been processed into ASCII text hex arrays with other tools and broken up into tiles and tile indices, etc.
 
Last edited:
Status
Not open for further replies.