Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Visual Studio Code workspace files
# IDE/editor files
*.code-workspace
**/.vscode
.vs/
.zed

# PlatformIO build directory
**/.pio
Expand Down
7,770 changes: 7,770 additions & 0 deletions data/webui/device_specific/BUILD_RS232/msxromdb.txt

Large diffs are not rendered by default.

7,770 changes: 7,770 additions & 0 deletions distfiles/SD/msxromdb.txt

Large diffs are not rendered by default.

735 changes: 368 additions & 367 deletions fujinet_pc.cmake

Large diffs are not rendered by default.

44 changes: 44 additions & 0 deletions include/romType.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#ifndef FUJI_ROM_TYPE_H
#define FUJI_ROM_TYPE_H

#include <stdint.h>

#define R_16K 0b10000000
#define R_8K 0b00000000
#define R_PG0 0b00000000
#define R_PG1 0b00100000
#define R_PG2 0b01000000
#define R_PG3 0b01100000

enum fujiROMType_t : uint8_t {
ROM_TYPE_UNKNOWN = 0x00,

// ----------------------------------------
// MSX ROM Types
//
// High 3 bits uses to indicate block size and page offset.
// Not currently used for anything. Low 5 bits are just an arbitrary ID.
// 0 0 0 0 0 0 0 0
// |_| |___| |_________|
// | | |
// | | +-- ID (0-32)
// | +-- page offset
// +-- 16KB blocks?
//
//
// 16K Blocks
ROM_TYPE_MSX_PLAIN_PAGE_0 = 0x01 | R_16K | R_PG0,
ROM_TYPE_MSX_PLAIN = 0x01 | R_16K | R_PG1,
ROM_TYPE_MSX_PLAIN_PAGE_1 = 0x01 | R_16K | R_PG1,
ROM_TYPE_MSX_PLAIN_PAGE_2 = 0x01 | R_16K | R_PG2,
ROM_TYPE_MSX_PLAIN_PAGE_3 = 0x01 | R_16K | R_PG3,
ROM_TYPE_MSX_MIRRORED = 0x02 | R_16K | R_PG1,
ROM_TYPE_MSX_ASCII16 = 0x03 | R_16K | R_PG1,
// 8K Blocks
ROM_TYPE_MSX_ASCII8 = 0x01 | R_8K | R_PG1,
ROM_TYPE_MSX_KONAMI = 0x02 | R_8K | R_PG1,
ROM_TYPE_MSX_KONAMI_SCC = 0x03 | R_8K | R_PG1,
// ----------------------------------------
};

#endif // FUJI_ROM_TYPE
50 changes: 38 additions & 12 deletions lib/device/rs232/disk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@
#include "disk.h"
#include "fujiCommandID.h"

#include <cstdint>
#include <cstring>
#include <algorithm>

#include "../../include/debug.h"

#include "fujiDevice.h"
#include "rs232/diskType.h"
#include "rs232/romIdentifier.h"
#include "romType.h"
#include "utils.h"

rs232Disk::rs232Disk()
Expand Down Expand Up @@ -195,14 +200,11 @@ mediatype_t rs232Disk::mount(fnFile *f, const char *filename, uint32_t disksize,
if (disk_type == MEDIATYPE_UNKNOWN && filename != nullptr)
disk_type = MediaType::discover_mediatype(filename);

// TODO: Stupid hack to treat ROM-sized files as ROMs and not disks. Should be
// replaced with proper ROM-handling logic
if (disksize == 8192 || disksize == 16384 || disksize == 32768)
return mountROM(f, filename, disksize, disk_type);

// Now mount based on MediaType
switch (disk_type)
{
case MEDIATYPE_ROM:
return mountROM(f, filename, disksize, disk_type);
case MEDIATYPE_IMG:
case MEDIATYPE_UNKNOWN:
default:
Expand All @@ -221,28 +223,52 @@ mediatype_t rs232Disk::mount_disk_media(fnFile *f, const char *filename, uint32_

mediatype_t rs232Disk::mountROM(fnFile *f, const char *filename, uint32_t disksize, mediatype_t disk_type)
{
uint32_t offset, rlen, sectorNum;
uint32_t offset, len, sectorNum;
uint16_t i;
uint32_t chunk_size = 512;
MediaTypeImg romImage;

// Lazily instantiate RomIdentifier -- loads 500K ROM DB into memory
if (_romIdentifier == nullptr) {
_romIdentifier = new RomIdentifier;
}

romImage.mount(f, disksize);

// Read in full ROM to identify it
std::vector<uint8_t> romData;
for (offset = sectorNum = 0; offset < disksize; offset += len, sectorNum++)
{
if (romImage.read(sectorNum, &len) != 0)
break;
for (i = 0; i < len; i++)
romData.push_back(romImage._disk_sectorbuff[i]);
}

// TODO: Don't assume MSX
// TODO: Should this be a sub-type of the MediaType z?
fujiROMType_t romType = _romIdentifier->identify_rom_type(romData);
if (romType == ROM_TYPE_UNKNOWN)
romType = ROM_TYPE_MSX_PLAIN;

Debug_printv("Attempting to send ROM contents to pico");
// "open" RAM in bank
if (!SYSTEM_BUS.sendCommand(FUJI_DEVICEID_DBC, NETCMD_OPEN, (uint16_t) 0)) {
if (!SYSTEM_BUS.sendCommand(FUJI_DEVICEID_DBC, NETCMD_OPEN, (uint16_t) 0, (uint8_t) romType)) {
Debug_printv("Failed to open pico");
return (mediatype_t) -1;
}

for (offset = sectorNum = 0; offset < disksize; offset += rlen, sectorNum++)
offset = 0;
len = 0;
while (offset < disksize)
{
if (romImage.read(sectorNum, &rlen) != 0)
break;
if (!SYSTEM_BUS.sendCommand(FUJI_DEVICEID_DBC, NETCMD_WRITE,
std::string((char *) romImage._disk_sectorbuff, rlen))) {
if (!SYSTEM_BUS.sendCommand(FUJI_DEVICEID_DBC, NETCMD_WRITE,
std::string(romData.begin() + offset, romData.begin() + offset + len))) {
Debug_printv("Failed to send block");
break;
}
offset += len;
len = std::min(disksize - offset, chunk_size);
}

// "closing" RAM will make the bank active
Expand Down
2 changes: 2 additions & 0 deletions lib/device/rs232/disk.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
#include "../disk.h"
#include "bus.h"
#include "media.h"
#include "rs232/romIdentifier.h"

class rs232Disk : public virtualDevice
{
private:
MediaType *_disk = nullptr;
time_t _mount_time = 0;
RomIdentifier *_romIdentifier = nullptr;

void rs232_read(uint32_t sector);
void rs232_write(uint32_t sector, bool verify);
Expand Down
4 changes: 4 additions & 0 deletions lib/media/rs232/diskType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ mediatype_t MediaType::discover_mediatype(const char *filename)
{
return MEDIATYPE_IMG;
}
else if (strcasecmp(ext, "ROM") == 0)
{
return MEDIATYPE_ROM;
}
}
return MEDIATYPE_UNKNOWN;
}
Expand Down
3 changes: 2 additions & 1 deletion lib/media/rs232/diskType.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ enum mediatype_t
{
MEDIATYPE_UNKNOWN = 0,
MEDIATYPE_IMG,
MEDIATYPE_COUNT
MEDIATYPE_COUNT,
MEDIATYPE_ROM,
};

class MediaType
Expand Down
96 changes: 96 additions & 0 deletions lib/media/rs232/romIdentifier.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#include <cstdint>
#include <fstream>
#include <string>

#include "debug.h"
#include "fnFsSD.h"
#include "fnFsSPIFFS.h"
#include "fsFlash.h"
#include "rs232/diskTypeImg.h"
#include "string_utils.h"
#include "romType.h"

#include "romIdentifier.h"

std::map<std::string, fujiROMType_t> name_to_type = {
{"ASCII8", ROM_TYPE_MSX_ASCII8},
{"ASCII16", ROM_TYPE_MSX_ASCII16},
{"Konami", ROM_TYPE_MSX_KONAMI},
{"KonamiSCC", ROM_TYPE_MSX_KONAMI_SCC},
};

RomIdentifier::RomIdentifier(void)
{
Debug_printf("RomIdentifier::RomIdentifier\n");
// TODO: Read from config to allow override
load_db();
}

RomIdentifier::~RomIdentifier(void)
{
return;
}

bool RomIdentifier::load_db()
{
FILE *fin = NULL; //declare fin
if (fnSDFAT.running() && fnSDFAT.exists(ROM_DB_FILENAME))
{
Debug_printf("Loading ROM database (%s) from SD\n", ROM_DB_FILENAME);
fin = fnSDFAT.file_open(ROM_DB_FILENAME);
}
else if (fsFlash.running() && fsFlash.exists(ROM_DB_FILENAME))
{
Debug_println("Loading ROM database from flash");
fin = fsFlash.file_open(ROM_DB_FILENAME);
}

if (fin == nullptr)
{
Debug_println("Failed to load ROM database");
return false;
}

char line[64];
while (fgets(line, 64, fin))
{
std::string row = std::string(line);
if (row.size() < 40)
continue;
size_t split = row.find("\t");
std::string sha1 = row.substr(0, split);
std::string type_str = row.substr(split + 1, row.size() - split - 2);
sha1_to_type[sha1] = get_type_from_name(type_str);
}

return true;
}

fujiROMType_t RomIdentifier::get_type_from_name(std::string name) {
auto it = name_to_type.find(name);
if (it != name_to_type.end()) {
return it->second;
}
return ROM_TYPE_UNKNOWN;
}

fujiROMType_t RomIdentifier::get_type_for_sha1(std::string sha1) {
auto it = sha1_to_type.find(sha1);
if (it != sha1_to_type.end()) {
return it->second;
}
return ROM_TYPE_UNKNOWN;
}

fujiROMType_t RomIdentifier::identify_rom_type(std::vector<uint8_t> rom_data)
{
std::string rom_str(rom_data.begin(), rom_data.end());
std::string sha1 = mstr::sha1(rom_str);
Debug_printf("RomIdentifier sha1: %s\n", sha1.c_str());
if (sha1 == "") {
return ROM_TYPE_UNKNOWN;
}
fujiROMType_t t = get_type_for_sha1(sha1);
Debug_printf("RomIdentifier fujiROMType t: %u\n", t);
return t;
}
28 changes: 28 additions & 0 deletions lib/media/rs232/romIdentifier.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef ROM_IDENTIFIER_H
#define ROM_IDENTIFIER_H

#include <map>
#include <string>

#include "romType.h"
#include "diskTypeImg.h"

#define ROM_DB_FILENAME "/msxromdb.txt"

class RomIdentifier
{
private:
std::map<std::string, fujiROMType_t> sha1_to_type;
std::string db_filepath;
bool load_db();

public:
RomIdentifier();
~RomIdentifier();
fujiROMType_t get_type_for_sha1(std::string sha1);
fujiROMType_t get_type_from_name(std::string name);
fujiROMType_t identify_rom_type(std::vector<uint8_t> rom_data);

};

#endif // ROM_INDENTFIER_H
Loading
Loading