OXYGENHUB
◆ main openmsx / src / fdc / SanyoFDC.cc
3.4 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#include "SanyoFDC.hh"
2
3
#include "DriveMultiplexer.hh"
4
#include "WD2793.hh"
5
6
#include "CacheLine.hh"
7
#include "serialize.hh"
8
9
// Note: although this implementation seems to work (e.g. for the Sanyo
10
// MFD-001), it has not been checked on real hardware how the FDC registers are
11
// mirrored across the slot, nor how the ROM is visible in the slot. Currently
12
// FDC registers are implemented to be not mirrored, and ROM is implemented to
13
// be visible in page 0 and 1.
14
15
namespace openmsx {
16
17
SanyoFDC::SanyoFDC(DeviceConfig& config)
18
	: WD2793BasedFDC(config)
19
{
20
	// ROM only visible in 0x0000-0x7FFF by default (not verified!)
21
	parseRomVisibility(config, 0x0000, 0x8000);
22
}
23
24
byte SanyoFDC::readMem(uint16_t address, EmuTime time)
25
{
26
	switch (address) {
27
	case 0x7FF8:
28
		return controller.getStatusReg(time);
29
	case 0x7FF9:
30
		return controller.getTrackReg(time);
31
	case 0x7FFA:
32
		return controller.getSectorReg(time);
33
	case 0x7FFB:
34
		return controller.getDataReg(time);
35
	case 0x7FFC:
36
	case 0x7FFD:
37
	case 0x7FFE:
38
	case 0x7FFF: {
39
		byte value = 0x3F;
40
		if (controller.getIRQ(time))  value |= 0x80;
41
		if (controller.getDTRQ(time)) value |= 0x40;
42
		return value;
43
	}
44
	default:
45
		return SanyoFDC::peekMem(address, time);
46
	}
47
}
48
49
byte SanyoFDC::peekMem(uint16_t address, EmuTime time) const
50
{
51
	switch (address) {
52
	case 0x7FF8:
53
		return controller.peekStatusReg(time);
54
	case 0x7FF9:
55
		return controller.peekTrackReg(time);
56
	case 0x7FFA:
57
		return controller.peekSectorReg(time);
58
	case 0x7FFB:
59
		return controller.peekDataReg(time);
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
		return MSXFDC::peekMem(address, time);
75
	}
76
}
77
78
const byte* SanyoFDC::getReadCacheLine(uint16_t start) const
79
{
80
	if ((start & CacheLine::HIGH) == (0x7FF8 & CacheLine::HIGH)) {
81
		// FDC at 0x7FF8-0x7FFC - mirroring behaviour unknown
82
		return nullptr;
83
	} else {
84
		return MSXFDC::getReadCacheLine(start);
85
	}
86
}
87
88
void SanyoFDC::writeMem(uint16_t address, byte value, EmuTime time)
89
{
90
	switch (address) {
91
	case 0x7FF8:
92
		controller.setCommandReg(value, time);
93
		break;
94
	case 0x7FF9:
95
		controller.setTrackReg(value, time);
96
		break;
97
	case 0x7FFA:
98
		controller.setSectorReg(value, time);
99
		break;
100
	case 0x7FFB:
101
		controller.setDataReg(value, time);
102
		break;
103
	case 0x7FFC:
104
	case 0x7FFD:
105
	case 0x7FFE:
106
	case 0x7FFF:
107
		// bit 0 -> select drive 0
108
		// bit 1 -> select drive 1
109
		// bit 2 -> side select
110
		// bit 3 -> motor on
111
		auto drive = [&] {
112
			switch (value & 3) {
113
				case 1:  return DriveMultiplexer::Drive::A;
114
				case 2:  return DriveMultiplexer::Drive::B;
115
				default: return DriveMultiplexer::Drive::NONE;
116
			}
117
		}();
118
		multiplexer.selectDrive(drive, time);
119
		multiplexer.setSide((value & 0x04) != 0);
120
		multiplexer.setMotor((value & 0x08) != 0, time);
121
		break;
122
	}
123
}
124
125
byte* SanyoFDC::getWriteCacheLine(uint16_t address)
126
{
127
	if ((address & CacheLine::HIGH) == (0x7FF8 & CacheLine::HIGH)) {
128
		// FDC at 0x7FF8-0x7FFC - mirroring behaviour unknown
129
		return nullptr;
130
	} else {
131
		return unmappedWrite.data();
132
	}
133
}
134
135
136
template<typename Archive>
137
void SanyoFDC::serialize(Archive& ar, unsigned /*version*/)
138
{
139
	ar.template serializeBase<WD2793BasedFDC>(*this);
140
}
141
INSTANTIATE_SERIALIZE_METHODS(SanyoFDC);
142
REGISTER_MSXDEVICE(SanyoFDC, "SanyoFDC");
143
144
} // namespace openmsx