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