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