openMSX
MSXDeviceSwitch.cc
Go to the documentation of this file.
1#include "MSXDeviceSwitch.hh"
3#include "MSXCPUInterface.hh"
4#include "MSXException.hh"
5#include "ranges.hh"
6#include "serialize.hh"
7#include "xrange.hh"
8#include <cassert>
9
10namespace openmsx {
11
13 : MSXDevice(config)
14{
15 ranges::fill(devices, nullptr);
16}
17
19{
20 // all devices must be unregistered
21 assert(ranges::all_of(devices, [](auto* dev) { return dev == nullptr; }));
22 assert(count == 0);
23}
24
26{
27 if (devices[id]) {
28 // TODO implement multiplexing
29 throw MSXException(
30 "Already have a switched device with id ", int(id));
31 }
32 devices[id] = device;
33 if (count == 0) {
34 for (auto port : xrange(0x40, 0x50)) {
35 getCPUInterface().register_IO_In (port, this);
36 getCPUInterface().register_IO_Out(port, this);
37 }
38 }
39 ++count;
40}
41
43{
44 --count;
45 if (count == 0) {
46 for (auto port : xrange(0x40, 0x50)) {
48 getCPUInterface().unregister_IO_In (port, this);
49 }
50 }
51 assert(devices[id]);
52 devices[id] = nullptr;
53}
54
55void MSXDeviceSwitch::reset(EmuTime::param /*time*/)
56{
57 selected = 0;
58}
59
60byte MSXDeviceSwitch::readIO(word port, EmuTime::param time)
61{
62 if (devices[selected]) {
63 return devices[selected]->readSwitchedIO(port, time);
64 } else {
65 return 0xFF;
66 }
67}
68
69byte MSXDeviceSwitch::peekIO(word port, EmuTime::param time) const
70{
71 if (devices[selected]) {
72 return devices[selected]->peekSwitchedIO(port, time);
73 } else {
74 return 0xFF;
75 }
76}
77
78void MSXDeviceSwitch::writeIO(word port, byte value, EmuTime::param time)
79{
80 if ((port & 0x0F) == 0x00) {
81 selected = value;
82 } else if (devices[selected]) {
83 devices[selected]->writeSwitchedIO(port, value, time);
84 } else {
85 // ignore
86 }
87}
88
89
90template<typename Archive>
91void MSXDeviceSwitch::serialize(Archive& ar, unsigned /*version*/)
92{
93 ar.template serializeBase<MSXDevice>(*this);
94 ar.serialize("selected", selected);
95}
97
98} // namespace openmsx
uintptr_t id
Definition: Interpreter.cc:27
void register_IO_Out(byte port, MSXDevice *device)
Devices can register their Out ports.
void register_IO_In(byte port, MSXDevice *device)
Devices can register their In ports.
void unregister_IO_In(byte port, MSXDevice *device)
void unregister_IO_Out(byte port, MSXDevice *device)
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.
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
void unregisterDevice(byte id)
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
void reset(EmuTime::param time) override
This method is called on reset.
MSXDeviceSwitch(const DeviceConfig &config)
void registerDevice(byte id, MSXSwitchedDevice *device)
void serialize(Archive &ar, unsigned version)
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition: MSXDevice.hh:34
MSXCPUInterface & getCPUInterface() const
Definition: MSXDevice.cc:133
This file implemented 3 utility functions:
Definition: Autofire.cc:9
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
bool all_of(InputRange &&range, UnaryPredicate pred)
Definition: ranges.hh:186
constexpr void fill(ForwardRange &&range, const T &value)
Definition: ranges.hh:287
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1021
constexpr auto xrange(T e)
Definition: xrange.hh:133