o switch to v46
This commit is contained in:
@@ -1,45 +1,46 @@
|
||||
#include <../base.hpp>
|
||||
|
||||
#define BPPU_CPP
|
||||
namespace SNES {
|
||||
|
||||
#include "bppu_mmio.cpp"
|
||||
#include "bppu_render.cpp"
|
||||
|
||||
void bPPU::enter() {
|
||||
loop:
|
||||
//H = 0 (initialize)
|
||||
scanline();
|
||||
if(ivcounter() == 0) frame();
|
||||
add_clocks(10);
|
||||
while(true) {
|
||||
//H = 0 (initialize)
|
||||
scanline();
|
||||
if(ivcounter() == 0) frame();
|
||||
add_clocks(10);
|
||||
|
||||
//H = 10 (OAM address reset)
|
||||
if(ivcounter() == (!overscan() ? 225 : 240)) {
|
||||
if(regs.display_disabled == false) {
|
||||
regs.oam_addr = regs.oam_baseaddr << 1;
|
||||
regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127;
|
||||
//H = 10 (OAM address reset)
|
||||
if(ivcounter() == (!overscan() ? 225 : 240)) {
|
||||
if(regs.display_disabled == false) {
|
||||
regs.oam_addr = regs.oam_baseaddr << 1;
|
||||
regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127;
|
||||
}
|
||||
}
|
||||
add_clocks(502);
|
||||
|
||||
//H = 512 (render)
|
||||
render_scanline();
|
||||
add_clocks(640);
|
||||
|
||||
//H = 1152 (cache OBSEL)
|
||||
cache.oam_basesize = regs.oam_basesize;
|
||||
cache.oam_nameselect = regs.oam_nameselect;
|
||||
cache.oam_tdaddr = regs.oam_tdaddr;
|
||||
add_clocks(ilineclocks() - 1152); //seek to start of next scanline
|
||||
}
|
||||
add_clocks(502);
|
||||
|
||||
//H = 512 (render)
|
||||
render_scanline();
|
||||
add_clocks(640);
|
||||
|
||||
//H = 1152 (cache OBSEL)
|
||||
cache.oam_basesize = regs.oam_basesize;
|
||||
cache.oam_nameselect = regs.oam_nameselect;
|
||||
cache.oam_tdaddr = regs.oam_tdaddr;
|
||||
add_clocks(ilineclocks() - 1152); //seek to start of next scanline
|
||||
|
||||
goto loop;
|
||||
}
|
||||
|
||||
void bPPU::add_clocks(unsigned clocks) {
|
||||
void bPPU::add_clocks(unsigned clocks) {
|
||||
tock(clocks);
|
||||
scheduler.addclocks_ppu(clocks);
|
||||
scheduler.sync_ppucpu();
|
||||
}
|
||||
|
||||
void bPPU::scanline() {
|
||||
snes.scanline();
|
||||
line = ivcounter();
|
||||
|
||||
if(line == 0) {
|
||||
@@ -76,7 +77,7 @@ void bPPU::render_scanline() {
|
||||
|
||||
void bPPU::frame() {
|
||||
PPU::frame();
|
||||
snes.frame();
|
||||
system.frame();
|
||||
|
||||
if(ifield() == 0) {
|
||||
display.interlace = regs.interlace;
|
||||
@@ -92,7 +93,7 @@ void bPPU::power() {
|
||||
for(unsigned i = 0; i < memory::cgram.size(); i++) memory::cgram[i] = 0x00;
|
||||
flush_tiledata_cache();
|
||||
|
||||
region = (snes.region() == SNES::NTSC ? 0 : 1); //0 = NTSC, 1 = PAL
|
||||
region = (system.region() == System::NTSC ? 0 : 1); //0 = NTSC, 1 = PAL
|
||||
|
||||
//$2100
|
||||
regs.display_disabled = 1;
|
||||
@@ -344,3 +345,5 @@ bPPU::bPPU() {
|
||||
bPPU::~bPPU() {
|
||||
free_tiledata_cache();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ uint8 bPPU::vram_mmio_read(uint16 addr) {
|
||||
} else {
|
||||
uint16 v = vcounter();
|
||||
uint16 h = hcounter();
|
||||
uint16 ls = ((snes.region() == SNES::NTSC ? 525 : 625) >> 1) - 1;
|
||||
uint16 ls = ((system.region() == System::NTSC ? 525 : 625) >> 1) - 1;
|
||||
if(interlace() && !field()) ls++;
|
||||
|
||||
if(v == ls && h == 1362) {
|
||||
@@ -333,17 +333,17 @@ void bPPU::mmio_w2115(uint8 value) {
|
||||
regs.vram_incmode = !!(value & 0x80);
|
||||
regs.vram_mapping = (value >> 2) & 3;
|
||||
switch(value & 3) {
|
||||
case 0: regs.vram_incsize = 1; break;
|
||||
case 1: regs.vram_incsize = 32; break;
|
||||
case 2: regs.vram_incsize = 128; break;
|
||||
case 3: regs.vram_incsize = 128; break;
|
||||
case 0: regs.vram_incsize = 1; break;
|
||||
case 1: regs.vram_incsize = 32; break;
|
||||
case 2: regs.vram_incsize = 128; break;
|
||||
case 3: regs.vram_incsize = 128; break;
|
||||
}
|
||||
}
|
||||
|
||||
//VMADDL
|
||||
void bPPU::mmio_w2116(uint8 value) {
|
||||
regs.vram_addr = (regs.vram_addr & 0xff00) | value;
|
||||
uint16 addr = get_vram_address();
|
||||
uint16 addr = get_vram_address();
|
||||
regs.vram_readbuffer = vram_mmio_read(addr + 0);
|
||||
regs.vram_readbuffer |= vram_mmio_read(addr + 1) << 8;
|
||||
}
|
||||
@@ -351,7 +351,7 @@ uint16 addr = get_vram_address();
|
||||
//VMADDH
|
||||
void bPPU::mmio_w2117(uint8 value) {
|
||||
regs.vram_addr = (value << 8) | (regs.vram_addr & 0x00ff);
|
||||
uint16 addr = get_vram_address();
|
||||
uint16 addr = get_vram_address();
|
||||
regs.vram_readbuffer = vram_mmio_read(addr + 0);
|
||||
regs.vram_readbuffer |= vram_mmio_read(addr + 1) << 8;
|
||||
}
|
||||
@@ -759,21 +759,20 @@ uint8 bPPU::mmio_read(unsigned addr) {
|
||||
case 0x2128:
|
||||
case 0x2129:
|
||||
case 0x212a: return regs.ppu1_mdr;
|
||||
case 0x2134: return mmio_r2134(); //MPYL
|
||||
case 0x2135: return mmio_r2135(); //MPYM
|
||||
case 0x2136: return mmio_r2136(); //MPYH
|
||||
case 0x2137: return mmio_r2137(); //SLHV
|
||||
case 0x2138: return mmio_r2138(); //OAMDATAREAD
|
||||
case 0x2139: return mmio_r2139(); //VMDATALREAD
|
||||
case 0x213a: return mmio_r213a(); //VMDATAHREAD
|
||||
case 0x213b: return mmio_r213b(); //CGDATAREAD
|
||||
case 0x213c: return mmio_r213c(); //OPHCT
|
||||
case 0x213d: return mmio_r213d(); //OPVCT
|
||||
case 0x213e: return mmio_r213e(); //STAT77
|
||||
case 0x213f: return mmio_r213f(); //STAT78
|
||||
case 0x2134: return mmio_r2134(); //MPYL
|
||||
case 0x2135: return mmio_r2135(); //MPYM
|
||||
case 0x2136: return mmio_r2136(); //MPYH
|
||||
case 0x2137: return mmio_r2137(); //SLHV
|
||||
case 0x2138: return mmio_r2138(); //OAMDATAREAD
|
||||
case 0x2139: return mmio_r2139(); //VMDATALREAD
|
||||
case 0x213a: return mmio_r213a(); //VMDATAHREAD
|
||||
case 0x213b: return mmio_r213b(); //CGDATAREAD
|
||||
case 0x213c: return mmio_r213c(); //OPHCT
|
||||
case 0x213d: return mmio_r213d(); //OPVCT
|
||||
case 0x213e: return mmio_r213e(); //STAT77
|
||||
case 0x213f: return mmio_r213f(); //STAT78
|
||||
}
|
||||
|
||||
//return 0x00;
|
||||
return cpu.regs.mdr;
|
||||
}
|
||||
|
||||
@@ -781,59 +780,60 @@ void bPPU::mmio_write(unsigned addr, uint8 data) {
|
||||
scheduler.sync_cpuppu();
|
||||
|
||||
switch(addr & 0xffff) {
|
||||
case 0x2100: mmio_w2100(data); return; //INIDISP
|
||||
case 0x2101: mmio_w2101(data); return; //OBSEL
|
||||
case 0x2102: mmio_w2102(data); return; //OAMADDL
|
||||
case 0x2103: mmio_w2103(data); return; //OAMADDH
|
||||
case 0x2104: mmio_w2104(data); return; //OAMDATA
|
||||
case 0x2105: mmio_w2105(data); return; //BGMODE
|
||||
case 0x2106: mmio_w2106(data); return; //MOSAIC
|
||||
case 0x2107: mmio_w2107(data); return; //BG1SC
|
||||
case 0x2108: mmio_w2108(data); return; //BG2SC
|
||||
case 0x2109: mmio_w2109(data); return; //BG3SC
|
||||
case 0x210a: mmio_w210a(data); return; //BG4SC
|
||||
case 0x210b: mmio_w210b(data); return; //BG12NBA
|
||||
case 0x210c: mmio_w210c(data); return; //BG34NBA
|
||||
case 0x210d: mmio_w210d(data); return; //BG1HOFS
|
||||
case 0x210e: mmio_w210e(data); return; //BG1VOFS
|
||||
case 0x210f: mmio_w210f(data); return; //BG2HOFS
|
||||
case 0x2110: mmio_w2110(data); return; //BG2VOFS
|
||||
case 0x2111: mmio_w2111(data); return; //BG3HOFS
|
||||
case 0x2112: mmio_w2112(data); return; //BG3VOFS
|
||||
case 0x2113: mmio_w2113(data); return; //BG4HOFS
|
||||
case 0x2114: mmio_w2114(data); return; //BG4VOFS
|
||||
case 0x2115: mmio_w2115(data); return; //VMAIN
|
||||
case 0x2116: mmio_w2116(data); return; //VMADDL
|
||||
case 0x2117: mmio_w2117(data); return; //VMADDH
|
||||
case 0x2118: mmio_w2118(data); return; //VMDATAL
|
||||
case 0x2119: mmio_w2119(data); return; //VMDATAH
|
||||
case 0x211a: mmio_w211a(data); return; //M7SEL
|
||||
case 0x211b: mmio_w211b(data); return; //M7A
|
||||
case 0x211c: mmio_w211c(data); return; //M7B
|
||||
case 0x211d: mmio_w211d(data); return; //M7C
|
||||
case 0x211e: mmio_w211e(data); return; //M7D
|
||||
case 0x211f: mmio_w211f(data); return; //M7X
|
||||
case 0x2120: mmio_w2120(data); return; //M7Y
|
||||
case 0x2121: mmio_w2121(data); return; //CGADD
|
||||
case 0x2122: mmio_w2122(data); return; //CGDATA
|
||||
case 0x2123: mmio_w2123(data); return; //W12SEL
|
||||
case 0x2124: mmio_w2124(data); return; //W34SEL
|
||||
case 0x2125: mmio_w2125(data); return; //WOBJSEL
|
||||
case 0x2126: mmio_w2126(data); return; //WH0
|
||||
case 0x2127: mmio_w2127(data); return; //WH1
|
||||
case 0x2128: mmio_w2128(data); return; //WH2
|
||||
case 0x2129: mmio_w2129(data); return; //WH3
|
||||
case 0x212a: mmio_w212a(data); return; //WBGLOG
|
||||
case 0x212b: mmio_w212b(data); return; //WOBJLOG
|
||||
case 0x212c: mmio_w212c(data); return; //TM
|
||||
case 0x212d: mmio_w212d(data); return; //TS
|
||||
case 0x212e: mmio_w212e(data); return; //TMW
|
||||
case 0x212f: mmio_w212f(data); return; //TSW
|
||||
case 0x2130: mmio_w2130(data); return; //CGWSEL
|
||||
case 0x2131: mmio_w2131(data); return; //CGADDSUB
|
||||
case 0x2132: mmio_w2132(data); return; //COLDATA
|
||||
case 0x2133: mmio_w2133(data); return; //SETINI
|
||||
case 0x2100: return mmio_w2100(data); //INIDISP
|
||||
case 0x2101: return mmio_w2101(data); //OBSEL
|
||||
case 0x2102: return mmio_w2102(data); //OAMADDL
|
||||
case 0x2103: return mmio_w2103(data); //OAMADDH
|
||||
case 0x2104: return mmio_w2104(data); //OAMDATA
|
||||
case 0x2105: return mmio_w2105(data); //BGMODE
|
||||
case 0x2106: return mmio_w2106(data); //MOSAIC
|
||||
case 0x2107: return mmio_w2107(data); //BG1SC
|
||||
case 0x2108: return mmio_w2108(data); //BG2SC
|
||||
case 0x2109: return mmio_w2109(data); //BG3SC
|
||||
case 0x210a: return mmio_w210a(data); //BG4SC
|
||||
case 0x210b: return mmio_w210b(data); //BG12NBA
|
||||
case 0x210c: return mmio_w210c(data); //BG34NBA
|
||||
case 0x210d: return mmio_w210d(data); //BG1HOFS
|
||||
case 0x210e: return mmio_w210e(data); //BG1VOFS
|
||||
case 0x210f: return mmio_w210f(data); //BG2HOFS
|
||||
case 0x2110: return mmio_w2110(data); //BG2VOFS
|
||||
case 0x2111: return mmio_w2111(data); //BG3HOFS
|
||||
case 0x2112: return mmio_w2112(data); //BG3VOFS
|
||||
case 0x2113: return mmio_w2113(data); //BG4HOFS
|
||||
case 0x2114: return mmio_w2114(data); //BG4VOFS
|
||||
case 0x2115: return mmio_w2115(data); //VMAIN
|
||||
case 0x2116: return mmio_w2116(data); //VMADDL
|
||||
case 0x2117: return mmio_w2117(data); //VMADDH
|
||||
case 0x2118: return mmio_w2118(data); //VMDATAL
|
||||
case 0x2119: return mmio_w2119(data); //VMDATAH
|
||||
case 0x211a: return mmio_w211a(data); //M7SEL
|
||||
case 0x211b: return mmio_w211b(data); //M7A
|
||||
case 0x211c: return mmio_w211c(data); //M7B
|
||||
case 0x211d: return mmio_w211d(data); //M7C
|
||||
case 0x211e: return mmio_w211e(data); //M7D
|
||||
case 0x211f: return mmio_w211f(data); //M7X
|
||||
case 0x2120: return mmio_w2120(data); //M7Y
|
||||
case 0x2121: return mmio_w2121(data); //CGADD
|
||||
case 0x2122: return mmio_w2122(data); //CGDATA
|
||||
case 0x2123: return mmio_w2123(data); //W12SEL
|
||||
case 0x2124: return mmio_w2124(data); //W34SEL
|
||||
case 0x2125: return mmio_w2125(data); //WOBJSEL
|
||||
case 0x2126: return mmio_w2126(data); //WH0
|
||||
case 0x2127: return mmio_w2127(data); //WH1
|
||||
case 0x2128: return mmio_w2128(data); //WH2
|
||||
case 0x2129: return mmio_w2129(data); //WH3
|
||||
case 0x212a: return mmio_w212a(data); //WBGLOG
|
||||
case 0x212b: return mmio_w212b(data); //WOBJLOG
|
||||
case 0x212c: return mmio_w212c(data); //TM
|
||||
case 0x212d: return mmio_w212d(data); //TS
|
||||
case 0x212e: return mmio_w212e(data); //TMW
|
||||
case 0x212f: return mmio_w212f(data); //TSW
|
||||
case 0x2130: return mmio_w2130(data); //CGWSEL
|
||||
case 0x2131: return mmio_w2131(data); //CGADDSUB
|
||||
case 0x2132: return mmio_w2132(data); //COLDATA
|
||||
case 0x2133: return mmio_w2133(data); //SETINI
|
||||
}
|
||||
}
|
||||
|
||||
#endif //ifdef BPPU_CPP
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifdef BPPU_CPP
|
||||
|
||||
void bPPU::build_sprite_list() {
|
||||
uint8 *tableA = memory::oam.handle();
|
||||
uint8 *tableB = memory::oam.handle() + 512;
|
||||
uint8 *tableA = memory::oam.data();
|
||||
uint8 *tableB = memory::oam.data() + 512;
|
||||
|
||||
for(unsigned i = 0; i < 128; i++) {
|
||||
unsigned x = !!(*tableB & (1 << ((i & 3) << 1))); //0x01, 0x04, 0x10, 0x40
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifdef PPU_CPP
|
||||
|
||||
//wrappers to allow PPUcounter::tick()/tock() to be inlined
|
||||
bool PPUcounter::region() const { return snes.region() == SNES::NTSC ? 0 : 1; }
|
||||
bool PPUcounter::region() const { return system.region() == System::NTSC ? 0 : 1; }
|
||||
bool PPUcounter::interlace() const { return ppu.interlace(); }
|
||||
void PPUcounter::scanline() { cpu.scanline(); }
|
||||
|
||||
@@ -15,20 +15,20 @@ void PPUcounter::scanline() { cpu.scanline(); }
|
||||
//dot 327 range = { 1310, 1312, 1314 }
|
||||
|
||||
uint16 PPUcounter::hdot() const {
|
||||
if(region() == 0 && interlace() == false && status.vcounter == 240 && status.field == 1) {
|
||||
return (status.hcounter >> 2);
|
||||
if(region() == 0 && interlace() == false && vcounter() == 240 && field() == 1) {
|
||||
return (hcounter() >> 2);
|
||||
} else {
|
||||
return (status.hcounter - ((status.hcounter > 1292) << 1) - ((status.hcounter > 1310) << 1)) >> 2;
|
||||
return (hcounter() - ((hcounter() > 1292) << 1) - ((hcounter() > 1310) << 1)) >> 2;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 PPUcounter::lineclocks() const {
|
||||
if(region() == 0 && interlace() == false && vcounter() == 240 && status.field == 1) return 1360;
|
||||
if(region() == 0 && interlace() == false && vcounter() == 240 && field() == 1) return 1360;
|
||||
return 1364;
|
||||
}
|
||||
|
||||
uint16 PPUcounter::ilineclocks() const {
|
||||
if(region() == 0 && interlace() == false && ivcounter() == 240 && status.field == 1) return 1360;
|
||||
if(region() == 0 && interlace() == false && ivcounter() == 240 && ifield() == 1) return 1360;
|
||||
return 1364;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
class PPUcounter {
|
||||
public:
|
||||
alwaysinline void tick() {
|
||||
history.ppudiff += 2;
|
||||
status.hcounter += 2;
|
||||
|
||||
if(status.hcounter >= 1360 && status.hcounter == lineclocks()) {
|
||||
status.hcounter = 0;
|
||||
status.vcounter++;
|
||||
@@ -17,7 +15,6 @@ public:
|
||||
status.vcounter = 0;
|
||||
status.field = !status.field;
|
||||
}
|
||||
|
||||
scanline();
|
||||
}
|
||||
|
||||
@@ -25,6 +22,7 @@ public:
|
||||
history.field [history.index] = status.field;
|
||||
history.vcounter[history.index] = status.vcounter;
|
||||
history.hcounter[history.index] = status.hcounter;
|
||||
history.ppudiff += 2;
|
||||
}
|
||||
|
||||
alwaysinline void tock(unsigned clocks) {
|
||||
@@ -67,7 +65,7 @@ private:
|
||||
uint16 vcounter[2048];
|
||||
uint16 hcounter[2048];
|
||||
|
||||
unsigned index;
|
||||
signed ppudiff;
|
||||
int32 index;
|
||||
int32 ppudiff;
|
||||
} history;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <../base.hpp>
|
||||
#define PPU_CPP
|
||||
|
||||
#define PPU_CPP
|
||||
namespace SNES {
|
||||
|
||||
#include "counter.cpp"
|
||||
|
||||
@@ -25,8 +27,8 @@ void PPU::frame() {
|
||||
}
|
||||
|
||||
void PPU::power() {
|
||||
ppu1_version = snes.config.ppu1.version;
|
||||
ppu2_version = snes.config.ppu2.version;
|
||||
ppu1_version = config.ppu1.version;
|
||||
ppu2_version = config.ppu2.version;
|
||||
}
|
||||
|
||||
void PPU::reset() {
|
||||
@@ -45,3 +47,5 @@ PPU::PPU() {
|
||||
PPU::~PPU() {
|
||||
delete[] output;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user