diff --git a/Code/automata.asm b/Code/automata.asm index a45ee28..a71a869 100644 --- a/Code/automata.asm +++ b/Code/automata.asm @@ -282,20 +282,11 @@ SwapBuffers: ; set old and rendered pointers to buffer1 ld a, HIGH(Buffer1) ldh [Old], a - ldh [Rendered + 1], a ; set new pointer to buffer0 ld a, HIGH(Buffer0) ldh [New], a - ; set video pointer to first tilemap - ld a, HIGH(_SCRN1) - ldh [Video + 1], a - - ; display bg 9800 that has just been filled - ld a, LCDCF_ON | LCDCF_BGON | LCDCF_BG9800 - ld [rLCDC], a - jr InitAutomata.resetLow .newToBuffer1 @@ -303,20 +294,11 @@ InitAutomata: ; set old and rendered pointers to buffer0 ld a, HIGH(Buffer0) ldh [Old], a - ldh [Rendered + 1], a ; set new pointer to buffer1 ld a, HIGH(Buffer1) ldh [New], a - ; set video pointer to second tilemap - ld a, HIGH(_SCRN0) - ldh [Video + 1], a - - ; display bg 9C00 that has just been filled - ld a, LCDCF_ON | LCDCF_BGON | LCDCF_BG9C00 - ld [rLCDC], a - .resetLow ; reset low bytes of pointers xor a diff --git a/Code/edit.asm b/Code/edit.asm index 0d0746e..16990fc 100644 --- a/Code/edit.asm +++ b/Code/edit.asm @@ -24,102 +24,15 @@ InitEdit: ldh [Down], a ld a, REPEAT_START_DELAY ldh [RepeatDelay], a - ret - -SECTION "Jingle", ROM0 -Jingle: - - ; load initial frequency into HL -FREQUENCY = 330 - ld hl, PULSE_FREQUENCY - - ; load step to be added to frequency in DE - ; based on if a != 0 or not - or a - jr z, .up -.down - ld de, 100 - jr .do -.up - ld de, -100 - -.do - ; load note count - ld b, 3 -.loop - - ; play pulse channel 1 with frequency set in HL - xor a - ldh [rNR10], a ; sweep - ld a, (%01 << 6) + 30 - ldh [rNR11], a ; pattern + sound length - ld a, $43 - ldh [rNR12], a ; init volume + envelope sweep - ld a, l - ldh [rNR13], a - ld a, h - or a, SOUND_START - ldh [rNR14], a - - ; add DE to HL frequency - add hl, de - - ; wait ~166ms - ld c, 6 -.delay - HaltAndClearInterrupts - dec c - jr nz, .delay - - ; repeat a few times - dec b - ret z - jr .loop - -EXPORT EditOldBuffer -SECTION "Edit old buffer", ROM0 -EditOldBuffer: - ; check start has been pressed - ldh a, [JoypadDown] - and a, PADF_START - ret z - - ; sound ON - ld a, $80 - ldh [rNR52], a - ld a, $77 - ldh [rNR50], a ; max volume on both speakers - ld a, $99 - ldh [rNR51], a ; channels 1 (pulse) and 4 (noise) on both speakers - - ; play jingle with notes going down - xor a - call Jingle - - ; wait v-blank - halt - - ; show sprites - ldh a, [rLCDC] - or a, LCDCF_OBJON - ldh [rLCDC], a - - ; init sprite animation xor a ldh [SpriteAnimation], a ld a, SPRITE_ANIM_DELAY ldh [SpriteDelay], a + ret - ; set video address to displayed - ldh a, [Video + 1] - xor a, %100 - ldh [Video + 1], a - - ; clear interrupts - xor a - ldh [rIF], a - -.loop +EXPORT EditOldBuffer +SECTION "Edit old buffer", ROM0 +EditOldBuffer: ; compute cursor X position ldh a, [SelectX] sla a @@ -152,22 +65,16 @@ EditOldBuffer: ; update sprite in OAM SetSprite 0, b, c, d, 0 - call UpdateJoypad - - ; check A button has been pressed + ; toggle targeted cell if A pressed ldh a, [JoypadDown] and a, PADF_A call nz, ToggleCell + ; clear if SELECT pressed ldh a, [JoypadDown] and a, PADF_SELECT call nz, Clear - ; check start has been pressed - ldh a, [JoypadDown] - and a, PADF_START - jr nz, .exit - ; reset input xor a ldh [Down], a @@ -251,38 +158,6 @@ EditOldBuffer: ldh [SelectY], a .endDown - ; wait v-blank -.skip - HaltAndClearInterrupts - - jp .loop - -.exit - - ld a, 1 - call Jingle - - ; hide sprites - ldh a, [rLCDC] - and a, ~LCDCF_OBJON - ldh [rLCDC], a - - ; set video address to next displayed - ldh a, [Video + 1] - xor a, %100 - ldh [Video + 1], a - - ; wait for sound to finish - ld b, 10 -.waitSound - HaltAndClearInterrupts - dec b - jr nz, .waitSound - - ; sound OFF - xor a - ldh [rNR52], a - ret SECTION "Value to flag", ROM0, ALIGN[8] @@ -330,6 +205,7 @@ ToggleCell: ldh a, [Video] ld l, a ldh a, [Video + 1] + xor a, %100 ld h, a MoveToCell 32 @@ -352,10 +228,10 @@ ToggleCell: ; do sound based on new value and a, b - jr z, .blurp1 + jr nz, .pulse ; do noisy sound -.blurp0 +.noise xor a ldh [rNR41], a ; sound length ld a, $F1 @@ -364,10 +240,10 @@ ToggleCell: ldh [rNR43], a ; frequency ld a, $80 ldh [rNR44], a ; start - jr .exit + ret ; do pulsy sound -.blurp1 +.pulse xor a ldh [rNR10], a ; sweep ld a, (%01 << 6) + 30 @@ -379,10 +255,8 @@ FREQUENCY = 100 ldh [rNR13], a ld a, SOUND_START | HIGH(PULSE_FREQUENCY) ldh [rNR14], a - -.exit ret - + SECTION "Clear buffers", ROM0 Clear: ; load old buffer address and store into rendered @@ -392,7 +266,7 @@ Clear: ldh a, [Old] ld h, a ld [Rendered + 1], a - + ; clear old buffer ld bc, 20 * 18 ld d, 0 @@ -452,24 +326,4 @@ Clear: or a, LCDCF_OBJON ldh [rLCDC], a - ; reset video pointer - ld hl, Video - ld a, [hl+] - ld h, [hl] - ld l, a - ld de, -(32 * 18) - add hl, de - ld a, l - ldh [Video], a - ld a, h - ldh [Video + 1], a - - ; reset rendered pointer - ldh a, [Progress] - ld l, a - ld [Rendered], a - ldh a, [Old] - ld h, a - ld [Rendered + 1], a - ret \ No newline at end of file diff --git a/Code/main.asm b/Code/main.asm index bace1f7..bafe898 100644 --- a/Code/main.asm +++ b/Code/main.asm @@ -1,8 +1,14 @@ INCLUDE "hardware.inc" INCLUDE "utils.inc" -EMPTY_BG_TILE EQU 17 _VRAM_BG_TILES EQU $9000 +EMPTY_BG_TILE EQU 17 + +ANIMATE EQU %01 +STEP EQU %10 + +SECTION "Main Memory", HRAM +Control: ds 1 SECTION "Header", ROM0[$100] EntryPoint: @@ -12,11 +18,69 @@ REPT $150 - $104 db 0 ENDR +SECTION "Jingle", ROM0 +Jingle: + + ; load initial frequency into HL +FREQUENCY = 330 + ld hl, PULSE_FREQUENCY + + ; load step to be added to frequency in DE + ; based on if a != 0 or not + or a + jr z, .up +.down + ld de, 100 + jr .do +.up + ld de, -100 + +.do + ; load note count + ld b, 3 +.loop + + ; play pulse channel 1 with frequency set in HL + xor a + ldh [rNR10], a ; sweep + ld a, (%01 << 6) + 30 + ldh [rNR11], a ; pattern + sound length + ld a, $43 + ldh [rNR12], a ; init volume + envelope sweep + ld a, l + ldh [rNR13], a + ld a, h + or a, SOUND_START + ldh [rNR14], a + + ; add DE to HL frequency + add hl, de + + ; wait ~166ms + ld c, 6 +.delay + HaltAndClearInterrupts + dec c + jr nz, .delay + + ; repeat a few times + dec b + ret z + jr .loop + SECTION "Main", ROM0[$150] Start: ; save gameboy type in B ld b, a + ; enable sound + ld a, $80 + ld [rNR52], a ; sound ON + ld a, $77 + ldh [rNR50], a ; max volume on both speakers + ld a, $99 + ldh [rNR51], a ; channels 1 (pulse) and 4 (noise) on both speakers + ; enable v-blank interrupt ld a, IEF_VBLANK ld [rIE], a @@ -70,6 +134,10 @@ ENDC ldh [rSCX], a ldh [rSCY], a + ; animate by default + ld a, ANIMATE + ldh [Control], a + ; clear screen (both buffers) ld hl, _SCRN0 ld d, EMPTY_BG_TILE @@ -84,6 +152,7 @@ ENDC call InitJoypad call InitAutomata + call InitRender call InitEdit ; enable h-blank interrupt in lcd stat @@ -95,11 +164,68 @@ ENDC ldh [rLCDC], a ClearAndEnableInterrupts + .mainloop + ; animate if a control bit is set + ldh a, [Control] + or a + jr z, .interact + call StartRender call UpdateAutomata call WaitRender call SwapBuffers - call UpdateJoypad + + ; clear step bit + ldh a, [Control] + and a, ~STEP + ldh [Control], a + + jr .checkpause + +.interact + HaltAndClearInterrupts + call EditOldBuffer - jp .mainloop + + ; step if B is pressed + ldh a, [JoypadDown] + and a, PADF_B + jr z, .checkpause + + ; enable step bit in control + ld a, STEP + ldh [Control], a + + ; do sound + ld a, $6E + ldh [rNR10], a ; sweep + ld a, (%01 << 6) + 30 + ldh [rNR11], a ; pattern + sound length + ld a, $62 + ldh [rNR12], a ; init volume + envelope sweep +FREQUENCY = 220 + ld a, LOW(PULSE_FREQUENCY) + ldh [rNR13], a + ld a, SOUND_START | HIGH(PULSE_FREQUENCY) + ldh [rNR14], a + +.checkpause + call UpdateJoypad + + ldh a, [JoypadDown] + and a, PADF_START + jr z, .mainloop + + ldh a, [Control] + xor a, ANIMATE + ldh [Control], a + and a, ANIMATE + call Jingle + + ; toggle sprites + ldh a, [rLCDC] + xor a, LCDCF_OBJON + ldh [rLCDC], a + + jr .mainloop diff --git a/Code/nintendo-out.asm b/Code/nintendo-out.asm index 13cba10..ef82b18 100644 --- a/Code/nintendo-out.asm +++ b/Code/nintendo-out.asm @@ -18,14 +18,6 @@ ScrollNintendoOut: dec b jr nz, .wait - ; sound ON - ld a, $80 - ldh [rNR52], a - ld a, $77 - ldh [rNR50], a ; max volume on both speakers - ld a, $88 - ldh [rNR51], a ; noise channel on both speakers - ; make noise xor a ldh [rNR41], a ; set sound duration @@ -93,8 +85,4 @@ ScrollNintendoOut: cp a, 88 jp nz, .scrollup - ; sound off - xor a - ldh [rNR52], a - ret \ No newline at end of file diff --git a/Code/render.asm b/Code/render.asm index 1c82869..5266f74 100644 --- a/Code/render.asm +++ b/Code/render.asm @@ -115,9 +115,26 @@ LCDStatInterruptHandler: ; return from v-blank or lcd interrupt reti +EXPORT InitRender +SECTION "Init render", ROM0 +InitRender: + ld a, $9C + ldh [Video + 1], a + xor a + ldh [Video], a + ret + EXPORT StartRender SECTION "StartRender", ROM0 -StartRender: +StartRender: + ; set rendered pointer to old buffer + ldh a, [Progress] + ld l, a + ld [Rendered], a + ldh a, [Old] + ld h, a + ld [Rendered + 1], a + ; start rendering ld a, 20 ldh [TilesLeft], a @@ -152,4 +169,19 @@ IF RENDER_IN_HBL != 0 HaltAndClearInterrupts ENDC + ; swap video pointer + ldh a, [Video + 1] + dec a + dec a + xor a, %100 + ldh [Video + 1], a + xor a + ldh [Video], a + + ; swap displayed BG + ldh a, [rLCDC] + xor a, LCDCF_BG9C00 + or a, LCDCF_ON | LCDCF_BGON + ldh [rLCDC], a + ret \ No newline at end of file diff --git a/rom.gb b/rom.gb index 15dcb65..67477bd 100644 Binary files a/rom.gb and b/rom.gb differ diff --git a/todo.txt b/todo.txt index 9b9e9fa..1926b11 100644 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,3 @@ -- skip nintendo intro on gbc/gba - step by step on B button (rewrite main loop to remove second main loop in edit) - music - intro screen