nuclear@0: ; vi:ft=rgbasm: nuclear@4: ; -------- build options ---------- nuclear@4: BUILD_CHESS equ 1 nuclear@4: BUILD_LOGO equ 2 nuclear@4: nuclear@4: BUILD = BUILD_LOGO nuclear@4: ; --------------------------------- nuclear@4: nuclear@0: include "hw.inc" nuclear@0: nuclear@0: xoffs_center equ 4 nuclear@0: yoffs_center equ 12 nuclear@0: nuclear@3: frame equ $ff80 nuclear@3: bnstate equ $ff81 nuclear@3: bnxor equ $ff82 nuclear@3: pause equ $ff83 nuclear@3: nuclear@3: BN_A equ $01 nuclear@3: BN_B equ $02 nuclear@3: BN_SELECT equ $04 nuclear@3: BN_START equ $08 nuclear@3: BN_RIGHT equ $10 nuclear@3: BN_LEFT equ $20 nuclear@3: BN_UP equ $40 nuclear@3: BN_DOWN equ $80 nuclear@0: nuclear@0: section "hdr", ROM0[$100] nuclear@0: nop nuclear@0: jp main nuclear@0: nuclear@0: rept $150 - $104 nuclear@0: db 0 nuclear@0: endr nuclear@0: nuclear@0: section "text", ROM0 nuclear@0: nuclear@0: main: nuclear@0: call init nuclear@0: nuclear@0: xor a, a nuclear@3: ldh [frame], a nuclear@3: ldh [bnstate], a nuclear@3: ldh [bnxor], a nuclear@3: ldh [pause], a nuclear@3: nuclear@0: .mainloop: nuclear@0: ldh a, [REG_LY] nuclear@0: cp a, 144 nuclear@0: jr c, .wait_hsync nuclear@0: nuclear@3: ; we're in vsync, increment frame counter, handle input, nuclear@3: ; and wait for the next frame nuclear@3: call read_input nuclear@3: nuclear@3: ; swap palette if A is pressed nuclear@3: ldh a, [bnxor] nuclear@3: and a, BN_A nuclear@3: jr z, .skip_akey ; skip if A haven't changed state since last frame nuclear@3: ldh a, [bnstate] nuclear@3: and a, BN_A nuclear@3: jr z, .skip_akey ; skip if A is not pressed nuclear@3: ldh a, [REG_BGP] nuclear@3: cpl nuclear@3: ldh [REG_BGP], a nuclear@3: .skip_akey: nuclear@3: ; toggle pause if start is pressed nuclear@3: ldh a, [bnxor] nuclear@3: and a, BN_START nuclear@3: jr z, .skip_startkey ; skip if start haven't changed state since last frame nuclear@3: ldh a, [bnstate] nuclear@3: and a, BN_START nuclear@3: jr z, .skip_startkey ; skip if start is not pressed nuclear@3: ldh a, [pause] nuclear@3: cpl nuclear@3: ldh [pause], a nuclear@3: .skip_startkey: nuclear@3: nuclear@3: ; increment frame if we're not paused nuclear@3: ldh a, [pause] nuclear@3: bit 0, a nuclear@3: jr nz, .skip_frameinc nuclear@3: ldh a, [frame] nuclear@0: inc a nuclear@3: ldh [frame], a nuclear@3: .skip_frameinc: nuclear@3: nuclear@3: nuclear@0: .wait_newframe: nuclear@0: ldh a, [REG_LY] nuclear@0: cp a, 0 nuclear@0: jr nz, .wait_newframe nuclear@0: nuclear@0: ; scanline code nuclear@0: .wait_hsync: nuclear@0: ldh a, [REG_STAT] nuclear@0: and a, STAT_MODE_MASK nuclear@0: jr nz, .wait_hsync nuclear@0: nuclear@3: ldh a, [frame] nuclear@0: ld d, a nuclear@0: nuclear@0: xor a, a nuclear@0: ld b, a nuclear@1: nuclear@0: ldh a, [REG_LY] nuclear@1: add a, d ; add frame number nuclear@0: ld c, a nuclear@0: nuclear@0: ld hl, sintab nuclear@1: add hl, bc ; hl now points to the sine value nuclear@0: nuclear@1: ld a, [hl] nuclear@1: nuclear@1: ; add a half-octave sine nuclear@1: ld e, a ; save first sine to e nuclear@1: sla d nuclear@1: ld a, [REG_LY] nuclear@1: sla a nuclear@1: add a, d nuclear@1: ld c, a nuclear@1: srl d nuclear@1: nuclear@1: ld hl, sintab nuclear@1: add hl, bc nuclear@1: ld a, [hl] nuclear@1: sra a nuclear@1: add a, e ; add previously saved sine nuclear@1: nuclear@1: add a, yoffs_center nuclear@0: ldh [REG_SCY], a nuclear@0: nuclear@1: ; do something for SCX too nuclear@1: ld a, d nuclear@1: sla a nuclear@1: ld d, a nuclear@1: nuclear@1: ldh a, [REG_LY] nuclear@1: add a, 32 nuclear@1: add a, d ; add frame number nuclear@1: ld c, a nuclear@1: nuclear@1: ld hl, sintab nuclear@1: add hl, bc nuclear@1: nuclear@1: ld a, [hl] nuclear@1: sra a nuclear@1: add a, xoffs_center nuclear@1: ldh [REG_SCX], a nuclear@1: nuclear@0: ; done, wait until we're out of hsync nuclear@0: .wait_endhsync: nuclear@0: ldh a, [REG_STAT] nuclear@0: and a, STAT_MODE_MASK nuclear@0: jr z, .wait_endhsync nuclear@0: nuclear@3: jp .mainloop nuclear@0: nuclear@0: nuclear@0: di nuclear@0: .end: halt nuclear@0: nop nuclear@0: jp .end nuclear@0: nuclear@0: init: nuclear@0: call wait_vsync nuclear@0: xor a, a nuclear@0: ldh [REG_LCDC], a nuclear@0: nuclear@2: ; setup palette nuclear@0: ld a, $1b nuclear@0: ldh [REG_BGP], a nuclear@0: nuclear@0: ; copy tiles nuclear@0: ld hl, $8000 nuclear@0: ld de, tiles nuclear@0: ld bc, tiles_end - tiles nuclear@0: .copytiles: nuclear@0: ld a, [de] nuclear@0: ld [hl+], a nuclear@0: inc de nuclear@0: dec bc nuclear@0: ld a, b nuclear@0: or c nuclear@0: jp nz, .copytiles nuclear@0: nuclear@4: IF BUILD == BUILD_LOGO nuclear@4: ; copy logo tilemap nuclear@0: ld hl, $9800 nuclear@0: ld de, tilemap nuclear@0: ld b, 21 nuclear@0: .copymap: nuclear@0: ld c, 21 nuclear@0: .copymaprow: nuclear@0: ld a, [de] nuclear@0: inc de nuclear@0: ld [hl+], a nuclear@0: dec c nuclear@0: jr nz, .copymaprow nuclear@0: nuclear@0: push bc nuclear@0: ld bc, 11 nuclear@0: add hl, bc nuclear@0: pop bc nuclear@0: nuclear@0: dec b nuclear@0: jr nz, .copymap nuclear@4: ELSE nuclear@4: ; generate chessboard tilemap nuclear@4: ld hl, $9800 nuclear@4: ld b, 32 nuclear@4: .fillscr: nuclear@4: ld c, 32 nuclear@4: .fillrow: nuclear@4: ld a, b nuclear@4: add a, c nuclear@4: and a, 1 nuclear@4: nuclear@4: ld [hl+], a nuclear@4: dec c nuclear@4: jr nz, .fillrow nuclear@4: nuclear@4: dec b nuclear@4: jr nz, .fillscr nuclear@4: ENDC nuclear@0: nuclear@0: ; center viewport nuclear@0: ld a, yoffs_center nuclear@0: ldh [REG_SCY], a nuclear@0: ld a, xoffs_center nuclear@0: ldh [REG_SCX], a nuclear@0: nuclear@0: ; configure LCD nuclear@0: ld a, LCDC_DISPON | LCDC_CHAR_8000 | LCDC_BGON nuclear@0: ldh [REG_LCDC], a nuclear@0: ret nuclear@0: nuclear@0: wait_vsync: nuclear@0: ldh a, [REG_LY] nuclear@0: cp a, 144 nuclear@0: jr c, wait_vsync nuclear@0: ret nuclear@0: nuclear@3: read_input: nuclear@3: ; read D-pad nuclear@3: ld a, P1_DPAD nuclear@3: ld [REG_P1], a nuclear@3: ld a, [REG_P1] nuclear@3: ld a, [REG_P1] nuclear@3: cpl nuclear@3: and a, $0f nuclear@3: swap a nuclear@3: ld b, a nuclear@3: ; read buttons nuclear@3: ld a, P1_BUTTONS nuclear@3: ld [REG_P1], a nuclear@3: ld a, [REG_P1] nuclear@3: ld a, [REG_P1] nuclear@3: ld a, [REG_P1] nuclear@3: ld a, [REG_P1] nuclear@3: ld a, [REG_P1] nuclear@3: ld a, [REG_P1] nuclear@3: cpl nuclear@3: and a, $0f nuclear@3: or a, b nuclear@3: ld b, a nuclear@3: ; reset port nuclear@3: ld a, P1_DPAD | P1_BUTTONS nuclear@3: ldh [REG_P1], a nuclear@3: ; calculate differences and save state variables nuclear@3: ldh a, [bnstate] nuclear@3: xor a, b nuclear@3: ldh [bnxor], a nuclear@3: ld a, b nuclear@3: ldh [bnstate], a nuclear@3: ret nuclear@3: nuclear@0: section "data", ROM0, align[8] nuclear@0: sintab: nuclear@0: include "sin.inc" nuclear@0: nuclear@4: IF BUILD == BUILD_LOGO nuclear@0: tiles: nuclear@0: incbin "logo.tiles" nuclear@0: tiles_end: nuclear@0: tilemap: nuclear@0: incbin "logo.tilemap" nuclear@0: tilemap_end: nuclear@4: nuclear@4: ELSE nuclear@4: ; chessboard tiles nuclear@4: tiles: nuclear@4: db $55,$00 nuclear@4: db $aa,$00 nuclear@4: db $55,$00 nuclear@4: db $aa,$00 nuclear@4: db $55,$00 nuclear@4: db $aa,$00 nuclear@4: db $55,$00 nuclear@4: db $aa,$00 nuclear@4: nuclear@4: db $ff,$aa nuclear@4: db $ff,$55 nuclear@4: db $ff,$aa nuclear@4: db $ff,$55 nuclear@4: db $ff,$aa nuclear@4: db $ff,$55 nuclear@4: db $ff,$aa nuclear@4: db $ff,$55 nuclear@4: tiles_end: nuclear@4: ENDC