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