Skip to content

Commit

Permalink
feat(fc): add board support TXC-22211A/C(132/173) (ares-emulator#1530)
Browse files Browse the repository at this point in the history
add TXC-22211A
  add TXC-22211C
  fix TXC-22211B mirror
  pass issue ares-emulator#755 
  pass issue ares-emulator#756
  • Loading branch information
ZengGengSen authored Jun 14, 2024
1 parent d7dfae7 commit 4e97f23
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 78 deletions.
3 changes: 2 additions & 1 deletion ares/fc/cartridge/board/board.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace Board {
#include "jv001.hpp"
#include "ic/jv001.hpp"
#include "ic/txc05-00002-010.hpp"

struct Interface {
VFS::Pak pak;
Expand Down
55 changes: 55 additions & 0 deletions ares/fc/cartridge/board/ic/jv001.hpp
Original file line number Diff line number Diff line change
@@ -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;
};
91 changes: 91 additions & 0 deletions ares/fc/cartridge/board/ic/txc05-00002-010.hpp
Original file line number Diff line number Diff line change
@@ -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;
};

48 changes: 0 additions & 48 deletions ares/fc/cartridge/board/jv001.hpp

This file was deleted.

109 changes: 81 additions & 28 deletions ares/fc/cartridge/board/unl-txc.cpp
Original file line number Diff line number Diff line change
@@ -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) {}
Expand All @@ -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;
}
2 changes: 1 addition & 1 deletion ares/fc/system/serialization.cpp
Original file line number Diff line number Diff line change
@@ -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);
Expand Down
8 changes: 8 additions & 0 deletions mia/medium/famicom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,10 @@ auto Famicom::analyzeINES(vector<u8>& 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"};
Expand Down Expand Up @@ -651,6 +655,10 @@ auto Famicom::analyzeINES(vector<u8>& 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"};
Expand Down

0 comments on commit 4e97f23

Please sign in to comment.