OXYGENHUB
◆ main openmsx / src / ide / BeerIDE.cc
3.3 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#include "BeerIDE.hh"
2
3
#include "IDEDevice.hh"
4
#include "IDEDeviceFactory.hh"
5
6
#include "GlobalSettings.hh"
7
#include "serialize.hh"
8
9
#include "narrow.hh"
10
11
namespace openmsx {
12
13
BeerIDE::BeerIDE(DeviceConfig& config)
14
	: MSXDevice(config)
15
	, i8255(*this, getCurrentTime(), config.getGlobalSettings().getInvalidPpiModeSetting())
16
	, rom(getName() + " ROM", "rom", config)
17
{
18
	device = IDEDeviceFactory::create(
19
		DeviceConfig(config, config.findChild("idedevice")));
20
21
	powerUp(getCurrentTime());
22
}
23
24
BeerIDE::~BeerIDE() = default;
25
26
void BeerIDE::reset(EmuTime time)
27
{
28
	controlReg = 0;
29
	dataReg = 0;
30
	device->reset(time);
31
	i8255.reset(time);
32
}
33
34
uint8_t BeerIDE::readMem(uint16_t address, EmuTime /*time*/)
35
{
36
	if (0x4000 <= address && address < 0x8000) {
37
		return rom[address & 0x3FFF];
38
	}
39
	return 0xFF;
40
}
41
42
const uint8_t* BeerIDE::getReadCacheLine(uint16_t start) const
43
{
44
	if (0x4000 <= start && start < 0x8000) {
45
		return &rom[start & 0x3FFF];
46
	}
47
	return unmappedRead.data();
48
}
49
50
uint8_t BeerIDE::readIO(uint16_t port, EmuTime time)
51
{
52
	return i8255.read(port & 0x03, time);
53
}
54
55
uint8_t BeerIDE::peekIO(uint16_t port, EmuTime time) const
56
{
57
	return i8255.peek(port & 0x03, time);
58
}
59
60
void BeerIDE::writeIO(uint16_t port, uint8_t value, EmuTime time)
61
{
62
	i8255.write(port & 0x03, value, time);
63
}
64
65
// I8255Interface
66
67
uint8_t BeerIDE::readA(EmuTime time)
68
{
69
	return peekA(time);
70
}
71
uint8_t BeerIDE::peekA(EmuTime /*time*/) const
72
{
73
	return narrow_cast<uint8_t>(dataReg & 0xFF);
74
}
75
void BeerIDE::writeA(uint8_t value, EmuTime /*time*/)
76
{
77
	dataReg &= 0xFF00;
78
	dataReg |= value;
79
}
80
81
uint8_t BeerIDE::readB(EmuTime time)
82
{
83
	return peekB(time);
84
}
85
uint8_t BeerIDE::peekB(EmuTime /*time*/) const
86
{
87
	return narrow_cast<uint8_t>(dataReg >> 8);
88
}
89
void BeerIDE::writeB(uint8_t value, EmuTime /*time*/)
90
{
91
	dataReg &= 0x00FF;
92
	dataReg |= (value << 8);
93
}
94
95
uint4_t BeerIDE::readC1(EmuTime time)
96
{
97
	return peekC1(time);
98
}
99
uint4_t BeerIDE::peekC1(EmuTime /*time*/) const
100
{
101
	return 0; // TODO check this
102
}
103
uint4_t BeerIDE::readC0(EmuTime time)
104
{
105
	return peekC0(time);
106
}
107
uint4_t BeerIDE::peekC0(EmuTime /*time*/) const
108
{
109
	return 0; // TODO check this
110
}
111
void BeerIDE::writeC1(uint4_t value, EmuTime time)
112
{
113
	changeControl(uint8_t((controlReg & 0x0F) | (value << 4)), time);
114
}
115
void BeerIDE::writeC0(uint4_t value, EmuTime time)
116
{
117
	changeControl((controlReg & 0xF0) | value, time);
118
}
119
void BeerIDE::changeControl(uint8_t value, EmuTime time)
120
{
121
	uint8_t diff = controlReg ^ value;
122
	controlReg = value;
123
	if ((diff & 0xE7) == 0) return; // nothing relevant changed
124
125
	uint8_t address = controlReg & 7;
126
	switch (value & 0xE0) {
127
	case 0x40: // read   /IORD=0,  /IOWR=1,  /CS0=0
128
		if (address == 0) {
129
			dataReg = device->readData(time);
130
		} else {
131
			dataReg = device->readReg(address, time);
132
		}
133
		break;
134
	case 0x80: // write  /IORD=1,  /IOWR=0,  /CS0=0
135
		if (address == 0) {
136
			device->writeData(dataReg, time);
137
		} else {
138
			device->writeReg(address, narrow_cast<uint8_t>(dataReg & 0xFF), time);
139
		}
140
		break;
141
	default: // all (6) other cases, nothing
142
		break;
143
	}
144
}
145
146
template<typename Archive>
147
void BeerIDE::serialize(Archive& ar, unsigned /*version*/)
148
{
149
	ar.template serializeBase<MSXDevice>(*this);
150
	ar.serialize("i8255", i8255);
151
	ar.serializePolymorphic("device", *device);
152
	ar.serialize("dataReg",    dataReg,
153
	             "controlReg", controlReg);
154
}
155
INSTANTIATE_SERIALIZE_METHODS(BeerIDE);
156
REGISTER_MSXDEVICE(BeerIDE, "BeerIDE");
157
158
} // namespace openmsx