Last active
September 20, 2019 20:42
-
-
Save glinesbdev/ecec0fd8a24bc9c54fe100961a0610f9 to your computer and use it in GitHub Desktop.
Gameboy Hello World
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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