Update to v082r09 release.

byuu says:

Skip this build if you can, it's CPU+PPU timing improvements that should
not visibly affect anything.
This commit is contained in:
Tim Allen
2011-09-15 22:14:07 +10:00
parent c668d10ac7
commit 7f4381b505
7 changed files with 103 additions and 83 deletions

View File

@@ -232,9 +232,9 @@ L rd = op_readpci();
template<void (CPU::*op)()> template<void (CPU::*op)()>
void CPU::opi_read_indirect_zero_page_x() { void CPU::opi_read_indirect_zero_page_x() {
zp = op_readpci(); zp = op_readpci();
op_readpc(); op_readzp(zp);
abs.l = op_readdp(zp++ + regs.x); abs.l = op_readzp(zp++ + regs.x);
abs.h = op_readdp(zp++ + regs.x); abs.h = op_readzp(zp++ + regs.x);
L rd = op_read(abs.w); L rd = op_read(abs.w);
call(op); call(op);
} }
@@ -242,8 +242,8 @@ L rd = op_read(abs.w);
template<void (CPU::*op)()> template<void (CPU::*op)()>
void CPU::opi_read_indirect_zero_page_y() { void CPU::opi_read_indirect_zero_page_y() {
rd = op_readpci(); rd = op_readpci();
abs.l = op_read(rd++); abs.l = op_readzp(rd++);
abs.h = op_read(rd++); abs.h = op_readzp(rd++);
op_page(abs.w, abs.w + regs.y); op_page(abs.w, abs.w + regs.y);
L rd = op_read(abs.w + regs.y); L rd = op_read(abs.w + regs.y);
call(op); call(op);
@@ -252,23 +252,23 @@ L rd = op_read(abs.w + regs.y);
template<void (CPU::*op)()> template<void (CPU::*op)()>
void CPU::opi_read_zero_page() { void CPU::opi_read_zero_page() {
zp = op_readpci(); zp = op_readpci();
L rd = op_read(zp); L rd = op_readzp(zp);
call(op); call(op);
} }
template<void (CPU::*op)()> template<void (CPU::*op)()>
void CPU::opi_read_zero_page_x() { void CPU::opi_read_zero_page_x() {
zp = op_readpci(); zp = op_readpci();
op_readpc(); op_readzp(zp);
L rd = op_readdp(zp + regs.x); L rd = op_readzp(zp + regs.x);
call(op); call(op);
} }
template<void (CPU::*op)()> template<void (CPU::*op)()>
void CPU::opi_read_zero_page_y() { void CPU::opi_read_zero_page_y() {
zp = op_readpci(); zp = op_readpci();
op_readpc(); op_readzp(zp);
L rd = op_readdp(zp + regs.y); L rd = op_readzp(zp + regs.y);
call(op); call(op);
} }
@@ -286,7 +286,7 @@ template<void (CPU::*op)()>
void CPU::opi_rmw_absolute_x() { void CPU::opi_rmw_absolute_x() {
abs.l = op_readpci(); abs.l = op_readpci();
abs.h = op_readpci(); abs.h = op_readpci();
op_readpc(); op_page_always(abs.w, abs.w + regs.x);
rd = op_read(abs.w + regs.x); rd = op_read(abs.w + regs.x);
op_write(abs.w + regs.x, rd); op_write(abs.w + regs.x, rd);
call(op); call(op);
@@ -296,20 +296,20 @@ L op_write(abs.w + regs.x, rd);
template<void (CPU::*op)()> template<void (CPU::*op)()>
void CPU::opi_rmw_zero_page() { void CPU::opi_rmw_zero_page() {
zp = op_readpci(); zp = op_readpci();
rd = op_read(zp); rd = op_readzp(zp);
op_write(zp, rd); op_writezp(zp, rd);
call(op); call(op);
L op_write(zp, rd); L op_writezp(zp, rd);
} }
template<void (CPU::*op)()> template<void (CPU::*op)()>
void CPU::opi_rmw_zero_page_x() { void CPU::opi_rmw_zero_page_x() {
zp = op_readpci(); zp = op_readpci();
op_readpc(); op_readzp(zp);
rd = op_readdp(zp + regs.x); rd = op_readzp(zp + regs.x);
op_writedp(zp + regs.x, rd); op_writezp(zp + regs.x, rd);
call(op); call(op);
L op_writedp(zp + regs.x, rd); L op_writezp(zp + regs.x, rd);
} }
void CPU::opi_set_flag(bool &flag) { void CPU::opi_set_flag(bool &flag) {
@@ -332,48 +332,48 @@ L op_write(abs.w, r);
void CPU::opi_store_absolute_x(uint8 &r) { void CPU::opi_store_absolute_x(uint8 &r) {
abs.l = op_readpci(); abs.l = op_readpci();
abs.h = op_readpci(); abs.h = op_readpci();
op_page(abs.w, abs.w + regs.x); op_page_always(abs.w, abs.w + regs.x);
L op_write(abs.w + regs.x, r); L op_write(abs.w + regs.x, r);
} }
void CPU::opi_store_absolute_y(uint8 &r) { void CPU::opi_store_absolute_y(uint8 &r) {
abs.l = op_readpci(); abs.l = op_readpci();
abs.h = op_readpci(); abs.h = op_readpci();
op_page(abs.w, abs.w + regs.y); op_page_always(abs.w, abs.w + regs.y);
L op_write(abs.w + regs.y, r); L op_write(abs.w + regs.y, r);
} }
void CPU::opi_store_indirect_zero_page_x(uint8 &r) { void CPU::opi_store_indirect_zero_page_x(uint8 &r) {
zp = op_readpci(); zp = op_readpci();
op_readpc(); op_readzp(zp);
abs.l = op_readdp(zp++ + regs.x); abs.l = op_readzp(zp++ + regs.x);
abs.h = op_readdp(zp++ + regs.x); abs.h = op_readzp(zp++ + regs.x);
L op_write(abs.w, r); L op_write(abs.w, r);
} }
void CPU::opi_store_indirect_zero_page_y(uint8 &r) { void CPU::opi_store_indirect_zero_page_y(uint8 &r) {
rd = op_readpci(); rd = op_readpci();
abs.l = op_read(rd++); abs.l = op_readzp(rd++);
abs.h = op_read(rd++); abs.h = op_readzp(rd++);
op_page(abs.w, abs.w + regs.y); op_page_always(abs.w, abs.w + regs.y);
L op_write(abs.w + regs.y, r); L op_write(abs.w + regs.y, r);
} }
void CPU::opi_store_zero_page(uint8 &r) { void CPU::opi_store_zero_page(uint8 &r) {
rd = op_readpci(); zp = op_readpci();
L op_write(rd, r); L op_writezp(zp, r);
} }
void CPU::opi_store_zero_page_x(uint8 &r) { void CPU::opi_store_zero_page_x(uint8 &r) {
zp = op_readpci(); zp = op_readpci();
op_readpc(); op_readzp(zp);
L op_writedp(zp + regs.x, r); L op_writezp(zp + regs.x, r);
} }
void CPU::opi_store_zero_page_y(uint8 &r) { void CPU::opi_store_zero_page_y(uint8 &r) {
zp = op_readpci(); zp = op_readpci();
op_readpc(); op_readzp(zp);
L op_writedp(zp + regs.y, r); L op_writezp(zp + regs.y, r);
} }
void CPU::opi_transfer(uint8 &s, uint8 &d, bool flag) { void CPU::opi_transfer(uint8 &s, uint8 &d, bool flag) {
@@ -492,11 +492,11 @@ L op_readpc();
void CPU::opill_nop_zero_page() { void CPU::opill_nop_zero_page() {
zp = op_readpci(); zp = op_readpci();
L op_readpc(); L op_readzp(zp);
} }
void CPU::opill_nop_zero_page_x() { void CPU::opill_nop_zero_page_x() {
zp = op_readpci(); zp = op_readpci();
op_readpc(); op_readzp(zp);
L op_readpc(); L op_readzp(zp + regs.x);
} }

View File

@@ -23,7 +23,7 @@ uint8 CPU::op_readsp() {
return op_read(0x0100 | ++regs.s); return op_read(0x0100 | ++regs.s);
} }
uint8 CPU::op_readdp(uint8 addr) { uint8 CPU::op_readzp(uint8 addr) {
return op_read(addr); return op_read(addr);
} }
@@ -33,12 +33,16 @@ void CPU::op_writesp(uint8 data) {
op_write(0x0100 | regs.s--, data); op_write(0x0100 | regs.s--, data);
} }
void CPU::op_writedp(uint8 addr, uint8 data) { void CPU::op_writezp(uint8 addr, uint8 data) {
op_write(addr, data); op_write(addr, data);
} }
// //
void CPU::op_page(uint16 x, uint16 y) { void CPU::op_page(uint16 x, uint16 y) {
if((x & 0xff00) != (y & 0xff00)) op_readpc(); if((x & 0xff00) != (y & 0xff00)) op_read((x & 0xff00) | (y & 0x00ff));
}
void CPU::op_page_always(uint16 x, uint16 y) {
op_read((x & 0xff00) | (y & 0x00ff));
} }

View File

@@ -4,9 +4,10 @@ void op_write(uint16 addr, uint8 data);
uint8 op_readpc(); uint8 op_readpc();
uint8 op_readpci(); uint8 op_readpci();
uint8 op_readsp(); uint8 op_readsp();
uint8 op_readdp(uint8 addr); uint8 op_readzp(uint8 addr);
void op_writesp(uint8 data); void op_writesp(uint8 data);
void op_writedp(uint8 addr, uint8 data); void op_writezp(uint8 addr, uint8 data);
void op_page(uint16 x, uint16 y); void op_page(uint16 x, uint16 y);
void op_page_always(uint16 x, uint16 y);

View File

@@ -4,7 +4,7 @@
namespace NES { namespace NES {
namespace Info { namespace Info {
static const char Name[] = "bnes"; static const char Name[] = "bnes";
static const char Version[] = "000.04"; static const char Version[] = "000.05";
} }
} }

View File

@@ -278,6 +278,48 @@ void PPU::scrolly_increment() {
// //
void PPU::raster_pixel(unsigned x) {
uint32 *output = buffer + status.ly * 256;
unsigned mask = 0x8000 >> (status.xaddr + x);
unsigned palette = 0;
palette |= (raster.tiledatalo & mask) ? 1 : 0;
palette |= (raster.tiledatahi & mask) ? 2 : 0;
if(palette) {
unsigned attr = raster.attribute;
if(mask >= 256) attr >>= 2;
palette |= (attr & 3) << 2;
}
if(status.bg_edge_enable == false && status.lx < 8) palette = 0;
for(unsigned sprite = 0; sprite < 8; sprite++) {
if(status.sprite_edge_enable == false && status.lx < 8) continue;
if(raster.oam[sprite].id == 64) continue;
unsigned spritex = status.lx - raster.oam[sprite].x;
if(spritex >= 8) continue;
if(raster.oam[sprite].attr & 0x40) spritex ^= 7;
unsigned mask = 0x80 >> spritex;
unsigned sprite_palette = 0;
sprite_palette |= (raster.oam[sprite].tiledatalo & mask) ? 1 : 0;
sprite_palette |= (raster.oam[sprite].tiledatahi & mask) ? 2 : 0;
if(sprite_palette == 0) continue;
if(raster.oam[sprite].id == 0 && palette) status.sprite_zero_hit = 1;
sprite_palette |= (raster.oam[sprite].attr & 3) << 2;
if((raster.oam[sprite].attr & 0x20) == 0 || palette == 0) {
palette = 16 + sprite_palette;
break;
}
}
if(raster_enable() == false) palette = 0;
output[status.lx++] = paletteRGB[cgram[palette]];
}
void PPU::raster_scanline() { void PPU::raster_scanline() {
if((status.ly >= 240 && status.ly <= 260)) { if((status.ly >= 240 && status.ly <= 260)) {
for(unsigned x = 0; x < 340; x++) tick(); for(unsigned x = 0; x < 340; x++) tick();
@@ -287,71 +329,42 @@ void PPU::raster_scanline() {
uint32 *output = buffer + status.ly * 256; uint32 *output = buffer + status.ly * 256;
signed lx = 0, ly = (status.ly == 261 ? -1 : status.ly); signed lx = 0, ly = (status.ly == 261 ? -1 : status.ly);
status.lx = 0;
for(unsigned tile = 0; tile < 32; tile++) { // 0-255 for(unsigned tile = 0; tile < 32; tile++) { // 0-255
unsigned mask = 0x8000 >> status.xaddr;
for(unsigned n = 0; n < 8; n++) {
uint8 palette = 0;
palette |= (raster.tiledatalo & mask) ? 1 : 0;
palette |= (raster.tiledatahi & mask) ? 2 : 0;
if(palette) {
unsigned attr = raster.attribute;
if(mask >= 256) attr >>= 2;
palette |= (attr & 3) << 2;
}
mask >>= 1;
if(status.bg_edge_enable == false && lx < 8) palette = 0;
for(unsigned sprite = 0; sprite < 8; sprite++) {
if(status.sprite_edge_enable == false && lx < 8) continue;
if(raster.oam[sprite].id == 64) continue;
unsigned spritex = lx - raster.oam[sprite].x;
if(spritex >= 8) continue;
if(raster.oam[sprite].attr & 0x40) spritex ^= 7;
unsigned mask = 0x80 >> spritex;
unsigned sprite_palette = 0;
sprite_palette |= (raster.oam[sprite].tiledatalo & mask) ? 1 : 0;
sprite_palette |= (raster.oam[sprite].tiledatahi & mask) ? 2 : 0;
if(sprite_palette == 0) continue;
if(raster.oam[sprite].id == 0) status.sprite_zero_hit = 1;
sprite_palette |= (raster.oam[sprite].attr & 3) << 2;
if((raster.oam[sprite].attr & 0x20) == 0 || palette == 0) {
palette = 16 + sprite_palette;
break;
}
}
if(raster_enable() == false) palette = 0;
output[lx++] = paletteRGB[cgram[palette]];
}
unsigned nametable = cartridge.ciram_read((uint13)status.vaddr); unsigned nametable = cartridge.ciram_read((uint13)status.vaddr);
unsigned tileaddr = status.bg_addr + (nametable << 4) + (scrolly() & 7); unsigned tileaddr = status.bg_addr + (nametable << 4) + (scrolly() & 7);
raster_pixel(0);
tick(); tick();
raster_pixel(1);
tick(); tick();
unsigned attribute = cartridge.ciram_read(0x03c0 | (status.vaddr & 0x0fc0) | ((scrolly() >> 5) << 3) | (scrollx() >> 5)); unsigned attribute = cartridge.ciram_read(0x03c0 | (status.vaddr & 0x0fc0) | ((scrolly() >> 5) << 3) | (scrollx() >> 5));
if(scrolly() & 16) attribute >>= 4; if(scrolly() & 16) attribute >>= 4;
if(scrollx() & 16) attribute >>= 2; if(scrollx() & 16) attribute >>= 2;
raster_pixel(2);
tick(); tick();
if(raster_enable()) { if(raster_enable()) {
scrollx_increment(); scrollx_increment();
if(tile == 31) scrolly_increment(); if(tile == 31) scrolly_increment();
} }
raster_pixel(3);
tick(); tick();
unsigned tiledatalo = cartridge.chr_read(tileaddr + 0); unsigned tiledatalo = cartridge.chr_read(tileaddr + 0);
raster_pixel(4);
tick(); tick();
raster_pixel(5);
tick(); tick();
unsigned tiledatahi = cartridge.chr_read(tileaddr + 8); unsigned tiledatahi = cartridge.chr_read(tileaddr + 8);
raster_pixel(6);
tick(); tick();
raster_pixel(7);
tick(); tick();
raster.nametable = (raster.nametable << 8) | nametable; raster.nametable = (raster.nametable << 8) | nametable;

View File

@@ -27,12 +27,14 @@ struct PPU : Processor {
void scrollx_increment(); void scrollx_increment();
void scrolly_increment(); void scrolly_increment();
void raster_pixel(unsigned x);
void raster_scanline(); void raster_scanline();
struct Status { struct Status {
uint8 mdr; uint8 mdr;
bool field; bool field;
unsigned lx;
unsigned ly; unsigned ly;
uint8 bus_data; uint8 bus_data;

View File

@@ -4,7 +4,7 @@
namespace SNES { namespace SNES {
namespace Info { namespace Info {
static const char Name[] = "bsnes"; static const char Name[] = "bsnes";
static const char Version[] = "082.08"; static const char Version[] = "082.09";
static const unsigned SerializerVersion = 21; static const unsigned SerializerVersion = 21;
} }
} }