trunk/src/emu/machine/idectrl.c
| r23587 | r23588 | |
| 90 | 90 | #define IDE_ERROR_BAD_LOCATION 0x10 |
| 91 | 91 | #define IDE_ERROR_BAD_SECTOR 0x80 |
| 92 | 92 | |
| 93 | | #define IDE_BUSMASTER_STATUS_ACTIVE 0x01 |
| 94 | | #define IDE_BUSMASTER_STATUS_ERROR 0x02 |
| 95 | | #define IDE_BUSMASTER_STATUS_IRQ 0x04 |
| 96 | 93 | |
| 97 | | |
| 98 | | void ide_controller_device::signal_interrupt() |
| 94 | void ide_controller_device::set_irq(int state) |
| 99 | 95 | { |
| 100 | | LOG(("IDE interrupt assert\n")); |
| 101 | | |
| 96 | if (state == ASSERT_LINE) |
| 97 | LOG(("IDE interrupt assert\n")); |
| 98 | else |
| 99 | LOG(("IDE interrupt clear\n")); |
| 100 | |
| 102 | 101 | /* signal an interrupt */ |
| 103 | | m_irq_handler(ASSERT_LINE); |
| 104 | | interrupt_pending = 1; |
| 105 | | bus_master_status |= IDE_BUSMASTER_STATUS_IRQ; |
| 102 | m_irq_handler(state); |
| 103 | interrupt_pending = state; |
| 106 | 104 | } |
| 107 | 105 | |
| 108 | | |
| 109 | | void ide_controller_device::clear_interrupt() |
| 106 | void ide_controller_device::set_dmarq(int state) |
| 110 | 107 | { |
| 111 | | LOG(("IDE interrupt clear\n")); |
| 112 | | |
| 113 | | /* clear an interrupt */ |
| 114 | | m_irq_handler(CLEAR_LINE); |
| 115 | | interrupt_pending = 0; |
| 116 | 108 | } |
| 117 | 109 | |
| 118 | 110 | |
| r23587 | r23588 | |
| 125 | 117 | { |
| 126 | 118 | ide_controller_device *ide = (ide_controller_device *)ptr; |
| 127 | 119 | ide->status &= ~IDE_STATUS_BUSY; |
| 128 | | ide->signal_interrupt(); |
| 120 | ide->set_irq(ASSERT_LINE); |
| 129 | 121 | } |
| 130 | 122 | |
| 131 | 123 | |
| r23587 | r23588 | |
| 134 | 126 | ide_controller_device *ide = (ide_controller_device *)ptr; |
| 135 | 127 | ide->status &= ~IDE_STATUS_BUSY; |
| 136 | 128 | ide->status |= IDE_STATUS_BUFFER_READY; |
| 137 | | ide->signal_interrupt(); |
| 129 | ide->set_irq(ASSERT_LINE); |
| 138 | 130 | } |
| 139 | 131 | |
| 140 | 132 | |
| r23587 | r23588 | |
| 265 | 257 | * |
| 266 | 258 | *************************************/ |
| 267 | 259 | |
| 268 | | void ide_controller_device::continue_read() |
| 260 | void ide_controller_device::read_buffer_empty() |
| 269 | 261 | { |
| 270 | 262 | /* reset the totals */ |
| 271 | 263 | buffer_offset = 0; |
| r23587 | r23588 | |
| 273 | 265 | /* clear the buffer ready and busy flag */ |
| 274 | 266 | status &= ~IDE_STATUS_BUFFER_READY; |
| 275 | 267 | status &= ~IDE_STATUS_BUSY; |
| 268 | error = IDE_ERROR_DEFAULT; |
| 269 | set_dmarq(0); |
| 276 | 270 | |
| 277 | 271 | if (master_password_enable || user_password_enable) |
| 278 | 272 | { |
| 279 | 273 | security_error(); |
| 280 | 274 | |
| 281 | 275 | sector_count = 0; |
| 282 | | bus_master_status &= ~IDE_BUSMASTER_STATUS_ACTIVE; |
| 283 | | dma_active = 0; |
| 284 | 276 | |
| 285 | 277 | return; |
| 286 | 278 | } |
| r23587 | r23588 | |
| 290 | 282 | sector_count--; |
| 291 | 283 | if (sector_count > 0) |
| 292 | 284 | read_next_sector(); |
| 293 | | else |
| 294 | | { |
| 295 | | bus_master_status &= ~IDE_BUSMASTER_STATUS_ACTIVE; |
| 296 | | dma_active = 0; |
| 297 | | } |
| 298 | 285 | } |
| 299 | 286 | |
| 300 | 287 | |
| 301 | | void ide_controller_device::write_buffer_to_dma() |
| 302 | | { |
| 303 | | int bytesleft = IDE_DISK_SECTOR_SIZE; |
| 304 | | UINT16 data = 0; |
| 305 | | |
| 306 | | // LOG(("Writing sector to %08X\n", dma_address)); |
| 307 | | |
| 308 | | /* loop until we've consumed all bytes */ |
| 309 | | while (bytesleft--) |
| 310 | | { |
| 311 | | data >>= 8; |
| 312 | | |
| 313 | | if (bytesleft & 1) |
| 314 | | data = read_dma(); |
| 315 | | |
| 316 | | /* if we're out of space, grab the next descriptor */ |
| 317 | | if (dma_bytes_left == 0) |
| 318 | | { |
| 319 | | /* if we're out of buffer space, that's bad */ |
| 320 | | if (dma_last_buffer) |
| 321 | | { |
| 322 | | LOG(("DMA Out of buffer space!\n")); |
| 323 | | return; |
| 324 | | } |
| 325 | | |
| 326 | | /* fetch the address */ |
| 327 | | dma_address = dma_space->read_byte(dma_descriptor++ ^ dma_address_xor); |
| 328 | | dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 8; |
| 329 | | dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 16; |
| 330 | | dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 24; |
| 331 | | dma_address &= 0xfffffffe; |
| 332 | | |
| 333 | | /* fetch the length */ |
| 334 | | dma_bytes_left = dma_space->read_byte(dma_descriptor++ ^ dma_address_xor); |
| 335 | | dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 8; |
| 336 | | dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 16; |
| 337 | | dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 24; |
| 338 | | dma_last_buffer = (dma_bytes_left >> 31) & 1; |
| 339 | | dma_bytes_left &= 0xfffe; |
| 340 | | if (dma_bytes_left == 0) |
| 341 | | dma_bytes_left = 0x10000; |
| 342 | | |
| 343 | | // LOG(("New DMA descriptor: address = %08X bytes = %04X last = %d\n", dma_address, dma_bytes_left, dma_last_buffer)); |
| 344 | | } |
| 345 | | |
| 346 | | /* write the next byte */ |
| 347 | | dma_space->write_byte(dma_address++, data & 0xff); |
| 348 | | dma_bytes_left--; |
| 349 | | } |
| 350 | | } |
| 351 | | |
| 352 | | |
| 353 | 288 | void ide_controller_device::read_sector_done() |
| 354 | 289 | { |
| 355 | 290 | ide_device_interface *dev = slot[cur_drive]->dev(); |
| r23587 | r23588 | |
| 390 | 325 | if (sectors_until_int == 0 || sector_count == 1) |
| 391 | 326 | { |
| 392 | 327 | sectors_until_int = ((command == IDE_COMMAND_READ_MULTIPLE_BLOCK) ? block_count : 1); |
| 393 | | signal_interrupt(); |
| 328 | set_irq(ASSERT_LINE); |
| 394 | 329 | } |
| 395 | 330 | |
| 396 | 331 | /* handle DMA */ |
| 397 | 332 | if (dma_active) |
| 398 | | write_buffer_to_dma(); |
| 333 | set_dmarq(1); |
| 399 | 334 | |
| 400 | 335 | /* if we're just verifying we can read the next sector */ |
| 401 | 336 | if (verify_only) |
| 402 | | continue_read(); |
| 337 | read_buffer_empty(); |
| 403 | 338 | } |
| 404 | 339 | |
| 405 | 340 | /* if we got an error, we need to report it */ |
| r23587 | r23588 | |
| 408 | 343 | /* set the error flag and the error */ |
| 409 | 344 | status |= IDE_STATUS_ERROR; |
| 410 | 345 | error = IDE_ERROR_BAD_SECTOR; |
| 411 | | bus_master_status |= IDE_BUSMASTER_STATUS_ERROR; |
| 412 | | bus_master_status &= ~IDE_BUSMASTER_STATUS_ACTIVE; |
| 413 | 346 | |
| 414 | 347 | /* signal an interrupt */ |
| 415 | | signal_interrupt(); |
| 348 | set_irq(ASSERT_LINE); |
| 416 | 349 | } |
| 417 | 350 | } |
| 418 | 351 | |
| r23587 | r23588 | |
| 509 | 442 | } |
| 510 | 443 | |
| 511 | 444 | |
| 512 | | void ide_controller_device::read_buffer_from_dma() |
| 445 | void ide_controller_device::write_buffer_full() |
| 513 | 446 | { |
| 514 | | int bytesleft = IDE_DISK_SECTOR_SIZE; |
| 515 | | UINT16 data = 0; |
| 447 | ide_device_interface *dev = slot[cur_drive]->dev(); |
| 516 | 448 | |
| 517 | | // LOG(("Reading sector from %08X\n", dma_address)); |
| 518 | | |
| 519 | | /* loop until we've consumed all bytes */ |
| 520 | | while (bytesleft--) |
| 449 | set_dmarq(0); |
| 450 | if (command == IDE_COMMAND_SECURITY_UNLOCK) |
| 521 | 451 | { |
| 522 | | /* if we're out of space, grab the next descriptor */ |
| 523 | | if (dma_bytes_left == 0) |
| 452 | if (user_password_enable && memcmp(buffer, user_password, 2 + 32) == 0) |
| 524 | 453 | { |
| 525 | | /* if we're out of buffer space, that's bad */ |
| 526 | | if (dma_last_buffer) |
| 454 | LOGPRINT(("IDE Unlocked user password\n")); |
| 455 | user_password_enable = 0; |
| 456 | } |
| 457 | if (master_password_enable && memcmp(buffer, master_password, 2 + 32) == 0) |
| 458 | { |
| 459 | LOGPRINT(("IDE Unlocked master password\n")); |
| 460 | master_password_enable = 0; |
| 461 | } |
| 462 | if (PRINTF_IDE_PASSWORD) |
| 463 | { |
| 464 | int i; |
| 465 | |
| 466 | for (i = 0; i < 34; i += 2) |
| 527 | 467 | { |
| 528 | | LOG(("DMA Out of buffer space!\n")); |
| 529 | | return; |
| 530 | | } |
| 468 | if (i % 8 == 2) |
| 469 | mame_printf_debug("\n"); |
| 531 | 470 | |
| 532 | | /* fetch the address */ |
| 533 | | dma_address = dma_space->read_byte(dma_descriptor++ ^ dma_address_xor); |
| 534 | | dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 8; |
| 535 | | dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 16; |
| 536 | | dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 24; |
| 537 | | dma_address &= 0xfffffffe; |
| 538 | | |
| 539 | | /* fetch the length */ |
| 540 | | dma_bytes_left = dma_space->read_byte(dma_descriptor++ ^ dma_address_xor); |
| 541 | | dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 8; |
| 542 | | dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 16; |
| 543 | | dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 24; |
| 544 | | dma_last_buffer = (dma_bytes_left >> 31) & 1; |
| 545 | | dma_bytes_left &= 0xfffe; |
| 546 | | if (dma_bytes_left == 0) |
| 547 | | dma_bytes_left = 0x10000; |
| 548 | | |
| 549 | | // LOG(("New DMA descriptor: address = %08X bytes = %04X last = %d\n", dma_address, dma_bytes_left, dma_last_buffer)); |
| 471 | mame_printf_debug("0x%02x, 0x%02x, ", buffer[i], buffer[i + 1]); |
| 472 | //mame_printf_debug("0x%02x%02x, ", buffer[i], buffer[i + 1]); |
| 473 | } |
| 474 | mame_printf_debug("\n"); |
| 550 | 475 | } |
| 551 | 476 | |
| 552 | | /* read the next byte */ |
| 553 | | data |= dma_space->read_byte(dma_address++) << 8; |
| 554 | | dma_bytes_left --; |
| 477 | /* clear the busy and error flags */ |
| 478 | status &= ~IDE_STATUS_ERROR; |
| 479 | status &= ~IDE_STATUS_BUSY; |
| 480 | status &= ~IDE_STATUS_BUFFER_READY; |
| 555 | 481 | |
| 556 | | if((bytesleft & 1) == 0) |
| 557 | | write_dma(data); |
| 482 | if (master_password_enable || user_password_enable) |
| 483 | security_error(); |
| 484 | else |
| 485 | status |= IDE_STATUS_DRIVE_READY; |
| 486 | } |
| 487 | else if (command == IDE_COMMAND_TAITO_GNET_UNLOCK_2) |
| 488 | { |
| 489 | UINT8 key[5] = { 0 }; |
| 490 | int i, bad = 0; |
| 491 | dev->read_key(key); |
| 558 | 492 | |
| 559 | | data >>= 8; |
| 493 | for (i=0; !bad && i<512; i++) |
| 494 | bad = ((i < 2 || i >= 7) && buffer[i]) || ((i >= 2 && i < 7) && buffer[i] != key[i-2]); |
| 495 | |
| 496 | status &= ~IDE_STATUS_BUSY; |
| 497 | status &= ~IDE_STATUS_BUFFER_READY; |
| 498 | if (bad) |
| 499 | status |= IDE_STATUS_ERROR; |
| 500 | else { |
| 501 | status &= ~IDE_STATUS_ERROR; |
| 502 | gnetreadlock= 0; |
| 503 | } |
| 560 | 504 | } |
| 505 | else |
| 506 | { |
| 507 | continue_write(); |
| 508 | } |
| 561 | 509 | } |
| 562 | 510 | |
| 563 | 511 | |
| r23587 | r23588 | |
| 592 | 540 | if (--sectors_until_int == 0 || sector_count == 1) |
| 593 | 541 | { |
| 594 | 542 | sectors_until_int = ((command == IDE_COMMAND_WRITE_MULTIPLE_BLOCK) ? block_count : 1); |
| 595 | | signal_interrupt(); |
| 543 | set_irq(ASSERT_LINE); |
| 596 | 544 | } |
| 597 | 545 | |
| 598 | 546 | /* signal an interrupt if there's more data needed */ |
| r23587 | r23588 | |
| 604 | 552 | /* keep going for DMA */ |
| 605 | 553 | if (dma_active && sector_count != 0) |
| 606 | 554 | { |
| 607 | | read_buffer_from_dma(); |
| 555 | set_dmarq(1); |
| 608 | 556 | } |
| 609 | | else |
| 610 | | dma_active = 0; |
| 611 | 557 | } |
| 612 | 558 | |
| 613 | 559 | /* if we got an error, we need to report it */ |
| r23587 | r23588 | |
| 616 | 562 | /* set the error flag and the error */ |
| 617 | 563 | status |= IDE_STATUS_ERROR; |
| 618 | 564 | error = IDE_ERROR_BAD_SECTOR; |
| 619 | | bus_master_status |= IDE_BUSMASTER_STATUS_ERROR; |
| 620 | | bus_master_status &= ~IDE_BUSMASTER_STATUS_ACTIVE; |
| 621 | 565 | |
| 622 | 566 | /* signal an interrupt */ |
| 623 | | signal_interrupt(); |
| 567 | set_irq(ASSERT_LINE); |
| 624 | 568 | } |
| 625 | 569 | } |
| 626 | 570 | |
| r23587 | r23588 | |
| 644 | 588 | UINT8 key[5]; |
| 645 | 589 | ide_device_interface *dev = slot[cur_drive]->dev(); |
| 646 | 590 | |
| 647 | | /* implicitly clear interrupts here */ |
| 648 | | clear_interrupt(); |
| 591 | /* implicitly clear interrupts & dmarq here */ |
| 592 | set_irq(CLEAR_LINE); |
| 593 | set_dmarq(0); |
| 649 | 594 | command = _command; |
| 650 | 595 | switch (command) |
| 651 | 596 | { |
| r23587 | r23588 | |
| 704 | 649 | verify_only = 0; |
| 705 | 650 | |
| 706 | 651 | /* start the read going */ |
| 707 | | if (bus_master_command & 1) |
| 708 | | read_first_sector(); |
| 652 | read_first_sector(); |
| 709 | 653 | break; |
| 710 | 654 | |
| 711 | 655 | case IDE_COMMAND_WRITE_MULTIPLE: |
| r23587 | r23588 | |
| 745 | 689 | dma_active = 1; |
| 746 | 690 | |
| 747 | 691 | /* start the read going */ |
| 748 | | if (bus_master_command & 1) |
| 749 | | { |
| 750 | | read_buffer_from_dma(); |
| 751 | | } |
| 692 | set_dmarq(1); |
| 752 | 693 | break; |
| 753 | 694 | |
| 754 | 695 | case IDE_COMMAND_SECURITY_UNLOCK: |
| r23587 | r23588 | |
| 761 | 702 | |
| 762 | 703 | /* mark the buffer ready */ |
| 763 | 704 | status |= IDE_STATUS_BUFFER_READY; |
| 764 | | signal_interrupt(); |
| 705 | set_irq(ASSERT_LINE); |
| 765 | 706 | break; |
| 766 | 707 | |
| 767 | 708 | case IDE_COMMAND_GET_INFO: |
| r23587 | r23588 | |
| 811 | 752 | /* for timeout disabled value is 0 */ |
| 812 | 753 | sector_count = 0; |
| 813 | 754 | /* signal an interrupt */ |
| 814 | | signal_interrupt(); |
| 755 | set_irq(ASSERT_LINE); |
| 815 | 756 | break; |
| 816 | 757 | |
| 817 | 758 | case IDE_COMMAND_SET_CONFIG: |
| r23587 | r23588 | |
| 829 | 770 | LOGPRINT(("IDE unknown command (F9)\n")); |
| 830 | 771 | |
| 831 | 772 | /* signal an interrupt */ |
| 832 | | signal_interrupt(); |
| 773 | set_irq(ASSERT_LINE); |
| 833 | 774 | break; |
| 834 | 775 | |
| 835 | 776 | case IDE_COMMAND_SET_FEATURES: |
| r23587 | r23588 | |
| 847 | 788 | status |= IDE_STATUS_DRIVE_READY; |
| 848 | 789 | |
| 849 | 790 | /* signal an interrupt */ |
| 850 | | signal_interrupt(); |
| 791 | set_irq(ASSERT_LINE); |
| 851 | 792 | break; |
| 852 | 793 | |
| 853 | 794 | case IDE_COMMAND_TAITO_GNET_UNLOCK_1: |
| r23587 | r23588 | |
| 856 | 797 | sector_count = 1; |
| 857 | 798 | status |= IDE_STATUS_DRIVE_READY; |
| 858 | 799 | status &= ~IDE_STATUS_ERROR; |
| 859 | | signal_interrupt(); |
| 800 | set_irq(ASSERT_LINE); |
| 860 | 801 | break; |
| 861 | 802 | |
| 862 | 803 | case IDE_COMMAND_TAITO_GNET_UNLOCK_2: |
| r23587 | r23588 | |
| 869 | 810 | |
| 870 | 811 | /* mark the buffer ready */ |
| 871 | 812 | status |= IDE_STATUS_BUFFER_READY; |
| 872 | | signal_interrupt(); |
| 813 | set_irq(ASSERT_LINE); |
| 873 | 814 | break; |
| 874 | 815 | |
| 875 | 816 | case IDE_COMMAND_TAITO_GNET_UNLOCK_3: |
| r23587 | r23588 | |
| 885 | 826 | /* update flags */ |
| 886 | 827 | status |= IDE_STATUS_DRIVE_READY; |
| 887 | 828 | status &= ~IDE_STATUS_ERROR; |
| 888 | | signal_interrupt(); |
| 829 | set_irq(ASSERT_LINE); |
| 889 | 830 | break; |
| 890 | 831 | |
| 891 | 832 | case IDE_COMMAND_SEEK: |
| r23587 | r23588 | |
| 900 | 841 | /* for timeout disabled value is 0 */ |
| 901 | 842 | sector_count = 0; |
| 902 | 843 | /* signal an interrupt */ |
| 903 | | signal_interrupt(); |
| 844 | set_irq(ASSERT_LINE); |
| 904 | 845 | break; |
| 905 | 846 | |
| 906 | 847 | |
| r23587 | r23588 | |
| 908 | 849 | LOGPRINT(("IDE unknown command (%02X)\n", command)); |
| 909 | 850 | status |= IDE_STATUS_ERROR; |
| 910 | 851 | error = IDE_ERROR_UNKNOWN_COMMAND; |
| 911 | | signal_interrupt(); |
| 852 | set_irq(ASSERT_LINE); |
| 912 | 853 | //debugger_break(device->machine()); |
| 913 | 854 | break; |
| 914 | 855 | } |
| r23587 | r23588 | |
| 1066 | 1007 | result |= IDE_STATUS_HIT_INDEX; |
| 1067 | 1008 | last_status_timer->adjust(attotime::never); |
| 1068 | 1009 | } |
| 1069 | | if (interrupt_pending) |
| 1070 | | clear_interrupt(); |
| 1010 | if (interrupt_pending == ASSERT_LINE) |
| 1011 | set_irq(CLEAR_LINE); |
| 1071 | 1012 | break; |
| 1072 | 1013 | |
| 1073 | 1014 | /* log anything else */ |
| r23587 | r23588 | |
| 1083 | 1024 | } |
| 1084 | 1025 | |
| 1085 | 1026 | |
| 1086 | | void ide_controller_device::write_buffer_full() |
| 1087 | | { |
| 1088 | | ide_device_interface *dev = slot[cur_drive]->dev(); |
| 1089 | | |
| 1090 | | if (command == IDE_COMMAND_SECURITY_UNLOCK) |
| 1091 | | { |
| 1092 | | if (user_password_enable && memcmp(buffer, user_password, 2 + 32) == 0) |
| 1093 | | { |
| 1094 | | LOGPRINT(("IDE Unlocked user password\n")); |
| 1095 | | user_password_enable = 0; |
| 1096 | | } |
| 1097 | | if (master_password_enable && memcmp(buffer, master_password, 2 + 32) == 0) |
| 1098 | | { |
| 1099 | | LOGPRINT(("IDE Unlocked master password\n")); |
| 1100 | | master_password_enable = 0; |
| 1101 | | } |
| 1102 | | if (PRINTF_IDE_PASSWORD) |
| 1103 | | { |
| 1104 | | int i; |
| 1105 | | |
| 1106 | | for (i = 0; i < 34; i += 2) |
| 1107 | | { |
| 1108 | | if (i % 8 == 2) |
| 1109 | | mame_printf_debug("\n"); |
| 1110 | | |
| 1111 | | mame_printf_debug("0x%02x, 0x%02x, ", buffer[i], buffer[i + 1]); |
| 1112 | | //mame_printf_debug("0x%02x%02x, ", buffer[i], buffer[i + 1]); |
| 1113 | | } |
| 1114 | | mame_printf_debug("\n"); |
| 1115 | | } |
| 1116 | | |
| 1117 | | /* clear the busy and error flags */ |
| 1118 | | status &= ~IDE_STATUS_ERROR; |
| 1119 | | status &= ~IDE_STATUS_BUSY; |
| 1120 | | status &= ~IDE_STATUS_BUFFER_READY; |
| 1121 | | |
| 1122 | | if (master_password_enable || user_password_enable) |
| 1123 | | security_error(); |
| 1124 | | else |
| 1125 | | status |= IDE_STATUS_DRIVE_READY; |
| 1126 | | } |
| 1127 | | else if (command == IDE_COMMAND_TAITO_GNET_UNLOCK_2) |
| 1128 | | { |
| 1129 | | UINT8 key[5] = { 0 }; |
| 1130 | | int i, bad = 0; |
| 1131 | | dev->read_key(key); |
| 1132 | | |
| 1133 | | for (i=0; !bad && i<512; i++) |
| 1134 | | bad = ((i < 2 || i >= 7) && buffer[i]) || ((i >= 2 && i < 7) && buffer[i] != key[i-2]); |
| 1135 | | |
| 1136 | | status &= ~IDE_STATUS_BUSY; |
| 1137 | | status &= ~IDE_STATUS_BUFFER_READY; |
| 1138 | | if (bad) |
| 1139 | | status |= IDE_STATUS_ERROR; |
| 1140 | | else { |
| 1141 | | status &= ~IDE_STATUS_ERROR; |
| 1142 | | gnetreadlock= 0; |
| 1143 | | } |
| 1144 | | } |
| 1145 | | else |
| 1146 | | continue_write(); |
| 1147 | | } |
| 1148 | | |
| 1149 | | void ide_controller_device::read_buffer_empty() |
| 1150 | | { |
| 1151 | | continue_read(); |
| 1152 | | error = IDE_ERROR_DEFAULT; |
| 1153 | | } |
| 1154 | | |
| 1155 | 1027 | READ16_MEMBER( ide_controller_device::read_cs1_pc ) |
| 1156 | 1028 | { |
| 1157 | 1029 | if (mem_mask == 0xff00) |
| r23587 | r23588 | |
| 1389 | 1261 | } |
| 1390 | 1262 | |
| 1391 | 1263 | |
| 1392 | | /************************************* |
| 1393 | | * |
| 1394 | | * Bus master read |
| 1395 | | * |
| 1396 | | *************************************/ |
| 1397 | | |
| 1398 | | READ32_MEMBER( bus_master_ide_controller_device::ide_bus_master32_r ) |
| 1399 | | { |
| 1400 | | LOG(("%s:ide_bus_master32_r(%d, %08x)\n", machine().describe_context(), offset, mem_mask)); |
| 1401 | | |
| 1402 | | switch( offset ) |
| 1403 | | { |
| 1404 | | case 0: |
| 1405 | | /* command register/status register */ |
| 1406 | | return bus_master_command | (bus_master_status << 16); |
| 1407 | | |
| 1408 | | case 1: |
| 1409 | | /* descriptor table register */ |
| 1410 | | return bus_master_descriptor; |
| 1411 | | } |
| 1412 | | |
| 1413 | | return 0xffffffff; |
| 1414 | | } |
| 1415 | | |
| 1416 | | |
| 1417 | | |
| 1418 | | /************************************* |
| 1419 | | * |
| 1420 | | * Bus master write |
| 1421 | | * |
| 1422 | | *************************************/ |
| 1423 | | |
| 1424 | | WRITE32_MEMBER( bus_master_ide_controller_device::ide_bus_master32_w ) |
| 1425 | | { |
| 1426 | | LOG(("%s:ide_bus_master32_w(%d, %08x, %08X)\n", machine().describe_context(), offset, mem_mask, data)); |
| 1427 | | |
| 1428 | | switch( offset ) |
| 1429 | | { |
| 1430 | | case 0: |
| 1431 | | if( ACCESSING_BITS_0_7 ) |
| 1432 | | { |
| 1433 | | /* command register */ |
| 1434 | | UINT8 old = bus_master_command; |
| 1435 | | UINT8 val = data & 0xff; |
| 1436 | | |
| 1437 | | /* save the read/write bit and the start/stop bit */ |
| 1438 | | bus_master_command = (old & 0xf6) | (val & 0x09); |
| 1439 | | bus_master_status = (bus_master_status & ~IDE_BUSMASTER_STATUS_ACTIVE) | (val & 0x01); |
| 1440 | | |
| 1441 | | /* handle starting a transfer */ |
| 1442 | | if (!(old & 1) && (val & 1)) |
| 1443 | | { |
| 1444 | | /* reset all the DMA data */ |
| 1445 | | dma_bytes_left = 0; |
| 1446 | | dma_last_buffer = 0; |
| 1447 | | dma_descriptor = bus_master_descriptor; |
| 1448 | | |
| 1449 | | /* if we're going live, start the pending read/write */ |
| 1450 | | if (dma_active) |
| 1451 | | { |
| 1452 | | if (bus_master_command & 8) |
| 1453 | | read_next_sector(); |
| 1454 | | else |
| 1455 | | { |
| 1456 | | read_buffer_from_dma(); |
| 1457 | | } |
| 1458 | | } |
| 1459 | | } |
| 1460 | | } |
| 1461 | | |
| 1462 | | if( ACCESSING_BITS_16_23 ) |
| 1463 | | { |
| 1464 | | /* status register */ |
| 1465 | | UINT8 old = bus_master_status; |
| 1466 | | UINT8 val = (data >> 16) & 0xff; |
| 1467 | | |
| 1468 | | /* save the DMA capable bits */ |
| 1469 | | bus_master_status = (old & 0x9f) | (val & 0x60); |
| 1470 | | |
| 1471 | | /* clear interrupt and error bits */ |
| 1472 | | if (val & IDE_BUSMASTER_STATUS_IRQ) |
| 1473 | | bus_master_status &= ~IDE_BUSMASTER_STATUS_IRQ; |
| 1474 | | if (val & IDE_BUSMASTER_STATUS_ERROR) |
| 1475 | | bus_master_status &= ~IDE_BUSMASTER_STATUS_ERROR; |
| 1476 | | } |
| 1477 | | break; |
| 1478 | | |
| 1479 | | case 1: |
| 1480 | | /* descriptor table register */ |
| 1481 | | bus_master_descriptor = data & 0xfffffffc; |
| 1482 | | break; |
| 1483 | | } |
| 1484 | | } |
| 1485 | | |
| 1486 | | |
| 1487 | 1264 | SLOT_INTERFACE_START(ide_devices) |
| 1488 | 1265 | SLOT_INTERFACE("hdd", IDE_HARDDISK) |
| 1489 | 1266 | SLOT_INTERFACE_END |
| r23587 | r23588 | |
| 1491 | 1268 | ide_controller_device::ide_controller_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : |
| 1492 | 1269 | device_t(mconfig, type, name, tag, owner, clock), |
| 1493 | 1270 | status(0), |
| 1494 | | bmcpu(NULL), |
| 1495 | | bmspace(0), |
| 1496 | | dma_space(NULL), |
| 1497 | | dma_active(0), |
| 1498 | | dma_address_xor(0), |
| 1499 | | dma_last_buffer(0), |
| 1500 | | dma_address(0), |
| 1501 | | dma_descriptor(0), |
| 1502 | | dma_bytes_left(0), |
| 1503 | | bus_master_command(0), |
| 1504 | | bus_master_status(0), |
| 1505 | | bus_master_descriptor(0), |
| 1506 | 1271 | adapter_control(0), |
| 1507 | 1272 | error(0), |
| 1508 | 1273 | command(0), |
| r23587 | r23588 | |
| 1530 | 1295 | |
| 1531 | 1296 | ide_controller_device::ide_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 1532 | 1297 | device_t(mconfig, IDE_CONTROLLER, "IDE Controller", tag, owner, clock), |
| 1533 | | bmcpu(NULL), |
| 1534 | | bmspace(0), |
| 1535 | | dma_space(NULL), |
| 1536 | | dma_active(0), |
| 1537 | | dma_address_xor(0), |
| 1538 | | dma_last_buffer(0), |
| 1539 | | dma_address(0), |
| 1540 | | dma_descriptor(0), |
| 1541 | | dma_bytes_left(0), |
| 1542 | | bus_master_command(0), |
| 1543 | | bus_master_status(0), |
| 1544 | | bus_master_descriptor(0), |
| 1545 | 1298 | adapter_control(0), |
| 1546 | 1299 | error(0), |
| 1547 | 1300 | command(0), |
| r23587 | r23588 | |
| 1564 | 1317 | { |
| 1565 | 1318 | } |
| 1566 | 1319 | |
| 1567 | | const device_type BUS_MASTER_IDE_CONTROLLER = &device_creator<bus_master_ide_controller_device>; |
| 1568 | | |
| 1569 | | bus_master_ide_controller_device::bus_master_ide_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 1570 | | ide_controller_device(mconfig, BUS_MASTER_IDE_CONTROLLER, "Bus Master IDE Controller", tag, owner, clock) |
| 1571 | | { |
| 1572 | | } |
| 1573 | | |
| 1574 | 1320 | //------------------------------------------------- |
| 1575 | 1321 | // device_start - device-specific startup |
| 1576 | 1322 | //------------------------------------------------- |
| r23587 | r23588 | |
| 1583 | 1329 | slot[0] = owner()->subdevice<ide_slot_device>("drive_0"); |
| 1584 | 1330 | slot[1] = owner()->subdevice<ide_slot_device>("drive_1"); |
| 1585 | 1331 | |
| 1586 | | /* find the bus master space */ |
| 1587 | | if (bmcpu != NULL) |
| 1588 | | { |
| 1589 | | device_t *bmtarget = machine().device(bmcpu); |
| 1590 | | if (bmtarget == NULL) |
| 1591 | | throw emu_fatalerror("IDE controller '%s' bus master target '%s' doesn't exist!", tag(), bmcpu); |
| 1592 | | device_memory_interface *memory; |
| 1593 | | if (!bmtarget->interface(memory)) |
| 1594 | | throw emu_fatalerror("IDE controller '%s' bus master target '%s' has no memory!", tag(), bmcpu); |
| 1595 | | dma_space = &memory->space(bmspace); |
| 1596 | | dma_address_xor = (dma_space->endianness() == ENDIANNESS_LITTLE) ? 0 : 3; |
| 1597 | | } |
| 1598 | | |
| 1599 | 1332 | /* create a timer for timing status */ |
| 1600 | 1333 | last_status_timer = machine().scheduler().timer_alloc(FUNC_NULL); |
| 1601 | 1334 | reset_timer = machine().scheduler().timer_alloc(FUNC(reset_callback), this); |
| r23587 | r23588 | |
| 1616 | 1349 | save_item(NAME(sectors_until_int)); |
| 1617 | 1350 | |
| 1618 | 1351 | save_item(NAME(dma_active)); |
| 1619 | | save_item(NAME(dma_last_buffer)); |
| 1620 | | save_item(NAME(dma_address)); |
| 1621 | | save_item(NAME(dma_descriptor)); |
| 1622 | | save_item(NAME(dma_bytes_left)); |
| 1623 | 1352 | |
| 1624 | | save_item(NAME(bus_master_command)); |
| 1625 | | save_item(NAME(bus_master_status)); |
| 1626 | | save_item(NAME(bus_master_descriptor)); |
| 1627 | | |
| 1628 | 1353 | save_item(NAME(config_unknown)); |
| 1629 | 1354 | save_item(NAME(config_register)); |
| 1630 | 1355 | save_item(NAME(config_register_num)); |
| r23587 | r23588 | |
| 1650 | 1375 | gnetreadlock = 0; |
| 1651 | 1376 | master_password_enable = (master_password != NULL); |
| 1652 | 1377 | user_password_enable = (user_password != NULL); |
| 1653 | | clear_interrupt(); |
| 1378 | set_irq(CLEAR_LINE); |
| 1379 | set_dmarq(0); |
| 1654 | 1380 | } |
| 1655 | 1381 | |
| 1656 | 1382 | |
| r23587 | r23588 | |
| 1691 | 1417 | void ide_slot_device::device_start() |
| 1692 | 1418 | { |
| 1693 | 1419 | } |
| 1420 | |
| 1421 | |
| 1422 | |
| 1423 | #define IDE_BUSMASTER_STATUS_ACTIVE 0x01 |
| 1424 | #define IDE_BUSMASTER_STATUS_ERROR 0x02 |
| 1425 | #define IDE_BUSMASTER_STATUS_IRQ 0x04 |
| 1426 | |
| 1427 | const device_type BUS_MASTER_IDE_CONTROLLER = &device_creator<bus_master_ide_controller_device>; |
| 1428 | |
| 1429 | bus_master_ide_controller_device::bus_master_ide_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 1430 | ide_controller_device(mconfig, BUS_MASTER_IDE_CONTROLLER, "Bus Master IDE Controller", tag, owner, clock), |
| 1431 | dma_address(0), |
| 1432 | dma_bytes_left(0), |
| 1433 | dma_descriptor(0), |
| 1434 | dma_last_buffer(0), |
| 1435 | bus_master_command(0), |
| 1436 | bus_master_status(0), |
| 1437 | bus_master_descriptor(0) |
| 1438 | { |
| 1439 | } |
| 1440 | |
| 1441 | void bus_master_ide_controller_device::device_start() |
| 1442 | { |
| 1443 | ide_controller_device::device_start(); |
| 1444 | |
| 1445 | /* find the bus master space */ |
| 1446 | if (bmcpu != NULL) |
| 1447 | { |
| 1448 | device_t *bmtarget = machine().device(bmcpu); |
| 1449 | if (bmtarget == NULL) |
| 1450 | throw emu_fatalerror("IDE controller '%s' bus master target '%s' doesn't exist!", tag(), bmcpu); |
| 1451 | device_memory_interface *memory; |
| 1452 | if (!bmtarget->interface(memory)) |
| 1453 | throw emu_fatalerror("IDE controller '%s' bus master target '%s' has no memory!", tag(), bmcpu); |
| 1454 | dma_space = &memory->space(bmspace); |
| 1455 | dma_address_xor = (dma_space->endianness() == ENDIANNESS_LITTLE) ? 0 : 3; |
| 1456 | } |
| 1457 | |
| 1458 | save_item(NAME(dma_address)); |
| 1459 | save_item(NAME(dma_bytes_left)); |
| 1460 | save_item(NAME(dma_descriptor)); |
| 1461 | save_item(NAME(dma_last_buffer)); |
| 1462 | save_item(NAME(bus_master_command)); |
| 1463 | save_item(NAME(bus_master_status)); |
| 1464 | save_item(NAME(bus_master_descriptor)); |
| 1465 | } |
| 1466 | |
| 1467 | void bus_master_ide_controller_device::set_irq(int state) |
| 1468 | { |
| 1469 | ide_controller_device::set_irq(state); |
| 1470 | |
| 1471 | if (m_irq != state) |
| 1472 | { |
| 1473 | m_irq = state; |
| 1474 | |
| 1475 | if( m_irq ) |
| 1476 | bus_master_status |= IDE_BUSMASTER_STATUS_IRQ; |
| 1477 | } |
| 1478 | } |
| 1479 | |
| 1480 | void bus_master_ide_controller_device::set_dmarq(int state) |
| 1481 | { |
| 1482 | if (m_dmarq != state) |
| 1483 | { |
| 1484 | m_dmarq = state; |
| 1485 | |
| 1486 | execute_dma(); |
| 1487 | } |
| 1488 | } |
| 1489 | |
| 1490 | /************************************* |
| 1491 | * |
| 1492 | * Bus master read |
| 1493 | * |
| 1494 | *************************************/ |
| 1495 | |
| 1496 | READ32_MEMBER( bus_master_ide_controller_device::ide_bus_master32_r ) |
| 1497 | { |
| 1498 | LOG(("%s:ide_bus_master32_r(%d, %08x)\n", machine().describe_context(), offset, mem_mask)); |
| 1499 | |
| 1500 | switch( offset ) |
| 1501 | { |
| 1502 | case 0: |
| 1503 | /* command register/status register */ |
| 1504 | return bus_master_command | (bus_master_status << 16); |
| 1505 | |
| 1506 | case 1: |
| 1507 | /* descriptor table register */ |
| 1508 | return bus_master_descriptor; |
| 1509 | } |
| 1510 | |
| 1511 | return 0xffffffff; |
| 1512 | } |
| 1513 | |
| 1514 | |
| 1515 | |
| 1516 | /************************************* |
| 1517 | * |
| 1518 | * Bus master write |
| 1519 | * |
| 1520 | *************************************/ |
| 1521 | |
| 1522 | WRITE32_MEMBER( bus_master_ide_controller_device::ide_bus_master32_w ) |
| 1523 | { |
| 1524 | LOG(("%s:ide_bus_master32_w(%d, %08x, %08X)\n", machine().describe_context(), offset, mem_mask, data)); |
| 1525 | |
| 1526 | switch( offset ) |
| 1527 | { |
| 1528 | case 0: |
| 1529 | if( ACCESSING_BITS_0_7 ) |
| 1530 | { |
| 1531 | /* command register */ |
| 1532 | UINT8 old = bus_master_command; |
| 1533 | UINT8 val = data & 0xff; |
| 1534 | |
| 1535 | /* save the read/write bit and the start/stop bit */ |
| 1536 | bus_master_command = (old & 0xf6) | (val & 0x09); |
| 1537 | |
| 1538 | if ((old ^ bus_master_command) & 1) |
| 1539 | { |
| 1540 | if (bus_master_command & 1) |
| 1541 | { |
| 1542 | /* handle starting a transfer */ |
| 1543 | bus_master_status |= IDE_BUSMASTER_STATUS_ACTIVE; |
| 1544 | |
| 1545 | /* reset all the DMA data */ |
| 1546 | dma_bytes_left = 0; |
| 1547 | dma_descriptor = bus_master_descriptor; |
| 1548 | |
| 1549 | /* if we're going live, start the pending read/write */ |
| 1550 | execute_dma(); |
| 1551 | } |
| 1552 | else if (bus_master_status & IDE_BUSMASTER_STATUS_ACTIVE) |
| 1553 | { |
| 1554 | bus_master_status &= ~IDE_BUSMASTER_STATUS_ACTIVE; |
| 1555 | |
| 1556 | LOG(("DMA Aborted!\n")); |
| 1557 | } |
| 1558 | } |
| 1559 | } |
| 1560 | |
| 1561 | if( ACCESSING_BITS_16_23 ) |
| 1562 | { |
| 1563 | /* status register */ |
| 1564 | UINT8 old = bus_master_status; |
| 1565 | UINT8 val = data >> 16; |
| 1566 | |
| 1567 | /* save the DMA capable bits */ |
| 1568 | bus_master_status = (old & 0x9f) | (val & 0x60); |
| 1569 | |
| 1570 | /* clear interrupt and error bits */ |
| 1571 | if (val & IDE_BUSMASTER_STATUS_IRQ) |
| 1572 | bus_master_status &= ~IDE_BUSMASTER_STATUS_IRQ; |
| 1573 | if (val & IDE_BUSMASTER_STATUS_ERROR) |
| 1574 | bus_master_status &= ~IDE_BUSMASTER_STATUS_ERROR; |
| 1575 | } |
| 1576 | break; |
| 1577 | |
| 1578 | case 1: |
| 1579 | /* descriptor table register */ |
| 1580 | bus_master_descriptor = data & 0xfffffffc; |
| 1581 | break; |
| 1582 | } |
| 1583 | } |
| 1584 | |
| 1585 | void bus_master_ide_controller_device::execute_dma() |
| 1586 | { |
| 1587 | while (m_dmarq && (bus_master_status & IDE_BUSMASTER_STATUS_ACTIVE)) |
| 1588 | { |
| 1589 | /* if we're out of space, grab the next descriptor */ |
| 1590 | if (dma_bytes_left == 0) |
| 1591 | { |
| 1592 | /* fetch the address */ |
| 1593 | dma_address = dma_space->read_byte(dma_descriptor++ ^ dma_address_xor); |
| 1594 | dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 8; |
| 1595 | dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 16; |
| 1596 | dma_address |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 24; |
| 1597 | dma_address &= 0xfffffffe; |
| 1598 | |
| 1599 | /* fetch the length */ |
| 1600 | dma_bytes_left = dma_space->read_byte(dma_descriptor++ ^ dma_address_xor); |
| 1601 | dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 8; |
| 1602 | dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 16; |
| 1603 | dma_bytes_left |= dma_space->read_byte(dma_descriptor++ ^ dma_address_xor) << 24; |
| 1604 | dma_last_buffer = (dma_bytes_left >> 31) & 1; |
| 1605 | dma_bytes_left &= 0xfffe; |
| 1606 | if (dma_bytes_left == 0) |
| 1607 | dma_bytes_left = 0x10000; |
| 1608 | |
| 1609 | // LOG(("New DMA descriptor: address = %08X bytes = %04X last = %d\n", dma_address, dma_bytes_left, dma_last_buffer)); |
| 1610 | } |
| 1611 | |
| 1612 | if (bus_master_command & 8) |
| 1613 | { |
| 1614 | // read from ata bus |
| 1615 | UINT16 data = read_dma(); |
| 1616 | |
| 1617 | // write to memory |
| 1618 | dma_space->write_byte(dma_address++, data & 0xff); |
| 1619 | dma_space->write_byte(dma_address++, data >> 8); |
| 1620 | } |
| 1621 | else |
| 1622 | { |
| 1623 | // read from memory; |
| 1624 | UINT16 data = dma_space->read_byte(dma_address++); |
| 1625 | data |= dma_space->read_byte(dma_address++) << 8; |
| 1626 | |
| 1627 | // write to ata bus |
| 1628 | write_dma(data); |
| 1629 | } |
| 1630 | |
| 1631 | dma_bytes_left -= 2; |
| 1632 | |
| 1633 | if (dma_bytes_left == 0 && dma_last_buffer) |
| 1634 | { |
| 1635 | bus_master_status &= ~IDE_BUSMASTER_STATUS_ACTIVE; |
| 1636 | |
| 1637 | if (m_dmarq) |
| 1638 | { |
| 1639 | LOG(("DMA Out of buffer space!\n")); |
| 1640 | } |
| 1641 | } |
| 1642 | } |
| 1643 | } |