Implemented better game loop and shadow OAM/DMA

This commit is contained in:
Jonatan Nilsson 2019-06-21 12:55:47 +00:00
parent d95b9460d3
commit 6e9bfd3feb
8 changed files with 121 additions and 71 deletions

View file

@ -1,23 +1,39 @@
INCLUDE "game/text.asm" INCLUDE "game/text.asm"
INCLUDE "game/controller.asm" INCLUDE "game/controller.asm"
; Shadow OAM, allows us to have a shadow copy of all sprites for
; editing whenever we want
SECTION "ram_shadowoam", WRAM0,ALIGN[8]
shadow_oam:
ds 160
shadow_oam_inuse:
ds 1
SECTION "Game Loop", ROM0 SECTION "Game Loop", ROM0
GameLoop: GameLoop:
ld de, HelloWorldStr ld de, FirstCutScene
call StartText call StartText
.mainloop .mainloop ; Our main game loop
; Start our game loop call UpdateController ; Update our controller
call UpdateController
call DrawActiveText ; Reset our oam sprites in use
xor a
ld [shadow_oam_inuse], a
; Call sprite handlers
; Call other handlers
call WaitVBlank call WaitVBlank
call DrawActiveText
call RunDMA
jr .mainloop jr .mainloop
Section "Hello wrold string", ROM0 Section "Hello wrold string", ROM0
HelloWorldStr: FirstCutScene:
; [ ] ; [ ]
db "...wake up...\n" db "...wake up...\n"
db "please wake up...#" db "please wake up...", "#"
db "...we don't have\n" db "...we don't have\n"
db "time, wake up...", 0 db "time, wake up...", 0

View file

@ -114,7 +114,6 @@ StartText:
ret ret
; Draw text if one is currently active ; Draw text if one is currently active
; @return a - 0 if not active, 1 if active
DrawActiveText: DrawActiveText:
ld a, [textwriter_active] ; Check if text is currently active ld a, [textwriter_active] ; Check if text is currently active
and a and a

View file

@ -64,26 +64,20 @@ Start:
ld a, SCRN_Y ld a, SCRN_Y
ld [rWY], a ld [rWY], a
; Reset OAM memory with zeros
ld hl, _OAMRAM ; Set position of OAM Ram to hl
ld a, 0 ; Fill that memory space with zero
ld b, $FEA0 - _OAMRAM ; Get the full size of the fill
call Memfill
; Reset WRAM memory with zeros
ld hl, _RAM ; Set position of OAM Ram to hl
ld a, $01 ; Fill that memory space with zero
ld bc, $E000 - _RAM ; Get the full size of the fill
call Memfill16
ld hl, _RAM ; Set position of OAM Ram to hl
ld a, $00 ; Fill that memory space with zero
ld bc, $E000 - _RAM ; Get the full size of the fill
call Memfill16
; Initialize other stuff ; Initialize other stuff
call InitTools
call InitController call InitController
call InitWindow call InitWindow
; Reset OAM memory with zeros
; First reset our shadow OAM
ld hl, shadow_oam ; Set position of OAM Ram to hl
ld a, 0 ; Fill that memory space with zero
ld b, shadow_oam_inuse - shadow_oam ; Get the full size of the fill
call Memfill
; Then call our OAM guy
call RunDMA
; Turn the screen on, display background ; Turn the screen on, display background
ld a, LCDCF_ON|LCDCF_BGON|LCDCF_WINON|LCDCF_WIN9C00 ld a, LCDCF_ON|LCDCF_BGON|LCDCF_WINON|LCDCF_WIN9C00
ld [rLCDC], a ; Set the screen flags ld [rLCDC], a ; Set the screen flags

BIN
main.o

Binary file not shown.

BIN
test.gb

Binary file not shown.

View file

@ -21,45 +21,51 @@ ROM Bank #0 (HOME):
$0029 = UpdateController.onenibble $0029 = UpdateController.onenibble
$0009 = UpdateController $0009 = UpdateController
$0000 = InitController $0000 = InitController
SECTION: $0166-$0176 ($0011 bytes) ["Game Loop"] SECTION: $017D-$0194 ($0018 bytes) ["Game Loop"]
$016C = GameLoop.mainloop $0183 = GameLoop.mainloop
$0166 = GameLoop $017D = GameLoop
SECTION: $00BB-$00FC ($0042 bytes) ["Hello wrold string"] SECTION: $00AB-$00EC ($0042 bytes) ["Hello wrold string"]
$00BB = HelloWorldStr $00AB = FirstCutScene
SECTION: $0150-$0165 ($0016 bytes) ["Tools"] SECTION: $0150-$017C ($002D bytes) ["Tools"]
$0159 = Memfill $0166 = Memfill
$0163 = WaitVBlank $0170 = WaitVBlank
$0150 = Memcpy $0173 = dma_routine_start
$0159 = Memfill.repeatFill $017D = dma_routine_end
$015E = Memfill16.repeatFill $015D = Memcpy
$015E = Memfill16 $0166 = Memfill.repeatFill
$016B = Memfill16.repeatFill
$0179 = dma_routine_start.loop
$0150 = InitTools
SECTION: $0040-$0040 ($0001 bytes) ["InterruptVblank"] SECTION: $0040-$0040 ($0001 bytes) ["InterruptVblank"]
SECTION: $0048-$0048 ($0001 bytes) ["InterruptLCDC"] SECTION: $0048-$0048 ($0001 bytes) ["InterruptLCDC"]
SECTION: $0050-$0050 ($0001 bytes) ["InterruptTimer_Overflow"] SECTION: $0050-$0050 ($0001 bytes) ["InterruptTimer_Overflow"]
SECTION: $0058-$0058 ($0001 bytes) ["InterruptSerial"] SECTION: $0058-$0058 ($0001 bytes) ["InterruptSerial"]
SECTION: $0060-$0060 ($0001 bytes) ["Interruptp1thru4"] SECTION: $0060-$0060 ($0001 bytes) ["Interruptp1thru4"]
SECTION: $0100-$014F ($0050 bytes) ["Header"] SECTION: $0100-$014F ($0050 bytes) ["Header"]
SECTION: $0061-$00BA ($005A bytes) ["Intro code"] SECTION: $0061-$00AA ($004A bytes) ["Intro code"]
$0061 = Start $0061 = Start
SECTION: $0280-$127F ($1000 bytes) ["Font"] SECTION: $0280-$127F ($1000 bytes) ["Font"]
$0280 = Page1 $0280 = Page1
$1280 = Page1End $1280 = Page1End
SLACK: $2CC3 bytes SLACK: $2CB5 bytes
WRAM Bank #0: WRAM Bank #0:
SECTION: $C000-$C008 ($0009 bytes) ["ram_textwriter"] SECTION: $C0A1-$C0A9 ($0009 bytes) ["ram_textwriter"]
$C002 = textwriter_posx $C0A3 = textwriter_posx
$C003 = textwriter_posy $C0A4 = textwriter_posy
$C007 = textwriter_ending $C0A8 = textwriter_ending
$C008 = textwriter_pausing $C0A9 = textwriter_pausing
$C005 = textwriter_active $C0A6 = textwriter_active
$C004 = textwriter_curdelay $C0A5 = textwriter_curdelay
$C006 = textwriter_starting $C0A7 = textwriter_starting
$C000 = textwriter_curtext $C0A1 = textwriter_curtext
SECTION: $C009-$C00A ($0002 bytes) ["ram_controller"] SECTION: $C0AA-$C0AB ($0002 bytes) ["ram_controller"]
$C00A = controller_newkeys $C0AB = controller_newkeys
$C009 = controller_curkeys $C0AA = controller_curkeys
SLACK: $0FF5 bytes SECTION: $C000-$C0A0 ($00A1 bytes) ["ram_shadowoam"]
$C0A0 = shadow_oam_inuse
$C000 = shadow_oam
SLACK: $0F54 bytes
WRAM Bank #1: WRAM Bank #1:
EMPTY EMPTY
@ -92,7 +98,9 @@ OAM:
EMPTY EMPTY
HRAM: HRAM:
EMPTY SECTION: $FF80-$FF8A ($000B bytes) ["hram_tools"]
$FF80 = RunDMA
SLACK: $0074 bytes
SRAM Bank #0: SRAM Bank #0:
EMPTY EMPTY

View file

@ -19,25 +19,31 @@
00:0029 UpdateController.onenibble 00:0029 UpdateController.onenibble
00:0009 UpdateController 00:0009 UpdateController
00:0000 InitController 00:0000 InitController
00:016C GameLoop.mainloop 00:0183 GameLoop.mainloop
00:0166 GameLoop 00:017D GameLoop
00:00BB HelloWorldStr 00:00AB FirstCutScene
00:0159 Memfill 00:0166 Memfill
00:0163 WaitVBlank 00:0170 WaitVBlank
00:0150 Memcpy 00:0173 dma_routine_start
00:0159 Memfill.repeatFill 00:017D dma_routine_end
00:015E Memfill16.repeatFill 00:015D Memcpy
00:015E Memfill16 00:0166 Memfill.repeatFill
00:016B Memfill16.repeatFill
00:0179 dma_routine_start.loop
00:0150 InitTools
00:0061 Start 00:0061 Start
00:0280 Page1 00:0280 Page1
00:1280 Page1End 00:1280 Page1End
00:C002 textwriter_posx 00:C0A3 textwriter_posx
00:C003 textwriter_posy 00:C0A4 textwriter_posy
00:C007 textwriter_ending 00:C0A8 textwriter_ending
00:C008 textwriter_pausing 00:C0A9 textwriter_pausing
00:C005 textwriter_active 00:C0A6 textwriter_active
00:C004 textwriter_curdelay 00:C0A5 textwriter_curdelay
00:C006 textwriter_starting 00:C0A7 textwriter_starting
00:C000 textwriter_curtext 00:C0A1 textwriter_curtext
00:C00A controller_newkeys 00:C0AB controller_newkeys
00:C009 controller_curkeys 00:C0AA controller_curkeys
00:C0A0 shadow_oam_inuse
00:C000 shadow_oam
00:FF80 RunDMA

View file

@ -1,5 +1,20 @@
; Like the NES and Super NES, DMA on the Game Boy takes access to RAM
; and ROM away from the CPU. But unlike those two, the CPU continues
; to run. So store a tiny subroutine in HRAM (tightly coupled
; memory) to keep the CPU busy until OAM DMA is done.
SECTION "hram_tools", HRAM
RunDMA: ds 11
SECTION "Tools", ROM0 SECTION "Tools", ROM0
InitTools:
; Copy the sprite DMA routine
ld de, dma_routine_start
ld hl, RunDMA
ld bc, dma_routine_end - dma_routine_start
call Memcpy
ret
; Memory copier ; Memory copier
; @param de - Address source to start of data to be copied ; @param de - Address source to start of data to be copied
; @param hl - Address destomatopm where to copy the data to ; @param hl - Address destomatopm where to copy the data to
@ -60,3 +75,15 @@ WaitVBlank:
.wait .wait
halt halt
ret ret
;;
; The routine gets copied to high RAM
dma_routine_start:
ld a,shadow_oam >> 8
ld [rDMA],a
ld a,40
.loop:
dec a
jr nz,.loop
ret
dma_routine_end: