openMSX
BeerIDE.cc
Go to the documentation of this file.
1#include "BeerIDE.hh"
2#include "IDEDeviceFactory.hh"
3#include "IDEDevice.hh"
4#include "GlobalSettings.hh"
5#include "narrow.hh"
6#include "serialize.hh"
7
8namespace openmsx {
9
11 : MSXDevice(config)
12 , i8255(*this, getCurrentTime(), config.getGlobalSettings().getInvalidPpiModeSetting())
13 , rom(getName() + " ROM", "rom", config)
14{
16 DeviceConfig(config, config.findChild("idedevice")));
17
19}
20
21BeerIDE::~BeerIDE() = default;
22
23void BeerIDE::reset(EmuTime::param time)
24{
25 controlReg = 0;
26 dataReg = 0;
27 device->reset(time);
28 i8255.reset(time);
29}
30
31byte BeerIDE::readMem(word address, EmuTime::param /*time*/)
32{
33 if (0x4000 <= address && address < 0x8000) {
34 return rom[address & 0x3FFF];
35 }
36 return 0xFF;
37}
38
39const byte* BeerIDE::getReadCacheLine(word start) const
40{
41 if (0x4000 <= start && start < 0x8000) {
42 return &rom[start & 0x3FFF];
43 }
44 return unmappedRead.data();
45}
46
47byte BeerIDE::readIO(word port, EmuTime::param time)
48{
49 return i8255.read(port & 0x03, time);
50}
51
52byte BeerIDE::peekIO(word port, EmuTime::param time) const
53{
54 return i8255.peek(port & 0x03, time);
55}
56
57void BeerIDE::writeIO(word port, byte value, EmuTime::param time)
58{
59 i8255.write(port & 0x03, value, time);
60}
61
62// I8255Interface
63
64byte BeerIDE::readA(EmuTime::param time)
65{
66 return peekA(time);
67}
68byte BeerIDE::peekA(EmuTime::param /*time*/) const
69{
70 return narrow_cast<byte>(dataReg & 0xFF);
71}
72void BeerIDE::writeA(byte value, EmuTime::param /*time*/)
73{
74 dataReg &= 0xFF00;
75 dataReg |= value;
76}
77
78byte BeerIDE::readB(EmuTime::param time)
79{
80 return peekB(time);
81}
82byte BeerIDE::peekB(EmuTime::param /*time*/) const
83{
84 return narrow_cast<byte>(dataReg >> 8);
85}
86void BeerIDE::writeB(byte value, EmuTime::param /*time*/)
87{
88 dataReg &= 0x00FF;
89 dataReg |= (value << 8);
90}
91
92nibble BeerIDE::readC1(EmuTime::param time)
93{
94 return peekC1(time);
95}
96nibble BeerIDE::peekC1(EmuTime::param /*time*/) const
97{
98 return 0; // TODO check this
99}
100nibble BeerIDE::readC0(EmuTime::param time)
101{
102 return peekC0(time);
103}
104nibble BeerIDE::peekC0(EmuTime::param /*time*/) const
105{
106 return 0; // TODO check this
107}
108void BeerIDE::writeC1(nibble value, EmuTime::param time)
109{
110 changeControl(byte((controlReg & 0x0F) | (value << 4)), time);
111}
112void BeerIDE::writeC0(nibble value, EmuTime::param time)
113{
114 changeControl((controlReg & 0xF0) | value, time);
115}
116void BeerIDE::changeControl(byte value, EmuTime::param time)
117{
118 byte diff = controlReg ^ value;
119 controlReg = value;
120 if ((diff & 0xE7) == 0) return; // nothing relevant changed
121
122 byte address = controlReg & 7;
123 switch (value & 0xE0) {
124 case 0x40: // read /IORD=0, /IOWR=1, /CS0=0
125 if (address == 0) {
126 dataReg = device->readData(time);
127 } else {
128 dataReg = device->readReg(address, time);
129 }
130 break;
131 case 0x80: // write /IORD=1, /IOWR=0, /CS0=0
132 if (address == 0) {
133 device->writeData(dataReg, time);
134 } else {
135 device->writeReg(address, narrow_cast<byte>(dataReg & 0xFF), time);
136 }
137 break;
138 default: // all (6) other cases, nothing
139 break;
140 }
141}
142
143template<typename Archive>
144void BeerIDE::serialize(Archive& ar, unsigned /*version*/)
145{
146 ar.template serializeBase<MSXDevice>(*this);
147 ar.serialize("i8255", i8255);
148 ar.serializePolymorphic("device", *device);
149 ar.serialize("dataReg", dataReg,
150 "controlReg", controlReg);
151}
154
155} // namespace openmsx
#define REGISTER_MSXDEVICE(CLASS, NAME)
Definition MSXDevice.hh:356
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
Definition BeerIDE.cc:52
void writeIO(word port, byte value, EmuTime::param time) override
Write a byte to a given IO port at a certain time to this device.
Definition BeerIDE.cc:57
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
Definition BeerIDE.cc:47
void reset(EmuTime::param time) override
This method is called on reset.
Definition BeerIDE.cc:23
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition BeerIDE.cc:31
BeerIDE(const DeviceConfig &config)
Definition BeerIDE.cc:10
const byte * getReadCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition BeerIDE.cc:39
void serialize(Archive &ar, unsigned version)
Definition BeerIDE.cc:144
~BeerIDE() override
const XMLElement * findChild(std::string_view name) const
void reset(EmuTime::param time)
Definition I8255.cc:33
byte peek(byte port, EmuTime::param time) const
Definition I8255.cc:58
byte read(byte port, EmuTime::param time)
Definition I8255.cc:42
void write(byte port, byte value, EmuTime::param time)
Definition I8255.cc:74
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition MSXDevice.hh:36
virtual void powerUp(EmuTime::param time)
This method is called when MSX is powered up.
Definition MSXDevice.cc:370
static std::array< byte, 0x10000 > unmappedRead
Definition MSXDevice.hh:306
EmuTime::param getCurrentTime() const
Definition MSXDevice.cc:125
std::unique_ptr< IDEDevice > create(const DeviceConfig &config)
This file implemented 3 utility functions:
Definition Autofire.cc:11
uint8_t nibble
4 bit integer
Definition openmsx.hh:23
uint16_t word
16 bit unsigned integer
Definition openmsx.hh:29
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)