Skip to content

Commit

Permalink
RomAscii16X: ASCII16-X mapper support.
Browse files Browse the repository at this point in the history
  • Loading branch information
grauw committed May 20, 2024
1 parent bd707fb commit 19da0a8
Show file tree
Hide file tree
Showing 11 changed files with 221 additions and 1 deletion.
2 changes: 2 additions & 0 deletions build/msvc/openmsx.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@
<ClCompile Include="$(OpenMSXSrcDir)\memory\RomArc.cc" />
<ClCompile Include="$(OpenMSXSrcDir)\memory\RomAscii16_2.cc" />
<ClCompile Include="$(OpenMSXSrcDir)\memory\RomAscii16kB.cc" />
<ClCompile Include="$(OpenMSXSrcDir)\memory\RomAscii16X.cc" />
<ClCompile Include="$(OpenMSXSrcDir)\memory\RomAscii8_8.cc" />
<ClCompile Include="$(OpenMSXSrcDir)\memory\RomAscii8kB.cc" />
<ClCompile Include="$(OpenMSXSrcDir)\memory\RomBlocks.cc" />
Expand Down Expand Up @@ -1134,6 +1135,7 @@
<None Include="$(OpenMSXSrcDir)\memory\RomArc.hh" />
<None Include="$(OpenMSXSrcDir)\memory\RomAscii16_2.hh" />
<None Include="$(OpenMSXSrcDir)\memory\RomAscii16kB.hh" />
<None Include="$(OpenMSXSrcDir)\memory\RomAscii16X.hh" />
<None Include="$(OpenMSXSrcDir)\memory\RomAscii8_8.hh" />
<None Include="$(OpenMSXSrcDir)\memory\RomAscii8kB.hh" />
<None Include="$(OpenMSXSrcDir)\memory\RomBlocks.hh" />
Expand Down
6 changes: 6 additions & 0 deletions build/msvc/openmsx.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,9 @@
<ClCompile Include="$(OpenMSXSrcDir)\memory\RomAscii16kB.cc">
<Filter>memory</Filter>
</ClCompile>
<ClCompile Include="$(OpenMSXSrcDir)\memory\RomAscii16X.cc">
<Filter>memory</Filter>
</ClCompile>
<ClCompile Include="$(OpenMSXSrcDir)\memory\RomAscii8_8.cc">
<Filter>memory</Filter>
</ClCompile>
Expand Down Expand Up @@ -2257,6 +2260,9 @@
<None Include="$(OpenMSXSrcDir)\memory\RomAscii16kB.hh">
<Filter>memory</Filter>
</None>
<None Include="$(OpenMSXSrcDir)\memory\RomAscii16X.hh">
<Filter>memory</Filter>
</None>
<None Include="$(OpenMSXSrcDir)\memory\RomAscii8_8.hh">
<Filter>memory</Filter>
</None>
Expand Down
25 changes: 25 additions & 0 deletions share/extensions/ASCII16-X_Mapper_XL.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" ?>
<!DOCTYPE msxconfig SYSTEM 'msxconfig2.dtd'>
<msxconfig>
<info>
<name>ASCII16-X Mapper XL</name>
<manufacturer>Grauw</manufacturer>
<code>ASCII16-X</code>
<release_year>2024</release_year>
<description>ASCII16-X Mapper Extra Large (XL) 8 MB</description>
<type>Flash cartridge</type>
</info>
<devices>
<primary slot="any">
<secondary slot="any">
<ASCII16-X id="ASCII16-X Mapper XL">
<mem base="0x0000" size="0x10000"/>
<rom>
<size>8192</size>
</rom>
<sramname>ASCII16-X_Mapper_XL.sram</sramname>
</YamahaSFG>
</secondary>
</primary>
</devices>
</msxconfig>
3 changes: 3 additions & 0 deletions src/DeviceFactory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
#include "DebugDevice.hh"
#include "V9990.hh"
#include "Video9000.hh"
#include "RomAscii16X.hh"
#include "ADVram.hh"
#include "NowindInterface.hh"
#include "MSXMirrorDevice.hh"
Expand Down Expand Up @@ -307,6 +308,8 @@ std::unique_ptr<MSXDevice> DeviceFactory::create(const DeviceConfig& conf)
result = make_unique<MusicalMemoryMapper>(conf);
} else if (type == "Carnivore2") {
result = make_unique<Carnivore2>(conf);
} else if (type == "ASCII16-X") {
result = make_unique<RomAscii16X>(conf);
} else if (type == "YamahaSKW01") {
result = make_unique<YamahaSKW01>(conf);
} else if (type == one_of("T7775", "T7937", "T9763", "T9769")) {
Expand Down
15 changes: 14 additions & 1 deletion src/memory/AmdFlash.hh
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ private:
[[nodiscard]] bool isSectorWritable(size_t sector) const;

public:
static constexpr unsigned MAX_CMD_SIZE = 5 + 32; // longest command is BufferProgram
static constexpr unsigned MAX_CMD_SIZE = 5 + 256; // longest command is BufferProgram

private:
MSXMotherBoard& motherBoard;
Expand Down Expand Up @@ -314,6 +314,19 @@ namespace AmdFlashChip
.primaryAlgorithm{{1, 3}, 0, 0, 2, 4, 1, 4, 0, 0, 1, {0xB5, 0xC5}, 0x02, 1},
},
}};

// Infineon / Cypress / Spansion S29GL064S70TFI040
static constexpr ValidatedChip S29GL064S70TFI040 = {{
.autoSelect{.manufacturer = AMD, .device{0x10, 0x00}, .extraCode = 0xFF0A, .readMask = 0x0F},
.geometry{DeviceInterface::x8x16, {{8, 0x2000}, {127, 0x10000}}},
.program{.bufferCommand = true, .pageSize = 256},
.cfi{
.command = true, .withAutoSelect = true, .exitCommand = true, .commandMask = 0xFF, .readMask = 0x7F,
.systemInterface{{0x27, 0x36, 0x00, 0x00}, {256, 256, 512, 65536}, {8, 8, 2, 1}},
.primaryAlgorithm{{1, 3}, 0, 8, 2, 1, 0, 8, 0, 0, 2, {0xB5, 0xC5}, 0x02, 1},
},
.misc {.statusCommand = true, .continuityCommand = true},
}};
}

} // namespace openmsx
Expand Down
120 changes: 120 additions & 0 deletions src/memory/RomAscii16X.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// ASCII-X 16kB cartridges
//
// Banks:
// first 16kB: 0x4000 - 0x7FFF and 0xC000 - 0xFFFF
// second 16kB: 0x8000 - 0xBFFF and 0x0000 - 0x3FFF
//
// Address to change banks:
// first 16kB: 0x6000 - 0x6FFF, 0xA000 - 0xAFFF, 0xE000 - 0xEFFF, 0x2000 - 0x2FFF
// second 16kB: 0x7000 - 0x7FFF, 0xB000 - 0xBFFF, 0xF000 - 0xFFFF, 0x3000 - 0x3FFF
//
// 12-bit bank number is composed by address bits 8-11 and the data bits.
//
// Backed by FlashROM.

#include "RomAscii16X.hh"
#include "narrow.hh"
#include "outer.hh"
#include "serialize.hh"

namespace openmsx {

RomAscii16X::RomAscii16X(const DeviceConfig& config)
: RomAscii16X(config, Rom(std::string(config.getAttributeValue("id")), "ASCII16-X", config))
{
}

RomAscii16X::RomAscii16X(const DeviceConfig& config, Rom&& rom_)
: MSXRom(config, std::move(rom_))
, debuggable(getMotherBoard(), getName())
, flash(rom, AmdFlashChip::S29GL064S70TFI040, {}, config)
{
}

void RomAscii16X::reset(EmuTime::param /* time */)
{
ranges::iota(bankRegs, word(0));

flash.reset();

invalidateDeviceRCache(); // flush all to be sure
}

unsigned RomAscii16X::getFlashAddr(word addr) const
{
word bank = bankRegs[((addr >> 14) & 1) ^ 1];
return (bank << 14) | (addr & 0x3FFF);
}

byte RomAscii16X::readMem(word addr, EmuTime::param /* time */)
{
return flash.read(getFlashAddr(addr));
}

byte RomAscii16X::peekMem(word addr, EmuTime::param /* time */) const
{
return flash.peek(getFlashAddr(addr));
}

const byte* RomAscii16X::getReadCacheLine(word addr) const
{
return flash.getReadCacheLine(getFlashAddr(addr));
}

void RomAscii16X::writeMem(word addr, byte value, EmuTime::param /* time */)
{
flash.write(getFlashAddr(addr), value);

if ((addr & 0x3FFF) >= 0x2000) {
const word index = (addr >> 12) & 1;
bankRegs[index] = (addr & 0x0F00) | value;
invalidateDeviceRCache(0x4000 ^ (index << 14), 0x4000);
invalidateDeviceRCache(0xC000 ^ (index << 14), 0x4000);
}
}

byte* RomAscii16X::getWriteCacheLine(word /* addr */)
{
return nullptr; // not cacheable
}

RomAscii16X::Debuggable::Debuggable(MSXMotherBoard& motherBoard_,
const std::string& name_)
: SimpleDebuggable(motherBoard_, name_ + " regs", "ASCII16-X bank registers", 4)
{
}

byte RomAscii16X::Debuggable::read(unsigned address)
{
auto& outer = OUTER(RomAscii16X, debuggable);
word bank = outer.bankRegs[(address >> 1) & 1];
return narrow<byte>(address & 1 ? bank >> 8 : bank & 0xFF);
}

void RomAscii16X::Debuggable::write(unsigned address, byte value,
EmuTime::param /* time */)
{
auto& outer = OUTER(RomAscii16X, debuggable);
word& bank = outer.bankRegs[(address >> 1) & 1];
if (address & 1) {
bank = (bank & 0x00FF) | narrow<word>((value << 8) & 0x0F00);
} else {
bank = (bank & 0x0F00) | value;
}

outer.invalidateDeviceRCache();
}

template<typename Archive>
void RomAscii16X::serialize(Archive& ar, unsigned /*version*/)
{
// skip MSXRom base class
ar.template serializeBase<MSXDevice>(*this);

ar.serialize("flash", flash,
"bankRegs", bankRegs);
}
INSTANTIATE_SERIALIZE_METHODS(RomAscii16X);
REGISTER_MSXDEVICE(RomAscii16X, "RomAscii16X");

} // namespace openmsx
43 changes: 43 additions & 0 deletions src/memory/RomAscii16X.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#ifndef ROMASCII16X_HH
#define ROMASCII16X_HH

#include "MSXRom.hh"
#include "AmdFlash.hh"
#include "SimpleDebuggable.hh"
#include <array>

namespace openmsx {

class RomAscii16X final : public MSXRom
{
public:
explicit RomAscii16X(const DeviceConfig& config);
RomAscii16X(const DeviceConfig& config, Rom&& rom);

void reset(EmuTime::param time) override;
[[nodiscard]] byte peekMem(word address, EmuTime::param time) const override;
[[nodiscard]] byte readMem(word address, EmuTime::param time) override;
[[nodiscard]] const byte* getReadCacheLine(word address) const override;
void writeMem(word address, byte value, EmuTime::param time) override;
[[nodiscard]] byte* getWriteCacheLine(word address) override;

template<typename Archive>
void serialize(Archive& ar, unsigned version);

private:
[[nodiscard]] unsigned getFlashAddr(word addr) const;

struct Debuggable final : SimpleDebuggable {
Debuggable(MSXMotherBoard& motherBoard, const std::string& name);
[[nodiscard]] byte read(unsigned address) override;
void write(unsigned address, byte value, EmuTime::param time) override;
} debuggable;

AmdFlash flash;

std::array<word, 2> bankRegs = {0, 0};
};

} // namespace openmsx

#endif
5 changes: 5 additions & 0 deletions src/memory/RomFactory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "RomAscii8kB.hh"
#include "RomAscii8_8.hh"
#include "RomAscii16kB.hh"
#include "RomAscii16X.hh"
#include "RomMSXWrite.hh"
#include "RomPadial8kB.hh"
#include "RomPadial16kB.hh"
Expand Down Expand Up @@ -88,6 +89,7 @@ using enum RomType;

if (const size_t signatureOffset = 16, signatureSize = 8; size >= (signatureOffset + signatureSize)) {
auto signature = std::string_view(std::bit_cast<const char*>(data.data()) + signatureOffset, signatureSize);
if (signature == std::string_view("ASCII16X")) return ASCII16X;
if (signature == std::string_view("ROM_NEO8")) return NEO8;
if (signature == std::string_view("ROM_NE16")) return NEO16;
}
Expand Down Expand Up @@ -267,6 +269,9 @@ std::unique_ptr<MSXDevice> create(const DeviceConfig& config)
case ASCII16:
result = make_unique<RomAscii16kB>(config, std::move(rom));
break;
case ASCII16X:
result = make_unique<RomAscii16X>(config, std::move(rom));
break;
case MSXWRITE:
result = make_unique<RomMSXWrite>(config, std::move(rom));
break;
Expand Down
1 change: 1 addition & 0 deletions src/memory/RomInfo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ static constexpr auto romTypeInfoArray = [] {
r[KBDMASTER] = {0x4000, "KeyboardMaster", "Konami Keyboard Master with VLM5030"}; // officially plain 16K
r[ASCII8] = {0x2000, "ASCII8", "ASCII 8kB"};
r[ASCII16] = {0x4000, "ASCII16", "ASCII 16kB"};
r[ASCII16X] = {0x4000, "ASCII16-X", "ASCII-X 16kB"};
r[R_TYPE] = {0x4000, "R-Type", "R-Type"};
r[CROSS_BLAIM] = {0x4000, "CrossBlaim", "Cross Blaim"};
r[HARRY_FOX] = {0x4000, "HarryFox", "Harry Fox"};
Expand Down
1 change: 1 addition & 0 deletions src/memory/RomTypes.hh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ enum class RomType {
ASCII16,
ASCII16_2,
ASCII16_8,
ASCII16X,
COLECOMEGACART,
CROSS_BLAIM,
DOOLY,
Expand Down
1 change: 1 addition & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ sources = files(
'memory/RomArc.cc',
'memory/RomAscii16_2.cc',
'memory/RomAscii16kB.cc',
'memory/RomAscii16X.cc',
'memory/RomAscii8_8.cc',
'memory/RomAscii8kB.cc',
'memory/RomBlocks.cc',
Expand Down

0 comments on commit 19da0a8

Please sign in to comment.