Implemented better game loop and shadow OAM/DMA
This commit is contained in:
parent
d95b9460d3
commit
6e9bfd3feb
8 changed files with 121 additions and 71 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
26
main.asm
26
main.asm
|
@ -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
BIN
main.o
Binary file not shown.
BIN
test.gb
BIN
test.gb
Binary file not shown.
64
test.map
64
test.map
|
@ -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
|
||||||
|
|
44
test.sym
44
test.sym
|
@ -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
|
||||||
|
|
27
tools.asm
27
tools.asm
|
@ -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:
|
||||||
|
|
Loading…
Reference in a new issue