Implemented better game loop and shadow OAM/DMA

master
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/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
GameLoop:
ld de, HelloWorldStr
ld de, FirstCutScene
call StartText
.mainloop
; Start our game loop
call UpdateController
call DrawActiveText
.mainloop ; Our main game loop
call UpdateController ; Update our controller
; Reset our oam sprites in use
xor a
ld [shadow_oam_inuse], a
; Call sprite handlers
; Call other handlers
call WaitVBlank
call DrawActiveText
call RunDMA
jr .mainloop
Section "Hello wrold string", ROM0
HelloWorldStr:
FirstCutScene:
; [ ]
db "...wake up...\n"
db "please wake up...#"
db "please wake up...", "#"
db "...we don't have\n"
db "time, wake up...", 0

View File

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

View File

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

View File

@ -19,25 +19,31 @@
00:0029 UpdateController.onenibble
00:0009 UpdateController
00:0000 InitController
00:016C GameLoop.mainloop
00:0166 GameLoop
00:00BB HelloWorldStr
00:0159 Memfill
00:0163 WaitVBlank
00:0150 Memcpy
00:0159 Memfill.repeatFill
00:015E Memfill16.repeatFill
00:015E Memfill16
00:0183 GameLoop.mainloop
00:017D GameLoop
00:00AB FirstCutScene
00:0166 Memfill
00:0170 WaitVBlank
00:0173 dma_routine_start
00:017D dma_routine_end
00:015D Memcpy
00:0166 Memfill.repeatFill
00:016B Memfill16.repeatFill
00:0179 dma_routine_start.loop
00:0150 InitTools
00:0061 Start
00:0280 Page1
00:1280 Page1End
00:C002 textwriter_posx
00:C003 textwriter_posy
00:C007 textwriter_ending
00:C008 textwriter_pausing
00:C005 textwriter_active
00:C004 textwriter_curdelay
00:C006 textwriter_starting
00:C000 textwriter_curtext
00:C00A controller_newkeys
00:C009 controller_curkeys
00:C0A3 textwriter_posx
00:C0A4 textwriter_posy
00:C0A8 textwriter_ending
00:C0A9 textwriter_pausing
00:C0A6 textwriter_active
00:C0A5 textwriter_curdelay
00:C0A7 textwriter_starting
00:C0A1 textwriter_curtext
00:C0AB controller_newkeys
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
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
; @param de - Address source to start of data to be copied
; @param hl - Address destomatopm where to copy the data to
@ -60,3 +75,15 @@ WaitVBlank:
.wait
halt
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: