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