openMSX
SanyoFDC.cc
Go to the documentation of this file.
1 #include "SanyoFDC.hh"
2 #include "CacheLine.hh"
3 #include "DriveMultiplexer.hh"
4 #include "WD2793.hh"
5 #include "serialize.hh"
6 
7 // Note: although this implementation seems to work (e.g. for the Sanyo
8 // MFD-001), it has not been checked on real hardware how the FDC registers are
9 // mirrored across the slot, nor how the ROM is visible in the slot. Currently
10 // FDC registers are implemented to be not mirrored, and ROM is implemented to
11 // be visible in page 0 and 1.
12 
13 namespace openmsx {
14 
16  : WD2793BasedFDC(config)
17 {
18 }
19 
20 byte SanyoFDC::readMem(word address, EmuTime::param time)
21 {
22  byte value;
23  switch (address) {
24  case 0x7FF8:
25  value = controller.getStatusReg(time);
26  break;
27  case 0x7FF9:
28  value = controller.getTrackReg(time);
29  break;
30  case 0x7FFA:
31  value = controller.getSectorReg(time);
32  break;
33  case 0x7FFB:
34  value = controller.getDataReg(time);
35  break;
36  case 0x7FFC:
37  case 0x7FFD:
38  case 0x7FFE:
39  case 0x7FFF:
40  value = 0x3F;
41  if (controller.getIRQ(time)) value |= 0x80;
42  if (controller.getDTRQ(time)) value |= 0x40;
43  break;
44  default:
45  value = SanyoFDC::peekMem(address, time);
46  break;
47  }
48  return value;
49 }
50 
51 byte SanyoFDC::peekMem(word address, EmuTime::param time) const
52 {
53  byte value;
54  switch (address) {
55  case 0x7FF8:
56  value = controller.peekStatusReg(time);
57  break;
58  case 0x7FF9:
59  value = controller.peekTrackReg(time);
60  break;
61  case 0x7FFA:
62  value = controller.peekSectorReg(time);
63  break;
64  case 0x7FFB:
65  value = controller.peekDataReg(time);
66  break;
67  case 0x7FFC:
68  case 0x7FFD:
69  case 0x7FFE:
70  case 0x7FFF:
71  // Drive control IRQ and DRQ lines are not connected to Z80 interrupt request
72  // bit 7: intrq
73  // bit 6: dtrq
74  // other bits read 1
75  value = 0x3F;
76  if (controller.peekIRQ(time)) value |= 0x80;
77  if (controller.peekDTRQ(time)) value |= 0x40;
78  break;
79  default:
80  if (address < 0x8000) {
81  // ROM only visible in 0x0000-0x7FFF (not verified!)
82  value = MSXFDC::peekMem(address, time);
83  } else {
84  value = 255;
85  }
86  break;
87  }
88  return value;
89 }
90 
91 const byte* SanyoFDC::getReadCacheLine(word start) const
92 {
93  if ((start & CacheLine::HIGH) == (0x7FF8 & CacheLine::HIGH)) {
94  // FDC at 0x7FF8-0x7FFC - mirroring behaviour unknown
95  return nullptr;
96  } else if (start < 0x8000) {
97  // ROM at 0x0000-0x7FFF (this is a guess, not checked!)
98  return MSXFDC::getReadCacheLine(start);
99  } else {
100  return unmappedRead;
101  }
102 }
103 
104 void SanyoFDC::writeMem(word address, byte value, EmuTime::param time)
105 {
106  switch (address) {
107  case 0x7FF8:
108  controller.setCommandReg(value, time);
109  break;
110  case 0x7FF9:
111  controller.setTrackReg(value, time);
112  break;
113  case 0x7FFA:
114  controller.setSectorReg(value, time);
115  break;
116  case 0x7FFB:
117  controller.setDataReg(value, time);
118  break;
119  case 0x7FFC:
120  case 0x7FFD:
121  case 0x7FFE:
122  case 0x7FFF:
123  // bit 0 -> select drive 0
124  // bit 1 -> select drive 1
125  // bit 2 -> side select
126  // bit 3 -> motor on
128  switch (value & 3) {
129  case 1:
131  break;
132  case 2:
134  break;
135  default:
137  }
138  multiplexer.selectDrive(drive, time);
139  multiplexer.setSide((value & 0x04) != 0);
140  multiplexer.setMotor((value & 0x08) != 0, time);
141  break;
142  }
143 }
144 
145 byte* SanyoFDC::getWriteCacheLine(word address) const
146 {
147  if ((address & CacheLine::HIGH) == (0x7FF8 & CacheLine::HIGH)) {
148  // FDC at 0x7FF8-0x7FFC - mirroring behaviour unknown
149  return nullptr;
150  } else {
151  return unmappedWrite;
152  }
153 }
154 
155 
156 template<typename Archive>
157 void SanyoFDC::serialize(Archive& ar, unsigned /*version*/)
158 {
159  ar.template serializeBase<WD2793BasedFDC>(*this);
160 }
162 REGISTER_MSXDEVICE(SanyoFDC, "SanyoFDC");
163 
164 } // namespace openmsx
openmsx::SanyoFDC::peekMem
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: SanyoFDC.cc:51
openmsx::SanyoFDC::readMem
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: SanyoFDC.cc:20
openmsx::MSXFDC::peekMem
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: MSXFDC.cc:55
openmsx::SanyoFDC::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: SanyoFDC.cc:104
openmsx::WD2793BasedFDC::multiplexer
DriveMultiplexer multiplexer
Definition: WD2793BasedFDC.hh:24
serialize.hh
openmsx::WD2793BasedFDC::controller
WD2793 controller
Definition: WD2793BasedFDC.hh:25
openmsx::DeviceConfig
Definition: DeviceConfig.hh:19
openmsx::MSXDevice::unmappedWrite
static byte unmappedWrite[0x10000]
Definition: MSXDevice.hh:293
openmsx::WD2793::getIRQ
bool getIRQ(EmuTime::param time)
Definition: WD2793.cc:105
openmsx::SanyoFDC::getReadCacheLine
const byte * getReadCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition: SanyoFDC.cc:91
openmsx::WD2793::getDataReg
byte getDataReg(EmuTime::param time)
Definition: WD2793.cc:260
openmsx::WD2793::peekStatusReg
byte peekStatusReg(EmuTime::param time) const
Definition: WD2793.cc:210
openmsx::WD2793::peekIRQ
bool peekIRQ(EmuTime::param time) const
Definition: WD2793.cc:110
openmsx::WD2793::getStatusReg
byte getStatusReg(EmuTime::param time)
Definition: WD2793.cc:170
openmsx::CacheLine::HIGH
constexpr unsigned HIGH
Definition: CacheLine.hh:10
openmsx::WD2793BasedFDC
Definition: WD2793BasedFDC.hh:11
openmsx::DriveMultiplexer::setMotor
void setMotor(bool status, EmuTime::param time) override
Set motor on/off.
Definition: DriveMultiplexer.cc:64
openmsx::DriveMultiplexer::NO_DRIVE
Definition: DriveMultiplexer.hh:20
openmsx::REGISTER_MSXDEVICE
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
openmsx::WD2793::getTrackReg
byte getTrackReg(EmuTime::param time)
Definition: WD2793.cc:221
openmsx::DriveMultiplexer::setSide
void setSide(bool side) override
Side select.
Definition: DriveMultiplexer.cc:43
openmsx::SanyoFDC::serialize
void serialize(Archive &ar, unsigned version)
Definition: SanyoFDC.cc:157
openmsx::DriveMultiplexer::DRIVE_B
Definition: DriveMultiplexer.hh:17
openmsx::WD2793::getSectorReg
byte getSectorReg(EmuTime::param time)
Definition: WD2793.cc:236
INSTANTIATE_SERIALIZE_METHODS
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:981
openmsx::DriveMultiplexer::DRIVE_A
Definition: DriveMultiplexer.hh:16
openmsx::WD2793::setDataReg
void setDataReg(byte value, EmuTime::param time)
Definition: WD2793.cc:246
CacheLine.hh
DriveMultiplexer.hh
WD2793.hh
openmsx::MSXDevice::unmappedRead
static byte unmappedRead[0x10000]
Definition: MSXDevice.hh:292
openmsx::word
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
openmsx::WD2793::peekSectorReg
byte peekSectorReg(EmuTime::param time) const
Definition: WD2793.cc:241
openmsx::SanyoFDC::getWriteCacheLine
byte * getWriteCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
Definition: SanyoFDC.cc:145
openmsx::DriveMultiplexer::selectDrive
void selectDrive(DriveNum num, EmuTime::param time)
Definition: DriveMultiplexer.cc:18
openmsx::WD2793::setCommandReg
void setCommandReg(byte value, EmuTime::param time)
Definition: WD2793.cc:122
openmsx::DriveMultiplexer::DriveNum
DriveNum
Definition: DriveMultiplexer.hh:15
openmsx::WD2793::peekDataReg
byte peekDataReg(EmuTime::param time) const
Definition: WD2793.cc:324
openmsx::MSXFDC::getReadCacheLine
const byte * getReadCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition: MSXFDC.cc:60
openmsx::SanyoFDC::SanyoFDC
SanyoFDC(const DeviceConfig &config)
Definition: SanyoFDC.cc:15
openmsx::WD2793::peekDTRQ
bool peekDTRQ(EmuTime::param time) const
Definition: WD2793.cc:95
openmsx::WD2793::peekTrackReg
byte peekTrackReg(EmuTime::param time) const
Definition: WD2793.cc:226
openmsx::WD2793::setSectorReg
void setSectorReg(byte value, EmuTime::param time)
Definition: WD2793.cc:231
openmsx::WD2793::getDTRQ
bool getDTRQ(EmuTime::param time)
Definition: WD2793.cc:90
openmsx::WD2793::setTrackReg
void setTrackReg(byte value, EmuTime::param time)
Definition: WD2793.cc:216
openmsx
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
SanyoFDC.hh
openmsx::SanyoFDC
Definition: SanyoFDC.hh:8