16 using std::unique_ptr;
27 :
Command(commandController, basename)
28 , interface(interface_)
33 const string& basename,
unsigned n,
MSXMotherBoard& motherBoard)
const
36 return make_unique<DiskChanger>(motherBoard, name,
false);
41 for (
unsigned i = 0; i < drives.size(); ++i) {
42 if (drives[i]->isRomdisk()) {
49 void NowindCommand::processHdimage(
59 set<unsigned> partitions;
60 auto pos = hdimage.find_last_of(
':');
66 auto wholeDisk = std::make_shared<DSKDiskImage>(
Filename(hdimage));
67 bool failOnError =
true;
68 if (partitions.empty()) {
71 for (
unsigned i = 1; i <= 31; ++i) {
76 for (
auto& p : partitions) {
78 auto partition = make_unique<DiskPartition>(
79 *wholeDisk, p, wholeDisk);
81 interface.basename,
unsigned(drives.size()),
83 drive->changeDisk(unique_ptr<Disk>(std::move(
partition)));
84 drives.push_back(std::move(drive));
85 }
catch (MSXException&) {
86 if (failOnError)
throw;
95 unsigned oldRomdisk = searchRomdisk(drives);
97 if (tokens.size() == 1) {
99 assert(!drives.empty());
101 for (
unsigned i = 0; i < drives.size(); ++i) {
102 result <<
"nowind" << i + 1 <<
": ";
103 if (dynamic_cast<NowindRomDisk*>(drives[i].
get())) {
104 result <<
"romdisk\n";
105 }
else if (
auto changer = dynamic_cast<DiskChanger*>(
107 string filename = changer->getDiskName().getOriginal();
108 result << (filename.empty() ?
"--empty--" : filename)
114 result <<
"phantom drives: "
117 result <<
"allow other diskroms: "
124 bool enablePhantom =
false;
125 bool disablePhantom =
false;
126 bool allowOther =
false;
127 bool disallowOther =
false;
128 bool changeDrives =
false;
129 unsigned romdisk = 255;
134 deque<string> args(tokens.begin() + 1, tokens.end());
135 while (error.empty() && !args.empty()) {
136 bool createDrive =
false;
139 string arg = std::move(args.front());
141 if ((arg ==
"--ctrl") || (arg ==
"-c")) {
142 enablePhantom =
false;
143 disablePhantom =
true;
144 }
else if ((arg ==
"--no-ctrl") || (arg ==
"-C")) {
145 enablePhantom =
true;
146 disablePhantom =
false;
147 }
else if ((arg ==
"--allow") || (arg ==
"-a")) {
149 disallowOther =
false;
150 }
else if ((arg ==
"--no-allow") || (arg ==
"-A")) {
152 disallowOther =
true;
154 }
else if ((arg ==
"--romdisk") || (arg ==
"-j")) {
155 if (romdisk != 255) {
156 error =
"Can only have one romdisk";
158 romdisk = unsigned(tmpDrives.size());
159 tmpDrives.push_back(make_unique<NowindRomDisk>());
163 }
else if ((arg ==
"--image") || (arg ==
"-i")) {
165 error =
"Missing argument for option: " + arg;
167 image = std::move(args.front());
172 }
else if ((arg ==
"--hdimage") || (arg ==
"-m")) {
174 error =
"Missing argument for option: " + arg;
177 string hdimage = std::move(args.front());
179 processHdimage(hdimage, tmpDrives);
194 interface.basename,
unsigned(tmpDrives.size()),
197 if (!image.empty()) {
198 if (drive->insertDisk(image)) {
199 error =
"Invalid disk image: " + image;
202 tmpDrives.push_back(std::move(drive));
205 if (tmpDrives.size() > 8) {
206 error =
"Can't have more than 8 drives";
210 bool optionsChanged =
false;
214 optionsChanged =
true;
218 optionsChanged =
true;
222 optionsChanged =
true;
226 optionsChanged =
true;
229 std::swap(tmpDrives, drives);
236 auto prevSize = tmpDrives.size();
238 for (
auto& d : drives) {
239 if (
auto disk = dynamic_cast<DiskChanger*>(d.get())) {
240 disk->createCommand();
244 if (!error.empty()) {
250 if (changeDrives && (prevSize != drives.size())) {
251 result +=
"Number of drives changed. ";
253 if (changeDrives && (romdisk != oldRomdisk)) {
254 if (oldRomdisk == 255) {
255 result +=
"Romdisk added. ";
256 }
else if (romdisk == 255) {
257 result +=
"Romdisk removed. ";
259 result +=
"Romdisk changed position. ";
262 if (optionsChanged) {
263 result +=
"Boot options changed. ";
265 if (!result.empty()) {
266 result +=
"You may need to reset the MSX for the changes to take effect.";
273 return "Similar to the disk<x> commands there is a nowind<x> command "
274 "for each nowind interface. This command is modeled after the "
275 "'usbhost' command of the real nowind interface. Though only a "
276 "subset of the options is supported. Here's a short overview.\n"
278 "Command line options\n"
279 " long short explanation\n"
280 "--image -i specify disk image\n"
281 "--hdimage -m specify harddisk image\n"
282 "--romdisk -j enable romdisk\n"
284 "--ctrl -c no phantom disks\n"
285 "--no-ctrl -C enable phantom disks\n"
286 "--allow -a allow other diskroms to initialize\n"
287 "--no-allow -A don't allow other diskroms to initialize\n"
293 "If you don't pass any arguments to this command, you'll get "
294 "an overview of the current nowind status.\n"
296 "This command will create a certain amount of drives on the "
297 "nowind interface and (optionally) insert diskimages in those "
298 "drives. For each of these drives there will also be a "
299 "'nowind<1..8>' command created. Those commands are similar to "
300 "e.g. the diska command. They can be used to access the more "
301 "advanced diskimage insertion options. See 'help nowind<1..8>' "
304 "In some cases it is needed to reboot the MSX before the "
305 "changes take effect. In those cases you'll get a message "
306 "that warns about this.\n"
309 "nowinda -a image.dsk -j Image.dsk is inserted into drive A: and the romdisk\n"
310 " will be drive B:. Other diskroms will be able to\n"
311 " install drives as well. For example when the MSX has\n"
312 " an internal diskdrive, drive C: en D: will be\n"
313 " available as well.\n"
314 "nowinda disk1.dsk disk2.dsk The two images will be inserted in A: and B:\n"
316 "nowinda -m hdimage.dsk Inserts a harddisk image. All available partitions\n"
317 " will be mounted as drives.\n"
318 "nowinda -m hdimage.dsk:1 Inserts the first partition only.\n"
319 "nowinda -m hdimage.dsk:2-4 Inserts the 2nd, 3th and 4th partition as drive A:\n"
325 static const char*
const extra[] = {