openMSX
SanyoFDC.cc
Go to the documentation of this file.
1#include "SanyoFDC.hh"
2#include "CacheLine.hh"
3#include "DriveMultiplexer.hh"
4#include "WD2793.hh"
5#include "serialize.hh"
6
7// Note: although this implementation seems to work (e.g. for the Sanyo
8// MFD-001), it has not been checked on real hardware how the FDC registers are
9// mirrored across the slot, nor how the ROM is visible in the slot. Currently
10// FDC registers are implemented to be not mirrored, and ROM is implemented to
11// be visible in page 0 and 1.
12
13namespace openmsx {
14
16 : WD2793BasedFDC(config)
17{
18}
19
20byte SanyoFDC::readMem(word address, EmuTime::param time)
21{
22 switch (address) {
23 case 0x7FF8:
24 return controller.getStatusReg(time);
25 case 0x7FF9:
26 return controller.getTrackReg(time);
27 case 0x7FFA:
28 return controller.getSectorReg(time);
29 case 0x7FFB:
30 return controller.getDataReg(time);
31 case 0x7FFC:
32 case 0x7FFD:
33 case 0x7FFE:
34 case 0x7FFF: {
35 byte value = 0x3F;
36 if (controller.getIRQ(time)) value |= 0x80;
37 if (controller.getDTRQ(time)) value |= 0x40;
38 return value;
39 }
40 default:
41 return SanyoFDC::peekMem(address, time);
42 }
43}
44
45byte SanyoFDC::peekMem(word address, EmuTime::param time) const
46{
47 switch (address) {
48 case 0x7FF8:
49 return controller.peekStatusReg(time);
50 break;
51 case 0x7FF9:
52 return controller.peekTrackReg(time);
53 break;
54 case 0x7FFA:
55 return controller.peekSectorReg(time);
56 break;
57 case 0x7FFB:
58 return controller.peekDataReg(time);
59 break;
60 case 0x7FFC:
61 case 0x7FFD:
62 case 0x7FFE:
63 case 0x7FFF: {
64 // Drive control IRQ and DRQ lines are not connected to Z80 interrupt request
65 // bit 7: intrq
66 // bit 6: dtrq
67 // other bits read 1
68 byte value = 0x3F;
69 if (controller.peekIRQ(time)) value |= 0x80;
70 if (controller.peekDTRQ(time)) value |= 0x40;
71 return value;
72 }
73 default:
74 if (address < 0x8000) {
75 // ROM only visible in 0x0000-0x7FFF (not verified!)
76 return MSXFDC::peekMem(address, time);
77 } else {
78 return 255;
79 }
80 break;
81 }
82}
83
84const byte* SanyoFDC::getReadCacheLine(word start) const
85{
86 if ((start & CacheLine::HIGH) == (0x7FF8 & CacheLine::HIGH)) {
87 // FDC at 0x7FF8-0x7FFC - mirroring behaviour unknown
88 return nullptr;
89 } else if (start < 0x8000) {
90 // ROM at 0x0000-0x7FFF (this is a guess, not checked!)
91 return MSXFDC::getReadCacheLine(start);
92 } else {
93 return unmappedRead;
94 }
95}
96
97void SanyoFDC::writeMem(word address, byte value, EmuTime::param time)
98{
99 switch (address) {
100 case 0x7FF8:
101 controller.setCommandReg(value, time);
102 break;
103 case 0x7FF9:
104 controller.setTrackReg(value, time);
105 break;
106 case 0x7FFA:
107 controller.setSectorReg(value, time);
108 break;
109 case 0x7FFB:
110 controller.setDataReg(value, time);
111 break;
112 case 0x7FFC:
113 case 0x7FFD:
114 case 0x7FFE:
115 case 0x7FFF:
116 // bit 0 -> select drive 0
117 // bit 1 -> select drive 1
118 // bit 2 -> side select
119 // bit 3 -> motor on
120 auto drive = [&] {
121 switch (value & 3) {
122 case 1: return DriveMultiplexer::DRIVE_A;
123 case 2: return DriveMultiplexer::DRIVE_B;
124 default: return DriveMultiplexer::NO_DRIVE;
125 }
126 }();
127 multiplexer.selectDrive(drive, time);
128 multiplexer.setSide((value & 0x04) != 0);
129 multiplexer.setMotor((value & 0x08) != 0, time);
130 break;
131 }
132}
133
135{
136 if ((address & CacheLine::HIGH) == (0x7FF8 & CacheLine::HIGH)) {
137 // FDC at 0x7FF8-0x7FFC - mirroring behaviour unknown
138 return nullptr;
139 } else {
140 return unmappedWrite;
141 }
142}
143
144
145template<typename Archive>
146void SanyoFDC::serialize(Archive& ar, unsigned /*version*/)
147{
148 ar.template serializeBase<WD2793BasedFDC>(*this);
149}
152
153} // 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
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: SanyoFDC.cc:20
const byte * getReadCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition: SanyoFDC.cc:84
byte * getWriteCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
Definition: SanyoFDC.cc:134
SanyoFDC(const DeviceConfig &config)
Definition: SanyoFDC.cc:15
void serialize(Archive &ar, unsigned version)
Definition: SanyoFDC.cc:146
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: SanyoFDC.cc:97
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: SanyoFDC.cc:45
DriveMultiplexer multiplexer
bool peekIRQ(EmuTime::param time) const
Definition: WD2793.cc:108
byte peekStatusReg(EmuTime::param time) const
Definition: WD2793.cc:208
byte getTrackReg(EmuTime::param time) const
Definition: WD2793.cc:219
byte getDataReg(EmuTime::param time)
Definition: WD2793.cc:258
byte getSectorReg(EmuTime::param time) const
Definition: WD2793.cc:234
bool peekDTRQ(EmuTime::param time) const
Definition: WD2793.cc:93
bool getDTRQ(EmuTime::param time) const
Definition: WD2793.cc:88
byte getStatusReg(EmuTime::param time)
Definition: WD2793.cc:168
byte peekTrackReg(EmuTime::param time) const
Definition: WD2793.cc:224
void setTrackReg(byte value, EmuTime::param time)
Definition: WD2793.cc:214
void setDataReg(byte value, EmuTime::param time)
Definition: WD2793.cc:244
byte peekDataReg(EmuTime::param time) const
Definition: WD2793.cc:323
void setCommandReg(byte value, EmuTime::param time)
Definition: WD2793.cc:120
bool getIRQ(EmuTime::param time) const
Definition: WD2793.cc:103
void setSectorReg(byte value, EmuTime::param time)
Definition: WD2793.cc:229
byte peekSectorReg(EmuTime::param time) const
Definition: WD2793.cc:239
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:1009