trunk/src/emu/machine/corvushd.c
| r31208 | r31209 | |
| 74 | 74 | device_t(mconfig, CORVUS_HDC, "Corvus Flat Cable HDC", tag, owner, clock, "corvus_hdc", __FILE__), |
| 75 | 75 | m_status(0), |
| 76 | 76 | m_prep_mode(false), |
| 77 | m_prep_drv(0), |
| 77 | 78 | m_sectors_per_track(0), |
| 78 | 79 | m_tracks_per_cylinder(0), |
| 79 | 80 | m_cylinders_per_drive(0), |
| r31208 | r31209 | |
| 761 | 762 | |
| 762 | 763 | |
| 763 | 764 | // |
| 764 | | // Corvus_Read_Firmware_Block |
| 765 | // corvus_enter_prep_mode |
| 765 | 766 | // |
| 767 | // Enter prep mode. In prep mode, only prep mode commands may be executed. |
| 768 | // |
| 769 | // The "prep block" is 512 bytes of Z80 machine code that the host sends to |
| 770 | // the controller. The controller will jump to this code after receiving it, |
| 771 | // and it is what actually implements prep mode commands. This HLE ignores |
| 772 | // the prep block from the host. |
| 773 | // |
| 774 | // Pass: |
| 775 | // drv: Corvus drive id (1..15) to be prepped |
| 776 | // prep_block: 512 bytes of Z80 machine code, contents ignored |
| 777 | // |
| 778 | // Returns: |
| 779 | // Status of command |
| 780 | // |
| 781 | UINT8 corvus_hdc_t::corvus_enter_prep_mode(UINT8 drv, UINT8 *prep_block) { |
| 782 | // check if drive is valid |
| 783 | if (!corvus_hdc_file(drv)) { |
| 784 | logerror("corvus_enter_prep_mode: Failure returned by corvus_hdc_file(%d)\n", drv); |
| 785 | return STAT_FATAL_ERR | STAT_DRIVE_NOT_ONLINE; |
| 786 | } |
| 787 | |
| 788 | LOG(("corvus_enter_prep_mode: Prep mode entered for drive %d, prep block follows:\n", drv)); |
| 789 | LOG_BUFFER(prep_block, 512); |
| 790 | |
| 791 | m_prep_mode = true; |
| 792 | m_prep_drv = drv; |
| 793 | return STAT_SUCCESS; |
| 794 | } |
| 795 | |
| 796 | |
| 797 | |
| 798 | // |
| 799 | // corvus_exit_prep_mode (Prep Mode Only) |
| 800 | // |
| 801 | // Exit from prep mode and return to normal command mode. |
| 802 | // |
| 803 | // Returns: |
| 804 | // Status of command (always success) |
| 805 | // |
| 806 | UINT8 corvus_hdc_t::corvus_exit_prep_mode() { |
| 807 | LOG(("corvus_exit_prep_mode: Prep mode exited\n")); |
| 808 | m_prep_mode = false; |
| 809 | m_prep_drv = 0; |
| 810 | return STAT_SUCCESS; |
| 811 | } |
| 812 | |
| 813 | |
| 814 | |
| 815 | // |
| 816 | // Corvus_Read_Firmware_Block (Prep Mode Only) |
| 817 | // |
| 766 | 818 | // Reads firmware information from the first cylinder of the drive |
| 767 | 819 | // |
| 768 | 820 | // Pass: |
| r31208 | r31209 | |
| 781 | 833 | LOG(("corvus_read_firmware_block: Reading firmware head: 0x%2.2x, sector: 0x%2.2x, relative_sector: 0x%2.2x\n", |
| 782 | 834 | head, sector, relative_sector)); |
| 783 | 835 | |
| 784 | | status = corvus_read_sector(1, relative_sector, m_buffer.read_512_response.data, 512); // TODO: Which drive should Prep Mode talk to ??? |
| 836 | status = corvus_read_sector(m_prep_drv, relative_sector, m_buffer.read_512_response.data, 512); |
| 785 | 837 | return status; |
| 786 | 838 | } |
| 787 | 839 | |
| 788 | 840 | |
| 789 | 841 | |
| 790 | 842 | // |
| 791 | | // Corvus_Write_Firmware_Block |
| 843 | // Corvus_Write_Firmware_Block (Prep Mode Only) |
| 792 | 844 | // |
| 793 | 845 | // Writes firmware information to the first cylinder of the drive |
| 794 | 846 | // |
| r31208 | r31209 | |
| 809 | 861 | LOG(("corvus_write_firmware_block: Writing firmware head: 0x%2.2x, sector: 0x%2.2x, relative_sector: 0x%2.2x\n", |
| 810 | 862 | head, sector, relative_sector)); |
| 811 | 863 | |
| 812 | | status = corvus_write_sector(1, relative_sector, buffer, 512); // TODO: Which drive should Prep Mode talk to ??? |
| 864 | status = corvus_write_sector(m_prep_drv, relative_sector, buffer, 512); |
| 813 | 865 | return status; |
| 814 | 866 | } |
| 815 | 867 | |
| 816 | 868 | |
| 817 | 869 | |
| 818 | 870 | // |
| 819 | | // Corvus_Format_Drive |
| 871 | // Corvus_Format_Drive (Prep Mode Only) |
| 820 | 872 | // |
| 821 | 873 | // Write the pattern provided across the entire disk |
| 822 | 874 | // |
| r31208 | r31209 | |
| 833 | 885 | UINT8 tbuffer[512]; |
| 834 | 886 | |
| 835 | 887 | // Set up m_tracks_per_cylinder and m_sectors_per_track |
| 836 | | corvus_hdc_file(1); |
| 888 | corvus_hdc_file(m_prep_drv); |
| 837 | 889 | |
| 838 | 890 | max_sector = m_sectors_per_track * m_tracks_per_cylinder * m_cylinders_per_drive; |
| 839 | 891 | |
| r31208 | r31209 | |
| 849 | 901 | LOG_BUFFER(pattern, 512); |
| 850 | 902 | |
| 851 | 903 | for(sector = 0; sector <= max_sector; sector++) { |
| 852 | | status = corvus_write_sector(1, sector, pattern, 512); |
| 904 | status = corvus_write_sector(m_prep_drv, sector, pattern, 512); |
| 853 | 905 | if(status != STAT_SUCCESS) { |
| 854 | 906 | logerror("corvus_format_drive: Error while formatting drive in corvus_write_sector--sector: 0x%5.5x, status: 0x%x2.2x\n", |
| 855 | 907 | sector, status); |
| r31208 | r31209 | |
| 995 | 1047 | corvus_get_drive_parameters(m_buffer.get_drive_parameters_command.drive); |
| 996 | 1048 | break; |
| 997 | 1049 | case PREP_MODE_SELECT: |
| 998 | | m_prep_mode = true; |
| 999 | | m_buffer.single_byte_response.status = STAT_SUCCESS; |
| 1050 | m_buffer.single_byte_response.status = |
| 1051 | corvus_enter_prep_mode(m_buffer.prep_mode_command.drive, |
| 1052 | m_buffer.prep_mode_command.prep_block); |
| 1000 | 1053 | break; |
| 1001 | 1054 | default: |
| 1002 | 1055 | m_xmit_bytes = 1; // Return a fatal status |
| r31208 | r31209 | |
| 1007 | 1060 | } else { // In Prep mode |
| 1008 | 1061 | switch(m_buffer.command.code) { |
| 1009 | 1062 | case PREP_MODE_SELECT: |
| 1010 | | m_prep_mode = true; |
| 1011 | | m_buffer.single_byte_response.status = STAT_SUCCESS; |
| 1063 | m_buffer.single_byte_response.status = |
| 1064 | corvus_enter_prep_mode(m_buffer.prep_mode_command.drive, |
| 1065 | m_buffer.prep_mode_command.prep_block); |
| 1012 | 1066 | break; |
| 1013 | 1067 | case PREP_RESET_DRIVE: |
| 1014 | | m_prep_mode = false; |
| 1015 | | m_buffer.single_byte_response.status = STAT_SUCCESS; |
| 1068 | m_buffer.single_byte_response.status = |
| 1069 | corvus_exit_prep_mode(); |
| 1016 | 1070 | break; |
| 1017 | 1071 | case PREP_READ_FIRMWARE: |
| 1018 | 1072 | m_buffer.drive_param_response.status = |
trunk/src/emu/machine/corvushd.h
| r31208 | r31209 | |
| 206 | 206 | }; |
| 207 | 207 | |
| 208 | 208 | UINT8 m_status; // Controller status byte (DIRECTION + BUSY/READY) |
| 209 | // Prep mode |
| 209 | 210 | bool m_prep_mode; // Whether the controller is in Prep Mode or not |
| 211 | UINT8 m_prep_drv; // If in prep mode, Corvus drive id (1..15) being prepped |
| 210 | 212 | // Physical drive info |
| 211 | 213 | UINT8 m_sectors_per_track; // Number of sectors per track for this drive |
| 212 | 214 | UINT8 m_tracks_per_cylinder;// Number of tracks per cylinder (heads) |
| r31208 | r31209 | |
| 400 | 402 | UINT8 boot_block; // Which boot block to read (0-7) |
| 401 | 403 | } old_boot_command; |
| 402 | 404 | // |
| 405 | // Put drive into prep mode command (0x11) |
| 406 | // |
| 407 | struct { |
| 408 | UINT8 code; // Command code |
| 409 | UINT8 drive; // Drive number (starts at 1) |
| 410 | UINT8 prep_block[512]; // Z80 machine code payload |
| 411 | } prep_mode_command; |
| 412 | // |
| 403 | 413 | // Read Firmware command (Prep Mode 0x32) |
| 404 | 414 | // |
| 405 | 415 | struct { |
| r31208 | r31209 | |
| 499 | 509 | UINT8 corvus_init_semaphore_table(); |
| 500 | 510 | UINT8 corvus_get_drive_parameters(UINT8 drv); |
| 501 | 511 | UINT8 corvus_read_boot_block(UINT8 block); |
| 512 | UINT8 corvus_enter_prep_mode(UINT8 drv, UINT8 *prep_block); |
| 513 | UINT8 corvus_exit_prep_mode(); |
| 502 | 514 | UINT8 corvus_read_firmware_block(UINT8 head, UINT8 sector); |
| 503 | 515 | UINT8 corvus_write_firmware_block(UINT8 head, UINT8 sector, UINT8 *buffer); |
| 504 | 516 | UINT8 corvus_format_drive(UINT8 *pattern, UINT16 len); |