diff --git a/Makefile b/Makefile index 2d8cd9c..cbc6a2a 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ is.gb is.gb.sym: $(IMGFILES) $(OFILES) $(OFILES): $(IMGFILES) %.o: %.s - rgbasm -o $@ $< + rgbasm -i inc -o $@ $< %.2bpp: %.png rgbgfx -o $@ $< diff --git a/hardware.inc b/inc/hardware.inc similarity index 100% rename from hardware.inc rename to inc/hardware.inc diff --git a/inc/input.inc b/inc/input.inc new file mode 100644 index 0000000..ca0bc61 --- /dev/null +++ b/inc/input.inc @@ -0,0 +1,8 @@ +DEF BTN_START EQU $80 +DEF BTN_SELECT EQU $40 +DEF BTN_B EQU $20 +DEF BTN_A EQU $10 +DEF BTN_DOWN EQU $8 +DEF BTN_UP EQU $4 +DEF BTN_LEFT EQU $2 +DEF BTN_RIGHT EQU $1 \ No newline at end of file diff --git a/src/input.s b/src/input.s new file mode 100644 index 0000000..156f17b --- /dev/null +++ b/src/input.s @@ -0,0 +1,56 @@ +INCLUDE "hardware.inc" + +Section "Input Data", WRAM0 + +lastKeys:: db +keys:: db + +Section "Input Code", ROM0 + +; Initialize input +; NOTE: Inline if needed +Keys_Init:: + ld hl, lastKeys + xor a + ld [hl+], a + ld [hl], a + +; Update the input state +Keys_Update:: + ld a, P1F_GET_BTN + ld [rP1], a + + ; wait a few cycles + ld a, [rP1] + ld a, [rP1] + + ; extract btn bits into top of B + cpl + and $f + swap a + ld b, a + ld a, P1F_GET_DPAD + ld [rP1], a + + ; wait more cycles + ld a, [rP1] + ld a, [rP1] + ld a, [rP1] + ld a, [rP1] + ld a, [rP1] + ld a, [rP1] + + ; extract dpad bits into bottom of B + cpl + and $f + or b + ld b, a + + ; lastKeys <- keys ; keys <- B + ld hl, keys + ld a, [hl] + ld [hl], b + dec hl + ld [hl], a + + ret diff --git a/src/main.s b/src/main.s index fc57d94..3d546af 100644 --- a/src/main.s +++ b/src/main.s @@ -36,7 +36,9 @@ start: ld c, 16 call memset - call PlayerInit + call OAM_Init + call Keys_Init + call Player_Init ; enable lcd, sprites and interrupts ld hl, rLCDC @@ -47,11 +49,13 @@ start: ld hl, rOBP0 ld [hl], %11100100 -.vbl: - ld a, [$ff41] - and 3 - cp 1 - jr nz, .vbl +.loop: + call Keys_Update + call Player_Update - halt - jp .vbl + call waitForVblank + + ld a, HIGH(_OAM) + call DMA_Start + + jp .loop diff --git a/src/oam.s b/src/oam.s new file mode 100644 index 0000000..74da1b8 --- /dev/null +++ b/src/oam.s @@ -0,0 +1,38 @@ +INCLUDE "hardware.inc" + +SECTION "OAM Mirror", WRAM0, ALIGN[8] + +_OAM:: ds 40 * 4 +_OAM_end: + +SECTION "OAM DMA routine", ROM0 + +; Initialize OAM +OAM_Init:: + ; Clear internal OAM + ld hl, _OAM + xor a + ld c, _OAM_end - _OAM + call memset + + ; Copy DMA transfer routine to HRAM + ld hl, waitForDMA + ld bc, DMA_Start + ld d, waitForDMA_end - waitForDMA + call memcpy + + ret + +waitForDMA: + ld [rDMA], a + ld a, 40 +.wait: + dec a + jr nz, .wait + ret +waitForDMA_end: + +SECTION "OAM DMA", HRAM + +DMA_Start:: + ds waitForDMA_end - waitForDMA diff --git a/src/player.s b/src/player.s index bb21619..1f91e9b 100644 --- a/src/player.s +++ b/src/player.s @@ -1,4 +1,5 @@ INCLUDE "hardware.inc" +INCLUDE "input.inc" Section "Player Data", WRAM0 @@ -17,9 +18,9 @@ Section "Player Code", ROM0 spriteData: INCBIN "png/player.2bpp" -PlayerInit:: +Player_Init:: ld a, 8 - ld hl, playerScreenX + ld hl, _OAM + 1 ld [hl], a ld bc, _VRAM8000 @@ -27,7 +28,7 @@ PlayerInit:: ld d, 16 call memcpy - ld hl, playerSprite + ld hl, _OAM ld a, 144-8 ld [hli], a ld a, 8 @@ -37,11 +38,32 @@ PlayerInit:: ld [hli], a ld bc, _OAMRAM - ld hl, playerSprite + ld hl, _OAM ld d, 4 call memcpy ret -PlayerDraw:: +Player_Update:: + ld hl, keys + ld b, [hl] + + ; check for move right + ld a, b + and BTN_RIGHT + jr z, .left + + ld hl, _OAM + 1 + inc [hl] + +.left: + ; check for move left + ld a, b + and BTN_LEFT + jr z, .done + + ld hl, _OAM + 1 + dec [hl] + +.done: ret diff --git a/src/util.s b/src/util.s index 18aed71..24614c0 100644 --- a/src/util.s +++ b/src/util.s @@ -1,5 +1,13 @@ SECTION "Utilities", ROM0 +; Busy-wait until vertical blank occurs +waitForVblank:: + ld a, [$ff41] + and 3 + cp 1 + jr nz, waitForVblank + ret + ; Copies data between two regions ; @param d Size (in bytes) to copy. Must be >0 ; @param bc Pointer to the destination region