- added instructions how to update the online documentation
[bochs-mirror.git] / iodev / harddrv.cc
blob0e6157af0b9371ae16865309a50ed3524190b3af
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: harddrv.cc,v 1.216 2008/12/11 18:01:56 vruppert Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2002 MandrakeSoft S.A.
6 //
7 // MandrakeSoft S.A.
8 // 43, rue d'Aboukir
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 /////////////////////////////////////////////////////////////////////////
28 // Useful docs:
29 // AT Attachment with Packet Interface
30 // working draft by T13 at www.t13.org
32 // Define BX_PLUGGABLE in files that can be compiled into plugins. For
33 // platforms that require a special tag on exported symbols, BX_PLUGGABLE
34 // is used to know when we are exporting symbols and when we are importing.
35 #define BX_PLUGGABLE
37 #include "iodev.h"
38 #include "hdimage.h"
39 #include "vmware3.h"
40 #include "vmware4.h"
41 #include "cdrom.h"
43 #define LOG_THIS theHardDrive->
45 #define INDEX_PULSE_CYCLE 10
47 #define PACKET_SIZE 12
49 // some packet handling macros
50 #define EXTRACT_FIELD(arr,byte,start,num_bits) (((arr)[(byte)] >> (start)) & ((1 << (num_bits)) - 1))
51 #define get_packet_field(c,b,s,n) (EXTRACT_FIELD((BX_SELECTED_CONTROLLER((c)).buffer),(b),(s),(n)))
52 #define get_packet_byte(c,b) (BX_SELECTED_CONTROLLER((c)).buffer[(b)])
53 #define get_packet_word(c,b) (((Bit16u)BX_SELECTED_CONTROLLER((c)).buffer[(b)] << 8) | BX_SELECTED_CONTROLLER((c)).buffer[(b)+1])
56 #define BX_CONTROLLER(c,a) (BX_HD_THIS channels[(c)].drives[(a)]).controller
57 #define BX_DRIVE(c,a) (BX_HD_THIS channels[(c)].drives[(a)])
59 #define BX_DRIVE_IS_PRESENT(c,a) (BX_HD_THIS channels[(c)].drives[(a)].device_type != IDE_NONE)
60 #define BX_DRIVE_IS_HD(c,a) (BX_HD_THIS channels[(c)].drives[(a)].device_type == IDE_DISK)
61 #define BX_DRIVE_IS_CD(c,a) (BX_HD_THIS channels[(c)].drives[(a)].device_type == IDE_CDROM)
63 #define BX_MASTER_IS_PRESENT(c) BX_DRIVE_IS_PRESENT((c),0)
64 #define BX_SLAVE_IS_PRESENT(c) BX_DRIVE_IS_PRESENT((c),1)
65 #define BX_ANY_IS_PRESENT(c) (BX_DRIVE_IS_PRESENT((c),0) || BX_DRIVE_IS_PRESENT((c),1))
67 #define BX_SELECTED_CONTROLLER(c) (BX_CONTROLLER((c),BX_HD_THIS channels[(c)].drive_select))
68 #define BX_SELECTED_DRIVE(c) (BX_DRIVE((c),BX_HD_THIS channels[(c)].drive_select))
69 #define BX_MASTER_SELECTED(c) (!BX_HD_THIS channels[(c)].drive_select)
70 #define BX_SLAVE_SELECTED(c) (BX_HD_THIS channels[(c)].drive_select)
72 #define BX_SELECTED_IS_PRESENT(c) (BX_DRIVE_IS_PRESENT((c),BX_SLAVE_SELECTED((c))))
73 #define BX_SELECTED_IS_HD(c) (BX_DRIVE_IS_HD((c),BX_SLAVE_SELECTED((c))))
74 #define BX_SELECTED_IS_CD(c) (BX_DRIVE_IS_CD((c),BX_SLAVE_SELECTED((c))))
76 #define BX_SELECTED_MODEL(c) (BX_HD_THIS channels[(c)].drives[BX_HD_THIS channels[(c)].drive_select].model_no)
77 #define BX_SELECTED_TYPE_STRING(channel) ((BX_SELECTED_IS_CD(channel)) ? "CD-ROM" : "DISK")
79 #define WRITE_FEATURES(c,a) do { Bit8u _a = a; \
80 BX_CONTROLLER((c),0).hob.feature = BX_CONTROLLER((c),0).features; \
81 BX_CONTROLLER((c),1).hob.feature = BX_CONTROLLER((c),1).features; \
82 BX_CONTROLLER((c),0).features = _a; BX_CONTROLLER((c),1).features = _a; } while(0)
83 #define WRITE_SECTOR_COUNT(c,a) do { Bit8u _a = a; \
84 BX_CONTROLLER((c),0).hob.nsector = BX_CONTROLLER((c),0).sector_count; \
85 BX_CONTROLLER((c),1).hob.nsector = BX_CONTROLLER((c),1).sector_count; \
86 BX_CONTROLLER((c),0).sector_count = _a; BX_CONTROLLER((c),1).sector_count = _a; } while(0)
87 #define WRITE_SECTOR_NUMBER(c,a) do { Bit8u _a = a; \
88 BX_CONTROLLER((c),0).hob.sector = BX_CONTROLLER((c),0).sector_no; \
89 BX_CONTROLLER((c),1).hob.sector = BX_CONTROLLER((c),1).sector_no; \
90 BX_CONTROLLER((c),0).sector_no = _a; BX_CONTROLLER((c),1).sector_no = _a; } while(0)
91 #define WRITE_CYLINDER_LOW(c,a) do { Bit8u _a = a; \
92 BX_CONTROLLER((c),0).hob.lcyl = (Bit8u)(BX_CONTROLLER((c),0).cylinder_no & 0xff); \
93 BX_CONTROLLER((c),1).hob.lcyl = (Bit8u)(BX_CONTROLLER((c),1).cylinder_no & 0xff); \
94 BX_CONTROLLER((c),0).cylinder_no = (BX_CONTROLLER((c),0).cylinder_no & 0xff00) | _a; \
95 BX_CONTROLLER((c),1).cylinder_no = (BX_CONTROLLER((c),1).cylinder_no & 0xff00) | _a; } while(0)
96 #define WRITE_CYLINDER_HIGH(c,a) do { Bit16u _a = a; \
97 BX_CONTROLLER((c),0).hob.hcyl = (Bit8u)(BX_CONTROLLER((c),0).cylinder_no >> 8); \
98 BX_CONTROLLER((c),1).hob.hcyl = (Bit8u)(BX_CONTROLLER((c),1).cylinder_no >> 8); \
99 BX_CONTROLLER((c),0).cylinder_no = (_a << 8) | (BX_CONTROLLER((c),0).cylinder_no & 0xff); \
100 BX_CONTROLLER((c),1).cylinder_no = (_a << 8) | (BX_CONTROLLER((c),1).cylinder_no & 0xff); } while(0)
101 #define WRITE_HEAD_NO(c,a) do { Bit8u _a = a; BX_CONTROLLER((c),0).head_no = _a; BX_CONTROLLER((c),1).head_no = _a; } while(0)
102 #define WRITE_LBA_MODE(c,a) do { Bit8u _a = a; BX_CONTROLLER((c),0).lba_mode = _a; BX_CONTROLLER((c),1).lba_mode = _a; } while(0)
104 BX_CPP_INLINE Bit16u read_16bit(const Bit8u* buf)
106 return (buf[0] << 8) | buf[1];
109 BX_CPP_INLINE Bit32u read_32bit(const Bit8u* buf)
111 return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
114 bx_hard_drive_c *theHardDrive = NULL;
116 int libharddrv_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
118 theHardDrive = new bx_hard_drive_c();
119 bx_devices.pluginHardDrive = theHardDrive;
120 BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theHardDrive, BX_PLUGIN_HARDDRV);
121 return(0); // Success
124 void libharddrv_LTX_plugin_fini(void)
126 delete theHardDrive;
129 bx_hard_drive_c::bx_hard_drive_c()
131 #if DLL_HD_SUPPORT
132 # error code must be fixed to use DLL_HD_SUPPORT and 4 ata channels
133 #endif
135 put("HD");
136 settype(HDLOG);
137 for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
138 for (Bit8u device=0; device<2; device ++) {
139 channels[channel].drives[device].hard_drive = NULL;
140 #ifdef LOWLEVEL_CDROM
141 channels[channel].drives[device].cdrom.cd = NULL;
142 #endif
145 iolight_timer_index = BX_NULL_TIMER_HANDLE;
148 bx_hard_drive_c::~bx_hard_drive_c()
150 for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
151 for (Bit8u device=0; device<2; device ++) {
152 if (channels[channel].drives[device].hard_drive != NULL) {
153 channels[channel].drives[device].hard_drive->close();
154 delete channels[channel].drives[device].hard_drive;
155 channels[channel].drives[device].hard_drive = NULL;
157 #ifdef LOWLEVEL_CDROM
158 if (channels[channel].drives[device].cdrom.cd != NULL) {
159 delete channels[channel].drives[device].cdrom.cd;
160 channels[channel].drives[device].cdrom.cd = NULL;
162 #endif
165 BX_DEBUG(("Exit"));
168 void bx_hard_drive_c::init(void)
170 Bit8u channel, image_mode;
171 char string[5];
172 char sbtext[8];
173 char ata_name[20];
174 bx_list_c *base;
176 BX_DEBUG(("Init $Id: harddrv.cc,v 1.216 2008/12/11 18:01:56 vruppert Exp $"));
178 for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
179 sprintf(ata_name, "ata.%d.resources", channel);
180 base = (bx_list_c*) SIM->get_param(ata_name);
181 if (SIM->get_param_bool("enabled", base)->get() == 1) {
182 BX_HD_THIS channels[channel].ioaddr1 = SIM->get_param_num("ioaddr1", base)->get();
183 BX_HD_THIS channels[channel].ioaddr2 = SIM->get_param_num("ioaddr2", base)->get();
184 BX_HD_THIS channels[channel].irq = SIM->get_param_num("irq", base)->get();
186 // Coherency check
187 if ((BX_HD_THIS channels[channel].ioaddr1 == 0) ||
188 (BX_HD_THIS channels[channel].ioaddr2 == 0) ||
189 (BX_HD_THIS channels[channel].irq == 0))
191 BX_PANIC(("incoherency for ata channel %d: io1=0x%x, io2=%x, irq=%d",
192 channel,
193 BX_HD_THIS channels[channel].ioaddr1,
194 BX_HD_THIS channels[channel].ioaddr2,
195 BX_HD_THIS channels[channel].irq));
198 else {
199 BX_HD_THIS channels[channel].ioaddr1 = 0;
200 BX_HD_THIS channels[channel].ioaddr2 = 0;
201 BX_HD_THIS channels[channel].irq = 0;
205 for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
206 sprintf(string ,"ATA%d", channel);
208 if (BX_HD_THIS channels[channel].irq != 0)
209 DEV_register_irq(BX_HD_THIS channels[channel].irq, string);
211 if (BX_HD_THIS channels[channel].ioaddr1 != 0) {
212 DEV_register_ioread_handler(this, read_handler,
213 BX_HD_THIS channels[channel].ioaddr1, string, 6);
214 DEV_register_iowrite_handler(this, write_handler,
215 BX_HD_THIS channels[channel].ioaddr1, string, 6);
216 for (unsigned addr=0x1; addr<=0x7; addr++) {
217 DEV_register_ioread_handler(this, read_handler,
218 BX_HD_THIS channels[channel].ioaddr1+addr, string, 1);
219 DEV_register_iowrite_handler(this, write_handler,
220 BX_HD_THIS channels[channel].ioaddr1+addr, string, 1);
224 // We don't want to register addresses 0x3f6 and 0x3f7 as they are handled by the floppy controller
225 if ((BX_HD_THIS channels[channel].ioaddr2 != 0) && (BX_HD_THIS channels[channel].ioaddr2 != 0x3f0)) {
226 for (unsigned addr=0x6; addr<=0x7; addr++) {
227 DEV_register_ioread_handler(this, read_handler,
228 BX_HD_THIS channels[channel].ioaddr2+addr, string, 1);
229 DEV_register_iowrite_handler(this, write_handler,
230 BX_HD_THIS channels[channel].ioaddr2+addr, string, 1);
234 BX_HD_THIS channels[channel].drive_select = 0;
237 channel = 0;
238 BX_HD_THIS cdrom_count = 0;
239 for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
240 for (Bit8u device=0; device<2; device ++) {
241 sprintf(ata_name, "ata.%d.%s", channel, (device==0)?"master":"slave");
242 base = (bx_list_c*) SIM->get_param(ata_name);
244 // Initialize controller state, even if device is not present
245 BX_CONTROLLER(channel,device).status.busy = 0;
246 BX_CONTROLLER(channel,device).status.drive_ready = 1;
247 BX_CONTROLLER(channel,device).status.write_fault = 0;
248 BX_CONTROLLER(channel,device).status.seek_complete = 1;
249 BX_CONTROLLER(channel,device).status.drq = 0;
250 BX_CONTROLLER(channel,device).status.corrected_data = 0;
251 BX_CONTROLLER(channel,device).status.index_pulse = 0;
252 BX_CONTROLLER(channel,device).status.index_pulse_count = 0;
253 BX_CONTROLLER(channel,device).status.err = 0;
255 BX_CONTROLLER(channel,device).error_register = 0x01; // diagnostic code: no error
256 BX_CONTROLLER(channel,device).head_no = 0;
257 BX_CONTROLLER(channel,device).sector_count = 1;
258 BX_CONTROLLER(channel,device).sector_no = 1;
259 BX_CONTROLLER(channel,device).cylinder_no = 0;
260 BX_CONTROLLER(channel,device).current_command = 0x00;
261 BX_CONTROLLER(channel,device).buffer_index = 0;
263 BX_CONTROLLER(channel,device).control.reset = 0;
264 BX_CONTROLLER(channel,device).control.disable_irq = 0;
265 BX_CONTROLLER(channel,device).reset_in_progress = 0;
267 BX_CONTROLLER(channel,device).multiple_sectors = 0;
268 BX_CONTROLLER(channel,device).lba_mode = 0;
270 BX_CONTROLLER(channel,device).features = 0;
271 BX_CONTROLLER(channel,device).mdma_mode = 0;
272 BX_CONTROLLER(channel,device).udma_mode = 0;
274 // If not present
275 BX_HD_THIS channels[channel].drives[device].device_type = IDE_NONE;
276 BX_HD_THIS channels[channel].drives[device].statusbar_id = -1;
277 BX_HD_THIS channels[channel].drives[device].iolight_counter = 0;
278 BX_HD_THIS channels[channel].drives[device].identify_set = 0;
279 if (!SIM->get_param_bool("present", base)->get()) continue;
281 // Make model string
282 strncpy((char*)BX_HD_THIS channels[channel].drives[device].model_no,
283 SIM->get_param_string("model", base)->getptr(), 40);
284 while (strlen((char *)BX_HD_THIS channels[channel].drives[device].model_no) < 40) {
285 strcat((char*)BX_HD_THIS channels[channel].drives[device].model_no, " ");
287 BX_HD_THIS channels[channel].drives[device].model_no[40] = 0;
289 if (SIM->get_param_enum("type", base)->get() == BX_ATA_DEVICE_DISK) {
290 BX_DEBUG(("Hard-Disk on target %d/%d",channel,device));
291 BX_HD_THIS channels[channel].drives[device].device_type = IDE_DISK;
292 sprintf(sbtext, "HD:%d-%s", channel, device?"S":"M");
293 BX_HD_THIS channels[channel].drives[device].statusbar_id =
294 bx_gui->register_statusitem(sbtext);
296 int cyl = SIM->get_param_num("cylinders", base)->get();
297 int heads = SIM->get_param_num("heads", base)->get();
298 int spt = SIM->get_param_num("spt", base)->get();
299 Bit64u disk_size = (Bit64u)cyl * heads * spt * 512;
301 /* instantiate the right class */
302 image_mode = SIM->get_param_enum("mode", base)->get();
303 switch (image_mode) {
305 case BX_ATA_MODE_FLAT:
306 BX_INFO(("HD on ata%d-%d: '%s' 'flat' mode ", channel, device,
307 SIM->get_param_string("path", base)->getptr()));
308 channels[channel].drives[device].hard_drive = new default_image_t();
309 break;
311 case BX_ATA_MODE_CONCAT:
312 BX_INFO(("HD on ata%d-%d: '%s' 'concat' mode ", channel, device,
313 SIM->get_param_string("path", base)->getptr()));
314 channels[channel].drives[device].hard_drive = new concat_image_t();
315 break;
317 #if EXTERNAL_DISK_SIMULATOR
318 case BX_ATA_MODE_EXTDISKSIM:
319 BX_INFO(("HD on ata%d-%d: '%s' 'External Simulator' mode ", channel, device,
320 SIM->get_param_string("path", base)->getptr()));
321 channels[channel].drives[device].hard_drive = new EXTERNAL_DISK_SIMULATOR_CLASS();
322 break;
323 #endif //EXTERNAL_DISK_SIMULATOR
325 #if DLL_HD_SUPPORT
326 case BX_ATA_MODE_DLL_HD:
327 BX_INFO(("HD on ata%d-%d: '%s' 'dll' mode ", channel, device,
328 SIM->get_param_string("path", base)->getptr()));
329 channels[channel].drives[device].hard_drive = new dll_image_t();
330 break;
331 #endif //DLL_HD_SUPPORT
333 case BX_ATA_MODE_SPARSE:
334 BX_INFO(("HD on ata%d-%d: '%s' 'sparse' mode ", channel, device,
335 SIM->get_param_string("path", base)->getptr()));
336 channels[channel].drives[device].hard_drive = new sparse_image_t();
337 break;
339 case BX_ATA_MODE_VMWARE3:
340 BX_INFO(("HD on ata%d-%d: '%s' 'vmware3' mode ", channel, device,
341 SIM->get_param_string("path", base)->getptr()));
342 channels[channel].drives[device].hard_drive = new vmware3_image_t();
343 break;
345 case BX_ATA_MODE_VMWARE4:
346 BX_INFO(("HD on ata%d-%d: '%s' 'vmware4' mode ", channel, device,
347 SIM->get_param_string("path", base)->getptr()));
348 channels[channel].drives[device].hard_drive = new vmware4_image_t();
349 break;
351 case BX_ATA_MODE_UNDOABLE:
352 BX_INFO(("HD on ata%d-%d: '%s' 'undoable' mode ", channel, device,
353 SIM->get_param_string("path", base)->getptr()));
354 channels[channel].drives[device].hard_drive = new undoable_image_t(
355 SIM->get_param_string("journal", base)->getptr());
356 break;
358 case BX_ATA_MODE_GROWING:
359 BX_INFO(("HD on ata%d-%d: '%s' 'growing' mode ", channel, device,
360 SIM->get_param_string("path", base)->getptr()));
361 channels[channel].drives[device].hard_drive = new growing_image_t();
362 break;
364 case BX_ATA_MODE_VOLATILE:
365 BX_INFO(("HD on ata%d-%d: '%s' 'volatile' mode ", channel, device,
366 SIM->get_param_string("path", base)->getptr()));
367 channels[channel].drives[device].hard_drive = new volatile_image_t(
368 SIM->get_param_string("journal", base)->getptr());
369 break;
371 #if BX_COMPRESSED_HD_SUPPORT
372 case BX_ATA_MODE_Z_UNDOABLE:
373 BX_PANIC(("z-undoable disk support not implemented"));
374 #if 0
375 BX_INFO(("HD on ata%d-%d: '%s' 'z-undoable' mode ", channel, device,
376 SIM->get_param_string("path", base)->getptr()));
377 channels[channel].drives[device].hard_drive = new z_undoable_image_t(disk_size,
378 SIM->get_param_string("journal", base)->getptr());
379 #endif
380 break;
382 case BX_ATA_MODE_Z_VOLATILE:
383 BX_PANIC(("z-volatile disk support not implemented"));
384 #if 0
385 BX_INFO(("HD on ata%d-%d: '%s' 'z-volatile' mode ", channel, device,
386 SIM->get_param_string("path", base)->getptr()));
387 channels[channel].drives[device].hard_drive = new z_volatile_image_t(disk_size,
388 SIM->get_param_string("journal", base)->getptr());
389 #endif
390 break;
391 #endif //BX_COMPRESSED_HD_SUPPORT
393 default:
394 BX_PANIC(("HD on ata%d-%d: '%s' unsupported HD mode : %s", channel, device,
395 SIM->get_param_string("path", base)->getptr(),
396 atadevice_mode_names[image_mode]));
397 break;
400 BX_HD_THIS channels[channel].drives[device].hard_drive->cylinders = cyl;
401 BX_HD_THIS channels[channel].drives[device].hard_drive->heads = heads;
402 BX_HD_THIS channels[channel].drives[device].hard_drive->sectors = spt;
403 bx_bool geometry_detect = 0;
405 if ((image_mode == BX_ATA_MODE_FLAT) || (image_mode == BX_ATA_MODE_CONCAT) ||
406 (image_mode == BX_ATA_MODE_GROWING) || (image_mode == BX_ATA_MODE_UNDOABLE) ||
407 (image_mode == BX_ATA_MODE_VOLATILE) || (image_mode == BX_ATA_MODE_VMWARE3) ||
408 (image_mode == BX_ATA_MODE_VMWARE4) || (image_mode == BX_ATA_MODE_SPARSE)) {
409 geometry_detect = ((cyl == 0) || (image_mode == BX_ATA_MODE_VMWARE3) || (image_mode == BX_ATA_MODE_VMWARE4));
410 if ((heads == 0) || (spt == 0)) {
411 BX_PANIC(("ata%d-%d cannot have zero heads, or sectors/track", channel, device));
413 } else {
414 if (cyl == 0 || heads == 0 || spt == 0) {
415 BX_PANIC(("ata%d-%d cannot have zero cylinders, heads, or sectors/track", channel, device));
419 /* open hard drive image file */
420 if ((BX_HD_THIS channels[channel].drives[device].hard_drive->open(SIM->get_param_string("path", base)->getptr())) < 0) {
421 BX_PANIC(("ata%d-%d: could not open hard drive image file '%s'", channel, device, SIM->get_param_string("path", base)->getptr()));
424 if (BX_HD_THIS channels[channel].drives[device].hard_drive->hd_size != 0) {
425 if (geometry_detect) {
426 // Autodetect number of cylinders
427 disk_size = BX_HD_THIS channels[channel].drives[device].hard_drive->hd_size;
428 if (image_mode != BX_ATA_MODE_VMWARE3 && image_mode != BX_ATA_MODE_VMWARE4) {
429 cyl = (int)(disk_size / (heads * spt * 512));
430 if (disk_size != (Bit64u)(cyl * heads * spt * 512)) {
431 BX_PANIC(("ata%d-%d: geometry autodetection failed", channel, device));
433 BX_HD_THIS channels[channel].drives[device].hard_drive->cylinders = cyl;
434 SIM->get_param_num("cylinders", base)->set(cyl);
435 } else {
436 cyl = BX_HD_THIS channels[channel].drives[device].hard_drive->cylinders;
437 heads = BX_HD_THIS channels[channel].drives[device].hard_drive->heads;
438 spt = BX_HD_THIS channels[channel].drives[device].hard_drive->sectors;
440 BX_INFO(("ata%d-%d: autodetect geometry: CHS=%d/%d/%d", channel, device, cyl, heads, spt));
441 } else {
442 if (disk_size != BX_HD_THIS channels[channel].drives[device].hard_drive->hd_size) {
443 BX_PANIC(("ata%d-%d disk size doesn't match specified geometry", channel, device));
444 // workaround large files problem with diskimages
445 BX_HD_THIS channels[channel].drives[device].hard_drive->hd_size = disk_size;
448 } else if (geometry_detect) {
449 BX_PANIC(("ata%d-%d image doesn't support geometry detection", channel, device));
451 } else if (SIM->get_param_enum("type", base)->get() == BX_ATA_DEVICE_CDROM) {
452 BX_DEBUG(("CDROM on target %d/%d",channel,device));
453 BX_HD_THIS channels[channel].drives[device].device_type = IDE_CDROM;
454 BX_HD_THIS channels[channel].drives[device].cdrom.locked = 0;
455 BX_HD_THIS channels[channel].drives[device].sense.sense_key = SENSE_NONE;
456 BX_HD_THIS channels[channel].drives[device].sense.asc = 0;
457 BX_HD_THIS channels[channel].drives[device].sense.ascq = 0;
458 sprintf(sbtext, "CD:%d-%s", channel, device?"S":"M");
459 BX_HD_THIS channels[channel].drives[device].statusbar_id =
460 bx_gui->register_statusitem(sbtext);
461 BX_HD_THIS cdrom_count++;
462 BX_HD_THIS channels[channel].drives[device].device_num = BX_HD_THIS cdrom_count + 48;
464 // Check bit fields
465 BX_CONTROLLER(channel,device).sector_count = 0;
466 BX_CONTROLLER(channel,device).interrupt_reason.c_d = 1;
467 if (BX_CONTROLLER(channel,device).sector_count != 0x01)
468 BX_PANIC(("interrupt reason bit field error"));
470 BX_CONTROLLER(channel,device).sector_count = 0;
471 BX_CONTROLLER(channel,device).interrupt_reason.i_o = 1;
472 if (BX_CONTROLLER(channel,device).sector_count != 0x02)
473 BX_PANIC(("interrupt reason bit field error"));
475 BX_CONTROLLER(channel,device).sector_count = 0;
476 BX_CONTROLLER(channel,device).interrupt_reason.rel = 1;
477 if (BX_CONTROLLER(channel,device).sector_count != 0x04)
478 BX_PANIC(("interrupt reason bit field error"));
480 BX_CONTROLLER(channel,device).sector_count = 0;
481 BX_CONTROLLER(channel,device).interrupt_reason.tag = 3;
482 if (BX_CONTROLLER(channel,device).sector_count != 0x18)
483 BX_PANIC(("interrupt reason bit field error"));
484 BX_CONTROLLER(channel,device).sector_count = 0;
486 // allocate low level driver
487 #ifdef LOWLEVEL_CDROM
488 BX_HD_THIS channels[channel].drives[device].cdrom.cd = new LOWLEVEL_CDROM(SIM->get_param_string("path", base)->getptr());
489 BX_INFO(("CD on ata%d-%d: '%s'",channel, device, SIM->get_param_string("path", base)->getptr()));
491 if (SIM->get_param_enum("status", base)->get() == BX_INSERTED) {
492 if (BX_HD_THIS channels[channel].drives[device].cdrom.cd->insert_cdrom()) {
493 BX_INFO(("Media present in CD-ROM drive"));
494 BX_HD_THIS channels[channel].drives[device].cdrom.ready = 1;
495 Bit32u capacity = BX_HD_THIS channels[channel].drives[device].cdrom.cd->capacity();
496 BX_HD_THIS channels[channel].drives[device].cdrom.capacity = capacity;
497 BX_INFO(("Capacity is %d sectors (%.2f MB)", capacity, (float)capacity / 512.0));
498 } else {
499 BX_INFO(("Could not locate CD-ROM, continuing with media not present"));
500 BX_HD_THIS channels[channel].drives[device].cdrom.ready = 0;
501 SIM->get_param_enum("status", base)->set(BX_EJECTED);
504 else
505 #endif
507 BX_INFO(("Media not present in CD-ROM drive"));
508 BX_HD_THIS channels[channel].drives[device].cdrom.ready = 0;
514 // generate CMOS values for hard drive if not using a CMOS image
515 if (!SIM->get_param_bool(BXPN_CMOSIMAGE_ENABLED)->get()) {
516 DEV_cmos_set_reg(0x12, 0x00); // start out with: no drive 0, no drive 1
518 if (BX_DRIVE_IS_HD(0,0)) {
519 base = (bx_list_c*) SIM->get_param(BXPN_ATA0_MASTER);
520 // Flag drive type as Fh, use extended CMOS location as real type
521 DEV_cmos_set_reg(0x12, (DEV_cmos_get_reg(0x12) & 0x0f) | 0xf0);
522 DEV_cmos_set_reg(0x19, 47); // user definable type
523 // AMI BIOS: 1st hard disk #cyl low byte
524 DEV_cmos_set_reg(0x1b, (SIM->get_param_num("cylinders", base)->get() & 0x00ff));
525 // AMI BIOS: 1st hard disk #cyl high byte
526 DEV_cmos_set_reg(0x1c, (SIM->get_param_num("cylinders", base)->get() & 0xff00) >> 8);
527 // AMI BIOS: 1st hard disk #heads
528 DEV_cmos_set_reg(0x1d, (SIM->get_param_num("heads", base)->get()));
529 // AMI BIOS: 1st hard disk write precompensation cylinder, low byte
530 DEV_cmos_set_reg(0x1e, 0xff); // -1
531 // AMI BIOS: 1st hard disk write precompensation cylinder, high byte
532 DEV_cmos_set_reg(0x1f, 0xff); // -1
533 // AMI BIOS: 1st hard disk control byte
534 DEV_cmos_set_reg(0x20, (0xc0 | ((SIM->get_param_num("heads", base)->get() > 8) << 3)));
535 // AMI BIOS: 1st hard disk landing zone, low byte
536 DEV_cmos_set_reg(0x21, DEV_cmos_get_reg(0x1b));
537 // AMI BIOS: 1st hard disk landing zone, high byte
538 DEV_cmos_set_reg(0x22, DEV_cmos_get_reg(0x1c));
539 // AMI BIOS: 1st hard disk sectors/track
540 DEV_cmos_set_reg(0x23, SIM->get_param_num("spt", base)->get());
543 //set up cmos for second hard drive
544 if (BX_DRIVE_IS_HD(0,1)) {
545 base = (bx_list_c*) SIM->get_param(BXPN_ATA0_SLAVE);
546 BX_DEBUG(("1: I will put 0xf into the second hard disk field"));
547 // fill in lower 4 bits of 0x12 for second HD
548 DEV_cmos_set_reg(0x12, (DEV_cmos_get_reg(0x12) & 0xf0) | 0x0f);
549 DEV_cmos_set_reg(0x1a, 47); // user definable type
550 // AMI BIOS: 2nd hard disk #cyl low byte
551 DEV_cmos_set_reg(0x24, (SIM->get_param_num("cylinders", base)->get() & 0x00ff));
552 // AMI BIOS: 2nd hard disk #cyl high byte
553 DEV_cmos_set_reg(0x25, (SIM->get_param_num("cylinders", base)->get() & 0xff00) >> 8);
554 // AMI BIOS: 2nd hard disk #heads
555 DEV_cmos_set_reg(0x26, (SIM->get_param_num("heads", base)->get()));
556 // AMI BIOS: 2nd hard disk write precompensation cylinder, low byte
557 DEV_cmos_set_reg(0x27, 0xff); // -1
558 // AMI BIOS: 2nd hard disk write precompensation cylinder, high byte
559 DEV_cmos_set_reg(0x28, 0xff); // -1
560 // AMI BIOS: 2nd hard disk, 0x80 if heads>8
561 DEV_cmos_set_reg(0x29, (SIM->get_param_num("heads", base)->get() > 8) ? 0x80 : 0x00);
562 // AMI BIOS: 2nd hard disk landing zone, low byte
563 DEV_cmos_set_reg(0x2a, DEV_cmos_get_reg(0x24));
564 // AMI BIOS: 2nd hard disk landing zone, high byte
565 DEV_cmos_set_reg(0x2b, DEV_cmos_get_reg(0x25));
566 // AMI BIOS: 2nd hard disk sectors/track
567 DEV_cmos_set_reg(0x2c, SIM->get_param_num("spt", base)->get());
570 DEV_cmos_set_reg(0x39, 0);
571 DEV_cmos_set_reg(0x3a, 0);
572 for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
573 for (Bit8u device=0; device<2; device ++) {
574 sprintf(ata_name, "ata.%d.%s", channel, (device==0)?"master":"slave");
575 base = (bx_list_c*) SIM->get_param(ata_name);
576 if (SIM->get_param_bool("present", base)->get()) {
577 if (BX_DRIVE_IS_HD(channel,device)) {
578 Bit16u cylinders = SIM->get_param_num("cylinders", base)->get();
579 Bit16u heads = SIM->get_param_num("heads", base)->get();
580 Bit16u spt = SIM->get_param_num("spt", base)->get();
581 Bit8u translation = SIM->get_param_enum("translation", base)->get();
583 Bit8u reg = 0x39 + channel/2;
584 Bit8u bitshift = 2 * (device+(2 * (channel%2)));
586 // Find the right translation if autodetect
587 if (translation == BX_ATA_TRANSLATION_AUTO) {
588 if((cylinders <= 1024) && (heads <= 16) && (spt <= 63)) {
589 translation = BX_ATA_TRANSLATION_NONE;
591 else if (((Bit32u)cylinders * (Bit32u)heads) <= 131072) {
592 translation = BX_ATA_TRANSLATION_LARGE;
594 else translation = BX_ATA_TRANSLATION_LBA;
596 BX_INFO(("translation on ata%d-%d set to '%s'",channel, device,
597 translation==BX_ATA_TRANSLATION_NONE?"none":
598 translation==BX_ATA_TRANSLATION_LARGE?"large":
599 "lba"));
602 // FIXME we should test and warn
603 // - if LBA and spt != 63
604 // - if RECHS and heads != 16
605 // - if NONE and size > 1024*16*SPT blocks
606 // - if LARGE and size > 8192*16*SPT blocks
607 // - if RECHS and size > 1024*240*SPT blocks
608 // - if LBA and size > 1024*255*63, not that we can do much about it
610 switch(translation) {
611 case BX_ATA_TRANSLATION_NONE:
612 DEV_cmos_set_reg(reg, DEV_cmos_get_reg(reg) | (0 << bitshift));
613 break;
614 case BX_ATA_TRANSLATION_LBA:
615 DEV_cmos_set_reg(reg, DEV_cmos_get_reg(reg) | (1 << bitshift));
616 break;
617 case BX_ATA_TRANSLATION_LARGE:
618 DEV_cmos_set_reg(reg, DEV_cmos_get_reg(reg) | (2 << bitshift));
619 break;
620 case BX_ATA_TRANSLATION_RECHS:
621 DEV_cmos_set_reg(reg, DEV_cmos_get_reg(reg) | (3 << bitshift));
622 break;
629 // Set the "non-extended" boot device. This will default to DISKC if cdrom
630 if (SIM->get_param_enum(BXPN_BOOTDRIVE1)->get() != BX_BOOT_FLOPPYA) {
631 // system boot sequence C:, A:
632 DEV_cmos_set_reg(0x2d, DEV_cmos_get_reg(0x2d) & 0xdf);
633 } else { // 'a'
634 // system boot sequence A:, C:
635 DEV_cmos_set_reg(0x2d, DEV_cmos_get_reg(0x2d) | 0x20);
638 // Set the "extended" boot sequence, bytes 0x38 and 0x3D (needed for cdrom booting)
639 BX_INFO(("Using boot sequence %s, %s, %s",
640 SIM->get_param_enum(BXPN_BOOTDRIVE1)->get_selected(),
641 SIM->get_param_enum(BXPN_BOOTDRIVE2)->get_selected(),
642 SIM->get_param_enum(BXPN_BOOTDRIVE3)->get_selected()));
643 DEV_cmos_set_reg(0x3d, SIM->get_param_enum(BXPN_BOOTDRIVE1)->get() |
644 (SIM->get_param_enum(BXPN_BOOTDRIVE2)->get() << 4));
646 // Set the signature check flag in cmos, inverted for compatibility
647 DEV_cmos_set_reg(0x38, SIM->get_param_bool(BXPN_FLOPPYSIGCHECK)->get() |
648 (SIM->get_param_enum(BXPN_BOOTDRIVE3)->get() << 4));
649 BX_INFO(("Floppy boot signature check is %sabled",
650 SIM->get_param_bool(BXPN_FLOPPYSIGCHECK)->get() ? "dis" : "en"));
653 // register timer for HD/CD i/o light
654 if (BX_HD_THIS iolight_timer_index == BX_NULL_TIMER_HANDLE) {
655 BX_HD_THIS iolight_timer_index =
656 DEV_register_timer(this, iolight_timer_handler, 100000, 0,0, "HD/CD i/o light");
660 void bx_hard_drive_c::reset(unsigned type)
662 for (unsigned channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
663 if (BX_HD_THIS channels[channel].irq)
664 DEV_pic_lower_irq(BX_HD_THIS channels[channel].irq);
668 void bx_hard_drive_c::register_state(void)
670 unsigned i, j;
671 char cname[4], dname[8];
672 bx_list_c *chan, *drive, *status;
674 bx_list_c *list = new bx_list_c(SIM->get_bochs_root(), "hard_drive", "Hard Drive State", BX_MAX_ATA_CHANNEL);
675 for (i=0; i<BX_MAX_ATA_CHANNEL; i++) {
676 sprintf(cname, "%d", i);
677 chan = new bx_list_c(list, cname, 3);
678 for (j=0; j<2; j++) {
679 if (BX_DRIVE_IS_PRESENT(i, j)) {
680 sprintf(dname, "drive%d", i);
681 drive = new bx_list_c(chan, dname, 27);
682 new bx_shadow_data_c(drive, "buffer", BX_CONTROLLER(i, j).buffer, MAX_MULTIPLE_SECTORS * 512);
683 status = new bx_list_c(drive, "status", 9);
684 new bx_shadow_bool_c(status, "busy", &BX_CONTROLLER(i, j).status.busy);
685 new bx_shadow_bool_c(status, "drive_ready", &BX_CONTROLLER(i, j).status.drive_ready);
686 new bx_shadow_bool_c(status, "write_fault", &BX_CONTROLLER(i, j).status.write_fault);
687 new bx_shadow_bool_c(status, "seek_complete", &BX_CONTROLLER(i, j).status.seek_complete);
688 new bx_shadow_bool_c(status, "drq", &BX_CONTROLLER(i, j).status.drq);
689 new bx_shadow_bool_c(status, "corrected_data", &BX_CONTROLLER(i, j).status.corrected_data);
690 new bx_shadow_bool_c(status, "index_pulse", &BX_CONTROLLER(i, j).status.index_pulse);
691 new bx_shadow_num_c(status, "index_pulse_count", &BX_CONTROLLER(i, j).status.index_pulse_count);
692 new bx_shadow_bool_c(status, "err", &BX_CONTROLLER(i, j).status.err);
693 new bx_shadow_num_c(drive, "error_register", &BX_CONTROLLER(i, j).error_register, BASE_HEX);
694 new bx_shadow_num_c(drive, "head_no", &BX_CONTROLLER(i, j).head_no, BASE_HEX);
695 new bx_shadow_num_c(drive, "sector_count", &BX_CONTROLLER(i, j).sector_count, BASE_HEX);
696 new bx_shadow_num_c(drive, "sector_no", &BX_CONTROLLER(i, j).sector_no, BASE_HEX);
697 new bx_shadow_num_c(drive, "cylinder_no", &BX_CONTROLLER(i, j).cylinder_no, BASE_HEX);
698 new bx_shadow_num_c(drive, "buffer_size", &BX_CONTROLLER(i, j).buffer_size, BASE_HEX);
699 new bx_shadow_num_c(drive, "buffer_index", &BX_CONTROLLER(i, j).buffer_index, BASE_HEX);
700 new bx_shadow_num_c(drive, "drq_index", &BX_CONTROLLER(i, j).drq_index, BASE_HEX);
701 new bx_shadow_num_c(drive, "current_command", &BX_CONTROLLER(i, j).current_command, BASE_HEX);
702 new bx_shadow_num_c(drive, "multiple_sectors", &BX_CONTROLLER(i, j).multiple_sectors, BASE_HEX);
703 new bx_shadow_num_c(drive, "lba_mode", &BX_CONTROLLER(i, j).lba_mode, BASE_HEX);
704 new bx_shadow_num_c(drive, "packet_dma", &BX_CONTROLLER(i, j).packet_dma, BASE_HEX);
705 new bx_shadow_bool_c(drive, "control_reset", &BX_CONTROLLER(i, j).control.reset);
706 new bx_shadow_bool_c(drive, "control_disable_irq", &BX_CONTROLLER(i, j).control.disable_irq);
707 new bx_shadow_num_c(drive, "reset_in_progress", &BX_CONTROLLER(i, j).reset_in_progress, BASE_HEX);
708 new bx_shadow_num_c(drive, "features", &BX_CONTROLLER(i, j).features, BASE_HEX);
709 new bx_shadow_num_c(drive, "mdma_mode", &BX_CONTROLLER(i, j).mdma_mode, BASE_HEX);
710 new bx_shadow_num_c(drive, "udma_mode", &BX_CONTROLLER(i, j).udma_mode, BASE_HEX);
711 new bx_shadow_num_c(drive, "hob_feature", &BX_CONTROLLER(i, j).hob.feature, BASE_HEX);
712 new bx_shadow_num_c(drive, "hob_nsector", &BX_CONTROLLER(i, j).hob.nsector, BASE_HEX);
713 new bx_shadow_num_c(drive, "hob_sector", &BX_CONTROLLER(i, j).hob.sector, BASE_HEX);
714 new bx_shadow_num_c(drive, "hob_lcyl", &BX_CONTROLLER(i, j).hob.lcyl, BASE_HEX);
715 new bx_shadow_num_c(drive, "hob_hcyl", &BX_CONTROLLER(i, j).hob.hcyl, BASE_HEX);
716 new bx_shadow_num_c(drive, "num_sectors", &BX_CONTROLLER(i, j).num_sectors, BASE_HEX);
717 new bx_shadow_bool_c(drive, "cdrom_locked", &BX_HD_THIS channels[i].drives[j].cdrom.locked);
720 new bx_shadow_num_c(chan, "drive_select", &BX_HD_THIS channels[i].drive_select);
724 void bx_hard_drive_c::iolight_timer_handler(void *this_ptr)
726 bx_hard_drive_c *class_ptr = (bx_hard_drive_c *) this_ptr;
727 class_ptr->iolight_timer();
730 void bx_hard_drive_c::iolight_timer()
732 for (unsigned channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
733 for (unsigned device=0; device<2; device++) {
734 if (BX_HD_THIS channels[channel].drives[device].iolight_counter > 0) {
735 if (--BX_HD_THIS channels[channel].drives[device].iolight_counter)
736 bx_pc_system.activate_timer(BX_HD_THIS iolight_timer_index, 100000, 0);
737 else
738 bx_gui->statusbar_setitem(BX_HD_THIS channels[channel].drives[device].statusbar_id, 0);
744 #define GOTO_RETURN_VALUE if(io_len==4) { \
745 goto return_value32; \
747 else if(io_len==2) { \
748 value16=(Bit16u)value32; \
749 goto return_value16; \
751 else { \
752 value8=(Bit8u)value32; \
753 goto return_value8; \
757 // static IO port read callback handler
758 // redirects to non-static class handler to avoid virtual functions
759 Bit32u bx_hard_drive_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
761 #if !BX_USE_HD_SMF
762 bx_hard_drive_c *class_ptr = (bx_hard_drive_c *) this_ptr;
763 return class_ptr->read(address, io_len);
766 Bit32u bx_hard_drive_c::read(Bit32u address, unsigned io_len)
768 #else
769 UNUSED(this_ptr);
770 #endif // !BX_USE_HD_SMF
771 Bit8u value8;
772 Bit16u value16;
773 Bit32u value32;
775 Bit8u channel = BX_MAX_ATA_CHANNEL;
776 Bit32u port = 0xff; // undefined
778 for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
779 if ((address & 0xfff8) == BX_HD_THIS channels[channel].ioaddr1) {
780 port = address - BX_HD_THIS channels[channel].ioaddr1;
781 break;
783 else if ((address & 0xfff8) == BX_HD_THIS channels[channel].ioaddr2) {
784 port = address - BX_HD_THIS channels[channel].ioaddr2 + 0x10;
785 break;
789 if (channel == BX_MAX_ATA_CHANNEL) {
790 if ((address < 0x03f6) || (address > 0x03f7)) {
791 BX_PANIC(("read: unable to find ATA channel, ioport=0x%04x", address));
792 } else {
793 channel = 0;
794 port = address - 0x03e0;
798 switch (port) {
799 case 0x00: // hard disk data (16bit) 0x1f0
800 if (BX_SELECTED_CONTROLLER(channel).status.drq == 0) {
801 BX_ERROR(("IO read(0x%04x) with drq == 0: last command was %02xh",
802 address, (unsigned) BX_SELECTED_CONTROLLER(channel).current_command));
803 return(0);
805 BX_DEBUG(("IO read(0x%04x): current command is %02xh",
806 address, (unsigned) BX_SELECTED_CONTROLLER(channel).current_command));
807 switch (BX_SELECTED_CONTROLLER(channel).current_command) {
808 case 0x20: // READ SECTORS, with retries
809 case 0x21: // READ SECTORS, without retries
810 case 0xC4: // READ MULTIPLE SECTORS
811 case 0x24: // READ SECTORS EXT
812 case 0x29: // READ MULTIPLE EXT
813 if (BX_SELECTED_CONTROLLER(channel).buffer_index >= BX_SELECTED_CONTROLLER(channel).buffer_size)
814 BX_PANIC(("IO read(0x%04x): buffer_index >= %d", address, BX_SELECTED_CONTROLLER(channel).buffer_size));
816 #if BX_SupportRepeatSpeedups
817 if (DEV_bulk_io_quantum_requested()) {
818 unsigned transferLen, quantumsMax;
819 quantumsMax = (BX_SELECTED_CONTROLLER(channel).buffer_size - BX_SELECTED_CONTROLLER(channel).buffer_index) / io_len;
820 if (quantumsMax == 0)
821 BX_PANIC(("IO read(0x%04x): not enough space for read", address));
822 DEV_bulk_io_quantum_transferred() = DEV_bulk_io_quantum_requested();
823 if (quantumsMax < DEV_bulk_io_quantum_transferred())
824 DEV_bulk_io_quantum_transferred() = quantumsMax;
825 transferLen = io_len * DEV_bulk_io_quantum_transferred();
826 memcpy((Bit8u*) DEV_bulk_io_host_addr(),
827 &BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index], transferLen);
828 DEV_bulk_io_host_addr() += transferLen;
829 BX_SELECTED_CONTROLLER(channel).buffer_index += transferLen;
830 value32 = 0; // Value returned not important;
832 else
833 #endif
835 value32 = 0L;
836 switch(io_len){
837 case 4:
838 value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+3] << 24);
839 value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+2] << 16);
840 case 2:
841 value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+1] << 8);
842 value32 |= BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index];
844 BX_SELECTED_CONTROLLER(channel).buffer_index += io_len;
847 // if buffer completely read
848 if (BX_SELECTED_CONTROLLER(channel).buffer_index >= BX_SELECTED_CONTROLLER(channel).buffer_size) {
849 // update sector count, sector number, cylinder,
850 // drive, head, status
851 // if there are more sectors, read next one in...
853 if ((BX_SELECTED_CONTROLLER(channel).current_command == 0xC4) ||
854 (BX_SELECTED_CONTROLLER(channel).current_command == 0x29)) {
855 if (BX_SELECTED_CONTROLLER(channel).num_sectors > BX_SELECTED_CONTROLLER(channel).multiple_sectors) {
856 BX_SELECTED_CONTROLLER(channel).buffer_size = BX_SELECTED_CONTROLLER(channel).multiple_sectors * 512;
857 } else {
858 BX_SELECTED_CONTROLLER(channel).buffer_size = BX_SELECTED_CONTROLLER(channel).num_sectors * 512;
862 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
863 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
864 BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
865 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
866 BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
867 BX_SELECTED_CONTROLLER(channel).status.err = 0;
869 if (BX_SELECTED_CONTROLLER(channel).num_sectors==0) {
870 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
871 } else { /* read next one into controller buffer */
872 BX_SELECTED_CONTROLLER(channel).status.drq = 1;
873 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
875 if (ide_read_sector(channel, BX_SELECTED_CONTROLLER(channel).buffer,
876 BX_SELECTED_CONTROLLER(channel).buffer_size)) {
877 BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
878 raise_interrupt(channel);
882 GOTO_RETURN_VALUE;
883 break;
885 case 0xec: // IDENTIFY DEVICE
886 case 0xa1:
887 unsigned index;
889 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
890 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
891 BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
892 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
893 BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
894 BX_SELECTED_CONTROLLER(channel).status.err = 0;
896 index = BX_SELECTED_CONTROLLER(channel).buffer_index;
897 value32 = BX_SELECTED_CONTROLLER(channel).buffer[index];
898 index++;
899 if (io_len >= 2) {
900 value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index] << 8);
901 index++;
903 if (io_len == 4) {
904 value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index] << 16);
905 value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index+1] << 24);
906 index += 2;
908 BX_SELECTED_CONTROLLER(channel).buffer_index = index;
910 if (BX_SELECTED_CONTROLLER(channel).buffer_index >= 512) {
911 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
912 if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
913 BX_INFO(("Read all drive ID Bytes ..."));
915 GOTO_RETURN_VALUE;
916 break;
918 case 0xa0:
920 unsigned index = BX_SELECTED_CONTROLLER(channel).buffer_index;
921 unsigned increment = 0;
923 // Load block if necessary
924 if (index >= BX_SELECTED_CONTROLLER(channel).buffer_size) {
925 if (index > BX_SELECTED_CONTROLLER(channel).buffer_size)
926 BX_PANIC(("index > %d : %d", BX_SELECTED_CONTROLLER(channel).buffer_size, index));
927 switch (BX_SELECTED_DRIVE(channel).atapi.command) {
928 case 0x28: // read (10)
929 case 0xa8: // read (12)
930 case 0xbe: // read cd
931 #ifdef LOWLEVEL_CDROM
932 if (!BX_SELECTED_DRIVE(channel).cdrom.ready) {
933 BX_PANIC(("Read with CDROM not ready"));
935 /* set status bar conditions for device */
936 if (!BX_SELECTED_DRIVE(channel).iolight_counter)
937 bx_gui->statusbar_setitem(BX_SELECTED_DRIVE(channel).statusbar_id, 1);
938 BX_SELECTED_DRIVE(channel).iolight_counter = 5;
939 bx_pc_system.activate_timer(BX_HD_THIS iolight_timer_index, 100000, 0);
940 if (!BX_SELECTED_DRIVE(channel).cdrom.cd->read_block(BX_SELECTED_CONTROLLER(channel).buffer,
941 BX_SELECTED_DRIVE(channel).cdrom.next_lba,
942 BX_SELECTED_CONTROLLER(channel).buffer_size))
944 BX_PANIC(("CDROM: read block %d failed", BX_SELECTED_DRIVE(channel).cdrom.next_lba));
946 BX_SELECTED_DRIVE(channel).cdrom.next_lba++;
947 BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks--;
949 if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
950 if (!BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks)
951 BX_INFO(("Last READ block loaded {CDROM}"));
952 else
953 BX_INFO(("READ block loaded (%d remaining) {CDROM}",
954 BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks));
956 // one block transfered, start at beginning
957 index = 0;
958 #else
959 BX_PANIC(("Read with no LOWLEVEL_CDROM"));
960 #endif
961 break;
963 default: // no need to load a new block
964 break;
968 value32 = BX_SELECTED_CONTROLLER(channel).buffer[index+increment];
969 increment++;
970 if (io_len >= 2) {
971 value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index+increment] << 8);
972 increment++;
974 if (io_len == 4) {
975 value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index+increment] << 16);
976 value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index+increment+1] << 24);
977 increment += 2;
979 BX_SELECTED_CONTROLLER(channel).buffer_index = index + increment;
980 BX_SELECTED_CONTROLLER(channel).drq_index += increment;
982 if (BX_SELECTED_CONTROLLER(channel).drq_index >= (unsigned)BX_SELECTED_DRIVE(channel).atapi.drq_bytes) {
983 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
984 BX_SELECTED_CONTROLLER(channel).drq_index = 0;
986 BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining -= BX_SELECTED_DRIVE(channel).atapi.drq_bytes;
988 if (BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining > 0) {
989 // one or more blocks remaining (works only for single block commands)
990 if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
991 BX_INFO(("PACKET drq bytes read"));
992 BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
993 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
994 BX_SELECTED_CONTROLLER(channel).status.drq = 1;
995 BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 0;
997 // set new byte count if last block
998 if (BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining < BX_SELECTED_CONTROLLER(channel).byte_count) {
999 BX_SELECTED_CONTROLLER(channel).byte_count = BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining;
1001 BX_SELECTED_DRIVE(channel).atapi.drq_bytes = BX_SELECTED_CONTROLLER(channel).byte_count;
1003 raise_interrupt(channel);
1004 } else {
1005 // all bytes read
1006 if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
1007 BX_INFO(("PACKET all bytes read"));
1008 BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
1009 BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
1010 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
1011 BX_SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
1012 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
1013 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
1014 BX_SELECTED_CONTROLLER(channel).status.err = 0;
1016 raise_interrupt(channel);
1019 GOTO_RETURN_VALUE;
1021 break;
1023 // List all the read operations that are defined in the ATA/ATAPI spec
1024 // that we don't support. Commands that are listed here will cause a
1025 // BX_ERROR, which is non-fatal, and the command will be aborted.
1026 case 0x08: BX_ERROR(("read cmd 0x08 (DEVICE RESET) not supported")); command_aborted(channel, 0x08); break;
1027 case 0x10: BX_ERROR(("read cmd 0x10 (RECALIBRATE) not supported")); command_aborted(channel, 0x10); break;
1028 case 0x22: BX_ERROR(("read cmd 0x22 (READ LONG) not supported")); command_aborted(channel, 0x22); break;
1029 case 0x23: BX_ERROR(("read cmd 0x23 (READ LONG NO RETRY) not supported")); command_aborted(channel, 0x23); break;
1030 case 0x25: BX_ERROR(("read cmd 0x25 (READ DMA EXT) not supported")); command_aborted(channel, 0x25); break;
1031 case 0x26: BX_ERROR(("read cmd 0x26 (READ DMA QUEUED EXT) not supported")); command_aborted(channel, 0x26); break;
1032 case 0x27: BX_ERROR(("read cmd 0x27 (READ NATIVE MAX ADDRESS EXT) not supported")); command_aborted(channel, 0x27); break;
1033 case 0x2A: BX_ERROR(("read cmd 0x2A (READ STREAM DMA) not supported")); command_aborted(channel, 0x2A); break;
1034 case 0x2B: BX_ERROR(("read cmd 0x2B (READ STREAM PIO) not supported")); command_aborted(channel, 0x2B); break;
1035 case 0x2F: BX_ERROR(("read cmd 0x2F (READ LOG EXT) not supported")); command_aborted(channel, 0x2F); break;
1036 case 0x30: BX_ERROR(("read cmd 0x30 (WRITE SECTORS) not supported")); command_aborted(channel, 0x30); break;
1037 case 0x31: BX_ERROR(("read cmd 0x31 (WRITE SECTORS NO RETRY) not supported")); command_aborted(channel, 0x31); break;
1038 case 0x32: BX_ERROR(("read cmd 0x32 (WRITE LONG) not supported")); command_aborted(channel, 0x32); break;
1039 case 0x33: BX_ERROR(("read cmd 0x33 (WRITE LONG NO RETRY) not supported")); command_aborted(channel, 0x33); break;
1040 case 0x34: BX_ERROR(("read cmd 0x34 (WRITE SECTORS EXT) not supported")); command_aborted(channel, 0x34); break;
1041 case 0x35: BX_ERROR(("read cmd 0x35 (WRITE DMA EXT) not supported")); command_aborted(channel, 0x35); break;
1042 case 0x36: BX_ERROR(("read cmd 0x36 (WRITE DMA QUEUED EXT) not supported")); command_aborted(channel, 0x36); break;
1043 case 0x37: BX_ERROR(("read cmd 0x37 (SET MAX ADDRESS EXT) not supported")); command_aborted(channel, 0x37); break;
1044 case 0x38: BX_ERROR(("read cmd 0x38 (CFA WRITE SECTORS W/OUT ERASE) not supported")); command_aborted(channel, 0x38); break;
1045 case 0x39: BX_ERROR(("read cmd 0x39 (WRITE MULTIPLE EXT) not supported")); command_aborted(channel, 0x39); break;
1046 case 0x3A: BX_ERROR(("read cmd 0x3A (WRITE STREAM DMA) not supported")); command_aborted(channel, 0x3A); break;
1047 case 0x3B: BX_ERROR(("read cmd 0x3B (WRITE STREAM PIO) not supported")); command_aborted(channel, 0x3B); break;
1048 case 0x3F: BX_ERROR(("read cmd 0x3F (WRITE LOG EXT) not supported")); command_aborted(channel, 0x3F); break;
1049 case 0x40: BX_ERROR(("read cmd 0x40 (READ VERIFY SECTORS) not supported")); command_aborted(channel, 0x40); break;
1050 case 0x41: BX_ERROR(("read cmd 0x41 (READ VERIFY SECTORS NO RETRY) not supported")); command_aborted(channel, 0x41); break;
1051 case 0x42: BX_ERROR(("read cmd 0x42 (READ VERIFY SECTORS EXT) not supported")); command_aborted(channel, 0x42); break;
1052 case 0x50: BX_ERROR(("read cmd 0x50 (FORMAT TRACK) not supported")); command_aborted(channel, 0x50); break;
1053 case 0x51: BX_ERROR(("read cmd 0x51 (CONFIGURE STREAM) not supported")); command_aborted(channel, 0x51); break;
1054 case 0x70: BX_ERROR(("read cmd 0x70 (SEEK) not supported")); command_aborted(channel, 0x70); break;
1055 case 0x87: BX_ERROR(("read cmd 0x87 (CFA TRANSLATE SECTOR) not supported")); command_aborted(channel, 0x87); break;
1056 case 0x90: BX_ERROR(("read cmd 0x90 (EXECUTE DEVICE DIAGNOSTIC) not supported")); command_aborted(channel, 0x90); break;
1057 case 0x91: BX_ERROR(("read cmd 0x91 (INITIALIZE DEVICE PARAMETERS) not supported")); command_aborted(channel, 0x91); break;
1058 case 0x92: BX_ERROR(("read cmd 0x92 (DOWNLOAD MICROCODE) not supported")); command_aborted(channel, 0x92); break;
1059 case 0x94: BX_ERROR(("read cmd 0x94 (STANDBY IMMEDIATE) not supported")); command_aborted(channel, 0x94); break;
1060 case 0x95: BX_ERROR(("read cmd 0x95 (IDLE IMMEDIATE) not supported")); command_aborted(channel, 0x95); break;
1061 case 0x96: BX_ERROR(("read cmd 0x96 (STANDBY) not supported")); command_aborted(channel, 0x96); break;
1062 case 0x97: BX_ERROR(("read cmd 0x97 (IDLE) not supported")); command_aborted(channel, 0x97); break;
1063 case 0x98: BX_ERROR(("read cmd 0x98 (CHECK POWER MODE) not supported")); command_aborted(channel, 0x98); break;
1064 case 0x99: BX_ERROR(("read cmd 0x99 (SLEEP) not supported")); command_aborted(channel, 0x99); break;
1065 case 0xA2: BX_ERROR(("read cmd 0xA2 (SERVICE) not supported")); command_aborted(channel, 0xA2); break;
1066 case 0xB0: BX_ERROR(("read cmd 0xB0 (SMART DISABLE OPERATIONS) not supported")); command_aborted(channel, 0xB0); break;
1067 case 0xB1: BX_ERROR(("read cmd 0xB1 (DEVICE CONFIGURATION FREEZE LOCK) not supported")); command_aborted(channel, 0xB1); break;
1068 case 0xC0: BX_ERROR(("read cmd 0xC0 (CFA ERASE SECTORS) not supported")); command_aborted(channel, 0xC0); break;
1069 case 0xC5: BX_ERROR(("read cmd 0xC5 (WRITE MULTIPLE) not supported")); command_aborted(channel, 0xC5); break;
1070 case 0xC6: BX_ERROR(("read cmd 0xC6 (SET MULTIPLE MODE) not supported")); command_aborted(channel, 0xC6); break;
1071 case 0xC7: BX_ERROR(("read cmd 0xC7 (READ DMA QUEUED) not supported")); command_aborted(channel, 0xC7); break;
1072 case 0xC8: BX_ERROR(("read cmd 0xC8 (READ DMA) not supported")); command_aborted(channel, 0xC8); break;
1073 case 0xC9: BX_ERROR(("read cmd 0xC9 (READ DMA NO RETRY) not supported")); command_aborted(channel, 0xC9); break;
1074 case 0xCA: BX_ERROR(("read cmd 0xCA (WRITE DMA) not supported")); command_aborted(channel, 0xCA); break;
1075 case 0xCC: BX_ERROR(("read cmd 0xCC (WRITE DMA QUEUED) not supported")); command_aborted(channel, 0xCC); break;
1076 case 0xCD: BX_ERROR(("read cmd 0xCD (CFA WRITE MULTIPLE W/OUT ERASE) not supported")); command_aborted(channel, 0xCD); break;
1077 case 0xD1: BX_ERROR(("read cmd 0xD1 (CHECK MEDIA CARD TYPE) not supported")); command_aborted(channel, 0xD1); break;
1078 case 0xDA: BX_ERROR(("read cmd 0xDA (GET MEDIA STATUS) not supported")); command_aborted(channel, 0xDA); break;
1079 case 0xDE: BX_ERROR(("read cmd 0xDE (MEDIA LOCK) not supported")); command_aborted(channel, 0xDE); break;
1080 case 0xDF: BX_ERROR(("read cmd 0xDF (MEDIA UNLOCK) not supported")); command_aborted(channel, 0xDF); break;
1081 case 0xE0: BX_ERROR(("read cmd 0xE0 (STANDBY IMMEDIATE) not supported")); command_aborted(channel, 0xE0); break;
1082 case 0xE1: BX_ERROR(("read cmd 0xE1 (IDLE IMMEDIATE) not supported")); command_aborted(channel, 0xE1); break;
1083 case 0xE2: BX_ERROR(("read cmd 0xE2 (STANDBY) not supported")); command_aborted(channel, 0xE2); break;
1084 case 0xE3: BX_ERROR(("read cmd 0xE3 (IDLE) not supported")); command_aborted(channel, 0xE3); break;
1085 case 0xE4: BX_ERROR(("read cmd 0xE4 (READ BUFFER) not supported")); command_aborted(channel, 0xE4); break;
1086 case 0xE5: BX_ERROR(("read cmd 0xE5 (CHECK POWER MODE) not supported")); command_aborted(channel, 0xE5); break;
1087 case 0xE6: BX_ERROR(("read cmd 0xE6 (SLEEP) not supported")); command_aborted(channel, 0xE6); break;
1088 case 0xE7: BX_ERROR(("read cmd 0xE7 (FLUSH CACHE) not supported")); command_aborted(channel, 0xE7); break;
1089 case 0xE8: BX_ERROR(("read cmd 0xE8 (WRITE BUFFER) not supported")); command_aborted(channel, 0xE8); break;
1090 case 0xEA: BX_ERROR(("read cmd 0xEA (FLUSH CACHE EXT) not supported")); command_aborted(channel, 0xEA); break;
1091 case 0xED: BX_ERROR(("read cmd 0xED (MEDIA EJECT) not supported")); command_aborted(channel, 0xED); break;
1092 case 0xEF: BX_ERROR(("read cmd 0xEF (SET FEATURES) not supported")); command_aborted(channel, 0xEF); break;
1093 case 0xF1: BX_ERROR(("read cmd 0xF1 (SECURITY SET PASSWORD) not supported")); command_aborted(channel, 0xF1); break;
1094 case 0xF2: BX_ERROR(("read cmd 0xF2 (SECURITY UNLOCK) not supported")); command_aborted(channel, 0xF2); break;
1095 case 0xF3: BX_ERROR(("read cmd 0xF3 (SECURITY ERASE PREPARE) not supported")); command_aborted(channel, 0xF3); break;
1096 case 0xF4: BX_ERROR(("read cmd 0xF4 (SECURITY ERASE UNIT) not supported")); command_aborted(channel, 0xF4); break;
1097 case 0xF5: BX_ERROR(("read cmd 0xF5 (SECURITY FREEZE LOCK) not supported")); command_aborted(channel, 0xF5); break;
1098 case 0xF6: BX_ERROR(("read cmd 0xF6 (SECURITY DISABLE PASSWORD) not supported")); command_aborted(channel, 0xF6); break;
1099 case 0xF8: BX_ERROR(("read cmd 0xF8 (READ NATIVE MAX ADDRESS) not supported")); command_aborted(channel, 0xF8); break;
1100 case 0xF9: BX_ERROR(("read cmd 0xF9 (SET MAX ADDRESS) not supported")); command_aborted(channel, 0xF9); break;
1102 default:
1103 BX_PANIC(("IO read(0x%04x): current command is %02xh", address,
1104 (unsigned) BX_SELECTED_CONTROLLER(channel).current_command));
1106 break;
1108 case 0x01: // hard disk error register 0x1f1
1109 // -- WARNING : On real hardware the controller registers are shared between drives.
1110 // So we must respond even if the select device is not present. Some OS uses this fact
1111 // to detect the disks.... minix2 for example
1112 value8 = (!BX_ANY_IS_PRESENT(channel)) ? 0 : BX_SELECTED_CONTROLLER(channel).error_register;
1113 goto return_value8;
1114 case 0x02: // hard disk sector count / interrupt reason 0x1f2
1115 value8 = (!BX_ANY_IS_PRESENT(channel)) ? 0 : BX_SELECTED_CONTROLLER(channel).sector_count;
1116 goto return_value8;
1117 case 0x03: // sector number 0x1f3
1118 value8 = (!BX_ANY_IS_PRESENT(channel)) ? 0 : BX_SELECTED_CONTROLLER(channel).sector_no;
1119 goto return_value8;
1120 case 0x04: // cylinder low 0x1f4
1121 value8 = (!BX_ANY_IS_PRESENT(channel)) ? 0 : (BX_SELECTED_CONTROLLER(channel).cylinder_no & 0x00ff);
1122 goto return_value8;
1123 case 0x05: // cylinder high 0x1f5
1124 value8 = (!BX_ANY_IS_PRESENT(channel)) ? 0 : BX_SELECTED_CONTROLLER(channel).cylinder_no >> 8;
1125 goto return_value8;
1127 case 0x06: // hard disk drive and head register 0x1f6
1128 // b7 Extended data field for ECC
1129 // b6/b5: Used to be sector size. 00=256,01=512,10=1024,11=128
1130 // Since 512 was always used, bit 6 was taken to mean LBA mode:
1131 // b6 1=LBA mode, 0=CHS mode
1132 // b5 1
1133 // b4: DRV
1134 // b3..0 HD3..HD0
1135 value8 = (1 << 7) |
1136 ((BX_SELECTED_CONTROLLER(channel).lba_mode>0) << 6) |
1137 (1 << 5) | // 01b = 512 sector size
1138 (BX_HD_THIS channels[channel].drive_select << 4) |
1139 (BX_SELECTED_CONTROLLER(channel).head_no << 0);
1140 goto return_value8;
1142 case 0x07: // Hard Disk Status 0x1f7
1143 case 0x16: // Hard Disk Alternate Status 0x3f6
1144 if (!BX_SELECTED_IS_PRESENT(channel)) {
1145 // (mch) Just return zero for these registers
1146 value8 = 0;
1147 } else {
1148 value8 = (
1149 (BX_SELECTED_CONTROLLER(channel).status.busy << 7) |
1150 (BX_SELECTED_CONTROLLER(channel).status.drive_ready << 6) |
1151 (BX_SELECTED_CONTROLLER(channel).status.write_fault << 5) |
1152 (BX_SELECTED_CONTROLLER(channel).status.seek_complete << 4) |
1153 (BX_SELECTED_CONTROLLER(channel).status.drq << 3) |
1154 (BX_SELECTED_CONTROLLER(channel).status.corrected_data << 2) |
1155 (BX_SELECTED_CONTROLLER(channel).status.index_pulse << 1) |
1156 (BX_SELECTED_CONTROLLER(channel).status.err));
1157 BX_SELECTED_CONTROLLER(channel).status.index_pulse_count++;
1158 BX_SELECTED_CONTROLLER(channel).status.index_pulse = 0;
1159 if (BX_SELECTED_CONTROLLER(channel).status.index_pulse_count >= INDEX_PULSE_CYCLE) {
1160 BX_SELECTED_CONTROLLER(channel).status.index_pulse = 1;
1161 BX_SELECTED_CONTROLLER(channel).status.index_pulse_count = 0;
1164 if (port == 0x07) {
1165 DEV_pic_lower_irq(BX_HD_THIS channels[channel].irq);
1167 goto return_value8;
1169 case 0x17: // Hard Disk Address Register 0x3f7
1170 // Obsolete and unsupported register. Not driven by hard
1171 // disk controller. Report all 1's. If floppy controller
1172 // is handling this address, it will call this function
1173 // set/clear D7 (the only bit it handles), then return
1174 // the combined value
1175 value8 = 0xff;
1176 goto return_value8;
1178 default:
1179 BX_PANIC(("hard drive: io read to address %x unsupported",
1180 (unsigned) address));
1183 BX_PANIC(("hard drive: shouldnt get here!"));
1184 return(0);
1186 return_value32:
1187 BX_DEBUG(("32-bit read from %04x = %08x {%s}",
1188 (unsigned) address, value32, BX_SELECTED_TYPE_STRING(channel)));
1189 return value32;
1191 return_value16:
1192 BX_DEBUG(("16-bit read from %04x = %04x {%s}",
1193 (unsigned) address, value16, BX_SELECTED_TYPE_STRING(channel)));
1194 return value16;
1196 return_value8:
1197 BX_DEBUG(("8-bit read from %04x = %02x {%s}",
1198 (unsigned) address, value8, BX_SELECTED_TYPE_STRING(channel)));
1199 return value8;
1202 // static IO port write callback handler
1203 // redirects to non-static class handler to avoid virtual functions
1205 void bx_hard_drive_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
1207 #if !BX_USE_HD_SMF
1208 bx_hard_drive_c *class_ptr = (bx_hard_drive_c *) this_ptr;
1209 class_ptr->write(address, value, io_len);
1212 void bx_hard_drive_c::write(Bit32u address, Bit32u value, unsigned io_len)
1214 #else
1215 UNUSED(this_ptr);
1216 #endif // !BX_USE_HD_SMF
1217 Bit64s logical_sector;
1218 bx_bool prev_control_reset;
1219 bx_bool lba48 = 0;
1221 Bit8u channel = BX_MAX_ATA_CHANNEL;
1222 Bit32u port = 0xff; // undefined
1223 int i;
1225 for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
1226 if ((address & 0xfff8) == BX_HD_THIS channels[channel].ioaddr1) {
1227 port = address - BX_HD_THIS channels[channel].ioaddr1;
1228 break;
1230 else if ((address & 0xfff8) == BX_HD_THIS channels[channel].ioaddr2) {
1231 port = address - BX_HD_THIS channels[channel].ioaddr2 + 0x10;
1232 break;
1236 if (channel == BX_MAX_ATA_CHANNEL) {
1237 if (address != 0x03f6) {
1238 BX_PANIC(("write: unable to find ATA channel, ioport=0x%04x", address));
1239 } else {
1240 channel = 0;
1241 port = address - 0x03e0;
1245 switch (io_len) {
1246 case 1:
1247 BX_DEBUG(("8-bit write to %04x = %02x {%s}",
1248 address, value, BX_SELECTED_TYPE_STRING(channel)));
1249 break;
1251 case 2:
1252 BX_DEBUG(("16-bit write to %04x = %04x {%s}",
1253 address, value, BX_SELECTED_TYPE_STRING(channel)));
1254 break;
1256 case 4:
1257 BX_DEBUG(("32-bit write to %04x = %08x {%s}",
1258 address, value, BX_SELECTED_TYPE_STRING(channel)));
1259 break;
1261 default:
1262 BX_DEBUG(("unknown-size write to %04x = %08x {%s}",
1263 address, value, BX_SELECTED_TYPE_STRING(channel)));
1264 break;
1267 switch (port) {
1268 case 0x00: // 0x1f0
1269 switch (BX_SELECTED_CONTROLLER(channel).current_command) {
1270 case 0x30: // WRITE SECTORS
1271 case 0xC5: // WRITE MULTIPLE SECTORS
1272 case 0x34: // WRITE SECTORS EXT
1273 case 0x39: // WRITE MULTIPLE EXT
1274 if (BX_SELECTED_CONTROLLER(channel).buffer_index >= BX_SELECTED_CONTROLLER(channel).buffer_size)
1275 BX_PANIC(("IO write(0x%04x): buffer_index >= %d", address, BX_SELECTED_CONTROLLER(channel).buffer_size));
1277 #if BX_SupportRepeatSpeedups
1278 if (DEV_bulk_io_quantum_requested()) {
1279 unsigned transferLen, quantumsMax;
1280 quantumsMax = (BX_SELECTED_CONTROLLER(channel).buffer_size - BX_SELECTED_CONTROLLER(channel).buffer_index) / io_len;
1281 if (quantumsMax == 0)
1282 BX_PANIC(("IO write(0x%04x): not enough space for write", address));
1283 DEV_bulk_io_quantum_transferred() = DEV_bulk_io_quantum_requested();
1284 if (quantumsMax < DEV_bulk_io_quantum_transferred())
1285 DEV_bulk_io_quantum_transferred() = quantumsMax;
1286 transferLen = io_len * DEV_bulk_io_quantum_transferred();
1287 memcpy(&BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index],
1288 (Bit8u*) DEV_bulk_io_host_addr(), transferLen);
1289 DEV_bulk_io_host_addr() += transferLen;
1290 BX_SELECTED_CONTROLLER(channel).buffer_index += transferLen;
1292 else
1293 #endif
1295 switch(io_len) {
1296 case 4:
1297 BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+3] = (Bit8u)(value >> 24);
1298 BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+2] = (Bit8u)(value >> 16);
1299 case 2:
1300 BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+1] = (Bit8u)(value >> 8);
1301 BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index] = (Bit8u) value;
1303 BX_SELECTED_CONTROLLER(channel).buffer_index += io_len;
1306 /* if buffer completely writtten */
1307 if (BX_SELECTED_CONTROLLER(channel).buffer_index >= BX_SELECTED_CONTROLLER(channel).buffer_size) {
1308 if (ide_write_sector(channel, BX_SELECTED_CONTROLLER(channel).buffer,
1309 BX_SELECTED_CONTROLLER(channel).buffer_size)) {
1310 if ((BX_SELECTED_CONTROLLER(channel).current_command == 0xC5) ||
1311 (BX_SELECTED_CONTROLLER(channel).current_command == 0x39)) {
1312 if (BX_SELECTED_CONTROLLER(channel).num_sectors > BX_SELECTED_CONTROLLER(channel).multiple_sectors) {
1313 BX_SELECTED_CONTROLLER(channel).buffer_size = BX_SELECTED_CONTROLLER(channel).multiple_sectors * 512;
1314 } else {
1315 BX_SELECTED_CONTROLLER(channel).buffer_size = BX_SELECTED_CONTROLLER(channel).num_sectors * 512;
1318 BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
1320 /* When the write is complete, controller clears the DRQ bit and
1321 * sets the BSY bit.
1322 * If at least one more sector is to be written, controller sets DRQ bit,
1323 * clears BSY bit, and issues IRQ
1326 if (BX_SELECTED_CONTROLLER(channel).num_sectors != 0) {
1327 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
1328 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
1329 BX_SELECTED_CONTROLLER(channel).status.drq = 1;
1330 BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
1331 BX_SELECTED_CONTROLLER(channel).status.err = 0;
1332 } else { /* no more sectors to write */
1333 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
1334 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
1335 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
1336 BX_SELECTED_CONTROLLER(channel).status.err = 0;
1337 BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
1339 raise_interrupt(channel);
1342 break;
1344 case 0xa0: // PACKET
1345 if (BX_SELECTED_CONTROLLER(channel).buffer_index >= PACKET_SIZE)
1346 BX_PANIC(("IO write(0x%04x): buffer_index >= PACKET_SIZE", address));
1348 switch (io_len) {
1349 case 4:
1350 BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+3] = (Bit8u)(value >> 24);
1351 BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+2] = (Bit8u)(value >> 16);
1352 case 2:
1353 BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+1] = (Bit8u)(value >> 8);
1354 BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index] = (Bit8u) value;
1356 BX_SELECTED_CONTROLLER(channel).buffer_index += io_len;
1358 /* if packet completely writtten */
1359 if (BX_SELECTED_CONTROLLER(channel).buffer_index >= PACKET_SIZE) {
1360 // complete command received
1361 Bit8u atapi_command = BX_SELECTED_CONTROLLER(channel).buffer[0];
1362 BX_SELECTED_CONTROLLER(channel).buffer_size = 2048;
1364 BX_DEBUG(("ata%d-%d: ATAPI command 0x%02x started", channel,
1365 BX_SLAVE_SELECTED(channel), atapi_command));
1367 switch (atapi_command) {
1368 case 0x00: // test unit ready
1369 if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
1370 atapi_cmd_nop(channel);
1371 } else {
1372 atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0);
1374 raise_interrupt(channel);
1375 break;
1377 case 0x03: // request sense
1379 int alloc_length = BX_SELECTED_CONTROLLER(channel).buffer[4];
1380 init_send_atapi_command(channel, atapi_command, 18, alloc_length);
1382 // sense data
1383 BX_SELECTED_CONTROLLER(channel).buffer[0] = 0x70 | (1 << 7);
1384 BX_SELECTED_CONTROLLER(channel).buffer[1] = 0;
1385 BX_SELECTED_CONTROLLER(channel).buffer[2] = BX_SELECTED_DRIVE(channel).sense.sense_key;
1386 BX_SELECTED_CONTROLLER(channel).buffer[3] = BX_SELECTED_DRIVE(channel).sense.information.arr[0];
1387 BX_SELECTED_CONTROLLER(channel).buffer[4] = BX_SELECTED_DRIVE(channel).sense.information.arr[1];
1388 BX_SELECTED_CONTROLLER(channel).buffer[5] = BX_SELECTED_DRIVE(channel).sense.information.arr[2];
1389 BX_SELECTED_CONTROLLER(channel).buffer[6] = BX_SELECTED_DRIVE(channel).sense.information.arr[3];
1390 BX_SELECTED_CONTROLLER(channel).buffer[7] = 17-7;
1391 BX_SELECTED_CONTROLLER(channel).buffer[8] = BX_SELECTED_DRIVE(channel).sense.specific_inf.arr[0];
1392 BX_SELECTED_CONTROLLER(channel).buffer[9] = BX_SELECTED_DRIVE(channel).sense.specific_inf.arr[1];
1393 BX_SELECTED_CONTROLLER(channel).buffer[10] = BX_SELECTED_DRIVE(channel).sense.specific_inf.arr[2];
1394 BX_SELECTED_CONTROLLER(channel).buffer[11] = BX_SELECTED_DRIVE(channel).sense.specific_inf.arr[3];
1395 BX_SELECTED_CONTROLLER(channel).buffer[12] = BX_SELECTED_DRIVE(channel).sense.asc;
1396 BX_SELECTED_CONTROLLER(channel).buffer[13] = BX_SELECTED_DRIVE(channel).sense.ascq;
1397 BX_SELECTED_CONTROLLER(channel).buffer[14] = BX_SELECTED_DRIVE(channel).sense.fruc;
1398 BX_SELECTED_CONTROLLER(channel).buffer[15] = BX_SELECTED_DRIVE(channel).sense.key_spec.arr[0];
1399 BX_SELECTED_CONTROLLER(channel).buffer[16] = BX_SELECTED_DRIVE(channel).sense.key_spec.arr[1];
1400 BX_SELECTED_CONTROLLER(channel).buffer[17] = BX_SELECTED_DRIVE(channel).sense.key_spec.arr[2];
1402 ready_to_send_atapi(channel);
1404 break;
1406 case 0x1b: // start stop unit
1408 char ata_name[20];
1409 //bx_bool Immed = (BX_SELECTED_CONTROLLER(channel).buffer[1] >> 0) & 1;
1410 bx_bool LoEj = (BX_SELECTED_CONTROLLER(channel).buffer[4] >> 1) & 1;
1411 bx_bool Start = (BX_SELECTED_CONTROLLER(channel).buffer[4] >> 0) & 1;
1413 if (!LoEj && !Start) { // stop the disc
1414 BX_ERROR(("FIXME: Stop disc not implemented"));
1415 atapi_cmd_nop(channel);
1416 raise_interrupt(channel);
1417 } else if (!LoEj && Start) { // start (spin up) the disc
1418 #ifdef LOWLEVEL_CDROM
1419 BX_SELECTED_DRIVE(channel).cdrom.cd->start_cdrom();
1420 #endif
1421 BX_ERROR(("FIXME: ATAPI start disc not reading TOC"));
1422 atapi_cmd_nop(channel);
1423 raise_interrupt(channel);
1424 } else if (LoEj && !Start) { // Eject the disc
1425 atapi_cmd_nop(channel);
1427 if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
1428 #ifdef LOWLEVEL_CDROM
1429 BX_SELECTED_DRIVE(channel).cdrom.cd->eject_cdrom();
1430 #endif
1431 BX_SELECTED_DRIVE(channel).cdrom.ready = 0;
1432 sprintf(ata_name, "ata.%d.%s", channel, BX_SLAVE_SELECTED(channel)?"slave":"master");
1433 bx_list_c *base = (bx_list_c*) SIM->get_param(ata_name);
1434 SIM->get_param_enum("status", base)->set(BX_EJECTED);
1435 bx_gui->update_drive_status_buttons();
1437 raise_interrupt(channel);
1438 } else { // Load the disc
1439 // My guess is that this command only closes the tray, that's a no-op for us
1440 atapi_cmd_nop(channel);
1441 raise_interrupt(channel);
1444 break;
1446 case 0xbd: // mechanism status
1448 Bit16u alloc_length = read_16bit(BX_SELECTED_CONTROLLER(channel).buffer + 8);
1450 if (alloc_length == 0)
1451 BX_PANIC(("Zero allocation length to MECHANISM STATUS not impl."));
1453 init_send_atapi_command(channel, atapi_command, 8, alloc_length);
1455 BX_SELECTED_CONTROLLER(channel).buffer[0] = 0; // reserved for non changers
1456 BX_SELECTED_CONTROLLER(channel).buffer[1] = 0; // reserved for non changers
1458 BX_SELECTED_CONTROLLER(channel).buffer[2] = 0; // Current LBA (TODO!)
1459 BX_SELECTED_CONTROLLER(channel).buffer[3] = 0; // Current LBA (TODO!)
1460 BX_SELECTED_CONTROLLER(channel).buffer[4] = 0; // Current LBA (TODO!)
1462 BX_SELECTED_CONTROLLER(channel).buffer[5] = 1; // one slot
1464 BX_SELECTED_CONTROLLER(channel).buffer[6] = 0; // slot table length
1465 BX_SELECTED_CONTROLLER(channel).buffer[7] = 0; // slot table length
1467 ready_to_send_atapi(channel);
1469 break;
1471 case 0x1a: // mode sense (6)
1472 case 0x5a: // mode sense (10)
1474 Bit16u alloc_length;
1476 if (atapi_command == 0x5a) {
1477 alloc_length = read_16bit(BX_SELECTED_CONTROLLER(channel).buffer + 7);
1478 } else {
1479 alloc_length = BX_SELECTED_CONTROLLER(channel).buffer[4];
1481 Bit8u PC = BX_SELECTED_CONTROLLER(channel).buffer[2] >> 6;
1482 Bit8u PageCode = BX_SELECTED_CONTROLLER(channel).buffer[2] & 0x3f;
1484 switch (PC) {
1485 case 0x0: // current values
1486 switch (PageCode) {
1487 case 0x01: // error recovery
1488 init_send_atapi_command(channel, atapi_command, sizeof(error_recovery_t) + 8, alloc_length);
1490 init_mode_sense_single(channel, &BX_SELECTED_DRIVE(channel).cdrom.current.error_recovery,
1491 sizeof(error_recovery_t));
1492 ready_to_send_atapi(channel);
1493 break;
1495 case 0x2a: // CD-ROM capabilities & mech. status
1496 init_send_atapi_command(channel, atapi_command, 28, alloc_length);
1497 init_mode_sense_single(channel, &BX_SELECTED_CONTROLLER(channel).buffer[8], 28);
1498 BX_SELECTED_CONTROLLER(channel).buffer[8] = 0x2a;
1499 BX_SELECTED_CONTROLLER(channel).buffer[9] = 0x12;
1500 BX_SELECTED_CONTROLLER(channel).buffer[10] = 0x00;
1501 BX_SELECTED_CONTROLLER(channel).buffer[11] = 0x00;
1502 // Multisession, Mode 2 Form 2, Mode 2 Form 1
1503 BX_SELECTED_CONTROLLER(channel).buffer[12] = 0x70;
1504 BX_SELECTED_CONTROLLER(channel).buffer[13] = (3 << 5);
1505 BX_SELECTED_CONTROLLER(channel).buffer[14] = (unsigned char) (1 |
1506 (BX_SELECTED_DRIVE(channel).cdrom.locked ? (1 << 1) : 0) |
1507 (1 << 3) |
1508 (1 << 5));
1509 BX_SELECTED_CONTROLLER(channel).buffer[15] = 0x00;
1510 BX_SELECTED_CONTROLLER(channel).buffer[16] = (706 >> 8) & 0xff;
1511 BX_SELECTED_CONTROLLER(channel).buffer[17] = 706 & 0xff;
1512 BX_SELECTED_CONTROLLER(channel).buffer[18] = 0;
1513 BX_SELECTED_CONTROLLER(channel).buffer[19] = 2;
1514 BX_SELECTED_CONTROLLER(channel).buffer[20] = (512 >> 8) & 0xff;
1515 BX_SELECTED_CONTROLLER(channel).buffer[21] = 512 & 0xff;
1516 BX_SELECTED_CONTROLLER(channel).buffer[22] = (706 >> 8) & 0xff;
1517 BX_SELECTED_CONTROLLER(channel).buffer[23] = 706 & 0xff;
1518 BX_SELECTED_CONTROLLER(channel).buffer[24] = 0;
1519 BX_SELECTED_CONTROLLER(channel).buffer[25] = 0;
1520 BX_SELECTED_CONTROLLER(channel).buffer[26] = 0;
1521 BX_SELECTED_CONTROLLER(channel).buffer[27] = 0;
1522 ready_to_send_atapi(channel);
1523 break;
1525 case 0x0d: // CD-ROM
1526 case 0x0e: // CD-ROM audio control
1527 case 0x3f: // all
1528 BX_ERROR(("cdrom: MODE SENSE (curr), code=%x not implemented yet",
1529 PageCode));
1530 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
1531 ASC_INV_FIELD_IN_CMD_PACKET, 1);
1532 raise_interrupt(channel);
1533 break;
1535 default:
1536 // not implemeted by this device
1537 BX_INFO(("cdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device",
1538 PC, PageCode));
1539 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
1540 ASC_INV_FIELD_IN_CMD_PACKET, 1);
1541 raise_interrupt(channel);
1542 break;
1544 break;
1546 case 0x1: // changeable values
1547 switch (PageCode) {
1548 case 0x01: // error recovery
1549 case 0x0d: // CD-ROM
1550 case 0x0e: // CD-ROM audio control
1551 case 0x2a: // CD-ROM capabilities & mech. status
1552 case 0x3f: // all
1553 BX_ERROR(("cdrom: MODE SENSE (chg), code=%x not implemented yet",
1554 PageCode));
1555 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
1556 ASC_INV_FIELD_IN_CMD_PACKET, 1);
1557 raise_interrupt(channel);
1558 break;
1560 default:
1561 // not implemeted by this device
1562 BX_INFO(("cdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device",
1563 PC, PageCode));
1564 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
1565 ASC_INV_FIELD_IN_CMD_PACKET, 1);
1566 raise_interrupt(channel);
1567 break;
1569 break;
1571 case 0x2: // default values
1572 switch (PageCode) {
1573 case 0x2a: // CD-ROM capabilities & mech. status, copied from current values
1574 init_send_atapi_command(channel, atapi_command, 28, alloc_length);
1575 init_mode_sense_single(channel, &BX_SELECTED_CONTROLLER(channel).buffer[8], 28);
1576 BX_SELECTED_CONTROLLER(channel).buffer[8] = 0x2a;
1577 BX_SELECTED_CONTROLLER(channel).buffer[9] = 0x12;
1578 BX_SELECTED_CONTROLLER(channel).buffer[10] = 0x00;
1579 BX_SELECTED_CONTROLLER(channel).buffer[11] = 0x00;
1580 // Multisession, Mode 2 Form 2, Mode 2 Form 1
1581 BX_SELECTED_CONTROLLER(channel).buffer[12] = 0x70;
1582 BX_SELECTED_CONTROLLER(channel).buffer[13] = (3 << 5);
1583 BX_SELECTED_CONTROLLER(channel).buffer[14] = (unsigned char) (1 |
1584 (BX_SELECTED_DRIVE(channel).cdrom.locked ? (1 << 1) : 0) |
1585 (1 << 3) |
1586 (1 << 5));
1587 BX_SELECTED_CONTROLLER(channel).buffer[15] = 0x00;
1588 BX_SELECTED_CONTROLLER(channel).buffer[16] = (706 >> 8) & 0xff;
1589 BX_SELECTED_CONTROLLER(channel).buffer[17] = 706 & 0xff;
1590 BX_SELECTED_CONTROLLER(channel).buffer[18] = 0;
1591 BX_SELECTED_CONTROLLER(channel).buffer[19] = 2;
1592 BX_SELECTED_CONTROLLER(channel).buffer[20] = (512 >> 8) & 0xff;
1593 BX_SELECTED_CONTROLLER(channel).buffer[21] = 512 & 0xff;
1594 BX_SELECTED_CONTROLLER(channel).buffer[22] = (706 >> 8) & 0xff;
1595 BX_SELECTED_CONTROLLER(channel).buffer[23] = 706 & 0xff;
1596 BX_SELECTED_CONTROLLER(channel).buffer[24] = 0;
1597 BX_SELECTED_CONTROLLER(channel).buffer[25] = 0;
1598 BX_SELECTED_CONTROLLER(channel).buffer[26] = 0;
1599 BX_SELECTED_CONTROLLER(channel).buffer[27] = 0;
1600 ready_to_send_atapi(channel);
1601 break;
1603 case 0x01: // error recovery
1604 case 0x0d: // CD-ROM
1605 case 0x0e: // CD-ROM audio control
1606 case 0x3f: // all
1607 BX_ERROR(("cdrom: MODE SENSE (dflt), code=%x not implemented", PageCode));
1608 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
1609 ASC_INV_FIELD_IN_CMD_PACKET, 1);
1610 raise_interrupt(channel);
1611 break;
1613 default:
1614 // not implemeted by this device
1615 BX_INFO(("cdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device",
1616 PC, PageCode));
1617 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
1618 ASC_INV_FIELD_IN_CMD_PACKET, 1);
1619 raise_interrupt(channel);
1620 break;
1622 break;
1624 case 0x3: // saved values not implemented
1625 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_SAVING_PARAMETERS_NOT_SUPPORTED, 1);
1626 raise_interrupt(channel);
1627 break;
1629 default:
1630 BX_PANIC(("Should not get here!"));
1631 break;
1634 break;
1636 case 0x12: // inquiry
1638 Bit8u alloc_length = BX_SELECTED_CONTROLLER(channel).buffer[4];
1640 init_send_atapi_command(channel, atapi_command, 36, alloc_length);
1642 BX_SELECTED_CONTROLLER(channel).buffer[0] = 0x05; // CD-ROM
1643 BX_SELECTED_CONTROLLER(channel).buffer[1] = 0x80; // Removable
1644 BX_SELECTED_CONTROLLER(channel).buffer[2] = 0x00; // ISO, ECMA, ANSI version
1645 BX_SELECTED_CONTROLLER(channel).buffer[3] = 0x21; // ATAPI-2, as specified
1646 BX_SELECTED_CONTROLLER(channel).buffer[4] = 31; // additional length (total 36)
1647 BX_SELECTED_CONTROLLER(channel).buffer[5] = 0x00; // reserved
1648 BX_SELECTED_CONTROLLER(channel).buffer[6] = 0x00; // reserved
1649 BX_SELECTED_CONTROLLER(channel).buffer[7] = 0x00; // reserved
1651 // Vendor ID
1652 const char* vendor_id = "BOCHS ";
1653 for (i = 0; i < 8; i++)
1654 BX_SELECTED_CONTROLLER(channel).buffer[8+i] = vendor_id[i];
1656 // Product ID
1657 const char* product_id = "Generic CD-ROM ";
1658 for (i = 0; i < 16; i++)
1659 BX_SELECTED_CONTROLLER(channel).buffer[16+i] = product_id[i];
1660 if (BX_HD_THIS cdrom_count > 1) {
1661 BX_SELECTED_CONTROLLER(channel).buffer[31] = BX_SELECTED_DRIVE(channel).device_num;
1664 // Product Revision level
1665 const char* rev_level = "1.0 ";
1666 for (i = 0; i < 4; i++)
1667 BX_SELECTED_CONTROLLER(channel).buffer[32+i] = rev_level[i];
1669 ready_to_send_atapi(channel);
1671 break;
1673 case 0x25: // read cd-rom capacity
1675 // no allocation length???
1676 init_send_atapi_command(channel, atapi_command, 8, 8);
1678 if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
1679 Bit32u capacity = BX_SELECTED_DRIVE(channel).cdrom.capacity - 1;
1680 BX_SELECTED_CONTROLLER(channel).buffer[0] = (capacity >> 24) & 0xff;
1681 BX_SELECTED_CONTROLLER(channel).buffer[1] = (capacity >> 16) & 0xff;
1682 BX_SELECTED_CONTROLLER(channel).buffer[2] = (capacity >> 8) & 0xff;
1683 BX_SELECTED_CONTROLLER(channel).buffer[3] = (capacity >> 0) & 0xff;
1684 BX_SELECTED_CONTROLLER(channel).buffer[4] = (2048 >> 24) & 0xff;
1685 BX_SELECTED_CONTROLLER(channel).buffer[5] = (2048 >> 16) & 0xff;
1686 BX_SELECTED_CONTROLLER(channel).buffer[6] = (2048 >> 8) & 0xff;
1687 BX_SELECTED_CONTROLLER(channel).buffer[7] = (2048 >> 0) & 0xff;
1688 ready_to_send_atapi(channel);
1689 } else {
1690 atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 1);
1691 raise_interrupt(channel);
1694 break;
1696 case 0xbe: // read cd
1698 if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
1699 Bit32u lba = read_32bit(BX_SELECTED_CONTROLLER(channel).buffer + 2);
1700 Bit32u transfer_length = BX_SELECTED_CONTROLLER(channel).buffer[8] |
1701 (BX_SELECTED_CONTROLLER(channel).buffer[7] << 8) |
1702 (BX_SELECTED_CONTROLLER(channel).buffer[6] << 16);
1703 Bit8u transfer_req = BX_SELECTED_CONTROLLER(channel).buffer[9];
1704 if (transfer_length == 0) {
1705 atapi_cmd_nop(channel);
1706 raise_interrupt(channel);
1707 break;
1709 switch (transfer_req & 0xf8) {
1710 case 0x00:
1711 atapi_cmd_nop(channel);
1712 raise_interrupt(channel);
1713 break;
1714 case 0xf8:
1715 BX_SELECTED_CONTROLLER(channel).buffer_size = 2352;
1716 case 0x10:
1717 init_send_atapi_command(channel, atapi_command,
1718 transfer_length * BX_SELECTED_CONTROLLER(channel).buffer_size,
1719 transfer_length * BX_SELECTED_CONTROLLER(channel).buffer_size, 1);
1720 BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks = transfer_length;
1721 BX_SELECTED_DRIVE(channel).cdrom.next_lba = lba;
1722 ready_to_send_atapi(channel);
1723 break;
1724 default:
1725 BX_ERROR(("Read CD: unknown format"));
1726 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 1);
1727 raise_interrupt(channel);
1729 } else {
1730 atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 1);
1731 raise_interrupt(channel);
1734 break;
1736 case 0x43: // read toc
1737 if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
1738 #ifdef LOWLEVEL_CDROM
1739 bx_bool msf = (BX_SELECTED_CONTROLLER(channel).buffer[1] >> 1) & 1;
1740 Bit8u starting_track = BX_SELECTED_CONTROLLER(channel).buffer[6];
1741 int toc_length;
1742 #endif
1743 Bit16u alloc_length = read_16bit(BX_SELECTED_CONTROLLER(channel).buffer + 7);
1744 Bit8u format = (BX_SELECTED_CONTROLLER(channel).buffer[9] >> 6);
1745 // Win32: I just read the TOC using Win32's IOCTRL functions (Ben)
1746 #if defined(WIN32)
1747 #ifdef LOWLEVEL_CDROM
1748 switch (format) {
1749 case 2:
1750 case 3:
1751 case 4:
1752 if (msf != 1)
1753 BX_ERROR(("READ_TOC_EX: msf not set for format %i", format));
1754 case 0:
1755 case 1:
1756 case 5:
1757 if (!(BX_SELECTED_DRIVE(channel).cdrom.cd->read_toc(BX_SELECTED_CONTROLLER(channel).buffer,
1758 &toc_length, msf, starting_track, format))) {
1759 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 1);
1760 raise_interrupt(channel);
1761 } else {
1762 init_send_atapi_command(channel, atapi_command, toc_length, alloc_length);
1763 ready_to_send_atapi(channel);
1765 break;
1766 default:
1767 BX_ERROR(("(READ TOC) format %d not supported", format));
1768 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 1);
1769 raise_interrupt(channel);
1771 #else
1772 BX_PANIC(("LOWLEVEL_CDROM not defined"));
1773 #endif
1774 #else // WIN32
1775 switch (format) {
1776 case 0:
1777 case 1:
1778 case 2:
1779 #ifdef LOWLEVEL_CDROM
1780 if (!(BX_SELECTED_DRIVE(channel).cdrom.cd->read_toc(BX_SELECTED_CONTROLLER(channel).buffer,
1781 &toc_length, msf, starting_track, format))) {
1782 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 1);
1783 raise_interrupt(channel);
1784 } else {
1785 init_send_atapi_command(channel, atapi_command, toc_length, alloc_length);
1786 ready_to_send_atapi(channel);
1788 #else
1789 BX_PANIC(("LOWLEVEL_CDROM not defined"));
1790 #endif
1791 break;
1793 default:
1794 BX_ERROR(("(READ TOC) format %d not supported", format));
1795 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 1);
1796 raise_interrupt(channel);
1797 break;
1799 #endif // WIN32
1800 } else {
1801 atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 1);
1802 raise_interrupt(channel);
1804 break;
1806 case 0x28: // read (10)
1807 case 0xa8: // read (12)
1809 Bit32s transfer_length;
1811 if (atapi_command == 0x28)
1812 transfer_length = read_16bit(BX_SELECTED_CONTROLLER(channel).buffer + 7);
1813 else
1814 transfer_length = read_32bit(BX_SELECTED_CONTROLLER(channel).buffer + 6);
1816 Bit32u lba = read_32bit(BX_SELECTED_CONTROLLER(channel).buffer + 2);
1818 if (!BX_SELECTED_DRIVE(channel).cdrom.ready) {
1819 atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 1);
1820 raise_interrupt(channel);
1821 break;
1823 if (lba > BX_SELECTED_DRIVE(channel).cdrom.capacity) {
1824 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR, 1);
1825 raise_interrupt(channel);
1826 break;
1829 // Ben: see comment below
1830 if (lba + transfer_length > BX_SELECTED_DRIVE(channel).cdrom.capacity) {
1831 transfer_length = (BX_SELECTED_DRIVE(channel).cdrom.capacity - lba);
1833 if (transfer_length <= 0) {
1834 atapi_cmd_nop(channel);
1835 raise_interrupt(channel);
1836 BX_INFO(("READ(%d) with transfer length <= 0, ok (%i)", atapi_command==0x28?10:12, transfer_length));
1837 break;
1840 /* Ben: I commented this out and added the three lines above. I am not sure this is the correct thing
1841 to do, but it seems to work.
1842 FIXME: I think that if the transfer_length is more than we can transfer, we should return
1843 some sort of flag/error/bitrep stating so. I haven't read the atapi specs enough to know
1844 what needs to be done though.
1846 if (lba + transfer_length > BX_SELECTED_DRIVE(channel).cdrom.capacity) {
1847 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR, 1);
1848 raise_interrupt(channel);
1849 break;
1852 BX_DEBUG(("cdrom: READ (%d) LBA=%d LEN=%d", atapi_command==0x28?10:12, lba, transfer_length));
1854 // handle command
1855 init_send_atapi_command(channel, atapi_command, transfer_length * 2048,
1856 transfer_length * 2048, 1);
1857 BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks = transfer_length;
1858 BX_SELECTED_DRIVE(channel).cdrom.next_lba = lba;
1859 ready_to_send_atapi(channel);
1861 break;
1863 case 0x2b: // seek
1865 Bit32u lba = read_32bit(BX_SELECTED_CONTROLLER(channel).buffer + 2);
1866 if (!BX_SELECTED_DRIVE(channel).cdrom.ready) {
1867 atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 1);
1868 raise_interrupt(channel);
1869 break;
1872 if (lba > BX_SELECTED_DRIVE(channel).cdrom.capacity) {
1873 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR, 1);
1874 raise_interrupt(channel);
1875 break;
1877 #ifdef LOWLEVEL_CDROM
1878 BX_SELECTED_DRIVE(channel).cdrom.cd->seek(lba);
1879 #else
1880 BX_PANIC(("Seek with no LOWLEVEL_CDROM"));
1881 #endif
1882 atapi_cmd_nop(channel);
1883 raise_interrupt(channel);
1885 break;
1887 case 0x1e: // prevent/allow medium removal
1888 if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
1889 BX_SELECTED_DRIVE(channel).cdrom.locked = BX_SELECTED_CONTROLLER(channel).buffer[4] & 1;
1890 atapi_cmd_nop(channel);
1891 } else {
1892 atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 1);
1894 raise_interrupt(channel);
1895 break;
1897 case 0x42: // read sub-channel
1899 bx_bool msf = get_packet_field(channel,1, 1, 1);
1900 bx_bool sub_q = get_packet_field(channel,2, 6, 1);
1901 Bit8u data_format = get_packet_byte(channel,3);
1902 Bit8u track_number = get_packet_byte(channel,6);
1903 Bit16u alloc_length = get_packet_word(channel,7);
1904 int ret_len = 4; // header size
1905 UNUSED(msf);
1906 UNUSED(track_number);
1908 if (!BX_SELECTED_DRIVE(channel).cdrom.ready) {
1909 atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 1);
1910 raise_interrupt(channel);
1911 } else {
1912 BX_SELECTED_CONTROLLER(channel).buffer[0] = 0;
1913 BX_SELECTED_CONTROLLER(channel).buffer[1] = 0; // audio not supported
1914 BX_SELECTED_CONTROLLER(channel).buffer[2] = 0;
1915 BX_SELECTED_CONTROLLER(channel).buffer[3] = 0;
1917 if (sub_q) { // !sub_q == header only
1918 if ((data_format == 2) || (data_format == 3)) { // UPC or ISRC
1919 ret_len = 24;
1920 BX_SELECTED_CONTROLLER(channel).buffer[4] = data_format;
1921 if (data_format == 3) {
1922 BX_SELECTED_CONTROLLER(channel).buffer[5] = 0x14;
1923 BX_SELECTED_CONTROLLER(channel).buffer[6] = 1;
1925 BX_SELECTED_CONTROLLER(channel).buffer[8] = 0; // no UPC, no ISRC
1926 } else {
1927 BX_ERROR(("Read sub-channel with SubQ not implemented (format=%d)", data_format));
1928 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
1929 ASC_INV_FIELD_IN_CMD_PACKET, 1);
1930 raise_interrupt(channel);
1931 break;
1934 init_send_atapi_command(channel, atapi_command, ret_len, alloc_length);
1935 ready_to_send_atapi(channel);
1938 break;
1940 case 0x51: // read disc info
1941 // no-op to keep the Linux CD-ROM driver happy
1942 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 1);
1943 raise_interrupt(channel);
1944 break;
1946 case 0x55: // mode select
1947 case 0xa6: // load/unload cd
1948 case 0x4b: // pause/resume
1949 case 0x45: // play audio
1950 case 0x47: // play audio msf
1951 case 0xbc: // play cd
1952 case 0xb9: // read cd msf
1953 case 0x44: // read header
1954 case 0xba: // scan
1955 case 0xbb: // set cd speed
1956 case 0x4e: // stop play/scan
1957 case 0x46: // get configuration
1958 case 0x4a: // get event status notification
1959 BX_DEBUG(("ATAPI command 0x%x not implemented yet", atapi_command));
1960 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0);
1961 raise_interrupt(channel);
1962 break;
1964 default:
1965 BX_ERROR(("Unknown ATAPI command 0x%x (%d)", atapi_command, atapi_command));
1966 atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 1);
1967 raise_interrupt(channel);
1968 break;
1971 break;
1973 default:
1974 BX_PANIC(("IO write(0x%04x): current command is %02xh", address,
1975 (unsigned) BX_SELECTED_CONTROLLER(channel).current_command));
1977 break;
1979 case 0x01: // hard disk write precompensation 0x1f1
1980 WRITE_FEATURES(channel,value);
1981 if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom)) {
1982 if (value == 0xff)
1983 BX_INFO(("no precompensation {%s}", BX_SELECTED_TYPE_STRING(channel)));
1984 else
1985 BX_INFO(("precompensation value %02x {%s}", (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
1987 break;
1989 case 0x02: // hard disk sector count 0x1f2
1990 WRITE_SECTOR_COUNT(channel,value);
1991 if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
1992 BX_INFO(("sector count = %u {%s}", (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
1993 break;
1995 case 0x03: // hard disk sector number 0x1f3
1996 WRITE_SECTOR_NUMBER(channel,value);
1997 if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
1998 BX_INFO(("sector number = %u {%s}", (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
1999 break;
2001 case 0x04: // hard disk cylinder low 0x1f4
2002 WRITE_CYLINDER_LOW(channel,value);
2003 if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
2004 BX_INFO(("cylinder low = %02xh {%s}", (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
2005 break;
2007 case 0x05: // hard disk cylinder high 0x1f5
2008 WRITE_CYLINDER_HIGH(channel,value);
2009 if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
2010 BX_INFO(("cylinder high = %02xh {%s}", (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
2011 break;
2013 case 0x06: // hard disk drive and head register 0x1f6
2014 // b7 Extended data field for ECC
2015 // b6/b5: Used to be sector size. 00=256,01=512,10=1024,11=128
2016 // Since 512 was always used, bit 6 was taken to mean LBA mode:
2017 // b6 1=LBA mode, 0=CHS mode
2018 // b5 1
2019 // b4: DRV
2020 // b3..0 HD3..HD0
2022 if ((value & 0xa0) != 0xa0) // 1x1xxxxx
2023 BX_DEBUG(("IO write 0x%04x (%02x): not 1x1xxxxxb", address, (unsigned) value));
2024 Bit32u drvsel = BX_HD_THIS channels[channel].drive_select = (value >> 4) & 0x01;
2025 WRITE_HEAD_NO(channel,value & 0xf);
2026 if (BX_SELECTED_CONTROLLER(channel).lba_mode == 0 && ((value >> 6) & 1) == 1)
2027 BX_DEBUG(("enabling LBA mode"));
2028 WRITE_LBA_MODE(channel,(value >> 6) & 1);
2029 if (!BX_SELECTED_IS_PRESENT(channel)) {
2030 BX_DEBUG(("ata%d: device set to %d which does not exist", channel, drvsel));
2033 break;
2035 case 0x07: // hard disk command 0x1f7
2036 // (mch) Writes to the command register with drive_select != 0
2037 // are ignored if no secondary device is present
2038 if ((BX_SLAVE_SELECTED(channel)) && (!BX_SLAVE_IS_PRESENT(channel)))
2039 break;
2040 // Writes to the command register clear the IRQ
2041 DEV_pic_lower_irq(BX_HD_THIS channels[channel].irq);
2043 if (BX_SELECTED_CONTROLLER(channel).status.busy) {
2044 BX_ERROR(("ata%d: command 0x%02x sent, controller BSY bit set", channel, value));
2045 break;
2047 if ((value & 0xf0) == 0x10)
2048 value = 0x10;
2049 BX_SELECTED_CONTROLLER(channel).status.err = 0;
2050 switch (value) {
2052 case 0x10: // CALIBRATE DRIVE
2053 if (!BX_SELECTED_IS_HD(channel)) {
2054 BX_INFO(("ata%d-%d: calibrate drive issued to non-disk",
2055 channel, BX_SLAVE_SELECTED(channel)));
2056 command_aborted(channel, value);
2057 break;
2060 if (!BX_SELECTED_IS_PRESENT(channel)) {
2061 BX_SELECTED_CONTROLLER(channel).error_register = 0x02; // Track 0 not found
2062 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
2063 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2064 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 0;
2065 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
2066 BX_SELECTED_CONTROLLER(channel).status.err = 1;
2067 raise_interrupt(channel);
2068 BX_INFO(("calibrate drive: disk ata%d-%d not present", channel, BX_SLAVE_SELECTED(channel)));
2069 break;
2072 /* move head to cylinder 0, issue IRQ */
2073 BX_SELECTED_CONTROLLER(channel).error_register = 0;
2074 BX_SELECTED_CONTROLLER(channel).cylinder_no = 0;
2075 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
2076 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2077 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
2078 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
2079 raise_interrupt(channel);
2080 break;
2082 case 0x24: // READ SECTORS EXT
2083 case 0x29: // READ MULTIPLE EXT
2084 lba48 = 1;
2085 case 0x20: // READ SECTORS, with retries
2086 case 0x21: // READ SECTORS, without retries
2087 case 0xC4: // READ MULTIPLE SECTORS
2088 /* update sector_no, always points to current sector
2089 * after each sector is read to buffer, DRQ bit set and issue IRQ
2090 * if interrupt handler transfers all data words into main memory,
2091 * and more sectors to read, then set BSY bit again, clear DRQ and
2092 * read next sector into buffer
2093 * sector count of 0 means 256 sectors
2096 if (!BX_SELECTED_IS_HD(channel)) {
2097 BX_INFO(("ata%d-%d: read sectors issued to non-disk",
2098 channel, BX_SLAVE_SELECTED(channel)));
2099 command_aborted(channel, value);
2100 break;
2102 // Lose98 accesses 0/0/0 in CHS mode
2103 if (!BX_SELECTED_CONTROLLER(channel).lba_mode &&
2104 !BX_SELECTED_CONTROLLER(channel).head_no &&
2105 !BX_SELECTED_CONTROLLER(channel).cylinder_no &&
2106 !BX_SELECTED_CONTROLLER(channel).sector_no) {
2107 BX_INFO(("ata%d-%d: : read from 0/0/0, aborting command",
2108 channel, BX_SLAVE_SELECTED(channel)));
2109 command_aborted(channel, value);
2110 break;
2113 lba48_transform(channel, lba48);
2114 if ((value == 0xC4) || (value == 0x29)) {
2115 if (BX_SELECTED_CONTROLLER(channel).multiple_sectors == 0) {
2116 command_aborted(channel, value);
2117 break;
2119 if (BX_SELECTED_CONTROLLER(channel).num_sectors > BX_SELECTED_CONTROLLER(channel).multiple_sectors) {
2120 BX_SELECTED_CONTROLLER(channel).buffer_size = BX_SELECTED_CONTROLLER(channel).multiple_sectors * 512;
2121 } else {
2122 BX_SELECTED_CONTROLLER(channel).buffer_size = BX_SELECTED_CONTROLLER(channel).num_sectors * 512;
2124 } else {
2125 BX_SELECTED_CONTROLLER(channel).buffer_size = 512;
2127 BX_SELECTED_CONTROLLER(channel).current_command = value;
2129 if (ide_read_sector(channel, BX_SELECTED_CONTROLLER(channel).buffer,
2130 BX_SELECTED_CONTROLLER(channel).buffer_size)) {
2131 BX_SELECTED_CONTROLLER(channel).error_register = 0;
2132 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
2133 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2134 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
2135 BX_SELECTED_CONTROLLER(channel).status.drq = 1;
2136 BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
2137 BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
2138 raise_interrupt(channel);
2140 break;
2142 case 0x34: // WRITE SECTORS EXT
2143 case 0x39: // WRITE MULTIPLE EXT
2144 lba48 = 1;
2145 case 0x30: // WRITE SECTORS, with retries
2146 case 0xC5: // WRITE MULTIPLE SECTORS
2147 /* update sector_no, always points to current sector
2148 * after each sector is read to buffer, DRQ bit set and issue IRQ
2149 * if interrupt handler transfers all data words into main memory,
2150 * and more sectors to read, then set BSY bit again, clear DRQ and
2151 * read next sector into buffer
2152 * sector count of 0 means 256 sectors
2155 if (!BX_SELECTED_IS_HD(channel)) {
2156 BX_INFO(("ata%d-%d: write sectors issued to non-disk",
2157 channel, BX_SLAVE_SELECTED(channel)));
2158 command_aborted(channel, value);
2159 break;
2161 lba48_transform(channel, lba48);
2162 if ((value == 0xC5) || (value ==0x39)) {
2163 if (BX_SELECTED_CONTROLLER(channel).multiple_sectors == 0) {
2164 command_aborted(channel, value);
2165 break;
2167 if (BX_SELECTED_CONTROLLER(channel).num_sectors > BX_SELECTED_CONTROLLER(channel).multiple_sectors) {
2168 BX_SELECTED_CONTROLLER(channel).buffer_size = BX_SELECTED_CONTROLLER(channel).multiple_sectors * 512;
2169 } else {
2170 BX_SELECTED_CONTROLLER(channel).buffer_size = BX_SELECTED_CONTROLLER(channel).num_sectors * 512;
2172 } else {
2173 BX_SELECTED_CONTROLLER(channel).buffer_size = 512;
2175 BX_SELECTED_CONTROLLER(channel).current_command = value;
2177 // implicit seek done :^)
2178 BX_SELECTED_CONTROLLER(channel).error_register = 0;
2179 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
2180 // BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2181 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
2182 BX_SELECTED_CONTROLLER(channel).status.drq = 1;
2183 BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
2184 break;
2186 case 0x90: // EXECUTE DEVICE DIAGNOSTIC
2187 set_signature(channel, BX_SLAVE_SELECTED(channel));
2188 BX_SELECTED_CONTROLLER(channel).error_register = 0x01;
2189 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
2190 raise_interrupt(channel);
2191 break;
2193 case 0x91: // INITIALIZE DRIVE PARAMETERS
2194 if (!BX_SELECTED_IS_HD(channel)) {
2195 BX_INFO(("ata%d-%d: initialize drive parameters issued to non-disk",
2196 channel, BX_SLAVE_SELECTED(channel)));
2197 command_aborted(channel, value);
2198 break;
2200 // sets logical geometry of specified drive
2201 BX_DEBUG(("ata%d-%d: init drive params: sec=%u, drive sel=%u, head=%u",
2202 channel, BX_SLAVE_SELECTED(channel),
2203 (unsigned) BX_SELECTED_CONTROLLER(channel).sector_count,
2204 (unsigned) BX_HD_THIS channels[channel].drive_select,
2205 (unsigned) BX_SELECTED_CONTROLLER(channel).head_no));
2206 if (!BX_SELECTED_IS_PRESENT(channel)) {
2207 BX_PANIC(("init drive params: disk ata%d-%d not present", channel, BX_SLAVE_SELECTED(channel)));
2208 //BX_SELECTED_CONTROLLER(channel).error_register = 0x12;
2209 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
2210 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2211 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
2212 raise_interrupt(channel);
2213 break;
2215 if (BX_SELECTED_CONTROLLER(channel).sector_count != BX_SELECTED_DRIVE(channel).hard_drive->sectors) {
2216 BX_ERROR(("ata%d-%d: init drive params: logical sector count %d not supported", channel, BX_SLAVE_SELECTED(channel),
2217 BX_SELECTED_CONTROLLER(channel).sector_count));
2218 command_aborted(channel, value);
2219 break;
2221 if (BX_SELECTED_CONTROLLER(channel).head_no == 0) {
2222 // Linux 2.6.x kernels use this value and don't like aborting here
2223 BX_ERROR(("ata%d-%d: init drive params: max. logical head number 0 not supported", channel, BX_SLAVE_SELECTED(channel)));
2224 } else if (BX_SELECTED_CONTROLLER(channel).head_no != (BX_SELECTED_DRIVE(channel).hard_drive->heads-1)) {
2225 BX_ERROR(("ata%d-%d: init drive params: max. logical head number %d not supported", channel, BX_SLAVE_SELECTED(channel),
2226 BX_SELECTED_CONTROLLER(channel).head_no));
2227 command_aborted(channel, value);
2228 break;
2230 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
2231 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2232 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
2233 raise_interrupt(channel);
2234 break;
2236 case 0xec: // IDENTIFY DEVICE
2238 Bit16u temp16;
2240 if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
2241 BX_INFO(("Drive ID Command issued : 0xec "));
2243 if (!BX_SELECTED_IS_PRESENT(channel)) {
2244 BX_INFO(("disk ata%d-%d not present, aborting",channel,BX_SLAVE_SELECTED(channel)));
2245 command_aborted(channel, value);
2246 break;
2248 if (BX_SELECTED_IS_CD(channel)) {
2249 set_signature(channel, BX_SLAVE_SELECTED(channel));
2250 command_aborted(channel, 0xec);
2251 } else {
2252 BX_SELECTED_CONTROLLER(channel).current_command = value;
2253 BX_SELECTED_CONTROLLER(channel).error_register = 0;
2255 // See ATA/ATAPI-4, 8.12
2256 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
2257 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2258 BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
2259 BX_SELECTED_CONTROLLER(channel).status.drq = 1;
2261 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
2262 BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
2264 BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
2265 if (!BX_SELECTED_DRIVE(channel).identify_set) {
2266 identify_drive(channel);
2268 // now convert the id_drive array (native 256 word format) to
2269 // the controller buffer (512 bytes)
2270 for (i=0; i<=255; i++) {
2271 temp16 = BX_SELECTED_DRIVE(channel).id_drive[i];
2272 BX_SELECTED_CONTROLLER(channel).buffer[i*2] = temp16 & 0x00ff;
2273 BX_SELECTED_CONTROLLER(channel).buffer[i*2+1] = temp16 >> 8;
2275 raise_interrupt(channel);
2278 break;
2280 case 0xef: // SET FEATURES
2281 switch(BX_SELECTED_CONTROLLER(channel).features) {
2282 case 0x03: // Set Transfer Mode
2284 Bit8u type = (BX_SELECTED_CONTROLLER(channel).sector_count >> 3);
2285 Bit8u mode = BX_SELECTED_CONTROLLER(channel).sector_count & 0x07;
2286 switch (type) {
2287 case 0x00: // PIO default
2288 case 0x01: // PIO mode
2289 BX_INFO(("ata%d-%d: set transfer mode to PIO", channel,
2290 BX_SLAVE_SELECTED(channel)));
2291 BX_SELECTED_CONTROLLER(channel).mdma_mode = 0x00;
2292 BX_SELECTED_CONTROLLER(channel).udma_mode = 0x00;
2293 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2294 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
2295 raise_interrupt(channel);
2296 break;
2297 case 0x04: // MDMA mode
2298 BX_INFO(("ata%d-%d: set transfer mode to MDMA%d", channel,
2299 BX_SLAVE_SELECTED(channel), mode));
2300 BX_SELECTED_CONTROLLER(channel).mdma_mode = (1 << mode);
2301 BX_SELECTED_CONTROLLER(channel).udma_mode = 0x00;
2302 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2303 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
2304 raise_interrupt(channel);
2305 break;
2306 case 0x08: // UDMA mode
2307 BX_SELECTED_CONTROLLER(channel).mdma_mode = 0x00;
2308 BX_SELECTED_CONTROLLER(channel).udma_mode = (1 << mode);
2309 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2310 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
2311 raise_interrupt(channel);
2312 break;
2313 default:
2314 BX_ERROR(("ata%d-%d: unknown transfer mode type 0x%02x", channel,
2315 BX_SLAVE_SELECTED(channel), type));
2316 command_aborted(channel, value);
2318 BX_SELECTED_DRIVE(channel).identify_set = 0;
2320 break;
2322 case 0x02: // Enable and
2323 case 0x82: // Disable write cache.
2324 case 0xAA: // Enable and
2325 case 0x55: // Disable look-ahead cache.
2326 case 0xCC: // Enable and
2327 case 0x66: // Disable reverting to power-on default
2328 BX_INFO(("ata%d-%d: SET FEATURES subcommand 0x%02x not supported, but returning success",
2329 channel,BX_SLAVE_SELECTED(channel),(unsigned) BX_SELECTED_CONTROLLER(channel).features));
2330 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2331 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
2332 raise_interrupt(channel);
2333 break;
2335 default:
2336 BX_ERROR(("ata%d-%d: SET FEATURES with unknown subcommand: 0x%02x",
2337 channel,BX_SLAVE_SELECTED(channel),(unsigned) BX_SELECTED_CONTROLLER(channel).features));
2338 command_aborted(channel, value);
2340 break;
2342 case 0x42: // READ VERIFY SECTORS EXT
2343 lba48 = 1;
2344 case 0x40: // READ VERIFY SECTORS
2345 case 0x41: // READ VERIFY SECTORS NO RETRY
2346 if (!BX_SELECTED_IS_HD(channel)) {
2347 BX_INFO(("ata%d-%d: read verify issued to non-disk",
2348 channel,BX_SLAVE_SELECTED(channel)));
2349 command_aborted(channel, value);
2350 break;
2352 lba48_transform(channel, lba48);
2353 BX_INFO(("ata%d-%d: verify command : 0x%02x !", channel,BX_SLAVE_SELECTED(channel), value));
2354 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
2355 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2356 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
2357 raise_interrupt(channel);
2358 break;
2360 case 0xc6: // SET MULTIPLE MODE
2361 if (!BX_SELECTED_IS_HD(channel)) {
2362 BX_INFO(("set multiple mode issued to non-disk"));
2363 command_aborted(channel, value);
2364 } else if ((BX_SELECTED_CONTROLLER(channel).sector_count > MAX_MULTIPLE_SECTORS) ||
2365 ((BX_SELECTED_CONTROLLER(channel).sector_count & (BX_SELECTED_CONTROLLER(channel).sector_count - 1)) != 0) ||
2366 (BX_SELECTED_CONTROLLER(channel).sector_count == 0)) {
2367 command_aborted(channel, value);
2368 } else {
2369 BX_DEBUG(("set multiple mode: sectors=%d", BX_SELECTED_CONTROLLER(channel).sector_count));
2370 BX_SELECTED_CONTROLLER(channel).multiple_sectors = BX_SELECTED_CONTROLLER(channel).sector_count;
2371 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
2372 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2373 BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
2374 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
2375 raise_interrupt(channel);
2377 break;
2379 // ATAPI commands
2380 case 0xa1: // IDENTIFY PACKET DEVICE
2382 Bit16u temp16;
2384 if (BX_SELECTED_IS_CD(channel)) {
2385 BX_SELECTED_CONTROLLER(channel).current_command = value;
2386 BX_SELECTED_CONTROLLER(channel).error_register = 0;
2388 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
2389 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2390 BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
2391 BX_SELECTED_CONTROLLER(channel).status.drq = 1;
2393 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
2394 BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
2396 BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
2397 if (!BX_SELECTED_DRIVE(channel).identify_set) {
2398 identify_ATAPI_drive(channel);
2400 // now convert the id_drive array (native 256 word format) to
2401 // the controller buffer (512 bytes)
2402 for (i = 0; i <= 255; i++) {
2403 temp16 = BX_SELECTED_DRIVE(channel).id_drive[i];
2404 BX_SELECTED_CONTROLLER(channel).buffer[i*2] = temp16 & 0x00ff;
2405 BX_SELECTED_CONTROLLER(channel).buffer[i*2+1] = temp16 >> 8;
2407 raise_interrupt(channel);
2408 } else {
2409 command_aborted(channel, 0xa1);
2412 break;
2414 case 0x08: // DEVICE RESET (atapi)
2415 if (BX_SELECTED_IS_CD(channel)) {
2416 set_signature(channel, BX_SLAVE_SELECTED(channel));
2418 BX_SELECTED_CONTROLLER(channel).status.busy = 1;
2419 BX_SELECTED_CONTROLLER(channel).error_register &= ~(1 << 7);
2421 BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
2422 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
2423 BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
2425 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
2426 } else {
2427 BX_DEBUG(("ATAPI Device Reset on non-cd device"));
2428 command_aborted(channel, 0x08);
2430 break;
2432 case 0xa0: // SEND PACKET (atapi)
2433 if (BX_SELECTED_IS_CD(channel)) {
2434 // PACKET
2435 BX_SELECTED_CONTROLLER(channel).packet_dma = (BX_SELECTED_CONTROLLER(channel).features & 1);
2436 if (BX_SELECTED_CONTROLLER(channel).features & (1 << 1)) {
2437 BX_ERROR(("PACKET-overlapped not supported"));
2438 command_aborted (channel, 0xa0);
2439 } else {
2440 // We're already ready!
2441 BX_SELECTED_CONTROLLER(channel).sector_count = 1;
2442 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
2443 BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
2444 // serv bit??
2445 BX_SELECTED_CONTROLLER(channel).status.drq = 1;
2447 // NOTE: no interrupt here
2448 BX_SELECTED_CONTROLLER(channel).current_command = value;
2449 BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
2451 } else {
2452 command_aborted (channel, 0xa0);
2454 break;
2456 case 0xa2: // SERVICE (atapi), optional
2457 if (BX_SELECTED_IS_CD(channel)) {
2458 BX_PANIC(("ATAPI SERVICE not implemented"));
2459 command_aborted(channel, 0xa2);
2460 } else {
2461 command_aborted(channel, 0xa2);
2463 break;
2465 // power management & flush cache stubs
2466 case 0xE0: // STANDBY NOW
2467 case 0xE1: // IDLE IMMEDIATE
2468 case 0xE7: // FLUSH CACHE
2469 case 0xEA: // FLUSH CACHE EXT
2470 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
2471 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2472 BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
2473 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
2474 raise_interrupt(channel);
2475 break;
2477 case 0xe5: // CHECK POWER MODE
2478 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
2479 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2480 BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
2481 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
2482 BX_SELECTED_CONTROLLER(channel).sector_count = 0xff; // Active or Idle mode
2483 raise_interrupt(channel);
2484 break;
2486 case 0x70: // SEEK (cgs)
2487 if (BX_SELECTED_IS_HD(channel)) {
2488 BX_DEBUG(("write cmd 0x70 (SEEK) executing"));
2489 if (!calculate_logical_address(channel, &logical_sector)) {
2490 BX_ERROR(("initial seek to sector %lu out of bounds, aborting", (unsigned long)logical_sector));
2491 command_aborted(channel, value);
2492 break;
2494 BX_SELECTED_CONTROLLER(channel).error_register = 0;
2495 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
2496 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2497 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
2498 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
2499 BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
2500 BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
2501 BX_DEBUG(("ata%d-%d: SEEK completed (IRQ %sabled)", channel,
2502 BX_SLAVE_SELECTED(channel), BX_SELECTED_CONTROLLER(channel).control.disable_irq?"dis":"en"));
2503 raise_interrupt(channel);
2504 } else {
2505 BX_INFO(("write cmd 0x70 (SEEK) not supported for non-disk"));
2506 command_aborted(channel, 0x70);
2508 break;
2510 case 0x25: // READ DMA EXT
2511 lba48 = 1;
2512 case 0xC8: // READ DMA
2513 if (BX_SELECTED_IS_HD(channel) && BX_HD_THIS bmdma_present()) {
2514 lba48_transform(channel, lba48);
2515 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2516 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
2517 BX_SELECTED_CONTROLLER(channel).status.drq = 1;
2518 BX_SELECTED_CONTROLLER(channel).current_command = value;
2519 } else {
2520 BX_ERROR(("write cmd 0x%02x (READ DMA) not supported", value));
2521 command_aborted(channel, value);
2523 break;
2525 case 0x35: // WRITE DMA EXT
2526 lba48 = 1;
2527 case 0xCA: // WRITE DMA
2528 if (BX_SELECTED_IS_HD(channel) && BX_HD_THIS bmdma_present()) {
2529 lba48_transform(channel, lba48);
2530 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
2531 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
2532 BX_SELECTED_CONTROLLER(channel).status.drq = 1;
2533 BX_SELECTED_CONTROLLER(channel).current_command = value;
2534 } else {
2535 BX_ERROR(("write cmd 0x%02x (WRITE DMA) not supported", value));
2536 command_aborted(channel, value);
2538 break;
2540 // List all the write operations that are defined in the ATA/ATAPI spec
2541 // that we don't support. Commands that are listed here will cause a
2542 // BX_ERROR, which is non-fatal, and the command will be aborted.
2543 case 0x22: BX_ERROR(("write cmd 0x22 (READ LONG) not supported")); command_aborted(channel, 0x22); break;
2544 case 0x23: BX_ERROR(("write cmd 0x23 (READ LONG NO RETRY) not supported")); command_aborted(channel, 0x23); break;
2545 case 0x26: BX_ERROR(("write cmd 0x26 (READ DMA QUEUED EXT) not supported"));command_aborted(channel, 0x26); break;
2546 case 0x27: BX_ERROR(("write cmd 0x27 (READ NATIVE MAX ADDRESS EXT) not supported"));command_aborted(channel, 0x27); break;
2547 case 0x2A: BX_ERROR(("write cmd 0x2A (READ STREAM DMA) not supported"));command_aborted(channel, 0x2A); break;
2548 case 0x2B: BX_ERROR(("write cmd 0x2B (READ STREAM PIO) not supported"));command_aborted(channel, 0x2B); break;
2549 case 0x2F: BX_ERROR(("write cmd 0x2F (READ LOG EXT) not supported"));command_aborted(channel, 0x2F); break;
2550 case 0x31: BX_ERROR(("write cmd 0x31 (WRITE SECTORS NO RETRY) not supported")); command_aborted(channel, 0x31); break;
2551 case 0x32: BX_ERROR(("write cmd 0x32 (WRITE LONG) not supported")); command_aborted(channel, 0x32); break;
2552 case 0x33: BX_ERROR(("write cmd 0x33 (WRITE LONG NO RETRY) not supported")); command_aborted(channel, 0x33); break;
2553 case 0x36: BX_ERROR(("write cmd 0x36 (WRITE DMA QUEUED EXT) not supported"));command_aborted(channel, 0x36); break;
2554 case 0x37: BX_ERROR(("write cmd 0x37 (SET MAX ADDRESS EXT) not supported"));command_aborted(channel, 0x37); break;
2555 case 0x38: BX_ERROR(("write cmd 0x38 (CFA WRITE SECTORS W/OUT ERASE) not supported"));command_aborted(channel, 0x38); break;
2556 case 0x3A: BX_ERROR(("write cmd 0x3A (WRITE STREAM DMA) not supported"));command_aborted(channel, 0x3A); break;
2557 case 0x3B: BX_ERROR(("write cmd 0x3B (WRITE STREAM PIO) not supported"));command_aborted(channel, 0x3B); break;
2558 case 0x3F: BX_ERROR(("write cmd 0x3F (WRITE LOG EXT) not supported"));command_aborted(channel, 0x3F); break;
2559 case 0x50: BX_ERROR(("write cmd 0x50 (FORMAT TRACK) not supported")); command_aborted(channel, 0x50); break;
2560 case 0x51: BX_ERROR(("write cmd 0x51 (CONFIGURE STREAM) not supported"));command_aborted(channel, 0x51); break;
2561 case 0x87: BX_ERROR(("write cmd 0x87 (CFA TRANSLATE SECTOR) not supported"));command_aborted(channel, 0x87); break;
2562 case 0x92: BX_ERROR(("write cmd 0x92 (DOWNLOAD MICROCODE) not supported"));command_aborted(channel, 0x92); break;
2563 case 0x94: BX_ERROR(("write cmd 0x94 (STANDBY IMMEDIATE) not supported")); command_aborted(channel, 0x94); break;
2564 case 0x95: BX_ERROR(("write cmd 0x95 (IDLE IMMEDIATE) not supported")); command_aborted(channel, 0x95); break;
2565 case 0x96: BX_ERROR(("write cmd 0x96 (STANDBY) not supported")); command_aborted(channel, 0x96); break;
2566 case 0x97: BX_ERROR(("write cmd 0x97 (IDLE) not supported")); command_aborted(channel, 0x97); break;
2567 case 0x98: BX_ERROR(("write cmd 0x98 (CHECK POWER MODE) not supported")); command_aborted(channel, 0x98); break;
2568 case 0x99: BX_ERROR(("write cmd 0x99 (SLEEP) not supported")); command_aborted(channel, 0x99); break;
2569 case 0xB0: BX_ERROR(("write cmd 0xB0 (SMART commands) not supported"));command_aborted(channel, 0xB0); break;
2570 case 0xB1: BX_ERROR(("write cmd 0xB1 (DEVICE CONFIGURATION commands) not supported"));command_aborted(channel, 0xB1); break;
2571 case 0xC0: BX_ERROR(("write cmd 0xC0 (CFA ERASE SECTORS) not supported"));command_aborted(channel, 0xC0); break;
2572 case 0xC7: BX_ERROR(("write cmd 0xC7 (READ DMA QUEUED) not supported"));command_aborted(channel, 0xC7); break;
2573 case 0xC9: BX_ERROR(("write cmd 0xC9 (READ DMA NO RETRY) not supported")); command_aborted(channel, 0xC9); break;
2574 case 0xCC: BX_ERROR(("write cmd 0xCC (WRITE DMA QUEUED) not supported"));command_aborted(channel, 0xCC); break;
2575 case 0xCD: BX_ERROR(("write cmd 0xCD (CFA WRITE MULTIPLE W/OUT ERASE) not supported"));command_aborted(channel, 0xCD); break;
2576 case 0xD1: BX_ERROR(("write cmd 0xD1 (CHECK MEDIA CARD TYPE) not supported"));command_aborted(channel, 0xD1); break;
2577 case 0xDA: BX_ERROR(("write cmd 0xDA (GET MEDIA STATUS) not supported"));command_aborted(channel, 0xDA); break;
2578 case 0xDE: BX_ERROR(("write cmd 0xDE (MEDIA LOCK) not supported"));command_aborted(channel, 0xDE); break;
2579 case 0xDF: BX_ERROR(("write cmd 0xDF (MEDIA UNLOCK) not supported"));command_aborted(channel, 0xDF); break;
2580 case 0xE2: BX_ERROR(("write cmd 0xE2 (STANDBY) not supported"));command_aborted(channel, 0xE2); break;
2581 case 0xE3: BX_ERROR(("write cmd 0xE3 (IDLE) not supported"));command_aborted(channel, 0xE3); break;
2582 case 0xE4: BX_ERROR(("write cmd 0xE4 (READ BUFFER) not supported"));command_aborted(channel, 0xE4); break;
2583 case 0xE6: BX_ERROR(("write cmd 0xE6 (SLEEP) not supported"));command_aborted(channel, 0xE6); break;
2584 case 0xE8: BX_ERROR(("write cmd 0xE8 (WRITE BUFFER) not supported"));command_aborted(channel, 0xE8); break;
2585 case 0xED: BX_ERROR(("write cmd 0xED (MEDIA EJECT) not supported"));command_aborted(channel, 0xED); break;
2586 case 0xF1: BX_ERROR(("write cmd 0xF1 (SECURITY SET PASSWORD) not supported"));command_aborted(channel, 0xF1); break;
2587 case 0xF2: BX_ERROR(("write cmd 0xF2 (SECURITY UNLOCK) not supported"));command_aborted(channel, 0xF2); break;
2588 case 0xF3: BX_ERROR(("write cmd 0xF3 (SECURITY ERASE PREPARE) not supported"));command_aborted(channel, 0xF3); break;
2589 case 0xF4: BX_ERROR(("write cmd 0xF4 (SECURITY ERASE UNIT) not supported"));command_aborted(channel, 0xF4); break;
2590 case 0xF5: BX_ERROR(("write cmd 0xF5 (SECURITY FREEZE LOCK) not supported"));command_aborted(channel, 0xF5); break;
2591 case 0xF6: BX_ERROR(("write cmd 0xF6 (SECURITY DISABLE PASSWORD) not supported"));command_aborted(channel, 0xF6); break;
2592 case 0xF8: BX_ERROR(("write cmd 0xF8 (READ NATIVE MAX ADDRESS) not supported"));command_aborted(channel, 0xF8); break;
2593 case 0xF9: BX_ERROR(("write cmd 0xF9 (SET MAX ADDRESS) not supported"));command_aborted(channel, 0xF9); break;
2595 default:
2596 BX_ERROR(("IO write to 0x%04x: unknown command 0x%02x", address, value));
2597 command_aborted(channel, value);
2599 break;
2601 case 0x16: // hard disk adapter control 0x3f6
2602 // (mch) Even if device 1 was selected, a write to this register
2603 // goes to device 0 (if device 1 is absent)
2605 prev_control_reset = BX_SELECTED_CONTROLLER(channel).control.reset;
2606 BX_HD_THIS channels[channel].drives[0].controller.control.reset = value & 0x04;
2607 BX_HD_THIS channels[channel].drives[1].controller.control.reset = value & 0x04;
2608 BX_HD_THIS channels[channel].drives[0].controller.control.disable_irq = value & 0x02;
2609 BX_HD_THIS channels[channel].drives[1].controller.control.disable_irq = value & 0x02;
2611 BX_DEBUG(("ata%d: adapter control reg: reset controller = %d", channel,
2612 (unsigned) (BX_SELECTED_CONTROLLER(channel).control.reset) ? 1 : 0));
2613 BX_DEBUG(("ata%d: adapter control reg: disable irq = %d", channel,
2614 (unsigned) (BX_SELECTED_CONTROLLER(channel).control.disable_irq) ? 1 : 0));
2616 if (!prev_control_reset && BX_SELECTED_CONTROLLER(channel).control.reset) {
2617 // transition from 0 to 1 causes all drives to reset
2618 BX_DEBUG(("Enter RESET mode"));
2620 // (mch) Set BSY, drive not ready
2621 for (int id = 0; id < 2; id++) {
2622 BX_CONTROLLER(channel,id).status.busy = 1;
2623 BX_CONTROLLER(channel,id).status.drive_ready = 0;
2624 BX_CONTROLLER(channel,id).reset_in_progress = 1;
2626 BX_CONTROLLER(channel,id).status.write_fault = 0;
2627 BX_CONTROLLER(channel,id).status.seek_complete = 1;
2628 BX_CONTROLLER(channel,id).status.drq = 0;
2629 BX_CONTROLLER(channel,id).status.corrected_data = 0;
2630 BX_CONTROLLER(channel,id).status.err = 0;
2632 BX_CONTROLLER(channel,id).error_register = 0x01; // diagnostic code: no error
2634 BX_CONTROLLER(channel,id).current_command = 0x00;
2635 BX_CONTROLLER(channel,id).buffer_index = 0;
2637 BX_CONTROLLER(channel,id).multiple_sectors = 0;
2638 BX_CONTROLLER(channel,id).lba_mode = 0;
2640 BX_CONTROLLER(channel,id).control.disable_irq = 0;
2641 DEV_pic_lower_irq(BX_HD_THIS channels[channel].irq);
2643 } else if (BX_SELECTED_CONTROLLER(channel).reset_in_progress &&
2644 !BX_SELECTED_CONTROLLER(channel).control.reset) {
2645 // Clear BSY and DRDY
2646 BX_DEBUG(("Reset complete {%s}", BX_SELECTED_TYPE_STRING(channel)));
2647 for (int id = 0; id < 2; id++) {
2648 BX_CONTROLLER(channel,id).status.busy = 0;
2649 BX_CONTROLLER(channel,id).status.drive_ready = 1;
2650 BX_CONTROLLER(channel,id).reset_in_progress = 0;
2652 set_signature(channel, id);
2655 BX_DEBUG(("ata%d: adapter control reg: disable irq = %d", channel,
2656 (unsigned) (BX_SELECTED_CONTROLLER(channel).control.disable_irq) ? 1 : 0));
2657 break;
2659 default:
2660 BX_PANIC(("hard drive: io write to address %x = %02x",
2661 (unsigned) address, (unsigned) value));
2665 bx_bool BX_CPP_AttrRegparmN(2)
2666 bx_hard_drive_c::calculate_logical_address(Bit8u channel, Bit64s *sector)
2668 Bit64s logical_sector;
2670 if (BX_SELECTED_CONTROLLER(channel).lba_mode) {
2671 if (!BX_SELECTED_CONTROLLER(channel).lba48) {
2672 logical_sector = ((Bit32u)BX_SELECTED_CONTROLLER(channel).head_no) << 24 |
2673 ((Bit32u)BX_SELECTED_CONTROLLER(channel).cylinder_no) << 8 |
2674 (Bit32u)BX_SELECTED_CONTROLLER(channel).sector_no;
2675 } else {
2676 logical_sector = ((Bit64u)BX_SELECTED_CONTROLLER(channel).hob.hcyl) << 40 |
2677 ((Bit64u)BX_SELECTED_CONTROLLER(channel).hob.lcyl) << 32 |
2678 ((Bit64u)BX_SELECTED_CONTROLLER(channel).hob.sector) << 24 |
2679 ((Bit64u)BX_SELECTED_CONTROLLER(channel).cylinder_no) << 8 |
2680 (Bit64u)BX_SELECTED_CONTROLLER(channel).sector_no;
2682 } else {
2683 logical_sector = ((Bit32u)BX_SELECTED_CONTROLLER(channel).cylinder_no * BX_SELECTED_DRIVE(channel).hard_drive->heads *
2684 BX_SELECTED_DRIVE(channel).hard_drive->sectors) +
2685 (Bit32u)(BX_SELECTED_CONTROLLER(channel).head_no * BX_SELECTED_DRIVE(channel).hard_drive->sectors) +
2686 (BX_SELECTED_CONTROLLER(channel).sector_no - 1);
2688 Bit32u sector_count=
2689 (Bit32u)BX_SELECTED_DRIVE(channel).hard_drive->cylinders *
2690 (Bit32u)BX_SELECTED_DRIVE(channel).hard_drive->heads *
2691 (Bit32u)BX_SELECTED_DRIVE(channel).hard_drive->sectors;
2693 if (logical_sector >= sector_count) {
2694 BX_ERROR (("calc_log_addr: out of bounds (%d/%d)", (Bit32u)logical_sector, sector_count));
2695 return 0;
2697 *sector = logical_sector;
2698 return 1;
2701 void BX_CPP_AttrRegparmN(1)
2702 bx_hard_drive_c::increment_address(Bit8u channel)
2704 BX_SELECTED_CONTROLLER(channel).sector_count--;
2705 BX_SELECTED_CONTROLLER(channel).num_sectors--;
2707 if (BX_SELECTED_CONTROLLER(channel).lba_mode) {
2708 Bit64s current_address = 0;
2709 calculate_logical_address(channel, &current_address);
2710 current_address++;
2711 if (!BX_SELECTED_CONTROLLER(channel).lba48) {
2712 BX_SELECTED_CONTROLLER(channel).head_no = (Bit8u)((current_address >> 24) & 0xf);
2713 BX_SELECTED_CONTROLLER(channel).cylinder_no = (Bit16u)((current_address >> 8) & 0xffff);
2714 BX_SELECTED_CONTROLLER(channel).sector_no = (Bit8u)((current_address) & 0xff);
2715 } else {
2716 BX_SELECTED_CONTROLLER(channel).hob.hcyl = (Bit8u)((current_address >> 40) & 0xff);
2717 BX_SELECTED_CONTROLLER(channel).hob.lcyl = (Bit8u)((current_address >> 32) & 0xff);
2718 BX_SELECTED_CONTROLLER(channel).hob.sector = (Bit8u)((current_address >> 24) & 0xff);
2719 BX_SELECTED_CONTROLLER(channel).cylinder_no = (Bit16u)((current_address >> 8) & 0xffff);
2720 BX_SELECTED_CONTROLLER(channel).sector_no = (Bit8u)((current_address) & 0xff);
2722 } else {
2723 BX_SELECTED_CONTROLLER(channel).sector_no++;
2724 if (BX_SELECTED_CONTROLLER(channel).sector_no > BX_SELECTED_DRIVE(channel).hard_drive->sectors) {
2725 BX_SELECTED_CONTROLLER(channel).sector_no = 1;
2726 BX_SELECTED_CONTROLLER(channel).head_no++;
2727 if (BX_SELECTED_CONTROLLER(channel).head_no >= BX_SELECTED_DRIVE(channel).hard_drive->heads) {
2728 BX_SELECTED_CONTROLLER(channel).head_no = 0;
2729 BX_SELECTED_CONTROLLER(channel).cylinder_no++;
2730 if (BX_SELECTED_CONTROLLER(channel).cylinder_no >= BX_SELECTED_DRIVE(channel).hard_drive->cylinders)
2731 BX_SELECTED_CONTROLLER(channel).cylinder_no = BX_SELECTED_DRIVE(channel).hard_drive->cylinders - 1;
2737 void bx_hard_drive_c::identify_ATAPI_drive(Bit8u channel)
2739 unsigned i;
2740 char serial_number[21];
2742 memset(&BX_SELECTED_DRIVE(channel).id_drive, 0, 512);
2744 BX_SELECTED_DRIVE(channel).id_drive[0] = (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0); // Removable CDROM, 50us response, 12 byte packets
2746 for (i = 1; i <= 9; i++)
2747 BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
2749 strcpy(serial_number, "BXCD00000 ");
2750 serial_number[8] = BX_SELECTED_DRIVE(channel).device_num;
2751 for (i = 0; i < 10; i++) {
2752 BX_SELECTED_DRIVE(channel).id_drive[10+i] = (serial_number[i*2] << 8) |
2753 serial_number[i*2 + 1];
2756 for (i = 20; i <= 22; i++)
2757 BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
2759 const char* firmware = "ALPHA1 ";
2760 for (i = 0; i < strlen(firmware)/2; i++) {
2761 BX_SELECTED_DRIVE(channel).id_drive[23+i] = (firmware[i*2] << 8) |
2762 firmware[i*2 + 1];
2764 BX_ASSERT((23+i) == 27);
2766 for (i = 0; i < strlen((char *) BX_SELECTED_MODEL(channel))/2; i++) {
2767 BX_SELECTED_DRIVE(channel).id_drive[27+i] = (BX_SELECTED_MODEL(channel)[i*2] << 8) |
2768 BX_SELECTED_MODEL(channel)[i*2 + 1];
2770 BX_ASSERT((27+i) == 47);
2772 BX_SELECTED_DRIVE(channel).id_drive[47] = 0;
2773 BX_SELECTED_DRIVE(channel).id_drive[48] = 1; // 32 bits access
2775 if (BX_HD_THIS bmdma_present()) {
2776 BX_SELECTED_DRIVE(channel).id_drive[49] = (1<<9) | (1<<8); // LBA and DMA
2777 } else {
2778 BX_SELECTED_DRIVE(channel).id_drive[49] = (1<<9); // LBA only supported
2781 BX_SELECTED_DRIVE(channel).id_drive[50] = 0;
2782 BX_SELECTED_DRIVE(channel).id_drive[51] = 0;
2783 BX_SELECTED_DRIVE(channel).id_drive[52] = 0;
2785 BX_SELECTED_DRIVE(channel).id_drive[53] = 3; // words 64-70, 54-58 valid
2787 for (i = 54; i <= 62; i++)
2788 BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
2790 // copied from CFA540A
2791 BX_SELECTED_DRIVE(channel).id_drive[63] = 0x0103; // variable (DMA stuff)
2792 BX_SELECTED_DRIVE(channel).id_drive[64] = 0x0001; // PIO
2793 BX_SELECTED_DRIVE(channel).id_drive[65] = 0x00b4;
2794 BX_SELECTED_DRIVE(channel).id_drive[66] = 0x00b4;
2795 BX_SELECTED_DRIVE(channel).id_drive[67] = 0x012c;
2796 BX_SELECTED_DRIVE(channel).id_drive[68] = 0x00b4;
2798 BX_SELECTED_DRIVE(channel).id_drive[69] = 0;
2799 BX_SELECTED_DRIVE(channel).id_drive[70] = 0;
2800 BX_SELECTED_DRIVE(channel).id_drive[71] = 30; // faked
2801 BX_SELECTED_DRIVE(channel).id_drive[72] = 30; // faked
2802 BX_SELECTED_DRIVE(channel).id_drive[73] = 0;
2803 BX_SELECTED_DRIVE(channel).id_drive[74] = 0;
2805 BX_SELECTED_DRIVE(channel).id_drive[75] = 0;
2807 for (i = 76; i <= 79; i++)
2808 BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
2810 BX_SELECTED_DRIVE(channel).id_drive[80] = 0x1e; // supports up to ATA/ATAPI-4
2811 BX_SELECTED_DRIVE(channel).id_drive[81] = 0;
2812 BX_SELECTED_DRIVE(channel).id_drive[82] = 0;
2813 BX_SELECTED_DRIVE(channel).id_drive[83] = 0;
2814 BX_SELECTED_DRIVE(channel).id_drive[84] = 0;
2815 BX_SELECTED_DRIVE(channel).id_drive[85] = 0;
2816 BX_SELECTED_DRIVE(channel).id_drive[86] = 0;
2817 BX_SELECTED_DRIVE(channel).id_drive[87] = 0;
2818 BX_SELECTED_DRIVE(channel).id_drive[88] = 0;
2820 BX_SELECTED_DRIVE(channel).identify_set = 1;
2823 void bx_hard_drive_c::identify_drive(Bit8u channel)
2825 unsigned i;
2826 char serial_number[21];
2827 Bit32u temp32;
2828 Bit64u num_sects;
2830 memset(&BX_SELECTED_DRIVE(channel).id_drive, 0, 512);
2832 // Identify Drive command return values definition
2834 // This code is rehashed from some that was donated.
2835 // I'm using ANSI X3.221-1994, AT Attachment Interface for Disk Drives
2836 // and X3T10 2008D Working Draft for ATA-3
2839 // Word 0: general config bit-significant info
2840 // Note: bits 1-5 and 8-14 are now "Vendor specific (obsolete)"
2841 // bit 15: 0=ATA device
2842 // 1=ATAPI device
2843 // bit 14: 1=format speed tolerance gap required
2844 // bit 13: 1=track offset option available
2845 // bit 12: 1=data strobe offset option available
2846 // bit 11: 1=rotational speed tolerance is > 0,5% (typo?)
2847 // bit 10: 1=disk transfer rate > 10Mbs
2848 // bit 9: 1=disk transfer rate > 5Mbs but <= 10Mbs
2849 // bit 8: 1=disk transfer rate <= 5Mbs
2850 // bit 7: 1=removable cartridge drive
2851 // bit 6: 1=fixed drive
2852 // bit 5: 1=spindle motor control option implemented
2853 // bit 4: 1=head switch time > 15 usec
2854 // bit 3: 1=not MFM encoded
2855 // bit 2: 1=soft sectored
2856 // bit 1: 1=hard sectored
2857 // bit 0: 0=reserved
2858 BX_SELECTED_DRIVE(channel).id_drive[0] = 0x0040;
2860 // Word 1: number of user-addressable cylinders in
2861 // default translation mode. If the value in words 60-61
2862 // exceed 16,515,072, this word shall contain 16,383.
2863 if (BX_SELECTED_DRIVE(channel).hard_drive->cylinders > 16383) {
2864 BX_SELECTED_DRIVE(channel).id_drive[1] = 16383;
2865 } else {
2866 BX_SELECTED_DRIVE(channel).id_drive[1] = BX_SELECTED_DRIVE(channel).hard_drive->cylinders;
2869 // Word 2: reserved
2871 // Word 3: number of user-addressable heads in default
2872 // translation mode
2873 BX_SELECTED_DRIVE(channel).id_drive[3] = BX_SELECTED_DRIVE(channel).hard_drive->heads;
2875 // Word 4: # unformatted bytes per translated track in default xlate mode
2876 // Word 5: # unformatted bytes per sector in default xlated mode
2877 // Word 6: # user-addressable sectors per track in default xlate mode
2878 // Note: words 4,5 are now "Vendor specific (obsolete)"
2879 BX_SELECTED_DRIVE(channel).id_drive[4] = (512 * BX_SELECTED_DRIVE(channel).hard_drive->sectors);
2880 BX_SELECTED_DRIVE(channel).id_drive[5] = 512;
2881 BX_SELECTED_DRIVE(channel).id_drive[6] = BX_SELECTED_DRIVE(channel).hard_drive->sectors;
2883 // Word 7-9: Vendor specific
2885 // Word 10-19: Serial number (20 ASCII characters, 0000h=not specified)
2886 // This field is right justified and padded with spaces (20h).
2887 strcpy(serial_number, "BXHD00000 ");
2888 serial_number[7] = channel + 49;
2889 serial_number[8] = BX_HD_THIS channels[channel].drive_select + 49;
2890 for (i = 0; i < 10; i++) {
2891 BX_SELECTED_DRIVE(channel).id_drive[10+i] = (serial_number[i*2] << 8) |
2892 serial_number[i*2 + 1];
2895 // Word 20: buffer type
2896 // 0000h = not specified
2897 // 0001h = single ported single sector buffer which is
2898 // not capable of simulataneous data xfers to/from
2899 // the host and the disk.
2900 // 0002h = dual ported multi-sector buffer capable of
2901 // simulatenous data xfers to/from the host and disk.
2902 // 0003h = dual ported mutli-sector buffer capable of
2903 // simulatenous data xfers with a read caching
2904 // capability.
2905 // 0004h-ffffh = reserved
2906 BX_SELECTED_DRIVE(channel).id_drive[20] = 3;
2908 // Word 21: buffer size in 512 byte increments, 0000h = not specified
2909 BX_SELECTED_DRIVE(channel).id_drive[21] = 512; // 512 Sectors = 256kB cache
2911 // Word 22: # of ECC bytes available on read/write long cmds
2912 // 0000h = not specified
2913 BX_SELECTED_DRIVE(channel).id_drive[22] = 4;
2915 // Word 23..26: Firmware revision (8 ascii chars, 0000h=not specified)
2916 // This field is left justified and padded with spaces (20h)
2917 for (i=23; i<=26; i++)
2918 BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
2920 // Word 27..46: Model number (40 ascii chars, 0000h=not specified)
2921 // This field is left justified and padded with spaces (20h)
2922 for (i=0; i<20; i++) {
2923 BX_SELECTED_DRIVE(channel).id_drive[27+i] = (BX_SELECTED_MODEL(channel)[i*2] << 8) |
2924 BX_SELECTED_MODEL(channel)[i*2 + 1];
2927 // Word 47: 15-8 Vendor unique
2928 // 7-0 00h= read/write multiple commands not implemented
2929 // xxh= maximum # of sectors that can be transferred
2930 // per interrupt on read and write multiple commands
2931 BX_SELECTED_DRIVE(channel).id_drive[47] = MAX_MULTIPLE_SECTORS;
2933 // Word 48: 0000h = cannot perform dword IO
2934 // 0001h = can perform dword IO
2935 BX_SELECTED_DRIVE(channel).id_drive[48] = 1;
2937 // Word 49: Capabilities
2938 // 15-10: 0 = reserved
2939 // 9: 1 = LBA supported
2940 // 8: 1 = DMA supported
2941 // 7-0: Vendor unique
2942 if (BX_HD_THIS bmdma_present()) {
2943 BX_SELECTED_DRIVE(channel).id_drive[49] = (1<<9) | (1<<8);
2944 } else {
2945 BX_SELECTED_DRIVE(channel).id_drive[49] = 1<<9;
2948 // Word 50: Reserved
2950 // Word 51: 15-8 PIO data transfer cycle timing mode
2951 // 7-0 Vendor unique
2952 BX_SELECTED_DRIVE(channel).id_drive[51] = 0x200;
2954 // Word 52: 15-8 DMA data transfer cycle timing mode
2955 // 7-0 Vendor unique
2956 BX_SELECTED_DRIVE(channel).id_drive[52] = 0x200;
2958 // Word 53: 15-1 Reserved
2959 // 2 1=the fields reported in word 88 are valid
2960 // 1 1=the fields reported in words 64-70 are valid
2961 // 0 1=the fields reported in words 54-58 are valid
2962 BX_SELECTED_DRIVE(channel).id_drive[53] = 0x07;
2964 // Word 54: # of user-addressable cylinders in curr xlate mode
2965 // Word 55: # of user-addressable heads in curr xlate mode
2966 // Word 56: # of user-addressable sectors/track in curr xlate mode
2967 if (BX_SELECTED_DRIVE(channel).hard_drive->cylinders > 16383) {
2968 BX_SELECTED_DRIVE(channel).id_drive[54] = 16383;
2969 } else {
2970 BX_SELECTED_DRIVE(channel).id_drive[54] = BX_SELECTED_DRIVE(channel).hard_drive->cylinders;
2972 BX_SELECTED_DRIVE(channel).id_drive[55] = BX_SELECTED_DRIVE(channel).hard_drive->heads;
2973 BX_SELECTED_DRIVE(channel).id_drive[56] = BX_SELECTED_DRIVE(channel).hard_drive->sectors;
2975 // Word 57-58: Current capacity in sectors
2976 // Excludes all sectors used for device specific purposes.
2977 temp32 =
2978 BX_SELECTED_DRIVE(channel).hard_drive->cylinders *
2979 BX_SELECTED_DRIVE(channel).hard_drive->heads *
2980 BX_SELECTED_DRIVE(channel).hard_drive->sectors;
2981 BX_SELECTED_DRIVE(channel).id_drive[57] = (temp32 & 0xffff); // LSW
2982 BX_SELECTED_DRIVE(channel).id_drive[58] = (temp32 >> 16); // MSW
2984 // Word 59: 15-9 Reserved
2985 // 8 1=multiple sector setting is valid
2986 // 7-0 current setting for number of sectors that can be
2987 // transferred per interrupt on R/W multiple commands
2988 if (BX_SELECTED_CONTROLLER(channel).multiple_sectors > 0)
2989 BX_SELECTED_DRIVE(channel).id_drive[59] = 0x0100 | BX_SELECTED_CONTROLLER(channel).multiple_sectors;
2990 else
2991 BX_SELECTED_DRIVE(channel).id_drive[59] = 0x0000;
2993 // Word 60-61:
2994 // If drive supports LBA Mode, these words reflect total # of user
2995 // addressable sectors. This value does not depend on the current
2996 // drive geometry. If the drive does not support LBA mode, these
2997 // words shall be set to 0.
2998 if (BX_SELECTED_DRIVE(channel).hard_drive->hd_size > 0)
2999 num_sects = (BX_SELECTED_DRIVE(channel).hard_drive->hd_size >> 9);
3000 else
3001 num_sects = BX_SELECTED_DRIVE(channel).hard_drive->cylinders * BX_SELECTED_DRIVE(channel).hard_drive->heads * BX_SELECTED_DRIVE(channel).hard_drive->sectors;
3002 BX_SELECTED_DRIVE(channel).id_drive[60] = (Bit16u)(num_sects & 0xffff); // LSW
3003 BX_SELECTED_DRIVE(channel).id_drive[61] = (Bit16u)(num_sects >> 16); // MSW
3005 // Word 62: 15-8 single word DMA transfer mode active
3006 // 7-0 single word DMA transfer modes supported
3007 // The low order byte identifies by bit, all the Modes which are
3008 // supported e.g., if Mode 0 is supported bit 0 is set.
3009 // The high order byte contains a single bit set to indiciate
3010 // which mode is active.
3011 BX_SELECTED_DRIVE(channel).id_drive[62] = 0x0;
3013 // Word 63: 15-8 multiword DMA transfer mode active
3014 // 7-0 multiword DMA transfer modes supported
3015 // The low order byte identifies by bit, all the Modes which are
3016 // supported e.g., if Mode 0 is supported bit 0 is set.
3017 // The high order byte contains a single bit set to indiciate
3018 // which mode is active.
3019 if (BX_HD_THIS bmdma_present()) {
3020 BX_SELECTED_DRIVE(channel).id_drive[63] = 0x07 | (BX_SELECTED_CONTROLLER(channel).mdma_mode << 8);
3021 } else {
3022 BX_SELECTED_DRIVE(channel).id_drive[63] = 0x0;
3025 // Word 64 PIO modes supported
3026 BX_SELECTED_DRIVE(channel).id_drive[64] = 0x00;
3028 // Word 65-68 PIO/DMA cycle time (nanoseconds)
3029 for (i=65; i<=68; i++)
3030 BX_SELECTED_DRIVE(channel).id_drive[i] = 120;
3032 // Word 69-79 Reserved
3034 // Word 80: 15-5 reserved
3035 // 6 supports ATA/ATAPI-6
3036 // 5 supports ATA/ATAPI-5
3037 // 4 supports ATA/ATAPI-4
3038 // 3 supports ATA-3
3039 // 2 supports ATA-2
3040 // 1 supports ATA-1
3041 // 0 reserved
3042 BX_SELECTED_DRIVE(channel).id_drive[80] = 0x7e;
3044 // Word 81: Minor version number
3045 BX_SELECTED_DRIVE(channel).id_drive[81] = 0x00;
3047 // Word 82: 15 obsolete
3048 // 14 NOP command supported
3049 // 13 READ BUFFER command supported
3050 // 12 WRITE BUFFER command supported
3051 // 11 obsolete
3052 // 10 Host protected area feature set supported
3053 // 9 DEVICE RESET command supported
3054 // 8 SERVICE interrupt supported
3055 // 7 release interrupt supported
3056 // 6 look-ahead supported
3057 // 5 write cache supported
3058 // 4 supports PACKET command feature set
3059 // 3 supports power management feature set
3060 // 2 supports removable media feature set
3061 // 1 supports securite mode feature set
3062 // 0 support SMART feature set
3063 BX_SELECTED_DRIVE(channel).id_drive[82] = 1 << 14;
3065 // Word 83: 15 shall be ZERO
3066 // 14 shall be ONE
3067 // 13 FLUSH CACHE EXT command supported
3068 // 12 FLUSH CACHE command supported
3069 // 11 Device configuration overlay supported
3070 // 10 48-bit Address feature set supported
3071 // 9 Automatic acoustic management supported
3072 // 8 SET MAX security supported
3073 // 7 reserved for 1407DT PARTIES
3074 // 6 SetF sub-command Power-Up supported
3075 // 5 Power-Up in standby feature set supported
3076 // 4 Removable media notification supported
3077 // 3 APM feature set supported
3078 // 2 CFA feature set supported
3079 // 1 READ/WRITE DMA QUEUED commands supported
3080 // 0 Download MicroCode supported
3081 BX_SELECTED_DRIVE(channel).id_drive[83] = (1 << 14) | (1 << 13) | (1 << 12) | (1 << 10);
3082 BX_SELECTED_DRIVE(channel).id_drive[84] = 1 << 14;
3083 BX_SELECTED_DRIVE(channel).id_drive[85] = 1 << 14;
3085 // Word 86: 15 shall be ZERO
3086 // 14 shall be ONE
3087 // 13 FLUSH CACHE EXT command enabled
3088 // 12 FLUSH CACHE command enabled
3089 // 11 Device configuration overlay enabled
3090 // 10 48-bit Address feature set enabled
3091 // 9 Automatic acoustic management enabled
3092 // 8 SET MAX security enabled
3093 // 7 reserved for 1407DT PARTIES
3094 // 6 SetF sub-command Power-Up enabled
3095 // 5 Power-Up in standby feature set enabled
3096 // 4 Removable media notification enabled
3097 // 3 APM feature set enabled
3098 // 2 CFA feature set enabled
3099 // 1 READ/WRITE DMA QUEUED commands enabled
3100 // 0 Download MicroCode enabled
3101 BX_SELECTED_DRIVE(channel).id_drive[86] = (1 << 14) | (1 << 13) | (1 << 12) | (1 << 10);
3102 BX_SELECTED_DRIVE(channel).id_drive[87] = 1 << 14;
3104 if (BX_HD_THIS bmdma_present()) {
3105 BX_SELECTED_DRIVE(channel).id_drive[88] = 0x3f | (BX_SELECTED_CONTROLLER(channel).udma_mode << 8);
3106 } else {
3107 BX_SELECTED_DRIVE(channel).id_drive[88] = 0x0;
3109 BX_SELECTED_DRIVE(channel).id_drive[93] = 1 | (1 << 14) | 0x2000;
3111 // Word 100-103: 48-bit total number of sectors
3112 BX_SELECTED_DRIVE(channel).id_drive[100] = (Bit16u)(num_sects & 0xffff);
3113 BX_SELECTED_DRIVE(channel).id_drive[101] = (Bit16u)(num_sects >> 16);
3114 BX_SELECTED_DRIVE(channel).id_drive[102] = (Bit16u)(num_sects >> 32);
3115 BX_SELECTED_DRIVE(channel).id_drive[103] = (Bit16u)(num_sects >> 48);
3117 // Word 128-159 Vendor unique
3118 // Word 160-255 Reserved
3120 BX_SELECTED_DRIVE(channel).identify_set = 1;
3123 void bx_hard_drive_c::init_send_atapi_command(Bit8u channel, Bit8u command, int req_length, int alloc_length, bx_bool lazy)
3125 // BX_SELECTED_CONTROLLER(channel).byte_count is a union of BX_SELECTED_CONTROLLER(channel).cylinder_no;
3126 // lazy is used to force a data read in the buffer at the next read.
3128 if (BX_SELECTED_CONTROLLER(channel).byte_count == 0xffff)
3129 BX_SELECTED_CONTROLLER(channel).byte_count = 0xfffe;
3131 if ((BX_SELECTED_CONTROLLER(channel).byte_count & 1) &&
3132 !(alloc_length <= BX_SELECTED_CONTROLLER(channel).byte_count))
3134 BX_INFO(("Odd byte count (0x%04x) to ATAPI command 0x%02x, using 0x%04x",
3135 BX_SELECTED_CONTROLLER(channel).byte_count, command, BX_SELECTED_CONTROLLER(channel).byte_count - 1));
3136 BX_SELECTED_CONTROLLER(channel).byte_count -= 1;
3139 if (!BX_SELECTED_CONTROLLER(channel).packet_dma) {
3140 if (BX_SELECTED_CONTROLLER(channel).byte_count == 0)
3141 BX_PANIC(("ATAPI command 0x%02x with zero byte count", command));
3144 if (alloc_length < 0)
3145 BX_PANIC(("Allocation length < 0"));
3146 if (alloc_length == 0)
3147 alloc_length = BX_SELECTED_CONTROLLER(channel).byte_count;
3149 BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
3150 BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 0;
3151 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
3152 BX_SELECTED_CONTROLLER(channel).status.drq = 1;
3153 BX_SELECTED_CONTROLLER(channel).status.err = 0;
3155 // no bytes transfered yet
3156 if (lazy)
3157 BX_SELECTED_CONTROLLER(channel).buffer_index = BX_SELECTED_CONTROLLER(channel).buffer_size;
3158 else
3159 BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
3160 BX_SELECTED_CONTROLLER(channel).drq_index = 0;
3162 if (BX_SELECTED_CONTROLLER(channel).byte_count > req_length)
3163 BX_SELECTED_CONTROLLER(channel).byte_count = req_length;
3165 if (BX_SELECTED_CONTROLLER(channel).byte_count > alloc_length)
3166 BX_SELECTED_CONTROLLER(channel).byte_count = alloc_length;
3168 BX_SELECTED_DRIVE(channel).atapi.command = command;
3169 BX_SELECTED_DRIVE(channel).atapi.drq_bytes = BX_SELECTED_CONTROLLER(channel).byte_count;
3170 BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining = (req_length < alloc_length) ? req_length : alloc_length;
3173 void bx_hard_drive_c::atapi_cmd_error(Bit8u channel, sense_t sense_key, asc_t asc, bx_bool show)
3175 if (show) {
3176 BX_ERROR(("ata%d-%d: atapi_cmd_error: key=%02x asc=%02x", channel, BX_SLAVE_SELECTED(channel), sense_key, asc));
3177 } else {
3178 BX_DEBUG(("ata%d-%d: atapi_cmd_error: key=%02x asc=%02x", channel, BX_SLAVE_SELECTED(channel), sense_key, asc));
3181 BX_SELECTED_CONTROLLER(channel).error_register = sense_key << 4;
3182 BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
3183 BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
3184 BX_SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
3185 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
3186 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
3187 BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
3188 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
3189 BX_SELECTED_CONTROLLER(channel).status.err = 1;
3191 BX_SELECTED_DRIVE(channel).sense.sense_key = sense_key;
3192 BX_SELECTED_DRIVE(channel).sense.asc = asc;
3193 BX_SELECTED_DRIVE(channel).sense.ascq = 0;
3196 void BX_CPP_AttrRegparmN(1)
3197 bx_hard_drive_c::atapi_cmd_nop(Bit8u channel)
3199 BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
3200 BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
3201 BX_SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
3202 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
3203 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
3204 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
3205 BX_SELECTED_CONTROLLER(channel).status.err = 0;
3208 void bx_hard_drive_c::init_mode_sense_single(Bit8u channel, const void* src, int size)
3210 // Header
3211 BX_SELECTED_CONTROLLER(channel).buffer[0] = (size+6) >> 8;
3212 BX_SELECTED_CONTROLLER(channel).buffer[1] = (size+6) & 0xff;
3213 if (BX_SELECTED_DRIVE(channel).cdrom.ready)
3214 BX_SELECTED_CONTROLLER(channel).buffer[2] = 0x12; // media present 120mm CD-ROM (CD-R) data/audio door closed
3215 else
3216 BX_SELECTED_CONTROLLER(channel).buffer[2] = 0x70; // no media present
3217 BX_SELECTED_CONTROLLER(channel).buffer[3] = 0; // reserved
3218 BX_SELECTED_CONTROLLER(channel).buffer[4] = 0; // reserved
3219 BX_SELECTED_CONTROLLER(channel).buffer[5] = 0; // reserved
3220 BX_SELECTED_CONTROLLER(channel).buffer[6] = 0; // reserved
3221 BX_SELECTED_CONTROLLER(channel).buffer[7] = 0; // reserved
3223 // Data
3224 memcpy(BX_SELECTED_CONTROLLER(channel).buffer + 8, src, size);
3227 void BX_CPP_AttrRegparmN(1)
3228 bx_hard_drive_c::ready_to_send_atapi(Bit8u channel)
3230 if (!BX_SELECTED_CONTROLLER(channel).packet_dma) {
3231 raise_interrupt(channel);
3235 void BX_CPP_AttrRegparmN(1)
3236 bx_hard_drive_c::raise_interrupt(Bit8u channel)
3238 BX_DEBUG(("raise_interrupt called, disable_irq = %02x", BX_SELECTED_CONTROLLER(channel).control.disable_irq));
3239 if (!BX_SELECTED_CONTROLLER(channel).control.disable_irq) {
3240 BX_DEBUG(("raising interrupt"));
3241 } else {
3242 BX_DEBUG(("Not raising interrupt"));
3244 if (!BX_SELECTED_CONTROLLER(channel).control.disable_irq) {
3245 Bit32u irq = BX_HD_THIS channels[channel].irq;
3246 BX_DEBUG(("Raising interrupt %d {%s}", irq, BX_SELECTED_TYPE_STRING(channel)));
3247 #if BX_SUPPORT_PCI
3248 DEV_ide_bmdma_set_irq(channel);
3249 #endif
3250 DEV_pic_raise_irq(irq);
3251 } else {
3252 if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
3253 BX_INFO(("Interrupt masked {%s}", BX_SELECTED_TYPE_STRING(channel)));
3257 void bx_hard_drive_c::command_aborted(Bit8u channel, unsigned value)
3259 BX_DEBUG(("aborting on command 0x%02x {%s}", value, BX_SELECTED_TYPE_STRING(channel)));
3260 BX_SELECTED_CONTROLLER(channel).current_command = 0;
3261 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
3262 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
3263 BX_SELECTED_CONTROLLER(channel).status.err = 1;
3264 BX_SELECTED_CONTROLLER(channel).error_register = 0x04; // command ABORTED
3265 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
3266 BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
3267 BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
3268 raise_interrupt(channel);
3271 Bit32u bx_hard_drive_c::get_device_handle(Bit8u channel, Bit8u device)
3273 BX_DEBUG(("get_device_handle %d %d",channel, device));
3274 if ((channel < BX_MAX_ATA_CHANNEL) && (device < 2)) {
3275 return ((channel*2) + device);
3278 return BX_MAX_ATA_CHANNEL*2;
3281 Bit32u bx_hard_drive_c::get_first_cd_handle(void)
3283 for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
3284 if (BX_DRIVE_IS_CD(channel,0)) return (channel*2);
3285 if (BX_DRIVE_IS_CD(channel,1)) return ((channel*2) + 1);
3287 return BX_MAX_ATA_CHANNEL*2;
3290 unsigned bx_hard_drive_c::get_cd_media_status(Bit32u handle)
3292 if (handle >= BX_MAX_ATA_CHANNEL*2) return 0;
3294 Bit8u channel = handle / 2;
3295 Bit8u device = handle % 2;
3296 return BX_HD_THIS channels[channel].drives[device].cdrom.ready;
3299 unsigned bx_hard_drive_c::set_cd_media_status(Bit32u handle, unsigned status)
3301 char ata_name[20];
3303 BX_DEBUG (("set_cd_media_status handle=%d status=%d", handle, status));
3304 if (handle >= BX_MAX_ATA_CHANNEL*2) return 0;
3306 Bit8u channel = handle / 2;
3307 Bit8u device = handle % 2;
3309 sprintf(ata_name, "ata.%d.%s", channel, (device==0)?"master":"slave");
3310 bx_list_c *base = (bx_list_c*) SIM->get_param(ata_name);
3311 // if setting to the current value, nothing to do
3312 if (status == BX_HD_THIS channels[channel].drives[device].cdrom.ready)
3313 return(status);
3314 // return 0 if no cdromd is present
3315 if (!BX_DRIVE_IS_CD(channel,device))
3316 return(0);
3318 if (status == 0) {
3319 // eject cdrom if not locked by guest OS
3320 if (BX_HD_THIS channels[channel].drives[device].cdrom.locked) return(1);
3321 else {
3322 #ifdef LOWLEVEL_CDROM
3323 BX_HD_THIS channels[channel].drives[device].cdrom.cd->eject_cdrom();
3324 #endif
3325 BX_HD_THIS channels[channel].drives[device].cdrom.ready = 0;
3326 SIM->get_param_enum("status", base)->set(BX_EJECTED);
3328 } else {
3329 // insert cdrom
3330 #ifdef LOWLEVEL_CDROM
3331 if (BX_HD_THIS channels[channel].drives[device].cdrom.cd->insert_cdrom(SIM->get_param_string("path", base)->getptr())) {
3332 BX_INFO(("Media present in CD-ROM drive"));
3333 BX_HD_THIS channels[channel].drives[device].cdrom.ready = 1;
3334 Bit32u capacity = BX_HD_THIS channels[channel].drives[device].cdrom.cd->capacity();
3335 BX_HD_THIS channels[channel].drives[device].cdrom.capacity = capacity;
3336 BX_INFO(("Capacity is %d sectors (%.2f MB)", capacity, (float)capacity / 512.0));
3337 SIM->get_param_enum("status", base)->set(BX_INSERTED);
3338 BX_SELECTED_DRIVE(channel).sense.sense_key = SENSE_UNIT_ATTENTION;
3339 BX_SELECTED_DRIVE(channel).sense.asc = 0;
3340 BX_SELECTED_DRIVE(channel).sense.ascq = 0;
3341 raise_interrupt(channel);
3343 else
3344 #endif
3346 BX_INFO(("Could not locate CD-ROM, continuing with media not present"));
3347 BX_HD_THIS channels[channel].drives[device].cdrom.ready = 0;
3348 SIM->get_param_enum("status", base)->set(BX_EJECTED);
3351 return (BX_HD_THIS channels[channel].drives[device].cdrom.ready);
3354 bx_bool bx_hard_drive_c::bmdma_present(void)
3356 #if BX_SUPPORT_PCI
3357 if (SIM->get_param_bool(BXPN_I440FX_SUPPORT)->get()) {
3358 return DEV_ide_bmdma_present();
3360 #endif
3361 return 0;
3364 #if BX_SUPPORT_PCI
3365 bx_bool bx_hard_drive_c::bmdma_read_sector(Bit8u channel, Bit8u *buffer, Bit32u *sector_size)
3367 if ((BX_SELECTED_CONTROLLER(channel).current_command == 0xC8) ||
3368 (BX_SELECTED_CONTROLLER(channel).current_command == 0x25)) {
3369 *sector_size = 512;
3370 if (!ide_read_sector(channel, buffer, 512)) {
3371 return 0;
3373 } else if (BX_SELECTED_CONTROLLER(channel).current_command == 0xA0) {
3374 if (BX_SELECTED_CONTROLLER(channel).packet_dma) {
3375 switch (BX_SELECTED_DRIVE(channel).atapi.command) {
3376 case 0x28: // read (10)
3377 case 0xa8: // read (12)
3378 case 0xbe: // read cd
3379 *sector_size = BX_SELECTED_CONTROLLER(channel).buffer_size;
3380 if (!BX_SELECTED_DRIVE(channel).cdrom.ready) {
3381 BX_PANIC(("Read with CDROM not ready"));
3382 return 0;
3384 /* set status bar conditions for device */
3385 if (!BX_SELECTED_DRIVE(channel).iolight_counter)
3386 bx_gui->statusbar_setitem(BX_SELECTED_DRIVE(channel).statusbar_id, 1);
3387 BX_SELECTED_DRIVE(channel).iolight_counter = 5;
3388 bx_pc_system.activate_timer(BX_HD_THIS iolight_timer_index, 100000, 0);
3389 if (!BX_SELECTED_DRIVE(channel).cdrom.cd->read_block(buffer, BX_SELECTED_DRIVE(channel).cdrom.next_lba,
3390 BX_SELECTED_CONTROLLER(channel).buffer_size))
3392 BX_PANIC(("CDROM: read block %d failed", BX_SELECTED_DRIVE(channel).cdrom.next_lba));
3393 return 0;
3395 BX_SELECTED_DRIVE(channel).cdrom.next_lba++;
3396 BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks--;
3397 break;
3398 default:
3399 memcpy(buffer, BX_SELECTED_CONTROLLER(channel).buffer, *sector_size);
3400 break;
3402 } else {
3403 BX_ERROR(("PACKET-DMA not active"));
3404 command_aborted(channel, BX_SELECTED_CONTROLLER(channel).current_command);
3405 return 0;
3407 } else {
3408 BX_ERROR(("DMA read not active"));
3409 command_aborted (channel, BX_SELECTED_CONTROLLER(channel).current_command);
3410 return 0;
3412 return 1;
3415 bx_bool bx_hard_drive_c::bmdma_write_sector(Bit8u channel, Bit8u *buffer)
3417 if ((BX_SELECTED_CONTROLLER(channel).current_command != 0xCA) &&
3418 (BX_SELECTED_CONTROLLER(channel).current_command != 0x35)) {
3419 BX_ERROR(("DMA write not active"));
3420 command_aborted (channel, BX_SELECTED_CONTROLLER(channel).current_command);
3421 return 0;
3423 if (!ide_write_sector(channel, buffer, 512)) {
3424 return 0;
3426 return 1;
3429 void bx_hard_drive_c::bmdma_complete(Bit8u channel)
3431 BX_SELECTED_CONTROLLER(channel).status.busy = 0;
3432 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
3433 BX_SELECTED_CONTROLLER(channel).status.drq = 0;
3434 BX_SELECTED_CONTROLLER(channel).status.err = 0;
3435 if (BX_SELECTED_IS_CD(channel)) {
3436 BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
3437 BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
3438 BX_SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
3439 } else {
3440 BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
3441 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
3442 BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
3444 raise_interrupt(channel);
3446 #endif
3448 void bx_hard_drive_c::set_signature(Bit8u channel, Bit8u id)
3450 // Device signature
3451 BX_CONTROLLER(channel,id).head_no = 0;
3452 BX_CONTROLLER(channel,id).sector_count = 1;
3453 BX_CONTROLLER(channel,id).sector_no = 1;
3454 if (BX_DRIVE_IS_HD(channel,id)) {
3455 BX_CONTROLLER(channel,id).cylinder_no = 0;
3456 BX_HD_THIS channels[channel].drive_select = 0;
3457 } else if (BX_DRIVE_IS_CD(channel,id)) {
3458 BX_CONTROLLER(channel,id).cylinder_no = 0xeb14;
3459 } else {
3460 BX_CONTROLLER(channel,id).cylinder_no = 0xffff;
3464 bx_bool bx_hard_drive_c::ide_read_sector(Bit8u channel, Bit8u *buffer, Bit32u buffer_size)
3466 Bit64s logical_sector = 0;
3467 Bit64s ret;
3469 int sector_count = (buffer_size / 512);
3470 Bit8u *bufptr = buffer;
3471 do {
3472 if (!calculate_logical_address(channel, &logical_sector)) {
3473 BX_ERROR(("ide_read_sector() reached invalid sector %lu, aborting", (unsigned long)logical_sector));
3474 command_aborted(channel, BX_SELECTED_CONTROLLER(channel).current_command);
3475 return 0;
3477 ret = BX_SELECTED_DRIVE(channel).hard_drive->lseek(logical_sector * 512, SEEK_SET);
3478 if (ret < 0) {
3479 BX_ERROR(("could not lseek() hard drive image file"));
3480 command_aborted(channel, BX_SELECTED_CONTROLLER(channel).current_command);
3481 return 0;
3483 /* set status bar conditions for device */
3484 if (!BX_SELECTED_DRIVE(channel).iolight_counter)
3485 bx_gui->statusbar_setitem(BX_SELECTED_DRIVE(channel).statusbar_id, 1);
3486 BX_SELECTED_DRIVE(channel).iolight_counter = 5;
3487 bx_pc_system.activate_timer(BX_HD_THIS iolight_timer_index, 100000, 0);
3488 ret = BX_SELECTED_DRIVE(channel).hard_drive->read((bx_ptr_t)bufptr, 512);
3489 if (ret < 512) {
3490 BX_ERROR(("could not read() hard drive image file at byte %lu", (unsigned long)logical_sector*512));
3491 command_aborted(channel, BX_SELECTED_CONTROLLER(channel).current_command);
3492 return 0;
3494 increment_address(channel);
3495 bufptr += 512;
3496 } while (--sector_count > 0);
3498 return 1;
3501 bx_bool bx_hard_drive_c::ide_write_sector(Bit8u channel, Bit8u *buffer, Bit32u buffer_size)
3503 Bit64s logical_sector = 0;
3504 Bit64s ret;
3506 int sector_count = (buffer_size / 512);
3507 Bit8u *bufptr = buffer;
3508 do {
3509 if (!calculate_logical_address(channel, &logical_sector)) {
3510 BX_ERROR(("ide_write_sector() reached invalid sector %lu, aborting", (unsigned long)logical_sector));
3511 command_aborted(channel, BX_SELECTED_CONTROLLER(channel).current_command);
3512 return 0;
3514 ret = BX_SELECTED_DRIVE(channel).hard_drive->lseek(logical_sector * 512, SEEK_SET);
3515 if (ret < 0) {
3516 BX_ERROR(("could not lseek() hard drive image file at byte %lu", (unsigned long)logical_sector * 512));
3517 command_aborted(channel, BX_SELECTED_CONTROLLER(channel).current_command);
3518 return 0;
3520 /* set status bar conditions for device */
3521 if (!BX_SELECTED_DRIVE(channel).iolight_counter)
3522 bx_gui->statusbar_setitem(BX_SELECTED_DRIVE(channel).statusbar_id, 1, 1 /* write */);
3523 BX_SELECTED_DRIVE(channel).iolight_counter = 5;
3524 bx_pc_system.activate_timer(BX_HD_THIS iolight_timer_index, 100000, 0);
3525 ret = BX_SELECTED_DRIVE(channel).hard_drive->write((bx_ptr_t)bufptr, 512);
3526 if (ret < 512) {
3527 BX_ERROR(("could not write() hard drive image file at byte %lu", (unsigned long)logical_sector*512));
3528 command_aborted(channel, BX_SELECTED_CONTROLLER(channel).current_command);
3529 return 0;
3531 increment_address(channel);
3532 bufptr += 512;
3533 } while (--sector_count > 0);
3535 return 1;
3538 void bx_hard_drive_c::lba48_transform(Bit8u channel, bx_bool lba48)
3540 BX_SELECTED_CONTROLLER(channel).lba48 = lba48;
3542 if (!BX_SELECTED_CONTROLLER(channel).lba48) {
3543 if (!BX_SELECTED_CONTROLLER(channel).sector_count)
3544 BX_SELECTED_CONTROLLER(channel).num_sectors = 256;
3545 else
3546 BX_SELECTED_CONTROLLER(channel).num_sectors = BX_SELECTED_CONTROLLER(channel).sector_count;
3547 } else {
3548 if (!BX_SELECTED_CONTROLLER(channel).sector_count && !BX_SELECTED_CONTROLLER(channel).hob.nsector)
3549 BX_SELECTED_CONTROLLER(channel).num_sectors = 65536;
3550 else
3551 BX_SELECTED_CONTROLLER(channel).num_sectors = (BX_SELECTED_CONTROLLER(channel).hob.nsector << 8) |
3552 BX_SELECTED_CONTROLLER(channel).sector_count;
3556 error_recovery_t::error_recovery_t()
3558 if (sizeof(error_recovery_t) != 8) {
3559 BX_PANIC(("error_recovery_t has size != 8"));
3562 data[0] = 0x01;
3563 data[1] = 0x06;
3564 data[2] = 0x00;
3565 data[3] = 0x05; // Try to recover 5 times
3566 data[4] = 0x00;
3567 data[5] = 0x00;
3568 data[6] = 0x00;
3569 data[7] = 0x00;