openMSX
MSXTurboRPCM.cc
Go to the documentation of this file.
1#include "MSXTurboRPCM.hh"
2#include "MSXMotherBoard.hh"
3#include "MSXMixer.hh"
4#include "serialize.hh"
5#include "unreachable.hh"
6
7namespace openmsx {
8
10 : MSXDevice(config)
11 , mixer(getMotherBoard().getMSXMixer())
12 , connector(getPluggingController(), "pcminput")
13 , dac("PCM", "Turbo-R PCM", config)
14 , reference(getCurrentTime())
15{
17}
18
20{
21 hardwareMute(false);
22}
23
24void MSXTurboRPCM::reset(EmuTime::param time)
25{
26 reference.reset(time);
27 status = 0;
28 DValue = 0x80; // TODO correct initial value?
29 hold = 0x80; // avoid UMR
30 dac.reset(time);
31 hardwareMute(false);
32}
33
34byte MSXTurboRPCM::readIO(word port, EmuTime::param time)
35{
36 return peekIO(port, time);
37}
38
39byte MSXTurboRPCM::peekIO(word port, EmuTime::param time) const
40{
41 switch (port & 0x01) {
42 case 0:
43 // bit 0-1 15.75kHz counter
44 // bit 2-7 not used
45 return reference.getTicksTill(time) & 0x03;
46 case 1:
47 // bit 0 BUFF 0->D/A TODO check this bit
48 // 1->A/D
49 // bit 1 MUTE mute ALL sound 0->muted
50 // bit 2 FILT filter 0->standard signal
51 // 1->filtered signal
52 // bit 3 SEL select 0->D/A
53 // 1->Mic/Jack
54 // bit 4 SMPL sample/hold 0->sample
55 // 1->hold
56 // bit 5-6 not used
57 // bit 7 COMP comparator result 0->greater
58 // 1->smaller
59 return (getComp(time) ? 0x80 : 0x00) | (status & 0x1F);
60 default: // unreachable, avoid warning
61 UNREACHABLE; return 0;
62 }
63}
64
65void MSXTurboRPCM::writeIO(word port, byte value, EmuTime::param time)
66{
67 switch (port & 0x01) {
68 case 0:
69 // While playing: sample value
70 // recording: compare value
71 // Resets counter
72 reference.advance(time);
73 DValue = value;
74 if (status & 0x02) {
75 dac.writeDAC(DValue, time);
76 }
77 break;
78
79 case 1:
80 // bit 0 BUFF
81 // bit 1 MUTE mute _all_ sound 0->no sound
82 // bit 2 FILT filter 1->filter on
83 // bit 3 SEL select 1->Mic/Jack 0->D/A
84 // bit 4 SMPL sample/hold 1->hold
85 // bit 5-7 not used
86 byte change = status ^ value;
87 status = value;
88
89 if ((change & 0x01) && ((status & 0x01) == 0)) {
90 dac.writeDAC(DValue, time);
91 }
92 // TODO status & 0x08
93 if ((change & 0x10) && (status & 0x10)) {
94 hold = getSample(time);
95 }
96 hardwareMute(!(status & 0x02));
97 break;
98 }
99}
100
101byte MSXTurboRPCM::getSample(EmuTime::param time) const
102{
103 return (status & 0x04)
104 ? (connector.readSample(time) / 256) + 0x80
105 : 0x80; // TODO check
106}
107
108bool MSXTurboRPCM::getComp(EmuTime::param time) const
109{
110 // TODO also when D/A ??
111 byte sample = (status & 0x10) ? hold : getSample(time);
112 return sample >= DValue;
113}
114
115void MSXTurboRPCM::hardwareMute(bool mute)
116{
117 if (mute == hwMute) return;
118
119 hwMute = mute;
120 if (hwMute) {
121 mixer.mute();
122 } else {
123 mixer.unmute();
124 }
125}
126
127
128template<typename Archive>
129void MSXTurboRPCM::serialize(Archive& ar, unsigned /*version*/)
130{
131 ar.template serializeBase<MSXDevice>(*this);
132 ar.serialize("audioConnector", connector,
133 "reference", reference,
134 "status", status,
135 "DValue", DValue,
136 "hold", hold,
137 "DAC", dac);
138
139 hardwareMute(!(status & 0x02)); // restore hwMute
140}
143
144} // namespace openmsx
int16_t readSample(EmuTime::param time) const
constexpr void reset(EmuTime::param e)
Reset the clock to start ticking at the given time.
Definition: Clock.hh:102
constexpr void advance(EmuTime::param e)
Advance this clock in time until the last tick which is not past the given time.
Definition: Clock.hh:110
constexpr unsigned getTicksTill(EmuTime::param e) const
Calculate the number of ticks for this clock until the given time.
Definition: Clock.hh:58
void reset(EmuTime::param time)
Definition: DACSound16S.cc:29
void writeDAC(uint8_t value, EmuTime::param time)
Definition: DACSound8U.cc:17
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition: MSXDevice.hh:34
EmuTime::param getCurrentTime() const
Definition: MSXDevice.cc:125
void mute()
TODO This methods (un)mute the sound.
Definition: MSXMixer.cc:609
MSXTurboRPCM(const DeviceConfig &config)
Definition: MSXTurboRPCM.cc:9
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: MSXTurboRPCM.cc:65
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
Definition: MSXTurboRPCM.cc:34
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
Definition: MSXTurboRPCM.cc:39
void serialize(Archive &ar, unsigned version)
~MSXTurboRPCM() override
Definition: MSXTurboRPCM.cc:19
void reset(EmuTime::param time) override
This method is called on reset.
Definition: MSXTurboRPCM.cc:24
This file implemented 3 utility functions:
Definition: Autofire.cc:9
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1021
#define UNREACHABLE
Definition: unreachable.hh:38