mirror of https://github.com/bsnes-emu/bsnes.git
Update to v099r02 release.
byuu says: Changelog: - renamed sfc/ppu/sprite (OAM oam;) to sfc/ppu/object (Object obj;) [hex_usr] - renamed sfc/ppu's memory {vram, oam, cgram} to just vram, oam, cgram - fixed addr&=~1 regression [hex_usr] - fixed 8bpp tiledata regression [hex_usr]
This commit is contained in:
parent
ae5b4c3bb3
commit
f1a80075fa
|
@ -9,7 +9,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "099.01";
|
||||
static const string Version = "099.02";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "http://byuu.org/";
|
||||
|
|
|
@ -121,7 +121,7 @@ auto PPU::Background::getTile() -> void {
|
|||
if(ty & 0x20) offset += screenY;
|
||||
|
||||
uint16 address = r.screenAddress + (offset << 1);
|
||||
tile = (ppu.memory.vram[address + 0] << 0) + (ppu.memory.vram[address + 1] << 8);
|
||||
tile = (ppu.vram[address + 0] << 0) + (ppu.vram[address + 1] << 8);
|
||||
bool mirrorY = tile & 0x8000;
|
||||
bool mirrorX = tile & 0x4000;
|
||||
priority = r.priority[bool(tile & 0x2000)];
|
||||
|
@ -137,16 +137,16 @@ auto PPU::Background::getTile() -> void {
|
|||
|
||||
switch(r.mode) {
|
||||
case Mode::BPP8:
|
||||
data[1].byte(3) = ppu.memory.vram[offset + 49];
|
||||
data[1].byte(2) = ppu.memory.vram[offset + 48];
|
||||
data[1].byte(1) = ppu.memory.vram[offset + 33];
|
||||
data[1].byte(0) = ppu.memory.vram[offset + 32];
|
||||
data[1].byte(3) = ppu.vram[offset + 49];
|
||||
data[1].byte(2) = ppu.vram[offset + 48];
|
||||
data[1].byte(1) = ppu.vram[offset + 33];
|
||||
data[1].byte(0) = ppu.vram[offset + 32];
|
||||
case Mode::BPP4:
|
||||
data[0].byte(3) = ppu.memory.vram[offset + 17];
|
||||
data[0].byte(2) = ppu.memory.vram[offset + 16];
|
||||
data[0].byte(3) = ppu.vram[offset + 17];
|
||||
data[0].byte(2) = ppu.vram[offset + 16];
|
||||
case Mode::BPP2:
|
||||
data[0].byte(1) = ppu.memory.vram[offset + 1];
|
||||
data[0].byte(0) = ppu.memory.vram[offset + 0];
|
||||
data[0].byte(1) = ppu.vram[offset + 1];
|
||||
data[0].byte(0) = ppu.vram[offset + 0];
|
||||
}
|
||||
|
||||
if(mirrorX) for(auto n : range(2)) {
|
||||
|
@ -193,10 +193,10 @@ auto PPU::Background::getTileColor() -> uint {
|
|||
|
||||
switch(r.mode) {
|
||||
case Mode::BPP8:
|
||||
color += data[1] >> 28 & 0x80;
|
||||
color += data[1] >> 21 & 0x40;
|
||||
color += data[1] >> 14 & 0x20;
|
||||
color += data[1] >> 7 & 0x10;
|
||||
color += data[1] >> 24 & 0x80;
|
||||
color += data[1] >> 17 & 0x40;
|
||||
color += data[1] >> 10 & 0x20;
|
||||
color += data[1] >> 3 & 0x10;
|
||||
data[1] <<= 1;
|
||||
case Mode::BPP4:
|
||||
color += data[0] >> 28 & 0x08;
|
||||
|
@ -275,5 +275,5 @@ auto PPU::Background::getTile(uint x, uint y) -> uint {
|
|||
if(y & 0x20) offset += screenY;
|
||||
|
||||
uint16 address = r.screenAddress + (offset << 1);
|
||||
return (ppu.memory.vram[address + 0] << 0) + (ppu.memory.vram[address + 1] << 8);
|
||||
return (ppu.vram[address + 0] << 0) + (ppu.vram[address + 1] << 8);
|
||||
}
|
||||
|
|
|
@ -50,8 +50,8 @@ auto PPU::Background::runMode7() -> void {
|
|||
case 1:
|
||||
px &= 1023;
|
||||
py &= 1023;
|
||||
tile = ppu.memory.vram[((py >> 3) * 128 + (px >> 3)) << 1];
|
||||
palette = ppu.memory.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
|
||||
tile = ppu.vram[((py >> 3) * 128 + (px >> 3)) << 1];
|
||||
palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
|
||||
break;
|
||||
|
||||
//palette color 0 outside of screen area
|
||||
|
@ -61,8 +61,8 @@ auto PPU::Background::runMode7() -> void {
|
|||
} else {
|
||||
px &= 1023;
|
||||
py &= 1023;
|
||||
tile = ppu.memory.vram[((py >> 3) * 128 + (px >> 3)) << 1];
|
||||
palette = ppu.memory.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
|
||||
tile = ppu.vram[((py >> 3) * 128 + (px >> 3)) << 1];
|
||||
palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -73,9 +73,9 @@ auto PPU::Background::runMode7() -> void {
|
|||
} else {
|
||||
px &= 1023;
|
||||
py &= 1023;
|
||||
tile = ppu.memory.vram[((py >> 3) * 128 + (px >> 3)) << 1];
|
||||
tile = ppu.vram[((py >> 3) * 128 + (px >> 3)) << 1];
|
||||
}
|
||||
palette = ppu.memory.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
|
||||
palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ auto PPU::getVramAddress() -> uint16 {
|
|||
auto PPU::vramRead(uint addr) -> uint8 {
|
||||
uint8 data = 0x00;
|
||||
if(r.displayDisable || vcounter() >= vdisp()) {
|
||||
data = memory.vram[addr];
|
||||
data = vram[addr];
|
||||
debugger.vramRead(addr, data);
|
||||
}
|
||||
return data;
|
||||
|
@ -20,30 +20,30 @@ auto PPU::vramRead(uint addr) -> uint8 {
|
|||
|
||||
auto PPU::vramWrite(uint addr, uint8 data) -> void {
|
||||
if(r.displayDisable || vcounter() >= vdisp()) {
|
||||
memory.vram[addr] = data;
|
||||
vram[addr] = data;
|
||||
debugger.vramWrite(addr, data);
|
||||
}
|
||||
}
|
||||
|
||||
auto PPU::oamRead(uint addr) -> uint8 {
|
||||
uint8 data = memory.oam[addr];
|
||||
uint8 data = oam[addr];
|
||||
debugger.oamRead(addr, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
auto PPU::oamWrite(uint addr, uint8 data) -> void {
|
||||
memory.oam[addr] = data;
|
||||
oam.update(addr, data);
|
||||
oam[addr] = data;
|
||||
obj.update(addr, data);
|
||||
debugger.oamWrite(addr, data);
|
||||
}
|
||||
|
||||
auto PPU::cgramRead(uint addr) -> uint8 {
|
||||
uint8 data = memory.cgram[addr];
|
||||
uint8 data = cgram[addr];
|
||||
debugger.cgramRead(addr, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
auto PPU::cgramWrite(uint addr, uint8 data) -> void {
|
||||
memory.cgram[addr] = data;
|
||||
cgram[addr] = data;
|
||||
debugger.cgramWrite(addr, data);
|
||||
}
|
||||
|
|
|
@ -13,21 +13,21 @@ auto PPU::read(uint24 addr, uint8 data) -> uint8 {
|
|||
|
||||
//MPYL
|
||||
case 0x2134: {
|
||||
uint result = ((int16)r.m7a * (int8)(r.m7b >> 8));
|
||||
uint result = (int16)r.m7a * (int8)(r.m7b >> 8);
|
||||
ppu1.mdr = (result >> 0);
|
||||
return ppu1.mdr;
|
||||
}
|
||||
|
||||
//MPYM
|
||||
case 0x2135: {
|
||||
uint result = ((int16)r.m7a * (int8)(r.m7b >> 8));
|
||||
uint result = (int16)r.m7a * (int8)(r.m7b >> 8);
|
||||
ppu1.mdr = (result >> 8);
|
||||
return ppu1.mdr;
|
||||
}
|
||||
|
||||
//MPYH
|
||||
case 0x2136: {
|
||||
uint result = ((int16)r.m7a * (int8)(r.m7b >> 8));
|
||||
uint result = (int16)r.m7a * (int8)(r.m7b >> 8);
|
||||
ppu1.mdr = (result >> 16);
|
||||
return ppu1.mdr;
|
||||
}
|
||||
|
@ -40,12 +40,12 @@ auto PPU::read(uint24 addr, uint8 data) -> uint8 {
|
|||
|
||||
//OAMDATAREAD
|
||||
case 0x2138: {
|
||||
uint10 addr = r.oamAddress++;
|
||||
if(!r.displayDisable && vcounter() < vdisp()) addr = latch.oamAddress;
|
||||
if(addr & 0x0200) addr &= 0x021f;
|
||||
uint10 address = r.oamAddress++;
|
||||
if(!r.displayDisable && vcounter() < vdisp()) address = latch.oamAddress;
|
||||
if(address & 0x0200) address &= 0x021f;
|
||||
|
||||
ppu1.mdr = oamRead(addr);
|
||||
oam.setFirstSprite();
|
||||
ppu1.mdr = oamRead(address);
|
||||
obj.setFirstSprite();
|
||||
return ppu1.mdr;
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ auto PPU::read(uint24 addr, uint8 data) -> uint8 {
|
|||
uint16 address = getVramAddress() + 0;
|
||||
ppu1.mdr = latch.vram >> 0;
|
||||
if(r.vramIncrementMode == 0) {
|
||||
addr &= ~1;
|
||||
address.bit(0) = 0;
|
||||
latch.vram.byte(0) = vramRead(address + 0);
|
||||
latch.vram.byte(1) = vramRead(address + 1);
|
||||
r.vramAddress += r.vramIncrementSize;
|
||||
|
@ -67,7 +67,7 @@ auto PPU::read(uint24 addr, uint8 data) -> uint8 {
|
|||
uint16 address = getVramAddress() + 1;
|
||||
ppu1.mdr = latch.vram >> 8;
|
||||
if(r.vramIncrementMode == 1) {
|
||||
addr &= ~1;
|
||||
address.bit(0) = 0;
|
||||
latch.vram.byte(0) = vramRead(address + 0);
|
||||
latch.vram.byte(1) = vramRead(address + 1);
|
||||
r.vramAddress += r.vramIncrementSize;
|
||||
|
@ -120,8 +120,8 @@ auto PPU::read(uint24 addr, uint8 data) -> uint8 {
|
|||
//STAT77
|
||||
case 0x213e: {
|
||||
ppu1.mdr &= 0x10;
|
||||
ppu1.mdr |= oam.r.timeOver << 7;
|
||||
ppu1.mdr |= oam.r.rangeOver << 6;
|
||||
ppu1.mdr |= obj.r.timeOver << 7;
|
||||
ppu1.mdr |= obj.r.rangeOver << 6;
|
||||
ppu1.mdr |= ppu1.version & 0x0f;
|
||||
return ppu1.mdr;
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ auto PPU::write(uint24 addr, uint8 data) -> void {
|
|||
|
||||
//INIDISP
|
||||
case 0x2100: {
|
||||
if(r.displayDisable && vcounter() == vdisp()) oam.addressReset();
|
||||
if(r.displayDisable && vcounter() == vdisp()) obj.addressReset();
|
||||
r.displayBrightness = data.bits(0,3);
|
||||
r.displayDisable = data.bit (7);
|
||||
return;
|
||||
|
@ -164,16 +164,16 @@ auto PPU::write(uint24 addr, uint8 data) -> void {
|
|||
|
||||
//OBSEL
|
||||
case 0x2101: {
|
||||
oam.r.tiledataAddress = data.bits(0,1) << 14;
|
||||
oam.r.nameSelect = data.bits(3,4);
|
||||
oam.r.baseSize = data.bits(5,7);
|
||||
obj.r.tiledataAddress = data.bits(0,1) << 14;
|
||||
obj.r.nameSelect = data.bits(3,4);
|
||||
obj.r.baseSize = data.bits(5,7);
|
||||
return;
|
||||
}
|
||||
|
||||
//OAMADDL
|
||||
case 0x2102: {
|
||||
r.oamBaseAddress = (r.oamBaseAddress & 0x0200) | (data << 1);
|
||||
oam.addressReset();
|
||||
obj.addressReset();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -181,25 +181,25 @@ auto PPU::write(uint24 addr, uint8 data) -> void {
|
|||
case 0x2103: {
|
||||
r.oamPriority = data & 0x80;
|
||||
r.oamBaseAddress = ((data & 0x01) << 9) | (r.oamBaseAddress & 0x01fe);
|
||||
oam.addressReset();
|
||||
obj.addressReset();
|
||||
return;
|
||||
}
|
||||
|
||||
//OAMDATA
|
||||
case 0x2104: {
|
||||
bool l = r.oamAddress & 1;
|
||||
uint10 addr = r.oamAddress++;
|
||||
if(!r.displayDisable && vcounter() < vdisp()) addr = latch.oamAddress;
|
||||
if(addr & 0x0200) addr &= 0x021f;
|
||||
uint10 address = r.oamAddress++;
|
||||
if(!r.displayDisable && vcounter() < vdisp()) address = latch.oamAddress;
|
||||
if(address & 0x0200) address &= 0x021f;
|
||||
|
||||
if(l == 0) latch.oam = data;
|
||||
if(addr & 0x0200) {
|
||||
oamWrite(addr, data);
|
||||
if(address & 0x0200) {
|
||||
oamWrite(address, data);
|
||||
} else if(l == 1) {
|
||||
oamWrite((addr & ~1) + 0, latch.oam);
|
||||
oamWrite((addr & ~1) + 1, data);
|
||||
oamWrite((address & ~1) + 0, latch.oam);
|
||||
oamWrite((address & ~1) + 1, data);
|
||||
}
|
||||
oam.setFirstSprite();
|
||||
obj.setFirstSprite();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -480,10 +480,10 @@ auto PPU::write(uint24 addr, uint8 data) -> void {
|
|||
|
||||
//WOBJSEL
|
||||
case 0x2125: {
|
||||
window.r.oam.oneInvert = data.bit(0);
|
||||
window.r.oam.oneEnable = data.bit(1);
|
||||
window.r.oam.twoInvert = data.bit(2);
|
||||
window.r.oam.twoEnable = data.bit(3);
|
||||
window.r.obj.oneInvert = data.bit(0);
|
||||
window.r.obj.oneEnable = data.bit(1);
|
||||
window.r.obj.twoInvert = data.bit(2);
|
||||
window.r.obj.twoEnable = data.bit(3);
|
||||
window.r.col.oneInvert = data.bit(4);
|
||||
window.r.col.oneEnable = data.bit(5);
|
||||
window.r.col.twoInvert = data.bit(6);
|
||||
|
@ -526,7 +526,7 @@ auto PPU::write(uint24 addr, uint8 data) -> void {
|
|||
|
||||
//WOBJLOG
|
||||
case 0x212b: {
|
||||
window.r.oam.mask = data.bits(0,1);
|
||||
window.r.obj.mask = data.bits(0,1);
|
||||
window.r.col.mask = data.bits(2,3);
|
||||
return;
|
||||
}
|
||||
|
@ -537,7 +537,7 @@ auto PPU::write(uint24 addr, uint8 data) -> void {
|
|||
bg2.r.aboveEnable = data.bit(1);
|
||||
bg3.r.aboveEnable = data.bit(2);
|
||||
bg4.r.aboveEnable = data.bit(3);
|
||||
oam.r.aboveEnable = data.bit(4);
|
||||
obj.r.aboveEnable = data.bit(4);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -547,7 +547,7 @@ auto PPU::write(uint24 addr, uint8 data) -> void {
|
|||
bg2.r.belowEnable = data.bit(1);
|
||||
bg3.r.belowEnable = data.bit(2);
|
||||
bg4.r.belowEnable = data.bit(3);
|
||||
oam.r.belowEnable = data.bit(4);
|
||||
obj.r.belowEnable = data.bit(4);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -557,7 +557,7 @@ auto PPU::write(uint24 addr, uint8 data) -> void {
|
|||
window.r.bg2.aboveEnable = data.bit(1);
|
||||
window.r.bg3.aboveEnable = data.bit(2);
|
||||
window.r.bg4.aboveEnable = data.bit(3);
|
||||
window.r.oam.aboveEnable = data.bit(4);
|
||||
window.r.obj.aboveEnable = data.bit(4);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -567,7 +567,7 @@ auto PPU::write(uint24 addr, uint8 data) -> void {
|
|||
window.r.bg2.belowEnable = data.bit(1);
|
||||
window.r.bg3.belowEnable = data.bit(2);
|
||||
window.r.bg4.belowEnable = data.bit(3);
|
||||
window.r.oam.belowEnable = data.bit(4);
|
||||
window.r.obj.belowEnable = data.bit(4);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -586,7 +586,7 @@ auto PPU::write(uint24 addr, uint8 data) -> void {
|
|||
screen.r.bg2.colorEnable = data.bit(1);
|
||||
screen.r.bg3.colorEnable = data.bit(2);
|
||||
screen.r.bg4.colorEnable = data.bit(3);
|
||||
screen.r.oam.colorEnable = data.bit(4);
|
||||
screen.r.obj.colorEnable = data.bit(4);
|
||||
screen.r.back.colorEnable = data.bit(5);
|
||||
screen.r.colorHalve = data.bit(6);
|
||||
screen.r.colorMode = data.bit(7);
|
||||
|
@ -604,7 +604,7 @@ auto PPU::write(uint24 addr, uint8 data) -> void {
|
|||
//SETINI
|
||||
case 0x2133: {
|
||||
r.interlace = data.bit(0);
|
||||
oam.r.interlace = data.bit(1);
|
||||
obj.r.interlace = data.bit(1);
|
||||
r.overscan = data.bit(2);
|
||||
r.pseudoHires = data.bit(3);
|
||||
r.extbg = data.bit(6);
|
||||
|
@ -633,7 +633,7 @@ auto PPU::updateVideoMode() -> void {
|
|||
memory::assign(bg2.r.priority, 7, 10);
|
||||
memory::assign(bg3.r.priority, 2, 5);
|
||||
memory::assign(bg4.r.priority, 1, 4);
|
||||
memory::assign(oam.r.priority, 3, 6, 9, 12);
|
||||
memory::assign(obj.r.priority, 3, 6, 9, 12);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
@ -645,12 +645,12 @@ auto PPU::updateVideoMode() -> void {
|
|||
memory::assign(bg1.r.priority, 5, 8);
|
||||
memory::assign(bg2.r.priority, 4, 7);
|
||||
memory::assign(bg3.r.priority, 1, 10);
|
||||
memory::assign(oam.r.priority, 2, 3, 6, 9);
|
||||
memory::assign(obj.r.priority, 2, 3, 6, 9);
|
||||
} else {
|
||||
memory::assign(bg1.r.priority, 6, 9);
|
||||
memory::assign(bg2.r.priority, 5, 8);
|
||||
memory::assign(bg3.r.priority, 1, 3);
|
||||
memory::assign(oam.r.priority, 2, 4, 7, 10);
|
||||
memory::assign(obj.r.priority, 2, 4, 7, 10);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -661,7 +661,7 @@ auto PPU::updateVideoMode() -> void {
|
|||
bg4.r.mode = Background::Mode::Inactive;
|
||||
memory::assign(bg1.r.priority, 3, 7);
|
||||
memory::assign(bg2.r.priority, 1, 5);
|
||||
memory::assign(oam.r.priority, 2, 4, 6, 8);
|
||||
memory::assign(obj.r.priority, 2, 4, 6, 8);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
@ -671,7 +671,7 @@ auto PPU::updateVideoMode() -> void {
|
|||
bg4.r.mode = Background::Mode::Inactive;
|
||||
memory::assign(bg1.r.priority, 3, 7);
|
||||
memory::assign(bg2.r.priority, 1, 5);
|
||||
memory::assign(oam.r.priority, 2, 4, 6, 8);
|
||||
memory::assign(obj.r.priority, 2, 4, 6, 8);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
|
@ -681,7 +681,7 @@ auto PPU::updateVideoMode() -> void {
|
|||
bg4.r.mode = Background::Mode::Inactive;
|
||||
memory::assign(bg1.r.priority, 3, 7);
|
||||
memory::assign(bg2.r.priority, 1, 5);
|
||||
memory::assign(oam.r.priority, 2, 4, 6, 8);
|
||||
memory::assign(obj.r.priority, 2, 4, 6, 8);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
|
@ -691,7 +691,7 @@ auto PPU::updateVideoMode() -> void {
|
|||
bg4.r.mode = Background::Mode::Inactive;
|
||||
memory::assign(bg1.r.priority, 3, 7);
|
||||
memory::assign(bg2.r.priority, 1, 5);
|
||||
memory::assign(oam.r.priority, 2, 4, 6, 8);
|
||||
memory::assign(obj.r.priority, 2, 4, 6, 8);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
|
@ -700,7 +700,7 @@ auto PPU::updateVideoMode() -> void {
|
|||
bg3.r.mode = Background::Mode::Inactive;
|
||||
bg4.r.mode = Background::Mode::Inactive;
|
||||
memory::assign(bg1.r.priority, 2, 5);
|
||||
memory::assign(oam.r.priority, 1, 3, 4, 6);
|
||||
memory::assign(obj.r.priority, 1, 3, 4, 6);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
|
@ -710,7 +710,7 @@ auto PPU::updateVideoMode() -> void {
|
|||
bg3.r.mode = Background::Mode::Inactive;
|
||||
bg4.r.mode = Background::Mode::Inactive;
|
||||
memory::assign(bg1.r.priority, 2);
|
||||
memory::assign(oam.r.priority, 1, 3, 4, 5);
|
||||
memory::assign(obj.r.priority, 1, 3, 4, 5);
|
||||
} else {
|
||||
bg1.r.mode = Background::Mode::Mode7;
|
||||
bg2.r.mode = Background::Mode::Mode7;
|
||||
|
@ -718,7 +718,7 @@ auto PPU::updateVideoMode() -> void {
|
|||
bg4.r.mode = Background::Mode::Inactive;
|
||||
memory::assign(bg1.r.priority, 3);
|
||||
memory::assign(bg2.r.priority, 1, 5);
|
||||
memory::assign(oam.r.priority, 2, 4, 6, 7);
|
||||
memory::assign(obj.r.priority, 2, 4, 6, 7);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
auto PPU::OAM::update(uint10 addr, uint8 data) -> void {
|
||||
auto PPU::Object::update(uint10 addr, uint8 data) -> void {
|
||||
if(!addr.bit(9)) {
|
||||
uint n = addr >> 2; //sprite#
|
||||
addr &= 3;
|
||||
|
@ -28,27 +28,27 @@ auto PPU::OAM::update(uint10 addr, uint8 data) -> void {
|
|||
}
|
||||
}
|
||||
|
||||
auto PPU::OAM::synchronize() -> void {
|
||||
for(auto n : range(544)) update(n, ppu.memory.oam[n]);
|
||||
auto PPU::Object::synchronize() -> void {
|
||||
for(auto n : range(544)) update(n, ppu.oam[n]);
|
||||
}
|
||||
|
||||
auto PPU::OAM::Object::width() const -> uint{
|
||||
auto PPU::Object::Sprite::width() const -> uint{
|
||||
if(size == 0) {
|
||||
static const uint width[] = { 8, 8, 8, 16, 16, 32, 16, 16};
|
||||
return width[ppu.oam.r.baseSize];
|
||||
return width[ppu.obj.r.baseSize];
|
||||
} else {
|
||||
static const uint width[] = {16, 32, 64, 32, 64, 64, 32, 32};
|
||||
return width[ppu.oam.r.baseSize];
|
||||
return width[ppu.obj.r.baseSize];
|
||||
}
|
||||
}
|
||||
|
||||
auto PPU::OAM::Object::height() const -> uint {
|
||||
auto PPU::Object::Sprite::height() const -> uint {
|
||||
if(size == 0) {
|
||||
if(ppu.oam.r.interlace && ppu.oam.r.baseSize >= 6) return 16; //hardware quirk
|
||||
if(ppu.obj.r.interlace && ppu.obj.r.baseSize >= 6) return 16; //hardware quirk
|
||||
static const uint height[] = { 8, 8, 8, 16, 16, 32, 32, 32};
|
||||
return height[ppu.oam.r.baseSize];
|
||||
return height[ppu.obj.r.baseSize];
|
||||
} else {
|
||||
static const uint height[] = {16, 32, 64, 32, 64, 64, 64, 32};
|
||||
return height[ppu.oam.r.baseSize];
|
||||
return height[ppu.obj.r.baseSize];
|
||||
}
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
#include "list.cpp"
|
||||
|
||||
auto PPU::OAM::addressReset() -> void {
|
||||
auto PPU::Object::addressReset() -> void {
|
||||
ppu.r.oamAddress = ppu.r.oamBaseAddress;
|
||||
setFirstSprite();
|
||||
}
|
||||
|
||||
auto PPU::OAM::setFirstSprite() -> void {
|
||||
auto PPU::Object::setFirstSprite() -> void {
|
||||
r.firstSprite = !ppu.r.oamPriority ? 0 : ppu.r.oamAddress >> 2;
|
||||
}
|
||||
|
||||
auto PPU::OAM::frame() -> void {
|
||||
auto PPU::Object::frame() -> void {
|
||||
r.timeOver = false;
|
||||
r.rangeOver = false;
|
||||
}
|
||||
|
||||
auto PPU::OAM::scanline() -> void {
|
||||
auto PPU::Object::scanline() -> void {
|
||||
t.x = 0;
|
||||
t.y = ppu.vcounter();
|
||||
|
||||
|
@ -43,7 +43,7 @@ auto PPU::OAM::scanline() -> void {
|
|||
}
|
||||
}
|
||||
|
||||
auto PPU::OAM::onScanline(Object& sprite) -> bool {
|
||||
auto PPU::Object::onScanline(Sprite& sprite) -> bool {
|
||||
if(sprite.x > 256 && (sprite.x + sprite.width() - 1) < 512) return false;
|
||||
int height = sprite.height() >> r.interlace;
|
||||
if(t.y >= sprite.y && t.y < (sprite.y + height)) return true;
|
||||
|
@ -51,7 +51,7 @@ auto PPU::OAM::onScanline(Object& sprite) -> bool {
|
|||
return false;
|
||||
}
|
||||
|
||||
auto PPU::OAM::run() -> void {
|
||||
auto PPU::Object::run() -> void {
|
||||
output.above.priority = 0;
|
||||
output.below.priority = 0;
|
||||
|
||||
|
@ -85,7 +85,7 @@ auto PPU::OAM::run() -> void {
|
|||
}
|
||||
}
|
||||
|
||||
auto PPU::OAM::tilefetch() -> void {
|
||||
auto PPU::Object::tilefetch() -> void {
|
||||
auto oamItem = t.item[t.active];
|
||||
auto oamTile = t.tile[t.active];
|
||||
|
||||
|
@ -141,12 +141,12 @@ auto PPU::OAM::tilefetch() -> void {
|
|||
uint pos = tiledataAddress + ((chry + ((chrx + mx) & 15)) << 5);
|
||||
uint16 addr = (pos & 0xffe0) + ((y & 7) * 2);
|
||||
|
||||
oamTile[n].data.byte(0) = ppu.memory.vram[addr + 0];
|
||||
oamTile[n].data.byte(1) = ppu.memory.vram[addr + 1];
|
||||
oamTile[n].data.byte(0) = ppu.vram[addr + 0];
|
||||
oamTile[n].data.byte(1) = ppu.vram[addr + 1];
|
||||
ppu.addClocks(2);
|
||||
|
||||
oamTile[n].data.byte(2) = ppu.memory.vram[addr + 16];
|
||||
oamTile[n].data.byte(3) = ppu.memory.vram[addr + 17];
|
||||
oamTile[n].data.byte(2) = ppu.vram[addr + 16];
|
||||
oamTile[n].data.byte(3) = ppu.vram[addr + 17];
|
||||
ppu.addClocks(2);
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ auto PPU::OAM::tilefetch() -> void {
|
|||
r.rangeOver |= (t.itemCount > 32);
|
||||
}
|
||||
|
||||
auto PPU::OAM::reset() -> void {
|
||||
auto PPU::Object::reset() -> void {
|
||||
for(auto n : range(128)) {
|
||||
list[n].x = 0;
|
||||
list[n].y = 0;
|
|
@ -1,4 +1,4 @@
|
|||
struct OAM {
|
||||
struct Object {
|
||||
alwaysinline auto addressReset() -> void;
|
||||
alwaysinline auto setFirstSprite() -> void;
|
||||
auto frame() -> void;
|
||||
|
@ -7,8 +7,8 @@ struct OAM {
|
|||
auto tilefetch() -> void;
|
||||
auto reset() -> void;
|
||||
|
||||
struct Object;
|
||||
auto onScanline(Object&) -> bool;
|
||||
struct Sprite;
|
||||
auto onScanline(Sprite&) -> bool;
|
||||
|
||||
//list.cpp
|
||||
auto update(uint10 addr, uint8 data) -> void;
|
||||
|
@ -65,7 +65,7 @@ struct OAM {
|
|||
} above, below;
|
||||
} output;
|
||||
|
||||
struct Object {
|
||||
struct Sprite {
|
||||
alwaysinline auto width() const -> uint;
|
||||
alwaysinline auto height() const -> uint;
|
||||
|
|
@ -7,9 +7,9 @@ PPU ppu;
|
|||
#include "memory.cpp"
|
||||
#include "mmio.cpp"
|
||||
#include "background/background.cpp"
|
||||
#include "screen/screen.cpp"
|
||||
#include "sprite/sprite.cpp"
|
||||
#include "object/object.cpp"
|
||||
#include "window/window.cpp"
|
||||
#include "screen/screen.cpp"
|
||||
#include "serialization.cpp"
|
||||
|
||||
PPU::PPU() :
|
||||
|
@ -62,7 +62,7 @@ auto PPU::main() -> void {
|
|||
bg3.run(0);
|
||||
bg4.run(0);
|
||||
if(pixel >= 0) {
|
||||
oam.run();
|
||||
obj.run();
|
||||
window.run();
|
||||
screen.run();
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ auto PPU::main() -> void {
|
|||
}
|
||||
|
||||
addClocks(14);
|
||||
oam.tilefetch();
|
||||
obj.tilefetch();
|
||||
} else {
|
||||
addClocks(1052 + 14 + 136);
|
||||
}
|
||||
|
@ -88,9 +88,9 @@ auto PPU::addClocks(uint clocks) -> void {
|
|||
}
|
||||
|
||||
auto PPU::power() -> void {
|
||||
for(auto& n : memory.vram) n = random(0x00);
|
||||
for(auto& n : memory.oam) n = random(0x00);
|
||||
for(auto& n : memory.cgram) n = random(0x00);
|
||||
for(auto& n : vram) n = random(0x00);
|
||||
for(auto& n : oam) n = random(0x00);
|
||||
for(auto& n : cgram) n = random(0x00);
|
||||
}
|
||||
|
||||
auto PPU::reset() -> void {
|
||||
|
@ -188,7 +188,7 @@ auto PPU::reset() -> void {
|
|||
bg2.reset();
|
||||
bg3.reset();
|
||||
bg4.reset();
|
||||
oam.reset();
|
||||
obj.reset();
|
||||
window.reset();
|
||||
screen.reset();
|
||||
|
||||
|
@ -208,7 +208,7 @@ auto PPU::scanline() -> void {
|
|||
bg2.scanline();
|
||||
bg3.scanline();
|
||||
bg4.scanline();
|
||||
oam.scanline();
|
||||
obj.scanline();
|
||||
window.scanline();
|
||||
screen.scanline();
|
||||
|
||||
|
@ -218,7 +218,7 @@ auto PPU::scanline() -> void {
|
|||
}
|
||||
|
||||
auto PPU::frame() -> void {
|
||||
oam.frame();
|
||||
obj.frame();
|
||||
display.interlace = r.interlace;
|
||||
display.overscan = r.overscan;
|
||||
}
|
||||
|
|
|
@ -31,13 +31,11 @@ struct PPU : Thread, PPUcounter {
|
|||
auto latchCounters() -> void;
|
||||
auto updateVideoMode() -> void;
|
||||
|
||||
struct {
|
||||
uint8 vram[64 * 1024];
|
||||
uint8 oam[544];
|
||||
uint8 cgram[512];
|
||||
} memory;
|
||||
|
||||
privileged:
|
||||
uint8 vram[64 * 1024];
|
||||
uint8 oam[544];
|
||||
uint8 cgram[512];
|
||||
|
||||
uint32* output = nullptr;
|
||||
|
||||
struct {
|
||||
|
@ -140,20 +138,20 @@ privileged:
|
|||
} r;
|
||||
|
||||
#include "background/background.hpp"
|
||||
#include "screen/screen.hpp"
|
||||
#include "sprite/sprite.hpp"
|
||||
#include "object/object.hpp"
|
||||
#include "window/window.hpp"
|
||||
#include "screen/screen.hpp"
|
||||
|
||||
Background bg1;
|
||||
Background bg2;
|
||||
Background bg3;
|
||||
Background bg4;
|
||||
OAM oam;
|
||||
Object obj;
|
||||
Window window;
|
||||
Screen screen;
|
||||
|
||||
friend class PPU::Background;
|
||||
friend class PPU::OAM;
|
||||
friend class PPU::Object;
|
||||
friend class PPU::Window;
|
||||
friend class PPU::Screen;
|
||||
friend class Scheduler;
|
||||
|
|
|
@ -51,9 +51,9 @@ auto PPU::Screen::below(bool hires) -> uint16 {
|
|||
priority = ppu.bg4.output.below.priority;
|
||||
math.below.color = paletteColor(ppu.bg4.output.below.palette);
|
||||
}
|
||||
if(ppu.oam.output.below.priority > priority) {
|
||||
priority = ppu.oam.output.below.priority;
|
||||
math.below.color = paletteColor(ppu.oam.output.below.palette);
|
||||
if(ppu.obj.output.below.priority > priority) {
|
||||
priority = ppu.obj.output.below.priority;
|
||||
math.below.color = paletteColor(ppu.obj.output.below.palette);
|
||||
}
|
||||
if(math.transparent = (priority == 0)) math.below.color = paletteColor(0);
|
||||
|
||||
|
@ -94,10 +94,10 @@ auto PPU::Screen::above() -> uint16 {
|
|||
math.above.color = paletteColor(ppu.bg4.output.above.palette);
|
||||
math.below.colorEnable = r.bg4.colorEnable;
|
||||
}
|
||||
if(ppu.oam.output.above.priority > priority) {
|
||||
priority = ppu.oam.output.above.priority;
|
||||
math.above.color = paletteColor(ppu.oam.output.above.palette);
|
||||
math.below.colorEnable = r.oam.colorEnable && ppu.oam.output.above.palette >= 192;
|
||||
if(ppu.obj.output.above.priority > priority) {
|
||||
priority = ppu.obj.output.above.priority;
|
||||
math.above.color = paletteColor(ppu.obj.output.above.palette);
|
||||
math.below.colorEnable = r.obj.colorEnable && ppu.obj.output.above.palette >= 192;
|
||||
}
|
||||
if(priority == 0) {
|
||||
math.above.color = paletteColor(0);
|
||||
|
@ -145,7 +145,7 @@ auto PPU::Screen::blend(uint x, uint y) const -> uint16 {
|
|||
auto PPU::Screen::paletteColor(uint palette) const -> uint16 {
|
||||
palette <<= 1;
|
||||
ppu.latch.cgramAddress = palette;
|
||||
return ppu.memory.cgram[palette + 0] + (ppu.memory.cgram[palette + 1] << 8);
|
||||
return ppu.cgram[palette + 0] << 0 | ppu.cgram[palette + 1] << 8;
|
||||
}
|
||||
|
||||
auto PPU::Screen::directColor(uint palette, uint tile) const -> uint16 {
|
||||
|
@ -170,7 +170,7 @@ auto PPU::Screen::reset() -> void {
|
|||
r.bg2.colorEnable = random(false);
|
||||
r.bg3.colorEnable = random(false);
|
||||
r.bg4.colorEnable = random(false);
|
||||
r.oam.colorEnable = random(false);
|
||||
r.obj.colorEnable = random(false);
|
||||
r.back.colorEnable = random(false);
|
||||
r.colorBlue = random(0);
|
||||
r.colorGreen = random(0);
|
||||
|
|
|
@ -24,7 +24,7 @@ struct Screen {
|
|||
bool colorHalve;
|
||||
struct Layer {
|
||||
bool colorEnable;
|
||||
} bg1, bg2, bg3, bg4, oam, back;
|
||||
} bg1, bg2, bg3, bg4, obj, back;
|
||||
|
||||
uint5 colorBlue;
|
||||
uint5 colorGreen;
|
||||
|
|
|
@ -14,9 +14,9 @@ auto PPU::serialize(serializer& s) -> void {
|
|||
Thread::serialize(s);
|
||||
PPUcounter::serialize(s);
|
||||
|
||||
s.array(memory.vram);
|
||||
s.array(memory.oam);
|
||||
s.array(memory.cgram);
|
||||
s.array(vram);
|
||||
s.array(oam);
|
||||
s.array(cgram);
|
||||
|
||||
s.integer(ppu1.version);
|
||||
s.integer(ppu1.mdr);
|
||||
|
@ -83,7 +83,7 @@ auto PPU::serialize(serializer& s) -> void {
|
|||
bg2.serialize(s);
|
||||
bg3.serialize(s);
|
||||
bg4.serialize(s);
|
||||
oam.serialize(s);
|
||||
obj.serialize(s);
|
||||
window.serialize(s);
|
||||
screen.serialize(s);
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ auto PPU::Background::serialize(serializer& s) -> void {
|
|||
s.array(data);
|
||||
}
|
||||
|
||||
auto PPU::OAM::serialize(serializer& s) -> void {
|
||||
auto PPU::Object::serialize(serializer& s) -> void {
|
||||
s.integer(r.aboveEnable);
|
||||
s.integer(r.belowEnable);
|
||||
s.integer(r.interlace);
|
||||
|
@ -224,13 +224,13 @@ auto PPU::Window::serialize(serializer& s) -> void {
|
|||
s.integer(r.bg4.aboveEnable);
|
||||
s.integer(r.bg4.belowEnable);
|
||||
|
||||
s.integer(r.oam.oneEnable);
|
||||
s.integer(r.oam.oneInvert);
|
||||
s.integer(r.oam.twoEnable);
|
||||
s.integer(r.oam.twoInvert);
|
||||
s.integer(r.oam.mask);
|
||||
s.integer(r.oam.aboveEnable);
|
||||
s.integer(r.oam.belowEnable);
|
||||
s.integer(r.obj.oneEnable);
|
||||
s.integer(r.obj.oneInvert);
|
||||
s.integer(r.obj.twoEnable);
|
||||
s.integer(r.obj.twoInvert);
|
||||
s.integer(r.obj.mask);
|
||||
s.integer(r.obj.aboveEnable);
|
||||
s.integer(r.obj.belowEnable);
|
||||
|
||||
s.integer(r.col.oneEnable);
|
||||
s.integer(r.col.oneInvert);
|
||||
|
@ -261,7 +261,7 @@ auto PPU::Screen::serialize(serializer& s) -> void {
|
|||
s.integer(r.bg2.colorEnable);
|
||||
s.integer(r.bg3.colorEnable);
|
||||
s.integer(r.bg4.colorEnable);
|
||||
s.integer(r.oam.colorEnable);
|
||||
s.integer(r.obj.colorEnable);
|
||||
s.integer(r.back.colorEnable);
|
||||
|
||||
s.integer(r.colorBlue);
|
||||
|
|
|
@ -27,9 +27,9 @@ auto PPU::Window::run() -> void {
|
|||
if(r.bg4.belowEnable) ppu.bg4.output.below.priority = 0;
|
||||
}
|
||||
|
||||
if(test(r.oam.oneEnable, one ^ r.oam.oneInvert, r.oam.twoEnable, two ^ r.oam.twoInvert, r.oam.mask)) {
|
||||
if(r.oam.aboveEnable) ppu.oam.output.above.priority = 0;
|
||||
if(r.oam.belowEnable) ppu.oam.output.below.priority = 0;
|
||||
if(test(r.obj.oneEnable, one ^ r.obj.oneInvert, r.obj.twoEnable, two ^ r.obj.twoInvert, r.obj.mask)) {
|
||||
if(r.obj.aboveEnable) ppu.obj.output.above.priority = 0;
|
||||
if(r.obj.belowEnable) ppu.obj.output.below.priority = 0;
|
||||
}
|
||||
|
||||
bool value = test(r.col.oneEnable, one ^ r.col.oneInvert, r.col.twoEnable, two ^ r.col.twoInvert, r.col.mask);
|
||||
|
@ -79,13 +79,13 @@ auto PPU::Window::reset() -> void {
|
|||
r.bg4.aboveEnable = random(false);
|
||||
r.bg4.belowEnable = random(false);
|
||||
|
||||
r.oam.oneEnable = random(false);
|
||||
r.oam.oneInvert = random(false);
|
||||
r.oam.twoEnable = random(false);
|
||||
r.oam.twoInvert = random(false);
|
||||
r.oam.mask = random(0);
|
||||
r.oam.aboveEnable = random(false);
|
||||
r.oam.belowEnable = random(false);
|
||||
r.obj.oneEnable = random(false);
|
||||
r.obj.oneInvert = random(false);
|
||||
r.obj.twoEnable = random(false);
|
||||
r.obj.twoInvert = random(false);
|
||||
r.obj.mask = random(0);
|
||||
r.obj.aboveEnable = random(false);
|
||||
r.obj.belowEnable = random(false);
|
||||
|
||||
r.col.oneEnable = random(false);
|
||||
r.col.oneInvert = random(false);
|
||||
|
|
|
@ -15,7 +15,7 @@ struct Window {
|
|||
uint2 mask;
|
||||
bool aboveEnable;
|
||||
bool belowEnable;
|
||||
} bg1, bg2, bg3, bg4, oam;
|
||||
} bg1, bg2, bg3, bg4, obj;
|
||||
|
||||
struct Color {
|
||||
bool oneEnable;
|
||||
|
|
Loading…
Reference in New Issue