openMSX
NationalFDC.cc
Go to the documentation of this file.
1 #include "NationalFDC.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 {
12 }
13 
14 byte NationalFDC::readMem(word address, EmuTime::param time)
15 {
16  byte value;
17  switch (address & 0x3FC7) {
18  case 0x3F80:
19  value = controller.getStatusReg(time);
20  break;
21  case 0x3F81:
22  value = controller.getTrackReg(time);
23  break;
24  case 0x3F82:
25  value = controller.getSectorReg(time);
26  break;
27  case 0x3F83:
28  value = controller.getDataReg(time);
29  break;
30  case 0x3F84:
31  case 0x3F85:
32  case 0x3F86:
33  case 0x3F87:
34  value = 0x7F;
35  if (controller.getIRQ(time)) value |= 0x80;
36  if (controller.getDTRQ(time)) value &= ~0x40;
37  break;
38  default:
39  value = NationalFDC::peekMem(address, time);
40  break;
41  }
42  return value;
43 }
44 
45 byte NationalFDC::peekMem(word address, EmuTime::param time) const
46 {
47  byte value;
48  // According to atarulum:
49  // 7FBC is mirrored in 7FBC - 7FBF
50  // 7FB8 - 7FBF is mirrored in 7F80 - 7FBF
51  switch (address & 0x3FC7) {
52  case 0x3F80:
53  value = controller.peekStatusReg(time);
54  break;
55  case 0x3F81:
56  value = controller.peekTrackReg(time);
57  break;
58  case 0x3F82:
59  value = controller.peekSectorReg(time);
60  break;
61  case 0x3F83:
62  value = controller.peekDataReg(time);
63  break;
64  case 0x3F84:
65  case 0x3F85:
66  case 0x3F86:
67  case 0x3F87:
68  // Drive control IRQ and DRQ lines are not connected to Z80 interrupt request
69  // bit 7: intrq
70  // bit 6: !dtrq
71  // other bits read 1
72  value = 0x7F;
73  if (controller.peekIRQ(time)) value |= 0x80;
74  if (controller.peekDTRQ(time)) value &= ~0x40;
75  break;
76  default:
77  if (address < 0x8000) {
78  // ROM only visible in 0x0000-0x7FFF
79  value = MSXFDC::peekMem(address, time);
80  } else {
81  value = 255;
82  }
83  break;
84  }
85  return value;
86 }
87 
88 const byte* NationalFDC::getReadCacheLine(word start) const
89 {
90  if ((start & 0x3FC0 & CacheLine::HIGH) == (0x3F80 & CacheLine::HIGH)) {
91  // FDC at 0x7FB8-0x7FBC (also mirrored)
92  return nullptr;
93  } else if (start < 0x8000) {
94  // ROM at 0x0000-0x7FFF
95  return MSXFDC::getReadCacheLine(start);
96  } else {
97  return unmappedRead;
98  }
99 }
100 
101 void NationalFDC::writeMem(word address, byte value, EmuTime::param time)
102 {
103  switch (address & 0x3FC7) {
104  case 0x3F80:
105  controller.setCommandReg(value, time);
106  break;
107  case 0x3F81:
108  controller.setTrackReg(value, time);
109  break;
110  case 0x3F82:
111  controller.setSectorReg(value, time);
112  break;
113  case 0x3F83:
114  controller.setDataReg(value, time);
115  break;
116  case 0x3F84:
117  case 0x3F85:
118  case 0x3F86:
119  case 0x3F87:
120  // bit 0 -> select drive 0
121  // bit 1 -> select drive 1
122  // bit 2 -> side select
123  // bit 3 -> motor on
125  switch (value & 3) {
126  case 1:
128  break;
129  case 2:
131  break;
132  default:
134  }
135  multiplexer.selectDrive(drive, time);
136  multiplexer.setSide((value & 0x04) != 0);
137  multiplexer.setMotor((value & 0x08) != 0, time);
138  break;
139  }
140 }
141 
143 {
144  if ((address & 0x3FC0) == (0x3F80 & CacheLine::HIGH)) {
145  // FDC at 0x7FB8-0x7FBC (also mirrored)
146  return nullptr;
147  } else {
148  return unmappedWrite;
149  }
150 }
151 
152 
153 template<typename Archive>
154 void NationalFDC::serialize(Archive& ar, unsigned /*version*/)
155 {
156  ar.template serializeBase<WD2793BasedFDC>(*this);
157 }
159 REGISTER_MSXDEVICE(NationalFDC, "NationalFDC");
160 
161 } // namespace openmsx
openmsx::NationalFDC::peekMem
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: NationalFDC.cc:45
openmsx::MSXFDC::peekMem
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: MSXFDC.cc:56
openmsx::WD2793BasedFDC::multiplexer
DriveMultiplexer multiplexer
Definition: WD2793BasedFDC.hh:25
serialize.hh
openmsx::NationalFDC
Definition: NationalFDC.hh:8
openmsx::WD2793BasedFDC::controller
WD2793 controller
Definition: WD2793BasedFDC.hh:26
openmsx::DeviceConfig
Definition: DeviceConfig.hh:19
openmsx::MSXDevice::unmappedWrite
static byte unmappedWrite[0x10000]
Definition: MSXDevice.hh:301
openmsx::NationalFDC::serialize
void serialize(Archive &ar, unsigned version)
Definition: NationalFDC.cc:154
openmsx::WD2793::getIRQ
bool getIRQ(EmuTime::param time)
Definition: WD2793.cc:105
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::NationalFDC::NationalFDC
NationalFDC(const DeviceConfig &config)
Definition: NationalFDC.cc:9
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:69
openmsx::DriveMultiplexer::NO_DRIVE
@ 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:48
openmsx::DriveMultiplexer::DRIVE_B
@ 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
@ DRIVE_A
Definition: DriveMultiplexer.hh:16
openmsx::WD2793::setDataReg
void setDataReg(byte value, EmuTime::param time)
Definition: WD2793.cc:246
CacheLine.hh
openmsx::NationalFDC::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: NationalFDC.cc:101
DriveMultiplexer.hh
WD2793.hh
openmsx::NationalFDC::readMem
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: NationalFDC.cc:14
NationalFDC.hh
openmsx::MSXDevice::unmappedRead
static byte unmappedRead[0x10000]
Definition: MSXDevice.hh:300
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::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:325
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:61
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::NationalFDC::getReadCacheLine
const byte * getReadCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition: NationalFDC.cc:88
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
openmsx::NationalFDC::getWriteCacheLine
byte * getWriteCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
Definition: NationalFDC.cc:142