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