openMSX
MicrosolFDC.cc
Go to the documentation of this file.
1#include "MicrosolFDC.hh"
2#include "DriveMultiplexer.hh"
3#include "WD2793.hh"
4#include "serialize.hh"
5
6namespace openmsx {
7
9 : WD2793BasedFDC(config)
10{
11}
12
13byte MicrosolFDC::readIO(word port, EmuTime::param time)
14{
15 switch (port & 0x07) {
16 case 0:
17 return controller.getStatusReg(time);
18 case 1:
19 return controller.getTrackReg(time);
20 case 2:
21 return controller.getSectorReg(time);
22 case 3:
23 return controller.getDataReg(time);
24 case 4: {
25 byte value = 0x7F;
26 if (controller.getIRQ(time)) value |= 0x80;
27 if (controller.getDTRQ(time)) value &= ~0x40;
28 return value;
29 }
30 default:
31 return 255;
32 }
33}
34
35byte MicrosolFDC::peekIO(word port, EmuTime::param time) const
36{
37 switch (port & 0x07) {
38 case 0:
39 return controller.peekStatusReg(time);
40 case 1:
41 return controller.peekTrackReg(time);
42 case 2:
43 return controller.peekSectorReg(time);
44 case 3:
45 return controller.peekDataReg(time);
46 case 4: {
47 byte value = 0x7F;
48 if (controller.peekIRQ(time)) value |= 0x80;
49 if (controller.peekDTRQ(time)) value &= ~0x40;
50 return value;
51 }
52 default:
53 return 255;
54 }
55}
56
57void MicrosolFDC::writeIO(word port, byte value, EmuTime::param time)
58{
59 switch (port & 0x07) {
60 case 0:
61 controller.setCommandReg(value, time);
62 break;
63 case 1:
64 controller.setTrackReg(value, time);
65 break;
66 case 2:
67 controller.setSectorReg(value, time);
68 break;
69 case 3:
70 controller.setDataReg(value, time);
71 break;
72 case 4:
73 // From Ricardo Bittencourt
74 // bit 0: drive select A
75 // bit 1: drive select B
76 // bit 2: drive select C
77 // bit 3: drive select D
78 // bit 4: side select
79 // bit 5: turn on motor
80 // bit 6: enable wait states
81 // bit 7: density: 0=single 1=double
82 //
83 // When you enable a drive select bit, the led on the
84 // disk-drive turns on. Since this was used as user feedback,
85 // in things such as "replace disk 1 when the led turns off"
86 // we need to connect this to the OSD later on.
87
88 // Set correct drive
89 DriveMultiplexer::DriveNum drive = [&] {
90 switch (value & 0x0F) {
91 case 1:
93 case 2:
95 case 4:
97 case 8:
99 default:
100 // No drive selected or two drives at same time
101 // The motor is enabled for all drives at the same time, so
102 // in a real machine you must take care to do not select more
103 // than one drive at the same time (you could get data
104 // collision).
106 }
107 }();
108 multiplexer.selectDrive(drive, time);
109 multiplexer.setSide((value & 0x10) != 0);
110 multiplexer.setMotor((value & 0x20) != 0, time);
111 break;
112 }
113}
114
115
116template<typename Archive>
117void MicrosolFDC::serialize(Archive& ar, unsigned /*version*/)
118{
119 ar.template serializeBase<WD2793BasedFDC>(*this);
120}
123
124} // namespace openmsx
#define REGISTER_MSXDEVICE(CLASS, NAME)
Definition MSXDevice.hh:354
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.
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.
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
void serialize(Archive &ar, unsigned version)
MicrosolFDC(const DeviceConfig &config)
Definition MicrosolFDC.cc:8
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
DriveMultiplexer multiplexer
uint8_t peekDataReg(EmuTime::param time) const
Definition WD2793.cc:314
bool peekIRQ(EmuTime::param time) const
Definition WD2793.cc:99
uint8_t getStatusReg(EmuTime::param time)
Definition WD2793.cc:159
void setTrackReg(uint8_t value, EmuTime::param time)
Definition WD2793.cc:205
void setSectorReg(uint8_t value, EmuTime::param time)
Definition WD2793.cc:220
uint8_t getTrackReg(EmuTime::param time) const
Definition WD2793.cc:210
uint8_t peekSectorReg(EmuTime::param time) const
Definition WD2793.cc:230
bool peekDTRQ(EmuTime::param time) const
Definition WD2793.cc:84
void setCommandReg(uint8_t value, EmuTime::param time)
Definition WD2793.cc:111
uint8_t peekTrackReg(EmuTime::param time) const
Definition WD2793.cc:215
bool getDTRQ(EmuTime::param time) const
Definition WD2793.cc:79
uint8_t peekStatusReg(EmuTime::param time) const
Definition WD2793.cc:199
uint8_t getDataReg(EmuTime::param time)
Definition WD2793.cc:249
void setDataReg(uint8_t value, EmuTime::param time)
Definition WD2793.cc:235
bool getIRQ(EmuTime::param time) const
Definition WD2793.cc:94
uint8_t getSectorReg(EmuTime::param time) const
Definition WD2793.cc:225
This file implemented 3 utility functions:
Definition Autofire.cc:9
uint16_t word
16 bit unsigned integer
Definition openmsx.hh:29
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)