fc: reuse shared X24C01 for Datach EEPROM

This commit is contained in:
ZengGengSen
2026-09-14 22:37:33 +01:00
committed by Luke Usher
parent e40b0db1ed
commit b71dabe7a9
4 changed files with 17 additions and 138 deletions
-1
View File
@@ -157,7 +157,6 @@ ares_add_sources(
CORE #
fc
INCLUDED #
cartridge/board/ic/bandai-24c01.hpp
cartridge/board/ic/jv001.hpp
cartridge/board/ic/txc05-00002-010.hpp
)
+17 -9
View File
@@ -5,20 +5,20 @@ struct BandaiDatach : BandaiLZ93D50 {
return nullptr;
}
Bandai24C01 external;
bool hasExternal = false;
M24C external;
auto load() -> void override {
BandaiLZ93D50::load();
if(auto fp = pak->read("external.eeprom")) {
if(hasExternal = fp->size() == 128) fp->read(external.memory, 128);
if(fp->size() == 128) external.load(M24C::Type::X24C01);
if(external) fp->read(external.memory, external.size());
}
}
auto save() -> void override {
BandaiLZ93D50::save();
if(hasExternal) {
if(auto fp = pak->write("external.eeprom")) fp->write(external.memory, 128);
if(external) {
if(auto fp = pak->write("external.eeprom")) fp->write(external.memory, external.size());
}
}
@@ -26,7 +26,7 @@ struct BandaiDatach : BandaiLZ93D50 {
data = BandaiLZ93D50::readPRG(address, data);
if(address >= 0x6000 && address < 0x8000) {
data.bit(3) = 0; //idle barcode signal
if(hasExternal) data.bit(4) = data.bit(4) && external.read();
if(external) data.bit(4) = data.bit(4) && external.read();
}
return data;
}
@@ -35,11 +35,19 @@ struct BandaiDatach : BandaiLZ93D50 {
if(address < 0x8000) return;
auto reg = address & 15;
if(reg <= 7) {
if(reg <= 3 && hasExternal) external.write(data.bit(3), external.data);
if(reg <= 3 && external) {
external.clock = data.bit(3);
external.data = external.data();
external.write();
}
return;
}
BandaiLZ93D50::writePRG(address, data);
if(reg == 13 && hasExternal) external.write(external.clock, data.bit(6));
if(reg == 13 && external) {
external.clock = external.clock();
external.data = data.bit(6);
external.write();
}
}
auto power() -> void override {
@@ -49,6 +57,6 @@ struct BandaiDatach : BandaiLZ93D50 {
auto serialize(serializer& s) -> void override {
BandaiLZ93D50::serialize(s);
if(hasExternal) s(external);
s(external);
}
};
-1
View File
@@ -1,5 +1,4 @@
namespace Board {
#include "ic/bandai-24c01.hpp"
#include "ic/jv001.hpp"
#include "ic/txc05-00002-010.hpp"
-127
View File
@@ -1,127 +0,0 @@
#pragma once
//LSB-first 24C01 serial interface used by Bandai Datach cartridges.
struct Bandai24C01 {
auto power() -> void {
mode = Mode::Standby;
clock = data = response = 1;
counter = address = input = output = reading = pending = 0;
for(auto& byte : page) byte = 0;
}
auto read() const -> bool {
return response;
}
auto write(bool scl, bool sda) -> void {
if(clock && scl && data && !sda) {
mode = Mode::Address;
counter = address = pending = 0;
response = 1;
} else if(clock && scl && !data && sda) {
//The four-byte page buffer is programmed on STOP. Programming is instantaneous.
for(u32 index : range(4)) {
if(pending.bit(index)) memory[(address & 0x7c) | index] = page[index];
}
pending = 0;
mode = Mode::Standby;
response = 1;
} else if(!clock && scl) {
switch(mode) {
case Mode::Address:
if(counter < 7) address.bit(counter++) = sda;
else if(counter == 7) reading = sda, counter++;
break;
case Mode::Read:
if(counter < 8) counter++;
break;
case Mode::ReadAck:
reading = !sda;
break;
case Mode::Write:
if(counter < 8) input.bit(counter++) = sda;
break;
default:
break;
}
} else if(clock && !scl) {
switch(mode) {
case Mode::Address:
if(counter == 8) mode = Mode::AddressAck, response = 0;
break;
case Mode::AddressAck:
counter = 0;
mode = reading ? Mode::Read : Mode::Write;
output = memory[address];
response = reading ? output.bit(0) : 1;
break;
case Mode::Read:
if(counter == 8) {
mode = Mode::ReadAck;
response = 1;
} else {
response = output.bit(counter);
}
break;
case Mode::ReadAck:
if(reading) {
address++;
counter = 0;
output = memory[address];
response = output.bit(0);
mode = Mode::Read;
} else {
mode = Mode::Standby;
response = 1;
}
break;
case Mode::Write:
if(counter == 8) {
page[address.bit(0,1)] = input;
pending.bit(address.bit(0,1)) = 1;
address.bit(0,1)++;
mode = Mode::WriteAck;
response = 0;
}
break;
case Mode::WriteAck:
mode = Mode::Write;
counter = 0;
response = 1;
break;
default:
break;
}
}
clock = scl;
data = sda;
}
auto serialize(serializer& s) -> void {
s(memory);
s(clock);
s(data);
s((u32&)mode);
s(counter);
s(address);
s(input);
s(output);
s(reading);
s(response);
s(page);
s(pending);
}
n8 memory[128];
n1 clock = 1;
n1 data = 1;
private:
enum class Mode : u32 { Standby, Address, AddressAck, Read, ReadAck, Write, WriteAck };
Mode mode = Mode::Standby;
n4 counter;
n7 address;
n8 input;
n8 output;
n1 reading;
n1 response = 1;
n8 page[4];
n4 pending;
};