mirror of
https://github.com/holub/mame
synced 2025-05-25 07:15:25 +03:00
Added support for 2 drives on IDE controller [Miodrag Milanovic]
This commit is contained in:
parent
da9b77677a
commit
29e524c885
@ -91,6 +91,7 @@
|
||||
|
||||
#define IDE_ERROR_NONE 0x00
|
||||
#define IDE_ERROR_DEFAULT 0x01
|
||||
#define IDE_ERROR_TRACK0_NOT_FOUND 0x02
|
||||
#define IDE_ERROR_UNKNOWN_COMMAND 0x04
|
||||
#define IDE_ERROR_BAD_LOCATION 0x10
|
||||
#define IDE_ERROR_BAD_SECTOR 0x80
|
||||
@ -104,6 +105,27 @@
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
typedef struct _ide_device ide_device;
|
||||
struct _ide_device
|
||||
{
|
||||
UINT8 features[IDE_DISK_SECTOR_SIZE];
|
||||
|
||||
UINT16 cur_cylinder;
|
||||
UINT8 cur_sector;
|
||||
UINT8 cur_head;
|
||||
UINT8 cur_head_reg;
|
||||
|
||||
UINT32 cur_lba;
|
||||
|
||||
UINT16 num_cylinders;
|
||||
UINT8 num_sectors;
|
||||
UINT8 num_heads;
|
||||
|
||||
chd_file *handle;
|
||||
hard_disk_file *disk;
|
||||
bool is_image_device;
|
||||
};
|
||||
|
||||
|
||||
typedef struct _ide_state ide_state;
|
||||
struct _ide_state
|
||||
@ -118,7 +140,6 @@ struct _ide_state
|
||||
UINT8 precomp_offset;
|
||||
|
||||
UINT8 buffer[IDE_DISK_SECTOR_SIZE];
|
||||
UINT8 features[IDE_DISK_SECTOR_SIZE];
|
||||
UINT16 buffer_offset;
|
||||
UINT16 sector_count;
|
||||
|
||||
@ -138,24 +159,10 @@ struct _ide_state
|
||||
UINT8 bus_master_status;
|
||||
UINT32 bus_master_descriptor;
|
||||
|
||||
UINT16 cur_cylinder;
|
||||
UINT8 cur_sector;
|
||||
UINT8 cur_head;
|
||||
UINT8 cur_head_reg;
|
||||
|
||||
UINT32 cur_lba;
|
||||
|
||||
UINT16 num_cylinders;
|
||||
UINT8 num_sectors;
|
||||
UINT8 num_heads;
|
||||
|
||||
UINT8 config_unknown;
|
||||
UINT8 config_register[IDE_CONFIG_REGISTERS];
|
||||
UINT8 config_register_num;
|
||||
|
||||
chd_file *handle;
|
||||
hard_disk_file *disk;
|
||||
bool is_image_device;
|
||||
emu_timer * last_status_timer;
|
||||
emu_timer * reset_timer;
|
||||
|
||||
@ -166,6 +173,9 @@ struct _ide_state
|
||||
|
||||
UINT8 gnetreadlock;
|
||||
ide_hardware * hardware;
|
||||
|
||||
UINT8 cur_drive;
|
||||
ide_device drive[2];
|
||||
};
|
||||
|
||||
|
||||
@ -176,7 +186,7 @@ struct _ide_state
|
||||
|
||||
static TIMER_CALLBACK( reset_callback );
|
||||
|
||||
static void ide_build_features(ide_state *ide);
|
||||
static void ide_build_features(ide_state *ide, int drive);
|
||||
|
||||
static void continue_read(ide_state *ide);
|
||||
static void read_sector_done(ide_state *ide);
|
||||
@ -275,10 +285,10 @@ INLINE void signal_delayed_interrupt(ide_state *ide, attotime time, int buffer_r
|
||||
INITIALIZATION AND RESET
|
||||
***************************************************************************/
|
||||
|
||||
UINT8 *ide_get_features(device_t *device)
|
||||
UINT8 *ide_get_features(device_t *device, int drive)
|
||||
{
|
||||
ide_state *ide = get_safe_token(device);
|
||||
return ide->features;
|
||||
return ide->drive[drive].features;
|
||||
}
|
||||
|
||||
void ide_set_gnet_readlock(device_t *device, const UINT8 onoff)
|
||||
@ -373,12 +383,12 @@ INLINE int convert_to_offset_and_size16(offs_t *offset, UINT32 mem_mask)
|
||||
INLINE UINT32 lba_address(ide_state *ide)
|
||||
{
|
||||
/* LBA direct? */
|
||||
if (ide->cur_head_reg & 0x40)
|
||||
return ide->cur_sector + ide->cur_cylinder * 256 + ide->cur_head * 16777216;
|
||||
if (ide->drive[ide->cur_drive].cur_head_reg & 0x40)
|
||||
return ide->drive[ide->cur_drive].cur_sector + ide->drive[ide->cur_drive].cur_cylinder * 256 + ide->drive[ide->cur_drive].cur_head * 16777216;
|
||||
|
||||
/* standard CHS */
|
||||
else
|
||||
return (ide->cur_cylinder * ide->num_heads + ide->cur_head) * ide->num_sectors + ide->cur_sector - 1;
|
||||
return (ide->drive[ide->cur_drive].cur_cylinder * ide->drive[ide->cur_drive].num_heads + ide->drive[ide->cur_drive].cur_head) * ide->drive[ide->cur_drive].num_sectors + ide->drive[ide->cur_drive].cur_sector - 1;
|
||||
}
|
||||
|
||||
|
||||
@ -392,14 +402,14 @@ INLINE UINT32 lba_address(ide_state *ide)
|
||||
INLINE void next_sector(ide_state *ide)
|
||||
{
|
||||
/* LBA direct? */
|
||||
if (ide->cur_head_reg & 0x40)
|
||||
if (ide->drive[ide->cur_drive].cur_head_reg & 0x40)
|
||||
{
|
||||
ide->cur_sector++;
|
||||
if (ide->cur_sector == 0)
|
||||
ide->drive[ide->cur_drive].cur_sector++;
|
||||
if (ide->drive[ide->cur_drive].cur_sector == 0)
|
||||
{
|
||||
ide->cur_cylinder++;
|
||||
if (ide->cur_cylinder == 0)
|
||||
ide->cur_head++;
|
||||
ide->drive[ide->cur_drive].cur_cylinder++;
|
||||
if (ide->drive[ide->cur_drive].cur_cylinder == 0)
|
||||
ide->drive[ide->cur_drive].cur_head++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -407,21 +417,21 @@ INLINE void next_sector(ide_state *ide)
|
||||
else
|
||||
{
|
||||
/* sectors are 1-based */
|
||||
ide->cur_sector++;
|
||||
if (ide->cur_sector > ide->num_sectors)
|
||||
ide->drive[ide->cur_drive].cur_sector++;
|
||||
if (ide->drive[ide->cur_drive].cur_sector > ide->drive[ide->cur_drive].num_sectors)
|
||||
{
|
||||
/* heads are 0 based */
|
||||
ide->cur_sector = 1;
|
||||
ide->cur_head++;
|
||||
if (ide->cur_head >= ide->num_heads)
|
||||
ide->drive[ide->cur_drive].cur_sector = 1;
|
||||
ide->drive[ide->cur_drive].cur_head++;
|
||||
if (ide->drive[ide->cur_drive].cur_head >= ide->drive[ide->cur_drive].num_heads)
|
||||
{
|
||||
ide->cur_head = 0;
|
||||
ide->cur_cylinder++;
|
||||
ide->drive[ide->cur_drive].cur_head = 0;
|
||||
ide->drive[ide->cur_drive].cur_cylinder++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ide->cur_lba = lba_address(ide);
|
||||
ide->drive[ide->cur_drive].cur_lba = lba_address(ide);
|
||||
}
|
||||
|
||||
|
||||
@ -445,168 +455,168 @@ static void swap_strncpy(UINT8 *dst, const char *src, int field_size_in_words)
|
||||
}
|
||||
|
||||
|
||||
static void ide_generate_features(ide_state *ide)
|
||||
static void ide_generate_features(ide_state *ide,int drive)
|
||||
{
|
||||
int total_sectors = ide->num_cylinders * ide->num_heads * ide->num_sectors;
|
||||
int sectors_per_track = ide->num_heads * ide->num_sectors;
|
||||
int total_sectors = ide->drive[drive].num_cylinders * ide->drive[drive].num_heads * ide->drive[drive].num_sectors;
|
||||
int sectors_per_track = ide->drive[drive].num_heads * ide->drive[drive].num_sectors;
|
||||
|
||||
/* basic geometry */
|
||||
ide->features[ 0*2+0] = 0x5a; /* 0: configuration bits */
|
||||
ide->features[ 0*2+1] = 0x04;
|
||||
ide->features[ 1*2+0] = ide->num_cylinders & 0xff; /* 1: logical cylinders */
|
||||
ide->features[ 1*2+1] = ide->num_cylinders >> 8;
|
||||
ide->features[ 2*2+0] = 0; /* 2: reserved */
|
||||
ide->features[ 2*2+1] = 0;
|
||||
ide->features[ 3*2+0] = ide->num_heads & 0xff; /* 3: logical heads */
|
||||
ide->features[ 3*2+1] = 0;/*ide->num_heads >> 8;*/
|
||||
ide->features[ 4*2+0] = 0; /* 4: vendor specific (obsolete) */
|
||||
ide->features[ 4*2+1] = 0;
|
||||
ide->features[ 5*2+0] = 0; /* 5: vendor specific (obsolete) */
|
||||
ide->features[ 5*2+1] = 0;
|
||||
ide->features[ 6*2+0] = ide->num_sectors & 0xff; /* 6: logical sectors per logical track */
|
||||
ide->features[ 6*2+1] = 0;/*ide->num_sectors >> 8;*/
|
||||
ide->features[ 7*2+0] = 0; /* 7: vendor-specific */
|
||||
ide->features[ 7*2+1] = 0;
|
||||
ide->features[ 8*2+0] = 0; /* 8: vendor-specific */
|
||||
ide->features[ 8*2+1] = 0;
|
||||
ide->features[ 9*2+0] = 0; /* 9: vendor-specific */
|
||||
ide->features[ 9*2+1] = 0;
|
||||
swap_strncpy(&ide->features[10*2+0], /* 10-19: serial number */
|
||||
ide->drive[drive].features[ 0*2+0] = 0x5a; /* 0: configuration bits */
|
||||
ide->drive[drive].features[ 0*2+1] = 0x04;
|
||||
ide->drive[drive].features[ 1*2+0] = ide->drive[drive].num_cylinders & 0xff; /* 1: logical cylinders */
|
||||
ide->drive[drive].features[ 1*2+1] = ide->drive[drive].num_cylinders >> 8;
|
||||
ide->drive[drive].features[ 2*2+0] = 0; /* 2: reserved */
|
||||
ide->drive[drive].features[ 2*2+1] = 0;
|
||||
ide->drive[drive].features[ 3*2+0] = ide->drive[drive].num_heads & 0xff; /* 3: logical heads */
|
||||
ide->drive[drive].features[ 3*2+1] = 0;/*ide->num_heads >> 8;*/
|
||||
ide->drive[drive].features[ 4*2+0] = 0; /* 4: vendor specific (obsolete) */
|
||||
ide->drive[drive].features[ 4*2+1] = 0;
|
||||
ide->drive[drive].features[ 5*2+0] = 0; /* 5: vendor specific (obsolete) */
|
||||
ide->drive[drive].features[ 5*2+1] = 0;
|
||||
ide->drive[drive].features[ 6*2+0] = ide->drive[drive].num_sectors & 0xff; /* 6: logical sectors per logical track */
|
||||
ide->drive[drive].features[ 6*2+1] = 0;/*ide->num_sectors >> 8;*/
|
||||
ide->drive[drive].features[ 7*2+0] = 0; /* 7: vendor-specific */
|
||||
ide->drive[drive].features[ 7*2+1] = 0;
|
||||
ide->drive[drive].features[ 8*2+0] = 0; /* 8: vendor-specific */
|
||||
ide->drive[drive].features[ 8*2+1] = 0;
|
||||
ide->drive[drive].features[ 9*2+0] = 0; /* 9: vendor-specific */
|
||||
ide->drive[drive].features[ 9*2+1] = 0;
|
||||
swap_strncpy(&ide->drive[drive].features[10*2+0], /* 10-19: serial number */
|
||||
"00000000000000000000", 10);
|
||||
ide->features[20*2+0] = 0; /* 20: vendor-specific */
|
||||
ide->features[20*2+1] = 0;
|
||||
ide->features[21*2+0] = 0; /* 21: vendor-specific */
|
||||
ide->features[21*2+1] = 0;
|
||||
ide->features[22*2+0] = 4; /* 22: # of vendor-specific bytes on read/write long commands */
|
||||
ide->features[22*2+1] = 0;
|
||||
swap_strncpy(&ide->features[23*2+0], /* 23-26: firmware revision */
|
||||
ide->drive[drive].features[20*2+0] = 0; /* 20: vendor-specific */
|
||||
ide->drive[drive].features[20*2+1] = 0;
|
||||
ide->drive[drive].features[21*2+0] = 0; /* 21: vendor-specific */
|
||||
ide->drive[drive].features[21*2+1] = 0;
|
||||
ide->drive[drive].features[22*2+0] = 4; /* 22: # of vendor-specific bytes on read/write long commands */
|
||||
ide->drive[drive].features[22*2+1] = 0;
|
||||
swap_strncpy(&ide->drive[drive].features[23*2+0], /* 23-26: firmware revision */
|
||||
"1.0", 4);
|
||||
swap_strncpy(&ide->features[27*2+0], /* 27-46: model number */
|
||||
swap_strncpy(&ide->drive[drive].features[27*2+0], /* 27-46: model number */
|
||||
"MAME Compressed Hard Disk", 20);
|
||||
ide->features[47*2+0] = 0x01; /* 47: read/write multiple support */
|
||||
ide->features[47*2+1] = 0x80;
|
||||
ide->features[48*2+0] = 0; /* 48: reserved */
|
||||
ide->features[48*2+1] = 0;
|
||||
ide->features[49*2+0] = 0x03; /* 49: capabilities */
|
||||
ide->features[49*2+1] = 0x0f;
|
||||
ide->features[50*2+0] = 0; /* 50: reserved */
|
||||
ide->features[50*2+1] = 0;
|
||||
ide->features[51*2+0] = 2; /* 51: PIO data transfer cycle timing mode */
|
||||
ide->features[51*2+1] = 0;
|
||||
ide->features[52*2+0] = 2; /* 52: single word DMA transfer cycle timing mode */
|
||||
ide->features[52*2+1] = 0;
|
||||
ide->features[53*2+0] = 3; /* 53: field validity */
|
||||
ide->features[53*2+1] = 0;
|
||||
ide->features[54*2+0] = ide->num_cylinders & 0xff; /* 54: number of current logical cylinders */
|
||||
ide->features[54*2+1] = ide->num_cylinders >> 8;
|
||||
ide->features[55*2+0] = ide->num_heads & 0xff; /* 55: number of current logical heads */
|
||||
ide->features[55*2+1] = 0;/*ide->num_heads >> 8;*/
|
||||
ide->features[56*2+0] = ide->num_sectors & 0xff; /* 56: number of current logical sectors per track */
|
||||
ide->features[56*2+1] = 0;/*ide->num_sectors >> 8;*/
|
||||
ide->features[57*2+0] = sectors_per_track & 0xff; /* 57-58: number of current logical sectors per track */
|
||||
ide->features[57*2+1] = sectors_per_track >> 8;
|
||||
ide->features[58*2+0] = sectors_per_track >> 16;
|
||||
ide->features[58*2+1] = sectors_per_track >> 24;
|
||||
ide->features[59*2+0] = 0; /* 59: multiple sector timing */
|
||||
ide->features[59*2+1] = 0;
|
||||
ide->features[60*2+0] = total_sectors & 0xff; /* 60-61: total user addressable sectors */
|
||||
ide->features[60*2+1] = total_sectors >> 8;
|
||||
ide->features[61*2+0] = total_sectors >> 16;
|
||||
ide->features[61*2+1] = total_sectors >> 24;
|
||||
ide->features[62*2+0] = 0x07; /* 62: single word dma transfer */
|
||||
ide->features[62*2+1] = 0x00;
|
||||
ide->features[63*2+0] = 0x07; /* 63: multiword DMA transfer */
|
||||
ide->features[63*2+1] = 0x04;
|
||||
ide->features[64*2+0] = 0x03; /* 64: flow control PIO transfer modes supported */
|
||||
ide->features[64*2+1] = 0x00;
|
||||
ide->features[65*2+0] = 0x78; /* 65: minimum multiword DMA transfer cycle time per word */
|
||||
ide->features[65*2+1] = 0x00;
|
||||
ide->features[66*2+0] = 0x78; /* 66: mfr's recommended multiword DMA transfer cycle time */
|
||||
ide->features[66*2+1] = 0x00;
|
||||
ide->features[67*2+0] = 0x4d; /* 67: minimum PIO transfer cycle time without flow control */
|
||||
ide->features[67*2+1] = 0x01;
|
||||
ide->features[68*2+0] = 0x78; /* 68: minimum PIO transfer cycle time with IORDY */
|
||||
ide->features[68*2+1] = 0x00;
|
||||
ide->features[69*2+0] = 0x00; /* 69-70: reserved */
|
||||
ide->features[69*2+1] = 0x00;
|
||||
ide->features[71*2+0] = 0x00; /* 71: reserved for IDENTIFY PACKET command */
|
||||
ide->features[71*2+1] = 0x00;
|
||||
ide->features[72*2+0] = 0x00; /* 72: reserved for IDENTIFY PACKET command */
|
||||
ide->features[72*2+1] = 0x00;
|
||||
ide->features[73*2+0] = 0x00; /* 73: reserved for IDENTIFY PACKET command */
|
||||
ide->features[73*2+1] = 0x00;
|
||||
ide->features[74*2+0] = 0x00; /* 74: reserved for IDENTIFY PACKET command */
|
||||
ide->features[74*2+1] = 0x00;
|
||||
ide->features[75*2+0] = 0x00; /* 75: queue depth */
|
||||
ide->features[75*2+1] = 0x00;
|
||||
ide->features[76*2+0] = 0x00; /* 76-79: reserved */
|
||||
ide->features[76*2+1] = 0x00;
|
||||
ide->features[80*2+0] = 0x00; /* 80: major version number */
|
||||
ide->features[80*2+1] = 0x00;
|
||||
ide->features[81*2+0] = 0x00; /* 81: minor version number */
|
||||
ide->features[81*2+1] = 0x00;
|
||||
ide->features[82*2+0] = 0x00; /* 82: command set supported */
|
||||
ide->features[82*2+1] = 0x00;
|
||||
ide->features[83*2+0] = 0x00; /* 83: command sets supported */
|
||||
ide->features[83*2+1] = 0x00;
|
||||
ide->features[84*2+0] = 0x00; /* 84: command set/feature supported extension */
|
||||
ide->features[84*2+1] = 0x00;
|
||||
ide->features[85*2+0] = 0x00; /* 85: command set/feature enabled */
|
||||
ide->features[85*2+1] = 0x00;
|
||||
ide->features[86*2+0] = 0x00; /* 86: command set/feature enabled */
|
||||
ide->features[86*2+1] = 0x00;
|
||||
ide->features[87*2+0] = 0x00; /* 87: command set/feature default */
|
||||
ide->features[87*2+1] = 0x00;
|
||||
ide->features[88*2+0] = 0x00; /* 88: additional DMA modes */
|
||||
ide->features[88*2+1] = 0x00;
|
||||
ide->features[89*2+0] = 0x00; /* 89: time required for security erase unit completion */
|
||||
ide->features[89*2+1] = 0x00;
|
||||
ide->features[90*2+0] = 0x00; /* 90: time required for enhanced security erase unit completion */
|
||||
ide->features[90*2+1] = 0x00;
|
||||
ide->features[91*2+0] = 0x00; /* 91: current advanced power management value */
|
||||
ide->features[91*2+1] = 0x00;
|
||||
ide->features[92*2+0] = 0x00; /* 92: master password revision code */
|
||||
ide->features[92*2+1] = 0x00;
|
||||
ide->features[93*2+0] = 0x00; /* 93: hardware reset result */
|
||||
ide->features[93*2+1] = 0x00;
|
||||
ide->features[94*2+0] = 0x00; /* 94: acoustic management values */
|
||||
ide->features[94*2+1] = 0x00;
|
||||
ide->features[95*2+0] = 0x00; /* 95-99: reserved */
|
||||
ide->features[95*2+1] = 0x00;
|
||||
ide->features[100*2+0] = total_sectors & 0xff; /* 100-103: maximum 48-bit LBA */
|
||||
ide->features[100*2+1] = total_sectors >> 8;
|
||||
ide->features[101*2+0] = total_sectors >> 16;
|
||||
ide->features[101*2+1] = total_sectors >> 24;
|
||||
ide->features[102*2+0] = 0x00;
|
||||
ide->features[102*2+1] = 0x00;
|
||||
ide->features[103*2+0] = 0x00;
|
||||
ide->features[103*2+1] = 0x00;
|
||||
ide->features[104*2+0] = 0x00; /* 104-126: reserved */
|
||||
ide->features[104*2+1] = 0x00;
|
||||
ide->features[127*2+0] = 0x00; /* 127: removable media status notification */
|
||||
ide->features[127*2+1] = 0x00;
|
||||
ide->features[128*2+0] = 0x00; /* 128: security status */
|
||||
ide->features[128*2+1] = 0x00;
|
||||
ide->features[129*2+0] = 0x00; /* 129-159: vendor specific */
|
||||
ide->features[129*2+1] = 0x00;
|
||||
ide->features[160*2+0] = 0x00; /* 160: CFA power mode 1 */
|
||||
ide->features[160*2+1] = 0x00;
|
||||
ide->features[161*2+0] = 0x00; /* 161-175: reserved for CompactFlash */
|
||||
ide->features[161*2+1] = 0x00;
|
||||
ide->features[176*2+0] = 0x00; /* 176-205: current media serial number */
|
||||
ide->features[176*2+1] = 0x00;
|
||||
ide->features[206*2+0] = 0x00; /* 206-254: reserved */
|
||||
ide->features[206*2+1] = 0x00;
|
||||
ide->features[255*2+0] = 0x00; /* 255: integrity word */
|
||||
ide->features[255*2+1] = 0x00;
|
||||
ide->drive[drive].features[47*2+0] = 0x01; /* 47: read/write multiple support */
|
||||
ide->drive[drive].features[47*2+1] = 0x80;
|
||||
ide->drive[drive].features[48*2+0] = 0; /* 48: reserved */
|
||||
ide->drive[drive].features[48*2+1] = 0;
|
||||
ide->drive[drive].features[49*2+0] = 0x03; /* 49: capabilities */
|
||||
ide->drive[drive].features[49*2+1] = 0x0f;
|
||||
ide->drive[drive].features[50*2+0] = 0; /* 50: reserved */
|
||||
ide->drive[drive].features[50*2+1] = 0;
|
||||
ide->drive[drive].features[51*2+0] = 2; /* 51: PIO data transfer cycle timing mode */
|
||||
ide->drive[drive].features[51*2+1] = 0;
|
||||
ide->drive[drive].features[52*2+0] = 2; /* 52: single word DMA transfer cycle timing mode */
|
||||
ide->drive[drive].features[52*2+1] = 0;
|
||||
ide->drive[drive].features[53*2+0] = 3; /* 53: field validity */
|
||||
ide->drive[drive].features[53*2+1] = 0;
|
||||
ide->drive[drive].features[54*2+0] = ide->drive[drive].num_cylinders & 0xff; /* 54: number of current logical cylinders */
|
||||
ide->drive[drive].features[54*2+1] = ide->drive[drive].num_cylinders >> 8;
|
||||
ide->drive[drive].features[55*2+0] = ide->drive[drive].num_heads & 0xff; /* 55: number of current logical heads */
|
||||
ide->drive[drive].features[55*2+1] = 0;/*ide->num_heads >> 8;*/
|
||||
ide->drive[drive].features[56*2+0] = ide->drive[drive].num_sectors & 0xff; /* 56: number of current logical sectors per track */
|
||||
ide->drive[drive].features[56*2+1] = 0;/*ide->num_sectors >> 8;*/
|
||||
ide->drive[drive].features[57*2+0] = sectors_per_track & 0xff; /* 57-58: number of current logical sectors per track */
|
||||
ide->drive[drive].features[57*2+1] = sectors_per_track >> 8;
|
||||
ide->drive[drive].features[58*2+0] = sectors_per_track >> 16;
|
||||
ide->drive[drive].features[58*2+1] = sectors_per_track >> 24;
|
||||
ide->drive[drive].features[59*2+0] = 0; /* 59: multiple sector timing */
|
||||
ide->drive[drive].features[59*2+1] = 0;
|
||||
ide->drive[drive].features[60*2+0] = total_sectors & 0xff; /* 60-61: total user addressable sectors */
|
||||
ide->drive[drive].features[60*2+1] = total_sectors >> 8;
|
||||
ide->drive[drive].features[61*2+0] = total_sectors >> 16;
|
||||
ide->drive[drive].features[61*2+1] = total_sectors >> 24;
|
||||
ide->drive[drive].features[62*2+0] = 0x07; /* 62: single word dma transfer */
|
||||
ide->drive[drive].features[62*2+1] = 0x00;
|
||||
ide->drive[drive].features[63*2+0] = 0x07; /* 63: multiword DMA transfer */
|
||||
ide->drive[drive].features[63*2+1] = 0x04;
|
||||
ide->drive[drive].features[64*2+0] = 0x03; /* 64: flow control PIO transfer modes supported */
|
||||
ide->drive[drive].features[64*2+1] = 0x00;
|
||||
ide->drive[drive].features[65*2+0] = 0x78; /* 65: minimum multiword DMA transfer cycle time per word */
|
||||
ide->drive[drive].features[65*2+1] = 0x00;
|
||||
ide->drive[drive].features[66*2+0] = 0x78; /* 66: mfr's recommended multiword DMA transfer cycle time */
|
||||
ide->drive[drive].features[66*2+1] = 0x00;
|
||||
ide->drive[drive].features[67*2+0] = 0x4d; /* 67: minimum PIO transfer cycle time without flow control */
|
||||
ide->drive[drive].features[67*2+1] = 0x01;
|
||||
ide->drive[drive].features[68*2+0] = 0x78; /* 68: minimum PIO transfer cycle time with IORDY */
|
||||
ide->drive[drive].features[68*2+1] = 0x00;
|
||||
ide->drive[drive].features[69*2+0] = 0x00; /* 69-70: reserved */
|
||||
ide->drive[drive].features[69*2+1] = 0x00;
|
||||
ide->drive[drive].features[71*2+0] = 0x00; /* 71: reserved for IDENTIFY PACKET command */
|
||||
ide->drive[drive].features[71*2+1] = 0x00;
|
||||
ide->drive[drive].features[72*2+0] = 0x00; /* 72: reserved for IDENTIFY PACKET command */
|
||||
ide->drive[drive].features[72*2+1] = 0x00;
|
||||
ide->drive[drive].features[73*2+0] = 0x00; /* 73: reserved for IDENTIFY PACKET command */
|
||||
ide->drive[drive].features[73*2+1] = 0x00;
|
||||
ide->drive[drive].features[74*2+0] = 0x00; /* 74: reserved for IDENTIFY PACKET command */
|
||||
ide->drive[drive].features[74*2+1] = 0x00;
|
||||
ide->drive[drive].features[75*2+0] = 0x00; /* 75: queue depth */
|
||||
ide->drive[drive].features[75*2+1] = 0x00;
|
||||
ide->drive[drive].features[76*2+0] = 0x00; /* 76-79: reserved */
|
||||
ide->drive[drive].features[76*2+1] = 0x00;
|
||||
ide->drive[drive].features[80*2+0] = 0x00; /* 80: major version number */
|
||||
ide->drive[drive].features[80*2+1] = 0x00;
|
||||
ide->drive[drive].features[81*2+0] = 0x00; /* 81: minor version number */
|
||||
ide->drive[drive].features[81*2+1] = 0x00;
|
||||
ide->drive[drive].features[82*2+0] = 0x00; /* 82: command set supported */
|
||||
ide->drive[drive].features[82*2+1] = 0x00;
|
||||
ide->drive[drive].features[83*2+0] = 0x00; /* 83: command sets supported */
|
||||
ide->drive[drive].features[83*2+1] = 0x00;
|
||||
ide->drive[drive].features[84*2+0] = 0x00; /* 84: command set/feature supported extension */
|
||||
ide->drive[drive].features[84*2+1] = 0x00;
|
||||
ide->drive[drive].features[85*2+0] = 0x00; /* 85: command set/feature enabled */
|
||||
ide->drive[drive].features[85*2+1] = 0x00;
|
||||
ide->drive[drive].features[86*2+0] = 0x00; /* 86: command set/feature enabled */
|
||||
ide->drive[drive].features[86*2+1] = 0x00;
|
||||
ide->drive[drive].features[87*2+0] = 0x00; /* 87: command set/feature default */
|
||||
ide->drive[drive].features[87*2+1] = 0x00;
|
||||
ide->drive[drive].features[88*2+0] = 0x00; /* 88: additional DMA modes */
|
||||
ide->drive[drive].features[88*2+1] = 0x00;
|
||||
ide->drive[drive].features[89*2+0] = 0x00; /* 89: time required for security erase unit completion */
|
||||
ide->drive[drive].features[89*2+1] = 0x00;
|
||||
ide->drive[drive].features[90*2+0] = 0x00; /* 90: time required for enhanced security erase unit completion */
|
||||
ide->drive[drive].features[90*2+1] = 0x00;
|
||||
ide->drive[drive].features[91*2+0] = 0x00; /* 91: current advanced power management value */
|
||||
ide->drive[drive].features[91*2+1] = 0x00;
|
||||
ide->drive[drive].features[92*2+0] = 0x00; /* 92: master password revision code */
|
||||
ide->drive[drive].features[92*2+1] = 0x00;
|
||||
ide->drive[drive].features[93*2+0] = 0x00; /* 93: hardware reset result */
|
||||
ide->drive[drive].features[93*2+1] = 0x00;
|
||||
ide->drive[drive].features[94*2+0] = 0x00; /* 94: acoustic management values */
|
||||
ide->drive[drive].features[94*2+1] = 0x00;
|
||||
ide->drive[drive].features[95*2+0] = 0x00; /* 95-99: reserved */
|
||||
ide->drive[drive].features[95*2+1] = 0x00;
|
||||
ide->drive[drive].features[100*2+0] = total_sectors & 0xff; /* 100-103: maximum 48-bit LBA */
|
||||
ide->drive[drive].features[100*2+1] = total_sectors >> 8;
|
||||
ide->drive[drive].features[101*2+0] = total_sectors >> 16;
|
||||
ide->drive[drive].features[101*2+1] = total_sectors >> 24;
|
||||
ide->drive[drive].features[102*2+0] = 0x00;
|
||||
ide->drive[drive].features[102*2+1] = 0x00;
|
||||
ide->drive[drive].features[103*2+0] = 0x00;
|
||||
ide->drive[drive].features[103*2+1] = 0x00;
|
||||
ide->drive[drive].features[104*2+0] = 0x00; /* 104-126: reserved */
|
||||
ide->drive[drive].features[104*2+1] = 0x00;
|
||||
ide->drive[drive].features[127*2+0] = 0x00; /* 127: removable media status notification */
|
||||
ide->drive[drive].features[127*2+1] = 0x00;
|
||||
ide->drive[drive].features[128*2+0] = 0x00; /* 128: security status */
|
||||
ide->drive[drive].features[128*2+1] = 0x00;
|
||||
ide->drive[drive].features[129*2+0] = 0x00; /* 129-159: vendor specific */
|
||||
ide->drive[drive].features[129*2+1] = 0x00;
|
||||
ide->drive[drive].features[160*2+0] = 0x00; /* 160: CFA power mode 1 */
|
||||
ide->drive[drive].features[160*2+1] = 0x00;
|
||||
ide->drive[drive].features[161*2+0] = 0x00; /* 161-175: reserved for CompactFlash */
|
||||
ide->drive[drive].features[161*2+1] = 0x00;
|
||||
ide->drive[drive].features[176*2+0] = 0x00; /* 176-205: current media serial number */
|
||||
ide->drive[drive].features[176*2+1] = 0x00;
|
||||
ide->drive[drive].features[206*2+0] = 0x00; /* 206-254: reserved */
|
||||
ide->drive[drive].features[206*2+1] = 0x00;
|
||||
ide->drive[drive].features[255*2+0] = 0x00; /* 255: integrity word */
|
||||
ide->drive[drive].features[255*2+1] = 0x00;
|
||||
}
|
||||
|
||||
|
||||
static void ide_build_features(ide_state *ide)
|
||||
static void ide_build_features(ide_state *ide, int drive)
|
||||
{
|
||||
memset(ide->features, 0, IDE_DISK_SECTOR_SIZE);
|
||||
if (chd_get_metadata (ide->handle, HARD_DISK_IDENT_METADATA_TAG, 0, ide->features, IDE_DISK_SECTOR_SIZE, 0, 0, 0) != CHDERR_NONE)
|
||||
ide_generate_features (ide);
|
||||
memset(ide->drive[drive].features, 0, IDE_DISK_SECTOR_SIZE);
|
||||
if (chd_get_metadata (ide->drive[drive].handle, HARD_DISK_IDENT_METADATA_TAG, 0, ide->drive[drive].features, IDE_DISK_SECTOR_SIZE, 0, 0, 0) != CHDERR_NONE)
|
||||
ide_generate_features (ide,drive);
|
||||
}
|
||||
|
||||
/*************************************
|
||||
@ -733,8 +743,8 @@ static void read_sector_done(ide_state *ide)
|
||||
return;
|
||||
}
|
||||
/* now do the read */
|
||||
if (ide->disk)
|
||||
count = hard_disk_read(ide->disk, lba, ide->buffer);
|
||||
if (ide->drive[ide->cur_drive].disk)
|
||||
count = hard_disk_read(ide->drive[ide->cur_drive].disk, lba, ide->buffer);
|
||||
else if (ide->hardware != NULL) {
|
||||
count = ide->hardware->read_sector(ide->device, lba, ide->buffer);
|
||||
}
|
||||
@ -809,12 +819,12 @@ static void read_first_sector(ide_state *ide)
|
||||
int new_lba = lba_address(ide);
|
||||
attotime seek_time;
|
||||
|
||||
if (new_lba == ide->cur_lba || new_lba == ide->cur_lba + 1)
|
||||
if (new_lba == ide->drive[ide->cur_drive].cur_lba || new_lba == ide->drive[ide->cur_drive].cur_lba + 1)
|
||||
seek_time = TIME_NO_SEEK_MULTISECTOR;
|
||||
else
|
||||
seek_time = TIME_SEEK_MULTISECTOR;
|
||||
|
||||
ide->cur_lba = new_lba;
|
||||
ide->drive[ide->cur_drive].cur_lba = new_lba;
|
||||
ide->device->machine().scheduler().timer_set(seek_time, FUNC(read_sector_done_callback), 0, ide);
|
||||
}
|
||||
else
|
||||
@ -934,8 +944,8 @@ static void write_sector_done(ide_state *ide)
|
||||
int lba = lba_address(ide), count = 0;
|
||||
|
||||
/* now do the write */
|
||||
if (ide->disk)
|
||||
count = hard_disk_write(ide->disk, lba, ide->buffer);
|
||||
if (ide->drive[ide->cur_drive].disk)
|
||||
count = hard_disk_write(ide->drive[ide->cur_drive].disk, lba, ide->buffer);
|
||||
else if (ide->hardware != NULL) {
|
||||
count = ide->hardware->write_sector(ide->device, lba, ide->buffer);
|
||||
}
|
||||
@ -1016,14 +1026,13 @@ static void handle_command(ide_state *ide, UINT8 command)
|
||||
|
||||
/* implicitly clear interrupts here */
|
||||
clear_interrupt(ide);
|
||||
|
||||
ide->command = command;
|
||||
switch (command)
|
||||
{
|
||||
case IDE_COMMAND_READ_MULTIPLE:
|
||||
case IDE_COMMAND_READ_MULTIPLE_ONCE:
|
||||
LOGPRINT(("IDE Read multiple: C=%d H=%d S=%d LBA=%d count=%d\n",
|
||||
ide->cur_cylinder, ide->cur_head, ide->cur_sector, lba_address(ide), ide->sector_count));
|
||||
ide->drive[ide->cur_drive].cur_cylinder, ide->drive[ide->cur_drive].cur_head, ide->drive[ide->cur_drive].cur_sector, lba_address(ide), ide->sector_count));
|
||||
|
||||
/* reset the buffer */
|
||||
ide->buffer_offset = 0;
|
||||
@ -1037,7 +1046,7 @@ static void handle_command(ide_state *ide, UINT8 command)
|
||||
|
||||
case IDE_COMMAND_READ_MULTIPLE_BLOCK:
|
||||
LOGPRINT(("IDE Read multiple block: C=%d H=%d S=%d LBA=%d count=%d\n",
|
||||
ide->cur_cylinder, ide->cur_head, ide->cur_sector, lba_address(ide), ide->sector_count));
|
||||
ide->drive[ide->cur_drive].cur_cylinder, ide->drive[ide->cur_drive].cur_head, ide->drive[ide->cur_drive].cur_sector, lba_address(ide), ide->sector_count));
|
||||
|
||||
/* reset the buffer */
|
||||
ide->buffer_offset = 0;
|
||||
@ -1052,7 +1061,7 @@ static void handle_command(ide_state *ide, UINT8 command)
|
||||
case IDE_COMMAND_VERIFY_MULTIPLE:
|
||||
case IDE_COMMAND_VERIFY_NORETRY:
|
||||
LOGPRINT(("IDE Read verify multiple with/without retries: C=%d H=%d S=%d LBA=%d count=%d\n",
|
||||
ide->cur_cylinder, ide->cur_head, ide->cur_sector, lba_address(ide), ide->sector_count));
|
||||
ide->drive[ide->cur_drive].cur_cylinder, ide->drive[ide->cur_drive].cur_head, ide->drive[ide->cur_drive].cur_sector, lba_address(ide), ide->sector_count));
|
||||
|
||||
/* reset the buffer */
|
||||
ide->buffer_offset = 0;
|
||||
@ -1066,7 +1075,7 @@ static void handle_command(ide_state *ide, UINT8 command)
|
||||
|
||||
case IDE_COMMAND_READ_DMA:
|
||||
LOGPRINT(("IDE Read multiple DMA: C=%d H=%d S=%d LBA=%d count=%d\n",
|
||||
ide->cur_cylinder, ide->cur_head, ide->cur_sector, lba_address(ide), ide->sector_count));
|
||||
ide->drive[ide->cur_drive].cur_cylinder, ide->drive[ide->cur_drive].cur_head, ide->drive[ide->cur_drive].cur_sector, lba_address(ide), ide->sector_count));
|
||||
|
||||
/* reset the buffer */
|
||||
ide->buffer_offset = 0;
|
||||
@ -1081,7 +1090,7 @@ static void handle_command(ide_state *ide, UINT8 command)
|
||||
|
||||
case IDE_COMMAND_WRITE_MULTIPLE:
|
||||
LOGPRINT(("IDE Write multiple: C=%d H=%d S=%d LBA=%d count=%d\n",
|
||||
ide->cur_cylinder, ide->cur_head, ide->cur_sector, lba_address(ide), ide->sector_count));
|
||||
ide->drive[ide->cur_drive].cur_cylinder, ide->drive[ide->cur_drive].cur_head, ide->drive[ide->cur_drive].cur_sector, lba_address(ide), ide->sector_count));
|
||||
|
||||
/* reset the buffer */
|
||||
ide->buffer_offset = 0;
|
||||
@ -1094,7 +1103,7 @@ static void handle_command(ide_state *ide, UINT8 command)
|
||||
|
||||
case IDE_COMMAND_WRITE_MULTIPLE_BLOCK:
|
||||
LOGPRINT(("IDE Write multiple block: C=%d H=%d S=%d LBA=%d count=%d\n",
|
||||
ide->cur_cylinder, ide->cur_head, ide->cur_sector, lba_address(ide), ide->sector_count));
|
||||
ide->drive[ide->cur_drive].cur_cylinder, ide->drive[ide->cur_drive].cur_head, ide->drive[ide->cur_drive].cur_sector, lba_address(ide), ide->sector_count));
|
||||
|
||||
/* reset the buffer */
|
||||
ide->buffer_offset = 0;
|
||||
@ -1107,7 +1116,7 @@ static void handle_command(ide_state *ide, UINT8 command)
|
||||
|
||||
case IDE_COMMAND_WRITE_DMA:
|
||||
LOGPRINT(("IDE Write multiple DMA: C=%d H=%d S=%d LBA=%d count=%d\n",
|
||||
ide->cur_cylinder, ide->cur_head, ide->cur_sector, lba_address(ide), ide->sector_count));
|
||||
ide->drive[ide->cur_drive].cur_cylinder, ide->drive[ide->cur_drive].cur_head, ide->drive[ide->cur_drive].cur_sector, lba_address(ide), ide->sector_count));
|
||||
|
||||
/* reset the buffer */
|
||||
ide->buffer_offset = 0;
|
||||
@ -1143,7 +1152,7 @@ static void handle_command(ide_state *ide, UINT8 command)
|
||||
ide->sector_count = 1;
|
||||
|
||||
/* build the features page */
|
||||
memcpy(ide->buffer, ide->features, sizeof(ide->buffer));
|
||||
memcpy(ide->buffer, ide->drive[ide->cur_drive].features, sizeof(ide->buffer));
|
||||
|
||||
/* indicate everything is ready */
|
||||
ide->status |= IDE_STATUS_BUFFER_READY;
|
||||
@ -1171,7 +1180,6 @@ static void handle_command(ide_state *ide, UINT8 command)
|
||||
case IDE_COMMAND_RECALIBRATE:
|
||||
/* clear the error too */
|
||||
ide->error = IDE_ERROR_NONE;
|
||||
|
||||
/* signal an interrupt */
|
||||
signal_delayed_interrupt(ide, MINIMUM_COMMAND_TIME, 0);
|
||||
break;
|
||||
@ -1187,12 +1195,12 @@ static void handle_command(ide_state *ide, UINT8 command)
|
||||
break;
|
||||
|
||||
case IDE_COMMAND_SET_CONFIG:
|
||||
LOGPRINT(("IDE Set configuration (%d heads, %d sectors)\n", ide->cur_head + 1, ide->sector_count));
|
||||
LOGPRINT(("IDE Set configuration (%d heads, %d sectors)\n", ide->drive[ide->cur_drive].cur_head + 1, ide->sector_count));
|
||||
ide->status &= ~IDE_STATUS_ERROR;
|
||||
ide->error = IDE_ERROR_NONE;
|
||||
|
||||
ide->num_sectors = ide->sector_count;
|
||||
ide->num_heads = ide->cur_head + 1;
|
||||
ide->drive[ide->cur_drive].num_sectors = ide->sector_count;
|
||||
ide->drive[ide->cur_drive].num_heads = ide->drive[ide->cur_drive].cur_head + 1;
|
||||
|
||||
/* signal an interrupt */
|
||||
signal_delayed_interrupt(ide, MINIMUM_COMMAND_TIME, 0);
|
||||
@ -1207,7 +1215,7 @@ static void handle_command(ide_state *ide, UINT8 command)
|
||||
break;
|
||||
|
||||
case IDE_COMMAND_SET_FEATURES:
|
||||
LOGPRINT(("IDE Set features (%02X %02X %02X %02X %02X)\n", ide->precomp_offset, ide->sector_count & 0xff, ide->cur_sector, ide->cur_cylinder & 0xff, ide->cur_cylinder >> 8));
|
||||
LOGPRINT(("IDE Set features (%02X %02X %02X %02X %02X)\n", ide->precomp_offset, ide->sector_count & 0xff, ide->drive[ide->cur_drive].cur_sector, ide->drive[ide->cur_drive].cur_cylinder & 0xff, ide->drive[ide->cur_drive].cur_cylinder >> 8));
|
||||
|
||||
/* signal an interrupt */
|
||||
signal_delayed_interrupt(ide, MINIMUM_COMMAND_TIME, 0);
|
||||
@ -1250,8 +1258,8 @@ static void handle_command(ide_state *ide, UINT8 command)
|
||||
LOGPRINT(("IDE GNET Unlock 3\n"));
|
||||
|
||||
/* key check */
|
||||
chd_get_metadata (ide->handle, HARD_DISK_KEY_METADATA_TAG, 0, key, 5, 0, 0, 0);
|
||||
if ((ide->precomp_offset == key[0]) && (ide->sector_count == key[1]) && (ide->cur_sector == key[2]) && (ide->cur_cylinder == (((UINT16)key[4]<<8)|key[3])))
|
||||
chd_get_metadata (ide->drive[ide->cur_drive].handle, HARD_DISK_KEY_METADATA_TAG, 0, key, 5, 0, 0, 0);
|
||||
if ((ide->precomp_offset == key[0]) && (ide->sector_count == key[1]) && (ide->drive[ide->cur_drive].cur_sector == key[2]) && (ide->drive[ide->cur_drive].cur_cylinder == (((UINT16)key[4]<<8)|key[3])))
|
||||
{
|
||||
ide->gnetreadlock= 0;
|
||||
}
|
||||
@ -1305,6 +1313,12 @@ static UINT32 ide_controller_read(device_t *device, int bank, offs_t offset, int
|
||||
// if (BANK(bank, offset) != IDE_BANK0_DATA && BANK(bank, offset) != IDE_BANK0_STATUS_COMMAND && BANK(bank, offset) != IDE_BANK1_STATUS_CONTROL)
|
||||
LOG(("%s:IDE read at %d:%X, size=%d\n", device->machine().describe_context(), bank, offset, size));
|
||||
|
||||
if (ide->drive[ide->cur_drive].disk) {
|
||||
ide->status |= IDE_STATUS_DRIVE_READY;
|
||||
} else {
|
||||
ide->status &= ~IDE_STATUS_DRIVE_READY;
|
||||
}
|
||||
|
||||
switch (BANK(bank, offset))
|
||||
{
|
||||
/* unknown config register */
|
||||
@ -1355,19 +1369,19 @@ static UINT32 ide_controller_read(device_t *device, int bank, offs_t offset, int
|
||||
|
||||
/* return the current sector */
|
||||
case IDE_BANK0_SECTOR_NUMBER:
|
||||
return ide->cur_sector;
|
||||
return ide->drive[ide->cur_drive].cur_sector;
|
||||
|
||||
/* return the current cylinder LSB */
|
||||
case IDE_BANK0_CYLINDER_LSB:
|
||||
return ide->cur_cylinder & 0xff;
|
||||
return ide->drive[ide->cur_drive].cur_cylinder & 0xff;
|
||||
|
||||
/* return the current cylinder MSB */
|
||||
case IDE_BANK0_CYLINDER_MSB:
|
||||
return ide->cur_cylinder >> 8;
|
||||
return ide->drive[ide->cur_drive].cur_cylinder >> 8;
|
||||
|
||||
/* return the current head */
|
||||
case IDE_BANK0_HEAD_NUMBER:
|
||||
return ide->cur_head_reg;
|
||||
return ide->drive[ide->cur_drive].cur_head_reg;
|
||||
|
||||
/* return the current status and clear any pending interrupts */
|
||||
case IDE_BANK0_STATUS_COMMAND:
|
||||
@ -1491,7 +1505,7 @@ static void ide_controller_write(device_t *device, int bank, offs_t offset, int
|
||||
{
|
||||
UINT8 key[5] = { 0, 0, 0, 0, 0 };
|
||||
int i, bad = 0;
|
||||
chd_get_metadata (ide->handle, HARD_DISK_KEY_METADATA_TAG, 0, key, 5, 0, 0, 0);
|
||||
chd_get_metadata (ide->drive[ide->cur_drive].handle, HARD_DISK_KEY_METADATA_TAG, 0, key, 5, 0, 0, 0);
|
||||
|
||||
for (i=0; !bad && i<512; i++)
|
||||
bad = ((i < 2 || i >= 7) && ide->buffer[i]) || ((i >= 2 && i < 7) && ide->buffer[i] != key[i-2]);
|
||||
@ -1524,24 +1538,24 @@ static void ide_controller_write(device_t *device, int bank, offs_t offset, int
|
||||
|
||||
/* current sector */
|
||||
case IDE_BANK0_SECTOR_NUMBER:
|
||||
ide->cur_sector = data;
|
||||
ide->drive[ide->cur_drive].cur_sector = data;
|
||||
break;
|
||||
|
||||
/* current cylinder LSB */
|
||||
case IDE_BANK0_CYLINDER_LSB:
|
||||
ide->cur_cylinder = (ide->cur_cylinder & 0xff00) | (data & 0xff);
|
||||
ide->drive[ide->cur_drive].cur_cylinder = (ide->drive[ide->cur_drive].cur_cylinder & 0xff00) | (data & 0xff);
|
||||
break;
|
||||
|
||||
/* current cylinder MSB */
|
||||
case IDE_BANK0_CYLINDER_MSB:
|
||||
ide->cur_cylinder = (ide->cur_cylinder & 0x00ff) | ((data & 0xff) << 8);
|
||||
ide->drive[ide->cur_drive].cur_cylinder = (ide->drive[ide->cur_drive].cur_cylinder & 0x00ff) | ((data & 0xff) << 8);
|
||||
break;
|
||||
|
||||
/* current head */
|
||||
case IDE_BANK0_HEAD_NUMBER:
|
||||
ide->cur_head = data & 0x0f;
|
||||
ide->cur_head_reg = data;
|
||||
// drive index = data & 0x10
|
||||
ide->cur_drive = (data & 0x10) >> 4;
|
||||
ide->drive[ide->cur_drive].cur_head = data & 0x0f;
|
||||
ide->drive[ide->cur_drive].cur_head_reg = data;
|
||||
// LBA mode = data & 0x40
|
||||
break;
|
||||
|
||||
@ -1858,9 +1872,17 @@ static DEVICE_START( ide_controller )
|
||||
|
||||
/* set MAME harddisk handle */
|
||||
config = (const ide_config *)downcast<const legacy_device_base *>(device)->inline_config();
|
||||
ide->handle = get_disk_handle(device->machine(), (config->master != NULL) ? config->master : device->tag());
|
||||
ide->disk = hard_disk_open(ide->handle);
|
||||
ide->is_image_device = false;
|
||||
|
||||
ide->drive[0].handle = get_disk_handle(device->machine(), (config->master != NULL) ? config->master : device->tag());
|
||||
ide->drive[0].disk = hard_disk_open(ide->drive[0].handle);
|
||||
ide->drive[0].is_image_device = false;
|
||||
|
||||
if (config->slave) {
|
||||
ide->drive[1].handle = get_disk_handle(device->machine(), config->slave);
|
||||
ide->drive[1].disk = hard_disk_open(ide->drive[1].handle);
|
||||
ide->drive[1].is_image_device = false;
|
||||
}
|
||||
|
||||
//assert_always(config->slave == NULL, "IDE controller does not yet support slave drives\n");
|
||||
|
||||
/* find the bus master space */
|
||||
@ -1879,23 +1901,38 @@ static DEVICE_START( ide_controller )
|
||||
}
|
||||
|
||||
/* get and copy the geometry */
|
||||
if (ide->disk != NULL)
|
||||
if (ide->drive[0].disk != NULL)
|
||||
{
|
||||
hdinfo = hard_disk_get_info(ide->disk);
|
||||
hdinfo = hard_disk_get_info(ide->drive[0].disk);
|
||||
if (hdinfo->sectorbytes == IDE_DISK_SECTOR_SIZE)
|
||||
{
|
||||
ide->num_cylinders = hdinfo->cylinders;
|
||||
ide->num_sectors = hdinfo->sectors;
|
||||
ide->num_heads = hdinfo->heads;
|
||||
if (PRINTF_IDE_COMMANDS) mame_printf_debug("CHS: %d %d %d\n", ide->num_cylinders, ide->num_heads, ide->num_sectors);
|
||||
ide->drive[0].num_cylinders = hdinfo->cylinders;
|
||||
ide->drive[0].num_sectors = hdinfo->sectors;
|
||||
ide->drive[0].num_heads = hdinfo->heads;
|
||||
if (PRINTF_IDE_COMMANDS) mame_printf_debug("CHS: %d %d %d\n", ide->drive[0].num_cylinders, ide->drive[0].num_heads, ide->drive[0].num_sectors);
|
||||
}
|
||||
|
||||
/* build the features page */
|
||||
ide_build_features(ide);
|
||||
} else if (config->hardware != NULL) {
|
||||
ide_build_features(ide,0);
|
||||
}
|
||||
if (ide->drive[1].disk != NULL)
|
||||
{
|
||||
hdinfo = hard_disk_get_info(ide->drive[1].disk);
|
||||
if (hdinfo->sectorbytes == IDE_DISK_SECTOR_SIZE)
|
||||
{
|
||||
ide->drive[1].num_cylinders = hdinfo->cylinders;
|
||||
ide->drive[1].num_sectors = hdinfo->sectors;
|
||||
ide->drive[1].num_heads = hdinfo->heads;
|
||||
if (PRINTF_IDE_COMMANDS) mame_printf_debug("CHS: %d %d %d\n", ide->drive[1].num_cylinders, ide->drive[1].num_heads, ide->drive[1].num_sectors);
|
||||
}
|
||||
|
||||
/* build the features page */
|
||||
ide_build_features(ide,1);
|
||||
}
|
||||
if (config->hardware != NULL) {
|
||||
ide->hardware = (ide_hardware *)config->hardware;
|
||||
ide->hardware->get_info(ide->device, ide->features, ide->num_cylinders, ide->num_sectors, ide->num_heads);
|
||||
ide_generate_features (ide);
|
||||
ide->hardware->get_info(ide->device, ide->drive[0].features, ide->drive[0].num_cylinders, ide->drive[0].num_sectors, ide->drive[0].num_heads);
|
||||
ide_generate_features (ide,0);
|
||||
}
|
||||
|
||||
/* create a timer for timing status */
|
||||
@ -1911,7 +1948,7 @@ static DEVICE_START( ide_controller )
|
||||
device->save_item(NAME(ide->precomp_offset));
|
||||
|
||||
device->save_item(NAME(ide->buffer));
|
||||
device->save_item(NAME(ide->features));
|
||||
//device->save_item(NAME(ide->features));
|
||||
device->save_item(NAME(ide->buffer_offset));
|
||||
device->save_item(NAME(ide->sector_count));
|
||||
|
||||
@ -1928,16 +1965,16 @@ static DEVICE_START( ide_controller )
|
||||
device->save_item(NAME(ide->bus_master_status));
|
||||
device->save_item(NAME(ide->bus_master_descriptor));
|
||||
|
||||
device->save_item(NAME(ide->cur_cylinder));
|
||||
device->save_item(NAME(ide->cur_sector));
|
||||
device->save_item(NAME(ide->cur_head));
|
||||
device->save_item(NAME(ide->cur_head_reg));
|
||||
//device->save_item(NAME(ide->cur_cylinder));
|
||||
//device->save_item(NAME(ide->cur_sector));
|
||||
//device->save_item(NAME(ide->cur_head));
|
||||
//device->save_item(NAME(ide->cur_head_reg));
|
||||
|
||||
device->save_item(NAME(ide->cur_lba));
|
||||
//device->save_item(NAME(ide->cur_lba));
|
||||
|
||||
device->save_item(NAME(ide->num_cylinders));
|
||||
device->save_item(NAME(ide->num_sectors));
|
||||
device->save_item(NAME(ide->num_heads));
|
||||
//device->save_item(NAME(ide->num_cylinders));
|
||||
//device->save_item(NAME(ide->num_sectors));
|
||||
//device->save_item(NAME(ide->num_heads));
|
||||
|
||||
device->save_item(NAME(ide->config_unknown));
|
||||
device->save_item(NAME(ide->config_register));
|
||||
@ -1957,10 +1994,15 @@ static DEVICE_START( ide_controller )
|
||||
static DEVICE_STOP( ide_controller )
|
||||
{
|
||||
ide_state *ide = get_safe_token(device);
|
||||
if (!ide->is_image_device) {
|
||||
if (!ide->drive[0].is_image_device) {
|
||||
/* close the hard disk */
|
||||
if (ide->disk != NULL)
|
||||
hard_disk_close(ide->disk);
|
||||
if (ide->drive[0].disk != NULL)
|
||||
hard_disk_close(ide->drive[0].disk);
|
||||
}
|
||||
if (!ide->drive[1].is_image_device) {
|
||||
/* close the hard disk */
|
||||
if (ide->drive[1].disk != NULL)
|
||||
hard_disk_close(ide->drive[1].disk);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1974,43 +2016,78 @@ static DEVICE_RESET( ide_controller )
|
||||
ide_state *ide = get_safe_token(device);
|
||||
const ide_config *config = (const ide_config *)downcast<const legacy_device_base *>(device)->inline_config();
|
||||
|
||||
ide->cur_drive = 0;
|
||||
LOG(("IDE controller reset performed\n"));
|
||||
astring hardtag;
|
||||
astring hardtag_master;
|
||||
astring hardtag_slave;
|
||||
if (config->master) {
|
||||
device->siblingtag(hardtag, config->master);
|
||||
device->siblingtag(hardtag_master, config->master);
|
||||
}
|
||||
if (config->slave) {
|
||||
device->siblingtag(hardtag_slave, config->slave);
|
||||
}
|
||||
|
||||
if (device->machine().device( hardtag.cstr() )) {
|
||||
if (!ide->disk)
|
||||
if (device->machine().device( hardtag_master.cstr() )) {
|
||||
if (!ide->drive[0].disk)
|
||||
{
|
||||
ide->handle = device->machine().device<harddisk_image_device>(hardtag.cstr())->get_chd_file(); // should be config->master
|
||||
ide->drive[0].handle = device->machine().device<harddisk_image_device>(hardtag_master.cstr())->get_chd_file(); // should be config->master
|
||||
|
||||
if (ide->handle)
|
||||
if (ide->drive[0].handle)
|
||||
{
|
||||
ide->disk = device->machine().device<harddisk_image_device>(hardtag.cstr())->get_hard_disk_file(); // should be config->master
|
||||
ide->is_image_device = true;
|
||||
ide->drive[0].disk = device->machine().device<harddisk_image_device>(hardtag_master.cstr())->get_hard_disk_file(); // should be config->master
|
||||
ide->drive[0].is_image_device = true;
|
||||
|
||||
if (ide->disk != NULL)
|
||||
if (ide->drive[0].disk != NULL)
|
||||
{
|
||||
const hard_disk_info *hdinfo;
|
||||
|
||||
hdinfo = hard_disk_get_info(ide->disk);
|
||||
hdinfo = hard_disk_get_info(ide->drive[0].disk);
|
||||
if (hdinfo->sectorbytes == IDE_DISK_SECTOR_SIZE)
|
||||
{
|
||||
ide->num_cylinders = hdinfo->cylinders;
|
||||
ide->num_sectors = hdinfo->sectors;
|
||||
ide->num_heads = hdinfo->heads;
|
||||
if (PRINTF_IDE_COMMANDS) printf("CHS: %d %d %d\n", ide->num_cylinders, ide->num_heads, ide->num_sectors);
|
||||
ide->drive[0].num_cylinders = hdinfo->cylinders;
|
||||
ide->drive[0].num_sectors = hdinfo->sectors;
|
||||
ide->drive[0].num_heads = hdinfo->heads;
|
||||
if (PRINTF_IDE_COMMANDS) printf("CHS: %d %d %d\n", ide->drive[0].num_cylinders, ide->drive[0].num_heads, ide->drive[0].num_sectors);
|
||||
}
|
||||
|
||||
/* build the features page */
|
||||
ide_build_features(ide);
|
||||
ide_build_features(ide,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ide->hardware != NULL) {
|
||||
ide->hardware->get_info(ide->device, ide->features, ide->num_cylinders, ide->num_sectors, ide->num_heads);
|
||||
ide_generate_features (ide);
|
||||
}
|
||||
if (device->machine().device( hardtag_slave.cstr() )) {
|
||||
if (!ide->drive[1].disk)
|
||||
{
|
||||
ide->drive[1].handle = device->machine().device<harddisk_image_device>(hardtag_slave.cstr())->get_chd_file(); // should be config->master
|
||||
|
||||
if (ide->drive[1].handle)
|
||||
{
|
||||
ide->drive[1].disk = device->machine().device<harddisk_image_device>(hardtag_slave.cstr())->get_hard_disk_file(); // should be config->master
|
||||
ide->drive[1].is_image_device = true;
|
||||
|
||||
if (ide->drive[1].disk != NULL)
|
||||
{
|
||||
const hard_disk_info *hdinfo;
|
||||
|
||||
hdinfo = hard_disk_get_info(ide->drive[1].disk);
|
||||
if (hdinfo->sectorbytes == IDE_DISK_SECTOR_SIZE)
|
||||
{
|
||||
ide->drive[1].num_cylinders = hdinfo->cylinders;
|
||||
ide->drive[1].num_sectors = hdinfo->sectors;
|
||||
ide->drive[1].num_heads = hdinfo->heads;
|
||||
if (PRINTF_IDE_COMMANDS) printf("CHS: %d %d %d\n", ide->drive[1].num_cylinders, ide->drive[1].num_heads, ide->drive[1].num_sectors);
|
||||
}
|
||||
|
||||
/* build the features page */
|
||||
ide_build_features(ide,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ide->hardware != NULL) {
|
||||
ide->hardware->get_info(ide->device, ide->drive[0].features, ide->drive[0].num_cylinders, ide->drive[0].num_sectors, ide->drive[0].num_heads);
|
||||
ide_generate_features (ide,0);
|
||||
}
|
||||
|
||||
/* reset the drive state */
|
||||
|
@ -67,7 +67,7 @@ struct _ide_config
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
UINT8 *ide_get_features(device_t *device);
|
||||
UINT8 *ide_get_features(device_t *device, int drive);
|
||||
|
||||
void ide_set_master_password(device_t *device, const UINT8 *password);
|
||||
void ide_set_user_password(device_t *device, const UINT8 *password);
|
||||
|
@ -167,7 +167,7 @@ static MACHINE_START( kinst )
|
||||
{
|
||||
kinst_state *state = machine.driver_data<kinst_state>();
|
||||
device_t *ide = machine.device("ide");
|
||||
UINT8 *features = ide_get_features(ide);
|
||||
UINT8 *features = ide_get_features(ide,0);
|
||||
|
||||
if (strncmp(machine.system().name, "kinst2", 6) != 0)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user