diff --git a/ares/fc/cartridge/board/board.hpp b/ares/fc/cartridge/board/board.hpp index 9d52fc3160..f2563694de 100644 --- a/ares/fc/cartridge/board/board.hpp +++ b/ares/fc/cartridge/board/board.hpp @@ -1,5 +1,6 @@ namespace Board { -#include "jv001.hpp" +#include "ic/jv001.hpp" +#include "ic/txc05-00002-010.hpp" struct Interface { VFS::Pak pak; diff --git a/ares/fc/cartridge/board/ic/jv001.hpp b/ares/fc/cartridge/board/ic/jv001.hpp new file mode 100644 index 0000000000..70e6eeee49 --- /dev/null +++ b/ares/fc/cartridge/board/ic/jv001.hpp @@ -0,0 +1,55 @@ +#pragma once +// JV001: 136/172 136 172 +// .--\/--. | .--\/--. | .--\/--. +// PPU A13 -> |01 28| -- GND | PPU A13 -> |01 28| -- GND | PPU A13 -> |01 28| -- GND +// CPU D5 <> |02 27| <- PPU R/W | CPU D5 <> |02 27| <- NC | CPU D0 <> |02 27| <- PPU R/W +// CPU D4 <> |03 26| -> Invert | CPU D4 <> |03 26| -> NC | CPU D1 <> |03 26| -> CIRAM A10 +// CPU D3 <> |04 25| <- PPU A11 | CPU D3 <> |04 25| <- NC | CPU D2 <> |04 25| <- PPU A11 +// CPU D2 <> |05 24| <- PPU A10 | CPU D2 <> |05 24| <- NC | CPU D3 <> |05 24| <- PPU A10 +// CPU D1 <> |06 23| -> O0 | CPU D1 <> |06 23| -> NC | CPU D4 <> |06 23| -> CHR A13 +// CPU D0 <> |07 22| -> O1 | CPU D0 <> |07 22| -> NC | CPU D5 <> |07 22| -> CHR A14 +// CPU A0 -> |08 21| -> O2 | CPU A0 -> |08 21| -> NC | CPU A0 -> |08 21| -> NC +// CPU A1 -> |09 20| -> O3 | CPU A1 -> |09 20| -> NC | CPU A1 -> |09 20| -> NC +// CPU A8 -> |10 19| -> O4 | CPU A8 -> |10 19| -> NC | CPU A8 -> |10 19| -> NC +// M2 -> |11 18| -> O5 | M2 -> |11 18| -> NC | M2 -> |11 18| -> NC +// /ROMSEL -> |12 17| <- CHR /OE | /ROMSEL -> |12 17| <- CHR /OE | /ROMSEL -> |12 17| <- CHR /OE +// CPU R/W -> |13 16| <- CPU A13 | CPU R/W -> |13 16| <- NC | CPU R/W -> |13 16| <- CPU A13 +// 5V -- |14 15| <- CPU A14 | 5V -- |14 15| <- NC | 5V -- |14 15| <- CPU A14 +// '------' | '------' | '------' +struct JV001 { + auto writePRG(n16 address, n8 data) -> void { + address &= 0xe103; + switch (address) { + case 0x4100: if (increment) { + ++reg.bit(0,3); + } else { + reg.bit(0,3) = in ^ (invert ? 0x0f : 0); + } + return; + case 0x4101: invert = data.bit(0); + return; + case 0x4102: reg.bit(4,5) = data.bit(4,5); + in = data.bit(0,3); + return; + case 0x4103: increment = data.bit(0); + return; + default: out.bit(0,3) = reg.bit(0,3); + out.bit(4,5) = reg.bit(4,5) ^ (invert ? 0x03 : 0); + return; + } + } + + auto serialize(serializer& s) -> void { + s(reg); + s(invert); + s(in); + s(increment); + s(out); + } + + n6 reg; + n1 invert; + n4 in; + n1 increment; + n6 out; +}; diff --git a/ares/fc/cartridge/board/ic/txc05-00002-010.hpp b/ares/fc/cartridge/board/ic/txc05-00002-010.hpp new file mode 100644 index 0000000000..16e5998b07 --- /dev/null +++ b/ares/fc/cartridge/board/ic/txc05-00002-010.hpp @@ -0,0 +1,91 @@ +#pragma once +// TXC 05-00002-010 +// .--\/--. +// Q2 <- |01 24| -> Q3 +// Q1 <- |02 23| -> Q4 +// Q0 <- |03 22| -> o3 +// i1 -> |04 21| <- CPU A13 (rn) +// i0 -> |05 20| <- CPU A14 (rn) +// io2 <> |06 19| -- GND +// 5V -- |07 18| <- CPU R/W (n) +// D5 <> |08 17| <- /ROMSEL (rn) +// D4 <> |09 16| <- M2 (n) +// D2 <> |10 15| <- CPU A8 (rn) +// D1 <> |11 14| <- CPU A1 (rn) +// D0 <> |12 13| <- CPU A0 (rn) +// '------' +// 36 132 173 +// .--\/--. .--\/--. .--\/--. +// NC <- |01 24| -> NC (r) PRG A15 <- |01 24| -> NC NC <- |01 24| -> NC +// (r) PRG A16 <- |02 23| -> NC (r) CHR A14 <- |02 23| -> NC *(r) CHR A15 <- |02 23| -> NC +// (r) PRG A15 <- |03 22| -> NC (r) CHR A13 <- |03 22| -> NC (r) CHR A13 <- |03 22| -> CHR A14 +// GND -> |04 21| <- CPU A13 (rn) GND -> |04 21| <- CPU A13 (fr) GND -> |04 21| <- CPU A13 (fr) +// 5V -> |05 20| <- CPU A14 (rn) 5V -> |05 20| <- CPU A14 (fr) 5V -> |05 20| <- CPU A14 (fr) +// NC <> |06 19| -- GND NC <> |06 19| -- GND NC <> |06 19| <- GND +// 5V -- |07 18| <- CPU R/W (n) 5V -- |07 18| <- CPU R/W (f) 5V -- |07 18| <- CPU R/W (f) +// NC <> |08 17| <- /ROMSEL (rn) GND <> |08 17| <- /ROMSEL (fr) GND <> |08 17| <- /ROMSEL (fr) +// NC <> |09 16| <- M2 (n) (fr) CPU D3 <> |09 16| <- M2 (f) (fr) CPU D3 <> |09 16| <- M2 (f) +// NC <> |10 15| <- CPU A8 (rn) (fr) CPU D2 <> |10 15| <- CPU A8 (fr) (fr) CPU D2 <> |10 15| <- CPU A8 (fr) +// (rn) CPU D5 <> |11 14| <- CPU A1 (rn) (fr) CPU D1 <> |11 14| <- CPU A1 (fr) (fr) CPU D1 <> |11 14| <- CPU A1 (fr) +// (rn) CPU D4 <> |12 13| <- CPU A0 (rn) (fr) CPU D0 <> |12 13| <- CPU A0 (fr) (fr) CPU D0 <> |12 13| <- CPU A0 (fr) +// '------'` '------' '------' +// 173*: TXC pin 2 was routed to CHR ROM pin 1 on a 28-pin package. +// On a UVEPROM, this is A15. +// However, no games were ever released using more than 32 KiB of CHR. +// TXC 05-00002-010: 36/132/173 +struct TXC05_00002_010 { + auto writePRG(n16 address, n8 data) -> void { + address &= 0xe103; + switch (address) { + case 0x4100: if (increment) { + ++reg.bit(0,3); + } else { + reg.bit(0,3) = in ^ (invert ? 0x0f : 0); + } + return; + case 0x4101: invert = data.bit(0); + if (overdown) { + o3 = (invert ? io2 : i0) | data.bit(5); + } else { + io2 = invert ? i1 : i0; + o3 = io2 | data.bit(5); + } + return; + case 0x4102: reg.bit(4,5) = data.bit(4,5); + in.bit(0,2) = data.bit(0,2); + in.bit(3) = in.bit(3) ^ invert; + return; + case 0x4103: increment = data.bit(0); + return; + default: out.bit(0,3) = reg.bit(0,3); + out.bit(4) = reg.bit(4) ^ invert; + return; + } + } + + auto serialize(serializer& s) -> void { + s(i0); + s(i1); + s(io2); + s(o3); + + s(increment); + s(invert); + s(overdown); + s(reg); + s(in); + s(out); + } + + bool overdown; // io2 is using input or output flag + + // 4 pin + n1 i0, i1, io2, o3; + + n1 increment; + n1 invert; + n6 reg; + n4 in; + n5 out; +}; + diff --git a/ares/fc/cartridge/board/jv001.hpp b/ares/fc/cartridge/board/jv001.hpp deleted file mode 100644 index e36ebc2b0a..0000000000 --- a/ares/fc/cartridge/board/jv001.hpp +++ /dev/null @@ -1,48 +0,0 @@ -struct JV001 { - auto power() -> void { - in = 0; - out = 0; - reg = 0; - mode = 0; - invert = 1; - } - - auto write(n16 address, n8 data) -> void { - if (address >= 0x4100 && address < 0x4104) { - switch (address & 0x03) { - case 0: accumulator = mode ? (accumulator + 1) : (staging ^ (invert ? 0x0f : 0)); - if (!mode) regInverter = inverter; - break; - case 1: invert = data.bit(0); break; - case 2: in = data; break; - case 3: mode = data.bit(0); break; - } - } - - if (address >= 0x8000) - out = reg; - } - - auto read() -> n8 { - return (regInverter ^ (invert ? 0x03 : 0)) << 4 | accumulator; - } - - auto serialize(serializer& s) -> void { - s(in); - s(out); - s(reg); - s(mode); - s(invert); - } - - n6 in; - n6 out; - n6 reg; - n1 mode; // increase - n1 invert; - - BitRange<6, 0, 3> staging{&in}; - BitRange<6, 4, 5> inverter{&in}; - BitRange<6, 0, 3> accumulator{®}; - BitRange<6, 4, 5> regInverter{®}; -}; diff --git a/ares/fc/cartridge/board/unl-txc.cpp b/ares/fc/cartridge/board/unl-txc.cpp index 74080dddc0..9d08a8710c 100644 --- a/ares/fc/cartridge/board/unl-txc.cpp +++ b/ares/fc/cartridge/board/unl-txc.cpp @@ -1,20 +1,13 @@ +// TXC-22211A: Mapper 132 // TXC-22211B: Mapper 172 -// 1991 賭馬 Racing (1991 Dǔmǎ Racing, "Enjoyable Horse Racing") -// 麻将方块 (Mahjong Block) (original release) -// Venice Beach Volley (Super Mega release) struct TXC : Interface { - static auto create(string id) -> Interface* { - // if (id == "TXC-22211A") return new TXC(Revision::TXC_22211A); - if (id == "TXC-22211B") return new TXC(Revision::TXC_22211B); - // if (id == "TXC-22211C") return new TXC(Revision::TXC_22211C); - return nullptr; - } + static auto create(string id) -> Interface*; enum class Revision : u32 { - // TXC_22211A, + TXC_22211A, TXC_22211B, - // TXC_22211C, + TXC_22211C, } revision; TXC(Revision revision) : revision(revision) {} @@ -26,56 +19,116 @@ struct TXC : Interface { Interface::load(programROM, "program.rom"); Interface::load(characterROM, "character.rom"); } +}; + +struct TXC_22211AC : TXC { + TXC_22211AC(Revision revision) : TXC(revision) {} auto readPRG(n32 address, n8 data) -> n8 override { - if (address >= 0x4100 && address < 0x4104 && revision == Revision::TXC_22211B) { - data = data & 0xc0 | bit::reverse(jv001.read()) >> 2; - chrBank = jv001.out.bit(0, 1); - mirror = jv001.invert; + if ((address & 0xe100) == 0x4100) { + data &= 0xf0; + data.bit(0,2) = txc.reg.bit(0,2); + data.bit(3) = txc.reg.bit(4); return data; } if (address < 0x8000) return data; + if (revision == Revision::TXC_22211A) + address = txc.out.bit(2) << 15 | (n15)address; + + return programROM.read(address); + } + + auto writePRG(n32 address, n8 data) -> void override { + if ((address & 0xe100) == 0x4100) { + txc.writePRG(address, data.bit(3) << 4 | data.bit(0,2)); + } + if (address < 0x8000) return; + + txc.writePRG(address, data.bit(3) << 4 | data.bit(0,2)); + } + + auto readCHR(n32 address, n8 data) -> n8 override { + if (address & 0x2000) return ppu.readCIRAM((n11)address); + + if (revision == Revision::TXC_22211A) + address = txc.out.bit(0,1) << 13 | (n13)address; + else + address = txc.out.bit(1) << 15 | txc.o3 << 14 | txc.out.bit(0) << 13 | (n13)address; + + return characterROM.read(address); + } + + auto writeCHR(n32 address, n8 data) -> void override { + if (address & 0x2000) return ppu.writeCIRAM((n11)address, data); + } + + auto power() -> void override { + txc = {}; + txc.overdown = false; + txc.i0 = 1; + txc.i1 = 0; + } + + auto serialize(serializer& s) -> void override { + s(txc); + } + + TXC05_00002_010 txc; +}; + +struct TXC_22211B : TXC { + TXC_22211B() : TXC(Revision::TXC_22211B) {} + + auto readPRG(n32 address, n8 data) -> n8 override { + if ((address & 0xe100) == 0x4100) { + n8 v = (jv001.reg.bit(4,5) ^ (jv001.invert ? 3 : 0)) << 4; + v |= jv001.reg.bit(0,3); + return data & 0xc0 | bit::reverse(v) >> 2; + } + if (address < 0x8000) return data; + return programROM.read((n15)address); } auto writePRG(n32 address, n8 data) -> void override { - if (revision == Revision::TXC_22211B) - return jv001.write(address, bit::reverse(data) >> 2); + if ((address & 0xe100) == 0x4100) + return jv001.writePRG(address, bit::reverse(data) >> 2); if (address < 0x8000) return; - chrBank = jv001.out.bit(0, 1); - mirror = jv001.invert; + return jv001.writePRG(address, bit::reverse(data) >> 2); } auto readCHR(n32 address, n8 data) -> n8 override { if (address & 0x2000) { - address = (address >> mirror & 0x0400) | (n10)address; + address = (address >> !jv001.invert & 0x0400) | (n10)address; return ppu.readCIRAM(address); } - - return characterROM.read(chrBank << 13 | (n13)address); + return characterROM.read(jv001.out.bit(0,1) << 13 | (n13)address); } auto writeCHR(n32 address, n8 data) -> void override { if (address & 0x2000) { - address = (address >> mirror & 0x0400) | (n10)address; + address = (address >> !jv001.invert & 0x0400) | (n10)address; return ppu.writeCIRAM(address, data); } } auto power() -> void override { jv001 = {}; - mirror = 0; } auto serialize(serializer& s) -> void override { s(jv001); - s(chrBank); - s(mirror); } JV001 jv001; - n2 chrBank; - n1 mirror; }; + +auto TXC::create(string id) -> Interface* { + if (id == "UNL-22211" ) return new TXC_22211AC(Revision::TXC_22211A); + if (id == "TXC-22211A") return new TXC_22211AC(Revision::TXC_22211A); + if (id == "TXC-22211B") return new TXC_22211B(); + if (id == "TXC-22211C") return new TXC_22211AC(Revision::TXC_22211C); + return nullptr; +} diff --git a/ares/fc/system/serialization.cpp b/ares/fc/system/serialization.cpp index 9369974925..382f56b9a7 100644 --- a/ares/fc/system/serialization.cpp +++ b/ares/fc/system/serialization.cpp @@ -1,4 +1,4 @@ -static const string SerializerVersion = "v144"; +static const string SerializerVersion = "v145"; auto System::serialize(bool synchronize) -> serializer { if(synchronize) scheduler.enter(Scheduler::Mode::Synchronize); diff --git a/mia/medium/famicom.cpp b/mia/medium/famicom.cpp index 09cd1e07c8..854ec68b1c 100644 --- a/mia/medium/famicom.cpp +++ b/mia/medium/famicom.cpp @@ -601,6 +601,10 @@ auto Famicom::analyzeINES(vector& data) -> string { if(!iNes2) chrram = 8192; break; + case 132: + s += " board: TXC-22211A\n"; + break; + case 140: s += " board: JALECO-JF-11\n"; s +={" mirror mode=", !mirror ? "horizontal" : "vertical", "\n"}; @@ -651,6 +655,10 @@ auto Famicom::analyzeINES(vector& data) -> string { s += " board: TXC-22211B\n"; break; + case 173: + s += " board: TXC-22211C\n"; + break; + case 180: s += " board: HVC-UNROMA\n"; s +={" mirror mode=", !mirror ? "horizontal" : "vertical", "\n"};