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  switch (address) {
23  case 0x7FF8:
24  return controller.getStatusReg(time);
25  case 0x7FF9:
26  return controller.getTrackReg(time);
27  case 0x7FFA:
28  return controller.getSectorReg(time);
29  case 0x7FFB:
30  return controller.getDataReg(time);
31  case 0x7FFC:
32  case 0x7FFD:
33  case 0x7FFE:
34  case 0x7FFF: {
35  byte value = 0x3F;
36  if (controller.getIRQ(time)) value |= 0x80;
37  if (controller.getDTRQ(time)) value |= 0x40;
38  return value;
39  }
40  default:
41  return SanyoFDC::peekMem(address, time);
42  }
43 }
44 
45 byte SanyoFDC::peekMem(word address, EmuTime::param time) const
46 {
47  switch (address) {
48  case 0x7FF8:
49  return controller.peekStatusReg(time);
50  break;
51  case 0x7FF9:
52  return controller.peekTrackReg(time);
53  break;
54  case 0x7FFA:
55  return controller.peekSectorReg(time);
56  break;
57  case 0x7FFB:
58  return controller.peekDataReg(time);
59  break;
60  case 0x7FFC:
61  case 0x7FFD:
62  case 0x7FFE:
63  case 0x7FFF: {
64  // Drive control IRQ and DRQ lines are not connected to Z80 interrupt request
65  // bit 7: intrq
66  // bit 6: dtrq
67  // other bits read 1
68  byte value = 0x3F;
69  if (controller.peekIRQ(time)) value |= 0x80;
70  if (controller.peekDTRQ(time)) value |= 0x40;
71  return value;
72  }
73  default:
74  if (address < 0x8000) {
75  // ROM only visible in 0x0000-0x7FFF (not verified!)
76  return MSXFDC::peekMem(address, time);
77  } else {
78  return 255;
79  }
80  break;
81  }
82 }
83 
84 const byte* SanyoFDC::getReadCacheLine(word start) const
85 {
86  if ((start & CacheLine::HIGH) == (0x7FF8 & CacheLine::HIGH)) {
87  // FDC at 0x7FF8-0x7FFC - mirroring behaviour unknown
88  return nullptr;
89  } else if (start < 0x8000) {
90  // ROM at 0x0000-0x7FFF (this is a guess, not checked!)
91  return MSXFDC::getReadCacheLine(start);
92  } else {
93  return unmappedRead;
94  }
95 }
96 
97 void SanyoFDC::writeMem(word address, byte value, EmuTime::param time)
98 {
99  switch (address) {
100  case 0x7FF8:
101  controller.setCommandReg(value, time);
102  break;
103  case 0x7FF9:
104  controller.setTrackReg(value, time);
105  break;
106  case 0x7FFA:
107  controller.setSectorReg(value, time);
108  break;
109  case 0x7FFB:
110  controller.setDataReg(value, time);
111  break;
112  case 0x7FFC:
113  case 0x7FFD:
114  case 0x7FFE:
115  case 0x7FFF:
116  // bit 0 -> select drive 0
117  // bit 1 -> select drive 1
118  // bit 2 -> side select
119  // bit 3 -> motor on
120  auto drive = [&] {
121  switch (value & 3) {
122  case 1: return DriveMultiplexer::DRIVE_A;
123  case 2: return DriveMultiplexer::DRIVE_B;
124  default: return DriveMultiplexer::NO_DRIVE;
125  }
126  }();
127  multiplexer.selectDrive(drive, time);
128  multiplexer.setSide((value & 0x04) != 0);
129  multiplexer.setMotor((value & 0x08) != 0, time);
130  break;
131  }
132 }
133 
134 byte* SanyoFDC::getWriteCacheLine(word address) const
135 {
136  if ((address & CacheLine::HIGH) == (0x7FF8 & CacheLine::HIGH)) {
137  // FDC at 0x7FF8-0x7FFC - mirroring behaviour unknown
138  return nullptr;
139  } else {
140  return unmappedWrite;
141  }
142 }
143 
144 
145 template<typename Archive>
146 void SanyoFDC::serialize(Archive& ar, unsigned /*version*/)
147 {
148  ar.template serializeBase<WD2793BasedFDC>(*this);
149 }
152 
153 } // namespace openmsx
void setMotor(bool status, EmuTime::param time) override
Set motor on/off.
void selectDrive(DriveNum num, EmuTime::param time)
void setSide(bool side) override
Side select.
static byte unmappedRead[0x10000]
Definition: MSXDevice.hh:301
static byte unmappedWrite[0x10000]
Definition: MSXDevice.hh:302
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: MSXFDC.cc:54
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:59
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
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:84
byte * getWriteCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
Definition: SanyoFDC.cc:134
SanyoFDC(const DeviceConfig &config)
Definition: SanyoFDC.cc:15
void serialize(Archive &ar, unsigned version)
Definition: SanyoFDC.cc:146
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:97
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: SanyoFDC.cc:45
DriveMultiplexer multiplexer
bool peekIRQ(EmuTime::param time) const
Definition: WD2793.cc:110
byte peekStatusReg(EmuTime::param time) const
Definition: WD2793.cc:210
byte getTrackReg(EmuTime::param time) const
Definition: WD2793.cc:221
byte getDataReg(EmuTime::param time)
Definition: WD2793.cc:260
byte getSectorReg(EmuTime::param time) const
Definition: WD2793.cc:236
bool peekDTRQ(EmuTime::param time) const
Definition: WD2793.cc:95
bool getDTRQ(EmuTime::param time) const
Definition: WD2793.cc:90
byte getStatusReg(EmuTime::param time)
Definition: WD2793.cc:170
byte peekTrackReg(EmuTime::param time) const
Definition: WD2793.cc:226
void setTrackReg(byte value, EmuTime::param time)
Definition: WD2793.cc:216
void setDataReg(byte value, EmuTime::param time)
Definition: WD2793.cc:246
byte peekDataReg(EmuTime::param time) const
Definition: WD2793.cc:325
void setCommandReg(byte value, EmuTime::param time)
Definition: WD2793.cc:122
bool getIRQ(EmuTime::param time) const
Definition: WD2793.cc:105
void setSectorReg(byte value, EmuTime::param time)
Definition: WD2793.cc:231
byte peekSectorReg(EmuTime::param time) const
Definition: WD2793.cc:241
constexpr unsigned HIGH
Definition: CacheLine.hh:10
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:998