trunk/src/emu/machine/idehd.c
| r23712 | r23713 | |
| 21 | 21 | #define TIME_SEEK_MULTISECTOR (attotime::from_msec(13)) |
| 22 | 22 | #define TIME_NO_SEEK_MULTISECTOR (attotime::from_nsec(16300)) |
| 23 | 23 | |
| 24 | | #define IDE_BANK0_DATA 0 |
| 25 | | #define IDE_BANK0_ERROR 1 |
| 26 | | #define IDE_BANK0_SECTOR_COUNT 2 |
| 27 | | #define IDE_BANK0_SECTOR_NUMBER 3 |
| 28 | | #define IDE_BANK0_CYLINDER_LSB 4 |
| 29 | | #define IDE_BANK0_CYLINDER_MSB 5 |
| 30 | | #define IDE_BANK0_HEAD_NUMBER 6 |
| 31 | | #define IDE_BANK0_STATUS_COMMAND 7 |
| 24 | #define IDE_CS0_DATA_RW 0 |
| 25 | #define IDE_CS0_ERROR_R 1 |
| 26 | #define IDE_CS0_FEATURE_W 1 |
| 27 | #define IDE_CS0_SECTOR_COUNT_RW 2 |
| 28 | #define IDE_CS0_SECTOR_NUMBER_RW 3 |
| 29 | #define IDE_CS0_CYLINDER_LOW_RW 4 |
| 30 | #define IDE_CS0_CYLINDER_HIGH_RW 5 |
| 31 | #define IDE_CS0_DEVICE_HEAD_RW 6 |
| 32 | #define IDE_CS0_STATUS_R 7 |
| 33 | #define IDE_CS0_COMMAND_W 7 |
| 32 | 34 | |
| 33 | | #define IDE_BANK1_STATUS_CONTROL 6 |
| 35 | #define IDE_CS1_ALTERNATE_STATUS_R 6 |
| 36 | #define IDE_CS1_DEVICE_CONTROL_W 6 |
| 34 | 37 | |
| 35 | 38 | #define IDE_COMMAND_READ_SECTORS 0x20 |
| 36 | 39 | #define IDE_COMMAND_READ_SECTORS_NORETRY 0x21 |
| r23712 | r23713 | |
| 90 | 93 | ide_device_interface(mconfig, *this), |
| 91 | 94 | device_slot_card_interface(mconfig, *this), |
| 92 | 95 | m_csel(0), |
| 93 | | m_dasp(0) |
| 96 | m_dasp(0), |
| 97 | m_dmack(0), |
| 98 | m_dmarq(0), |
| 99 | m_irq(0) |
| 94 | 100 | { |
| 95 | 101 | } |
| 96 | 102 | |
| 97 | 103 | void ide_mass_storage_device::set_irq(int state) |
| 98 | 104 | { |
| 99 | | if (state == ASSERT_LINE) |
| 100 | | LOG(("IDE interrupt assert\n")); |
| 101 | | else |
| 102 | | LOG(("IDE interrupt clear\n")); |
| 105 | if (m_irq != state) |
| 106 | { |
| 107 | m_irq = state; |
| 103 | 108 | |
| 104 | | m_interrupt_pending = state; |
| 109 | if (state == ASSERT_LINE) |
| 110 | LOG(("IDE interrupt assert\n")); |
| 111 | else |
| 112 | LOG(("IDE interrupt clear\n")); |
| 105 | 113 | |
| 106 | | /* signal an interrupt */ |
| 107 | | m_irq_handler(state); |
| 114 | /* signal an interrupt */ |
| 115 | m_irq_handler(state); |
| 116 | } |
| 108 | 117 | } |
| 109 | 118 | |
| 110 | 119 | void ide_mass_storage_device::set_dmarq(int state) |
| 111 | 120 | { |
| 112 | | m_dmarq_handler(state); |
| 121 | if (m_dmarq != state) |
| 122 | { |
| 123 | m_dmarq = state; |
| 124 | |
| 125 | m_dmarq_handler(state); |
| 126 | } |
| 113 | 127 | } |
| 114 | 128 | |
| 115 | 129 | WRITE_LINE_MEMBER( ide_mass_storage_device::write_csel ) |
| r23712 | r23713 | |
| 122 | 136 | m_dasp = state; |
| 123 | 137 | } |
| 124 | 138 | |
| 139 | WRITE_LINE_MEMBER( ide_mass_storage_device::write_dmack ) |
| 140 | { |
| 141 | m_dmack = state; |
| 142 | } |
| 143 | |
| 125 | 144 | /************************************* |
| 126 | 145 | * |
| 127 | 146 | * Compute the LBA address |
| r23712 | r23713 | |
| 340 | 359 | save_item(NAME(m_command)); |
| 341 | 360 | save_item(NAME(m_error)); |
| 342 | 361 | |
| 343 | | save_item(NAME(m_adapter_control)); |
| 344 | | save_item(NAME(m_precomp_offset)); |
| 362 | save_item(NAME(m_device_control)); |
| 363 | save_item(NAME(m_feature)); |
| 345 | 364 | save_item(NAME(m_sector_count)); |
| 346 | 365 | |
| 347 | | save_item(NAME(m_interrupt_pending)); |
| 366 | save_item(NAME(m_irq)); |
| 367 | save_item(NAME(m_dmarq)); |
| 348 | 368 | save_item(NAME(m_sectors_until_int)); |
| 349 | 369 | |
| 350 | 370 | save_item(NAME(m_master_password_enable)); |
| r23712 | r23713 | |
| 368 | 388 | m_master_password_enable = (m_master_password != NULL); |
| 369 | 389 | m_user_password_enable = (m_user_password != NULL); |
| 370 | 390 | m_error = IDE_ERROR_DEFAULT; |
| 371 | | m_status = IDE_STATUS_DRIVE_READY | IDE_STATUS_SEEK_COMPLETE; |
| 391 | |
| 392 | m_status = IDE_STATUS_DSC; |
| 393 | if (is_ready()) |
| 394 | { |
| 395 | m_status |= IDE_STATUS_DRDY; |
| 396 | } |
| 397 | |
| 372 | 398 | m_cur_drive = 0; |
| 373 | 399 | |
| 374 | 400 | /* reset the drive state */ |
| r23712 | r23713 | |
| 381 | 407 | switch(id) |
| 382 | 408 | { |
| 383 | 409 | case TID_DELAYED_INTERRUPT: |
| 384 | | m_status &= ~IDE_STATUS_BUSY; |
| 410 | m_status &= ~IDE_STATUS_BSY; |
| 385 | 411 | set_irq(ASSERT_LINE); |
| 386 | 412 | break; |
| 387 | 413 | |
| 388 | 414 | case TID_DELAYED_INTERRUPT_BUFFER_READY: |
| 389 | | m_status &= ~IDE_STATUS_BUSY; |
| 390 | | m_status |= IDE_STATUS_BUFFER_READY; |
| 415 | m_status &= ~IDE_STATUS_BSY; |
| 416 | m_status |= IDE_STATUS_DRQ; |
| 417 | |
| 391 | 418 | set_irq(ASSERT_LINE); |
| 392 | 419 | break; |
| 393 | 420 | |
| r23712 | r23713 | |
| 397 | 424 | |
| 398 | 425 | case TID_SECURITY_ERROR_DONE: |
| 399 | 426 | /* clear error state */ |
| 400 | | m_status &= ~IDE_STATUS_ERROR; |
| 401 | | m_status |= IDE_STATUS_DRIVE_READY; |
| 427 | m_status &= ~IDE_STATUS_ERR; |
| 428 | m_status |= IDE_STATUS_DRDY; |
| 402 | 429 | break; |
| 403 | 430 | |
| 404 | 431 | case TID_READ_SECTOR_DONE_CALLBACK: |
| r23712 | r23713 | |
| 414 | 441 | void ide_mass_storage_device::signal_delayed_interrupt(attotime time, int buffer_ready) |
| 415 | 442 | { |
| 416 | 443 | /* clear buffer ready and set the busy flag */ |
| 417 | | m_status &= ~IDE_STATUS_BUFFER_READY; |
| 418 | | m_status |= IDE_STATUS_BUSY; |
| 444 | m_status &= ~IDE_STATUS_DRQ; |
| 445 | m_status |= IDE_STATUS_BSY; |
| 419 | 446 | |
| 420 | 447 | /* set a timer */ |
| 421 | 448 | if (buffer_ready) |
| r23712 | r23713 | |
| 476 | 503 | void ide_mass_storage_device::security_error() |
| 477 | 504 | { |
| 478 | 505 | /* set error state */ |
| 479 | | m_status |= IDE_STATUS_ERROR; |
| 480 | | m_status &= ~IDE_STATUS_DRIVE_READY; |
| 506 | m_status |= IDE_STATUS_ERR; |
| 507 | m_status &= ~IDE_STATUS_DRDY; |
| 481 | 508 | |
| 482 | 509 | /* just set a timer and mark ourselves error */ |
| 483 | 510 | timer_set(TIME_SECURITY_ERROR, TID_SECURITY_ERROR_DONE); |
| r23712 | r23713 | |
| 497 | 524 | m_buffer_offset = 0; |
| 498 | 525 | |
| 499 | 526 | /* clear the buffer ready and busy flag */ |
| 500 | | m_status &= ~IDE_STATUS_BUFFER_READY; |
| 501 | | m_status &= ~IDE_STATUS_BUSY; |
| 527 | m_status &= ~IDE_STATUS_DRQ; |
| 528 | m_status &= ~IDE_STATUS_BSY; |
| 502 | 529 | m_error = IDE_ERROR_DEFAULT; |
| 503 | 530 | set_dmarq(CLEAR_LINE); |
| 504 | 531 | |
| r23712 | r23713 | |
| 525 | 552 | |
| 526 | 553 | /* GNET readlock check */ |
| 527 | 554 | if (m_gnetreadlock) { |
| 528 | | m_status &= ~IDE_STATUS_ERROR; |
| 529 | | m_status &= ~IDE_STATUS_BUSY; |
| 555 | m_status &= ~IDE_STATUS_ERR; |
| 556 | m_status &= ~IDE_STATUS_BSY; |
| 530 | 557 | return; |
| 531 | 558 | } |
| 532 | 559 | |
| r23712 | r23713 | |
| 535 | 562 | |
| 536 | 563 | /* by default, mark the buffer ready and the seek complete */ |
| 537 | 564 | if (!m_verify_only) |
| 538 | | m_status |= IDE_STATUS_BUFFER_READY; |
| 539 | | m_status |= IDE_STATUS_SEEK_COMPLETE; |
| 565 | m_status |= IDE_STATUS_DRQ; |
| 540 | 566 | |
| 567 | m_status |= IDE_STATUS_DSC; |
| 568 | |
| 541 | 569 | /* and clear the busy and error flags */ |
| 542 | | m_status &= ~IDE_STATUS_ERROR; |
| 543 | | m_status &= ~IDE_STATUS_BUSY; |
| 570 | m_status &= ~IDE_STATUS_ERR; |
| 571 | m_status &= ~IDE_STATUS_BSY; |
| 544 | 572 | |
| 545 | 573 | /* if we succeeded, advance to the next sector and set the nice bits */ |
| 546 | 574 | if (count == 1) |
| r23712 | r23713 | |
| 575 | 603 | else |
| 576 | 604 | { |
| 577 | 605 | /* set the error flag and the error */ |
| 578 | | m_status |= IDE_STATUS_ERROR; |
| 606 | m_status |= IDE_STATUS_ERR; |
| 579 | 607 | m_error = IDE_ERROR_BAD_SECTOR; |
| 580 | 608 | |
| 581 | 609 | /* signal an interrupt */ |
| r23712 | r23713 | |
| 587 | 615 | void ide_mass_storage_device::read_first_sector() |
| 588 | 616 | { |
| 589 | 617 | /* mark ourselves busy */ |
| 590 | | m_status |= IDE_STATUS_BUSY; |
| 618 | m_status |= IDE_STATUS_BSY; |
| 591 | 619 | |
| 592 | 620 | /* just set a timer */ |
| 593 | 621 | if (m_command == IDE_COMMAND_READ_MULTIPLE) |
| r23712 | r23713 | |
| 611 | 639 | void ide_mass_storage_device::read_next_sector() |
| 612 | 640 | { |
| 613 | 641 | /* mark ourselves busy */ |
| 614 | | m_status |= IDE_STATUS_BUSY; |
| 642 | m_status |= IDE_STATUS_BSY; |
| 615 | 643 | |
| 616 | 644 | if (m_command == IDE_COMMAND_READ_MULTIPLE) |
| 617 | 645 | { |
| r23712 | r23713 | |
| 641 | 669 | m_buffer_offset = 0; |
| 642 | 670 | |
| 643 | 671 | /* clear the buffer ready flag */ |
| 644 | | m_status &= ~IDE_STATUS_BUFFER_READY; |
| 645 | | m_status |= IDE_STATUS_BUSY; |
| 672 | m_status &= ~IDE_STATUS_DRQ; |
| 673 | m_status |= IDE_STATUS_BSY; |
| 646 | 674 | |
| 647 | 675 | if (m_command == IDE_COMMAND_WRITE_MULTIPLE) |
| 648 | 676 | { |
| r23712 | r23713 | |
| 668 | 696 | void ide_mass_storage_device::write_buffer_full() |
| 669 | 697 | { |
| 670 | 698 | set_dmarq(CLEAR_LINE); |
| 699 | |
| 671 | 700 | if (m_command == IDE_COMMAND_SECURITY_UNLOCK) |
| 672 | 701 | { |
| 673 | 702 | if (m_user_password_enable && memcmp(m_buffer, m_user_password, 2 + 32) == 0) |
| r23712 | r23713 | |
| 696 | 725 | } |
| 697 | 726 | |
| 698 | 727 | /* clear the busy and error flags */ |
| 699 | | m_status &= ~IDE_STATUS_ERROR; |
| 700 | | m_status &= ~IDE_STATUS_BUSY; |
| 701 | | m_status &= ~IDE_STATUS_BUFFER_READY; |
| 728 | m_status &= ~IDE_STATUS_ERR; |
| 729 | m_status &= ~IDE_STATUS_BSY; |
| 730 | m_status &= ~IDE_STATUS_DRQ; |
| 702 | 731 | |
| 703 | 732 | if (m_master_password_enable || m_user_password_enable) |
| 704 | 733 | security_error(); |
| 705 | 734 | else |
| 706 | | m_status |= IDE_STATUS_DRIVE_READY; |
| 735 | m_status |= IDE_STATUS_DRDY; |
| 707 | 736 | } |
| 708 | 737 | else if (m_command == IDE_COMMAND_TAITO_GNET_UNLOCK_2) |
| 709 | 738 | { |
| r23712 | r23713 | |
| 714 | 743 | for (i=0; !bad && i<512; i++) |
| 715 | 744 | bad = ((i < 2 || i >= 7) && m_buffer[i]) || ((i >= 2 && i < 7) && m_buffer[i] != key[i-2]); |
| 716 | 745 | |
| 717 | | m_status &= ~IDE_STATUS_BUSY; |
| 718 | | m_status &= ~IDE_STATUS_BUFFER_READY; |
| 746 | m_status &= ~IDE_STATUS_BSY; |
| 747 | m_status &= ~IDE_STATUS_DRQ; |
| 719 | 748 | if (bad) |
| 720 | | m_status |= IDE_STATUS_ERROR; |
| 749 | m_status |= IDE_STATUS_ERR; |
| 721 | 750 | else { |
| 722 | | m_status &= ~IDE_STATUS_ERROR; |
| 751 | m_status &= ~IDE_STATUS_ERR; |
| 723 | 752 | m_gnetreadlock= 0; |
| 724 | 753 | } |
| 725 | 754 | } |
| r23712 | r23713 | |
| 738 | 767 | count = write_sector(lba, m_buffer); |
| 739 | 768 | |
| 740 | 769 | /* by default, mark the buffer ready and the seek complete */ |
| 741 | | m_status |= IDE_STATUS_BUFFER_READY; |
| 742 | | m_status |= IDE_STATUS_SEEK_COMPLETE; |
| 770 | m_status |= IDE_STATUS_DRQ; |
| 771 | m_status |= IDE_STATUS_DSC; |
| 743 | 772 | |
| 744 | 773 | /* and clear the busy adn error flags */ |
| 745 | | m_status &= ~IDE_STATUS_ERROR; |
| 746 | | m_status &= ~IDE_STATUS_BUSY; |
| 774 | m_status &= ~IDE_STATUS_ERR; |
| 775 | m_status &= ~IDE_STATUS_BSY; |
| 747 | 776 | |
| 748 | 777 | /* if we succeeded, advance to the next sector and set the nice bits */ |
| 749 | 778 | if (count == 1) |
| r23712 | r23713 | |
| 767 | 796 | if (m_sector_count > 0) |
| 768 | 797 | m_sector_count--; |
| 769 | 798 | if (m_sector_count == 0) |
| 770 | | m_status &= ~IDE_STATUS_BUFFER_READY; |
| 799 | m_status &= ~IDE_STATUS_DRQ; |
| 771 | 800 | |
| 772 | 801 | /* keep going for DMA */ |
| 773 | 802 | if (m_dma_active && m_sector_count != 0) |
| r23712 | r23713 | |
| 780 | 809 | else |
| 781 | 810 | { |
| 782 | 811 | /* set the error flag and the error */ |
| 783 | | m_status |= IDE_STATUS_ERROR; |
| 812 | m_status |= IDE_STATUS_ERR; |
| 784 | 813 | m_error = IDE_ERROR_BAD_SECTOR; |
| 785 | 814 | |
| 786 | 815 | /* signal an interrupt */ |
| r23712 | r23713 | |
| 796 | 825 | * |
| 797 | 826 | *************************************/ |
| 798 | 827 | |
| 799 | | void ide_mass_storage_device::handle_command(UINT8 _command) |
| 828 | void ide_mass_storage_device::handle_command() |
| 800 | 829 | { |
| 801 | 830 | UINT8 key[5]; |
| 802 | 831 | |
| 803 | 832 | /* implicitly clear interrupts & dmarq here */ |
| 804 | 833 | set_irq(CLEAR_LINE); |
| 805 | 834 | set_dmarq(CLEAR_LINE); |
| 806 | | m_command = _command; |
| 835 | |
| 807 | 836 | switch (m_command) |
| 808 | 837 | { |
| 809 | 838 | case IDE_COMMAND_READ_SECTORS: |
| r23712 | r23713 | |
| 875 | 904 | m_dma_active = 0; |
| 876 | 905 | |
| 877 | 906 | /* mark the buffer ready */ |
| 878 | | m_status |= IDE_STATUS_BUFFER_READY; |
| 907 | m_status |= IDE_STATUS_DRQ; |
| 879 | 908 | break; |
| 880 | 909 | |
| 881 | 910 | case IDE_COMMAND_WRITE_MULTIPLE: |
| r23712 | r23713 | |
| 888 | 917 | m_dma_active = 0; |
| 889 | 918 | |
| 890 | 919 | /* mark the buffer ready */ |
| 891 | | m_status |= IDE_STATUS_BUFFER_READY; |
| 920 | m_status |= IDE_STATUS_DRQ; |
| 892 | 921 | break; |
| 893 | 922 | |
| 894 | 923 | case IDE_COMMAND_WRITE_DMA: |
| r23712 | r23713 | |
| 900 | 929 | m_sectors_until_int = m_sector_count; |
| 901 | 930 | m_dma_active = 1; |
| 902 | 931 | |
| 932 | /* mark the buffer ready */ |
| 933 | m_status |= IDE_STATUS_DRQ; |
| 934 | |
| 903 | 935 | /* start the read going */ |
| 904 | 936 | set_dmarq(ASSERT_LINE); |
| 905 | 937 | break; |
| r23712 | r23713 | |
| 913 | 945 | m_dma_active = 0; |
| 914 | 946 | |
| 915 | 947 | /* mark the buffer ready */ |
| 916 | | m_status |= IDE_STATUS_BUFFER_READY; |
| 948 | m_status |= IDE_STATUS_DRQ; |
| 949 | |
| 917 | 950 | set_irq(ASSERT_LINE); |
| 918 | 951 | break; |
| 919 | 952 | |
| r23712 | r23713 | |
| 928 | 961 | memcpy(m_buffer, m_features, sizeof(m_buffer)); |
| 929 | 962 | |
| 930 | 963 | /* indicate everything is ready */ |
| 931 | | m_status |= IDE_STATUS_BUFFER_READY; |
| 932 | | m_status |= IDE_STATUS_SEEK_COMPLETE; |
| 933 | | m_status |= IDE_STATUS_DRIVE_READY; |
| 964 | m_status |= IDE_STATUS_DRQ; |
| 965 | m_status |= IDE_STATUS_DSC; |
| 966 | m_status |= IDE_STATUS_DRDY; |
| 934 | 967 | |
| 935 | 968 | /* and clear the busy adn error flags */ |
| 936 | | m_status &= ~IDE_STATUS_ERROR; |
| 937 | | m_status &= ~IDE_STATUS_BUSY; |
| 969 | m_status &= ~IDE_STATUS_ERR; |
| 970 | m_status &= ~IDE_STATUS_BSY; |
| 938 | 971 | |
| 939 | 972 | /* clear the error too */ |
| 940 | 973 | m_error = IDE_ERROR_NONE; |
| r23712 | r23713 | |
| 969 | 1002 | |
| 970 | 1003 | case IDE_COMMAND_SET_CONFIG: |
| 971 | 1004 | LOGPRINT(("IDE Set configuration (%d heads, %d sectors)\n", m_cur_head + 1, m_sector_count)); |
| 972 | | m_status &= ~IDE_STATUS_ERROR; |
| 1005 | m_status &= ~IDE_STATUS_ERR; |
| 973 | 1006 | m_error = IDE_ERROR_NONE; |
| 974 | 1007 | set_geometry(m_sector_count,m_cur_head + 1); |
| 975 | 1008 | |
| r23712 | r23713 | |
| 986 | 1019 | break; |
| 987 | 1020 | |
| 988 | 1021 | case IDE_COMMAND_SET_FEATURES: |
| 989 | | LOGPRINT(("IDE Set features (%02X %02X %02X %02X %02X)\n", m_precomp_offset, m_sector_count & 0xff, m_cur_sector, m_cur_cylinder & 0xff, m_cur_cylinder >> 8)); |
| 1022 | LOGPRINT(("IDE Set features (%02X %02X %02X %02X %02X)\n", m_feature, m_sector_count & 0xff, m_cur_sector, m_cur_cylinder & 0xff, m_cur_cylinder >> 8)); |
| 990 | 1023 | |
| 991 | 1024 | /* signal an interrupt */ |
| 992 | 1025 | signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0); |
| r23712 | r23713 | |
| 997 | 1030 | |
| 998 | 1031 | m_block_count = m_sector_count; |
| 999 | 1032 | // judge dredd wants 'drive ready' on this command |
| 1000 | | m_status |= IDE_STATUS_DRIVE_READY; |
| 1033 | m_status |= IDE_STATUS_DRDY; |
| 1001 | 1034 | |
| 1002 | 1035 | /* signal an interrupt */ |
| 1003 | 1036 | set_irq(ASSERT_LINE); |
| r23712 | r23713 | |
| 1007 | 1040 | LOGPRINT(("IDE GNET Unlock 1\n")); |
| 1008 | 1041 | |
| 1009 | 1042 | m_sector_count = 1; |
| 1010 | | m_status |= IDE_STATUS_DRIVE_READY; |
| 1011 | | m_status &= ~IDE_STATUS_ERROR; |
| 1043 | m_status |= IDE_STATUS_DRDY; |
| 1044 | m_status &= ~IDE_STATUS_ERR; |
| 1012 | 1045 | set_irq(ASSERT_LINE); |
| 1013 | 1046 | break; |
| 1014 | 1047 | |
| r23712 | r23713 | |
| 1021 | 1054 | m_dma_active = 0; |
| 1022 | 1055 | |
| 1023 | 1056 | /* mark the buffer ready */ |
| 1024 | | m_status |= IDE_STATUS_BUFFER_READY; |
| 1057 | m_status |= IDE_STATUS_DRQ; |
| 1058 | |
| 1025 | 1059 | set_irq(ASSERT_LINE); |
| 1026 | 1060 | break; |
| 1027 | 1061 | |
| r23712 | r23713 | |
| 1030 | 1064 | |
| 1031 | 1065 | /* key check */ |
| 1032 | 1066 | read_key(key); |
| 1033 | | if ((m_precomp_offset == key[0]) && (m_sector_count == key[1]) && (m_cur_sector == key[2]) && (m_cur_cylinder == (((UINT16)key[4]<<8)|key[3]))) |
| 1067 | if ((m_feature == key[0]) && (m_sector_count == key[1]) && (m_cur_sector == key[2]) && (m_cur_cylinder == (((UINT16)key[4]<<8)|key[3]))) |
| 1034 | 1068 | { |
| 1035 | 1069 | m_gnetreadlock= 0; |
| 1036 | 1070 | } |
| 1037 | 1071 | |
| 1038 | 1072 | /* update flags */ |
| 1039 | | m_status |= IDE_STATUS_DRIVE_READY; |
| 1040 | | m_status &= ~IDE_STATUS_ERROR; |
| 1073 | m_status |= IDE_STATUS_DRDY; |
| 1074 | m_status &= ~IDE_STATUS_ERR; |
| 1041 | 1075 | set_irq(ASSERT_LINE); |
| 1042 | 1076 | break; |
| 1043 | 1077 | |
| r23712 | r23713 | |
| 1059 | 1093 | |
| 1060 | 1094 | default: |
| 1061 | 1095 | LOGPRINT(("IDE unknown command (%02X)\n", m_command)); |
| 1062 | | m_status |= IDE_STATUS_ERROR; |
| 1096 | m_status |= IDE_STATUS_ERR; |
| 1063 | 1097 | m_error = IDE_ERROR_UNKNOWN_COMMAND; |
| 1064 | 1098 | set_irq(ASSERT_LINE); |
| 1065 | 1099 | //debugger_break(device->machine()); |
| r23712 | r23713 | |
| 1069 | 1103 | |
| 1070 | 1104 | UINT16 ide_mass_storage_device::read_dma() |
| 1071 | 1105 | { |
| 1072 | | if (m_cur_drive != m_csel) |
| 1106 | UINT16 result = 0xffff; |
| 1107 | |
| 1108 | if (device_selected()) |
| 1073 | 1109 | { |
| 1074 | | if (m_csel == 0 && m_dasp == 0) |
| 1075 | | return 0; |
| 1110 | if (!m_dmack) |
| 1111 | { |
| 1112 | logerror( "%s: read_dma ignored (!DMACK)\n", machine().describe_context() ); |
| 1113 | } |
| 1114 | else if( !m_dmarq) |
| 1115 | { |
| 1116 | logerror( "%s: read_dma ignored (!DMARQ)\n", machine().describe_context() ); |
| 1117 | } |
| 1118 | else if (m_status & IDE_STATUS_BSY) |
| 1119 | { |
| 1120 | logerror( "%s: read_dma ignored (BSY)\n", machine().describe_context() ); |
| 1121 | } |
| 1122 | else if (!(m_status & IDE_STATUS_DRQ)) |
| 1123 | { |
| 1124 | logerror( "%s: read_dma ignored (!DRQ)\n", machine().describe_context() ); |
| 1125 | } |
| 1126 | else |
| 1127 | { |
| 1128 | result = m_buffer[m_buffer_offset++]; |
| 1129 | result |= m_buffer[m_buffer_offset++] << 8; |
| 1076 | 1130 | |
| 1077 | | return 0xffff; |
| 1131 | if (m_buffer_offset >= IDE_DISK_SECTOR_SIZE) |
| 1132 | { |
| 1133 | LOG(("%s:IDE completed DMA read\n", machine().describe_context())); |
| 1134 | read_buffer_empty(); |
| 1135 | } |
| 1136 | } |
| 1078 | 1137 | } |
| 1079 | 1138 | |
| 1080 | | UINT16 result = m_buffer[m_buffer_offset++]; |
| 1081 | | result |= m_buffer[m_buffer_offset++] << 8; |
| 1082 | | |
| 1083 | | if (m_buffer_offset >= IDE_DISK_SECTOR_SIZE) |
| 1084 | | { |
| 1085 | | LOG(("%s:IDE completed DMA read\n", machine().describe_context())); |
| 1086 | | read_buffer_empty(); |
| 1087 | | } |
| 1088 | | |
| 1089 | 1139 | return result; |
| 1090 | 1140 | } |
| 1091 | 1141 | |
| 1092 | 1142 | READ16_MEMBER( ide_mass_storage_device::read_cs0 ) |
| 1093 | 1143 | { |
| 1094 | | UINT16 result = 0; |
| 1095 | | |
| 1096 | 1144 | /* logit */ |
| 1097 | | // if (offset != IDE_BANK0_DATA && offset != IDE_BANK0_STATUS_COMMAND) |
| 1145 | // if (offset != IDE_CS0_DATA_RW && offset != IDE_CS0_STATUS_R) |
| 1098 | 1146 | LOG(("%s:IDE cs0 read at %X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask)); |
| 1099 | 1147 | |
| 1100 | | if (m_cur_drive != m_csel) |
| 1101 | | { |
| 1102 | | if (m_csel == 0 && m_dasp == 0) |
| 1103 | | return 0; |
| 1148 | UINT16 result = 0xffff; |
| 1104 | 1149 | |
| 1105 | | return 0xffff; |
| 1106 | | } |
| 1107 | | |
| 1108 | | if (is_ready()) { |
| 1109 | | m_status |= IDE_STATUS_DRIVE_READY; |
| 1110 | | } else { |
| 1111 | | m_status &= ~IDE_STATUS_DRIVE_READY; |
| 1112 | | } |
| 1113 | | |
| 1114 | | switch (offset) |
| 1150 | if (device_selected() || single_device()) |
| 1115 | 1151 | { |
| 1116 | | /* read data if there's data to be read */ |
| 1117 | | case IDE_BANK0_DATA: |
| 1118 | | if (m_status & IDE_STATUS_BUFFER_READY) |
| 1152 | if (m_dmack) |
| 1153 | { |
| 1154 | logerror( "%s: read_cs0 %04x %04x ignored (DMACK)\n", machine().describe_context(), offset, mem_mask ); |
| 1155 | } |
| 1156 | else if ((m_status & IDE_STATUS_BSY) && offset != IDE_CS0_STATUS_R) |
| 1157 | { |
| 1158 | if (device_selected()) |
| 1119 | 1159 | { |
| 1120 | | /* fetch the correct amount of data */ |
| 1121 | | result = m_buffer[m_buffer_offset++]; |
| 1122 | | if (mem_mask == 0xffff) |
| 1123 | | result |= m_buffer[m_buffer_offset++] << 8; |
| 1160 | switch (offset) |
| 1161 | { |
| 1162 | case IDE_CS0_DATA_RW: |
| 1163 | logerror( "%s: read_cs0 %04x %04x ignored (BSY)\n", machine().describe_context(), offset, mem_mask ); |
| 1164 | break; |
| 1124 | 1165 | |
| 1125 | | /* if we're at the end of the buffer, handle it */ |
| 1126 | | if (m_buffer_offset >= IDE_DISK_SECTOR_SIZE) |
| 1127 | | { |
| 1128 | | LOG(("%s:IDE completed PIO read\n", machine().describe_context())); |
| 1129 | | read_buffer_empty(); |
| 1166 | default: |
| 1167 | result = m_status; |
| 1168 | |
| 1169 | if (m_last_status_timer->elapsed() > TIME_PER_ROTATION) |
| 1170 | { |
| 1171 | result |= IDE_STATUS_IDX; |
| 1172 | m_last_status_timer->adjust(attotime::never); |
| 1173 | } |
| 1174 | break; |
| 1130 | 1175 | } |
| 1131 | 1176 | } |
| 1132 | | break; |
| 1177 | else |
| 1178 | { |
| 1179 | result = 0; |
| 1180 | } |
| 1181 | } |
| 1182 | else |
| 1183 | { |
| 1184 | switch (offset) |
| 1185 | { |
| 1186 | /* read data if there's data to be read */ |
| 1187 | case IDE_CS0_DATA_RW: |
| 1188 | if (device_selected()) |
| 1189 | { |
| 1190 | if (m_status & IDE_STATUS_DRQ) |
| 1191 | { |
| 1192 | /* fetch the correct amount of data */ |
| 1193 | result = m_buffer[m_buffer_offset++]; |
| 1194 | if (mem_mask == 0xffff) |
| 1195 | result |= m_buffer[m_buffer_offset++] << 8; |
| 1133 | 1196 | |
| 1134 | | /* return the current error */ |
| 1135 | | case IDE_BANK0_ERROR: |
| 1136 | | result = m_error; |
| 1137 | | break; |
| 1197 | /* if we're at the end of the buffer, handle it */ |
| 1198 | if (m_buffer_offset >= IDE_DISK_SECTOR_SIZE) |
| 1199 | { |
| 1200 | LOG(("%s:IDE completed PIO read\n", machine().describe_context())); |
| 1201 | read_buffer_empty(); |
| 1202 | } |
| 1203 | } |
| 1204 | } |
| 1205 | else |
| 1206 | { |
| 1207 | result = 0; |
| 1208 | } |
| 1209 | break; |
| 1138 | 1210 | |
| 1139 | | /* return the current sector count */ |
| 1140 | | case IDE_BANK0_SECTOR_COUNT: |
| 1141 | | result = m_sector_count; |
| 1142 | | break; |
| 1211 | /* return the current error */ |
| 1212 | case IDE_CS0_ERROR_R: |
| 1213 | result = m_error; |
| 1214 | break; |
| 1143 | 1215 | |
| 1144 | | /* return the current sector */ |
| 1145 | | case IDE_BANK0_SECTOR_NUMBER: |
| 1146 | | result = m_cur_sector; |
| 1147 | | break; |
| 1216 | /* return the current sector count */ |
| 1217 | case IDE_CS0_SECTOR_COUNT_RW: |
| 1218 | result = m_sector_count; |
| 1219 | break; |
| 1148 | 1220 | |
| 1149 | | /* return the current cylinder LSB */ |
| 1150 | | case IDE_BANK0_CYLINDER_LSB: |
| 1151 | | result = m_cur_cylinder & 0xff; |
| 1152 | | break; |
| 1221 | /* return the current sector */ |
| 1222 | case IDE_CS0_SECTOR_NUMBER_RW: |
| 1223 | result = m_cur_sector; |
| 1224 | break; |
| 1153 | 1225 | |
| 1154 | | /* return the current cylinder MSB */ |
| 1155 | | case IDE_BANK0_CYLINDER_MSB: |
| 1156 | | result = m_cur_cylinder >> 8; |
| 1157 | | break; |
| 1226 | /* return the current cylinder LSB */ |
| 1227 | case IDE_CS0_CYLINDER_LOW_RW: |
| 1228 | result = m_cur_cylinder & 0xff; |
| 1229 | break; |
| 1158 | 1230 | |
| 1159 | | /* return the current head */ |
| 1160 | | case IDE_BANK0_HEAD_NUMBER: |
| 1161 | | result = m_cur_head_reg; |
| 1162 | | break; |
| 1231 | /* return the current cylinder MSB */ |
| 1232 | case IDE_CS0_CYLINDER_HIGH_RW: |
| 1233 | result = m_cur_cylinder >> 8; |
| 1234 | break; |
| 1163 | 1235 | |
| 1164 | | /* return the current status and clear any pending interrupts */ |
| 1165 | | case IDE_BANK0_STATUS_COMMAND: |
| 1166 | | result = m_status; |
| 1167 | | if (m_last_status_timer->elapsed() > TIME_PER_ROTATION) |
| 1168 | | { |
| 1169 | | result |= IDE_STATUS_HIT_INDEX; |
| 1170 | | m_last_status_timer->adjust(attotime::never); |
| 1236 | /* return the current head */ |
| 1237 | case IDE_CS0_DEVICE_HEAD_RW: |
| 1238 | result = m_cur_head_reg; |
| 1239 | break; |
| 1240 | |
| 1241 | /* return the current status and clear any pending interrupts */ |
| 1242 | case IDE_CS0_STATUS_R: |
| 1243 | if (device_selected()) |
| 1244 | { |
| 1245 | result = m_status; |
| 1246 | |
| 1247 | if (m_last_status_timer->elapsed() > TIME_PER_ROTATION) |
| 1248 | { |
| 1249 | result |= IDE_STATUS_IDX; |
| 1250 | m_last_status_timer->adjust(attotime::never); |
| 1251 | } |
| 1252 | |
| 1253 | set_irq(CLEAR_LINE); |
| 1254 | } |
| 1255 | else |
| 1256 | { |
| 1257 | result = 0; |
| 1258 | } |
| 1259 | break; |
| 1260 | |
| 1261 | /* log anything else */ |
| 1262 | default: |
| 1263 | logerror("%s:unknown IDE cs0 read at %03X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask); |
| 1264 | break; |
| 1171 | 1265 | } |
| 1172 | | if (m_interrupt_pending == ASSERT_LINE) |
| 1173 | | set_irq(CLEAR_LINE); |
| 1174 | | break; |
| 1175 | | |
| 1176 | | /* log anything else */ |
| 1177 | | default: |
| 1178 | | logerror("%s:unknown IDE cs0 read at %03X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask); |
| 1179 | | break; |
| 1266 | } |
| 1180 | 1267 | } |
| 1181 | 1268 | |
| 1182 | 1269 | /* return the result */ |
| r23712 | r23713 | |
| 1185 | 1272 | |
| 1186 | 1273 | READ16_MEMBER( ide_mass_storage_device::read_cs1 ) |
| 1187 | 1274 | { |
| 1188 | | if (m_cur_drive != m_csel) |
| 1189 | | { |
| 1190 | | if (m_csel == 0 && m_dasp == 0) |
| 1191 | | return 0; |
| 1192 | | |
| 1193 | | return 0xffff; |
| 1194 | | } |
| 1195 | | |
| 1196 | | if (is_ready()) { |
| 1197 | | m_status |= IDE_STATUS_DRIVE_READY; |
| 1198 | | } else { |
| 1199 | | m_status &= ~IDE_STATUS_DRIVE_READY; |
| 1200 | | } |
| 1201 | | |
| 1202 | 1275 | /* logit */ |
| 1203 | | // if (offset != IDE_BANK1_STATUS_CONTROL) |
| 1276 | // if (offset != IDE_CS1_ALTERNATE_STATUS_R) |
| 1204 | 1277 | LOG(("%s:IDE cs1 read at %X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask)); |
| 1205 | | /* return the current status but don't clear interrupts */ |
| 1206 | 1278 | |
| 1207 | | UINT16 result = 0; |
| 1279 | UINT16 result = 0xffff; |
| 1208 | 1280 | |
| 1209 | | switch (offset) |
| 1281 | if (device_selected() || single_device()) |
| 1210 | 1282 | { |
| 1211 | | case IDE_BANK1_STATUS_CONTROL: |
| 1212 | | result = m_status; |
| 1213 | | if (m_last_status_timer->elapsed() > TIME_PER_ROTATION) |
| 1283 | if (m_dmack) |
| 1284 | { |
| 1285 | logerror( "%s: read_cs1 %04x %04x ignored (DMACK)\n", machine().describe_context(), offset, mem_mask ); |
| 1286 | } |
| 1287 | else |
| 1288 | { |
| 1289 | switch (offset) |
| 1214 | 1290 | { |
| 1215 | | result |= IDE_STATUS_HIT_INDEX; |
| 1216 | | m_last_status_timer->adjust(attotime::never); |
| 1291 | case IDE_CS1_ALTERNATE_STATUS_R: |
| 1292 | if( device_selected() ) |
| 1293 | { |
| 1294 | /* return the current status but don't clear interrupts */ |
| 1295 | result = m_status; |
| 1296 | if (m_last_status_timer->elapsed() > TIME_PER_ROTATION) |
| 1297 | { |
| 1298 | result |= IDE_STATUS_IDX; |
| 1299 | m_last_status_timer->adjust(attotime::never); |
| 1300 | } |
| 1301 | } |
| 1302 | else |
| 1303 | { |
| 1304 | result = 0; |
| 1305 | } |
| 1306 | break; |
| 1307 | |
| 1308 | /* log anything else */ |
| 1309 | default: |
| 1310 | logerror("%s:unknown IDE cs1 read at %03X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask); |
| 1311 | break; |
| 1217 | 1312 | } |
| 1218 | | break; |
| 1219 | | |
| 1220 | | /* log anything else */ |
| 1221 | | default: |
| 1222 | | logerror("%s:unknown IDE cs1 read at %03X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask); |
| 1223 | | break; |
| 1313 | } |
| 1224 | 1314 | } |
| 1225 | 1315 | |
| 1226 | 1316 | /* return the result */ |
| r23712 | r23713 | |
| 1229 | 1319 | |
| 1230 | 1320 | void ide_mass_storage_device::write_dma( UINT16 data ) |
| 1231 | 1321 | { |
| 1232 | | if (m_cur_drive != m_csel) |
| 1233 | | return; |
| 1322 | if (device_selected()) |
| 1323 | { |
| 1324 | if (!m_dmack) |
| 1325 | { |
| 1326 | logerror( "%s: write_dma %04x ignored (!DMACK)\n", machine().describe_context(), data ); |
| 1327 | } |
| 1328 | else if( !m_dmarq) |
| 1329 | { |
| 1330 | logerror( "%s: write_dma %04x ignored (!DMARQ)\n", machine().describe_context(), data ); |
| 1331 | } |
| 1332 | else if (m_status & IDE_STATUS_BSY) |
| 1333 | { |
| 1334 | logerror( "%s: write_dma %04x ignored (BSY)\n", machine().describe_context(), data ); |
| 1335 | } |
| 1336 | else if (!(m_status & IDE_STATUS_DRQ)) |
| 1337 | { |
| 1338 | logerror( "%s: write_dma %04x ignored (!DRQ)\n", machine().describe_context(), data ); |
| 1339 | } |
| 1340 | else |
| 1341 | { |
| 1342 | m_buffer[m_buffer_offset++] = data; |
| 1343 | m_buffer[m_buffer_offset++] = data >> 8; |
| 1234 | 1344 | |
| 1235 | | m_buffer[m_buffer_offset++] = data; |
| 1236 | | m_buffer[m_buffer_offset++] = data >> 8; |
| 1237 | | |
| 1238 | | /* if we're at the end of the buffer, handle it */ |
| 1239 | | if (m_buffer_offset >= IDE_DISK_SECTOR_SIZE) |
| 1240 | | { |
| 1241 | | LOG(("%s:IDE completed DMA write\n", machine().describe_context())); |
| 1242 | | write_buffer_full(); |
| 1345 | /* if we're at the end of the buffer, handle it */ |
| 1346 | if (m_buffer_offset >= IDE_DISK_SECTOR_SIZE) |
| 1347 | { |
| 1348 | LOG(("%s:IDE completed DMA write\n", machine().describe_context())); |
| 1349 | write_buffer_full(); |
| 1350 | } |
| 1351 | } |
| 1243 | 1352 | } |
| 1244 | 1353 | } |
| 1245 | 1354 | |
| 1246 | 1355 | WRITE16_MEMBER( ide_mass_storage_device::write_cs0 ) |
| 1247 | 1356 | { |
| 1248 | | switch (offset) |
| 1249 | | { |
| 1250 | | case IDE_BANK0_HEAD_NUMBER: |
| 1251 | | m_cur_drive = (data & 0x10) >> 4; |
| 1252 | | break; |
| 1253 | | } |
| 1254 | | |
| 1255 | | if (m_cur_drive != m_csel) |
| 1256 | | return; |
| 1257 | | |
| 1258 | 1357 | /* logit */ |
| 1259 | | if (offset != IDE_BANK0_DATA) |
| 1358 | if (offset != IDE_CS0_DATA_RW) |
| 1260 | 1359 | LOG(("%s:IDE cs0 write to %X = %08X, mem_mask=%d\n", machine().describe_context(), offset, data, mem_mask)); |
| 1261 | 1360 | // fprintf(stderr, "ide write %03x %02x mem_mask=%d\n", offset, data, size); |
| 1262 | | switch (offset) |
| 1361 | |
| 1362 | if (m_dmack) |
| 1263 | 1363 | { |
| 1264 | | /* write data */ |
| 1265 | | case IDE_BANK0_DATA: |
| 1266 | | if (m_status & IDE_STATUS_BUFFER_READY) |
| 1267 | | { |
| 1268 | | /* store the correct amount of data */ |
| 1269 | | m_buffer[m_buffer_offset++] = data; |
| 1270 | | if (mem_mask == 0xffff) |
| 1271 | | m_buffer[m_buffer_offset++] = data >> 8; |
| 1364 | logerror( "%s: write_cs0 %04x %04x %04x ignored (DMACK)\n", machine().describe_context(), offset, data, mem_mask ); |
| 1365 | } |
| 1366 | else if ((m_status & IDE_STATUS_BSY) && offset != IDE_CS0_COMMAND_W) |
| 1367 | { |
| 1368 | logerror( "%s: write_cs0 %04x %04x %04x ignored (BSY)\n", machine().describe_context(), offset, data, mem_mask ); |
| 1369 | } |
| 1370 | else if ((m_status & IDE_STATUS_DRQ) && offset != IDE_CS0_DATA_RW && offset != IDE_CS0_COMMAND_W) |
| 1371 | { |
| 1372 | logerror( "%s: write_cs0 %04x %04x %04x ignored (DRQ)\n", machine().describe_context(), offset, data, mem_mask ); |
| 1373 | } |
| 1374 | else |
| 1375 | { |
| 1376 | switch (offset) |
| 1377 | { |
| 1378 | /* write data */ |
| 1379 | case IDE_CS0_DATA_RW: |
| 1380 | if( device_selected() ) |
| 1381 | { |
| 1382 | if (!(m_status & IDE_STATUS_DRQ)) |
| 1383 | { |
| 1384 | logerror( "%s: write_cs0 %04x %04x %04x ignored (!DRQ)\n", machine().describe_context(), offset, data, mem_mask ); |
| 1385 | } |
| 1386 | else |
| 1387 | { |
| 1388 | /* store the correct amount of data */ |
| 1389 | m_buffer[m_buffer_offset++] = data; |
| 1390 | if (mem_mask == 0xffff) |
| 1391 | m_buffer[m_buffer_offset++] = data >> 8; |
| 1272 | 1392 | |
| 1273 | | /* if we're at the end of the buffer, handle it */ |
| 1274 | | if (m_buffer_offset >= IDE_DISK_SECTOR_SIZE) |
| 1275 | | { |
| 1276 | | LOG(("%s:IDE completed PIO write\n", machine().describe_context())); |
| 1277 | | write_buffer_full(); |
| 1393 | /* if we're at the end of the buffer, handle it */ |
| 1394 | if (m_buffer_offset >= IDE_DISK_SECTOR_SIZE) |
| 1395 | { |
| 1396 | LOG(("%s:IDE completed PIO write\n", machine().describe_context())); |
| 1397 | write_buffer_full(); |
| 1398 | } |
| 1399 | } |
| 1278 | 1400 | } |
| 1279 | | } |
| 1280 | | break; |
| 1401 | break; |
| 1281 | 1402 | |
| 1282 | | /* precompensation offset?? */ |
| 1283 | | case IDE_BANK0_ERROR: |
| 1284 | | m_precomp_offset = data; |
| 1285 | | break; |
| 1403 | case IDE_CS0_FEATURE_W: |
| 1404 | m_feature = data; |
| 1405 | break; |
| 1286 | 1406 | |
| 1287 | | /* sector count */ |
| 1288 | | case IDE_BANK0_SECTOR_COUNT: |
| 1289 | | m_sector_count = data ? data : 256; |
| 1290 | | break; |
| 1407 | /* sector count */ |
| 1408 | case IDE_CS0_SECTOR_COUNT_RW: |
| 1409 | m_sector_count = data ? data : 256; |
| 1410 | break; |
| 1291 | 1411 | |
| 1292 | | /* current sector */ |
| 1293 | | case IDE_BANK0_SECTOR_NUMBER: |
| 1294 | | m_cur_sector = data; |
| 1295 | | break; |
| 1412 | /* current sector */ |
| 1413 | case IDE_CS0_SECTOR_NUMBER_RW: |
| 1414 | m_cur_sector = data; |
| 1415 | break; |
| 1296 | 1416 | |
| 1297 | | /* current cylinder LSB */ |
| 1298 | | case IDE_BANK0_CYLINDER_LSB: |
| 1299 | | m_cur_cylinder = (m_cur_cylinder & 0xff00) | (data & 0xff); |
| 1300 | | break; |
| 1417 | /* current cylinder LSB */ |
| 1418 | case IDE_CS0_CYLINDER_LOW_RW: |
| 1419 | m_cur_cylinder = (m_cur_cylinder & 0xff00) | (data & 0xff); |
| 1420 | break; |
| 1301 | 1421 | |
| 1302 | | /* current cylinder MSB */ |
| 1303 | | case IDE_BANK0_CYLINDER_MSB: |
| 1304 | | m_cur_cylinder = (m_cur_cylinder & 0x00ff) | ((data & 0xff) << 8); |
| 1305 | | break; |
| 1422 | /* current cylinder MSB */ |
| 1423 | case IDE_CS0_CYLINDER_HIGH_RW: |
| 1424 | m_cur_cylinder = ((data << 8) & 0xff00) | (m_cur_cylinder & 0xff); |
| 1425 | break; |
| 1306 | 1426 | |
| 1307 | | /* current head */ |
| 1308 | | case IDE_BANK0_HEAD_NUMBER: |
| 1309 | | m_cur_head = data & 0x0f; |
| 1310 | | m_cur_head_reg = data; |
| 1311 | | // LBA mode = data & 0x40 |
| 1312 | | break; |
| 1427 | /* current head */ |
| 1428 | case IDE_CS0_DEVICE_HEAD_RW: |
| 1429 | // LBA mode = data & 0x40 |
| 1430 | m_cur_drive = (data & 0x10) >> 4; |
| 1431 | m_cur_head = data & 0x0f; |
| 1432 | m_cur_head_reg = data; |
| 1433 | break; |
| 1313 | 1434 | |
| 1314 | | /* command */ |
| 1315 | | case IDE_BANK0_STATUS_COMMAND: |
| 1316 | | handle_command(data); |
| 1317 | | break; |
| 1435 | /* command */ |
| 1436 | case IDE_CS0_COMMAND_W: |
| 1437 | m_command = data; |
| 1438 | |
| 1439 | if (device_selected() || m_command == IDE_COMMAND_DIAGNOSTIC) |
| 1440 | handle_command(); |
| 1441 | break; |
| 1442 | } |
| 1318 | 1443 | } |
| 1319 | 1444 | } |
| 1320 | 1445 | |
| 1321 | 1446 | WRITE16_MEMBER( ide_mass_storage_device::write_cs1 ) |
| 1322 | 1447 | { |
| 1323 | | if (m_cur_drive != m_csel) |
| 1324 | | return; |
| 1325 | | |
| 1326 | 1448 | /* logit */ |
| 1327 | 1449 | LOG(("%s:IDE cs1 write to %X = %08X, mem_mask=%d\n", machine().describe_context(), offset, data, mem_mask)); |
| 1328 | 1450 | |
| 1329 | | switch (offset) |
| 1451 | if (m_dmack) |
| 1330 | 1452 | { |
| 1331 | | /* adapter control */ |
| 1332 | | case IDE_BANK1_STATUS_CONTROL: |
| 1333 | | m_adapter_control = data; |
| 1453 | logerror( "%s: write_cs1 %04x %04x %04x ignored (DMACK)\n", machine().describe_context(), offset, data, mem_mask ); |
| 1454 | } |
| 1455 | else |
| 1456 | { |
| 1457 | switch (offset) |
| 1458 | { |
| 1459 | /* adapter control */ |
| 1460 | case IDE_CS1_DEVICE_CONTROL_W: |
| 1461 | m_device_control = data; |
| 1334 | 1462 | |
| 1335 | | /* handle controller reset */ |
| 1336 | | //if (data == 0x04) |
| 1337 | | if (data & 0x04) |
| 1338 | | { |
| 1339 | | m_status |= IDE_STATUS_BUSY; |
| 1340 | | m_status &= ~IDE_STATUS_DRIVE_READY; |
| 1341 | | m_reset_timer->adjust(attotime::from_msec(5)); |
| 1342 | | } |
| 1343 | | break; |
| 1463 | if (data & 0x02) |
| 1464 | { |
| 1465 | // nIEN |
| 1466 | logerror( "%s: write_cs1 %04x %04x %04x nIEN not supported\n", machine().describe_context(), offset, data, mem_mask ); |
| 1467 | } |
| 1468 | |
| 1469 | if (data & 0x04) |
| 1470 | { |
| 1471 | // SRST |
| 1472 | m_status |= IDE_STATUS_BSY; |
| 1473 | m_status &= ~IDE_STATUS_DRDY; |
| 1474 | m_reset_timer->adjust(attotime::from_msec(5)); |
| 1475 | } |
| 1476 | break; |
| 1477 | } |
| 1344 | 1478 | } |
| 1345 | 1479 | } |
| 1346 | 1480 | |
| r23712 | r23713 | |
| 1371 | 1505 | |
| 1372 | 1506 | void ide_hdd_device::device_reset() |
| 1373 | 1507 | { |
| 1374 | | ide_mass_storage_device::device_reset(); |
| 1375 | | |
| 1376 | 1508 | m_handle = subdevice<harddisk_image_device>("harddisk")->get_chd_file(); |
| 1377 | 1509 | |
| 1378 | 1510 | if (m_handle) |
| r23712 | r23713 | |
| 1385 | 1517 | m_disk = hard_disk_open(m_handle); |
| 1386 | 1518 | } |
| 1387 | 1519 | |
| 1520 | ide_mass_storage_device::device_reset(); |
| 1521 | |
| 1388 | 1522 | if (m_disk != NULL) |
| 1389 | 1523 | { |
| 1390 | 1524 | const hard_disk_info *hdinfo = hard_disk_get_info(m_disk); |