mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-08-11 23:04:40 +02: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:
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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));
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user