trunk/src/emu/bus/isa/omti8621.c
| r29180 | r29181 | |
| 28 | 28 | #define LOG2(x) { if (verbose > 1) LOG(x)} |
| 29 | 29 | #define LOG3(x) { if (verbose > 2) LOG(x)} |
| 30 | 30 | |
| 31 | | #define DLOG(x) { logerror ("%s: ", cpu_context(disk->device)); logerror x; logerror ("\n"); } |
| 32 | | #define DLOG1(x) { if (verbose > 0) DLOG(x)} |
| 33 | | #define DLOG2(x) { if (verbose > 1) DLOG(x)} |
| 34 | | |
| 35 | 31 | #define OMTI_DISK_SECTOR_SIZE 1056 |
| 36 | 32 | |
| 37 | 33 | #define OMTI_DISK_TYPE_155_MB 0x607 // Micropolis 1355 (170 MB Dtype = 607) |
| r29180 | r29181 | |
| 51 | 47 | // forward declaration of image class |
| 52 | 48 | extern const device_type OMTI_DISK; |
| 53 | 49 | |
| 54 | | class omti_disk_image_device : public device_t, |
| 55 | | public device_image_interface |
| 56 | | { |
| 57 | | public: |
| 58 | | // construction/destruction |
| 59 | | omti_disk_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 60 | | |
| 61 | | // image-level overrides |
| 62 | | virtual iodevice_t image_type() const { return IO_HARDDISK; } |
| 63 | | |
| 64 | | virtual bool is_readable() const { return 1; } |
| 65 | | virtual bool is_writeable() const { return 1; } |
| 66 | | virtual bool is_creatable() const { return 1; } |
| 67 | | virtual bool must_be_loaded() const { return 0; } |
| 68 | | virtual bool is_reset_on_load() const { return 0; } |
| 69 | | virtual const char *image_interface() const { return NULL; } |
| 70 | | virtual const char *file_extensions() const { return "awd"; } |
| 71 | | virtual const option_guide *create_option_guide() const { return NULL; } |
| 72 | | |
| 73 | | virtual bool call_create(int format_type, option_resolution *format_options); |
| 74 | | |
| 75 | | disk_data *token() { return &m_token; } |
| 76 | | protected: |
| 77 | | // device-level overrides |
| 78 | | virtual void device_config_complete(); |
| 79 | | virtual void device_start(); |
| 80 | | virtual void device_reset(); |
| 81 | | |
| 82 | | disk_data m_token; |
| 83 | | }; |
| 84 | | |
| 85 | 50 | /* |
| 86 | 51 | * I/O register offsets |
| 87 | 52 | */ |
| r29180 | r29181 | |
| 279 | 244 | sector_buffer.resize(OMTI_DISK_SECTOR_SIZE*OMTI_MAX_BLOCK_COUNT); |
| 280 | 245 | |
| 281 | 246 | m_timer = timer_alloc(0, NULL); |
| 282 | | |
| 283 | | device_t *device0 = subdevice(OMTI_DISK0_TAG); |
| 284 | | our_disks[0] = (disk_data *) downcast<omti_disk_image_device *>(device0)->token(); |
| 285 | | |
| 286 | | device_t *device1 = subdevice(OMTI_DISK1_TAG); |
| 287 | | our_disks[1] = (disk_data *) downcast<omti_disk_image_device *>(device1)->token(); |
| 247 | |
| 248 | our_disks[0] = subdevice<omti_disk_image_device>(OMTI_DISK0_TAG); |
| 249 | our_disks[1] = subdevice<omti_disk_image_device>(OMTI_DISK1_TAG); |
| 288 | 250 | } |
| 289 | 251 | |
| 290 | 252 | /*------------------------------------------------- |
| r29180 | r29181 | |
| 320 | 282 | m_installed = true; |
| 321 | 283 | } |
| 322 | 284 | |
| 323 | | set_jumper(our_disks[0]->type); |
| 285 | set_jumper(our_disks[0]->m_type); |
| 324 | 286 | |
| 325 | 287 | // should go from reset to idle after 100 us |
| 326 | 288 | // state->omti_state = OMTI_STATE_RESET; |
| r29180 | r29181 | |
| 422 | 384 | LOG2(("set_configuration_data lun=%x", lun)); |
| 423 | 385 | |
| 424 | 386 | // initialize the configuration data |
| 425 | | disk_data *disk = our_disks[lun]; |
| 387 | omti_disk_image_device *disk = our_disks[lun]; |
| 426 | 388 | |
| 427 | | disk->config_data[0] = (disk->cylinders - 1) >> 8; // Number of Cylinders (MSB) |
| 428 | | disk->config_data[1] = (disk->cylinders - 1) & 0xff; // Number of Cylinders (LSB) (-1) |
| 429 | | disk->config_data[2] = disk->heads - 1; // Number of Heads (-1) |
| 430 | | disk->config_data[3] = disk->sectors - 1; // Number of Sectors (-1) |
| 431 | | disk->config_data[4] = 0x02; // Drive Configuration Word (MSB) |
| 432 | | disk->config_data[5] = 0x44; // Drive Configuration Word (LSB) |
| 433 | | disk->config_data[6] = 0x00; // ISG AFTER INDEX |
| 434 | | disk->config_data[7] = 0x00; // PLO SYN Field (ID) |
| 435 | | disk->config_data[8] = 0x00; // PLO SYN Field (DATA) |
| 436 | | disk->config_data[9] = 0x00; // ISG AFTER SECTOR |
| 389 | disk->m_config_data[0] = (disk->m_cylinders - 1) >> 8; // Number of Cylinders (MSB) |
| 390 | disk->m_config_data[1] = (disk->m_cylinders - 1) & 0xff; // Number of Cylinders (LSB) (-1) |
| 391 | disk->m_config_data[2] = disk->m_heads - 1; // Number of Heads (-1) |
| 392 | disk->m_config_data[3] = disk->m_sectors - 1; // Number of Sectors (-1) |
| 393 | disk->m_config_data[4] = 0x02; // Drive Configuration Word (MSB) |
| 394 | disk->m_config_data[5] = 0x44; // Drive Configuration Word (LSB) |
| 395 | disk->m_config_data[6] = 0x00; // ISG AFTER INDEX |
| 396 | disk->m_config_data[7] = 0x00; // PLO SYN Field (ID) |
| 397 | disk->m_config_data[8] = 0x00; // PLO SYN Field (DATA) |
| 398 | disk->m_config_data[9] = 0x00; // ISG AFTER SECTOR |
| 437 | 399 | } |
| 438 | 400 | |
| 439 | 401 | /*************************************************************************** |
| r29180 | r29181 | |
| 457 | 419 | UINT16 sector = cdb[2] & 0x3f; |
| 458 | 420 | UINT32 cylinder = cdb[3] + ((cdb[2] & 0xc0) << 2) + ((cdb[1] & 0x80) << 3); |
| 459 | 421 | UINT8 block_count = cdb[4]; |
| 460 | | disk_data *disk = our_disks[lun]; |
| 422 | omti_disk_image_device *disk = our_disks[lun]; |
| 461 | 423 | |
| 462 | | UINT32 disk_track = cylinder * disk->heads + head; |
| 463 | | UINT32 disk_addr = (disk_track * disk->sectors) + sector; |
| 424 | UINT32 disk_track = cylinder * disk->m_heads + head; |
| 425 | UINT32 disk_addr = (disk_track * disk->m_sectors) + sector; |
| 464 | 426 | |
| 465 | 427 | if (block_count > OMTI_MAX_BLOCK_COUNT) { |
| 466 | 428 | LOG(("########### check_disk_address: unexpected block count %x", block_count)); |
| r29180 | r29181 | |
| 469 | 431 | |
| 470 | 432 | if (lun > OMTI_MAX_LUN) { |
| 471 | 433 | sense_code = OMTI_SENSE_CODE_DRIVE_NOT_READY; |
| 472 | | } else if (!disk->image->exists()) { |
| 434 | } else if (!disk->m_image->exists()) { |
| 473 | 435 | sense_code = OMTI_SENSE_CODE_DRIVE_NOT_READY; |
| 474 | 436 | } else if (sector >= OMTI_MAX_BLOCK_COUNT) { |
| 475 | 437 | sense_code = OMTI_SENSE_CODE_ILLEGAL_ADDRESS | OMTI_SENSE_CODE_ADDRESS_VALID; |
| 476 | | } else if (head >= disk->heads) { |
| 438 | } else if (head >= disk->m_heads) { |
| 477 | 439 | sense_code = OMTI_SENSE_CODE_ILLEGAL_ADDRESS | OMTI_SENSE_CODE_ADDRESS_VALID; |
| 478 | | } else if (cylinder >= disk->cylinders) { |
| 440 | } else if (cylinder >= disk->m_cylinders) { |
| 479 | 441 | sense_code = OMTI_SENSE_CODE_ILLEGAL_ADDRESS | OMTI_SENSE_CODE_ADDRESS_VALID; |
| 480 | 442 | } else if ( disk_track == diskaddr_format_bad_track && disk_track != 0) { |
| 481 | 443 | sense_code = OMTI_SENSE_CODE_BAD_TRACK; |
| r29180 | r29181 | |
| 502 | 464 | UINT8 lun = get_lun(cdb); |
| 503 | 465 | UINT16 head = cdb[1] & 0x1f; |
| 504 | 466 | UINT32 cylinder = cdb[3] + ((cdb[2] & 0xc0) << 2) + ((cdb[1] & 0x80) << 3); |
| 505 | | return cylinder * our_disks[lun]->heads + head; |
| 467 | return cylinder * our_disks[lun]->m_heads + head; |
| 506 | 468 | } |
| 507 | 469 | |
| 508 | 470 | /*************************************************************************** |
| r29180 | r29181 | |
| 512 | 474 | UINT32 omti8621_device::get_disk_address(const UINT8 * cdb) { |
| 513 | 475 | UINT8 lun = get_lun(cdb); |
| 514 | 476 | UINT16 sector = cdb[2] & 0x3f; |
| 515 | | return get_disk_track(cdb) * our_disks[lun]->sectors + sector; |
| 477 | return get_disk_track(cdb) * our_disks[lun]->m_sectors + sector; |
| 516 | 478 | } |
| 517 | 479 | |
| 518 | 480 | /*************************************************************************** |
| r29180 | r29181 | |
| 538 | 500 | void omti8621_device::read_sectors_from_disk(INT32 diskaddr, UINT8 count, UINT8 lun) |
| 539 | 501 | { |
| 540 | 502 | UINT8 *data_buffer = sector_buffer; |
| 541 | | device_image_interface *image = our_disks[lun]->image; |
| 503 | device_image_interface *image = our_disks[lun]->m_image; |
| 542 | 504 | |
| 543 | 505 | while (count-- > 0) { |
| 544 | 506 | LOG2(("read_sectors_from_disk lun=%d diskaddr=%x", lun, diskaddr)); |
| r29180 | r29181 | |
| 558 | 520 | void omti8621_device::write_sectors_to_disk(INT32 diskaddr, UINT8 count, UINT8 lun) |
| 559 | 521 | { |
| 560 | 522 | UINT8 *data_buffer = sector_buffer; |
| 561 | | device_image_interface *image = our_disks[lun]->image; |
| 523 | device_image_interface *image = our_disks[lun]->m_image; |
| 562 | 524 | |
| 563 | 525 | while (count-- > 0) { |
| 564 | 526 | LOG2(("write_sectors_to_disk lun=%d diskaddr=%x", lun, diskaddr)); |
| r29180 | r29181 | |
| 582 | 544 | |
| 583 | 545 | void omti8621_device::copy_sectors(INT32 dst_addr, INT32 src_addr, UINT8 count, UINT8 lun) |
| 584 | 546 | { |
| 585 | | device_image_interface *image = our_disks[lun]->image; |
| 547 | device_image_interface *image = our_disks[lun]->m_image; |
| 586 | 548 | |
| 587 | 549 | LOG2(("copy_sectors lun=%d src_addr=%x dst_addr=%x count=%x", lun, src_addr, dst_addr, count)); |
| 588 | 550 | |
| r29180 | r29181 | |
| 635 | 597 | |
| 636 | 598 | if (check_disk_address(cdb) ) { |
| 637 | 599 | if ((cdb[5] & 0x40) == 0) { |
| 638 | | memset(sector_buffer, 0x6C, OMTI_DISK_SECTOR_SIZE * our_disks[lun]->sectors); |
| 600 | memset(sector_buffer, 0x6C, OMTI_DISK_SECTOR_SIZE * our_disks[lun]->m_sectors); |
| 639 | 601 | } |
| 640 | | write_sectors_to_disk(disk_addr, our_disks[lun]->sectors, lun); |
| 602 | write_sectors_to_disk(disk_addr, our_disks[lun]->m_sectors, lun); |
| 641 | 603 | } |
| 642 | 604 | |
| 643 | 605 | } |
| r29180 | r29181 | |
| 648 | 610 | |
| 649 | 611 | void omti8621_device::set_esdi_defect_list(UINT8 lun, UINT8 head) |
| 650 | 612 | { |
| 651 | | disk_data *disk = our_disks[lun]; |
| 613 | omti_disk_image_device *disk = our_disks[lun]; |
| 652 | 614 | |
| 653 | | memset(disk->esdi_defect_list, 0, sizeof(disk->esdi_defect_list)); |
| 654 | | disk->esdi_defect_list[0] = 1; // month |
| 655 | | disk->esdi_defect_list[1] = 1; // day |
| 656 | | disk->esdi_defect_list[2] = 90; // year |
| 657 | | disk->esdi_defect_list[3] = head; |
| 658 | | memset(disk->esdi_defect_list+6, 0xff, 5); // end of defect list |
| 615 | memset(disk->m_esdi_defect_list, 0, sizeof(disk->m_esdi_defect_list)); |
| 616 | disk->m_esdi_defect_list[0] = 1; // month |
| 617 | disk->m_esdi_defect_list[1] = 1; // day |
| 618 | disk->m_esdi_defect_list[2] = 90; // year |
| 619 | disk->m_esdi_defect_list[3] = head; |
| 620 | memset(disk->m_esdi_defect_list+6, 0xff, 5); // end of defect list |
| 659 | 621 | } |
| 660 | 622 | |
| 661 | 623 | /*************************************************************************** |
| r29180 | r29181 | |
| 785 | 747 | void omti8621_device::do_command(const UINT8 cdb[], const UINT16 cdb_length) |
| 786 | 748 | { |
| 787 | 749 | UINT8 lun = get_lun(cdb); |
| 788 | | disk_data *disk = our_disks[lun]; |
| 750 | omti_disk_image_device *disk = our_disks[lun]; |
| 789 | 751 | int command_duration = 0; // ms |
| 790 | 752 | |
| 791 | 753 | log_command( cdb, cdb_length); |
| r29180 | r29181 | |
| 799 | 761 | set_interrupt(CLEAR_LINE); |
| 800 | 762 | } |
| 801 | 763 | |
| 802 | | if (!disk->image->exists()) { |
| 764 | if (!disk->m_image->exists()) { |
| 803 | 765 | command_status |= OMTI_COMMAND_STATUS_ERROR; // no such drive |
| 804 | 766 | } |
| 805 | 767 | |
| 806 | 768 | switch (cdb[0]) { |
| 807 | 769 | case OMTI_CMD_TEST_DRIVE_READY: // 0x00 |
| 808 | | if (!disk->image->exists()) |
| 770 | if (!disk->m_image->exists()) |
| 809 | 771 | { |
| 810 | 772 | set_sense_data(OMTI_SENSE_CODE_DRIVE_NOT_READY, cdb); |
| 811 | 773 | } |
| r29180 | r29181 | |
| 866 | 828 | |
| 867 | 829 | case OMTI_CMD_READ_ESDI_DEFECT_LIST: // 0x37 |
| 868 | 830 | set_esdi_defect_list(get_lun(cdb), cdb[1] & 0x1f); |
| 869 | | set_data_transfer(disk->esdi_defect_list, sizeof(disk->esdi_defect_list)); |
| 831 | set_data_transfer(disk->m_esdi_defect_list, sizeof(disk->m_esdi_defect_list)); |
| 870 | 832 | break; |
| 871 | 833 | |
| 872 | 834 | case OMTI_CMD_ASSIGN_ALTERNATE_TRACK: // 0x11 |
| r29180 | r29181 | |
| 917 | 879 | |
| 918 | 880 | case OMTI_CMD_READ_CONFIGURATION: // 0xEC |
| 919 | 881 | set_configuration_data(get_lun(cdb)); |
| 920 | | set_data_transfer(disk->config_data, sizeof(disk->config_data)); |
| 882 | set_data_transfer(disk->m_config_data, sizeof(disk->m_config_data)); |
| 921 | 883 | break; |
| 922 | 884 | |
| 923 | 885 | case OMTI_CMD_INVALID_COMMAND: // 0xFF |
| r29180 | r29181 | |
| 1196 | 1158 | |
| 1197 | 1159 | UINT32 omti8621_device::get_sector(INT32 diskaddr, UINT8 *data_buffer, UINT32 length, UINT8 lun) |
| 1198 | 1160 | { |
| 1199 | | disk_data *disk = our_disks[lun]; |
| 1161 | omti_disk_image_device *disk = our_disks[lun]; |
| 1200 | 1162 | |
| 1201 | | if (disk->image == NULL || !disk->image->exists()) |
| 1163 | if (disk->m_image == NULL || !disk->m_image->exists()) |
| 1202 | 1164 | { |
| 1203 | 1165 | return 0; |
| 1204 | 1166 | } |
| r29180 | r29181 | |
| 1209 | 1171 | // restrict length to size of 1 sector (i.e. 1024 Byte) |
| 1210 | 1172 | length = length < OMTI_DISK_SECTOR_SIZE ? length : OMTI_DISK_SECTOR_SIZE; |
| 1211 | 1173 | |
| 1212 | | disk->image->fseek(diskaddr * OMTI_DISK_SECTOR_SIZE, SEEK_SET); |
| 1213 | | disk->image->fread(data_buffer, length); |
| 1174 | disk->m_image->fseek(diskaddr * OMTI_DISK_SECTOR_SIZE, SEEK_SET); |
| 1175 | disk->m_image->fread(data_buffer, length); |
| 1214 | 1176 | |
| 1215 | 1177 | return length; |
| 1216 | 1178 | } |
| r29180 | r29181 | |
| 1282 | 1244 | |
| 1283 | 1245 | |
| 1284 | 1246 | /*************************************************************************** |
| 1285 | | get_safe_disk_token - makes sure that the passed in device is a OMTI disk |
| 1286 | | ***************************************************************************/ |
| 1287 | | |
| 1288 | | INLINE disk_data *get_safe_disk_token(device_t *device) { |
| 1289 | | assert(device != NULL); |
| 1290 | | assert(device->type() == OMTI_DISK); |
| 1291 | | return (disk_data *) downcast<omti_disk_image_device *>(device)->token(); |
| 1292 | | } |
| 1293 | | |
| 1294 | | /*************************************************************************** |
| 1295 | 1247 | omti_disk_config - configure disk parameters |
| 1296 | 1248 | ***************************************************************************/ |
| 1297 | 1249 | |
| 1298 | | static void omti_disk_config(disk_data *disk, UINT16 disk_type) |
| 1250 | void omti_disk_image_device::omti_disk_config(UINT16 disk_type) |
| 1299 | 1251 | { |
| 1300 | | DLOG1(("omti_disk_config: configuring disk with type %x", disk_type)); |
| 1252 | LOG1(("omti_disk_config: configuring disk with type %x", disk_type)); |
| 1301 | 1253 | |
| 1302 | 1254 | switch (disk_type) |
| 1303 | 1255 | { |
| 1304 | 1256 | case OMTI_DISK_TYPE_348_MB: // Maxtor 380 MB (348-MB FA formatted) |
| 1305 | | disk->cylinders = 1223; |
| 1306 | | disk->heads = 15; |
| 1307 | | disk->sectors = 18; |
| 1257 | m_cylinders = 1223; |
| 1258 | m_heads = 15; |
| 1259 | m_sectors = 18; |
| 1308 | 1260 | break; |
| 1309 | 1261 | |
| 1310 | 1262 | case OMTI_DISK_TYPE_155_MB: // Micropolis 170 MB (155-MB formatted) |
| 1311 | 1263 | default: |
| 1312 | | disk->cylinders = 1023; |
| 1313 | | disk->heads = 8; |
| 1314 | | disk->sectors = 18; |
| 1264 | m_cylinders = 1023; |
| 1265 | m_heads = 8; |
| 1266 | m_sectors = 18; |
| 1315 | 1267 | break; |
| 1316 | 1268 | } |
| 1317 | 1269 | |
| 1318 | | disk->type = disk_type; |
| 1319 | | disk->sectorbytes = OMTI_DISK_SECTOR_SIZE; |
| 1320 | | disk->sector_count = disk->cylinders * disk->heads * disk->sectors; |
| 1270 | m_type = disk_type; |
| 1271 | m_sectorbytes = OMTI_DISK_SECTOR_SIZE; |
| 1272 | m_sector_count = m_cylinders * m_heads * m_sectors; |
| 1321 | 1273 | } |
| 1322 | 1274 | |
| 1323 | 1275 | /*------------------------------------------------- |
| r29180 | r29181 | |
| 1326 | 1278 | |
| 1327 | 1279 | void omti_disk_image_device::device_start() |
| 1328 | 1280 | { |
| 1329 | | disk_data *disk = get_safe_disk_token(this); |
| 1281 | m_image = this; |
| 1330 | 1282 | |
| 1331 | | disk->device = this; |
| 1332 | | // note: we must have disk->device before we can log |
| 1333 | | |
| 1334 | | disk->image = this; |
| 1335 | | |
| 1336 | | if (disk->image->image_core_file() == NULL) |
| 1283 | if (m_image->image_core_file() == NULL) |
| 1337 | 1284 | { |
| 1338 | | DLOG1(("device_start_omti_disk: no disk")); |
| 1285 | LOG1(("device_start_omti_disk: no disk")); |
| 1339 | 1286 | } |
| 1340 | 1287 | else |
| 1341 | 1288 | { |
| 1342 | | DLOG1(("device_start_omti_disk: with disk image %s",disk->image->basename() )); |
| 1289 | LOG1(("device_start_omti_disk: with disk image %s",m_image->basename() )); |
| 1343 | 1290 | } |
| 1344 | 1291 | |
| 1345 | 1292 | // default disk type |
| 1346 | | omti_disk_config(disk, OMTI_DISK_TYPE_DEFAULT); |
| 1293 | omti_disk_config(OMTI_DISK_TYPE_DEFAULT); |
| 1347 | 1294 | } |
| 1348 | 1295 | |
| 1349 | 1296 | /*------------------------------------------------- |
| r29180 | r29181 | |
| 1351 | 1298 | -------------------------------------------------*/ |
| 1352 | 1299 | |
| 1353 | 1300 | void omti_disk_image_device::device_reset() |
| 1354 | | { |
| 1355 | | disk_data *disk = get_safe_disk_token(this); |
| 1356 | | DLOG1(("device_reset_omti_disk")); |
| 1301 | { |
| 1302 | LOG1(("device_reset_omti_disk")); |
| 1357 | 1303 | |
| 1358 | 1304 | if (exists() && fseek(0, SEEK_END) == 0) |
| 1359 | 1305 | { |
| 1360 | 1306 | UINT32 disk_size = (UINT32)(ftell() / OMTI_DISK_SECTOR_SIZE); |
| 1361 | 1307 | UINT16 disk_type = disk_size >= 300000 ? OMTI_DISK_TYPE_348_MB : OMTI_DISK_TYPE_155_MB; |
| 1362 | | if (disk_type != disk->type) { |
| 1363 | | DLOG1(("device_reset_omti_disk: disk size=%d blocks, disk type=%x", disk_size, disk_type )); |
| 1364 | | omti_disk_config(disk, disk_type); |
| 1308 | if (disk_type != m_type) { |
| 1309 | LOG1(("device_reset_omti_disk: disk size=%d blocks, disk type=%x", disk_size, disk_type )); |
| 1310 | omti_disk_config(disk_type); |
| 1365 | 1311 | } |
| 1366 | 1312 | } |
| 1367 | 1313 | } |
| r29180 | r29181 | |
| 1372 | 1318 | |
| 1373 | 1319 | bool omti_disk_image_device::call_create(int format_type, option_resolution *format_options) |
| 1374 | 1320 | { |
| 1375 | | disk_data *disk = get_safe_disk_token(this); |
| 1376 | | DLOG(("device_create_omti_disk: creating OMTI Disk with %d blocks", disk->sector_count)); |
| 1321 | LOG(("device_create_omti_disk: creating OMTI Disk with %d blocks", m_sector_count)); |
| 1377 | 1322 | |
| 1378 | 1323 | int x; |
| 1379 | 1324 | unsigned char sectordata[OMTI_DISK_SECTOR_SIZE]; // empty block data |
| 1380 | 1325 | |
| 1381 | 1326 | |
| 1382 | 1327 | memset(sectordata, 0x55, sizeof(sectordata)); |
| 1383 | | for (x = 0; x < disk->sector_count; x++) |
| 1328 | for (x = 0; x < m_sector_count; x++) |
| 1384 | 1329 | { |
| 1385 | 1330 | if (fwrite(sectordata, OMTI_DISK_SECTOR_SIZE) |
| 1386 | 1331 | < OMTI_DISK_SECTOR_SIZE) |
trunk/src/emu/bus/nubus/nubus_image.c
| r29180 | r29181 | |
| 14 | 14 | |
| 15 | 15 | #define MESSIMG_DISK_SECTOR_SIZE (512) |
| 16 | 16 | |
| 17 | | // messimg_disk_image_device |
| 18 | | |
| 19 | | class messimg_disk_image_device : public device_t, |
| 20 | | public device_image_interface |
| 21 | | { |
| 22 | | public: |
| 23 | | // construction/destruction |
| 24 | | messimg_disk_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 25 | | |
| 26 | | // image-level overrides |
| 27 | | virtual iodevice_t image_type() const { return IO_QUICKLOAD; } |
| 28 | | |
| 29 | | virtual bool is_readable() const { return 1; } |
| 30 | | virtual bool is_writeable() const { return 1; } |
| 31 | | virtual bool is_creatable() const { return 0; } |
| 32 | | virtual bool must_be_loaded() const { return 0; } |
| 33 | | virtual bool is_reset_on_load() const { return 0; } |
| 34 | | virtual const char *image_interface() const { return NULL; } |
| 35 | | virtual const char *file_extensions() const { return "img"; } |
| 36 | | virtual const option_guide *create_option_guide() const { return NULL; } |
| 37 | | |
| 38 | | virtual bool call_load(); |
| 39 | | virtual void call_unload(); |
| 40 | | |
| 41 | | disk_data *token() { return &m_token; } |
| 42 | | protected: |
| 43 | | // device-level overrides |
| 44 | | virtual void device_config_complete(); |
| 45 | | virtual void device_start(); |
| 46 | | virtual void device_reset(); |
| 47 | | |
| 48 | | disk_data m_token; |
| 49 | | }; |
| 50 | | |
| 51 | 17 | // device type definition |
| 52 | 18 | extern const device_type MESSIMG_DISK; |
| 53 | 19 | |
| r29180 | r29181 | |
| 65 | 31 | }; |
| 66 | 32 | |
| 67 | 33 | |
| 68 | | /*************************************************************************** |
| 69 | | get_safe_disk_token - makes sure that the passed in device is a messimg disk |
| 70 | | ***************************************************************************/ |
| 71 | | |
| 72 | | INLINE disk_data *get_safe_disk_token(device_t *device) { |
| 73 | | assert(device != NULL); |
| 74 | | assert(device->type() == MESSIMG_DISK); |
| 75 | | return (disk_data *) downcast<messimg_disk_image_device *>(device)->token(); |
| 76 | | } |
| 77 | | |
| 78 | 34 | /*------------------------------------------------- |
| 79 | 35 | device start callback |
| 80 | 36 | -------------------------------------------------*/ |
| 81 | 37 | |
| 82 | 38 | void messimg_disk_image_device::device_start() |
| 83 | 39 | { |
| 84 | | disk_data *disk = get_safe_disk_token(this); |
| 40 | m_data = (UINT8 *)NULL; |
| 85 | 41 | |
| 86 | | disk->device = this; |
| 87 | | disk->image = this; |
| 88 | | disk->data = (UINT8 *)NULL; |
| 89 | | |
| 90 | 42 | if (exists() && fseek(0, SEEK_END) == 0) |
| 91 | 43 | { |
| 92 | | disk->size = (UINT32)ftell(); |
| 44 | m_size = (UINT32)ftell(); |
| 93 | 45 | } |
| 94 | 46 | } |
| 95 | 47 | |
| 96 | 48 | bool messimg_disk_image_device::call_load() |
| 97 | 49 | { |
| 98 | | disk_data *disk = get_safe_disk_token(this); |
| 99 | | |
| 100 | 50 | fseek(0, SEEK_END); |
| 101 | | disk->size = (UINT32)ftell(); |
| 102 | | if (disk->size > (256*1024*1024)) |
| 51 | m_size = (UINT32)ftell(); |
| 52 | if (m_size > (256*1024*1024)) |
| 103 | 53 | { |
| 104 | 54 | printf("Mac image too large: must be 256MB or less!\n"); |
| 105 | | disk->size = 0; |
| 55 | m_size = 0; |
| 106 | 56 | return IMAGE_INIT_FAIL; |
| 107 | 57 | } |
| 108 | 58 | |
| 109 | | disk->data = (UINT8 *)auto_alloc_array_clear(machine(), UINT32, disk->size/sizeof(UINT32)); |
| 59 | m_data = (UINT8 *)auto_alloc_array_clear(machine(), UINT32, m_size/sizeof(UINT32)); |
| 110 | 60 | fseek(0, SEEK_SET); |
| 111 | | fread(disk->data, disk->size); |
| 112 | | disk->ejected = false; |
| 61 | fread(m_data, m_size); |
| 62 | m_ejected = false; |
| 113 | 63 | |
| 114 | 64 | return IMAGE_INIT_PASS; |
| 115 | 65 | } |
| 116 | 66 | |
| 117 | 67 | void messimg_disk_image_device::call_unload() |
| 118 | 68 | { |
| 119 | | disk_data *disk = get_safe_disk_token(this); |
| 120 | | |
| 121 | 69 | // TODO: track dirty sectors and only write those |
| 122 | 70 | fseek(0, SEEK_SET); |
| 123 | | fwrite(disk->data, disk->size); |
| 124 | | disk->size = 0; |
| 125 | | //free(disk->data); |
| 71 | fwrite(m_data, m_size); |
| 72 | m_size = 0; |
| 73 | //free(m_data); |
| 126 | 74 | } |
| 127 | 75 | |
| 128 | 76 | /*------------------------------------------------- |
| r29180 | r29181 | |
| 210 | 158 | m_nubus->install_device(slotspace+4, slotspace+7, read32_delegate(FUNC(nubus_image_device::image_status_r), this), write32_delegate(FUNC(nubus_image_device::image_status_w), this)); |
| 211 | 159 | m_nubus->install_device(superslotspace, superslotspace+((256*1024*1024)-1), read32_delegate(FUNC(nubus_image_device::image_super_r), this), write32_delegate(FUNC(nubus_image_device::image_super_w), this)); |
| 212 | 160 | |
| 213 | | device_t *device0 = subdevice(IMAGE_DISK0_TAG); |
| 214 | | m_image = (disk_data *) downcast<messimg_disk_image_device *>(device0)->token(); |
| 161 | m_image = subdevice<messimg_disk_image_device>(IMAGE_DISK0_TAG); |
| 215 | 162 | } |
| 216 | 163 | |
| 217 | 164 | //------------------------------------------------- |
| r29180 | r29181 | |
| 224 | 171 | |
| 225 | 172 | WRITE32_MEMBER( nubus_image_device::image_status_w ) |
| 226 | 173 | { |
| 227 | | m_image->ejected = true; |
| 174 | m_image->m_ejected = true; |
| 228 | 175 | } |
| 229 | 176 | |
| 230 | 177 | READ32_MEMBER( nubus_image_device::image_status_r ) |
| 231 | 178 | { |
| 232 | | if(m_image->ejected) { |
| 179 | if(m_image->m_ejected) { |
| 233 | 180 | return 0; |
| 234 | 181 | } |
| 235 | 182 | |
| 236 | | if(m_image->size) { |
| 183 | if(m_image->m_size) { |
| 237 | 184 | return 1; |
| 238 | 185 | } |
| 239 | 186 | return 0; |
| r29180 | r29181 | |
| 245 | 192 | |
| 246 | 193 | READ32_MEMBER( nubus_image_device::image_r ) |
| 247 | 194 | { |
| 248 | | return m_image->size; |
| 195 | return m_image->m_size; |
| 249 | 196 | } |
| 250 | 197 | |
| 251 | 198 | WRITE32_MEMBER( nubus_image_device::image_super_w ) |
| 252 | 199 | { |
| 253 | | UINT32 *image = (UINT32*)m_image->data; |
| 200 | UINT32 *image = (UINT32*)m_image->m_data; |
| 254 | 201 | data = ((data & 0xff) << 24) | ((data & 0xff00) << 8) | ((data & 0xff0000) >> 8) | ((data & 0xff000000) >> 24); |
| 255 | 202 | mem_mask = ((mem_mask & 0xff) << 24) | ((mem_mask & 0xff00) << 8) | ((mem_mask & 0xff0000) >> 8) | ((mem_mask & 0xff000000) >> 24); |
| 256 | 203 | |
| r29180 | r29181 | |
| 259 | 206 | |
| 260 | 207 | READ32_MEMBER( nubus_image_device::image_super_r ) |
| 261 | 208 | { |
| 262 | | UINT32 *image = (UINT32*)m_image->data; |
| 209 | UINT32 *image = (UINT32*)m_image->m_data; |
| 263 | 210 | UINT32 data = image[offset]; |
| 264 | 211 | return ((data & 0xff) << 24) | ((data & 0xff00) << 8) | ((data & 0xff0000) >> 8) | ((data & 0xff000000) >> 24); |
| 265 | 212 | } |