1 /*
2  * IDE ATA/ATAPI and controller emulation for DOSBox-X
3  * (C) 2012 Jonathan Campbell
4 
5  * [insert open source license here]
6  */
7 
8 /* $Id: ide.cpp,v 1.49 2009-04-10 09:53:04 c2woody Exp $ */
9 
10 #include "dosbox.h"
11 
12 #include <algorithm>
13 #include <cmath>
14 #include <cassert>
15 
16 #include "bios_disk.h"
17 #include "callback.h"
18 #include "control.h"
19 #include "cpu.h"
20 #include "ide.h"
21 #include "inout.h"
22 #include "mem.h"
23 #include "mixer.h"
24 #include "pic.h"
25 #include "setup.h"
26 #include "string_utils.h"
27 #include "timer.h"
28 
29 #include "../src/dos/cdrom.h"
30 
31 extern int bootdrive;
32 extern bool bootguest, bootvm, use_quick_reboot;
33 
34 static void ide_altio_w(io_port_t port, io_val_t val, io_width_t width);
35 static uint32_t ide_altio_r(io_port_t port, io_width_t width);
36 static void ide_baseio_w(io_port_t port, io_val_t val, io_width_t width);
37 static uint32_t ide_baseio_r(io_port_t port, io_width_t width);
38 bool GetMSCDEXDrive(uint8_t drive_letter, CDROM_Interface **_cdrom);
39 
40 enum IDEDeviceType { IDE_TYPE_NONE, IDE_TYPE_HDD = 1, IDE_TYPE_CDROM };
41 
42 enum IDEDeviceState {
43 	IDE_DEV_READY = 0,
44 	IDE_DEV_SELECT_WAIT,
45 	IDE_DEV_CONFUSED,
46 	IDE_DEV_BUSY,
47 	IDE_DEV_DATA_READ,
48 	IDE_DEV_DATA_WRITE,
49 	IDE_DEV_ATAPI_PACKET_COMMAND,
50 	IDE_DEV_ATAPI_BUSY
51 };
52 
53 enum {
54 	IDE_STATUS_BUSY = 0x80,
55 	IDE_STATUS_DRIVE_READY = 0x40,
56 	IDE_STATUS_DRIVE_SEEK_COMPLETE = 0x10,
57 	IDE_STATUS_DRQ = 0x08,
58 	IDE_STATUS_ERROR = 0x01
59 };
60 
61 class IDEController;
62 
63 #if 0 // unused
64 static inline bool drivehead_is_lba48(uint8_t val) {
65     return (val&0xE0) == 0x40;
66 }
67 #endif
68 
drivehead_is_lba(uint8_t val)69 static inline bool drivehead_is_lba(uint8_t val)
70 {
71 	return (val & 0xE0) == 0xE0;
72 }
73 
74 #if 0 // unused
75 static inline bool drivehead_is_chs(uint8_t val) {
76     return (val&0xE0) == 0xA0;
77 }
78 #endif
79 
get_controller_name(int index)80 static const char *get_controller_name(int index)
81 {
82 	switch (index) {
83 	case 0: return "primary";
84 	case 1: return "secondary";
85 	case 2: return "tertiary";
86 	case 3: return "quaternary";
87 	default: return "unknown-controller_name";
88 	}
89 }
90 
get_cable_slot_name(const bool is_second_slot)91 static const char *get_cable_slot_name(const bool is_second_slot)
92 {
93 	return is_second_slot ? "second" : "first";
94 }
95 
96 class IDEDevice {
97 public:
98 	IDEController *controller = nullptr;
99 	uint16_t feature = 0;
100 	uint16_t count = 0;
101 	uint16_t lba[3] = {}; /* feature = BASE+1  count = BASE+2   lba[3] = BASE+3,+4,+5 */
102 	uint8_t command = 0;
103 	uint8_t drivehead = 0;
104 	uint8_t status = 0x00; /* command/status = BASE+7  drivehead = BASE+6 */
105 	enum IDEDeviceType type = IDE_TYPE_NONE;
106 	bool faked_command = false; /* if set, DOSBox is sending commands to itself */
107 	bool allow_writing = true;
108 	bool motor_on = true;
109 	bool asleep = false;
110 	IDEDeviceState state = IDE_DEV_READY;
111 	/* feature: 0x1F1 (Word 00h in ATA specs)
112 	     count: 0x1F2 (Word 01h in ATA specs)
113 	    lba[3]: 0x1F3 (Word 02h) 0x1F4 (Word 03h) and 0x1F5 (Word 04h)
114 	 drivehead: 0x1F6 (copy of last value written)
115 	   command: 0x1F7 (Word 05h)
116 	    status: 0x1F7 (value read back to IDE controller, including busy and drive ready bits as well as
117 	error status)
118 
119 	In C/H/S modes lba[3] becomes lba[0]=sector lba[1]=cylinder-low lba[2]=cylinder-high and
120 	the code must read the 4-bit head number from drivehead[bits 3:0].
121 
122 	"drivehead" in this struct is always maintained as a device copy of the controller's
123 	drivehead value. it is only updated on write, and not returned on read.
124 
125 	"allow_writing" if set allows the DOS program/OS to write the registers. It is
126 	clear during command execution, obviously, so the state of the device is not confused
127 	while executing the command.
128 
129 	Registers are 16-bit where applicable so future revisions of this code
130 	can support LBA48 commands */
131 public:
132 	/* tweakable parameters */
133 	double ide_select_delay = 0.5;  /* 500us. time between writing 0x1F6 and drive readiness */
134 	double ide_spinup_delay = 3000; /* 3 seconds. time it takes to spin the hard disk motor up to speed */
135 	double ide_spindown_delay = 1000; /* 1 second. time it takes for hard disk motor to spin down */
136 	double ide_identify_command_delay = 0.01; /* 10us */
137 public:
IDEDevice(IDEController * c,const IDEDeviceType device_type)138 	IDEDevice(IDEController *c, const IDEDeviceType device_type) : controller(c), type(device_type) {}
139 	IDEDevice(const IDEDevice &other) = delete;            // prevent copying
140 	IDEDevice &operator=(const IDEDevice &other) = delete; // prevent assignment
141 	virtual ~IDEDevice();
142 
143 	virtual void host_reset_begin();    /* IDE controller -> upon setting bit 2 of alt (0x3F6) */
144 	virtual void host_reset_complete(); /* IDE controller -> upon setting bit 2 of alt (0x3F6) */
145 	virtual void select(uint8_t ndh, bool switched_to);
146 	virtual void deselect();
147 	virtual void abort_error();
148 	virtual void abort_normal();
149 	virtual void interface_wakeup();
150 	virtual void writecommand(uint8_t cmd);
151 	virtual uint32_t data_read(io_width_t width);          /* read from 1F0h data port from IDE device */
152 	virtual void data_write(uint32_t v, io_width_t width); /* write to 1F0h data port to IDE device */
153 	virtual bool command_interruption_ok(uint8_t cmd);
154 	virtual void abort_silent();
155 };
156 
157 class IDEATADevice : public IDEDevice {
158 public:
159 	IDEATADevice(IDEController *c, uint8_t disk_index);
160 	IDEATADevice(const IDEATADevice &other) = delete;            // prevent copying
161 	IDEATADevice &operator=(const IDEATADevice &other) = delete; // prevent assignment
162 	virtual ~IDEATADevice();
163 
164 	virtual void writecommand(uint8_t cmd);
165 
166 public:
167 	std::string id_serial = "8086";
168 	std::string id_firmware_rev = "8086";
169 	std::string id_model = "DOSBox IDE disk";
170 	uint8_t bios_disk_index;
171 
172 	std::shared_ptr<imageDisk> getBIOSdisk();
173 
174 	void update_from_biosdisk();
175 	virtual uint32_t data_read(io_width_t width);          /* read from 1F0h data port from IDE device */
176 	virtual void data_write(uint32_t v, io_width_t width); /* write to 1F0h data port to IDE device */
177 	virtual void generate_identify_device();
178 	virtual void prepare_read(uint32_t offset, uint32_t size);
179 	virtual void prepare_write(uint32_t offset, uint32_t size);
180 	virtual void io_completion();
181 	virtual bool increment_current_address(uint32_t count = 1);
182 
183 public:
184 	uint8_t sector[512 * 128] = {};
185 	uint32_t sector_i = 0;
186 	uint32_t sector_total = 0;
187 
188 	uint32_t multiple_sector_max = sizeof(sector) / 512;
189 	uint32_t multiple_sector_count = 1;
190 
191 	uint32_t heads = 0;
192 	uint32_t sects = 0;
193 	uint32_t cyls = 0;
194 
195 	uint32_t headshr = 0;
196 	uint32_t progress_count = 0;
197 
198 	uint32_t phys_heads = 0;
199 	uint32_t phys_sects = 0;
200 	uint32_t phys_cyls = 0;
201 
202 	bool geo_translate = false;
203 };
204 
205 enum {
206 	LOAD_NO_DISC = 0,
207 	LOAD_INSERT_CD,    /* user is "inserting" the CD */
208 	LOAD_IDLE,         /* disc is stationary, not spinning */
209 	LOAD_DISC_LOADING, /* disc is "spinning up" */
210 	LOAD_DISC_READIED, /* disc just "became ready" */
211 	LOAD_READY
212 };
213 
214 class IDEATAPICDROMDevice : public IDEDevice {
215 public:
216 	IDEATAPICDROMDevice(IDEController *c, uint8_t requested_drive_index);
217 	IDEATAPICDROMDevice(const IDEATAPICDROMDevice &other) = delete;            // prevent copying
218 	IDEATAPICDROMDevice &operator=(const IDEATAPICDROMDevice &other) = delete; // prevent assignment
219 	virtual ~IDEATAPICDROMDevice();
220 
221 	virtual void writecommand(uint8_t cmd);
222 
223 public:
224 	std::string id_serial = "123456789";
225 	std::string id_firmware_rev = "0.83-X";
226 	std::string id_model = "DOSBox-X Virtual CD-ROM";
227 	uint8_t drive_index = 0;
228 
229 	CDROM_Interface *getMSCDEXDrive();
230 	void update_from_cdrom();
231 	virtual uint32_t data_read(io_width_t width);          /* read from 1F0h data port from IDE device */
232 	virtual void data_write(uint32_t v, io_width_t width); /* write to 1F0h data port to IDE device */
233 	virtual void generate_identify_device();
234 	virtual void generate_mmc_inquiry();
235 	virtual void prepare_read(uint32_t offset, uint32_t size);
236 	virtual void prepare_write(uint32_t offset, uint32_t size);
237 	virtual void set_sense(uint8_t SK, uint8_t ASC = 0, uint8_t ASCQ = 0, uint32_t len = 0);
238 	virtual bool common_spinup_response(bool trigger, bool wait);
239 	virtual void on_mode_select_io_complete();
240 	virtual void atapi_io_completion();
241 	virtual void io_completion();
242 	virtual void atapi_cmd_completion();
243 	virtual void on_atapi_busy_time();
244 	virtual void read_subchannel();
245 	virtual void play_audio_msf();
246 	virtual void pause_resume();
247 	virtual void play_audio10();
248 	virtual void mode_sense();
249 	virtual void read_toc();
250 
251 public:
252 	/* if set, PACKET data transfer is to be read by host */
253 	bool atapi_to_host = false;
254 
255 	/* drive takes 1 second to spin up from idle */
256 	double spinup_time = 1000;
257 
258 	/* drive spins down automatically after 10 seconds */
259 	double spindown_timeout = 10000;
260 
261 	/* a quick user that can switch CDs in 4 seconds */
262 	double cd_insertion_time = 4000;
263 
264 	/* host maximum byte count during PACKET transfer */
265 	uint32_t host_maximum_byte_count = 0;
266 
267 	/* INQUIRY strings */
268 	std::string id_mmc_vendor_id = "DOSBox-X";
269 	std::string id_mmc_product_id = "Virtual CD-ROM";
270 	std::string id_mmc_product_rev = "0.83-X";
271 	uint32_t LBA = 0;
272 	uint32_t TransferLength = 0;
273 	int loading_mode = LOAD_IDLE;
274 	bool has_changed = false;
275 
276 public:
277 	uint8_t sense[256] = {};
278 	uint32_t sense_length = 0;
279 	uint8_t atapi_cmd[12] = {};
280 	uint8_t atapi_cmd_i = 0;
281 	uint8_t atapi_cmd_total = 0;
282 	uint8_t sector[512 * 128] = {};
283 	uint32_t sector_i = 0;
284 	uint32_t sector_total = 0;
285 };
286 
287 class IDEController {
288 public:
289 	int IRQ = -1;
290 	bool int13fakeio = false; /* on certain INT 13h calls, force IDE state as if BIOS had carried them out */
291 	bool int13fakev86io = false; /* on certain INT 13h calls in virtual 8086 mode, trigger fake CPU I/O traps */
292 	bool enable_pio32 = false; /* enable 32-bit PIO (if disabled, attempts at 32-bit PIO are handled as if
293 	                              two 16-bit I/O) */
294 	bool ignore_pio32 = false; /* if 32-bit PIO enabled, but ignored, writes do nothing, reads return
295 	                              0xFFFFFFFF */
296 	bool register_pnp = false;
297 	uint16_t alt_io = 0;
298 	uint16_t base_io = 0;
299 	uint8_t interface_index = 0;
300 	IO_ReadHandleObject ReadHandler[8] = {};
301 	IO_ReadHandleObject ReadHandlerAlt[2] = {};
302 	IO_WriteHandleObject WriteHandler[8] = {};
303 	IO_WriteHandleObject WriteHandlerAlt[2] = {};
304 
305 public:
306 	IDEDevice *device[2] = {nullptr, nullptr}; /* IDE devices (master, slave) */
307 	uint32_t select = 0;       /* selected device (0 or 1) */
308 	uint32_t status = 0;       /* status register */
309 	uint32_t drivehead = 0; /* which is selected, status register (0x1F7) but ONLY if no device exists at
310 	                           selection, drive/head register (0x1F6) */
311 	bool interrupt_enable = true; /* bit 1 of alt (0x3F6) */
312 	bool host_reset = false;      /* bit 2 of alt */
313 	bool irq_pending = false;
314 	/* defaults for CD-ROM emulation */
315 	double spinup_time = 0.0;
316 	double spindown_timeout = 0.0;
317 	double cd_insertion_time = 0.0;
318 
319 public:
320 	IDEController(const uint8_t index,
321 	              const uint8_t irq,
322 	              const uint16_t port,
323 	              const uint16_t alt_port);
324 	IDEController(const IDEController &other) = delete; // prevent copying
325 	IDEController &operator=(const IDEController &other) = delete; // prevent assignment
326 	~IDEController();
327 
328 	void install_io_ports();
329 	void uninstall_io_ports();
330 	void raise_irq();
331 	void lower_irq();
332 };
333 
334 static std::array<IDEController *, MAX_IDE_CONTROLLERS> idecontroller{{
335         nullptr,
336         nullptr,
337         nullptr,
338         nullptr,
339 }};
340 
341 static void IDE_DelayedCommand(uint32_t idx /*which IDE controller*/);
342 static IDEController *GetIDEController(uint32_t idx);
343 
IDE_ATAPI_SpinDown(uint32_t idx)344 static void IDE_ATAPI_SpinDown(uint32_t idx /*which IDE controller*/)
345 {
346 	IDEController *ctrl = GetIDEController(idx);
347 	if (ctrl == nullptr)
348 		return;
349 
350 	for (uint32_t i = 0; i < 2; i++) {
351 		IDEDevice *dev = ctrl->device[i];
352 		if (dev == nullptr)
353 			continue;
354 
355 		if (dev->type == IDE_TYPE_HDD) {
356 			// Empty
357 		} else if (dev->type == IDE_TYPE_CDROM) {
358 			IDEATAPICDROMDevice *atapi = (IDEATAPICDROMDevice *)dev;
359 
360 			if (atapi->loading_mode == LOAD_DISC_READIED || atapi->loading_mode == LOAD_READY) {
361 				atapi->loading_mode = LOAD_IDLE;
362 				LOG_MSG("IDE: ATAPI CD-ROM spinning down");
363 			}
364 		} else {
365 			LOG_WARNING("IDE: Unknown ATAPI spinup callback");
366 		}
367 	}
368 }
369 
370 static void IDE_ATAPI_SpinUpComplete(uint32_t idx /*which IDE controller*/);
371 
IDE_ATAPI_CDInsertion(uint32_t idx)372 static void IDE_ATAPI_CDInsertion(uint32_t idx /*which IDE controller*/)
373 {
374 	IDEController *ctrl = GetIDEController(idx);
375 	if (ctrl == nullptr)
376 		return;
377 
378 	for (uint32_t i = 0; i < 2; i++) {
379 		IDEDevice *dev = ctrl->device[i];
380 		if (dev == nullptr)
381 			continue;
382 
383 		if (dev->type == IDE_TYPE_HDD) {
384 			// Empty
385 		} else if (dev->type == IDE_TYPE_CDROM) {
386 			IDEATAPICDROMDevice *atapi = (IDEATAPICDROMDevice *)dev;
387 
388 			if (atapi->loading_mode == LOAD_INSERT_CD) {
389 				atapi->loading_mode = LOAD_DISC_LOADING;
390 				LOG_MSG("IDE: ATAPI CD-ROM loading inserted CD");
391 				PIC_RemoveSpecificEvents(IDE_ATAPI_SpinDown, idx);
392 				PIC_RemoveSpecificEvents(IDE_ATAPI_CDInsertion, idx);
393 				PIC_AddEvent(IDE_ATAPI_SpinUpComplete, atapi->spinup_time /*ms*/, idx);
394 			}
395 		} else {
396 			LOG_WARNING("IDE: Unknown ATAPI spinup callback");
397 		}
398 	}
399 }
400 
IDE_ATAPI_SpinUpComplete(uint32_t idx)401 static void IDE_ATAPI_SpinUpComplete(uint32_t idx /*which IDE controller*/)
402 {
403 	IDEController *ctrl = GetIDEController(idx);
404 	if (ctrl == nullptr)
405 		return;
406 
407 	for (uint32_t i = 0; i < 2; i++) {
408 		IDEDevice *dev = ctrl->device[i];
409 		if (dev == nullptr)
410 			continue;
411 
412 		if (dev->type == IDE_TYPE_HDD) {
413 			// Empty
414 		} else if (dev->type == IDE_TYPE_CDROM) {
415 			IDEATAPICDROMDevice *atapi = (IDEATAPICDROMDevice *)dev;
416 
417 			if (atapi->loading_mode == LOAD_DISC_LOADING) {
418 				atapi->loading_mode = LOAD_DISC_READIED;
419 				LOG_MSG("IDE: ATAPI CD-ROM spinup complete");
420 				PIC_RemoveSpecificEvents(IDE_ATAPI_SpinDown, idx);
421 				PIC_RemoveSpecificEvents(IDE_ATAPI_CDInsertion, idx);
422 				PIC_AddEvent(IDE_ATAPI_SpinDown, atapi->spindown_timeout /*ms*/, idx);
423 			}
424 		} else {
425 			LOG_WARNING("IDE: Unknown ATAPI spinup callback");
426 		}
427 	}
428 }
429 
430 /* returns "true" if command should proceed as normal, "false" if sense data was set and command should not
431  * proceed. this function helps to enforce virtual "spin up" and "ready" delays. */
common_spinup_response(bool trigger,bool wait)432 bool IDEATAPICDROMDevice::common_spinup_response(bool trigger, bool wait)
433 {
434 	if (loading_mode == LOAD_IDLE) {
435 		if (trigger) {
436 			LOG_MSG("IDE: ATAPI CD-ROM triggered to spin up from idle");
437 			loading_mode = LOAD_DISC_LOADING;
438 			PIC_RemoveSpecificEvents(IDE_ATAPI_SpinDown, controller->interface_index);
439 			PIC_RemoveSpecificEvents(IDE_ATAPI_CDInsertion, controller->interface_index);
440 			PIC_AddEvent(IDE_ATAPI_SpinUpComplete, spinup_time /*ms*/, controller->interface_index);
441 		}
442 	} else if (loading_mode == LOAD_READY) {
443 		if (trigger) {
444 			PIC_RemoveSpecificEvents(IDE_ATAPI_SpinDown, controller->interface_index);
445 			PIC_RemoveSpecificEvents(IDE_ATAPI_CDInsertion, controller->interface_index);
446 			PIC_AddEvent(IDE_ATAPI_SpinDown, spindown_timeout /*ms*/, controller->interface_index);
447 		}
448 	}
449 
450 	switch (loading_mode) {
451 	case LOAD_NO_DISC:
452 	case LOAD_INSERT_CD:
453 		set_sense(/*SK=*/0x02, /*ASC=*/0x3A); /* Medium Not Present */
454 		return false;
455 	case LOAD_DISC_LOADING:
456 		if (has_changed && !wait /*if command will block until LOADING complete*/) {
457 			set_sense(/*SK=*/0x02, /*ASC=*/0x04, /*ASCQ=*/0x01); /* Medium is becoming available */
458 			return false;
459 		}
460 		break;
461 	case LOAD_DISC_READIED:
462 		loading_mode = LOAD_READY;
463 		if (has_changed) {
464 			if (trigger)
465 				has_changed = false;
466 			set_sense(/*SK=*/0x02, /*ASC=*/0x28, /*ASCQ=*/0x00); /* Medium is ready (has changed) */
467 			return false;
468 		}
469 		break;
470 	case LOAD_IDLE:
471 	case LOAD_READY: break;
472 	default: abort();
473 	}
474 
475 	return true;
476 }
477 
read_subchannel()478 void IDEATAPICDROMDevice::read_subchannel()
479 {
480 	//  uint8_t Format = atapi_cmd[2] & 0xF;
481 	//  uint8_t Track = atapi_cmd[6];
482 	uint8_t paramList = atapi_cmd[3];
483 	uint8_t attr, track, index;
484 	bool SUBQ = !!(atapi_cmd[2] & 0x40);
485 	bool TIME = !!(atapi_cmd[1] & 2);
486 	uint8_t *write;
487 	uint8_t astat;
488 	bool playing, pause;
489 	TMSF rel, abs;
490 
491 	CDROM_Interface *cdrom = getMSCDEXDrive();
492 	if (cdrom == nullptr) {
493 		LOG_WARNING("IDE: WARNING: ATAPI READ TOC unable to get CDROM drive");
494 		prepare_read(0, 8);
495 		return;
496 	}
497 
498 	if (paramList == 0 || paramList > 3) {
499 		LOG_WARNING("IDE: ATAPI READ SUBCHANNEL unknown param list");
500 		prepare_read(0, 8);
501 		return;
502 	} else if (paramList == 2) {
503 		LOG_WARNING("IDE: ATAPI READ SUBCHANNEL Media Catalog Number not supported");
504 		prepare_read(0, 8);
505 		return;
506 	} else if (paramList == 3) {
507 		LOG_WARNING("IDE: ATAPI READ SUBCHANNEL ISRC not supported");
508 		prepare_read(0, 8);
509 		return;
510 	}
511 
512 	/* get current subchannel position */
513 	if (!cdrom->GetAudioSub(attr, track, index, rel, abs)) {
514 		LOG_WARNING("IDE: ATAPI READ SUBCHANNEL unable to read current pos");
515 		prepare_read(0, 8);
516 		return;
517 	}
518 
519 	if (!cdrom->GetAudioStatus(playing, pause))
520 		playing = pause = false;
521 
522 	if (playing)
523 		astat = pause ? 0x12 : 0x11;
524 	else
525 		astat = 0x13;
526 
527 	std::fill_n(sector, 8, 0);
528 	write = sector;
529 	*write++ = 0x00;
530 	*write++ = astat; /* AUDIO STATUS */
531 	*write++ = 0x00;  /* SUBCHANNEL DATA LENGTH */
532 	*write++ = 0x00;
533 
534 	if (SUBQ) {
535 		*write++ = 0x01;               /* subchannel data format code */
536 		*write++ = (attr >> 4) | 0x10; /* ADR/CONTROL */
537 		*write++ = track;
538 		*write++ = index;
539 		if (TIME) {
540 			*write++ = 0x00;
541 			*write++ = abs.min;
542 			*write++ = abs.sec;
543 			*write++ = abs.fr;
544 			*write++ = 0x00;
545 			*write++ = rel.min;
546 			*write++ = rel.sec;
547 			*write++ = rel.fr;
548 		} else {
549 			uint32_t sec;
550 
551 			sec = (abs.min * 60u * 75u) + (abs.sec * 75u) + abs.fr - 150u;
552 			*write++ = (uint8_t)(sec >> 24u);
553 			*write++ = (uint8_t)(sec >> 16u);
554 			*write++ = (uint8_t)(sec >> 8u);
555 			*write++ = (uint8_t)(sec >> 0u);
556 
557 			sec = (rel.min * 60u * 75u) + (rel.sec * 75u) + rel.fr - 150u;
558 			*write++ = (uint8_t)(sec >> 24u);
559 			*write++ = (uint8_t)(sec >> 16u);
560 			*write++ = (uint8_t)(sec >> 8u);
561 			*write++ = (uint8_t)(sec >> 0u);
562 		}
563 	}
564 
565 	{
566 		uint32_t x = (uint32_t)(write - sector) - 4;
567 		sector[2] = check_cast<uint8_t>(x >> 8);
568 		sector[3] = check_cast<uint8_t>(x);
569 	}
570 
571 	prepare_read(0, std::min((uint32_t)(write - sector), host_maximum_byte_count));
572 #if 0
573     for (size_t i=0;i < sector_total;i++) LOG_MSG("IDE: Subchannel %02x ",sector[i]);
574 #endif
575 }
576 
mode_sense()577 void IDEATAPICDROMDevice::mode_sense()
578 {
579 	uint8_t PAGE = atapi_cmd[2] & 0x3F;
580 	//  uint8_t SUBPAGE = atapi_cmd[3];
581 	uint8_t *write;
582 	uint32_t x;
583 
584 	write = sector;
585 
586 	/* Mode Parameter List MMC-3 Table 340 */
587 	/* - Mode parameter header */
588 	/* - Page(s) */
589 
590 	/* Mode Parameter Header (response for 10-byte MODE SENSE) SPC-2 Table 148 */
591 	*write++ = 0x00; /* MODE DATA LENGTH                     (MSB) */
592 	*write++ = 0x00; /*                                      (LSB) */
593 	*write++ = 0x00; /* MEDIUM TYPE */
594 	*write++ = 0x00; /* DEVICE-SPECIFIC PARAMETER */
595 	*write++ = 0x00; /* Reserved */
596 	*write++ = 0x00; /* Reserved */
597 	*write++ = 0x00; /* BLOCK DESCRIPTOR LENGTH              (MSB) */
598 	*write++ = 0x00; /*                                      (LSB) */
599 	/* NTS: MMC-3 Table 342 says that BLOCK DESCRIPTOR LENGTH is zero, where it would be 8 for legacy units */
600 
601 	/* Mode Page Format MMC-3 Table 341 */
602 	*write++ = PAGE; /* PS|reserved|Page Code */
603 	*write++ = 0x00; /* Page Length (n - 1) ... Length in bytes of the mode parameters that follow */
604 	switch (PAGE) {
605 	case 0x01:               /* Read error recovery MMC-3 Section 6.3.4 table 344 */
606 		*write++ = 0x00; /* +2 Error recovery Parameter  AWRE|ARRE|TB|RC|Reserved|PER|DTE|DCR */
607 		*write++ = 3;    /* +3 Read Retry Count */
608 		*write++ = 0x00; /* +4 Reserved */
609 		*write++ = 0x00; /* +5 Reserved */
610 		*write++ = 0x00; /* +6 Reserved */
611 		*write++ = 0x00; /* +7 Reserved */
612 		*write++ = 0x00; /* +8 Write Retry Count (this is not yet CD burner) */
613 		*write++ = 0x00; /* +9 Reserved */
614 		*write++ = 0x00; /* +10 Recovery Time Limit (should be zero)         (MSB) */
615 		*write++ = 0x00; /* +11                                              (LSB) */
616 		break;
617 	case 0x0E:               /* CD-ROM audio control MMC-3 Section 6.3.7 table 354 */
618 		                 /* also MMC-1 Section 5.2.3.1 table 97 */
619 		*write++ = 0x04; /* +2 Reserved|IMMED=1|SOTC=0|Reserved */
620 		*write++ = 0x00; /* +3 Reserved */
621 		*write++ = 0x00; /* +4 Reserved */
622 		*write++ = 0x00; /* +5 Reserved */
623 		*write++ = 0x00; /* +6 Obsolete (75) */
624 		*write++ = 75;   /* +7 Obsolete (75) */
625 		*write++ = 0x01; /* +8 output port 0 selection (0001b = channel 0) */
626 		*write++ = 0xFF; /* +9 output port 0 volume (0xFF = 0dB atten.) */
627 		*write++ = 0x02; /* +10 output port 1 selection (0010b = channel 1) */
628 		*write++ = 0xFF; /* +11 output port 1 volume (0xFF = 0dB atten.) */
629 		*write++ = 0x00; /* +12 output port 2 selection (none) */
630 		*write++ = 0x00; /* +13 output port 2 volume (0x00 = mute) */
631 		*write++ = 0x00; /* +14 output port 3 selection (none) */
632 		*write++ = 0x00; /* +15 output port 3 volume (0x00 = mute) */
633 		break;
634 	case 0x2A: /* CD-ROM mechanical status MMC-3 Section 6.3.11 table 361 */
635 		   /*    MSB            |             |             |             |              |    |    |    LSB    */
636 		*write++ = 0x07; /* +2 Reserved       |Reserved     |DVD-RAM read |DVD-R read   |DVD-ROM read
637 		                    |   Method 2    | CD-RW read   | CD-R read */
638 		*write++ = 0x00; /* +3 Reserved       |Reserved     |DVD-RAM write|DVD-R write  |   Reserved
639 		                    |  Test Write   | CD-RW write  | CD-R write */
640 		*write++ = 0x71; /* +4 Buffer Underrun|Multisession |Mode 2 form 2|Mode 2 form 1|Digital Port
641 		                    2|Digital Port 1 |  Composite   | Audio play */
642 		*write++ = 0xFF; /* +5 Read code bar  |UPC          |ISRC         |C2 Pointers  |R-W deintcorr
643 		                    | R-W supported |CDDA accurate |CDDA support */
644 		*write++ = 0x2F; /* +6 Loading mechanism type                     |Reserved     |Eject
645 		                    |Prevent Jumper |Lock state    |Lock */
646 		                 /*      0 (0x00) = Caddy
647 		                  *      1 (0x20) = Tray
648 		                  *      2 (0x40) = Popup
649 		                  *      3 (0x60) = Reserved
650 		                  *      4 (0x80) = Changer with indivually changeable discs
651 		                  *      5 (0xA0) = Changer using a magazine mechanism
652 		                  *      6 (0xC0) = Reserved
653 		                  *      6 (0xE0) = Reserved */
654 		*write++ = 0x03; /* +7 Reserved       |Reserved     |R-W in leadin|Side chg cap |S/W slot sel
655 		                    |Changer disc pr|Sep. ch. mute |Sep. volume levels */
656 
657 		x = 176 * 8; /* +8 maximum speed supported in kB: 8X  (obsolete in MMC-3) */
658 		*write++ = check_cast<uint8_t>(x >> 8);
659 		*write++ = check_cast<uint8_t>(x & 0xff);
660 
661 		x = 256; /* +10 Number of volume levels supported */
662 		*write++ = check_cast<uint8_t>(x >> 8);
663 		*write++ = check_cast<uint8_t>(x & 0xff);
664 
665 		x = 6 * 256; /* +12 buffer size supported by drive in kB */
666 		*write++ = check_cast<uint8_t>(x >> 8);
667 		*write++ = check_cast<uint8_t>(x & 0xff);
668 
669 		x = 176 * 8; /* +14 current read speed selected in kB: 8X  (obsolete in MMC-3) */
670 		*write++ = check_cast<uint8_t>(x >> 8);
671 		*write++ = check_cast<uint8_t>(x & 0xff);
672 
673 		*write++ = 0;    /* +16 Reserved */
674 		*write++ = 0x00; /* +17 Reserved | Reserved | Length | Length | LSBF | RCK | BCK | Reserved */
675 
676 		x = 0; /* +18 maximum write speed supported in kB: 0  (obsolete in MMC-3) */
677 		*write++ = check_cast<uint8_t>(x >> 8);
678 		*write++ = check_cast<uint8_t>(x & 0xff);
679 
680 		assert(x == 0); /* +20 current write speed in kB: 0  (obsolete in MMC-3) */
681 		*write++ = check_cast<uint8_t>(x >> 8);
682 		*write++ = check_cast<uint8_t>(x & 0xff);
683 		break;
684 	default:
685 		std::fill_n(write, 6, 0);
686 		write += 6;
687 		LOG_WARNING("IDE: MODE SENSE on page 0x%02x not supported", PAGE);
688 		break;
689 	}
690 
691 	/* mode param header, data length */
692 	x = (uint32_t)(write - sector) - 2;
693 	sector[0] = (uint8_t)(x >> 8u);
694 	sector[1] = (uint8_t)x;
695 	/* page length */
696 	sector[8 + 1] = check_cast<uint8_t>((uint32_t)(write - sector) - 2 - 8);
697 
698 	prepare_read(0, std::min((uint32_t)(write - sector), host_maximum_byte_count));
699 #if 0
700     for (size_t i=0;i < sector_total;i++) printf("IDE: Sense %02x ",sector[i]);
701 #endif
702 }
703 
pause_resume()704 void IDEATAPICDROMDevice::pause_resume()
705 {
706 	bool Resume = !!(atapi_cmd[8] & 1);
707 
708 	CDROM_Interface *cdrom = getMSCDEXDrive();
709 	if (cdrom == nullptr) {
710 		LOG_WARNING("IDE: ATAPI READ TOC unable to get CDROM drive");
711 		sector_total = 0;
712 		return;
713 	}
714 
715 	cdrom->PauseAudio(Resume);
716 }
717 
play_audio_msf()718 void IDEATAPICDROMDevice::play_audio_msf()
719 {
720 	uint32_t start_lba = 0;
721 	uint32_t end_lba = 0;
722 
723 	CDROM_Interface *cdrom = getMSCDEXDrive();
724 	if (cdrom == nullptr) {
725 		LOG_WARNING("IDE: ATAPI READ TOC unable to get CDROM drive");
726 		sector_total = 0;
727 		return;
728 	}
729 
730 	if (atapi_cmd[3] == 0xFF && atapi_cmd[4] == 0xFF && atapi_cmd[5] == 0xFF)
731 		start_lba = 0xFFFFFFFF;
732 	else {
733 		start_lba = (atapi_cmd[3] * 60u * 75u) + (atapi_cmd[4] * 75u) + atapi_cmd[5];
734 
735 		if (start_lba >= 150u)
736 			start_lba -= 150u; /* LBA sector 0 == M:S:F sector 0:2:0 */
737 		else
738 			start_lba = 0;
739 	}
740 
741 	if (atapi_cmd[6] == 0xFF && atapi_cmd[7] == 0xFF && atapi_cmd[8] == 0xFF)
742 		end_lba = 0xFFFFFFFF;
743 	else {
744 		end_lba = (atapi_cmd[6] * 60u * 75u) + (atapi_cmd[7] * 75u) + atapi_cmd[8];
745 
746 		if (end_lba >= 150u)
747 			end_lba -= 150u; /* LBA sector 0 == M:S:F sector 0:2:0 */
748 		else
749 			end_lba = 0;
750 	}
751 
752 	if (start_lba == end_lba) {
753 		/* The play length field specifies the number of contiguous logical blocks that shall
754 		 * be played. A play length of zero indicates that no audio operation shall occur.
755 		 * This condition is not an error. */
756 		/* TBD: How do we interpret that? Does that mean audio playback stops? Or does it
757 		 * mean we do nothing to the state of audio playback? */
758 		sector_total = 0;
759 		return;
760 	}
761 
762 	/* LBA 0xFFFFFFFF means start playing wherever the optics of the CD sit */
763 	if (start_lba != 0xFFFFFFFF)
764 		cdrom->PlayAudioSector(start_lba, end_lba - start_lba);
765 	else
766 		cdrom->PauseAudio(true);
767 
768 	sector_total = 0;
769 }
770 
play_audio10()771 void IDEATAPICDROMDevice::play_audio10()
772 {
773 	uint16_t play_length;
774 	uint32_t start_lba;
775 
776 	CDROM_Interface *cdrom = getMSCDEXDrive();
777 	if (cdrom == nullptr) {
778 		LOG_WARNING("IDE: ATAPI READ TOC unable to get CDROM drive");
779 		sector_total = 0;
780 		return;
781 	}
782 
783 	start_lba = ((uint32_t)atapi_cmd[2] << 24) + ((uint32_t)atapi_cmd[3] << 16) +
784 	            ((uint32_t)atapi_cmd[4] << 8) + ((uint32_t)atapi_cmd[5] << 0);
785 
786 	play_length = check_cast<uint16_t>(((uint16_t)atapi_cmd[7] << 8) + ((uint16_t)atapi_cmd[8] << 0));
787 
788 	if (play_length == 0) {
789 		/* The play length field specifies the number of contiguous logical blocks that shall
790 		 * be played. A play length of zero indicates that no audio operation shall occur.
791 		 * This condition is not an error. */
792 		/* TBD: How do we interpret that? Does that mean audio playback stops? Or does it
793 		 * mean we do nothing to the state of audio playback? */
794 		sector_total = 0;
795 		return;
796 	}
797 
798 	/* LBA 0xFFFFFFFF means start playing wherever the optics of the CD sit */
799 	if (start_lba != 0xFFFFFFFF)
800 		cdrom->PlayAudioSector(start_lba, play_length);
801 	else
802 		cdrom->PauseAudio(true);
803 
804 	sector_total = 0;
805 }
806 
807 #if 0 /* TODO move to library */
808 static uint8_t dec2bcd(uint8_t c) {
809     return ((c / 10) << 4) + (c % 10);
810 }
811 #endif
812 
read_toc()813 void IDEATAPICDROMDevice::read_toc()
814 {
815 	/* NTS: The SCSI MMC standards say we're allowed to indicate the return data
816 	 *      is longer than it's allocation length. But here's the thing: some MS-DOS
817 	 *      CD-ROM drivers will ask for the TOC but only provide enough room for one
818 	 *      entry (OAKCDROM.SYS) and if we signal more data than it's buffer, it will
819 	 *      reject our response and render the CD-ROM drive inaccessible. So to make
820 	 *      this emulation work, we have to cut our response short to the driver's
821 	 *      allocation length */
822 	uint32_t AllocationLength = ((uint32_t)atapi_cmd[7] << 8) + atapi_cmd[8];
823 	uint8_t Format = atapi_cmd[2] & 0xF;
824 	uint8_t Track = atapi_cmd[6];
825 	bool TIME = !!(atapi_cmd[1] & 2);
826 	uint8_t *write;
827 	uint8_t first, last, track;
828 	TMSF leadOut;
829 
830 	CDROM_Interface *cdrom = getMSCDEXDrive();
831 	if (cdrom == nullptr) {
832 		LOG_WARNING("IDE: ATAPI READ TOC unable to get CDROM drive");
833 		prepare_read(0, 8);
834 		return;
835 	}
836 
837 	std::fill_n(sector, 8, 0);
838 
839 	if (!cdrom->GetAudioTracks(first, last, leadOut)) {
840 		LOG_WARNING("IDE: ATAPI READ TOC failed to get track info");
841 		prepare_read(0, 8);
842 		return;
843 	}
844 
845 	/* start 2 bytes out. we'll fill in the data length later */
846 	write = sector + 2;
847 
848 	if (Format == 1) { /* Read multisession info */
849 		uint8_t attr;
850 		TMSF start;
851 
852 		*write++ = (uint8_t)1; /* @+2 first complete session */
853 		*write++ = (uint8_t)1; /* @+3 last complete session */
854 
855 		if (!cdrom->GetAudioTrackInfo(first, start, attr)) {
856 			LOG_WARNING("IDE: ATAPI READ TOC unable to read track %u information", first);
857 			attr = 0x41; /* ADR=1 CONTROL=4 */
858 			start.min = 0;
859 			start.sec = 0;
860 			start.fr = 0;
861 		}
862 
863 		LOG_MSG("IDE: ATAPI playing Track %u (attr=0x%02x %02u:%02u:%02u)", first, attr, start.min,
864 		        start.sec, start.fr);
865 
866 		*write++ = 0x00;               /* entry+0 RESERVED */
867 		*write++ = (attr >> 4) | 0x10; /* entry+1 ADR=1 CONTROL=4 (DATA) */
868 		*write++ = first;              /* entry+2 TRACK */
869 		*write++ = 0x00;               /* entry+3 RESERVED */
870 
871 		/* then, start address of first track in session */
872 		if (TIME) {
873 			*write++ = 0x00;
874 			*write++ = start.min;
875 			*write++ = start.sec;
876 			*write++ = start.fr;
877 		} else {
878 			uint32_t sec = (start.min * 60u * 75u) + (start.sec * 75u) + start.fr - 150u;
879 			*write++ = (uint8_t)(sec >> 24u);
880 			*write++ = (uint8_t)(sec >> 16u);
881 			*write++ = (uint8_t)(sec >> 8u);
882 			*write++ = (uint8_t)(sec >> 0u);
883 		}
884 	} else if (Format == 0) { /* Read table of contents */
885 		*write++ = first; /* @+2 */
886 		*write++ = last;  /* @+3 */
887 
888 		for (track = first; track <= last; track++) {
889 			uint8_t attr;
890 			TMSF start;
891 
892 			if (!cdrom->GetAudioTrackInfo(track, start, attr)) {
893 				LOG_WARNING("IDE: ATAPI READ TOC unable to read track %u information", track);
894 				attr = 0x41; /* ADR=1 CONTROL=4 */
895 				start.min = 0;
896 				start.sec = 0;
897 				start.fr = 0;
898 			}
899 
900 			if (track < Track)
901 				continue;
902 			if ((write + 8) > (sector + AllocationLength))
903 				break;
904 
905 			LOG_MSG("IDE: ATAPI playing Track %u (attr=0x%02x %02u:%02u:%02u)", first, attr,
906 			        start.min, start.sec, start.fr);
907 
908 			*write++ = 0x00;               /* entry+0 RESERVED */
909 			*write++ = (attr >> 4) | 0x10; /* entry+1 ADR=1 CONTROL=4 (DATA) */
910 			*write++ = track;              /* entry+2 TRACK */
911 			*write++ = 0x00;               /* entry+3 RESERVED */
912 			if (TIME) {
913 				*write++ = 0x00;
914 				*write++ = start.min;
915 				*write++ = start.sec;
916 				*write++ = start.fr;
917 			} else {
918 				uint32_t sec = (start.min * 60u * 75u) + (start.sec * 75u) + start.fr - 150u;
919 				*write++ = (uint8_t)(sec >> 24u);
920 				*write++ = (uint8_t)(sec >> 16u);
921 				*write++ = (uint8_t)(sec >> 8u);
922 				*write++ = (uint8_t)(sec >> 0u);
923 			}
924 		}
925 
926 		if ((write + 8) <= (sector + AllocationLength)) {
927 			*write++ = 0x00;
928 			*write++ = 0x14;
929 			*write++ = 0xAA; /*TRACK*/
930 			*write++ = 0x00;
931 			if (TIME) {
932 				*write++ = 0x00;
933 				*write++ = leadOut.min;
934 				*write++ = leadOut.sec;
935 				*write++ = leadOut.fr;
936 			} else {
937 				uint32_t sec = (leadOut.min * 60u * 75u) + (leadOut.sec * 75u) + leadOut.fr - 150u;
938 				*write++ = (uint8_t)(sec >> 24u);
939 				*write++ = (uint8_t)(sec >> 16u);
940 				*write++ = (uint8_t)(sec >> 8u);
941 				*write++ = (uint8_t)(sec >> 0u);
942 			}
943 		}
944 	} else {
945 		LOG_WARNING("IDE: ATAPI READ TOC Format=%u not supported", Format);
946 		prepare_read(0, 8);
947 		return;
948 	}
949 
950 	/* update the TOC data length field */
951 	{
952 		uint32_t x = (uint32_t)(write - sector) - 2;
953 		sector[0] = check_cast<uint8_t>(x >> 8);
954 		sector[1] = x & 0xFF;
955 	}
956 
957 	prepare_read(0, std::min(std::min((uint32_t)(write - sector), host_maximum_byte_count), AllocationLength));
958 }
959 
960 /* when the ATAPI command has been accepted, and the timeout has passed */
on_atapi_busy_time()961 void IDEATAPICDROMDevice::on_atapi_busy_time()
962 {
963 	/* if the drive is spinning up, then the command waits */
964 	if (loading_mode == LOAD_DISC_LOADING) {
965 		switch (atapi_cmd[0]) {
966 		case 0x00:                                                  /* TEST UNIT READY */
967 		case 0x03: /* REQUEST SENSE */ allow_writing = true; break; /* do not delay */
968 		default: PIC_AddEvent(IDE_DelayedCommand, 100 /*ms*/, controller->interface_index); return;
969 		}
970 	} else if (loading_mode == LOAD_DISC_READIED) {
971 		switch (atapi_cmd[0]) {
972 		case 0x00:                                                  /* TEST UNIT READY */
973 		case 0x03: /* REQUEST SENSE */ allow_writing = true; break; /* do not delay */
974 		default:
975 			if (!common_spinup_response(/*spin up*/ true, /*wait*/ false)) {
976 				count = 0x03;
977 				state = IDE_DEV_READY;
978 				feature = check_cast<uint16_t>(((sense[2] & 0xF) << 4) |
979 				                               ((sense[2] & 0xF) ? 0x04 /*abort*/ : 0x00));
980 				status = IDE_STATUS_DRIVE_READY |
981 				         ((sense[2] & 0xF) ? IDE_STATUS_ERROR : IDE_STATUS_DRIVE_SEEK_COMPLETE);
982 				controller->raise_irq();
983 				allow_writing = true;
984 				return;
985 			}
986 			break;
987 		}
988 	}
989 
990 	switch (atapi_cmd[0]) {
991 	case 0x03: /* REQUEST SENSE */
992 		prepare_read(0, std::min(sense_length, host_maximum_byte_count));
993 		memcpy(sector, sense, sense_length);
994 
995 		feature = 0x00;
996 		state = IDE_DEV_DATA_READ;
997 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRQ | IDE_STATUS_DRIVE_SEEK_COMPLETE;
998 
999 		/* ATAPI protocol also says we write back into LBA 23:8 what
1000 		 * we're going to transfer in the block */
1001 		lba[2] = check_cast<uint16_t>(sector_total >> 8);
1002 		lba[1] = check_cast<uint16_t>(sector_total);
1003 
1004 		controller->raise_irq();
1005 		allow_writing = true;
1006 		break;
1007 	case 0x1E: /* PREVENT ALLOW MEDIUM REMOVAL */
1008 		count = 0x03;
1009 		feature = 0x00;
1010 		sector_total = 0x00;
1011 		state = IDE_DEV_DATA_READ;
1012 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1013 
1014 		/* Don't care. Do nothing. */
1015 
1016 		/* ATAPI protocol also says we write back into LBA 23:8 what we're going to transfer in the block */
1017 		lba[2] = check_cast<uint16_t>(sector_total >> 8);
1018 		lba[1] = check_cast<uint16_t>(sector_total);
1019 
1020 		controller->raise_irq();
1021 		allow_writing = true;
1022 		break;
1023 	case 0x25: /* READ CAPACITY */ {
1024 		const uint32_t secsize = 2048;
1025 		uint8_t first, last;
1026 		TMSF leadOut;
1027 
1028 		CDROM_Interface *cdrom = getMSCDEXDrive();
1029 
1030 		if (!cdrom->GetAudioTracks(first, last, leadOut))
1031 			LOG_WARNING("IDE: ATAPI READ TOC failed to get track info");
1032 
1033 		uint32_t sec = (leadOut.min * 60u * 75u) + (leadOut.sec * 75u) + leadOut.fr - 150u;
1034 
1035 		prepare_read(0, std::min((uint32_t)8, host_maximum_byte_count));
1036 		sector[0] = sec >> 24u;
1037 		sector[1] = check_cast<uint8_t>(sec >> 16u);
1038 		sector[2] = check_cast<uint8_t>(sec >> 8u);
1039 		sector[3] = sec & 0xFF;
1040 		sector[4] = secsize >> 24u;
1041 		sector[5] = secsize >> 16u;
1042 		sector[6] = secsize >> 8u;
1043 		sector[7] = secsize & 0xFF;
1044 		//          LOG_MSG("sec=%lu secsize=%lu",sec,secsize);
1045 
1046 		feature = 0x00;
1047 		state = IDE_DEV_DATA_READ;
1048 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRQ | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1049 
1050 		/* ATAPI protocol also says we write back into LBA 23:8 what we're going to transfer in the block */
1051 		lba[2] = check_cast<uint16_t>(sector_total >> 8);
1052 		lba[1] = check_cast<uint16_t>(sector_total);
1053 
1054 		controller->raise_irq();
1055 		allow_writing = true;
1056 	} break;
1057 	case 0x2B: /* SEEK */
1058 		count = 0x03;
1059 		feature = 0x00;
1060 		sector_total = 0x00;
1061 		state = IDE_DEV_DATA_READ;
1062 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1063 
1064 		/* Don't care. Do nothing. */
1065 
1066 		/* Except... Windows 95's CD player expects the SEEK command to interrupt CD audio playback.
1067 		 * In fact it depends on it to the exclusion of commands explicitly standardized to... you
1068 		 * know... stop or pause playback. Oh Microsoft, you twits... */
1069 		{
1070 			CDROM_Interface *cdrom = getMSCDEXDrive();
1071 			if (cdrom) {
1072 				bool playing, pause;
1073 
1074 				if (!cdrom->GetAudioStatus(playing, pause))
1075 					playing = true;
1076 
1077 				if (playing) {
1078 					LOG_MSG("IDE: ATAPI: Interrupting CD audio playback due to SEEK");
1079 					cdrom->StopAudio();
1080 				}
1081 			}
1082 		}
1083 
1084 		/* ATAPI protocol also says we write back into LBA 23:8 what we're going to transfer in the block */
1085 		lba[2] = check_cast<uint16_t>(sector_total >> 8);
1086 		lba[1] = check_cast<uint16_t>(sector_total);
1087 
1088 		controller->raise_irq();
1089 		allow_writing = true;
1090 		break;
1091 	case 0x12: /* INQUIRY */
1092 		/* NTS: the state of atapi_to_host doesn't seem to matter. */
1093 		generate_mmc_inquiry();
1094 		prepare_read(0, std::min((uint32_t)36, host_maximum_byte_count));
1095 
1096 		feature = 0x00;
1097 		state = IDE_DEV_DATA_READ;
1098 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRQ | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1099 
1100 		/* ATAPI protocol also says we write back into LBA 23:8 what we're going to transfer in the block */
1101 		lba[2] = check_cast<uint16_t>(sector_total >> 8);
1102 		lba[1] = check_cast<uint16_t>(sector_total);
1103 
1104 		controller->raise_irq();
1105 		allow_writing = true;
1106 		break;
1107 	case 0x28: /* READ(10) */
1108 	case 0xA8: /* READ(12) */
1109 		if (TransferLength == 0) {
1110 			/* this is legal. the SCSI MMC standards say so.
1111 			   and apparently, MSCDEX.EXE issues READ(10) commands with transfer length == 0
1112 			   to test the drive, so we have to emulate this */
1113 			feature = 0x00;
1114 			count = 0x03;     /* no more transfer */
1115 			sector_total = 0; /*nothing to transfer */
1116 			state = IDE_DEV_READY;
1117 			status = IDE_STATUS_DRIVE_READY;
1118 		} else {
1119 			/* OK, try to read */
1120 			CDROM_Interface *cdrom = getMSCDEXDrive();
1121 			bool res = (cdrom != nullptr ? cdrom->ReadSectorsHost(/*buffer*/ sector, false, LBA, TransferLength)
1122 			                          : false);
1123 			if (res) {
1124 				prepare_read(0, std::min((TransferLength * 2048), host_maximum_byte_count));
1125 				feature = 0x00;
1126 				state = IDE_DEV_DATA_READ;
1127 				status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRQ | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1128 			} else {
1129 				feature = 0xF4;   /* abort sense=0xF */
1130 				count = 0x03;     /* no more transfer */
1131 				sector_total = 0; /*nothing to transfer */
1132 				state = IDE_DEV_READY;
1133 				status = IDE_STATUS_DRIVE_READY | IDE_STATUS_ERROR;
1134 				LOG_WARNING("IDE: ATAPI: Failed to read %lu sectors at %lu",
1135 				        (unsigned long)TransferLength, (unsigned long)LBA);
1136 				/* TBD: write sense data */
1137 			}
1138 		}
1139 
1140 		/* ATAPI protocol also says we write back into LBA 23:8 what we're going to transfer in the block */
1141 		lba[2] = check_cast<uint16_t>(sector_total >> 8);
1142 		lba[1] = check_cast<uint16_t>(sector_total);
1143 
1144 		controller->raise_irq();
1145 		allow_writing = true;
1146 		break;
1147 	case 0x42: /* READ SUB-CHANNEL */
1148 		read_subchannel();
1149 
1150 		feature = 0x00;
1151 		state = IDE_DEV_DATA_READ;
1152 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRQ | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1153 
1154 		/* ATAPI protocol also says we write back into LBA 23:8 what we're going to transfer in the block */
1155 		lba[2] = check_cast<uint16_t>(sector_total >> 8);
1156 		lba[1] = check_cast<uint16_t>(sector_total);
1157 
1158 		controller->raise_irq();
1159 		allow_writing = true;
1160 		break;
1161 	case 0x43: /* READ TOC */
1162 		read_toc();
1163 
1164 		feature = 0x00;
1165 		state = IDE_DEV_DATA_READ;
1166 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRQ | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1167 
1168 		/* ATAPI protocol also says we write back into LBA 23:8 what we're going to transfer in the block */
1169 		lba[2] = check_cast<uint16_t>(sector_total >> 8);
1170 		lba[1] = check_cast<uint16_t>(sector_total);
1171 
1172 		controller->raise_irq();
1173 		allow_writing = true;
1174 		break;
1175 	case 0x45: /* PLAY AUDIO(10) */
1176 		play_audio10();
1177 
1178 		count = 0x03;
1179 		feature = 0x00;
1180 		sector_total = 0x00;
1181 		state = IDE_DEV_DATA_READ;
1182 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1183 
1184 		/* ATAPI protocol also says we write back into LBA 23:8 what we're going to transfer in the block */
1185 		lba[2] = check_cast<uint16_t>(sector_total >> 8);
1186 		lba[1] = check_cast<uint16_t>(sector_total);
1187 
1188 		controller->raise_irq();
1189 		allow_writing = true;
1190 		break;
1191 	case 0x47: /* PLAY AUDIO MSF */
1192 		play_audio_msf();
1193 
1194 		count = 0x03;
1195 		feature = 0x00;
1196 		sector_total = 0x00;
1197 		state = IDE_DEV_DATA_READ;
1198 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1199 
1200 		/* ATAPI protocol also says we write back into LBA 23:8 what we're going to transfer in the block */
1201 		lba[2] = check_cast<uint16_t>(sector_total >> 8);
1202 		lba[1] = check_cast<uint16_t>(sector_total);
1203 
1204 		controller->raise_irq();
1205 		allow_writing = true;
1206 		break;
1207 	case 0x4B: /* PAUSE/RESUME */
1208 		pause_resume();
1209 
1210 		count = 0x03;
1211 		feature = 0x00;
1212 		sector_total = 0x00;
1213 		state = IDE_DEV_DATA_READ;
1214 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1215 
1216 		/* ATAPI protocol also says we write back into LBA 23:8 what we're going to transfer in the block */
1217 		lba[2] = check_cast<uint16_t>(sector_total >> 8);
1218 		lba[1] = check_cast<uint16_t>(sector_total);
1219 
1220 		controller->raise_irq();
1221 		allow_writing = true;
1222 		break;
1223 	case 0x55: /* MODE SELECT(10) */
1224 		/* we need the data written first, will act in I/O completion routine */
1225 		{
1226 			uint32_t x;
1227 
1228 			x = (uint32_t)lba[1] + ((uint32_t)lba[2] << 8u);
1229 
1230 			/* Windows 95 likes to set 0xFFFF here for whatever reason.
1231 			 * Negotiate it down to a maximum of 512 for sanity's sake */
1232 			if (x > 512)
1233 				x = 512;
1234 			lba[2] = check_cast<uint16_t>(x >> 8u);
1235 			lba[1] = check_cast<uint16_t>(x);
1236 
1237 			//              LOG_MSG("MODE SELECT expecting %u bytes",x);
1238 			prepare_write(0, (x + 1u) & (~1u));
1239 		}
1240 
1241 		feature = 0x00;
1242 		state = IDE_DEV_DATA_WRITE;
1243 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRQ | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1244 		controller->raise_irq();
1245 		allow_writing = true;
1246 		break;
1247 	case 0x5A: /* MODE SENSE(10) */
1248 		mode_sense();
1249 
1250 		feature = 0x00;
1251 		state = IDE_DEV_DATA_READ;
1252 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRQ | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1253 
1254 		/* ATAPI protocol also says we write back into LBA 23:8 what we're going to transfer in the block */
1255 		lba[2] = check_cast<uint16_t>(sector_total >> 8);
1256 		lba[1] = check_cast<uint16_t>(sector_total);
1257 
1258 		controller->raise_irq();
1259 		allow_writing = true;
1260 		break;
1261 	default:
1262 		LOG_WARNING("IDE: Unknown ATAPI command after busy wait. Why?");
1263 		abort_error();
1264 		controller->raise_irq();
1265 		allow_writing = true;
1266 		break;
1267 	}
1268 }
1269 
set_sense(uint8_t SK,uint8_t ASC,uint8_t ASCQ,uint32_t len)1270 void IDEATAPICDROMDevice::set_sense(uint8_t SK, uint8_t ASC, uint8_t ASCQ, uint32_t len)
1271 {
1272 	if (len < 18)
1273 		len = 18;
1274 	memset(sense, 0, len);
1275 	sense_length = len;
1276 
1277 	sense[0] = 0x70;                          /* RESPONSE CODE */
1278 	sense[2] = SK & 0xF;                      /* SENSE KEY */
1279 	sense[7] = check_cast<uint8_t>(len - 18); /* additional sense length */
1280 	sense[12] = ASC;
1281 	sense[13] = ASCQ;
1282 }
1283 
IDEATAPICDROMDevice(IDEController * c,uint8_t requested_drive_index)1284 IDEATAPICDROMDevice::IDEATAPICDROMDevice(IDEController *c, uint8_t requested_drive_index)
1285         : IDEDevice(c, IDE_TYPE_CDROM),
1286           drive_index(requested_drive_index)
1287 {
1288 	IDEATAPICDROMDevice::set_sense(/*SK=*/0);
1289 
1290 	/* TBD: Spinup/down times should be dosbox.conf configurable, if the DOSBox gamers
1291 	 *        care more about loading times than emulation accuracy. */
1292 	if (c->cd_insertion_time > 0)
1293 		cd_insertion_time = c->cd_insertion_time;
1294 
1295 	if (c->spinup_time > 0)
1296 		spinup_time = c->spinup_time;
1297 
1298 	if (c->spindown_timeout > 0)
1299 		spindown_timeout = c->spindown_timeout;
1300 }
1301 
~IDEATAPICDROMDevice()1302 IDEATAPICDROMDevice::~IDEATAPICDROMDevice()
1303 {}
1304 
on_mode_select_io_complete()1305 void IDEATAPICDROMDevice::on_mode_select_io_complete()
1306 {
1307 	uint32_t AllocationLength = ((uint32_t)atapi_cmd[7] << 8) + atapi_cmd[8];
1308 	uint8_t *scan, *fence;
1309 	size_t i;
1310 
1311 	/* the first 8 bytes are a mode parameter header.
1312 	 * It's supposed to provide length, density, etc. or whatever the hell
1313 	 * it means. Windows 95 seems to send all zeros there, so ignore it.
1314 	 *
1315 	 * we care about the bytes following it, which contain page_0 mode
1316 	 * pages */
1317 
1318 	scan = sector + 8;
1319 	fence = sector + std::min(sector_total, AllocationLength);
1320 
1321 	while ((scan + 2) < fence) {
1322 		uint8_t PAGE = *scan++;
1323 		uint32_t LEN = (uint32_t)(*scan++);
1324 
1325 		if ((scan + LEN) > fence) {
1326 			LOG_WARNING("IDE: ATAPI MODE SELECT warning, page_0 length extends %u bytes past buffer",
1327 			        (uint32_t)(scan + LEN - fence));
1328 			break;
1329 		}
1330 
1331 		LOG_MSG("IDE: ATAPI MODE SELECT, PAGE 0x%02x len=%u", PAGE, LEN);
1332 		LOG_MSG("  ");
1333 		for (i = 0; i < LEN; i++)
1334 			LOG_MSG("%02x ", scan[i]);
1335 		LOG_MSG(" ");
1336 
1337 		scan += LEN;
1338 	}
1339 }
1340 
atapi_io_completion()1341 void IDEATAPICDROMDevice::atapi_io_completion()
1342 {
1343 	/* for most ATAPI PACKET commands, the transfer is done and we need to clear
1344 	   all indication of a possible data transfer */
1345 
1346 	if (count == 0x00) { /* the command was expecting data. now it can act on it */
1347 		switch (atapi_cmd[0]) {
1348 		case 0x55: /* MODE SELECT(10) */ on_mode_select_io_complete(); break;
1349 		}
1350 	}
1351 
1352 	count = 0x03; /* no more data (command/data=1, input/output=1) */
1353 	status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1354 	state = IDE_DEV_READY;
1355 	allow_writing = true;
1356 
1357 	/* Apparently: real IDE ATAPI controllers fire another IRQ after the transfer.
1358 	   And there are MS-DOS CD-ROM drivers that assume that. */
1359 	controller->raise_irq();
1360 }
1361 
io_completion()1362 void IDEATAPICDROMDevice::io_completion()
1363 {
1364 	/* lower DRQ */
1365 	status &= ~IDE_STATUS_DRQ;
1366 
1367 	/* depending on the command, either continue it or finish up */
1368 	switch (command) {
1369 	case 0xA0: /*ATAPI PACKET*/ atapi_io_completion(); break;
1370 	default: /* most commands: signal drive ready, return to ready state */
1371 		/* NTS: Some MS-DOS CD-ROM drivers will loop endlessly if we never set "drive seek complete"
1372 		        because they like to hit the device with DEVICE RESET (08h) whether or not it's
1373 		    a hard disk or CD-ROM drive */
1374 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1375 		state = IDE_DEV_READY;
1376 		allow_writing = true;
1377 		break;
1378 	}
1379 }
1380 
increment_current_address(uint32_t n)1381 bool IDEATADevice::increment_current_address(uint32_t n)
1382 {
1383 	if (n == 0)
1384 		return false;
1385 
1386 	if (drivehead_is_lba(drivehead)) {
1387 		/* 28-bit LBA:
1388 		 *    drivehead: 27:24
1389 		 *    lba[2]:    23:16
1390 		 *    lba[1]:    15:8
1391 		 *    lba[0]:    7:0 */
1392 		do {
1393 			if (((++lba[0]) & 0xFF) == 0x00) {
1394 				lba[0] = 0x00;
1395 				if (((++lba[1]) & 0xFF) == 0x00) {
1396 					lba[1] = 0x00;
1397 					if (((++lba[2]) & 0xFF) == 0x00) {
1398 						lba[2] = 0x00;
1399 						if (((++drivehead) & 0xF) == 0) {
1400 							drivehead -= 0x10;
1401 							return false;
1402 						}
1403 					}
1404 				}
1405 			}
1406 		} while ((--n) != 0);
1407 	} else {
1408 		/* C/H/S increment with rollover */
1409 		do {
1410 			/* increment sector */
1411 			if (((++lba[0]) & 0xFF) == ((sects + 1) & 0xFF)) {
1412 				lba[0] = 1;
1413 				/* increment head */
1414 				if (((++drivehead) & 0xF) == (heads & 0xF)) {
1415 					drivehead &= 0xF0;
1416 					if (heads == 16)
1417 						drivehead -= 0x10;
1418 					/* increment cylinder */
1419 					if (((++lba[1]) & 0xFF) == 0x00) {
1420 						if (((++lba[2]) & 0xFF) == 0x00) {
1421 							return false;
1422 						}
1423 					}
1424 				}
1425 			}
1426 		} while ((--n) != 0);
1427 	}
1428 
1429 	return true;
1430 }
1431 
io_completion()1432 void IDEATADevice::io_completion()
1433 {
1434 	/* lower DRQ */
1435 	status &= ~IDE_STATUS_DRQ;
1436 
1437 	/* depending on the command, either continue it or finish up */
1438 	switch (command) {
1439 	case 0x20: /* READ SECTOR */
1440 		/* OK, decrement count, increment address */
1441 		/* NTS: Remember that count == 0 means the host wanted to transfer 256 sectors */
1442 		progress_count++;
1443 		if ((count & 0xFF) == 1) {
1444 			/* end of the transfer */
1445 			count = 0;
1446 			status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1447 			state = IDE_DEV_READY;
1448 			allow_writing = true;
1449 			return;
1450 		} else if ((count & 0xFF) == 0)
1451 			count = 255;
1452 		else
1453 			count--;
1454 
1455 		if (!increment_current_address()) {
1456 			LOG_WARNING("IDE: READ advance error");
1457 			abort_error();
1458 			return;
1459 		}
1460 
1461 		/* cause another delay, another sector read */
1462 		state = IDE_DEV_BUSY;
1463 		status = IDE_STATUS_BUSY;
1464 		PIC_AddEvent(IDE_DelayedCommand, 0.00001 /*ms*/, controller->interface_index);
1465 		break;
1466 	case 0xC5: /* WRITE MULTIPLE */
1467 	case 0x30: /* WRITE SECTOR */
1468 		/* this is where the drive has accepted the sector, lowers DRQ, and begins executing the command */
1469 		state = IDE_DEV_BUSY;
1470 		status = IDE_STATUS_BUSY;
1471 		PIC_AddEvent(IDE_DelayedCommand, ((progress_count == 0 && !faked_command) ? 0.1 : 0.00001) /*ms*/,
1472 		             controller->interface_index);
1473 		break;
1474 	case 0xC4: /* READ MULTIPLE */
1475 		/* OK, decrement count, increment address */
1476 		/* NTS: Remember that count == 0 means the host wanted to transfer 256 sectors */
1477 		for (uint32_t cc = 0; cc < multiple_sector_count; cc++) {
1478 			progress_count++;
1479 			if ((count & 0xFF) == 1) {
1480 				/* end of the transfer */
1481 				count = 0;
1482 				status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1483 				state = IDE_DEV_READY;
1484 				allow_writing = true;
1485 				return;
1486 			} else if ((count & 0xFF) == 0)
1487 				count = 255;
1488 			else
1489 				count--;
1490 
1491 			if (!increment_current_address()) {
1492 				LOG_WARNING("IDE: READ advance error");
1493 				abort_error();
1494 				return;
1495 			}
1496 		}
1497 
1498 		/* cause another delay, another sector read */
1499 		state = IDE_DEV_BUSY;
1500 		status = IDE_STATUS_BUSY;
1501 		PIC_AddEvent(IDE_DelayedCommand, 0.00001 /*ms*/, controller->interface_index);
1502 		break;
1503 	default: /* most commands: signal drive ready, return to ready state */
1504 		/* NTS: Some MS-DOS CD-ROM drivers will loop endlessly if we never set "drive seek complete"
1505 		        because they like to hit the device with DEVICE RESET (08h) whether or not it's
1506 		    a hard disk or CD-ROM drive */
1507 		count = 0;
1508 		drivehead &= 0xF0;
1509 		lba[0] = 0;
1510 		lba[1] = lba[2] = 0;
1511 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
1512 		state = IDE_DEV_READY;
1513 		allow_writing = true;
1514 		break;
1515 	}
1516 }
1517 
data_read(io_width_t width)1518 uint32_t IDEATAPICDROMDevice::data_read(io_width_t width)
1519 {
1520 	uint32_t w = ~0u;
1521 
1522 	if (state != IDE_DEV_DATA_READ)
1523 		return 0xFFFFUL;
1524 
1525 	if (!(status & IDE_STATUS_DRQ)) {
1526 		LOG_MSG("IDE: Data read when DRQ=0");
1527 		return 0xFFFFUL;
1528 	}
1529 
1530 	if (sector_i >= sector_total)
1531 		return 0xFFFFUL;
1532 
1533 	if (width == io_width_t::dword) {
1534 		w = host_readd(sector + sector_i);
1535 		sector_i += 4;
1536 	} else if (width == io_width_t::word) {
1537 		w = host_readw(sector + sector_i);
1538 		sector_i += 2;
1539 	}
1540 	/* NTS: Some MS-DOS CD-ROM drivers like OAKCDROM.SYS use byte-wide I/O for the initial identification */
1541 	else if (width == io_width_t::byte) {
1542 		w = sector[sector_i++];
1543 	}
1544 
1545 	if (sector_i >= sector_total)
1546 		io_completion();
1547 
1548 	return w;
1549 }
1550 
1551 /* TBD: Your code should also be paying attention to the "transfer length" field
1552          in many of the commands here. Right now it doesn't matter. */
atapi_cmd_completion()1553 void IDEATAPICDROMDevice::atapi_cmd_completion()
1554 {
1555 #if 0
1556     LOG_MSG("IDE: ATAPI command %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x to_host=%u",
1557         atapi_cmd[ 0],atapi_cmd[ 1],atapi_cmd[ 2],atapi_cmd[ 3],atapi_cmd[ 4],atapi_cmd[ 5],
1558         atapi_cmd[ 6],atapi_cmd[ 7],atapi_cmd[ 8],atapi_cmd[ 9],atapi_cmd[10],atapi_cmd[11],
1559         atapi_to_host);
1560 #endif
1561 
1562 	switch (atapi_cmd[0]) {
1563 	case 0x00: /* TEST UNIT READY */
1564 		if (common_spinup_response(/*spin up*/ false, /*wait*/ false))
1565 			set_sense(0); /* <- nothing wrong */
1566 
1567 		count = 0x03;
1568 		state = IDE_DEV_READY;
1569 		feature = check_cast<uint16_t>(((sense[2] & 0xF) << 4) |
1570 		                               ((sense[2] & 0xF) ? 0x04 /*abort*/ : 0x00));
1571 		status = IDE_STATUS_DRIVE_READY |
1572 		         ((sense[2] & 0xF) ? IDE_STATUS_ERROR : IDE_STATUS_DRIVE_SEEK_COMPLETE);
1573 		controller->raise_irq();
1574 		allow_writing = true;
1575 		break;
1576 	case 0x03: /* REQUEST SENSE */
1577 		count = 0x02;
1578 		state = IDE_DEV_ATAPI_BUSY;
1579 		status = IDE_STATUS_BUSY;
1580 		PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : 1) /*ms*/, controller->interface_index);
1581 		break;
1582 	case 0x1E: /* PREVENT ALLOW MEDIUM REMOVAL */
1583 		count = 0x02;
1584 		state = IDE_DEV_ATAPI_BUSY;
1585 		status = IDE_STATUS_BUSY;
1586 		PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : 1) /*ms*/, controller->interface_index);
1587 		break;
1588 	case 0x25: /* READ CAPACITY */
1589 		count = 0x02;
1590 		state = IDE_DEV_ATAPI_BUSY;
1591 		status = IDE_STATUS_BUSY;
1592 		PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : 1) /*ms*/, controller->interface_index);
1593 		break;
1594 	case 0x2B: /* SEEK */
1595 		if (common_spinup_response(/*spin up*/ true, /*wait*/ true)) {
1596 			set_sense(0); /* <- nothing wrong */
1597 			count = 0x02;
1598 			state = IDE_DEV_ATAPI_BUSY;
1599 			status = IDE_STATUS_BUSY;
1600 			PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : 1) /*ms*/,
1601 			             controller->interface_index);
1602 		} else {
1603 			count = 0x03;
1604 			state = IDE_DEV_READY;
1605 			feature = check_cast<uint16_t>(((sense[2] & 0xF) << 4) |
1606 			                               ((sense[2] & 0xF) ? 0x04 /*abort*/ : 0x00));
1607 			status = IDE_STATUS_DRIVE_READY |
1608 			         ((sense[2] & 0xF) ? IDE_STATUS_ERROR : IDE_STATUS_DRIVE_SEEK_COMPLETE);
1609 			controller->raise_irq();
1610 			allow_writing = true;
1611 		}
1612 		break;
1613 	case 0x12: /* INQUIRY */
1614 		count = 0x02;
1615 		state = IDE_DEV_ATAPI_BUSY;
1616 		status = IDE_STATUS_BUSY;
1617 		PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : 1) /*ms*/, controller->interface_index);
1618 		break;
1619 	case 0xA8: /* READ(12) */
1620 		if (common_spinup_response(/*spin up*/ true, /*wait*/ true)) {
1621 			set_sense(0); /* <- nothing wrong */
1622 
1623 			/* TBD: MSCDEX.EXE appears to test the drive by issuing READ(10) with transfer
1624 			   length == 0. This is all well and good but our response seems to cause a temporary
1625 			   2-3 second pause for each attempt. Why? */
1626 			LBA = ((uint32_t)atapi_cmd[2] << 24UL) | ((uint32_t)atapi_cmd[3] << 16UL) |
1627 			      ((uint32_t)atapi_cmd[4] << 8UL) | ((uint32_t)atapi_cmd[5] << 0UL);
1628 			TransferLength = ((uint32_t)atapi_cmd[6] << 24UL) | ((uint32_t)atapi_cmd[7] << 16UL) |
1629 			                 ((uint32_t)atapi_cmd[8] << 8UL) | ((uint32_t)atapi_cmd[9]);
1630 
1631 			/* TBD: We actually should NOT be capping the transfer length, but instead should
1632 			   be breaking the larger transfer into smaller DRQ block transfers like
1633 			   most IDE ATAPI drives do. Writing the test IDE code taught me that if you
1634 			   go to most drives and request a transfer length of 0xFFFE the drive will
1635 			   happily set itself up to transfer that many sectors in one IDE command! */
1636 			/* NTS: In case you're wondering, it's legal to issue READ(10) with transfer length ==
1637 			   0. MSCDEX.EXE does it when starting up, for example */
1638 			if ((TransferLength * 2048) > sizeof(sector))
1639 				TransferLength = sizeof(sector) / 2048;
1640 
1641 			count = 0x02;
1642 			state = IDE_DEV_ATAPI_BUSY;
1643 			status = IDE_STATUS_BUSY;
1644 			/* TBD: Emulate CD-ROM spin-up delay, and seek delay */
1645 			PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : 3) /*ms*/,
1646 			             controller->interface_index);
1647 		} else {
1648 			count = 0x03;
1649 			state = IDE_DEV_READY;
1650 			feature = check_cast<uint16_t>(((sense[2] & 0xF) << 4) |
1651 			                               ((sense[2] & 0xF) ? 0x04 /*abort*/ : 0x00));
1652 			status = IDE_STATUS_DRIVE_READY |
1653 			         ((sense[2] & 0xF) ? IDE_STATUS_ERROR : IDE_STATUS_DRIVE_SEEK_COMPLETE);
1654 			controller->raise_irq();
1655 			allow_writing = true;
1656 		}
1657 		break;
1658 	case 0x28: /* READ(10) */
1659 		if (common_spinup_response(/*spin up*/ true, /*wait*/ true)) {
1660 			set_sense(0); /* <- nothing wrong */
1661 
1662 			/* TBD: MSCDEX.EXE appears to test the drive by issuing READ(10) with transfer
1663 			   length == 0. This is all well and good but our response seems to cause a temporary
1664 			   2-3 second pause for each attempt. Why? */
1665 			LBA = ((uint32_t)atapi_cmd[2] << 24UL) | ((uint32_t)atapi_cmd[3] << 16UL) |
1666 			      ((uint32_t)atapi_cmd[4] << 8UL) | ((uint32_t)atapi_cmd[5] << 0UL);
1667 			TransferLength = ((uint32_t)atapi_cmd[7] << 8) | ((uint32_t)atapi_cmd[8]);
1668 
1669 			/* TBD: We actually should NOT be capping the transfer length, but instead should
1670 			   be breaking the larger transfer into smaller DRQ block transfers like
1671 			   most IDE ATAPI drives do. Writing the test IDE code taught me that if you
1672 			   go to most drives and request a transfer length of 0xFFFE the drive will
1673 			   happily set itself up to transfer that many sectors in one IDE command! */
1674 			/* NTS: In case you're wondering, it's legal to issue READ(10) with transfer length ==
1675 			   0. MSCDEX.EXE does it when starting up, for example */
1676 			if ((TransferLength * 2048) > sizeof(sector))
1677 				TransferLength = sizeof(sector) / 2048;
1678 
1679 			count = 0x02;
1680 			state = IDE_DEV_ATAPI_BUSY;
1681 			status = IDE_STATUS_BUSY;
1682 			/* TBD: Emulate CD-ROM spin-up delay, and seek delay */
1683 			PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : 3) /*ms*/,
1684 			             controller->interface_index);
1685 		} else {
1686 			count = 0x03;
1687 			state = IDE_DEV_READY;
1688 			feature = check_cast<uint16_t>(((sense[2] & 0xF) << 4) |
1689 			                               ((sense[2] & 0xF) ? 0x04 /*abort*/ : 0x00));
1690 			status = IDE_STATUS_DRIVE_READY |
1691 			         ((sense[2] & 0xF) ? IDE_STATUS_ERROR : IDE_STATUS_DRIVE_SEEK_COMPLETE);
1692 			controller->raise_irq();
1693 			allow_writing = true;
1694 		}
1695 		break;
1696 	case 0x42: /* READ SUB-CHANNEL */
1697 		if (common_spinup_response(/*spin up*/ true, /*wait*/ true)) {
1698 			set_sense(0); /* <- nothing wrong */
1699 
1700 			count = 0x02;
1701 			state = IDE_DEV_ATAPI_BUSY;
1702 			status = IDE_STATUS_BUSY;
1703 			PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : 1) /*ms*/,
1704 			             controller->interface_index);
1705 		} else {
1706 			count = 0x03;
1707 			state = IDE_DEV_READY;
1708 			feature = check_cast<uint16_t>(((sense[2] & 0xF) << 4) |
1709 			                               ((sense[2] & 0xF) ? 0x04 /*abort*/ : 0x00));
1710 			status = IDE_STATUS_DRIVE_READY |
1711 			         ((sense[2] & 0xF) ? IDE_STATUS_ERROR : IDE_STATUS_DRIVE_SEEK_COMPLETE);
1712 			controller->raise_irq();
1713 			allow_writing = true;
1714 		}
1715 		break;
1716 	case 0x43: /* READ TOC */
1717 		if (common_spinup_response(/*spin up*/ true, /*wait*/ true)) {
1718 			set_sense(0); /* <- nothing wrong */
1719 
1720 			count = 0x02;
1721 			state = IDE_DEV_ATAPI_BUSY;
1722 			status = IDE_STATUS_BUSY;
1723 			PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : 1) /*ms*/,
1724 			             controller->interface_index);
1725 		} else {
1726 			count = 0x03;
1727 			state = IDE_DEV_READY;
1728 			feature = check_cast<uint16_t>(((sense[2] & 0xF) << 4) |
1729 			                               ((sense[2] & 0xF) ? 0x04 /*abort*/ : 0x00));
1730 			status = IDE_STATUS_DRIVE_READY |
1731 			         ((sense[2] & 0xF) ? IDE_STATUS_ERROR : IDE_STATUS_DRIVE_SEEK_COMPLETE);
1732 			controller->raise_irq();
1733 			allow_writing = true;
1734 		}
1735 		break;
1736 	case 0x45: /* PLAY AUDIO (1) */
1737 	case 0x47: /* PLAY AUDIO MSF */
1738 	case 0x4B: /* PAUSE/RESUME */
1739 		if (common_spinup_response(/*spin up*/ true, /*wait*/ true)) {
1740 			set_sense(0); /* <- nothing wrong */
1741 
1742 			count = 0x02;
1743 			state = IDE_DEV_ATAPI_BUSY;
1744 			status = IDE_STATUS_BUSY;
1745 			PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : 1) /*ms*/,
1746 			             controller->interface_index);
1747 		} else {
1748 			count = 0x03;
1749 			state = IDE_DEV_READY;
1750 			feature = check_cast<uint16_t>(((sense[2] & 0xF) << 4) |
1751 			                               ((sense[2] & 0xF) ? 0x04 /*abort*/ : 0x00));
1752 			status = IDE_STATUS_DRIVE_READY |
1753 			         ((sense[2] & 0xF) ? IDE_STATUS_ERROR : IDE_STATUS_DRIVE_SEEK_COMPLETE);
1754 			controller->raise_irq();
1755 			allow_writing = true;
1756 		}
1757 		break;
1758 	case 0x55:            /* MODE SELECT(10) */
1759 		count = 0x00; /* we will be accepting data */
1760 		state = IDE_DEV_ATAPI_BUSY;
1761 		status = IDE_STATUS_BUSY;
1762 		PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : 1) /*ms*/, controller->interface_index);
1763 		break;
1764 	case 0x5A: /* MODE SENSE(10) */
1765 		count = 0x02;
1766 		state = IDE_DEV_ATAPI_BUSY;
1767 		status = IDE_STATUS_BUSY;
1768 		PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : 1) /*ms*/, controller->interface_index);
1769 		break;
1770 	default:
1771 		/* we don't know the command, immediately return an error */
1772 		LOG_WARNING("IDE: Unknown ATAPI command %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
1773 		        atapi_cmd[0], atapi_cmd[1], atapi_cmd[2], atapi_cmd[3], atapi_cmd[4], atapi_cmd[5],
1774 		        atapi_cmd[6], atapi_cmd[7], atapi_cmd[8], atapi_cmd[9], atapi_cmd[10], atapi_cmd[11]);
1775 
1776 		abort_error();
1777 		count = 0x03; /* no more data (command/data=1, input/output=1) */
1778 		feature = 0xF4;
1779 		controller->raise_irq();
1780 		allow_writing = true;
1781 		break;
1782 	}
1783 }
1784 
data_write(uint32_t v,io_width_t width)1785 void IDEATAPICDROMDevice::data_write(uint32_t v, io_width_t width)
1786 {
1787 	if (state == IDE_DEV_ATAPI_PACKET_COMMAND) {
1788 		if (atapi_cmd_i < atapi_cmd_total)
1789 			atapi_cmd[atapi_cmd_i++] = check_cast<uint8_t>(v & 0xFF);
1790 		if ((width == io_width_t::word || width == io_width_t::dword) && atapi_cmd_i < atapi_cmd_total)
1791 			atapi_cmd[atapi_cmd_i++] = check_cast<uint8_t>(v >> 8) & 0xFF;
1792 		if (width == io_width_t::dword && atapi_cmd_i < atapi_cmd_total) {
1793 			atapi_cmd[atapi_cmd_i++] = check_cast<uint8_t>(v >> 16) & 0xFF;
1794 			atapi_cmd[atapi_cmd_i++] = check_cast<uint8_t>(v >> 24) & 0xFF;
1795 		}
1796 
1797 		if (atapi_cmd_i >= atapi_cmd_total)
1798 			atapi_cmd_completion();
1799 	} else {
1800 		if (state != IDE_DEV_DATA_WRITE) {
1801 			LOG_WARNING("IDE: ATAPI data write when device not in data_write state");
1802 			return;
1803 		}
1804 		if (!(status & IDE_STATUS_DRQ)) {
1805 			LOG_WARNING("IDE: ATAPI data write with drq=0");
1806 			return;
1807 		}
1808 		if ((sector_i + static_cast<uint8_t>(width)) > sector_total) {
1809 			LOG_WARNING("IDE: ATAPI sector already full %lu / %lu", (unsigned long)sector_i,
1810 			        (unsigned long)sector_total);
1811 			return;
1812 		}
1813 
1814 		if (width == io_width_t::dword) {
1815 			host_writed(sector + sector_i, v);
1816 			sector_i += 4;
1817 		} else if (width == io_width_t::word) {
1818 			host_writew(sector + sector_i, check_cast<uint16_t>(v));
1819 			sector_i += 2;
1820 		} else if (width == io_width_t::byte) {
1821 			sector[sector_i++] = check_cast<uint8_t>(v);
1822 		}
1823 
1824 		if (sector_i >= sector_total)
1825 			io_completion();
1826 	}
1827 }
1828 
data_read(io_width_t width)1829 uint32_t IDEATADevice::data_read(io_width_t width)
1830 {
1831 	uint32_t w = ~0u;
1832 
1833 	if (state != IDE_DEV_DATA_READ)
1834 		return 0xFFFFUL;
1835 
1836 	if (!(status & IDE_STATUS_DRQ)) {
1837 		LOG_MSG("IDE: Data read when DRQ=0");
1838 		return 0xFFFFUL;
1839 	}
1840 
1841 	if ((sector_i + static_cast<uint8_t>(width)) > sector_total) {
1842 		LOG_WARNING("IDE: ATA: sector already read %lu / %lu", (unsigned long)sector_i,
1843 		        (unsigned long)sector_total);
1844 		return 0xFFFFUL;
1845 	}
1846 
1847 	if (width == io_width_t::dword) {
1848 		w = host_readd(sector + sector_i);
1849 		sector_i += 4;
1850 	} else if (width == io_width_t::word) {
1851 		w = host_readw(sector + sector_i);
1852 		sector_i += 2;
1853 	}
1854 	/* NTS: Some MS-DOS CD-ROM drivers like OAKCDROM.SYS use byte-wide I/O for the initial identification */
1855 	else if (width == io_width_t::byte) {
1856 		w = sector[sector_i++];
1857 	}
1858 
1859 	if (sector_i >= sector_total)
1860 		io_completion();
1861 
1862 	return w;
1863 }
1864 
data_write(uint32_t v,io_width_t width)1865 void IDEATADevice::data_write(uint32_t v, io_width_t width)
1866 {
1867 	if (state != IDE_DEV_DATA_WRITE) {
1868 		LOG_WARNING("IDE: ATA: data write when device not in data_write state");
1869 		return;
1870 	}
1871 	if (!(status & IDE_STATUS_DRQ)) {
1872 		LOG_WARNING("IDE: ATA: data write with drq=0");
1873 		return;
1874 	}
1875 	if ((sector_i + static_cast<uint8_t>(width)) > sector_total) {
1876 		LOG_WARNING("IDE: ATA: sector already full %lu / %lu", (unsigned long)sector_i,
1877 		        (unsigned long)sector_total);
1878 		return;
1879 	}
1880 
1881 	if (width == io_width_t::dword) {
1882 		host_writed(sector + sector_i, v);
1883 		sector_i += 4;
1884 	} else if (width == io_width_t::word) {
1885 		host_writew(sector + sector_i, check_cast<uint16_t>(v));
1886 		sector_i += 2;
1887 	} else if (width == io_width_t::byte) {
1888 		sector[sector_i++] = check_cast<uint8_t>(v);
1889 	}
1890 
1891 	if (sector_i >= sector_total)
1892 		io_completion();
1893 }
1894 
prepare_read(uint32_t offset,uint32_t size)1895 void IDEATAPICDROMDevice::prepare_read(uint32_t offset, uint32_t size)
1896 {
1897 	/* I/O must be WORD ALIGNED */
1898 	assert((offset & 1) == 0);
1899 	//  assert((size&1) == 0);
1900 
1901 	sector_i = offset;
1902 	sector_total = size;
1903 	assert(sector_i <= sector_total);
1904 	assert(sector_total <= sizeof(sector));
1905 }
1906 
prepare_write(uint32_t offset,uint32_t size)1907 void IDEATAPICDROMDevice::prepare_write(uint32_t offset, uint32_t size)
1908 {
1909 	/* I/O must be WORD ALIGNED */
1910 	assert((offset & 1) == 0);
1911 	//  assert((size&1) == 0);
1912 
1913 	sector_i = offset;
1914 	sector_total = size;
1915 	assert(sector_i <= sector_total);
1916 	assert(sector_total <= sizeof(sector));
1917 }
1918 
prepare_write(uint32_t offset,uint32_t size)1919 void IDEATADevice::prepare_write(uint32_t offset, uint32_t size)
1920 {
1921 	/* I/O must be WORD ALIGNED */
1922 	assert((offset & 1) == 0);
1923 	//  assert((size&1) == 0);
1924 
1925 	sector_i = offset;
1926 	sector_total = size;
1927 	assert(sector_i <= sector_total);
1928 	assert(sector_total <= sizeof(sector));
1929 }
1930 
prepare_read(uint32_t offset,uint32_t size)1931 void IDEATADevice::prepare_read(uint32_t offset, uint32_t size)
1932 {
1933 	/* I/O must be WORD ALIGNED */
1934 	assert((offset & 1) == 0);
1935 	//  assert((size&1) == 0);
1936 
1937 	sector_i = offset;
1938 	sector_total = size;
1939 	assert(sector_i <= sector_total);
1940 	assert(sector_total <= sizeof(sector));
1941 }
1942 
generate_mmc_inquiry()1943 void IDEATAPICDROMDevice::generate_mmc_inquiry()
1944 {
1945 	uint32_t i;
1946 
1947 	/* IN RESPONSE TO ATAPI COMMAND 0x12: INQUIRY */
1948 	std::fill_n(sector, 36, 0);
1949 	sector[0] = (0 << 5) | 5; /* Peripheral qualifier=0   device type=5 (CDROM) */
1950 	sector[1] = 0x80;         /* RMB=1 removable media */
1951 	sector[3] = 0x21;
1952 	sector[4] = 36 - 5; /* additional length */
1953 
1954 	for (i = 0; i < 8 && i < id_mmc_vendor_id.length(); i++)
1955 		sector[i + 8] = (uint8_t)id_mmc_vendor_id[i];
1956 	for (; i < 8; i++)
1957 		sector[i + 8] = ' ';
1958 
1959 	for (i = 0; i < 16 && i < id_mmc_product_id.length(); i++)
1960 		sector[i + 16] = (uint8_t)id_mmc_product_id[i];
1961 	for (; i < 16; i++)
1962 		sector[i + 16] = ' ';
1963 
1964 	for (i = 0; i < 4 && i < id_mmc_product_rev.length(); i++)
1965 		sector[i + 32] = (uint8_t)id_mmc_product_rev[i];
1966 	for (; i < 4; i++)
1967 		sector[i + 32] = ' ';
1968 }
1969 
generate_identify_device()1970 void IDEATAPICDROMDevice::generate_identify_device()
1971 {
1972 	uint8_t csum;
1973 	uint32_t i;
1974 
1975 	/* IN RESPONSE TO IDENTIFY DEVICE (0xA1)
1976 	   GENERATE 512-BYTE REPLY */
1977 	std::fill_n(sector, 512, 0);
1978 
1979 	host_writew(sector + (0 * 2), 0x85C0U); /* ATAPI device, command set #5 (what the fuck does that
1980 	                                           mean?), removable, */
1981 
1982 	for (i = 0; i < 20 && i < id_serial.length(); i++)
1983 		sector[(i ^ 1) + (10 * 2)] = (uint8_t)id_serial[i];
1984 	for (; i < 20; i++)
1985 		sector[(i ^ 1) + (10 * 2)] = ' ';
1986 
1987 	for (i = 0; i < 8 && i < id_firmware_rev.length(); i++)
1988 		sector[(i ^ 1) + (23 * 2)] = (uint8_t)id_firmware_rev[i];
1989 	for (; i < 8; i++)
1990 		sector[(i ^ 1) + (23 * 2)] = ' ';
1991 
1992 	for (i = 0; i < 40 && i < id_model.length(); i++)
1993 		sector[(i ^ 1) + (27 * 2)] = (uint8_t)id_model[i];
1994 	for (; i < 40; i++)
1995 		sector[(i ^ 1) + (27 * 2)] = ' ';
1996 
1997 	host_writew(sector + (49 * 2), 0x0800UL |         /*IORDY supported*/
1998 	                                       0x0200UL | /*must be one*/
1999 	                                       0);
2000 	host_writew(sector + (50 * 2), 0x4000UL);
2001 	host_writew(sector + (51 * 2), 0x00F0UL);
2002 	host_writew(sector + (52 * 2), 0x00F0UL);
2003 	host_writew(sector + (53 * 2), 0x0006UL);
2004 	host_writew(sector + (64 * 2), /* PIO modes supported */
2005 	            0x0003UL);
2006 	host_writew(sector + (67 * 2), /* PIO cycle time */
2007 	            0x0078UL);
2008 	host_writew(sector + (68 * 2), /* PIO cycle time */
2009 	            0x0078UL);
2010 	host_writew(sector + (80 * 2), 0x007E); /* major version number. Here we say we support ATA-1 through ATA-8 */
2011 	host_writew(sector + (81 * 2), 0x0022); /* minor version */
2012 	host_writew(sector + (82 * 2), 0x4008); /* command set: NOP, DEVICE RESET[XXXXX], POWER MANAGEMENT */
2013 	host_writew(sector + (83 * 2), 0x0000); /* command set: LBA48[XXXX] */
2014 	host_writew(sector + (85 * 2), 0x4208); /* commands in 82 enabled */
2015 	host_writew(sector + (86 * 2), 0x0000); /* commands in 83 enabled */
2016 
2017 	/* ATA-8 integrity checksum */
2018 	sector[510] = 0xA5;
2019 	csum = 0;
2020 	for (i = 0; i < 511; i++)
2021 		csum += sector[i];
2022 	sector[511] = 0 - csum;
2023 }
2024 
generate_identify_device()2025 void IDEATADevice::generate_identify_device()
2026 {
2027 	//  imageDisk *disk = getBIOSdisk();
2028 	uint8_t csum;
2029 	uint32_t i;
2030 
2031 	/* IN RESPONSE TO IDENTIFY DEVICE (0xEC)
2032 	   GENERATE 512-BYTE REPLY */
2033 	std::fill_n(sector, 512, 0);
2034 
2035 	/* total disk capacity in sectors */
2036 	uint64_t total = sects;
2037 	total *= cyls;
2038 	total *= heads;
2039 
2040 	uint64_t ptotal = phys_sects;
2041 	ptotal *= phys_cyls;
2042 	ptotal *= phys_heads;
2043 
2044 	host_writew(sector + (0 * 2), 0x0040); /* bit 6: 1=fixed disk */
2045 	host_writew(sector + (1 * 2), check_cast<uint16_t>(phys_cyls));
2046 	host_writew(sector + (3 * 2), check_cast<uint16_t>(phys_heads));
2047 	host_writew(sector + (4 * 2), check_cast<uint16_t>(phys_sects * 512)); /* unformatted bytes per track */
2048 	host_writew(sector + (5 * 2), 512); /* unformatted bytes per sector */
2049 	host_writew(sector + (6 * 2), check_cast<uint16_t>(phys_sects));
2050 
2051 	for (i = 0; i < 20 && i < id_serial.length(); i++)
2052 		sector[(i ^ 1) + (10 * 2)] = (uint8_t)id_serial[i];
2053 	for (; i < 20; i++)
2054 		sector[(i ^ 1) + (10 * 2)] = ' ';
2055 
2056 	host_writew(sector + (20 * 2), 1); /* ATA-1: single-ported single sector buffer */
2057 	host_writew(sector + (21 * 2), 4); /* ATA-1: ECC bytes on read/write long */
2058 
2059 	for (i = 0; i < 8 && i < id_firmware_rev.length(); i++)
2060 		sector[(i ^ 1) + (23 * 2)] = (uint8_t)id_firmware_rev[i];
2061 	for (; i < 8; i++)
2062 		sector[(i ^ 1) + (23 * 2)] = ' ';
2063 
2064 	for (i = 0; i < 40 && i < id_model.length(); i++)
2065 		sector[(i ^ 1) + (27 * 2)] = (uint8_t)id_model[i];
2066 	for (; i < 40; i++)
2067 		sector[(i ^ 1) + (27 * 2)] = ' ';
2068 
2069 	if (multiple_sector_max != 0)
2070 		host_writew(sector + (47 * 2),
2071 		            check_cast<uint16_t>(0x80 | multiple_sector_max)); /* <- READ/WRITE MULTIPLE MAX SECTORS */
2072 
2073 	host_writew(sector + (48 * 2), 0x0000); /* :0  0=we do not support doubleword (32-bit) PIO */
2074 	host_writew(sector + (49 * 2), 0x0A00); /* :13 0=Standby timer values managed by device */
2075 	                                        /* :11 1=IORDY supported */
2076 	                                        /* :10 0=IORDY not disabled */
2077 	                                        /* :9  1=LBA supported */
2078 	                                        /* :8  0=DMA not supported */
2079 	host_writew(sector + (50 * 2), 0x4000); /* TBD: ??? */
2080 	host_writew(sector + (51 * 2), 0x00F0); /* PIO data transfer cycle timing mode */
2081 	host_writew(sector + (52 * 2), 0x00F0); /* DMA data transfer cycle timing mode */
2082 	host_writew(sector + (53 * 2), 0x0007); /* :2  1=the fields in word 88 are valid */
2083 	                                        /* :1  1=the fields in word (70:64) are valid */
2084 	                                        /* :0  1= ??? */
2085 	host_writew(sector + (54 * 2), check_cast<uint16_t>(cyls));  /* current cylinders */
2086 	host_writew(sector + (55 * 2), check_cast<uint16_t>(heads)); /* current heads */
2087 	host_writew(sector + (56 * 2), check_cast<uint16_t>(sects)); /* current sectors per track */
2088 	host_writed(sector + (57 * 2), check_cast<uint16_t>(total)); /* current capacity in sectors */
2089 
2090 	if (multiple_sector_count != 0)
2091 		host_writew(sector + (59 * 2),
2092 		            check_cast<uint16_t>(0x0100 | multiple_sector_count)); /* :8  multiple sector
2093 		                                                                      setting is valid */
2094 	/* 7:0 current setting for number of log. sectors per DRQ of READ/WRITE MULTIPLE */
2095 
2096 	host_writed(sector + (60 * 2), check_cast<uint16_t>(ptotal)); /* total user addressable sectors (LBA) */
2097 	host_writew(sector + (62 * 2), 0x0000);                       /* TBD: ??? */
2098 	host_writew(sector + (63 * 2), 0x0000); /* :10 0=Multiword DMA mode 2 not selected */
2099 	                                        /* TBD: Basically, we don't do DMA. Fill out this comment */
2100 	host_writew(sector + (64 * 2), 0x0003); /* 7:0 PIO modes supported (TBD: ???) */
2101 	host_writew(sector + (65 * 2), 0x0000); /* TBD: ??? */
2102 	host_writew(sector + (66 * 2), 0x0000); /* TBD: ??? */
2103 	host_writew(sector + (67 * 2), 0x0078); /* TBD: ??? */
2104 	host_writew(sector + (68 * 2), 0x0078); /* TBD: ??? */
2105 	host_writew(sector + (80 * 2), 0x007E); /* major version number. Here we say we support ATA-1 through ATA-8 */
2106 	host_writew(sector + (81 * 2), 0x0022); /* minor version */
2107 	host_writew(sector + (82 * 2), 0x4208); /* command set: NOP, DEVICE RESET[XXXXX], POWER MANAGEMENT */
2108 	host_writew(sector + (83 * 2), 0x4000); /* command set: LBA48[XXXX] */
2109 	host_writew(sector + (84 * 2), 0x4000); /* TBD: ??? */
2110 	host_writew(sector + (85 * 2), 0x4208); /* commands in 82 enabled */
2111 	host_writew(sector + (86 * 2), 0x4000); /* commands in 83 enabled */
2112 	host_writew(sector + (87 * 2), 0x4000); /* TBD: ??? */
2113 	host_writew(sector + (88 * 2), 0x0000); /* TBD: ??? */
2114 	host_writew(sector + (93 * 3), 0x0000); /* TBD: ??? */
2115 
2116 	/* ATA-8 integrity checksum */
2117 	sector[510] = 0xA5;
2118 	csum = 0;
2119 	for (i = 0; i < 511; i++)
2120 		csum += sector[i];
2121 	sector[511] = 0 - csum;
2122 }
2123 
IDEATADevice(IDEController * c,uint8_t disk_index)2124 IDEATADevice::IDEATADevice(IDEController *c, uint8_t disk_index)
2125         : IDEDevice(c, IDE_TYPE_HDD),
2126           bios_disk_index(disk_index)
2127 {}
2128 
~IDEATADevice()2129 IDEATADevice::~IDEATADevice()
2130 {}
2131 
getBIOSdisk()2132 std::shared_ptr<imageDisk> IDEATADevice::getBIOSdisk()
2133 {
2134 	if (bios_disk_index >= (2 + MAX_HDD_IMAGES))
2135 		return nullptr;
2136 	return imageDiskList[bios_disk_index];
2137 }
2138 
getMSCDEXDrive()2139 CDROM_Interface *IDEATAPICDROMDevice::getMSCDEXDrive()
2140 {
2141 	CDROM_Interface *cdrom = nullptr;
2142 
2143 	if (!GetMSCDEXDrive(drive_index, &cdrom))
2144 		return nullptr;
2145 
2146 	return cdrom;
2147 }
2148 
update_from_cdrom()2149 void IDEATAPICDROMDevice::update_from_cdrom()
2150 {
2151 	CDROM_Interface *cdrom = getMSCDEXDrive();
2152 	if (cdrom == nullptr) {
2153 		LOG_WARNING("IDE: IDE update from CD-ROM failed, disk not available");
2154 		return;
2155 	}
2156 }
2157 
update_from_biosdisk()2158 void IDEATADevice::update_from_biosdisk()
2159 {
2160 	std::shared_ptr<imageDisk> dsk = getBIOSdisk();
2161 	if (dsk == nullptr) {
2162 		LOG_WARNING("IDE: IDE update from BIOS disk failed, disk not available");
2163 		return;
2164 	}
2165 
2166 	headshr = 0;
2167 	geo_translate = false;
2168 	cyls = dsk->cylinders;
2169 	heads = dsk->heads;
2170 	sects = dsk->sectors;
2171 
2172 	/* One additional correction: The disk image is probably using BIOS-style geometry
2173 	   translation (such as C/H/S 1024/64/63) which is impossible given that the IDE
2174 	   standard only allows up to 16 heads. So we have to translate the geometry. */
2175 	while (heads > 16 && (heads & 1) == 0) {
2176 		cyls <<= 1U;
2177 		heads >>= 1U;
2178 		headshr++;
2179 	}
2180 
2181 	/* If we can't divide the heads down, then pick a LBA-like mapping that is good enough.
2182 	 * Note that if what we pick does not evenly map to the INT 13h geometry, and the partition
2183 	 * contained within is not an LBA type FAT16/FAT32 partition, then Windows 95's IDE driver
2184 	 * will ignore this device and fall back to using INT 13h. For user convenience we will
2185 	 * print a warning to reminder the user of exactly that. */
2186 	if (heads > 16) {
2187 		geo_translate = true;
2188 
2189 		uint64_t tmp = heads;
2190 		tmp *= cyls;
2191 		tmp *= sects;
2192 
2193 		sects = 63;
2194 		heads = 16;
2195 		cyls = static_cast<uint32_t>((tmp + ((63 * 16) - 1)) / (63 * 16));
2196 		LOG_WARNING("IDE: Unable to reduce heads to 16 and below");
2197 		LOG_MSG("    If at all possible, please consider using INT 13h geometry with a head");
2198 		LOG_MSG("    count that is easier to map to the BIOS, like 240 heads or 128 heads/track.");
2199 		LOG_MSG("    Some OSes, such as Windows 95, will not enable their 32-bit IDE driver if");
2200 		LOG_MSG("    a clean mapping does not exist between IDE and BIOS geometry.");
2201 		LOG_MSG("    Mapping BIOS DISK C/H/S %u/%u/%u as IDE %u/%u/%u (non-straightforward mapping)",
2202 		        dsk->cylinders, dsk->heads, dsk->sectors, cyls, heads, sects);
2203 	} else {
2204 		LOG_MSG("IDE: Mapping BIOS DISK C/H/S %u/%u/%u as IDE %u/%u/%u", dsk->cylinders, dsk->heads,
2205 		        dsk->sectors, cyls, heads, sects);
2206 	}
2207 
2208 	phys_heads = heads;
2209 	phys_sects = sects;
2210 	phys_cyls = cyls;
2211 }
2212 
2213 // Get an existing IDE controller, or create a new one if it doesn't exist
get_or_create_controller(const int8_t i)2214 IDEController *get_or_create_controller(const int8_t i)
2215 {
2216 	// Hold the controllers for the lifetime of the program
2217 	static std::vector<std::unique_ptr<IDEController>> ide_controllers = {};
2218 
2219 	// Note that all checks are asserts because calls to this should be
2220 	// programmatically managed (and not come from user data).
2221 
2222 	// Is the requested controller out of bounds?
2223 	assert(i >= 0 && i < MAX_IDE_CONTROLLERS);
2224 	const auto index = static_cast<uint8_t>(i);
2225 
2226 	// Does the requested controller already exist?
2227 	if (idecontroller.at(index)) {
2228 		return idecontroller[index];
2229 	}
2230 
2231 	// Create a new controller
2232 	assert(idecontroller.at(index) == nullptr); // consistency check
2233 	assert(index == ide_controllers.size());    // index should be the next
2234 	                                            // available slot
2235 
2236 	ide_controllers.emplace_back(std::make_unique<IDEController>(index, 0, 0, 0));
2237 	assert(idecontroller.at(index) != nullptr); // consistency check
2238 	return idecontroller[index];
2239 }
2240 
IDE_Get_Next_Cable_Slot(int8_t & index,bool & slave)2241 void IDE_Get_Next_Cable_Slot(int8_t &index, bool &slave)
2242 {
2243 	index = -1;
2244 	slave = false;
2245 	for (int8_t i = 0; i < MAX_IDE_CONTROLLERS; ++i) {
2246 		const auto c = get_or_create_controller(i);
2247 		assert(c);
2248 
2249 		// If both devices are populated, then the controller is already used (so we can't use it)
2250 		if (c->device[0] && c->device[1]) {
2251 			continue;
2252 		}
2253 		if (!c->device[0]) {
2254 			slave = false;
2255 			index = i;
2256 			break;
2257 		}
2258 		if (!c->device[1]) {
2259 			slave = true;
2260 			index = i;
2261 			break;
2262 		}
2263 	}
2264 }
2265 
2266 /* drive_index = drive letter 0...A to 25...Z */
IDE_ATAPI_MediaChangeNotify(uint8_t requested_drive_index)2267 void IDE_ATAPI_MediaChangeNotify(uint8_t requested_drive_index)
2268 {
2269 	for (uint32_t ide = 0; ide < MAX_IDE_CONTROLLERS; ide++) {
2270 		IDEController *c = idecontroller[ide];
2271 		if (c == nullptr)
2272 			continue;
2273 		for (uint32_t ms = 0; ms < 2; ms++) {
2274 			IDEDevice *dev = c->device[ms];
2275 			if (dev == nullptr)
2276 				continue;
2277 			if (dev->type == IDE_TYPE_CDROM) {
2278 				IDEATAPICDROMDevice *atapi = (IDEATAPICDROMDevice *)dev;
2279 				if (requested_drive_index == atapi->drive_index) {
2280 					LOG_MSG("IDE: ATAPI acknowledge media change for drive %c",
2281 					        requested_drive_index + 'A');
2282 					atapi->has_changed = true;
2283 					atapi->loading_mode = LOAD_INSERT_CD;
2284 					PIC_RemoveSpecificEvents(IDE_ATAPI_SpinDown, c->interface_index);
2285 					PIC_RemoveSpecificEvents(IDE_ATAPI_SpinUpComplete, c->interface_index);
2286 					PIC_RemoveSpecificEvents(IDE_ATAPI_CDInsertion, c->interface_index);
2287 					PIC_AddEvent(IDE_ATAPI_CDInsertion, atapi->cd_insertion_time /*ms*/,
2288 					             c->interface_index);
2289 				}
2290 			}
2291 		}
2292 	}
2293 }
2294 
2295 /* drive_index = drive letter 0...A to 25...Z */
IDE_CDROM_Attach(int8_t index,bool slave,const int8_t requested_drive_index)2296 void IDE_CDROM_Attach(int8_t index, bool slave, const int8_t requested_drive_index)
2297 {
2298 	if (index < 0 || index >= MAX_IDE_CONTROLLERS)
2299 		return;
2300 
2301 	// Check if the requested drive index is valid
2302 	assert(requested_drive_index >= 0 && requested_drive_index < DOS_DRIVES);
2303 	const auto drive_index = static_cast<uint8_t>(requested_drive_index);
2304 
2305 	auto c = get_or_create_controller(index);
2306 	if (c == nullptr)
2307 		return;
2308 
2309 	if (c->device[slave ? 1 : 0] != nullptr) {
2310 		LOG_WARNING("IDE: %s controller slot %s is already taken", get_controller_name(index), get_cable_slot_name(slave));
2311 		return;
2312 	}
2313 
2314 	if (!GetMSCDEXDrive(drive_index, nullptr)) {
2315 		LOG_WARNING("IDE: Asked to attach CD-ROM that does not exist");
2316 		return;
2317 	}
2318 
2319 	auto dev = new IDEATAPICDROMDevice(c, drive_index);
2320 	dev->update_from_cdrom();
2321 	c->device[slave ? 1 : 0] = (IDEDevice *)dev;
2322 
2323     LOG_MSG("Attached ATAPI CD-ROM on %s IDE controller's %s cable slot",  get_controller_name(index), get_cable_slot_name(slave));
2324 }
2325 
2326 /* drive_index = drive letter 0...A to 25...Z */
IDE_CDROM_Detach(const int8_t requested_drive_index)2327 void IDE_CDROM_Detach(const int8_t requested_drive_index)
2328 {
2329 	// Check if the requested drive index is valid
2330 	assert(requested_drive_index >= 0 && requested_drive_index < DOS_DRIVES);
2331 	const auto drive_index = static_cast<uint8_t>(requested_drive_index);
2332 
2333 	for (uint8_t index = 0; index < MAX_IDE_CONTROLLERS; index++) {
2334 		IDEController *c = idecontroller[index];
2335 		if (c)
2336 			for (int slave = 0; slave < 2; slave++) {
2337 				IDEATAPICDROMDevice *dev;
2338 				dev = dynamic_cast<IDEATAPICDROMDevice *>(c->device[slave]);
2339 				if (dev && dev->drive_index == drive_index) {
2340 					delete dev;
2341 					c->device[slave] = nullptr;
2342 				}
2343 			}
2344 	}
2345 }
2346 
IDE_CDROM_Detach_Ret(int8_t & indexret,bool & slaveret,int8_t drive_index)2347 void IDE_CDROM_Detach_Ret(int8_t &indexret,bool &slaveret,int8_t drive_index) {
2348     indexret = -1;
2349     for (uint8_t index = 0; index < MAX_IDE_CONTROLLERS; index++) {
2350         IDEController *c = idecontroller[index];
2351         if (c)
2352         for (int slave = 0; slave < 2; slave++) {
2353             IDEATAPICDROMDevice *dev;
2354             dev = dynamic_cast<IDEATAPICDROMDevice*>(c->device[slave]);
2355             if (dev && dev->drive_index == drive_index) {
2356                 delete dev;
2357                 c->device[slave] = nullptr;
2358                 slaveret = slave;
2359                 indexret = check_cast<int8_t>(index);
2360             }
2361         }
2362     }
2363 }
2364 
IDE_CDROM_DetachAll()2365 void IDE_CDROM_DetachAll()
2366 {
2367 	for (uint8_t index = 0; index < MAX_IDE_CONTROLLERS; index++) {
2368 		IDEController *c = idecontroller[index];
2369 		if (c)
2370 			for (int slave = 0; slave < 2; slave++) {
2371 				IDEATAPICDROMDevice *dev;
2372 				dev = dynamic_cast<IDEATAPICDROMDevice *>(c->device[slave]);
2373 				if (dev) {
2374 					delete dev;
2375 					c->device[slave] = nullptr;
2376 				}
2377 			}
2378 	}
2379 }
2380 
2381 /* bios_disk_index = index into BIOS INT 13h disk array: imageDisk *imageDiskList[MAX_DISK_IMAGES]; */
IDE_Hard_Disk_Attach(int8_t index,bool slave,uint8_t bios_disk_index)2382 void IDE_Hard_Disk_Attach(int8_t index,
2383                           bool slave,
2384                           uint8_t bios_disk_index /*not INT13h, the index into DOSBox's BIOS drive emulation*/)
2385 {
2386 	IDEController *c;
2387 	IDEATADevice *dev;
2388 
2389 	if (index < 0 || index >= MAX_IDE_CONTROLLERS)
2390 		return;
2391 	c = idecontroller[static_cast<uint8_t>(index)];
2392 	if (c == nullptr)
2393 		return;
2394 
2395 	if (c->device[slave ? 1 : 0] != nullptr) {
2396 		LOG_WARNING("IDE: Controller %u %s already taken", index, slave ? "slave" : "master");
2397 		return;
2398 	}
2399 
2400 	if (imageDiskList[bios_disk_index] == nullptr) {
2401 		LOG_WARNING("IDE: Asked to attach bios disk that does not exist");
2402 		return;
2403 	}
2404 
2405 	dev = new IDEATADevice(c, bios_disk_index);
2406 	dev->update_from_biosdisk();
2407 	c->device[slave ? 1 : 0] = (IDEDevice *)dev;
2408 }
2409 
2410 /* bios_disk_index = index into BIOS INT 13h disk array: imageDisk *imageDiskList[MAX_DISK_IMAGES]; */
IDE_Hard_Disk_Detach(uint8_t bios_disk_index)2411 void IDE_Hard_Disk_Detach(uint8_t bios_disk_index)
2412 {
2413 	for (uint8_t index = 0; index < MAX_IDE_CONTROLLERS; index++) {
2414 		IDEController *c = idecontroller[index];
2415 		if (c)
2416 			for (int slave = 0; slave < 2; slave++) {
2417 				IDEATADevice *dev;
2418 				dev = dynamic_cast<IDEATADevice *>(c->device[slave]);
2419 				if (dev && dev->bios_disk_index == bios_disk_index) {
2420 					delete dev;
2421 					c->device[slave] = nullptr;
2422 				}
2423 			}
2424 	}
2425 }
2426 
2427 char idepos[4];
GetIDEPosition(uint8_t bios_disk_index)2428 char *GetIDEPosition(uint8_t bios_disk_index)
2429 {
2430 	for (uint8_t index = 0; index < MAX_IDE_CONTROLLERS; index++) {
2431 		IDEController *c = GetIDEController(index);
2432 		if (c)
2433 			for (int slave = 0; slave < 2; slave++) {
2434 				IDEATADevice *dev = dynamic_cast<IDEATADevice *>(c->device[slave]);
2435 				if (dev && dev->bios_disk_index == bios_disk_index) {
2436 					safe_sprintf(idepos, "%d%c", index + 1, slave ? 's' : 'm');
2437 					return idepos;
2438 				}
2439 			}
2440 	}
2441 	return (char *)("");
2442 }
2443 
GetIDEInfo()2444 std::string GetIDEInfo()
2445 {
2446 	std::string info = {};
2447 	for (uint8_t index = 0; index < MAX_IDE_CONTROLLERS; index++) {
2448 		IDEController *c = GetIDEController(index);
2449 		if (c)
2450 			for (int slave = 0; slave < 2; slave++) {
2451 				info += "IDE position " + std::to_string(index + 1) + (slave ? 's' : 'm') + ": ";
2452 				if (dynamic_cast<IDEATADevice *>(c->device[slave]))
2453 					info += "disk image";
2454 				else if (dynamic_cast<IDEATAPICDROMDevice *>(c->device[slave]))
2455 					info += "CD image";
2456 				else
2457 					info += "none";
2458 			}
2459 	}
2460 	return info;
2461 }
2462 
GetIDEController(uint32_t idx)2463 static IDEController *GetIDEController(uint32_t idx)
2464 {
2465 	if (idx >= MAX_IDE_CONTROLLERS)
2466 		return nullptr;
2467 	return idecontroller[idx];
2468 }
2469 
GetIDESelectedDevice(IDEController * ide)2470 static IDEDevice *GetIDESelectedDevice(IDEController *ide)
2471 {
2472 	if (ide == nullptr)
2473 		return nullptr;
2474 	return ide->device[ide->select];
2475 }
2476 
IDE_CPU_Is_Vm86()2477 static bool IDE_CPU_Is_Vm86()
2478 {
2479 	return (cpu.pmode && ((GETFLAG_IOPL < cpu.cpl) || GETFLAG(VM)));
2480 }
2481 
2482 static void ide_baseio_w(io_port_t port, io_val_t val, io_width_t width);
2483 
IDE_SelfIO_In(IDEController *,io_port_t port,io_width_t width)2484 static uint32_t IDE_SelfIO_In(IDEController * /* ide */, io_port_t port, io_width_t width)
2485 {
2486 	return ide_baseio_r(port, width);
2487 }
2488 
IDE_SelfIO_Out(IDEController *,io_port_t port,io_val_t val,io_width_t width)2489 static void IDE_SelfIO_Out(IDEController * /* ide */, io_port_t port, io_val_t val, io_width_t width)
2490 {
2491 	ide_baseio_w(port, val, width);
2492 }
2493 
2494 /* INT 13h extensions */
IDE_EmuINT13DiskReadByBIOS_LBA(uint8_t disk,uint64_t lba)2495 void IDE_EmuINT13DiskReadByBIOS_LBA(uint8_t disk, uint64_t lba)
2496 {
2497 	IDEController *ide;
2498 	IDEDevice *dev;
2499 	uint8_t idx, ms;
2500 
2501 	if (disk < 0x80)
2502 		return;
2503 	if (lba >= (1ULL << 28ULL))
2504 		return; /* this code does not support LBA48 */
2505 
2506 	for (idx = 0; idx < MAX_IDE_CONTROLLERS; idx++) {
2507 		ide = GetIDEController(idx);
2508 		if (ide == nullptr)
2509 			continue;
2510 		if (!ide->int13fakeio && !ide->int13fakev86io)
2511 			continue;
2512 
2513 		/* TBD: Print a warning message if the IDE controller is busy (debug/warning message) */
2514 
2515 		/* TBD: Force IDE state to readiness, abort command, etc. */
2516 
2517 		/* for master/slave device... */
2518 		for (ms = 0; ms < 2; ms++) {
2519 			dev = ide->device[ms];
2520 			if (dev == nullptr)
2521 				continue;
2522 
2523 			/* TBD: Print a warning message if the IDE device is busy or in the middle of a command */
2524 
2525 			/* TBD: Forcibly device-reset the IDE device */
2526 
2527 			/* Issue I/O to ourself to select drive */
2528 			dev->faked_command = true;
2529 			IDE_SelfIO_In(ide, ide->base_io + 7u, io_width_t::byte);
2530 			IDE_SelfIO_Out(ide, ide->base_io + 6u, static_cast<uint16_t>(ms << 4u), io_width_t::byte);
2531 			dev->faked_command = false;
2532 
2533 			if (dev->type == IDE_TYPE_HDD) {
2534 				IDEATADevice *ata = (IDEATADevice *)dev;
2535 				//              static bool int13_fix_wrap_warned = false;
2536 				bool vm86 = IDE_CPU_Is_Vm86();
2537 
2538 				if ((ata->bios_disk_index - 2) == (disk - 0x80)) {
2539 					//                  imageDisk *dsk = ata->getBIOSdisk();
2540 
2541 					if (ide->int13fakev86io && vm86) {
2542 						dev->faked_command = true;
2543 
2544 						/* we MUST clear interrupts.
2545 						 * leaving them enabled causes Win95 (or DOSBox?) to
2546 						 * recursively pagefault and DOSBox to crash. In any case it
2547 						 * seems Win95's IDE driver assumes the BIOS INT 13h code will
2548 						 * do this since it's customary for the BIOS to do it at some
2549 						 * point, usually just before reading the sector data. */
2550 						CPU_CLI();
2551 
2552 						/* We're in virtual 8086 mode and we're asked to fake I/O as if
2553 						 * executing a BIOS subroutine. Some OS's like Windows 95 rely on
2554 						 * executing INT 13h in virtual 8086 mode: on startup, the ESDI
2555 						 * driver traps IDE ports and then executes INT 13h to watch what
2556 						 * I/O ports it uses. It then uses that information to decide
2557 						 * what IDE hard disk and controller corresponds to what DOS
2558 						 * drive. So to get 32-bit disk access to work in Windows 95,
2559 						 * we have to put on a good show to convince Windows 95 we're
2560 						 * a legitimate BIOS INT 13h call doing it's job. */
2561 						IDE_SelfIO_In(ide, ide->base_io + 7u,
2562 						              io_width_t::byte); /* dum de dum reading status */
2563 						IDE_SelfIO_Out(ide, ide->base_io + 6u,
2564 						               static_cast<uint16_t>(ms << 4u) + 0xE0u +
2565 						                       check_cast<uint32_t>(lba >> 24u),
2566 						               io_width_t::byte); /* drive and head */
2567 						IDE_SelfIO_In(ide, ide->base_io + 7u,
2568 						              io_width_t::byte); /* dum de dum reading status */
2569 						IDE_SelfIO_Out(ide, ide->base_io + 2u, 0x01,
2570 						               io_width_t::byte); /* sector count */
2571 						IDE_SelfIO_Out(ide, ide->base_io + 3u, lba & 0xFF,
2572 						               io_width_t::byte); /* sector number */
2573 						IDE_SelfIO_Out(ide, ide->base_io + 4u, (lba >> 8u) & 0xFF,
2574 						               io_width_t::byte); /* cylinder lo */
2575 						IDE_SelfIO_Out(ide, ide->base_io + 5u, (lba >> 16u) & 0xFF,
2576 						               io_width_t::byte); /* cylinder hi */
2577 						IDE_SelfIO_Out(ide, ide->base_io + 6u,
2578 						               static_cast<uint16_t>(ms << 4u) + 0xE0 +
2579 						                       check_cast<uint32_t>(lba >> 24u),
2580 						               io_width_t::byte); /* drive and head */
2581 						IDE_SelfIO_In(ide, ide->base_io + 7u,
2582 						              io_width_t::byte); /* dum de dum reading status */
2583 						IDE_SelfIO_Out(ide, ide->base_io + 7u, 0x20,
2584 						               io_width_t::byte); /* issue READ */
2585 
2586 						do {
2587 							/* TBD: Timeout needed */
2588 							uint32_t i = IDE_SelfIO_In(ide, ide->alt_io,
2589 							                           io_width_t::byte);
2590 							if ((i & 0x80) == 0)
2591 								break;
2592 						} while (1);
2593 						IDE_SelfIO_In(ide, ide->base_io + 7u, io_width_t::byte);
2594 
2595 						/* for brevity assume it worked. we're here to bullshit
2596 						 * Windows 95 after all */
2597 						for (uint32_t i = 0; i < 256; i++)
2598 							IDE_SelfIO_In(ide, ide->base_io + 0u,
2599 							              io_width_t::word); /* 16-bit IDE data read */
2600 
2601 						/* one more */
2602 						IDE_SelfIO_In(ide, ide->base_io + 7u,
2603 						              io_width_t::byte); /* dum de dum reading status */
2604 
2605 						/* assume IRQ happened and clear it */
2606 						if (ide->IRQ >= 8)
2607 							IDE_SelfIO_Out(ide, 0xA0, 0x60u + (uint32_t)ide->IRQ - 8u,
2608 							               io_width_t::byte); /* specific EOI */
2609 						else
2610 							IDE_SelfIO_Out(ide, 0x20, 0x60u + (uint32_t)ide->IRQ,
2611 							               io_width_t::byte); /* specific EOI */
2612 
2613 						ata->abort_normal();
2614 						dev->faked_command = false;
2615 					} else {
2616 						/* hack IDE state as if a BIOS executing IDE disk routines.
2617 						 * This is required if we want IDE emulation to work with
2618 						 * Windows 3.11 Windows for Workgroups 32-bit disk access
2619 						 * (WDCTRL), because the driver "tests" the controller by
2620 						 * issuing INT 13h calls then reading back IDE registers to
2621 						 * see if they match the C/H/S it requested */
2622 						dev->feature = 0x00; /* clear error (WDCTRL test phase 5/C/13) */
2623 						dev->count = 0x00; /* clear sector count (WDCTRL test phase 6/D/14) */
2624 						dev->lba[0] = lba & 0xFF; /* leave sector number the same
2625 						                             (WDCTRL test phase 7/E/15) */
2626 						dev->lba[1] = (lba >> 8u) & 0xFF;  /* leave cylinder the same
2627 						                                      (WDCTRL test phase  8/F/16)  */
2628 						dev->lba[2] = (lba >> 16u) & 0xFF; /* ...ditto */
2629 						dev->drivehead = check_cast<uint8_t>(
2630 						        0xE0u | static_cast<uint16_t>(ms << 4u) |
2631 						        (lba >> 24u)); /* drive head and master/slave (WDCTRL
2632 						                          test phase 9/10/17) */
2633 						ide->drivehead = dev->drivehead;
2634 						dev->status = IDE_STATUS_DRIVE_READY |
2635 						              IDE_STATUS_DRIVE_SEEK_COMPLETE; /* status (WDCTRL
2636 						                                                 test phase A/11/18) */
2637 						dev->allow_writing = true;
2638 						static bool vm86_warned = false;
2639 
2640 						if (vm86 && !vm86_warned) {
2641 							LOG_WARNING("IDE: INT 13h extensions read from virtual 8086 mode.");
2642 							LOG_WARNING("     If using Windows 95 OSR2, please set int13fakev86io=true for proper 32-bit disk access");
2643 							vm86_warned = true;
2644 						}
2645 					}
2646 
2647 					/* break out, we're done */
2648 					idx = MAX_IDE_CONTROLLERS;
2649 					break;
2650 				}
2651 			}
2652 		}
2653 	}
2654 }
2655 
2656 /* this is called after INT 13h AH=0x02 READ DISK to change IDE state to simulate the BIOS in action.
2657  * this is needed for old "32-bit disk drivers" like WDCTRL in Windows 3.11 Windows for Workgroups,
2658  * which issues INT 13h to read-test and then reads IDE registers to see if they match expectations */
IDE_EmuINT13DiskReadByBIOS(uint8_t disk,uint32_t cyl,uint32_t head,unsigned sect)2659 void IDE_EmuINT13DiskReadByBIOS(uint8_t disk, uint32_t cyl, uint32_t head, unsigned sect)
2660 {
2661 	IDEController *ide;
2662 	IDEDevice *dev;
2663 	uint8_t idx, ms;
2664 
2665 	if (disk < 0x80)
2666 		return;
2667 
2668 	for (idx = 0; idx < MAX_IDE_CONTROLLERS; idx++) {
2669 		ide = GetIDEController(idx);
2670 		if (ide == nullptr)
2671 			continue;
2672 		if (!ide->int13fakeio && !ide->int13fakev86io)
2673 			continue;
2674 
2675 		/* TBD: Print a warning message if the IDE controller is busy (debug/warning message) */
2676 
2677 		/* TBD: Force IDE state to readiness, abort command, etc. */
2678 
2679 		/* for master/slave device... */
2680 		for (ms = 0; ms < 2; ms++) {
2681 			dev = ide->device[ms];
2682 			if (dev == nullptr)
2683 				continue;
2684 
2685 			/* TBD: Print a warning message if the IDE device is busy or in the middle of a command */
2686 
2687 			/* TBD: Forcibly device-reset the IDE device */
2688 
2689 			/* Issue I/O to ourself to select drive */
2690 			dev->faked_command = true;
2691 			IDE_SelfIO_In(ide, ide->base_io + 7u, io_width_t::byte);
2692 			IDE_SelfIO_Out(ide, ide->base_io + 6u, static_cast<uint16_t>(ms << 4u), io_width_t::byte);
2693 			dev->faked_command = false;
2694 
2695 			if (dev->type == IDE_TYPE_HDD) {
2696 				IDEATADevice *ata = (IDEATADevice *)dev;
2697 				bool vm86 = IDE_CPU_Is_Vm86();
2698 
2699 				if ((ata->bios_disk_index - 2) == (disk - 0x80)) {
2700 					std::shared_ptr<imageDisk> dsk = ata->getBIOSdisk();
2701 
2702 					/* print warning if INT 13h is being called after the OS changed
2703 					 * logical geometry */
2704 					if (ata->sects != ata->phys_sects || ata->heads != ata->phys_heads ||
2705 					    ata->cyls != ata->phys_cyls)
2706 						LOG_WARNING("IDE: INT 13h I/O issued on drive attached to IDE emulation with changed logical geometry!");
2707 
2708 					/* HACK: src/ints/bios_disk.cpp implementation doesn't correctly
2709 					 *       wrap sector numbers across tracks. it fullfills the read
2710 					 *       by counting sectors and reading from C,H,S+i which means
2711 					 *       that if the OS assumes the ability to read across track
2712 					 *       boundaries (as Windows 95 does) we will get invalid
2713 					 *       sector numbers, which in turn fouls up our emulation.
2714 					 *
2715 					 *       Windows 95 OSR2 for example, will happily ask for 63
2716 					 *       sectors starting at C/H/S 30/9/42 without regard for
2717 					 *       track boundaries. */
2718 					if (sect > dsk->sectors) {
2719 #if 0 /* this warning is pointless */
2720                         static bool int13_fix_wrap_warned = false;
2721                         if (!int13_fix_wrap_warned) {
2722                             LOG_WARNING("IDE: INT 13h implementation warning: we were given over-large sector number.");
2723                             LOG_WARNING("     This is normally the fault of DOSBox INT 13h emulation that counts sectors");
2724                             LOG_WARNING("     Without consideration of track boundaries");
2725                             int13_fix_wrap_warned = true;
2726                         }
2727 #endif
2728 
2729 						do {
2730 							sect -= dsk->sectors;
2731 							if ((++head) >= dsk->heads) {
2732 								head -= dsk->heads;
2733 								cyl++;
2734 							}
2735 						} while (sect > dsk->sectors);
2736 					}
2737 
2738 					/* translate BIOS INT 13h geometry to IDE geometry */
2739 					if (ata->headshr != 0 || ata->geo_translate) {
2740 						unsigned long lba;
2741 
2742 						if (dsk == nullptr)
2743 							return;
2744 						lba = (head * dsk->sectors) +
2745 						      (cyl * dsk->sectors * dsk->heads) + sect - 1;
2746 						sect = (lba % ata->sects) + 1;
2747 						head = (lba / ata->sects) % ata->heads;
2748 						cyl = check_cast<uint32_t>(lba / ata->sects / ata->heads);
2749 					}
2750 
2751 					if (ide->int13fakev86io && vm86) {
2752 						dev->faked_command = true;
2753 
2754 						/* we MUST clear interrupts.
2755 						 * leaving them enabled causes Win95 (or DOSBox?) to
2756 						 * recursively pagefault and DOSBox to crash. In any case it
2757 						 * seems Win95's IDE driver assumes the BIOS INT 13h code will
2758 						 * do this since it's customary for the BIOS to do it at some
2759 						 * point, usually just before reading the sector data. */
2760 						CPU_CLI();
2761 
2762 						/* We're in virtual 8086 mode and we're asked to fake I/O as if
2763 						 * executing a BIOS subroutine. Some OS's like Windows 95 rely on
2764 						 * executing INT 13h in virtual 8086 mode: on startup, the ESDI
2765 						 * driver traps IDE ports and then executes INT 13h to watch what
2766 						 * I/O ports it uses. It then uses that information to decide
2767 						 * what IDE hard disk and controller corresponds to what DOS
2768 						 * drive. So to get 32-bit disk access to work in Windows 95,
2769 						 * we have to put on a good show to convince Windows 95 we're
2770 						 * a legitimate BIOS INT 13h call doing it's job. */
2771 						IDE_SelfIO_In(ide, ide->base_io + 7u,
2772 						              io_width_t::byte); /* dum de dum reading status */
2773 						IDE_SelfIO_Out(ide, ide->base_io + 6u,
2774 						               static_cast<uint16_t>(ms << 4u) + 0xA0u + head,
2775 						               io_width_t::byte); /* drive and head */
2776 						IDE_SelfIO_In(ide, ide->base_io + 7u,
2777 						              io_width_t::byte); /* dum de dum reading status */
2778 						IDE_SelfIO_Out(ide, ide->base_io + 2u, 0x01,
2779 						               io_width_t::byte); /* sector count */
2780 						IDE_SelfIO_Out(ide, ide->base_io + 3u, sect,
2781 						               io_width_t::byte); /* sector number */
2782 						IDE_SelfIO_Out(ide, ide->base_io + 4u, cyl & 0xFF,
2783 						               io_width_t::byte); /* cylinder lo */
2784 						IDE_SelfIO_Out(ide, ide->base_io + 5u, (cyl >> 8u) & 0xFF,
2785 						               io_width_t::byte); /* cylinder hi */
2786 						IDE_SelfIO_Out(ide, ide->base_io + 6u,
2787 						               static_cast<uint16_t>(ms << 4u) + 0xA0u + head,
2788 						               io_width_t::byte); /* drive and head */
2789 						IDE_SelfIO_In(ide, ide->base_io + 7u,
2790 						              io_width_t::byte); /* dum de dum reading status */
2791 						IDE_SelfIO_Out(ide, ide->base_io + 7u, 0x20u,
2792 						               io_width_t::byte); /* issue READ */
2793 
2794 						do {
2795 							/* TBD: Timeout needed */
2796 							uint32_t i = IDE_SelfIO_In(ide, ide->alt_io,
2797 							                           io_width_t::byte);
2798 							if ((i & 0x80) == 0)
2799 								break;
2800 						} while (1);
2801 						IDE_SelfIO_In(ide, ide->base_io + 7u, io_width_t::byte);
2802 
2803 						/* for brevity assume it worked. we're here to bullshit
2804 						 * Windows 95 after all */
2805 						for (uint32_t i = 0; i < 256; i++)
2806 							IDE_SelfIO_In(ide, ide->base_io + 0, io_width_t::word); /* 16-bit IDE data read */
2807 
2808 						/* one more */
2809 						IDE_SelfIO_In(ide, ide->base_io + 7u,
2810 						              io_width_t::byte); /* dum de dum reading status */
2811 
2812 						/* assume IRQ happened and clear it */
2813 						if (ide->IRQ >= 8)
2814 							IDE_SelfIO_Out(ide, 0xA0, 0x60u + (uint32_t)ide->IRQ - 8u,
2815 							               io_width_t::byte); /* specific EOI */
2816 						else
2817 							IDE_SelfIO_Out(ide, 0x20, 0x60u + (uint32_t)ide->IRQ,
2818 							               io_width_t::byte); /* specific EOI */
2819 
2820 						ata->abort_normal();
2821 						dev->faked_command = false;
2822 					} else {
2823 						/* hack IDE state as if a BIOS executing IDE disk routines.
2824 						 * This is required if we want IDE emulation to work with
2825 						 * Windows 3.11 Windows for Workgroups 32-bit disk access
2826 						 * (WDCTRL), because the driver "tests" the controller by
2827 						 * issuing INT 13h calls then reading back IDE registers to
2828 						 * see if they match the C/H/S it requested */
2829 						dev->feature = 0x00; /* clear error (WDCTRL test phase 5/C/13) */
2830 						dev->count = 0x00; /* clear sector count (WDCTRL test phase 6/D/14) */
2831 						dev->lba[0] = check_cast<uint16_t>(sect); /* leave sector number
2832 						                                             the same (WDCTRL
2833 						                                             test phase 7/E/15) */
2834 						dev->lba[1] = check_cast<uint16_t>(
2835 						        cyl); /* leave cylinder the same (WDCTRL test phase 8/F/16) */
2836 						dev->lba[2] = check_cast<uint16_t>(cyl >> 8u); /* ...ditto */
2837 						dev->drivehead = check_cast<uint8_t>(
2838 						        0xA0u | static_cast<uint16_t>(ms << 4u) |
2839 						        head); /* drive head and master/slave (WDCTRL test phase 9/10/17) */
2840 						ide->drivehead = dev->drivehead;
2841 						dev->status = IDE_STATUS_DRIVE_READY |
2842 						              IDE_STATUS_DRIVE_SEEK_COMPLETE; /* status (WDCTRL
2843 						                                                 test phase A/11/18) */
2844 						dev->allow_writing = true;
2845 						static bool vm86_warned = false;
2846 
2847 						if (vm86 && !vm86_warned) {
2848 							LOG_WARNING("IDE: INT 13h read from virtual 8086 mode.");
2849 							LOG_WARNING("     If using Windows 95, please set int13fakev86io=true for proper 32-bit disk access");
2850 							vm86_warned = true;
2851 						}
2852 					}
2853 
2854 					/* break out, we're done */
2855 					idx = MAX_IDE_CONTROLLERS;
2856 					break;
2857 				}
2858 			}
2859 		}
2860 	}
2861 }
2862 
2863 /* this is called by src/ints/bios_disk.cpp whenever INT 13h AH=0x00 is called on a hard disk.
2864  * this gives us a chance to update IDE state as if the BIOS had gone through with a full disk reset as requested. */
IDE_ResetDiskByBIOS(uint8_t disk)2865 void IDE_ResetDiskByBIOS(uint8_t disk)
2866 {
2867 	IDEController *ide;
2868 	IDEDevice *dev;
2869 	uint8_t idx, ms;
2870 
2871 	if (disk < 0x80)
2872 		return;
2873 
2874 	for (idx = 0; idx < MAX_IDE_CONTROLLERS; idx++) {
2875 		ide = GetIDEController(idx);
2876 		if (ide == nullptr)
2877 			continue;
2878 		if (!ide->int13fakeio && !ide->int13fakev86io)
2879 			continue;
2880 
2881 		/* TBD: Print a warning message if the IDE controller is busy (debug/warning message) */
2882 
2883 		/* TBD: Force IDE state to readiness, abort command, etc. */
2884 
2885 		/* for master/slave device... */
2886 		for (ms = 0; ms < 2; ms++) {
2887 			dev = ide->device[ms];
2888 			if (dev == nullptr)
2889 				continue;
2890 
2891 			/* TBD: Print a warning message if the IDE device is busy or in the middle of a command */
2892 
2893 			/* TBD: Forcibly device-reset the IDE device */
2894 
2895 			/* Issue I/O to ourself to select drive */
2896 			IDE_SelfIO_In(ide, ide->base_io + 7u, io_width_t::byte);
2897 			IDE_SelfIO_Out(ide, ide->base_io + 6u, static_cast<uint16_t>(ms << 4u), io_width_t::byte);
2898 
2899 			/* TBD: Forcibly device-reset the IDE device */
2900 
2901 			if (dev->type == IDE_TYPE_HDD) {
2902 				IDEATADevice *ata = (IDEATADevice *)dev;
2903 
2904 				if ((ata->bios_disk_index - 2) == (disk - 0x80)) {
2905 					LOG_MSG("IDE: %d%c reset by BIOS disk 0x%02x", (uint32_t)(idx + 1),
2906 					        ms ? 's' : 'm', (uint32_t)disk);
2907 
2908 					if (ide->int13fakev86io && IDE_CPU_Is_Vm86()) {
2909 						/* issue the DEVICE RESET command */
2910 						IDE_SelfIO_In(ide, ide->base_io + 7u, io_width_t::byte);
2911 						IDE_SelfIO_Out(ide, ide->base_io + 7u, 0x08, io_width_t::byte);
2912 
2913 						IDE_SelfIO_In(ide, ide->base_io + 7u, io_width_t::byte);
2914 
2915 						/* assume IRQ happened and clear it */
2916 						if (ide->IRQ >= 8)
2917 							IDE_SelfIO_Out(ide, 0xA0, 0x60u + (uint32_t)ide->IRQ - 8u,
2918 							               io_width_t::byte); /* specific EOI */
2919 						else
2920 							IDE_SelfIO_Out(ide, 0x20, 0x60u + (uint32_t)ide->IRQ,
2921 							               io_width_t::byte); /* specific EOI */
2922 					} else {
2923 						/* Windows 3.1 WDCTRL needs this, or else, it will read the
2924 						 * status register and see something other than
2925 						 * DRIVE_READY|SEEK_COMPLETE */
2926 						dev->writecommand(0x08);
2927 
2928 						/* and then immediately clear the IRQ */
2929 						ide->lower_irq();
2930 					}
2931 				}
2932 			}
2933 		}
2934 	}
2935 }
2936 
IDE_DelayedCommand(uint32_t idx)2937 static void IDE_DelayedCommand(uint32_t idx /*which IDE controller*/)
2938 {
2939 	IDEDevice *dev = GetIDESelectedDevice(GetIDEController(idx));
2940 	if (dev == nullptr)
2941 		return;
2942 
2943 	if (dev->type == IDE_TYPE_HDD) {
2944 		IDEATADevice *ata = (IDEATADevice *)dev;
2945 		uint32_t sectorn = 0; /* TBD: expand to uint64_t when adding LBA48 emulation */
2946 		uint32_t sectcount;
2947 		std::shared_ptr<imageDisk> disk;
2948 		//      int i;
2949 
2950 		switch (dev->command) {
2951 		case 0x30: /* WRITE SECTOR */
2952 			disk = ata->getBIOSdisk();
2953 			if (disk == nullptr) {
2954 				LOG_WARNING("IDE: ATA READ fail, bios disk N/A");
2955 				ata->abort_error();
2956 				dev->controller->raise_irq();
2957 				return;
2958 			}
2959 
2960 			// Sector count is unused, but retained as a comment
2961 			// sectcount = ata->count & 0xFF;
2962 			// if (sectcount == 0) sectcount = 256;
2963 			if (drivehead_is_lba(ata->drivehead)) {
2964 				/* LBA */
2965 				sectorn = ((ata->drivehead & 0xFu) << 24u) | (uint32_t)ata->lba[0] |
2966 				          ((uint32_t)ata->lba[1] << 8u) | ((uint32_t)ata->lba[2] << 16u);
2967 			} else {
2968 				/* C/H/S */
2969 				if (ata->lba[0] == 0) {
2970 					LOG_WARNING("IDE: ATA sector 0 does not exist");
2971 					ata->abort_error();
2972 					dev->controller->raise_irq();
2973 					return;
2974 				} else if ((ata->drivehead & 0xFu) >= ata->heads ||
2975 				           (uint32_t)ata->lba[0] > ata->sects ||
2976 				           (uint32_t)(ata->lba[1] | (ata->lba[2] << 8u)) >= ata->cyls) {
2977 					LOG_WARNING("IDE: C/H/S %u/%u/%u out of bounds %u/%u/%u",
2978 					        (uint32_t)(ata->lba[1] | (ata->lba[2] << 8u)),
2979 					        (ata->drivehead & 0xFu), (uint32_t)(ata->lba[0]), ata->cyls,
2980 					        ata->heads, ata->sects);
2981 					ata->abort_error();
2982 					dev->controller->raise_irq();
2983 					return;
2984 				}
2985 
2986 				sectorn = ((ata->drivehead & 0xF) * ata->sects) +
2987 				          (((uint32_t)ata->lba[1] | ((uint32_t)ata->lba[2] << 8u)) *
2988 				           ata->sects * ata->heads) +
2989 				          ((uint32_t)ata->lba[0] - 1u);
2990 			}
2991 
2992 			if (disk->Write_AbsoluteSector(sectorn, ata->sector) != 0) {
2993 				LOG_WARNING("IDE: Failed to write sector");
2994 				ata->abort_error();
2995 				dev->controller->raise_irq();
2996 				return;
2997 			}
2998 
2999 			/* NTS: the way this command works is that the drive writes ONE sector, then fires the IRQ
3000 			        and lets the host read it, then reads another sector, fires the IRQ, etc. One
3001 			    IRQ signal per sector. We emulate that here by adding another event to trigger this
3002 			    call unless the sector count has just dwindled to zero, then we let it stop. */
3003 			if ((ata->count & 0xFF) == 1) {
3004 				/* end of the transfer */
3005 				ata->count = 0;
3006 				ata->status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
3007 				dev->controller->raise_irq();
3008 				ata->state = IDE_DEV_READY;
3009 				ata->allow_writing = true;
3010 				return;
3011 			} else if ((ata->count & 0xFF) == 0)
3012 				ata->count = 255;
3013 			else
3014 				ata->count--;
3015 			ata->progress_count++;
3016 
3017 			if (!ata->increment_current_address()) {
3018 				LOG_WARNING("IDE: READ advance error");
3019 				ata->abort_error();
3020 				return;
3021 			}
3022 
3023 			/* begin another sector */
3024 			dev->state = IDE_DEV_DATA_WRITE;
3025 			dev->status = IDE_STATUS_DRQ | IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
3026 			ata->prepare_write(0, 512);
3027 			dev->controller->raise_irq();
3028 			break;
3029 
3030 		case 0x20: /* READ SECTOR */
3031 			disk = ata->getBIOSdisk();
3032 			if (disk == nullptr) {
3033 				LOG_MSG("IDE: ATA READ fail, bios disk N/A");
3034 				ata->abort_error();
3035 				dev->controller->raise_irq();
3036 				return;
3037 			}
3038 			// Sector count is unused, but retained as a comment
3039 			// sectcount = ata->count & 0xFF;
3040 			// if (sectcount == 0) sectcount = 256;
3041 			if (drivehead_is_lba(ata->drivehead)) {
3042 				/* LBA */
3043 				sectorn = (((uint32_t)ata->drivehead & 0xFu) << 24u) | (uint32_t)ata->lba[0] |
3044 				          ((uint32_t)ata->lba[1] << 8u) | ((uint32_t)ata->lba[2] << 16u);
3045 			} else {
3046 				/* C/H/S */
3047 				if (ata->lba[0] == 0) {
3048 					LOG_MSG("IDE: C/H/S access mode and sector==0");
3049 					ata->abort_error();
3050 					dev->controller->raise_irq();
3051 					return;
3052 				} else if ((uint32_t)(ata->drivehead & 0xF) >= ata->heads ||
3053 				           (uint32_t)ata->lba[0] > ata->sects ||
3054 				           (ata->lba[1] | ((uint32_t)ata->lba[2] << 8u)) >= ata->cyls) {
3055 					LOG_WARNING("IDE: C/H/S %u/%u/%u out of bounds %u/%u/%u",
3056 					        (ata->lba[1] | ((uint32_t)ata->lba[2] << 8u)),
3057 					        (uint32_t)(ata->drivehead & 0xF), (uint32_t)ata->lba[0],
3058 					        ata->cyls, ata->heads, ata->sects);
3059 					ata->abort_error();
3060 					dev->controller->raise_irq();
3061 					return;
3062 				}
3063 
3064 				sectorn = ((ata->drivehead & 0xFu) * ata->sects) +
3065 				          ((ata->lba[1] | ((uint32_t)ata->lba[2] << 8u)) * ata->sects * ata->heads) +
3066 				          ((uint32_t)ata->lba[0] - 1u);
3067 			}
3068 
3069 			if (disk->Read_AbsoluteSector(sectorn, ata->sector) != 0) {
3070 				LOG_WARNING("IDE: ATA read failed");
3071 				ata->abort_error();
3072 				dev->controller->raise_irq();
3073 				return;
3074 			}
3075 
3076 			/* NTS: the way this command works is that the drive reads ONE sector, then fires the IRQ
3077 			        and lets the host read it, then reads another sector, fires the IRQ, etc. One
3078 			    IRQ signal per sector. We emulate that here by adding another event to trigger this
3079 			    call unless the sector count has just dwindled to zero, then we let it stop. */
3080 			/* NTS: The sector advance + count decrement is done in the I/O completion function */
3081 			dev->state = IDE_DEV_DATA_READ;
3082 			dev->status = IDE_STATUS_DRQ | IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
3083 			ata->prepare_read(0, 512);
3084 			dev->controller->raise_irq();
3085 			break;
3086 
3087 		case 0x40: /* READ SECTOR VERIFY WITH RETRY */
3088 		case 0x41: /* READ SECTOR VERIFY WITHOUT RETRY */
3089 			disk = ata->getBIOSdisk();
3090 			if (disk == nullptr) {
3091 				LOG_WARNING("IDE: ATA READ fail, bios disk N/A");
3092 				ata->abort_error();
3093 				dev->controller->raise_irq();
3094 				return;
3095 			}
3096 			// Sector count is unused, but retained as a comment
3097 			// sectcount = ata->count & 0xFF;
3098 			// if (sectcount == 0) sectcount = 256;
3099 			if (drivehead_is_lba(ata->drivehead)) {
3100 				/* LBA */
3101 				sectorn = (((uint32_t)ata->drivehead & 0xFu) << 24u) | (uint32_t)ata->lba[0] |
3102 				          ((uint32_t)ata->lba[1] << 8u) | ((uint32_t)ata->lba[2] << 16u);
3103 			} else {
3104 				/* C/H/S */
3105 				if (ata->lba[0] == 0) {
3106 					LOG_WARNING("IDE: C/H/S access mode and sector==0");
3107 					ata->abort_error();
3108 					dev->controller->raise_irq();
3109 					return;
3110 				} else if ((uint32_t)(ata->drivehead & 0xF) >= ata->heads ||
3111 				           (uint32_t)ata->lba[0] > ata->sects ||
3112 				           (ata->lba[1] | ((uint32_t)ata->lba[2] << 8u)) >= ata->cyls) {
3113 					LOG_WARNING("IDE: C/H/S %u/%u/%u out of bounds %u/%u/%u",
3114 					        ata->lba[1] | ((uint32_t)ata->lba[2] << 8u), ata->drivehead & 0xFu,
3115 					        (uint32_t)ata->lba[0], ata->cyls, ata->heads, ata->sects);
3116 					ata->abort_error();
3117 					dev->controller->raise_irq();
3118 					return;
3119 				}
3120 
3121 				sectorn = (((uint32_t)ata->drivehead & 0xFu) * ata->sects) +
3122 				          (((uint32_t)ata->lba[1] | ((uint32_t)ata->lba[2] << 8u)) *
3123 				           ata->sects * ata->heads) +
3124 				          ((uint32_t)ata->lba[0] - 1u);
3125 			}
3126 
3127 			if (disk->Read_AbsoluteSector(sectorn, ata->sector) != 0) {
3128 				LOG_WARNING("IDE: ATA read failed");
3129 				ata->abort_error();
3130 				dev->controller->raise_irq();
3131 				return;
3132 			}
3133 
3134 			if ((ata->count & 0xFF) == 1) {
3135 				/* end of the transfer */
3136 				ata->count = 0;
3137 				ata->status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
3138 				dev->controller->raise_irq();
3139 				ata->state = IDE_DEV_READY;
3140 				ata->allow_writing = true;
3141 				return;
3142 			} else if ((ata->count & 0xFF) == 0)
3143 				ata->count = 255;
3144 			else
3145 				ata->count--;
3146 			ata->progress_count++;
3147 
3148 			if (!ata->increment_current_address()) {
3149 				LOG_WARNING("IDE: READ advance error");
3150 				ata->abort_error();
3151 				return;
3152 			}
3153 
3154 			ata->state = IDE_DEV_BUSY;
3155 			ata->status = IDE_STATUS_BUSY;
3156 			PIC_AddEvent(IDE_DelayedCommand, 0.00001 /*ms*/, dev->controller->interface_index);
3157 			break;
3158 
3159 		case 0xC4: /* READ MULTIPLE */
3160 			disk = ata->getBIOSdisk();
3161 			if (disk == nullptr) {
3162 				LOG_WARNING("IDE: ATA READ fail, bios disk N/A");
3163 				ata->abort_error();
3164 				dev->controller->raise_irq();
3165 				return;
3166 			}
3167 
3168 			sectcount = ata->count & 0xFF;
3169 			if (sectcount == 0)
3170 				sectcount = 256;
3171 			if (drivehead_is_lba(ata->drivehead)) {
3172 				/* LBA */
3173 				sectorn = (((uint32_t)ata->drivehead & 0xFu) << 24u) | (uint32_t)ata->lba[0] |
3174 				          ((uint32_t)ata->lba[1] << 8u) | ((uint32_t)ata->lba[2] << 16u);
3175 			} else {
3176 				/* C/H/S */
3177 				if (ata->lba[0] == 0) {
3178 					LOG_WARNING("IDE: C/H/S access mode and sector==0");
3179 					ata->abort_error();
3180 					dev->controller->raise_irq();
3181 					return;
3182 				} else if ((uint32_t)(ata->drivehead & 0xF) >= ata->heads ||
3183 				           (uint32_t)ata->lba[0] > ata->sects ||
3184 				           (ata->lba[1] | ((uint32_t)ata->lba[2] << 8u)) >= ata->cyls) {
3185 					LOG_WARNING("IDE: C/H/S %u/%u/%u out of bounds %u/%u/%u",
3186 					        (ata->lba[1] | ((uint32_t)ata->lba[2] << 8u)),
3187 					        (uint32_t)(ata->drivehead & 0xF), (uint32_t)ata->lba[0],
3188 					        ata->cyls, ata->heads, ata->sects);
3189 					ata->abort_error();
3190 					dev->controller->raise_irq();
3191 					return;
3192 				}
3193 
3194 				sectorn = ((ata->drivehead & 0xF) * ata->sects) +
3195 				          (((uint32_t)ata->lba[1] | ((uint32_t)ata->lba[2] << 8u)) *
3196 				           ata->sects * ata->heads) +
3197 				          ((uint32_t)ata->lba[0] - 1);
3198 			}
3199 
3200 			if ((512 * ata->multiple_sector_count) > sizeof(ata->sector))
3201 				E_Exit("SECTOR OVERFLOW");
3202 
3203 			for (uint32_t cc = 0; cc < std::min(ata->multiple_sector_count, sectcount); cc++) {
3204 				/* it would be great if the disk object had a "read
3205 				 * multiple sectors" member function */
3206 				if (disk->Read_AbsoluteSector(sectorn + cc, ata->sector + (cc * 512)) != 0) {
3207 					LOG_WARNING("IDE: ATA read failed");
3208 					ata->abort_error();
3209 					dev->controller->raise_irq();
3210 					return;
3211 				}
3212 			}
3213 
3214 			/* NTS: the way this command works is that the drive reads ONE sector, then fires the IRQ
3215 			        and lets the host read it, then reads another sector, fires the IRQ, etc. One
3216 			    IRQ signal per sector. We emulate that here by adding another event to trigger this
3217 			    call unless the sector count has just dwindled to zero, then we let it stop. */
3218 			/* NTS: The sector advance + count decrement is done in the I/O completion function */
3219 			dev->state = IDE_DEV_DATA_READ;
3220 			dev->status = IDE_STATUS_DRQ | IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
3221 			ata->prepare_read(0, 512 * std::min(ata->multiple_sector_count, sectcount));
3222 			dev->controller->raise_irq();
3223 			break;
3224 
3225 		case 0xC5: /* WRITE MULTIPLE */
3226 			disk = ata->getBIOSdisk();
3227 			if (disk == nullptr) {
3228 				LOG_WARNING("IDE: ATA READ fail, bios disk N/A");
3229 				ata->abort_error();
3230 				dev->controller->raise_irq();
3231 				return;
3232 			}
3233 
3234 			sectcount = ata->count & 0xFF;
3235 			if (sectcount == 0)
3236 				sectcount = 256;
3237 			if (drivehead_is_lba(ata->drivehead)) {
3238 				/* LBA */
3239 				sectorn = (((uint32_t)ata->drivehead & 0xF) << 24) | (uint32_t)ata->lba[0] |
3240 				          ((uint32_t)ata->lba[1] << 8) | ((uint32_t)ata->lba[2] << 16);
3241 			} else {
3242 				/* C/H/S */
3243 				if (ata->lba[0] == 0) {
3244 					LOG_WARNING("IDE: ATA sector 0 does not exist");
3245 					ata->abort_error();
3246 					dev->controller->raise_irq();
3247 					return;
3248 				} else if ((uint32_t)(ata->drivehead & 0xF) >= ata->heads ||
3249 				           (uint32_t)ata->lba[0] > ata->sects ||
3250 				           (ata->lba[1] | ((uint32_t)ata->lba[2] << 8)) >= ata->cyls) {
3251 					LOG_WARNING("IDE: C/H/S %u/%u/%u out of bounds %u/%u/%u",
3252 					        (ata->lba[1] | ((uint32_t)ata->lba[2] << 8)),
3253 					        (uint32_t)(ata->drivehead & 0xF), (uint32_t)ata->lba[0],
3254 					        ata->cyls, ata->heads, ata->sects);
3255 					ata->abort_error();
3256 					dev->controller->raise_irq();
3257 					return;
3258 				}
3259 
3260 				sectorn = ((uint32_t)(ata->drivehead & 0xF) * ata->sects) +
3261 				          (((uint32_t)ata->lba[1] | ((uint32_t)ata->lba[2] << 8)) *
3262 				           ata->sects * ata->heads) +
3263 				          ((uint32_t)ata->lba[0] - 1);
3264 			}
3265 
3266 			for (uint32_t cc = 0; cc < std::min(ata->multiple_sector_count, sectcount); cc++) {
3267 				/* it would be great if the disk object had a "write
3268 				 * multiple sectors" member function */
3269 				if (disk->Write_AbsoluteSector(sectorn + cc, ata->sector + (cc * 512)) != 0) {
3270 					LOG_WARNING("IDE: Failed to write sector");
3271 					ata->abort_error();
3272 					dev->controller->raise_irq();
3273 					return;
3274 				}
3275 			}
3276 
3277 			for (uint32_t cc = 0; cc < std::min(ata->multiple_sector_count, sectcount); cc++) {
3278 				if ((ata->count & 0xFF) == 1) {
3279 					/* end of the transfer */
3280 					ata->count = 0;
3281 					ata->status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
3282 					dev->controller->raise_irq();
3283 					ata->state = IDE_DEV_READY;
3284 					ata->allow_writing = true;
3285 					return;
3286 				} else if ((ata->count & 0xFF) == 0)
3287 					ata->count = 255;
3288 				else
3289 					ata->count--;
3290 				ata->progress_count++;
3291 
3292 				if (!ata->increment_current_address()) {
3293 					LOG_WARNING("IDE: READ advance error");
3294 					ata->abort_error();
3295 					return;
3296 				}
3297 			}
3298 
3299 			/* begin another sector */
3300 			sectcount = ata->count & 0xFF;
3301 			if (sectcount == 0)
3302 				sectcount = 256;
3303 			dev->state = IDE_DEV_DATA_WRITE;
3304 			dev->status = IDE_STATUS_DRQ | IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
3305 			ata->prepare_write(0, 512 * std::min(ata->multiple_sector_count, sectcount));
3306 			dev->controller->raise_irq();
3307 			break;
3308 
3309 		case 0xEC: /*IDENTIFY DEVICE (CONTINUED) */
3310 			dev->state = IDE_DEV_DATA_READ;
3311 			dev->status = IDE_STATUS_DRQ | IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
3312 			ata->generate_identify_device();
3313 			ata->prepare_read(0, 512);
3314 			dev->count = 0x01;
3315 			dev->lba[0] = 0x00;
3316 			dev->feature = 0x00;
3317 			dev->lba[1] = 0x00;
3318 			dev->lba[2] = 0x00;
3319 			dev->controller->raise_irq();
3320 			break;
3321 		default:
3322 			LOG_WARNING("IDE: Unknown delayed IDE/ATA command");
3323 			dev->abort_error();
3324 			dev->controller->raise_irq();
3325 			break;
3326 		}
3327 	} else if (dev->type == IDE_TYPE_CDROM) {
3328 		IDEATAPICDROMDevice *atapi = (IDEATAPICDROMDevice *)dev;
3329 
3330 		if (dev->state == IDE_DEV_ATAPI_BUSY) {
3331 			switch (dev->command) {
3332 			case 0xA0: /*ATAPI PACKET*/ atapi->on_atapi_busy_time(); break;
3333 			default:
3334 				LOG_WARNING("IDE: Unknown delayed IDE/ATAPI busy wait command");
3335 				dev->abort_error();
3336 				dev->controller->raise_irq();
3337 				break;
3338 			}
3339 		} else {
3340 			switch (dev->command) {
3341 			case 0xA0: /*ATAPI PACKET*/
3342 				dev->state = IDE_DEV_ATAPI_PACKET_COMMAND;
3343 				dev->status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE |
3344 				              IDE_STATUS_DRQ;
3345 				dev->count = 0x01;           /* input/output == 0, command/data == 1 */
3346 				atapi->atapi_cmd_total = 12; /* NTS: do NOT raise IRQ */
3347 				atapi->atapi_cmd_i = 0;
3348 				break;
3349 			case 0xA1: /*IDENTIFY PACKET DEVICE (CONTINUED) */
3350 				dev->state = IDE_DEV_DATA_READ;
3351 				dev->status = IDE_STATUS_DRQ | IDE_STATUS_DRIVE_READY |
3352 				              IDE_STATUS_DRIVE_SEEK_COMPLETE;
3353 				atapi->generate_identify_device();
3354 				atapi->prepare_read(0, 512);
3355 				dev->controller->raise_irq();
3356 				break;
3357 			default:
3358 				LOG_WARNING("IDE: Unknown delayed IDE/ATAPI command");
3359 				dev->abort_error();
3360 				dev->controller->raise_irq();
3361 				break;
3362 			}
3363 		}
3364 	} else {
3365 		LOG_WARNING("IDE: delayed command");
3366 		dev->abort_error();
3367 		dev->controller->raise_irq();
3368 	}
3369 }
3370 
raise_irq()3371 void IDEController::raise_irq()
3372 {
3373 	irq_pending = true;
3374 	if (IRQ >= 0 && interrupt_enable)
3375 		PIC_ActivateIRQ(check_cast<uint8_t>(IRQ));
3376 }
3377 
lower_irq()3378 void IDEController::lower_irq()
3379 {
3380 	irq_pending = false;
3381 	if (IRQ >= 0)
3382 		PIC_DeActivateIRQ(check_cast<uint8_t>(IRQ));
3383 }
3384 
match_ide_controller(io_port_t port)3385 IDEController *match_ide_controller(io_port_t port)
3386 {
3387 	for (uint32_t i = 0; i < MAX_IDE_CONTROLLERS; i++) {
3388 		IDEController *ide = idecontroller[i];
3389 		if (ide == nullptr)
3390 			continue;
3391 		if (ide->base_io != 0U && ide->base_io == (port & 0xFFF8U))
3392 			return ide;
3393 		if (ide->alt_io != 0U && ide->alt_io == (port & 0xFFFEU))
3394 			return ide;
3395 	}
3396 
3397 	return nullptr;
3398 }
3399 
data_read(io_width_t)3400 uint32_t IDEDevice::data_read(io_width_t)
3401 {
3402 	return 0xAAAAU;
3403 }
3404 
data_write(io_val_t,io_width_t)3405 void IDEDevice::data_write(io_val_t, io_width_t)
3406 {}
3407 
3408 /* IDE controller -> upon writing bit 2 of alt (0x3F6) */
host_reset_complete()3409 void IDEDevice::host_reset_complete()
3410 {
3411 	status = 0x00;
3412 	asleep = false;
3413 	allow_writing = true;
3414 	state = IDE_DEV_READY;
3415 }
3416 
host_reset_begin()3417 void IDEDevice::host_reset_begin()
3418 {
3419 	status = 0xFF;
3420 	asleep = false;
3421 	allow_writing = true;
3422 	state = IDE_DEV_BUSY;
3423 }
3424 
~IDEDevice()3425 IDEDevice::~IDEDevice()
3426 {}
3427 
abort_silent()3428 void IDEDevice::abort_silent()
3429 {
3430 	assert(controller != nullptr);
3431 
3432 	/* a command was written while another is in progress */
3433 	state = IDE_DEV_READY;
3434 	allow_writing = true;
3435 	command = 0x00;
3436 	status = IDE_STATUS_ERROR | IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
3437 }
3438 
abort_error()3439 void IDEDevice::abort_error()
3440 {
3441 	assert(controller != nullptr);
3442 	LOG_WARNING("IDE: abort dh=0x%02x with error on 0x%03x", drivehead, controller->base_io);
3443 
3444 	/* a command was written while another is in progress */
3445 	state = IDE_DEV_READY;
3446 	allow_writing = true;
3447 	command = 0x00;
3448 	status = IDE_STATUS_ERROR | IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
3449 }
3450 
abort_normal()3451 void IDEDevice::abort_normal()
3452 {
3453 	/* a command was written while another is in progress */
3454 	state = IDE_DEV_READY;
3455 	allow_writing = true;
3456 	command = 0x00;
3457 	status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
3458 }
3459 
interface_wakeup()3460 void IDEDevice::interface_wakeup()
3461 {
3462 	if (asleep) {
3463 		asleep = false;
3464 	}
3465 }
3466 
command_interruption_ok(uint8_t cmd)3467 bool IDEDevice::command_interruption_ok(uint8_t cmd)
3468 {
3469 	/* apparently this is OK, if the Linux kernel is doing it:
3470 	 * writing the same command byte as the one in progress, OR, issuing
3471 	 * Device Reset while another command is waiting for data read/write */
3472 	if (cmd == command)
3473 		return true;
3474 	if (state != IDE_DEV_READY && state != IDE_DEV_BUSY && cmd == 0x08) {
3475 		LOG_WARNING("IDE: Device reset while another (%02x) is in progress (state=%u). Aborting current command to begin another",
3476 		        command, state);
3477 		abort_silent();
3478 		return true;
3479 	}
3480 
3481 	if (state != IDE_DEV_READY) {
3482 		LOG_WARNING("IDE: Command %02x written while another (%02x) is in progress (state=%u). Aborting current command",
3483 		        cmd, command, state);
3484 		abort_error();
3485 		return false;
3486 	}
3487 
3488 	return true;
3489 }
3490 
writecommand(uint8_t cmd)3491 void IDEDevice::writecommand(uint8_t cmd)
3492 {
3493 	if (!command_interruption_ok(cmd))
3494 		return;
3495 
3496 	/* if the drive is asleep, then writing a command wakes it up */
3497 	interface_wakeup();
3498 
3499 	/* drive is ready to accept command */
3500 	LOG_WARNING("IDE: IDE command %02X", cmd);
3501 	abort_error();
3502 }
3503 
writecommand(uint8_t cmd)3504 void IDEATAPICDROMDevice::writecommand(uint8_t cmd)
3505 {
3506 	if (!command_interruption_ok(cmd))
3507 		return;
3508 
3509 	/* if the drive is asleep, then writing a command wakes it up */
3510 	interface_wakeup();
3511 
3512 	/* drive is ready to accept command */
3513 	allow_writing = false;
3514 	command = cmd;
3515 	switch (cmd) {
3516 	case 0x08: /* DEVICE RESET */
3517 		status = 0x00;
3518 		drivehead &= 0x10;
3519 		controller->drivehead = drivehead;
3520 		count = 0x01;
3521 		lba[0] = 0x01;
3522 		feature = 0x01;
3523 		lba[1] = 0x14; /* <- magic ATAPI identification */
3524 		lba[2] = 0xEB;
3525 		/* NTS: Testing suggests that ATAPI devices do NOT trigger an IRQ on receipt of this command */
3526 		allow_writing = true;
3527 		break;
3528 	case 0xEC: /* IDENTIFY DEVICE */
3529 		/* "devices that implement the PACKET command set shall post command aborted and place PACKET
3530 		   command feature set in the appropriate fields". We have to do this. Unlike OAKCDROM.SYS
3531 		   Windows 95 appears to autodetect IDE devices by what they do when they're sent command 0xEC
3532 		   out of the blue---Microsoft didn't write their IDE drivers to use command 0x08 DEVICE
3533 		   RESET. */
3534 	case 0x20: /* READ SECTOR */
3535 		abort_normal();
3536 		status = IDE_STATUS_ERROR | IDE_STATUS_DRIVE_READY;
3537 		drivehead &= 0x30;
3538 		controller->drivehead = drivehead;
3539 		count = 0x01;
3540 		lba[0] = 0x01;
3541 		feature = 0x04; /* abort */
3542 		lba[1] = 0x14;  /* <- magic ATAPI identification */
3543 		lba[2] = 0xEB;
3544 		controller->raise_irq();
3545 		allow_writing = true;
3546 		break;
3547 	case 0xA0: /* ATAPI PACKET */
3548 		if (feature & 1) {
3549 			/* this code does not support DMA packet commands */
3550 			LOG_MSG("IDE: Attempted DMA transfer");
3551 			abort_error();
3552 			count = 0x03; /* no more data (command/data=1, input/output=1) */
3553 			feature = 0xF4;
3554 			controller->raise_irq();
3555 		} else {
3556 			state = IDE_DEV_BUSY;
3557 			status = IDE_STATUS_BUSY;
3558 			atapi_to_host = (feature >> 2) & 1; /* 0=to device 1=to host */
3559 			host_maximum_byte_count = ((uint32_t)lba[2] << 8) +
3560 			                          (uint32_t)lba[1]; /* LBA field bits 23:8 are byte count */
3561 			if (host_maximum_byte_count == 0)
3562 				host_maximum_byte_count = 0x10000UL;
3563 			PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : 0.25) /*ms*/,
3564 			             controller->interface_index);
3565 		}
3566 		break;
3567 	case 0xA1: /* IDENTIFY PACKET DEVICE */
3568 		state = IDE_DEV_BUSY;
3569 		status = IDE_STATUS_BUSY;
3570 		PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : ide_identify_command_delay),
3571 		             controller->interface_index);
3572 		break;
3573 	default:
3574 		LOG_WARNING("IDE: IDE/ATAPI command %02X", cmd);
3575 		abort_error();
3576 		allow_writing = true;
3577 		count = 0x03; /* no more data (command/data=1, input/output=1) */
3578 		feature = 0xF4;
3579 		controller->raise_irq();
3580 		break;
3581 	}
3582 }
3583 
is_power_of_2(io_val_t val)3584 static inline bool is_power_of_2(io_val_t val)
3585 {
3586 	return (val != 0) && ((val & (val - 1)) == 0);
3587 }
3588 
writecommand(uint8_t cmd)3589 void IDEATADevice::writecommand(uint8_t cmd)
3590 {
3591 	if (!command_interruption_ok(cmd))
3592 		return;
3593 
3594 	if (!faked_command) {
3595 		if (drivehead_is_lba(drivehead)) {
3596 			// unused
3597 			// uint64_t n =
3598 			// ((uint32_t)(drivehead&0xF)<<24)+((uint32_t)lba[2]<<16)+((uint32_t)lba[1]<<8)+(uint32_t)lba[0];
3599 		}
3600 
3601 		LOG(LOG_SB, LOG_NORMAL)("IDE: ATA command %02x", cmd);
3602 	}
3603 
3604 	/* if the drive is asleep, then writing a command wakes it up */
3605 	interface_wakeup();
3606 
3607 	/* TBD: OAKCDROM.SYS is sending the hard disk command 0xA0 (ATAPI packet) for some reason. Why? */
3608 
3609 	/* drive is ready to accept command */
3610 	allow_writing = false;
3611 	command = cmd;
3612 	switch (cmd) {
3613 	case 0x00: /* NOP */
3614 		feature = 0x04;
3615 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_ERROR;
3616 		controller->raise_irq();
3617 		allow_writing = true;
3618 		break;
3619 	case 0x08: /* DEVICE RESET */
3620 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
3621 		drivehead &= 0x10;
3622 		controller->drivehead = drivehead;
3623 		count = 0x01;
3624 		lba[0] = 0x01;
3625 		feature = 0x00;
3626 		lba[1] = lba[2] = 0;
3627 		/* NTS: Testing suggests that ATA hard drives DO fire an IRQ at this stage.
3628 		        In fact, Windows 95 won't detect hard drives that don't fire an IRQ in desponse */
3629 		controller->raise_irq();
3630 		allow_writing = true;
3631 		break;
3632 	case 0x10:
3633 	case 0x11:
3634 	case 0x12:
3635 	case 0x13:
3636 	case 0x14:
3637 	case 0x15:
3638 	case 0x16:
3639 	case 0x17: /* RECALIBRATE (1xh) */
3640 	case 0x18:
3641 	case 0x19:
3642 	case 0x1A:
3643 	case 0x1B:
3644 	case 0x1C:
3645 	case 0x1D:
3646 	case 0x1E:
3647 	case 0x1F:
3648 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
3649 		/* "if the command is executed in CHS mode, then ... sector number register shall be 1.
3650 		 *  if executed in LAB mode, then ... sector number register shall be 0" */
3651 		if (drivehead_is_lba(drivehead))
3652 			lba[0] = 0x00;
3653 		else
3654 			lba[0] = 0x01;
3655 		drivehead &= 0x10;
3656 		controller->drivehead = drivehead;
3657 		lba[1] = lba[2] = 0;
3658 		feature = 0x00;
3659 		controller->raise_irq();
3660 		allow_writing = true;
3661 		break;
3662 	case 0x30: /* WRITE SECTOR */
3663 		/* the drive does NOT signal an interrupt. it sets DRQ and waits for a sector
3664 		 * to be transferred to it before executing the command */
3665 		progress_count = 0;
3666 		state = IDE_DEV_DATA_WRITE;
3667 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRQ;
3668 		prepare_write(0, 512);
3669 		break;
3670 	case 0x20: /* READ SECTOR */
3671 	case 0x40: /* READ SECTOR VERIFY WITH RETRY */
3672 	case 0x41: /* READ SECTOR VERIFY WITHOUT RETRY */
3673 	case 0xC4: /* READ MULTIPLE */
3674 		progress_count = 0;
3675 		state = IDE_DEV_BUSY;
3676 		status = IDE_STATUS_BUSY;
3677 		PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : 0.1) /*ms*/,
3678 		             controller->interface_index);
3679 		break;
3680 	case 0x91: /* INITIALIZE DEVICE PARAMETERS */
3681 		if ((uint32_t)count != sects || (uint32_t)((drivehead & 0xF) + 1) != heads) {
3682 			if (count == 0) {
3683 				LOG_WARNING("IDE: OS attempted to change geometry to invalid H/S %u/%u",
3684 				        count, (drivehead & 0xF) + 1);
3685 				abort_error();
3686 				allow_writing = true;
3687 				return;
3688 			} else {
3689 				uint32_t ncyls;
3690 
3691 				ncyls = (phys_cyls * phys_heads * phys_sects);
3692 				ncyls += (count * ((uint32_t)(drivehead & 0xF) + 1u)) - 1u;
3693 				ncyls /= count * ((uint32_t)(drivehead & 0xF) + 1u);
3694 
3695 				/* the OS is changing logical disk geometry, so update our head/sector count
3696 				 * (needed for Windows ME) */
3697 				LOG_WARNING("IDE: OS is changing logical geometry from C/H/S %u/%u/%u to logical H/S %u/%u/%u",
3698 				        (int)cyls, (int)heads, (int)sects, (int)ncyls, (drivehead & 0xF) + 1,
3699 				        (int)count);
3700 				LOG_WARNING("     Compatibility issues may occur if the OS tries to use INT 13 at the same time!");
3701 
3702 				cyls = ncyls;
3703 				sects = count;
3704 				heads = (drivehead & 0xFu) + 1u;
3705 			}
3706 		}
3707 
3708 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
3709 		allow_writing = true;
3710 		break;
3711 	case 0xC5: /* WRITE MULTIPLE */
3712 		/* the drive does NOT signal an interrupt. it sets DRQ and waits for a sector
3713 		 * to be transferred to it before executing the command */
3714 		progress_count = 0;
3715 		state = IDE_DEV_DATA_WRITE;
3716 		status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRQ;
3717 		prepare_write(0UL, 512UL * std::min(multiple_sector_count, (count == 0 ? 256u : count)));
3718 		break;
3719 	case 0xC6: /* SET MULTIPLE MODE */
3720 		/* only sector counts 1, 2, 4, 8, 16, 32, 64, and 128 are legal by standard.
3721 		 * NTS: There's a bug in VirtualBox that makes 0 legal too! */
3722 		if (count != 0 && count <= multiple_sector_max && is_power_of_2(count)) {
3723 			multiple_sector_count = count;
3724 			status = IDE_STATUS_DRIVE_READY | IDE_STATUS_DRIVE_SEEK_COMPLETE;
3725 		} else {
3726 			feature = 0x04; /* abort error */
3727 			abort_error();
3728 		}
3729 		controller->raise_irq();
3730 		allow_writing = true;
3731 		break;
3732 	case 0xA0: /*ATAPI PACKET*/
3733 		   /* We're not an ATAPI packet device!
3734 		    * Windows 95 seems to issue this at startup to hard drives. Duh. */
3735 		   /* fall through */
3736 	case 0xA1: /* IDENTIFY PACKET DEVICE */
3737 		/* We are not an ATAPI packet device.
3738 		 * Most MS-DOS drivers and Windows 95 like to issue both IDENTIFY ATA and IDENTIFY ATAPI
3739 		 * commands. I also gather from some contributers on the github comments that people think our
3740 		 * "Unknown IDE/ATA command" error message is part of some other error in the emulation.
3741 		 * Rather than put up with that, we'll just silently abort the command with an error. */
3742 		abort_normal();
3743 		status = IDE_STATUS_ERROR | IDE_STATUS_DRIVE_READY;
3744 		drivehead &= 0x30;
3745 		controller->drivehead = drivehead;
3746 		count = 0x01;
3747 		lba[0] = 0x01;
3748 		feature = 0x04; /* abort */
3749 		lba[1] = 0x00;
3750 		lba[2] = 0x00;
3751 		controller->raise_irq();
3752 		allow_writing = true;
3753 		break;
3754 	case 0xEC: /* IDENTIFY DEVICE */
3755 		state = IDE_DEV_BUSY;
3756 		status = IDE_STATUS_BUSY;
3757 		PIC_AddEvent(IDE_DelayedCommand, (faked_command ? 0.000001 : ide_identify_command_delay),
3758 		             controller->interface_index);
3759 		break;
3760 	default:
3761 		LOG_WARNING("IDE: IDE/ATA command %02X", cmd);
3762 		abort_error();
3763 		allow_writing = true;
3764 		controller->raise_irq();
3765 		break;
3766 	}
3767 }
3768 
deselect()3769 void IDEDevice::deselect()
3770 {}
3771 
3772 /* the hard disk or CD-ROM class override of this member is responsible for checking
3773    the head value and clamping within range if C/H/S mode is selected */
select(uint8_t ndh,bool switched_to)3774 void IDEDevice::select(uint8_t ndh, bool switched_to)
3775 {
3776 	(void)switched_to; // UNUSED
3777 	(void)ndh;         // UNUSED
3778 	/* NTS: I thought there was some delay between selecting a drive and sending a command.
3779 	    Apparently I was wrong. */
3780 	if (allow_writing)
3781 		drivehead = ndh;
3782 	//  status = (!asleep)?(IDE_STATUS_DRIVE_READY|IDE_STATUS_DRIVE_SEEK_COMPLETE):0;
3783 	//  allow_writing = !asleep;
3784 	//  state = IDE_DEV_READY;
3785 }
3786 
IDEController(const uint8_t index,const uint8_t irq,const uint16_t port,const uint16_t alt_port)3787 IDEController::IDEController(const uint8_t index,
3788                              const uint8_t irq,
3789                              const uint16_t port,
3790                              const uint16_t alt_port)
3791 {
3792 	constexpr int CONFIGS = 4;
3793 	constexpr std::array<uint8_t, CONFIGS> irqs{{
3794 	        14, /* primary */
3795 	        15, /* secondary */
3796 	        11, /* tertiary */
3797 	        10, /* quaternary */
3798 	}};
3799 	constexpr std::array<uint16_t, CONFIGS> base_ios{{
3800 	        0x1F0, /* primary */
3801 	        0x170, /* secondary */
3802 	        0x1E8, /* tertiary */
3803 	        0x168, /* quaternary */
3804 	}};
3805 	constexpr std::array<uint16_t, CONFIGS> alt_ios{{
3806 	        0x3F6, /* primary */
3807 	        0x376, /* secondary */
3808 	        0x3EE, /* tertiary */
3809 	        0x36E, /* quaternary */
3810 	}};
3811 
3812 	assert(index < CONFIGS);
3813 	interface_index = index;
3814 
3815 	IRQ = contains(irqs, irq) ? irq : irqs[index];
3816 
3817 	base_io = contains(base_ios, port) ? port : base_ios[index];
3818 
3819 	alt_io = contains(alt_ios, alt_port) ? alt_port : alt_ios[index];
3820 
3821 	LOG_MSG("IDE: Created %s controller IRQ %d, base I/O port %03xh, alternate I/O port %03xh",
3822 	        get_controller_name(index), IRQ, base_io, alt_io);
3823 
3824 	install_io_ports();
3825 	PIC_SetIRQMask((uint32_t)IRQ, false);
3826 
3827 	idecontroller[index] = this;
3828 }
3829 
install_io_ports()3830 void IDEController::install_io_ports()
3831 {
3832 	if (base_io != 0) {
3833 		for (io_port_t i = 0; i < 8; i++) {
3834 			WriteHandler[i].Install(base_io + i, ide_baseio_w, io_width_t::dword);
3835 			ReadHandler[i].Install(base_io + i, ide_baseio_r, io_width_t::dword);
3836 		}
3837 	}
3838 
3839 	if (alt_io != 0) {
3840 		WriteHandlerAlt[0].Install(alt_io, ide_altio_w, io_width_t::dword);
3841 		ReadHandlerAlt[0].Install(alt_io, ide_altio_r, io_width_t::dword);
3842 
3843 		WriteHandlerAlt[1].Install(alt_io + 1u, ide_altio_w, io_width_t::dword);
3844 		ReadHandlerAlt[1].Install(alt_io + 1u, ide_altio_r, io_width_t::dword);
3845 	}
3846 }
3847 
uninstall_io_ports()3848 void IDEController::uninstall_io_ports()
3849 {
3850 	// Uninstall the eight sets of base I/O ports
3851 	assert(base_io != 0);
3852 	for (auto & h : WriteHandler)
3853 		h.Uninstall();
3854 	for (auto & h : ReadHandler)
3855 		h.Uninstall();
3856 
3857 	// Uninstall the two sets of alternate I/O ports
3858 	assert(alt_io != 0);
3859 	for (auto & h : WriteHandlerAlt)
3860 		h.Uninstall();
3861 	for (auto & h : ReadHandlerAlt)
3862 		h.Uninstall();
3863 }
3864 
~IDEController()3865 IDEController::~IDEController()
3866 {
3867 	lower_irq();
3868 	uninstall_io_ports();
3869 
3870 	for (auto &d : device) {
3871 		delete d;
3872 		d = nullptr;
3873 	}
3874 	idecontroller[interface_index] = nullptr;
3875 }
3876 
ide_altio_w(io_port_t port,io_val_t val,io_width_t width)3877 static void ide_altio_w(io_port_t port, io_val_t val, io_width_t width)
3878 {
3879 	IDEController *ide = match_ide_controller(port);
3880 	if (ide == nullptr) {
3881 		LOG_WARNING("IDE: port read from I/O port not registered to IDE, yet callback triggered");
3882 		return;
3883 	}
3884 
3885 	if (!ide->enable_pio32 && width == io_width_t::dword) {
3886 		ide_altio_w(port, val & 0xFFFF, io_width_t::word);
3887 		ide_altio_w(port + 2u, val >> 16u, io_width_t::word);
3888 		return;
3889 	} else if (ide->ignore_pio32 && width == io_width_t::dword)
3890 		return;
3891 
3892 	port &= 1;
3893 
3894 	if (port == 0) { /*3F6*/
3895 		ide->interrupt_enable = (val & 2u) ? 0 : 1;
3896 		if (ide->interrupt_enable) {
3897 			if (ide->irq_pending)
3898 				ide->raise_irq();
3899 		} else {
3900 			if (ide->IRQ >= 0)
3901 				PIC_DeActivateIRQ(check_cast<uint8_t>(ide->IRQ));
3902 		}
3903 
3904 		if ((val & 4) && !ide->host_reset) {
3905 			if (ide->device[0])
3906 				ide->device[0]->host_reset_begin();
3907 			if (ide->device[1])
3908 				ide->device[1]->host_reset_begin();
3909 			ide->host_reset = 1;
3910 		} else if (!(val & 4) && ide->host_reset) {
3911 			if (ide->device[0])
3912 				ide->device[0]->host_reset_complete();
3913 			if (ide->device[1])
3914 				ide->device[1]->host_reset_complete();
3915 			ide->host_reset = 0;
3916 		}
3917 	}
3918 }
3919 
ide_altio_r(io_port_t port,io_width_t width)3920 static uint32_t ide_altio_r(io_port_t port, io_width_t width)
3921 {
3922 	IDEController *ide = match_ide_controller(port);
3923 	IDEDevice *dev;
3924 
3925 	if (ide == nullptr) {
3926 		LOG_WARNING("IDE: port read from I/O port not registered to IDE, yet callback triggered");
3927 		return UINT32_MAX;
3928 	}
3929 
3930 	if (!ide->enable_pio32 && width == io_width_t::dword)
3931 		return ide_altio_r(port, io_width_t::word) + (ide_altio_r(port + 2u, io_width_t::word) << 16u);
3932 	else if (ide->ignore_pio32 && width == io_width_t::dword)
3933 		return UINT32_MAX;
3934 
3935 	dev = ide->device[ide->select];
3936 
3937 	port &= 1;
3938 
3939 	if (port == 0) /*3F6(R) status, does NOT clear interrupt*/
3940 		return (dev != nullptr) ? dev->status : ide->status;
3941 	else /*3F7(R) Drive Address Register*/
3942 		return 0x80u | (ide->select == 0 ? 0u : 1u) | (ide->select == 1 ? 0u : 2u) |
3943 		       ((dev != nullptr) ? (((dev->drivehead & 0xFu) ^ 0xFu) << 2u) : 0x3Cu);
3944 
3945 	return UINT32_MAX;
3946 }
3947 
ide_baseio_r(io_port_t port,io_width_t width)3948 static uint32_t ide_baseio_r(io_port_t port, io_width_t width)
3949 {
3950 	IDEController *ide = match_ide_controller(port);
3951 	IDEDevice *dev;
3952 	uint32_t ret = UINT32_MAX;
3953 
3954 	if (ide == nullptr) {
3955 		LOG_WARNING("IDE: port read from I/O port not registered to IDE, yet callback triggered");
3956 		return UINT32_MAX;
3957 	}
3958 
3959 	if (!ide->enable_pio32 && width == io_width_t::dword)
3960 		return ide_baseio_r(port, io_width_t::word) + (ide_baseio_r(port + 2, io_width_t::word) << 16);
3961 	else if (ide->ignore_pio32 && width == io_width_t::dword)
3962 		return UINT32_MAX;
3963 
3964 	dev = ide->device[ide->select];
3965 
3966 	port &= 7;
3967 
3968 	switch (port) {
3969 	case 0: /* 1F0 */ ret = (dev != nullptr) ? dev->data_read(width) : 0xFFFFFFFFUL; break;
3970 	case 1: /* 1F1 */ ret = (dev != nullptr) ? dev->feature : 0x00; break;
3971 	case 2: /* 1F2 */ ret = (dev != nullptr) ? dev->count : 0x00; break;
3972 	case 3: /* 1F3 */ ret = (dev != nullptr) ? dev->lba[0] : 0x00; break;
3973 	case 4: /* 1F4 */ ret = (dev != nullptr) ? dev->lba[1] : 0x00; break;
3974 	case 5: /* 1F5 */ ret = (dev != nullptr) ? dev->lba[2] : 0x00; break;
3975 	case 6: /* 1F6 */ ret = ide->drivehead; break;
3976 	case 7: /* 1F7 */
3977 		/* if an IDE device exists at selection return it's status, else return our status */
3978 		if (dev && dev->status & IDE_STATUS_BUSY) {
3979 		} else if (dev == nullptr && ide->status & IDE_STATUS_BUSY) {
3980 		} else {
3981 			ide->lower_irq();
3982 		}
3983 
3984 		ret = (dev != nullptr) ? dev->status : ide->status;
3985 		break;
3986 	}
3987 
3988 	return ret;
3989 }
3990 
ide_baseio_w(io_port_t port,io_val_t val,io_width_t width)3991 static void ide_baseio_w(io_port_t port, io_val_t val, io_width_t width)
3992 {
3993 	IDEController *ide = match_ide_controller(port);
3994 	IDEDevice *dev;
3995 
3996 	if (ide == nullptr) {
3997 		LOG_WARNING("IDE: port read from I/O port not registered to IDE, yet callback triggered");
3998 		return;
3999 	}
4000 
4001 	if (!ide->enable_pio32 && width == io_width_t::dword) {
4002 		ide_baseio_w(port, val & 0xFFFF, io_width_t::word);
4003 		ide_baseio_w(port + 2, val >> 16, io_width_t::word);
4004 		return;
4005 	} else if (ide->ignore_pio32 && width == io_width_t::dword)
4006 		return;
4007 
4008 	dev = ide->device[ide->select];
4009 
4010 	port &= 7;
4011 
4012 	/* ignore I/O writes if the controller is busy */
4013 	if (dev) {
4014 		if (dev->status & IDE_STATUS_BUSY) {
4015 			if (port == 6 && ((val >> 4) & 1) == ide->select) {
4016 				/* some MS-DOS drivers like ATAPICD.SYS are just very pedantic about writing
4017 				 * to port +6 to ensure the right drive is selected */
4018 				return;
4019 			} else {
4020 				LOG_WARNING("IDE: W-%03X %02X BUSY DROP [DEV]", port + ide->base_io, (int)val);
4021 				return;
4022 			}
4023 		}
4024 	} else if (ide->status & IDE_STATUS_BUSY) {
4025 		if (port == 6 && ((val >> 4) & 1) == ide->select) {
4026 			/* some MS-DOS drivers like ATAPICD.SYS are just very pedantic about writing to port
4027 			 * +6 to ensure the right drive is selected */
4028 			return;
4029 		} else {
4030 			LOG_WARNING("IDE: W-%03X %02X BUSY DROP [IDE]", port + ide->base_io, (int)val);
4031 			return;
4032 		}
4033 	}
4034 
4035 #if 0
4036     if (ide == idecontroller[1])
4037         LOG_MSG("IDE: baseio write port %u val %02x",(uint32_t)port,(uint32_t)val);
4038 #endif
4039 
4040 	if (port >= 1 && port <= 5 && dev && !dev->allow_writing) {
4041 		LOG_WARNING("IDE: Write to port %u val %02x when device not ready to accept writing",
4042 		        (uint32_t)port, val);
4043 	}
4044 
4045 	switch (port) {
4046 	case 0: /* 1F0 */
4047 		if (dev)
4048 			dev->data_write(val, width); /* <- TBD: what about 32-bit PIO modes? */
4049 		break;
4050 	case 1:                                /* 1F1 */
4051 		if (dev && dev->allow_writing) /* TBD: LBA48 16-bit wide register */
4052 			dev->feature = check_cast<uint16_t>(val);
4053 		break;
4054 	case 2:                                /* 1F2 */
4055 		if (dev && dev->allow_writing) /* TBD: LBA48 16-bit wide register */
4056 			dev->count = check_cast<uint16_t>(val);
4057 		break;
4058 	case 3:                                /* 1F3 */
4059 		if (dev && dev->allow_writing) /* TBD: LBA48 16-bit wide register */
4060 			dev->lba[0] = check_cast<uint16_t>(val);
4061 		break;
4062 	case 4:                                /* 1F4 */
4063 		if (dev && dev->allow_writing) /* TBD: LBA48 16-bit wide register */
4064 			dev->lba[1] = check_cast<uint16_t>(val);
4065 		break;
4066 	case 5:                                /* 1F5 */
4067 		if (dev && dev->allow_writing) /* TBD: LBA48 16-bit wide register */
4068 			dev->lba[2] = check_cast<uint16_t>(val);
4069 		break;
4070 	case 6: /* 1F6 */
4071 		if (((val >> 4) & 1) != ide->select) {
4072 			ide->lower_irq();
4073 			/* update select pointer if bit 4 changes.
4074 			   also emulate IDE busy state when changing drives */
4075 			if (dev)
4076 				dev->deselect();
4077 			ide->select = (val >> 4) & 1;
4078 			dev = ide->device[ide->select];
4079 			if (dev)
4080 				dev->select(check_cast<uint8_t>(val), 1);
4081 			else
4082 				ide->status = 0; /* NTS: if there is no drive there you're supposed to not
4083 				                    have anything set */
4084 		} else if (dev) {
4085 			dev->select(check_cast<uint8_t>(val), 0);
4086 		} else {
4087 			ide->status = 0; /* NTS: if there is no drive there you're supposed to not have anything set */
4088 		}
4089 
4090 		ide->drivehead = check_cast<uint8_t>(val);
4091 		break;
4092 	case 7: /* 1F7 */
4093 		if (dev)
4094 			dev->writecommand(check_cast<uint8_t>(val));
4095 		break;
4096 	}
4097 }
4098