openMSX
NowindHost.hh
Go to the documentation of this file.
1#ifndef NOWINDHOST_HH
2#define NOWINDHOST_HH
3
4#include "DiskImageUtils.hh"
5#include "circular_buffer.hh"
6#include "openmsx.hh"
7#include <array>
8#include <fstream>
9#include <memory>
10#include <optional>
11#include <span>
12#include <string>
13#include <vector>
14
15namespace openmsx {
16
17class SectorAccessibleDisk;
18class DiskContainer;
19
21{
22public:
23 using Drives = std::vector<std::unique_ptr<DiskContainer>>;
24
25 explicit NowindHost(const Drives& drives);
27
28 // public for usb-host implementation
29 [[nodiscard]] bool isDataAvailable() const;
30
31 // read one byte of response-data from the host (msx <- pc)
32 byte read();
33
34 // like read(), but without side effects (doesn't consume the data)
35 [[nodiscard]] byte peek() const;
36
37 // Write one byte of command-data to the host (msx -> pc)
38 // Time parameter is in milliseconds. Emulators can pass emulation
39 // time, USB-host can pass real time.
40 void write(byte data, unsigned time);
41
42 void setAllowOtherDiskRoms(bool allow) { allowOtherDiskRoms = allow; }
43 [[nodiscard]] bool getAllowOtherDiskRoms() const { return allowOtherDiskRoms; }
44
45 void setEnablePhantomDrives(bool enable) { enablePhantomDrives = enable; }
46 [[nodiscard]] bool getEnablePhantomDrives() const { return enablePhantomDrives; }
47
48 template<typename Archive>
49 void serialize(Archive& ar, unsigned version);
50
51 // public for serialization
52 enum class State {
53 SYNC1, // waiting for AF
54 SYNC2, // waiting for 05
55 COMMAND, // waiting for command (9 bytes)
56 DISKREAD, // waiting for AF07
57 DISKWRITE, // waiting for AA<data>AA
58 DEVOPEN, // waiting for filename (11 bytes)
59 IMAGE, // waiting for filename
60 MESSAGE, // waiting for null-terminated message
61 };
62
63private:
64 void msxReset();
65 [[nodiscard]] SectorAccessibleDisk* getDisk() const;
66 void executeCommand();
67
68 void send(byte value);
69 void send16(word value);
70 void sendHeader();
71 void purge();
72
73 void DRIVES();
74 void DSKCHG();
75 void CHOICE();
76 void INIENV();
77 void setDateMSX();
78
79 [[nodiscard]] unsigned getSectorAmount() const;
80 [[nodiscard]] unsigned getStartSector() const;
81 [[nodiscard]] unsigned getStartAddress() const;
82 [[nodiscard]] unsigned getCurrentAddress() const;
83
84 void diskReadInit(const SectorAccessibleDisk& disk);
85 void doDiskRead1();
86 void doDiskRead2();
87 void transferSectors(unsigned transferAddress, unsigned amount);
88 void transferSectorsBackwards(unsigned transferAddress, unsigned amount);
89
90 void diskWriteInit(const SectorAccessibleDisk& disk);
91 void doDiskWrite1();
92 void doDiskWrite2();
93
94 [[nodiscard]] word getFCB() const;
95 [[nodiscard]] std::string extractName(int begin, int end) const;
96 unsigned readHelper1(unsigned dev, std::span<char, 256> buffer);
97 void readHelper2(std::span<const char> buffer);
98 [[nodiscard]] int getDeviceNum() const;
99 int getFreeDeviceNum();
100 void deviceOpen();
101 void deviceClose();
102 void deviceWrite();
103 void deviceRead();
104
105 void callImage(const std::string& filename);
106
107private:
108 static constexpr unsigned MAX_DEVICES = 16;
109
110 const Drives& drives;
111
112 cb_queue<byte> hostToMsxFifo;
113
114 struct Device {
115 std::optional<std::fstream> fs; // not in use when fs == nullopt
116 word fcb;
117 };
118 std::array<Device, MAX_DEVICES> devices;
119
120 // state-machine
121 std::vector<SectorBuffer> buffer;// work buffer for disk read/write
122 unsigned lastTime = 0; // last time a byte was received from MSX
123 State state = State::SYNC1;
124 unsigned recvCount; // how many bytes recv in this state
125 unsigned transferred; // progress within disk read/write
126 unsigned retryCount; // only used for disk read
127 unsigned transferSize; // size of current chunk
128 std::array<byte, 9> cmdData; // reg_[cbedlhfa] + cmd
129 std::array<byte, 240 + 2> extraData; // extra data for disk read/write
130
131 byte romDisk = 255; // index of rom disk (255 = no rom disk)
132 bool allowOtherDiskRoms = false;
133 bool enablePhantomDrives = true;
134};
135
136} // namespace openmsx
137
138#endif // NOWINDHOST_HH
This implements a queue on top of circular_buffer (not part of boost).
byte peek() const
Definition NowindHost.cc:52
void serialize(Archive &ar, unsigned version)
void setEnablePhantomDrives(bool enable)
Definition NowindHost.hh:45
void write(byte data, unsigned time)
Definition NowindHost.cc:70
std::vector< std::unique_ptr< DiskContainer > > Drives
Definition NowindHost.hh:23
bool isDataAvailable() const
Definition NowindHost.cc:63
bool getAllowOtherDiskRoms() const
Definition NowindHost.hh:43
void setAllowOtherDiskRoms(bool allow)
Definition NowindHost.hh:42
bool getEnablePhantomDrives() const
Definition NowindHost.hh:46
This file implemented 3 utility functions:
Definition Autofire.cc:11
uint16_t word
16 bit unsigned integer
Definition openmsx.hh:29
constexpr auto begin(const zstring_view &x)
constexpr auto end(const zstring_view &x)