OXYGENHUB
◆ main openmsx / src / fdc / AVTFDC.cc
2.6 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#include "AVTFDC.hh"
2
3
#include "DriveMultiplexer.hh"
4
#include "WD2793.hh"
5
6
#include "serialize.hh"
7
8
namespace openmsx {
9
10
AVTFDC::AVTFDC(DeviceConfig& config)
11
	: WD2793BasedFDC(config)
12
{
13
}
14
15
byte AVTFDC::readIO(uint16_t port, EmuTime time)
16
{
17
	switch (port & 0x07) {
18
	case 0:
19
		return controller.getStatusReg(time);
20
	case 1:
21
		return controller.getTrackReg(time);
22
	case 2:
23
		return controller.getSectorReg(time);
24
	case 3:
25
		return controller.getDataReg(time);
26
	case 4: {
27
		byte value = 0x7F;
28
		if (controller.getIRQ(time))  value |=  0x80;
29
		if (controller.getDTRQ(time)) value &= ~0x40;
30
		return value;
31
	}
32
	default:
33
		return 255;
34
	}
35
}
36
37
byte AVTFDC::peekIO(uint16_t port, EmuTime time) const
38
{
39
	switch (port & 0x07) {
40
	case 0:
41
		return controller.peekStatusReg(time);
42
	case 1:
43
		return controller.peekTrackReg(time);
44
	case 2:
45
		return controller.peekSectorReg(time);
46
	case 3:
47
		return controller.peekDataReg(time);
48
	case 4: {
49
		byte value = 0x7F;
50
		if (controller.peekIRQ(time))  value |=  0x80;
51
		if (controller.peekDTRQ(time)) value &= ~0x40;
52
		return value;
53
	}
54
	default:
55
		return 255;
56
	}
57
}
58
59
void AVTFDC::writeIO(uint16_t port, byte value, EmuTime time)
60
{
61
	switch (port & 0x07) {
62
	case 0:
63
		controller.setCommandReg(value, time);
64
		break;
65
	case 1:
66
		controller.setTrackReg(value, time);
67
		break;
68
	case 2:
69
		controller.setSectorReg(value, time);
70
		break;
71
	case 3:
72
		controller.setDataReg(value, time);
73
		break;
74
	case 4: /* nothing only read... */
75
		break;
76
	case 5:
77
		// From mohai
78
		// bit 0:  drive select A (and motor on, as this is a WD1770,
79
		// we use this as workaround)
80
		// bit 1:  drive select B (and motor on, as this is a WD1770,
81
		// we use this as workaround)
82
		// bit 2:  side select
83
		// bit 3:  density: 1=single 0=double (not supported by openMSX)
84
		//
85
		// Set correct drive
86
		auto drive = [&] {
87
			switch (value & 0x03) {
88
			case 1:
89
				return DriveMultiplexer::Drive::A;
90
			case 2:
91
				return DriveMultiplexer::Drive::B;
92
			default:
93
				// No drive selected or two drives at same time
94
				// The motor is enabled for all drives at the same time, so
95
				// in a real machine you must take care to do not select more
96
				// than one drive at the same time (you could get data
97
				// collision).
98
				return DriveMultiplexer::Drive::NONE;
99
			}
100
		}();
101
		multiplexer.selectDrive(drive, time);
102
		multiplexer.setSide((value & 0x04) != 0);
103
		multiplexer.setMotor(drive != DriveMultiplexer::Drive::NONE, time);
104
		break;
105
	}
106
}
107
108
109
template<typename Archive>
110
void AVTFDC::serialize(Archive& ar, unsigned /*version*/)
111
{
112
	ar.template serializeBase<WD2793BasedFDC>(*this);
113
}
114
INSTANTIATE_SERIALIZE_METHODS(AVTFDC);
115
REGISTER_MSXDEVICE(AVTFDC, "AVTFDC");
116
117
} // namespace openmsx