1 /////////////////////////////////////////////////////////////////////////
2 // $Id: harddrv.cc,v 1.216 2008/12/11 18:01:56 vruppert Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2002 MandrakeSoft S.A.
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 /////////////////////////////////////////////////////////////////////////
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.
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)
129 bx_hard_drive_c::bx_hard_drive_c()
132 # error code must be fixed to use DLL_HD_SUPPORT and 4 ata channels
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
;
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
;
168 void bx_hard_drive_c::init(void)
170 Bit8u channel
, image_mode
;
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();
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",
193 BX_HD_THIS channels
[channel
].ioaddr1
,
194 BX_HD_THIS channels
[channel
].ioaddr2
,
195 BX_HD_THIS channels
[channel
].irq
));
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;
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;
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;
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();
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();
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();
323 #endif //EXTERNAL_DISK_SIMULATOR
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();
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();
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();
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();
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());
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();
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());
371 #if BX_COMPRESSED_HD_SUPPORT
372 case BX_ATA_MODE_Z_UNDOABLE
:
373 BX_PANIC(("z-undoable disk support not implemented"));
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());
382 case BX_ATA_MODE_Z_VOLATILE
:
383 BX_PANIC(("z-volatile disk support not implemented"));
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());
391 #endif //BX_COMPRESSED_HD_SUPPORT
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
]));
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
));
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
);
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
));
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;
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));
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
);
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":
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
));
614 case BX_ATA_TRANSLATION_LBA
:
615 DEV_cmos_set_reg(reg
, DEV_cmos_get_reg(reg
) | (1 << bitshift
));
617 case BX_ATA_TRANSLATION_LARGE
:
618 DEV_cmos_set_reg(reg
, DEV_cmos_get_reg(reg
) | (2 << bitshift
));
620 case BX_ATA_TRANSLATION_RECHS
:
621 DEV_cmos_set_reg(reg
, DEV_cmos_get_reg(reg
) | (3 << bitshift
));
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);
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)
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);
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; \
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
)
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
)
770 #endif // !BX_USE_HD_SMF
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
;
783 else if ((address
& 0xfff8) == BX_HD_THIS channels
[channel
].ioaddr2
) {
784 port
= address
- BX_HD_THIS channels
[channel
].ioaddr2
+ 0x10;
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
));
794 port
= address
- 0x03e0;
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
));
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;
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);
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;
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
);
885 case 0xec: // IDENTIFY DEVICE
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
];
900 value32
|= (BX_SELECTED_CONTROLLER(channel
).buffer
[index
] << 8);
904 value32
|= (BX_SELECTED_CONTROLLER(channel
).buffer
[index
] << 16);
905 value32
|= (BX_SELECTED_CONTROLLER(channel
).buffer
[index
+1] << 24);
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 ..."));
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}"));
953 BX_INFO(("READ block loaded (%d remaining) {CDROM}",
954 BX_SELECTED_DRIVE(channel
).cdrom
.remaining_blocks
));
956 // one block transfered, start at beginning
959 BX_PANIC(("Read with no LOWLEVEL_CDROM"));
963 default: // no need to load a new block
968 value32
= BX_SELECTED_CONTROLLER(channel
).buffer
[index
+increment
];
971 value32
|= (BX_SELECTED_CONTROLLER(channel
).buffer
[index
+increment
] << 8);
975 value32
|= (BX_SELECTED_CONTROLLER(channel
).buffer
[index
+increment
] << 16);
976 value32
|= (BX_SELECTED_CONTROLLER(channel
).buffer
[index
+increment
+1] << 24);
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
);
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
);
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;
1103 BX_PANIC(("IO read(0x%04x): current command is %02xh", address
,
1104 (unsigned) BX_SELECTED_CONTROLLER(channel
).current_command
));
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
;
1114 case 0x02: // hard disk sector count / interrupt reason 0x1f2
1115 value8
= (!BX_ANY_IS_PRESENT(channel
)) ? 0 : BX_SELECTED_CONTROLLER(channel
).sector_count
;
1117 case 0x03: // sector number 0x1f3
1118 value8
= (!BX_ANY_IS_PRESENT(channel
)) ? 0 : BX_SELECTED_CONTROLLER(channel
).sector_no
;
1120 case 0x04: // cylinder low 0x1f4
1121 value8
= (!BX_ANY_IS_PRESENT(channel
)) ? 0 : (BX_SELECTED_CONTROLLER(channel
).cylinder_no
& 0x00ff);
1123 case 0x05: // cylinder high 0x1f5
1124 value8
= (!BX_ANY_IS_PRESENT(channel
)) ? 0 : BX_SELECTED_CONTROLLER(channel
).cylinder_no
>> 8;
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
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);
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
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;
1165 DEV_pic_lower_irq(BX_HD_THIS channels
[channel
].irq
);
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
1179 BX_PANIC(("hard drive: io read to address %x unsupported",
1180 (unsigned) address
));
1183 BX_PANIC(("hard drive: shouldnt get here!"));
1187 BX_DEBUG(("32-bit read from %04x = %08x {%s}",
1188 (unsigned) address
, value32
, BX_SELECTED_TYPE_STRING(channel
)));
1192 BX_DEBUG(("16-bit read from %04x = %04x {%s}",
1193 (unsigned) address
, value16
, BX_SELECTED_TYPE_STRING(channel
)));
1197 BX_DEBUG(("8-bit read from %04x = %02x {%s}",
1198 (unsigned) address
, value8
, BX_SELECTED_TYPE_STRING(channel
)));
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
)
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
)
1216 #endif // !BX_USE_HD_SMF
1217 Bit64s logical_sector
;
1218 bx_bool prev_control_reset
;
1221 Bit8u channel
= BX_MAX_ATA_CHANNEL
;
1222 Bit32u port
= 0xff; // undefined
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
;
1230 else if ((address
& 0xfff8) == BX_HD_THIS channels
[channel
].ioaddr2
) {
1231 port
= address
- BX_HD_THIS channels
[channel
].ioaddr2
+ 0x10;
1236 if (channel
== BX_MAX_ATA_CHANNEL
) {
1237 if (address
!= 0x03f6) {
1238 BX_PANIC(("write: unable to find ATA channel, ioport=0x%04x", address
));
1241 port
= address
- 0x03e0;
1247 BX_DEBUG(("8-bit write to %04x = %02x {%s}",
1248 address
, value
, BX_SELECTED_TYPE_STRING(channel
)));
1252 BX_DEBUG(("16-bit write to %04x = %04x {%s}",
1253 address
, value
, BX_SELECTED_TYPE_STRING(channel
)));
1257 BX_DEBUG(("32-bit write to %04x = %08x {%s}",
1258 address
, value
, BX_SELECTED_TYPE_STRING(channel
)));
1262 BX_DEBUG(("unknown-size write to %04x = %08x {%s}",
1263 address
, value
, BX_SELECTED_TYPE_STRING(channel
)));
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
;
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);
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;
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
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
);
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
));
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);
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
);
1372 atapi_cmd_error(channel
, SENSE_NOT_READY
, ASC_MEDIUM_NOT_PRESENT
, 0);
1374 raise_interrupt(channel
);
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
);
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
);
1406 case 0x1b: // start stop unit
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();
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();
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
);
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
);
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);
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;
1485 case 0x0: // current values
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
);
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) |
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
);
1525 case 0x0d: // CD-ROM
1526 case 0x0e: // CD-ROM audio control
1528 BX_ERROR(("cdrom: MODE SENSE (curr), code=%x not implemented yet",
1530 atapi_cmd_error(channel
, SENSE_ILLEGAL_REQUEST
,
1531 ASC_INV_FIELD_IN_CMD_PACKET
, 1);
1532 raise_interrupt(channel
);
1536 // not implemeted by this device
1537 BX_INFO(("cdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device",
1539 atapi_cmd_error(channel
, SENSE_ILLEGAL_REQUEST
,
1540 ASC_INV_FIELD_IN_CMD_PACKET
, 1);
1541 raise_interrupt(channel
);
1546 case 0x1: // changeable values
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
1553 BX_ERROR(("cdrom: MODE SENSE (chg), code=%x not implemented yet",
1555 atapi_cmd_error(channel
, SENSE_ILLEGAL_REQUEST
,
1556 ASC_INV_FIELD_IN_CMD_PACKET
, 1);
1557 raise_interrupt(channel
);
1561 // not implemeted by this device
1562 BX_INFO(("cdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device",
1564 atapi_cmd_error(channel
, SENSE_ILLEGAL_REQUEST
,
1565 ASC_INV_FIELD_IN_CMD_PACKET
, 1);
1566 raise_interrupt(channel
);
1571 case 0x2: // default values
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) |
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
);
1603 case 0x01: // error recovery
1604 case 0x0d: // CD-ROM
1605 case 0x0e: // CD-ROM audio control
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
);
1614 // not implemeted by this device
1615 BX_INFO(("cdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device",
1617 atapi_cmd_error(channel
, SENSE_ILLEGAL_REQUEST
,
1618 ASC_INV_FIELD_IN_CMD_PACKET
, 1);
1619 raise_interrupt(channel
);
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
);
1630 BX_PANIC(("Should not get here!"));
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
1652 const char* vendor_id
= "BOCHS ";
1653 for (i
= 0; i
< 8; i
++)
1654 BX_SELECTED_CONTROLLER(channel
).buffer
[8+i
] = vendor_id
[i
];
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
);
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
);
1690 atapi_cmd_error(channel
, SENSE_NOT_READY
, ASC_MEDIUM_NOT_PRESENT
, 1);
1691 raise_interrupt(channel
);
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
);
1709 switch (transfer_req
& 0xf8) {
1711 atapi_cmd_nop(channel
);
1712 raise_interrupt(channel
);
1715 BX_SELECTED_CONTROLLER(channel
).buffer_size
= 2352;
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
);
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
);
1730 atapi_cmd_error(channel
, SENSE_NOT_READY
, ASC_MEDIUM_NOT_PRESENT
, 1);
1731 raise_interrupt(channel
);
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];
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)
1747 #ifdef LOWLEVEL_CDROM
1753 BX_ERROR(("READ_TOC_EX: msf not set for format %i", format
));
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
);
1762 init_send_atapi_command(channel
, atapi_command
, toc_length
, alloc_length
);
1763 ready_to_send_atapi(channel
);
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
);
1772 BX_PANIC(("LOWLEVEL_CDROM not defined"));
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
);
1785 init_send_atapi_command(channel
, atapi_command
, toc_length
, alloc_length
);
1786 ready_to_send_atapi(channel
);
1789 BX_PANIC(("LOWLEVEL_CDROM not defined"));
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
);
1801 atapi_cmd_error(channel
, SENSE_NOT_READY
, ASC_MEDIUM_NOT_PRESENT
, 1);
1802 raise_interrupt(channel
);
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);
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
);
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
);
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
));
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);
1852 BX_DEBUG(("cdrom: READ (%d) LBA=%d LEN=%d", atapi_command
==0x28?10:12, lba
, transfer_length
));
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
);
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
);
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
);
1877 #ifdef LOWLEVEL_CDROM
1878 BX_SELECTED_DRIVE(channel
).cdrom
.cd
->seek(lba
);
1880 BX_PANIC(("Seek with no LOWLEVEL_CDROM"));
1882 atapi_cmd_nop(channel
);
1883 raise_interrupt(channel
);
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
);
1892 atapi_cmd_error(channel
, SENSE_NOT_READY
, ASC_MEDIUM_NOT_PRESENT
, 1);
1894 raise_interrupt(channel
);
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
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
);
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
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
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
);
1934 init_send_atapi_command(channel
, atapi_command
, ret_len
, alloc_length
);
1935 ready_to_send_atapi(channel
);
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
);
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
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
);
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
);
1974 BX_PANIC(("IO write(0x%04x): current command is %02xh", address
,
1975 (unsigned) BX_SELECTED_CONTROLLER(channel
).current_command
));
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
)) {
1983 BX_INFO(("no precompensation {%s}", BX_SELECTED_TYPE_STRING(channel
)));
1985 BX_INFO(("precompensation value %02x {%s}", (unsigned) value
, BX_SELECTED_TYPE_STRING(channel
)));
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
)));
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
)));
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
)));
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
)));
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
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
));
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
)))
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
));
2047 if ((value
& 0xf0) == 0x10)
2049 BX_SELECTED_CONTROLLER(channel
).status
.err
= 0;
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
);
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
)));
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
);
2082 case 0x24: // READ SECTORS EXT
2083 case 0x29: // READ MULTIPLE EXT
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
);
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
);
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
);
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;
2122 BX_SELECTED_CONTROLLER(channel
).buffer_size
= BX_SELECTED_CONTROLLER(channel
).num_sectors
* 512;
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
);
2142 case 0x34: // WRITE SECTORS EXT
2143 case 0x39: // WRITE MULTIPLE EXT
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
);
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
);
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;
2170 BX_SELECTED_CONTROLLER(channel
).buffer_size
= BX_SELECTED_CONTROLLER(channel
).num_sectors
* 512;
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;
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
);
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
);
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
);
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
);
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
);
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
);
2236 case 0xec: // IDENTIFY DEVICE
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
);
2248 if (BX_SELECTED_IS_CD(channel
)) {
2249 set_signature(channel
, BX_SLAVE_SELECTED(channel
));
2250 command_aborted(channel
, 0xec);
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
);
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;
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
);
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
);
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
);
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;
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
);
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
);
2342 case 0x42: // READ VERIFY SECTORS EXT
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
);
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
);
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
);
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
);
2380 case 0xa1: // IDENTIFY PACKET DEVICE
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
);
2409 command_aborted(channel
, 0xa1);
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;
2427 BX_DEBUG(("ATAPI Device Reset on non-cd device"));
2428 command_aborted(channel
, 0x08);
2432 case 0xa0: // SEND PACKET (atapi)
2433 if (BX_SELECTED_IS_CD(channel
)) {
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);
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;
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;
2452 command_aborted (channel
, 0xa0);
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);
2461 command_aborted(channel
, 0xa2);
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
);
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
);
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
);
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
);
2505 BX_INFO(("write cmd 0x70 (SEEK) not supported for non-disk"));
2506 command_aborted(channel
, 0x70);
2510 case 0x25: // READ DMA EXT
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
;
2520 BX_ERROR(("write cmd 0x%02x (READ DMA) not supported", value
));
2521 command_aborted(channel
, value
);
2525 case 0x35: // WRITE DMA EXT
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
;
2535 BX_ERROR(("write cmd 0x%02x (WRITE DMA) not supported", value
));
2536 command_aborted(channel
, value
);
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;
2596 BX_ERROR(("IO write to 0x%04x: unknown command 0x%02x", address
, value
));
2597 command_aborted(channel
, value
);
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));
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
;
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
;
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
));
2697 *sector
= logical_sector
;
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
, ¤t_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);
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);
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
)
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) |
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
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
)
2826 char serial_number
[21];
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
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;
2866 BX_SELECTED_DRIVE(channel
).id_drive
[1] = BX_SELECTED_DRIVE(channel
).hard_drive
->cylinders
;
2871 // Word 3: number of user-addressable heads in default
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
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);
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;
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.
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
;
2991 BX_SELECTED_DRIVE(channel
).id_drive
[59] = 0x0000;
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);
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);
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
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
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
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
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);
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
3157 BX_SELECTED_CONTROLLER(channel
).buffer_index
= BX_SELECTED_CONTROLLER(channel
).buffer_size
;
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
)
3176 BX_ERROR(("ata%d-%d: atapi_cmd_error: key=%02x asc=%02x", channel
, BX_SLAVE_SELECTED(channel
), sense_key
, asc
));
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
)
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
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
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"));
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
)));
3248 DEV_ide_bmdma_set_irq(channel
);
3250 DEV_pic_raise_irq(irq
);
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
)
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
)
3314 // return 0 if no cdromd is present
3315 if (!BX_DRIVE_IS_CD(channel
,device
))
3319 // eject cdrom if not locked by guest OS
3320 if (BX_HD_THIS channels
[channel
].drives
[device
].cdrom
.locked
) return(1);
3322 #ifdef LOWLEVEL_CDROM
3323 BX_HD_THIS channels
[channel
].drives
[device
].cdrom
.cd
->eject_cdrom();
3325 BX_HD_THIS channels
[channel
].drives
[device
].cdrom
.ready
= 0;
3326 SIM
->get_param_enum("status", base
)->set(BX_EJECTED
);
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
);
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)
3357 if (SIM
->get_param_bool(BXPN_I440FX_SUPPORT
)->get()) {
3358 return DEV_ide_bmdma_present();
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)) {
3370 if (!ide_read_sector(channel
, buffer
, 512)) {
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"));
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
));
3395 BX_SELECTED_DRIVE(channel
).cdrom
.next_lba
++;
3396 BX_SELECTED_DRIVE(channel
).cdrom
.remaining_blocks
--;
3399 memcpy(buffer
, BX_SELECTED_CONTROLLER(channel
).buffer
, *sector_size
);
3403 BX_ERROR(("PACKET-DMA not active"));
3404 command_aborted(channel
, BX_SELECTED_CONTROLLER(channel
).current_command
);
3408 BX_ERROR(("DMA read not active"));
3409 command_aborted (channel
, BX_SELECTED_CONTROLLER(channel
).current_command
);
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
);
3423 if (!ide_write_sector(channel
, buffer
, 512)) {
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;
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
);
3448 void bx_hard_drive_c::set_signature(Bit8u channel
, Bit8u id
)
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;
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;
3469 int sector_count
= (buffer_size
/ 512);
3470 Bit8u
*bufptr
= buffer
;
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
);
3477 ret
= BX_SELECTED_DRIVE(channel
).hard_drive
->lseek(logical_sector
* 512, SEEK_SET
);
3479 BX_ERROR(("could not lseek() hard drive image file"));
3480 command_aborted(channel
, BX_SELECTED_CONTROLLER(channel
).current_command
);
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);
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
);
3494 increment_address(channel
);
3496 } while (--sector_count
> 0);
3501 bx_bool
bx_hard_drive_c::ide_write_sector(Bit8u channel
, Bit8u
*buffer
, Bit32u buffer_size
)
3503 Bit64s logical_sector
= 0;
3506 int sector_count
= (buffer_size
/ 512);
3507 Bit8u
*bufptr
= buffer
;
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
);
3514 ret
= BX_SELECTED_DRIVE(channel
).hard_drive
->lseek(logical_sector
* 512, SEEK_SET
);
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
);
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);
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
);
3531 increment_address(channel
);
3533 } while (--sector_count
> 0);
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;
3546 BX_SELECTED_CONTROLLER(channel
).num_sectors
= BX_SELECTED_CONTROLLER(channel
).sector_count
;
3548 if (!BX_SELECTED_CONTROLLER(channel
).sector_count
&& !BX_SELECTED_CONTROLLER(channel
).hob
.nsector
)
3549 BX_SELECTED_CONTROLLER(channel
).num_sectors
= 65536;
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"));
3565 data
[3] = 0x05; // Try to recover 5 times