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
91  bool motor;
92  switch (value & 0x03) {
93  case 1:
95  motor = value & 0x04;
96  break;
97  case 2:
99  motor = value & 0x08;
100  break;
101  default:
102  // No drive selected or two drives at same time
103  // In a real machine you must take care to do not select more
104  // than one drive at the same time (you could get data
105  // collision).
107  motor = false;
108  }
109  multiplexer.selectDrive(drive, time);
110  multiplexer.setMotor(motor, time);
111  break;
112  case 8:
113  // bit 0: density flag (1=single, 0=double)
114  // bit 1: side select
115  // TODO density flag not yet supported
116  multiplexer.setSide((value & 0x02) != 0);
117  break;
118  }
119 }
120 
121 template<typename Archive>
122 void SVIFDC::serialize(Archive& ar, unsigned /*version*/)
123 {
124  ar.template serializeBase<WD2793BasedFDC>(*this);
125 }
127 REGISTER_MSXDEVICE(SVIFDC, "SVI-328 FDC");
128 
129 } // namespace openmsx
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
byte peekDataReg(EmuTime::param time) const
Definition: WD2793.cc:320
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
void setCommandReg(byte value, EmuTime::param time)
Definition: WD2793.cc:122
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
byte getStatusReg(EmuTime::param time)
Definition: WD2793.cc:166
byte peekSectorReg(EmuTime::param time) const
Definition: WD2793.cc:237
byte getSectorReg(EmuTime::param time)
Definition: WD2793.cc:232
bool getDTRQ(EmuTime::param time)
Definition: WD2793.cc:90
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
Definition: SVIFDC.cc:52
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
DriveMultiplexer multiplexer
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
void setMotor(bool status, EmuTime::param time) override
Set motor on/off.
void setSectorReg(byte value, EmuTime::param time)
Definition: WD2793.cc:227
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
SVIFDC(const DeviceConfig &config)
Definition: SVIFDC.cc:29
byte getDataReg(EmuTime::param time)
Definition: WD2793.cc:256
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:840
byte peekStatusReg(EmuTime::param time) const
Definition: WD2793.cc:206
void setSide(bool side) override
Side select.
bool peekIRQ(EmuTime::param time) const
Definition: WD2793.cc:110
byte peekTrackReg(EmuTime::param time) const
Definition: WD2793.cc:222
void setTrackReg(byte value, EmuTime::param time)
Definition: WD2793.cc:212
bool getIRQ(EmuTime::param time)
Definition: WD2793.cc:105
void serialize(Archive &ar, unsigned version)
Definition: SVIFDC.cc:122
void selectDrive(DriveNum num, EmuTime::param time)
byte getTrackReg(EmuTime::param time)
Definition: WD2793.cc:217
bool peekDTRQ(EmuTime::param time) const
Definition: WD2793.cc:95
void setDataReg(byte value, EmuTime::param time)
Definition: WD2793.cc:242