openMSX
PhilipsFDC.cc
Go to the documentation of this file.
1 #include "PhilipsFDC.hh"
2 #include "CacheLine.hh"
3 #include "DriveMultiplexer.hh"
4 #include "WD2793.hh"
5 #include "serialize.hh"
6 
7 namespace openmsx {
8 
10  : WD2793BasedFDC(config)
11 {
13 }
14 
16 {
18  writeMem(0x3FFC, 0x00, time);
19  writeMem(0x3FFD, 0x00, time);
20 }
21 
23 {
24  byte value;
25  switch (address & 0x3FFF) {
26  case 0x3FF8:
27  value = controller->getStatusReg(time);
28  break;
29  case 0x3FF9:
30  value = controller->getTrackReg(time);
31  break;
32  case 0x3FFA:
33  value = controller->getSectorReg(time);
34  break;
35  case 0x3FFB:
36  value = controller->getDataReg(time);
37  break;
38  case 0x3FFF:
39  value = 0xC0;
40  if (controller->getIRQ(time)) value &= ~0x40;
41  if (controller->getDTRQ(time)) value &= ~0x80;
42  break;
43  default:
44  value = PhilipsFDC::peekMem(address, time);
45  break;
46  }
47  return value;
48 }
49 
51 {
52  byte value;
53  // FDC registers are mirrored in
54  // 0x3FF8-0x3FFF
55  // 0x7FF8-0x7FFF
56  // 0xBFF8-0xBFFF
57  // 0xFFF8-0xFFFF
58  switch (address & 0x3FFF) {
59  case 0x3FF8:
60  value = controller->peekStatusReg(time);
61  break;
62  case 0x3FF9:
63  value = controller->peekTrackReg(time);
64  break;
65  case 0x3FFA:
66  value = controller->peekSectorReg(time);
67  break;
68  case 0x3FFB:
69  value = controller->peekDataReg(time);
70  break;
71  case 0x3FFC:
72  // bit 0 = side select
73  // TODO check other bits !!
74  value = sideReg; // value = multiplexer.getSideSelect();
75  break;
76  case 0x3FFD:
77  // bit 1,0 -> drive number
78  // (00 or 10: drive A, 01: drive B, 11: nothing)
79  // bit 7 -> motor on
80  // TODO check other bits !!
81  value = driveReg; // multiplexer.getSelectedDrive();
82  break;
83  case 0x3FFE:
84  // not used
85  value = 255;
86  break;
87  case 0x3FFF:
88  // Drive control IRQ and DRQ lines are not connected to Z80
89  // interrupt request
90  // bit 6: !intrq
91  // bit 7: !dtrq
92  // TODO check other bits !!
93  value = 0xC0;
94  if (controller->peekIRQ(time)) value &= ~0x40;
95  if (controller->peekDTRQ(time)) value &= ~0x80;
96  break;
97 
98  default:
99  if ((0x4000 <= address) && (address < 0x8000)) {
100  // ROM only visible in 0x4000-0x7FFF
101  value = MSXFDC::peekMem(address, time);
102  } else {
103  value = 255;
104  }
105  break;
106  }
107  //PRT_DEBUG("PhilipsFDC read 0x" << hex << (int)address <<
108  // " 0x" << (int)value << dec);
109  return value;
110 }
111 
113 {
114  // if address overlap 0x7ff8-0x7ffb then return nullptr,
115  // else normal ROM behaviour
116  if ((start & 0x3FF8 & CacheLine::HIGH) == (0x3FF8 & CacheLine::HIGH)) {
117  return nullptr;
118  } else if ((0x4000 <= start) && (start < 0x8000)) {
119  // ROM visible in 0x4000-0x7FFF
120  return MSXFDC::getReadCacheLine(start);
121  } else {
122  return unmappedRead;
123  }
124 }
125 
126 void PhilipsFDC::writeMem(word address, byte value, EmuTime::param time)
127 {
128  //PRT_DEBUG("PhilipsFDC write 0x" << hex << (int)address <<
129  // " 0x" << (int)value << dec);
130  switch (address & 0x3FFF) {
131  case 0x3FF8:
132  controller->setCommandReg(value, time);
133  break;
134  case 0x3FF9:
135  controller->setTrackReg(value, time);
136  break;
137  case 0x3FFA:
138  controller->setSectorReg(value, time);
139  break;
140  case 0x3FFB:
141  controller->setDataReg(value, time);
142  break;
143  case 0x3FFC:
144  // bit 0 = side select
145  // TODO check other bits !!
146  sideReg = value;
147  multiplexer->setSide(value & 1);
148  break;
149  case 0x3FFD:
150  // bit 1,0 -> drive number
151  // (00 or 10: drive A, 01: drive B, 11: nothing)
152  // TODO bit 6 -> drive LED (0 -> off, 1 -> on)
153  // bit 7 -> motor on
154  // TODO check other bits !!
155  driveReg = value;
157  switch (value & 3) {
158  case 0:
159  case 2:
161  break;
162  case 1:
164  break;
165  case 3:
166  default:
168  }
169  multiplexer->selectDrive(drive, time);
170  multiplexer->setMotor((value & 128) != 0, time);
171  break;
172  }
173 }
174 
176 {
177  if ((address & 0x3FF8) == (0x3FF8 & CacheLine::HIGH)) {
178  return nullptr;
179  } else {
180  return unmappedWrite;
181  }
182 }
183 
184 
185 template<typename Archive>
186 void PhilipsFDC::serialize(Archive& ar, unsigned /*version*/)
187 {
188  ar.template serializeBase<WD2793BasedFDC>(*this);
189  ar.serialize("sideReg", sideReg);
190  ar.serialize("driveReg", driveReg);
191 }
193 REGISTER_MSXDEVICE(PhilipsFDC, "PhilipsFDC");
194 
195 } // namespace openmsx
virtual void reset(EmuTime::param time)
This method is called on reset.
REGISTER_MSXDEVICE(DebugDevice,"DebugDevice")
const std::unique_ptr< DriveMultiplexer > multiplexer
EmuTime::param getCurrentTime() const
Definition: MSXDevice.cc:151
unsigned char byte
8 bit unsigned integer
Definition: openmsx.hh:33
virtual byte readMem(word address, EmuTime::param time)
Read a byte from a location at a certain time from this device.
Definition: PhilipsFDC.cc:22
virtual byte peekMem(word address, EmuTime::param time) const
Read a byte from a given memory location.
Definition: MSXFDC.cc:53
virtual const byte * getReadCacheLine(word start) const
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading...
Definition: PhilipsFDC.cc:112
const std::unique_ptr< WD2793 > controller
virtual byte * getWriteCacheLine(word address) const
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing...
Definition: PhilipsFDC.cc:175
virtual void reset(EmuTime::param time)
This method is called on reset.
Definition: PhilipsFDC.cc:15
unsigned short word
16 bit unsigned integer
Definition: openmsx.hh:38
virtual byte peekMem(word address, EmuTime::param time) const
Read a byte from a given memory location.
Definition: PhilipsFDC.cc:50
void serialize(Archive &ar, unsigned version)
Definition: PhilipsFDC.cc:186
virtual const byte * getReadCacheLine(word start) const
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading...
Definition: MSXFDC.cc:58
static byte unmappedRead[0x10000]
Definition: MSXDevice.hh:260
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:802
static byte unmappedWrite[0x10000]
Definition: MSXDevice.hh:261
virtual void writeMem(word address, byte value, EmuTime::param time)
Write a given byte to a given location at a certain time to this device.
Definition: PhilipsFDC.cc:126
PhilipsFDC(const DeviceConfig &config)
Definition: PhilipsFDC.cc:9