; vi:ft=rgbasm:
; -------- build options ----------
BUILD_CHESS equ 1
BUILD_LOGO equ 2

BUILD = BUILD_LOGO
; ---------------------------------

include "hw.inc"

xoffs_center equ 4
yoffs_center equ 12

frame equ $ff80
bnstate equ $ff81
bnxor equ $ff82
pause equ $ff83

BN_A		equ $01
BN_B		equ $02
BN_SELECT	equ $04
BN_START	equ $08
BN_RIGHT	equ $10
BN_LEFT		equ $20
BN_UP		equ $40
BN_DOWN		equ $80

section "hdr", ROM0[$100]
        nop
        jp main

rept $150 - $104
        db 0
endr

section "text", ROM0

main:
	call init

	xor a, a
	ldh [frame], a
	ldh [bnstate], a
	ldh [bnxor], a
	ldh [pause], a

.mainloop:
	ldh a, [REG_LY]
	cp a, 144
	jr c, .wait_hsync

	; we're in vsync, increment frame counter, handle input,
	; and wait for the next frame
	call read_input

	; swap palette if A is pressed
	ldh a, [bnxor]
	and a, BN_A
	jr z, .skip_akey  ; skip if A haven't changed state since last frame
	ldh a, [bnstate]
	and a, BN_A
	jr z, .skip_akey  ; skip if A is not pressed
	ldh a, [REG_BGP]
	cpl
	ldh [REG_BGP], a
.skip_akey:
	; toggle pause if start is pressed
	ldh a, [bnxor]
	and a, BN_START
	jr z, .skip_startkey ; skip if start haven't changed state since last frame
	ldh a, [bnstate]
	and a, BN_START
	jr z, .skip_startkey ; skip if start is not pressed
	ldh a, [pause]
	cpl
	ldh [pause], a
.skip_startkey:

	; increment frame if we're not paused
	ldh a, [pause]
	bit 0, a
	jr nz, .skip_frameinc
	ldh a, [frame]
	inc a
	ldh [frame], a
.skip_frameinc:


.wait_newframe:
	ldh a, [REG_LY]
	cp a, 0
	jr nz, .wait_newframe

	; scanline code
.wait_hsync:
	ldh a, [REG_STAT]
	and a, STAT_MODE_MASK
	jr nz, .wait_hsync

	ldh a, [frame]
	ld d, a

	xor a, a
	ld b, a

	ldh a, [REG_LY]
	add a, d	; add frame number
	ld c, a

	ld hl, sintab
	add hl, bc	; hl now points to the sine value

	ld a, [hl]

	; add a half-octave sine
	ld e, a		; save first sine to e
	sla d
	ld a, [REG_LY]
	sla a
	add a, d
	ld c, a
	srl d

	ld hl, sintab
	add hl, bc
	ld a, [hl]
	sra a
	add a, e	; add previously saved sine

	add a, yoffs_center
	ldh [REG_SCY], a

	; do something for SCX too
	ld a, d
	sla a
	ld d, a

	ldh a, [REG_LY]
	add a, 32
	add a, d	; add frame number
	ld c, a

	ld hl, sintab
	add hl, bc

	ld a, [hl]
	sra a
	add a, xoffs_center
	ldh [REG_SCX], a

	; done, wait until we're out of hsync
.wait_endhsync:
	ldh a, [REG_STAT]
	and a, STAT_MODE_MASK
	jr z, .wait_endhsync

	jp .mainloop


	di
.end:   halt
        nop
        jp .end

init:
	call wait_vsync
	xor a, a
	ldh [REG_LCDC], a

	; setup palette
	ld a, $1b
	ldh [REG_BGP], a

	; copy tiles
	ld hl, $8000
	ld de, tiles
	ld bc, tiles_end - tiles
.copytiles:
	ld a, [de]
	ld [hl+], a
	inc de
	dec bc
	ld a, b
	or c
	jp nz, .copytiles

IF BUILD == BUILD_LOGO
	; copy logo tilemap
	ld hl, $9800
	ld de, tilemap
	ld b, 21
.copymap:
	ld c, 21
.copymaprow:
	ld a, [de]
	inc de
	ld [hl+], a
	dec c
	jr nz, .copymaprow

	push bc
	ld bc, 11
	add hl, bc
	pop bc

	dec b
	jr nz, .copymap
ELSE
	; generate chessboard tilemap
	ld hl, $9800
	ld b, 32
.fillscr:
	ld c, 32
.fillrow:
	ld a, b
	add a, c
	and a, 1

	ld [hl+], a
	dec c
	jr nz, .fillrow

	dec b
	jr nz, .fillscr
ENDC

	; center viewport
	ld a, yoffs_center
	ldh [REG_SCY], a
	ld a, xoffs_center
	ldh [REG_SCX], a

	; configure LCD
	ld a, LCDC_DISPON | LCDC_CHAR_8000 | LCDC_BGON
	ldh [REG_LCDC], a
	ret

wait_vsync:
	ldh a, [REG_LY]
	cp a, 144
	jr c, wait_vsync
	ret

read_input:
	; read D-pad
	ld a, P1_DPAD
	ld [REG_P1], a
	ld a, [REG_P1]
	ld a, [REG_P1]
	cpl
	and a, $0f
	swap a
	ld b, a
	; read buttons
	ld a, P1_BUTTONS
	ld [REG_P1], a
	ld a, [REG_P1]
	ld a, [REG_P1]
	ld a, [REG_P1]
	ld a, [REG_P1]
	ld a, [REG_P1]
	ld a, [REG_P1]
	cpl
	and a, $0f
	or a, b
	ld b, a
	; reset port
	ld a, P1_DPAD | P1_BUTTONS
	ldh [REG_P1], a
	; calculate differences and save state variables
	ldh a, [bnstate]
	xor a, b
	ldh [bnxor], a
	ld a, b
	ldh [bnstate], a
	ret

section "data", ROM0, align[8]
sintab:
include "sin.inc"

IF BUILD == BUILD_LOGO
tiles:
incbin "logo.tiles"
tiles_end:
tilemap:
incbin "logo.tilemap"
tilemap_end:

ELSE
; chessboard tiles
tiles:
	db $ff,$00
	db $81,$00
	db $81,$00
	db $81,$00
	db $81,$00
	db $81,$00
	db $81,$00
	db $ff,$00

	db $00,$ff
	db $7e,$ff
	db $7e,$ff
	db $7e,$ff
	db $7e,$ff
	db $7e,$ff
	db $7e,$ff
	db $00,$ff
tiles_end:
ENDC