From 5f39119b231806d057bffe0f8662e0e7abf884af Mon Sep 17 00:00:00 2001 From: devinacker Date: Tue, 28 May 2019 23:00:22 -0400 Subject: [PATCH 1/5] backport fixes to SA1 mul/div --- bsnes/snes/chip/sa1/mmio/mmio.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/bsnes/snes/chip/sa1/mmio/mmio.cpp b/bsnes/snes/chip/sa1/mmio/mmio.cpp index 1bb6e962..a91b8455 100644 --- a/bsnes/snes/chip/sa1/mmio/mmio.cpp +++ b/bsnes/snes/chip/sa1/mmio/mmio.cpp @@ -407,15 +407,17 @@ void SA1::mmio_w2254(uint8 data) { if(mmio.acm == 0) { if(mmio.md == 0) { //signed multiplication - mmio.mr = (int16)mmio.ma * (int16)mmio.mb; + mmio.mr = (uint32)((int16)mmio.ma * (int16)mmio.mb); mmio.mb = 0; } else { //unsigned division if(mmio.mb == 0) { mmio.mr = 0; } else { - int16 quotient = (int16)mmio.ma / (uint16)mmio.mb; - uint16 remainder = (int16)mmio.ma % (uint16)mmio.mb; + int16 dividend = mmio.ma; + uint16 divisor = mmio.mb; + uint16 remainder = (dividend >= 0) ? (dividend % divisor) : ((dividend % divisor + divisor) % divisor); + uint16 quotient = (dividend - remainder) / divisor; mmio.mr = (remainder << 16) | quotient; } mmio.ma = 0; From a64f937f1c3643c132b637a0c0c3862633afdd7e Mon Sep 17 00:00:00 2001 From: devinacker Date: Sun, 2 Jun 2019 17:06:14 -0400 Subject: [PATCH 2/5] add support for expanded SPC7110 ROMs (tengai makyou zero translation) --- common/nall/snes/cartridge.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/nall/snes/cartridge.hpp b/common/nall/snes/cartridge.hpp index 09285543..acb8b3ec 100644 --- a/common/nall/snes/cartridge.hpp +++ b/common/nall/snes/cartridge.hpp @@ -283,6 +283,10 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) { xml << " \n"; xml << " \n"; xml << " \n"; + if (size >= 0x700000) { + // Tengai Makyou Zero english translation + xml << " \n"; + } xml << " \n"; xml << " \n"; From ece84e519d1ba4e17d44513ea8681d7dad74909b Mon Sep 17 00:00:00 2001 From: devinacker Date: Sun, 2 Jun 2019 17:33:08 -0400 Subject: [PATCH 3/5] backport higan v106r131 sprite handling changes --- bsnes/snes/ppu/ppu.cpp | 17 +++------ bsnes/snes/ppu/ppu.hpp | 1 - bsnes/snes/ppu/serialization.cpp | 22 +++++------ bsnes/snes/ppu/sprite/sprite.cpp | 64 ++++++++++++++------------------ bsnes/snes/ppu/sprite/sprite.hpp | 4 +- 5 files changed, 45 insertions(+), 63 deletions(-) diff --git a/bsnes/snes/ppu/ppu.cpp b/bsnes/snes/ppu/ppu.cpp index 1f77a849..54256c8e 100644 --- a/bsnes/snes/ppu/ppu.cpp +++ b/bsnes/snes/ppu/ppu.cpp @@ -60,6 +60,7 @@ void PPU::enter() { add_clocks(2); } + oam.scanline(); add_clocks(14); oam.tilefetch(); } else { @@ -108,35 +109,29 @@ void PPU::reset() { window.reset(); screen.reset(); - frame(); + system.frame(); } void PPU::scanline() { if(vcounter() == 0) { - frame(); + system.frame(); + display.interlace = regs.interlace; + display.overscan = regs.overscan; bg1.frame(); bg2.frame(); bg3.frame(); bg4.frame(); + oam.frame(); } bg1.scanline(); bg2.scanline(); bg3.scanline(); bg4.scanline(); - oam.scanline(); window.scanline(); screen.scanline(); } -void PPU::frame() { - system.frame(); - oam.frame(); - - display.interlace = regs.interlace; - display.overscan = regs.overscan; -} - PPU::PPU() : bg1(*this, Background::ID::BG1), bg2(*this, Background::ID::BG2), diff --git a/bsnes/snes/ppu/ppu.hpp b/bsnes/snes/ppu/ppu.hpp index 4631c86f..81289cbb 100644 --- a/bsnes/snes/ppu/ppu.hpp +++ b/bsnes/snes/ppu/ppu.hpp @@ -55,7 +55,6 @@ class PPU : public Processor, public PPUcounter, public MMIO { void add_clocks(unsigned); void scanline(); - void frame(); friend class PPU::Background; friend class PPU::Sprite; diff --git a/bsnes/snes/ppu/serialization.cpp b/bsnes/snes/ppu/serialization.cpp index cf4276ab..65c80aa6 100644 --- a/bsnes/snes/ppu/serialization.cpp +++ b/bsnes/snes/ppu/serialization.cpp @@ -144,18 +144,16 @@ void PPU::Sprite::serialize(serializer &s) { s.integer(t.tile_count); s.integer(t.active); - for(unsigned n = 0; n < 2; n++) { - s.array(t.item[n]); - for(unsigned i = 0; i < 34; i++) { - s.integer(t.tile[n][i].x); - s.integer(t.tile[n][i].priority); - s.integer(t.tile[n][i].palette); - s.integer(t.tile[n][i].hflip); - s.integer(t.tile[n][i].d0); - s.integer(t.tile[n][i].d1); - s.integer(t.tile[n][i].d2); - s.integer(t.tile[n][i].d3); - } + s.array(t.item); + for(unsigned i = 0; i < 34; i++) { + s.integer(t.tile[i].x); + s.integer(t.tile[i].priority); + s.integer(t.tile[i].palette); + s.integer(t.tile[i].hflip); + s.integer(t.tile[i].d0); + s.integer(t.tile[i].d1); + s.integer(t.tile[i].d2); + s.integer(t.tile[i].d3); } s.integer(regs.main_enable); diff --git a/bsnes/snes/ppu/sprite/sprite.cpp b/bsnes/snes/ppu/sprite/sprite.cpp index c4a9fef3..3f66e255 100644 --- a/bsnes/snes/ppu/sprite/sprite.cpp +++ b/bsnes/snes/ppu/sprite/sprite.cpp @@ -23,25 +23,21 @@ void PPU::Sprite::scanline() { t.item_count = 0; t.tile_count = 0; - t.active = !t.active; - auto oam_item = t.item[t.active]; - auto oam_tile = t.tile[t.active]; - if(t.y == (!self.regs.overscan ? 225 : 240) && self.regs.display_disable == false) address_reset(); - if(t.y >= (!self.regs.overscan ? 224 : 239)) return; + if(t.y >= (!self.regs.overscan ? 224 : 239) || self.regs.display_disable == true) return; - memset(oam_item, 0xff, 32); //default to invalid - for(unsigned i = 0; i < 34; i++) oam_tile[i].x = 0xffff; //default to invalid + memset(t.item, 0xff, 32); //default to invalid + for(unsigned i = 0; i < 34; i++) t.tile[i].x = 0xffff; //default to invalid for(unsigned i = 0; i < 128; i++) { unsigned sprite = (regs.first_sprite + i) & 127; if(on_scanline(list[sprite]) == false) continue; if(t.item_count++ >= 32) break; - oam_item[t.item_count - 1] = sprite; + t.item[t.item_count - 1] = sprite; } - if(t.item_count > 0 && oam_item[t.item_count - 1] != 0xff) { - ppu.regs.oam_iaddr = 0x0200 + (oam_item[t.item_count - 1] >> 2); + if(t.item_count > 0 && t.item[t.item_count - 1] != 0xff) { + ppu.regs.oam_iaddr = 0x0200 + (t.item[t.item_count - 1] >> 2); } } @@ -57,12 +53,11 @@ void PPU::Sprite::run() { output.main.priority = 0; output.sub.priority = 0; - auto oam_tile = t.tile[!t.active]; unsigned priority_table[] = { regs.priority0, regs.priority1, regs.priority2, regs.priority3 }; unsigned x = t.x++; for(unsigned n = 0; n < 34; n++) { - auto tile = oam_tile[n]; + auto tile = t.tile[n]; if(tile.x == 0xffff) break; int px = x - sclip<9>(tile.x); @@ -90,12 +85,9 @@ void PPU::Sprite::run() { } void PPU::Sprite::tilefetch() { - auto oam_item = t.item[t.active]; - auto oam_tile = t.tile[t.active]; - for(signed i = 31; i >= 0; i--) { - if(oam_item[i] == 0xff) continue; - auto sprite = list[oam_item[i]]; + if(t.item[i] == 0xff) continue; + auto sprite = list[t.item[i]]; unsigned tile_width = sprite.width() >> 3; signed x = sprite.x; @@ -135,21 +127,21 @@ void PPU::Sprite::tilefetch() { if(t.tile_count++ >= 34) break; unsigned n = t.tile_count - 1; - oam_tile[n].x = sx; - oam_tile[n].priority = sprite.priority; - oam_tile[n].palette = 128 + (sprite.palette << 4); - oam_tile[n].hflip = sprite.hflip; + t.tile[n].x = sx; + t.tile[n].priority = sprite.priority; + t.tile[n].palette = 128 + (sprite.palette << 4); + t.tile[n].hflip = sprite.hflip; unsigned mx = (sprite.hflip == false) ? tx : ((tile_width - 1) - tx); unsigned pos = tiledata_addr + ((chry + ((chrx + mx) & 15)) << 5); uint16 addr = (pos & 0xffe0) + ((y & 7) * 2); - oam_tile[n].d0 = memory::vram[addr + 0]; - oam_tile[n].d1 = memory::vram[addr + 1]; + t.tile[n].d0 = memory::vram[addr + 0]; + t.tile[n].d1 = memory::vram[addr + 1]; self.add_clocks(2); - oam_tile[n].d2 = memory::vram[addr + 16]; - oam_tile[n].d3 = memory::vram[addr + 17]; + t.tile[n].d2 = memory::vram[addr + 16]; + t.tile[n].d3 = memory::vram[addr + 17]; self.add_clocks(2); } } @@ -179,18 +171,16 @@ void PPU::Sprite::reset() { t.tile_count = 0; t.active = 0; - for(unsigned n = 0; n < 2; n++) { - memset(t.item[n], 0, 32); - for(unsigned i = 0; i < 34; i++) { - t.tile[n][i].x = 0; - t.tile[n][i].priority = 0; - t.tile[n][i].palette = 0; - t.tile[n][i].hflip = 0; - t.tile[n][i].d0 = 0; - t.tile[n][i].d1 = 0; - t.tile[n][i].d2 = 0; - t.tile[n][i].d3 = 0; - } + memset(t.item, 0, 32); + for(unsigned i = 0; i < 34; i++) { + t.tile[i].x = 0; + t.tile[i].priority = 0; + t.tile[i].palette = 0; + t.tile[i].hflip = 0; + t.tile[i].d0 = 0; + t.tile[i].d1 = 0; + t.tile[i].d2 = 0; + t.tile[i].d3 = 0; } regs.main_enable = random(0); diff --git a/bsnes/snes/ppu/sprite/sprite.hpp b/bsnes/snes/ppu/sprite/sprite.hpp index 4a823066..a18ecf65 100644 --- a/bsnes/snes/ppu/sprite/sprite.hpp +++ b/bsnes/snes/ppu/sprite/sprite.hpp @@ -29,8 +29,8 @@ class Sprite { unsigned tile_count; bool active; - uint8 item[2][32]; - TileItem tile[2][34]; + uint8 item[32]; + TileItem tile[34]; } t; struct Regs { From a94bd56829fd60e20bf68b633e37631a339eb6f3 Mon Sep 17 00:00:00 2001 From: devinacker Date: Sat, 8 Jun 2019 18:05:30 -0400 Subject: [PATCH 4/5] Revert "backport higan v106r131 sprite handling changes" This reverts commit ece84e519d1ba4e17d44513ea8681d7dad74909b. --- bsnes/snes/ppu/ppu.cpp | 17 ++++++--- bsnes/snes/ppu/ppu.hpp | 1 + bsnes/snes/ppu/serialization.cpp | 22 ++++++----- bsnes/snes/ppu/sprite/sprite.cpp | 64 ++++++++++++++++++-------------- bsnes/snes/ppu/sprite/sprite.hpp | 4 +- 5 files changed, 63 insertions(+), 45 deletions(-) diff --git a/bsnes/snes/ppu/ppu.cpp b/bsnes/snes/ppu/ppu.cpp index 54256c8e..1f77a849 100644 --- a/bsnes/snes/ppu/ppu.cpp +++ b/bsnes/snes/ppu/ppu.cpp @@ -60,7 +60,6 @@ void PPU::enter() { add_clocks(2); } - oam.scanline(); add_clocks(14); oam.tilefetch(); } else { @@ -109,29 +108,35 @@ void PPU::reset() { window.reset(); screen.reset(); - system.frame(); + frame(); } void PPU::scanline() { if(vcounter() == 0) { - system.frame(); - display.interlace = regs.interlace; - display.overscan = regs.overscan; + frame(); bg1.frame(); bg2.frame(); bg3.frame(); bg4.frame(); - oam.frame(); } bg1.scanline(); bg2.scanline(); bg3.scanline(); bg4.scanline(); + oam.scanline(); window.scanline(); screen.scanline(); } +void PPU::frame() { + system.frame(); + oam.frame(); + + display.interlace = regs.interlace; + display.overscan = regs.overscan; +} + PPU::PPU() : bg1(*this, Background::ID::BG1), bg2(*this, Background::ID::BG2), diff --git a/bsnes/snes/ppu/ppu.hpp b/bsnes/snes/ppu/ppu.hpp index 81289cbb..4631c86f 100644 --- a/bsnes/snes/ppu/ppu.hpp +++ b/bsnes/snes/ppu/ppu.hpp @@ -55,6 +55,7 @@ class PPU : public Processor, public PPUcounter, public MMIO { void add_clocks(unsigned); void scanline(); + void frame(); friend class PPU::Background; friend class PPU::Sprite; diff --git a/bsnes/snes/ppu/serialization.cpp b/bsnes/snes/ppu/serialization.cpp index 65c80aa6..cf4276ab 100644 --- a/bsnes/snes/ppu/serialization.cpp +++ b/bsnes/snes/ppu/serialization.cpp @@ -144,16 +144,18 @@ void PPU::Sprite::serialize(serializer &s) { s.integer(t.tile_count); s.integer(t.active); - s.array(t.item); - for(unsigned i = 0; i < 34; i++) { - s.integer(t.tile[i].x); - s.integer(t.tile[i].priority); - s.integer(t.tile[i].palette); - s.integer(t.tile[i].hflip); - s.integer(t.tile[i].d0); - s.integer(t.tile[i].d1); - s.integer(t.tile[i].d2); - s.integer(t.tile[i].d3); + for(unsigned n = 0; n < 2; n++) { + s.array(t.item[n]); + for(unsigned i = 0; i < 34; i++) { + s.integer(t.tile[n][i].x); + s.integer(t.tile[n][i].priority); + s.integer(t.tile[n][i].palette); + s.integer(t.tile[n][i].hflip); + s.integer(t.tile[n][i].d0); + s.integer(t.tile[n][i].d1); + s.integer(t.tile[n][i].d2); + s.integer(t.tile[n][i].d3); + } } s.integer(regs.main_enable); diff --git a/bsnes/snes/ppu/sprite/sprite.cpp b/bsnes/snes/ppu/sprite/sprite.cpp index 3f66e255..c4a9fef3 100644 --- a/bsnes/snes/ppu/sprite/sprite.cpp +++ b/bsnes/snes/ppu/sprite/sprite.cpp @@ -23,21 +23,25 @@ void PPU::Sprite::scanline() { t.item_count = 0; t.tile_count = 0; + t.active = !t.active; + auto oam_item = t.item[t.active]; + auto oam_tile = t.tile[t.active]; + if(t.y == (!self.regs.overscan ? 225 : 240) && self.regs.display_disable == false) address_reset(); - if(t.y >= (!self.regs.overscan ? 224 : 239) || self.regs.display_disable == true) return; + if(t.y >= (!self.regs.overscan ? 224 : 239)) return; - memset(t.item, 0xff, 32); //default to invalid - for(unsigned i = 0; i < 34; i++) t.tile[i].x = 0xffff; //default to invalid + memset(oam_item, 0xff, 32); //default to invalid + for(unsigned i = 0; i < 34; i++) oam_tile[i].x = 0xffff; //default to invalid for(unsigned i = 0; i < 128; i++) { unsigned sprite = (regs.first_sprite + i) & 127; if(on_scanline(list[sprite]) == false) continue; if(t.item_count++ >= 32) break; - t.item[t.item_count - 1] = sprite; + oam_item[t.item_count - 1] = sprite; } - if(t.item_count > 0 && t.item[t.item_count - 1] != 0xff) { - ppu.regs.oam_iaddr = 0x0200 + (t.item[t.item_count - 1] >> 2); + if(t.item_count > 0 && oam_item[t.item_count - 1] != 0xff) { + ppu.regs.oam_iaddr = 0x0200 + (oam_item[t.item_count - 1] >> 2); } } @@ -53,11 +57,12 @@ void PPU::Sprite::run() { output.main.priority = 0; output.sub.priority = 0; + auto oam_tile = t.tile[!t.active]; unsigned priority_table[] = { regs.priority0, regs.priority1, regs.priority2, regs.priority3 }; unsigned x = t.x++; for(unsigned n = 0; n < 34; n++) { - auto tile = t.tile[n]; + auto tile = oam_tile[n]; if(tile.x == 0xffff) break; int px = x - sclip<9>(tile.x); @@ -85,9 +90,12 @@ void PPU::Sprite::run() { } void PPU::Sprite::tilefetch() { + auto oam_item = t.item[t.active]; + auto oam_tile = t.tile[t.active]; + for(signed i = 31; i >= 0; i--) { - if(t.item[i] == 0xff) continue; - auto sprite = list[t.item[i]]; + if(oam_item[i] == 0xff) continue; + auto sprite = list[oam_item[i]]; unsigned tile_width = sprite.width() >> 3; signed x = sprite.x; @@ -127,21 +135,21 @@ void PPU::Sprite::tilefetch() { if(t.tile_count++ >= 34) break; unsigned n = t.tile_count - 1; - t.tile[n].x = sx; - t.tile[n].priority = sprite.priority; - t.tile[n].palette = 128 + (sprite.palette << 4); - t.tile[n].hflip = sprite.hflip; + oam_tile[n].x = sx; + oam_tile[n].priority = sprite.priority; + oam_tile[n].palette = 128 + (sprite.palette << 4); + oam_tile[n].hflip = sprite.hflip; unsigned mx = (sprite.hflip == false) ? tx : ((tile_width - 1) - tx); unsigned pos = tiledata_addr + ((chry + ((chrx + mx) & 15)) << 5); uint16 addr = (pos & 0xffe0) + ((y & 7) * 2); - t.tile[n].d0 = memory::vram[addr + 0]; - t.tile[n].d1 = memory::vram[addr + 1]; + oam_tile[n].d0 = memory::vram[addr + 0]; + oam_tile[n].d1 = memory::vram[addr + 1]; self.add_clocks(2); - t.tile[n].d2 = memory::vram[addr + 16]; - t.tile[n].d3 = memory::vram[addr + 17]; + oam_tile[n].d2 = memory::vram[addr + 16]; + oam_tile[n].d3 = memory::vram[addr + 17]; self.add_clocks(2); } } @@ -171,16 +179,18 @@ void PPU::Sprite::reset() { t.tile_count = 0; t.active = 0; - memset(t.item, 0, 32); - for(unsigned i = 0; i < 34; i++) { - t.tile[i].x = 0; - t.tile[i].priority = 0; - t.tile[i].palette = 0; - t.tile[i].hflip = 0; - t.tile[i].d0 = 0; - t.tile[i].d1 = 0; - t.tile[i].d2 = 0; - t.tile[i].d3 = 0; + for(unsigned n = 0; n < 2; n++) { + memset(t.item[n], 0, 32); + for(unsigned i = 0; i < 34; i++) { + t.tile[n][i].x = 0; + t.tile[n][i].priority = 0; + t.tile[n][i].palette = 0; + t.tile[n][i].hflip = 0; + t.tile[n][i].d0 = 0; + t.tile[n][i].d1 = 0; + t.tile[n][i].d2 = 0; + t.tile[n][i].d3 = 0; + } } regs.main_enable = random(0); diff --git a/bsnes/snes/ppu/sprite/sprite.hpp b/bsnes/snes/ppu/sprite/sprite.hpp index a18ecf65..4a823066 100644 --- a/bsnes/snes/ppu/sprite/sprite.hpp +++ b/bsnes/snes/ppu/sprite/sprite.hpp @@ -29,8 +29,8 @@ class Sprite { unsigned tile_count; bool active; - uint8 item[32]; - TileItem tile[34]; + uint8 item[2][32]; + TileItem tile[2][34]; } t; struct Regs { From 399d8294cf0b0e757aed75e273ce47dff2ba61e1 Mon Sep 17 00:00:00 2001 From: devinacker Date: Sat, 8 Jun 2019 18:57:16 -0400 Subject: [PATCH 5/5] backport PPU timing tweaks from v106r124 etc --- bsnes/snes/ppu/ppu.cpp | 8 +++----- bsnes/snes/ppu/sprite/sprite.cpp | 4 +--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/bsnes/snes/ppu/ppu.cpp b/bsnes/snes/ppu/ppu.cpp index 1f77a849..58f28d13 100644 --- a/bsnes/snes/ppu/ppu.cpp +++ b/bsnes/snes/ppu/ppu.cpp @@ -38,7 +38,7 @@ void PPU::enter() { } scanline(); - add_clocks(68); + add_clocks(28); if(vcounter() <= (!regs.overscan ? 224 : 239)) { for(signed pixel = -7; pixel <= 255; pixel++) { @@ -60,13 +60,11 @@ void PPU::enter() { add_clocks(2); } - add_clocks(14); + add_clocks(14 + 34*2); oam.tilefetch(); - } else { - add_clocks(1052 + 14 + 136); } - add_clocks(lineclocks() - 68 - 1052 - 14 - 136); + add_clocks(lineclocks() - hcounter()); } } diff --git a/bsnes/snes/ppu/sprite/sprite.cpp b/bsnes/snes/ppu/sprite/sprite.cpp index c4a9fef3..75e25740 100644 --- a/bsnes/snes/ppu/sprite/sprite.cpp +++ b/bsnes/snes/ppu/sprite/sprite.cpp @@ -146,15 +146,13 @@ void PPU::Sprite::tilefetch() { oam_tile[n].d0 = memory::vram[addr + 0]; oam_tile[n].d1 = memory::vram[addr + 1]; - self.add_clocks(2); - oam_tile[n].d2 = memory::vram[addr + 16]; oam_tile[n].d3 = memory::vram[addr + 17]; self.add_clocks(2); } } - if(t.tile_count < 34) self.add_clocks((34 - t.tile_count) * 4); + if(t.tile_count < 34) self.add_clocks((34 - t.tile_count) * 2); regs.time_over |= (t.tile_count > 34); regs.range_over |= (t.item_count > 32); }