Skip to content

Instantly share code, notes, and snippets.

@glinesbdev
Last active September 20, 2019 20:42
Show Gist options
  • Save glinesbdev/ecec0fd8a24bc9c54fe100961a0610f9 to your computer and use it in GitHub Desktop.
Save glinesbdev/ecec0fd8a24bc9c54fe100961a0610f9 to your computer and use it in GitHub Desktop.
Gameboy Hello World
INCLUDE "hardware.inc"
; Beginning of the rom
SECTION "Header", ROM0[$100]
di ; Disable interrupts since we don't want to be interrupted
jp Start ; Jump to the Start label
nop ; No nothing for 1 cycle (approx: 1MgHz)
ds $150 - $104 ; Write nothing for $150 to $104 which is the rom header information
; This is the start of the program
SECTION "Program", ROM0
Start:
.waitVBlank
; We need to wait for the VBlank state to be over
; During a VBlank, we can't access anything in the RAM
; The VBlank duration is from 144 - 153 then flips back to 0
ld a, [rLY] ; Get the address value of the LCDC (LCD Controller)
cp 144 ; Is the value 144?
jr c, .waitVBlank ; Keep checking if it's not 0
; We also can't draw tiles to the screen while it's on
; So now we turn off the LCD screen
xor a ; Use a logical OR with register a against itself and assign the value back into a
; When using a XOR (Exclusive OR), anything XOR'd with itself will be 0
; Effectively changing whatever the value of a was to 0
ld [rLCDC], a ; Set the LCDC to a, which is 0
; What we need to do now is to get the string data that we'll be printing out to the display
; We set this up before going into the next label, .copyFont
ld hl, $9000 ; Assign the literal value of $9000 to the hl register
; $9000 is the address of the first section of the third part of the VRAM tiles
; This section is empty when you boot the rom
ld de, FontTiles ; Get the data from the FontTiles label into de
ld bc, FontTilesEnd - FontTiles ; Get the count of all of the tiles
; This will act as the loop counter for .copyFont
.copyFont
; Now we need to get the font out of the font file hand into memory
ld a, [de] ; Get the address value of the data in the de register
ld [hli], a ; Insert the byte into the hl register and increase it's value by 1
inc de ; Increase the value of the de register by one
; We have to increase this manually since the hl register is the only
; register that can use the hl(i) shorthand syntax
dec bc ; Decrease the value of the bc register
ld a, b ; Put the value of the b register into the a register
or c ; Assign the value of `or c` to register a
jr nz, .copyFont ; If the value in the a register is not zero, go back to .copyFont
; Now that we have the data from FontTiles into VRAM, we need to now get it onto the display
ld hl, $9800 ; This will print the data of the hl register in to the
; memory address of $9800 which is the top left of the Gameboy's display
ld de, HelloWorldStr ; This puts the data of the HelloWorldStr label into the de register
.copyString
ld a, [de] ; Put the address value of the de register into the a register
ld [hli], a ; Insert the byte into the hl register and increase it's value by 1
inc de ; Increase the value of the de register by one
and a ; Check to see if the byte we copied to a is a 0
jr nz, .copyString ; Do the instruction set inside .copyString if a is not zero
; Whew, now that we have the data onto the screen, now we have to turn it back on!
; Remember that we had to turn off the screen to write anything to it.
; Reference: http://gbdev.gg8.se/wiki/articles/Video_Display#FF47_-_BGP_-_BG_Palette_Data_.28R.2FW.29_-_Non_CGB_Mode_Only
ld a, %11100100 ; This will set the binary value for background pallete color
; It doesn't matter how we set this i.e. it could be hex $E4
; I chose binary in this case because it makes more sense visually
; when looking at the above reference
ld [rBGP], a ; set the BGP (Background Pallete) to the color we selected
; We will turn the sound off since we don't have sound in this program
xor a ; A value XOR'd by itself is 0 - you could write `ld a, 0` as well.
ld [rNR52], a ; We set the address value of register NR52 to a, which is 0
; Register NR52 is the register that determines if the sound is on or off
; 1 = on, 0 = off
; We also don't want to have any scrolling in this program so we will turn that off too
ld [rSCX], a ; Turn off horizontal scrolling by setting the address value to 0
ld [rSCY], a ; Turn off vertical scrolling by setting the address value to 0
; Now we can turn the screen back on!
; Reference: http://gbdev.gg8.se/wiki/articles/Video_Display#LCD_Control_Register
ld a, %10000001 ; Set the value of register a to a binary value
; Reminder that this could be hex: $81
ld [rLCDC], a ; Put the value in register a into the address value of the LCDC register
; Now we are done with all of our instructions! But to stop the CPU from processing all the
; remaining memory addresses, we will lock the program here infinitely
.lockup
jr .lockup
SECTION "Font", ROM0
FontTiles:
INCBIN "font.chr" ; INCBIN will take the bytes of the file and store it in the label, in this case
FontTilesEnd:
SECTION "Hello World String", ROM0
HelloWorldStr:
db "Hello World!", 0 ; We add the 0 so that we know that the string is over
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment