openMSX
MSXAudio.cc
Go to the documentation of this file.
1 #include "MSXAudio.hh"
2 #include "Y8950Periphery.hh"
3 #include "DACSound8U.hh"
4 #include "StringOp.hh"
5 #include "serialize.hh"
6 #include <memory>
7 
8 using std::string;
9 
10 namespace openmsx {
11 
12 // MSXAudio
13 
15  : MSXDevice(config)
16  , y8950(getName(), config,
17  config.getChildDataAsInt("sampleram", 256) * 1024,
18  getCurrentTime(), *this)
19  , dacValue(0x80), dacEnabled(false)
20 {
21  auto type = config.getChildData("type", "philips");
23  if (cmp(type, "philips")) {
24  dac = std::make_unique<DACSound8U>(
25  getName() + " 8-bit DAC", "MSX-AUDIO 8-bit DAC",
26  config);
27  }
29 }
30 
32 {
33  // delete soon, because PanasonicAudioPeriphery still uses
34  // this object in its destructor
35  periphery.reset();
36 }
37 
38 Y8950Periphery& MSXAudio::createPeriphery(const string& soundDeviceName)
39 {
41  *this, getDeviceConfig2(), soundDeviceName);
42  return *periphery;
43 }
44 
45 void MSXAudio::powerUp(EmuTime::param time)
46 {
47  y8950.clearRam();
48  reset(time);
49 }
50 
51 void MSXAudio::reset(EmuTime::param time)
52 {
53  y8950.reset(time);
54  periphery->reset();
55  registerLatch = 0; // TODO check
56 }
57 
58 byte MSXAudio::readIO(word port, EmuTime::param time)
59 {
60  if ((port & 0xE8) == 0x08) {
61  // read DAC
62  return 0xFF;
63  } else {
64  return (port & 1) ? y8950.readReg(registerLatch, time)
65  : y8950.readStatus(time);
66  }
67 }
68 
69 byte MSXAudio::peekIO(word port, EmuTime::param time) const
70 {
71  if ((port & 0xE8) == 0x08) {
72  // read DAC
73  return 0xFF; // read always returns 0xFF
74  } else {
75  return (port & 1) ? y8950.peekReg(registerLatch, time)
76  : y8950.peekStatus(time);
77  }
78 }
79 
80 void MSXAudio::writeIO(word port, byte value, EmuTime::param time)
81 {
82  if ((port & 0xE8) == 0x08) {
83  dacValue = value;
84  if (dacEnabled) {
85  assert(dac);
86  dac->writeDAC(dacValue, time);
87  }
88  } else if ((port & 0x01) == 0) {
89  // 0xC0 or 0xC2
90  registerLatch = value;
91  } else {
92  // 0xC1 or 0xC3
93  y8950.writeReg(registerLatch, value, time);
94  }
95 }
96 
97 byte MSXAudio::readMem(word address, EmuTime::param time)
98 {
99  return periphery->readMem(address, time);
100 }
101 byte MSXAudio::peekMem(word address, EmuTime::param time) const
102 {
103  return periphery->peekMem(address, time);
104 }
105 void MSXAudio::writeMem(word address, byte value, EmuTime::param time)
106 {
107  periphery->writeMem(address, value, time);
108 }
109 const byte* MSXAudio::getReadCacheLine(word start) const
110 {
111  return periphery->getReadCacheLine(start);
112 }
114 {
115  return periphery->getWriteCacheLine(start);
116 }
117 
118 void MSXAudio::enableDAC(bool enable, EmuTime::param time)
119 {
120  if ((dacEnabled != enable) && dac) {
121  dacEnabled = enable;
122  byte value = dacEnabled ? dacValue : 0x80;
123  dac->writeDAC(value, time);
124  }
125 }
126 
127 template<typename Archive>
128 void MSXAudio::serialize(Archive& ar, unsigned /*version*/)
129 {
130  ar.serializePolymorphic("periphery", *periphery);
131  ar.serialize("Y8950", y8950,
132  "registerLatch", registerLatch,
133  "dacValue", dacValue,
134  "dacEnabled", dacEnabled);
135 
136  if constexpr (Archive::IS_LOADER) {
137  // restore dac status
138  if (dacEnabled) {
139  assert(dac);
140  dac->writeDAC(dacValue, getCurrentTime());
141  }
142  }
143 }
146 
147 } // namespace openmsx
const std::string & getChildData(std::string_view name) const
Definition: DeviceConfig.cc:43
void powerUp(EmuTime::param time) override
This method is called when MSX is powered up.
Definition: MSXAudio.cc:45
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: MSXAudio.cc:101
const byte * getReadCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition: MSXAudio.cc:109
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: MSXAudio.cc:80
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
Definition: MSXAudio.cc:58
void writeMem(word address, byte value, EmuTime::param time) override
Write a given byte to a given location at a certain time to this device.
Definition: MSXAudio.cc:105
MSXAudio(const DeviceConfig &config)
Definition: MSXAudio.cc:14
byte * getWriteCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
Definition: MSXAudio.cc:113
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: MSXAudio.cc:97
void serialize(Archive &ar, unsigned version)
Definition: MSXAudio.cc:128
void reset(EmuTime::param time) override
This method is called on reset.
Definition: MSXAudio.cc:51
~MSXAudio() override
Definition: MSXAudio.cc:31
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
Definition: MSXAudio.cc:69
Y8950Periphery & createPeriphery(const std::string &soundDeviceName)
Creates a periphery object for this MSXAudio cartridge.
Definition: MSXAudio.cc:38
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition: MSXDevice.hh:32
const DeviceConfig & getDeviceConfig2() const
Definition: MSXDevice.hh:233
virtual std::string getName() const
Returns a human-readable name for this device.
Definition: MSXDevice.cc:376
EmuTime::param getCurrentTime() const
Definition: MSXDevice.cc:128
static std::unique_ptr< Y8950Periphery > create(MSXAudio &audio, const DeviceConfig &config, const std::string &soundDeviceName)
Models the 4 general purpose I/O pins on the Y8950 (controlled by registers r#18 and r#19)
void reset(EmuTime::param time)
Definition: Y8950.cc:551
byte readStatus(EmuTime::param time) const
Definition: Y8950.cc:1178
byte peekReg(byte rg, EmuTime::param time) const
Definition: Y8950.cc:1155
void clearRam()
Definition: Y8950.cc:545
void writeReg(byte rg, byte data, EmuTime::param time)
Definition: Y8950.cc:896
byte readReg(byte rg, EmuTime::param time)
Definition: Y8950.cc:1140
byte peekStatus(EmuTime::param time) const
Definition: Y8950.cc:1185
string getName(KeyCode keyCode)
Translate key code to key name.
Definition: Keys.cc:742
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:983