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
7namespace openmsx {
8
10 : WD2793BasedFDC(config)
11{
12}
13
14byte 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
39byte 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
76const 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.data();
86 }
87}
88
89void 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::Drive::NONE;
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.data();
133 }
134}
135
136
137template<typename Archive>
138void NationalFDC::serialize(Archive& ar, unsigned /*version*/)
139{
140 ar.template serializeBase<WD2793BasedFDC>(*this);
141}
144
145} // namespace openmsx
#define REGISTER_MSXDEVICE(CLASS, NAME)
Definition MSXDevice.hh:356
void setMotor(bool status, EmuTime::param time) override
Set motor on/off.
void selectDrive(Drive num, EmuTime::param time)
void setSide(bool side) override
Side select.
static std::array< byte, 0x10000 > unmappedRead
Definition MSXDevice.hh:306
static std::array< byte, 0x10000 > unmappedWrite
Definition MSXDevice.hh:307
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 serialize(Archive &ar, unsigned version)
const byte * getReadCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
byte * getWriteCacheLine(word address) override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
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.
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.
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)