// $Id: MSXDeviceSwitch.hh 5098 2006-01-28 16:36:24Z m9710797 $ #ifndef MSXDEVICESWITCH_HH #define MSXDEVICESWITCH_HH #include "MSXDevice.hh" #include "noncopyable.hh" namespace openmsx { /** * The MSX2 Hardware Specification says ports 0x41-0x4F are Switched I/O ports. * Output of a ID value to port 0x40 selects a specific I/O device and connects * it to the CPU. * * It is possible to give numbers between 0 and 255 as a device number. * However, when reading the device number, the complement is given, so 0 and * 255 are not used. ID numbers between 1 and 127 are manufacturers ID number * as in expanded BIOS call. 128 to 254 are device numbers. As a basic rule, * those device which are designed specifically for one machine should contain * the manufacturers company ID while peripheral device which can be used for * all MSX should have device ID number. Also, Z80 CPU has 16 bit address in * I/O space so it is recommended to access in 16 bit by decoding the upper 8 * bit for those ID which might be expanded in the future. Especially for * device which are connected with make ID can expand the address space by 256 * times so it is future proofed. * * Maker ID * 1 ASCII/Microsoft * 2 Canon * 3 Casio * 4 Fujitsu * 5 General * 6 Hitachi * 7 Kyocera * 8 Matsushita * 9 Mitsubishi * 10 NEC * 11 Nippon Gakki * 12 JVC * 13 Philips * 14 Pioneer * 15 Sanyo * 16 Sharp * 17 SONY * 18 Spectravideo * 19 Toshiba * 20 Mitsumi * * Device ID * 128 Image Scanner (Matsushita) * 247 Kanji 12x12 * 254 MPS2 (ASCII) */ class MSXSwitchedDevice : private noncopyable { public: MSXSwitchedDevice(MSXMotherBoard& motherBoard, byte id); virtual ~MSXSwitchedDevice(); virtual void reset(const EmuTime& time); virtual byte readIO(word port, const EmuTime& time) = 0; virtual byte peekIO(word port, const EmuTime& time) const = 0; virtual void writeIO(word port, byte value, const EmuTime& time) = 0; private: MSXMotherBoard& motherBoard; byte id; }; class MSXDeviceSwitch : public MSXDevice { public: MSXDeviceSwitch(MSXMotherBoard& motherBoard, const XMLElement& config, const EmuTime& time); virtual ~MSXDeviceSwitch(); // (un)register methods for devices void registerDevice(byte id, MSXSwitchedDevice* device); void unregisterDevice(byte id); virtual void reset(const EmuTime& time); virtual byte readIO(word port, const EmuTime& time); virtual byte peekIO(word port, const EmuTime& time) const; virtual void writeIO(word port, byte value, const EmuTime& time); private: MSXSwitchedDevice* devices[256]; unsigned count; byte selected; }; } // namespace openmsx #endif