openMSX
MSXPPI.cc
Go to the documentation of this file.
1#include "MSXPPI.hh"
2#include "LedStatus.hh"
3#include "MSXCPUInterface.hh"
4#include "MSXMotherBoard.hh"
5#include "Reactor.hh"
6#include "CassettePort.hh"
7#include "RenShaTurbo.hh"
8#include "GlobalSettings.hh"
9#include "serialize.hh"
10
11namespace openmsx {
12
14 : MSXDevice(config)
15 , cassettePort(getMotherBoard().getCassettePort())
16 , renshaTurbo(getMotherBoard().getRenShaTurbo())
17 , i8255(*this, getCurrentTime(), config.getGlobalSettings().getInvalidPpiModeSetting())
18 , click(config)
19 , keyboard(
20 config.getMotherBoard(),
21 config.getMotherBoard().getScheduler(),
22 config.getMotherBoard().getCommandController(),
23 config.getMotherBoard().getReactor().getEventDistributor(),
24 config.getMotherBoard().getMSXEventDistributor(),
25 config.getMotherBoard().getStateChangeDistributor(),
26 Keyboard::Matrix::MSX, config)
27{
29}
30
32{
33 powerDown(EmuTime::dummy());
34}
35
37 return keyboard;
38}
39
40void MSXPPI::reset(EmuTime::param time)
41{
42 i8255.reset(time);
43 click.reset(time);
44}
45
46void MSXPPI::powerDown(EmuTime::param /*time*/)
47{
49}
50
51byte MSXPPI::readIO(word port, EmuTime::param time)
52{
53 return i8255.read(port & 0x03, time);
54}
55
56byte MSXPPI::peekIO(word port, EmuTime::param time) const
57{
58 return i8255.peek(port & 0x03, time);
59}
60
61void MSXPPI::writeIO(word port, byte value, EmuTime::param time)
62{
63 i8255.write(port & 0x03, value, time);
64}
65
66
67// I8255Interface
68
69byte MSXPPI::readA(EmuTime::param time)
70{
71 return peekA(time);
72}
73byte MSXPPI::peekA(EmuTime::param /*time*/) const
74{
75 // port A is normally an output on MSX, reading from an output port
76 // is handled internally in the 8255
77 // TODO check this on a real MSX
78 // TODO returning 0 fixes the 'get_selected_slot' script right after
79 // reset (when PPI directions are not yet set). For now this
80 // solution is good enough.
81 return 0;
82}
83void MSXPPI::writeA(byte value, EmuTime::param /*time*/)
84{
86}
87
88byte MSXPPI::readB(EmuTime::param time)
89{
90 return peekB(time);
91}
92byte MSXPPI::peekB(EmuTime::param time) const
93{
94 auto row = keyboard.getKeys()[selectedRow];
95 if (selectedRow == 8) {
96 row |= renshaTurbo.getSignal(time) ? 1 : 0;
97 }
98 return row;
99}
100void MSXPPI::writeB(byte /*value*/, EmuTime::param /*time*/)
101{
102 // probably nothing happens on a real MSX
103}
104
105nibble MSXPPI::readC1(EmuTime::param time)
106{
107 return peekC1(time);
108}
109nibble MSXPPI::peekC1(EmuTime::param /*time*/) const
110{
111 return 15; // TODO check this
112}
113nibble MSXPPI::readC0(EmuTime::param time)
114{
115 return peekC0(time);
116}
117nibble MSXPPI::peekC0(EmuTime::param /*time*/) const
118{
119 return 15; // TODO check this
120}
121void MSXPPI::writeC1(nibble value, EmuTime::param time)
122{
123 if ((prevBits ^ value) & 1) {
124 cassettePort.setMotor((value & 1) == 0, time); // 0=0n, 1=Off
125 }
126 if ((prevBits ^ value) & 2) {
127 cassettePort.cassetteOut((value & 2) != 0, time);
128 }
129 if ((prevBits ^ value) & 4) {
130 getLedStatus().setLed(LedStatus::CAPS, (value & 4) == 0);
131 }
132 if ((prevBits ^ value) & 8) {
133 click.setClick((value & 8) != 0, time);
134 }
135 prevBits = value;
136}
137void MSXPPI::writeC0(nibble value, EmuTime::param /*time*/)
138{
139 selectedRow = value;
140}
141
142
143template<typename Archive>
144void MSXPPI::serialize(Archive& ar, unsigned /*version*/)
145{
146 ar.template serializeBase<MSXDevice>(*this);
147 ar.serialize("i8255", i8255);
148
149 // merge prevBits and selectedRow into one byte
150 auto portC = byte((prevBits << 4) | (selectedRow << 0));
151 ar.serialize("portC", portC);
152 if constexpr (Archive::IS_LOADER) {
153 selectedRow = (portC >> 0) & 0xF;
154 nibble bits = (portC >> 4) & 0xF;
155 writeC1(bits, getCurrentTime());
156 }
157 ar.serialize("keyboard", keyboard);
158}
161
162} // namespace openmsx
#define REGISTER_MSXDEVICE(CLASS, NAME)
Definition MSXDevice.hh:356
virtual void cassetteOut(bool output, EmuTime::param time)=0
Writes one bit to the cassette port.
virtual void setMotor(bool status, EmuTime::param time)=0
Sets the cassette motor relay false = off true = on.
void reset(EmuTime::param time)
Definition I8255.cc:33
byte peek(byte port, EmuTime::param time) const
Definition I8255.cc:58
byte read(byte port, EmuTime::param time)
Definition I8255.cc:42
void write(byte port, byte value, EmuTime::param time)
Definition I8255.cc:74
void reset(EmuTime::param time)
Definition KeyClick.cc:10
void setClick(bool status, EmuTime::param time)
Definition KeyClick.cc:15
std::span< const uint8_t, KeyMatrixPosition::NUM_ROWS > getKeys() const
Returns a pointer to the current KeyBoard matrix.
Definition Keyboard.cc:809
void setLed(Led led, bool status)
Definition LedStatus.cc:44
void setPrimarySlots(byte value)
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition MSXDevice.hh:36
LedStatus & getLedStatus() const
Definition MSXDevice.cc:153
EmuTime::param getCurrentTime() const
Definition MSXDevice.cc:125
MSXCPUInterface & getCPUInterface() const
Definition MSXDevice.cc:133
void powerDown(EmuTime::param time) override
This method is called when MSX is powered down.
Definition MSXPPI.cc:46
~MSXPPI() override
Definition MSXPPI.cc:31
void reset(EmuTime::param time) override
This method is called on reset.
Definition MSXPPI.cc:40
const Keyboard & getKeyboard() const
Definition MSXPPI.cc:36
MSXPPI(const DeviceConfig &config)
Definition MSXPPI.cc:13
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
Definition MSXPPI.cc:56
void serialize(Archive &ar, unsigned version)
Definition MSXPPI.cc:144
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
Definition MSXPPI.cc:51
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.
Definition MSXPPI.cc:61
bool getSignal(EmuTime::param time)
Get the output signal in negative logic.
This file implemented 3 utility functions:
Definition Autofire.cc:11
uint8_t byte
8 bit unsigned integer
Definition openmsx.hh:26
uint8_t nibble
4 bit integer
Definition openmsx.hh:23
uint16_t word
16 bit unsigned integer
Definition openmsx.hh:29
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)