trunk/src/emu/machine/scsidev.c
| r17965 | r17966 | |
| 19 | 19 | save_item( NAME( phase ) ); |
| 20 | 20 | } |
| 21 | 21 | |
| 22 | #define SCSI_SENSE_SIZE 4 |
| 23 | |
| 22 | 24 | void scsidev_device::ExecCommand( int *transferLength ) |
| 23 | 25 | { |
| 24 | 26 | UINT8 *command; |
| r17965 | r17966 | |
| 27 | 29 | |
| 28 | 30 | switch( command[ 0 ] ) |
| 29 | 31 | { |
| 30 | | case 0x00: // TEST UNIT READY |
| 31 | | SetPhase( SCSI_PHASE_STATUS ); |
| 32 | | *transferLength = 0; |
| 33 | | break; |
| 32 | case SCSI_CMD_TEST_UNIT_READY: |
| 33 | SetPhase( SCSI_PHASE_STATUS ); |
| 34 | *transferLength = 0; |
| 35 | break; |
| 34 | 36 | |
| 35 | | default: |
| 36 | | logerror( "%s: SCSIDEV unknown command %02x\n", machine().describe_context(), command[ 0 ] ); |
| 37 | | *transferLength = 0; |
| 38 | | break; |
| 37 | case SCSI_CMD_RECALIBRATE: |
| 38 | SetPhase( SCSI_PHASE_STATUS ); |
| 39 | *transferLength = 0; |
| 40 | break; |
| 41 | |
| 42 | case SCSI_CMD_REQUEST_SENSE: |
| 43 | SetPhase( SCSI_PHASE_DATAOUT ); |
| 44 | *transferLength = SCSI_SENSE_SIZE; |
| 45 | break; |
| 46 | |
| 47 | case SCSI_CMD_SEND_DIAGNOSTIC: |
| 48 | SetPhase( SCSI_PHASE_DATAOUT ); |
| 49 | *transferLength = ( command[ 3 ] << 8 ) + command[ 4 ]; |
| 50 | break; |
| 51 | |
| 52 | default: |
| 53 | logerror( "%s: SCSIDEV unknown command %02x\n", machine().describe_context(), command[ 0 ] ); |
| 54 | *transferLength = 0; |
| 55 | break; |
| 39 | 56 | } |
| 40 | 57 | } |
| 41 | 58 | |
| r17965 | r17966 | |
| 47 | 64 | |
| 48 | 65 | switch( command[ 0 ] ) |
| 49 | 66 | { |
| 50 | | default: |
| 51 | | logerror( "%s: SCSIDEV unknown read %02x\n", machine().describe_context(), command[ 0 ] ); |
| 52 | | break; |
| 67 | case SCSI_CMD_REQUEST_SENSE: |
| 68 | data[ 0 ] = SCSI_SENSE_NO_SENSE; |
| 69 | data[ 1 ] = 0x00; |
| 70 | data[ 2 ] = 0x00; |
| 71 | data[ 3 ] = 0x00; |
| 72 | break; |
| 73 | default: |
| 74 | logerror( "%s: SCSIDEV unknown read %02x\n", machine().describe_context(), command[ 0 ] ); |
| 75 | break; |
| 53 | 76 | } |
| 54 | 77 | } |
| 55 | 78 | |
| r17965 | r17966 | |
| 61 | 84 | |
| 62 | 85 | switch( command[ 0 ] ) |
| 63 | 86 | { |
| 64 | | default: |
| 65 | | logerror( "%s: SCSIDEV unknown write %02x\n", machine().describe_context(), command[ 0 ] ); |
| 66 | | break; |
| 87 | case SCSI_CMD_SEND_DIAGNOSTIC: |
| 88 | break; |
| 89 | |
| 90 | default: |
| 91 | logerror( "%s: SCSIDEV unknown write %02x\n", machine().describe_context(), command[ 0 ] ); |
| 92 | break; |
| 67 | 93 | } |
| 68 | 94 | } |
| 69 | 95 | |
trunk/src/emu/machine/scsidev.h
| r17965 | r17966 | |
| 49 | 49 | #define SCSI_PHASE_MESSAGE_OUT ( 6 ) |
| 50 | 50 | #define SCSI_PHASE_MESSAGE_IN ( 7 ) |
| 51 | 51 | |
| 52 | #define SCSI_CMD_TEST_UNIT_READY ( 0x00 ) |
| 53 | #define SCSI_CMD_RECALIBRATE ( 0x01 ) |
| 54 | #define SCSI_CMD_REQUEST_SENSE ( 0x03 ) |
| 55 | #define SCSI_CMD_MODE_SELECT ( 0x15 ) |
| 56 | #define SCSI_CMD_SEND_DIAGNOSTIC ( 0x1d ) |
| 57 | |
| 58 | // |
| 59 | // Status / Sense data taken from Adaptec ACB40x0 documentation. |
| 60 | // |
| 61 | |
| 62 | #define SCSI_STATUS_OK 0x00 |
| 63 | #define SCSI_STATUS_CHECK 0x02 |
| 64 | #define SCSI_STATUS_EQUAL 0x04 |
| 65 | #define SCSI_STATUS_BUSY 0x08 |
| 66 | |
| 67 | #define SCSI_SENSE_ADDR_VALID 0x80 |
| 68 | #define SCSI_SENSE_NO_SENSE 0x00 |
| 69 | #define SCSI_SENSE_NO_INDEX 0x01 |
| 70 | #define SCSI_SENSE_SEEK_NOT_COMP 0x02 |
| 71 | #define SCSI_SENSE_WRITE_FAULT 0x03 |
| 72 | #define SCSI_SENSE_DRIVE_NOT_READY 0x04 |
| 73 | #define SCSI_SENSE_NO_TRACK0 0x06 |
| 74 | #define SCSI_SENSE_ID_CRC_ERROR 0x10 |
| 75 | #define SCSI_SENSE_UNCORRECTABLE 0x11 |
| 76 | #define SCSI_SENSE_ADDRESS_NF 0x12 |
| 77 | #define SCSI_SENSE_RECORD_NOT_FOUND 0x14 |
| 78 | #define SCSI_SENSE_SEEK_ERROR 0x15 |
| 79 | #define SCSI_SENSE_DATA_CHECK_RETRY 0x18 |
| 80 | #define SCSI_SENSE_ECC_VERIFY 0x19 |
| 81 | #define SCSI_SENSE_INTERLEAVE_ERROR 0x1A |
| 82 | #define SCSI_SENSE_UNFORMATTED 0x1C |
| 83 | #define SCSI_SENSE_ILLEGAL_COMMAND 0x20 |
| 84 | #define SCSI_SENSE_ILLEGAL_ADDRESS 0x21 |
| 85 | #define SCSI_SENSE_VOLUME_OVERFLOW 0x23 |
| 86 | #define SCSI_SENSE_BAD_ARGUMENT 0x24 |
| 87 | #define SCSI_SENSE_INVALID_LUN 0x25 |
| 88 | #define SCSI_SENSE_CART_CHANGED 0x28 |
| 89 | #define SCSI_SENSE_ERROR_OVERFLOW 0x2C |
| 90 | |
| 52 | 91 | // SCSI IDs |
| 53 | 92 | enum |
| 54 | 93 | { |
trunk/src/emu/machine/scsibus.c
| r17965 | r17966 | |
| 105 | 105 | break; |
| 106 | 106 | |
| 107 | 107 | case SCSI_PHASE_STATUS: |
| 108 | | result=status; // return command status |
| 108 | result=SCSI_STATUS_OK; // return command status |
| 109 | 109 | break; |
| 110 | 110 | |
| 111 | 111 | case SCSI_PHASE_MESSAGE_IN: |
| r17965 | r17966 | |
| 264 | 264 | //is_linked=command[cmd_idx-1] & 0x01; |
| 265 | 265 | is_linked=0; |
| 266 | 266 | |
| 267 | | // Assume command will succeed, if not set sytatus below. |
| 268 | | if (command[0]!=SCSI_CMD_REQUEST_SENSE) |
| 269 | | SET_STATUS_SENSE(SCSI_STATUS_OK,SCSI_SENSE_NO_SENSE); |
| 270 | | |
| 271 | 267 | // Check for locally executed commands, and if found execute them |
| 272 | 268 | switch (command[0]) |
| 273 | 269 | { |
| 274 | | // Recalibrate drive |
| 275 | | case SCSI_CMD_RECALIBRATE: |
| 276 | | LOG(1,"SCSIBUS: Recalibrate drive\n"); |
| 277 | | command_local=1; |
| 278 | | xfer_count=0; |
| 279 | | data_last=xfer_count; |
| 280 | | bytes_left=0; |
| 281 | | devices[last_id]->SetPhase(SCSI_PHASE_STATUS); |
| 282 | | break; |
| 283 | | |
| 284 | | // Request sense, return previous error codes |
| 285 | | case SCSI_CMD_REQUEST_SENSE: |
| 286 | | LOG(1,"SCSIBUS: request_sense\n"); |
| 287 | | command_local=1; |
| 288 | | xfer_count=SCSI_SENSE_SIZE; |
| 289 | | data_last=xfer_count; |
| 290 | | bytes_left=0; |
| 291 | | buffer[0]=sense; |
| 292 | | buffer[1]=0x00; |
| 293 | | buffer[2]=0x00; |
| 294 | | buffer[3]=0x00; |
| 295 | | SET_STATUS_SENSE(SCSI_STATUS_OK,SCSI_SENSE_NO_SENSE); |
| 296 | | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
| 297 | | break; |
| 298 | | |
| 299 | 270 | // Format unit |
| 300 | 271 | case SCSI_CMD_FORMAT_UNIT: |
| 301 | 272 | LOG(1,"SCSIBUS: format unit command[1]=%02X & 0x10\n",(command[1] & 0x10)); |
| r17965 | r17966 | |
| 311 | 282 | dataout_timer->adjust(attotime::from_seconds(FORMAT_UNIT_TIMEOUT)); |
| 312 | 283 | break; |
| 313 | 284 | |
| 314 | | // Send diagnostic info |
| 315 | | case SCSI_CMD_SEND_DIAGNOSTIC: |
| 316 | | LOG(1,"SCSIBUS: send_diagnostic\n"); |
| 317 | | command_local=1; |
| 318 | | xfer_count=(command[3]<<8)+command[4]; |
| 319 | | data_last=xfer_count; |
| 320 | | bytes_left=0; |
| 321 | | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
| 322 | | break; |
| 323 | | |
| 324 | 285 | case SCSI_CMD_SEARCH_DATA_EQUAL: |
| 325 | 286 | LOG(1,"SCSIBUS: Search_data_equaln"); |
| 326 | 287 | command_local=1; |
trunk/src/emu/machine/scsibus.h
| r17965 | r17966 | |
| 45 | 45 | #define ADAPTEC_BUF_SIZE 1024 |
| 46 | 46 | |
| 47 | 47 | // scsidev |
| 48 | | #define SCSI_CMD_RECALIBRATE 0x01 |
| 49 | | #define SCSI_CMD_REQUEST_SENSE 0x03 |
| 50 | | #define SCSI_CMD_MODE_SELECT 0x15 |
| 51 | | #define SCSI_CMD_SEND_DIAGNOSTIC 0x1D |
| 52 | | #define SCSI_CMD_BUFFER_WRITE 0x3B |
| 53 | | #define SCSI_CMD_BUFFER_READ 0x3C |
| 48 | #define SCSI_CMD_BUFFER_WRITE ( 0x3b ) |
| 49 | #define SCSI_CMD_BUFFER_READ ( 0x3c ) |
| 54 | 50 | |
| 55 | 51 | // scsihd |
| 56 | 52 | #define SCSI_CMD_FORMAT_UNIT 0x04 |
| r17965 | r17966 | |
| 61 | 57 | #define IS_COMMAND(cmd) (command[0]==cmd) |
| 62 | 58 | #define IS_READ_COMMAND() ((command[0]==0x08) || (command[0]==0x28) || (command[0]==0xa8)) |
| 63 | 59 | #define IS_WRITE_COMMAND() ((command[0]==0x0a) || (command[0]==0x2a)) |
| 64 | | #define SET_STATUS_SENSE(stat,sen) { status=(stat); sense=(sen); } |
| 65 | 60 | |
| 66 | 61 | #define FORMAT_UNIT_TIMEOUT 5 |
| 67 | 62 | |
| 68 | | // |
| 69 | | // Status / Sense data taken from Adaptec ACB40x0 documentation. |
| 70 | | // |
| 71 | | |
| 72 | | #define SCSI_STATUS_OK 0x00 |
| 73 | | #define SCSI_STATUS_CHECK 0x02 |
| 74 | | #define SCSI_STATUS_EQUAL 0x04 |
| 75 | | #define SCSI_STATUS_BUSY 0x08 |
| 76 | | |
| 77 | | #define SCSI_SENSE_ADDR_VALID 0x80 |
| 78 | | #define SCSI_SENSE_NO_SENSE 0x00 |
| 79 | | #define SCSI_SENSE_NO_INDEX 0x01 |
| 80 | | #define SCSI_SENSE_SEEK_NOT_COMP 0x02 |
| 81 | | #define SCSI_SENSE_WRITE_FAULT 0x03 |
| 82 | | #define SCSI_SENSE_DRIVE_NOT_READY 0x04 |
| 83 | | #define SCSI_SENSE_NO_TRACK0 0x06 |
| 84 | | #define SCSI_SENSE_ID_CRC_ERROR 0x10 |
| 85 | | #define SCSI_SENSE_UNCORRECTABLE 0x11 |
| 86 | | #define SCSI_SENSE_ADDRESS_NF 0x12 |
| 87 | | #define SCSI_SENSE_RECORD_NOT_FOUND 0x14 |
| 88 | | #define SCSI_SENSE_SEEK_ERROR 0x15 |
| 89 | | #define SCSI_SENSE_DATA_CHECK_RETRY 0x18 |
| 90 | | #define SCSI_SENSE_ECC_VERIFY 0x19 |
| 91 | | #define SCSI_SENSE_INTERLEAVE_ERROR 0x1A |
| 92 | | #define SCSI_SENSE_UNFORMATTED 0x1C |
| 93 | | #define SCSI_SENSE_ILLEGAL_COMMAND 0x20 |
| 94 | | #define SCSI_SENSE_ILLEGAL_ADDRESS 0x21 |
| 95 | | #define SCSI_SENSE_VOLUME_OVERFLOW 0x23 |
| 96 | | #define SCSI_SENSE_BAD_ARGUMENT 0x24 |
| 97 | | #define SCSI_SENSE_INVALID_LUN 0x25 |
| 98 | | #define SCSI_SENSE_CART_CHANGED 0x28 |
| 99 | | #define SCSI_SENSE_ERROR_OVERFLOW 0x2C |
| 100 | | |
| 101 | | #define SCSI_SENSE_SIZE 4 |
| 102 | | |
| 103 | 63 | struct adaptec_sense_t |
| 104 | 64 | { |
| 105 | 65 | // parameter list |
| r17965 | r17966 | |
| 197 | 157 | UINT8 cmd_idx; |
| 198 | 158 | UINT8 is_linked; |
| 199 | 159 | |
| 200 | | UINT8 status; |
| 201 | | UINT8 sense; |
| 202 | | |
| 203 | 160 | UINT8 buffer[ADAPTEC_BUF_SIZE]; |
| 204 | 161 | UINT16 data_idx; |
| 205 | 162 | int xfer_count; |