diff --git a/share/extensions/fujinet-config.rom b/share/extensions/fujinet-config.rom index cffb8c66c4..ccaac6018a 100644 Binary files a/share/extensions/fujinet-config.rom and b/share/extensions/fujinet-config.rom differ diff --git a/src/serial/FujiNet.cc b/src/serial/FujiNet.cc index f35e6fb22b..367620243f 100644 --- a/src/serial/FujiNet.cc +++ b/src/serial/FujiNet.cc @@ -1,3 +1,4 @@ +#undef UNUSED #include "FujiNet.hh" #include "FujiBusPacket.h" #include "Timer.hh" @@ -25,10 +26,14 @@ FujiNet::FujiNet(DeviceConfig& config) : MSXDevice(config) , rom(getName() + " ROM", "rom", config) , userRom(0) + , debugMode( + getCommandController(), "fujinet_debug", + "Enable FujiNet debug logging", false) { thread = std::thread(&FujiNet::readSocket, this); stopReading = false; userRomEnabled = false; + userRomLoaded = false; } FujiNet::~FujiNet() @@ -52,7 +57,9 @@ void FujiNet::close() void FujiNet::readSocket() { - getCliComm().printInfo("FujiNet: Start read loop"); + if (debugMode.getBoolean()) { + getCliComm().printInfo("FujiNet: Start read loop"); + } char buf[MAX_BUF_LEN]; while (!stopReading) { @@ -86,9 +93,11 @@ void FujiNet::readSocket() continue; } else if (n > 0) { - getCliComm().printInfo("FujiNet: Read ", n, " bytes from pty"); - std::string str(buf, n); - getCliComm().printInfo(str); + if (debugMode.getBoolean()) { + getCliComm().printInfo("FujiNet: Read ", n, " bytes from pty"); + std::string str(buf, n); + getCliComm().printInfo(str); + } std::lock_guard lock(mtx); for (auto i : xrange(std::min(n, MAX_BUF_LEN - rxBuffer.size()))) { rxBuffer.push_back(buf[i]); @@ -113,20 +122,26 @@ void FujiNet::handleDBCCommand(std::unique_ptr packet) switch (packet->command()) { case FUJICMD_OPEN: - getCliComm().printInfo("FUJICMD_OPEN"); + if (debugMode.getBoolean()) { + getCliComm().printInfo("FUJICMD_OPEN"); + } clearUserROM(); fujiBusAck(); break; case FUJICMD_WRITE: - getCliComm().printInfo("FUJICMD_WRITE"); + if (debugMode.getBoolean()) { + getCliComm().printInfo("FUJICMD_WRITE"); + } if (packet->data()) writeUserROM(*(packet->data())); fujiBusAck(); break; case FUJICMD_CLOSE: - getCliComm().printInfo("FUJICMD_CLOSE"); + if (debugMode.getBoolean()) { + getCliComm().printInfo("FUJICMD_CLOSE"); + } if (userRom.size()) - enableUserROM(); + readyUserROM(); fujiBusAck(); break; default: @@ -155,6 +170,7 @@ void FujiNet::fujiBusAck() void FujiNet::clearUserROM() { + userRomLoaded = false; userRom.clear(); } @@ -165,6 +181,11 @@ void FujiNet::writeUserROM(std::span data) } } +void FujiNet::readyUserROM() +{ + userRomLoaded = true; +} + void FujiNet::enableUserROM() { userRomEnabled = true; @@ -182,37 +203,48 @@ void FujiNet::reset(EmuTime /*time*/) uint8_t FujiNet::readMem(uint16_t address, EmuTime time) { - getCliComm().printInfo("FujiNet: readMem() ", address); + if (debugMode.getBoolean()) { + getCliComm().printInfo("FujiNet: readMem() ", address); + } auto value = peekMem(address, time); switch (address) { case IO_GETC_ADDR: if (!rxBuffer.empty()) { std::lock_guard lock(mtx); rxBuffer.pop_front(); - char formatted[16]; - if (value > 31 && value < 127) { - sprintf(formatted, "$%02X %c", value, value); - } else { - sprintf(formatted, "$%02X", value); - } - getCliComm().printInfo("FujiNet: GETC -> ", formatted); + if (debugMode.getBoolean()) { + char formatted[16]; + if (value > 31 && value < 127) { + sprintf(formatted, "$%02X %c", value, value); + } else { + sprintf(formatted, "$%02X", value); + } + getCliComm().printInfo("FujiNet: GETC -> ", formatted); + } } else { - getCliComm().printInfo("FujiNet: GETC -> empty!"); + if (debugMode.getBoolean()) { + getCliComm().printInfo("FujiNet: GETC -> empty!"); + } } break; case IO_STATUS_ADDR: - if (value == 0b10000000) { - getCliComm().printInfo("FujiNet: STAT -> data available"); - } else { - getCliComm().printInfo("FujiNet: STAT -> no data"); - } + if (debugMode.getBoolean()) { + if (value == 0b10000000) { + getCliComm().printInfo("FujiNet: STAT -> data available"); + } else { + getCliComm().printInfo("FujiNet: STAT -> no data"); + } + } + ; } return value; } uint8_t FujiNet::peekMem(uint16_t address, EmuTime /*time*/) const { - getCliComm().printInfo("FujiNet: peekMem() ", address); + if (debugMode.getBoolean()) { + getCliComm().printInfo("FujiNet: peekMem() ", address); + } switch (address) { case IO_GETC_ADDR: { std::lock_guard lock(mtx); @@ -222,11 +254,15 @@ uint8_t FujiNet::peekMem(uint16_t address, EmuTime /*time*/) const return 0x00; } case IO_STATUS_ADDR: { + // bit 7 when 1 means data available + // bit 6 when 1 means user rom is ready + // bit 6 when 0 means user rom is not ready std::lock_guard lock(mtx); + uint8_t status = (userRomLoaded ? 0x40 : 0x00); if (!rxBuffer.empty()) { - return 0x80; // data available + status |= 0x80; } - return 0x00; + return status; } default: if (address < 0x4000 || 0xC000 <= address) return 0xFF; @@ -241,12 +277,14 @@ void FujiNet::writeMem(uint16_t address, uint8_t value, EmuTime /*time*/) switch (address) { case IO_PUTC_ADDR: // IO_PUTC if (sock != OPENMSX_INVALID_SOCKET) { - char formatted[16]; - if (value > 31 && value < 127) - sprintf(formatted, "$%02X %c", value, value); - else - sprintf(formatted, "$%02X", value); - // getCliComm().printInfo("FujiNet: PUTC ", formatted); + if (debugMode.getBoolean()) { + char formatted[16]; + if (value > 31 && value < 127) + sprintf(formatted, "$%02X %c", value, value); + else + sprintf(formatted, "$%02X", value); + getCliComm().printInfo("FujiNet: PUTC ", formatted); + } // txBuffer.push_back(value); // if (value == SLIP_END) { @@ -277,6 +315,17 @@ void FujiNet::writeMem(uint16_t address, uint8_t value, EmuTime /*time*/) (void)res; // ignore error } return; + case IO_CONTROL_ADDR: + // when writing if bit 7 is high that signals "switch rom to bank" + // bits 6~1 is reserved and must be 0 + // when bit 0 is 1 that means switching to user rom + // when bit 0 is 0 that means switching to config rom + if (value == 0x81) { + enableUserROM(); + } else if (value == 0x80){ + disableUserROM(); + } + return; default: break; } diff --git a/src/serial/FujiNet.hh b/src/serial/FujiNet.hh index b7036c8ac0..fcaaa8341f 100644 --- a/src/serial/FujiNet.hh +++ b/src/serial/FujiNet.hh @@ -8,6 +8,7 @@ #include "Socket.hh" #include "Rom.hh" #include "Poller.hh" +#include "BooleanSetting.hh" #include "circular_buffer.hh" @@ -44,12 +45,15 @@ private: void clearUserROM(); void writeUserROM(std::span data); + void readyUserROM(); void enableUserROM(); void disableUserROM(); Rom rom; std::vector userRom; bool userRomEnabled; + bool userRomLoaded; + BooleanSetting debugMode; std::thread thread; // receiving thread (reads from pty) Poller poller; // to abort read-thread in a portable way mutable std::mutex mtx; // to protect shared data between emulation and receiving thread