mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-01-18 05:08:55 +01:00
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:
parent
c668d10ac7
commit
7f4381b505
@ -232,9 +232,9 @@ L rd = op_readpci();
|
||||
template<void (CPU::*op)()>
|
||||
void CPU::opi_read_indirect_zero_page_x() {
|
||||
zp = op_readpci();
|
||||
op_readpc();
|
||||
abs.l = op_readdp(zp++ + regs.x);
|
||||
abs.h = op_readdp(zp++ + regs.x);
|
||||
op_readzp(zp);
|
||||
abs.l = op_readzp(zp++ + regs.x);
|
||||
abs.h = op_readzp(zp++ + regs.x);
|
||||
L rd = op_read(abs.w);
|
||||
call(op);
|
||||
}
|
||||
@ -242,8 +242,8 @@ L rd = op_read(abs.w);
|
||||
template<void (CPU::*op)()>
|
||||
void CPU::opi_read_indirect_zero_page_y() {
|
||||
rd = op_readpci();
|
||||
abs.l = op_read(rd++);
|
||||
abs.h = op_read(rd++);
|
||||
abs.l = op_readzp(rd++);
|
||||
abs.h = op_readzp(rd++);
|
||||
op_page(abs.w, abs.w + regs.y);
|
||||
L rd = op_read(abs.w + regs.y);
|
||||
call(op);
|
||||
@ -252,23 +252,23 @@ L rd = op_read(abs.w + regs.y);
|
||||
template<void (CPU::*op)()>
|
||||
void CPU::opi_read_zero_page() {
|
||||
zp = op_readpci();
|
||||
L rd = op_read(zp);
|
||||
L rd = op_readzp(zp);
|
||||
call(op);
|
||||
}
|
||||
|
||||
template<void (CPU::*op)()>
|
||||
void CPU::opi_read_zero_page_x() {
|
||||
zp = op_readpci();
|
||||
op_readpc();
|
||||
L rd = op_readdp(zp + regs.x);
|
||||
op_readzp(zp);
|
||||
L rd = op_readzp(zp + regs.x);
|
||||
call(op);
|
||||
}
|
||||
|
||||
template<void (CPU::*op)()>
|
||||
void CPU::opi_read_zero_page_y() {
|
||||
zp = op_readpci();
|
||||
op_readpc();
|
||||
L rd = op_readdp(zp + regs.y);
|
||||
op_readzp(zp);
|
||||
L rd = op_readzp(zp + regs.y);
|
||||
call(op);
|
||||
}
|
||||
|
||||
@ -286,7 +286,7 @@ template<void (CPU::*op)()>
|
||||
void CPU::opi_rmw_absolute_x() {
|
||||
abs.l = op_readpci();
|
||||
abs.h = op_readpci();
|
||||
op_readpc();
|
||||
op_page_always(abs.w, abs.w + regs.x);
|
||||
rd = op_read(abs.w + regs.x);
|
||||
op_write(abs.w + regs.x, rd);
|
||||
call(op);
|
||||
@ -296,20 +296,20 @@ L op_write(abs.w + regs.x, rd);
|
||||
template<void (CPU::*op)()>
|
||||
void CPU::opi_rmw_zero_page() {
|
||||
zp = op_readpci();
|
||||
rd = op_read(zp);
|
||||
op_write(zp, rd);
|
||||
rd = op_readzp(zp);
|
||||
op_writezp(zp, rd);
|
||||
call(op);
|
||||
L op_write(zp, rd);
|
||||
L op_writezp(zp, rd);
|
||||
}
|
||||
|
||||
template<void (CPU::*op)()>
|
||||
void CPU::opi_rmw_zero_page_x() {
|
||||
zp = op_readpci();
|
||||
op_readpc();
|
||||
rd = op_readdp(zp + regs.x);
|
||||
op_writedp(zp + regs.x, rd);
|
||||
op_readzp(zp);
|
||||
rd = op_readzp(zp + regs.x);
|
||||
op_writezp(zp + regs.x, rd);
|
||||
call(op);
|
||||
L op_writedp(zp + regs.x, rd);
|
||||
L op_writezp(zp + regs.x, rd);
|
||||
}
|
||||
|
||||
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) {
|
||||
abs.l = 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);
|
||||
}
|
||||
|
||||
void CPU::opi_store_absolute_y(uint8 &r) {
|
||||
abs.l = 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);
|
||||
}
|
||||
|
||||
void CPU::opi_store_indirect_zero_page_x(uint8 &r) {
|
||||
zp = op_readpci();
|
||||
op_readpc();
|
||||
abs.l = op_readdp(zp++ + regs.x);
|
||||
abs.h = op_readdp(zp++ + regs.x);
|
||||
op_readzp(zp);
|
||||
abs.l = op_readzp(zp++ + regs.x);
|
||||
abs.h = op_readzp(zp++ + regs.x);
|
||||
L op_write(abs.w, r);
|
||||
}
|
||||
|
||||
void CPU::opi_store_indirect_zero_page_y(uint8 &r) {
|
||||
rd = op_readpci();
|
||||
abs.l = op_read(rd++);
|
||||
abs.h = op_read(rd++);
|
||||
op_page(abs.w, abs.w + regs.y);
|
||||
abs.l = op_readzp(rd++);
|
||||
abs.h = op_readzp(rd++);
|
||||
op_page_always(abs.w, abs.w + regs.y);
|
||||
L op_write(abs.w + regs.y, r);
|
||||
}
|
||||
|
||||
void CPU::opi_store_zero_page(uint8 &r) {
|
||||
rd = op_readpci();
|
||||
L op_write(rd, r);
|
||||
zp = op_readpci();
|
||||
L op_writezp(zp, r);
|
||||
}
|
||||
|
||||
void CPU::opi_store_zero_page_x(uint8 &r) {
|
||||
zp = op_readpci();
|
||||
op_readpc();
|
||||
L op_writedp(zp + regs.x, r);
|
||||
op_readzp(zp);
|
||||
L op_writezp(zp + regs.x, r);
|
||||
}
|
||||
|
||||
void CPU::opi_store_zero_page_y(uint8 &r) {
|
||||
zp = op_readpci();
|
||||
op_readpc();
|
||||
L op_writedp(zp + regs.y, r);
|
||||
op_readzp(zp);
|
||||
L op_writezp(zp + regs.y, r);
|
||||
}
|
||||
|
||||
void CPU::opi_transfer(uint8 &s, uint8 &d, bool flag) {
|
||||
@ -492,11 +492,11 @@ L op_readpc();
|
||||
|
||||
void CPU::opill_nop_zero_page() {
|
||||
zp = op_readpci();
|
||||
L op_readpc();
|
||||
L op_readzp(zp);
|
||||
}
|
||||
|
||||
void CPU::opill_nop_zero_page_x() {
|
||||
zp = op_readpci();
|
||||
op_readpc();
|
||||
L op_readpc();
|
||||
op_readzp(zp);
|
||||
L op_readzp(zp + regs.x);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ uint8 CPU::op_readsp() {
|
||||
return op_read(0x0100 | ++regs.s);
|
||||
}
|
||||
|
||||
uint8 CPU::op_readdp(uint8 addr) {
|
||||
uint8 CPU::op_readzp(uint8 addr) {
|
||||
return op_read(addr);
|
||||
}
|
||||
|
||||
@ -33,12 +33,16 @@ void CPU::op_writesp(uint8 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);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
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));
|
||||
}
|
||||
|
@ -4,9 +4,10 @@ void op_write(uint16 addr, uint8 data);
|
||||
uint8 op_readpc();
|
||||
uint8 op_readpci();
|
||||
uint8 op_readsp();
|
||||
uint8 op_readdp(uint8 addr);
|
||||
uint8 op_readzp(uint8 addr);
|
||||
|
||||
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_always(uint16 x, uint16 y);
|
||||
|
@ -4,7 +4,7 @@
|
||||
namespace NES {
|
||||
namespace Info {
|
||||
static const char Name[] = "bnes";
|
||||
static const char Version[] = "000.04";
|
||||
static const char Version[] = "000.05";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
if((status.ly >= 240 && status.ly <= 260)) {
|
||||
for(unsigned x = 0; x < 340; x++) tick();
|
||||
@ -287,71 +329,42 @@ void PPU::raster_scanline() {
|
||||
|
||||
uint32 *output = buffer + status.ly * 256;
|
||||
signed lx = 0, ly = (status.ly == 261 ? -1 : status.ly);
|
||||
status.lx = 0;
|
||||
|
||||
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 tileaddr = status.bg_addr + (nametable << 4) + (scrolly() & 7);
|
||||
raster_pixel(0);
|
||||
tick();
|
||||
|
||||
raster_pixel(1);
|
||||
tick();
|
||||
|
||||
unsigned attribute = cartridge.ciram_read(0x03c0 | (status.vaddr & 0x0fc0) | ((scrolly() >> 5) << 3) | (scrollx() >> 5));
|
||||
if(scrolly() & 16) attribute >>= 4;
|
||||
if(scrollx() & 16) attribute >>= 2;
|
||||
raster_pixel(2);
|
||||
tick();
|
||||
|
||||
if(raster_enable()) {
|
||||
scrollx_increment();
|
||||
if(tile == 31) scrolly_increment();
|
||||
}
|
||||
raster_pixel(3);
|
||||
tick();
|
||||
|
||||
unsigned tiledatalo = cartridge.chr_read(tileaddr + 0);
|
||||
raster_pixel(4);
|
||||
tick();
|
||||
|
||||
raster_pixel(5);
|
||||
tick();
|
||||
|
||||
unsigned tiledatahi = cartridge.chr_read(tileaddr + 8);
|
||||
raster_pixel(6);
|
||||
tick();
|
||||
|
||||
raster_pixel(7);
|
||||
tick();
|
||||
|
||||
raster.nametable = (raster.nametable << 8) | nametable;
|
||||
|
@ -27,12 +27,14 @@ struct PPU : Processor {
|
||||
void scrollx_increment();
|
||||
void scrolly_increment();
|
||||
|
||||
void raster_pixel(unsigned x);
|
||||
void raster_scanline();
|
||||
|
||||
struct Status {
|
||||
uint8 mdr;
|
||||
|
||||
bool field;
|
||||
unsigned lx;
|
||||
unsigned ly;
|
||||
|
||||
uint8 bus_data;
|
||||
|
@ -4,7 +4,7 @@
|
||||
namespace SNES {
|
||||
namespace Info {
|
||||
static const char Name[] = "bsnes";
|
||||
static const char Version[] = "082.08";
|
||||
static const char Version[] = "082.09";
|
||||
static const unsigned SerializerVersion = 21;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user