cec1c57d98
- preparing for commit of all the changes. We'll keep this patch in case something goes wrong
6577 lines
295 KiB
Plaintext
6577 lines
295 KiB
Plaintext
----------------------------------------------------------------------
|
|
Patch name: patch.4ata-channels
|
|
Author: christophe Bothamy
|
|
Date: 14 september 2002
|
|
|
|
Detailed description:
|
|
|
|
I merged Bryce's patch and mine. Here are the descriptions of both :
|
|
|
|
----------------------------------------------------------------------
|
|
|
|
This patch adds 4 ata channels support for Bochs. Features :
|
|
- number of active channels defined at boot-time config
|
|
- new options in bochsrc
|
|
- up to 8 devices support (disks or cdroms)
|
|
- up to 4 cdrom devices can be changed at runtime config
|
|
|
|
You'll want to use BIOS-bochs-new-ata to be able to access new
|
|
devices from the bios.
|
|
|
|
I have not split "harddrv.cc" in simpler files yet.
|
|
|
|
----------------------------------------------------------------------
|
|
|
|
This patch applies on top of Christophe Bothamy's 4ata-channels patch.
|
|
I'm keeping a separate patch in case Christophe wants to make revisions
|
|
to his patch without my changes getting in the way.
|
|
|
|
I have just been working on the configuration interface part, in both the
|
|
text interface and wxWindows.
|
|
|
|
- set default I/O address for all ata channels, even the ones which are
|
|
disabled by default. It's easier to configure from scratch if we have
|
|
reasonable defaults already. (I know many options default to zero instead
|
|
of reasonable defaults, but I don't like that either.)
|
|
- eliminate huge initialization lists atachannel_init_list[][] and
|
|
atadevice_init_list[][] by creating the bx_list_c and calling the add()
|
|
method from inside a loop.
|
|
- fix bugs in the bochsrc output code (extra or missing comma problems)
|
|
- Also I'm using a trick: since the dependent_list and the menus contain almost
|
|
the same items, I build just one list at first. Then since I need to add a
|
|
few more items to the dependent list (but I don't want them to show on the
|
|
menu) I call bx_list_c::clone() to make a copy to use as the dependent list.
|
|
Example:
|
|
BXP_ATA0 menu:
|
|
BXP_ATA0_PRESENT, BXP_ATA0_IOADDR1, BXP_ATA0_IOADDR2, BXP_ATA0_IRQ
|
|
dependent list for BXP_ATA0_PRESENT:
|
|
BXP_ATA0_PRESENT, BXP_ATA0_IOADDR1, BXP_ATA0_IOADDR2, BXP_ATA0_IRQ,
|
|
BXP_ATA0_MASTER_PRESENT, BXP_ATA0_SLAVE_PRESENT
|
|
- the ata devices have both a "present" boolean parameter and a "type" enum
|
|
parameter. I removed the "none" value in the type enum, because it was
|
|
the same as having present=false. This made the enable/disable logic
|
|
somewhat easier.
|
|
- Now the ATA channel present parameters have a dependent_list which includes
|
|
both the ATA channel parameters and also the ATA device parameters that are
|
|
on that channel. This way, when you disable the ATA channel, the devices on
|
|
the channel will be disabled too. I am using the dependent_list instead of
|
|
the callback function that calls set_enable because it allows wxWindows to do
|
|
the enable/disables without any special code to handle each case.
|
|
- a few changes relating to bx_param_num_c::update_dependents():
|
|
- don't allow a parameter to disable itself. This allows the "present" param
|
|
to be included in its own dependency list without danger of disabling
|
|
itself forever.
|
|
- before, if a param with dependents had a value of zero, it would disable
|
|
its dependent parameters. Now it will also disable its dependents
|
|
if the param itself is disabled.
|
|
- when a parameter with dependents is enabled/disabled, it now calls
|
|
update_dependents() as well. Before this only happened when the value was
|
|
changed.
|
|
- in wxdialog.cc, I've added equivalent logic in EnableChanged and EnumChanged
|
|
so that the wxWindows dialogs follow the same dependency rules. It doesn't
|
|
work in quite the same way because the text interface changes the params
|
|
immediately while the wxWindows interface only changes the params when Ok
|
|
is pressed, but it is very similar.
|
|
- in wxWindows, replace the Edit Hard Disk and Edit Cdrom menu items with ATA
|
|
Controller items.
|
|
- in ParamDialog, I now add the wxStaticText label for each parameter to
|
|
the ParamStruct. If the param is enabled/disabled, the label will be
|
|
changed as well. Esp. since gtk wxCheckboxes do not change visibly when
|
|
disabled, having the label change to grey is good.
|
|
- in the selection of boot disk, I didn't check for all possibilities of
|
|
hard disks and cdroms. If you want to boot from a hard disk, you should
|
|
make it ata0-master, and if you want to boot from a cdrom, you should
|
|
make it ata0-slave. This is just a wxwindows limitation, because Christophe
|
|
says the BIOS would be able to boot a hard disk on ata3-slave if that
|
|
was the first one, but I think we can live with it for now.
|
|
- add clone() method of bx_list_c, which makes a copy.
|
|
|
|
I could not use the dependent_list trick to handle the "type" field of
|
|
the ATA devices. When type=disk, it's supposed to enable cylinders, heads,
|
|
and spt, but when type=cdrom, it's supposed to disable C/H/S and enable the
|
|
inserted/ejected param instead. There's currently no way to do this with
|
|
dependent_list, so I left this behavior in the bx_param_handler callback
|
|
function.
|
|
|
|
The problem with using callback functions to handle the enabling of other
|
|
parameters (and the reason that I've been moving away from them for this
|
|
purpose) is that in a GUI dialog box, you don't want to change any parameter
|
|
value until the user presses "Ok". If callback functions control the enabling
|
|
of other parameters, I cannot know which parts of the dialog to enable/disable
|
|
without modifying the parameter with set().
|
|
|
|
Possible solutions:
|
|
1) have the dialog box code remember the old value of every param, to be able
|
|
to implement Cancel.
|
|
2) in each param structure, remember the new value and the previous value.
|
|
Then if the user presses cancel, I can revert each param back to its previous
|
|
value.
|
|
3) for special cases such as enabling C/H/S when type=disk, duplicate
|
|
the enable/disable code in each implementation of the user interface.
|
|
|
|
#3 is what I've done in ParamDialog::EnumChanged.
|
|
|
|
Patch was created with:
|
|
cvs diff -u
|
|
Apply patch to what version:
|
|
cvs checked out on 14 september 2002
|
|
Instructions:
|
|
To patch, go to main bochs directory.
|
|
Type "patch -p0 < THIS_PATCH_FILE".
|
|
----------------------------------------------------------------------
|
|
Index: misc/bximage.c
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/misc/bximage.c,v
|
|
retrieving revision 1.10
|
|
diff -u -r1.10 bximage.c
|
|
--- misc/bximage.c 5 Sep 2002 16:50:03 -0000 1.10
|
|
+++ misc/bximage.c 22 Sep 2002 20:46:02 -0000
|
|
@@ -261,7 +261,7 @@
|
|
printf (" total size=%.2f megabytes\n", (float)sectors*512.0/1024.0/1024.0);
|
|
if (ask_string ("\nWhat should I name the image?\n[c.img] ", "c.img", filename) < 0)
|
|
fatal (EOF_ERR);
|
|
- sprintf (bochsrc_line, "diskc: file=\"%s\", cyl=%d, heads=%d, spt=%d", filename, cyl, heads, spt);
|
|
+ sprintf (bochsrc_line, "ata0-master: type=disk, path=\"%s\", cylinders=%d, heads=%d, spt=%d", filename, cyl, heads, spt);
|
|
} else {
|
|
int fdsize, cyl=0, heads=0, spt=0;
|
|
char *name = NULL;
|
|
Index: bochs.h
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/bochs.h,v
|
|
retrieving revision 1.95
|
|
diff -u -r1.95 bochs.h
|
|
--- bochs.h 21 Sep 2002 11:38:12 -0000 1.95
|
|
+++ bochs.h 22 Sep 2002 20:46:03 -0000
|
|
@@ -491,6 +491,7 @@
|
|
|
|
|
|
|
|
+/* Already in gui/siminterface.h ???
|
|
#define BX_FLOPPY_NONE 10 // floppy not present
|
|
#define BX_FLOPPY_1_2 11 // 1.2M 5.25"
|
|
#define BX_FLOPPY_1_44 12 // 1.44M 3.5"
|
|
@@ -498,6 +499,7 @@
|
|
#define BX_FLOPPY_720K 14 // 720K 3.5"
|
|
#define BX_FLOPPY_360K 15 // 360K 5.25"
|
|
#define BX_FLOPPY_LAST 15 // last one
|
|
+*/
|
|
|
|
|
|
#define BX_READ 0
|
|
@@ -549,6 +551,13 @@
|
|
#define BX_PATHNAME_LEN 512
|
|
|
|
typedef struct {
|
|
+ bx_param_bool_c *Opresent;
|
|
+ bx_param_num_c *Oioaddr1;
|
|
+ bx_param_num_c *Oioaddr2;
|
|
+ bx_param_num_c *Oirq;
|
|
+ } bx_ata_options;
|
|
+
|
|
+typedef struct {
|
|
bx_param_string_c *Opath;
|
|
bx_param_num_c *Oaddress;
|
|
} bx_rom_options;
|
|
@@ -630,10 +639,12 @@
|
|
typedef struct {
|
|
bx_floppy_options floppya;
|
|
bx_floppy_options floppyb;
|
|
- bx_disk_options diskc;
|
|
- bx_disk_options diskd;
|
|
+ bx_ata_options ata[BX_MAX_ATA_CHANNEL];
|
|
+ bx_atadevice_options atadevice[BX_MAX_ATA_CHANNEL][2];
|
|
+ // bx_disk_options diskc;
|
|
+ // bx_disk_options diskd;
|
|
+ // bx_cdrom_options cdromd;
|
|
bx_serial_options com[BX_N_SERIAL_PORTS];
|
|
- bx_cdrom_options cdromd;
|
|
bx_rom_options rom;
|
|
bx_vgarom_options vgarom;
|
|
bx_rom_options optrom[BX_N_OPTROM_IMAGES]; // Optional rom images
|
|
Index: config.h.in
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/config.h.in,v
|
|
retrieving revision 1.72
|
|
diff -u -r1.72 config.h.in
|
|
--- config.h.in 22 Sep 2002 16:11:11 -0000 1.72
|
|
+++ config.h.in 22 Sep 2002 20:46:04 -0000
|
|
@@ -270,6 +270,13 @@
|
|
// [[Provide example of partitioning]]
|
|
#define BX_SPLIT_HD_SUPPORT 0
|
|
|
|
+// This option defines the number of supported ATA channels.
|
|
+// There are up to two drives per ATA channel.
|
|
+#define BX_MAX_ATA_CHANNEL 4
|
|
+
|
|
+#if (BX_MAX_ATA_CHANNEL>4 || BX_MAX_ATA_CHANNEL<1)
|
|
+# error "BX_MAX_ATA_CHANNEL should be between 1 and 4"
|
|
+#endif
|
|
|
|
// =================================================================
|
|
// BEGIN: OPTIONAL DEBUGGER SECTION
|
|
Index: main.cc
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/main.cc,v
|
|
retrieving revision 1.143
|
|
diff -u -r1.143 main.cc
|
|
--- main.cc 20 Sep 2002 18:14:25 -0000 1.143
|
|
+++ main.cc 22 Sep 2002 20:46:06 -0000
|
|
@@ -113,9 +113,18 @@
|
|
SIM->get_param (BXP_LOAD32BITOS_INITRD)->set_enabled (enable);
|
|
}
|
|
break;
|
|
- case BXP_CDROM_STATUS:
|
|
+ case BXP_ATA0_MASTER_STATUS:
|
|
+ case BXP_ATA0_SLAVE_STATUS:
|
|
+ case BXP_ATA1_MASTER_STATUS:
|
|
+ case BXP_ATA1_SLAVE_STATUS:
|
|
+ case BXP_ATA2_MASTER_STATUS:
|
|
+ case BXP_ATA2_SLAVE_STATUS:
|
|
+ case BXP_ATA3_MASTER_STATUS:
|
|
+ case BXP_ATA3_SLAVE_STATUS:
|
|
if ((set) && (SIM->get_init_done ())) {
|
|
- bx_devices.hard_drive->set_cd_media_status(val == BX_INSERTED);
|
|
+ Bit8u device = id - BXP_ATA0_MASTER_STATUS;
|
|
+ Bit32u handle = bx_devices.hard_drive->get_device_handle (device/2, device%2);
|
|
+ bx_devices.hard_drive->set_cd_media_status(handle, val == BX_INSERTED);
|
|
bx_gui.update_drive_status_buttons ();
|
|
}
|
|
break;
|
|
@@ -144,6 +153,42 @@
|
|
case BXP_KBD_PASTE_DELAY:
|
|
if (set) bx_keyboard.paste_delay_changed ();
|
|
break;
|
|
+ case BXP_ATA0_MASTER_TYPE:
|
|
+ case BXP_ATA0_SLAVE_TYPE:
|
|
+ case BXP_ATA1_MASTER_TYPE:
|
|
+ case BXP_ATA1_SLAVE_TYPE:
|
|
+ case BXP_ATA2_MASTER_TYPE:
|
|
+ case BXP_ATA2_SLAVE_TYPE:
|
|
+ case BXP_ATA3_MASTER_TYPE:
|
|
+ case BXP_ATA3_SLAVE_TYPE:
|
|
+ if (set) {
|
|
+ int device = id - BXP_ATA0_MASTER_TYPE;
|
|
+ switch (val) {
|
|
+ case BX_ATA_DEVICE_DISK:
|
|
+ SIM->get_param_num ((bx_id)(BXP_ATA0_MASTER_PRESENT + device))->set (1);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_PATH + device))->set_enabled (1);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_CYLINDERS + device))->set_enabled (1);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_HEADS + device))->set_enabled (1);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_SPT + device))->set_enabled (1);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_STATUS + device))->set_enabled (0);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_MODEL + device))->set_enabled (1);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_BIOSDETECT + device))->set_enabled (1);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_TRANSLATION + device))->set_enabled (1);
|
|
+ break;
|
|
+ case BX_ATA_DEVICE_CDROM:
|
|
+ SIM->get_param_num ((bx_id)(BXP_ATA0_MASTER_PRESENT + device))->set (1);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_PATH + device))->set_enabled (1);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_CYLINDERS + device))->set_enabled (0);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_HEADS + device))->set_enabled (0);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_SPT + device))->set_enabled (0);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_STATUS + device))->set_enabled (1);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_MODEL + device))->set_enabled (1);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_BIOSDETECT + device))->set_enabled (1);
|
|
+ SIM->get_param ((bx_id)(BXP_ATA0_MASTER_TRANSLATION + device))->set_enabled (0);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
default:
|
|
BX_PANIC (("bx_param_handler called with unknown id %d", id));
|
|
return -1;
|
|
@@ -153,12 +198,14 @@
|
|
|
|
char *bx_param_string_handler (bx_param_string_c *param, int set, char *val, int maxlen)
|
|
{
|
|
+ bx_id id = param->get_id ();
|
|
+
|
|
int empty = 0;
|
|
if ((strlen(val) < 1) || !strcmp ("none", val)) {
|
|
empty = 1;
|
|
val = "none";
|
|
}
|
|
- switch (param->get_id ()) {
|
|
+ switch (id) {
|
|
case BXP_FLOPPYA_PATH:
|
|
if (set==1) {
|
|
if (SIM->get_init_done ()) {
|
|
@@ -209,46 +256,44 @@
|
|
}
|
|
}
|
|
break;
|
|
- case BXP_DISKC_PATH:
|
|
- if (set==1) {
|
|
- SIM->get_param_num(BXP_DISKC_PRESENT)->set (!empty);
|
|
- SIM->get_param_num(BXP_DISKC_CYLINDERS)->set_enabled (!empty);
|
|
- SIM->get_param_num(BXP_DISKC_HEADS)->set_enabled (!empty);
|
|
- SIM->get_param_num(BXP_DISKC_SPT)->set_enabled (!empty);
|
|
- }
|
|
- break;
|
|
- case BXP_DISKD_PATH:
|
|
- if (set==1) {
|
|
- SIM->get_param_num(BXP_DISKD_PRESENT)->set (!empty);
|
|
- SIM->get_param_num(BXP_DISKD_CYLINDERS)->set_enabled (!empty);
|
|
- SIM->get_param_num(BXP_DISKD_HEADS)->set_enabled (!empty);
|
|
- SIM->get_param_num(BXP_DISKD_SPT)->set_enabled (!empty);
|
|
- }
|
|
- break;
|
|
- case BXP_CDROM_PATH:
|
|
+
|
|
+ case BXP_ATA0_MASTER_PATH:
|
|
+ case BXP_ATA0_SLAVE_PATH:
|
|
+ case BXP_ATA1_MASTER_PATH:
|
|
+ case BXP_ATA1_SLAVE_PATH:
|
|
+ case BXP_ATA2_MASTER_PATH:
|
|
+ case BXP_ATA2_SLAVE_PATH:
|
|
+ case BXP_ATA3_MASTER_PATH:
|
|
+ case BXP_ATA3_SLAVE_PATH:
|
|
if (set==1) {
|
|
+ Bit8u device = id - BXP_ATA0_MASTER_PATH;
|
|
+ Bit32u handle = bx_devices.hard_drive->get_device_handle(device/2, device%2);
|
|
+
|
|
if (SIM->get_init_done ()) {
|
|
if (empty) {
|
|
- bx_devices.hard_drive->set_cd_media_status(0);
|
|
+ bx_devices.hard_drive->set_cd_media_status(handle, 0);
|
|
bx_gui.update_drive_status_buttons ();
|
|
} else {
|
|
- if (!SIM->get_param_num(BXP_CDROM_PRESENT)->get ()) {
|
|
+ if (!SIM->get_param_num((bx_id)(BXP_ATA0_MASTER_PRESENT + device))->get ()) {
|
|
BX_ERROR(("Cannot add a cdrom drive at runtime"));
|
|
- bx_options.cdromd.Opath->set ("none");
|
|
+ bx_options.atadevice[device/2][device%2].Opresent->set (0);
|
|
+ }
|
|
+ if (SIM->get_param_num((bx_id)(BXP_ATA0_MASTER_TYPE + device))->get () != BX_ATA_DEVICE_CDROM) {
|
|
+ BX_ERROR(("Device is not a cdrom drive"));
|
|
+ bx_options.atadevice[device/2][device%2].Opresent->set (0);
|
|
}
|
|
}
|
|
if ((bx_devices.hard_drive) &&
|
|
- (SIM->get_param_num(BXP_CDROM_STATUS)->get () == BX_INSERTED)) {
|
|
+ (SIM->get_param_num((bx_id)(BXP_ATA0_MASTER_STATUS + device))->get () == BX_INSERTED) &&
|
|
+ (SIM->get_param_num((bx_id)(BXP_ATA0_MASTER_TYPE + device))->get () == BX_ATA_DEVICE_CDROM)) {
|
|
// tell the device model that we removed, then inserted the cd
|
|
- bx_devices.hard_drive->set_cd_media_status(0);
|
|
- bx_devices.hard_drive->set_cd_media_status(1);
|
|
+ bx_devices.hard_drive->set_cd_media_status(handle, 0);
|
|
+ bx_devices.hard_drive->set_cd_media_status(handle, 1);
|
|
}
|
|
- } else {
|
|
- SIM->get_param_num(BXP_CDROM_PRESENT)->set (!empty);
|
|
- SIM->get_param_num(BXP_CDROM_STATUS)->set_enabled (!empty);
|
|
}
|
|
}
|
|
break;
|
|
+
|
|
case BXP_SCREENMODE:
|
|
if (set==1) {
|
|
BX_INFO (("Screen mode changed to %s", val));
|
|
@@ -260,7 +305,6 @@
|
|
return val;
|
|
}
|
|
|
|
-
|
|
void bx_init_options ()
|
|
{
|
|
int i;
|
|
@@ -370,127 +414,229 @@
|
|
bx_options.floppyb.Otype->set_handler (bx_param_handler);
|
|
bx_options.floppyb.Ostatus->set_handler (bx_param_handler);
|
|
|
|
- // diskc options
|
|
- bx_options.diskc.Opresent = new bx_param_bool_c (BXP_DISKC_PRESENT,
|
|
- "diskc:present",
|
|
- "Controls whether diskc is installed or not",
|
|
- 0);
|
|
- bx_options.diskc.Opath = new bx_param_filename_c (BXP_DISKC_PATH,
|
|
- "",
|
|
- "Pathname of the hard drive image",
|
|
- "", BX_PATHNAME_LEN);
|
|
- bx_options.diskc.Ocylinders = new bx_param_num_c (BXP_DISKC_CYLINDERS,
|
|
- "diskc:cylinders",
|
|
- "Number of cylinders",
|
|
- 0, 65535,
|
|
- 0);
|
|
- bx_options.diskc.Oheads = new bx_param_num_c (BXP_DISKC_HEADS,
|
|
- "diskc:heads",
|
|
- "Number of heads",
|
|
- 0, 65535,
|
|
- 0);
|
|
- bx_options.diskc.Ospt = new bx_param_num_c (BXP_DISKC_SPT,
|
|
- "diskc:spt",
|
|
- "Number of sectors per track",
|
|
- 0, 65535,
|
|
- 0);
|
|
- bx_options.diskc.Opath->set_ask_format ("Enter new filename, or 'none' for no disk: [%s] ");
|
|
- bx_options.diskc.Ocylinders->set_ask_format ("Enter number of cylinders: [%d] ");
|
|
- bx_options.diskc.Oheads->set_ask_format ("Enter number of heads: [%d] ");
|
|
- bx_options.diskc.Ospt->set_ask_format ("Enter number of sectors per track: [%d] ");
|
|
- bx_options.diskc.Opath->set_format ("%s");
|
|
- bx_options.diskc.Ocylinders->set_format (", %d cylinders, ");
|
|
- bx_options.diskc.Oheads->set_format ("%d heads, ");
|
|
- bx_options.diskc.Ospt->set_format ("%d sectors/track");
|
|
- bx_param_c *diskc_init_list[] = {
|
|
- bx_options.diskc.Opath,
|
|
- bx_options.diskc.Ocylinders,
|
|
- bx_options.diskc.Oheads,
|
|
- bx_options.diskc.Ospt,
|
|
- NULL
|
|
+ // disk options
|
|
+
|
|
+ // FIXME use descr and name
|
|
+ char *s_atachannel[] = {
|
|
+ "ATA channel 0",
|
|
+ "ATA channel 1",
|
|
+ "ATA channel 2",
|
|
+ "ATA channel 3",
|
|
+ };
|
|
+ char *s_atadevice[4][2] = {
|
|
+ { "Master ATA device on channel 0",
|
|
+ "Slave ATA device on channel 0" },
|
|
+ { "Master ATA device on channel 1",
|
|
+ "Slave ATA device on channel 1" },
|
|
+ { "Master ATA device on channel 2",
|
|
+ "Slave ATA device on channel 2" },
|
|
+ { "Master ATA device on channel 3",
|
|
+ "Slave ATA device on channel 3" }
|
|
+ };
|
|
+ Bit16u ata_default_ioaddr1[BX_MAX_ATA_CHANNEL] = {
|
|
+ 0x1f0, 0x170, 0x1e8, 0x168
|
|
};
|
|
- menu = new bx_list_c (BXP_DISKC, "Hard disk 0", "All options for hard disk 0", diskc_init_list);
|
|
- menu->get_options ()->set (menu->BX_SERIES_ASK);
|
|
- // if path is the word "none", then do not ask the other options and
|
|
- // set present=0.
|
|
- bx_options.diskc.Opath->set_handler (bx_param_string_handler);
|
|
- bx_options.diskc.Opath->set ("none");
|
|
-
|
|
- // diskd options
|
|
- bx_options.diskd.Opresent = new bx_param_bool_c (BXP_DISKD_PRESENT,
|
|
- "diskd:present",
|
|
- "Controls whether diskd is installed or not",
|
|
- 0);
|
|
- bx_options.diskd.Opath = new bx_param_filename_c (BXP_DISKD_PATH,
|
|
- "diskd:path",
|
|
- "Pathname of the hard drive image",
|
|
- "", BX_PATHNAME_LEN);
|
|
- bx_options.diskd.Ocylinders = new bx_param_num_c (BXP_DISKD_CYLINDERS,
|
|
- "diskd:cylinders",
|
|
- "Number of cylinders",
|
|
- 0, 65535,
|
|
- 0);
|
|
- bx_options.diskd.Oheads = new bx_param_num_c (BXP_DISKD_HEADS,
|
|
- "diskd:heads",
|
|
- "Number of heads",
|
|
- 0, 65535,
|
|
- 0);
|
|
- bx_options.diskd.Ospt = new bx_param_num_c (BXP_DISKD_SPT,
|
|
- "diskd:spt",
|
|
- "Number of sectors per track",
|
|
- 0, 65535,
|
|
- 0);
|
|
- bx_options.diskd.Opath->set_ask_format ("Enter new filename, or none for no disk: [%s] ");
|
|
- bx_options.diskd.Ocylinders->set_ask_format ("Enter number of cylinders: [%d] ");
|
|
- bx_options.diskd.Oheads->set_ask_format ("Enter number of heads: [%d] ");
|
|
- bx_options.diskd.Ospt->set_ask_format ("Enter number of sectors per track: [%d] ");
|
|
- bx_options.diskd.Opath->set_format ("%s");
|
|
- bx_options.diskd.Ocylinders->set_format (", %d cylinders, ");
|
|
- bx_options.diskd.Oheads->set_format ("%d heads, ");
|
|
- bx_options.diskd.Ospt->set_format ("%d sectors/track");
|
|
- bx_param_c *diskd_init_list[] = {
|
|
- bx_options.diskd.Opath,
|
|
- bx_options.diskd.Ocylinders,
|
|
- bx_options.diskd.Oheads,
|
|
- bx_options.diskd.Ospt,
|
|
- NULL
|
|
+ Bit8u ata_default_irq[BX_MAX_ATA_CHANNEL] = {
|
|
+ 14, 15, 12, 11
|
|
};
|
|
- menu = new bx_list_c (BXP_DISKD, "Hard disk 1", "All options for hard disk 1", diskd_init_list);
|
|
- menu->get_options ()->set (menu->BX_SERIES_ASK);
|
|
- bx_options.diskd.Opath->set_handler (bx_param_string_handler);
|
|
- bx_options.diskd.Opath->set ("none");
|
|
|
|
- // cdrom options
|
|
- bx_options.cdromd.Opresent = new bx_param_bool_c (BXP_CDROM_PRESENT,
|
|
- "CDROM is present",
|
|
- "Controls whether cdromd is installed or not",
|
|
- 0);
|
|
- bx_options.cdromd.Opath = new bx_param_filename_c (BXP_CDROM_PATH,
|
|
- "CDROM image filename",
|
|
- "Pathname of the cdrom device or image",
|
|
- "", BX_PATHNAME_LEN);
|
|
- bx_options.cdromd.Opath->set_format ("%s");
|
|
-#if BX_UI_TEXT
|
|
- bx_options.cdromd.Opath->set_ask_format ("Enter new filename, or 'none' for no CDROM: [%s] ");
|
|
-#endif
|
|
- bx_options.cdromd.Ostatus = new bx_param_enum_c (BXP_CDROM_STATUS,
|
|
- "Is the CDROM inserted or ejected",
|
|
- "Inserted or ejected",
|
|
- floppy_status_names,
|
|
- BX_INSERTED,
|
|
- BX_EJECTED);
|
|
- bx_options.cdromd.Ostatus->set_format (", %s");
|
|
- bx_options.cdromd.Ostatus->set_ask_format ("Is the CDROM inserted or ejected? [%s] ");
|
|
- bx_param_c *cdromd_init_list[] = {
|
|
- bx_options.cdromd.Opath,
|
|
- bx_options.cdromd.Ostatus,
|
|
- NULL
|
|
- };
|
|
- menu = new bx_list_c (BXP_CDROMD, "CDROM", "Options for the CDROM", cdromd_init_list);
|
|
- menu->get_options ()->set (menu->BX_SERIES_ASK);
|
|
- bx_options.cdromd.Opath->set_handler (bx_param_string_handler);
|
|
- bx_options.cdromd.Opath->set ("none");
|
|
- bx_options.cdromd.Ostatus->set_handler (bx_param_handler);
|
|
+ bx_list_c *ata[BX_MAX_ATA_CHANNEL];
|
|
+
|
|
+ for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel ++) {
|
|
+
|
|
+ ata[channel] = new bx_list_c ((bx_id)(BXP_ATA0+channel), s_atachannel[channel], s_atachannel[channel], 8);
|
|
+ ata[channel]->get_options ()->set (ata[channel]->BX_SERIES_ASK);
|
|
+
|
|
+ ata[channel]->add (bx_options.ata[channel].Opresent = new bx_param_bool_c ((bx_id)(BXP_ATA0_PRESENT+channel),
|
|
+ "ata:present",
|
|
+ "Controls whether ata channel is installed or not",
|
|
+ 0));
|
|
+
|
|
+ ata[channel]->add (bx_options.ata[channel].Oioaddr1 = new bx_param_num_c ((bx_id)(BXP_ATA0_IOADDR1+channel),
|
|
+ "ata:ioaddr1",
|
|
+ "IO adress of ata command block",
|
|
+ 0, 0xffff,
|
|
+ ata_default_ioaddr1[channel]));
|
|
+
|
|
+ ata[channel]->add (bx_options.ata[channel].Oioaddr2 = new bx_param_num_c ((bx_id)(BXP_ATA0_IOADDR2+channel),
|
|
+ "ata:ioaddr2",
|
|
+ "IO adress of ata control block",
|
|
+ 0, 0xffff,
|
|
+ ata_default_ioaddr1[channel] + 0x200));
|
|
+
|
|
+ ata[channel]->add (bx_options.ata[channel].Oirq = new bx_param_num_c ((bx_id)(BXP_ATA0_IRQ+channel),
|
|
+ "ata:irq",
|
|
+ "IRQ of ata ",
|
|
+ 0, 15,
|
|
+ ata_default_irq[channel]));
|
|
+
|
|
+ // all items in the ata[channel] menu depend on the present flag.
|
|
+ // The menu list is complete, but a few dependent_list items will
|
|
+ // be added later. Use clone() to make a copy of the dependent_list
|
|
+ // so that it can be changed without affecting the menu.
|
|
+ bx_options.ata[channel].Opresent->set_dependent_list (
|
|
+ ata[channel]->clone());
|
|
+
|
|
+ for (Bit8u slave=0; slave<2; slave++) {
|
|
+
|
|
+ menu = bx_options.atadevice[channel][slave].Omenu = new bx_list_c ((bx_id)(BXP_ATA0_MASTER+channel*2+slave),
|
|
+ s_atadevice[channel][slave],
|
|
+ s_atadevice[channel][slave],
|
|
+ 12 /* list max size */);
|
|
+ menu->get_options ()->set (menu->BX_SERIES_ASK);
|
|
+
|
|
+ menu->add (bx_options.atadevice[channel][slave].Opresent = new bx_param_bool_c ((bx_id)(BXP_ATA0_MASTER_PRESENT+channel*2+slave),
|
|
+ "ata-device:present",
|
|
+ "Controls whether ata device is installed or not",
|
|
+ 0));
|
|
+
|
|
+ menu->add (bx_options.atadevice[channel][slave].Otype = new bx_param_enum_c ((bx_id)(BXP_ATA0_MASTER_TYPE+channel*2+slave),
|
|
+ "ata-device:type",
|
|
+ "Type of ATA device",
|
|
+ atadevice_type_names,
|
|
+ BX_ATA_DEVICE_DISK,
|
|
+ BX_ATA_DEVICE_DISK));
|
|
+
|
|
+ menu->add (bx_options.atadevice[channel][slave].Opath = new bx_param_filename_c ((bx_id)(BXP_ATA0_MASTER_PATH+channel*2+slave),
|
|
+ "ata-device:path",
|
|
+ "Pathname of the image",
|
|
+ "", BX_PATHNAME_LEN));
|
|
+
|
|
+ menu->add (bx_options.atadevice[channel][slave].Ocylinders = new bx_param_num_c ((bx_id)(BXP_ATA0_MASTER_CYLINDERS+channel*2+slave),
|
|
+ "ata-device:cylinders",
|
|
+ "Number of cylinders",
|
|
+ 0, 65535,
|
|
+ 0));
|
|
+ menu->add (bx_options.atadevice[channel][slave].Oheads = new bx_param_num_c ((bx_id)(BXP_ATA0_MASTER_HEADS+channel*2+slave),
|
|
+ "ata-device:heads",
|
|
+ "Number of heads",
|
|
+ 0, 65535,
|
|
+ 0));
|
|
+ menu->add (bx_options.atadevice[channel][slave].Ospt = new bx_param_num_c ((bx_id)(BXP_ATA0_MASTER_SPT+channel*2+slave),
|
|
+ "ata-device:spt",
|
|
+ "Number of sectors per track",
|
|
+ 0, 65535,
|
|
+ 0));
|
|
+
|
|
+ menu->add (bx_options.atadevice[channel][slave].Ostatus = new bx_param_enum_c ((bx_id)(BXP_ATA0_MASTER_STATUS+channel*2+slave),
|
|
+ "ata-device:status",
|
|
+ "Inserted or ejected",
|
|
+ atadevice_status_names,
|
|
+ BX_INSERTED,
|
|
+ BX_EJECTED));
|
|
+
|
|
+ menu->add (bx_options.atadevice[channel][slave].Omodel = new bx_param_string_c ((bx_id)(BXP_ATA0_MASTER_MODEL+channel*2+slave),
|
|
+ "ata-device:model",
|
|
+ "Model name",
|
|
+ "Generic 1234", 40));
|
|
+
|
|
+ menu->add (bx_options.atadevice[channel][slave].Obiosdetect = new bx_param_enum_c ((bx_id)(BXP_ATA0_MASTER_BIOSDETECT+channel*2+slave),
|
|
+ "ata-device:biosdetect",
|
|
+ "Type of bios detection",
|
|
+ atadevice_biosdetect_names,
|
|
+ BX_ATA_BIOSDETECT_AUTO,
|
|
+ BX_ATA_BIOSDETECT_NONE));
|
|
+
|
|
+ menu->add (bx_options.atadevice[channel][slave].Otranslation = new bx_param_enum_c ((bx_id)(BXP_ATA0_MASTER_TRANSLATION+channel*2+slave),
|
|
+ "How the ata-disk translation is done by the bios",
|
|
+ "Type of translation",
|
|
+ atadevice_translation_names,
|
|
+ BX_ATA_TRANSLATION_LBA,
|
|
+ BX_ATA_TRANSLATION_NONE));
|
|
+
|
|
+ bx_options.atadevice[channel][slave].Opresent->set_dependent_list (
|
|
+ menu->clone ());
|
|
+ // the menu and all items on it depend on the Opresent flag
|
|
+ bx_options.atadevice[channel][slave].Opresent->get_dependent_list()->add(menu);
|
|
+ // the present flag depends on the ATA channel's present flag
|
|
+ bx_options.ata[channel].Opresent->get_dependent_list()->add (
|
|
+ bx_options.atadevice[channel][slave].Opresent);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Enable first ata interface by default, disable the others.
|
|
+ bx_options.ata[0].Opresent->set_initial_val(1);
|
|
+
|
|
+ // now that the dependence relationships are established, call set() on
|
|
+ // the ata device present params to set all enables correctly.
|
|
+ for (i=0; i<BX_MAX_ATA_CHANNEL; i++)
|
|
+ bx_options.ata[i].Opresent->set (i==0);
|
|
+
|
|
+ for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel ++) {
|
|
+
|
|
+ bx_options.ata[channel].Opresent->set_ask_format (
|
|
+ BX_WITH_WX? "Enable?"
|
|
+ : "Channel is enabled: [%s] ");
|
|
+ bx_options.ata[channel].Oioaddr1->set_ask_format (
|
|
+ BX_WITH_WX? "I/O Address 1:"
|
|
+ : "Enter new ioaddr1: [0x%x] ");
|
|
+ bx_options.ata[channel].Oioaddr2->set_ask_format (
|
|
+ BX_WITH_WX? "I/O Address 2:"
|
|
+ : "Enter new ioaddr2: [0x%x] ");
|
|
+ bx_options.ata[channel].Oirq->set_ask_format (
|
|
+ BX_WITH_WX? "IRQ:"
|
|
+ : "Enter new IRQ: [%d] ");
|
|
+#if !BX_WITH_WX
|
|
+ bx_options.ata[channel].Opresent->set_format ("enabled: %s");
|
|
+ bx_options.ata[channel].Oioaddr1->set_format (", ioaddr1: 0x%x");
|
|
+ bx_options.ata[channel].Oioaddr2->set_format (", ioaddr2: 0x%x");
|
|
+ bx_options.ata[channel].Oirq->set_format (", irq: %d");
|
|
+#endif
|
|
+ bx_options.ata[channel].Oioaddr1->set_base (16);
|
|
+ bx_options.ata[channel].Oioaddr2->set_base (16);
|
|
+
|
|
+ for (Bit8u slave=0; slave<2; slave++) {
|
|
+
|
|
+ bx_options.atadevice[channel][slave].Opresent->set_ask_format (
|
|
+ BX_WITH_WX? "Enable?"
|
|
+ : "Device is enabled: [%s] ");
|
|
+ bx_options.atadevice[channel][slave].Otype->set_ask_format (
|
|
+ BX_WITH_WX? "Type of ATA device:"
|
|
+ : "Enter type of ATA device, disk or cdrom: [%s] ");
|
|
+ bx_options.atadevice[channel][slave].Opath->set_ask_format (
|
|
+ BX_WITH_WX? "Path or physical device name:"
|
|
+ : "Enter new filename: [%s] ");
|
|
+ bx_options.atadevice[channel][slave].Ocylinders->set_ask_format (
|
|
+ BX_WITH_WX? "Cylinders:"
|
|
+ : "Enter number of cylinders: [%d] ");
|
|
+ bx_options.atadevice[channel][slave].Oheads->set_ask_format (
|
|
+ BX_WITH_WX? "Heads:"
|
|
+ : "Enter number of heads: [%d] ");
|
|
+ bx_options.atadevice[channel][slave].Ospt->set_ask_format (
|
|
+ BX_WITH_WX? "Sectors per track:"
|
|
+ : "Enter number of sectors per track: [%d] ");
|
|
+ bx_options.atadevice[channel][slave].Ostatus->set_ask_format (
|
|
+ BX_WITH_WX? "Inserted?"
|
|
+ : "Is the device inserted or ejected? [%s] ");
|
|
+ bx_options.atadevice[channel][slave].Omodel->set_ask_format (
|
|
+ BX_WITH_WX? "Model name:"
|
|
+ : "Enter new model name: [%s]");
|
|
+ bx_options.atadevice[channel][slave].Otranslation->set_ask_format (
|
|
+ BX_WITH_WX? "Translation type:"
|
|
+ : "Enter translation type: [%s]");
|
|
+ bx_options.atadevice[channel][slave].Obiosdetect->set_ask_format (
|
|
+ BX_WITH_WX? "BIOS Detection:"
|
|
+ : "Enter bios detection type: [%s]");
|
|
+
|
|
+#if !BX_WITH_WX
|
|
+ bx_options.atadevice[channel][slave].Opresent->set_format ("enabled: %s");
|
|
+ bx_options.atadevice[channel][slave].Otype->set_format (", %s");
|
|
+ bx_options.atadevice[channel][slave].Opath->set_format (" on '%s'");
|
|
+ bx_options.atadevice[channel][slave].Ocylinders->set_format (", %d cylinders");
|
|
+ bx_options.atadevice[channel][slave].Oheads->set_format (", %d heads");
|
|
+ bx_options.atadevice[channel][slave].Ospt->set_format (", %d sectors/track");
|
|
+ bx_options.atadevice[channel][slave].Ostatus->set_format (", %s");
|
|
+ bx_options.atadevice[channel][slave].Omodel->set_format (", model '%s'");
|
|
+ bx_options.atadevice[channel][slave].Otranslation->set_format (", translation '%s'");
|
|
+ bx_options.atadevice[channel][slave].Obiosdetect->set_format (", biosdetect '%s'");
|
|
+#endif
|
|
+
|
|
+ bx_options.atadevice[channel][slave].Otype->set_handler (bx_param_handler);
|
|
+
|
|
+ bx_options.atadevice[channel][slave].Ostatus->set_handler (bx_param_handler);
|
|
+ bx_options.atadevice[channel][slave].Opath->set_handler (bx_param_string_handler);
|
|
+ }
|
|
+ }
|
|
|
|
bx_options.OnewHardDriveSupport = new bx_param_bool_c (BXP_NEWHARDDRIVESUPPORT,
|
|
"New hard drive support",
|
|
@@ -515,9 +661,27 @@
|
|
bx_param_c *disk_menu_init_list[] = {
|
|
SIM->get_param (BXP_FLOPPYA),
|
|
SIM->get_param (BXP_FLOPPYB),
|
|
- SIM->get_param (BXP_DISKC),
|
|
- SIM->get_param (BXP_DISKD),
|
|
- SIM->get_param (BXP_CDROMD),
|
|
+ //SIM->get_param (BXP_DISKC),
|
|
+ //SIM->get_param (BXP_DISKD),
|
|
+ //SIM->get_param (BXP_CDROMD),
|
|
+ SIM->get_param (BXP_ATA0),
|
|
+ SIM->get_param (BXP_ATA0_MASTER),
|
|
+ SIM->get_param (BXP_ATA0_SLAVE),
|
|
+#if BX_MAX_ATA_CHANNEL>1
|
|
+ SIM->get_param (BXP_ATA1),
|
|
+ SIM->get_param (BXP_ATA1_MASTER),
|
|
+ SIM->get_param (BXP_ATA1_SLAVE),
|
|
+#endif
|
|
+#if BX_MAX_ATA_CHANNEL>2
|
|
+ SIM->get_param (BXP_ATA2),
|
|
+ SIM->get_param (BXP_ATA2_MASTER),
|
|
+ SIM->get_param (BXP_ATA2_SLAVE),
|
|
+#endif
|
|
+#if BX_MAX_ATA_CHANNEL>3
|
|
+ SIM->get_param (BXP_ATA3),
|
|
+ SIM->get_param (BXP_ATA3_MASTER),
|
|
+ SIM->get_param (BXP_ATA3_SLAVE),
|
|
+#endif
|
|
SIM->get_param (BXP_NEWHARDDRIVESUPPORT),
|
|
SIM->get_param (BXP_BOOTDRIVE),
|
|
SIM->get_param (BXP_FLOPPYSIGCHECK),
|
|
@@ -990,19 +1154,26 @@
|
|
bx_options.floppyb.Odevtype->reset();
|
|
bx_options.floppyb.Otype->reset();
|
|
bx_options.floppyb.Ostatus->reset();
|
|
- bx_options.diskc.Opresent->reset();
|
|
- bx_options.diskc.Opath->reset();
|
|
- bx_options.diskc.Ocylinders->reset();
|
|
- bx_options.diskc.Oheads->reset();
|
|
- bx_options.diskc.Ospt->reset();
|
|
- bx_options.diskd.Opresent->reset();
|
|
- bx_options.diskd.Opath->reset();
|
|
- bx_options.diskd.Ocylinders->reset();
|
|
- bx_options.diskd.Oheads->reset();
|
|
- bx_options.diskd.Ospt->reset();
|
|
- bx_options.cdromd.Opresent->reset();
|
|
- bx_options.cdromd.Opath->reset();
|
|
- bx_options.cdromd.Ostatus->reset();
|
|
+
|
|
+ for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
|
|
+ bx_options.ata[channel].Opresent->reset();
|
|
+ bx_options.ata[channel].Oioaddr1->reset();
|
|
+ bx_options.ata[channel].Oioaddr2->reset();
|
|
+ bx_options.ata[channel].Oirq->reset();
|
|
+
|
|
+ for (Bit8u slave=0; slave<2; slave++) {
|
|
+ bx_options.atadevice[channel][slave].Opresent->reset();
|
|
+ bx_options.atadevice[channel][slave].Otype->reset();
|
|
+ bx_options.atadevice[channel][slave].Opath->reset();
|
|
+ bx_options.atadevice[channel][slave].Ocylinders->reset();
|
|
+ bx_options.atadevice[channel][slave].Oheads->reset();
|
|
+ bx_options.atadevice[channel][slave].Ospt->reset();
|
|
+ bx_options.atadevice[channel][slave].Ostatus->reset();
|
|
+ bx_options.atadevice[channel][slave].Omodel->reset();
|
|
+ bx_options.atadevice[channel][slave].Obiosdetect->reset();
|
|
+ bx_options.atadevice[channel][slave].Otranslation->reset();
|
|
+ }
|
|
+ }
|
|
bx_options.OnewHardDriveSupport->reset();
|
|
|
|
// boot & memory
|
|
@@ -1822,7 +1993,168 @@
|
|
}
|
|
}
|
|
|
|
+ else if ((!strncmp(params[0], "ata", 3)) && (strlen(params[0]) == 4)) {
|
|
+ Bit8u channel = params[0][3];
|
|
+
|
|
+ if ((channel < '0') || (channel > '9')) {
|
|
+ BX_PANIC(("%s: ataX directive malformed.", context));
|
|
+ }
|
|
+ channel-='0';
|
|
+ if (channel >= BX_MAX_ATA_CHANNEL) {
|
|
+ BX_PANIC(("%s: ataX directive malformed.", context));
|
|
+ }
|
|
+
|
|
+ if ((num_params < 2) || (num_params > 5)) {
|
|
+ BX_PANIC(("%s: ataX directive malformed.", context));
|
|
+ }
|
|
+
|
|
+ if (strncmp(params[1], "enabled=", 8)) {
|
|
+ BX_PANIC(("%s: ataX directive malformed.", context));
|
|
+ }
|
|
+ else {
|
|
+ bx_options.ata[channel].Opresent->set (atol(¶ms[1][8]));
|
|
+ }
|
|
+
|
|
+ if (num_params > 2) {
|
|
+ if (strncmp(params[2], "ioaddr1=", 8)) {
|
|
+ BX_PANIC(("%s: ataX directive malformed.", context));
|
|
+ }
|
|
+ else {
|
|
+ if ( (params[2][8] == '0') && (params[2][9] == 'x') )
|
|
+ bx_options.ata[channel].Oioaddr1->set (strtoul (¶ms[2][8], NULL, 16));
|
|
+ else
|
|
+ bx_options.ata[channel].Oioaddr1->set (strtoul (¶ms[2][8], NULL, 10));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (num_params > 3) {
|
|
+ if (strncmp(params[3], "ioaddr2=", 8)) {
|
|
+ BX_PANIC(("%s: ataX directive malformed.", context));
|
|
+ }
|
|
+ else {
|
|
+ if ( (params[3][8] == '0') && (params[3][9] == 'x') )
|
|
+ bx_options.ata[channel].Oioaddr2->set (strtoul (¶ms[3][8], NULL, 16));
|
|
+ else
|
|
+ bx_options.ata[channel].Oioaddr2->set (strtoul (¶ms[3][8], NULL, 10));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (num_params > 4) {
|
|
+ if (strncmp(params[4], "irq=", 4)) {
|
|
+ BX_PANIC(("%s: ataX directive malformed.", context));
|
|
+ }
|
|
+ else {
|
|
+ bx_options.ata[channel].Oirq->set (atol(¶ms[4][4]));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // ataX-master, ataX-slave
|
|
+ else if ((!strncmp(params[0], "ata", 3)) && (strlen(params[0]) > 4)) {
|
|
+ Bit8u channel = params[0][3], slave = 0;
|
|
+
|
|
+ if ((channel < '0') || (channel > '9')) {
|
|
+ BX_PANIC(("%s: ataX-master/slave directive malformed.", context));
|
|
+ }
|
|
+ channel-='0';
|
|
+ if (channel >= BX_MAX_ATA_CHANNEL) {
|
|
+ BX_PANIC(("%s: ataX-master/slave directive malformed.", context));
|
|
+ }
|
|
+
|
|
+ if ((strcmp(¶ms[0][4], "-slave")) &&
|
|
+ (strcmp(¶ms[0][4], "-master"))) {
|
|
+ BX_PANIC(("%s: ataX-master/slave directive malformed.", context));
|
|
+ }
|
|
+
|
|
+ if (!strcmp(¶ms[0][4], "-slave")) {
|
|
+ slave = 1;
|
|
+ }
|
|
+
|
|
+ if (bx_options.atadevice[channel][slave].Opresent->get()) {
|
|
+ BX_PANIC(("%s: %s device of ata channel %d already defined.", context, slave?"slave":"master",channel));
|
|
+ }
|
|
+
|
|
+ for (i=1; i<num_params; i++) {
|
|
+ if (!strcmp(params[i], "type=disk")) {
|
|
+ bx_options.atadevice[channel][slave].Otype->set (BX_ATA_DEVICE_DISK);
|
|
+ }
|
|
+ else if (!strcmp(params[i], "type=cdrom")) {
|
|
+ bx_options.atadevice[channel][slave].Otype->set (BX_ATA_DEVICE_CDROM);
|
|
+ }
|
|
+ else if (!strncmp(params[i], "path=", 5)) {
|
|
+ bx_options.atadevice[channel][slave].Opath->set (¶ms[i][5]);
|
|
+ }
|
|
+ else if (!strncmp(params[i], "cylinders=", 10)) {
|
|
+ bx_options.atadevice[channel][slave].Ocylinders->set (atol(¶ms[i][10]));
|
|
+ }
|
|
+ else if (!strncmp(params[i], "heads=", 6)) {
|
|
+ bx_options.atadevice[channel][slave].Oheads->set (atol(¶ms[i][6]));
|
|
+ }
|
|
+ else if (!strncmp(params[i], "spt=", 4)) {
|
|
+ bx_options.atadevice[channel][slave].Ospt->set (atol(¶ms[i][4]));
|
|
+ }
|
|
+ else if (!strncmp(params[i], "model=", 6)) {
|
|
+ bx_options.atadevice[channel][slave].Omodel->set(¶ms[i][6]);
|
|
+ }
|
|
+ else if (!strcmp(params[i], "biosdetect=none")) {
|
|
+ bx_options.atadevice[channel][slave].Obiosdetect->set(BX_ATA_BIOSDETECT_NONE);
|
|
+ }
|
|
+ else if (!strcmp(params[i], "biosdetect=cmos")) {
|
|
+ bx_options.atadevice[channel][slave].Obiosdetect->set(BX_ATA_BIOSDETECT_CMOS);
|
|
+ }
|
|
+ else if (!strcmp(params[i], "biosdetect=auto")) {
|
|
+ bx_options.atadevice[channel][slave].Obiosdetect->set(BX_ATA_BIOSDETECT_AUTO);
|
|
+ }
|
|
+ else if (!strcmp(params[i], "translation=none")) {
|
|
+ bx_options.atadevice[channel][slave].Otranslation->set(BX_ATA_TRANSLATION_NONE);
|
|
+ }
|
|
+ else if (!strcmp(params[i], "translation=lba")) {
|
|
+ bx_options.atadevice[channel][slave].Otranslation->set(BX_ATA_TRANSLATION_LBA);
|
|
+ }
|
|
+ else if (!strcmp(params[i], "translation=large")) {
|
|
+ bx_options.atadevice[channel][slave].Otranslation->set(BX_ATA_TRANSLATION_LARGE);
|
|
+ }
|
|
+ else if (!strcmp(params[i], "status=ejected")) {
|
|
+ bx_options.atadevice[channel][slave].Ostatus->set(BX_EJECTED);
|
|
+ }
|
|
+ else if (!strcmp(params[i], "status=inserted")) {
|
|
+ bx_options.atadevice[channel][slave].Ostatus->set(BX_INSERTED);
|
|
+ }
|
|
+ else {
|
|
+ BX_PANIC(("%s: ataX-master/slave directive malformed.", context));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Enables the ata device
|
|
+ bx_options.atadevice[channel][slave].Opresent->set(1);
|
|
+
|
|
+ // if enabled check if device ok
|
|
+ if (bx_options.atadevice[channel][slave].Opresent->get() == 1) {
|
|
+ if (bx_options.atadevice[channel][slave].Otype->get() == BX_ATA_DEVICE_DISK) {
|
|
+ if ((strlen(bx_options.atadevice[channel][slave].Opath->getptr()) ==0) ||
|
|
+ (bx_options.atadevice[channel][slave].Ocylinders->get() == 0) ||
|
|
+ (bx_options.atadevice[channel][slave].Oheads->get() ==0 ) ||
|
|
+ (bx_options.atadevice[channel][slave].Ospt->get() == 0)) {
|
|
+ BX_PANIC(("%s: ataX-master/slave directive malformed.", context));
|
|
+ }
|
|
+ }
|
|
+ else if (bx_options.atadevice[channel][slave].Otype->get() == BX_ATA_DEVICE_CDROM) {
|
|
+ if (strlen(bx_options.atadevice[channel][slave].Opath->getptr()) == 0) {
|
|
+ BX_PANIC(("%s: ataX-master/slave directive malformed.", context));
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ BX_PANIC(("%s: ataX-master/slave: type sould be specified ", context));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ // Legacy disk options emulation
|
|
else if (!strcmp(params[0], "diskc")) {
|
|
+ if (bx_options.atadevice[0][0].Opresent->get()) {
|
|
+ BX_PANIC(("%s: master device of ata channel 0 already defined.", context));
|
|
+ }
|
|
if (num_params != 5) {
|
|
BX_PANIC(("%s: diskc directive malformed.", context));
|
|
}
|
|
@@ -1832,13 +2164,18 @@
|
|
strncmp(params[4], "spt=", 4)) {
|
|
BX_PANIC(("%s: diskc directive malformed.", context));
|
|
}
|
|
- bx_options.diskc.Opath->set (¶ms[1][5]);
|
|
- bx_options.diskc.Ocylinders->set (atol(¶ms[2][4]));
|
|
- bx_options.diskc.Oheads->set (atol(¶ms[3][6]));
|
|
- bx_options.diskc.Ospt->set (atol(¶ms[4][4]));
|
|
- bx_options.diskc.Opresent->set (1);
|
|
+ bx_options.ata[0].Opresent->set(1);
|
|
+ bx_options.atadevice[0][0].Otype->set (BX_ATA_DEVICE_DISK);
|
|
+ bx_options.atadevice[0][0].Opath->set (¶ms[1][5]);
|
|
+ bx_options.atadevice[0][0].Ocylinders->set (atol(¶ms[2][4]));
|
|
+ bx_options.atadevice[0][0].Oheads->set (atol(¶ms[3][6]));
|
|
+ bx_options.atadevice[0][0].Ospt->set (atol(¶ms[4][4]));
|
|
+ bx_options.atadevice[0][0].Opresent->set (1);
|
|
}
|
|
else if (!strcmp(params[0], "diskd")) {
|
|
+ if (bx_options.atadevice[0][1].Opresent->get()) {
|
|
+ BX_PANIC(("%s: slave device of ata channel 0 already defined.", context));
|
|
+ }
|
|
if (num_params != 5) {
|
|
BX_PANIC(("%s: diskd directive malformed.", context));
|
|
}
|
|
@@ -1848,11 +2185,47 @@
|
|
strncmp(params[4], "spt=", 4)) {
|
|
BX_PANIC(("%s: diskd directive malformed.", context));
|
|
}
|
|
- bx_options.diskd.Opath->set (¶ms[1][5]);
|
|
- bx_options.diskd.Ocylinders->set (atol( ¶ms[2][4]));
|
|
- bx_options.diskd.Oheads->set (atol( ¶ms[3][6] ));
|
|
- bx_options.diskd.Ospt->set (atol( ¶ms[4][4] ));
|
|
- bx_options.diskd.Opresent->set (1);
|
|
+ bx_options.ata[0].Opresent->set(1);
|
|
+ bx_options.atadevice[0][1].Otype->set (BX_ATA_DEVICE_DISK);
|
|
+ bx_options.atadevice[0][1].Opath->set (¶ms[1][5]);
|
|
+ bx_options.atadevice[0][1].Ocylinders->set (atol( ¶ms[2][4]));
|
|
+ bx_options.atadevice[0][1].Oheads->set (atol( ¶ms[3][6]));
|
|
+ bx_options.atadevice[0][1].Ospt->set (atol( ¶ms[4][4]));
|
|
+ bx_options.atadevice[0][1].Opresent->set (1);
|
|
+ }
|
|
+ else if (!strcmp(params[0], "cdromd")) {
|
|
+ if (bx_options.atadevice[0][1].Opresent->get()) {
|
|
+ BX_PANIC(("%s: slave device of ata channel 0 already defined.", context));
|
|
+ }
|
|
+ if (num_params != 3) {
|
|
+ BX_PANIC(("%s: cdromd directive malformed.", context));
|
|
+ }
|
|
+ if (strncmp(params[1], "dev=", 4) || strncmp(params[2], "status=", 7)) {
|
|
+ BX_PANIC(("%s: cdromd directive malformed.", context));
|
|
+ }
|
|
+ bx_options.ata[0].Opresent->set(1);
|
|
+ bx_options.atadevice[0][1].Otype->set (BX_ATA_DEVICE_CDROM);
|
|
+ bx_options.atadevice[0][1].Opath->set (¶ms[1][4]);
|
|
+ if (!strcmp(params[2], "status=inserted"))
|
|
+ bx_options.atadevice[0][1].Ostatus->set (BX_INSERTED);
|
|
+ else if (!strcmp(params[2], "status=ejected"))
|
|
+ bx_options.atadevice[0][1].Ostatus->set (BX_EJECTED);
|
|
+ else {
|
|
+ BX_PANIC(("%s: cdromd directive malformed.", context));
|
|
+ }
|
|
+ bx_options.atadevice[0][1].Opresent->set (1);
|
|
+ }
|
|
+
|
|
+ else if (!strcmp(params[0], "boot")) {
|
|
+ if (!strcmp(params[1], "a")) {
|
|
+ bx_options.Obootdrive->set (BX_BOOT_FLOPPYA);
|
|
+ } else if (!strcmp(params[1], "c")) {
|
|
+ bx_options.Obootdrive->set (BX_BOOT_DISKC);
|
|
+ } else if (!strcmp(params[1], "cdrom")) {
|
|
+ bx_options.Obootdrive->set (BX_BOOT_CDROM);
|
|
+ } else {
|
|
+ BX_PANIC(("%s: boot directive with unknown boot device '%s'. use 'a', 'c' or 'cdrom'.", context, params[1]));
|
|
+ }
|
|
}
|
|
|
|
else if (!strcmp(params[0], "com1")) {
|
|
@@ -1914,35 +2287,6 @@
|
|
}
|
|
#endif
|
|
|
|
- else if (!strcmp(params[0], "cdromd")) {
|
|
- if (num_params != 3) {
|
|
- BX_PANIC(("%s: cdromd directive malformed.", context));
|
|
- }
|
|
- if (strncmp(params[1], "dev=", 4) || strncmp(params[2], "status=", 7)) {
|
|
- BX_PANIC(("%s: cdromd directive malformed.", context));
|
|
- }
|
|
- bx_options.cdromd.Opath->set (¶ms[1][4]);
|
|
- if (!strcmp(params[2], "status=inserted"))
|
|
- bx_options.cdromd.Ostatus->set (BX_INSERTED);
|
|
- else if (!strcmp(params[2], "status=ejected"))
|
|
- bx_options.cdromd.Ostatus->set (BX_EJECTED);
|
|
- else {
|
|
- BX_PANIC(("%s: cdromd directive malformed.", context));
|
|
- }
|
|
- bx_options.cdromd.Opresent->set (1);
|
|
- }
|
|
-
|
|
- else if (!strcmp(params[0], "boot")) {
|
|
- if (!strcmp(params[1], "a")) {
|
|
- bx_options.Obootdrive->set (BX_BOOT_FLOPPYA);
|
|
- } else if (!strcmp(params[1], "c")) {
|
|
- bx_options.Obootdrive->set (BX_BOOT_DISKC);
|
|
- } else if (!strcmp(params[1], "cdrom")) {
|
|
- bx_options.Obootdrive->set (BX_BOOT_CDROM);
|
|
- } else {
|
|
- BX_PANIC(("%s: boot directive with unknown boot device '%s'. use 'a', 'c' or 'cdrom'.", context, params[1]));
|
|
- }
|
|
- }
|
|
else if (!strcmp(params[0], "floppy_bootsig_check")) {
|
|
if (num_params != 2) {
|
|
BX_PANIC(("%s: floppy_bootsig_check directive malformed.", context));
|
|
@@ -2503,15 +2847,11 @@
|
|
if(!strncmp(params[1], "keys=", 4)) {
|
|
bx_options.Ouser_shortcut->set (strdup(¶ms[1][5]));
|
|
}
|
|
- }
|
|
-
|
|
-
|
|
+ }
|
|
else {
|
|
BX_PANIC(( "%s: directive '%s' not understood", context, params[0]));
|
|
}
|
|
|
|
- if (bx_options.diskd.Opresent->get () && bx_options.cdromd.Opresent->get ())
|
|
- BX_PANIC(("At present, using both diskd and cdromd at once is not supported."));
|
|
}
|
|
|
|
static char *fdtypes[] = {
|
|
@@ -2536,32 +2876,64 @@
|
|
}
|
|
|
|
int
|
|
-bx_write_disk_options (FILE *fp, int drive, bx_disk_options *opt)
|
|
+bx_write_ata_options (FILE *fp, Bit8u channel, bx_ata_options *opt)
|
|
{
|
|
- if (!opt->Opresent->get ()) {
|
|
- fprintf (fp, "# no disk%c\n", (char)'c'+drive);
|
|
- return 0;
|
|
- }
|
|
- fprintf (fp, "disk%c: file=\"%s\", cyl=%d, heads=%d, spt=%d\n",
|
|
- (char)'c'+drive,
|
|
- opt->Opath->getptr (),
|
|
- opt->Ocylinders->get (),
|
|
- opt->Oheads->get (),
|
|
- opt->Ospt->get ());
|
|
+ fprintf (fp, "ata%d: enabled=%d", channel, opt->Opresent->get());
|
|
+
|
|
+ if (opt->Opresent->get()) {
|
|
+ fprintf (fp, ", ioaddr1=0x%x, ioaddr2=0x%x, irq=%d", opt->Oioaddr1->get(),
|
|
+ opt->Oioaddr2->get(), opt->Oirq->get());
|
|
+ }
|
|
+
|
|
+ fprintf (fp, "\n");
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
-bx_write_cdrom_options (FILE *fp, int drive, bx_cdrom_options *opt)
|
|
+bx_write_atadevice_options (FILE *fp, Bit8u channel, Bit8u drive, bx_atadevice_options *opt)
|
|
{
|
|
- BX_ASSERT (drive == 0);
|
|
- if (!opt->Opresent->get ()) {
|
|
- fprintf (fp, "# no cdromd\n");
|
|
- return 0;
|
|
+ if (opt->Opresent->get()) {
|
|
+ fprintf (fp, "ata%d-%s: ", channel, drive==0?"master":"slave");
|
|
+
|
|
+ if (opt->Otype->get() == BX_ATA_DEVICE_DISK) {
|
|
+ fprintf (fp, "type=disk, path=\"%s\", cylinders=%d, heads=%d, spt=%d",
|
|
+ opt->Opath->getptr(), opt->Ocylinders->get(), opt->Oheads->get(), opt->Ospt->get());
|
|
+
|
|
+ switch(opt->Otranslation->get()) {
|
|
+ case BX_ATA_TRANSLATION_NONE:
|
|
+ fprintf (fp, ", translation=none");
|
|
+ break;
|
|
+ case BX_ATA_TRANSLATION_LBA:
|
|
+ fprintf (fp, ", translation=lba");
|
|
+ break;
|
|
+ case BX_ATA_TRANSLATION_LARGE:
|
|
+ fprintf (fp, ", translation=large");
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ else if (opt->Otype->get() == BX_ATA_DEVICE_CDROM) {
|
|
+ fprintf (fp, "type=cdrom, path=\"%s\", status=%s",
|
|
+ opt->Opath->getptr(),
|
|
+ opt->Ostatus->get ()==BX_EJECTED ? "ejected" : "inserted");
|
|
+ }
|
|
+
|
|
+ switch(opt->Obiosdetect->get()) {
|
|
+ case BX_ATA_BIOSDETECT_NONE:
|
|
+ fprintf (fp, ", biosdetect=none");
|
|
+ break;
|
|
+ case BX_ATA_BIOSDETECT_CMOS:
|
|
+ fprintf (fp, ", biosdetect=cmos");
|
|
+ break;
|
|
+ case BX_ATA_BIOSDETECT_AUTO:
|
|
+ fprintf (fp, ", biosdetect=auto");
|
|
+ break;
|
|
+ }
|
|
+ if (strlen(opt->Omodel->getptr())>0) {
|
|
+ fprintf (fp, ", model=\"%s\"", opt->Omodel->getptr());
|
|
+ }
|
|
+
|
|
+ fprintf (fp, "\n");
|
|
}
|
|
- fprintf (fp, "cdromd: dev=%s, status=%s\n",
|
|
- opt->Opath->getptr (),
|
|
- opt->Ostatus->get ()==BX_INSERTED ? "inserted" : "ejected");
|
|
return 0;
|
|
}
|
|
|
|
@@ -2682,9 +3054,11 @@
|
|
// the structs like bx_floppy_options::print or something.
|
|
bx_write_floppy_options (fp, 0, &bx_options.floppya);
|
|
bx_write_floppy_options (fp, 1, &bx_options.floppyb);
|
|
- bx_write_disk_options (fp, 0, &bx_options.diskc);
|
|
- bx_write_disk_options (fp, 1, &bx_options.diskd);
|
|
- bx_write_cdrom_options (fp, 0, &bx_options.cdromd);
|
|
+ for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
|
|
+ bx_write_ata_options (fp, channel, &bx_options.ata[channel]);
|
|
+ bx_write_atadevice_options (fp, channel, 0, &bx_options.atadevice[channel][0]);
|
|
+ bx_write_atadevice_options (fp, channel, 1, &bx_options.atadevice[channel][1]);
|
|
+ }
|
|
if (strlen (bx_options.rom.Opath->getptr ()) > 0)
|
|
fprintf (fp, "romimage: file=%s, address=0x%05x\n", bx_options.rom.Opath->getptr(), (unsigned int)bx_options.rom.Oaddress->get ());
|
|
else
|
|
Index: .bochsrc
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/.bochsrc,v
|
|
retrieving revision 1.48
|
|
diff -u -r1.48 .bochsrc
|
|
--- .bochsrc 20 Sep 2002 13:23:45 -0000 1.48
|
|
+++ .bochsrc 22 Sep 2002 20:46:06 -0000
|
|
@@ -84,6 +84,79 @@
|
|
floppyb: 1_44=b.img, status=inserted
|
|
|
|
#=======================================================================
|
|
+# ATA[0-3]: enabled=[0|1], ioaddr1=, ioaddr2=, irq=
|
|
+#
|
|
+# These options enables up to 4 ata channels. For each channel
|
|
+# the two base io address and the irq must be specified.
|
|
+#
|
|
+# ata0 is enabled by default, with ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
|
|
+#
|
|
+# Examples:
|
|
+# ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
|
|
+# ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
|
|
+# ata2: enabled=1, ioaddr1=0x1e8, ioaddr2=0x3e8, irq=12
|
|
+# ata3: enabled=1, ioaddr1=0x168, ioaddr2=0x368, irq=11
|
|
+#=======================================================================
|
|
+ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
|
|
+ata1: enabled=0, ioaddr1=0x170, ioaddr2=0x370, irq=15
|
|
+ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e8, irq=12
|
|
+ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x368, irq=11
|
|
+
|
|
+#=======================================================================
|
|
+#
|
|
+# ATA[0-3]-MASTER:
|
|
+# ATA[0-3]-SLAVE:
|
|
+#
|
|
+# This defines the type and characteristics of all attached ata devices:
|
|
+# type= type of attached device [disk|cdrom]
|
|
+# path= path of the image
|
|
+# cylinders= only valid for disks
|
|
+# heads= only valid for disks
|
|
+# spt= only valid for disks
|
|
+# status= only valid for cdroms [inserted|ejected]
|
|
+# biosdetect= type of biosdetection [none|auto], only for disks on ata0 [cmos]
|
|
+# translation=type of transation of the bios, only for disks [none|lba|large]
|
|
+# model= string returned by identify device command
|
|
+#
|
|
+# Point this at a 10M, 20M, or 30M hard disk image file, cdrom iso file,
|
|
+# or physical cdrom device.
|
|
+# To create # a hard disk image, try running bximage.
|
|
+# It will help you choose the size and then suggest a line that
|
|
+# works with it.
|
|
+#
|
|
+# In UNIX it may be possible to use a raw device as a Bochs hard disk,
|
|
+# but WE DON'T RECOMMEND IT. In Windows there is no easy way.
|
|
+#
|
|
+# In windows, the drive letter + colon notation should be used for cdroms.
|
|
+# Depending on versions of windows and drivers, you may only be able to
|
|
+# access the "first" cdrom in the system.
|
|
+#
|
|
+# The path, cylinders, heads, and spt are mandatory for type=disk
|
|
+# The path is mandatory for type=cdrom
|
|
+#
|
|
+# Default values are:
|
|
+# biosdetect=auto, translation=lba, model="Generic 1234"
|
|
+#
|
|
+# The biosdetect and translation options have currently no effect on the bios
|
|
+#
|
|
+# Examples:
|
|
+# ata0-master: type=disk, path=10M.sample, cylinders=306, heads=4, spt=17
|
|
+# ata0-slave: type=disk, path=20M.sample, cylinders=615, heads=4, spt=17
|
|
+# ata1-master: type=disk, path=30M.sample, cylinders=615, heads=6, spt=17
|
|
+# ata1-slave: type=disk, path=46M.sample, cylinders=940, heads=6, spt=17
|
|
+# ata2-master: type=disk, path=62M.sample, cylinders=940, heads=8, spt=17
|
|
+# ata2-slave: type=disk, path=112M.sample, cylinders=900, heads=15, spt=17
|
|
+# ata3-master: type=disk, path=483M.sample, cylinders=1024, heads=15, spt=63
|
|
+# ata3-slave: type=cdrom, path=iso.sample, status=inserted
|
|
+#=======================================================================
|
|
+ata0-master: type=disk, path="30M.sample", cylinders=615, heads=6, spt=17
|
|
+#ata0-slave: dev=D:, status=inserted # for win32
|
|
+#ata0-slave: dev=/dev/cdrom, status=inserted
|
|
+
|
|
+#=======================================================================
|
|
+#
|
|
+# The DISKC option is deprecated. Use ATA* options instead.
|
|
+#
|
|
# DISKC: file=, cyl=, heads=, spt=
|
|
# Point this at a 10M, 20M, or 30M hard disk image file. To create
|
|
# a hard disk image, try running bximage. It will help you choose the
|
|
@@ -101,9 +174,12 @@
|
|
# diskc: file=112M.sample, cyl=900, heads=15, spt=17
|
|
# diskc: file=483M.sample, cyl=1024, heads=15, spt=63
|
|
#=======================================================================
|
|
-diskc: file="30M.sample", cyl=615, heads=6, spt=17
|
|
+#diskc: file="30M.sample", cyl=615, heads=6, spt=17
|
|
|
|
#=======================================================================
|
|
+#
|
|
+# The DISKD option is deprecated. Use ATA* options instead.
|
|
+#
|
|
# DISKD:
|
|
# See DISKC above for syntax
|
|
#
|
|
@@ -112,7 +188,10 @@
|
|
#diskd: file="diskd.img", cyl=615, heads=6, spt=17
|
|
|
|
#=======================================================================
|
|
-# CDROM
|
|
+#
|
|
+# The CDROMD option is deprecated. Use ATA* options instead.
|
|
+#
|
|
+# CDROMD:
|
|
#
|
|
# cdromd: dev=/dev/cdrom, status=inserted
|
|
# cdromd: dev=/dev/cdrom, status=ejected
|
|
Index: gui/control.cc
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/gui/control.cc,v
|
|
retrieving revision 1.61
|
|
diff -u -r1.61 control.cc
|
|
--- gui/control.cc 20 Sep 2002 18:14:27 -0000 1.61
|
|
+++ gui/control.cc 22 Sep 2002 20:46:07 -0000
|
|
@@ -302,19 +302,22 @@
|
|
"---------------------\n"
|
|
"1. Floppy disk 0: %s\n"
|
|
"2. Floppy disk 1: %s\n"
|
|
-"3. CDROM: %s\n"
|
|
-"4. (not implemented)\n"
|
|
-"5. Log options for all devices\n"
|
|
-"6. Log options for individual devices\n"
|
|
-"7. VGA Update Interval: %d\n"
|
|
-"8. Mouse: %s\n"
|
|
-"9. Keyboard paste delay: %d\n"
|
|
-"10. Userbutton shortcut: %s\n"
|
|
-"11. Instruction tracing: off (doesn't exist yet)\n"
|
|
-"12. Continue simulation\n"
|
|
-"13. Quit now\n"
|
|
+"3. 1st CDROM: %s\n"
|
|
+"4. 2nd CDROM: %s\n"
|
|
+"5. 3rd CDROM: %s\n"
|
|
+"6. 4th CDROM: %s\n"
|
|
+"7. (not implemented)\n"
|
|
+"8. Log options for all devices\n"
|
|
+"9. Log options for individual devices\n"
|
|
+"10. VGA Update Interval: %d\n"
|
|
+"11. Mouse: %s\n"
|
|
+"12. Keyboard paste delay: %d\n"
|
|
+"13. Userbutton shortcut: %s\n"
|
|
+"14. Instruction tracing: off (doesn't exist yet)\n"
|
|
+"15. Continue simulation\n"
|
|
+"16. Quit now\n"
|
|
"\n"
|
|
-"Please choose one: [12] ";
|
|
+"Please choose one: [15] ";
|
|
|
|
char *menu_prompt_list[BX_CI_N_MENUS] = {
|
|
NULL,
|
|
@@ -338,9 +341,9 @@
|
|
void build_runtime_options_prompt (char *format, char *buf, int size)
|
|
{
|
|
bx_floppy_options floppyop;
|
|
- bx_cdrom_options cdromop;
|
|
+ bx_atadevice_options cdromop;
|
|
/* bx_param_num_c *ips = SIM->get_param_num (BXP_IPS); */
|
|
- char buffer[3][128];
|
|
+ char buffer[6][128];
|
|
for (int i=0; i<2; i++) {
|
|
SIM->get_floppy_options (i, &floppyop);
|
|
if (floppyop.Odevtype->get () == BX_FLOPPY_NONE)
|
|
@@ -352,14 +355,20 @@
|
|
if (!floppyop.Opath->getptr ()[0]) strcpy (buffer[i], "none");
|
|
}
|
|
}
|
|
- SIM->get_cdrom_options (0, &cdromop);
|
|
- if (!cdromop.Opresent->get ())
|
|
- sprintf (buffer[2], "(not present)");
|
|
- else
|
|
- sprintf (buffer[2], "%s, %s",
|
|
- cdromop.Opath->getptr (),
|
|
- (cdromop.Ostatus->get () == BX_INSERTED)? "inserted" : "ejected");
|
|
+
|
|
+ // 4 cdroms supported at run time
|
|
+ int device;
|
|
+ for (Bit8u cdrom=0; cdrom<4; cdrom++) {
|
|
+ if (!SIM->get_cdrom_options (cdrom, &cdromop, &device) || !cdromop.Opresent->get ())
|
|
+ sprintf (buffer[2+cdrom], "(not present)");
|
|
+ else
|
|
+ sprintf (buffer[2+cdrom], "(%s on ata%d) %s, %s",
|
|
+ device&1?"slave":"master", device/2, cdromop.Opath->getptr (),
|
|
+ (cdromop.Ostatus->get () == BX_INSERTED)? "inserted" : "ejected");
|
|
+ }
|
|
+
|
|
snprintf (buf, size, format, buffer[0], buffer[1], buffer[2],
|
|
+ buffer[3], buffer[4], buffer[5],
|
|
/* ips->get (), */
|
|
SIM->get_param_num (BXP_VGA_UPDATE_INTERVAL)->get (),
|
|
SIM->get_param_num (BXP_MOUSE_ENABLED)->get () ? "enabled" : "disabled",
|
|
@@ -452,9 +461,9 @@
|
|
case BX_CI_RUNTIME:
|
|
char prompt[1024];
|
|
bx_floppy_options floppyop;
|
|
- bx_cdrom_options cdromop;
|
|
+ bx_atadevice_options cdromop;
|
|
build_runtime_options_prompt (runtime_menu_prompt, prompt, 1024);
|
|
- if (ask_uint (prompt, 1, 13, 12, &choice, 10) < 0) return -1;
|
|
+ if (ask_uint (prompt, 1, 16, 15, &choice, 10) < 0) return -1;
|
|
switch (choice) {
|
|
case 1:
|
|
SIM->get_floppy_options (0, &floppyop);
|
|
@@ -465,22 +474,31 @@
|
|
if (floppyop.Odevtype->get () != BX_FLOPPY_NONE) do_menu (BXP_FLOPPYB);
|
|
break;
|
|
case 3:
|
|
- SIM->get_cdrom_options (0, &cdromop);
|
|
- if (cdromop.Opresent->get ()) do_menu (BXP_CDROMD);
|
|
+ case 4:
|
|
+ case 5:
|
|
+ case 6:
|
|
+ int device;
|
|
+ if (SIM->get_cdrom_options (choice - 3, &cdromop, &device) && cdromop.Opresent->get ()) {
|
|
+ // disable type selection
|
|
+ SIM->get_param((bx_id)(BXP_ATA0_MASTER_TYPE + device))->set_enabled(0);
|
|
+ SIM->get_param((bx_id)(BXP_ATA0_MASTER_MODEL + device))->set_enabled(0);
|
|
+ SIM->get_param((bx_id)(BXP_ATA0_MASTER_BIOSDETECT + device))->set_enabled(0);
|
|
+ do_menu ((bx_id)(BXP_ATA0_MASTER + device));
|
|
+ }
|
|
break;
|
|
- case 4: // not implemented yet because I would have to mess with
|
|
+ case 7: // not implemented yet because I would have to mess with
|
|
// resetting timers and pits and everything on the fly.
|
|
// askparam (BXP_IPS);
|
|
break;
|
|
- case 5: bx_log_options (0); break;
|
|
- case 6: bx_log_options (1); break;
|
|
- case 7: askparam (BXP_VGA_UPDATE_INTERVAL); break;
|
|
- case 8: askparam (BXP_MOUSE_ENABLED); break;
|
|
- case 9: askparam (BXP_KBD_PASTE_DELAY); break;
|
|
- case 10: askparam (BXP_USER_SHORTCUT); break;
|
|
- case 11: NOT_IMPLEMENTED (choice); break;
|
|
- case 12: fprintf (stderr, "Continuing simulation\n"); return 0;
|
|
- case 13:
|
|
+ case 8: bx_log_options (0); break;
|
|
+ case 9: bx_log_options (1); break;
|
|
+ case 10: askparam (BXP_VGA_UPDATE_INTERVAL); break;
|
|
+ case 11: askparam (BXP_MOUSE_ENABLED); break;
|
|
+ case 12: askparam (BXP_KBD_PASTE_DELAY); break;
|
|
+ case 13: askparam (BXP_USER_SHORTCUT); break;
|
|
+ case 14: NOT_IMPLEMENTED (choice); break;
|
|
+ case 15: fprintf (stderr, "Continuing simulation\n"); return 0;
|
|
+ case 16:
|
|
fprintf (stderr, "You chose quit on the configuration interface.\n");
|
|
SIM->quit_sim (1);
|
|
return -1;
|
|
Index: gui/gui.cc
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/gui/gui.cc,v
|
|
retrieving revision 1.48
|
|
diff -u -r1.48 gui.cc
|
|
--- gui/gui.cc 21 Sep 2002 19:38:47 -0000 1.48
|
|
+++ gui/gui.cc 22 Sep 2002 20:46:07 -0000
|
|
@@ -108,9 +108,9 @@
|
|
BX_GRAVITY_LEFT, floppyB_handler);
|
|
|
|
// CDROM
|
|
- BX_GUI_THIS cdromD_status =
|
|
- bx_devices.hard_drive->get_cd_media_status()
|
|
- && bx_options.cdromd.Opresent->get ();
|
|
+ Bit32u handle = bx_devices.hard_drive->get_first_cd_handle();
|
|
+ BX_GUI_THIS cdromD_status = bx_devices.hard_drive->get_cd_media_status(handle);
|
|
+
|
|
if (BX_GUI_THIS cdromD_status)
|
|
BX_GUI_THIS cdromD_hbar_id = headerbar_bitmap(BX_GUI_THIS cdromD_bmap_id,
|
|
BX_GRAVITY_LEFT, cdromD_handler);
|
|
@@ -162,9 +162,8 @@
|
|
BX_GUI_THIS floppyB_status =
|
|
bx_devices.floppy->get_media_status (1)
|
|
&& bx_options.floppyb.Ostatus->get ();
|
|
- BX_GUI_THIS cdromD_status =
|
|
- bx_devices.hard_drive->get_cd_media_status()
|
|
- && bx_options.cdromd.Opresent->get ();
|
|
+ Bit32u handle = bx_devices.hard_drive->get_first_cd_handle();
|
|
+ BX_GUI_THIS cdromD_status = bx_devices.hard_drive->get_cd_media_status(handle);
|
|
if (BX_GUI_THIS floppyA_status)
|
|
replace_bitmap(BX_GUI_THIS floppyA_hbar_id, BX_GUI_THIS floppyA_bmap_id);
|
|
else {
|
|
@@ -243,22 +242,29 @@
|
|
void
|
|
bx_gui_c::cdromD_handler(void)
|
|
{
|
|
+ Bit32u handle = bx_devices.hard_drive->get_first_cd_handle();
|
|
#if BX_WITH_WX
|
|
// instead of just toggling the status, call wxWindows to bring up
|
|
// a dialog asking what disk image you want to switch to.
|
|
- int ret = SIM->ask_param (BXP_CDROM_PATH);
|
|
+ // BBD: for now, find the first cdrom and call ask_param on that.
|
|
+ // Since we could have multiple cdroms now, maybe we should be adding
|
|
+ // one cdrom button for each?
|
|
+ bx_param_c *cdrom = SIM->get_first_cdrom ();
|
|
+ if (cdrom == NULL)
|
|
+ return; // no cdrom found
|
|
+ int ret = SIM->ask_param (cdrom->get_id ());
|
|
if (ret < 0) return; // cancelled
|
|
// eject and then insert the disk. If the new path is invalid,
|
|
// the status will return 0.
|
|
- unsigned status = bx_devices.hard_drive->set_cd_media_status(0);
|
|
+ unsigned status = bx_devices.hard_drive->set_cd_media_status(handle, 0);
|
|
printf ("eject disk, new_status is %d\n", status);
|
|
- status = bx_devices.hard_drive->set_cd_media_status(1);
|
|
+ status = bx_devices.hard_drive->set_cd_media_status(handle, 1);
|
|
printf ("insert disk, new_status is %d\n", status);
|
|
fflush (stdout);
|
|
BX_GUI_THIS cdromD_status = status;
|
|
#else
|
|
BX_GUI_THIS cdromD_status =
|
|
- bx_devices.hard_drive->set_cd_media_status(!BX_GUI_THIS cdromD_status);
|
|
+ bx_devices.hard_drive->set_cd_media_status(handle, !BX_GUI_THIS cdromD_status);
|
|
#endif
|
|
BX_GUI_THIS update_drive_status_buttons ();
|
|
}
|
|
Index: gui/siminterface.h
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/gui/siminterface.h,v
|
|
retrieving revision 1.69
|
|
diff -u -r1.69 siminterface.h
|
|
--- gui/siminterface.h 20 Sep 2002 17:56:22 -0000 1.69
|
|
+++ gui/siminterface.h 22 Sep 2002 20:46:08 -0000
|
|
@@ -128,12 +128,12 @@
|
|
BXP_ROM_ADDRESS,
|
|
BXP_VGA_ROM_PATH,
|
|
BXP_OPTROM1_PATH,
|
|
- BXP_OPTROM1_ADDRESS,
|
|
BXP_OPTROM2_PATH,
|
|
- BXP_OPTROM2_ADDRESS,
|
|
BXP_OPTROM3_PATH,
|
|
- BXP_OPTROM3_ADDRESS,
|
|
BXP_OPTROM4_PATH,
|
|
+ BXP_OPTROM1_ADDRESS,
|
|
+ BXP_OPTROM2_ADDRESS,
|
|
+ BXP_OPTROM3_ADDRESS,
|
|
BXP_OPTROM4_ADDRESS,
|
|
BXP_KBD_SERIAL_DELAY,
|
|
BXP_KBD_PASTE_DELAY,
|
|
@@ -149,18 +149,114 @@
|
|
BXP_FLOPPYB_TYPE,
|
|
BXP_FLOPPYB_STATUS,
|
|
BXP_FLOPPYB,
|
|
- BXP_DISKC_PRESENT,
|
|
- BXP_DISKC_PATH,
|
|
- BXP_DISKC_CYLINDERS,
|
|
- BXP_DISKC_HEADS,
|
|
- BXP_DISKC_SPT,
|
|
- BXP_DISKC,
|
|
- BXP_DISKD_PRESENT,
|
|
- BXP_DISKD_PATH,
|
|
- BXP_DISKD_CYLINDERS,
|
|
- BXP_DISKD_HEADS,
|
|
- BXP_DISKD_SPT,
|
|
- BXP_DISKD,
|
|
+ BXP_ATA0,
|
|
+ BXP_ATA1,
|
|
+ BXP_ATA2,
|
|
+ BXP_ATA3,
|
|
+ BXP_ATA0_PRESENT,
|
|
+ BXP_ATA1_PRESENT,
|
|
+ BXP_ATA2_PRESENT,
|
|
+ BXP_ATA3_PRESENT,
|
|
+ BXP_ATA0_IOADDR1,
|
|
+ BXP_ATA1_IOADDR1,
|
|
+ BXP_ATA2_IOADDR1,
|
|
+ BXP_ATA3_IOADDR1,
|
|
+ BXP_ATA0_IOADDR2,
|
|
+ BXP_ATA1_IOADDR2,
|
|
+ BXP_ATA2_IOADDR2,
|
|
+ BXP_ATA3_IOADDR2,
|
|
+ BXP_ATA0_IRQ,
|
|
+ BXP_ATA1_IRQ,
|
|
+ BXP_ATA2_IRQ,
|
|
+ BXP_ATA3_IRQ,
|
|
+ BXP_ATA0_MASTER,
|
|
+ BXP_ATA0_SLAVE,
|
|
+ BXP_ATA1_MASTER,
|
|
+ BXP_ATA1_SLAVE,
|
|
+ BXP_ATA2_MASTER,
|
|
+ BXP_ATA2_SLAVE,
|
|
+ BXP_ATA3_MASTER,
|
|
+ BXP_ATA3_SLAVE,
|
|
+ BXP_ATA0_MASTER_PRESENT,
|
|
+ BXP_ATA0_SLAVE_PRESENT,
|
|
+ BXP_ATA1_MASTER_PRESENT,
|
|
+ BXP_ATA1_SLAVE_PRESENT,
|
|
+ BXP_ATA2_MASTER_PRESENT,
|
|
+ BXP_ATA2_SLAVE_PRESENT,
|
|
+ BXP_ATA3_MASTER_PRESENT,
|
|
+ BXP_ATA3_SLAVE_PRESENT,
|
|
+ BXP_ATA0_MASTER_TYPE,
|
|
+ BXP_ATA0_SLAVE_TYPE,
|
|
+ BXP_ATA1_MASTER_TYPE,
|
|
+ BXP_ATA1_SLAVE_TYPE,
|
|
+ BXP_ATA2_MASTER_TYPE,
|
|
+ BXP_ATA2_SLAVE_TYPE,
|
|
+ BXP_ATA3_MASTER_TYPE,
|
|
+ BXP_ATA3_SLAVE_TYPE,
|
|
+ BXP_ATA0_MASTER_PATH,
|
|
+ BXP_ATA0_SLAVE_PATH,
|
|
+ BXP_ATA1_MASTER_PATH,
|
|
+ BXP_ATA1_SLAVE_PATH,
|
|
+ BXP_ATA2_MASTER_PATH,
|
|
+ BXP_ATA2_SLAVE_PATH,
|
|
+ BXP_ATA3_MASTER_PATH,
|
|
+ BXP_ATA3_SLAVE_PATH,
|
|
+ BXP_ATA0_MASTER_CYLINDERS,
|
|
+ BXP_ATA0_SLAVE_CYLINDERS,
|
|
+ BXP_ATA1_MASTER_CYLINDERS,
|
|
+ BXP_ATA1_SLAVE_CYLINDERS,
|
|
+ BXP_ATA2_MASTER_CYLINDERS,
|
|
+ BXP_ATA2_SLAVE_CYLINDERS,
|
|
+ BXP_ATA3_MASTER_CYLINDERS,
|
|
+ BXP_ATA3_SLAVE_CYLINDERS,
|
|
+ BXP_ATA0_MASTER_HEADS,
|
|
+ BXP_ATA0_SLAVE_HEADS,
|
|
+ BXP_ATA1_MASTER_HEADS,
|
|
+ BXP_ATA1_SLAVE_HEADS,
|
|
+ BXP_ATA2_MASTER_HEADS,
|
|
+ BXP_ATA2_SLAVE_HEADS,
|
|
+ BXP_ATA3_MASTER_HEADS,
|
|
+ BXP_ATA3_SLAVE_HEADS,
|
|
+ BXP_ATA0_MASTER_SPT,
|
|
+ BXP_ATA0_SLAVE_SPT,
|
|
+ BXP_ATA1_MASTER_SPT,
|
|
+ BXP_ATA1_SLAVE_SPT,
|
|
+ BXP_ATA2_MASTER_SPT,
|
|
+ BXP_ATA2_SLAVE_SPT,
|
|
+ BXP_ATA3_MASTER_SPT,
|
|
+ BXP_ATA3_SLAVE_SPT,
|
|
+ BXP_ATA0_MASTER_STATUS,
|
|
+ BXP_ATA0_SLAVE_STATUS,
|
|
+ BXP_ATA1_MASTER_STATUS,
|
|
+ BXP_ATA1_SLAVE_STATUS,
|
|
+ BXP_ATA2_MASTER_STATUS,
|
|
+ BXP_ATA2_SLAVE_STATUS,
|
|
+ BXP_ATA3_MASTER_STATUS,
|
|
+ BXP_ATA3_SLAVE_STATUS,
|
|
+ BXP_ATA0_MASTER_MODEL,
|
|
+ BXP_ATA0_SLAVE_MODEL,
|
|
+ BXP_ATA1_MASTER_MODEL,
|
|
+ BXP_ATA1_SLAVE_MODEL,
|
|
+ BXP_ATA2_MASTER_MODEL,
|
|
+ BXP_ATA2_SLAVE_MODEL,
|
|
+ BXP_ATA3_MASTER_MODEL,
|
|
+ BXP_ATA3_SLAVE_MODEL,
|
|
+ BXP_ATA0_MASTER_BIOSDETECT,
|
|
+ BXP_ATA0_SLAVE_BIOSDETECT,
|
|
+ BXP_ATA1_MASTER_BIOSDETECT,
|
|
+ BXP_ATA1_SLAVE_BIOSDETECT,
|
|
+ BXP_ATA2_MASTER_BIOSDETECT,
|
|
+ BXP_ATA2_SLAVE_BIOSDETECT,
|
|
+ BXP_ATA3_MASTER_BIOSDETECT,
|
|
+ BXP_ATA3_SLAVE_BIOSDETECT,
|
|
+ BXP_ATA0_MASTER_TRANSLATION,
|
|
+ BXP_ATA0_SLAVE_TRANSLATION,
|
|
+ BXP_ATA1_MASTER_TRANSLATION,
|
|
+ BXP_ATA1_SLAVE_TRANSLATION,
|
|
+ BXP_ATA2_MASTER_TRANSLATION,
|
|
+ BXP_ATA2_SLAVE_TRANSLATION,
|
|
+ BXP_ATA3_MASTER_TRANSLATION,
|
|
+ BXP_ATA3_SLAVE_TRANSLATION,
|
|
#define BXP_PARAMS_PER_SERIAL_PORT 2
|
|
BXP_COM1_ENABLED,
|
|
BXP_COM1_PATH,
|
|
@@ -170,10 +266,6 @@
|
|
BXP_COM3_PATH,
|
|
BXP_COM4_ENABLED,
|
|
BXP_COM4_PATH,
|
|
- BXP_CDROM_PRESENT,
|
|
- BXP_CDROM_PATH,
|
|
- BXP_CDROM_STATUS,
|
|
- BXP_CDROMD,
|
|
BXP_PRIVATE_COLORMAP,
|
|
BXP_FULLSCREEN,
|
|
BXP_SCREENMODE,
|
|
@@ -670,11 +762,12 @@
|
|
char *get_name () { return name; }
|
|
char *get_description () { return description; }
|
|
int get_enabled () { return enabled; }
|
|
- void set_enabled (int enabled) { this->enabled = enabled; }
|
|
+ virtual void set_enabled (int enabled) { this->enabled = enabled; }
|
|
void reset () {}
|
|
int getint () {return -1;}
|
|
static const char* set_default_format (const char *f);
|
|
static const char *get_default_format () { return default_text_format; }
|
|
+ virtual bx_list_c *get_dependent_list () { return NULL; }
|
|
#if BX_UI_TEXT
|
|
virtual void text_print (FILE *fp) {}
|
|
virtual int text_ask (FILE *fpin, FILE *fpout) {return -1;}
|
|
@@ -709,14 +802,16 @@
|
|
Bit32s min, Bit32s max, Bit32s initial_val);
|
|
void reset ();
|
|
void set_handler (param_event_handler handler);
|
|
- bx_list_c *get_dependent_list () { return dependent_list; }
|
|
+ virtual bx_list_c *get_dependent_list () { return dependent_list; }
|
|
void set_dependent_list (bx_list_c *l) {
|
|
dependent_list = l;
|
|
update_dependents ();
|
|
}
|
|
+ virtual void set_enabled (int enabled);
|
|
virtual Bit32s get ();
|
|
virtual void set (Bit32s val);
|
|
void set_base (int base) { this->base = base; }
|
|
+ void set_initial_val (Bit32s initial_val) { this->val.number = this->initial_val = initial_val;}
|
|
int get_base () { return base; }
|
|
Bit32s get_min () { return min; }
|
|
Bit32s get_max () { return max; }
|
|
@@ -897,13 +992,16 @@
|
|
bx_list_c (bx_id id, char *name, char *description, bx_param_c **init_list);
|
|
bx_list_c (bx_id id, char *name, char *description, int maxsize);
|
|
virtual ~bx_list_c();
|
|
+ bx_list_c *clone ();
|
|
void add (bx_param_c *param);
|
|
bx_param_c *get (int index);
|
|
int get_size () { return size; }
|
|
bx_param_num_c *get_options () { return options; }
|
|
+ void set_options (bx_param_num_c *newopt) { options = newopt; }
|
|
bx_param_num_c *get_choice () { return choice; }
|
|
bx_param_string_c *get_title () { return title; }
|
|
- void set_parent (bx_param_c *parent);
|
|
+ void set_parent (bx_param_c *newparent) { parent = newparent; }
|
|
+ bx_param_c *get_parent () { return parent; }
|
|
#if BX_UI_TEXT
|
|
virtual void text_print (FILE *);
|
|
virtual int text_ask (FILE *fpin, FILE *fpout);
|
|
@@ -922,6 +1020,19 @@
|
|
#define BX_FLOPPY_LAST 15 // last legal value of floppy type
|
|
#define BX_FLOPPY_GUESS 20 // decide based on image size
|
|
|
|
+#define BX_ATA_DEVICE_DISK 0
|
|
+#define BX_ATA_DEVICE_CDROM 1
|
|
+#define BX_ATA_DEVICE_LAST 1
|
|
+
|
|
+#define BX_ATA_BIOSDETECT_NONE 0
|
|
+#define BX_ATA_BIOSDETECT_AUTO 1
|
|
+#define BX_ATA_BIOSDETECT_CMOS 2
|
|
+
|
|
+#define BX_ATA_TRANSLATION_NONE 0
|
|
+#define BX_ATA_TRANSLATION_LBA 1
|
|
+#define BX_ATA_TRANSLATION_LARGE 2
|
|
+#define BX_ATA_TRANSLATION_LAST 2
|
|
+
|
|
extern char *floppy_type_names[];
|
|
extern int floppy_type_n_sectors[];
|
|
extern int n_floppy_type_names;
|
|
@@ -933,6 +1044,14 @@
|
|
extern int n_loader_os_names;
|
|
extern char *keyboard_type_names[];
|
|
extern int n_keyboard_type_names;
|
|
+extern char *atadevice_type_names[];
|
|
+extern int n_atadevice_type_names;
|
|
+extern char *atadevice_status_names[];
|
|
+extern int n_atadevice_status_names;
|
|
+extern char *atadevice_biosdetect_names[];
|
|
+extern int n_atadevice_biosdetect_names;
|
|
+extern char *atadevice_translation_names[];
|
|
+extern int n_atadevice_translation_names;
|
|
|
|
typedef struct {
|
|
bx_param_enum_c *Odevtype;
|
|
@@ -942,25 +1061,24 @@
|
|
} bx_floppy_options;
|
|
|
|
typedef struct {
|
|
+ bx_list_c *Omenu;
|
|
bx_param_bool_c *Opresent;
|
|
+ bx_param_enum_c *Otype;
|
|
bx_param_string_c *Opath;
|
|
bx_param_num_c *Ocylinders;
|
|
bx_param_num_c *Oheads;
|
|
bx_param_num_c *Ospt;
|
|
- } bx_disk_options;
|
|
+ bx_param_enum_c *Ostatus;
|
|
+ bx_param_string_c *Omodel;
|
|
+ bx_param_enum_c *Obiosdetect;
|
|
+ bx_param_enum_c *Otranslation;
|
|
+ } bx_atadevice_options;
|
|
|
|
typedef struct {
|
|
bx_param_bool_c *Oenabled;
|
|
bx_param_string_c *Odev;
|
|
} bx_serial_options;
|
|
|
|
-struct bx_cdrom_options
|
|
-{
|
|
- bx_param_bool_c *Opresent;
|
|
- bx_param_string_c *Opath;
|
|
- bx_param_enum_c *Ostatus;
|
|
-};
|
|
-
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// base class simulator interface, contains just virtual functions.
|
|
@@ -982,6 +1100,7 @@
|
|
virtual bx_param_num_c *get_param_num (bx_id id) {return NULL;}
|
|
virtual bx_param_string_c *get_param_string (bx_id id) {return NULL;}
|
|
virtual bx_param_bool_c *get_param_bool (bx_id id) {return NULL;}
|
|
+ virtual bx_param_enum_c *get_param_enum (bx_id id) {return NULL;}
|
|
virtual int get_n_log_modules () {return -1;}
|
|
virtual char *get_prefix (int mod) {return 0;}
|
|
virtual int get_log_action (int mod, int level) {return -1;}
|
|
@@ -1008,7 +1127,7 @@
|
|
virtual int get_log_prefix (char *prefix, int len) {return -1;}
|
|
virtual int set_log_prefix (char *prefix) {return -1;}
|
|
virtual int get_floppy_options (int drive, bx_floppy_options *out) {return -1;}
|
|
- virtual int get_cdrom_options (int drive, bx_cdrom_options *out) {return -1;}
|
|
+ virtual int get_cdrom_options (int drive, bx_atadevice_options *out, int *where = NULL) {return -1;}
|
|
virtual char *get_floppy_type_name (int type) {return NULL;}
|
|
|
|
// The CI calls set_notify_callback to register its event handler function.
|
|
@@ -1043,6 +1162,8 @@
|
|
// changed. The CI will reread the parameters and change its display if it's
|
|
// appropriate. Maybe later: mention which params have changed to save time.
|
|
virtual void refresh_ci () {}
|
|
+ // return first cdrom in ATA interface
|
|
+ bx_param_c *get_first_cdrom () {return NULL;}
|
|
#if BX_DEBUGGER
|
|
// for debugger: same behavior as pressing control-C
|
|
virtual void debug_break () {}
|
|
Index: gui/siminterface.cc
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/gui/siminterface.cc,v
|
|
retrieving revision 1.64
|
|
diff -u -r1.64 siminterface.cc
|
|
--- gui/siminterface.cc 20 Sep 2002 17:56:21 -0000 1.64
|
|
+++ gui/siminterface.cc 22 Sep 2002 20:46:09 -0000
|
|
@@ -50,6 +50,7 @@
|
|
virtual bx_param_num_c *get_param_num (bx_id id);
|
|
virtual bx_param_string_c *get_param_string (bx_id id);
|
|
virtual bx_param_bool_c *get_param_bool (bx_id id);
|
|
+ virtual bx_param_enum_c *get_param_enum (bx_id id);
|
|
virtual int get_n_log_modules ();
|
|
virtual char *get_prefix (int mod);
|
|
virtual int get_log_action (int mod, int level);
|
|
@@ -72,7 +73,7 @@
|
|
virtual int get_log_prefix (char *prefix, int len);
|
|
virtual int set_log_prefix (char *prefix);
|
|
virtual int get_floppy_options (int drive, bx_floppy_options *out);
|
|
- virtual int get_cdrom_options (int drive, bx_cdrom_options *out);
|
|
+ virtual int get_cdrom_options (int drive, bx_atadevice_options *out, int *device = NULL);
|
|
virtual char *get_floppy_type_name (int type);
|
|
virtual void set_notify_callback (sim_interface_callback_t func, void *arg);
|
|
virtual BxEvent* sim_to_ci_event (BxEvent *event);
|
|
@@ -84,6 +85,7 @@
|
|
virtual void periodic ();
|
|
virtual int create_disk_image (const char *filename, int sectors, Boolean overwrite);
|
|
virtual void refresh_ci ();
|
|
+ bx_param_c *get_first_cdrom ();
|
|
#if BX_DEBUGGER
|
|
virtual void debug_break ();
|
|
virtual void debug_interpret_cmd (char *cmd);
|
|
@@ -143,6 +145,19 @@
|
|
return NULL;
|
|
}
|
|
|
|
+bx_param_enum_c *
|
|
+bx_real_sim_c::get_param_enum (bx_id id) {
|
|
+ bx_param_c *generic = get_param(id);
|
|
+ if (generic==NULL) {
|
|
+ BX_PANIC (("get_param_enum(%u) could not find a parameter", id));
|
|
+ return NULL;
|
|
+ }
|
|
+ if (generic->get_type () == BXT_PARAM_ENUM)
|
|
+ return (bx_param_enum_c *)generic;
|
|
+ BX_PANIC (("get_param_enum %u could not find a enum parameter with that id", id));
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
void bx_init_siminterface ()
|
|
{
|
|
siminterface_log = new logfunctions ();
|
|
@@ -340,10 +355,20 @@
|
|
}
|
|
|
|
int
|
|
-bx_real_sim_c::get_cdrom_options (int drive, bx_cdrom_options *out)
|
|
+bx_real_sim_c::get_cdrom_options (int level, bx_atadevice_options *out, int *where = NULL)
|
|
{
|
|
- BX_ASSERT (drive == 0);
|
|
- *out = bx_options.cdromd;
|
|
+ for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
|
|
+ for (Bit8u device=0; device<2; device++) {
|
|
+ if (bx_options.atadevice[channel][device].Otype->get() == BX_ATA_DEVICE_CDROM) {
|
|
+ if (level==0) {
|
|
+ *out = bx_options.atadevice[channel][device];
|
|
+ if (where != NULL) *where=(channel*2)+device;
|
|
+ return 1;
|
|
+ }
|
|
+ else level--;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
return 0;
|
|
}
|
|
|
|
@@ -358,6 +383,14 @@
|
|
int n_loader_os_names = 3;
|
|
char *keyboard_type_names[] = { "xt", "at", "mf", NULL };
|
|
int n_keyboard_type_names = 3;
|
|
+char *atadevice_type_names[] = { "hard disk", "cdrom", NULL };
|
|
+int n_atadevice_type_names = 2;
|
|
+char *atadevice_status_names[] = { "ejected", "inserted", NULL };
|
|
+int n_atadevice_status_names = 2;
|
|
+char *atadevice_biosdetect_names[] = { "none", "auto", "cmos", NULL };
|
|
+int n_atadevice_biosdetect_names = 3;
|
|
+char *atadevice_translation_names[] = { "none", "lba", "large", NULL };
|
|
+int n_atadevice_translation_names = 3;
|
|
|
|
char *
|
|
bx_real_sim_c::get_floppy_type_name (int type)
|
|
@@ -533,6 +566,23 @@
|
|
// the event will be freed by the recipient
|
|
}
|
|
|
|
+bx_param_c *
|
|
+bx_real_sim_c::get_first_cdrom ()
|
|
+{
|
|
+ for (int channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
|
|
+ if (!bx_options.ata[channel].Opresent->get ())
|
|
+ continue;
|
|
+ for (int slave=0; slave<2; slave++) {
|
|
+ Bit32u present = bx_options.atadevice[channel][slave].Opresent->get ();
|
|
+ Bit32u type = bx_options.atadevice[channel][slave].Otype->get ();
|
|
+ if (present && type == BX_ATA_DEVICE_CDROM) {
|
|
+ return bx_options.atadevice[channel][slave].Omenu;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
#if BX_DEBUGGER
|
|
|
|
// this can be safely called from either thread.
|
|
@@ -688,12 +738,22 @@
|
|
void bx_param_num_c::update_dependents ()
|
|
{
|
|
if (dependent_list) {
|
|
- int en = val.number? 1 : 0;
|
|
- for (int i=0; i<dependent_list->get_size (); i++)
|
|
- dependent_list->get (i)->set_enabled (en);
|
|
+ int en = val.number && enabled;
|
|
+ for (int i=0; i<dependent_list->get_size (); i++) {
|
|
+ bx_param_c *param = dependent_list->get (i);
|
|
+ if (param != this)
|
|
+ param->set_enabled (en);
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+void
|
|
+bx_param_num_c::set_enabled (int en)
|
|
+{
|
|
+ bx_param_c::set_enabled (en);
|
|
+ update_dependents ();
|
|
+}
|
|
+
|
|
bx_shadow_num_c::bx_shadow_num_c (bx_id id,
|
|
char *name,
|
|
char *description,
|
|
@@ -1042,6 +1102,17 @@
|
|
this->parent = NULL;
|
|
}
|
|
|
|
+bx_list_c *
|
|
+bx_list_c::clone ()
|
|
+{
|
|
+ bx_list_c *newlist = new bx_list_c (BXP_NULL, name, description, maxsize);
|
|
+ for (int i=0; i<get_size (); i++)
|
|
+ newlist->add (get(i));
|
|
+ newlist->set_options (get_options ());
|
|
+ newlist->set_parent (get_parent ());
|
|
+ return newlist;
|
|
+}
|
|
+
|
|
void
|
|
bx_list_c::add (bx_param_c *param)
|
|
{
|
|
@@ -1058,8 +1129,3 @@
|
|
return list[index];
|
|
}
|
|
|
|
-void
|
|
-bx_list_c::set_parent (bx_param_c *parent)
|
|
-{
|
|
- this->parent = parent;
|
|
-}
|
|
Index: gui/wxdialog.cc
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/gui/wxdialog.cc,v
|
|
retrieving revision 1.42
|
|
diff -u -r1.42 wxdialog.cc
|
|
--- gui/wxdialog.cc 20 Sep 2002 21:25:09 -0000 1.42
|
|
+++ gui/wxdialog.cc 22 Sep 2002 20:46:11 -0000
|
|
@@ -1709,6 +1709,7 @@
|
|
BEGIN_EVENT_TABLE(ParamDialog, wxDialog)
|
|
EVT_BUTTON(-1, ParamDialog::OnEvent)
|
|
EVT_CHECKBOX(-1, ParamDialog::OnEvent)
|
|
+ EVT_CHOICE(-1, ParamDialog::OnEvent)
|
|
EVT_TEXT(-1, ParamDialog::OnEvent)
|
|
END_EVENT_TABLE()
|
|
|
|
@@ -1817,14 +1818,14 @@
|
|
pstr->id = genId ();
|
|
pstr->param = param_generic;
|
|
int type = param_generic->get_type ();
|
|
-#define ADD_LABEL(x) sizer->Add (new wxStaticText (this, -1, wxString (x)), 0, wxALIGN_RIGHT|wxALL, 3)
|
|
+ char *prompt = pstr->param->get_ask_format ();
|
|
+ if (!prompt) prompt = pstr->param->get_name ();
|
|
+ wxASSERT (prompt != NULL);
|
|
+#define ADD_LABEL(x) sizer->Add (pstr->label = new wxStaticText (this, -1, wxString (x)), 0, wxALIGN_RIGHT|wxALL, 3)
|
|
switch (type) {
|
|
case BXT_PARAM_BOOL: {
|
|
bx_param_bool_c *param = (bx_param_bool_c*) param_generic;
|
|
- if (!plain) {
|
|
- char *prompt = param->get_name ();
|
|
- ADD_LABEL (prompt);
|
|
- }
|
|
+ if (!plain) ADD_LABEL (prompt);
|
|
wxCheckBox *ckbx = new wxCheckBox (this, pstr->id, "");
|
|
ckbx->SetValue (param->get ());
|
|
sizer->Add (ckbx);
|
|
@@ -1836,10 +1837,7 @@
|
|
}
|
|
case BXT_PARAM_NUM: {
|
|
bx_param_num_c *param = (bx_param_num_c*) param_generic;
|
|
- if (!plain) {
|
|
- char *prompt = param->get_name ();
|
|
- ADD_LABEL (prompt);
|
|
- }
|
|
+ if (!plain) ADD_LABEL (prompt);
|
|
wxTextCtrl *textctrl = new wxTextCtrl (this, pstr->id, "");
|
|
const char *format = param->get_format ();
|
|
if (!format)
|
|
@@ -1854,10 +1852,7 @@
|
|
}
|
|
case BXT_PARAM_ENUM: {
|
|
bx_param_enum_c *param = (bx_param_enum_c*) param_generic;
|
|
- if (!plain) {
|
|
- char *prompt = param->get_name ();
|
|
- ADD_LABEL (prompt);
|
|
- }
|
|
+ if (!plain) ADD_LABEL (prompt);
|
|
wxChoice *choice = new wxChoice (this, pstr->id);
|
|
sizer->Add (choice);
|
|
if (!plain) sizer->Add (1, 1); // spacer
|
|
@@ -1874,10 +1869,7 @@
|
|
}
|
|
case BXT_PARAM_STRING: {
|
|
bx_param_string_c *param = (bx_param_string_c*) param_generic;
|
|
- if (!plain) {
|
|
- char *prompt = param->get_name ();
|
|
- ADD_LABEL (prompt);
|
|
- }
|
|
+ if (!plain) ADD_LABEL (prompt);
|
|
bool isFilename = param->get_options ()->get () & param->BX_IS_FILENAME;
|
|
wxTextCtrl *txtctrl = new wxTextCtrl (this, pstr->id, "", wxDefaultPosition, isFilename? longTextSize : wxDefaultSize);
|
|
txtctrl->SetValue (param->getptr ());
|
|
@@ -1901,20 +1893,24 @@
|
|
}
|
|
case BXT_LIST: {
|
|
bx_list_c *list = (bx_list_c*) param_generic;
|
|
- wxStaticBox *box = new wxStaticBox (this, -1, list->get_name ());
|
|
+ wxStaticBox *box = new wxStaticBox (this, -1, prompt);
|
|
wxStaticBoxSizer *boxsz = new wxStaticBoxSizer (box, wxVERTICAL);
|
|
wxFlexGridSizer *gridSz = new wxFlexGridSizer (3);
|
|
- boxsz->Add (gridSz, 1, wxGROW|wxALL, 20);
|
|
+ boxsz->Add (gridSz, 1, wxGROW|wxALL, 10);
|
|
// put all items in the list inside the boxsz sizer.
|
|
for (int i=0; i<list->get_size (); i++) {
|
|
bx_param_c *child = list->get (i);
|
|
AddParam (child, gridSz);
|
|
}
|
|
// add the boxsz to mainSizer
|
|
- mainSizer->Add (boxsz, 0, wxALL, 10);
|
|
+ mainSizer->Add (boxsz, 0, wxALL|wxGROW, 10);
|
|
// clear gridSizer variable so that any future parameters force
|
|
// creation of a new one.
|
|
gridSizer = NULL;
|
|
+ // add to hashes
|
|
+ pstr->u.staticbox = box;
|
|
+ idHash->Put (pstr->id, pstr);
|
|
+ paramHash->Put (pstr->param->get_id (), pstr);
|
|
break;
|
|
}
|
|
default:
|
|
@@ -1974,26 +1970,108 @@
|
|
ParamStruct *pstr = (ParamStruct*) node->GetData ();
|
|
if (pstr->param->get_type () == BXT_PARAM_BOOL)
|
|
EnableChanged (pstr);
|
|
+ // special cases that can't be handled in the usual way
|
|
}
|
|
}
|
|
|
|
void ParamDialog::EnableChanged (ParamStruct *pstrOfCheckbox)
|
|
{
|
|
+ wxLogDebug ("EnableChanged on checkbox %s", pstrOfCheckbox->param->get_name ());
|
|
bx_param_bool_c *enableParam = (bx_param_bool_c*) pstrOfCheckbox->param;
|
|
wxASSERT (enableParam->get_type () == BXT_PARAM_BOOL); // or we wouldn't be here
|
|
- // if nothing depends on this "enableParam", then we're done
|
|
- bx_list_c *list = enableParam->get_dependent_list ();
|
|
- if (list == NULL) return;
|
|
- // Now we know the object has dependents. Step through the list of
|
|
- // dependents, use the paramHash table to find their ParamStruct,
|
|
- // and enable/disable them as needed.
|
|
bool en = pstrOfCheckbox->u.checkbox->GetValue ();
|
|
+ EnableChangedRecursive (enableParam->get_dependent_list (), en, pstrOfCheckbox);
|
|
+}
|
|
+
|
|
+void ParamDialog::EnableChangedRecursive (
|
|
+ bx_list_c *list,
|
|
+ bool en,
|
|
+ ParamStruct *pstrOfCheckbox)
|
|
+{
|
|
+ if (list==NULL) return;
|
|
for (int i=0; i<list->get_size (); i++) {
|
|
bx_param_c *param = list->get(i);
|
|
ParamStruct *pstr = (ParamStruct*) paramHash->Get (param->get_id ());
|
|
if (pstr) {
|
|
+ if (param == pstrOfCheckbox->param) {
|
|
+ wxLogDebug ("not setting enable on checkbox '%s' that triggered the enable change", pstrOfCheckbox->param->get_name ());
|
|
+ continue;
|
|
+ }
|
|
wxLogDebug ("setting enable for param '%s' to %d", pstr->param->get_name (), en?1:0);
|
|
- pstr->u.window->Enable (en);
|
|
+ if (en != pstr->u.window->IsEnabled ()) {
|
|
+ EnableParam (pstr->param->get_id (), en);
|
|
+ //pstr->u.window->Enable (en);
|
|
+ //if (pstr->browseButton) pstr->browseButton->Enable (en);
|
|
+ //if (pstr->label) pstr->label->Enable (en);
|
|
+ bx_list_c *deps = pstr->param->get_dependent_list ();
|
|
+ if (deps) {
|
|
+ wxLogDebug ("recursing on dependent list of %s", list->get_name ());
|
|
+ wxASSERT (pstr->param->get_type () == BXT_PARAM_BOOL);
|
|
+ bool dep_en = pstr->u.window->IsEnabled () && pstr->u.checkbox->GetValue ();
|
|
+ EnableChangedRecursive (deps, dep_en, pstr);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // if any enums changed, give them a chance to update
|
|
+ for (int i=0; i<list->get_size (); i++) {
|
|
+ bx_param_c *param = list->get(i);
|
|
+ ParamStruct *pstr = (ParamStruct*) paramHash->Get (param->get_id ());
|
|
+ if (pstr) {
|
|
+ if (pstr->param->get_type () == BXT_PARAM_ENUM)
|
|
+ EnumChanged (pstr);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void ParamDialog::EnableParam (int param_id, bool enabled)
|
|
+{
|
|
+ ParamStruct *pstr = (ParamStruct*) paramHash->Get (param_id);
|
|
+ if (!pstr) return;
|
|
+ if (pstr->label) pstr->label->Enable (enabled);
|
|
+ if (pstr->browseButton) pstr->browseButton->Enable (enabled);
|
|
+ if (pstr->u.window) pstr->u.window->Enable (enabled);
|
|
+}
|
|
+
|
|
+void ParamDialog::EnumChanged (ParamStruct *pstr)
|
|
+{
|
|
+ wxLogDebug ("EnumChanged");
|
|
+ int id = pstr->param->get_id ();
|
|
+ switch (id) {
|
|
+ case BXP_ATA0_MASTER_TYPE:
|
|
+ case BXP_ATA0_SLAVE_TYPE:
|
|
+ case BXP_ATA1_MASTER_TYPE:
|
|
+ case BXP_ATA1_SLAVE_TYPE:
|
|
+ case BXP_ATA2_MASTER_TYPE:
|
|
+ case BXP_ATA2_SLAVE_TYPE:
|
|
+ case BXP_ATA3_MASTER_TYPE:
|
|
+ case BXP_ATA3_SLAVE_TYPE: {
|
|
+ int delta = id - BXP_ATA0_MASTER_TYPE;
|
|
+ // find out if "present" checkbox is checked
|
|
+ bx_id present_id = (bx_id) (BXP_ATA0_MASTER_PRESENT+delta);
|
|
+ ParamStruct *present = (ParamStruct*) paramHash->Get (present_id);
|
|
+ wxASSERT (present && present->param->get_type () == BXT_PARAM_BOOL);
|
|
+ if (!present->u.checkbox->GetValue ())
|
|
+ break; // device not enabled, leave it alone
|
|
+ if (!present->u.checkbox->IsEnabled ())
|
|
+ break; // enable button for the device is not enabled
|
|
+ wxASSERT (pstr->param->get_type () == BXT_PARAM_ENUM);
|
|
+ int type = pstr->u.choice->GetSelection ();
|
|
+ if (type == BX_ATA_DEVICE_DISK) {
|
|
+ // enable cylinders, heads, spt
|
|
+ wxLogDebug ("enabling disk parameters");
|
|
+ EnableParam (BXP_ATA0_MASTER_CYLINDERS+delta, 1);
|
|
+ EnableParam (BXP_ATA0_MASTER_HEADS+delta, 1);
|
|
+ EnableParam (BXP_ATA0_MASTER_SPT+delta, 1);
|
|
+ EnableParam (BXP_ATA0_MASTER_STATUS+delta, 0);
|
|
+ } else {
|
|
+ // enable inserted
|
|
+ wxLogDebug ("enabling cdrom parameters");
|
|
+ EnableParam (BXP_ATA0_MASTER_CYLINDERS+delta, 0);
|
|
+ EnableParam (BXP_ATA0_MASTER_HEADS+delta, 0);
|
|
+ EnableParam (BXP_ATA0_MASTER_SPT+delta, 0);
|
|
+ EnableParam (BXP_ATA0_MASTER_STATUS+delta, 1);
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
@@ -2041,7 +2119,7 @@
|
|
void ParamDialog::OnEvent(wxCommandEvent& event)
|
|
{
|
|
int id = event.GetId ();
|
|
- //wxLogMessage ("event was from id=%d", id);
|
|
+ wxLogMessage ("event was from id=%d", id);
|
|
if (isGeneratedId (id)) {
|
|
ParamStruct *pstr = (ParamStruct*) idHash->Get (id);
|
|
if (pstr == NULL) {
|
|
@@ -2050,10 +2128,13 @@
|
|
}
|
|
if (id == pstr->id) {
|
|
IFDBG_DLG (wxLogDebug ("event came from window %p (id=%d) controlled by parameter '%s'", pstr->u.window, id, pstr->param->get_name ()));
|
|
- if (pstr->param->get_type () == BXT_PARAM_BOOL) {
|
|
- // we know that a wxCheckBox changed state. We don't yet know
|
|
- // if that checkbox was enabling anything.
|
|
- EnableChanged (pstr);
|
|
+ switch (pstr->param->get_type ()) {
|
|
+ case BXT_PARAM_BOOL:
|
|
+ EnableChanged (pstr);
|
|
+ break;
|
|
+ case BXT_PARAM_ENUM:
|
|
+ EnumChanged (pstr);
|
|
+ break;
|
|
}
|
|
return;
|
|
}
|
|
Index: gui/wxdialog.h
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/gui/wxdialog.h,v
|
|
retrieving revision 1.39
|
|
diff -u -r1.39 wxdialog.h
|
|
--- gui/wxdialog.h 22 Sep 2002 04:52:55 -0000 1.39
|
|
+++ gui/wxdialog.h 22 Sep 2002 20:46:12 -0000
|
|
@@ -728,11 +728,13 @@
|
|
struct ParamStruct : public wxObject {
|
|
bx_param_c *param;
|
|
int id;
|
|
+ wxStaticText *label;
|
|
union _u_tag {
|
|
wxWindow *window;
|
|
wxChoice *choice;
|
|
wxTextCtrl *text;
|
|
wxCheckBox *checkbox;
|
|
+ wxStaticBox *staticbox;
|
|
} u;
|
|
int browseButtonId; // only for filename params
|
|
wxButton *browseButton; // only for filename params
|
|
@@ -760,6 +762,9 @@
|
|
// map parameter ID (BXP_*) onto ParamStruct.
|
|
wxHashTable *paramHash;
|
|
virtual void EnableChanged ();
|
|
+ void EnableParam (int param_id, bool enabled);
|
|
+ void EnumChanged (ParamStruct *pstr);
|
|
+ void EnableChangedRecursive (bx_list_c *list, bool en, ParamStruct *pstrOfCheckbox);
|
|
void EnableChanged (ParamStruct *pstr);
|
|
bool CopyGuiToParam ();
|
|
public:
|
|
Index: gui/wxmain.h
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/gui/wxmain.h,v
|
|
retrieving revision 1.29
|
|
diff -u -r1.29 wxmain.h
|
|
--- gui/wxmain.h 20 Sep 2002 21:25:09 -0000 1.29
|
|
+++ gui/wxmain.h 22 Sep 2002 20:46:12 -0000
|
|
@@ -28,9 +28,11 @@
|
|
ID_Config_Save,
|
|
ID_Edit_FD_0,
|
|
ID_Edit_FD_1,
|
|
- ID_Edit_HD_0,
|
|
- ID_Edit_HD_1,
|
|
- ID_Edit_Cdrom,
|
|
+ ID_Edit_ATA0,
|
|
+ ID_Edit_ATA1,
|
|
+ ID_Edit_ATA2,
|
|
+ ID_Edit_ATA3,
|
|
+ ID_Edit_Cdrom, // for toolbar. FIXME: toolbar can't handle >1 cdrom
|
|
ID_Edit_Boot,
|
|
ID_Edit_Memory,
|
|
ID_Edit_Sound,
|
|
@@ -197,8 +199,7 @@
|
|
#endif
|
|
static bool editFloppyValidate (FloppyConfigDialog *dialog);
|
|
void editFloppyConfig (int drive);
|
|
- void editHDConfig (int drive);
|
|
- void editCdromConfig ();
|
|
+ void editATAConfig (int channel);
|
|
void OnToolbarClick(wxCommandEvent& event);
|
|
int HandleAskParam (BxEvent *event);
|
|
int HandleAskParamString (bx_param_string_c *param);
|
|
Index: gui/wxmain.cc
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/gui/wxmain.cc,v
|
|
retrieving revision 1.55
|
|
diff -u -r1.55 wxmain.cc
|
|
--- gui/wxmain.cc 22 Sep 2002 04:36:09 -0000 1.55
|
|
+++ gui/wxmain.cc 22 Sep 2002 20:46:15 -0000
|
|
@@ -168,9 +168,10 @@
|
|
EVT_MENU(ID_Simulate_PauseResume, MyFrame::OnPauseResumeSim)
|
|
EVT_MENU(ID_Simulate_Stop, MyFrame::OnKillSim)
|
|
EVT_MENU(ID_Sim2CI_Event, MyFrame::OnSim2CIEvent)
|
|
- EVT_MENU(ID_Edit_HD_0, MyFrame::OnOtherEvent)
|
|
- EVT_MENU(ID_Edit_HD_1, MyFrame::OnOtherEvent)
|
|
- EVT_MENU(ID_Edit_Cdrom, MyFrame::OnOtherEvent)
|
|
+ EVT_MENU(ID_Edit_ATA0, MyFrame::OnOtherEvent)
|
|
+ EVT_MENU(ID_Edit_ATA1, MyFrame::OnOtherEvent)
|
|
+ EVT_MENU(ID_Edit_ATA2, MyFrame::OnOtherEvent)
|
|
+ EVT_MENU(ID_Edit_ATA3, MyFrame::OnOtherEvent)
|
|
EVT_MENU(ID_Edit_Boot, MyFrame::OnEditBoot)
|
|
EVT_MENU(ID_Edit_Memory, MyFrame::OnEditMemory)
|
|
EVT_MENU(ID_Edit_Sound, MyFrame::OnEditSound)
|
|
@@ -279,9 +280,10 @@
|
|
menuEdit = new wxMenu;
|
|
menuEdit->Append( ID_Edit_FD_0, "Floppy Disk &0..." );
|
|
menuEdit->Append( ID_Edit_FD_1, "Floppy Disk &1..." );
|
|
- menuEdit->Append( ID_Edit_HD_0, "Hard Disk 0..." );
|
|
- menuEdit->Append( ID_Edit_HD_1, "Hard Disk 1..." );
|
|
- menuEdit->Append( ID_Edit_Cdrom, "Cdrom..." );
|
|
+ menuEdit->Append( ID_Edit_ATA0, "ATA Controller 0..." );
|
|
+ menuEdit->Append( ID_Edit_ATA1, "ATA Controller 1..." );
|
|
+ menuEdit->Append( ID_Edit_ATA2, "ATA Controller 2..." );
|
|
+ menuEdit->Append( ID_Edit_ATA3, "ATA Controller 3..." );
|
|
menuEdit->Append( ID_Edit_Boot, "&Boot..." );
|
|
menuEdit->Append( ID_Edit_Memory, "&Memory..." );
|
|
menuEdit->Append( ID_Edit_Sound, "&Sound..." );
|
|
@@ -402,24 +404,22 @@
|
|
int bootDevices = 0;
|
|
wxString devices[MAX_BOOT_DEVICES];
|
|
int dev_id[MAX_BOOT_DEVICES];
|
|
- bx_param_bool_c *floppy = (bx_param_bool_c *)
|
|
- SIM->get_param (BXP_FLOPPYA_DEVTYPE);
|
|
- bx_param_bool_c *hd = (bx_param_bool_c *)
|
|
- SIM->get_param (BXP_DISKC_PRESENT);
|
|
- bx_param_bool_c *cdrom = (bx_param_bool_c *)
|
|
- SIM->get_param (BXP_CDROM_PRESENT);
|
|
- wxASSERT (floppy->get_type () == BXT_PARAM_ENUM
|
|
- && hd->get_type () == BXT_PARAM_BOOL
|
|
- && cdrom->get_type () == BXT_PARAM_BOOL);
|
|
+ bx_param_enum_c *floppy = SIM->get_param_enum (BXP_FLOPPYA_DEVTYPE);
|
|
+ bx_param_bool_c *ata0_mpres = SIM->get_param_bool (BXP_ATA0_MASTER_PRESENT);
|
|
+ bx_param_enum_c *ata0_mtype = SIM->get_param_enum (BXP_ATA0_MASTER_TYPE);
|
|
+ bx_param_bool_c *ata0_spres = SIM->get_param_bool (BXP_ATA0_SLAVE_PRESENT);
|
|
+ bx_param_enum_c *ata0_stype = SIM->get_param_enum (BXP_ATA0_SLAVE_TYPE);
|
|
if (floppy->get () != BX_FLOPPY_NONE) {
|
|
devices[bootDevices] = wxT("First floppy drive");
|
|
dev_id[bootDevices++] = BX_BOOT_FLOPPYA;
|
|
}
|
|
- if (hd->get ()) {
|
|
+#warning wxwindows interface will only allow booting from hard disk if it is on ATA0 master
|
|
+ if (ata0_mpres->get() && ata0_mtype->get() == BX_ATA_DEVICE_DISK) {
|
|
devices[bootDevices] = wxT("First hard drive");
|
|
dev_id[bootDevices++] = BX_BOOT_DISKC;
|
|
}
|
|
- if (cdrom->get ()) {
|
|
+#warning wxwindows interface will only allow booting from cdrom if it is on ATA0 slave
|
|
+ if (ata0_spres->get() && ata0_stype->get() == BX_ATA_DEVICE_CDROM) {
|
|
devices[bootDevices] = wxT("CD-ROM drive");
|
|
dev_id[bootDevices++] = BX_BOOT_CDROM;
|
|
}
|
|
@@ -834,8 +834,11 @@
|
|
bool canConfigure = (change == Stop);
|
|
menuConfiguration->Enable (ID_Config_New, canConfigure);
|
|
menuConfiguration->Enable (ID_Config_Read, canConfigure);
|
|
- menuEdit->Enable (ID_Edit_HD_0, canConfigure);
|
|
- menuEdit->Enable (ID_Edit_HD_1, canConfigure);
|
|
+#warning For now, leave ATA devices so that you configure them during runtime. Otherwise you cannot change the CD image at runtime.
|
|
+ //menuEdit->Enable (ID_Edit_ATA0, canConfigure);
|
|
+ //menuEdit->Enable (ID_Edit_ATA1, canConfigure);
|
|
+ //menuEdit->Enable (ID_Edit_ATA2, canConfigure);
|
|
+ //menuEdit->Enable (ID_Edit_ATA3, canConfigure);
|
|
menuEdit->Enable( ID_Edit_Boot, canConfigure);
|
|
menuEdit->Enable( ID_Edit_Memory, canConfigure);
|
|
menuEdit->Enable( ID_Edit_Sound, canConfigure);
|
|
@@ -853,8 +856,12 @@
|
|
menuEdit->Enable (ID_Edit_FD_0, canConfigure || param->get_enabled ());
|
|
param = SIM->get_param(BXP_FLOPPYB);
|
|
menuEdit->Enable (ID_Edit_FD_1, canConfigure || param->get_enabled ());
|
|
- param = SIM->get_param(BXP_CDROMD);
|
|
- menuEdit->Enable (ID_Edit_Cdrom, canConfigure || param->get_enabled ());
|
|
+ /*
|
|
+ // this menu item removed, since you can configure the cdrom from the
|
|
+ // ATA controller menu items instead.
|
|
+ param = SIM->get_first_cdrom ();
|
|
+ menuEdit->Enable (ID_Edit_Cdrom, canConfigure || (param&¶m->get_enabled ()));
|
|
+ */
|
|
}
|
|
|
|
void MyFrame::OnStartSim(wxCommandEvent& event)
|
|
@@ -1152,9 +1159,12 @@
|
|
int id = event.GetId ();
|
|
wxLogMessage ("event id=%d", id);
|
|
switch (id) {
|
|
- case ID_Edit_HD_0: editHDConfig (0); break;
|
|
- case ID_Edit_HD_1: editHDConfig (1); break;
|
|
- case ID_Edit_Cdrom: editCdromConfig (); break;
|
|
+ case ID_Edit_ATA0:
|
|
+ case ID_Edit_ATA1:
|
|
+ case ID_Edit_ATA2:
|
|
+ case ID_Edit_ATA3:
|
|
+ editATAConfig (id - ID_Edit_ATA0);
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
@@ -1217,106 +1227,14 @@
|
|
}
|
|
}
|
|
|
|
-void MyFrame::editHDConfig (int drive)
|
|
-{
|
|
- HDConfigDialog dlg (this, -1);
|
|
- dlg.SetDriveName (drive==0? BX_HARD_DISK0_NAME : BX_HARD_DISK1_NAME);
|
|
- bx_list_c *list = (bx_list_c*) SIM->get_param ((drive==0)? BXP_DISKC : BXP_DISKD);
|
|
- if (!list) { wxLogError ("HD object param is null"); return; }
|
|
- bx_param_filename_c *fname = (bx_param_filename_c*) list->get(0);
|
|
- bx_param_num_c *cyl = (bx_param_num_c *) list->get(1);
|
|
- bx_param_num_c *heads = (bx_param_num_c *) list->get(2);
|
|
- bx_param_num_c *spt = (bx_param_num_c *) list->get(3);
|
|
- bx_param_bool_c *present = (bx_param_bool_c *)
|
|
- SIM->get_param (drive==0? BXP_DISKC_PRESENT : BXP_DISKD_PRESENT);
|
|
- wxASSERT (fname->get_type () == BXT_PARAM_STRING
|
|
- && cyl->get_type () == BXT_PARAM_NUM
|
|
- && heads->get_type () == BXT_PARAM_NUM
|
|
- && spt->get_type() == BXT_PARAM_NUM
|
|
- && present->get_type() == BXT_PARAM_BOOL);
|
|
- dlg.SetFilename (fname->getptr ());
|
|
- dlg.SetGeomRange (0, cyl->get_min(), cyl->get_max ());
|
|
- dlg.SetGeomRange (1, heads->get_min(), heads->get_max ());
|
|
- dlg.SetGeomRange (2, spt->get_min(), spt->get_max ());
|
|
- dlg.SetGeom (0, cyl->get ());
|
|
- dlg.SetGeom (1, heads->get ());
|
|
- dlg.SetGeom (2, spt->get ());
|
|
- dlg.SetEnable (present->get ());
|
|
- int n = dlg.ShowModal ();
|
|
- wxLogMessage ("HD config returned %d", n);
|
|
- if (n==wxID_OK) {
|
|
- char filename[1024];
|
|
- wxString fn (dlg.GetFilename ());
|
|
- strncpy (filename, fn.c_str (), sizeof (filename));
|
|
- wxLogMessage ("filename is '%s'", filename);
|
|
- fname->set (filename);
|
|
- cyl->set (dlg.GetGeom (0));
|
|
- heads->set (dlg.GetGeom (1));
|
|
- spt->set (dlg.GetGeom (2));
|
|
- present->set (dlg.GetEnable ());
|
|
- wxLogMessage ("present=%d cyl=%d heads=%d spt=%d", present->get (), cyl->get(), heads->get(), spt->get());
|
|
- if (drive==1 && present->get ()) {
|
|
- // check that diskD and cdrom are not enabled at the same time
|
|
- bx_param_bool_c *cdromd = (bx_param_bool_c*)
|
|
- SIM->get_param(BXP_CDROM_PRESENT);
|
|
- if (cdromd->get ()) {
|
|
- wxString msg;
|
|
- msg.Printf ("You cannot have both %s and %s enabled. Disabling %s.",
|
|
- BX_HARD_DISK1_NAME, BX_CDROM_NAME, BX_CDROM_NAME);
|
|
- wxMessageBox( msg, "Device conflict", wxOK | wxICON_ERROR );
|
|
- cdromd->set (0);
|
|
- }
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-void MyFrame::editCdromConfig ()
|
|
+void MyFrame::editATAConfig (int channel)
|
|
{
|
|
- CdromConfigDialog dlg (this, -1);
|
|
- dlg.SetDriveName (BX_CDROM_NAME);
|
|
- bx_param_filename_c *fname =
|
|
- (bx_param_filename_c*) SIM->get_param(BXP_CDROM_PATH);
|
|
- bx_param_bool_c *present =
|
|
- (bx_param_bool_c*) SIM->get_param(BXP_CDROM_PRESENT);
|
|
- bx_param_enum_c *status =
|
|
- (bx_param_enum_c*) SIM->get_param(BXP_CDROM_STATUS);
|
|
- wxASSERT (fname->get_type () == BXT_PARAM_STRING
|
|
- && present->get_type () == BXT_PARAM_BOOL
|
|
- && status->get_type () == BXT_PARAM_ENUM);
|
|
-#if defined(__linux__)
|
|
- dlg.AddRadio ("Physical CD-ROM drive /dev/cdrom", "/dev/cdrom");
|
|
-#elif defined (WIN32)
|
|
- dlg.AddRadio ("Physical CD-ROM drive D:", "D:");
|
|
-#else
|
|
- // add your favorite operating system here
|
|
-#endif
|
|
- dlg.SetEnable (present->get () ? TRUE : FALSE);
|
|
- dlg.SetFilename (fname->getptr ());
|
|
- dlg.SetEjected (status->get () == BX_EJECTED);
|
|
- int n = dlg.ShowModal ();
|
|
- wxLogMessage ("cdrom config returned %d", n);
|
|
- if (n==wxID_OK) {
|
|
- char filename[1024];
|
|
- wxString fn (dlg.GetFilename ());
|
|
- strncpy (filename, fn.c_str (), sizeof(filename));
|
|
- fname->set (filename);
|
|
- present->set (dlg.GetEnable ());
|
|
- status->set (dlg.GetEjected () ? BX_EJECTED : BX_INSERTED);
|
|
- wxLogMessage ("filename is '%s'", filename);
|
|
- wxLogMessage ("enabled=%d ejected=%d", present->get(), status->get());
|
|
- // cdrom and hard disk D cannot both be enabled.
|
|
- if (present->get ()) {
|
|
- bx_param_bool_c *diskd = (bx_param_bool_c*)
|
|
- SIM->get_param(BXP_DISKD_PRESENT);
|
|
- if (diskd->get ()) {
|
|
- wxString msg;
|
|
- msg.Printf ("You cannot have both %s and %s enabled. Disabling %s.",
|
|
- BX_CDROM_NAME, BX_HARD_DISK1_NAME, BX_HARD_DISK1_NAME);
|
|
- wxMessageBox( msg, "Device conflict", wxOK | wxICON_ERROR );
|
|
- diskd->set (0);
|
|
- }
|
|
- }
|
|
- }
|
|
+ ParamDialog dlg (this, -1);
|
|
+ dlg.SetTitle ("Configure ATA0");
|
|
+ dlg.AddParam (SIM->get_param ((bx_id)(BXP_ATA0+channel)));
|
|
+ dlg.AddParam (SIM->get_param ((bx_id)(BXP_ATA0_MASTER+channel*2)));
|
|
+ dlg.AddParam (SIM->get_param ((bx_id)(BXP_ATA0_SLAVE+channel*2)));
|
|
+ dlg.ShowModal ();
|
|
}
|
|
|
|
void MyFrame::OnToolbarClick(wxCommandEvent& event)
|
|
Index: iodev/harddrv.cc
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/iodev/harddrv.cc,v
|
|
retrieving revision 1.72
|
|
diff -u -r1.72 harddrv.cc
|
|
--- iodev/harddrv.cc 16 Sep 2002 16:58:36 -0000 1.72
|
|
+++ iodev/harddrv.cc 22 Sep 2002 20:46:16 -0000
|
|
@@ -56,76 +56,99 @@
|
|
#endif
|
|
|
|
|
|
-static unsigned char model_no[41] =
|
|
- "Generic 1234 ";
|
|
-
|
|
static unsigned max_multiple_sectors = 0; // was 0x3f
|
|
static unsigned curr_multiple_sectors = 0; // was 0x3f
|
|
|
|
// some packet handling macros
|
|
#define EXTRACT_FIELD(arr,byte,start,num_bits) (((arr)[(byte)] >> (start)) & ((1 << (num_bits)) - 1))
|
|
-#define get_packet_field(b,s,n) (EXTRACT_FIELD((BX_SELECTED_CONTROLLER.buffer),(b),(s),(n)))
|
|
-#define get_packet_byte(b) (BX_SELECTED_CONTROLLER.buffer[(b)])
|
|
-#define get_packet_word(b) (((uint16)BX_SELECTED_CONTROLLER.buffer[(b)] << 8) | BX_SELECTED_CONTROLLER.buffer[(b)+1])
|
|
-
|
|
-
|
|
-#define BX_CONTROLLER(a) (BX_HD_THIS s[(a)]).controller
|
|
-#define BX_SELECTED_CONTROLLER (BX_CONTROLLER(BX_HD_THIS drive_select))
|
|
-
|
|
-#define WRITE_FEATURES(a) do { uint8 _a = a; BX_CONTROLLER(0).features = _a; BX_CONTROLLER(1).features = _a; } while(0)
|
|
-#define WRITE_SECTOR_COUNT(a) do { uint8 _a = a; BX_CONTROLLER(0).sector_count = _a; BX_CONTROLLER(1).sector_count = _a; } while(0)
|
|
-#define WRITE_SECTOR_NUMBER(a) do { uint8 _a = a; BX_CONTROLLER(0).sector_no = _a; BX_CONTROLLER(1).sector_no = _a; } while(0)
|
|
-#define WRITE_CYLINDER_LOW(a) do { uint8 _a = a; BX_CONTROLLER(0).cylinder_no = (BX_CONTROLLER(0).cylinder_no & 0xff00) | _a; BX_CONTROLLER(1).cylinder_no = (BX_CONTROLLER(1).cylinder_no & 0xff00) | _a; } while(0)
|
|
-#define WRITE_CYLINDER_HIGH(a) do { uint16 _a = a; BX_CONTROLLER(0).cylinder_no = (_a << 8) | (BX_CONTROLLER(0).cylinder_no & 0xff); BX_CONTROLLER(1).cylinder_no = (_a << 8) | (BX_CONTROLLER(1).cylinder_no & 0xff); } while(0)
|
|
-#define WRITE_HEAD_NO(a) do { uint8 _a = a; BX_CONTROLLER(0).head_no = _a; BX_CONTROLLER(1).head_no = _a; } while(0)
|
|
-#define WRITE_LBA_MODE(a) do { uint8 _a = a; BX_CONTROLLER(0).lba_mode = _a; BX_CONTROLLER(1).lba_mode = _a; } while(0)
|
|
+#define get_packet_field(c,b,s,n) (EXTRACT_FIELD((BX_SELECTED_CONTROLLER((c)).buffer),(b),(s),(n)))
|
|
+#define get_packet_byte(c,b) (BX_SELECTED_CONTROLLER((c)).buffer[(b)])
|
|
+#define get_packet_word(c,b) (((uint16)BX_SELECTED_CONTROLLER((c)).buffer[(b)] << 8) | BX_SELECTED_CONTROLLER((c)).buffer[(b)+1])
|
|
+
|
|
+
|
|
+#define BX_CONTROLLER(c,a) (BX_HD_THIS channels[(c)].drives[(a)]).controller
|
|
+#define BX_DRIVE(c,a) (BX_HD_THIS channels[(c)].drives[(a)])
|
|
+
|
|
+#define BX_DRIVE_IS_PRESENT(c,a) (BX_HD_THIS channels[(c)].drives[(a)].device_type != IDE_NONE)
|
|
+#define BX_DRIVE_IS_HD(c,a) (BX_HD_THIS channels[(c)].drives[(a)].device_type == IDE_DISK)
|
|
+#define BX_DRIVE_IS_CD(c,a) (BX_HD_THIS channels[(c)].drives[(a)].device_type == IDE_CDROM)
|
|
+
|
|
+#define BX_MASTER_IS_PRESENT(c) BX_DRIVE_IS_PRESENT((c),0)
|
|
+#define BX_SLAVE_IS_PRESENT(c) BX_DRIVE_IS_PRESENT((c),1)
|
|
+
|
|
+#define BX_SELECTED_CONTROLLER(c) (BX_CONTROLLER((c),BX_HD_THIS channels[(c)].drive_select))
|
|
+#define BX_SELECTED_DRIVE(c) (BX_DRIVE((c),BX_HD_THIS channels[(c)].drive_select))
|
|
+#define BX_MASTER_SELECTED(c) (!BX_HD_THIS channels[(c)].drive_select)
|
|
+#define BX_SLAVE_SELECTED(c) (BX_HD_THIS channels[(c)].drive_select)
|
|
+
|
|
+#define BX_SELECTED_IS_PRESENT(c) (BX_DRIVE_IS_PRESENT((c),BX_SLAVE_SELECTED((c))))
|
|
+#define BX_SELECTED_IS_HD(c) (BX_DRIVE_IS_HD((c),BX_SLAVE_SELECTED((c))))
|
|
+#define BX_SELECTED_IS_CD(c) (BX_DRIVE_IS_CD((c),BX_SLAVE_SELECTED((c))))
|
|
+
|
|
+#define BX_SELECTED_MODEL(c) (BX_HD_THIS channels[(c)].drives[BX_HD_THIS channels[(c)].drive_select].model_no)
|
|
+#define BX_SELECTED_TYPE_STRING(channel) ((BX_SELECTED_IS_CD(channel)) ? "CD-ROM" : "DISK")
|
|
+
|
|
+#define WRITE_FEATURES(c,a) do { uint8 _a = a; BX_CONTROLLER((c),0).features = _a; BX_CONTROLLER((c),1).features = _a; } while(0)
|
|
+#define WRITE_SECTOR_COUNT(c,a) do { uint8 _a = a; BX_CONTROLLER((c),0).sector_count = _a; BX_CONTROLLER((c),1).sector_count = _a; } while(0)
|
|
+#define WRITE_SECTOR_NUMBER(c,a) do { uint8 _a = a; BX_CONTROLLER((c),0).sector_no = _a; BX_CONTROLLER((c),1).sector_no = _a; } while(0)
|
|
+#define WRITE_CYLINDER_LOW(c,a) do { uint8 _a = a; BX_CONTROLLER((c),0).cylinder_no = (BX_CONTROLLER((c),0).cylinder_no & 0xff00) | _a; BX_CONTROLLER((c),1).cylinder_no = (BX_CONTROLLER((c),1).cylinder_no & 0xff00) | _a; } while(0)
|
|
+#define WRITE_CYLINDER_HIGH(c,a) do { uint16 _a = a; BX_CONTROLLER((c),0).cylinder_no = (_a << 8) | (BX_CONTROLLER((c),0).cylinder_no & 0xff); BX_CONTROLLER((c),1).cylinder_no = (_a << 8) | (BX_CONTROLLER((c),1).cylinder_no & 0xff); } while(0)
|
|
+#define WRITE_HEAD_NO(c,a) do { uint8 _a = a; BX_CONTROLLER((c),0).head_no = _a; BX_CONTROLLER((c),1).head_no = _a; } while(0)
|
|
+#define WRITE_LBA_MODE(c,a) do { uint8 _a = a; BX_CONTROLLER((c),0).lba_mode = _a; BX_CONTROLLER((c),1).lba_mode = _a; } while(0)
|
|
|
|
|
|
//static unsigned im_here = 0;
|
|
|
|
bx_hard_drive_c::bx_hard_drive_c(void)
|
|
{
|
|
- s[0].hard_drive = NULL;
|
|
- s[1].hard_drive = NULL;
|
|
+#if DLL_HD_SUPPORT
|
|
+# error code must be fixed to use DLL_HD_SUPPORT and 4 ata channels
|
|
+#endif
|
|
+
|
|
+ for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
|
|
+ channels[channel].drives[0].hard_drive = NULL;
|
|
+ channels[channel].drives[1].hard_drive = NULL;
|
|
put("HD");
|
|
settype(HDLOG);
|
|
#if EXTERNAL_DISK_SIMULATOR
|
|
- s[0].hard_drive = new EXTERNAL_DISK_SIMULATOR_CLASS();
|
|
- s[1].hard_drive = new EXTERNAL_DISK_SIMULATOR_CLASS();
|
|
+ channels[channel].drives[0].hard_drive = new EXTERNAL_DISK_SIMULATOR_CLASS();
|
|
+ channels[channel].drives[1].hard_drive = new EXTERNAL_DISK_SIMULATOR_CLASS();
|
|
#else
|
|
|
|
#if BX_SPLIT_HD_SUPPORT
|
|
// use new concatenated image object
|
|
- s[0].hard_drive = new concat_image_t();
|
|
+ channels[channel].drives[0].hard_drive = new concat_image_t();
|
|
#if DLL_HD_SUPPORT
|
|
- s[1].hard_drive = new dll_image_t();
|
|
+ channels[channel].drives[1].hard_drive = new dll_image_t();
|
|
#else
|
|
- s[1].hard_drive = new concat_image_t();
|
|
+ channels[channel].drives[1].hard_drive = new concat_image_t();
|
|
#endif
|
|
#else
|
|
- s[0].hard_drive = new default_image_t();
|
|
+ channels[channel].drives[0].hard_drive = new default_image_t();
|
|
#if DLL_HD_SUPPORT
|
|
- s[1].hard_drive = new dll_image_t();
|
|
+ channels[channel].drives[1].hard_drive = new dll_image_t();
|
|
#else
|
|
- s[1].hard_drive = new default_image_t();
|
|
+ channels[channel].drives[1].hard_drive = new default_image_t();
|
|
#endif
|
|
#endif
|
|
-
|
|
#endif
|
|
+ }
|
|
}
|
|
|
|
bx_hard_drive_c::~bx_hard_drive_c(void)
|
|
{
|
|
BX_DEBUG(("Exit."));
|
|
- if ( s[0].hard_drive != NULL ) /* DT 17.12.2001 21:55 */
|
|
- {
|
|
- delete s[0].hard_drive;
|
|
- s[0].hard_drive = NULL;
|
|
- }
|
|
- if ( s[1].hard_drive != NULL )
|
|
- {
|
|
- delete s[1].hard_drive;
|
|
- s[1].hard_drive = NULL; /* DT 17.12.2001 21:56 */
|
|
+ for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
|
|
+ if (channels[channel].drives[0].hard_drive != NULL ) /* DT 17.12.2001 21:55 */
|
|
+ {
|
|
+ delete channels[channel].drives[0].hard_drive;
|
|
+ channels[channel].drives[0].hard_drive = NULL;
|
|
+ }
|
|
+ if ( channels[channel].drives[1].hard_drive != NULL )
|
|
+ {
|
|
+ delete channels[channel].drives[1].hard_drive;
|
|
+ channels[channel].drives[1].hard_drive = NULL; /* DT 17.12.2001 21:56 */
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -135,166 +158,230 @@
|
|
void
|
|
bx_hard_drive_c::init(bx_devices_c *d, bx_cmos_c *cmos)
|
|
{
|
|
+ Bit8u channel;
|
|
+ char string[5];
|
|
+
|
|
BX_HD_THIS devices = d;
|
|
BX_DEBUG(("Init $Id: harddrv.cc,v 1.72 2002/09/16 16:58:36 bdenney Exp $"));
|
|
|
|
- /* HARD DRIVE 0 */
|
|
+ for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
|
|
+ if (bx_options.ata[channel].Opresent->get() == 1) {
|
|
+ BX_HD_THIS channels[channel].ioaddr1 = bx_options.ata[channel].Oioaddr1->get();
|
|
+ BX_HD_THIS channels[channel].ioaddr2 = bx_options.ata[channel].Oioaddr2->get();
|
|
+ BX_HD_THIS channels[channel].irq = bx_options.ata[channel].Oirq->get();
|
|
+
|
|
+ // Coherency check
|
|
+ if ( (BX_HD_THIS channels[channel].ioaddr1 == 0) ||
|
|
+ (BX_HD_THIS channels[channel].ioaddr2 == 0) ||
|
|
+ (BX_HD_THIS channels[channel].irq == 0) ) {
|
|
+ BX_PANIC(("incoherency for ata channel %d: io1=0x%x, io2=%x, irq=%d",
|
|
+ channel,
|
|
+ BX_HD_THIS channels[channel].ioaddr1,
|
|
+ BX_HD_THIS channels[channel].ioaddr2,
|
|
+ BX_HD_THIS channels[channel].irq));
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ BX_HD_THIS channels[channel].ioaddr1 = 0;
|
|
+ BX_HD_THIS channels[channel].ioaddr2 = 0;
|
|
+ BX_HD_THIS channels[channel].irq = 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
|
|
+ sprintf(string ,"ATA%d", channel);
|
|
|
|
- BX_HD_THIS devices->register_irq(14, "Hard Drive 0");
|
|
- for (unsigned addr=0x01F0; addr<=0x01F7; addr++) {
|
|
- BX_HD_THIS devices->register_io_read_handler(this, read_handler,
|
|
- addr, "Hard Drive 0");
|
|
- BX_HD_THIS devices->register_io_write_handler(this, write_handler,
|
|
- addr, "Hard Drive 0");
|
|
- }
|
|
-#if 0
|
|
- // this would be necessary to make the second HD master on the
|
|
- // second controller, using 0x170-0x177 and irq15. But it currently
|
|
- // works as second disk on the first IDE controller, so this code
|
|
- // is not needed.
|
|
- BX_HD_THIS devices->register_irq(15, "Hard Drive 1");
|
|
- for (unsigned addr=0x0170; addr<=0x0177; addr++) {
|
|
- BX_HD_THIS devices->register_io_read_handler(this, read_handler,
|
|
- addr, "Hard Drive 1");
|
|
- BX_HD_THIS devices->register_io_write_handler(this, write_handler,
|
|
- addr, "Hard Drive 1");
|
|
+ if (BX_HD_THIS channels[channel].irq != 0)
|
|
+ BX_HD_THIS devices->register_irq(BX_HD_THIS channels[channel].irq, strdup(string));
|
|
+
|
|
+ if (BX_HD_THIS channels[channel].ioaddr1 != 0) {
|
|
+ for (unsigned addr=0x0; addr<=0x7; addr++) {
|
|
+ BX_HD_THIS devices->register_io_read_handler(this, read_handler,
|
|
+ BX_HD_THIS channels[channel].ioaddr1+addr, strdup(string));
|
|
+ BX_HD_THIS devices->register_io_write_handler(this, write_handler,
|
|
+ BX_HD_THIS channels[channel].ioaddr1+addr, strdup(string));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // We don't want to register addresses 0x3f6 and 0x3f7 as they are handled by the floppy controller
|
|
+ if ((BX_HD_THIS channels[channel].ioaddr2 != 0) && (BX_HD_THIS channels[channel].ioaddr2 != 0x3f0)) {
|
|
+ for (unsigned addr=0x6; addr<=0x7; addr++) {
|
|
+ BX_HD_THIS devices->register_io_read_handler(this, read_handler,
|
|
+ BX_HD_THIS channels[channel].ioaddr2+addr, strdup(string));
|
|
+ BX_HD_THIS devices->register_io_write_handler(this, write_handler,
|
|
+ BX_HD_THIS channels[channel].ioaddr2+addr, strdup(string));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ BX_HD_THIS channels[channel].drive_select = 0;
|
|
}
|
|
-#endif
|
|
|
|
- BX_HD_THIS drive_select = 0;
|
|
-
|
|
- BX_HD_THIS s[0].hard_drive->cylinders = bx_options.diskc.Ocylinders->get ();
|
|
- BX_HD_THIS s[0].hard_drive->heads = bx_options.diskc.Oheads->get ();
|
|
- BX_HD_THIS s[0].hard_drive->sectors = bx_options.diskc.Ospt->get ();
|
|
- BX_HD_THIS s[0].device_type = IDE_DISK;
|
|
- BX_HD_THIS s[1].hard_drive->cylinders = bx_options.diskd.Ocylinders->get ();
|
|
- BX_HD_THIS s[1].hard_drive->heads = bx_options.diskd.Oheads->get ();
|
|
- BX_HD_THIS s[1].hard_drive->sectors = bx_options.diskd.Ospt->get ();
|
|
- BX_HD_THIS s[1].device_type = IDE_DISK;
|
|
-
|
|
- if (bx_options.cdromd.Opresent->get ()) {
|
|
- bx_options.diskd.Opresent->set (1);
|
|
- BX_DEBUG(( "Experimental CDROM on target 1" ));
|
|
- BX_HD_THIS s[1].device_type = IDE_CDROM;
|
|
- BX_HD_THIS s[1].cdrom.locked = 0;
|
|
- BX_HD_THIS s[1].sense.sense_key = SENSE_NONE;
|
|
- BX_HD_THIS s[1].sense.asc = 0;
|
|
- BX_HD_THIS s[1].sense.ascq = 0;
|
|
- // Check bit fields
|
|
- BX_CONTROLLER(1).sector_count = 0;
|
|
- BX_CONTROLLER(1).interrupt_reason.c_d = 1;
|
|
- if (BX_CONTROLLER(1).sector_count != 0x01)
|
|
- BX_PANIC(("interrupt reason bit field error"));
|
|
+ channel = 0;
|
|
+ for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
|
|
+ for (Bit8u device=0; device<2; device ++) {
|
|
+
|
|
+ // If not present
|
|
+ BX_HD_THIS channels[channel].drives[device].device_type = IDE_NONE;
|
|
+ if (!bx_options.atadevice[channel][device].Opresent->get()) {
|
|
+ continue;
|
|
+ }
|
|
|
|
- BX_CONTROLLER(1).sector_count = 0;
|
|
- BX_CONTROLLER(1).interrupt_reason.i_o = 1;
|
|
- if (BX_CONTROLLER(1).sector_count != 0x02)
|
|
- BX_PANIC(("interrupt reason bit field error"));
|
|
+ // Make model string
|
|
+ strncpy((char*)BX_HD_THIS channels[channel].drives[device].model_no,
|
|
+ bx_options.atadevice[channel][device].Omodel->getptr(), 40);
|
|
+ while (strlen((char *)BX_HD_THIS channels[channel].drives[device].model_no) < 40) {
|
|
+ strcat ((char*)BX_HD_THIS channels[channel].drives[device].model_no, " ");
|
|
+ }
|
|
|
|
- BX_CONTROLLER(1).sector_count = 0;
|
|
- BX_CONTROLLER(1).interrupt_reason.rel = 1;
|
|
- if (BX_CONTROLLER(1).sector_count != 0x04)
|
|
+ if (bx_options.atadevice[channel][device].Otype->get() == BX_ATA_DEVICE_DISK) {
|
|
+ BX_DEBUG(( "Hard-Disk on target %d/%d",channel,device));
|
|
+ BX_HD_THIS channels[channel].drives[device].device_type = IDE_DISK;
|
|
+ BX_HD_THIS channels[channel].drives[device].hard_drive->cylinders = bx_options.atadevice[channel][device].Ocylinders->get ();
|
|
+ BX_HD_THIS channels[channel].drives[device].hard_drive->heads = bx_options.atadevice[channel][device].Oheads->get ();
|
|
+ BX_HD_THIS channels[channel].drives[device].hard_drive->sectors = bx_options.atadevice[channel][device].Ospt->get ();
|
|
+
|
|
+ /* open hard drive image file */
|
|
+ if ((BX_HD_THIS channels[channel].drives[device].hard_drive->open(bx_options.atadevice[channel][device].Opath->getptr ())) < 0) {
|
|
+ BX_PANIC(("could not open hard drive image file '%s'", bx_options.atadevice[channel][device].Opath->getptr ()));
|
|
+ }
|
|
+ BX_INFO(("HD on ata%d-%d: '%s'",channel, device, bx_options.atadevice[channel][device].Opath->getptr ()));
|
|
+ }
|
|
+ else if (bx_options.atadevice[channel][device].Otype->get() == BX_ATA_DEVICE_CDROM) {
|
|
+ BX_DEBUG(( "CDROM on target %d/%d",channel,device));
|
|
+ BX_HD_THIS channels[channel].drives[device].device_type = IDE_CDROM;
|
|
+ BX_HD_THIS channels[channel].drives[device].cdrom.locked = 0;
|
|
+ BX_HD_THIS channels[channel].drives[device].sense.sense_key = SENSE_NONE;
|
|
+ BX_HD_THIS channels[channel].drives[device].sense.asc = 0;
|
|
+ BX_HD_THIS channels[channel].drives[device].sense.ascq = 0;
|
|
+
|
|
+ // Check bit fields
|
|
+ BX_CONTROLLER(channel,device).sector_count = 0;
|
|
+ BX_CONTROLLER(channel,device).interrupt_reason.c_d = 1;
|
|
+ if (BX_CONTROLLER(channel,device).sector_count != 0x01)
|
|
+ BX_PANIC(("interrupt reason bit field error"));
|
|
+
|
|
+ BX_CONTROLLER(channel,device).sector_count = 0;
|
|
+ BX_CONTROLLER(channel,device).interrupt_reason.i_o = 1;
|
|
+ if (BX_CONTROLLER(channel,device).sector_count != 0x02)
|
|
+ BX_PANIC(("interrupt reason bit field error"));
|
|
+
|
|
+ BX_CONTROLLER(channel,device).sector_count = 0;
|
|
+ BX_CONTROLLER(channel,device).interrupt_reason.rel = 1;
|
|
+ if (BX_CONTROLLER(channel,device).sector_count != 0x04)
|
|
BX_PANIC(("interrupt reason bit field error"));
|
|
|
|
- BX_CONTROLLER(1).sector_count = 0;
|
|
- BX_CONTROLLER(1).interrupt_reason.tag = 3;
|
|
- if (BX_CONTROLLER(1).sector_count != 0x18)
|
|
+ BX_CONTROLLER(channel,device).sector_count = 0;
|
|
+ BX_CONTROLLER(channel,device).interrupt_reason.tag = 3;
|
|
+ if (BX_CONTROLLER(channel,device).sector_count != 0x18)
|
|
BX_PANIC(("interrupt reason bit field error"));
|
|
- BX_CONTROLLER(1).sector_count = 0;
|
|
+ BX_CONTROLLER(channel,device).sector_count = 0;
|
|
|
|
// allocate low level driver
|
|
#ifdef LOWLEVEL_CDROM
|
|
- BX_HD_THIS s[1].cdrom.cd = new LOWLEVEL_CDROM(bx_options.cdromd.Opath->getptr ());
|
|
-#endif
|
|
+ BX_HD_THIS channels[channel].drives[device].cdrom.cd = new LOWLEVEL_CDROM(bx_options.atadevice[channel][device].Opath->getptr ());
|
|
+ BX_INFO(("CD on ata%d-%d: '%s'",channel, device, bx_options.atadevice[channel][device].Opath->getptr ()));
|
|
|
|
-#ifdef LOWLEVEL_CDROM
|
|
- if (bx_options.cdromd.Ostatus->get () == BX_INSERTED) {
|
|
- if (BX_HD_THIS s[1].cdrom.cd->insert_cdrom()) {
|
|
+ if (bx_options.atadevice[channel][device].Ostatus->get () == BX_INSERTED) {
|
|
+ if (BX_HD_THIS channels[channel].drives[device].cdrom.cd->insert_cdrom()) {
|
|
BX_INFO(( "Media present in CD-ROM drive"));
|
|
- BX_HD_THIS s[1].cdrom.ready = 1;
|
|
- BX_HD_THIS s[1].cdrom.capacity = BX_HD_THIS s[1].cdrom.cd->capacity();
|
|
+ BX_HD_THIS channels[channel].drives[device].cdrom.ready = 1;
|
|
+ BX_HD_THIS channels[channel].drives[device].cdrom.capacity = BX_HD_THIS channels[channel].drives[device].cdrom.cd->capacity();
|
|
} else {
|
|
BX_INFO(( "Could not locate CD-ROM, continuing with media not present"));
|
|
- BX_HD_THIS s[1].cdrom.ready = 0;
|
|
- bx_options.cdromd.Ostatus->set(BX_EJECTED);
|
|
+ BX_HD_THIS channels[channel].drives[device].cdrom.ready = 0;
|
|
+ bx_options.atadevice[channel][device].Ostatus->set(BX_EJECTED);
|
|
}
|
|
} else {
|
|
#endif
|
|
BX_INFO(( "Media not present in CD-ROM drive" ));
|
|
- BX_HD_THIS s[1].cdrom.ready = 0;
|
|
+ BX_HD_THIS channels[channel].drives[device].cdrom.ready = 0;
|
|
#ifdef LOWLEVEL_CDROM
|
|
}
|
|
#endif
|
|
- }
|
|
+ }
|
|
|
|
- /* open hard drive image file */
|
|
- if (bx_options.diskc.Opresent->get ()) {
|
|
- if ((BX_HD_THIS s[0].hard_drive->open(bx_options.diskc.Opath->getptr ())) < 0) {
|
|
- BX_PANIC(("could not open hard drive image file '%s'",
|
|
- bx_options.diskc.Opath->getptr ()));
|
|
- }
|
|
- BX_INFO(("hd0: '%s'",bx_options.diskc.Opath->getptr ()));
|
|
- }
|
|
- if (bx_options.diskd.Opresent->get () && !bx_options.cdromd.Opresent->get ()) {
|
|
- if ((BX_HD_THIS s[1].hard_drive->open(bx_options.diskd.Opath->getptr ())) < 0) {
|
|
- BX_PANIC(("could not open hard drive image file '%s'",
|
|
- bx_options.diskd.Opath->getptr ()));
|
|
- }
|
|
- BX_INFO(("hd1: '%s'",bx_options.diskd.Opath->getptr()));
|
|
+ BX_CONTROLLER(channel,device).status.busy = 0;
|
|
+ BX_CONTROLLER(channel,device).status.drive_ready = 1;
|
|
+ BX_CONTROLLER(channel,device).status.write_fault = 0;
|
|
+ BX_CONTROLLER(channel,device).status.seek_complete = 1;
|
|
+ BX_CONTROLLER(channel,device).status.drq = 0;
|
|
+ BX_CONTROLLER(channel,device).status.corrected_data = 0;
|
|
+ BX_CONTROLLER(channel,device).status.index_pulse = 0;
|
|
+ BX_CONTROLLER(channel,device).status.index_pulse_count = 0;
|
|
+ BX_CONTROLLER(channel,device).status.err = 0;
|
|
+
|
|
+ BX_CONTROLLER(channel,device).error_register = 0x01; // diagnostic code: no error
|
|
+ BX_CONTROLLER(channel,device).head_no = 0;
|
|
+ BX_CONTROLLER(channel,device).sector_count = 1;
|
|
+ BX_CONTROLLER(channel,device).sector_no = 1;
|
|
+ BX_CONTROLLER(channel,device).cylinder_no = 0;
|
|
+ BX_CONTROLLER(channel,device).current_command = 0x00;
|
|
+ BX_CONTROLLER(channel,device).buffer_index = 0;
|
|
+
|
|
+ BX_CONTROLLER(channel,device).control.reset = 0;
|
|
+ BX_CONTROLLER(channel,device).control.disable_irq = 0;
|
|
+
|
|
+ BX_CONTROLLER(channel,device).reset_in_progress = 0;
|
|
+
|
|
+ BX_CONTROLLER(channel,device).sectors_per_block = 0x80;
|
|
+ BX_CONTROLLER(channel,device).lba_mode = 0;
|
|
+
|
|
+ BX_CONTROLLER(channel,device).features = 0;
|
|
+ }
|
|
}
|
|
|
|
// generate CMOS values for hard drive if not using a CMOS image
|
|
if (!bx_options.cmos.OcmosImage->get ()) {
|
|
cmos->s.reg[0x12] = 0x00; // start out with: no drive 0, no drive 1
|
|
|
|
- if (bx_options.diskc.Opresent->get ()) {
|
|
+ if (BX_DRIVE_IS_HD(0,0)) {
|
|
// Flag drive type as Fh, use extended CMOS location as real type
|
|
cmos->s.reg[0x12] = (cmos->s.reg[0x12] & 0x0f) | 0xf0;
|
|
cmos->s.reg[0x19] = 47; // user definable type
|
|
// AMI BIOS: 1st hard disk #cyl low byte
|
|
- cmos->s.reg[0x1b] = (bx_options.diskc.Ocylinders->get () & 0x00ff);
|
|
+ cmos->s.reg[0x1b] = (bx_options.atadevice[0][0].Ocylinders->get () & 0x00ff);
|
|
// AMI BIOS: 1st hard disk #cyl high byte
|
|
- cmos->s.reg[0x1c] = (bx_options.diskc.Ocylinders->get () & 0xff00) >> 8;
|
|
+ cmos->s.reg[0x1c] = (bx_options.atadevice[0][0].Ocylinders->get () & 0xff00) >> 8;
|
|
// AMI BIOS: 1st hard disk #heads
|
|
- cmos->s.reg[0x1d] = (bx_options.diskc.Oheads->get ());
|
|
+ cmos->s.reg[0x1d] = (bx_options.atadevice[0][0].Oheads->get ());
|
|
// AMI BIOS: 1st hard disk write precompensation cylinder, low byte
|
|
cmos->s.reg[0x1e] = 0xff; // -1
|
|
// AMI BIOS: 1st hard disk write precompensation cylinder, high byte
|
|
cmos->s.reg[0x1f] = 0xff; // -1
|
|
// AMI BIOS: 1st hard disk control byte
|
|
- cmos->s.reg[0x20] = 0xc0 | ((bx_options.diskc.Oheads->get () > 8) << 3);
|
|
+ cmos->s.reg[0x20] = 0xc0 | ((bx_options.atadevice[0][0].Oheads->get () > 8) << 3);
|
|
// AMI BIOS: 1st hard disk landing zone, low byte
|
|
cmos->s.reg[0x21] = cmos->s.reg[0x1b];
|
|
// AMI BIOS: 1st hard disk landing zone, high byte
|
|
cmos->s.reg[0x22] = cmos->s.reg[0x1c];
|
|
// AMI BIOS: 1st hard disk sectors/track
|
|
- cmos->s.reg[0x23] = bx_options.diskc.Ospt->get ();
|
|
+ cmos->s.reg[0x23] = bx_options.atadevice[0][0].Ospt->get ();
|
|
}
|
|
|
|
//set up cmos for second hard drive
|
|
- if (bx_options.diskd.Opresent->get () && !bx_options.cdromd.Opresent->get ()) {
|
|
+ if (BX_DRIVE_IS_HD(0,1)) {
|
|
BX_DEBUG(("1: I will put 0xf into the second hard disk field"));
|
|
// fill in lower 4 bits of 0x12 for second HD
|
|
cmos->s.reg[0x12] = (cmos->s.reg[0x12] & 0xf0) | 0x0f;
|
|
cmos->s.reg[0x1a] = 47; // user definable type
|
|
// AMI BIOS: 2nd hard disk #cyl low byte
|
|
- cmos->s.reg[0x24] = (bx_options.diskd.Ocylinders->get () & 0x00ff);
|
|
+ cmos->s.reg[0x24] = (bx_options.atadevice[0][1].Ocylinders->get () & 0x00ff);
|
|
// AMI BIOS: 2nd hard disk #cyl high byte
|
|
- cmos->s.reg[0x25] = (bx_options.diskd.Ocylinders->get () & 0xff00) >> 8;
|
|
+ cmos->s.reg[0x25] = (bx_options.atadevice[0][1].Ocylinders->get () & 0xff00) >> 8;
|
|
// AMI BIOS: 2nd hard disk #heads
|
|
- cmos->s.reg[0x26] = (bx_options.diskd.Oheads->get ());
|
|
+ cmos->s.reg[0x26] = (bx_options.atadevice[0][1].Oheads->get ());
|
|
// AMI BIOS: 2nd hard disk write precompensation cylinder, low byte
|
|
cmos->s.reg[0x27] = 0xff; // -1
|
|
// AMI BIOS: 2nd hard disk write precompensation cylinder, high byte
|
|
cmos->s.reg[0x28] = 0xff; // -1
|
|
// AMI BIOS: 2nd hard disk, 0x80 if heads>8
|
|
- cmos->s.reg[0x29] = (bx_options.diskd.Oheads->get () > 8) ? 0x80 : 0x00;
|
|
+ cmos->s.reg[0x29] = (bx_options.atadevice[0][1].Oheads->get () > 8) ? 0x80 : 0x00;
|
|
// AMI BIOS: 2nd hard disk landing zone, low byte
|
|
cmos->s.reg[0x2a] = cmos->s.reg[0x24];
|
|
// AMI BIOS: 2nd hard disk landing zone, high byte
|
|
cmos->s.reg[0x2b] = cmos->s.reg[0x25];
|
|
// AMI BIOS: 2nd hard disk sectors/track
|
|
- cmos->s.reg[0x2c] = bx_options.diskd.Ospt->get ();
|
|
+ cmos->s.reg[0x2c] = bx_options.atadevice[0][1].Ospt->get ();
|
|
}
|
|
|
|
|
|
@@ -330,38 +417,6 @@
|
|
BX_INFO(("Floppy boot signature check is %sabled", bx_options.OfloppySigCheck->get() ? "dis" : "en"));
|
|
}
|
|
|
|
- //switch (stat_buf.st_size) {
|
|
- // }
|
|
-
|
|
- for (int id = 0; id < 2; id++) {
|
|
- BX_CONTROLLER(id).status.busy = 0;
|
|
- BX_CONTROLLER(id).status.drive_ready = 1;
|
|
- BX_CONTROLLER(id).status.write_fault = 0;
|
|
- BX_CONTROLLER(id).status.seek_complete = 1;
|
|
- BX_CONTROLLER(id).status.drq = 0;
|
|
- BX_CONTROLLER(id).status.corrected_data = 0;
|
|
- BX_CONTROLLER(id).status.index_pulse = 0;
|
|
- BX_CONTROLLER(id).status.index_pulse_count = 0;
|
|
- BX_CONTROLLER(id).status.err = 0;
|
|
-
|
|
- BX_CONTROLLER(id).error_register = 0x01; // diagnostic code: no error
|
|
- BX_CONTROLLER(id).head_no = 0;
|
|
- BX_CONTROLLER(id).sector_count = 1;
|
|
- BX_CONTROLLER(id).sector_no = 1;
|
|
- BX_CONTROLLER(id).cylinder_no = 0;
|
|
- BX_CONTROLLER(id).current_command = 0x00;
|
|
- BX_CONTROLLER(id).buffer_index = 0;
|
|
-
|
|
- BX_CONTROLLER(id).control.reset = 0;
|
|
- BX_CONTROLLER(id).control.disable_irq = 0;
|
|
-
|
|
- BX_CONTROLLER(id).reset_in_progress = 0;
|
|
-
|
|
- BX_CONTROLLER(id).sectors_per_block = 0x80;
|
|
- BX_CONTROLLER(id).lba_mode = 0;
|
|
-
|
|
- BX_CONTROLLER(id).features = 0;
|
|
- }
|
|
}
|
|
|
|
void
|
|
@@ -406,27 +461,47 @@
|
|
Bit16u value16;
|
|
Bit32u value32;
|
|
|
|
- if (io_len>1 && address!=0x1f0) {
|
|
+ Bit8u channel = BX_MAX_ATA_CHANNEL;
|
|
+ Bit32u port;
|
|
+
|
|
+ for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
|
|
+ if ((address >= BX_HD_THIS channels[channel].ioaddr1)
|
|
+ && (address <= BX_HD_THIS channels[channel].ioaddr1 + 7) ) {
|
|
+ port = address - BX_HD_THIS channels[channel].ioaddr1;
|
|
+ break;
|
|
+ }
|
|
+ else if ((address >= BX_HD_THIS channels[channel].ioaddr2)
|
|
+ && (address <= BX_HD_THIS channels[channel].ioaddr2 + 7) ) {
|
|
+ port = address - BX_HD_THIS channels[channel].ioaddr2 + 0x10;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (channel == BX_MAX_ATA_CHANNEL) {
|
|
+ BX_PANIC(("Unable to find ATA channel, ioport=0x%04x", address));
|
|
+ }
|
|
+
|
|
+ if (io_len>1 && port!=0x00) {
|
|
BX_PANIC(("non-byte IO read to %04x", (unsigned) address));
|
|
}
|
|
|
|
- switch (address) {
|
|
- case 0x1f0: // hard disk data (16bit)
|
|
- if (BX_SELECTED_CONTROLLER.status.drq == 0) {
|
|
+ switch (port) {
|
|
+ case 0x00: // hard disk data (16bit) 0x1f0
|
|
+ if (BX_SELECTED_CONTROLLER(channel).status.drq == 0) {
|
|
BX_ERROR(("IO read(1f0h) with drq == 0: last command was %02xh",
|
|
- (unsigned) BX_SELECTED_CONTROLLER.current_command));
|
|
+ (unsigned) BX_SELECTED_CONTROLLER(channel).current_command));
|
|
return(0);
|
|
}
|
|
BX_DEBUG(("IO read(1f0h): current command is %02xh",
|
|
- (unsigned) BX_SELECTED_CONTROLLER.current_command));
|
|
- switch (BX_SELECTED_CONTROLLER.current_command) {
|
|
+ (unsigned) BX_SELECTED_CONTROLLER(channel).current_command));
|
|
+ switch (BX_SELECTED_CONTROLLER(channel).current_command) {
|
|
case 0x20: // READ SECTORS, with retries
|
|
case 0x21: // READ SECTORS, without retries
|
|
if (io_len == 1) {
|
|
BX_PANIC(("byte IO read from %04x",
|
|
(unsigned) address));
|
|
}
|
|
- if (BX_SELECTED_CONTROLLER.buffer_index >= 512)
|
|
+ if (BX_SELECTED_CONTROLLER(channel).buffer_index >= 512)
|
|
BX_PANIC(("IO read(1f0): buffer_index >= 512"));
|
|
|
|
#if BX_SupportRepeatSpeedups
|
|
@@ -455,70 +530,69 @@
|
|
value32 = 0L;
|
|
switch(io_len){
|
|
case 4:
|
|
- value32 |= (BX_SELECTED_CONTROLLER.buffer[BX_SELECTED_CONTROLLER.buffer_index+3] << 24);
|
|
- value32 |= (BX_SELECTED_CONTROLLER.buffer[BX_SELECTED_CONTROLLER.buffer_index+2] << 16);
|
|
+ value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+3] << 24);
|
|
+ value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+2] << 16);
|
|
case 2:
|
|
- value32 |= (BX_SELECTED_CONTROLLER.buffer[BX_SELECTED_CONTROLLER.buffer_index+1] << 8);
|
|
- value32 |= BX_SELECTED_CONTROLLER.buffer[BX_SELECTED_CONTROLLER.buffer_index];
|
|
+ value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+1] << 8);
|
|
+ value32 |= BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index];
|
|
}
|
|
-
|
|
- BX_SELECTED_CONTROLLER.buffer_index += io_len;
|
|
}
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index += io_len;
|
|
|
|
// if buffer completely read
|
|
- if (BX_SELECTED_CONTROLLER.buffer_index >= 512) {
|
|
+ if (BX_SELECTED_CONTROLLER(channel).buffer_index >= 512) {
|
|
// update sector count, sector number, cylinder,
|
|
// drive, head, status
|
|
// if there are more sectors, read next one in...
|
|
//
|
|
- BX_SELECTED_CONTROLLER.buffer_index = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
|
|
|
|
- increment_address();
|
|
+ increment_address(channel);
|
|
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.write_fault = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
|
|
if (bx_options.OnewHardDriveSupport->get ())
|
|
- BX_SELECTED_CONTROLLER.status.seek_complete = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
|
|
else
|
|
- BX_SELECTED_CONTROLLER.status.seek_complete = 0;
|
|
- BX_SELECTED_CONTROLLER.status.corrected_data = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.seek_complete = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
|
|
- if (BX_SELECTED_CONTROLLER.sector_count==0) {
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
+ if (BX_SELECTED_CONTROLLER(channel).sector_count==0) {
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
}
|
|
else { /* read next one into controller buffer */
|
|
Bit32u logical_sector;
|
|
int ret;
|
|
|
|
- BX_SELECTED_CONTROLLER.status.drq = 1;
|
|
- BX_SELECTED_CONTROLLER.status.seek_complete = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
|
|
|
|
#if TEST_READ_BEYOND_END==1
|
|
- BX_SELECTED_CONTROLLER.cylinder_no += 100000;
|
|
+ BX_SELECTED_CONTROLLER(channel).cylinder_no += 100000;
|
|
#endif
|
|
- if (!calculate_logical_address(&logical_sector)) {
|
|
+ if (!calculate_logical_address(channel, &logical_sector)) {
|
|
BX_ERROR(("multi-sector read reached invalid sector %u, aborting", logical_sector));
|
|
- command_aborted (BX_SELECTED_CONTROLLER.current_command);
|
|
+ command_aborted (channel, BX_SELECTED_CONTROLLER(channel).current_command);
|
|
GOTO_RETURN_VALUE ;
|
|
}
|
|
- ret = BX_SELECTED_HD.hard_drive->lseek(logical_sector * 512, SEEK_SET);
|
|
+ ret = BX_SELECTED_DRIVE(channel).hard_drive->lseek(logical_sector * 512, SEEK_SET);
|
|
if (ret < 0) {
|
|
BX_ERROR(("could not lseek() hard drive image file"));
|
|
- command_aborted (BX_SELECTED_CONTROLLER.current_command);
|
|
+ command_aborted (channel, BX_SELECTED_CONTROLLER(channel).current_command);
|
|
GOTO_RETURN_VALUE ;
|
|
}
|
|
- ret = BX_SELECTED_HD.hard_drive->read((bx_ptr_t) BX_SELECTED_CONTROLLER.buffer, 512);
|
|
+ ret = BX_SELECTED_DRIVE(channel).hard_drive->read((bx_ptr_t) BX_SELECTED_CONTROLLER(channel).buffer, 512);
|
|
if (ret < 512) {
|
|
BX_ERROR(("logical sector was %u", (unsigned) logical_sector));
|
|
BX_ERROR(("could not read() hard drive image file at byte %d", logical_sector*512));
|
|
- command_aborted (BX_SELECTED_CONTROLLER.current_command);
|
|
+ command_aborted (channel, BX_SELECTED_CONTROLLER(channel).current_command);
|
|
GOTO_RETURN_VALUE ;
|
|
}
|
|
|
|
- BX_SELECTED_CONTROLLER.buffer_index = 0;
|
|
- raise_interrupt();
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
|
|
+ raise_interrupt(channel);
|
|
}
|
|
}
|
|
GOTO_RETURN_VALUE ;
|
|
@@ -529,61 +603,61 @@
|
|
if (bx_options.OnewHardDriveSupport->get ()) {
|
|
unsigned index;
|
|
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.write_fault = 0;
|
|
- BX_SELECTED_CONTROLLER.status.seek_complete = 1;
|
|
- BX_SELECTED_CONTROLLER.status.corrected_data = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
|
|
- index = BX_SELECTED_CONTROLLER.buffer_index;
|
|
- value32 = BX_SELECTED_CONTROLLER.buffer[index];
|
|
+ index = BX_SELECTED_CONTROLLER(channel).buffer_index;
|
|
+ value32 = BX_SELECTED_CONTROLLER(channel).buffer[index];
|
|
index++;
|
|
if (io_len >= 2) {
|
|
- value32 |= (BX_SELECTED_CONTROLLER.buffer[index] << 8);
|
|
+ value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index] << 8);
|
|
index++;
|
|
}
|
|
if (io_len == 4) {
|
|
- value32 |= (BX_SELECTED_CONTROLLER.buffer[index] << 16);
|
|
- value32 |= (BX_SELECTED_CONTROLLER.buffer[index+1] << 24);
|
|
+ value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index] << 16);
|
|
+ value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index+1] << 24);
|
|
index += 2;
|
|
}
|
|
- BX_SELECTED_CONTROLLER.buffer_index = index;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index = index;
|
|
|
|
- if (BX_SELECTED_CONTROLLER.buffer_index >= 512) {
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- if (bx_dbg.disk || (CDROM_SELECTED && bx_dbg.cdrom))
|
|
+ if (BX_SELECTED_CONTROLLER(channel).buffer_index >= 512) {
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
|
|
BX_INFO(("Read all drive ID Bytes ..."));
|
|
}
|
|
GOTO_RETURN_VALUE;
|
|
}
|
|
else
|
|
BX_PANIC(("IO read(1f0h): current command is %02xh",
|
|
- (unsigned) BX_SELECTED_CONTROLLER.current_command));
|
|
+ (unsigned) BX_SELECTED_CONTROLLER(channel).current_command));
|
|
|
|
case 0xa0: {
|
|
- unsigned index = BX_SELECTED_CONTROLLER.buffer_index;
|
|
+ unsigned index = BX_SELECTED_CONTROLLER(channel).buffer_index;
|
|
unsigned increment = 0;
|
|
|
|
// Load block if necessary
|
|
if (index >= 2048) {
|
|
if (index > 2048)
|
|
BX_PANIC(("index > 2048 : 0x%x",index));
|
|
- switch (BX_SELECTED_HD.atapi.command) {
|
|
+ switch (BX_SELECTED_DRIVE(channel).atapi.command) {
|
|
case 0x28: // read (10)
|
|
case 0xa8: // read (12)
|
|
#ifdef LOWLEVEL_CDROM
|
|
- BX_SELECTED_HD.cdrom.cd->read_block(BX_SELECTED_CONTROLLER.buffer,
|
|
- BX_SELECTED_HD.cdrom.next_lba);
|
|
- BX_SELECTED_HD.cdrom.next_lba++;
|
|
- BX_SELECTED_HD.cdrom.remaining_blocks--;
|
|
+ BX_SELECTED_DRIVE(channel).cdrom.cd->read_block(BX_SELECTED_CONTROLLER(channel).buffer,
|
|
+ BX_SELECTED_DRIVE(channel).cdrom.next_lba);
|
|
+ BX_SELECTED_DRIVE(channel).cdrom.next_lba++;
|
|
+ BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks--;
|
|
|
|
- if (bx_dbg.disk || (CDROM_SELECTED && bx_dbg.cdrom))
|
|
- if (!BX_SELECTED_HD.cdrom.remaining_blocks)
|
|
+ if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
|
|
+ if (!BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks)
|
|
BX_INFO(("Last READ block loaded {CDROM}"));
|
|
else
|
|
BX_INFO(("READ block loaded (%d remaining) {CDROM}",
|
|
- BX_SELECTED_HD.cdrom.remaining_blocks));
|
|
+ BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks));
|
|
|
|
// one block transfered, start at beginning
|
|
index = 0;
|
|
@@ -597,55 +671,55 @@
|
|
}
|
|
}
|
|
|
|
- value32 = BX_SELECTED_CONTROLLER.buffer[index+increment];
|
|
+ value32 = BX_SELECTED_CONTROLLER(channel).buffer[index+increment];
|
|
increment++;
|
|
if (io_len >= 2) {
|
|
- value32 |= (BX_SELECTED_CONTROLLER.buffer[index+increment] << 8);
|
|
+ value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index+increment] << 8);
|
|
increment++;
|
|
}
|
|
if (io_len == 4) {
|
|
- value32 |= (BX_SELECTED_CONTROLLER.buffer[index+increment] << 16);
|
|
- value32 |= (BX_SELECTED_CONTROLLER.buffer[index+increment+1] << 24);
|
|
+ value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index+increment] << 16);
|
|
+ value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index+increment+1] << 24);
|
|
increment += 2;
|
|
}
|
|
- BX_SELECTED_CONTROLLER.buffer_index = index + increment;
|
|
- BX_SELECTED_CONTROLLER.drq_index += increment;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index = index + increment;
|
|
+ BX_SELECTED_CONTROLLER(channel).drq_index += increment;
|
|
|
|
- if (BX_SELECTED_CONTROLLER.drq_index >= (unsigned)BX_SELECTED_HD.atapi.drq_bytes) {
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- BX_SELECTED_CONTROLLER.drq_index = 0;
|
|
+ if (BX_SELECTED_CONTROLLER(channel).drq_index >= (unsigned)BX_SELECTED_DRIVE(channel).atapi.drq_bytes) {
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).drq_index = 0;
|
|
|
|
- BX_SELECTED_HD.atapi.total_bytes_remaining -= BX_SELECTED_HD.atapi.drq_bytes;
|
|
+ BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining -= BX_SELECTED_DRIVE(channel).atapi.drq_bytes;
|
|
|
|
- if (BX_SELECTED_HD.atapi.total_bytes_remaining > 0) {
|
|
+ if (BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining > 0) {
|
|
// one or more blocks remaining (works only for single block commands)
|
|
- if (bx_dbg.disk || (CDROM_SELECTED && bx_dbg.cdrom))
|
|
+ if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
|
|
BX_INFO(("PACKET drq bytes read"));
|
|
- BX_SELECTED_CONTROLLER.interrupt_reason.i_o = 1;
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 1;
|
|
- BX_SELECTED_CONTROLLER.interrupt_reason.c_d = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 0;
|
|
|
|
// set new byte count if last block
|
|
- if (BX_SELECTED_HD.atapi.total_bytes_remaining < BX_SELECTED_CONTROLLER.byte_count) {
|
|
- BX_SELECTED_CONTROLLER.byte_count = BX_SELECTED_HD.atapi.total_bytes_remaining;
|
|
+ if (BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining < BX_SELECTED_CONTROLLER(channel).byte_count) {
|
|
+ BX_SELECTED_CONTROLLER(channel).byte_count = BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining;
|
|
}
|
|
- BX_SELECTED_HD.atapi.drq_bytes = BX_SELECTED_CONTROLLER.byte_count;
|
|
+ BX_SELECTED_DRIVE(channel).atapi.drq_bytes = BX_SELECTED_CONTROLLER(channel).byte_count;
|
|
|
|
- raise_interrupt();
|
|
+ raise_interrupt(channel);
|
|
} else {
|
|
// all bytes read
|
|
- if (bx_dbg.disk || (CDROM_SELECTED && bx_dbg.cdrom))
|
|
+ if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
|
|
BX_INFO(("PACKET all bytes read"));
|
|
- BX_SELECTED_CONTROLLER.interrupt_reason.i_o = 1;
|
|
- BX_SELECTED_CONTROLLER.interrupt_reason.c_d = 1;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.interrupt_reason.rel = 0;
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
|
|
- raise_interrupt();
|
|
+ raise_interrupt(channel);
|
|
}
|
|
}
|
|
GOTO_RETURN_VALUE;
|
|
@@ -655,111 +729,111 @@
|
|
// List all the read operations that are defined in the ATA/ATAPI spec
|
|
// that we don't support. Commands that are listed here will cause a
|
|
// BX_ERROR, which is non-fatal, and the command will be aborted.
|
|
- case 0x08: BX_ERROR(("read cmd 0x08 (DEVICE RESET) not supported")); command_aborted(0x08); break;
|
|
- case 0x10: BX_ERROR(("read cmd 0x10 (RECALIBRATE) not supported")); command_aborted(0x10); break;
|
|
- case 0x22: BX_ERROR(("read cmd 0x22 (READ LONG) not supported")); command_aborted(0x22); break;
|
|
- case 0x23: BX_ERROR(("read cmd 0x23 (READ LONG NO RETRY) not supported")); command_aborted(0x23); break;
|
|
- case 0x24: BX_ERROR(("read cmd 0x24 (READ SECTORS EXT) not supported")); command_aborted(0x24); break;
|
|
- case 0x25: BX_ERROR(("read cmd 0x25 (READ DMA EXT) not supported")); command_aborted(0x25); break;
|
|
- case 0x26: BX_ERROR(("read cmd 0x26 (READ DMA QUEUED EXT) not supported")); command_aborted(0x26); break;
|
|
- case 0x27: BX_ERROR(("read cmd 0x27 (READ NATIVE MAX ADDRESS EXT) not supported")); command_aborted(0x27); break;
|
|
- case 0x29: BX_ERROR(("read cmd 0x29 (READ MULTIPLE EXT) not supported")); command_aborted(0x29); break;
|
|
- case 0x2A: BX_ERROR(("read cmd 0x2A (READ STREAM DMA) not supported")); command_aborted(0x2A); break;
|
|
- case 0x2B: BX_ERROR(("read cmd 0x2B (READ STREAM PIO) not supported")); command_aborted(0x2B); break;
|
|
- case 0x2F: BX_ERROR(("read cmd 0x2F (READ LOG EXT) not supported")); command_aborted(0x2F); break;
|
|
- case 0x30: BX_ERROR(("read cmd 0x30 (WRITE SECTORS) not supported")); command_aborted(0x30); break;
|
|
- case 0x31: BX_ERROR(("read cmd 0x31 (WRITE SECTORS NO RETRY) not supported")); command_aborted(0x31); break;
|
|
- case 0x32: BX_ERROR(("read cmd 0x32 (WRITE LONG) not supported")); command_aborted(0x32); break;
|
|
- case 0x33: BX_ERROR(("read cmd 0x33 (WRITE LONG NO RETRY) not supported")); command_aborted(0x33); break;
|
|
- case 0x34: BX_ERROR(("read cmd 0x34 (WRITE SECTORS EXT) not supported")); command_aborted(0x34); break;
|
|
- case 0x35: BX_ERROR(("read cmd 0x35 (WRITE DMA EXT) not supported")); command_aborted(0x35); break;
|
|
- case 0x36: BX_ERROR(("read cmd 0x36 (WRITE DMA QUEUED EXT) not supported")); command_aborted(0x36); break;
|
|
- case 0x37: BX_ERROR(("read cmd 0x37 (SET MAX ADDRESS EXT) not supported")); command_aborted(0x37); break;
|
|
- case 0x38: BX_ERROR(("read cmd 0x38 (CFA WRITE SECTORS W/OUT ERASE) not supported")); command_aborted(0x38); break;
|
|
- case 0x39: BX_ERROR(("read cmd 0x39 (WRITE MULTIPLE EXT) not supported")); command_aborted(0x39); break;
|
|
- case 0x3A: BX_ERROR(("read cmd 0x3A (WRITE STREAM DMA) not supported")); command_aborted(0x3A); break;
|
|
- case 0x3B: BX_ERROR(("read cmd 0x3B (WRITE STREAM PIO) not supported")); command_aborted(0x3B); break;
|
|
- case 0x3F: BX_ERROR(("read cmd 0x3F (WRITE LOG EXT) not supported")); command_aborted(0x3F); break;
|
|
- case 0x40: BX_ERROR(("read cmd 0x40 (READ VERIFY SECTORS) not supported")); command_aborted(0x40); break;
|
|
- case 0x41: BX_ERROR(("read cmd 0x41 (READ VERIFY SECTORS NO RETRY) not supported")); command_aborted(0x41); break;
|
|
- case 0x42: BX_ERROR(("read cmd 0x42 (READ VERIFY SECTORS EXT) not supported")); command_aborted(0x42); break;
|
|
- case 0x50: BX_ERROR(("read cmd 0x50 (FORMAT TRACK) not supported")); command_aborted(0x50); break;
|
|
- case 0x51: BX_ERROR(("read cmd 0x51 (CONFIGURE STREAM) not supported")); command_aborted(0x51); break;
|
|
- case 0x70: BX_ERROR(("read cmd 0x70 (SEEK) not supported")); command_aborted(0x70); break;
|
|
- case 0x87: BX_ERROR(("read cmd 0x87 (CFA TRANSLATE SECTOR) not supported")); command_aborted(0x87); break;
|
|
- case 0x90: BX_ERROR(("read cmd 0x90 (EXECUTE DEVICE DIAGNOSTIC) not supported")); command_aborted(0x90); break;
|
|
- case 0x91: BX_ERROR(("read cmd 0x91 (INITIALIZE DEVICE PARAMETERS) not supported")); command_aborted(0x91); break;
|
|
- case 0x92: BX_ERROR(("read cmd 0x92 (DOWNLOAD MICROCODE) not supported")); command_aborted(0x92); break;
|
|
- case 0x94: BX_ERROR(("read cmd 0x94 (STANDBY IMMEDIATE) not supported")); command_aborted(0x94); break;
|
|
- case 0x95: BX_ERROR(("read cmd 0x95 (IDLE IMMEDIATE) not supported")); command_aborted(0x95); break;
|
|
- case 0x96: BX_ERROR(("read cmd 0x96 (STANDBY) not supported")); command_aborted(0x96); break;
|
|
- case 0x97: BX_ERROR(("read cmd 0x97 (IDLE) not supported")); command_aborted(0x97); break;
|
|
- case 0x98: BX_ERROR(("read cmd 0x98 (CHECK POWER MODE) not supported")); command_aborted(0x98); break;
|
|
- case 0x99: BX_ERROR(("read cmd 0x99 (SLEEP) not supported")); command_aborted(0x99); break;
|
|
- case 0xA2: BX_ERROR(("read cmd 0xA2 (SERVICE) not supported")); command_aborted(0xA2); break;
|
|
- case 0xB0: BX_ERROR(("read cmd 0xB0 (SMART DISABLE OPERATIONS) not supported")); command_aborted(0xB0); break;
|
|
- case 0xB1: BX_ERROR(("read cmd 0xB1 (DEVICE CONFIGURATION FREEZE LOCK) not supported")); command_aborted(0xB1); break;
|
|
- case 0xC0: BX_ERROR(("read cmd 0xC0 (CFA ERASE SECTORS) not supported")); command_aborted(0xC0); break;
|
|
- case 0xC4: BX_ERROR(("read cmd 0xC4 (READ MULTIPLE) not supported")); command_aborted(0xC4); break;
|
|
- case 0xC5: BX_ERROR(("read cmd 0xC5 (WRITE MULTIPLE) not supported")); command_aborted(0xC5); break;
|
|
- case 0xC6: BX_ERROR(("read cmd 0xC6 (SET MULTIPLE MODE) not supported")); command_aborted(0xC6); break;
|
|
- case 0xC7: BX_ERROR(("read cmd 0xC7 (READ DMA QUEUED) not supported")); command_aborted(0xC7); break;
|
|
- case 0xC8: BX_ERROR(("read cmd 0xC8 (READ DMA) not supported")); command_aborted(0xC8); break;
|
|
- case 0xC9: BX_ERROR(("read cmd 0xC9 (READ DMA NO RETRY) not supported")); command_aborted(0xC9); break;
|
|
- case 0xCA: BX_ERROR(("read cmd 0xCA (WRITE DMA) not supported")); command_aborted(0xCA); break;
|
|
- case 0xCC: BX_ERROR(("read cmd 0xCC (WRITE DMA QUEUED) not supported")); command_aborted(0xCC); break;
|
|
- case 0xCD: BX_ERROR(("read cmd 0xCD (CFA WRITE MULTIPLE W/OUT ERASE) not supported")); command_aborted(0xCD); break;
|
|
- case 0xD1: BX_ERROR(("read cmd 0xD1 (CHECK MEDIA CARD TYPE) not supported")); command_aborted(0xD1); break;
|
|
- case 0xDA: BX_ERROR(("read cmd 0xDA (GET MEDIA STATUS) not supported")); command_aborted(0xDA); break;
|
|
- case 0xDE: BX_ERROR(("read cmd 0xDE (MEDIA LOCK) not supported")); command_aborted(0xDE); break;
|
|
- case 0xDF: BX_ERROR(("read cmd 0xDF (MEDIA UNLOCK) not supported")); command_aborted(0xDF); break;
|
|
- case 0xE0: BX_ERROR(("read cmd 0xE0 (STANDBY IMMEDIATE) not supported")); command_aborted(0xE0); break;
|
|
- case 0xE1: BX_ERROR(("read cmd 0xE1 (IDLE IMMEDIATE) not supported")); command_aborted(0xE1); break;
|
|
- case 0xE2: BX_ERROR(("read cmd 0xE2 (STANDBY) not supported")); command_aborted(0xE2); break;
|
|
- case 0xE3: BX_ERROR(("read cmd 0xE3 (IDLE) not supported")); command_aborted(0xE3); break;
|
|
- case 0xE4: BX_ERROR(("read cmd 0xE4 (READ BUFFER) not supported")); command_aborted(0xE4); break;
|
|
- case 0xE5: BX_ERROR(("read cmd 0xE5 (CHECK POWER MODE) not supported")); command_aborted(0xE5); break;
|
|
- case 0xE6: BX_ERROR(("read cmd 0xE6 (SLEEP) not supported")); command_aborted(0xE6); break;
|
|
- case 0xE7: BX_ERROR(("read cmd 0xE7 (FLUSH CACHE) not supported")); command_aborted(0xE7); break;
|
|
- case 0xE8: BX_ERROR(("read cmd 0xE8 (WRITE BUFFER) not supported")); command_aborted(0xE8); break;
|
|
- case 0xEA: BX_ERROR(("read cmd 0xEA (FLUSH CACHE EXT) not supported")); command_aborted(0xEA); break;
|
|
- case 0xED: BX_ERROR(("read cmd 0xED (MEDIA EJECT) not supported")); command_aborted(0xED); break;
|
|
- case 0xEF: BX_ERROR(("read cmd 0xEF (SET FEATURES) not supported")); command_aborted(0xEF); break;
|
|
- case 0xF1: BX_ERROR(("read cmd 0xF1 (SECURITY SET PASSWORD) not supported")); command_aborted(0xF1); break;
|
|
- case 0xF2: BX_ERROR(("read cmd 0xF2 (SECURITY UNLOCK) not supported")); command_aborted(0xF2); break;
|
|
- case 0xF3: BX_ERROR(("read cmd 0xF3 (SECURITY ERASE PREPARE) not supported")); command_aborted(0xF3); break;
|
|
- case 0xF4: BX_ERROR(("read cmd 0xF4 (SECURITY ERASE UNIT) not supported")); command_aborted(0xF4); break;
|
|
- case 0xF5: BX_ERROR(("read cmd 0xF5 (SECURITY FREEZE LOCK) not supported")); command_aborted(0xF5); break;
|
|
- case 0xF6: BX_ERROR(("read cmd 0xF6 (SECURITY DISABLE PASSWORD) not supported")); command_aborted(0xF6); break;
|
|
- case 0xF8: BX_ERROR(("read cmd 0xF8 (READ NATIVE MAX ADDRESS) not supported")); command_aborted(0xF8); break;
|
|
- case 0xF9: BX_ERROR(("read cmd 0xF9 (SET MAX ADDRESS) not supported")); command_aborted(0xF9); break;
|
|
+ case 0x08: BX_ERROR(("read cmd 0x08 (DEVICE RESET) not supported")); command_aborted(channel, 0x08); break;
|
|
+ case 0x10: BX_ERROR(("read cmd 0x10 (RECALIBRATE) not supported")); command_aborted(channel, 0x10); break;
|
|
+ case 0x22: BX_ERROR(("read cmd 0x22 (READ LONG) not supported")); command_aborted(channel, 0x22); break;
|
|
+ case 0x23: BX_ERROR(("read cmd 0x23 (READ LONG NO RETRY) not supported")); command_aborted(channel, 0x23); break;
|
|
+ case 0x24: BX_ERROR(("read cmd 0x24 (READ SECTORS EXT) not supported")); command_aborted(channel, 0x24); break;
|
|
+ case 0x25: BX_ERROR(("read cmd 0x25 (READ DMA EXT) not supported")); command_aborted(channel, 0x25); break;
|
|
+ case 0x26: BX_ERROR(("read cmd 0x26 (READ DMA QUEUED EXT) not supported")); command_aborted(channel, 0x26); break;
|
|
+ case 0x27: BX_ERROR(("read cmd 0x27 (READ NATIVE MAX ADDRESS EXT) not supported")); command_aborted(channel, 0x27); break;
|
|
+ case 0x29: BX_ERROR(("read cmd 0x29 (READ MULTIPLE EXT) not supported")); command_aborted(channel, 0x29); break;
|
|
+ case 0x2A: BX_ERROR(("read cmd 0x2A (READ STREAM DMA) not supported")); command_aborted(channel, 0x2A); break;
|
|
+ case 0x2B: BX_ERROR(("read cmd 0x2B (READ STREAM PIO) not supported")); command_aborted(channel, 0x2B); break;
|
|
+ case 0x2F: BX_ERROR(("read cmd 0x2F (READ LOG EXT) not supported")); command_aborted(channel, 0x2F); break;
|
|
+ case 0x30: BX_ERROR(("read cmd 0x30 (WRITE SECTORS) not supported")); command_aborted(channel, 0x30); break;
|
|
+ case 0x31: BX_ERROR(("read cmd 0x31 (WRITE SECTORS NO RETRY) not supported")); command_aborted(channel, 0x31); break;
|
|
+ case 0x32: BX_ERROR(("read cmd 0x32 (WRITE LONG) not supported")); command_aborted(channel, 0x32); break;
|
|
+ case 0x33: BX_ERROR(("read cmd 0x33 (WRITE LONG NO RETRY) not supported")); command_aborted(channel, 0x33); break;
|
|
+ case 0x34: BX_ERROR(("read cmd 0x34 (WRITE SECTORS EXT) not supported")); command_aborted(channel, 0x34); break;
|
|
+ case 0x35: BX_ERROR(("read cmd 0x35 (WRITE DMA EXT) not supported")); command_aborted(channel, 0x35); break;
|
|
+ case 0x36: BX_ERROR(("read cmd 0x36 (WRITE DMA QUEUED EXT) not supported")); command_aborted(channel, 0x36); break;
|
|
+ case 0x37: BX_ERROR(("read cmd 0x37 (SET MAX ADDRESS EXT) not supported")); command_aborted(channel, 0x37); break;
|
|
+ case 0x38: BX_ERROR(("read cmd 0x38 (CFA WRITE SECTORS W/OUT ERASE) not supported")); command_aborted(channel, 0x38); break;
|
|
+ case 0x39: BX_ERROR(("read cmd 0x39 (WRITE MULTIPLE EXT) not supported")); command_aborted(channel, 0x39); break;
|
|
+ case 0x3A: BX_ERROR(("read cmd 0x3A (WRITE STREAM DMA) not supported")); command_aborted(channel, 0x3A); break;
|
|
+ case 0x3B: BX_ERROR(("read cmd 0x3B (WRITE STREAM PIO) not supported")); command_aborted(channel, 0x3B); break;
|
|
+ case 0x3F: BX_ERROR(("read cmd 0x3F (WRITE LOG EXT) not supported")); command_aborted(channel, 0x3F); break;
|
|
+ case 0x40: BX_ERROR(("read cmd 0x40 (READ VERIFY SECTORS) not supported")); command_aborted(channel, 0x40); break;
|
|
+ case 0x41: BX_ERROR(("read cmd 0x41 (READ VERIFY SECTORS NO RETRY) not supported")); command_aborted(channel, 0x41); break;
|
|
+ case 0x42: BX_ERROR(("read cmd 0x42 (READ VERIFY SECTORS EXT) not supported")); command_aborted(channel, 0x42); break;
|
|
+ case 0x50: BX_ERROR(("read cmd 0x50 (FORMAT TRACK) not supported")); command_aborted(channel, 0x50); break;
|
|
+ case 0x51: BX_ERROR(("read cmd 0x51 (CONFIGURE STREAM) not supported")); command_aborted(channel, 0x51); break;
|
|
+ case 0x70: BX_ERROR(("read cmd 0x70 (SEEK) not supported")); command_aborted(channel, 0x70); break;
|
|
+ case 0x87: BX_ERROR(("read cmd 0x87 (CFA TRANSLATE SECTOR) not supported")); command_aborted(channel, 0x87); break;
|
|
+ case 0x90: BX_ERROR(("read cmd 0x90 (EXECUTE DEVICE DIAGNOSTIC) not supported")); command_aborted(channel, 0x90); break;
|
|
+ case 0x91: BX_ERROR(("read cmd 0x91 (INITIALIZE DEVICE PARAMETERS) not supported")); command_aborted(channel, 0x91); break;
|
|
+ case 0x92: BX_ERROR(("read cmd 0x92 (DOWNLOAD MICROCODE) not supported")); command_aborted(channel, 0x92); break;
|
|
+ case 0x94: BX_ERROR(("read cmd 0x94 (STANDBY IMMEDIATE) not supported")); command_aborted(channel, 0x94); break;
|
|
+ case 0x95: BX_ERROR(("read cmd 0x95 (IDLE IMMEDIATE) not supported")); command_aborted(channel, 0x95); break;
|
|
+ case 0x96: BX_ERROR(("read cmd 0x96 (STANDBY) not supported")); command_aborted(channel, 0x96); break;
|
|
+ case 0x97: BX_ERROR(("read cmd 0x97 (IDLE) not supported")); command_aborted(channel, 0x97); break;
|
|
+ case 0x98: BX_ERROR(("read cmd 0x98 (CHECK POWER MODE) not supported")); command_aborted(channel, 0x98); break;
|
|
+ case 0x99: BX_ERROR(("read cmd 0x99 (SLEEP) not supported")); command_aborted(channel, 0x99); break;
|
|
+ case 0xA2: BX_ERROR(("read cmd 0xA2 (SERVICE) not supported")); command_aborted(channel, 0xA2); break;
|
|
+ case 0xB0: BX_ERROR(("read cmd 0xB0 (SMART DISABLE OPERATIONS) not supported")); command_aborted(channel, 0xB0); break;
|
|
+ case 0xB1: BX_ERROR(("read cmd 0xB1 (DEVICE CONFIGURATION FREEZE LOCK) not supported")); command_aborted(channel, 0xB1); break;
|
|
+ case 0xC0: BX_ERROR(("read cmd 0xC0 (CFA ERASE SECTORS) not supported")); command_aborted(channel, 0xC0); break;
|
|
+ case 0xC4: BX_ERROR(("read cmd 0xC4 (READ MULTIPLE) not supported")); command_aborted(channel, 0xC4); break;
|
|
+ case 0xC5: BX_ERROR(("read cmd 0xC5 (WRITE MULTIPLE) not supported")); command_aborted(channel, 0xC5); break;
|
|
+ case 0xC6: BX_ERROR(("read cmd 0xC6 (SET MULTIPLE MODE) not supported")); command_aborted(channel, 0xC6); break;
|
|
+ case 0xC7: BX_ERROR(("read cmd 0xC7 (READ DMA QUEUED) not supported")); command_aborted(channel, 0xC7); break;
|
|
+ case 0xC8: BX_ERROR(("read cmd 0xC8 (READ DMA) not supported")); command_aborted(channel, 0xC8); break;
|
|
+ case 0xC9: BX_ERROR(("read cmd 0xC9 (READ DMA NO RETRY) not supported")); command_aborted(channel, 0xC9); break;
|
|
+ case 0xCA: BX_ERROR(("read cmd 0xCA (WRITE DMA) not supported")); command_aborted(channel, 0xCA); break;
|
|
+ case 0xCC: BX_ERROR(("read cmd 0xCC (WRITE DMA QUEUED) not supported")); command_aborted(channel, 0xCC); break;
|
|
+ case 0xCD: BX_ERROR(("read cmd 0xCD (CFA WRITE MULTIPLE W/OUT ERASE) not supported")); command_aborted(channel, 0xCD); break;
|
|
+ case 0xD1: BX_ERROR(("read cmd 0xD1 (CHECK MEDIA CARD TYPE) not supported")); command_aborted(channel, 0xD1); break;
|
|
+ case 0xDA: BX_ERROR(("read cmd 0xDA (GET MEDIA STATUS) not supported")); command_aborted(channel, 0xDA); break;
|
|
+ case 0xDE: BX_ERROR(("read cmd 0xDE (MEDIA LOCK) not supported")); command_aborted(channel, 0xDE); break;
|
|
+ case 0xDF: BX_ERROR(("read cmd 0xDF (MEDIA UNLOCK) not supported")); command_aborted(channel, 0xDF); break;
|
|
+ case 0xE0: BX_ERROR(("read cmd 0xE0 (STANDBY IMMEDIATE) not supported")); command_aborted(channel, 0xE0); break;
|
|
+ case 0xE1: BX_ERROR(("read cmd 0xE1 (IDLE IMMEDIATE) not supported")); command_aborted(channel, 0xE1); break;
|
|
+ case 0xE2: BX_ERROR(("read cmd 0xE2 (STANDBY) not supported")); command_aborted(channel, 0xE2); break;
|
|
+ case 0xE3: BX_ERROR(("read cmd 0xE3 (IDLE) not supported")); command_aborted(channel, 0xE3); break;
|
|
+ case 0xE4: BX_ERROR(("read cmd 0xE4 (READ BUFFER) not supported")); command_aborted(channel, 0xE4); break;
|
|
+ case 0xE5: BX_ERROR(("read cmd 0xE5 (CHECK POWER MODE) not supported")); command_aborted(channel, 0xE5); break;
|
|
+ case 0xE6: BX_ERROR(("read cmd 0xE6 (SLEEP) not supported")); command_aborted(channel, 0xE6); break;
|
|
+ case 0xE7: BX_ERROR(("read cmd 0xE7 (FLUSH CACHE) not supported")); command_aborted(channel, 0xE7); break;
|
|
+ case 0xE8: BX_ERROR(("read cmd 0xE8 (WRITE BUFFER) not supported")); command_aborted(channel, 0xE8); break;
|
|
+ case 0xEA: BX_ERROR(("read cmd 0xEA (FLUSH CACHE EXT) not supported")); command_aborted(channel, 0xEA); break;
|
|
+ case 0xED: BX_ERROR(("read cmd 0xED (MEDIA EJECT) not supported")); command_aborted(channel, 0xED); break;
|
|
+ case 0xEF: BX_ERROR(("read cmd 0xEF (SET FEATURES) not supported")); command_aborted(channel, 0xEF); break;
|
|
+ case 0xF1: BX_ERROR(("read cmd 0xF1 (SECURITY SET PASSWORD) not supported")); command_aborted(channel, 0xF1); break;
|
|
+ case 0xF2: BX_ERROR(("read cmd 0xF2 (SECURITY UNLOCK) not supported")); command_aborted(channel, 0xF2); break;
|
|
+ case 0xF3: BX_ERROR(("read cmd 0xF3 (SECURITY ERASE PREPARE) not supported")); command_aborted(channel, 0xF3); break;
|
|
+ case 0xF4: BX_ERROR(("read cmd 0xF4 (SECURITY ERASE UNIT) not supported")); command_aborted(channel, 0xF4); break;
|
|
+ case 0xF5: BX_ERROR(("read cmd 0xF5 (SECURITY FREEZE LOCK) not supported")); command_aborted(channel, 0xF5); break;
|
|
+ case 0xF6: BX_ERROR(("read cmd 0xF6 (SECURITY DISABLE PASSWORD) not supported")); command_aborted(channel, 0xF6); break;
|
|
+ case 0xF8: BX_ERROR(("read cmd 0xF8 (READ NATIVE MAX ADDRESS) not supported")); command_aborted(channel, 0xF8); break;
|
|
+ case 0xF9: BX_ERROR(("read cmd 0xF9 (SET MAX ADDRESS) not supported")); command_aborted(channel, 0xF9); break;
|
|
|
|
default:
|
|
BX_PANIC(("IO read(1f0h): current command is %02xh",
|
|
- (unsigned) BX_SELECTED_CONTROLLER.current_command));
|
|
+ (unsigned) BX_SELECTED_CONTROLLER(channel).current_command));
|
|
}
|
|
break;
|
|
|
|
- case 0x1f1: // hard disk error register
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
- value8 = BX_SELECTED_CONTROLLER.error_register;
|
|
+ case 0x01: // hard disk error register 0x1f1
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
+ value8 = (!BX_SELECTED_IS_PRESENT(channel)) ? 0 : BX_SELECTED_CONTROLLER(channel).error_register;
|
|
goto return_value8;
|
|
break;
|
|
- case 0x1f2: // hard disk sector count / interrupt reason
|
|
- value8 = BX_SELECTED_CONTROLLER.sector_count;
|
|
+ case 0x02: // hard disk sector count / interrupt reason 0x1f2
|
|
+ value8 = (!BX_SELECTED_IS_PRESENT(channel)) ? 0 : BX_SELECTED_CONTROLLER(channel).sector_count;
|
|
goto return_value8;
|
|
break;
|
|
- case 0x1f3: // sector number
|
|
- value8 = BX_SELECTED_CONTROLLER.sector_no;
|
|
+ case 0x03: // sector number 0x1f3
|
|
+ value8 = (!BX_SELECTED_IS_PRESENT(channel)) ? 0 : BX_SELECTED_CONTROLLER(channel).sector_no;
|
|
goto return_value8;
|
|
- case 0x1f4: // cylinder low
|
|
- value8 = (BX_SELECTED_CONTROLLER.cylinder_no & 0x00ff);
|
|
+ case 0x04: // cylinder low 0x1f4
|
|
+ value8 = (!BX_SELECTED_IS_PRESENT(channel)) ? 0 : (BX_SELECTED_CONTROLLER(channel).cylinder_no & 0x00ff);
|
|
goto return_value8;
|
|
- case 0x1f5: // cylinder high
|
|
- value8 = BX_SELECTED_CONTROLLER.cylinder_no >> 8;
|
|
+ case 0x05: // cylinder high 0x1f5
|
|
+ value8 = (!BX_SELECTED_IS_PRESENT(channel)) ? 0 : BX_SELECTED_CONTROLLER(channel).cylinder_no >> 8;
|
|
goto return_value8;
|
|
|
|
- case 0x1f6: // hard disk drive and head register
|
|
+ case 0x06: // hard disk drive and head register 0x1f6
|
|
// b7 Extended data field for ECC
|
|
// b6/b5: Used to be sector size. 00=256,01=512,10=1024,11=128
|
|
// Since 512 was always used, bit 6 was taken to mean LBA mode:
|
|
@@ -768,42 +842,41 @@
|
|
// b4: DRV
|
|
// b3..0 HD3..HD0
|
|
value8 = (1 << 7) |
|
|
- ((BX_SELECTED_CONTROLLER.lba_mode>0) << 6) |
|
|
+ ((BX_SELECTED_CONTROLLER(channel).lba_mode>0) << 6) |
|
|
(1 << 5) | // 01b = 512 sector size
|
|
- (BX_HD_THIS drive_select << 4) |
|
|
- (BX_SELECTED_CONTROLLER.head_no << 0);
|
|
+ (BX_HD_THIS channels[channel].drive_select << 4) |
|
|
+ (BX_SELECTED_CONTROLLER(channel).head_no << 0);
|
|
goto return_value8;
|
|
break;
|
|
-//BX_CONTROLLER(0).lba_mode
|
|
+//BX_CONTROLLER(channel,0).lba_mode
|
|
|
|
- case 0x1f7: // Hard Disk Status
|
|
- case 0x3f6: // Hard Disk Alternate Status
|
|
- if ((!BX_HD_THIS drive_select && !bx_options.diskc.Opresent->get ()) ||
|
|
- (BX_HD_THIS drive_select && !bx_options.diskd.Opresent->get ())) {
|
|
+ case 0x07: // Hard Disk Status 0x1f7
|
|
+ case 0x16: // Hard Disk Alternate Status 0x3f6
|
|
+ if (!BX_SELECTED_IS_PRESENT(channel)) {
|
|
// (mch) Just return zero for these registers
|
|
value8 = 0;
|
|
} else {
|
|
value8 = (
|
|
- (BX_SELECTED_CONTROLLER.status.busy << 7) |
|
|
- (BX_SELECTED_CONTROLLER.status.drive_ready << 6) |
|
|
- (BX_SELECTED_CONTROLLER.status.write_fault << 5) |
|
|
- (BX_SELECTED_CONTROLLER.status.seek_complete << 4) |
|
|
- (BX_SELECTED_CONTROLLER.status.drq << 3) |
|
|
- (BX_SELECTED_CONTROLLER.status.corrected_data << 2) |
|
|
- (BX_SELECTED_CONTROLLER.status.index_pulse << 1) |
|
|
- (BX_SELECTED_CONTROLLER.status.err) );
|
|
- BX_SELECTED_CONTROLLER.status.index_pulse_count++;
|
|
- BX_SELECTED_CONTROLLER.status.index_pulse = 0;
|
|
- if (BX_SELECTED_CONTROLLER.status.index_pulse_count >= INDEX_PULSE_CYCLE) {
|
|
- BX_SELECTED_CONTROLLER.status.index_pulse = 1;
|
|
- BX_SELECTED_CONTROLLER.status.index_pulse_count = 0;
|
|
+ (BX_SELECTED_CONTROLLER(channel).status.busy << 7) |
|
|
+ (BX_SELECTED_CONTROLLER(channel).status.drive_ready << 6) |
|
|
+ (BX_SELECTED_CONTROLLER(channel).status.write_fault << 5) |
|
|
+ (BX_SELECTED_CONTROLLER(channel).status.seek_complete << 4) |
|
|
+ (BX_SELECTED_CONTROLLER(channel).status.drq << 3) |
|
|
+ (BX_SELECTED_CONTROLLER(channel).status.corrected_data << 2) |
|
|
+ (BX_SELECTED_CONTROLLER(channel).status.index_pulse << 1) |
|
|
+ (BX_SELECTED_CONTROLLER(channel).status.err) );
|
|
+ BX_SELECTED_CONTROLLER(channel).status.index_pulse_count++;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.index_pulse = 0;
|
|
+ if (BX_SELECTED_CONTROLLER(channel).status.index_pulse_count >= INDEX_PULSE_CYCLE) {
|
|
+ BX_SELECTED_CONTROLLER(channel).status.index_pulse = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.index_pulse_count = 0;
|
|
}
|
|
}
|
|
- if (address == 0x1f7) BX_HD_THIS devices->pic->lower_irq(14);
|
|
+ if (port == 0x07) BX_HD_THIS devices->pic->lower_irq(BX_HD_THIS channels[channel].irq);
|
|
goto return_value8;
|
|
break;
|
|
|
|
- case 0x3f7: // Hard Disk Address Register
|
|
+ case 0x17: // Hard Disk Address Register 0x3f7
|
|
// Obsolete and unsupported register. Not driven by hard
|
|
// disk controller. Report all 1's. If floppy controller
|
|
// is handling this address, it will call this function
|
|
@@ -813,19 +886,6 @@
|
|
goto return_value8;
|
|
break;
|
|
|
|
-#if 0
|
|
- // you'll need these to support second IDE controller, not needed yet.
|
|
- case 0x170:
|
|
- case 0x171:
|
|
- case 0x172:
|
|
- case 0x173:
|
|
- case 0x174:
|
|
- case 0x175:
|
|
- case 0x176:
|
|
- case 0x177:
|
|
- BX_INFO(("[disk] ignoring read from 0x%04x", address));
|
|
- break;
|
|
-#endif
|
|
default:
|
|
BX_PANIC(("hard drive: io read to address %x unsupported",
|
|
(unsigned) address));
|
|
@@ -836,17 +896,17 @@
|
|
|
|
return_value32:
|
|
BX_DEBUG(("32-bit read from %04x = %08x {%s}",
|
|
- (unsigned) address, value32, DEVICE_TYPE_STRING));
|
|
+ (unsigned) address, value32, BX_SELECTED_TYPE_STRING(channel)));
|
|
return value32;
|
|
|
|
return_value16:
|
|
BX_DEBUG(("16-bit read from %04x = %04x {%s}",
|
|
- (unsigned) address, value16, DEVICE_TYPE_STRING));
|
|
+ (unsigned) address, value16, BX_SELECTED_TYPE_STRING(channel)));
|
|
return value16;
|
|
|
|
return_value8:
|
|
BX_DEBUG(("8-bit read from %04x = %02x {%s}",
|
|
- (unsigned) address, value8, DEVICE_TYPE_STRING));
|
|
+ (unsigned) address, value8, BX_SELECTED_TYPE_STRING(channel)));
|
|
return value8;
|
|
}
|
|
|
|
@@ -873,44 +933,64 @@
|
|
int ret;
|
|
Boolean prev_control_reset;
|
|
|
|
- if (io_len>1 && address!=0x1f0) {
|
|
+ Bit8u channel = BX_MAX_ATA_CHANNEL;
|
|
+ Bit32u port;
|
|
+
|
|
+ for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
|
|
+ if ((address >= BX_HD_THIS channels[channel].ioaddr1)
|
|
+ && (address <= BX_HD_THIS channels[channel].ioaddr1 + 7) ) {
|
|
+ port = address - BX_HD_THIS channels[channel].ioaddr1;
|
|
+ break;
|
|
+ }
|
|
+ else if ((address >= BX_HD_THIS channels[channel].ioaddr2)
|
|
+ && (address <= BX_HD_THIS channels[channel].ioaddr2 + 7) ) {
|
|
+ port = address - BX_HD_THIS channels[channel].ioaddr2 + 0x10;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (channel == BX_MAX_ATA_CHANNEL) {
|
|
+ BX_PANIC(("Unable to find ATA channel, ioport=0x%04x", address));
|
|
+ }
|
|
+
|
|
+ if (io_len>1 && port!=0x00) {
|
|
BX_PANIC(("non-byte IO write to %04x", (unsigned) address));
|
|
}
|
|
|
|
- if (bx_dbg.disk || (CDROM_SELECTED && bx_dbg.cdrom)) {
|
|
+ if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom)) {
|
|
switch (io_len) {
|
|
case 1:
|
|
BX_INFO(("8-bit write to %04x = %02x {%s}",
|
|
- (unsigned) address, (unsigned) value, DEVICE_TYPE_STRING));
|
|
+ (unsigned) address, (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
|
|
break;
|
|
|
|
case 2:
|
|
BX_INFO(("16-bit write to %04x = %04x {%s}",
|
|
- (unsigned) address, (unsigned) value, DEVICE_TYPE_STRING));
|
|
+ (unsigned) address, (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
|
|
break;
|
|
|
|
case 4:
|
|
BX_INFO(("32-bit write to %04x = %08x {%s}",
|
|
- (unsigned) address, (unsigned) value, DEVICE_TYPE_STRING));
|
|
+ (unsigned) address, (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
|
|
break;
|
|
|
|
default:
|
|
BX_INFO(("unknown-size write to %04x = %08x {%s}",
|
|
- (unsigned) address, (unsigned) value, DEVICE_TYPE_STRING));
|
|
+ (unsigned) address, (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
|
|
break;
|
|
}
|
|
}
|
|
|
|
BX_DEBUG(("IO write to %04x = %02x", (unsigned) address, (unsigned) value));
|
|
|
|
- switch (address) {
|
|
- case 0x1f0:
|
|
+ switch (port) {
|
|
+ case 0x00: // 0x1f0
|
|
if (io_len == 1) {
|
|
BX_PANIC(("byte IO write to 0x1f0"));
|
|
}
|
|
- switch (BX_SELECTED_CONTROLLER.current_command) {
|
|
+ switch (BX_SELECTED_CONTROLLER(channel).current_command) {
|
|
case 0x30: // WRITE SECTORS
|
|
- if (BX_SELECTED_CONTROLLER.buffer_index >= 512)
|
|
+ if (BX_SELECTED_CONTROLLER(channel).buffer_index >= 512)
|
|
BX_PANIC(("IO write(1f0): buffer_index >= 512"));
|
|
|
|
#if BX_SupportRepeatSpeedups
|
|
@@ -938,231 +1018,232 @@
|
|
{
|
|
switch(io_len){
|
|
case 4:
|
|
- BX_SELECTED_CONTROLLER.buffer[BX_SELECTED_CONTROLLER.buffer_index+3] = (Bit8u)(value >> 24);
|
|
- BX_SELECTED_CONTROLLER.buffer[BX_SELECTED_CONTROLLER.buffer_index+2] = (Bit8u)(value >> 16);
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+3] = (Bit8u)(value >> 24);
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+2] = (Bit8u)(value >> 16);
|
|
case 2:
|
|
- BX_SELECTED_CONTROLLER.buffer[BX_SELECTED_CONTROLLER.buffer_index+1] = (Bit8u)(value >> 8);
|
|
- BX_SELECTED_CONTROLLER.buffer[BX_SELECTED_CONTROLLER.buffer_index] = (Bit8u) value;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+1] = (Bit8u)(value >> 8);
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index] = (Bit8u) value;
|
|
}
|
|
|
|
- BX_SELECTED_CONTROLLER.buffer_index += io_len;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index += io_len;
|
|
}
|
|
|
|
/* if buffer completely writtten */
|
|
- if (BX_SELECTED_CONTROLLER.buffer_index >= 512) {
|
|
+ if (BX_SELECTED_CONTROLLER(channel).buffer_index >= 512) {
|
|
Bit32u logical_sector;
|
|
int ret;
|
|
|
|
#if TEST_WRITE_BEYOND_END==1
|
|
- BX_SELECTED_CONTROLLER.cylinder_no += 100000;
|
|
+ BX_SELECTED_CONTROLLER(channel).cylinder_no += 100000;
|
|
#endif
|
|
- if (!calculate_logical_address(&logical_sector)) {
|
|
+ if (!calculate_logical_address(channel, &logical_sector)) {
|
|
BX_ERROR(("write reached invalid sector %u, aborting", logical_sector));
|
|
- command_aborted (BX_SELECTED_CONTROLLER.current_command);
|
|
+ command_aborted (channel, BX_SELECTED_CONTROLLER(channel).current_command);
|
|
return;
|
|
}
|
|
#if TEST_WRITE_BEYOND_END==2
|
|
logical_sector += 100000;
|
|
#endif
|
|
- ret = BX_SELECTED_HD.hard_drive->lseek(logical_sector * 512, SEEK_SET);
|
|
+ ret = BX_SELECTED_DRIVE(channel).hard_drive->lseek(logical_sector * 512, SEEK_SET);
|
|
if (ret < 0) {
|
|
BX_ERROR(("could not lseek() hard drive image file at byte %u", logical_sector * 512));
|
|
- command_aborted (BX_SELECTED_CONTROLLER.current_command);
|
|
+ command_aborted (channel, BX_SELECTED_CONTROLLER(channel).current_command);
|
|
return;
|
|
}
|
|
- ret = BX_SELECTED_HD.hard_drive->write((bx_ptr_t) BX_SELECTED_CONTROLLER.buffer, 512);
|
|
+ ret = BX_SELECTED_DRIVE(channel).hard_drive->write((bx_ptr_t) BX_SELECTED_CONTROLLER(channel).buffer, 512);
|
|
if (ret < 512) {
|
|
BX_ERROR(("could not write() hard drive image file at byte %d", logical_sector*512));
|
|
- command_aborted (BX_SELECTED_CONTROLLER.current_command);
|
|
+ command_aborted (channel, BX_SELECTED_CONTROLLER(channel).current_command);
|
|
return;
|
|
}
|
|
|
|
- BX_SELECTED_CONTROLLER.buffer_index = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
|
|
|
|
/* update sector count, sector number, cylinder,
|
|
* drive, head, status
|
|
* if there are more sectors, read next one in...
|
|
*/
|
|
|
|
- increment_address();
|
|
+ increment_address(channel);
|
|
|
|
/* When the write is complete, controller clears the DRQ bit and
|
|
* sets the BSY bit.
|
|
* If at least one more sector is to be written, controller sets DRQ bit,
|
|
- * clears BSY bit, and issues IRQ 14
|
|
+ * clears BSY bit, and issues IRQ
|
|
*/
|
|
|
|
- if (BX_SELECTED_CONTROLLER.sector_count!=0) {
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 1;
|
|
- BX_SELECTED_CONTROLLER.status.corrected_data = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
+ if (BX_SELECTED_CONTROLLER(channel).sector_count!=0) {
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
}
|
|
else { /* no more sectors to write */
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
- BX_SELECTED_CONTROLLER.status.corrected_data = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
|
|
}
|
|
- raise_interrupt();
|
|
+ raise_interrupt(channel);
|
|
}
|
|
break;
|
|
|
|
case 0xa0: // PACKET
|
|
- if (BX_SELECTED_CONTROLLER.buffer_index >= PACKET_SIZE)
|
|
+ if (BX_SELECTED_CONTROLLER(channel).buffer_index >= PACKET_SIZE)
|
|
BX_PANIC(("IO write(1f0): buffer_index >= PACKET_SIZE"));
|
|
- BX_SELECTED_CONTROLLER.buffer[BX_SELECTED_CONTROLLER.buffer_index] = value;
|
|
- BX_SELECTED_CONTROLLER.buffer[BX_SELECTED_CONTROLLER.buffer_index+1] = (value >> 8);
|
|
- BX_SELECTED_CONTROLLER.buffer_index += 2;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index] = value;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+1] = (value >> 8);
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index += 2;
|
|
|
|
/* if packet completely writtten */
|
|
- if (BX_SELECTED_CONTROLLER.buffer_index >= PACKET_SIZE) {
|
|
+ if (BX_SELECTED_CONTROLLER(channel).buffer_index >= PACKET_SIZE) {
|
|
// complete command received
|
|
- Bit8u atapi_command = BX_SELECTED_CONTROLLER.buffer[0];
|
|
+ Bit8u atapi_command = BX_SELECTED_CONTROLLER(channel).buffer[0];
|
|
|
|
if (bx_dbg.cdrom)
|
|
BX_INFO(("cdrom: ATAPI command 0x%x started", atapi_command));
|
|
|
|
switch (atapi_command) {
|
|
case 0x00: // test unit ready
|
|
- if (BX_SELECTED_HD.cdrom.ready) {
|
|
- atapi_cmd_nop();
|
|
+ if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
|
|
+ atapi_cmd_nop(channel);
|
|
} else {
|
|
- atapi_cmd_error(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
+ atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
}
|
|
- raise_interrupt();
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
|
|
case 0x03: { // request sense
|
|
- int alloc_length = BX_SELECTED_CONTROLLER.buffer[4];
|
|
- init_send_atapi_command(atapi_command, 18, alloc_length);
|
|
+ int alloc_length = BX_SELECTED_CONTROLLER(channel).buffer[4];
|
|
+ init_send_atapi_command(channel, atapi_command, 18, alloc_length);
|
|
|
|
// sense data
|
|
- BX_SELECTED_CONTROLLER.buffer[0] = 0x70 | (1 << 7);
|
|
- BX_SELECTED_CONTROLLER.buffer[1] = 0;
|
|
- BX_SELECTED_CONTROLLER.buffer[2] = BX_SELECTED_HD.sense.sense_key;
|
|
- BX_SELECTED_CONTROLLER.buffer[3] = BX_SELECTED_HD.sense.information.arr[0];
|
|
- BX_SELECTED_CONTROLLER.buffer[4] = BX_SELECTED_HD.sense.information.arr[1];
|
|
- BX_SELECTED_CONTROLLER.buffer[5] = BX_SELECTED_HD.sense.information.arr[2];
|
|
- BX_SELECTED_CONTROLLER.buffer[6] = BX_SELECTED_HD.sense.information.arr[3];
|
|
- BX_SELECTED_CONTROLLER.buffer[7] = 17-7;
|
|
- BX_SELECTED_CONTROLLER.buffer[8] = BX_SELECTED_HD.sense.specific_inf.arr[0];
|
|
- BX_SELECTED_CONTROLLER.buffer[9] = BX_SELECTED_HD.sense.specific_inf.arr[1];
|
|
- BX_SELECTED_CONTROLLER.buffer[10] = BX_SELECTED_HD.sense.specific_inf.arr[2];
|
|
- BX_SELECTED_CONTROLLER.buffer[11] = BX_SELECTED_HD.sense.specific_inf.arr[3];
|
|
- BX_SELECTED_CONTROLLER.buffer[12] = BX_SELECTED_HD.sense.asc;
|
|
- BX_SELECTED_CONTROLLER.buffer[13] = BX_SELECTED_HD.sense.ascq;
|
|
- BX_SELECTED_CONTROLLER.buffer[14] = BX_SELECTED_HD.sense.fruc;
|
|
- BX_SELECTED_CONTROLLER.buffer[15] = BX_SELECTED_HD.sense.key_spec.arr[0];
|
|
- BX_SELECTED_CONTROLLER.buffer[16] = BX_SELECTED_HD.sense.key_spec.arr[1];
|
|
- BX_SELECTED_CONTROLLER.buffer[17] = BX_SELECTED_HD.sense.key_spec.arr[2];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[0] = 0x70 | (1 << 7);
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[1] = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[2] = BX_SELECTED_DRIVE(channel).sense.sense_key;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[3] = BX_SELECTED_DRIVE(channel).sense.information.arr[0];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[4] = BX_SELECTED_DRIVE(channel).sense.information.arr[1];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[5] = BX_SELECTED_DRIVE(channel).sense.information.arr[2];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[6] = BX_SELECTED_DRIVE(channel).sense.information.arr[3];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[7] = 17-7;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[8] = BX_SELECTED_DRIVE(channel).sense.specific_inf.arr[0];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[9] = BX_SELECTED_DRIVE(channel).sense.specific_inf.arr[1];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[10] = BX_SELECTED_DRIVE(channel).sense.specific_inf.arr[2];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[11] = BX_SELECTED_DRIVE(channel).sense.specific_inf.arr[3];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[12] = BX_SELECTED_DRIVE(channel).sense.asc;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[13] = BX_SELECTED_DRIVE(channel).sense.ascq;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[14] = BX_SELECTED_DRIVE(channel).sense.fruc;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[15] = BX_SELECTED_DRIVE(channel).sense.key_spec.arr[0];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[16] = BX_SELECTED_DRIVE(channel).sense.key_spec.arr[1];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[17] = BX_SELECTED_DRIVE(channel).sense.key_spec.arr[2];
|
|
|
|
- ready_to_send_atapi();
|
|
+ ready_to_send_atapi(channel);
|
|
}
|
|
break;
|
|
|
|
case 0x1b: { // start stop unit
|
|
- //Boolean Immed = (BX_SELECTED_CONTROLLER.buffer[1] >> 0) & 1;
|
|
- Boolean LoEj = (BX_SELECTED_CONTROLLER.buffer[4] >> 1) & 1;
|
|
- Boolean Start = (BX_SELECTED_CONTROLLER.buffer[4] >> 0) & 1;
|
|
+ //Boolean Immed = (BX_SELECTED_CONTROLLER(channel).buffer[1] >> 0) & 1;
|
|
+ Boolean LoEj = (BX_SELECTED_CONTROLLER(channel).buffer[4] >> 1) & 1;
|
|
+ Boolean Start = (BX_SELECTED_CONTROLLER(channel).buffer[4] >> 0) & 1;
|
|
|
|
if (!LoEj && !Start) { // stop the disc
|
|
BX_PANIC(("Stop disc not implemented"));
|
|
} else if (!LoEj && Start) { // start the disc and read the TOC
|
|
// BX_PANIC(("Start disc not implemented"));
|
|
BX_ERROR(("FIXME: ATAPI start disc not reading TOC"));
|
|
- atapi_cmd_nop();
|
|
- raise_interrupt();
|
|
+ atapi_cmd_nop(channel);
|
|
+ raise_interrupt(channel);
|
|
} else if (LoEj && !Start) { // Eject the disc
|
|
- atapi_cmd_nop();
|
|
- if (BX_HD_THIS s[1].cdrom.ready) {
|
|
+ atapi_cmd_nop(channel);
|
|
+
|
|
+ if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
|
|
#ifdef LOWLEVEL_CDROM
|
|
- BX_HD_THIS s[1].cdrom.cd->eject_cdrom();
|
|
+ BX_SELECTED_DRIVE(channel).cdrom.cd->eject_cdrom();
|
|
#endif
|
|
- BX_HD_THIS s[1].cdrom.ready = 0;
|
|
- bx_options.cdromd.Ostatus->set(BX_EJECTED);
|
|
+ BX_SELECTED_DRIVE(channel).cdrom.ready = 0;
|
|
+ bx_options.atadevice[channel][BX_SLAVE_SELECTED(channel)].Ostatus->set(BX_EJECTED);
|
|
bx_gui.update_drive_status_buttons();
|
|
}
|
|
- raise_interrupt();
|
|
+ raise_interrupt(channel);
|
|
} else { // Load the disc
|
|
// My guess is that this command only closes the tray, that's a no-op for us
|
|
- atapi_cmd_nop();
|
|
- raise_interrupt();
|
|
+ atapi_cmd_nop(channel);
|
|
+ raise_interrupt(channel);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 0xbd: { // mechanism status
|
|
- uint16 alloc_length = read_16bit(BX_SELECTED_CONTROLLER.buffer + 8);
|
|
+ uint16 alloc_length = read_16bit(BX_SELECTED_CONTROLLER(channel).buffer + 8);
|
|
|
|
if (alloc_length == 0)
|
|
BX_PANIC(("Zero allocation length to MECHANISM STATUS not impl."));
|
|
|
|
- init_send_atapi_command(atapi_command, 8, alloc_length);
|
|
+ init_send_atapi_command(channel, atapi_command, 8, alloc_length);
|
|
|
|
- BX_SELECTED_CONTROLLER.buffer[0] = 0; // reserved for non changers
|
|
- BX_SELECTED_CONTROLLER.buffer[1] = 0; // reserved for non changers
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[0] = 0; // reserved for non changers
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[1] = 0; // reserved for non changers
|
|
|
|
- BX_SELECTED_CONTROLLER.buffer[2] = 0; // Current LBA (TODO!)
|
|
- BX_SELECTED_CONTROLLER.buffer[3] = 0; // Current LBA (TODO!)
|
|
- BX_SELECTED_CONTROLLER.buffer[4] = 0; // Current LBA (TODO!)
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[2] = 0; // Current LBA (TODO!)
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[3] = 0; // Current LBA (TODO!)
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[4] = 0; // Current LBA (TODO!)
|
|
|
|
- BX_SELECTED_CONTROLLER.buffer[5] = 1; // one slot
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[5] = 1; // one slot
|
|
|
|
- BX_SELECTED_CONTROLLER.buffer[6] = 0; // slot table length
|
|
- BX_SELECTED_CONTROLLER.buffer[7] = 0; // slot table length
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[6] = 0; // slot table length
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[7] = 0; // slot table length
|
|
|
|
- ready_to_send_atapi();
|
|
+ ready_to_send_atapi(channel);
|
|
}
|
|
break;
|
|
|
|
case 0x5a: { // mode sense
|
|
- uint16 alloc_length = read_16bit(BX_SELECTED_CONTROLLER.buffer + 7);
|
|
+ uint16 alloc_length = read_16bit(BX_SELECTED_CONTROLLER(channel).buffer + 7);
|
|
|
|
- Bit8u PC = BX_SELECTED_CONTROLLER.buffer[2] >> 6;
|
|
- Bit8u PageCode = BX_SELECTED_CONTROLLER.buffer[2] & 0x3f;
|
|
+ Bit8u PC = BX_SELECTED_CONTROLLER(channel).buffer[2] >> 6;
|
|
+ Bit8u PageCode = BX_SELECTED_CONTROLLER(channel).buffer[2] & 0x3f;
|
|
|
|
switch (PC) {
|
|
case 0x0: // current values
|
|
switch (PageCode) {
|
|
case 0x01: // error recovery
|
|
- init_send_atapi_command(atapi_command, sizeof(error_recovery_t) + 8, alloc_length);
|
|
+ init_send_atapi_command(channel, atapi_command, sizeof(error_recovery_t) + 8, alloc_length);
|
|
|
|
- init_mode_sense_single(&BX_SELECTED_HD.cdrom.current.error_recovery,
|
|
+ init_mode_sense_single(channel, &BX_SELECTED_DRIVE(channel).cdrom.current.error_recovery,
|
|
sizeof(error_recovery_t));
|
|
- ready_to_send_atapi();
|
|
+ ready_to_send_atapi(channel);
|
|
break;
|
|
|
|
case 0x2a: // CD-ROM capabilities & mech. status
|
|
- init_send_atapi_command(atapi_command, 28, alloc_length);
|
|
- init_mode_sense_single(&BX_SELECTED_CONTROLLER.buffer[8], 28);
|
|
- BX_SELECTED_CONTROLLER.buffer[8] = 0x2a;
|
|
- BX_SELECTED_CONTROLLER.buffer[9] = 0x12;
|
|
- BX_SELECTED_CONTROLLER.buffer[10] = 0x00;
|
|
- BX_SELECTED_CONTROLLER.buffer[11] = 0x00;
|
|
- BX_SELECTED_CONTROLLER.buffer[12] = 0x00;
|
|
- BX_SELECTED_CONTROLLER.buffer[13] = (3 << 5);
|
|
- BX_SELECTED_CONTROLLER.buffer[14] = (unsigned char)
|
|
+ init_send_atapi_command(channel, atapi_command, 28, alloc_length);
|
|
+ init_mode_sense_single(channel, &BX_SELECTED_CONTROLLER(channel).buffer[8], 28);
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[8] = 0x2a;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[9] = 0x12;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[10] = 0x00;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[11] = 0x00;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[12] = 0x00;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[13] = (3 << 5);
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[14] = (unsigned char)
|
|
(1 |
|
|
- (BX_SELECTED_HD.cdrom.locked ? (1 << 1) : 0) |
|
|
+ (BX_SELECTED_DRIVE(channel).cdrom.locked ? (1 << 1) : 0) |
|
|
(1 << 3) |
|
|
(1 << 5));
|
|
- BX_SELECTED_CONTROLLER.buffer[15] = 0x00;
|
|
- BX_SELECTED_CONTROLLER.buffer[16] = (706 >> 8) & 0xff;
|
|
- BX_SELECTED_CONTROLLER.buffer[17] = 706 & 0xff;
|
|
- BX_SELECTED_CONTROLLER.buffer[18] = 0;
|
|
- BX_SELECTED_CONTROLLER.buffer[19] = 2;
|
|
- BX_SELECTED_CONTROLLER.buffer[20] = (512 >> 8) & 0xff;
|
|
- BX_SELECTED_CONTROLLER.buffer[21] = 512 & 0xff;
|
|
- BX_SELECTED_CONTROLLER.buffer[22] = (706 >> 8) & 0xff;
|
|
- BX_SELECTED_CONTROLLER.buffer[23] = 706 & 0xff;
|
|
- BX_SELECTED_CONTROLLER.buffer[24] = 0;
|
|
- BX_SELECTED_CONTROLLER.buffer[25] = 0;
|
|
- BX_SELECTED_CONTROLLER.buffer[26] = 0;
|
|
- BX_SELECTED_CONTROLLER.buffer[27] = 0;
|
|
- ready_to_send_atapi();
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[15] = 0x00;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[16] = (706 >> 8) & 0xff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[17] = 706 & 0xff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[18] = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[19] = 2;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[20] = (512 >> 8) & 0xff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[21] = 512 & 0xff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[22] = (706 >> 8) & 0xff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[23] = 706 & 0xff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[24] = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[25] = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[26] = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[27] = 0;
|
|
+ ready_to_send_atapi(channel);
|
|
break;
|
|
|
|
case 0x0d: // CD-ROM
|
|
@@ -1171,9 +1252,9 @@
|
|
BX_ERROR(("cdrom: MODE SENSE (curr), code=%x"
|
|
" not implemented yet",
|
|
PageCode));
|
|
- atapi_cmd_error(SENSE_ILLEGAL_REQUEST,
|
|
+ atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
|
|
ASC_INV_FIELD_IN_CMD_PACKET);
|
|
- raise_interrupt();
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
|
|
default:
|
|
@@ -1181,9 +1262,9 @@
|
|
BX_INFO(("cdrom: MODE SENSE PC=%x, PageCode=%x,"
|
|
" not implemented by device",
|
|
PC, PageCode));
|
|
- atapi_cmd_error(SENSE_ILLEGAL_REQUEST,
|
|
+ atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
|
|
ASC_INV_FIELD_IN_CMD_PACKET);
|
|
- raise_interrupt();
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
}
|
|
break;
|
|
@@ -1198,9 +1279,9 @@
|
|
BX_ERROR(("cdrom: MODE SENSE (chg), code=%x",
|
|
" not implemented yet",
|
|
PageCode));
|
|
- atapi_cmd_error(SENSE_ILLEGAL_REQUEST,
|
|
+ atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
|
|
ASC_INV_FIELD_IN_CMD_PACKET);
|
|
- raise_interrupt();
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
|
|
default:
|
|
@@ -1208,9 +1289,9 @@
|
|
BX_INFO(("cdrom: MODE SENSE PC=%x, PageCode=%x,"
|
|
" not implemented by device",
|
|
PC, PageCode));
|
|
- atapi_cmd_error(SENSE_ILLEGAL_REQUEST,
|
|
+ atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
|
|
ASC_INV_FIELD_IN_CMD_PACKET);
|
|
- raise_interrupt();
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
}
|
|
break;
|
|
@@ -1231,16 +1312,16 @@
|
|
BX_INFO(("cdrom: MODE SENSE PC=%x, PageCode=%x,"
|
|
" not implemented by device",
|
|
PC, PageCode));
|
|
- atapi_cmd_error(SENSE_ILLEGAL_REQUEST,
|
|
+ atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
|
|
ASC_INV_FIELD_IN_CMD_PACKET);
|
|
- raise_interrupt();
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case 0x3: // saved values not implemented
|
|
- atapi_cmd_error(SENSE_ILLEGAL_REQUEST, ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
|
|
- raise_interrupt();
|
|
+ atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
|
|
default:
|
|
@@ -1251,96 +1332,96 @@
|
|
break;
|
|
|
|
case 0x12: { // inquiry
|
|
- uint8 alloc_length = BX_SELECTED_CONTROLLER.buffer[4];
|
|
+ uint8 alloc_length = BX_SELECTED_CONTROLLER(channel).buffer[4];
|
|
|
|
- init_send_atapi_command(atapi_command, 36, alloc_length);
|
|
+ init_send_atapi_command(channel, atapi_command, 36, alloc_length);
|
|
|
|
- BX_SELECTED_CONTROLLER.buffer[0] = 0x05; // CD-ROM
|
|
- BX_SELECTED_CONTROLLER.buffer[1] = 0x80; // Removable
|
|
- BX_SELECTED_CONTROLLER.buffer[2] = 0x00; // ISO, ECMA, ANSI version
|
|
- BX_SELECTED_CONTROLLER.buffer[3] = 0x21; // ATAPI-2, as specified
|
|
- BX_SELECTED_CONTROLLER.buffer[4] = 31; // additional length (total 36)
|
|
- BX_SELECTED_CONTROLLER.buffer[5] = 0x00; // reserved
|
|
- BX_SELECTED_CONTROLLER.buffer[6] = 0x00; // reserved
|
|
- BX_SELECTED_CONTROLLER.buffer[7] = 0x00; // reserved
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[0] = 0x05; // CD-ROM
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[1] = 0x80; // Removable
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[2] = 0x00; // ISO, ECMA, ANSI version
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[3] = 0x21; // ATAPI-2, as specified
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[4] = 31; // additional length (total 36)
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[5] = 0x00; // reserved
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[6] = 0x00; // reserved
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[7] = 0x00; // reserved
|
|
|
|
// Vendor ID
|
|
const char* vendor_id = "VTAB\0\0\0\0";
|
|
int i;
|
|
for (i = 0; i < 8; i++)
|
|
- BX_SELECTED_CONTROLLER.buffer[8+i] = vendor_id[i];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[8+i] = vendor_id[i];
|
|
|
|
// Product ID
|
|
const char* product_id = "Turbo CD-ROM\0\0\0\0";
|
|
for (i = 0; i < 16; i++)
|
|
- BX_SELECTED_CONTROLLER.buffer[16+i] = product_id[i];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[16+i] = product_id[i];
|
|
|
|
// Product Revision level
|
|
const char* rev_level = "R0\0\0";
|
|
for (i = 0; i < 4; i++)
|
|
- BX_SELECTED_CONTROLLER.buffer[32+i] = rev_level[i];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[32+i] = rev_level[i];
|
|
|
|
- ready_to_send_atapi();
|
|
+ ready_to_send_atapi(channel);
|
|
}
|
|
break;
|
|
|
|
case 0x25: { // read cd-rom capacity
|
|
// no allocation length???
|
|
- init_send_atapi_command(atapi_command, 8, 8);
|
|
+ init_send_atapi_command(channel, atapi_command, 8, 8);
|
|
|
|
- if (BX_SELECTED_HD.cdrom.ready) {
|
|
- uint32 capacity = BX_SELECTED_HD.cdrom.capacity;
|
|
+ if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
|
|
+ uint32 capacity = BX_SELECTED_DRIVE(channel).cdrom.capacity;
|
|
BX_INFO(("Capacity is %d sectors (%d bytes)", capacity, capacity * 2048));
|
|
- BX_SELECTED_CONTROLLER.buffer[0] = (capacity >> 24) & 0xff;
|
|
- BX_SELECTED_CONTROLLER.buffer[1] = (capacity >> 16) & 0xff;
|
|
- BX_SELECTED_CONTROLLER.buffer[2] = (capacity >> 8) & 0xff;
|
|
- BX_SELECTED_CONTROLLER.buffer[3] = (capacity >> 0) & 0xff;
|
|
- BX_SELECTED_CONTROLLER.buffer[4] = (2048 >> 24) & 0xff;
|
|
- BX_SELECTED_CONTROLLER.buffer[5] = (2048 >> 16) & 0xff;
|
|
- BX_SELECTED_CONTROLLER.buffer[6] = (2048 >> 8) & 0xff;
|
|
- BX_SELECTED_CONTROLLER.buffer[7] = (2048 >> 0) & 0xff;
|
|
- ready_to_send_atapi();
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[0] = (capacity >> 24) & 0xff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[1] = (capacity >> 16) & 0xff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[2] = (capacity >> 8) & 0xff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[3] = (capacity >> 0) & 0xff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[4] = (2048 >> 24) & 0xff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[5] = (2048 >> 16) & 0xff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[6] = (2048 >> 8) & 0xff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[7] = (2048 >> 0) & 0xff;
|
|
+ ready_to_send_atapi(channel);
|
|
} else {
|
|
- atapi_cmd_error(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
- raise_interrupt();
|
|
+ atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
+ raise_interrupt(channel);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 0xbe: { // read cd
|
|
- if (BX_SELECTED_HD.cdrom.ready) {
|
|
+ if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
|
|
BX_ERROR(("Read CD with CD present not implemented"));
|
|
- atapi_cmd_error(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
|
|
- raise_interrupt();
|
|
+ atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
|
|
+ raise_interrupt(channel);
|
|
} else {
|
|
- atapi_cmd_error(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
- raise_interrupt();
|
|
+ atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
+ raise_interrupt(channel);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 0x43: { // read toc
|
|
- if (BX_SELECTED_HD.cdrom.ready) {
|
|
+ if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
|
|
#ifdef LOWLEVEL_CDROM
|
|
- bool msf = (BX_SELECTED_CONTROLLER.buffer[1] >> 1) & 1;
|
|
- uint8 starting_track = BX_SELECTED_CONTROLLER.buffer[6];
|
|
+ bool msf = (BX_SELECTED_CONTROLLER(channel).buffer[1] >> 1) & 1;
|
|
+ uint8 starting_track = BX_SELECTED_CONTROLLER(channel).buffer[6];
|
|
#endif
|
|
- uint16 alloc_length = read_16bit(BX_SELECTED_CONTROLLER.buffer + 7);
|
|
+ uint16 alloc_length = read_16bit(BX_SELECTED_CONTROLLER(channel).buffer + 7);
|
|
|
|
- uint8 format = (BX_SELECTED_CONTROLLER.buffer[9] >> 6);
|
|
+ uint8 format = (BX_SELECTED_CONTROLLER(channel).buffer[9] >> 6);
|
|
int i;
|
|
switch (format) {
|
|
case 0:
|
|
#ifdef LOWLEVEL_CDROM
|
|
int toc_length;
|
|
- if (!BX_SELECTED_HD.cdrom.cd->read_toc(BX_SELECTED_CONTROLLER.buffer,
|
|
- &toc_length, msf, starting_track)) {
|
|
- atapi_cmd_error(SENSE_ILLEGAL_REQUEST,
|
|
+ if (!(BX_SELECTED_DRIVE(channel).cdrom.cd->read_toc(BX_SELECTED_CONTROLLER(channel).buffer,
|
|
+ &toc_length, msf, starting_track))) {
|
|
+ atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
|
|
ASC_INV_FIELD_IN_CMD_PACKET);
|
|
- raise_interrupt();
|
|
+ raise_interrupt(channel);
|
|
} else {
|
|
- init_send_atapi_command(atapi_command, toc_length, alloc_length);
|
|
- ready_to_send_atapi();
|
|
+ init_send_atapi_command(channel, atapi_command, toc_length, alloc_length);
|
|
+ ready_to_send_atapi(channel);
|
|
}
|
|
#else
|
|
BX_PANIC(("LOWLEVEL_CDROM not defined"));
|
|
@@ -1349,16 +1430,16 @@
|
|
|
|
case 1:
|
|
// multi session stuff. we ignore this and emulate a single session only
|
|
- init_send_atapi_command(atapi_command, 12, alloc_length);
|
|
+ init_send_atapi_command(channel, atapi_command, 12, alloc_length);
|
|
|
|
- BX_SELECTED_CONTROLLER.buffer[0] = 0;
|
|
- BX_SELECTED_CONTROLLER.buffer[1] = 0x0a;
|
|
- BX_SELECTED_CONTROLLER.buffer[2] = 1;
|
|
- BX_SELECTED_CONTROLLER.buffer[3] = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[0] = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[1] = 0x0a;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[2] = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[3] = 1;
|
|
for (i = 0; i < 8; i++)
|
|
- BX_SELECTED_CONTROLLER.buffer[4+i] = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[4+i] = 0;
|
|
|
|
- ready_to_send_atapi();
|
|
+ ready_to_send_atapi(channel);
|
|
break;
|
|
|
|
case 2:
|
|
@@ -1367,114 +1448,114 @@
|
|
break;
|
|
}
|
|
} else {
|
|
- atapi_cmd_error(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
- raise_interrupt();
|
|
+ atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
+ raise_interrupt(channel);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 0x28: { // read (10)
|
|
- uint32 transfer_length = read_16bit(BX_SELECTED_CONTROLLER.buffer + 7);
|
|
- uint32 lba = read_32bit(BX_SELECTED_CONTROLLER.buffer + 2);
|
|
+ uint32 transfer_length = read_16bit(BX_SELECTED_CONTROLLER(channel).buffer + 7);
|
|
+ uint32 lba = read_32bit(BX_SELECTED_CONTROLLER(channel).buffer + 2);
|
|
|
|
- if (!BX_SELECTED_HD.cdrom.ready) {
|
|
- atapi_cmd_error(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
- raise_interrupt();
|
|
+ if (!BX_SELECTED_DRIVE(channel).cdrom.ready) {
|
|
+ atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
}
|
|
|
|
if (transfer_length == 0) {
|
|
- atapi_cmd_nop();
|
|
- raise_interrupt();
|
|
+ atapi_cmd_nop(channel);
|
|
+ raise_interrupt(channel);
|
|
BX_INFO(("READ(10) with transfer length 0, ok"));
|
|
break;
|
|
}
|
|
|
|
- if (lba + transfer_length > BX_SELECTED_HD.cdrom.capacity) {
|
|
- atapi_cmd_error(SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
|
|
- raise_interrupt();
|
|
+ if (lba + transfer_length > BX_SELECTED_DRIVE(channel).cdrom.capacity) {
|
|
+ atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
}
|
|
|
|
//BX_INFO(("cdrom: READ LBA=%d LEN=%d", lba, transfer_length));
|
|
|
|
// handle command
|
|
- init_send_atapi_command(atapi_command, transfer_length * 2048,
|
|
+ init_send_atapi_command(channel, atapi_command, transfer_length * 2048,
|
|
transfer_length * 2048, true);
|
|
- BX_SELECTED_HD.cdrom.remaining_blocks = transfer_length;
|
|
- BX_SELECTED_HD.cdrom.next_lba = lba;
|
|
- ready_to_send_atapi();
|
|
+ BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks = transfer_length;
|
|
+ BX_SELECTED_DRIVE(channel).cdrom.next_lba = lba;
|
|
+ ready_to_send_atapi(channel);
|
|
}
|
|
break;
|
|
|
|
case 0x2b: { // seek
|
|
- uint32 lba = read_32bit(BX_SELECTED_CONTROLLER.buffer + 2);
|
|
- if (!BX_SELECTED_HD.cdrom.ready) {
|
|
- atapi_cmd_error(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
- raise_interrupt();
|
|
+ uint32 lba = read_32bit(BX_SELECTED_CONTROLLER(channel).buffer + 2);
|
|
+ if (!BX_SELECTED_DRIVE(channel).cdrom.ready) {
|
|
+ atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
}
|
|
|
|
- if (lba > BX_SELECTED_HD.cdrom.capacity) {
|
|
- atapi_cmd_error(SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
|
|
- raise_interrupt();
|
|
+ if (lba > BX_SELECTED_DRIVE(channel).cdrom.capacity) {
|
|
+ atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
}
|
|
BX_INFO(("cdrom: SEEK (ignored)"));
|
|
- atapi_cmd_nop();
|
|
- raise_interrupt();
|
|
+ atapi_cmd_nop(channel);
|
|
+ raise_interrupt(channel);
|
|
}
|
|
break;
|
|
|
|
case 0x1e: { // prevent/allow medium removal
|
|
- if (BX_SELECTED_HD.cdrom.ready) {
|
|
- BX_SELECTED_HD.cdrom.locked = BX_SELECTED_CONTROLLER.buffer[4] & 1;
|
|
- atapi_cmd_nop();
|
|
+ if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
|
|
+ BX_SELECTED_DRIVE(channel).cdrom.locked = BX_SELECTED_CONTROLLER(channel).buffer[4] & 1;
|
|
+ atapi_cmd_nop(channel);
|
|
} else {
|
|
- atapi_cmd_error(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
+ atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
}
|
|
- raise_interrupt();
|
|
+ raise_interrupt(channel);
|
|
}
|
|
break;
|
|
|
|
case 0x42: { // read sub-channel
|
|
- bool msf = get_packet_field(1, 1, 1);
|
|
- bool sub_q = get_packet_field(2, 6, 1);
|
|
- uint8 data_format = get_packet_byte(3);
|
|
- uint8 track_number = get_packet_byte(6);
|
|
- uint16 alloc_length = get_packet_word(7);
|
|
+ bool msf = get_packet_field(channel,1, 1, 1);
|
|
+ bool sub_q = get_packet_field(channel,2, 6, 1);
|
|
+ uint8 data_format = get_packet_byte(channel,3);
|
|
+ uint8 track_number = get_packet_byte(channel,6);
|
|
+ uint16 alloc_length = get_packet_word(channel,7);
|
|
UNUSED(msf);
|
|
UNUSED(data_format);
|
|
UNUSED(track_number);
|
|
|
|
- if (!BX_SELECTED_HD.cdrom.ready) {
|
|
- atapi_cmd_error(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
- raise_interrupt();
|
|
+ if (!BX_SELECTED_DRIVE(channel).cdrom.ready) {
|
|
+ atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
|
+ raise_interrupt(channel);
|
|
} else {
|
|
- BX_SELECTED_CONTROLLER.buffer[0] = 0;
|
|
- BX_SELECTED_CONTROLLER.buffer[1] = 0; // audio not supported
|
|
- BX_SELECTED_CONTROLLER.buffer[2] = 0;
|
|
- BX_SELECTED_CONTROLLER.buffer[3] = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[0] = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[1] = 0; // audio not supported
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[2] = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[3] = 0;
|
|
|
|
int ret_len = 4; // header size
|
|
|
|
if (sub_q) { // !sub_q == header only
|
|
BX_ERROR(("Read sub-channel with SubQ not implemented"));
|
|
- atapi_cmd_error(SENSE_ILLEGAL_REQUEST,
|
|
+ atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
|
|
ASC_INV_FIELD_IN_CMD_PACKET);
|
|
- raise_interrupt();
|
|
+ raise_interrupt(channel);
|
|
}
|
|
|
|
- init_send_atapi_command(atapi_command, ret_len, alloc_length);
|
|
- ready_to_send_atapi();
|
|
+ init_send_atapi_command(channel, atapi_command, ret_len, alloc_length);
|
|
+ ready_to_send_atapi(channel);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 0x51: { // read disc info
|
|
// no-op to keep the Linux CD-ROM driver happy
|
|
- atapi_cmd_error(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
|
|
- raise_interrupt();
|
|
+ atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
|
|
+ raise_interrupt(channel);
|
|
}
|
|
break;
|
|
|
|
@@ -1492,8 +1573,8 @@
|
|
case 0x4e: // stop play/scan
|
|
BX_ERROR(("ATAPI command 0x%x not implemented yet",
|
|
atapi_command));
|
|
- atapi_cmd_error(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
|
|
- raise_interrupt();
|
|
+ atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
default:
|
|
BX_PANIC(("Unknown ATAPI command 0x%x (%d)",
|
|
@@ -1506,45 +1587,45 @@
|
|
|
|
default:
|
|
BX_PANIC(("IO write(1f0h): current command is %02xh",
|
|
- (unsigned) BX_SELECTED_CONTROLLER.current_command));
|
|
+ (unsigned) BX_SELECTED_CONTROLLER(channel).current_command));
|
|
}
|
|
break;
|
|
|
|
- case 0x1f1: /* hard disk write precompensation */
|
|
- WRITE_FEATURES(value);
|
|
- if (bx_dbg.disk || (CDROM_SELECTED && bx_dbg.cdrom)) {
|
|
+ case 0x01: // hard disk write precompensation 0x1f1
|
|
+ WRITE_FEATURES(channel,value);
|
|
+ if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom)) {
|
|
if (value == 0xff)
|
|
- BX_INFO(("no precompensation {%s}", DEVICE_TYPE_STRING));
|
|
+ BX_INFO(("no precompensation {%s}", BX_SELECTED_TYPE_STRING(channel)));
|
|
else
|
|
- BX_INFO(("precompensation value %02x {%s}", (unsigned) value, DEVICE_TYPE_STRING));
|
|
+ BX_INFO(("precompensation value %02x {%s}", (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
|
|
}
|
|
break;
|
|
|
|
- case 0x1f2: /* hard disk sector count */
|
|
- WRITE_SECTOR_COUNT(value);
|
|
- if (bx_dbg.disk || (CDROM_SELECTED && bx_dbg.cdrom))
|
|
- BX_INFO(("sector count = %u {%s}", (unsigned) value, DEVICE_TYPE_STRING));
|
|
+ case 0x02: // hard disk sector count 0x1f2
|
|
+ WRITE_SECTOR_COUNT(channel,value);
|
|
+ if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
|
|
+ BX_INFO(("sector count = %u {%s}", (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
|
|
break;
|
|
|
|
- case 0x1f3: /* hard disk sector number */
|
|
- WRITE_SECTOR_NUMBER(value);
|
|
- if (bx_dbg.disk || (CDROM_SELECTED && bx_dbg.cdrom))
|
|
- BX_INFO(("sector number = %u {%s}", (unsigned) value, DEVICE_TYPE_STRING));
|
|
+ case 0x03: // hard disk sector number 0x1f3
|
|
+ WRITE_SECTOR_NUMBER(channel,value);
|
|
+ if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
|
|
+ BX_INFO(("sector number = %u {%s}", (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
|
|
break;
|
|
|
|
- case 0x1f4: /* hard disk cylinder low */
|
|
- WRITE_CYLINDER_LOW(value);
|
|
- if (bx_dbg.disk || (CDROM_SELECTED && bx_dbg.cdrom))
|
|
- BX_INFO(("cylinder low = %02xh {%s}", (unsigned) value, DEVICE_TYPE_STRING));
|
|
+ case 0x04: // hard disk cylinder low 0x1f4
|
|
+ WRITE_CYLINDER_LOW(channel,value);
|
|
+ if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
|
|
+ BX_INFO(("cylinder low = %02xh {%s}", (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
|
|
break;
|
|
|
|
- case 0x1f5: /* hard disk cylinder high */
|
|
- WRITE_CYLINDER_HIGH(value);
|
|
- if (bx_dbg.disk || (CDROM_SELECTED && bx_dbg.cdrom))
|
|
- BX_INFO(("cylinder high = %02xh {%s}", (unsigned) value, DEVICE_TYPE_STRING));
|
|
+ case 0x05: // hard disk cylinder high 0x1f5
|
|
+ WRITE_CYLINDER_HIGH(channel,value);
|
|
+ if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
|
|
+ BX_INFO(("cylinder high = %02xh {%s}", (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
|
|
break;
|
|
|
|
- case 0x1f6: // hard disk drive and head register
|
|
+ case 0x06: // hard disk drive and head register 0x1f6
|
|
// b7 Extended data field for ECC
|
|
// b6/b5: Used to be sector size. 00=256,01=512,10=1024,11=128
|
|
// Since 512 was always used, bit 6 was taken to mean LBA mode:
|
|
@@ -1555,410 +1636,399 @@
|
|
{
|
|
if ( (value & 0xa0) != 0xa0 ) // 1x1xxxxx
|
|
BX_INFO(("IO write 1f6 (%02x): not 1x1xxxxxb", (unsigned) value));
|
|
- Bit32u drvsel = BX_HD_THIS drive_select = (value >> 4) & 0x01;
|
|
- WRITE_HEAD_NO(value & 0xf);
|
|
- if (BX_SELECTED_CONTROLLER.lba_mode == 0 && ((value >> 6) & 1) == 1)
|
|
+ Bit32u drvsel = BX_HD_THIS channels[channel].drive_select = (value >> 4) & 0x01;
|
|
+ WRITE_HEAD_NO(channel,value & 0xf);
|
|
+ if (BX_SELECTED_CONTROLLER(channel).lba_mode == 0 && ((value >> 6) & 1) == 1)
|
|
BX_INFO(("enabling LBA mode"));
|
|
- WRITE_LBA_MODE((value >> 6) & 1);
|
|
- if (!drvsel && !bx_options.diskc.Opresent->get ()) {
|
|
- BX_ERROR (("device set to 0 which does not exist"));
|
|
- BX_SELECTED_CONTROLLER.error_register = 0x04; // aborted
|
|
- BX_SELECTED_CONTROLLER.status.err = 1;
|
|
- } else if (drvsel && !bx_options.diskd.Opresent->get ()) {
|
|
- BX_ERROR (("device set to 1 which does not exist"));
|
|
- BX_SELECTED_CONTROLLER.error_register = 0x04; // aborted
|
|
- BX_SELECTED_CONTROLLER.status.err = 1;
|
|
- }
|
|
+ WRITE_LBA_MODE(channel,(value >> 6) & 1);
|
|
+ if (!BX_SELECTED_IS_PRESENT(channel)) {
|
|
+ BX_ERROR (("device set to %d which does not exist",drvsel));
|
|
+ BX_SELECTED_CONTROLLER(channel).error_register = 0x04; // aborted
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 1;
|
|
+ }
|
|
break;
|
|
}
|
|
|
|
- case 0x1f7: // hard disk command
|
|
+ case 0x07: // hard disk command 0x1f7
|
|
// (mch) Writes to the command register with drive_select != 0
|
|
// are ignored if no secondary device is present
|
|
- if (BX_HD_THIS drive_select != 0 && value != 0x90 && !bx_options.diskd.Opresent->get ())
|
|
+ if ((BX_SLAVE_SELECTED(channel)) && (!BX_SLAVE_IS_PRESENT(channel)))
|
|
break;
|
|
|
|
- if (BX_SELECTED_CONTROLLER.status.busy)
|
|
+ if (BX_SELECTED_CONTROLLER(channel).status.busy)
|
|
BX_PANIC(("hard disk: command sent, controller BUSY"));
|
|
if ( (value & 0xf0) == 0x10 )
|
|
value = 0x10;
|
|
switch (value) {
|
|
|
|
case 0x10: // CALIBRATE DRIVE
|
|
- if (BX_SELECTED_HD.device_type != IDE_DISK)
|
|
+ if (!BX_SELECTED_IS_HD(channel))
|
|
BX_PANIC(("calibrate drive issued to non-disk"));
|
|
- if ((BX_HD_THIS drive_select == 0 && !bx_options.diskc.Opresent->get ()) ||
|
|
- (BX_HD_THIS drive_select != 0 && !bx_options.diskd.Opresent->get ())) {
|
|
- BX_SELECTED_CONTROLLER.error_register = 0x02; // Track 0 not found
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.seek_complete = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 1;
|
|
- raise_interrupt();
|
|
- BX_INFO(("calibrate drive: disk%c not present", BX_HD_THIS drive_select+67));
|
|
+ if (!BX_SELECTED_IS_PRESENT(channel)) {
|
|
+ BX_SELECTED_CONTROLLER(channel).error_register = 0x02; // Track 0 not found
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.seek_complete = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 1;
|
|
+ raise_interrupt(channel);
|
|
+ BX_INFO(("calibrate drive: disk ata%d-%d not present", channel, BX_SLAVE_SELECTED(channel)));
|
|
break;
|
|
}
|
|
|
|
- /* move head to cylinder 0, issue IRQ 14 */
|
|
- BX_SELECTED_CONTROLLER.error_register = 0;
|
|
- BX_SELECTED_CONTROLLER.cylinder_no = 0;
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.seek_complete = 1;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
- raise_interrupt();
|
|
+ /* move head to cylinder 0, issue IRQ */
|
|
+ BX_SELECTED_CONTROLLER(channel).error_register = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).cylinder_no = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
|
|
case 0x20: // READ MULTIPLE SECTORS, with retries
|
|
case 0x21: // READ MULTIPLE SECTORS, without retries
|
|
/* update sector_no, always points to current sector
|
|
- * after each sector is read to buffer, DRQ bit set and issue IRQ 14
|
|
+ * after each sector is read to buffer, DRQ bit set and issue IRQ
|
|
* if interrupt handler transfers all data words into main memory,
|
|
* and more sectors to read, then set BSY bit again, clear DRQ and
|
|
* read next sector into buffer
|
|
* sector count of 0 means 256 sectors
|
|
*/
|
|
|
|
- if (BX_SELECTED_HD.device_type != IDE_DISK)
|
|
+ if (!BX_SELECTED_IS_HD(channel))
|
|
BX_PANIC(("read multiple issued to non-disk"));
|
|
|
|
- BX_SELECTED_CONTROLLER.current_command = value;
|
|
+ BX_SELECTED_CONTROLLER(channel).current_command = value;
|
|
|
|
// Lose98 accesses 0/0/0 in CHS mode
|
|
- if (!BX_SELECTED_CONTROLLER.lba_mode &&
|
|
- !BX_SELECTED_CONTROLLER.head_no &&
|
|
- !BX_SELECTED_CONTROLLER.cylinder_no &&
|
|
- !BX_SELECTED_CONTROLLER.sector_no) {
|
|
+ if (!BX_SELECTED_CONTROLLER(channel).lba_mode &&
|
|
+ !BX_SELECTED_CONTROLLER(channel).head_no &&
|
|
+ !BX_SELECTED_CONTROLLER(channel).cylinder_no &&
|
|
+ !BX_SELECTED_CONTROLLER(channel).sector_no) {
|
|
BX_INFO(("Read from 0/0/0, aborting command"));
|
|
- command_aborted(value);
|
|
+ command_aborted(channel, value);
|
|
break;
|
|
}
|
|
|
|
#if TEST_READ_BEYOND_END==2
|
|
- BX_SELECTED_CONTROLLER.cylinder_no += 100000;
|
|
+ BX_SELECTED_CONTROLLER(channel).cylinder_no += 100000;
|
|
#endif
|
|
- if (!calculate_logical_address(&logical_sector)) {
|
|
+ if (!calculate_logical_address(channel, &logical_sector)) {
|
|
BX_ERROR(("initial read from sector %u out of bounds, aborting", logical_sector));
|
|
- command_aborted(value);
|
|
+ command_aborted(channel, value);
|
|
break;
|
|
}
|
|
#if TEST_READ_BEYOND_END==3
|
|
logical_sector += 100000;
|
|
#endif
|
|
- ret=BX_SELECTED_HD.hard_drive->lseek(logical_sector * 512, SEEK_SET);
|
|
+ ret=BX_SELECTED_DRIVE(channel).hard_drive->lseek(logical_sector * 512, SEEK_SET);
|
|
if (ret < 0) {
|
|
BX_ERROR (("could not lseek() hard drive image file, aborting"));
|
|
- command_aborted(value);
|
|
+ command_aborted(channel, value);
|
|
break;
|
|
}
|
|
- ret = BX_SELECTED_HD.hard_drive->read((bx_ptr_t) BX_SELECTED_CONTROLLER.buffer, 512);
|
|
+ ret = BX_SELECTED_DRIVE(channel).hard_drive->read((bx_ptr_t) BX_SELECTED_CONTROLLER(channel).buffer, 512);
|
|
if (ret < 512) {
|
|
BX_ERROR(("logical sector was %u", (unsigned) logical_sector));
|
|
BX_ERROR(("could not read() hard drive image file at byte %d", logical_sector*512));
|
|
- command_aborted(value);
|
|
+ command_aborted(channel, value);
|
|
break;
|
|
}
|
|
|
|
- BX_SELECTED_CONTROLLER.error_register = 0;
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.seek_complete = 1;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 1;
|
|
- BX_SELECTED_CONTROLLER.status.corrected_data = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
- BX_SELECTED_CONTROLLER.buffer_index = 0;
|
|
- raise_interrupt();
|
|
+ BX_SELECTED_CONTROLLER(channel).error_register = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
|
|
case 0x30: /* WRITE SECTORS, with retries */
|
|
/* update sector_no, always points to current sector
|
|
- * after each sector is read to buffer, DRQ bit set and issue IRQ 14
|
|
+ * after each sector is read to buffer, DRQ bit set and issue IRQ
|
|
* if interrupt handler transfers all data words into main memory,
|
|
* and more sectors to read, then set BSY bit again, clear DRQ and
|
|
* read next sector into buffer
|
|
* sector count of 0 means 256 sectors
|
|
*/
|
|
|
|
- if (BX_SELECTED_HD.device_type != IDE_DISK)
|
|
+ if (!BX_SELECTED_IS_HD(channel))
|
|
BX_PANIC(("write multiple issued to non-disk"));
|
|
|
|
- if (BX_SELECTED_CONTROLLER.status.busy) {
|
|
+ if (BX_SELECTED_CONTROLLER(channel).status.busy) {
|
|
BX_PANIC(("write command: BSY bit set"));
|
|
}
|
|
- BX_SELECTED_CONTROLLER.current_command = value;
|
|
+ BX_SELECTED_CONTROLLER(channel).current_command = value;
|
|
|
|
// implicit seek done :^)
|
|
- BX_SELECTED_CONTROLLER.error_register = 0;
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- // BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.seek_complete = 1;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 1;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
- BX_SELECTED_CONTROLLER.buffer_index = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).error_register = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ // BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
|
|
break;
|
|
|
|
case 0x90: // EXECUTE DEVICE DIAGNOSTIC
|
|
- if (BX_SELECTED_CONTROLLER.status.busy) {
|
|
+ if (BX_SELECTED_CONTROLLER(channel).status.busy) {
|
|
BX_PANIC(("diagnostic command: BSY bit set"));
|
|
}
|
|
- if (BX_SELECTED_HD.device_type != IDE_DISK)
|
|
+ if (!BX_SELECTED_IS_HD(channel))
|
|
BX_PANIC(("drive diagnostics issued to non-disk"));
|
|
- BX_SELECTED_CONTROLLER.error_register = 0x81; // Drive 1 failed, no error on drive 0
|
|
- // BX_SELECTED_CONTROLLER.status.busy = 0; // not needed
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).error_register = 0x81; // Drive 1 failed, no error on drive 0
|
|
+ // BX_SELECTED_CONTROLLER(channel).status.busy = 0; // not needed
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
break;
|
|
|
|
case 0x91: // INITIALIZE DRIVE PARAMETERS
|
|
- if (BX_SELECTED_CONTROLLER.status.busy) {
|
|
+ if (BX_SELECTED_CONTROLLER(channel).status.busy) {
|
|
BX_PANIC(("init drive parameters command: BSY bit set"));
|
|
}
|
|
- if (BX_SELECTED_HD.device_type != IDE_DISK)
|
|
+ if (!BX_SELECTED_IS_HD(channel))
|
|
BX_PANIC(("initialize drive parameters issued to non-disk"));
|
|
// sets logical geometry of specified drive
|
|
BX_DEBUG(("init drive params: sec=%u, drive sel=%u, head=%u",
|
|
- (unsigned) BX_SELECTED_CONTROLLER.sector_count,
|
|
- (unsigned) BX_HD_THIS drive_select,
|
|
- (unsigned) BX_SELECTED_CONTROLLER.head_no));
|
|
- if ((BX_HD_THIS drive_select == 0 && !bx_options.diskc.Opresent->get ()) ||
|
|
- (BX_HD_THIS drive_select != 0 && !bx_options.diskd.Opresent->get ())) {
|
|
- BX_PANIC(("init drive params: disk%c not present", BX_HD_THIS drive_select+67));
|
|
- //BX_SELECTED_CONTROLLER.error_register = 0x12;
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
- raise_interrupt();
|
|
+ (unsigned) BX_SELECTED_CONTROLLER(channel).sector_count,
|
|
+ (unsigned) BX_HD_THIS channels[channel].drive_select,
|
|
+ (unsigned) BX_SELECTED_CONTROLLER(channel).head_no));
|
|
+ if (!BX_SELECTED_IS_PRESENT(channel)) {
|
|
+ BX_PANIC(("init drive params: disk ata%d-%d% not present", channel, BX_SLAVE_SELECTED(channel)));
|
|
+ //BX_SELECTED_CONTROLLER(channel).error_register = 0x12;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
}
|
|
- if (BX_SELECTED_CONTROLLER.sector_count != BX_SELECTED_HD.hard_drive->sectors)
|
|
- BX_PANIC(("init drive params: sector count doesnt match"));
|
|
- if ( BX_SELECTED_CONTROLLER.head_no != (BX_SELECTED_HD.hard_drive->heads-1) )
|
|
- BX_PANIC(("init drive params: head number doesn't match"));
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
- raise_interrupt();
|
|
+ if (BX_SELECTED_CONTROLLER(channel).sector_count != BX_SELECTED_DRIVE(channel).hard_drive->sectors)
|
|
+ BX_PANIC(("init drive params: sector count doesnt match %ld!=%ld", BX_SELECTED_CONTROLLER(channel).sector_count, BX_SELECTED_DRIVE(channel).hard_drive->sectors));
|
|
+ if ( BX_SELECTED_CONTROLLER(channel).head_no != (BX_SELECTED_DRIVE(channel).hard_drive->heads-1) )
|
|
+ BX_PANIC(("init drive params: head number doesn't match %d != %d",BX_SELECTED_CONTROLLER(channel).head_no, BX_SELECTED_DRIVE(channel).hard_drive->heads-1));
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
|
|
case 0xec: // IDENTIFY DEVICE
|
|
if (bx_options.OnewHardDriveSupport->get ()) {
|
|
- if (bx_dbg.disk || (CDROM_SELECTED && bx_dbg.cdrom))
|
|
+ if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
|
|
BX_INFO(("Drive ID Command issued : 0xec "));
|
|
|
|
- if (!BX_HD_THIS drive_select && !bx_options.diskc.Opresent->get ()) {
|
|
- BX_INFO(("1st drive not present, aborting"));
|
|
- command_aborted(value);
|
|
- break;
|
|
- }
|
|
- if (BX_HD_THIS drive_select && !bx_options.diskd.Opresent->get ()) {
|
|
- BX_INFO(("2nd drive not present, aborting"));
|
|
- command_aborted(value);
|
|
+ if (!BX_SELECTED_IS_PRESENT(channel)) {
|
|
+ BX_INFO(("disk ata%d-%d not present, aborting",channel,BX_SLAVE_SELECTED(channel)));
|
|
+ command_aborted(channel, value);
|
|
break;
|
|
}
|
|
- if (BX_SELECTED_HD.device_type == IDE_CDROM) {
|
|
- BX_SELECTED_CONTROLLER.head_no = 0;
|
|
- BX_SELECTED_CONTROLLER.sector_count = 1;
|
|
- BX_SELECTED_CONTROLLER.sector_no = 1;
|
|
- BX_SELECTED_CONTROLLER.cylinder_no = 0xeb14;
|
|
- command_aborted(0xec);
|
|
+ if (BX_SELECTED_IS_CD(channel)) {
|
|
+ BX_SELECTED_CONTROLLER(channel).head_no = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_count = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_no = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).cylinder_no = 0xeb14;
|
|
+ command_aborted(channel, 0xec);
|
|
} else {
|
|
- BX_SELECTED_CONTROLLER.current_command = value;
|
|
- BX_SELECTED_CONTROLLER.error_register = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).current_command = value;
|
|
+ BX_SELECTED_CONTROLLER(channel).error_register = 0;
|
|
|
|
// See ATA/ATAPI-4, 8.12
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.write_fault = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 1;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
-
|
|
- BX_SELECTED_CONTROLLER.status.seek_complete = 1;
|
|
- BX_SELECTED_CONTROLLER.status.corrected_data = 0;
|
|
-
|
|
- BX_SELECTED_CONTROLLER.buffer_index = 0;
|
|
- raise_interrupt();
|
|
- identify_drive(BX_HD_THIS drive_select);
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
+
|
|
+ BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
|
|
+
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
|
|
+ raise_interrupt(channel);
|
|
+ identify_drive(channel);
|
|
}
|
|
}
|
|
else {
|
|
BX_INFO(("sent IDENTIFY DEVICE (0xec) to old hard drive"));
|
|
- command_aborted(value);
|
|
+ command_aborted(channel, value);
|
|
}
|
|
break;
|
|
|
|
case 0xef: // SET FEATURES
|
|
- switch(BX_SELECTED_CONTROLLER.features) {
|
|
+ switch(BX_SELECTED_CONTROLLER(channel).features) {
|
|
case 0x02: // Enable and
|
|
case 0x82: // Disable write cache.
|
|
case 0xAA: // Enable and
|
|
case 0x55: // Disable look-ahead cache.
|
|
+ case 0xCC: // Enable and
|
|
case 0x66: // Disable reverting to power-on default
|
|
- case 0xCC: // Enable reverting to power-on default
|
|
- BX_INFO(("SET FEATURES subcommand 0x%02x not supported by disk.", (unsigned) BX_SELECTED_CONTROLLER.features));
|
|
- command_aborted(value);
|
|
+ BX_INFO(("SET FEATURES subcommand 0x%02x not supported by disk.", (unsigned) BX_SELECTED_CONTROLLER(channel).features));
|
|
+ command_aborted(channel, value);
|
|
break;
|
|
|
|
default:
|
|
- BX_PANIC(("SET FEATURES with unknown subcommand: 0x%02x", (unsigned) BX_SELECTED_CONTROLLER.features ));
|
|
+ BX_PANIC(("SET FEATURES with unknown subcommand: 0x%02x", (unsigned) BX_SELECTED_CONTROLLER(channel).features ));
|
|
}
|
|
break;
|
|
|
|
case 0x40: // READ VERIFY SECTORS
|
|
if (bx_options.OnewHardDriveSupport->get ()) {
|
|
- if (BX_SELECTED_HD.device_type != IDE_DISK)
|
|
+ if (!BX_SELECTED_IS_HD(channel))
|
|
BX_PANIC(("read verify issued to non-disk"));
|
|
BX_INFO(("Verify Command : 0x40 ! "));
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
- raise_interrupt();
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
+ raise_interrupt(channel);
|
|
}
|
|
else {
|
|
BX_INFO(("sent READ VERIFY SECTORS (0x40) to old hard drive"));
|
|
- command_aborted(value);
|
|
+ command_aborted(channel, value);
|
|
}
|
|
break;
|
|
|
|
case 0xc6: // SET MULTIPLE MODE (mch)
|
|
- if (BX_SELECTED_CONTROLLER.sector_count != 128 &&
|
|
- BX_SELECTED_CONTROLLER.sector_count != 64 &&
|
|
- BX_SELECTED_CONTROLLER.sector_count != 32 &&
|
|
- BX_SELECTED_CONTROLLER.sector_count != 16 &&
|
|
- BX_SELECTED_CONTROLLER.sector_count != 8 &&
|
|
- BX_SELECTED_CONTROLLER.sector_count != 4 &&
|
|
- BX_SELECTED_CONTROLLER.sector_count != 2)
|
|
- command_aborted(value);
|
|
+ if (BX_SELECTED_CONTROLLER(channel).sector_count != 128 &&
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_count != 64 &&
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_count != 32 &&
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_count != 16 &&
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_count != 8 &&
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_count != 4 &&
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_count != 2)
|
|
+ command_aborted(channel, value);
|
|
|
|
- if (BX_SELECTED_HD.device_type != IDE_DISK)
|
|
+ if (!BX_SELECTED_IS_HD(channel))
|
|
BX_PANIC(("set multiple mode issued to non-disk"));
|
|
|
|
- BX_SELECTED_CONTROLLER.sectors_per_block = BX_SELECTED_CONTROLLER.sector_count;
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.write_fault = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).sectors_per_block = BX_SELECTED_CONTROLLER(channel).sector_count;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
break;
|
|
|
|
// ATAPI commands
|
|
case 0xa1: // IDENTIFY PACKET DEVICE
|
|
- if (BX_SELECTED_HD.device_type == IDE_CDROM) {
|
|
- BX_SELECTED_CONTROLLER.current_command = value;
|
|
- BX_SELECTED_CONTROLLER.error_register = 0;
|
|
-
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.write_fault = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 1;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
-
|
|
- BX_SELECTED_CONTROLLER.status.seek_complete = 1;
|
|
- BX_SELECTED_CONTROLLER.status.corrected_data = 0;
|
|
-
|
|
- BX_SELECTED_CONTROLLER.buffer_index = 0;
|
|
- raise_interrupt();
|
|
- identify_ATAPI_drive(BX_HD_THIS drive_select);
|
|
+ if (BX_SELECTED_IS_CD(channel)) {
|
|
+ BX_SELECTED_CONTROLLER(channel).current_command = value;
|
|
+ BX_SELECTED_CONTROLLER(channel).error_register = 0;
|
|
+
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
+
|
|
+ BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
|
|
+
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
|
|
+ raise_interrupt(channel);
|
|
+ identify_ATAPI_drive(channel);
|
|
} else {
|
|
- command_aborted(0xa1);
|
|
+ command_aborted(channel, 0xa1);
|
|
}
|
|
break;
|
|
|
|
case 0x08: // DEVICE RESET (atapi)
|
|
- if (BX_SELECTED_HD.device_type == IDE_CDROM) {
|
|
- BX_SELECTED_CONTROLLER.status.busy = 1;
|
|
- BX_SELECTED_CONTROLLER.error_register &= ~(1 << 7);
|
|
+ if (BX_SELECTED_IS_CD(channel)) {
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).error_register &= ~(1 << 7);
|
|
|
|
// device signature
|
|
- BX_SELECTED_CONTROLLER.head_no = 0;
|
|
- BX_SELECTED_CONTROLLER.sector_count = 1;
|
|
- BX_SELECTED_CONTROLLER.sector_no = 1;
|
|
- BX_SELECTED_CONTROLLER.cylinder_no = 0xeb14;
|
|
-
|
|
- BX_SELECTED_CONTROLLER.status.write_fault = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- BX_SELECTED_CONTROLLER.status.corrected_data = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).head_no = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_count = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_no = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).cylinder_no = 0xeb14;
|
|
+
|
|
+ BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
|
|
} else {
|
|
BX_DEBUG(("ATAPI Device Reset on non-cd device"));
|
|
- command_aborted(0x08);
|
|
+ command_aborted(channel, 0x08);
|
|
}
|
|
break;
|
|
|
|
case 0xa0: // SEND PACKET (atapi)
|
|
- if (BX_SELECTED_HD.device_type == IDE_CDROM) {
|
|
+ if (BX_SELECTED_IS_CD(channel)) {
|
|
// PACKET
|
|
- if (BX_SELECTED_CONTROLLER.features & (1 << 0))
|
|
+ if (BX_SELECTED_CONTROLLER(channel).features & (1 << 0))
|
|
BX_PANIC(("PACKET-DMA not supported"));
|
|
- if (BX_SELECTED_CONTROLLER.features & (1 << 1))
|
|
+ if (BX_SELECTED_CONTROLLER(channel).features & (1 << 1))
|
|
BX_PANIC(("PACKET-overlapped not supported"));
|
|
|
|
// We're already ready!
|
|
- BX_SELECTED_CONTROLLER.sector_count = 1;
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.write_fault = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_count = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
|
|
// serv bit??
|
|
- BX_SELECTED_CONTROLLER.status.drq = 1;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
|
|
// NOTE: no interrupt here
|
|
- BX_SELECTED_CONTROLLER.current_command = value;
|
|
- BX_SELECTED_CONTROLLER.buffer_index = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).current_command = value;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
|
|
} else {
|
|
- command_aborted (0xa0);
|
|
+ command_aborted (channel, 0xa0);
|
|
}
|
|
break;
|
|
|
|
case 0xa2: // SERVICE (atapi), optional
|
|
- if (BX_SELECTED_HD.device_type == IDE_CDROM) {
|
|
+ if (BX_SELECTED_IS_CD(channel)) {
|
|
BX_PANIC(("ATAPI SERVICE not implemented"));
|
|
} else {
|
|
- command_aborted (0xa2);
|
|
+ command_aborted (channel, 0xa2);
|
|
}
|
|
break;
|
|
|
|
// power management
|
|
case 0xe5: // CHECK POWER MODE
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.write_fault = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
- BX_SELECTED_CONTROLLER.sector_count = 0xff; // Active or Idle mode
|
|
- raise_interrupt();
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_count = 0xff; // Active or Idle mode
|
|
+ raise_interrupt(channel);
|
|
break;
|
|
|
|
case 0x70: // SEEK (cgs)
|
|
- if (BX_SELECTED_HD.device_type == IDE_DISK) {
|
|
+ if (BX_SELECTED_IS_HD(channel)) {
|
|
BX_DEBUG(("write cmd 0x70 (SEEK) executing"));
|
|
- if (!calculate_logical_address(&logical_sector)) {
|
|
+ if (!calculate_logical_address(channel, &logical_sector)) {
|
|
BX_ERROR(("initial seek to sector %u out of bounds, aborting", logical_sector));
|
|
- command_aborted(value);
|
|
+ command_aborted(channel, value);
|
|
break;
|
|
}
|
|
- BX_SELECTED_CONTROLLER.error_register = 0;
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.seek_complete = 1;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 1;
|
|
- BX_SELECTED_CONTROLLER.status.corrected_data = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
- BX_SELECTED_CONTROLLER.buffer_index = 0;
|
|
- BX_DEBUG(("s[0].controller.control.disable_irq = %02x", (BX_HD_THIS s[0]).controller.control.disable_irq));
|
|
- BX_DEBUG(("s[1].controller.control.disable_irq = %02x", (BX_HD_THIS s[1]).controller.control.disable_irq));
|
|
- BX_DEBUG(("SEEK completed. error_register = %02x", BX_SELECTED_CONTROLLER.error_register));
|
|
- raise_interrupt();
|
|
+ BX_SELECTED_CONTROLLER(channel).error_register = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
|
|
+ BX_DEBUG(("s[0].controller.control.disable_irq = %02x", (BX_HD_THIS channels[channel].drives[0]).controller.control.disable_irq));
|
|
+ BX_DEBUG(("s[1].controller.control.disable_irq = %02x", (BX_HD_THIS channels[channel].drives[1]).controller.control.disable_irq));
|
|
+ BX_DEBUG(("SEEK completed. error_register = %02x", BX_SELECTED_CONTROLLER(channel).error_register));
|
|
+ raise_interrupt(channel);
|
|
BX_DEBUG(("SEEK interrupt completed"));
|
|
} else {
|
|
BX_ERROR(("write cmd 0x70 (SEEK) not supported for non-disk"));
|
|
- command_aborted(0x70);
|
|
+ command_aborted(channel, 0x70);
|
|
}
|
|
break;
|
|
|
|
@@ -1967,161 +2037,150 @@
|
|
// List all the write operations that are defined in the ATA/ATAPI spec
|
|
// that we don't support. Commands that are listed here will cause a
|
|
// BX_ERROR, which is non-fatal, and the command will be aborted.
|
|
- case 0x22: BX_ERROR(("write cmd 0x22 (READ LONG) not supported")); command_aborted(0x22); break;
|
|
- case 0x23: BX_ERROR(("write cmd 0x23 (READ LONG NO RETRY) not supported")); command_aborted(0x23); break;
|
|
- case 0x24: BX_ERROR(("write cmd 0x24 (READ SECTORS EXT) not supported"));command_aborted(0x24); break;
|
|
- case 0x25: BX_ERROR(("write cmd 0x25 (READ DMA EXT) not supported"));command_aborted(0x25); break;
|
|
- case 0x26: BX_ERROR(("write cmd 0x26 (READ DMA QUEUED EXT) not supported"));command_aborted(0x26); break;
|
|
- case 0x27: BX_ERROR(("write cmd 0x27 (READ NATIVE MAX ADDRESS EXT) not supported"));command_aborted(0x27); break;
|
|
- case 0x29: BX_ERROR(("write cmd 0x29 (READ MULTIPLE EXT) not supported"));command_aborted(0x29); break;
|
|
- case 0x2A: BX_ERROR(("write cmd 0x2A (READ STREAM DMA) not supported"));command_aborted(0x2A); break;
|
|
- case 0x2B: BX_ERROR(("write cmd 0x2B (READ STREAM PIO) not supported"));command_aborted(0x2B); break;
|
|
- case 0x2F: BX_ERROR(("write cmd 0x2F (READ LOG EXT) not supported"));command_aborted(0x2F); break;
|
|
- case 0x31: BX_ERROR(("write cmd 0x31 (WRITE SECTORS NO RETRY) not supported")); command_aborted(0x31); break;
|
|
- case 0x32: BX_ERROR(("write cmd 0x32 (WRITE LONG) not supported")); command_aborted(0x32); break;
|
|
- case 0x33: BX_ERROR(("write cmd 0x33 (WRITE LONG NO RETRY) not supported")); command_aborted(0x33); break;
|
|
- case 0x34: BX_ERROR(("write cmd 0x34 (WRITE SECTORS EXT) not supported"));command_aborted(0x34); break;
|
|
- case 0x35: BX_ERROR(("write cmd 0x35 (WRITE DMA EXT) not supported"));command_aborted(0x35); break;
|
|
- case 0x36: BX_ERROR(("write cmd 0x36 (WRITE DMA QUEUED EXT) not supported"));command_aborted(0x36); break;
|
|
- case 0x37: BX_ERROR(("write cmd 0x37 (SET MAX ADDRESS EXT) not supported"));command_aborted(0x37); break;
|
|
- case 0x38: BX_ERROR(("write cmd 0x38 (CFA WRITE SECTORS W/OUT ERASE) not supported"));command_aborted(0x38); break;
|
|
- case 0x39: BX_ERROR(("write cmd 0x39 (WRITE MULTIPLE EXT) not supported"));command_aborted(0x39); break;
|
|
- case 0x3A: BX_ERROR(("write cmd 0x3A (WRITE STREAM DMA) not supported"));command_aborted(0x3A); break;
|
|
- case 0x3B: BX_ERROR(("write cmd 0x3B (WRITE STREAM PIO) not supported"));command_aborted(0x3B); break;
|
|
- case 0x3F: BX_ERROR(("write cmd 0x3F (WRITE LOG EXT) not supported"));command_aborted(0x3F); break;
|
|
- case 0x41: BX_ERROR(("write cmd 0x41 (READ VERIFY SECTORS NO RETRY) not supported")); command_aborted(0x41); break;
|
|
- case 0x42: BX_ERROR(("write cmd 0x42 (READ VERIFY SECTORS EXT) not supported"));command_aborted(0x42); break;
|
|
- case 0x50: BX_ERROR(("write cmd 0x50 (FORMAT TRACK) not supported")); command_aborted(0x50); break;
|
|
- case 0x51: BX_ERROR(("write cmd 0x51 (CONFIGURE STREAM) not supported"));command_aborted(0x51); break;
|
|
- case 0x87: BX_ERROR(("write cmd 0x87 (CFA TRANSLATE SECTOR) not supported"));command_aborted(0x87); break;
|
|
- case 0x92: BX_ERROR(("write cmd 0x92 (DOWNLOAD MICROCODE) not supported"));command_aborted(0x92); break;
|
|
- case 0x94: BX_ERROR(("write cmd 0x94 (STANDBY IMMEDIATE) not supported")); command_aborted(0x94); break;
|
|
- case 0x95: BX_ERROR(("write cmd 0x95 (IDLE IMMEDIATE) not supported")); command_aborted(0x95); break;
|
|
- case 0x96: BX_ERROR(("write cmd 0x96 (STANDBY) not supported")); command_aborted(0x96); break;
|
|
- case 0x97: BX_ERROR(("write cmd 0x97 (IDLE) not supported")); command_aborted(0x97); break;
|
|
- case 0x98: BX_ERROR(("write cmd 0x98 (CHECK POWER MODE) not supported")); command_aborted(0x98); break;
|
|
- case 0x99: BX_ERROR(("write cmd 0x99 (SLEEP) not supported")); command_aborted(0x99); break;
|
|
- case 0xB0: BX_ERROR(("write cmd 0xB0 (SMART commands) not supported"));command_aborted(0xB0); break;
|
|
- case 0xB1: BX_ERROR(("write cmd 0xB1 (DEVICE CONFIGURATION commands) not supported"));command_aborted(0xB1); break;
|
|
- case 0xC0: BX_ERROR(("write cmd 0xC0 (CFA ERASE SECTORS) not supported"));command_aborted(0xC0); break;
|
|
- case 0xC4: BX_ERROR(("write cmd 0xC4 (READ MULTIPLE) not supported"));command_aborted(0xC4); break;
|
|
- case 0xC5: BX_ERROR(("write cmd 0xC5 (WRITE MULTIPLE) not supported"));command_aborted(0xC5); break;
|
|
- case 0xC7: BX_ERROR(("write cmd 0xC7 (READ DMA QUEUED) not supported"));command_aborted(0xC7); break;
|
|
- case 0xC8: BX_ERROR(("write cmd 0xC8 (READ DMA) not supported"));command_aborted(0xC8); break;
|
|
- case 0xC9: BX_ERROR(("write cmd 0xC9 (READ DMA NO RETRY) not supported")); command_aborted(0xC9); break;
|
|
- case 0xCA: BX_ERROR(("write cmd 0xCA (WRITE DMA) not supported"));command_aborted(0xCA); break;
|
|
- case 0xCC: BX_ERROR(("write cmd 0xCC (WRITE DMA QUEUED) not supported"));command_aborted(0xCC); break;
|
|
- case 0xCD: BX_ERROR(("write cmd 0xCD (CFA WRITE MULTIPLE W/OUT ERASE) not supported"));command_aborted(0xCD); break;
|
|
- case 0xD1: BX_ERROR(("write cmd 0xD1 (CHECK MEDIA CARD TYPE) not supported"));command_aborted(0xD1); break;
|
|
- case 0xDA: BX_ERROR(("write cmd 0xDA (GET MEDIA STATUS) not supported"));command_aborted(0xDA); break;
|
|
- case 0xDE: BX_ERROR(("write cmd 0xDE (MEDIA LOCK) not supported"));command_aborted(0xDE); break;
|
|
- case 0xDF: BX_ERROR(("write cmd 0xDF (MEDIA UNLOCK) not supported"));command_aborted(0xDF); break;
|
|
- case 0xE0: BX_ERROR(("write cmd 0xE0 (STANDBY IMMEDIATE) not supported"));command_aborted(0xE0); break;
|
|
- case 0xE1: BX_ERROR(("write cmd 0xE1 (IDLE IMMEDIATE) not supported"));command_aborted(0xE1); break;
|
|
- case 0xE2: BX_ERROR(("write cmd 0xE2 (STANDBY) not supported"));command_aborted(0xE2); break;
|
|
- case 0xE3: BX_ERROR(("write cmd 0xE3 (IDLE) not supported"));command_aborted(0xE3); break;
|
|
- case 0xE4: BX_ERROR(("write cmd 0xE4 (READ BUFFER) not supported"));command_aborted(0xE4); break;
|
|
- case 0xE6: BX_ERROR(("write cmd 0xE6 (SLEEP) not supported"));command_aborted(0xE6); break;
|
|
- case 0xE7: BX_ERROR(("write cmd 0xE7 (FLUSH CACHE) not supported"));command_aborted(0xE7); break;
|
|
- case 0xE8: BX_ERROR(("write cmd 0xE8 (WRITE BUFFER) not supported"));command_aborted(0xE8); break;
|
|
- case 0xEA: BX_ERROR(("write cmd 0xEA (FLUSH CACHE EXT) not supported"));command_aborted(0xEA); break;
|
|
- case 0xED: BX_ERROR(("write cmd 0xED (MEDIA EJECT) not supported"));command_aborted(0xED); break;
|
|
- case 0xF1: BX_ERROR(("write cmd 0xF1 (SECURITY SET PASSWORD) not supported"));command_aborted(0xF1); break;
|
|
- case 0xF2: BX_ERROR(("write cmd 0xF2 (SECURITY UNLOCK) not supported"));command_aborted(0xF2); break;
|
|
- case 0xF3: BX_ERROR(("write cmd 0xF3 (SECURITY ERASE PREPARE) not supported"));command_aborted(0xF3); break;
|
|
- case 0xF4: BX_ERROR(("write cmd 0xF4 (SECURITY ERASE UNIT) not supported"));command_aborted(0xF4); break;
|
|
- case 0xF5: BX_ERROR(("write cmd 0xF5 (SECURITY FREEZE LOCK) not supported"));command_aborted(0xF5); break;
|
|
- case 0xF6: BX_ERROR(("write cmd 0xF6 (SECURITY DISABLE PASSWORD) not supported"));command_aborted(0xF6); break;
|
|
- case 0xF8: BX_ERROR(("write cmd 0xF8 (READ NATIVE MAX ADDRESS) not supported"));command_aborted(0xF8); break;
|
|
- case 0xF9: BX_ERROR(("write cmd 0xF9 (SET MAX ADDRESS) not supported"));command_aborted(0xF9); break;
|
|
+ case 0x22: BX_ERROR(("write cmd 0x22 (READ LONG) not supported")); command_aborted(channel, 0x22); break;
|
|
+ case 0x23: BX_ERROR(("write cmd 0x23 (READ LONG NO RETRY) not supported")); command_aborted(channel, 0x23); break;
|
|
+ case 0x24: BX_ERROR(("write cmd 0x24 (READ SECTORS EXT) not supported"));command_aborted(channel, 0x24); break;
|
|
+ case 0x25: BX_ERROR(("write cmd 0x25 (READ DMA EXT) not supported"));command_aborted(channel, 0x25); break;
|
|
+ case 0x26: BX_ERROR(("write cmd 0x26 (READ DMA QUEUED EXT) not supported"));command_aborted(channel, 0x26); break;
|
|
+ case 0x27: BX_ERROR(("write cmd 0x27 (READ NATIVE MAX ADDRESS EXT) not supported"));command_aborted(channel, 0x27); break;
|
|
+ case 0x29: BX_ERROR(("write cmd 0x29 (READ MULTIPLE EXT) not supported"));command_aborted(channel, 0x29); break;
|
|
+ case 0x2A: BX_ERROR(("write cmd 0x2A (READ STREAM DMA) not supported"));command_aborted(channel, 0x2A); break;
|
|
+ case 0x2B: BX_ERROR(("write cmd 0x2B (READ STREAM PIO) not supported"));command_aborted(channel, 0x2B); break;
|
|
+ case 0x2F: BX_ERROR(("write cmd 0x2F (READ LOG EXT) not supported"));command_aborted(channel, 0x2F); break;
|
|
+ case 0x31: BX_ERROR(("write cmd 0x31 (WRITE SECTORS NO RETRY) not supported")); command_aborted(channel, 0x31); break;
|
|
+ case 0x32: BX_ERROR(("write cmd 0x32 (WRITE LONG) not supported")); command_aborted(channel, 0x32); break;
|
|
+ case 0x33: BX_ERROR(("write cmd 0x33 (WRITE LONG NO RETRY) not supported")); command_aborted(channel, 0x33); break;
|
|
+ case 0x34: BX_ERROR(("write cmd 0x34 (WRITE SECTORS EXT) not supported"));command_aborted(channel, 0x34); break;
|
|
+ case 0x35: BX_ERROR(("write cmd 0x35 (WRITE DMA EXT) not supported"));command_aborted(channel, 0x35); break;
|
|
+ case 0x36: BX_ERROR(("write cmd 0x36 (WRITE DMA QUEUED EXT) not supported"));command_aborted(channel, 0x36); break;
|
|
+ case 0x37: BX_ERROR(("write cmd 0x37 (SET MAX ADDRESS EXT) not supported"));command_aborted(channel, 0x37); break;
|
|
+ case 0x38: BX_ERROR(("write cmd 0x38 (CFA WRITE SECTORS W/OUT ERASE) not supported"));command_aborted(channel, 0x38); break;
|
|
+ case 0x39: BX_ERROR(("write cmd 0x39 (WRITE MULTIPLE EXT) not supported"));command_aborted(channel, 0x39); break;
|
|
+ case 0x3A: BX_ERROR(("write cmd 0x3A (WRITE STREAM DMA) not supported"));command_aborted(channel, 0x3A); break;
|
|
+ case 0x3B: BX_ERROR(("write cmd 0x3B (WRITE STREAM PIO) not supported"));command_aborted(channel, 0x3B); break;
|
|
+ case 0x3F: BX_ERROR(("write cmd 0x3F (WRITE LOG EXT) not supported"));command_aborted(channel, 0x3F); break;
|
|
+ case 0x41: BX_ERROR(("write cmd 0x41 (READ VERIFY SECTORS NO RETRY) not supported")); command_aborted(channel, 0x41); break;
|
|
+ case 0x42: BX_ERROR(("write cmd 0x42 (READ VERIFY SECTORS EXT) not supported"));command_aborted(channel, 0x42); break;
|
|
+ case 0x50: BX_ERROR(("write cmd 0x50 (FORMAT TRACK) not supported")); command_aborted(channel, 0x50); break;
|
|
+ case 0x51: BX_ERROR(("write cmd 0x51 (CONFIGURE STREAM) not supported"));command_aborted(channel, 0x51); break;
|
|
+ case 0x87: BX_ERROR(("write cmd 0x87 (CFA TRANSLATE SECTOR) not supported"));command_aborted(channel, 0x87); break;
|
|
+ case 0x92: BX_ERROR(("write cmd 0x92 (DOWNLOAD MICROCODE) not supported"));command_aborted(channel, 0x92); break;
|
|
+ case 0x94: BX_ERROR(("write cmd 0x94 (STANDBY IMMEDIATE) not supported")); command_aborted(channel, 0x94); break;
|
|
+ case 0x95: BX_ERROR(("write cmd 0x95 (IDLE IMMEDIATE) not supported")); command_aborted(channel, 0x95); break;
|
|
+ case 0x96: BX_ERROR(("write cmd 0x96 (STANDBY) not supported")); command_aborted(channel, 0x96); break;
|
|
+ case 0x97: BX_ERROR(("write cmd 0x97 (IDLE) not supported")); command_aborted(channel, 0x97); break;
|
|
+ case 0x98: BX_ERROR(("write cmd 0x98 (CHECK POWER MODE) not supported")); command_aborted(channel, 0x98); break;
|
|
+ case 0x99: BX_ERROR(("write cmd 0x99 (SLEEP) not supported")); command_aborted(channel, 0x99); break;
|
|
+ case 0xB0: BX_ERROR(("write cmd 0xB0 (SMART commands) not supported"));command_aborted(channel, 0xB0); break;
|
|
+ case 0xB1: BX_ERROR(("write cmd 0xB1 (DEVICE CONFIGURATION commands) not supported"));command_aborted(channel, 0xB1); break;
|
|
+ case 0xC0: BX_ERROR(("write cmd 0xC0 (CFA ERASE SECTORS) not supported"));command_aborted(channel, 0xC0); break;
|
|
+ case 0xC4: BX_ERROR(("write cmd 0xC4 (READ MULTIPLE) not supported"));command_aborted(channel, 0xC4); break;
|
|
+ case 0xC5: BX_ERROR(("write cmd 0xC5 (WRITE MULTIPLE) not supported"));command_aborted(channel, 0xC5); break;
|
|
+ case 0xC7: BX_ERROR(("write cmd 0xC7 (READ DMA QUEUED) not supported"));command_aborted(channel, 0xC7); break;
|
|
+ case 0xC8: BX_ERROR(("write cmd 0xC8 (READ DMA) not supported"));command_aborted(channel, 0xC8); break;
|
|
+ case 0xC9: BX_ERROR(("write cmd 0xC9 (READ DMA NO RETRY) not supported")); command_aborted(channel, 0xC9); break;
|
|
+ case 0xCA: BX_ERROR(("write cmd 0xCA (WRITE DMA) not supported"));command_aborted(channel, 0xCA); break;
|
|
+ case 0xCC: BX_ERROR(("write cmd 0xCC (WRITE DMA QUEUED) not supported"));command_aborted(channel, 0xCC); break;
|
|
+ case 0xCD: BX_ERROR(("write cmd 0xCD (CFA WRITE MULTIPLE W/OUT ERASE) not supported"));command_aborted(channel, 0xCD); break;
|
|
+ case 0xD1: BX_ERROR(("write cmd 0xD1 (CHECK MEDIA CARD TYPE) not supported"));command_aborted(channel, 0xD1); break;
|
|
+ case 0xDA: BX_ERROR(("write cmd 0xDA (GET MEDIA STATUS) not supported"));command_aborted(channel, 0xDA); break;
|
|
+ case 0xDE: BX_ERROR(("write cmd 0xDE (MEDIA LOCK) not supported"));command_aborted(channel, 0xDE); break;
|
|
+ case 0xDF: BX_ERROR(("write cmd 0xDF (MEDIA UNLOCK) not supported"));command_aborted(channel, 0xDF); break;
|
|
+ case 0xE0: BX_ERROR(("write cmd 0xE0 (STANDBY IMMEDIATE) not supported"));command_aborted(channel, 0xE0); break;
|
|
+ case 0xE1: BX_ERROR(("write cmd 0xE1 (IDLE IMMEDIATE) not supported"));command_aborted(channel, 0xE1); break;
|
|
+ case 0xE2: BX_ERROR(("write cmd 0xE2 (STANDBY) not supported"));command_aborted(channel, 0xE2); break;
|
|
+ case 0xE3: BX_ERROR(("write cmd 0xE3 (IDLE) not supported"));command_aborted(channel, 0xE3); break;
|
|
+ case 0xE4: BX_ERROR(("write cmd 0xE4 (READ BUFFER) not supported"));command_aborted(channel, 0xE4); break;
|
|
+ case 0xE6: BX_ERROR(("write cmd 0xE6 (SLEEP) not supported"));command_aborted(channel, 0xE6); break;
|
|
+ case 0xE7: BX_ERROR(("write cmd 0xE7 (FLUSH CACHE) not supported"));command_aborted(channel, 0xE7); break;
|
|
+ case 0xE8: BX_ERROR(("write cmd 0xE8 (WRITE BUFFER) not supported"));command_aborted(channel, 0xE8); break;
|
|
+ case 0xEA: BX_ERROR(("write cmd 0xEA (FLUSH CACHE EXT) not supported"));command_aborted(channel, 0xEA); break;
|
|
+ case 0xED: BX_ERROR(("write cmd 0xED (MEDIA EJECT) not supported"));command_aborted(channel, 0xED); break;
|
|
+ case 0xF1: BX_ERROR(("write cmd 0xF1 (SECURITY SET PASSWORD) not supported"));command_aborted(channel, 0xF1); break;
|
|
+ case 0xF2: BX_ERROR(("write cmd 0xF2 (SECURITY UNLOCK) not supported"));command_aborted(channel, 0xF2); break;
|
|
+ case 0xF3: BX_ERROR(("write cmd 0xF3 (SECURITY ERASE PREPARE) not supported"));command_aborted(channel, 0xF3); break;
|
|
+ case 0xF4: BX_ERROR(("write cmd 0xF4 (SECURITY ERASE UNIT) not supported"));command_aborted(channel, 0xF4); break;
|
|
+ case 0xF5: BX_ERROR(("write cmd 0xF5 (SECURITY FREEZE LOCK) not supported"));command_aborted(channel, 0xF5); break;
|
|
+ case 0xF6: BX_ERROR(("write cmd 0xF6 (SECURITY DISABLE PASSWORD) not supported"));command_aborted(channel, 0xF6); break;
|
|
+ case 0xF8: BX_ERROR(("write cmd 0xF8 (READ NATIVE MAX ADDRESS) not supported"));command_aborted(channel, 0xF8); break;
|
|
+ case 0xF9: BX_ERROR(("write cmd 0xF9 (SET MAX ADDRESS) not supported"));command_aborted(channel, 0xF9); break;
|
|
|
|
default:
|
|
BX_PANIC(("IO write(1f7h): command 0x%02x", (unsigned) value));
|
|
// if user foolishly decides to continue, abort the command
|
|
// so that the software knows the drive didn't understand it.
|
|
- command_aborted(value);
|
|
+ command_aborted(channel, value);
|
|
}
|
|
break;
|
|
|
|
- case 0x3f6: // hard disk adapter control
|
|
+ case 0x16: // hard disk adapter control 0x3f6
|
|
// (mch) Even if device 1 was selected, a write to this register
|
|
// goes to device 0 (if device 1 is absent)
|
|
|
|
- prev_control_reset = BX_SELECTED_CONTROLLER.control.reset;
|
|
- BX_HD_THIS s[0].controller.control.reset = value & 0x04;
|
|
- BX_HD_THIS s[1].controller.control.reset = value & 0x04;
|
|
- // CGS: was: BX_SELECTED_CONTROLLER.control.disable_irq = value & 0x02;
|
|
- BX_HD_THIS s[0].controller.control.disable_irq = value & 0x02;
|
|
- BX_HD_THIS s[1].controller.control.disable_irq = value & 0x02;
|
|
- //BX_DEBUG(( "adpater control reg: reset controller = %d",
|
|
- // (unsigned) (BX_SELECTED_CONTROLLER.control.reset) ? 1 : 0 ));
|
|
- //BX_DEBUG(( "adpater control reg: disable_irq(14) = %d",
|
|
- // (unsigned) (BX_SELECTED_CONTROLLER.control.disable_irq) ? 1 : 0 ));
|
|
- if (!prev_control_reset && BX_SELECTED_CONTROLLER.control.reset) {
|
|
+ prev_control_reset = BX_SELECTED_CONTROLLER(channel).control.reset;
|
|
+ BX_HD_THIS channels[channel].drives[0].controller.control.reset = value & 0x04;
|
|
+ BX_HD_THIS channels[channel].drives[1].controller.control.reset = value & 0x04;
|
|
+ // CGS: was: BX_SELECTED_CONTROLLER(channel).control.disable_irq = value & 0x02;
|
|
+ BX_HD_THIS channels[channel].drives[0].controller.control.disable_irq = value & 0x02;
|
|
+ BX_HD_THIS channels[channel].drives[1].controller.control.disable_irq = value & 0x02;
|
|
+
|
|
+ BX_DEBUG(( "adpater control reg: reset controller = %d",
|
|
+ (unsigned) (BX_SELECTED_CONTROLLER(channel).control.reset) ? 1 : 0 ));
|
|
+ BX_DEBUG(( "adpater control reg: disable_irq(X) = %d",
|
|
+ (unsigned) (BX_SELECTED_CONTROLLER(channel).control.disable_irq) ? 1 : 0 ));
|
|
+
|
|
+ if (!prev_control_reset && BX_SELECTED_CONTROLLER(channel).control.reset) {
|
|
// transition from 0 to 1 causes all drives to reset
|
|
BX_DEBUG(("hard drive: RESET"));
|
|
|
|
// (mch) Set BSY, drive not ready
|
|
for (int id = 0; id < 2; id++) {
|
|
- BX_CONTROLLER(id).status.busy = 1;
|
|
- BX_CONTROLLER(id).status.drive_ready = 0;
|
|
- BX_CONTROLLER(id).reset_in_progress = 1;
|
|
+ BX_CONTROLLER(channel,id).status.busy = 1;
|
|
+ BX_CONTROLLER(channel,id).status.drive_ready = 0;
|
|
+ BX_CONTROLLER(channel,id).reset_in_progress = 1;
|
|
|
|
- BX_CONTROLLER(id).status.write_fault = 0;
|
|
- BX_CONTROLLER(id).status.seek_complete = 1;
|
|
- BX_CONTROLLER(id).status.drq = 0;
|
|
- BX_CONTROLLER(id).status.corrected_data = 0;
|
|
- BX_CONTROLLER(id).status.err = 0;
|
|
+ BX_CONTROLLER(channel,id).status.write_fault = 0;
|
|
+ BX_CONTROLLER(channel,id).status.seek_complete = 1;
|
|
+ BX_CONTROLLER(channel,id).status.drq = 0;
|
|
+ BX_CONTROLLER(channel,id).status.corrected_data = 0;
|
|
+ BX_CONTROLLER(channel,id).status.err = 0;
|
|
|
|
- BX_CONTROLLER(id).error_register = 0x01; // diagnostic code: no error
|
|
+ BX_CONTROLLER(channel,id).error_register = 0x01; // diagnostic code: no error
|
|
|
|
- BX_CONTROLLER(id).current_command = 0x00;
|
|
- BX_CONTROLLER(id).buffer_index = 0;
|
|
+ BX_CONTROLLER(channel,id).current_command = 0x00;
|
|
+ BX_CONTROLLER(channel,id).buffer_index = 0;
|
|
|
|
- BX_CONTROLLER(id).sectors_per_block = 0x80;
|
|
- BX_CONTROLLER(id).lba_mode = 0;
|
|
+ BX_CONTROLLER(channel,id).sectors_per_block = 0x80;
|
|
+ BX_CONTROLLER(channel,id).lba_mode = 0;
|
|
|
|
- BX_CONTROLLER(id).control.disable_irq = 0;
|
|
+ BX_CONTROLLER(channel,id).control.disable_irq = 0;
|
|
}
|
|
- } else if (BX_SELECTED_CONTROLLER.reset_in_progress &&
|
|
- !BX_SELECTED_CONTROLLER.control.reset) {
|
|
+ } else if (BX_SELECTED_CONTROLLER(channel).reset_in_progress &&
|
|
+ !BX_SELECTED_CONTROLLER(channel).control.reset) {
|
|
// Clear BSY and DRDY
|
|
- BX_DEBUG(("Reset complete {%s}", DEVICE_TYPE_STRING));
|
|
+ BX_DEBUG(("Reset complete {%s}", BX_SELECTED_TYPE_STRING(channel)));
|
|
for (int id = 0; id < 2; id++) {
|
|
- BX_CONTROLLER(id).status.busy = 0;
|
|
- BX_CONTROLLER(id).status.drive_ready = 1;
|
|
- BX_CONTROLLER(id).reset_in_progress = 0;
|
|
+ BX_CONTROLLER(channel,id).status.busy = 0;
|
|
+ BX_CONTROLLER(channel,id).status.drive_ready = 1;
|
|
+ BX_CONTROLLER(channel,id).reset_in_progress = 0;
|
|
|
|
// Device signature
|
|
- if (BX_HD_THIS s[id].device_type == IDE_DISK) {
|
|
- BX_CONTROLLER(id).head_no = 0;
|
|
- BX_CONTROLLER(id).sector_count = 1;
|
|
- BX_CONTROLLER(id).sector_no = 1;
|
|
- BX_CONTROLLER(id).cylinder_no = 0;
|
|
+ if (BX_DRIVE_IS_HD(channel,id)) {
|
|
+ BX_CONTROLLER(channel,id).head_no = 0;
|
|
+ BX_CONTROLLER(channel,id).sector_count = 1;
|
|
+ BX_CONTROLLER(channel,id).sector_no = 1;
|
|
+ BX_CONTROLLER(channel,id).cylinder_no = 0;
|
|
} else {
|
|
- BX_CONTROLLER(id).head_no = 0;
|
|
- BX_CONTROLLER(id).sector_count = 1;
|
|
- BX_CONTROLLER(id).sector_no = 1;
|
|
- BX_CONTROLLER(id).cylinder_no = 0xeb14;
|
|
+ BX_CONTROLLER(channel,id).head_no = 0;
|
|
+ BX_CONTROLLER(channel,id).sector_count = 1;
|
|
+ BX_CONTROLLER(channel,id).sector_no = 1;
|
|
+ BX_CONTROLLER(channel,id).cylinder_no = 0xeb14;
|
|
}
|
|
}
|
|
}
|
|
- BX_DEBUG(("s[0].controller.control.disable_irq = %02x", (BX_HD_THIS s[0]).controller.control.disable_irq));
|
|
- BX_DEBUG(("s[1].controller.control.disable_irq = %02x", (BX_HD_THIS s[1]).controller.control.disable_irq));
|
|
+ BX_DEBUG(("s[0].controller.control.disable_irq = %02x", (BX_HD_THIS channels[channel].drives[0]).controller.control.disable_irq));
|
|
+ BX_DEBUG(("s[1].controller.control.disable_irq = %02x", (BX_HD_THIS channels[channel].drives[1]).controller.control.disable_irq));
|
|
break;
|
|
-#if 0
|
|
- // you'll need these to support second IDE controller, not needed yet.
|
|
- case 0x170:
|
|
- case 0x171:
|
|
- case 0x172:
|
|
- case 0x173:
|
|
- case 0x174:
|
|
- case 0x175:
|
|
- case 0x176:
|
|
- case 0x177:
|
|
- BX_DEBUG(("ignoring write to 0x%04x", address));
|
|
- break;
|
|
-#endif
|
|
|
|
default:
|
|
BX_PANIC(("hard drive: io write to address %x = %02x",
|
|
@@ -2132,30 +2191,32 @@
|
|
void
|
|
bx_hard_drive_c::close_harddrive(void)
|
|
{
|
|
- BX_HD_THIS s[0].hard_drive->close();
|
|
- BX_HD_THIS s[1].hard_drive->close();
|
|
+ for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
|
|
+ BX_HD_THIS channels[channel].drives[0].hard_drive->close();
|
|
+ BX_HD_THIS channels[channel].drives[1].hard_drive->close();
|
|
+ }
|
|
}
|
|
|
|
|
|
Boolean
|
|
-bx_hard_drive_c::calculate_logical_address(Bit32u *sector)
|
|
+bx_hard_drive_c::calculate_logical_address(Bit8u channel, Bit32u *sector)
|
|
{
|
|
Bit32u logical_sector;
|
|
|
|
- if (BX_SELECTED_CONTROLLER.lba_mode) {
|
|
- //bx_printf ("disk: calculate: %d %d %d\n", ((Bit32u)BX_SELECTED_CONTROLLER.head_no), ((Bit32u)BX_SELECTED_CONTROLLER.cylinder_no), (Bit32u)BX_SELECTED_CONTROLLER.sector_no);
|
|
- logical_sector = ((Bit32u)BX_SELECTED_CONTROLLER.head_no) << 24 |
|
|
- ((Bit32u)BX_SELECTED_CONTROLLER.cylinder_no) << 8 |
|
|
- (Bit32u)BX_SELECTED_CONTROLLER.sector_no;
|
|
+ if (BX_SELECTED_CONTROLLER(channel).lba_mode) {
|
|
+ //bx_printf ("disk: calculate: %d %d %d\n", ((Bit32u)BX_SELECTED_CONTROLLER(channel).head_no), ((Bit32u)BX_SELECTED_CONTROLLER(channel).cylinder_no), (Bit32u)BX_SELECTED_CONTROLLER(channel).sector_no);
|
|
+ logical_sector = ((Bit32u)BX_SELECTED_CONTROLLER(channel).head_no) << 24 |
|
|
+ ((Bit32u)BX_SELECTED_CONTROLLER(channel).cylinder_no) << 8 |
|
|
+ (Bit32u)BX_SELECTED_CONTROLLER(channel).sector_no;
|
|
//bx_printf ("disk: result: %u\n", logical_sector);
|
|
} else
|
|
- logical_sector = (BX_SELECTED_CONTROLLER.cylinder_no * BX_SELECTED_HD.hard_drive->heads *
|
|
- BX_SELECTED_HD.hard_drive->sectors) +
|
|
- (BX_SELECTED_CONTROLLER.head_no * BX_SELECTED_HD.hard_drive->sectors) +
|
|
- (BX_SELECTED_CONTROLLER.sector_no - 1);
|
|
+ logical_sector = (BX_SELECTED_CONTROLLER(channel).cylinder_no * BX_SELECTED_DRIVE(channel).hard_drive->heads *
|
|
+ BX_SELECTED_DRIVE(channel).hard_drive->sectors) +
|
|
+ (BX_SELECTED_CONTROLLER(channel).head_no * BX_SELECTED_DRIVE(channel).hard_drive->sectors) +
|
|
+ (BX_SELECTED_CONTROLLER(channel).sector_no - 1);
|
|
|
|
if (logical_sector >=
|
|
- (BX_SELECTED_HD.hard_drive->cylinders * BX_SELECTED_HD.hard_drive->heads * BX_SELECTED_HD.hard_drive->sectors)) {
|
|
+ (BX_SELECTED_DRIVE(channel).hard_drive->cylinders * BX_SELECTED_DRIVE(channel).hard_drive->heads * BX_SELECTED_DRIVE(channel).hard_drive->sectors)) {
|
|
BX_ERROR (("calc_log_addr: out of bounds"));
|
|
return false;
|
|
}
|
|
@@ -2164,246 +2225,238 @@
|
|
}
|
|
|
|
void
|
|
-bx_hard_drive_c::increment_address()
|
|
+bx_hard_drive_c::increment_address(Bit8u channel)
|
|
{
|
|
- BX_SELECTED_CONTROLLER.sector_count--;
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_count--;
|
|
|
|
- if (BX_SELECTED_CONTROLLER.lba_mode) {
|
|
+ if (BX_SELECTED_CONTROLLER(channel).lba_mode) {
|
|
Bit32u current_address;
|
|
- calculate_logical_address(¤t_address);
|
|
+ calculate_logical_address(channel, ¤t_address);
|
|
current_address++;
|
|
- BX_SELECTED_CONTROLLER.head_no = (current_address >> 24) & 0xf;
|
|
- BX_SELECTED_CONTROLLER.cylinder_no = (current_address >> 8) & 0xffff;
|
|
- BX_SELECTED_CONTROLLER.sector_no = (current_address) & 0xff;
|
|
+ BX_SELECTED_CONTROLLER(channel).head_no = (current_address >> 24) & 0xf;
|
|
+ BX_SELECTED_CONTROLLER(channel).cylinder_no = (current_address >> 8) & 0xffff;
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_no = (current_address) & 0xff;
|
|
} else {
|
|
- BX_SELECTED_CONTROLLER.sector_no++;
|
|
- if (BX_SELECTED_CONTROLLER.sector_no > BX_SELECTED_HD.hard_drive->sectors) {
|
|
- BX_SELECTED_CONTROLLER.sector_no = 1;
|
|
- BX_SELECTED_CONTROLLER.head_no++;
|
|
- if (BX_SELECTED_CONTROLLER.head_no >= BX_SELECTED_HD.hard_drive->heads) {
|
|
- BX_SELECTED_CONTROLLER.head_no = 0;
|
|
- BX_SELECTED_CONTROLLER.cylinder_no++;
|
|
- if (BX_SELECTED_CONTROLLER.cylinder_no >= BX_SELECTED_HD.hard_drive->cylinders)
|
|
- BX_SELECTED_CONTROLLER.cylinder_no = BX_SELECTED_HD.hard_drive->cylinders - 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_no++;
|
|
+ if (BX_SELECTED_CONTROLLER(channel).sector_no > BX_SELECTED_DRIVE(channel).hard_drive->sectors) {
|
|
+ BX_SELECTED_CONTROLLER(channel).sector_no = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).head_no++;
|
|
+ if (BX_SELECTED_CONTROLLER(channel).head_no >= BX_SELECTED_DRIVE(channel).hard_drive->heads) {
|
|
+ BX_SELECTED_CONTROLLER(channel).head_no = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).cylinder_no++;
|
|
+ if (BX_SELECTED_CONTROLLER(channel).cylinder_no >= BX_SELECTED_DRIVE(channel).hard_drive->cylinders)
|
|
+ BX_SELECTED_CONTROLLER(channel).cylinder_no = BX_SELECTED_DRIVE(channel).hard_drive->cylinders - 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
-bx_hard_drive_c::identify_ATAPI_drive(unsigned drive)
|
|
+bx_hard_drive_c::identify_ATAPI_drive(Bit8u channel)
|
|
{
|
|
unsigned i;
|
|
|
|
- if (drive != (unsigned)BX_HD_THIS drive_select) {
|
|
- BX_PANIC(("identify_drive panic (drive != drive_select)"));
|
|
- }
|
|
-
|
|
- BX_SELECTED_HD.id_drive[0] = (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0); // Removable CDROM, 50us response, 12 byte packets
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[0] = (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0); // Removable CDROM, 50us response, 12 byte packets
|
|
|
|
for (i = 1; i <= 9; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
const char* serial_number = " VT00001\0\0\0\0\0\0\0\0\0\0\0\0";
|
|
for (i = 0; i < 10; i++) {
|
|
- BX_SELECTED_HD.id_drive[10+i] = (serial_number[i*2] << 8) |
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[10+i] = (serial_number[i*2] << 8) |
|
|
serial_number[i*2 + 1];
|
|
}
|
|
|
|
for (i = 20; i <= 22; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
const char* firmware = "ALPHA1 ";
|
|
for (i = 0; i < strlen(firmware)/2; i++) {
|
|
- BX_SELECTED_HD.id_drive[23+i] = (firmware[i*2] << 8) |
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[23+i] = (firmware[i*2] << 8) |
|
|
firmware[i*2 + 1];
|
|
}
|
|
BX_ASSERT((23+i) == 27);
|
|
|
|
- for (i = 0; i < strlen((char *) model_no)/2; i++) {
|
|
- BX_SELECTED_HD.id_drive[27+i] = (model_no[i*2] << 8) |
|
|
- model_no[i*2 + 1];
|
|
+ for (i = 0; i < strlen((char *) BX_SELECTED_MODEL(channel))/2; i++) {
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[27+i] = (BX_SELECTED_MODEL(channel)[i*2] << 8) |
|
|
+ BX_SELECTED_MODEL(channel)[i*2 + 1];
|
|
}
|
|
BX_ASSERT((27+i) == 47);
|
|
|
|
- BX_SELECTED_HD.id_drive[47] = 0;
|
|
- BX_SELECTED_HD.id_drive[48] = 1; // 32 bits access
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[47] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[48] = 1; // 32 bits access
|
|
|
|
- BX_SELECTED_HD.id_drive[49] = (1 << 9); // LBA supported
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[49] = (1 << 9); // LBA supported
|
|
|
|
- BX_SELECTED_HD.id_drive[50] = 0;
|
|
- BX_SELECTED_HD.id_drive[51] = 0;
|
|
- BX_SELECTED_HD.id_drive[52] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[50] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[51] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[52] = 0;
|
|
|
|
- BX_SELECTED_HD.id_drive[53] = 3; // words 64-70, 54-58 valid
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[53] = 3; // words 64-70, 54-58 valid
|
|
|
|
for (i = 54; i <= 62; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
// copied from CFA540A
|
|
- BX_SELECTED_HD.id_drive[63] = 0x0103; // variable (DMA stuff)
|
|
- BX_SELECTED_HD.id_drive[64] = 0x0001; // PIO
|
|
- BX_SELECTED_HD.id_drive[65] = 0x00b4;
|
|
- BX_SELECTED_HD.id_drive[66] = 0x00b4;
|
|
- BX_SELECTED_HD.id_drive[67] = 0x012c;
|
|
- BX_SELECTED_HD.id_drive[68] = 0x00b4;
|
|
-
|
|
- BX_SELECTED_HD.id_drive[69] = 0;
|
|
- BX_SELECTED_HD.id_drive[70] = 0;
|
|
- BX_SELECTED_HD.id_drive[71] = 30; // faked
|
|
- BX_SELECTED_HD.id_drive[72] = 30; // faked
|
|
- BX_SELECTED_HD.id_drive[73] = 0;
|
|
- BX_SELECTED_HD.id_drive[74] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[63] = 0x0103; // variable (DMA stuff)
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[64] = 0x0001; // PIO
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[65] = 0x00b4;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[66] = 0x00b4;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[67] = 0x012c;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[68] = 0x00b4;
|
|
+
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[69] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[70] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[71] = 30; // faked
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[72] = 30; // faked
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[73] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[74] = 0;
|
|
|
|
- BX_SELECTED_HD.id_drive[75] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[75] = 0;
|
|
|
|
for (i = 76; i <= 79; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
- BX_SELECTED_HD.id_drive[80] = 0x1e; // supports up to ATA/ATAPI-4
|
|
- BX_SELECTED_HD.id_drive[81] = 0;
|
|
- BX_SELECTED_HD.id_drive[82] = 0;
|
|
- BX_SELECTED_HD.id_drive[83] = 0;
|
|
- BX_SELECTED_HD.id_drive[84] = 0;
|
|
- BX_SELECTED_HD.id_drive[85] = 0;
|
|
- BX_SELECTED_HD.id_drive[86] = 0;
|
|
- BX_SELECTED_HD.id_drive[87] = 0;
|
|
- BX_SELECTED_HD.id_drive[88] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[80] = 0x1e; // supports up to ATA/ATAPI-4
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[81] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[82] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[83] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[84] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[85] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[86] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[87] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[88] = 0;
|
|
|
|
for (i = 89; i <= 126; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
- BX_SELECTED_HD.id_drive[127] = 0;
|
|
- BX_SELECTED_HD.id_drive[128] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[127] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[128] = 0;
|
|
|
|
for (i = 129; i <= 159; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
for (i = 160; i <= 255; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
// now convert the id_drive array (native 256 word format) to
|
|
// the controller buffer (512 bytes)
|
|
Bit16u temp16;
|
|
for (i = 0; i <= 255; i++) {
|
|
- temp16 = BX_SELECTED_HD.id_drive[i];
|
|
- BX_SELECTED_CONTROLLER.buffer[i*2] = temp16 & 0x00ff;
|
|
- BX_SELECTED_CONTROLLER.buffer[i*2+1] = temp16 >> 8;
|
|
+ temp16 = BX_SELECTED_DRIVE(channel).id_drive[i];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[i*2] = temp16 & 0x00ff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[i*2+1] = temp16 >> 8;
|
|
}
|
|
}
|
|
|
|
void
|
|
-bx_hard_drive_c::identify_drive(unsigned drive)
|
|
+bx_hard_drive_c::identify_drive(Bit8u channel)
|
|
{
|
|
unsigned i;
|
|
Bit32u temp32;
|
|
Bit16u temp16;
|
|
|
|
- if (drive != BX_HD_THIS drive_select) {
|
|
- BX_PANIC(("identify_drive panic (drive != drive_select)"));
|
|
- }
|
|
-
|
|
#if defined(CONNER_CFA540A)
|
|
- BX_SELECTED_HD.id_drive[0] = 0x0c5a;
|
|
- BX_SELECTED_HD.id_drive[1] = 0x0418;
|
|
- BX_SELECTED_HD.id_drive[2] = 0;
|
|
- BX_SELECTED_HD.id_drive[3] = BX_SELECTED_HD.hard_drive->heads;
|
|
- BX_SELECTED_HD.id_drive[4] = 0x9fb7;
|
|
- BX_SELECTED_HD.id_drive[5] = 0x0289;
|
|
- BX_SELECTED_HD.id_drive[6] = BX_SELECTED_HD.hard_drive->sectors;
|
|
- BX_SELECTED_HD.id_drive[7] = 0x0030;
|
|
- BX_SELECTED_HD.id_drive[8] = 0x000a;
|
|
- BX_SELECTED_HD.id_drive[9] = 0x0000;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[0] = 0x0c5a;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[1] = 0x0418;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[2] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[3] = BX_SELECTED_DRIVE(channel).hard_drive->heads;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[4] = 0x9fb7;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[5] = 0x0289;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[6] = BX_SELECTED_DRIVE(channel).hard_drive->sectors;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[7] = 0x0030;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[8] = 0x000a;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[9] = 0x0000;
|
|
|
|
char* serial_number = " CA00GSQ\0\0\0\0\0\0\0\0\0\0\0\0";
|
|
for (i = 0; i < 10; i++) {
|
|
- BX_SELECTED_HD.id_drive[10+i] = (serial_number[i*2] << 8) |
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[10+i] = (serial_number[i*2] << 8) |
|
|
serial_number[i*2 + 1];
|
|
}
|
|
|
|
- BX_SELECTED_HD.id_drive[20] = 3;
|
|
- BX_SELECTED_HD.id_drive[21] = 512; // 512 Sectors = 256kB cache
|
|
- BX_SELECTED_HD.id_drive[22] = 4;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[20] = 3;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[21] = 512; // 512 Sectors = 256kB cache
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[22] = 4;
|
|
|
|
char* firmware = "8FT054 ";
|
|
for (i = 0; i < strlen(firmware)/2; i++) {
|
|
- BX_SELECTED_HD.id_drive[23+i] = (firmware[i*2] << 8) |
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[23+i] = (firmware[i*2] << 8) |
|
|
firmware[i*2 + 1];
|
|
}
|
|
BX_ASSERT((23+i) == 27);
|
|
|
|
char* model = "Conner Peripherals 540MB - CFA540A ";
|
|
for (i = 0; i < strlen(model)/2; i++) {
|
|
- BX_SELECTED_HD.id_drive[27+i] = (model[i*2] << 8) |
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[27+i] = (model[i*2] << 8) |
|
|
model[i*2 + 1];
|
|
}
|
|
BX_ASSERT((27+i) == 47);
|
|
|
|
- BX_SELECTED_HD.id_drive[47] = 0x8080; // multiple mode identification
|
|
- BX_SELECTED_HD.id_drive[48] = 0;
|
|
- BX_SELECTED_HD.id_drive[49] = 0x0f01;
|
|
-
|
|
- BX_SELECTED_HD.id_drive[50] = 0;
|
|
-
|
|
- BX_SELECTED_HD.id_drive[51] = 0;
|
|
- BX_SELECTED_HD.id_drive[52] = 0x0002;
|
|
- BX_SELECTED_HD.id_drive[53] = 0x0003;
|
|
- BX_SELECTED_HD.id_drive[54] = 0x0418;
|
|
-
|
|
- BX_SELECTED_HD.id_drive[55] = BX_SELECTED_HD.hard_drive->heads;
|
|
- BX_SELECTED_HD.id_drive[56] = BX_SELECTED_HD.hard_drive->sectors;
|
|
-
|
|
- BX_SELECTED_HD.id_drive[57] = 0x1e80;
|
|
- BX_SELECTED_HD.id_drive[58] = 0x0010;
|
|
- BX_SELECTED_HD.id_drive[59] = 0x0100 | BX_SELECTED_CONTROLLER.sectors_per_block;
|
|
- BX_SELECTED_HD.id_drive[60] = 0x20e0;
|
|
- BX_SELECTED_HD.id_drive[61] = 0x0010;
|
|
-
|
|
- BX_SELECTED_HD.id_drive[62] = 0;
|
|
-
|
|
- BX_SELECTED_HD.id_drive[63] = 0x0103; // variable (DMA stuff)
|
|
- BX_SELECTED_HD.id_drive[64] = 0x0001; // PIO
|
|
- BX_SELECTED_HD.id_drive[65] = 0x00b4;
|
|
- BX_SELECTED_HD.id_drive[66] = 0x00b4;
|
|
- BX_SELECTED_HD.id_drive[67] = 0x012c;
|
|
- BX_SELECTED_HD.id_drive[68] = 0x00b4;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[47] = 0x8080; // multiple mode identification
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[48] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[49] = 0x0f01;
|
|
+
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[50] = 0;
|
|
+
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[51] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[52] = 0x0002;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[53] = 0x0003;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[54] = 0x0418;
|
|
+
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[55] = BX_SELECTED_DRIVE(channel).hard_drive->heads;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[56] = BX_SELECTED_DRIVE(channel).hard_drive->sectors;
|
|
+
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[57] = 0x1e80;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[58] = 0x0010;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[59] = 0x0100 | BX_SELECTED_CONTROLLER(channel).sectors_per_block;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[60] = 0x20e0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[61] = 0x0010;
|
|
+
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[62] = 0;
|
|
+
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[63] = 0x0103; // variable (DMA stuff)
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[64] = 0x0001; // PIO
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[65] = 0x00b4;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[66] = 0x00b4;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[67] = 0x012c;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[68] = 0x00b4;
|
|
|
|
for (i = 69; i <= 79; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
- BX_SELECTED_HD.id_drive[80] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[80] = 0;
|
|
|
|
- BX_SELECTED_HD.id_drive[81] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[81] = 0;
|
|
|
|
- BX_SELECTED_HD.id_drive[82] = 0;
|
|
- BX_SELECTED_HD.id_drive[83] = 0;
|
|
- BX_SELECTED_HD.id_drive[84] = 0;
|
|
- BX_SELECTED_HD.id_drive[85] = 0;
|
|
- BX_SELECTED_HD.id_drive[86] = 0;
|
|
- BX_SELECTED_HD.id_drive[87] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[82] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[83] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[84] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[85] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[86] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[87] = 0;
|
|
|
|
for (i = 88; i <= 127; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
- BX_SELECTED_HD.id_drive[128] = 0x0418;
|
|
- BX_SELECTED_HD.id_drive[129] = 0x103f;
|
|
- BX_SELECTED_HD.id_drive[130] = 0x0418;
|
|
- BX_SELECTED_HD.id_drive[131] = 0x103f;
|
|
- BX_SELECTED_HD.id_drive[132] = 0x0004;
|
|
- BX_SELECTED_HD.id_drive[133] = 0xffff;
|
|
- BX_SELECTED_HD.id_drive[134] = 0;
|
|
- BX_SELECTED_HD.id_drive[135] = 0x5050;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[128] = 0x0418;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[129] = 0x103f;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[130] = 0x0418;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[131] = 0x103f;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[132] = 0x0004;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[133] = 0xffff;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[134] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[135] = 0x5050;
|
|
|
|
for (i = 136; i <= 144; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
- BX_SELECTED_HD.id_drive[145] = 0x302e;
|
|
- BX_SELECTED_HD.id_drive[146] = 0x3245;
|
|
- BX_SELECTED_HD.id_drive[147] = 0x2020;
|
|
- BX_SELECTED_HD.id_drive[148] = 0x2020;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[145] = 0x302e;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[146] = 0x3245;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[147] = 0x2020;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[148] = 0x2020;
|
|
|
|
for (i = 149; i <= 255; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
#else
|
|
|
|
@@ -2433,36 +2486,36 @@
|
|
// bit 2: 1=soft sectored
|
|
// bit 1: 1=hard sectored
|
|
// bit 0: 0=reserved
|
|
- BX_SELECTED_HD.id_drive[0] = 0x0040;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[0] = 0x0040;
|
|
|
|
// Word 1: number of user-addressable cylinders in
|
|
// default translation mode. If the value in words 60-61
|
|
// exceed 16,515,072, this word shall contain 16,383.
|
|
- BX_SELECTED_HD.id_drive[1] = BX_SELECTED_HD.hard_drive->cylinders;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[1] = BX_SELECTED_DRIVE(channel).hard_drive->cylinders;
|
|
|
|
// Word 2: reserved
|
|
- BX_SELECTED_HD.id_drive[2] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[2] = 0;
|
|
|
|
// Word 3: number of user-addressable heads in default
|
|
// translation mode
|
|
- BX_SELECTED_HD.id_drive[3] = BX_SELECTED_HD.hard_drive->heads;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[3] = BX_SELECTED_DRIVE(channel).hard_drive->heads;
|
|
|
|
// Word 4: # unformatted bytes per translated track in default xlate mode
|
|
// Word 5: # unformatted bytes per sector in default xlated mode
|
|
// Word 6: # user-addressable sectors per track in default xlate mode
|
|
// Note: words 4,5 are now "Vendor specific (obsolete)"
|
|
- BX_SELECTED_HD.id_drive[4] = (512 * BX_SELECTED_HD.hard_drive->sectors);
|
|
- BX_SELECTED_HD.id_drive[5] = 512;
|
|
- BX_SELECTED_HD.id_drive[6] = BX_SELECTED_HD.hard_drive->sectors;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[4] = (512 * BX_SELECTED_DRIVE(channel).hard_drive->sectors);
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[5] = 512;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[6] = BX_SELECTED_DRIVE(channel).hard_drive->sectors;
|
|
|
|
// Word 7-9: Vendor specific
|
|
for (i=7; i<=9; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
// Word 10-19: Serial number (20 ASCII characters, 0000h=not specified)
|
|
// This field is right justified and padded with spaces (20h).
|
|
for (i=10; i<=19; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
// Word 20: buffer type
|
|
// 0000h = not specified
|
|
@@ -2475,92 +2528,92 @@
|
|
// simulatenous data xfers with a read caching
|
|
// capability.
|
|
// 0004h-ffffh = reserved
|
|
- BX_SELECTED_HD.id_drive[20] = 3;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[20] = 3;
|
|
|
|
// Word 21: buffer size in 512 byte increments, 0000h = not specified
|
|
- BX_SELECTED_HD.id_drive[21] = 512; // 512 Sectors = 256kB cache
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[21] = 512; // 512 Sectors = 256kB cache
|
|
|
|
// Word 22: # of ECC bytes available on read/write long cmds
|
|
// 0000h = not specified
|
|
- BX_SELECTED_HD.id_drive[22] = 4;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[22] = 4;
|
|
|
|
// Word 23..26: Firmware revision (8 ascii chars, 0000h=not specified)
|
|
// This field is left justified and padded with spaces (20h)
|
|
for (i=23; i<=26; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
// Word 27..46: Model number (40 ascii chars, 0000h=not specified)
|
|
// This field is left justified and padded with spaces (20h)
|
|
// for (i=27; i<=46; i++)
|
|
-// BX_SELECTED_HD.id_drive[i] = 0;
|
|
+// BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
for (i=0; i<20; i++) {
|
|
- BX_SELECTED_HD.id_drive[27+i] = (model_no[i*2] << 8) |
|
|
- model_no[i*2 + 1];
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[27+i] = (BX_SELECTED_MODEL(channel)[i*2] << 8) |
|
|
+ BX_SELECTED_MODEL(channel)[i*2 + 1];
|
|
}
|
|
|
|
// Word 47: 15-8 Vendor unique
|
|
// 7-0 00h= read/write multiple commands not implemented
|
|
// xxh= maximum # of sectors that can be transferred
|
|
// per interrupt on read and write multiple commands
|
|
- BX_SELECTED_HD.id_drive[47] = max_multiple_sectors;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[47] = max_multiple_sectors;
|
|
|
|
// Word 48: 0000h = cannot perform dword IO
|
|
// 0001h = can perform dword IO
|
|
- BX_SELECTED_HD.id_drive[48] = 1;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[48] = 1;
|
|
|
|
// Word 49: Capabilities
|
|
// 15-10: 0 = reserved
|
|
// 9: 1 = LBA supported
|
|
// 8: 1 = DMA supported
|
|
// 7-0: Vendor unique
|
|
- BX_SELECTED_HD.id_drive[49] = 1<<9;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[49] = 1<<9;
|
|
|
|
// Word 50: Reserved
|
|
- BX_SELECTED_HD.id_drive[50] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[50] = 0;
|
|
|
|
// Word 51: 15-8 PIO data transfer cycle timing mode
|
|
// 7-0 Vendor unique
|
|
- BX_SELECTED_HD.id_drive[51] = 0x200;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[51] = 0x200;
|
|
|
|
// Word 52: 15-8 DMA data transfer cycle timing mode
|
|
// 7-0 Vendor unique
|
|
- BX_SELECTED_HD.id_drive[52] = 0x200;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[52] = 0x200;
|
|
|
|
// Word 53: 15-1 Reserved
|
|
// 0 1=the fields reported in words 54-58 are valid
|
|
// 0=the fields reported in words 54-58 may be valid
|
|
- BX_SELECTED_HD.id_drive[53] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[53] = 0;
|
|
|
|
// Word 54: # of user-addressable cylinders in curr xlate mode
|
|
// Word 55: # of user-addressable heads in curr xlate mode
|
|
// Word 56: # of user-addressable sectors/track in curr xlate mode
|
|
- BX_SELECTED_HD.id_drive[54] = BX_SELECTED_HD.hard_drive->cylinders;
|
|
- BX_SELECTED_HD.id_drive[55] = BX_SELECTED_HD.hard_drive->heads;
|
|
- BX_SELECTED_HD.id_drive[56] = BX_SELECTED_HD.hard_drive->sectors;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[54] = BX_SELECTED_DRIVE(channel).hard_drive->cylinders;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[55] = BX_SELECTED_DRIVE(channel).hard_drive->heads;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[56] = BX_SELECTED_DRIVE(channel).hard_drive->sectors;
|
|
|
|
// Word 57-58: Current capacity in sectors
|
|
// Excludes all sectors used for device specific purposes.
|
|
temp32 =
|
|
- BX_SELECTED_HD.hard_drive->cylinders *
|
|
- BX_SELECTED_HD.hard_drive->heads *
|
|
- BX_SELECTED_HD.hard_drive->sectors;
|
|
- BX_SELECTED_HD.id_drive[57] = (temp32 & 0xffff); // LSW
|
|
- BX_SELECTED_HD.id_drive[58] = (temp32 >> 16); // MSW
|
|
+ BX_SELECTED_DRIVE(channel).hard_drive->cylinders *
|
|
+ BX_SELECTED_DRIVE(channel).hard_drive->heads *
|
|
+ BX_SELECTED_DRIVE(channel).hard_drive->sectors;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[57] = (temp32 & 0xffff); // LSW
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[58] = (temp32 >> 16); // MSW
|
|
|
|
// Word 59: 15-9 Reserved
|
|
// 8 1=multiple sector setting is valid
|
|
// 7-0 current setting for number of sectors that can be
|
|
// transferred per interrupt on R/W multiple commands
|
|
- BX_SELECTED_HD.id_drive[59] = 0x0000 | curr_multiple_sectors;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[59] = 0x0000 | curr_multiple_sectors;
|
|
|
|
// Word 60-61:
|
|
// If drive supports LBA Mode, these words reflect total # of user
|
|
// addressable sectors. This value does not depend on the current
|
|
// drive geometry. If the drive does not support LBA mode, these
|
|
// words shall be set to 0.
|
|
- Bit32u num_sects = BX_SELECTED_HD.hard_drive->cylinders * BX_SELECTED_HD.hard_drive->heads * BX_SELECTED_HD.hard_drive->sectors;
|
|
- BX_SELECTED_HD.id_drive[60] = num_sects & 0xffff; // LSW
|
|
- BX_SELECTED_HD.id_drive[61] = num_sects >> 16; // MSW
|
|
+ Bit32u num_sects = BX_SELECTED_DRIVE(channel).hard_drive->cylinders * BX_SELECTED_DRIVE(channel).hard_drive->heads * BX_SELECTED_DRIVE(channel).hard_drive->sectors;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[60] = num_sects & 0xffff; // LSW
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[61] = num_sects >> 16; // MSW
|
|
|
|
// Word 62: 15-8 single word DMA transfer mode active
|
|
// 7-0 single word DMA transfer modes supported
|
|
@@ -2568,7 +2621,7 @@
|
|
// supported e.g., if Mode 0 is supported bit 0 is set.
|
|
// The high order byte contains a single bit set to indiciate
|
|
// which mode is active.
|
|
- BX_SELECTED_HD.id_drive[62] = 0x0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[62] = 0x0;
|
|
|
|
// Word 63: 15-8 multiword DMA transfer mode active
|
|
// 7-0 multiword DMA transfer modes supported
|
|
@@ -2576,11 +2629,11 @@
|
|
// supported e.g., if Mode 0 is supported bit 0 is set.
|
|
// The high order byte contains a single bit set to indiciate
|
|
// which mode is active.
|
|
- BX_SELECTED_HD.id_drive[63] = 0x0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[63] = 0x0;
|
|
|
|
// Word 64-79 Reserved
|
|
for (i=64; i<=79; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
// Word 80: 15-5 reserved
|
|
// 4 supports ATA/ATAPI-4
|
|
@@ -2588,10 +2641,10 @@
|
|
// 2 supports ATA-2
|
|
// 1 supports ATA-1
|
|
// 0 reserved
|
|
- BX_SELECTED_HD.id_drive[80] = (1 << 2) | (1 << 1);
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[80] = (1 << 2) | (1 << 1);
|
|
|
|
// Word 81: Minor version number
|
|
- BX_SELECTED_HD.id_drive[81] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[81] = 0;
|
|
|
|
// Word 82: 15 obsolete
|
|
// 14 NOP command supported
|
|
@@ -2609,226 +2662,257 @@
|
|
// 2 supports removable media feature set
|
|
// 1 supports securite mode feature set
|
|
// 0 support SMART feature set
|
|
- BX_SELECTED_HD.id_drive[82] = 1 << 14;
|
|
- BX_SELECTED_HD.id_drive[83] = 1 << 14;
|
|
- BX_SELECTED_HD.id_drive[84] = 1 << 14;
|
|
- BX_SELECTED_HD.id_drive[85] = 1 << 14;
|
|
- BX_SELECTED_HD.id_drive[86] = 0;
|
|
- BX_SELECTED_HD.id_drive[87] = 1 << 14;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[82] = 1 << 14;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[83] = 1 << 14;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[84] = 1 << 14;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[85] = 1 << 14;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[86] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[87] = 1 << 14;
|
|
|
|
for (i=88; i<=127; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
// Word 128-159 Vendor unique
|
|
for (i=128; i<=159; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
// Word 160-255 Reserved
|
|
for (i=160; i<=255; i++)
|
|
- BX_SELECTED_HD.id_drive[i] = 0;
|
|
+ BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
|
|
|
|
#endif
|
|
|
|
- BX_DEBUG(("Drive ID Info. initialized : %04d {%s}", 512, DEVICE_TYPE_STRING));
|
|
+ BX_DEBUG(("Drive ID Info. initialized : %04d {%s}", 512, BX_SELECTED_TYPE_STRING(channel)));
|
|
|
|
// now convert the id_drive array (native 256 word format) to
|
|
// the controller buffer (512 bytes)
|
|
for (i=0; i<=255; i++) {
|
|
- temp16 = BX_SELECTED_HD.id_drive[i];
|
|
- BX_SELECTED_CONTROLLER.buffer[i*2] = temp16 & 0x00ff;
|
|
- BX_SELECTED_CONTROLLER.buffer[i*2+1] = temp16 >> 8;
|
|
+ temp16 = BX_SELECTED_DRIVE(channel).id_drive[i];
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[i*2] = temp16 & 0x00ff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[i*2+1] = temp16 >> 8;
|
|
}
|
|
}
|
|
|
|
void
|
|
-bx_hard_drive_c::init_send_atapi_command(Bit8u command, int req_length, int alloc_length, bool lazy)
|
|
+bx_hard_drive_c::init_send_atapi_command(Bit8u channel, Bit8u command, int req_length, int alloc_length, bool lazy)
|
|
{
|
|
- // BX_SELECTED_CONTROLLER.byte_count is a union of BX_SELECTED_CONTROLLER.cylinder_no;
|
|
+ // BX_SELECTED_CONTROLLER(channel).byte_count is a union of BX_SELECTED_CONTROLLER(channel).cylinder_no;
|
|
// lazy is used to force a data read in the buffer at the next read.
|
|
|
|
- if (BX_SELECTED_CONTROLLER.byte_count == 0xffff)
|
|
- BX_SELECTED_CONTROLLER.byte_count = 0xfffe;
|
|
+ if (BX_SELECTED_CONTROLLER(channel).byte_count == 0xffff)
|
|
+ BX_SELECTED_CONTROLLER(channel).byte_count = 0xfffe;
|
|
|
|
- if ((BX_SELECTED_CONTROLLER.byte_count & 1)
|
|
- && !(alloc_length <= BX_SELECTED_CONTROLLER.byte_count)) {
|
|
+ if ((BX_SELECTED_CONTROLLER(channel).byte_count & 1)
|
|
+ && !(alloc_length <= BX_SELECTED_CONTROLLER(channel).byte_count)) {
|
|
BX_INFO(("Odd byte count (0x%04x) to ATAPI command 0x%02x, using 0x%04x",
|
|
- BX_SELECTED_CONTROLLER.byte_count, command, BX_SELECTED_CONTROLLER.byte_count - 1));
|
|
- BX_SELECTED_CONTROLLER.byte_count -= 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).byte_count, command, BX_SELECTED_CONTROLLER(channel).byte_count - 1));
|
|
+ BX_SELECTED_CONTROLLER(channel).byte_count -= 1;
|
|
}
|
|
|
|
- if (BX_SELECTED_CONTROLLER.byte_count == 0)
|
|
+ if (BX_SELECTED_CONTROLLER(channel).byte_count == 0)
|
|
BX_PANIC(("ATAPI command with zero byte count"));
|
|
|
|
if (alloc_length < 0)
|
|
BX_PANIC(("Allocation length < 0"));
|
|
if (alloc_length == 0)
|
|
- alloc_length = BX_SELECTED_CONTROLLER.byte_count;
|
|
+ alloc_length = BX_SELECTED_CONTROLLER(channel).byte_count;
|
|
|
|
- BX_SELECTED_CONTROLLER.interrupt_reason.i_o = 1;
|
|
- BX_SELECTED_CONTROLLER.interrupt_reason.c_d = 0;
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 1;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
|
|
// no bytes transfered yet
|
|
if (lazy)
|
|
- BX_SELECTED_CONTROLLER.buffer_index = 2048;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index = 2048;
|
|
else
|
|
- BX_SELECTED_CONTROLLER.buffer_index = 0;
|
|
- BX_SELECTED_CONTROLLER.drq_index = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).drq_index = 0;
|
|
|
|
- if (BX_SELECTED_CONTROLLER.byte_count > req_length)
|
|
- BX_SELECTED_CONTROLLER.byte_count = req_length;
|
|
+ if (BX_SELECTED_CONTROLLER(channel).byte_count > req_length)
|
|
+ BX_SELECTED_CONTROLLER(channel).byte_count = req_length;
|
|
|
|
- if (BX_SELECTED_CONTROLLER.byte_count > alloc_length)
|
|
- BX_SELECTED_CONTROLLER.byte_count = alloc_length;
|
|
+ if (BX_SELECTED_CONTROLLER(channel).byte_count > alloc_length)
|
|
+ BX_SELECTED_CONTROLLER(channel).byte_count = alloc_length;
|
|
|
|
- BX_SELECTED_HD.atapi.command = command;
|
|
- BX_SELECTED_HD.atapi.drq_bytes = BX_SELECTED_CONTROLLER.byte_count;
|
|
- BX_SELECTED_HD.atapi.total_bytes_remaining = (req_length < alloc_length) ? req_length : alloc_length;
|
|
+ BX_SELECTED_DRIVE(channel).atapi.command = command;
|
|
+ BX_SELECTED_DRIVE(channel).atapi.drq_bytes = BX_SELECTED_CONTROLLER(channel).byte_count;
|
|
+ BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining = (req_length < alloc_length) ? req_length : alloc_length;
|
|
|
|
// if (lazy) {
|
|
// // bias drq_bytes and total_bytes_remaining
|
|
- // BX_SELECTED_HD.atapi.drq_bytes += 2048;
|
|
- // BX_SELECTED_HD.atapi.total_bytes_remaining += 2048;
|
|
+ // BX_SELECTED_DRIVE(channel).atapi.drq_bytes += 2048;
|
|
+ // BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining += 2048;
|
|
// }
|
|
}
|
|
|
|
void
|
|
-bx_hard_drive_c::atapi_cmd_error(sense_t sense_key, asc_t asc)
|
|
+bx_hard_drive_c::atapi_cmd_error(Bit8u channel, sense_t sense_key, asc_t asc)
|
|
{
|
|
- BX_SELECTED_CONTROLLER.error_register = sense_key << 4;
|
|
- BX_SELECTED_CONTROLLER.interrupt_reason.i_o = 1;
|
|
- BX_SELECTED_CONTROLLER.interrupt_reason.c_d = 1;
|
|
- BX_SELECTED_CONTROLLER.interrupt_reason.rel = 0;
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.write_fault = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 1;
|
|
-
|
|
- BX_SELECTED_HD.sense.sense_key = sense_key;
|
|
- BX_SELECTED_HD.sense.asc = asc;
|
|
- BX_SELECTED_HD.sense.ascq = 0;
|
|
+ BX_ERROR(("atapi_cmd_error channel=%02x key=%02x asc=%02x", channel, sense_key, asc));
|
|
+
|
|
+ BX_SELECTED_CONTROLLER(channel).error_register = sense_key << 4;
|
|
+ BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 1;
|
|
+
|
|
+ BX_SELECTED_DRIVE(channel).sense.sense_key = sense_key;
|
|
+ BX_SELECTED_DRIVE(channel).sense.asc = asc;
|
|
+ BX_SELECTED_DRIVE(channel).sense.ascq = 0;
|
|
}
|
|
|
|
void
|
|
-bx_hard_drive_c::atapi_cmd_nop()
|
|
+bx_hard_drive_c::atapi_cmd_nop(Bit8u channel)
|
|
{
|
|
- BX_SELECTED_CONTROLLER.interrupt_reason.i_o = 1;
|
|
- BX_SELECTED_CONTROLLER.interrupt_reason.c_d = 1;
|
|
- BX_SELECTED_CONTROLLER.interrupt_reason.rel = 0;
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- BX_SELECTED_CONTROLLER.status.err = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 0;
|
|
}
|
|
|
|
void
|
|
-bx_hard_drive_c::init_mode_sense_single(const void* src, int size)
|
|
+bx_hard_drive_c::init_mode_sense_single(Bit8u channel, const void* src, int size)
|
|
{
|
|
// Header
|
|
- BX_SELECTED_CONTROLLER.buffer[0] = (size+6) >> 8;
|
|
- BX_SELECTED_CONTROLLER.buffer[1] = (size+6) & 0xff;
|
|
- BX_SELECTED_CONTROLLER.buffer[2] = 0x70; // no media present
|
|
- BX_SELECTED_CONTROLLER.buffer[3] = 0; // reserved
|
|
- BX_SELECTED_CONTROLLER.buffer[4] = 0; // reserved
|
|
- BX_SELECTED_CONTROLLER.buffer[5] = 0; // reserved
|
|
- BX_SELECTED_CONTROLLER.buffer[6] = 0; // reserved
|
|
- BX_SELECTED_CONTROLLER.buffer[7] = 0; // reserved
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[0] = (size+6) >> 8;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[1] = (size+6) & 0xff;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[2] = 0x70; // no media present
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[3] = 0; // reserved
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[4] = 0; // reserved
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[5] = 0; // reserved
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[6] = 0; // reserved
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer[7] = 0; // reserved
|
|
|
|
// Data
|
|
- memcpy(BX_SELECTED_CONTROLLER.buffer + 8, src, size);
|
|
+ memcpy(BX_SELECTED_CONTROLLER(channel).buffer + 8, src, size);
|
|
}
|
|
|
|
void
|
|
-bx_hard_drive_c::ready_to_send_atapi()
|
|
+bx_hard_drive_c::ready_to_send_atapi(Bit8u channel)
|
|
{
|
|
- raise_interrupt();
|
|
+ raise_interrupt(channel);
|
|
}
|
|
|
|
void
|
|
-bx_hard_drive_c::raise_interrupt()
|
|
+bx_hard_drive_c::raise_interrupt(Bit8u channel)
|
|
{
|
|
- BX_DEBUG(("raise_interrupt called, disable_irq = %02x", BX_SELECTED_CONTROLLER.control.disable_irq));
|
|
- if (!BX_SELECTED_CONTROLLER.control.disable_irq) { BX_DEBUG(("raising interrupt")); } else { BX_DEBUG(("Not raising interrupt")); }
|
|
- if (!BX_SELECTED_CONTROLLER.control.disable_irq) {
|
|
- Bit32u irq = 14; // always 1st IDE controller
|
|
- // for second controller, you would want irq 15
|
|
- BX_DEBUG(("Raising interrupt %d {%s}", irq, DEVICE_TYPE_STRING));
|
|
+ BX_DEBUG(("raise_interrupt called, disable_irq = %02x", BX_SELECTED_CONTROLLER(channel).control.disable_irq));
|
|
+ if (!BX_SELECTED_CONTROLLER(channel).control.disable_irq) { BX_DEBUG(("raising interrupt")); } else { BX_DEBUG(("Not raising interrupt")); }
|
|
+ if (!BX_SELECTED_CONTROLLER(channel).control.disable_irq) {
|
|
+ Bit32u irq = BX_HD_THIS channels[channel].irq;
|
|
+ BX_DEBUG(("Raising interrupt %d {%s}", irq, BX_SELECTED_TYPE_STRING(channel)));
|
|
BX_HD_THIS devices->pic->raise_irq(irq);
|
|
} else {
|
|
- if (bx_dbg.disk || (CDROM_SELECTED && bx_dbg.cdrom))
|
|
- BX_INFO(("Interrupt masked {%s}", DEVICE_TYPE_STRING));
|
|
+ if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
|
|
+ BX_INFO(("Interrupt masked {%s}", BX_SELECTED_TYPE_STRING(channel)));
|
|
}
|
|
}
|
|
|
|
void
|
|
-bx_hard_drive_c::command_aborted(unsigned value)
|
|
+bx_hard_drive_c::command_aborted(Bit8u channel, unsigned value)
|
|
{
|
|
- BX_DEBUG(("aborting on command 0x%02x {%s}", value, DEVICE_TYPE_STRING));
|
|
- BX_SELECTED_CONTROLLER.current_command = 0;
|
|
- BX_SELECTED_CONTROLLER.status.busy = 0;
|
|
- BX_SELECTED_CONTROLLER.status.drive_ready = 1;
|
|
- BX_SELECTED_CONTROLLER.status.err = 1;
|
|
- BX_SELECTED_CONTROLLER.error_register = 0x04; // command ABORTED
|
|
- BX_SELECTED_CONTROLLER.status.drq = 0;
|
|
- BX_SELECTED_CONTROLLER.status.seek_complete = 0;
|
|
- BX_SELECTED_CONTROLLER.status.corrected_data = 0;
|
|
- BX_SELECTED_CONTROLLER.buffer_index = 0;
|
|
- raise_interrupt();
|
|
+ BX_DEBUG(("aborting on command 0x%02x {%s}", value, BX_SELECTED_TYPE_STRING(channel)));
|
|
+ BX_SELECTED_CONTROLLER(channel).current_command = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.busy = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.err = 1;
|
|
+ BX_SELECTED_CONTROLLER(channel).error_register = 0x04; // command ABORTED
|
|
+ BX_SELECTED_CONTROLLER(channel).status.drq = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.seek_complete = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
|
|
+ BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
|
|
+ raise_interrupt(channel);
|
|
+}
|
|
+
|
|
+ Bit32u
|
|
+bx_hard_drive_c::get_device_handle(Bit8u channel, Bit8u device)
|
|
+{
|
|
+ BX_DEBUG(("get_device_handle %d %d",channel, device));
|
|
+ if ((channel < BX_MAX_ATA_CHANNEL) && (device < 2)) {
|
|
+ return ((channel*2) + device);
|
|
+ }
|
|
+
|
|
+ return BX_MAX_ATA_CHANNEL*2;
|
|
+}
|
|
+
|
|
+ Bit32u
|
|
+bx_hard_drive_c::get_first_cd_handle(void)
|
|
+{
|
|
+ for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
|
|
+ if (BX_DRIVE_IS_CD(channel,0)) return (channel*2);
|
|
+ if (BX_DRIVE_IS_CD(channel,1)) return ((channel*2) + 1);
|
|
+ }
|
|
+ return BX_MAX_ATA_CHANNEL*2;
|
|
}
|
|
|
|
unsigned
|
|
-bx_hard_drive_c::get_cd_media_status(void)
|
|
+bx_hard_drive_c::get_cd_media_status(Bit32u handle)
|
|
{
|
|
- return( BX_HD_THIS s[1].cdrom.ready );
|
|
+ if ( handle >= BX_MAX_ATA_CHANNEL*2 ) return 0;
|
|
+
|
|
+ Bit8u channel = handle / 2;
|
|
+ Bit8u device = handle % 2;
|
|
+ return( BX_HD_THIS channels[channel].drives[device].cdrom.ready );
|
|
}
|
|
|
|
unsigned
|
|
-bx_hard_drive_c::set_cd_media_status(unsigned status)
|
|
+bx_hard_drive_c::set_cd_media_status(Bit32u handle, unsigned status)
|
|
{
|
|
+ if ( handle >= BX_MAX_ATA_CHANNEL*2 ) return 0;
|
|
+
|
|
+ Bit8u channel = handle / 2;
|
|
+ Bit8u device = handle % 2;
|
|
+
|
|
// if setting to the current value, nothing to do
|
|
- if (status == BX_HD_THIS s[1].cdrom.ready)
|
|
+ if (status == BX_HD_THIS channels[channel].drives[device].cdrom.ready)
|
|
return(status);
|
|
// return 0 if no cdromd is present
|
|
- if (!bx_options.cdromd.Opresent->get())
|
|
+ if (!BX_DRIVE_IS_CD(channel,device))
|
|
return(0);
|
|
|
|
if (status == 0) {
|
|
// eject cdrom if not locked by guest OS
|
|
- if (BX_HD_THIS s[1].cdrom.locked) return(1);
|
|
+ if (BX_HD_THIS channels[channel].drives[device].cdrom.locked) return(1);
|
|
else {
|
|
#ifdef LOWLEVEL_CDROM
|
|
- BX_HD_THIS s[1].cdrom.cd->eject_cdrom();
|
|
+ BX_HD_THIS channels[channel].drives[device].cdrom.cd->eject_cdrom();
|
|
#endif
|
|
- BX_HD_THIS s[1].cdrom.ready = 0;
|
|
- bx_options.cdromd.Ostatus->set(BX_EJECTED);
|
|
+ BX_HD_THIS channels[channel].drives[device].cdrom.ready = 0;
|
|
+ bx_options.atadevice[channel][device].Ostatus->set(BX_EJECTED);
|
|
}
|
|
}
|
|
else {
|
|
// insert cdrom
|
|
#ifdef LOWLEVEL_CDROM
|
|
- if (BX_HD_THIS s[1].cdrom.cd->insert_cdrom(bx_options.cdromd.Opath->getptr())) {
|
|
+ if (BX_HD_THIS channels[channel].drives[device].cdrom.cd->insert_cdrom(bx_options.atadevice[channel][device].Opath->getptr())) {
|
|
BX_INFO(( "Media present in CD-ROM drive"));
|
|
- BX_HD_THIS s[1].cdrom.ready = 1;
|
|
- BX_HD_THIS s[1].cdrom.capacity = BX_HD_THIS s[1].cdrom.cd->capacity();
|
|
- bx_options.cdromd.Ostatus->set(BX_INSERTED);
|
|
- BX_SELECTED_HD.sense.sense_key = SENSE_UNIT_ATTENTION;
|
|
- BX_SELECTED_HD.sense.asc = 0;
|
|
- BX_SELECTED_HD.sense.ascq = 0;
|
|
- raise_interrupt();
|
|
+ BX_HD_THIS channels[channel].drives[device].cdrom.ready = 1;
|
|
+ BX_HD_THIS channels[channel].drives[device].cdrom.capacity = BX_HD_THIS channels[channel].drives[device].cdrom.cd->capacity();
|
|
+ bx_options.atadevice[channel][device].Ostatus->set(BX_INSERTED);
|
|
+ BX_SELECTED_DRIVE(channel).sense.sense_key = SENSE_UNIT_ATTENTION;
|
|
+ BX_SELECTED_DRIVE(channel).sense.asc = 0;
|
|
+ BX_SELECTED_DRIVE(channel).sense.ascq = 0;
|
|
+ raise_interrupt(channel);
|
|
}
|
|
else {
|
|
#endif
|
|
BX_INFO(( "Could not locate CD-ROM, continuing with media not present"));
|
|
- BX_HD_THIS s[1].cdrom.ready = 0;
|
|
- bx_options.cdromd.Ostatus->set(BX_EJECTED);
|
|
+ BX_HD_THIS channels[channel].drives[device].cdrom.ready = 0;
|
|
+ bx_options.atadevice[channel][device].Ostatus->set(BX_EJECTED);
|
|
#ifdef LOWLEVEL_CDROM
|
|
}
|
|
#endif
|
|
}
|
|
- return( BX_HD_THIS s[1].cdrom.ready );
|
|
+ return( BX_HD_THIS channels[channel].drives[device].cdrom.ready );
|
|
}
|
|
|
|
|
|
Index: iodev/harddrv.h
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/iodev/harddrv.h,v
|
|
retrieving revision 1.13
|
|
diff -u -r1.13 harddrv.h
|
|
--- iodev/harddrv.h 12 Sep 2002 06:49:04 -0000 1.13
|
|
+++ iodev/harddrv.h 22 Sep 2002 20:46:16 -0000
|
|
@@ -184,7 +184,6 @@
|
|
Boolean err;
|
|
} status;
|
|
Bit8u error_register;
|
|
- // Bit8u drive_select; this field was moved :^(
|
|
Bit8u head_no;
|
|
union {
|
|
Bit8u sector_count;
|
|
@@ -282,12 +281,8 @@
|
|
# define BX_HD_THIS this->
|
|
#endif
|
|
|
|
-#define BX_SELECTED_HD BX_HD_THIS s[BX_HD_THIS drive_select]
|
|
-#define CDROM_SELECTED (BX_HD_THIS s[BX_HD_THIS drive_select].device_type == IDE_CDROM)
|
|
-#define DEVICE_TYPE_STRING ((CDROM_SELECTED) ? "CD-ROM" : "DISK")
|
|
-
|
|
typedef enum {
|
|
- IDE_DISK, IDE_CDROM
|
|
+ IDE_NONE, IDE_DISK, IDE_CDROM
|
|
} device_type_t;
|
|
|
|
class bx_hard_drive_c : public logfunctions {
|
|
@@ -298,8 +293,10 @@
|
|
BX_HD_SMF void close_harddrive(void);
|
|
BX_HD_SMF void init(bx_devices_c *d, bx_cmos_c *cmos);
|
|
BX_HD_SMF void reset(unsigned type);
|
|
- BX_HD_SMF unsigned get_cd_media_status(void);
|
|
- BX_HD_SMF unsigned set_cd_media_status(unsigned status);
|
|
+ BX_HD_SMF Bit32u get_device_handle(Bit8u channel, Bit8u device);
|
|
+ BX_HD_SMF Bit32u get_first_cd_handle(void);
|
|
+ BX_HD_SMF unsigned get_cd_media_status(Bit32u handle);
|
|
+ BX_HD_SMF unsigned set_cd_media_status(Bit32u handle, unsigned status);
|
|
|
|
#if !BX_USE_HD_SMF
|
|
Bit32u read(Bit32u address, unsigned io_len);
|
|
@@ -311,36 +308,46 @@
|
|
|
|
private:
|
|
|
|
- BX_HD_SMF Boolean calculate_logical_address(Bit32u *sector);
|
|
- BX_HD_SMF void increment_address();
|
|
- BX_HD_SMF void identify_drive(unsigned drive);
|
|
- BX_HD_SMF void identify_ATAPI_drive(unsigned drive);
|
|
- BX_HD_SMF void command_aborted(unsigned command);
|
|
-
|
|
- BX_HD_SMF void init_send_atapi_command(Bit8u command, int req_length, int alloc_length, bool lazy = false);
|
|
- BX_HD_SMF void ready_to_send_atapi();
|
|
- BX_HD_SMF void raise_interrupt();
|
|
- BX_HD_SMF void atapi_cmd_error(sense_t sense_key, asc_t asc);
|
|
- BX_HD_SMF void init_mode_sense_single(const void* src, int size);
|
|
- BX_HD_SMF void atapi_cmd_nop();
|
|
-
|
|
- struct sStruct {
|
|
- device_image_t* hard_drive;
|
|
- device_type_t device_type;
|
|
- // 512 byte buffer for ID drive command
|
|
- // These words are stored in native word endian format, as
|
|
- // they are fetched and returned via a return(), so
|
|
- // there's no need to keep them in x86 endian format.
|
|
- Bit16u id_drive[256];
|
|
-
|
|
- controller_t controller;
|
|
- cdrom_t cdrom;
|
|
- sense_info_t sense;
|
|
- atapi_t atapi;
|
|
-
|
|
- } s[2];
|
|
+ BX_HD_SMF Boolean calculate_logical_address(Bit8u channel, Bit32u *sector);
|
|
+ BX_HD_SMF void increment_address(Bit8u channel);
|
|
+ BX_HD_SMF void identify_drive(Bit8u channel);
|
|
+ BX_HD_SMF void identify_ATAPI_drive(Bit8u channel);
|
|
+ BX_HD_SMF void command_aborted(Bit8u channel, unsigned command);
|
|
+
|
|
+ BX_HD_SMF void init_send_atapi_command(Bit8u channel, Bit8u command, int req_length, int alloc_length, bool lazy = false);
|
|
+ BX_HD_SMF void ready_to_send_atapi(Bit8u channel);
|
|
+ BX_HD_SMF void raise_interrupt(Bit8u channel);
|
|
+ BX_HD_SMF void atapi_cmd_error(Bit8u channel, sense_t sense_key, asc_t asc);
|
|
+ BX_HD_SMF void init_mode_sense_single(Bit8u channel, const void* src, int size);
|
|
+ BX_HD_SMF void atapi_cmd_nop(Bit8u channel);
|
|
+
|
|
+ // FIXME:
|
|
+ // For each ATA channel we should have one controller struct
|
|
+ // and an array of two drive structs
|
|
+ struct channel_t {
|
|
+ struct drive_t {
|
|
+ device_image_t* hard_drive;
|
|
+ device_type_t device_type;
|
|
+ // 512 byte buffer for ID drive command
|
|
+ // These words are stored in native word endian format, as
|
|
+ // they are fetched and returned via a return(), so
|
|
+ // there's no need to keep them in x86 endian format.
|
|
+ Bit16u id_drive[256];
|
|
+
|
|
+ controller_t controller;
|
|
+ cdrom_t cdrom;
|
|
+ sense_info_t sense;
|
|
+ atapi_t atapi;
|
|
+
|
|
+ Bit8u model_no[41];
|
|
+ } drives[2];
|
|
+ unsigned drive_select;
|
|
+
|
|
+ Bit16u ioaddr1;
|
|
+ Bit16u ioaddr2;
|
|
+ Bit8u irq;
|
|
|
|
- unsigned drive_select;
|
|
+ } channels[BX_MAX_ATA_CHANNEL];
|
|
|
|
bx_devices_c *devices;
|
|
};
|