14[[nodiscard]]
static byte getKeyboardLayout(
const MSXPSG& psg)
18 auto value = psg.getDeviceConfig().getChildData(
"keyboardlayout",
"50on");
20 if (cmp(value,
"50on")) {
22 }
else if (cmp(value,
"jis")) {
26 "Illegal keyboard layout configuration in '", psg.getName(),
27 "' device configuration: '", value,
28 "', expected 'jis' or '50on'.");
34 , cassette(getMotherBoard().getCassettePort())
35 , renShaTurbo(getMotherBoard().getRenShaTurbo())
37 , keyLayout(getKeyboardLayout(*
this))
38 , addressMask(config.getChildDataAsBool(
"mirrored_registers",
true) ? 0x0f : 0xff)
39 , ay8910(getName(), *this, config, getCurrentTime())
41 reset(getCurrentTime());
62 switch (port & 0x03) {
78 switch (port & 0x03) {
80 registerLatch = value & addressMask;
90byte MSXPSG::readA(EmuTime::param time)
92 byte joystick = ports[selectedPort]->read(time) |
93 ((renShaTurbo.
getSignal(time)) ? 0x10 : 0x00);
97 Perhaps
this behavior is different between MSX machines with a discrete
98 AY8910 chip versus machines with the PSG integrated in the MSX-engine?
101 byte pin67 = prev << (4 - 2 * selectedPort);
102 joystick &= (pin67| 0xCF);
105 byte cassetteInput = cassette.
cassetteIn(time) ? 0x80 : 0x00;
106 return joystick | keyLayout | cassetteInput;
109void MSXPSG::writeB(
byte value, EmuTime::param time)
111 byte val0 = (value & 0x03) | ((value & 0x10) >> 2);
112 byte val1 = ((value & 0x0C) >> 2) | ((value & 0x20) >> 3);
113 ports[0]->write(val0, time);
114 ports[1]->write(val1, time);
115 selectedPort = (value & 0x40) >> 6;
117 if ((prev ^ value) & 0x80) {
125template<
typename Archive>
128 ar.template serializeBase<MSXDevice>(*
this);
129 ar.serialize(
"ay8910", ay8910);
130 if (ar.versionBelow(version, 2)) {
131 assert(Archive::IS_LOADER);
133 ar.serialize(
"joystickportA", *checked_cast<JoystickPort*>(ports[0]),
134 "joystickportB", *checked_cast<JoystickPort*>(ports[1]));
136 ar.serialize(
"registerLatch", registerLatch);
138 ar.serialize(
"portB", portB);
139 if constexpr (Archive::IS_LOADER) {
void test(const IterableBitSet< N > &s, std::initializer_list< size_t > list)
#define REGISTER_MSXDEVICE(CLASS, NAME)
This class implements the AY-3-8910 sound chip.
uint8_t readRegister(unsigned reg, EmuTime::param time)
void reset(EmuTime::param time)
void writeRegister(unsigned reg, uint8_t value, EmuTime::param time)
uint8_t peekRegister(unsigned reg, EmuTime::param time) const
virtual bool cassetteIn(EmuTime::param time)=0
Reads one bit from the cassette port.
void setLed(Led led, bool status)
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
MSXMotherBoard & getMotherBoard() const
Get the mother board this device belongs to.
LedStatus & getLedStatus() const
EmuTime::param getCurrentTime() const
JoystickPortIf & getJoystickPort(unsigned port)
MSXPSG(const DeviceConfig &config)
void powerDown(EmuTime::param time) override
This method is called when MSX is powered down.
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.
void serialize(Archive &ar, unsigned version)
void reset(EmuTime::param time) override
This method is called on reset.
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
bool getSignal(EmuTime::param time)
Get the output signal in negative logic.
This file implemented 3 utility functions:
uint16_t word
16 bit unsigned integer
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)