17 , rom(getName() +
" ROM",
"rom", config)
18 , flash(rom, AmdFlashChip::AM29F040, {}, config)
22 if ((rom.size() % 0x4000) != 0) {
23 throw MSXException(
"NowindInterface ROM size must be a multiple of 16kB");
25 if (rom.size() == 0) {
26 throw MSXException(
"NowindInterface ROM size cannot be zero");
28 if (rom.size() >
size_t(256 * 0x4000)) {
29 throw MSXException(
"NowindInterface ROM size cannot be larger than 4MB");
32 nowindsInUse = getMotherBoard().getSharedStuff<NowindsInUse>(
"nowindsInUse");
35 while ((*nowindsInUse)[i]) {
36 if (++i == MAX_NOWINDS) {
37 throw MSXException(
"Too many nowind interfaces.");
40 (*nowindsInUse)[i] =
true;
41 basename[6] = char(
'a' + i);
43 command.emplace(basename, getCommandController(), *
this);
46 auto drive = command->createDiskChanger(basename, 0, getMotherBoard());
47 drive->createCommand();
48 drives.push_back(std::move(drive));
50 reset(EmuTime::dummy());
55 unsigned i = basename[6] -
'a';
56 assert((*nowindsInUse)[i]);
57 (*nowindsInUse)[i] =
false;
72 if (((0x2000 <= address) && (address < 0x4000)) ||
73 ((0x8000 <= address) && (address < 0xA000))) {
75 }
else if ((0x4000 <= address) && (address < 0xC000)) {
77 return flash.
peek(bank * 0x4000 + (address & 0x3FFF));
85 if (((0x2000 <= address) && (address < 0x4000)) ||
86 ((0x8000 <= address) && (address < 0xA000))) {
88 }
else if ((0x4000 <= address) && (address < 0xC000)) {
90 return flash.
read(bank * 0x4000 + (address & 0x3FFF));
98 if (((0x2000 <= address) && (address < 0x4000)) ||
99 ((0x8000 <= address) && (address < 0xA000))) {
102 }
else if ((0x4000 <= address) && (address < 0xC000)) {
112 if (address < 0x4000) {
113 flash.
write(bank * 0x4000 + address, value);
114 }
else if (((0x4000 <= address) && (address < 0x6000)) ||
115 ((0x8000 <= address) && (address < 0xA000))) {
118 }
else if (((0x6000 <= address) && (address < 0x8000)) ||
119 ((0xA000 <= address) && (address < 0xC000))) {
120 auto max = narrow<uint8_t>((rom.
size() / 0x4000) - 1);
121 bank = (value <= max) ? value : (value & max);
129 if (address < 0xC000) {
138template<
typename Archive>
141 ar.template serializeBase<MSXDevice>(*
this);
142 ar.serialize(
"flash", flash);
144 ar.serialize(
"nowindhost", host,
#define REGISTER_MSXDEVICE(CLASS, NAME)
void write(size_t address, uint8_t value)
const uint8_t * getReadCacheLine(size_t address) const
uint8_t read(size_t address)
uint8_t peek(size_t address) const
Represents a clock with a fixed frequency.
constexpr unsigned getTicksTill(EmuTime::param e) const
Calculate the number of ticks for this clock until the given time.
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
MSXMotherBoard & getMotherBoard() const
Get the mother board this device belongs to.
void invalidateDeviceRCache()
static std::array< byte, 0x10000 > unmappedRead
static std::array< byte, 0x10000 > unmappedWrite
void write(byte data, unsigned time)
~NowindInterface() override
const byte * getReadCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
byte * getWriteCacheLine(word address) override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
void reset(EmuTime::param time) override
This method is called on reset.
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
NowindInterface(const DeviceConfig &config)
void serialize(Archive &ar, unsigned version)
void writeMem(word address, byte value, EmuTime::param time) override
Write a given byte to a given location at a certain time to this device.
This file implemented 3 utility functions:
uint16_t word
16 bit unsigned integer
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)