123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- #include "MSXDeviceSwitch.hh"
- #include "MSXSwitchedDevice.hh"
- #include "MSXCPUInterface.hh"
- #include "MSXException.hh"
- #include "ranges.hh"
- #include "serialize.hh"
- #include <cassert>
- namespace openmsx {
- MSXDeviceSwitch::MSXDeviceSwitch(const DeviceConfig& config)
- : MSXDevice(config)
- {
- ranges::fill(devices, nullptr);
- count = 0;
- selected = 0;
- }
- MSXDeviceSwitch::~MSXDeviceSwitch()
- {
- // all devices must be unregistered
- assert(ranges::all_of(devices, [](auto* dev) { return dev == nullptr; }));
- assert(count == 0);
- }
- void MSXDeviceSwitch::registerDevice(byte id, MSXSwitchedDevice* device)
- {
- if (devices[id]) {
- // TODO implement multiplexing
- throw MSXException(
- "Already have a switched device with id ", int(id));
- }
- devices[id] = device;
- if (count == 0) {
- for (byte port = 0x40; port < 0x50; ++port) {
- getCPUInterface().register_IO_In (port, this);
- getCPUInterface().register_IO_Out(port, this);
- }
- }
- ++count;
- }
- void MSXDeviceSwitch::unregisterDevice(byte id)
- {
- --count;
- if (count == 0) {
- for (byte port = 0x40; port < 0x50; ++port) {
- getCPUInterface().unregister_IO_Out(port, this);
- getCPUInterface().unregister_IO_In (port, this);
- }
- }
- assert(devices[id]);
- devices[id] = nullptr;
- }
- void MSXDeviceSwitch::reset(EmuTime::param /*time*/)
- {
- selected = 0;
- }
- byte MSXDeviceSwitch::readIO(word port, EmuTime::param time)
- {
- if (devices[selected]) {
- return devices[selected]->readSwitchedIO(port, time);
- } else {
- return 0xFF;
- }
- }
- byte MSXDeviceSwitch::peekIO(word port, EmuTime::param time) const
- {
- if (devices[selected]) {
- return devices[selected]->peekSwitchedIO(port, time);
- } else {
- return 0xFF;
- }
- }
- void MSXDeviceSwitch::writeIO(word port, byte value, EmuTime::param time)
- {
- if ((port & 0x0F) == 0x00) {
- selected = value;
- } else if (devices[selected]) {
- devices[selected]->writeSwitchedIO(port, value, time);
- } else {
- // ignore
- }
- }
- template<typename Archive>
- void MSXDeviceSwitch::serialize(Archive& ar, unsigned /*version*/)
- {
- ar.template serializeBase<MSXDevice>(*this);
- ar.serialize("selected", selected);
- }
- INSTANTIATE_SERIALIZE_METHODS(MSXDeviceSwitch);
- } // namespace openmsx
|