openMSX
NowindInterface.cc
Go to the documentation of this file.
1#include "NowindInterface.hh"
2#include "DiskChanger.hh"
3#include "Clock.hh"
4#include "MSXMotherBoard.hh"
5#include "MSXException.hh"
6#include "serialize.hh"
7#include "serialize_stl.hh"
8#include <cassert>
9#include <functional>
10#include <memory>
11
12namespace openmsx {
13
15 : MSXDevice(config)
16 , rom(getName() + " ROM", "rom", config)
17 , flashConfig(rom.getSize() / 0x10000, {0x10000, false})
18 , flash(rom, flashConfig, 0x01A4,
20 , host(drives)
21 , basename("nowindX")
22{
23 nowindsInUse = getMotherBoard().getSharedStuff<NowindsInUse>("nowindsInUse");
24
25 unsigned i = 0;
26 while ((*nowindsInUse)[i]) {
27 if (++i == MAX_NOWINDS) {
28 throw MSXException("Too many nowind interfaces.");
29 }
30 }
31 (*nowindsInUse)[i] = true;
32 basename[6] = char('a' + i);
33
34 command.emplace(basename, getCommandController(), *this);
35
36 // start with one (empty) drive
37 auto drive = command->createDiskChanger(basename, 0, getMotherBoard());
38 drive->createCommand();
39 drives.push_back(std::move(drive));
40
41 reset(EmuTime::dummy());
42}
43
45{
46 unsigned i = basename[6] - 'a';
47 assert((*nowindsInUse)[i]);
48 (*nowindsInUse)[i] = false;
49}
50
51void NowindInterface::reset(EmuTime::param /*time*/)
52{
53 // version 1 didn't change the bank number
54 // version 2 (produced by Sunrise) does reset the bank number
55 bank = 0;
56
57 // Flash state is NOT changed on reset
58 //flash.reset();
59}
60
61byte NowindInterface::peekMem(word address, EmuTime::param /*time*/) const
62{
63 if (((0x2000 <= address) && (address < 0x4000)) ||
64 ((0x8000 <= address) && (address < 0xA000))) {
65 return host.peek();
66 } else if ((0x4000 <= address) && (address < 0xC000)) {
67 // note: range 0x8000-0xA000 is already handled above
68 return flash.peek(bank * 0x4000 + (address & 0x3FFF));
69 } else {
70 return 0xFF;
71 }
72}
73
74byte NowindInterface::readMem(word address, EmuTime::param /*time*/)
75{
76 if (((0x2000 <= address) && (address < 0x4000)) ||
77 ((0x8000 <= address) && (address < 0xA000))) {
78 return host.read();
79 } else if ((0x4000 <= address) && (address < 0xC000)) {
80 // note: range 0x8000-0xA000 is already handled above
81 return flash.read(bank * 0x4000 + (address & 0x3FFF));
82 } else {
83 return 0xFF;
84 }
85}
86
87const byte* NowindInterface::getReadCacheLine(word address) const
88{
89 if (((0x2000 <= address) && (address < 0x4000)) ||
90 ((0x8000 <= address) && (address < 0xA000))) {
91 // nowind region, not cacheable
92 return nullptr;
93 } else if ((0x4000 <= address) && (address < 0xC000)) {
94 // note: range 0x8000-0xA000 is already handled above
95 return flash.getReadCacheLine(bank * 0x4000 + (address & 0x3FFF));
96 } else {
97 return unmappedRead;
98 }
99}
100
101void NowindInterface::writeMem(word address, byte value, EmuTime::param time)
102{
103 if (address < 0x4000) {
104 flash.write(bank * 0x4000 + address, value);
105 } else if (((0x4000 <= address) && (address < 0x6000)) ||
106 ((0x8000 <= address) && (address < 0xA000))) {
107 constexpr Clock<1000> clock(EmuTime::zero());
108 host.write(value, clock.getTicksTill(time));
109 } else if (((0x6000 <= address) && (address < 0x8000)) ||
110 ((0xA000 <= address) && (address < 0xC000))) {
111 byte max = rom.getSize() / (16 * 1024);
112 bank = (value < max) ? value : value & (max - 1);
113 invalidateDeviceRCache(0x4000, 0x4000);
114 invalidateDeviceRCache(0xA000, 0x2000);
115 }
116}
117
119{
120 if (address < 0xC000) {
121 // not cacheable
122 return nullptr;
123 } else {
124 return unmappedWrite;
125 }
126}
127
128
129template<typename Archive>
130void NowindInterface::serialize(Archive& ar, unsigned /*version*/)
131{
132 ar.template serializeBase<MSXDevice>(*this);
133 ar.serialize("flash", flash);
134 ar.serializeWithID("drives", drives, std::ref(getMotherBoard()));
135 ar.serialize("nowindhost", host,
136 "bank", bank);
137
138 // don't serialize command, rom, basename
139}
142
143} // namespace openmsx
void write(unsigned address, byte value)
Definition: AmdFlash.cc:265
byte peek(unsigned address) const
Definition: AmdFlash.cc:212
byte read(unsigned address) const
Definition: AmdFlash.cc:248
const byte * getReadCacheLine(unsigned address) const
Definition: AmdFlash.cc:254
Represents a clock with a fixed frequency.
Definition: Clock.hh:19
constexpr unsigned getTicksTill(EmuTime::param e) const
Calculate the number of ticks for this clock until the given time.
Definition: Clock.hh:58
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition: MSXDevice.hh:33
MSXMotherBoard & getMotherBoard() const
Get the mother board this device belongs to.
Definition: MSXDevice.cc:71
void invalidateDeviceRCache()
Definition: MSXDevice.hh:210
static byte unmappedRead[0x10000]
Definition: MSXDevice.hh:301
static byte unmappedWrite[0x10000]
Definition: MSXDevice.hh:302
byte peek() const
Definition: NowindHost.cc:52
void write(byte data, unsigned time)
Definition: NowindHost.cc:70
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) const 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.
unsigned getSize() const
Definition: Rom.hh:34
constexpr vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:283
std::string getName(KeyCode keyCode)
Translate key code to key name.
Definition: Keys.cc:727
This file implemented 3 utility functions:
Definition: Autofire.cc:9
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1009