split totaltorender into linesleft and tilesleft, makes rendering code simpler and faster
This commit is contained in:
207
Code/main.asm
207
Code/main.asm
@@ -74,16 +74,18 @@ Start:
|
|||||||
ldh [Rendered], a
|
ldh [Rendered], a
|
||||||
ldh [Video], a
|
ldh [Video], a
|
||||||
|
|
||||||
; set total to render to 0 so that interrupts don't start rendering
|
; set lines and tiles left to 0 to avoid rendering in interrupts
|
||||||
ldh [TotalToRender], a
|
ldh [LinesLeft], a
|
||||||
ldh [TotalToRender + 1], a
|
ldh [TilesLeft], a
|
||||||
|
|
||||||
; enable v-blank interrupt
|
; enable v-blank interrupt
|
||||||
ld a, IEF_VBLANK
|
ld a, IEF_VBLANK
|
||||||
ld [rIE], a
|
ld [rIE], a
|
||||||
|
|
||||||
; enable interrupts
|
; enable interrupts while clearing interrupt flags
|
||||||
|
xor a
|
||||||
ei
|
ei
|
||||||
|
ldh [rIF], a
|
||||||
|
|
||||||
; wait for v-blank
|
; wait for v-blank
|
||||||
halt
|
halt
|
||||||
@@ -129,26 +131,28 @@ Start:
|
|||||||
call MemoryCopy
|
call MemoryCopy
|
||||||
|
|
||||||
; set total to render to start rendering
|
; set total to render to start rendering
|
||||||
ld a, LOW(20 * 18)
|
ld a, 18
|
||||||
ldh [TotalToRender], a
|
ldh [LinesLeft], a
|
||||||
ld a, HIGH(20 * 18)
|
ld a, 20
|
||||||
ldh [TotalToRender + 1], a
|
ldh [TilesLeft], a
|
||||||
|
|
||||||
|
; enable h-blank interrupt in lcd stat
|
||||||
|
ld a, STATF_MODE00
|
||||||
|
ld [rSTAT], a
|
||||||
|
|
||||||
; enable screen but don't display anything yet
|
; enable screen but don't display anything yet
|
||||||
ld a, LCDCF_ON
|
ld a, LCDCF_ON
|
||||||
ld [rLCDC], a
|
ld [rLCDC], a
|
||||||
|
|
||||||
; enable h-blank interrupt in lcd stat
|
|
||||||
ld a, STATF_MODE00
|
|
||||||
ld [rSTAT], a
|
|
||||||
|
|
||||||
.mainloop
|
.mainloop
|
||||||
|
|
||||||
; enable v-blank and lcd stat interrupt for h-blank
|
; enable v-blank and lcd stat interrupt for h-blank
|
||||||
di
|
di
|
||||||
ld a, IEF_VBLANK; | IEF_LCDC
|
ld a, IEF_VBLANK | IEF_LCDC
|
||||||
ld [rIE], a
|
ld [rIE], a
|
||||||
|
xor a
|
||||||
ei
|
ei
|
||||||
|
ldh [rIF], a
|
||||||
|
|
||||||
.topleft
|
.topleft
|
||||||
; handle top left corner
|
; handle top left corner
|
||||||
@@ -288,28 +292,30 @@ Start:
|
|||||||
inc [hl]
|
inc [hl]
|
||||||
|
|
||||||
; wait end of rendering
|
; wait end of rendering
|
||||||
.waitRenderHigh
|
.waitLines
|
||||||
; check high byte of TotalToRender
|
; check high byte of TotalToRender
|
||||||
ldh a, [TotalToRender + 1]
|
ldh a, [LinesLeft]
|
||||||
or a
|
or a
|
||||||
jr z, .waitRenderLow
|
jr z, .waitTiles
|
||||||
halt
|
halt
|
||||||
jr .waitRenderHigh
|
jr .waitLines
|
||||||
|
|
||||||
.waitRenderLow
|
.waitTiles
|
||||||
; check low byte of TotalToRender
|
; check low byte of TotalToRender
|
||||||
ldh a, [TotalToRender]
|
ldh a, [TilesLeft]
|
||||||
or a
|
or a
|
||||||
jr z, .swap
|
jr z, .swap
|
||||||
halt
|
halt
|
||||||
jr .waitRenderLow
|
jr .waitTiles
|
||||||
|
|
||||||
.swap
|
.swap
|
||||||
; enable only v-blank interrupt
|
; enable only v-blank interrupt
|
||||||
di
|
di
|
||||||
ld a, IEF_VBLANK
|
ld a, IEF_VBLANK
|
||||||
ld [rIE], a
|
ld [rIE], a
|
||||||
|
xor a
|
||||||
ei
|
ei
|
||||||
|
ldh [rIF], a
|
||||||
|
|
||||||
; wait v-blank
|
; wait v-blank
|
||||||
halt
|
halt
|
||||||
@@ -365,11 +371,11 @@ Start:
|
|||||||
ldh [Rendered], a
|
ldh [Rendered], a
|
||||||
ldh [Video], a
|
ldh [Video], a
|
||||||
|
|
||||||
; set total to render to start rendering
|
; set total to render to restart rendering
|
||||||
ld a, LOW(20 * 18)
|
ld a, 20
|
||||||
ldh [TotalToRender], a
|
ldh [TilesLeft], a
|
||||||
ld a, HIGH(20 * 18)
|
ld a, 18
|
||||||
ldh [TotalToRender + 1], a
|
ldh [LinesLeft], a
|
||||||
|
|
||||||
jp .mainloop
|
jp .mainloop
|
||||||
|
|
||||||
@@ -555,89 +561,72 @@ Conway:
|
|||||||
|
|
||||||
SECTION "V-Blank Interrupt Handler", ROM0[$40]
|
SECTION "V-Blank Interrupt Handler", ROM0[$40]
|
||||||
VBlankInterruptHandler:
|
VBlankInterruptHandler:
|
||||||
; save a
|
; save registers
|
||||||
push af
|
push af
|
||||||
|
push de
|
||||||
; set max number of cells to render
|
push bc
|
||||||
ld a, 64
|
push hl
|
||||||
ldh [MaxRender], a
|
|
||||||
|
|
||||||
; render
|
; render
|
||||||
jp Render
|
jp Render
|
||||||
|
|
||||||
SECTION "LCD Stat Interrupt Handler", ROM0[$48]
|
SECTION "LCD Stat Interrupt Handler", ROM0[$48]
|
||||||
LCDStatInterruptHandler:
|
LCDStatInterruptHandler:
|
||||||
; save a
|
; save registers
|
||||||
push af
|
push af
|
||||||
|
push de
|
||||||
; set max number of cells to render
|
push bc
|
||||||
ld a, 1
|
push hl
|
||||||
ldh [MaxRender], a
|
|
||||||
|
|
||||||
; render
|
; render
|
||||||
jp Render
|
jp Render
|
||||||
|
|
||||||
SECTION "Render", ROM0
|
SECTION "Render", ROM0
|
||||||
Render:
|
Render:
|
||||||
; save registers
|
; check there are lines to render
|
||||||
push de
|
ldh a, [LinesLeft]
|
||||||
push bc
|
|
||||||
push hl
|
|
||||||
|
|
||||||
; load counter into b
|
|
||||||
ldh a, [MaxRender]
|
|
||||||
ld b, a
|
|
||||||
|
|
||||||
; check there is more than 255 bytes to render left
|
|
||||||
ldh a, [TotalToRender + 1]
|
|
||||||
and a
|
|
||||||
jr nz, .render
|
|
||||||
|
|
||||||
; check there is anything at all to render
|
|
||||||
ldh a, [TotalToRender]
|
|
||||||
and a
|
and a
|
||||||
jr z, .exit
|
jr z, .exit
|
||||||
|
|
||||||
; check we're not trying to render more than what's left to render
|
; check there are tiles to render
|
||||||
cp a, b
|
ldh a, [TilesLeft]
|
||||||
jr nc, .render
|
and a
|
||||||
|
jr z, .exit
|
||||||
; render only what's left to
|
|
||||||
ld b, a
|
.render
|
||||||
|
|
||||||
.render
|
|
||||||
; save render count so that we can decrement total later
|
|
||||||
push bc
|
|
||||||
|
|
||||||
; load buffer pointer into DE
|
; load buffer pointer into DE
|
||||||
ld hl, Rendered
|
ld hl, Rendered
|
||||||
ld a, [hl+]
|
ld a, [hl+]
|
||||||
ld d, [hl]
|
ld d, [hl]
|
||||||
ld e, a
|
ld e, a
|
||||||
|
|
||||||
; load video pointer into HL
|
; load video pointer into HL
|
||||||
ld hl, Video
|
ld hl, Video
|
||||||
ld a, [hl+]
|
ld a, [hl+]
|
||||||
ld h, [hl]
|
ld h, [hl]
|
||||||
ld l, a
|
ld l, a
|
||||||
|
|
||||||
; set c to number of tiles before next line
|
; set c to point to tiles left to render
|
||||||
ld a, l
|
.nextline
|
||||||
and a, $E0
|
ld c, LOW(TilesLeft)
|
||||||
add a, 20
|
|
||||||
sub a, l
|
|
||||||
ld c, a
|
|
||||||
|
|
||||||
.loop
|
.loop
|
||||||
|
; check we can still render
|
||||||
|
ldh a, [rSTAT]
|
||||||
|
and a, STATF_BUSY
|
||||||
|
jr nz, .finish
|
||||||
|
|
||||||
; copy one byte
|
; copy one byte
|
||||||
ld a, [de]
|
ld a, [de]
|
||||||
ld [hl+], a
|
ld [hl+], a
|
||||||
inc de
|
inc de
|
||||||
|
|
||||||
; check if we need to go to next line
|
; loop while there are tiles to render
|
||||||
dec c
|
ld a, [$FF00+c]
|
||||||
jr nz , .countdown
|
dec a
|
||||||
|
ld [$FF00+c], a
|
||||||
|
jr nz, .loop
|
||||||
|
|
||||||
; go to next line
|
; go to next line
|
||||||
push de
|
push de
|
||||||
ld de, 32 - 20
|
ld de, 32 - 20
|
||||||
@@ -645,45 +634,39 @@ Render:
|
|||||||
pop de
|
pop de
|
||||||
ld c, 20
|
ld c, 20
|
||||||
|
|
||||||
; loop over if not finished
|
; loop while there are lines to render
|
||||||
.countdown
|
ld c, LOW(LinesLeft)
|
||||||
dec b
|
ld a, [$FF00+c]
|
||||||
jr nz, .loop
|
dec a
|
||||||
|
ld [$FF00+c], a
|
||||||
|
jr z, .finish
|
||||||
|
|
||||||
|
ld a, 20
|
||||||
|
ldh [TilesLeft], a
|
||||||
|
|
||||||
|
jr .nextline
|
||||||
|
|
||||||
; save incremented video and buffer pointers
|
; save incremented video and buffer pointers
|
||||||
|
.finish
|
||||||
ld a, l
|
ld a, l
|
||||||
ldh [Video], a
|
ldh [Video], a
|
||||||
ld a, h
|
ld a, h
|
||||||
ldh [Video + 1], a
|
ldh [Video + 1], a
|
||||||
|
|
||||||
ld a, e
|
ld a, e
|
||||||
ldh [Rendered], a
|
ldh [Rendered], a
|
||||||
ld a, d
|
ld a, d
|
||||||
ldh [Rendered + 1], a
|
ldh [Rendered + 1], a
|
||||||
|
|
||||||
; restore max render
|
|
||||||
pop bc
|
|
||||||
|
|
||||||
; decrement total to render
|
|
||||||
ldh a, [TotalToRender]
|
|
||||||
sub a, b
|
|
||||||
ldh [TotalToRender], a
|
|
||||||
jr nc, .exit
|
|
||||||
ld hl, TotalToRender + 1
|
|
||||||
dec [hl]
|
|
||||||
|
|
||||||
.exit
|
.exit
|
||||||
; restore registers
|
; restore registers saved in interrupt handler
|
||||||
pop hl
|
pop hl
|
||||||
pop bc
|
pop bc
|
||||||
pop de
|
pop de
|
||||||
|
|
||||||
; restore A saved in interrupt handler
|
|
||||||
pop af
|
pop af
|
||||||
|
|
||||||
; return from v-blank or lcd interrupt
|
; return from v-blank or lcd interrupt
|
||||||
reti
|
reti
|
||||||
|
|
||||||
|
|
||||||
; automata buffers with 4 cells per byte
|
; automata buffers with 4 cells per byte
|
||||||
; 2x2 bytes per cell, bit ordering:
|
; 2x2 bytes per cell, bit ordering:
|
||||||
@@ -707,8 +690,8 @@ Cells: ds 9
|
|||||||
Result: ds 1
|
Result: ds 1
|
||||||
|
|
||||||
SECTION "Render Memory", HRAM
|
SECTION "Render Memory", HRAM
|
||||||
MaxRender: ds 1 ; max number of tiles to render before leaving
|
LinesLeft: ds 1 ; number of lines left to render
|
||||||
TotalToRender: ds 2 ; total number of tiles to render left
|
TilesLeft: ds 1 ; number of tiles left to render in current line
|
||||||
Video: ds 2 ; pointer to tilemap
|
Video: ds 2 ; pointer to tilemap
|
||||||
Rendered: ds 2 ; pointer to bufferX
|
Rendered: ds 2 ; pointer to bufferX
|
||||||
|
|
||||||
@@ -754,22 +737,22 @@ BitsSet:
|
|||||||
SECTION "Default Map", ROM0
|
SECTION "Default Map", ROM0
|
||||||
DefaultMap:
|
DefaultMap:
|
||||||
; 20x18 map with a glider on the top left corner
|
; 20x18 map with a glider on the top left corner
|
||||||
db 1, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
db 9,12, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
db 0, 1, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
db 0, 9,12, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
db 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
db 0, 0, 3, 1, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
db 0, 5, 0,10,10, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
db 0, 1,12, 6, 2,12, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
db 0, 0,12, 4, 0,12, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
db 0, 5, 0,10,10, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
db 0, 1, 0, 2, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
db 0, 0, 3, 1, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user