INCLUDE "hardware.inc"

; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Header section
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SECTION "Header", ROM0[$100]
	jp EntryPoint
	ds $150 - @, 0	; Make room for the header!

; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Initialization section
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

EntryPoint:
					; Do not turn the LCD off outside of VBlank
WaitVBlank1:
	ld a, [rLY]		; Load our LCD Y position into  a
	cp 144			; Compare to 144
	jp c, WaitVBlank1; Jump if carry (if a < 144)
	
	; Turn the LCD off
	ld a, 0			; Load 0's into a
	ld [rLCDC], a	; Set our LCD Controller to 0 to turn everything off
	
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; V RAM operations
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	; Copy the background tile data
	ld de, bgTileStart	; Load our tile block start into d/e
	ld hl, $9000	; Load our VRAM start into h/l
	ld bc, bgTileEnd - bgTileStart	; Load the size of our tile block into b/c
Memcopy1:
	ld a, [de]	; Load value from source into a.
	ld [hli], a	; Load that value into destination and increment destination pointer.
	inc de		; Increment our source pointer.
	dec bc		; Decrement our length value
	ld a, b		; Load the value of b into a
	or a, c		; Or a with c
	jp nz, Memcopy1		; While a and c are nonzero, jump back to Memcopy

	; Copy the background tilemap data
	ld de, bgMapStart	; Load our tilemap block start into d/e
	ld hl, $9800	; Load our VRAM start into h/l
	ld bc, bgMapEnd - bgMapStart	; Load the size of our tilemap block into b/c
Memcopy2:
	ld a, [de]	; Load value from source into a.
	ld [hli], a	; Load that value into destination and increment destination pointer.
	inc de		; Increment our source pointer.
	dec bc		; Decrement our length value
	ld a, b		; Load the value of b into a
	or a, c		; Or a with c
	jp nz, Memcopy2		; While a and c are nonzero, jump back to Memcopy

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; OAM RAM operations
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Startup
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	; Turn the LCD on
	ld a, LCDCF_ON | LCDCF_BGON		; Pretty clear what this does, actually.
	ld [rLCDC], a	; LCDCF_ON and LDCDF_BGON are the bits that control the LCD and background
	
	; During the first (blank) frame, initialize display registers
	ld a, %00011011	; rBGP = FF47. Palettes: ID 0:white 1:LG 2:DG 3:Black
	ld [rBGP], a

; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Main program loop
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Main:
	; Wait until it's *not* VBLANK
	ld a, [rLY]		; Load our LCD Y position into a
	cp 144			; Compare it to 144
	jp nc, Main		; Jump if carry (a < 144)
WaitVBlank2:
	; Wait until it *is* VBLANK
	ld a,[rLY]
	cp 144
	jp c, WaitVBlank2
	
	jp Main			; Loop infinitely

; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Functions
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Tile data
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SECTION "Tile data", ROM0

bgTileStart:
	db %11111111, %11111111
	db %11111111, %11111111
	db %11111111, %11111111
	db %11111111, %11111111
	db %11111111, %11111111
	db %11111111, %11111111
	db %11111111, %11111111
	db %11111111, %11111111

	db %10100101, %11000011
	db %10100101, %11000011
	db %10100101, %11000011
	db %10100101, %11000011
	db %10100101, %11000011
	db %10011001, %11100111
	db %11000011, %11111111
	db %11111111, %11111111

	db %11111111, %11111111
	db %11000000, %11111111
	db %10011111, %11100000
	db %10100000, %11000000
	db %10100000, %11000000
	db %10011111, %11100000
	db %11000000, %11111111
	db %11111111, %11111111

	db %10100100, %11000011
	db %10100010, %11000001
	db %10010001, %11100000
	db %11001000, %11110000
	db %11100100, %11111000
	db %11110011, %11111100
	db %11111000, %11111111
	db %11111111, %11111111

	db %11111111, %11111111
	db %11000011, %11111111
	db %10011001, %11100111
	db %10100101, %11000011
	db %10100101, %11000011
	db %10100101, %11000011
	db %10100101, %11000011
	db %10100101, %11000011

	db %10100101, %11000011
	db %10100101, %11000011
	db %10100101, %11000011
	db %10100101, %11000011
	db %10100101, %11000011
	db %10100101, %11000011
	db %10100101, %11000011
	db %10100101, %11000011

	db %11111111, %11111111
	db %11111000, %11111111
	db %11110011, %11111100
	db %11100100, %11111000
	db %11001000, %11110000
	db %10010001, %11100000
	db %10100010, %11000001
	db %10100100, %11000011

	db %10100100, %11000011
	db %10100010, %11000001
	db %10010001, %11100000
	db %11001000, %11110000
	db %11001000, %11110000
	db %10010001, %11100000
	db %10100010, %11000001
	db %10100100, %11000011

	db %11111111, %11111111
	db %00000011, %11111111
	db %11111001, %00000111
	db %00000101, %00000011
	db %00000101, %00000011
	db %11111001, %00000111
	db %00000011, %11111111
	db %11111111, %11111111

	db %00100101, %11000011
	db %01000101, %10000011
	db %10001001, %00000111
	db %00010011, %00001111
	db %00100111, %00011111
	db %11001111, %00111111
	db %00011111, %11111111
	db %11111111, %11111111

	db %11111111, %11111111
	db %00000000, %11111111
	db %11111111, %00000000
	db %00000000, %00000000
	db %00000000, %00000000
	db %11111111, %00000000
	db %00000000, %11111111
	db %11111111, %11111111

	db %00100100, %11000011
	db %01000010, %10000001
	db %10000001, %00000000
	db %00011000, %00000000
	db %00100100, %00011000
	db %11000011, %00111100
	db %00011000, %11111111
	db %11111111, %11111111

	db %11111111, %11111111
	db %00011111, %11111111
	db %11001111, %00111111
	db %00100111, %00011111
	db %00010011, %00001111
	db %10001001, %00000111
	db %01000101, %10000011
	db %00100101, %11000011

	db %00100101, %11000011
	db %01000101, %10000011
	db %10001001, %00000111
	db %00010011, %00001111
	db %00010011, %00001111
	db %10001001, %00000111
	db %01000101, %10000011
	db %00100101, %11000011

	db %11111111, %11111111
	db %00011000, %11111111
	db %11000011, %00111100
	db %00100100, %00011000
	db %00011000, %00000000
	db %10000001, %00000000
	db %01000010, %10000001
	db %00100100, %11000011

	db %00100100, %11000011
	db %01000010, %10000001
	db %10000001, %00000000
	db %00011000, %00000000
	db %00011000, %00000000
	db %10000001, %00000000
	db %01000010, %10000001
	db %00100100, %11000011
bgTileEnd:

bgMapStart:
	db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$04,$00,$04,$06,$0A,$08,$04,$00,$00,$04,$00,$00,$06,$0A,$0C,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$05,$00,$05,$05,$00,$00,$05,$00,$00,$05,$00,$00,$05,$00,$05,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$07,$0A,$0D,$07,$0A,$08,$05,$00,$00,$05,$00,$00,$05,$00,$05,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$05,$00,$05,$05,$00,$00,$05,$00,$00,$05,$00,$00,$05,$00,$05,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$01,$00,$01,$03,$0A,$08,$03,$0A,$08,$03,$0A,$08,$03,$0A,$09,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$04,$04,$04,$06,$0A,$0C,$06,$0A,$0C,$04,$00,$00,$06,$0C,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$05,$05,$05,$05,$00,$05,$05,$00,$05,$05,$00,$00,$05,$03,$0C,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$05,$05,$05,$05,$00,$05,$07,$0E,$09,$05,$00,$00,$05,$00,$05,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$05,$05,$05,$05,$00,$05,$05,$03,$0C,$05,$00,$00,$05,$06,$09,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$03,$0B,$09,$03,$0A,$09,$01,$00,$01,$03,$0A,$08,$03,$09,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
bgMapEnd:

; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Global variables
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~