trunk/src/mess/machine/smc92x4.c
| r18988 | r18989 | |
| 25 | 25 | /* |
| 26 | 26 | Definition of bits in the status register |
| 27 | 27 | */ |
| 28 | | #define ST_INTPEND 0x80 /* interrupt pending */ |
| 29 | | #define ST_DMAREQ 0x40 /* DMA request */ |
| 30 | | #define ST_DONE 0x20 /* command done */ |
| 31 | | #define ST_TERMCOD 0x18 /* termination code (see below) */ |
| 32 | | #define ST_RDYCHNG 0x04 /* ready change */ |
| 33 | | #define ST_OVRUN 0x02 /* overrun/underrun */ |
| 34 | | #define ST_BADSECT 0x01 /* bad sector */ |
| 28 | #define ST_INTPEND 0x80 /* interrupt pending */ |
| 29 | #define ST_DMAREQ 0x40 /* DMA request */ |
| 30 | #define ST_DONE 0x20 /* command done */ |
| 31 | #define ST_TERMCOD 0x18 /* termination code (see below) */ |
| 32 | #define ST_RDYCHNG 0x04 /* ready change */ |
| 33 | #define ST_OVRUN 0x02 /* overrun/underrun */ |
| 34 | #define ST_BADSECT 0x01 /* bad sector */ |
| 35 | 35 | |
| 36 | 36 | /* |
| 37 | 37 | Definition of the termination codes (INT_STATUS) |
| 38 | 38 | */ |
| 39 | | #define ST_TC_SUCCESS 0x00 /* Successful completion */ |
| 40 | | #define ST_TC_RDIDERR 0x08 /* Error in READ-ID sequence */ |
| 41 | | #define ST_TC_SEEKERR 0x10 /* Error in SEEK sequence */ |
| 42 | | #define ST_TC_DATAERR 0x18 /* Error in DATA-TRANSFER seq. */ |
| 39 | #define ST_TC_SUCCESS 0x00 /* Successful completion */ |
| 40 | #define ST_TC_RDIDERR 0x08 /* Error in READ-ID sequence */ |
| 41 | #define ST_TC_SEEKERR 0x10 /* Error in SEEK sequence */ |
| 42 | #define ST_TC_DATAERR 0x18 /* Error in DATA-TRANSFER seq. */ |
| 43 | 43 | |
| 44 | 44 | |
| 45 | 45 | /* |
| 46 | 46 | Definition of bits in the Termination-Conditions register |
| 47 | 47 | */ |
| 48 | | #define TC_CRCPRE 0x80 /* CRC register preset, must be 1 */ |
| 49 | | #define TC_UNUSED 0x40 /* bit 6 is not used and must be 0 */ |
| 50 | | #define TC_INTDONE 0x20 /* interrupt on done */ |
| 51 | | #define TC_TDELDAT 0x10 /* terminate on deleted data */ |
| 52 | | #define TC_TDSTAT3 0x08 /* terminate on drive status 3 change */ |
| 53 | | #define TC_TWPROT 0x04 /* terminate on write-protect (FDD only) */ |
| 54 | | #define TC_INTRDCH 0x02 /* interrupt on ready change (FDD only) */ |
| 55 | | #define TC_TWRFLT 0x01 /* interrupt on write-fault (HDD only) */ |
| 48 | #define TC_CRCPRE 0x80 /* CRC register preset, must be 1 */ |
| 49 | #define TC_UNUSED 0x40 /* bit 6 is not used and must be 0 */ |
| 50 | #define TC_INTDONE 0x20 /* interrupt on done */ |
| 51 | #define TC_TDELDAT 0x10 /* terminate on deleted data */ |
| 52 | #define TC_TDSTAT3 0x08 /* terminate on drive status 3 change */ |
| 53 | #define TC_TWPROT 0x04 /* terminate on write-protect (FDD only) */ |
| 54 | #define TC_INTRDCH 0x02 /* interrupt on ready change (FDD only) */ |
| 55 | #define TC_TWRFLT 0x01 /* interrupt on write-fault (HDD only) */ |
| 56 | 56 | |
| 57 | 57 | /* |
| 58 | 58 | Definition of bits in the Chip-Status register |
| 59 | 59 | */ |
| 60 | | #define CS_RETREQ 0x80 /* retry required */ |
| 61 | | #define CS_ECCATT 0x40 /* ECC correction attempted */ |
| 62 | | #define CS_CRCERR 0x20 /* ECC/CRC error */ |
| 63 | | #define CS_DELDATA 0x10 /* deleted data mark */ |
| 64 | | #define CS_SYNCERR 0x08 /* synchronization error */ |
| 65 | | #define CS_COMPERR 0x04 /* compare error */ |
| 66 | | #define CS_PRESDRV 0x03 /* present drive selected */ |
| 60 | #define CS_RETREQ 0x80 /* retry required */ |
| 61 | #define CS_ECCATT 0x40 /* ECC correction attempted */ |
| 62 | #define CS_CRCERR 0x20 /* ECC/CRC error */ |
| 63 | #define CS_DELDATA 0x10 /* deleted data mark */ |
| 64 | #define CS_SYNCERR 0x08 /* synchronization error */ |
| 65 | #define CS_COMPERR 0x04 /* compare error */ |
| 66 | #define CS_PRESDRV 0x03 /* present drive selected */ |
| 67 | 67 | |
| 68 | 68 | /* |
| 69 | 69 | Definition of bits in the Mode register |
| 70 | 70 | */ |
| 71 | | #define MO_TYPE 0x80 /* Hard disk (1) or floppy (0) */ |
| 72 | | #define MO_CRCECC 0x60 /* Values for CRC/ECC handling */ |
| 73 | | #define MO_DENSITY 0x10 /* FM = 1; MFM = 0 */ |
| 74 | | #define MO_UNUSED 0x08 /* Unused, 0 */ |
| 75 | | #define MO_STEPRATE 0x07 /* Step rates */ |
| 71 | #define MO_TYPE 0x80 /* Hard disk (1) or floppy (0) */ |
| 72 | #define MO_CRCECC 0x60 /* Values for CRC/ECC handling */ |
| 73 | #define MO_DENSITY 0x10 /* FM = 1; MFM = 0 */ |
| 74 | #define MO_UNUSED 0x08 /* Unused, 0 */ |
| 75 | #define MO_STEPRATE 0x07 /* Step rates */ |
| 76 | 76 | |
| 77 | 77 | /* |
| 78 | 78 | hfdc state structure |
| r18988 | r18989 | |
| 108 | 108 | ab0 desired head 0 |
| 109 | 109 | */ |
| 110 | 110 | |
| 111 | | #define OUT1_DRVSEL3 0x80 |
| 112 | | #define OUT1_DRVSEL2 0x40 |
| 113 | | #define OUT1_DRVSEL1 0x20 |
| 114 | | #define OUT1_DRVSEL0 0x10 |
| 115 | | #define OUT2_DRVSEL3_ 0x80 |
| 116 | | #define OUT2_REDWRT 0x40 |
| 117 | | #define OUT2_STEPDIR 0x20 |
| 118 | | #define OUT2_STEPPULSE 0x10 |
| 119 | | #define OUT2_HEADSEL3 0x08 |
| 120 | | #define OUT2_HEADSEL2 0x04 |
| 121 | | #define OUT2_HEADSEL1 0x02 |
| 122 | | #define OUT2_HEADSEL0 0x01 |
| 111 | #define OUT1_DRVSEL3 0x80 |
| 112 | #define OUT1_DRVSEL2 0x40 |
| 113 | #define OUT1_DRVSEL1 0x20 |
| 114 | #define OUT1_DRVSEL0 0x10 |
| 115 | #define OUT2_DRVSEL3_ 0x80 |
| 116 | #define OUT2_REDWRT 0x40 |
| 117 | #define OUT2_STEPDIR 0x20 |
| 118 | #define OUT2_STEPPULSE 0x10 |
| 119 | #define OUT2_HEADSEL3 0x08 |
| 120 | #define OUT2_HEADSEL2 0x04 |
| 121 | #define OUT2_HEADSEL1 0x02 |
| 122 | #define OUT2_HEADSEL0 0x01 |
| 123 | 123 | |
| 124 | | #define DRIVE_TYPE 0x03 |
| 125 | | #define TYPE_AT 0x00 |
| 126 | | #define TYPE_FLOPPY 0x02 /* for testing on any floppy type */ |
| 127 | | #define TYPE_FLOPPY8 0x02 |
| 128 | | #define TYPE_FLOPPY5 0x03 |
| 124 | #define DRIVE_TYPE 0x03 |
| 125 | #define TYPE_AT 0x00 |
| 126 | #define TYPE_FLOPPY 0x02 /* for testing on any floppy type */ |
| 127 | #define TYPE_FLOPPY8 0x02 |
| 128 | #define TYPE_FLOPPY5 0x03 |
| 129 | 129 | |
| 130 | 130 | #define MAX_SECTOR_LEN 256 |
| 131 | 131 | |
| 132 | 132 | #define FORMAT_LONG false |
| 133 | 133 | |
| 134 | | #define ERROR 0 |
| 135 | | #define DONE 1 |
| 136 | | #define AGAIN 2 |
| 137 | | #define UNDEF 3 |
| 134 | #define ERROR 0 |
| 135 | #define DONE 1 |
| 136 | #define AGAIN 2 |
| 137 | #define UNDEF 3 |
| 138 | 138 | |
| 139 | 139 | enum |
| 140 | 140 | { |
| r18988 | r18989 | |
| 149 | 149 | Step rates in microseconds for MFM. This is set in the mode register, |
| 150 | 150 | bits 0-2. Single density doubles all values. |
| 151 | 151 | */ |
| 152 | | static const int step_hd[] = { 22, 50, 100, 200, 400, 800, 1600, 3200 }; |
| 153 | | static const int step_flop8[] = { 218, 500, 1000, 2000, 4000, 8000, 16000, 32000 }; |
| 154 | | static const int step_flop5[] = { 436, 1000, 2000, 4000, 8000, 16000, 32000, 64000 }; |
| 152 | static const int step_hd[] = { 22, 50, 100, 200, 400, 800, 1600, 3200 }; |
| 153 | static const int step_flop8[] = { 218, 500, 1000, 2000, 4000, 8000, 16000, 32000 }; |
| 154 | static const int step_flop5[] = { 436, 1000, 2000, 4000, 8000, 16000, 32000, 64000 }; |
| 155 | 155 | |
| 156 | 156 | /* |
| 157 | 157 | 0.2 seconds for a revolution (300 rpm), +50% average waiting for index |
| r18988 | r18989 | |
| 171 | 171 | DMA15_8=1, |
| 172 | 172 | DMA23_16=2, |
| 173 | 173 | DESIRED_SECTOR=3, |
| 174 | | DESIRED_HEAD=4, CURRENT_HEAD=4, |
| 175 | | DESIRED_CYLINDER=5, CURRENT_CYLINDER=5, |
| 176 | | SECTOR_COUNT=6, CURRENT_IDENT=6, |
| 177 | | RETRY_COUNT=7, TEMP_STORAGE2=7, |
| 178 | | MODE=8, CHIP_STATUS=8, |
| 179 | | INT_COMM_TERM=9, DRIVE_STATUS=9, |
| 180 | | DATA_DELAY=10, DATA=10, |
| 181 | | COMMAND=11, INT_STATUS=11 |
| 174 | DESIRED_HEAD=4, CURRENT_HEAD=4, |
| 175 | DESIRED_CYLINDER=5, CURRENT_CYLINDER=5, |
| 176 | SECTOR_COUNT=6, CURRENT_IDENT=6, |
| 177 | RETRY_COUNT=7, TEMP_STORAGE2=7, |
| 178 | MODE=8, CHIP_STATUS=8, |
| 179 | INT_COMM_TERM=9, DRIVE_STATUS=9, |
| 180 | DATA_DELAY=10, DATA=10, |
| 181 | COMMAND=11, INT_STATUS=11 |
| 182 | 182 | }; |
| 183 | 183 | |
| 184 | | #define TRKSIZE_DD 6144 |
| 185 | | #define TRKSIZE_SD 3172 |
| 184 | #define TRKSIZE_DD 6144 |
| 185 | #define TRKSIZE_SD 3172 |
| 186 | 186 | |
| 187 | 187 | #define VERBOSE 1 |
| 188 | 188 | #define LOG logerror |
| r18988 | r18989 | |
| 444 | 444 | sync_status_in(); |
| 445 | 445 | break; |
| 446 | 446 | case WRITE_TIMER: |
| 447 | | deldata = m_command & 0x10; |
| 447 | // The specification is contraditory here :-( |
| 448 | // For formatting, bit 0x10 = 1 means normal, 0 means deleted |
| 449 | // while for writing sectors it is the opposite?! |
| 450 | // We believe the existing drivers which all set the bit for normal writing. |
| 451 | deldata = 0x10 - (m_command & 0x10); |
| 448 | 452 | redcur = m_command & 0x08; |
| 449 | 453 | precomp = m_command & 0x07; |
| 450 | 454 | write_long = ((m_register_w[MODE]& MO_CRCECC)==0x40); |
| r18988 | r18989 | |
| 866 | 870 | |
| 867 | 871 | if (m_selected_drive_type & TYPE_FLOPPY) |
| 868 | 872 | { |
| 873 | if (VERBOSE>4) LOG("smc92x4 info: write sector CHS=(%d,%d,%d)\n", id.C, id.H, id.R); |
| 869 | 874 | floppy_drive_write_sector_data(m_drive, id.H, sector_data_id, (char *) buf, sector_len, false); |
| 870 | 875 | } |
| 871 | 876 | else |
| r18988 | r18989 | |
| 892 | 897 | if (m_register_w[SECTOR_COUNT] == 0) return; |
| 893 | 898 | |
| 894 | 899 | /* Else this is a multi-sector operation. */ |
| 895 | | m_register_w[DESIRED_SECTOR] = m_register_r[DESIRED_SECTOR] = (m_register_w[DESIRED_SECTOR]+1) & 0xff; |
| 900 | m_register_w[DESIRED_SECTOR] = m_register_r[DESIRED_SECTOR] = (m_register_w[DESIRED_SECTOR]+1) & 0xff; |
| 896 | 901 | |
| 897 | 902 | /* Reinitialize retry count. */ |
| 898 | 903 | m_register_w[RETRY_COUNT] = retry; |
| r18988 | r18989 | |
| 1948 | 1953 | m_register_pointer++; |
| 1949 | 1954 | } |
| 1950 | 1955 | else |
| 1951 | | process_command(data); // command register |
| 1956 | process_command(data); // command register |
| 1952 | 1957 | } |
| 1953 | 1958 | |
| 1954 | 1959 | |