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
7namespace openmsx {
8
10 : WD2793BasedFDC(config)
11{
13}
14
15void PhilipsFDC::reset(EmuTime::param time)
16{
18 writeMem(0x3FFC, 0x00, time);
19 writeMem(0x3FFD, 0x00, time);
20}
21
22byte PhilipsFDC::readMem(word address, EmuTime::param time)
23{
24 switch (address & 0x3FFF) {
25 case 0x3FF8:
26 return controller.getStatusReg(time);
27 case 0x3FF9:
28 return controller.getTrackReg(time);
29 case 0x3FFA:
30 return controller.getSectorReg(time);
31 case 0x3FFB:
32 return controller.getDataReg(time);
33 case 0x3FFD: {
34 byte res = driveReg & ~4;
35 if (!multiplexer.diskChanged()) {
36 res |= 4;
37 }
38 return res;
39 }
40 case 0x3FFF: {
41 // bit 6: !intrq
42 // bit 7: !dtrq
43 // bit 5: !type1 (Philips VY-0010/JVC HC-FC303, pin 2 of FDD
44 // interface, indicates DS drive)
45 // bit 4: !type0 (Philips VY-0010/JVC HC-FC303, pin 1 of FDD
46 // interface)
47 // Other bits are not connected, according to service manuals
48 // of VY-0010 and Sony HBD-50.
49 byte value = 0xFF; // all bits are pulled up to 1
50 if (controller.getIRQ(time)) value &= ~0x40;
51 if (controller.getDTRQ(time)) value &= ~0x80;
52 return value;
53 }
54 default:
55 return PhilipsFDC::peekMem(address, time);
56 }
57}
58
59byte PhilipsFDC::peekMem(word address, EmuTime::param time) const
60{
61 // FDC registers are mirrored in
62 // 0x3FF8-0x3FFF
63 // 0x7FF8-0x7FFF
64 // 0xBFF8-0xBFFF
65 // 0xFFF8-0xFFFF
66 switch (address & 0x3FFF) {
67 case 0x3FF8:
68 return controller.peekStatusReg(time);
69 case 0x3FF9:
70 return controller.peekTrackReg(time);
71 case 0x3FFA:
72 return controller.peekSectorReg(time);
73 case 0x3FFB:
74 return controller.peekDataReg(time);
75 case 0x3FFC:
76 // bit 0 = side select
77 // TODO check other bits !!
78 return sideReg; // return multiplexer.getSideSelect();
79 case 0x3FFD: {
80 // bit 1,0 -> drive number
81 // (00 or 10: drive A, 01: drive B, 11: nothing)
82 // bit 2 -> 0 iff disk changed
83 // TODO This is required on Sony_HB-F500P.
84 // Do other machines have this bit as well?
85 // bit 7 -> motor on
86 // TODO check other bits !!
87 byte res = driveReg & ~4;
89 res |= 4;
90 }
91 return res;
92 }
93 case 0x3FFE:
94 // not used
95 return 255;
96 case 0x3FFF: {
97 // Drive control IRQ and DRQ lines are not connected to Z80
98 // interrupt request
99 // bit 6: !intrq
100 // bit 7: !dtrq
101 // bit 5: !type1 (Philips VY-0010/JVC HC-FC303, pin 2 of FDD
102 // interface, indicates DS drive)
103 // bit 4: !type0 (Philips VY-0010/JVC HC-FC303, pin 1 of FDD
104 // interface)
105 // Other bits are not connected, according to service manuals
106 // of VY-0010 and Sony HBD-50.
107 byte value = 0xFF; // all bits are pulled up to 1
108 if (controller.peekIRQ(time)) value &= ~0x40;
109 if (controller.peekDTRQ(time)) value &= ~0x80;
110 return value;
111 }
112 default:
113 if ((0x4000 <= address) && (address < 0x8000)) {
114 // ROM only visible in 0x4000-0x7FFF
115 return MSXFDC::peekMem(address, time);
116 } else {
117 return 255;
118 }
119 }
120}
121
122const byte* PhilipsFDC::getReadCacheLine(word start) const
123{
124 // if address overlap 0x7ff8-0x7ffb then return nullptr,
125 // else normal ROM behaviour
126 if ((start & 0x3FF8 & CacheLine::HIGH) == (0x3FF8 & CacheLine::HIGH)) {
127 return nullptr;
128 } else if ((0x4000 <= start) && (start < 0x8000)) {
129 // ROM visible in 0x4000-0x7FFF
130 return MSXFDC::getReadCacheLine(start);
131 } else {
132 return unmappedRead.data();
133 }
134}
135
136void PhilipsFDC::writeMem(word address, byte value, EmuTime::param time)
137{
138 switch (address & 0x3FFF) {
139 case 0x3FF8:
140 controller.setCommandReg(value, time);
141 break;
142 case 0x3FF9:
143 controller.setTrackReg(value, time);
144 break;
145 case 0x3FFA:
146 controller.setSectorReg(value, time);
147 break;
148 case 0x3FFB:
149 controller.setDataReg(value, time);
150 break;
151 case 0x3FFC:
152 // bit 0 = side select
153 // TODO check other bits !!
154 sideReg = value;
155 multiplexer.setSide(value & 1);
156 break;
157 case 0x3FFD:
158 // bit 1,0 -> drive number
159 // (00 or 10: drive A, 01: drive B, 11: nothing)
160 // TODO bit 6 -> drive LED (0 -> off, 1 -> on)
161 // bit 7 -> motor on
162 // TODO check other bits !!
163 driveReg = value;
164 DriveMultiplexer::DriveNum drive = [&] {
165 switch (value & 3) {
166 case 0:
167 case 2:
169 case 1:
171 case 3:
172 default:
174 }
175 }();
176 multiplexer.selectDrive(drive, time);
177 multiplexer.setMotor((value & 128) != 0, time);
178 break;
179 }
180}
181
183{
184 if ((address & 0x3FF8) == (0x3FF8 & CacheLine::HIGH)) {
185 return nullptr;
186 } else {
187 return unmappedWrite.data();
188 }
189}
190
191
192template<typename Archive>
193void PhilipsFDC::serialize(Archive& ar, unsigned /*version*/)
194{
195 ar.template serializeBase<WD2793BasedFDC>(*this);
196 ar.serialize("sideReg", sideReg,
197 "driveReg", driveReg);
198}
201
202} // namespace openmsx
#define REGISTER_MSXDEVICE(CLASS, NAME)
Definition MSXDevice.hh:354
void setMotor(bool status, EmuTime::param time) override
Set motor on/off.
bool peekDiskChanged() const override
void selectDrive(DriveNum num, EmuTime::param time)
bool diskChanged() override
Is disk changed?
void setSide(bool side) override
Side select.
static std::array< byte, 0x10000 > unmappedRead
Definition MSXDevice.hh:304
static std::array< byte, 0x10000 > unmappedWrite
Definition MSXDevice.hh:305
EmuTime::param getCurrentTime() const
Definition MSXDevice.cc:125
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition MSXFDC.cc:55
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
void reset(EmuTime::param time) override
This method is called on reset.
Definition PhilipsFDC.cc:15
byte * getWriteCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
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.
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)
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition PhilipsFDC.cc:22
PhilipsFDC(const DeviceConfig &config)
Definition PhilipsFDC.cc:9
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition PhilipsFDC.cc:59
void reset(EmuTime::param time) override
This method is called on reset.
DriveMultiplexer multiplexer
uint8_t peekDataReg(EmuTime::param time) const
Definition WD2793.cc:314
bool peekIRQ(EmuTime::param time) const
Definition WD2793.cc:99
uint8_t getStatusReg(EmuTime::param time)
Definition WD2793.cc:159
void setTrackReg(uint8_t value, EmuTime::param time)
Definition WD2793.cc:205
void setSectorReg(uint8_t value, EmuTime::param time)
Definition WD2793.cc:220
uint8_t getTrackReg(EmuTime::param time) const
Definition WD2793.cc:210
uint8_t peekSectorReg(EmuTime::param time) const
Definition WD2793.cc:230
bool peekDTRQ(EmuTime::param time) const
Definition WD2793.cc:84
void setCommandReg(uint8_t value, EmuTime::param time)
Definition WD2793.cc:111
uint8_t peekTrackReg(EmuTime::param time) const
Definition WD2793.cc:215
bool getDTRQ(EmuTime::param time) const
Definition WD2793.cc:79
uint8_t peekStatusReg(EmuTime::param time) const
Definition WD2793.cc:199
uint8_t getDataReg(EmuTime::param time)
Definition WD2793.cc:249
void setDataReg(uint8_t value, EmuTime::param time)
Definition WD2793.cc:235
bool getIRQ(EmuTime::param time) const
Definition WD2793.cc:94
uint8_t getSectorReg(EmuTime::param time) const
Definition WD2793.cc:225
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)