openMSX
MSXYamahaSFG.cc
Go to the documentation of this file.
1 #include "MSXYamahaSFG.hh"
2 #include "CacheLine.hh"
3 #include "serialize.hh"
4 
5 namespace openmsx {
6 
7 static YM2151::Variant parseVariant(const DeviceConfig& config)
8 {
9  auto variant = config.getChildData("variant", "YM2151");
10  if (variant == "YM2151") return YM2151::Variant::YM2151;
11  if (variant == "YM2164") return YM2151::Variant::YM2164;
12  throw MSXException("Invalid variant '", variant, "', expected 'YM2151' or 'YM2164'.");
13 }
14 
16  : MSXDevice(config)
17  , rom(getName() + " ROM", "rom", config)
18  , ym2151(getName(), "Yamaha SFG-01/05", config, getCurrentTime(), parseVariant(config))
19  , ym2148(getName(), getMotherBoard())
20 {
22 }
23 
24 void MSXYamahaSFG::reset(EmuTime::param time)
25 {
26  ym2151.reset(time);
27  ym2148.reset();
28  registerLatch = 0; // TODO check
29  irqVector = 255; // TODO check
30  irqVector2148 = 255; // TODO check
31 }
32 
33 void MSXYamahaSFG::writeMem(word address, byte value, EmuTime::param time)
34 {
35  word maskedAddress = address & 0x3FFF;
36  switch (maskedAddress) {
37  case 0x3FF0: // OPM ADDRESS REGISTER
38  writeRegisterPort(value, time);
39  break;
40  case 0x3FF1: // OPM DATA REGISTER
41  writeDataPort(value, time);
42  break;
43  case 0x3FF2: // Register for data latched to ST0 to ST7 output ports
44  // TODO: keyboardLatch = value;
45  //std::cerr << "TODO: keyboardLatch = " << (int)value << '\n';
46  break;
47  case 0x3FF3: // MIDI IRQ VECTOR ADDRESS REGISTER
48  irqVector2148 = value;
49  break;
50  case 0x3FF4: // EXTERNAL IRQ VECTOR ADDRESS REGISTER
51  // IRQ vector for YM2151 (+ default vector ???)
52  irqVector = value;
53  break;
54  case 0x3FF5: // MIDI standard UART DATA WRITE BUFFER
55  ym2148.writeData(value, time);
56  break;
57  case 0x3FF6: // MIDI standard UART COMMAND REGISTER
58  ym2148.writeCommand(value);
59  break;
60  }
61 }
62 
64 {
65  if ((start & 0x3FFF & CacheLine::HIGH) == (0x3FF0 & CacheLine::HIGH)) {
66  return nullptr;
67  }
68  return unmappedWrite;
69 }
70 
72 {
73  return ym2148.pendingIRQ() ? irqVector2148 : irqVector;
74 }
75 
76 void MSXYamahaSFG::writeRegisterPort(byte value, EmuTime::param /*time*/)
77 {
78  registerLatch = value;
79 }
80 
81 void MSXYamahaSFG::writeDataPort(byte value, EmuTime::param time)
82 {
83  ym2151.writeReg(registerLatch, value, time);
84 }
85 
86 byte MSXYamahaSFG::readMem(word address, EmuTime::param time)
87 {
88  word maskedAddress = address & 0x3FFF;
89  if (maskedAddress < 0x3FF0 || maskedAddress >= 0x3FF8) {
90  return peekMem(address, time);
91  }
92  switch (maskedAddress) {
93  case 0x3FF0: // (not used, it seems)
94  case 0x3FF1: // OPM STATUS REGISTER
95  case 0x3FF2: // Data buffer for SD0 to SD7 input ports
96  return peekMem(address, time);
97  case 0x3FF5: // MIDI standard UART DATA READ BUFFER
98  return ym2148.readData(time);
99  case 0x3FF6: // MIDI standard UART STATUS REGISTER
100  return ym2148.readStatus(time);
101  }
102  return 0xFF;
103 }
104 
105 byte MSXYamahaSFG::peekMem(word address, EmuTime::param time) const
106 {
107  word maskedAddress = address & 0x3FFF;
108  if (maskedAddress < 0x3FF0 || maskedAddress >= 0x3FF8) {
109  // size can also be 16kB for SFG-01 or 32kB for SFG-05
110  return rom[address & (rom.getSize() - 1)];
111  }
112  switch (maskedAddress) {
113  case 0x3FF0: // (not used, it seems)
114  return 0xFF;
115  case 0x3FF1: // OPM STATUS REGISTER
116  return ym2151.readStatus();
117  case 0x3FF2: // Data buffer for SD0 to SD7 input ports
118  // TODO: return getKbdStatus();
119  break;
120  case 0x3FF5: // MIDI standard UART DATA READ BUFFER
121  return ym2148.peekData(time);
122  case 0x3FF6: // MIDI standard UART STATUS REGISTER
123  return ym2148.peekStatus(time);
124  }
125  return 0xFF;
126 }
127 
128 const byte* MSXYamahaSFG::getReadCacheLine(word start) const
129 {
130  if ((start & 0x3FFF & CacheLine::HIGH) == (0x3FF0 & CacheLine::HIGH)) {
131  return nullptr;
132  }
133  return &rom[start & (rom.getSize() - 1)];
134 }
135 
136 // version 1: initial version
137 // version 2: moved irqVector2148 from ym2148 to here
138 template<typename Archive>
139 void MSXYamahaSFG::serialize(Archive& ar, unsigned version)
140 {
141  ar.serialize("YM2151", ym2151,
142  "YM2148", ym2148,
143  "registerLatch", registerLatch,
144  "irqVector", irqVector);
145  if (ar.versionAtLeast(version, 2)) {
146  ar.serialize("irqVector2148", irqVector2148);
147  } else {
148  irqVector2148 = 255; // could be retrieved from the old ym2148
149  // savestate data, but I didn't bother
150  }
151 }
154 
155 } // namespace openmsx
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition: MSXDevice.hh:33
EmuTime::param getCurrentTime() const
Definition: MSXDevice.cc:126
static byte unmappedWrite[0x10000]
Definition: MSXDevice.hh:302
void reset(EmuTime::param time) override
This method is called on reset.
Definition: MSXYamahaSFG.cc:24
MSXYamahaSFG(const DeviceConfig &config)
Definition: MSXYamahaSFG.cc:15
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: MSXYamahaSFG.cc:86
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: MSXYamahaSFG.cc:33
byte readIRQVector() override
Gets IRQ vector used in IM2.
Definition: MSXYamahaSFG.cc:71
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
const byte * getReadCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
void serialize(Archive &ar, unsigned version)
byte * getWriteCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
Definition: MSXYamahaSFG.cc:63
unsigned getSize() const
Definition: Rom.hh:34
void reset()
Definition: YM2148.cc:43
byte readData(EmuTime::param time)
Definition: YM2148.cc:124
void writeCommand(byte value)
Definition: YM2148.cc:136
byte peekData(EmuTime::param time) const
Definition: YM2148.cc:130
byte readStatus(EmuTime::param time) const
Definition: YM2148.cc:114
byte peekStatus(EmuTime::param time) const
Definition: YM2148.cc:118
bool pendingIRQ() const
Definition: YM2148.cc:222
void writeData(byte value, EmuTime::param time)
Definition: YM2148.cc:179
byte readStatus() const
Definition: YM2151.cc:1548
void writeReg(byte r, byte v, EmuTime::param time)
Definition: YM2151.cc:649
void reset(EmuTime::param time)
Definition: YM2151.cc:929
constexpr unsigned HIGH
Definition: CacheLine.hh:10
std::string getName(KeyCode keyCode)
Translate key code to key name.
Definition: Keys.cc:727
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:1009