Skip to content

Commit

Permalink
somewhat faster (1 scanline) update, ensures correct order, but requi…
Browse files Browse the repository at this point in the history
…res a manual flush (not yet implemented) if buffer isn't full
  • Loading branch information
hcs64 committed Jun 21, 2011
1 parent 9f5b6ae commit f2dc849
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 77 deletions.
52 changes: 35 additions & 17 deletions test/test.as
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ shared tile_stage_s tile_stage[8]

#ram.org 0x300, 1024 // HACK: just made up a large number for now
byte next_stage_index
byte cur_stage_index
byte tile_stage_written // 0: nmi needs to write to ppu, nonzero: main thread is writing
byte red_start_x
byte red_start_y
byte red_start_dir
Expand Down Expand Up @@ -116,7 +116,7 @@ interrupt.nmi int_nmi()

// 341/3 cycles per line + change (8 cycles)
lda #0x20 // 2
ldy #8+(8*12) // 2
ldy #9+(8*12) // 2
waitloop:
ldx #20 // 2 * lines
do {
Expand Down Expand Up @@ -210,28 +210,37 @@ function some_tests()
pha

find_free_tile_stage()
pha
init_tile_stage_red(Tile_ArrowRight)
pla
tax
pla
pha
ldy #1
pos_to_nametable()
finalize_tile_stage_XY()
finalize_tile_stage()

find_free_tile_stage()
pha
init_tile_stage_red(Tile_ArrowLeft)
pla
tax
pla
pha
ldy #2
pos_to_nametable()
finalize_tile_stage_XY()
finalize_tile_stage()

find_free_tile_stage()
pha
init_tile_stage_red(Tile_ArrowRight)
pla
tax
pla
pha
ldy #3
pos_to_nametable()
finalize_tile_stage_XY()
finalize_tile_stage()

pla
tay
Expand All @@ -252,31 +261,40 @@ function some_tests()
pha

find_free_tile_stage()
pha
init_tile_stage_red(Tile_ArrowUp)
pla
tax
pla
pha
tay
lda #4
lda #5
pos_to_nametable()
finalize_tile_stage_XY()
finalize_tile_stage()

find_free_tile_stage()
pha
init_tile_stage_red(Tile_ArrowDown)
pla
tax
pla
pha
tay
lda #5
lda #6
pos_to_nametable()
finalize_tile_stage_XY()
finalize_tile_stage()

find_free_tile_stage()
pha
init_tile_stage_red(Tile_ArrowUp)
pla
tax
pla
pha
tay
lda #6
lda #7
pos_to_nametable()
finalize_tile_stage_XY()
finalize_tile_stage()

pla
tay
Expand Down Expand Up @@ -459,8 +477,7 @@ function init_ingame_unique_names()
ppu_ctl0_clear(CR_ADDRINC32)
}

// In: A = x, Y = y
// Out: X = low byte, Y = high byte
// In: A = x, Y = y, X = tile stage address offset
function pos_to_nametable()
{
asl A
Expand All @@ -474,15 +491,15 @@ function pos_to_nametable()
cpy #8
if (plus)
{
ldx #0x1
ldy #0x1
sec
sbc #8
}
else
{
ldx #0
ldy #0
}
stx tmp_byte
sty tmp_byte

asl A
rol tmp_byte
Expand All @@ -493,8 +510,9 @@ function pos_to_nametable()
asl A
rol tmp_byte

tax
sta tile_stage_addr, X
ldy tmp_byte
sty tile_stage_addr+1, X
}

/******************************************************************************/
Expand Down
117 changes: 57 additions & 60 deletions test/tiles.as
Original file line number Diff line number Diff line change
Expand Up @@ -2,63 +2,54 @@
function init_tile_stage()
{
ldx #sizeof(tile_stage_addr)-2
lda #0x80
do {
sta tile_stage_addr+1, X
dex
dex
} while (not minus)
// start with full buffer
stx next_stage_index
// nmi doesn't need to do anything yet (nonzero)
stx tile_stage_written
}

function find_free_tile_stage()
{
ldx #sizeof(tile_stage_addr)

find_free_tile_loop:
dex // each entry is a word
dex
bmi find_free_tile_stage
ldx next_stage_index

if (minus) {
// next index is negative, need to wait for nmi to process buffer
do {
ldx tile_stage_written
} while (zero)

ldx #sizeof(tile_stage_addr)-2
}

lda tile_stage_addr+1, X // high byte has high bit set for empty
txa
tay // save free entry's address offset

bpl find_free_tile_loop
// decrement for next time
dex
dex
stx next_stage_index

stx cur_stage_index
tax

inx // move to next index
inx

// X is the free entry's index, convert to staging buffer offset
// X is the free entry's address offset, convert to staging buffer offset
txa
asl A
asl A
asl A
tax
dex // move back to penultimate byte
tya
}

inline write_1_tile_stage(index)
{
// 126 cycles
ldx tile_stage_addr[index] // 3
lda tile_stage_addr[index]+1 // 3

// burn off the three excess cycles accumulated by skipping
bpl compensate_staged_1 // 3, 2
compensate_staged_1:
bpl compensate_staged_2 // 3, 2
compensate_staged_2:
bpl compensate_staged_3 // 3, 2
compensate_staged_3:

bpl do_staged_tile // 3, 2

// tile 1, throwaway
lda #hi(PATTERN_TABLE_0_ADDRESS+16) // 0, 2
ldx #lo(PATTERN_TABLE_0_ADDRESS+16) // 0, 2

do_staged_tile:


sta PPU.ADDRESS // 4
stx PPU.ADDRESS // 4

Expand Down Expand Up @@ -95,24 +86,40 @@ do_staged_tile:
sta PPU.IO
lda tile_stage[index].tile_buf_1[0]
sta PPU.IO

// mark this free again
lda #0x80 // 2
sta tile_stage_addr[index]+1 // 3
}

function write_tile_stages()
{
ppu_clean_latch()

write_1_tile_stage(0)
write_1_tile_stage(1)
write_1_tile_stage(2)
write_1_tile_stage(3)
write_1_tile_stage(4)
write_1_tile_stage(5)
write_1_tile_stage(6)
lda tile_stage_written
beq do_write_tile_stages
// 2 + 2 + 202*2 + 201*3 + 2 + 3 = 1016 cycles

lda #202 // 2
tax // 2

do {
dex // 2*202
} while (not zero) // 3*201 + 2

jmp skip_tile_stages// 3

do_write_tile_stages:
// 3 + 126*8 + 2 + 3 = 1016 cycles
write_1_tile_stage(7)
write_1_tile_stage(6)
write_1_tile_stage(5)
write_1_tile_stage(4)
write_1_tile_stage(3)
write_1_tile_stage(2)
write_1_tile_stage(1)
write_1_tile_stage(0)

lda #1 // 2
sta tile_stage_written // 3

skip_tile_stages:

vram_clear_address()
}
Expand All @@ -139,23 +146,13 @@ inline init_tile_stage_red(tile_addr)
tax
}

inline finalize_tile_stage(vram_addr)
function finalize_tile_stage()
{
ldx cur_stage_index
lda #lo(vram_addr)
sta tile_stage_addr, X
lda #hi(vram_addr)
sta tile_stage_addr+1, X // storing the hi makes it count
}

inline finalize_tile_stage_XY()
{
txa

ldx cur_stage_index

sta tile_stage_addr, X
sty tile_stage_addr+1, X // storing the hi makes it count
lda next_stage_index
if (minus) {
ldx #0
stx tile_stage_written // nmi needs to write
}
}

/******************************************************************************/
Expand Down

0 comments on commit f2dc849

Please sign in to comment.