openMSX
MSXYamahaSFG.cc
Go to the documentation of this file.
1#include "MSXYamahaSFG.hh"
2#include "CacheLine.hh"
3#include "serialize.hh"
4
5namespace openmsx {
6
7static 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
24void 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
33void 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.data();
69}
70
72{
73 return ym2148.pendingIRQ() ? irqVector2148 : irqVector;
74}
75
76void MSXYamahaSFG::writeRegisterPort(byte value, EmuTime::param /*time*/)
77{
78 registerLatch = value;
79}
80
81void MSXYamahaSFG::writeDataPort(byte value, EmuTime::param time)
82{
83 ym2151.writeReg(registerLatch, value, time);
84}
85
86byte 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
105byte 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.size() - 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
128const 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.size() - 1)];
134}
135
136// version 1: initial version
137// version 2: moved irqVector2148 from ym2148 to here
138template<typename Archive>
139void 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
#define REGISTER_MSXDEVICE(CLASS, NAME)
Definition MSXDevice.hh:356
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition MSXDevice.hh:36
static std::array< byte, 0x10000 > unmappedWrite
Definition MSXDevice.hh:307
EmuTime::param getCurrentTime() const
Definition MSXDevice.cc:125
void reset(EmuTime::param time) override
This method is called on reset.
MSXYamahaSFG(const DeviceConfig &config)
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
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.
byte * getWriteCacheLine(word start) override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
byte readIRQVector() override
Gets IRQ vector used in IM2.
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)
auto size() const
Definition Rom.hh:37
void reset()
Definition YM2148.cc:42
byte readData(EmuTime::param time)
Definition YM2148.cc:123
void writeCommand(byte value)
Definition YM2148.cc:135
byte peekData(EmuTime::param time) const
Definition YM2148.cc:129
byte readStatus(EmuTime::param time) const
Definition YM2148.cc:113
byte peekStatus(EmuTime::param time) const
Definition YM2148.cc:117
bool pendingIRQ() const
Definition YM2148.cc:221
void writeData(byte value, EmuTime::param time)
Definition YM2148.cc:178
uint8_t readStatus() const
Definition YM2151.cc:1535
void reset(EmuTime::param time)
Definition YM2151.cc:927
void writeReg(uint8_t r, uint8_t v, EmuTime::param time)
Definition YM2151.cc:651
constexpr unsigned HIGH
Definition CacheLine.hh:10
This file implemented 3 utility functions:
Definition Autofire.cc:11
uint16_t word
16 bit unsigned integer
Definition openmsx.hh:29
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)