Skip to content

Instantly share code, notes, and snippets.

@rats-god
Created September 30, 2017 20:32
Show Gist options
  • Save rats-god/7a1047ac6ed507fd3e9f3f816e98a19f to your computer and use it in GitHub Desktop.
Save rats-god/7a1047ac6ed507fd3e9f3f816e98a19f to your computer and use it in GitHub Desktop.
"hello world" in gb-z80 assembly
[objects]
main.o
;;; hello world demo in gb-z80
;;; by feeb <phoebe@slub.co>
;;; the following conveys the memory layout to the assembler.
.memorymap
slotsize $4000
defaultslot 0
slot 0 $0000
slot 1 $4000
.endme
.rombanksize $4000 ; internal definition used for error checking
.rombanks 2 ; written to $0x0148
; (wla-dx complains if this is not defined via a
; directive)
.org $100 ; execution starts here.
_start: nop
jr boot ; needs to quickly jump because nintendo logo starts at 0x0104
nintendo_logo:
;; gameboy hardware checks this memory location, and refuses to boot
;; if this does not match known value.
.org $104
.db $CE $ED $66 $66 $CC $0D $00 $0B $03 $73 $00 $83 $00 $0C $00 $0D
.db $00 $08 $11 $1F $88 $89 $00 $0E $DC $CC $6E $E6 $DD $DD $D9 $99
.db $BB $BB $67 $63 $6E $0E $EC $CC $DD $DC $99 $9F $BB $B9 $33 $3E
;;; set up necessary metadata
;;; the gb hardware checks two specific things and refuses to boot if they are
;;; invalid:
;;; * the nintendo logo, as specified above
;;; * the checksum bits at 0x14D and 0x14E
configuration:
;; title of game in uppercase ascii. this is located in 0x0134
;; but this directive makes this more legible
.name "WOOF WOOF"
.org $143 ; cartridge type
.db $0 ; 0x00 = not a color gb
.org $144 ; licensing code
; used in calculating checksum and complement
.db $0 ; set to 0 by default
.db $0 ; "
.org $146 ; super gb function availability
.db $0 ; 0x00 = no super gb function
.org $147 ; cartridge architecture
.DB $0 ; 0x00 = rom only
;; rom size
;; 0x00 = 256kbit
.org $148
.db $0
;; ram size
;; 0x00 = none
.org $149
.db $0
;; destination code
;; 0x00 = japanese
;; 0x01 = non-japanese
.org $14A
.db $1
;; old licensing code
;; 0x33 = look at bits 0x144-0x145
;; anything else = don't look there
;; this doesn't seem to be important.
.org $14B
.db $0
;; "mask rom version number"
;; 0x00 = default value
.org $14C
.db $0
;; gameboy will not boot the rom if the checksum bytes aren't set correctly.
;; these are wla-dx directives that will calculate these bytes, which saves
;; us some headache
.computechecksum
.computecomplementcheck
.org $40 ;vbi.
reti
.org $48 ;lcd stat.
reti
.org $50 ; timer.
reti
.org $58 ; serial.
reti
.org $60 ; high to low.
reti
;;; at this point, the gameboy has successfully booted and transfers control
;;; to our code.
;;; our goal is to display a checkerboard, so:
.org $150
boot:
di ; disable interrupts
nop ; wait for disabled interrupts to take effect
;; window/background display configuration (LCDC)
;; 7: lcd control (1 = lcd on)
;; 6: window tile map display select (0 = 0x9800 -> 0x9BFF)
;; 5: window display (0 = off)
;; 4: bg & window tile data select (1 = 0x8000 -> 0x8FFF)
;; 3: bg tile map display select (1 = 0x9C00 -> 0x9FFF)
;; 2: object (aka sprite) size (0 = 8x8)
;; 1: object (aka sprite) display (0 = off)
;; 0: bg & window display (1 = on)
ld hl, $FF40
ld (hl), %10011001
;; populate tile data
call load_tile
;; palettes
ld a, %11100100 ; the default value (11 is darkest, 00 is lightest, etc)
cpl
ldh ($47), a ; palette for background tiles
ldh ($48), a ; palette 1 for sprites
ldh ($49), a ; palette 2 for sprites
call bg_display ; render background
halt ; we're done, so stop
load_tile:
;; load representation of checkered tile into video ram
ld hl, $8000 ; set pointer to beginning of video ram
; (this should match the value specified in LCDC bit 4)
ld bc, $2
ld (hl), $00cc
add hl, bc
ld (hl), $00cc
add hl, bc
ld (hl), $0033
add hl, bc
ld (hl), $0033
add hl, bc
ld (hl), $00cc
add hl, bc
ld (hl), $00cc
add hl, bc
ld (hl), $0033
add hl, bc
ld (hl), $0033
ret
bg_display:
;; load 0s into every memory address from 0x9C00 -> 0x9FFF
;; 0 is the index of the tile that we defined earlier
ld hl, $9C00
ld a, $FF
bg_display_loop:
ld (hl), $0
inc hl
cp l
jp nz,bg_display_loop
ret
AS = wla-gb
LD = wlalink
SOURCE = main.s
ROMFILE = woof.gb
all: $(ROMFILE)
run: all
mednafen $(ROMFILE)
main.o:
wla-gb $(SOURCE)
$(ROMFILE): main.o
wlalink -v Linkfile $(ROMFILE)
clean:
rm *.o
rm *.gb
rm *.s.d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment