trunk/src/emu/machine/idehd.c
| r23730 | r23731 | |
| 45 | 45 | #define IDE_COMMAND_SET_BLOCK_COUNT 0xc6 |
| 46 | 46 | #define IDE_COMMAND_READ_DMA 0xc8 |
| 47 | 47 | #define IDE_COMMAND_WRITE_DMA 0xca |
| 48 | | #define IDE_COMMAND_GET_INFO 0xec |
| 48 | #define IDE_COMMAND_IDENTIFY_DEVICE 0xec |
| 49 | 49 | #define IDE_COMMAND_SET_FEATURES 0xef |
| 50 | 50 | #define IDE_COMMAND_SECURITY_UNLOCK 0xf2 |
| 51 | 51 | #define IDE_COMMAND_UNKNOWN_F9 0xf9 |
| r23730 | r23731 | |
| 57 | 57 | #define IDE_COMMAND_IDLE_IMMEDIATE 0xe1 |
| 58 | 58 | #define IDE_COMMAND_IDLE 0xe3 |
| 59 | 59 | |
| 60 | #define IDE_DEVICE_CONTROL_NIEN 0x02 |
| 61 | #define IDE_DEVICE_CONTROL_SRST 0x04 |
| 62 | |
| 60 | 63 | enum |
| 61 | 64 | { |
| 62 | 65 | TID_NULL, |
| r23730 | r23731 | |
| 97 | 100 | |
| 98 | 101 | void ide_mass_storage_device::update_irq() |
| 99 | 102 | { |
| 100 | | if (device_selected() && (m_device_control & 2) == 0) |
| 103 | if (device_selected() && (m_device_control & IDE_DEVICE_CONTROL_NIEN) == 0) |
| 101 | 104 | m_irq_handler(m_irq); |
| 102 | 105 | else |
| 103 | 106 | m_irq_handler(CLEAR_LINE); |
| r23730 | r23731 | |
| 152 | 155 | UINT32 ide_mass_storage_device::lba_address() |
| 153 | 156 | { |
| 154 | 157 | /* LBA direct? */ |
| 155 | | if (m_device_head & 0x40) |
| 156 | | return ((m_device_head & 0xf) << 24) | (m_cylinder_high << 16) | (m_cylinder_low << 8) | m_sector_number; |
| 158 | if (m_device_head & IDE_DEVICE_HEAD_L) |
| 159 | return ((m_device_head & IDE_DEVICE_HEAD_HS) << 24) | (m_cylinder_high << 16) | (m_cylinder_low << 8) | m_sector_number; |
| 157 | 160 | |
| 158 | 161 | /* standard CHS */ |
| 159 | 162 | else |
| 160 | | return (((((m_cylinder_high << 8 ) | m_cylinder_low) * m_num_heads) + (m_device_head & 0xf)) * m_num_sectors) + m_sector_number - 1; |
| 163 | return (((((m_cylinder_high << 8 ) | m_cylinder_low) * m_num_heads) + (m_device_head & IDE_DEVICE_HEAD_HS)) * m_num_sectors) + m_sector_number - 1; |
| 161 | 164 | } |
| 162 | 165 | |
| 163 | 166 | |
| r23730 | r23731 | |
| 180 | 183 | } |
| 181 | 184 | |
| 182 | 185 | |
| 183 | | void ide_mass_storage_device::ide_build_features() |
| 186 | void ide_mass_storage_device::ide_build_identify_device() |
| 184 | 187 | { |
| 185 | | memset(m_features, 0, IDE_DISK_SECTOR_SIZE); |
| 188 | memset(m_identify_device, 0, IDE_DISK_SECTOR_SIZE); |
| 186 | 189 | int total_sectors = m_num_cylinders * m_num_heads * m_num_sectors; |
| 187 | 190 | |
| 188 | 191 | /* basic geometry */ |
| 189 | | m_features[ 0*2+0] = 0x5a; /* 0: configuration bits */ |
| 190 | | m_features[ 0*2+1] = 0x04; |
| 191 | | m_features[ 1*2+0] = m_num_cylinders & 0xff; /* 1: logical cylinders */ |
| 192 | | m_features[ 1*2+1] = m_num_cylinders >> 8; |
| 193 | | m_features[ 2*2+0] = 0; /* 2: reserved */ |
| 194 | | m_features[ 2*2+1] = 0; |
| 195 | | m_features[ 3*2+0] = m_num_heads & 0xff; /* 3: logical heads */ |
| 196 | | m_features[ 3*2+1] = 0;/*num_heads >> 8;*/ |
| 197 | | m_features[ 4*2+0] = 0; /* 4: vendor specific (obsolete) */ |
| 198 | | m_features[ 4*2+1] = 0; |
| 199 | | m_features[ 5*2+0] = 0; /* 5: vendor specific (obsolete) */ |
| 200 | | m_features[ 5*2+1] = 0; |
| 201 | | m_features[ 6*2+0] = m_num_sectors & 0xff; /* 6: logical sectors per logical track */ |
| 202 | | m_features[ 6*2+1] = 0;/*num_sectors >> 8;*/ |
| 203 | | m_features[ 7*2+0] = 0; /* 7: vendor-specific */ |
| 204 | | m_features[ 7*2+1] = 0; |
| 205 | | m_features[ 8*2+0] = 0; /* 8: vendor-specific */ |
| 206 | | m_features[ 8*2+1] = 0; |
| 207 | | m_features[ 9*2+0] = 0; /* 9: vendor-specific */ |
| 208 | | m_features[ 9*2+1] = 0; |
| 209 | | swap_strncpy(&m_features[10*2+0], /* 10-19: serial number */ |
| 192 | m_identify_device[ 0*2+0] = 0x5a; /* 0: configuration bits */ |
| 193 | m_identify_device[ 0*2+1] = 0x04; |
| 194 | m_identify_device[ 1*2+0] = m_num_cylinders & 0xff; /* 1: logical cylinders */ |
| 195 | m_identify_device[ 1*2+1] = m_num_cylinders >> 8; |
| 196 | m_identify_device[ 2*2+0] = 0; /* 2: reserved */ |
| 197 | m_identify_device[ 2*2+1] = 0; |
| 198 | m_identify_device[ 3*2+0] = m_num_heads & 0xff; /* 3: logical heads */ |
| 199 | m_identify_device[ 3*2+1] = 0;/*num_heads >> 8;*/ |
| 200 | m_identify_device[ 4*2+0] = 0; /* 4: vendor specific (obsolete) */ |
| 201 | m_identify_device[ 4*2+1] = 0; |
| 202 | m_identify_device[ 5*2+0] = 0; /* 5: vendor specific (obsolete) */ |
| 203 | m_identify_device[ 5*2+1] = 0; |
| 204 | m_identify_device[ 6*2+0] = m_num_sectors & 0xff; /* 6: logical sectors per logical track */ |
| 205 | m_identify_device[ 6*2+1] = 0;/*num_sectors >> 8;*/ |
| 206 | m_identify_device[ 7*2+0] = 0; /* 7: vendor-specific */ |
| 207 | m_identify_device[ 7*2+1] = 0; |
| 208 | m_identify_device[ 8*2+0] = 0; /* 8: vendor-specific */ |
| 209 | m_identify_device[ 8*2+1] = 0; |
| 210 | m_identify_device[ 9*2+0] = 0; /* 9: vendor-specific */ |
| 211 | m_identify_device[ 9*2+1] = 0; |
| 212 | swap_strncpy(&m_identify_device[10*2+0], /* 10-19: serial number */ |
| 210 | 213 | "00000000000000000000", 10); |
| 211 | | m_features[20*2+0] = 0; /* 20: vendor-specific */ |
| 212 | | m_features[20*2+1] = 0; |
| 213 | | m_features[21*2+0] = 0; /* 21: vendor-specific */ |
| 214 | | m_features[21*2+1] = 0; |
| 215 | | m_features[22*2+0] = 4; /* 22: # of vendor-specific bytes on read/write long commands */ |
| 216 | | m_features[22*2+1] = 0; |
| 217 | | swap_strncpy(&m_features[23*2+0], /* 23-26: firmware revision */ |
| 214 | m_identify_device[20*2+0] = 0; /* 20: vendor-specific */ |
| 215 | m_identify_device[20*2+1] = 0; |
| 216 | m_identify_device[21*2+0] = 0; /* 21: vendor-specific */ |
| 217 | m_identify_device[21*2+1] = 0; |
| 218 | m_identify_device[22*2+0] = 4; /* 22: # of vendor-specific bytes on read/write long commands */ |
| 219 | m_identify_device[22*2+1] = 0; |
| 220 | swap_strncpy(&m_identify_device[23*2+0], /* 23-26: firmware revision */ |
| 218 | 221 | "1.0", 4); |
| 219 | | swap_strncpy(&m_features[27*2+0], /* 27-46: model number */ |
| 222 | swap_strncpy(&m_identify_device[27*2+0], /* 27-46: model number */ |
| 220 | 223 | "MAME Compressed Hard Disk", 20); |
| 221 | | m_features[47*2+0] = 0x01; /* 47: read/write multiple support */ |
| 222 | | m_features[47*2+1] = 0x80; |
| 223 | | m_features[48*2+0] = 0; /* 48: reserved */ |
| 224 | | m_features[48*2+1] = 0; |
| 225 | | m_features[49*2+0] = 0x03; /* 49: capabilities */ |
| 226 | | m_features[49*2+1] = 0x0f; |
| 227 | | m_features[50*2+0] = 0; /* 50: reserved */ |
| 228 | | m_features[50*2+1] = 0; |
| 229 | | m_features[51*2+0] = 2; /* 51: PIO data transfer cycle timing mode */ |
| 230 | | m_features[51*2+1] = 0; |
| 231 | | m_features[52*2+0] = 2; /* 52: single word DMA transfer cycle timing mode */ |
| 232 | | m_features[52*2+1] = 0; |
| 233 | | m_features[53*2+0] = 3; /* 53: field validity */ |
| 234 | | m_features[53*2+1] = 0; |
| 235 | | m_features[54*2+0] = m_num_cylinders & 0xff; /* 54: number of current logical cylinders */ |
| 236 | | m_features[54*2+1] = m_num_cylinders >> 8; |
| 237 | | m_features[55*2+0] = m_num_heads & 0xff; /* 55: number of current logical heads */ |
| 238 | | m_features[55*2+1] = 0;/*num_heads >> 8;*/ |
| 239 | | m_features[56*2+0] = m_num_sectors & 0xff; /* 56: number of current logical sectors per track */ |
| 240 | | m_features[56*2+1] = 0;/*num_sectors >> 8;*/ |
| 241 | | m_features[57*2+0] = total_sectors & 0xff; /* 57-58: current capacity in sectors (ATA-1 through ATA-5; obsoleted in ATA-6) */ |
| 242 | | m_features[57*2+1] = total_sectors >> 8; |
| 243 | | m_features[58*2+0] = total_sectors >> 16; |
| 244 | | m_features[58*2+1] = total_sectors >> 24; |
| 245 | | m_features[59*2+0] = 0; /* 59: multiple sector timing */ |
| 246 | | m_features[59*2+1] = 0; |
| 247 | | m_features[60*2+0] = total_sectors & 0xff; /* 60-61: total user addressable sectors for LBA mode (ATA-1 through ATA-7) */ |
| 248 | | m_features[60*2+1] = total_sectors >> 8; |
| 249 | | m_features[61*2+0] = total_sectors >> 16; |
| 250 | | m_features[61*2+1] = total_sectors >> 24; |
| 251 | | m_features[62*2+0] = 0x07; /* 62: single word dma transfer */ |
| 252 | | m_features[62*2+1] = 0x00; |
| 253 | | m_features[63*2+0] = 0x07; /* 63: multiword DMA transfer */ |
| 254 | | m_features[63*2+1] = 0x04; |
| 255 | | m_features[64*2+0] = 0x03; /* 64: flow control PIO transfer modes supported */ |
| 256 | | m_features[64*2+1] = 0x00; |
| 257 | | m_features[65*2+0] = 0x78; /* 65: minimum multiword DMA transfer cycle time per word */ |
| 258 | | m_features[65*2+1] = 0x00; |
| 259 | | m_features[66*2+0] = 0x78; /* 66: mfr's recommended multiword DMA transfer cycle time */ |
| 260 | | m_features[66*2+1] = 0x00; |
| 261 | | m_features[67*2+0] = 0x4d; /* 67: minimum PIO transfer cycle time without flow control */ |
| 262 | | m_features[67*2+1] = 0x01; |
| 263 | | m_features[68*2+0] = 0x78; /* 68: minimum PIO transfer cycle time with IORDY */ |
| 264 | | m_features[68*2+1] = 0x00; |
| 265 | | m_features[69*2+0] = 0x00; /* 69-70: reserved */ |
| 266 | | m_features[69*2+1] = 0x00; |
| 267 | | m_features[71*2+0] = 0x00; /* 71: reserved for IDENTIFY PACKET command */ |
| 268 | | m_features[71*2+1] = 0x00; |
| 269 | | m_features[72*2+0] = 0x00; /* 72: reserved for IDENTIFY PACKET command */ |
| 270 | | m_features[72*2+1] = 0x00; |
| 271 | | m_features[73*2+0] = 0x00; /* 73: reserved for IDENTIFY PACKET command */ |
| 272 | | m_features[73*2+1] = 0x00; |
| 273 | | m_features[74*2+0] = 0x00; /* 74: reserved for IDENTIFY PACKET command */ |
| 274 | | m_features[74*2+1] = 0x00; |
| 275 | | m_features[75*2+0] = 0x00; /* 75: queue depth */ |
| 276 | | m_features[75*2+1] = 0x00; |
| 277 | | m_features[76*2+0] = 0x00; /* 76-79: reserved */ |
| 278 | | m_features[76*2+1] = 0x00; |
| 279 | | m_features[80*2+0] = 0x00; /* 80: major version number */ |
| 280 | | m_features[80*2+1] = 0x00; |
| 281 | | m_features[81*2+0] = 0x00; /* 81: minor version number */ |
| 282 | | m_features[81*2+1] = 0x00; |
| 283 | | m_features[82*2+0] = 0x00; /* 82: command set supported */ |
| 284 | | m_features[82*2+1] = 0x00; |
| 285 | | m_features[83*2+0] = 0x00; /* 83: command sets supported */ |
| 286 | | m_features[83*2+1] = 0x00; |
| 287 | | m_features[84*2+0] = 0x00; /* 84: command set/feature supported extension */ |
| 288 | | m_features[84*2+1] = 0x00; |
| 289 | | m_features[85*2+0] = 0x00; /* 85: command set/feature enabled */ |
| 290 | | m_features[85*2+1] = 0x00; |
| 291 | | m_features[86*2+0] = 0x00; /* 86: command set/feature enabled */ |
| 292 | | m_features[86*2+1] = 0x00; |
| 293 | | m_features[87*2+0] = 0x00; /* 87: command set/feature default */ |
| 294 | | m_features[87*2+1] = 0x00; |
| 295 | | m_features[88*2+0] = 0x00; /* 88: additional DMA modes */ |
| 296 | | m_features[88*2+1] = 0x00; |
| 297 | | m_features[89*2+0] = 0x00; /* 89: time required for security erase unit completion */ |
| 298 | | m_features[89*2+1] = 0x00; |
| 299 | | m_features[90*2+0] = 0x00; /* 90: time required for enhanced security erase unit completion */ |
| 300 | | m_features[90*2+1] = 0x00; |
| 301 | | m_features[91*2+0] = 0x00; /* 91: current advanced power management value */ |
| 302 | | m_features[91*2+1] = 0x00; |
| 303 | | m_features[92*2+0] = 0x00; /* 92: master password revision code */ |
| 304 | | m_features[92*2+1] = 0x00; |
| 305 | | m_features[93*2+0] = 0x00; /* 93: hardware reset result */ |
| 306 | | m_features[93*2+1] = 0x00; |
| 307 | | m_features[94*2+0] = 0x00; /* 94: acoustic management values */ |
| 308 | | m_features[94*2+1] = 0x00; |
| 309 | | m_features[95*2+0] = 0x00; /* 95-99: reserved */ |
| 310 | | m_features[95*2+1] = 0x00; |
| 311 | | m_features[100*2+0] = total_sectors & 0xff; /* 100-103: maximum 48-bit LBA */ |
| 312 | | m_features[100*2+1] = total_sectors >> 8; |
| 313 | | m_features[101*2+0] = total_sectors >> 16; |
| 314 | | m_features[101*2+1] = total_sectors >> 24; |
| 315 | | m_features[102*2+0] = 0x00; |
| 316 | | m_features[102*2+1] = 0x00; |
| 317 | | m_features[103*2+0] = 0x00; |
| 318 | | m_features[103*2+1] = 0x00; |
| 319 | | m_features[104*2+0] = 0x00; /* 104-126: reserved */ |
| 320 | | m_features[104*2+1] = 0x00; |
| 321 | | m_features[127*2+0] = 0x00; /* 127: removable media status notification */ |
| 322 | | m_features[127*2+1] = 0x00; |
| 323 | | m_features[128*2+0] = 0x00; /* 128: security status */ |
| 324 | | m_features[128*2+1] = 0x00; |
| 325 | | m_features[129*2+0] = 0x00; /* 129-159: vendor specific */ |
| 326 | | m_features[129*2+1] = 0x00; |
| 327 | | m_features[160*2+0] = 0x00; /* 160: CFA power mode 1 */ |
| 328 | | m_features[160*2+1] = 0x00; |
| 329 | | m_features[161*2+0] = 0x00; /* 161-175: reserved for CompactFlash */ |
| 330 | | m_features[161*2+1] = 0x00; |
| 331 | | m_features[176*2+0] = 0x00; /* 176-205: current media serial number */ |
| 332 | | m_features[176*2+1] = 0x00; |
| 333 | | m_features[206*2+0] = 0x00; /* 206-254: reserved */ |
| 334 | | m_features[206*2+1] = 0x00; |
| 335 | | m_features[255*2+0] = 0x00; /* 255: integrity word */ |
| 336 | | m_features[255*2+1] = 0x00; |
| 224 | m_identify_device[47*2+0] = 0x01; /* 47: read/write multiple support */ |
| 225 | m_identify_device[47*2+1] = 0x80; |
| 226 | m_identify_device[48*2+0] = 0; /* 48: reserved */ |
| 227 | m_identify_device[48*2+1] = 0; |
| 228 | m_identify_device[49*2+0] = 0x03; /* 49: capabilities */ |
| 229 | m_identify_device[49*2+1] = 0x0f; |
| 230 | m_identify_device[50*2+0] = 0; /* 50: reserved */ |
| 231 | m_identify_device[50*2+1] = 0; |
| 232 | m_identify_device[51*2+0] = 2; /* 51: PIO data transfer cycle timing mode */ |
| 233 | m_identify_device[51*2+1] = 0; |
| 234 | m_identify_device[52*2+0] = 2; /* 52: single word DMA transfer cycle timing mode */ |
| 235 | m_identify_device[52*2+1] = 0; |
| 236 | m_identify_device[53*2+0] = 3; /* 53: field validity */ |
| 237 | m_identify_device[53*2+1] = 0; |
| 238 | m_identify_device[54*2+0] = m_num_cylinders & 0xff; /* 54: number of current logical cylinders */ |
| 239 | m_identify_device[54*2+1] = m_num_cylinders >> 8; |
| 240 | m_identify_device[55*2+0] = m_num_heads & 0xff; /* 55: number of current logical heads */ |
| 241 | m_identify_device[55*2+1] = 0;/*num_heads >> 8;*/ |
| 242 | m_identify_device[56*2+0] = m_num_sectors & 0xff; /* 56: number of current logical sectors per track */ |
| 243 | m_identify_device[56*2+1] = 0;/*num_sectors >> 8;*/ |
| 244 | m_identify_device[57*2+0] = total_sectors & 0xff; /* 57-58: current capacity in sectors (ATA-1 through ATA-5; obsoleted in ATA-6) */ |
| 245 | m_identify_device[57*2+1] = total_sectors >> 8; |
| 246 | m_identify_device[58*2+0] = total_sectors >> 16; |
| 247 | m_identify_device[58*2+1] = total_sectors >> 24; |
| 248 | m_identify_device[59*2+0] = 0; /* 59: multiple sector timing */ |
| 249 | m_identify_device[59*2+1] = 0; |
| 250 | m_identify_device[60*2+0] = total_sectors & 0xff; /* 60-61: total user addressable sectors for LBA mode (ATA-1 through ATA-7) */ |
| 251 | m_identify_device[60*2+1] = total_sectors >> 8; |
| 252 | m_identify_device[61*2+0] = total_sectors >> 16; |
| 253 | m_identify_device[61*2+1] = total_sectors >> 24; |
| 254 | m_identify_device[62*2+0] = 0x07; /* 62: single word dma transfer */ |
| 255 | m_identify_device[62*2+1] = 0x00; |
| 256 | m_identify_device[63*2+0] = 0x07; /* 63: multiword DMA transfer */ |
| 257 | m_identify_device[63*2+1] = 0x04; |
| 258 | m_identify_device[64*2+0] = 0x03; /* 64: flow control PIO transfer modes supported */ |
| 259 | m_identify_device[64*2+1] = 0x00; |
| 260 | m_identify_device[65*2+0] = 0x78; /* 65: minimum multiword DMA transfer cycle time per word */ |
| 261 | m_identify_device[65*2+1] = 0x00; |
| 262 | m_identify_device[66*2+0] = 0x78; /* 66: mfr's recommended multiword DMA transfer cycle time */ |
| 263 | m_identify_device[66*2+1] = 0x00; |
| 264 | m_identify_device[67*2+0] = 0x4d; /* 67: minimum PIO transfer cycle time without flow control */ |
| 265 | m_identify_device[67*2+1] = 0x01; |
| 266 | m_identify_device[68*2+0] = 0x78; /* 68: minimum PIO transfer cycle time with IORDY */ |
| 267 | m_identify_device[68*2+1] = 0x00; |
| 268 | m_identify_device[69*2+0] = 0x00; /* 69-70: reserved */ |
| 269 | m_identify_device[69*2+1] = 0x00; |
| 270 | m_identify_device[71*2+0] = 0x00; /* 71: reserved for IDENTIFY PACKET command */ |
| 271 | m_identify_device[71*2+1] = 0x00; |
| 272 | m_identify_device[72*2+0] = 0x00; /* 72: reserved for IDENTIFY PACKET command */ |
| 273 | m_identify_device[72*2+1] = 0x00; |
| 274 | m_identify_device[73*2+0] = 0x00; /* 73: reserved for IDENTIFY PACKET command */ |
| 275 | m_identify_device[73*2+1] = 0x00; |
| 276 | m_identify_device[74*2+0] = 0x00; /* 74: reserved for IDENTIFY PACKET command */ |
| 277 | m_identify_device[74*2+1] = 0x00; |
| 278 | m_identify_device[75*2+0] = 0x00; /* 75: queue depth */ |
| 279 | m_identify_device[75*2+1] = 0x00; |
| 280 | m_identify_device[76*2+0] = 0x00; /* 76-79: reserved */ |
| 281 | m_identify_device[76*2+1] = 0x00; |
| 282 | m_identify_device[80*2+0] = 0x00; /* 80: major version number */ |
| 283 | m_identify_device[80*2+1] = 0x00; |
| 284 | m_identify_device[81*2+0] = 0x00; /* 81: minor version number */ |
| 285 | m_identify_device[81*2+1] = 0x00; |
| 286 | m_identify_device[82*2+0] = 0x00; /* 82: command set supported */ |
| 287 | m_identify_device[82*2+1] = 0x00; |
| 288 | m_identify_device[83*2+0] = 0x00; /* 83: command sets supported */ |
| 289 | m_identify_device[83*2+1] = 0x00; |
| 290 | m_identify_device[84*2+0] = 0x00; /* 84: command set/feature supported extension */ |
| 291 | m_identify_device[84*2+1] = 0x00; |
| 292 | m_identify_device[85*2+0] = 0x00; /* 85: command set/feature enabled */ |
| 293 | m_identify_device[85*2+1] = 0x00; |
| 294 | m_identify_device[86*2+0] = 0x00; /* 86: command set/feature enabled */ |
| 295 | m_identify_device[86*2+1] = 0x00; |
| 296 | m_identify_device[87*2+0] = 0x00; /* 87: command set/feature default */ |
| 297 | m_identify_device[87*2+1] = 0x00; |
| 298 | m_identify_device[88*2+0] = 0x00; /* 88: additional DMA modes */ |
| 299 | m_identify_device[88*2+1] = 0x00; |
| 300 | m_identify_device[89*2+0] = 0x00; /* 89: time required for security erase unit completion */ |
| 301 | m_identify_device[89*2+1] = 0x00; |
| 302 | m_identify_device[90*2+0] = 0x00; /* 90: time required for enhanced security erase unit completion */ |
| 303 | m_identify_device[90*2+1] = 0x00; |
| 304 | m_identify_device[91*2+0] = 0x00; /* 91: current advanced power management value */ |
| 305 | m_identify_device[91*2+1] = 0x00; |
| 306 | m_identify_device[92*2+0] = 0x00; /* 92: master password revision code */ |
| 307 | m_identify_device[92*2+1] = 0x00; |
| 308 | m_identify_device[93*2+0] = 0x00; /* 93: hardware reset result */ |
| 309 | m_identify_device[93*2+1] = 0x00; |
| 310 | m_identify_device[94*2+0] = 0x00; /* 94: acoustic management values */ |
| 311 | m_identify_device[94*2+1] = 0x00; |
| 312 | m_identify_device[95*2+0] = 0x00; /* 95-99: reserved */ |
| 313 | m_identify_device[95*2+1] = 0x00; |
| 314 | m_identify_device[100*2+0] = total_sectors & 0xff; /* 100-103: maximum 48-bit LBA */ |
| 315 | m_identify_device[100*2+1] = total_sectors >> 8; |
| 316 | m_identify_device[101*2+0] = total_sectors >> 16; |
| 317 | m_identify_device[101*2+1] = total_sectors >> 24; |
| 318 | m_identify_device[102*2+0] = 0x00; |
| 319 | m_identify_device[102*2+1] = 0x00; |
| 320 | m_identify_device[103*2+0] = 0x00; |
| 321 | m_identify_device[103*2+1] = 0x00; |
| 322 | m_identify_device[104*2+0] = 0x00; /* 104-126: reserved */ |
| 323 | m_identify_device[104*2+1] = 0x00; |
| 324 | m_identify_device[127*2+0] = 0x00; /* 127: removable media status notification */ |
| 325 | m_identify_device[127*2+1] = 0x00; |
| 326 | m_identify_device[128*2+0] = 0x00; /* 128: security status */ |
| 327 | m_identify_device[128*2+1] = 0x00; |
| 328 | m_identify_device[129*2+0] = 0x00; /* 129-159: vendor specific */ |
| 329 | m_identify_device[129*2+1] = 0x00; |
| 330 | m_identify_device[160*2+0] = 0x00; /* 160: CFA power mode 1 */ |
| 331 | m_identify_device[160*2+1] = 0x00; |
| 332 | m_identify_device[161*2+0] = 0x00; /* 161-175: reserved for CompactFlash */ |
| 333 | m_identify_device[161*2+1] = 0x00; |
| 334 | m_identify_device[176*2+0] = 0x00; /* 176-205: current media serial number */ |
| 335 | m_identify_device[176*2+1] = 0x00; |
| 336 | m_identify_device[206*2+0] = 0x00; /* 206-254: reserved */ |
| 337 | m_identify_device[206*2+1] = 0x00; |
| 338 | m_identify_device[255*2+0] = 0x00; /* 255: integrity word */ |
| 339 | m_identify_device[255*2+1] = 0x00; |
| 337 | 340 | } |
| 338 | 341 | |
| 339 | 342 | //------------------------------------------------- |
| r23730 | r23731 | |
| 358 | 361 | save_item(NAME(m_command)); |
| 359 | 362 | save_item(NAME(m_device_control)); |
| 360 | 363 | |
| 361 | | save_item(NAME(m_has_features)); |
| 362 | | save_item(NAME(m_features)); |
| 364 | save_item(NAME(m_can_identify_device)); |
| 365 | save_item(NAME(m_identify_device)); |
| 363 | 366 | save_item(NAME(m_cur_lba)); |
| 364 | 367 | save_item(NAME(m_irq)); |
| 365 | 368 | save_item(NAME(m_dmarq)); |
| r23730 | r23731 | |
| 386 | 389 | m_status |= IDE_STATUS_DRDY; |
| 387 | 390 | } |
| 388 | 391 | |
| 392 | if (m_can_identify_device) |
| 393 | m_error = IDE_ERROR_DIAGNOSTIC_PASSED; |
| 394 | else |
| 395 | m_error = IDE_ERROR_DIAGNOSTIC_FAILED; |
| 396 | |
| 397 | m_sector_count = 1; |
| 398 | m_sector_number = 1; |
| 399 | m_cylinder_low = 0; |
| 400 | m_cylinder_high = 0; |
| 401 | m_device_head = 0; |
| 402 | |
| 389 | 403 | /* reset the drive state */ |
| 390 | 404 | set_irq(CLEAR_LINE); |
| 391 | 405 | set_dmarq(CLEAR_LINE); |
| r23730 | r23731 | |
| 444 | 458 | void ide_mass_storage_device::next_sector() |
| 445 | 459 | { |
| 446 | 460 | /* LBA direct? */ |
| 447 | | if (m_device_head & 0x40) |
| 461 | if (m_device_head & IDE_DEVICE_HEAD_L) |
| 448 | 462 | { |
| 449 | 463 | m_sector_number++; |
| 450 | 464 | if (m_sector_number == 0) |
| r23730 | r23731 | |
| 454 | 468 | { |
| 455 | 469 | m_cylinder_high++; |
| 456 | 470 | if( m_cylinder_high == 0) |
| 457 | | m_device_head = (m_device_head & ~0xf) | ((m_device_head + 1) & 0xf); |
| 471 | m_device_head = (m_device_head & ~IDE_DEVICE_HEAD_HS) | ((m_device_head + 1) & IDE_DEVICE_HEAD_HS); |
| 458 | 472 | } |
| 459 | 473 | } |
| 460 | 474 | } |
| r23730 | r23731 | |
| 468 | 482 | { |
| 469 | 483 | /* heads are 0 based */ |
| 470 | 484 | m_sector_number = 1; |
| 471 | | m_device_head = (m_device_head & ~0xf) | ((m_device_head + 1) & 0xf); |
| 472 | | if ((m_device_head & 0xf) >= m_num_heads) |
| 485 | m_device_head = (m_device_head & ~IDE_DEVICE_HEAD_HS) | ((m_device_head + 1) & IDE_DEVICE_HEAD_HS); |
| 486 | if ((m_device_head & IDE_DEVICE_HEAD_HS) >= m_num_heads) |
| 473 | 487 | { |
| 474 | | m_device_head &= ~0xf; |
| 488 | m_device_head &= ~IDE_DEVICE_HEAD_HS; |
| 475 | 489 | m_cylinder_low++; |
| 476 | 490 | if (m_cylinder_low == 0) |
| 477 | 491 | m_cylinder_high++; |
| r23730 | r23731 | |
| 517 | 531 | if (m_master_password_enable || m_user_password_enable) |
| 518 | 532 | { |
| 519 | 533 | security_error(); |
| 520 | | m_sector_count = 0; |
| 521 | 534 | return; |
| 522 | 535 | } |
| 523 | 536 | |
| r23730 | r23731 | |
| 772 | 785 | case IDE_COMMAND_READ_SECTORS: |
| 773 | 786 | case IDE_COMMAND_READ_SECTORS_NORETRY: |
| 774 | 787 | LOGPRINT(("IDE Read multiple: C=%d H=%d S=%d LBA=%d count=%d\n", |
| 775 | | (m_cylinder_high << 8) | m_cylinder_low, m_device_head & 0xf, m_sector_number, lba_address(), m_sector_count)); |
| 788 | (m_cylinder_high << 8) | m_cylinder_low, m_device_head & IDE_DEVICE_HEAD_HS, m_sector_number, lba_address(), m_sector_count)); |
| 776 | 789 | |
| 777 | 790 | m_sectors_until_int = 1; |
| 778 | 791 | |
| r23730 | r23731 | |
| 782 | 795 | |
| 783 | 796 | case IDE_COMMAND_READ_MULTIPLE: |
| 784 | 797 | LOGPRINT(("IDE Read multiple block: C=%d H=%d S=%d LBA=%d count=%d\n", |
| 785 | | (m_cylinder_high << 8) | m_cylinder_low, m_device_head & 0xf, m_sector_number, lba_address(), m_sector_count)); |
| 798 | (m_cylinder_high << 8) | m_cylinder_low, m_device_head & IDE_DEVICE_HEAD_HS, m_sector_number, lba_address(), m_sector_count)); |
| 786 | 799 | |
| 787 | 800 | m_sectors_until_int = 1; |
| 788 | 801 | |
| r23730 | r23731 | |
| 793 | 806 | case IDE_COMMAND_VERIFY_SECTORS: |
| 794 | 807 | case IDE_COMMAND_VERIFY_SECTORS_NORETRY: |
| 795 | 808 | LOGPRINT(("IDE Read verify multiple with/without retries: C=%d H=%d S=%d LBA=%d count=%d\n", |
| 796 | | (m_cylinder_high << 8) | m_cylinder_low, m_device_head & 0xf, m_sector_number, lba_address(), m_sector_count)); |
| 809 | (m_cylinder_high << 8) | m_cylinder_low, m_device_head & IDE_DEVICE_HEAD_HS, m_sector_number, lba_address(), m_sector_count)); |
| 797 | 810 | |
| 798 | 811 | /* reset the buffer */ |
| 799 | 812 | m_sectors_until_int = m_sector_count; |
| r23730 | r23731 | |
| 804 | 817 | |
| 805 | 818 | case IDE_COMMAND_READ_DMA: |
| 806 | 819 | LOGPRINT(("IDE Read multiple DMA: C=%d H=%d S=%d LBA=%d count=%d\n", |
| 807 | | (m_cylinder_high << 8) | m_cylinder_low, m_device_head & 0xf, m_sector_number, lba_address(), m_sector_count)); |
| 820 | (m_cylinder_high << 8) | m_cylinder_low, m_device_head & IDE_DEVICE_HEAD_HS, m_sector_number, lba_address(), m_sector_count)); |
| 808 | 821 | |
| 809 | 822 | /* reset the buffer */ |
| 810 | 823 | m_sectors_until_int = m_sector_count; |
| r23730 | r23731 | |
| 816 | 829 | case IDE_COMMAND_WRITE_SECTORS: |
| 817 | 830 | case IDE_COMMAND_WRITE_SECTORS_NORETRY: |
| 818 | 831 | LOGPRINT(("IDE Write multiple: C=%d H=%d S=%d LBA=%d count=%d\n", |
| 819 | | (m_cylinder_high << 8) | m_cylinder_low, m_device_head & 0xf, m_sector_number, lba_address(), m_sector_count)); |
| 832 | (m_cylinder_high << 8) | m_cylinder_low, m_device_head & IDE_DEVICE_HEAD_HS, m_sector_number, lba_address(), m_sector_count)); |
| 820 | 833 | |
| 821 | 834 | /* reset the buffer */ |
| 822 | 835 | m_sectors_until_int = 1; |
| r23730 | r23731 | |
| 827 | 840 | |
| 828 | 841 | case IDE_COMMAND_WRITE_MULTIPLE: |
| 829 | 842 | LOGPRINT(("IDE Write multiple block: C=%d H=%d S=%d LBA=%d count=%d\n", |
| 830 | | (m_cylinder_high << 8) | m_cylinder_low, m_device_head & 0xf, m_sector_number, lba_address(), m_sector_count)); |
| 843 | (m_cylinder_high << 8) | m_cylinder_low, m_device_head & IDE_DEVICE_HEAD_HS, m_sector_number, lba_address(), m_sector_count)); |
| 831 | 844 | |
| 832 | 845 | /* reset the buffer */ |
| 833 | 846 | m_sectors_until_int = 1; |
| r23730 | r23731 | |
| 838 | 851 | |
| 839 | 852 | case IDE_COMMAND_WRITE_DMA: |
| 840 | 853 | LOGPRINT(("IDE Write multiple DMA: C=%d H=%d S=%d LBA=%d count=%d\n", |
| 841 | | (m_cylinder_high << 8) | m_cylinder_low, m_device_head & 0xf, m_sector_number, lba_address(), m_sector_count)); |
| 854 | (m_cylinder_high << 8) | m_cylinder_low, m_device_head & IDE_DEVICE_HEAD_HS, m_sector_number, lba_address(), m_sector_count)); |
| 842 | 855 | |
| 843 | 856 | /* reset the buffer */ |
| 844 | 857 | m_sectors_until_int = m_sector_count; |
| r23730 | r23731 | |
| 859 | 872 | set_irq(ASSERT_LINE); |
| 860 | 873 | return true; |
| 861 | 874 | |
| 862 | | case IDE_COMMAND_GET_INFO: |
| 863 | | LOGPRINT(("IDE Read features\n")); |
| 875 | case IDE_COMMAND_IDENTIFY_DEVICE: |
| 876 | LOGPRINT(("IDE Identify device\n")); |
| 864 | 877 | |
| 865 | | if (m_has_features) |
| 878 | if (m_can_identify_device) |
| 866 | 879 | { |
| 867 | | m_sector_count = 1; |
| 880 | memcpy(m_buffer, m_identify_device, sizeof(m_buffer)); |
| 868 | 881 | |
| 869 | | /* build the features page */ |
| 870 | | memcpy(m_buffer, m_features, sizeof(m_buffer)); |
| 871 | | |
| 872 | | /* indicate everything is ready */ |
| 873 | | m_status |= IDE_STATUS_DRQ; |
| 874 | | |
| 875 | 882 | /* signal an interrupt */ |
| 876 | 883 | signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 1); |
| 877 | 884 | } |
| r23730 | r23731 | |
| 880 | 887 | m_status |= IDE_STATUS_ERR; |
| 881 | 888 | m_error = IDE_ERROR_NONE; |
| 882 | 889 | m_status &= ~IDE_STATUS_DRDY; |
| 883 | | set_irq(ASSERT_LINE); |
| 890 | signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0); |
| 884 | 891 | } |
| 885 | 892 | return true; |
| 886 | 893 | |
| 887 | 894 | case IDE_COMMAND_DIAGNOSTIC: |
| 888 | | m_error = IDE_ERROR_DIAGNOSTIC_PASSED; |
| 895 | if (m_can_identify_device) |
| 896 | m_error = IDE_ERROR_DIAGNOSTIC_PASSED; |
| 897 | else |
| 898 | m_error = IDE_ERROR_DIAGNOSTIC_FAILED; |
| 889 | 899 | |
| 890 | 900 | /* signal an interrupt */ |
| 891 | 901 | signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0); |
| r23730 | r23731 | |
| 897 | 907 | return true; |
| 898 | 908 | |
| 899 | 909 | case IDE_COMMAND_IDLE: |
| 900 | | /* for timeout disabled value is 0 */ |
| 901 | | m_sector_count = 0; |
| 902 | 910 | /* signal an interrupt */ |
| 903 | 911 | set_irq(ASSERT_LINE); |
| 904 | 912 | return true; |
| 905 | 913 | |
| 906 | 914 | case IDE_COMMAND_SET_CONFIG: |
| 907 | | LOGPRINT(("IDE Set configuration (%d heads, %d sectors)\n", (m_device_head & 0xf) + 1, m_sector_count)); |
| 908 | | set_geometry(m_sector_count,(m_device_head & 0xf) + 1); |
| 915 | LOGPRINT(("IDE Set configuration (%d heads, %d sectors)\n", (m_device_head & IDE_DEVICE_HEAD_HS) + 1, m_sector_count)); |
| 916 | set_geometry(m_sector_count,(m_device_head & IDE_DEVICE_HEAD_HS) + 1); |
| 909 | 917 | |
| 910 | 918 | /* signal an interrupt */ |
| 911 | 919 | signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0); |
| r23730 | r23731 | |
| 936 | 944 | return true; |
| 937 | 945 | |
| 938 | 946 | case IDE_COMMAND_SEEK: |
| 939 | | /* |
| 940 | | cur_cylinder, cur_sector and cur_head |
| 941 | | are all already set in this case so no need |
| 942 | | so that implements actual seek |
| 943 | | */ |
| 944 | | |
| 945 | | /* for timeout disabled value is 0 */ |
| 946 | | m_sector_count = 0; |
| 947 | | |
| 948 | 947 | /* signal an interrupt */ |
| 949 | 948 | set_irq(ASSERT_LINE); |
| 950 | 949 | return true; |
| r23730 | r23731 | |
| 1231 | 1230 | } |
| 1232 | 1231 | else |
| 1233 | 1232 | { |
| 1233 | UINT8 old; |
| 1234 | |
| 1234 | 1235 | switch (offset) |
| 1235 | 1236 | { |
| 1236 | 1237 | /* write data */ |
| r23730 | r23731 | |
| 1284 | 1285 | |
| 1285 | 1286 | /* current head */ |
| 1286 | 1287 | case IDE_CS0_DEVICE_HEAD_RW: |
| 1288 | old = m_device_head; |
| 1287 | 1289 | m_device_head = data; |
| 1288 | 1290 | |
| 1289 | | update_irq(); |
| 1291 | if ((m_device_head ^ old) & IDE_DEVICE_HEAD_DRV) |
| 1292 | update_irq(); |
| 1290 | 1293 | break; |
| 1291 | 1294 | |
| 1292 | 1295 | /* command */ |
| r23730 | r23731 | |
| 1329 | 1332 | } |
| 1330 | 1333 | else |
| 1331 | 1334 | { |
| 1335 | UINT8 old; |
| 1336 | |
| 1332 | 1337 | switch (offset) |
| 1333 | 1338 | { |
| 1334 | 1339 | /* adapter control */ |
| 1335 | 1340 | case IDE_CS1_DEVICE_CONTROL_W: |
| 1341 | old = m_device_control; |
| 1336 | 1342 | m_device_control = data; |
| 1337 | 1343 | |
| 1338 | | update_irq(); |
| 1344 | if ((m_device_control ^ old) & IDE_DEVICE_CONTROL_NIEN) |
| 1345 | update_irq(); |
| 1339 | 1346 | |
| 1340 | | if (data & 0x04) |
| 1347 | if ((m_device_control ^ old) & IDE_DEVICE_CONTROL_SRST) |
| 1341 | 1348 | { |
| 1342 | | // SRST |
| 1343 | | m_status |= IDE_STATUS_BSY; |
| 1344 | | m_status &= ~IDE_STATUS_DRDY; |
| 1345 | | m_reset_timer->adjust(attotime::from_msec(5)); |
| 1349 | if (m_device_control & IDE_DEVICE_CONTROL_SRST) |
| 1350 | { |
| 1351 | m_status |= IDE_STATUS_BSY; |
| 1352 | set_irq(CLEAR_LINE); |
| 1353 | m_reset_timer->adjust(attotime::from_msec(5)); |
| 1354 | } |
| 1346 | 1355 | } |
| 1347 | 1356 | break; |
| 1348 | 1357 | } |
| r23730 | r23731 | |
| 1403 | 1412 | } |
| 1404 | 1413 | // build the features page |
| 1405 | 1414 | UINT32 metalength; |
| 1406 | | if (m_handle->read_metadata (HARD_DISK_IDENT_METADATA_TAG, 0, m_features, IDE_DISK_SECTOR_SIZE, metalength) != CHDERR_NONE) |
| 1407 | | ide_build_features(); |
| 1415 | if (m_handle->read_metadata (HARD_DISK_IDENT_METADATA_TAG, 0, m_identify_device, IDE_DISK_SECTOR_SIZE, metalength) != CHDERR_NONE) |
| 1416 | ide_build_identify_device(); |
| 1408 | 1417 | |
| 1409 | | m_has_features = 1; |
| 1418 | m_can_identify_device = 1; |
| 1410 | 1419 | } |
| 1411 | 1420 | } |
| 1412 | 1421 | |