-/*
+k/*
Skelton for retropc emulator
Author : Takeda.Toshiya
#ifdef _SCSI_DEBUG_LOG
this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Read Mode Select 6-byte\n"), scsi_id);
#endif
- read_mode = (command[4] != 0);
- break;
+ // start position
+// position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
+// position *= physical_block_size();
+ position = 0;
+ // transfer length
+// remain = command[4];// * logical_block_size();
+ remain = 11;
+ if(remain != 0) {
+ // clear data buffer
+ buffer->clear();
+ // change to data in phase
+ set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time);
+ } else {
+ // transfer length is zero, change to status phase
+ set_dat(SCSI_STATUS_GOOD);
+ set_sense_code(SCSI_SENSE_NOSENSE);
+ set_phase_delay(SCSI_PHASE_STATUS, 10.0);
+ }
+ return;
case 0xd8:
#ifdef _SCSI_DEBUG_LOG
case 0x00: /* Get first and last track numbers */
buffer->write(TO_BCD(1));
buffer->write(TO_BCD(track_num));
+ // PC-8801 CD BIOS invites 4 bytes ?
+ buffer->write(0);
+ buffer->write(0);
break;
case 0x01: /* Get total disk size in MSF format */
{
buffer->write((msf >> 16) & 0xff);
buffer->write((msf >> 8) & 0xff);
buffer->write((msf >> 0) & 0xff);
+ // PC-8801 CD BIOS invites 4 bytes ?
+ buffer->write(0);
}
break;
case 0x02: /* Get track information */
}
}
while(length > 0) {
- uint8_t tmp_buffer[SCSI_BUFFER_SIZE];
- int tmp_length = min(length, (int)sizeof(tmp_buffer));
+ uint8_t tmp_buffer[2352];
+// int tmp_length = min(length, (int)sizeof(tmp_buffer));
+ int tmp_length = 2352 - offset;
if(fio_img->Fread(tmp_buffer, tmp_length, 1) != 1) {
#ifdef _SCSI_DEBUG_LOG
set_sense_code(SCSI_SENSE_ILLGLBLKADDR); //SCSI_SENSE_NORECORDFND
return false;
}
- for(int i = 0; i < tmp_length && length > 0; i++) {
- if(offset >= 16 && offset < 16 + 2048) {
+ for(int i = 0; i < tmp_length; i++) {
+ if(offset >= 16 && offset < 16 + logical_block_size()) {
int value = tmp_buffer[i];
buffer->write(value);
length--;
return true;
}
+bool SCSI_CDROM::write_buffer(int length)
+{
+ for(int i = 0; i < length; i++) {
+ int value = buffer->read();
+ if(command[0] == SCSI_CMD_MODE_SEL6) {
+ if(i == 4) {
+ #ifdef _SCSI_DEBUG_LOG
+ this->out_debug_log(_T("[SCSI_DEV:ID=%d] NEC Read Mode = %02X\n"), scsi_id, value);
+ #endif
+ read_mode = (value != 0);
+ } else if(i == 10) {
+ #ifdef _SCSI_DEBUG_LOG
+ this->out_debug_log(_T("[SCSI_DEV:ID=%d] NEC Retry Count = %02X\n"), scsi_id, value);
+ #endif
+ }
+ }
+ position++;
+ }
+ set_sense_code(SCSI_SENSE_NOSENSE);
+ return true;
+}
+
int get_frames_from_msf(const char *string)
{
const char *ptr = string;
switch(phase) {
case SCSI_PHASE_DATA_OUT:
if(--remain > 0) {
+ // flush buffer
+ if(buffer->full()) {
+ if(!write_buffer(buffer->count())) {
+ // change to status phase
+ set_dat(SCSI_STATUS_CHKCOND);
+ set_phase_delay(SCSI_PHASE_STATUS, 10.0);
+ break;
+ }
+ buffer->clear(); // just in case
+ }
switch(command[0]) {
case SCSI_CMD_WRITE6:
case SCSI_CMD_WRITE10:
case SCSI_CMD_WRITE12:
- // flush buffer
- if(buffer->full()) {
- if(!write_buffer(buffer->count())) {
- // change to status phase
- set_dat(SCSI_STATUS_CHKCOND);
- set_phase_delay(SCSI_PHASE_STATUS, 10.0);
- break;
- }
- }
// request to write next data
{
next_req_usec += 1000000.0 / bytes_per_sec;
}
break;
default:
- // flush buffer
- if(buffer->full()) {
- buffer->clear();
- }
// request to write next data
set_req_delay(1, 1.0);
break;
}
} else {
- switch(command[0]) {
- case SCSI_CMD_WRITE6:
- case SCSI_CMD_WRITE10:
- case SCSI_CMD_WRITE12:
- // flush buffer
- if(!buffer->empty()) {
- if(!write_buffer(buffer->count())) {
- // change to status phase
- set_dat(SCSI_STATUS_CHKCOND);
- set_phase_delay(SCSI_PHASE_STATUS, 10.0);
- break;
- }
- }
- break;
- default:
- // flush buffer
- if(!buffer->empty()) {
- buffer->clear();
+ // flush buffer
+ if(!buffer->empty()) {
+ if(!write_buffer(buffer->count())) {
+ // change to status phase
+ set_dat(SCSI_STATUS_CHKCOND);
+ set_phase_delay(SCSI_PHASE_STATUS, 10.0);
+ break;
}
- break;
+ buffer->clear(); // just in case
}
// change to status phase
set_dat(SCSI_STATUS_GOOD);
void SCSI_DEV::set_req(int value)
{
#ifdef _SCSI_DEBUG_LOG
- this->out_debug_log(_T("[SCSI_DEV:ID=%d] REQ = %d\n"), scsi_id, value ? 1 : 0);
+// this->out_debug_log(_T("[SCSI_DEV:ID=%d] REQ = %d\n"), scsi_id, value ? 1 : 0);
#endif
if(event_req != -1) {
cancel_event(this, event_req);
position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3];
position *= physical_block_size();
// transfer length
- remain = 16;
+// remain = 16;
+ remain = command[4];
// create sense data table
buffer->clear();
- buffer->write(SCSI_SERROR_CURRENT);
- buffer->write(0x00);
- buffer->write(is_device_ready() ? SCSI_KEY_NOSENSE : SCSI_KEY_UNITATT);
- buffer->write(0x00);
- buffer->write(0x00);
- buffer->write(0x00);
- buffer->write(0x00);
- buffer->write(0x08);
- buffer->write(0x00);
- buffer->write(0x00);
- buffer->write(0x00);
- buffer->write(0x00);
- buffer->write(0x00);
- buffer->write(0x00);
- buffer->write(0x00);
- buffer->write(0x00);
+ for(int i = 0; i < remain; i++) {
+ int value = 0;
+ switch(i) {
+ case 0: value = SCSI_SERROR_CURRENT; break;
+ case 2: value = is_device_ready() ? SCSI_KEY_NOSENSE : SCSI_KEY_UNITATT; break;
+ case 7: value = 0x08; break;
+ }
+ buffer->write(value);
+ }
// change to data in phase
set_dat(buffer->read());
set_phase_delay(SCSI_PHASE_DATA_IN, 10.0);
bool SCSI_HDD::read_buffer(int length)
{
+ if(!(command[0] == SCSI_CMD_READ6 || command[0] == SCSI_CMD_READ10 || command[0] == SCSI_CMD_READ12)) {
+ for(int i = 0; i < length; i++) {
+ buffer->write(0);
+ position++;
+ }
+ set_sense_code(SCSI_SENSE_NOSENSE);
+ return true;
+ }
HARDDISK *unit = disk[get_logical_unit_number()];
if(!(unit != NULL && unit->mounted())) {
bool SCSI_HDD::write_buffer(int length)
{
+ if(!(command[0] == SCSI_CMD_WRITE6 || command[0] == SCSI_CMD_WRITE10 || command[0] == SCSI_CMD_WRITE12)) {
+ for(int i = 0; i < length; i++) {
+ buffer->read();
+ position++;
+ }
+ set_sense_code(SCSI_SENSE_NOSENSE);
+ return true;
+ }
HARDDISK *unit = disk[get_logical_unit_number()];
if(!(unit != NULL && unit->mounted())) {
case SIG_SCSI_ACK:
#ifdef _SCSI_DEBUG_LOG
- this->out_debug_log(_T("[SCSI_HOST] ACK = %d\n"), (data & mask) ? 1 : 0);
+// this->out_debug_log(_T("[SCSI_HOST] ACK = %d\n"), (data & mask) ? 1 : 0);
#endif
write_signals(&outputs_ack, (data & mask) ? 0xffffffff : 0);
ack_status = data & mask;