openMSX
SVIFDC.cc
Go to the documentation of this file.
1 #include "SVIFDC.hh"
2 #include "serialize.hh"
3 
4 // Floppy disk controller FD1793
5 //
6 // 30H Command to FDC
7 // 30H Status from FDC
8 // 31H Track register
9 // 32H Sector register
10 // 33H Data register
11 //
12 // 34H Address of INTRQ and DRQ
13 // 10000000B Interrupt request bit
14 // 01000000B Data request bit
15 //
16 // 34H Address of disk select and motor control
17 // 00000001B Select disk 0 bit
18 // 00000010B Select disk 1 bit
19 // 00000100B Disk 0 motor on bit
20 // 00001000B Disk 1 motor on bit
21 //
22 // 38H Address of density select flag
23 // 00000000B Density MFM bit
24 // 00000001B Density FM bit
25 // 00000010B Select second side
26 
27 namespace openmsx {
28 
30  : WD2793BasedFDC(config, "", false) // doesn't require a <rom>
31 {
32 }
33 
34 byte SVIFDC::readIO(word port, EmuTime::param time)
35 {
36  switch (port & 0x07) {
37  case 0:
38  return controller.getStatusReg(time);
39  case 1:
40  return controller.getTrackReg(time);
41  case 2:
42  return controller.getSectorReg(time);
43  case 3:
44  return controller.getDataReg(time);
45  case 4:
46  return (controller.getIRQ (time) ? 0x80 : 0x00) |
47  (controller.getDTRQ(time) ? 0x40 : 0x00);
48  }
49  return 255;
50 }
51 
52 byte SVIFDC::peekIO(word port, EmuTime::param time) const
53 {
54  switch (port & 0x07) {
55  case 0:
56  return controller.peekStatusReg(time);
57  case 1:
58  return controller.peekTrackReg(time);
59  case 2:
60  return controller.peekSectorReg(time);
61  case 3:
62  return controller.peekDataReg(time);
63  case 4:
64  return (controller.peekIRQ (time) ? 0x80 : 0x00) |
65  (controller.peekDTRQ(time) ? 0x40 : 0x00);
66  }
67  return 255;
68 }
69 
70 void SVIFDC::writeIO(word port, byte value, EmuTime::param time)
71 {
72  switch (port & 0x0F) {
73  case 0:
74  controller.setCommandReg(value, time);
75  break;
76  case 1:
77  controller.setTrackReg(value, time);
78  break;
79  case 2:
80  controller.setSectorReg(value, time);
81  break;
82  case 3:
83  controller.setDataReg(value, time);
84  break;
85  case 4: {
86  // bit 0: drive select A
87  // bit 1: drive select B
88  // bit 2: motor on drive A
89  // bit 3: motor on drive B
90  auto [drive, motor] = [&]() -> std::pair<DriveMultiplexer::DriveNum, bool> {
91  switch (value & 0x03) {
92  case 1:
93  return {DriveMultiplexer::DRIVE_A, value & 0x04};
94  case 2:
95  return {DriveMultiplexer::DRIVE_B, value & 0x08};
96  default:
97  // No drive selected or two drives at same time
98  // In a real machine you must take care to do not select more
99  // than one drive at the same time (you could get data
100  // collision).
101  return {DriveMultiplexer::NO_DRIVE, false};
102  }
103  }();
104  multiplexer.selectDrive(drive, time);
105  multiplexer.setMotor(motor, time);
106  break;
107  }
108  case 8:
109  // bit 0: density flag (1=single, 0=double)
110  // bit 1: side select
111  // TODO density flag not yet supported
112  multiplexer.setSide((value & 0x02) != 0);
113  break;
114  }
115 }
116 
117 template<typename Archive>
118 void SVIFDC::serialize(Archive& ar, unsigned /*version*/)
119 {
120  ar.template serializeBase<WD2793BasedFDC>(*this);
121 }
123 REGISTER_MSXDEVICE(SVIFDC, "SVI-328 FDC");
124 
125 } // namespace openmsx
openmsx::WD2793BasedFDC::multiplexer
DriveMultiplexer multiplexer
Definition: WD2793BasedFDC.hh:25
openmsx::SVIFDC::writeIO
void writeIO(word port, byte value, EmuTime::param time) override
Write a byte to a given IO port at a certain time to this device.
Definition: SVIFDC.cc:70
serialize.hh
openmsx::WD2793BasedFDC::controller
WD2793 controller
Definition: WD2793BasedFDC.hh:26
openmsx::DeviceConfig
Definition: DeviceConfig.hh:20
openmsx::WD2793::getDataReg
byte getDataReg(EmuTime::param time)
Definition: WD2793.cc:260
openmsx::WD2793::peekStatusReg
byte peekStatusReg(EmuTime::param time) const
Definition: WD2793.cc:210
openmsx::WD2793::peekIRQ
bool peekIRQ(EmuTime::param time) const
Definition: WD2793.cc:110
openmsx::SVIFDC::SVIFDC
SVIFDC(const DeviceConfig &config)
Definition: SVIFDC.cc:29
openmsx::WD2793::getStatusReg
byte getStatusReg(EmuTime::param time)
Definition: WD2793.cc:170
openmsx::WD2793BasedFDC
Definition: WD2793BasedFDC.hh:12
openmsx::DriveMultiplexer::setMotor
void setMotor(bool status, EmuTime::param time) override
Set motor on/off.
Definition: DriveMultiplexer.cc:69
openmsx::DriveMultiplexer::NO_DRIVE
@ NO_DRIVE
Definition: DriveMultiplexer.hh:20
openmsx::REGISTER_MSXDEVICE
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
openmsx::DriveMultiplexer::setSide
void setSide(bool side) override
Side select.
Definition: DriveMultiplexer.cc:48
openmsx::DriveMultiplexer::DRIVE_B
@ DRIVE_B
Definition: DriveMultiplexer.hh:17
openmsx::WD2793::getDTRQ
bool getDTRQ(EmuTime::param time) const
Definition: WD2793.cc:90
openmsx::SVIFDC::serialize
void serialize(Archive &ar, unsigned version)
Definition: SVIFDC.cc:118
openmsx::SVIFDC::readIO
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
Definition: SVIFDC.cc:34
openmsx::WD2793::getIRQ
bool getIRQ(EmuTime::param time) const
Definition: WD2793.cc:105
INSTANTIATE_SERIALIZE_METHODS
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:982
openmsx::WD2793::getSectorReg
byte getSectorReg(EmuTime::param time) const
Definition: WD2793.cc:236
openmsx::DriveMultiplexer::DRIVE_A
@ DRIVE_A
Definition: DriveMultiplexer.hh:16
openmsx::WD2793::setDataReg
void setDataReg(byte value, EmuTime::param time)
Definition: WD2793.cc:246
openmsx::WD2793::getTrackReg
byte getTrackReg(EmuTime::param time) const
Definition: WD2793.cc:221
openmsx::word
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
openmsx::WD2793::peekSectorReg
byte peekSectorReg(EmuTime::param time) const
Definition: WD2793.cc:241
openmsx::SVIFDC
Definition: SVIFDC.hh:9
openmsx::DriveMultiplexer::selectDrive
void selectDrive(DriveNum num, EmuTime::param time)
Definition: DriveMultiplexer.cc:18
openmsx::WD2793::setCommandReg
void setCommandReg(byte value, EmuTime::param time)
Definition: WD2793.cc:122
openmsx::WD2793::peekDataReg
byte peekDataReg(EmuTime::param time) const
Definition: WD2793.cc:325
openmsx::SVIFDC::peekIO
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
Definition: SVIFDC.cc:52
openmsx::WD2793::peekDTRQ
bool peekDTRQ(EmuTime::param time) const
Definition: WD2793.cc:95
openmsx::WD2793::peekTrackReg
byte peekTrackReg(EmuTime::param time) const
Definition: WD2793.cc:226
openmsx::WD2793::setSectorReg
void setSectorReg(byte value, EmuTime::param time)
Definition: WD2793.cc:231
openmsx::WD2793::setTrackReg
void setTrackReg(byte value, EmuTime::param time)
Definition: WD2793.cc:216
openmsx
This file implemented 3 utility functions:
Definition: Autofire.cc:5
SVIFDC.hh