Merge pull request #85 from akuker/phrax0-patch-1

Update controllers
This commit is contained in:
akuker 2021-03-21 19:57:31 -05:00 committed by GitHub
commit 6333d3aad5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 567 additions and 521 deletions

View File

@ -5,12 +5,12 @@
// //
// Copyright (C) 2001-2006 (ytanaka@ipc-tokai.or.jp) // Copyright (C) 2001-2006 (ytanaka@ipc-tokai.or.jp)
// Copyright (C) 2014-2020 GIMONS // Copyright (C) 2014-2020 GIMONS
// Copyright (C) akuker // Copyright (C) akuker
// //
// Licensed under the BSD 3-Clause License. // Licensed under the BSD 3-Clause License.
// See LICENSE file in the project root folder. // See LICENSE file in the project root folder.
// //
// [ SASI device controller ] // [ SASI device controller ]
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "controllers/sasidev_ctrl.h" #include "controllers/sasidev_ctrl.h"
@ -37,10 +37,10 @@ SASIDEV::SASIDEV(Device *dev)
{ {
int i; int i;
#ifndef RASCSI #ifndef RASCSI
// Remember host device // Remember host device
host = dev; host = dev;
#endif // RASCSI #endif // RASCSI
// Work initialization // Work initialization
ctrl.phase = BUS::busfree; ctrl.phase = BUS::busfree;
@ -49,9 +49,9 @@ SASIDEV::SASIDEV(Device *dev)
memset(ctrl.cmd, 0x00, sizeof(ctrl.cmd)); memset(ctrl.cmd, 0x00, sizeof(ctrl.cmd));
ctrl.status = 0x00; ctrl.status = 0x00;
ctrl.message = 0x00; ctrl.message = 0x00;
#ifdef RASCSI #ifdef RASCSI
ctrl.execstart = 0; ctrl.execstart = 0;
#endif // RASCSI #endif // RASCSI
ctrl.bufsize = 0x800; ctrl.bufsize = 0x800;
ctrl.buffer = (BYTE *)malloc(ctrl.bufsize); ctrl.buffer = (BYTE *)malloc(ctrl.bufsize);
memset(ctrl.buffer, 0x00, ctrl.bufsize); memset(ctrl.buffer, 0x00, ctrl.bufsize);
@ -96,9 +96,9 @@ void FASTCALL SASIDEV::Reset()
ctrl.phase = BUS::busfree; ctrl.phase = BUS::busfree;
ctrl.status = 0x00; ctrl.status = 0x00;
ctrl.message = 0x00; ctrl.message = 0x00;
#ifdef RASCSI #ifdef RASCSI
ctrl.execstart = 0; ctrl.execstart = 0;
#endif // RASCSI #endif // RASCSI
memset(ctrl.buffer, 0x00, ctrl.bufsize); memset(ctrl.buffer, 0x00, ctrl.bufsize);
ctrl.blocks = 0; ctrl.blocks = 0;
ctrl.next = 0; ctrl.next = 0;
@ -301,9 +301,9 @@ BUS::phase_t FASTCALL SASIDEV::Process()
// For the monitor tool, we shouldn't need to reset. We're just logging information // For the monitor tool, we shouldn't need to reset. We're just logging information
// Reset // Reset
if (ctrl.bus->GetRST()) { if (ctrl.bus->GetRST()) {
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "RESET signal received"); Log(Log::Normal, "SASI - RESET signal received");
#endif // DISK_LOG #endif // DISK_LOG
// Reset the controller // Reset the controller
Reset(); Reset();
@ -371,9 +371,9 @@ void FASTCALL SASIDEV::BusFree()
// Phase change // Phase change
if (ctrl.phase != BUS::busfree) { if (ctrl.phase != BUS::busfree) {
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Bus free phase"); Log(Log::Normal, "SASI - Bus free phase");
#endif // DISK_LOG #endif // DISK_LOG
// Phase Setting // Phase Setting
ctrl.phase = BUS::busfree; ctrl.phase = BUS::busfree;
@ -421,10 +421,9 @@ void FASTCALL SASIDEV::Selection()
return; return;
} }
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, Log(Log::Normal,"SASI - Selection Phase ID=%d (with device)", ctrl.id);
"Selection Phase ID=%d (with device)", ctrl.id); #endif // DISK_LOG
#endif // DISK_LOG
// Phase change // Phase change
ctrl.phase = BUS::selection; ctrl.phase = BUS::selection;
@ -447,19 +446,19 @@ void FASTCALL SASIDEV::Selection()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void FASTCALL SASIDEV::Command() void FASTCALL SASIDEV::Command()
{ {
#ifdef RASCSI #ifdef RASCSI
int count; int count;
int i; int i;
#endif // RASCSI #endif // RASCSI
ASSERT(this); ASSERT(this);
// Phase change // Phase change
if (ctrl.phase != BUS::command) { if (ctrl.phase != BUS::command) {
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Command Phase"); Log(Log::Normal, "SASI - Command Phase");
#endif // DISK_LOG #endif // DISK_LOG
// Phase Setting // Phase Setting
ctrl.phase = BUS::command; ctrl.phase = BUS::command;
@ -474,7 +473,7 @@ void FASTCALL SASIDEV::Command()
ctrl.length = 6; ctrl.length = 6;
ctrl.blocks = 1; ctrl.blocks = 1;
#ifdef RASCSI #ifdef RASCSI
// Command reception handshake (10 bytes are automatically received at the first command) // Command reception handshake (10 bytes are automatically received at the first command)
count = ctrl.bus->CommandHandShake(ctrl.buffer); count = ctrl.bus->CommandHandShake(ctrl.buffer);
@ -506,13 +505,13 @@ void FASTCALL SASIDEV::Command()
// Execution Phase // Execution Phase
Execute(); Execute();
#else #else
// Request the command // Request the command
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
return; return;
#endif // RASCSI #endif // RASCSI
} }
#ifndef RASCSI #ifndef RASCSI
// Requesting // Requesting
if (ctrl.bus->GetREQ()) { if (ctrl.bus->GetREQ()) {
// Sent by the initiator // Sent by the initiator
@ -525,7 +524,7 @@ void FASTCALL SASIDEV::Command()
ReceiveNext(); ReceiveNext();
} }
} }
#endif // RASCSI #endif // RASCSI
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -537,9 +536,9 @@ void FASTCALL SASIDEV::Execute()
{ {
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Execution Phase Command %02X", ctrl.cmd[0]); Log(Log::Normal, "SASI - Execution Phase Command %02X", ctrl.cmd[0]);
#endif // DISK_LOG #endif // DISK_LOG
// Phase Setting // Phase Setting
ctrl.phase = BUS::execute; ctrl.phase = BUS::execute;
@ -547,9 +546,9 @@ void FASTCALL SASIDEV::Execute()
// Initialization for data transfer // Initialization for data transfer
ctrl.offset = 0; ctrl.offset = 0;
ctrl.blocks = 1; ctrl.blocks = 1;
#ifdef RASCSI #ifdef RASCSI
ctrl.execstart = SysTimer::GetTimerLow(); ctrl.execstart = SysTimer::GetTimerLow();
#endif // RASCSI #endif // RASCSI
// Process by command // Process by command
switch (ctrl.cmd[0]) { switch (ctrl.cmd[0]) {
@ -603,14 +602,25 @@ void FASTCALL SASIDEV::Execute()
CmdAssign(); CmdAssign();
return; return;
// RESERVE UNIT(16)
case 0x16:
CmdReserveUnit();
return;
// RELEASE UNIT(17)
case 0x17:
CmdReleaseUnit();
return;
// SPECIFY(SASIのみ) // SPECIFY(SASIのみ)
case 0xc2: case 0xc2:
CmdSpecify(); CmdSpecify();
return; return;
} }
// Unsupported command // Unsupported command
Log(Log::Warning, "Unsupported command $%02X", ctrl.cmd[0]); Log(Log::Warning, "SASI - Unsupported command $%02X", ctrl.cmd[0]);
CmdInvalid(); CmdInvalid();
} }
@ -621,17 +631,17 @@ void FASTCALL SASIDEV::Execute()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void FASTCALL SASIDEV::Status() void FASTCALL SASIDEV::Status()
{ {
#ifdef RASCSI #ifdef RASCSI
DWORD min_exec_time; DWORD min_exec_time;
DWORD time; DWORD time;
#endif // RASCSI #endif // RASCSI
ASSERT(this); ASSERT(this);
// Phase change // Phase change
if (ctrl.phase != BUS::status) { if (ctrl.phase != BUS::status) {
#ifdef RASCSI #ifdef RASCSI
// Minimum execution time // Minimum execution time
if (ctrl.execstart > 0) { if (ctrl.execstart > 0) {
min_exec_time = IsSASI() ? min_exec_time_sasi : min_exec_time_scsi; min_exec_time = IsSASI() ? min_exec_time_sasi : min_exec_time_scsi;
@ -643,11 +653,11 @@ void FASTCALL SASIDEV::Status()
} else { } else {
SysTimer::SleepUsec(5); SysTimer::SleepUsec(5);
} }
#endif // RASCSI #endif // RASCSI
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Status phase"); Log(Log::Normal, "SASI - Status phase");
#endif // DISK_LOG #endif // DISK_LOG
// Phase Setting // Phase Setting
ctrl.phase = BUS::status; ctrl.phase = BUS::status;
@ -663,22 +673,22 @@ void FASTCALL SASIDEV::Status()
ctrl.blocks = 1; ctrl.blocks = 1;
ctrl.buffer[0] = (BYTE)ctrl.status; ctrl.buffer[0] = (BYTE)ctrl.status;
#ifndef RASCSI #ifndef RASCSI
// Request status // Request status
ctrl.bus->SetDAT(ctrl.buffer[0]); ctrl.bus->SetDAT(ctrl.buffer[0]);
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Status Phase $%02X", ctrl.status); Log(Log::Normal, "SASI - Status Phase $%02X", ctrl.status);
#endif // DISK_LOG #endif // DISK_LOG
#endif // RASCSI #endif // RASCSI
return; return;
} }
#ifdef RASCSI #ifdef RASCSI
// Send // Send
Send(); Send();
#else #else
// Requesting // Requesting
if (ctrl.bus->GetREQ()) { if (ctrl.bus->GetREQ()) {
// Initiator received // Initiator received
@ -691,7 +701,7 @@ void FASTCALL SASIDEV::Status()
Send(); Send();
} }
} }
#endif // RASCSI #endif // RASCSI
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -706,9 +716,9 @@ void FASTCALL SASIDEV::MsgIn()
// Phase change // Phase change
if (ctrl.phase != BUS::msgin) { if (ctrl.phase != BUS::msgin) {
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Message in phase"); Log(Log::Normal, "SASI - Message in phase");
#endif // DISK_LOG #endif // DISK_LOG
// Phase Setting // Phase Setting
ctrl.phase = BUS::msgin; ctrl.phase = BUS::msgin;
@ -723,22 +733,22 @@ void FASTCALL SASIDEV::MsgIn()
ASSERT(ctrl.blocks > 0); ASSERT(ctrl.blocks > 0);
ctrl.offset = 0; ctrl.offset = 0;
#ifndef RASCSI #ifndef RASCSI
// Request message // Request message
ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]);
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Message in phase $%02X", ctrl.buffer[ctrl.offset]); Log(Log::Normal, "SASI - Message in phase $%02X", ctrl.buffer[ctrl.offset]);
#endif // DISK_LOG #endif // DISK_LOG
#endif // RASCSI #endif // RASCSI
return; return;
} }
#ifdef RASCSI #ifdef RASCSI
//Send //Send
Send(); Send();
#else #else
// Requesting // Requesting
if (ctrl.bus->GetREQ()) { if (ctrl.bus->GetREQ()) {
// Initator received // Initator received
@ -751,7 +761,7 @@ void FASTCALL SASIDEV::MsgIn()
Send(); Send();
} }
} }
#endif // RASCSI #endif // RASCSI
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -761,10 +771,10 @@ void FASTCALL SASIDEV::MsgIn()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void FASTCALL SASIDEV::DataIn() void FASTCALL SASIDEV::DataIn()
{ {
#ifdef RASCSI #ifdef RASCSI
DWORD min_exec_time; DWORD min_exec_time;
DWORD time; DWORD time;
#endif // RASCSI #endif // RASCSI
ASSERT(this); ASSERT(this);
ASSERT(ctrl.length >= 0); ASSERT(ctrl.length >= 0);
@ -772,7 +782,7 @@ void FASTCALL SASIDEV::DataIn()
// Phase change // Phase change
if (ctrl.phase != BUS::datain) { if (ctrl.phase != BUS::datain) {
#ifdef RASCSI #ifdef RASCSI
// Minimum execution time // Minimum execution time
if (ctrl.execstart > 0) { if (ctrl.execstart > 0) {
min_exec_time = IsSASI() ? min_exec_time_sasi : min_exec_time_scsi; min_exec_time = IsSASI() ? min_exec_time_sasi : min_exec_time_scsi;
@ -782,7 +792,7 @@ void FASTCALL SASIDEV::DataIn()
} }
ctrl.execstart = 0; ctrl.execstart = 0;
} }
#endif // RASCSI #endif // RASCSI
// If the length is 0, go to the status phase // If the length is 0, go to the status phase
if (ctrl.length == 0) { if (ctrl.length == 0) {
@ -790,9 +800,9 @@ void FASTCALL SASIDEV::DataIn()
return; return;
} }
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Data-in Phase"); Log(Log::Normal, "SASI - Data-in Phase");
#endif // DISK_LOG #endif // DISK_LOG
// Phase Setting // Phase Setting
ctrl.phase = BUS::datain; ctrl.phase = BUS::datain;
@ -807,20 +817,20 @@ void FASTCALL SASIDEV::DataIn()
ASSERT(ctrl.blocks > 0); ASSERT(ctrl.blocks > 0);
ctrl.offset = 0; ctrl.offset = 0;
#ifndef RASCSI #ifndef RASCSI
// Assert the DAT signal // Assert the DAT signal
ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]);
// Request data // Request data
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
#endif // RASCSI #endif // RASCSI
return; return;
} }
#ifdef RASCSI #ifdef RASCSI
// Send // Send
Send(); Send();
#else #else
// Requesting // Requesting
if (ctrl.bus->GetREQ()) { if (ctrl.bus->GetREQ()) {
// Initator received // Initator received
@ -833,7 +843,7 @@ void FASTCALL SASIDEV::DataIn()
Send(); Send();
} }
} }
#endif // RASCSI #endif // RASCSI
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -843,10 +853,10 @@ void FASTCALL SASIDEV::DataIn()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void FASTCALL SASIDEV::DataOut() void FASTCALL SASIDEV::DataOut()
{ {
#ifdef RASCSI #ifdef RASCSI
DWORD min_exec_time; DWORD min_exec_time;
DWORD time; DWORD time;
#endif // RASCSI #endif // RASCSI
ASSERT(this); ASSERT(this);
ASSERT(ctrl.length >= 0); ASSERT(ctrl.length >= 0);
@ -854,7 +864,7 @@ void FASTCALL SASIDEV::DataOut()
// Phase change // Phase change
if (ctrl.phase != BUS::dataout) { if (ctrl.phase != BUS::dataout) {
#ifdef RASCSI #ifdef RASCSI
// Minimum execution time // Minimum execution time
if (ctrl.execstart > 0) { if (ctrl.execstart > 0) {
min_exec_time = IsSASI() ? min_exec_time_sasi : min_exec_time_scsi; min_exec_time = IsSASI() ? min_exec_time_sasi : min_exec_time_scsi;
@ -864,7 +874,7 @@ void FASTCALL SASIDEV::DataOut()
} }
ctrl.execstart = 0; ctrl.execstart = 0;
} }
#endif // RASCSI #endif // RASCSI
// If the length is 0, go to the status phase // If the length is 0, go to the status phase
if (ctrl.length == 0) { if (ctrl.length == 0) {
@ -872,9 +882,9 @@ void FASTCALL SASIDEV::DataOut()
return; return;
} }
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Data out phase"); Log(Log::Normal, "SASI - Data out phase");
#endif // DISK_LOG #endif // DISK_LOG
// Phase Setting // Phase Setting
ctrl.phase = BUS::dataout; ctrl.phase = BUS::dataout;
@ -889,17 +899,17 @@ void FASTCALL SASIDEV::DataOut()
ASSERT(ctrl.blocks > 0); ASSERT(ctrl.blocks > 0);
ctrl.offset = 0; ctrl.offset = 0;
#ifndef RASCSI #ifndef RASCSI
// Request data // Request data
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
#endif // RASCSI #endif // RASCSI
return; return;
} }
#ifdef RASCSI #ifdef RASCSI
// Receive // Receive
Receive(); Receive();
#else #else
// Requesting // Requesting
if (ctrl.bus->GetREQ()) { if (ctrl.bus->GetREQ()) {
// Sent by the initiator // Sent by the initiator
@ -912,7 +922,7 @@ void FASTCALL SASIDEV::DataOut()
ReceiveNext(); ReceiveNext();
} }
} }
#endif // RASCSI #endif // RASCSI
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -945,9 +955,9 @@ void FASTCALL SASIDEV::Error()
return; return;
} }
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Warning, "Error occured (going to status phase)"); Log(Log::Warning, "SASI - Error occured (going to status phase)");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -971,9 +981,9 @@ void FASTCALL SASIDEV::CmdTestUnitReady()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "TEST UNIT READY Command "); Log(Log::Normal, "SASI - TEST UNIT READY Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -1006,9 +1016,9 @@ void FASTCALL SASIDEV::CmdRezero()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "REZERO UNIT Command "); Log(Log::Normal, "SASI - REZERO UNIT Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -1040,9 +1050,9 @@ void FASTCALL SASIDEV::CmdRequestSense()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "REQUEST SENSE Command "); Log(Log::Normal, "SASI - REQUEST SENSE Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -1055,9 +1065,9 @@ void FASTCALL SASIDEV::CmdRequestSense()
ctrl.length = ctrl.unit[lun]->RequestSense(ctrl.cmd, ctrl.buffer); ctrl.length = ctrl.unit[lun]->RequestSense(ctrl.cmd, ctrl.buffer);
ASSERT(ctrl.length > 0); ASSERT(ctrl.length > 0);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Sense key $%02X", ctrl.buffer[2]); Log(Log::Normal, "SASI - Sense key $%02X", ctrl.buffer[2]);
#endif // DISK_LOG #endif // DISK_LOG
// Read phase // Read phase
DataIn(); DataIn();
@ -1075,9 +1085,9 @@ void FASTCALL SASIDEV::CmdFormat()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "FORMAT UNIT Command "); Log(Log::Normal, "SASI - FORMAT UNIT Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -1110,9 +1120,9 @@ void FASTCALL SASIDEV::CmdReassign()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "REASSIGN BLOCKS Command "); Log(Log::Normal, "SASI - REASSIGN BLOCKS Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -1133,6 +1143,42 @@ void FASTCALL SASIDEV::CmdReassign()
Status(); Status();
} }
// The following commands RESERVE UNIT and RELEASE UNIT are not properly implemented.
// These commands are used in multi-initator environments which this project is not targeted at.
// For now, we simply reply with an OK. -phrax 2021-03-06
//---------------------------------------------------------------------------
//
// RESERVE UNIT(16)
//
//---------------------------------------------------------------------------
void FASTCALL SASIDEV::CmdReserveUnit()
{
ASSERT(this);
#if defined(DISK_LOG)
Log(Log::Normal, "SASI - RESERVE UNIT Command");
#endif // DISK_LOG
// status phase
Status();
}
//---------------------------------------------------------------------------
//
// RELEASE UNIT(17)
//
//---------------------------------------------------------------------------
void FASTCALL SASIDEV::CmdReleaseUnit()
{
ASSERT(this);
#if defined(DISK_LOG)
Log(Log::Normal, "SASI - RELEASE UNIT Command");
#endif // DISK_LOG
// status phase
Status();
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// READ(6) // READ(6)
@ -1163,10 +1209,9 @@ void FASTCALL SASIDEV::CmdRead6()
ctrl.blocks = 0x100; ctrl.blocks = 0x100;
} }
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, Log(Log::Normal,"SASI - READ(6) command record=%06X blocks=%d", record, ctrl.blocks);
"READ(6) command record=%06X blocks=%d", record, ctrl.blocks); #endif // DISK_LOG
#endif // DISK_LOG
// Command processing on drive // Command processing on drive
ctrl.length = ctrl.unit[lun]->Read(ctrl.buffer, record); ctrl.length = ctrl.unit[lun]->Read(ctrl.buffer, record);
@ -1213,10 +1258,9 @@ void FASTCALL SASIDEV::CmdWrite6()
ctrl.blocks = 0x100; ctrl.blocks = 0x100;
} }
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, Log(Log::Normal,"SASI - WRITE(6) command record=%06X blocks=%d", record, ctrl.blocks);
"WRITE(6) command record=%06X blocks=%d", record, ctrl.blocks); #endif // DISK_LOG
#endif // DISK_LOG
// Command processing on drive // Command processing on drive
ctrl.length = ctrl.unit[lun]->WriteCheck(record); ctrl.length = ctrl.unit[lun]->WriteCheck(record);
@ -1245,9 +1289,9 @@ void FASTCALL SASIDEV::CmdSeek6()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "SEEK(6) Command "); Log(Log::Normal, "SASI - SEEK(6) Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -1280,9 +1324,9 @@ void FASTCALL SASIDEV::CmdAssign()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "ASSIGN Command "); Log(Log::Normal, "SASI - ASSIGN Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -1318,9 +1362,9 @@ void FASTCALL SASIDEV::CmdSpecify()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "SPECIFY Command "); Log(Log::Normal, "SASI - SPECIFY Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -1355,9 +1399,9 @@ void FASTCALL SASIDEV::CmdInvalid()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Command not supported"); Log(Log::Normal, "SASI - Command not supported");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -1383,16 +1427,16 @@ void FASTCALL SASIDEV::CmdInvalid()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void FASTCALL SASIDEV::Send() void FASTCALL SASIDEV::Send()
{ {
#ifdef RASCSI #ifdef RASCSI
int len; int len;
#endif // RASCSI #endif // RASCSI
BOOL result; BOOL result;
ASSERT(this); ASSERT(this);
ASSERT(!ctrl.bus->GetREQ()); ASSERT(!ctrl.bus->GetREQ());
ASSERT(ctrl.bus->GetIO()); ASSERT(ctrl.bus->GetIO());
#ifdef RASCSI #ifdef RASCSI
// Check that the length isn't 0 // Check that the length isn't 0
if (ctrl.length != 0) { if (ctrl.length != 0) {
len = ctrl.bus->SendHandShake( len = ctrl.bus->SendHandShake(
@ -1409,7 +1453,7 @@ void FASTCALL SASIDEV::Send()
ctrl.length = 0; ctrl.length = 0;
return; return;
} }
#else #else
// Offset and Length // Offset and Length
ASSERT(ctrl.length >= 1); ASSERT(ctrl.length >= 1);
ctrl.offset++; ctrl.offset++;
@ -1422,7 +1466,7 @@ void FASTCALL SASIDEV::Send()
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
return; return;
} }
#endif // RASCSI #endif // RASCSI
// Remove block and initialize the result // Remove block and initialize the result
ctrl.blocks--; ctrl.blocks--;
@ -1435,9 +1479,9 @@ void FASTCALL SASIDEV::Send()
result = XferIn(ctrl.buffer); result = XferIn(ctrl.buffer);
//** printf("xfer in: %d \n",result); //** printf("xfer in: %d \n",result);
#ifndef RASCSI #ifndef RASCSI
ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]);
#endif // RASCSI #endif // RASCSI
} }
} }
@ -1451,10 +1495,10 @@ void FASTCALL SASIDEV::Send()
if (ctrl.blocks != 0){ if (ctrl.blocks != 0){
ASSERT(ctrl.length > 0); ASSERT(ctrl.length > 0);
ASSERT(ctrl.offset == 0); ASSERT(ctrl.offset == 0);
#ifndef RASCSI #ifndef RASCSI
// Signal line operated by the target // Signal line operated by the target
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
#endif // RASCSI #endif // RASCSI
return; return;
} }
@ -1538,9 +1582,9 @@ void FASTCALL SASIDEV::Receive()
// Command phase // Command phase
case BUS::command: case BUS::command:
ctrl.cmd[ctrl.offset] = data; ctrl.cmd[ctrl.offset] = data;
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Command phase $%02X", data); Log(Log::Normal, "SASI - Command phase $%02X", data);
#endif // DISK_LOG #endif // DISK_LOG
// Set the length again with the first data (offset 0) // Set the length again with the first data (offset 0)
if (ctrl.offset == 0) { if (ctrl.offset == 0) {
@ -1580,9 +1624,9 @@ void FASTCALL SASIDEV::Receive()
void FASTCALL SASIDEV::ReceiveNext() void FASTCALL SASIDEV::ReceiveNext()
#endif // RASCSI #endif // RASCSI
{ {
#ifdef RASCSI #ifdef RASCSI
int len; int len;
#endif // RASCSI #endif // RASCSI
BOOL result; BOOL result;
ASSERT(this); ASSERT(this);
@ -1591,7 +1635,7 @@ void FASTCALL SASIDEV::ReceiveNext()
ASSERT(!ctrl.bus->GetREQ()); ASSERT(!ctrl.bus->GetREQ());
ASSERT(!ctrl.bus->GetIO()); ASSERT(!ctrl.bus->GetIO());
#ifdef RASCSI #ifdef RASCSI
// Length != 0 if received // Length != 0 if received
if (ctrl.length != 0) { if (ctrl.length != 0) {
// Receive // Receive
@ -1609,7 +1653,7 @@ void FASTCALL SASIDEV::ReceiveNext()
ctrl.length = 0; ctrl.length = 0;
return; return;
} }
#else #else
// Offset and Length // Offset and Length
ASSERT(ctrl.length >= 1); ASSERT(ctrl.length >= 1);
ctrl.offset++; ctrl.offset++;
@ -1621,7 +1665,7 @@ void FASTCALL SASIDEV::ReceiveNext()
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
return; return;
} }
#endif // RASCSI #endif // RASCSI
// Remove the control block and initialize the result // Remove the control block and initialize the result
ctrl.blocks--; ctrl.blocks--;
@ -1648,22 +1692,22 @@ void FASTCALL SASIDEV::ReceiveNext()
if (ctrl.blocks != 0){ if (ctrl.blocks != 0){
ASSERT(ctrl.length > 0); ASSERT(ctrl.length > 0);
ASSERT(ctrl.offset == 0); ASSERT(ctrl.offset == 0);
#ifndef RASCSI #ifndef RASCSI
// Signal line operated by the target // Signal line operated by the target
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
#endif // RASCSI #endif // RASCSI
return; return;
} }
// Move to the next phase // Move to the next phase
switch (ctrl.phase) { switch (ctrl.phase) {
#ifndef RASCSI #ifndef RASCSI
// Command phase // Command phase
case BUS::command: case BUS::command:
// Execution Phase // Execution Phase
Execute(); Execute();
break; break;
#endif // RASCSI #endif // RASCSI
// Data out phase // Data out phase
case BUS::dataout: case BUS::dataout:
@ -1856,7 +1900,7 @@ void FASTCALL SASIDEV::FlushUnit()
// Debug code related to Issue #2 on github, where we get an unhandled Model select when // Debug code related to Issue #2 on github, where we get an unhandled Model select when
// the mac is rebooted // the mac is rebooted
// https://github.com/akuker/RASCSI/issues/2 // https://github.com/akuker/RASCSI/issues/2
Log(Log::Warning, "Received \'Mode Select\'\n"); Log(Log::Warning, "SASI - Received \'Mode Select\'\n");
Log(Log::Warning, " Operation Code: [%02X]\n", ctrl.cmd[0]); Log(Log::Warning, " Operation Code: [%02X]\n", ctrl.cmd[0]);
Log(Log::Warning, " Logical Unit %01X, PF %01X, SP %01X [%02X]\n", ctrl.cmd[1] >> 5, 1 & (ctrl.cmd[1] >> 4), ctrl.cmd[1] & 1, ctrl.cmd[1]); Log(Log::Warning, " Logical Unit %01X, PF %01X, SP %01X [%02X]\n", ctrl.cmd[1] >> 5, 1 & (ctrl.cmd[1] >> 4), ctrl.cmd[1] & 1, ctrl.cmd[1]);
Log(Log::Warning, " Reserved: %02X\n", ctrl.cmd[2]); Log(Log::Warning, " Reserved: %02X\n", ctrl.cmd[2]);
@ -1868,13 +1912,13 @@ void FASTCALL SASIDEV::FlushUnit()
if (!ctrl.unit[lun]->ModeSelect( if (!ctrl.unit[lun]->ModeSelect(
ctrl.cmd, ctrl.buffer, ctrl.offset)) { ctrl.cmd, ctrl.buffer, ctrl.offset)) {
// MODE SELECT failed // MODE SELECT failed
Log(Log::Warning, "Error occured while processing Mode Select command %02X\n", (unsigned char)ctrl.cmd[0]); Log(Log::Warning, "SASI - Error occured while processing Mode Select command %02X\n", (unsigned char)ctrl.cmd[0]);
return; return;
} }
break; break;
default: default:
Log(Log::Warning, "Received an invalid flush command %02X!!!!!\n",ctrl.cmd[0]); Log(Log::Warning, "SASI - Received an invalid flush command %02X!!!!!\n",ctrl.cmd[0]);
ASSERT(FALSE); ASSERT(FALSE);
break; break;
} }
@ -1938,13 +1982,13 @@ void SASIDEV::GetPhaseStr(char *str)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void FASTCALL SASIDEV::Log(Log::loglevel level, const char *format, ...) void FASTCALL SASIDEV::Log(Log::loglevel level, const char *format, ...)
{ {
#if !defined(BAREMETAL) #if !defined(BAREMETAL)
#ifdef DISK_LOG #ifdef DISK_LOG
char buffer[0x200]; char buffer[0x200];
char buffer2[0x250]; char buffer2[0x250];
char buffer3[0x250]; char buffer3[0x250];
char phase_str[20]; char phase_str[20];
#endif #endif
va_list args; va_list args;
va_start(args, format); va_start(args, format);
@ -1953,15 +1997,15 @@ void FASTCALL SASIDEV::Log(Log::loglevel level, const char *format, ...)
return; return;
} }
#ifdef RASCSI #ifdef RASCSI
#ifndef DISK_LOG #ifndef DISK_LOG
if (level == Log::Warning) { if (level == Log::Warning) {
return; return;
} }
#endif // DISK_LOG #endif // DISK_LOG
#endif // RASCSI #endif // RASCSI
#ifdef DISK_LOG #ifdef DISK_LOG
// format // format
vsprintf(buffer, format, args); vsprintf(buffer, format, args);
@ -1970,30 +2014,28 @@ void FASTCALL SASIDEV::Log(Log::loglevel level, const char *format, ...)
// Add the date/timestamp // Add the date/timestamp
// current date/time based on current system // current date/time based on current system
time_t now = time(0); time_t now = time(0);
// convert now to string form // convert now to string form
char* dt = ctime(&now); char* dt = ctime(&now);
strcpy(buffer2, "[");
strcat(buffer2, dt);
// Get rid of the carriage return
buffer2[strlen(buffer2)-1] = '\0';
strcat(buffer2, "] ");
strcpy(buffer2, "["); // Get the phase
strcat(buffer2, dt); this->GetPhaseStr(phase_str);
// Get rid of the carriage return sprintf(buffer3, "[%d][%s] ", this->GetID(), phase_str);
buffer2[strlen(buffer2)-1] = '\0'; strcat(buffer2,buffer3);
strcat(buffer2, "] "); strcat(buffer2, buffer);
// Get the phase // Log output
this->GetPhaseStr(phase_str); #ifdef RASCSI
sprintf(buffer3, "[%d][%s] ", this->GetID(), phase_str);
strcat(buffer2,buffer3);
strcat(buffer2, buffer);
// Log output
#ifdef RASCSI
printf("%s\n", buffer2); printf("%s\n", buffer2);
#else #else
host->GetVM()->GetLog()->Format(level, host, buffer); host->GetVM()->GetLog()->Format(level, host, buffer);
#endif // RASCSI #endif // RASCSI
#endif // BAREMETAL #endif // BAREMETAL
#endif // DISK_LOG #endif // DISK_LOG
} }

View File

@ -5,12 +5,12 @@
// //
// Copyright (C) 2001-2006 (ytanaka@ipc-tokai.or.jp) // Copyright (C) 2001-2006 (ytanaka@ipc-tokai.or.jp)
// Copyright (C) 2014-2020 GIMONS // Copyright (C) 2014-2020 GIMONS
// Copyright (C) akuker // Copyright (C) akuker
// //
// Licensed under the BSD 3-Clause License. // Licensed under the BSD 3-Clause License.
// See LICENSE file in the project root folder. // See LICENSE file in the project root folder.
// //
// [ SASI device controller ] // [ SASI device controller ]
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#pragma once #pragma once
@ -31,181 +31,140 @@
class SASIDEV class SASIDEV
{ {
public: public:
// Maximum number of logical units
enum { enum {
UnitMax = 8 UnitMax = 8 // Maximum number of logical units
}; };
#ifdef RASCSI #ifdef RASCSI
// For timing adjustments // For timing adjustments
enum { enum {
min_exec_time_sasi = 100, // SASI BOOT/FORMAT 30:NG 35:OK min_exec_time_sasi = 100, // SASI BOOT/FORMAT 30:NG 35:OK
min_exec_time_scsi = 50 min_exec_time_scsi = 50
}; };
#endif // RASCSI #endif // RASCSI
// Internal data definition // Internal data definition
typedef struct { typedef struct {
// 全般 // 全般
BUS::phase_t phase; // Transition phase BUS::phase_t phase; // Transition phase
int id; // Controller ID (0-7) int id; // Controller ID (0-7)
BUS *bus; // Bus BUS *bus; // Bus
// commands // commands
DWORD cmd[10]; // Command data DWORD cmd[10]; // Command data
DWORD status; // Status data DWORD status; // Status data
DWORD message; // Message data DWORD message; // Message data
#ifdef RASCSI #ifdef RASCSI
// Run // Run
DWORD execstart; // Execution start time DWORD execstart; // Execution start time
#endif // RASCSI #endif // RASCSI
// Transfer // Transfer
BYTE *buffer; // Transfer data buffer BYTE *buffer; // Transfer data buffer
int bufsize; // Transfer data buffer size int bufsize; // Transfer data buffer size
DWORD blocks; // Number of transfer block DWORD blocks; // Number of transfer block
DWORD next; // Next record DWORD next; // Next record
DWORD offset; // Transfer offset DWORD offset; // Transfer offset
DWORD length; // Transfer remaining length DWORD length; // Transfer remaining length
// Logical unit // Logical unit
Disk *unit[UnitMax]; Disk *unit[UnitMax]; // Logical Unit
// Logical Unit
} ctrl_t; } ctrl_t;
public: public:
// Basic Functions // Basic Functions
#ifdef RASCSI #ifdef RASCSI
SASIDEV(); SASIDEV();
#else #else
SASIDEV(Device *dev);
#endif //RASCSI
// Constructor SASIDEV(Device *dev); // Constructor
virtual ~SASIDEV();
// Destructor #endif //RASCSI
virtual void FASTCALL Reset(); virtual ~SASIDEV(); // Destructor
// Device Reset virtual void FASTCALL Reset(); // Device Reset
#ifndef RASCSI
virtual BOOL FASTCALL Save(Fileio *fio, int ver); #ifndef RASCSI
// Save virtual BOOL FASTCALL Save(Fileio *fio, int ver); // Save
virtual BOOL FASTCALL Load(Fileio *fio, int ver); virtual BOOL FASTCALL Load(Fileio *fio, int ver); // Load
// Load #endif //RASCSI
#endif //RASCSI
// External API // External API
virtual BUS::phase_t FASTCALL Process(); virtual BUS::phase_t FASTCALL Process(); // Run
// Run
// Connect // Connect
void FASTCALL Connect(int id, BUS *sbus); void FASTCALL Connect(int id, BUS *sbus); // Controller connection
// Controller connection Disk* FASTCALL GetUnit(int no); // Get logical unit
Disk* FASTCALL GetUnit(int no); void FASTCALL SetUnit(int no, Disk *dev); // Logical unit setting
// Get logical unit BOOL FASTCALL HasUnit(); // Has a valid logical unit
void FASTCALL SetUnit(int no, Disk *dev);
// Logical unit setting
BOOL FASTCALL HasUnit();
// Has a valid logical unit
// Other // Other
BUS::phase_t FASTCALL GetPhase() {return ctrl.phase;} BUS::phase_t FASTCALL GetPhase() {return ctrl.phase;} // Get the phase
// Get the phase #ifdef DISK_LOG
#ifdef DISK_LOG
// Function to get the current phase as a String.
void FASTCALL GetPhaseStr(char *str);
#endif
int FASTCALL GetID() {return ctrl.id;} // Function to get the current phase as a String.
// Get the ID void FASTCALL GetPhaseStr(char *str);
void FASTCALL GetCTRL(ctrl_t *buffer); #endif
// Get the internal information
ctrl_t* FASTCALL GetWorkAddr() { return &ctrl; } int FASTCALL GetID() {return ctrl.id;} // Get the ID
// Get the internal information address void FASTCALL GetCTRL(ctrl_t *buffer); // Get the internal information
virtual BOOL FASTCALL IsSASI() const {return TRUE;} ctrl_t* FASTCALL GetWorkAddr() { return &ctrl; } // Get the internal information address
// SASI Check virtual BOOL FASTCALL IsSASI() const {return TRUE;} // SASI Check
virtual BOOL FASTCALL IsSCSI() const {return FALSE;} virtual BOOL FASTCALL IsSCSI() const {return FALSE;} // SCSI check
// SCSI check Disk* FASTCALL GetBusyUnit(); // Get the busy unit
Disk* FASTCALL GetBusyUnit();
// Get the busy unit
protected: protected:
// Phase processing // Phase processing
virtual void FASTCALL BusFree(); virtual void FASTCALL BusFree(); // Bus free phase
// Bus free phase virtual void FASTCALL Selection(); // Selection phase
virtual void FASTCALL Selection(); virtual void FASTCALL Command(); // Command phase
// Selection phase virtual void FASTCALL Execute(); // Execution phase
virtual void FASTCALL Command(); void FASTCALL Status(); // Status phase
// Command phase void FASTCALL MsgIn(); // Message in phase
virtual void FASTCALL Execute(); void FASTCALL DataIn(); // Data in phase
// Execution phase void FASTCALL DataOut(); // Data out phase
void FASTCALL Status(); virtual void FASTCALL Error(); // Common error handling
// Status phase
void FASTCALL MsgIn();
// Message in phase
void FASTCALL DataIn();
// Data in phase
void FASTCALL DataOut();
// Data out phase
virtual void FASTCALL Error();
// Common error handling
// commands // commands
void FASTCALL CmdTestUnitReady(); void FASTCALL CmdTestUnitReady(); // TEST UNIT READY command
// TEST UNIT READY command void FASTCALL CmdRezero(); // REZERO UNIT command
void FASTCALL CmdRezero(); void FASTCALL CmdRequestSense(); // REQUEST SENSE command
// REZERO UNIT command void FASTCALL CmdFormat(); // FORMAT command
void FASTCALL CmdRequestSense(); void FASTCALL CmdReassign(); // REASSIGN BLOCKS command
// REQUEST SENSE command void FASTCALL CmdReserveUnit(); // RESERVE UNIT command
void FASTCALL CmdFormat(); void FASTCALL CmdReleaseUnit(); // RELEASE UNIT command
// FORMAT command void FASTCALL CmdRead6(); // READ(6) command
void FASTCALL CmdReassign(); void FASTCALL CmdWrite6(); // WRITE(6) command
// REASSIGN BLOCKS command void FASTCALL CmdSeek6(); // SEEK(6) command
void FASTCALL CmdRead6(); void FASTCALL CmdAssign(); // ASSIGN command
// READ(6) command void FASTCALL CmdSpecify(); // SPECIFY command
void FASTCALL CmdWrite6(); void FASTCALL CmdInvalid(); // Unsupported command
// WRITE(6) command
void FASTCALL CmdSeek6();
// SEEK(6) command
void FASTCALL CmdAssign();
// ASSIGN command
void FASTCALL CmdSpecify();
// SPECIFY command
void FASTCALL CmdInvalid();
// Unsupported command
// データ転送 // データ転送
virtual void FASTCALL Send(); virtual void FASTCALL Send(); // Send data
// Send data
#ifndef RASCSI #ifndef RASCSI
virtual void FASTCALL SendNext(); virtual void FASTCALL SendNext(); // Continue sending data
// Continue sending data #endif // RASCSI
#endif // RASCSI
virtual void FASTCALL Receive(); virtual void FASTCALL Receive(); // Receive data
// Receive data
#ifndef RASCSI #ifndef RASCSI
virtual void FASTCALL ReceiveNext(); virtual void FASTCALL ReceiveNext(); // Continue receiving data
// Continue receiving data #endif // RASCSI
#endif // RASCSI
BOOL FASTCALL XferIn(BYTE* buf); BOOL FASTCALL XferIn(BYTE* buf); // Data transfer IN
// Data transfer IN BOOL FASTCALL XferOut(BOOL cont); // Data transfer OUT
BOOL FASTCALL XferOut(BOOL cont);
// Data transfer OUT
// Special operations // Special operations
void FASTCALL FlushUnit(); void FASTCALL FlushUnit(); // Flush the logical unit
// Flush the logical unit
// Log // Log
void FASTCALL Log(Log::loglevel level, const char *format, ...); void FASTCALL Log(Log::loglevel level, const char *format, ...); // Log output
// Log output
protected: protected:
#ifndef RASCSI #ifndef RASCSI
Device *host; Device *host; // Host device
// Host device #endif // RASCSI
#endif // RASCSI ctrl_t ctrl; // Internal data
ctrl_t ctrl;
// Internal data
}; };

View File

@ -5,12 +5,12 @@
// //
// Copyright (C) 2001-2006 (ytanaka@ipc-tokai.or.jp) // Copyright (C) 2001-2006 (ytanaka@ipc-tokai.or.jp)
// Copyright (C) 2014-2020 GIMONS // Copyright (C) 2014-2020 GIMONS
// Copyright (C) akuker // Copyright (C) akuker
// //
// Licensed under the BSD 3-Clause License. // Licensed under the BSD 3-Clause License.
// See LICENSE file in the project root folder. // See LICENSE file in the project root folder.
// //
// [ SCSI device controller ] // [ SCSI device controller ]
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "controllers/scsidev_ctrl.h" #include "controllers/scsidev_ctrl.h"
@ -81,9 +81,9 @@ BUS::phase_t FASTCALL SCSIDEV::Process()
// Reset // Reset
if (ctrl.bus->GetRST()) { if (ctrl.bus->GetRST()) {
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "RESET信号受信"); Log(Log::Normal, "SCSI - RESET信号受信");
#endif // DISK_LOG #endif // DISK_LOG
// Reset the controller // Reset the controller
Reset(); Reset();
@ -162,9 +162,9 @@ void FASTCALL SCSIDEV::BusFree()
// Phase change // Phase change
if (ctrl.phase != BUS::busfree) { if (ctrl.phase != BUS::busfree) {
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Bus free phase"); Log(Log::Normal, "SCSI - Bus free phase");
#endif // DISK_LOG #endif // DISK_LOG
// Phase setting // Phase setting
ctrl.phase = BUS::busfree; ctrl.phase = BUS::busfree;
@ -215,10 +215,9 @@ void FASTCALL SCSIDEV::Selection()
return; return;
} }
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, Log(Log::Normal,"SCSI - Selection Phase ID=%d (with device)", ctrl.id);
"Selection Phase ID=%d (with device)", ctrl.id); #endif // DISK_LOG
#endif // DISK_LOG
// Phase setting // Phase setting
ctrl.phase = BUS::selection; ctrl.phase = BUS::selection;
@ -248,9 +247,9 @@ void FASTCALL SCSIDEV::Execute()
{ {
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Execution phase command $%02X", ctrl.cmd[0]); Log(Log::Normal, "SCSI - Execution phase command $%02X", ctrl.cmd[0]);
#endif // DISK_LOG #endif // DISK_LOG
// Phase Setting // Phase Setting
ctrl.phase = BUS::execute; ctrl.phase = BUS::execute;
@ -258,9 +257,9 @@ void FASTCALL SCSIDEV::Execute()
// Initialization for data transfer // Initialization for data transfer
ctrl.offset = 0; ctrl.offset = 0;
ctrl.blocks = 1; ctrl.blocks = 1;
#ifdef RASCSI #ifdef RASCSI
ctrl.execstart = SysTimer::GetTimerLow(); ctrl.execstart = SysTimer::GetTimerLow();
#endif // RASCSI #endif // RASCSI
// Process by command // Process by command
switch (ctrl.cmd[0]) { switch (ctrl.cmd[0]) {
@ -314,6 +313,26 @@ void FASTCALL SCSIDEV::Execute()
CmdModeSelect(); CmdModeSelect();
return; return;
// RESERVE(6)
case 0x16:
CmdReserve6();
return;
// RESERVE(10)
case 0x56:
CmdReserve10();
return;
// RELEASE(6)
case 0x17:
CmdRelease6();
return;
// RELEASE(10)
case 0x57:
CmdRelease10();
return;
// MDOE SENSE // MDOE SENSE
case 0x1a: case 0x1a:
CmdModeSense(); CmdModeSense();
@ -412,7 +431,7 @@ void FASTCALL SCSIDEV::Execute()
} }
// No other support // No other support
Log(Log::Normal, "Unsupported command received: $%02X", ctrl.cmd[0]); Log(Log::Normal, "SCSI - Unsupported command received: $%02X", ctrl.cmd[0]);
CmdInvalid(); CmdInvalid();
} }
@ -428,12 +447,11 @@ void FASTCALL SCSIDEV::MsgOut()
// Phase change // Phase change
if (ctrl.phase != BUS::msgout) { if (ctrl.phase != BUS::msgout) {
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Message Out Phase"); Log(Log::Normal, "SCSI - Message Out Phase"); // Message out phase after selection
#endif // DISK_LOG #endif // DISK_LOG
// Message out phase after selection // process the IDENTIFY message
// process the IDENTIFY message
if (ctrl.phase == BUS::selection) { if (ctrl.phase == BUS::selection) {
scsi.atnmsg = TRUE; scsi.atnmsg = TRUE;
scsi.msc = 0; scsi.msc = 0;
@ -453,17 +471,18 @@ void FASTCALL SCSIDEV::MsgOut()
ctrl.length = 1; ctrl.length = 1;
ctrl.blocks = 1; ctrl.blocks = 1;
#ifndef RASCSI #ifndef RASCSI
// Request message // Request message
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
#endif // RASCSI #endif // RASCSI
return; return;
} }
#ifdef RASCSI #ifdef RASCSI
// Receive // Receive
Receive(); Receive();
#else #else
// Requesting // Requesting
if (ctrl.bus->GetREQ()) { if (ctrl.bus->GetREQ()) {
// Sent by the initiator // Sent by the initiator
@ -476,7 +495,7 @@ void FASTCALL SCSIDEV::MsgOut()
ReceiveNext(); ReceiveNext();
} }
} }
#endif // RASCSI #endif // RASCSI
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -507,9 +526,9 @@ void FASTCALL SCSIDEV::Error()
return; return;
} }
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Error (to status phase)"); Log(Log::Normal, "SCSI - Error (to status phase)");
#endif // DISK_LOG #endif // DISK_LOG
// Set status and message(CHECK CONDITION) // Set status and message(CHECK CONDITION)
ctrl.status = 0x02; ctrl.status = 0x02;
@ -539,9 +558,9 @@ void FASTCALL SCSIDEV::CmdInquiry()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "INQUIRY Command"); Log(Log::Normal, "SCSI - INQUIRY Command");
#endif // DISK_LOG #endif // DISK_LOG
// Find a valid unit // Find a valid unit
disk = NULL; disk = NULL;
@ -588,9 +607,9 @@ void FASTCALL SCSIDEV::CmdModeSelect()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "MODE SELECT Command"); Log(Log::Normal, "SCSI - MODE SELECT Command");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -611,6 +630,75 @@ void FASTCALL SCSIDEV::CmdModeSelect()
DataOut(); DataOut();
} }
// The following commands RESERVE(6), RESERVE(10), RELEASE(6) and RELEASE(10)
// are not properly implemented. These commands are used in multi-initator environments
// which this project is not targeted at. For now, we simply reply with an OK.
// -phrax 2021-03-06
//---------------------------------------------------------------------------
//
// RESERVE(6)
//
//---------------------------------------------------------------------------
void FASTCALL SCSIDEV::CmdReserve6()
{
ASSERT(this);
#if defined(DISK_LOG)
Log(Log::Normal, "SCSI - RESERVE(6) Command");
#endif // DISK_LOG
// status phase
Status();
}
//---------------------------------------------------------------------------
//
// RESERVE(10)
//
//---------------------------------------------------------------------------
void FASTCALL SCSIDEV::CmdReserve10()
{
ASSERT(this);
#if defined(DISK_LOG)
Log(Log::Normal, "SCSI - RESERVE(10) Command");
#endif // DISK_LOG
// status phase
Status();
}
//---------------------------------------------------------------------------
//
// RELEASE(6)
//
//---------------------------------------------------------------------------
void FASTCALL SCSIDEV::CmdRelease6()
{
ASSERT(this);
#if defined(DISK_LOG)
Log(Log::Normal, "SCSI - RELEASE(6) Command");
#endif // DISK_LOG
// status phase
Status();
}
//---------------------------------------------------------------------------
//
// RELEASE(10)
//
//---------------------------------------------------------------------------
void FASTCALL SCSIDEV::CmdRelease10()
{
ASSERT(this);
#if defined(DISK_LOG)
Log(Log::Normal, "SCSI - RELEASE(10) Command");
#endif // DISK_LOG
// status phase
Status();
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// MODE SENSE // MODE SENSE
@ -622,9 +710,9 @@ void FASTCALL SCSIDEV::CmdModeSense()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "MODE SENSE Command "); Log(Log::Normal, "SCSI - MODE SENSE Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -637,8 +725,7 @@ void FASTCALL SCSIDEV::CmdModeSense()
ctrl.length = ctrl.unit[lun]->ModeSense(ctrl.cmd, ctrl.buffer); ctrl.length = ctrl.unit[lun]->ModeSense(ctrl.cmd, ctrl.buffer);
ASSERT(ctrl.length >= 0); ASSERT(ctrl.length >= 0);
if (ctrl.length == 0) { if (ctrl.length == 0) {
Log(Log::Warning, Log(Log::Warning,"SCSI - Not supported MODE SENSE page $%02X", ctrl.cmd[2]);
"Not supported MODE SENSE page $%02X", ctrl.cmd[2]);
// Failure (Error) // Failure (Error)
Error(); Error();
@ -661,9 +748,9 @@ void FASTCALL SCSIDEV::CmdStartStop()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "START STOP UNIT Command "); Log(Log::Normal, "SCSI - START STOP UNIT Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -696,9 +783,9 @@ void FASTCALL SCSIDEV::CmdSendDiag()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "SEND DIAGNOSTIC Command "); Log(Log::Normal, "SCSI - SEND DIAGNOSTIC Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -731,9 +818,9 @@ void FASTCALL SCSIDEV::CmdRemoval()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "PREVENT/ALLOW MEDIUM REMOVAL Command "); Log(Log::Normal, "SCSI - PREVENT/ALLOW MEDIUM REMOVAL Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -766,9 +853,9 @@ void FASTCALL SCSIDEV::CmdReadCapacity()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "READ CAPACITY Command "); Log(Log::Normal, "SCSI - READ CAPACITY Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -829,9 +916,9 @@ void FASTCALL SCSIDEV::CmdRead10()
ctrl.blocks <<= 8; ctrl.blocks <<= 8;
ctrl.blocks |= ctrl.cmd[8]; ctrl.blocks |= ctrl.cmd[8];
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "READ(10) command record=%08X block=%d", record, ctrl.blocks); Log(Log::Normal, "SCSI - READ(10) command record=%08X block=%d", record, ctrl.blocks);
#endif // DISK_LOG #endif // DISK_LOG
// Do not process 0 blocks // Do not process 0 blocks
if (ctrl.blocks == 0) { if (ctrl.blocks == 0) {
@ -891,10 +978,9 @@ void FASTCALL SCSIDEV::CmdWrite10()
ctrl.blocks <<= 8; ctrl.blocks <<= 8;
ctrl.blocks |= ctrl.cmd[8]; ctrl.blocks |= ctrl.cmd[8];
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, Log(Log::Normal,"SCSI - WRTIE(10) command record=%08X blocks=%d", record, ctrl.blocks);
"WRTIE(10) command record=%08X blocks=%d", record, ctrl.blocks); #endif // DISK_LOG
#endif // DISK_LOG
// Do not process 0 blocks // Do not process 0 blocks
if (ctrl.blocks == 0) { if (ctrl.blocks == 0) {
@ -929,9 +1015,9 @@ void FASTCALL SCSIDEV::CmdSeek10()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "SEEK(10) Command "); Log(Log::Normal, "SCSI - SEEK(10) Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -984,10 +1070,9 @@ void FASTCALL SCSIDEV::CmdVerify()
ctrl.blocks <<= 8; ctrl.blocks <<= 8;
ctrl.blocks |= ctrl.cmd[8]; ctrl.blocks |= ctrl.cmd[8];
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, Log(Log::Normal,"SCSI - VERIFY command record=%08X blocks=%d", record, ctrl.blocks);
"VERIFY command record=%08X blocks=%d", record, ctrl.blocks); #endif // DISK_LOG
#endif // DISK_LOG
// Do not process 0 blocks // Do not process 0 blocks
if (ctrl.blocks == 0) { if (ctrl.blocks == 0) {
@ -1057,12 +1142,11 @@ void FASTCALL SCSIDEV::CmdSynchronizeCache()
void FASTCALL SCSIDEV::CmdReadDefectData10() void FASTCALL SCSIDEV::CmdReadDefectData10()
{ {
DWORD lun; DWORD lun;
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "READ DEFECT DATA(10) Command "); Log(Log::Normal, "SCSI - READ DEFECT DATA(10) Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -1092,7 +1176,6 @@ void FASTCALL SCSIDEV::CmdReadDefectData10()
void FASTCALL SCSIDEV::CmdReadToc() void FASTCALL SCSIDEV::CmdReadToc()
{ {
DWORD lun; DWORD lun;
ASSERT(this); ASSERT(this);
// Logical Unit // Logical Unit
@ -1218,9 +1301,9 @@ void FASTCALL SCSIDEV::CmdModeSelect10()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "MODE SELECT10 Command "); Log(Log::Normal, "SCSI - MODE SELECT10 Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -1252,9 +1335,9 @@ void FASTCALL SCSIDEV::CmdModeSense10()
ASSERT(this); ASSERT(this);
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "MODE SENSE(10) Command "); Log(Log::Normal, "SCSI - MODE SENSE(10) Command ");
#endif // DISK_LOG #endif // DISK_LOG
// Logical Unit // Logical Unit
lun = (ctrl.cmd[1] >> 5) & 0x07; lun = (ctrl.cmd[1] >> 5) & 0x07;
@ -1267,8 +1350,7 @@ void FASTCALL SCSIDEV::CmdModeSense10()
ctrl.length = ctrl.unit[lun]->ModeSense10(ctrl.cmd, ctrl.buffer); ctrl.length = ctrl.unit[lun]->ModeSense10(ctrl.cmd, ctrl.buffer);
ASSERT(ctrl.length >= 0); ASSERT(ctrl.length >= 0);
if (ctrl.length == 0) { if (ctrl.length == 0) {
Log(Log::Warning, Log(Log::Warning,"SCSI - Not supported MODE SENSE(10) page $%02X", ctrl.cmd[2]);
"Not supported MODE SENSE(10) page $%02X", ctrl.cmd[2]);
// Failure (Error) // Failure (Error)
Error(); Error();
@ -1394,16 +1476,16 @@ void FASTCALL SCSIDEV::CmdSendMessage10()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void FASTCALL SCSIDEV::Send() void FASTCALL SCSIDEV::Send()
{ {
#ifdef RASCSI #ifdef RASCSI
int len; int len;
#endif // RASCSI #endif // RASCSI
BOOL result; BOOL result;
ASSERT(this); ASSERT(this);
ASSERT(!ctrl.bus->GetREQ()); ASSERT(!ctrl.bus->GetREQ());
ASSERT(ctrl.bus->GetIO()); ASSERT(ctrl.bus->GetIO());
#ifdef RASCSI #ifdef RASCSI
//if Length! = 0, send //if Length! = 0, send
if (ctrl.length != 0) { if (ctrl.length != 0) {
len = ctrl.bus->SendHandShake( len = ctrl.bus->SendHandShake(
@ -1420,20 +1502,20 @@ void FASTCALL SCSIDEV::Send()
ctrl.length = 0; ctrl.length = 0;
return; return;
} }
#else #else
// offset and length // offset and length
ASSERT(ctrl.length >= 1); ASSERT(ctrl.length >= 1);
ctrl.offset++; ctrl.offset++;
ctrl.length--; ctrl.length--;
// Immediately after ACK is asserted, if the data has been // Immediately after ACK is asserted, if the data has been
// set by SendNext, raise the request // set by SendNext, raise the request
if (ctrl.length != 0) { if (ctrl.length != 0) {
// Signal line operated by the target // Signal line operated by the target
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
return; return;
} }
#endif // RASCSI #endif // RASCSI
// Block subtraction, result initialization // Block subtraction, result initialization
ctrl.blocks--; ctrl.blocks--;
@ -1442,11 +1524,11 @@ void FASTCALL SCSIDEV::Send()
// Processing after data collection (read/data-in only) // Processing after data collection (read/data-in only)
if (ctrl.phase == BUS::datain) { if (ctrl.phase == BUS::datain) {
if (ctrl.blocks != 0) { if (ctrl.blocks != 0) {
// // set next buffer (set offset, length) // set next buffer (set offset, length)
result = XferIn(ctrl.buffer); result = XferIn(ctrl.buffer);
#ifndef RASCSI #ifndef RASCSI
ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]);
#endif // RASCSI #endif // RASCSI
} }
} }
@ -1460,10 +1542,10 @@ void FASTCALL SCSIDEV::Send()
if (ctrl.blocks != 0){ if (ctrl.blocks != 0){
ASSERT(ctrl.length > 0); ASSERT(ctrl.length > 0);
ASSERT(ctrl.offset == 0); ASSERT(ctrl.offset == 0);
#ifndef RASCSI #ifndef RASCSI
// Signal line operated by the target // Signal line operated by the target
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
#endif // RASCSI #endif // RASCSI
return; return;
} }
@ -1556,9 +1638,9 @@ void FASTCALL SCSIDEV::Receive()
// Command phase // Command phase
case BUS::command: case BUS::command:
ctrl.cmd[ctrl.offset] = data; ctrl.cmd[ctrl.offset] = data;
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Command phase $%02X", data); Log(Log::Normal, "SCSI - Command phase $%02X", data);
#endif // DISK_LOG #endif // DISK_LOG
// Set the length again with the first data (offset 0) // Set the length again with the first data (offset 0)
if (ctrl.offset == 0) { if (ctrl.offset == 0) {
@ -1572,9 +1654,9 @@ void FASTCALL SCSIDEV::Receive()
// Message out phase // Message out phase
case BUS::msgout: case BUS::msgout:
ctrl.message = data; ctrl.message = data;
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Message out phase $%02X", data); Log(Log::Normal, "SCSI - Message out phase $%02X", data);
#endif // DISK_LOG #endif // DISK_LOG
break; break;
// Data out phase // Data out phase
@ -1598,6 +1680,7 @@ void FASTCALL SCSIDEV::Receive()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void FASTCALL SCSIDEV::Receive() void FASTCALL SCSIDEV::Receive()
#else #else
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// Continue receiving data // Continue receiving data
@ -1606,9 +1689,9 @@ void FASTCALL SCSIDEV::Receive()
void FASTCALL SCSIDEV::ReceiveNext() void FASTCALL SCSIDEV::ReceiveNext()
#endif // RASCSI #endif // RASCSI
{ {
#ifdef RASCSI #ifdef RASCSI
int len; int len;
#endif // RASCSI #endif // RASCSI
BOOL result; BOOL result;
int i; int i;
BYTE data; BYTE data;
@ -1619,7 +1702,7 @@ void FASTCALL SCSIDEV::ReceiveNext()
ASSERT(!ctrl.bus->GetREQ()); ASSERT(!ctrl.bus->GetREQ());
ASSERT(!ctrl.bus->GetIO()); ASSERT(!ctrl.bus->GetIO());
#ifdef RASCSI #ifdef RASCSI
// Length != 0 if received // Length != 0 if received
if (ctrl.length != 0) { if (ctrl.length != 0) {
// Receive // Receive
@ -1637,7 +1720,7 @@ void FASTCALL SCSIDEV::ReceiveNext()
ctrl.length = 0;; ctrl.length = 0;;
return; return;
} }
#else #else
// Offset and Length // Offset and Length
ASSERT(ctrl.length >= 1); ASSERT(ctrl.length >= 1);
ctrl.offset++; ctrl.offset++;
@ -1649,7 +1732,7 @@ void FASTCALL SCSIDEV::ReceiveNext()
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
return; return;
} }
#endif // RASCSI #endif // RASCSI
// Block subtraction, result initialization // Block subtraction, result initialization
ctrl.blocks--; ctrl.blocks--;
@ -1696,10 +1779,10 @@ void FASTCALL SCSIDEV::ReceiveNext()
if (ctrl.blocks != 0){ if (ctrl.blocks != 0){
ASSERT(ctrl.length > 0); ASSERT(ctrl.length > 0);
ASSERT(ctrl.offset == 0); ASSERT(ctrl.offset == 0);
#ifndef RASCSI #ifndef RASCSI
// Signal line operated by the target // Signal line operated by the target
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
#endif // RASCSI #endif // RASCSI
return; return;
} }
@ -1707,7 +1790,7 @@ void FASTCALL SCSIDEV::ReceiveNext()
switch (ctrl.phase) { switch (ctrl.phase) {
// Command phase // Command phase
case BUS::command: case BUS::command:
#ifdef RASCSI #ifdef RASCSI
// Command data transfer // Command data transfer
len = 6; len = 6;
if (ctrl.buffer[0] >= 0x20 && ctrl.buffer[0] <= 0x7D) { if (ctrl.buffer[0] >= 0x20 && ctrl.buffer[0] <= 0x7D) {
@ -1716,11 +1799,11 @@ void FASTCALL SCSIDEV::ReceiveNext()
} }
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
ctrl.cmd[i] = (DWORD)ctrl.buffer[i]; ctrl.cmd[i] = (DWORD)ctrl.buffer[i];
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, "Command $%02X", ctrl.cmd[i]); Log(Log::Normal, "SCSI - Command $%02X", ctrl.cmd[i]);
#endif // DISK_LOG #endif // DISK_LOG
} }
#endif // RASCSI #endif // RASCSI
// Execution Phase // Execution Phase
Execute(); Execute();
@ -1734,10 +1817,10 @@ void FASTCALL SCSIDEV::ReceiveNext()
ctrl.offset = 0; ctrl.offset = 0;
ctrl.length = 1; ctrl.length = 1;
ctrl.blocks = 1; ctrl.blocks = 1;
#ifndef RASCSI #ifndef RASCSI
// Request message // Request message
ctrl.bus->SetREQ(TRUE); ctrl.bus->SetREQ(TRUE);
#endif // RASCSI #endif // RASCSI
return; return;
} }
@ -1750,20 +1833,18 @@ void FASTCALL SCSIDEV::ReceiveNext()
// ABORT // ABORT
if (data == 0x06) { if (data == 0x06) {
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, Log(Log::Normal,"SCSI - Message code ABORT $%02X", data);
"Message code ABORT $%02X", data); #endif // DISK_LOG
#endif // DISK_LOG
BusFree(); BusFree();
return; return;
} }
// BUS DEVICE RESET // BUS DEVICE RESET
if (data == 0x0C) { if (data == 0x0C) {
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, Log(Log::Normal,"SCSI - Message code BUS DEVICE RESET $%02X", data);
"Message code BUS DEVICE RESET $%02X", data); #endif // DISK_LOG
#endif // DISK_LOG
scsi.syncoffset = 0; scsi.syncoffset = 0;
BusFree(); BusFree();
return; return;
@ -1771,18 +1852,16 @@ void FASTCALL SCSIDEV::ReceiveNext()
// IDENTIFY // IDENTIFY
if (data >= 0x80) { if (data >= 0x80) {
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, Log(Log::Normal,"SCSI - Message code IDENTIFY $%02X", data);
"Message code IDENTIFY $%02X", data); #endif // DISK_LOG
#endif // DISK_LOG
} }
// Extended Message // Extended Message
if (data == 0x01) { if (data == 0x01) {
#if defined(DISK_LOG) #if defined(DISK_LOG)
Log(Log::Normal, Log(Log::Normal,"SCSI - Message code EXTENDED MESSAGE $%02X", data);
"Message code EXTENDED MESSAGE $%02X", data); #endif // DISK_LOG
#endif // DISK_LOG
// Check only when synchronous transfer is possible // Check only when synchronous transfer is possible
if (!scsi.syncenable || scsi.msb[i + 2] != 0x01) { if (!scsi.syncenable || scsi.msb[i + 2] != 0x01) {

View File

@ -5,12 +5,12 @@
// //
// Copyright (C) 2001-2006 (ytanaka@ipc-tokai.or.jp) // Copyright (C) 2001-2006 (ytanaka@ipc-tokai.or.jp)
// Copyright (C) 2014-2020 GIMONS // Copyright (C) 2014-2020 GIMONS
// Copyright (C) akuker // Copyright (C) akuker
// //
// Licensed under the BSD 3-Clause License. // Licensed under the BSD 3-Clause License.
// See LICENSE file in the project root folder. // See LICENSE file in the project root folder.
// //
// [ SCSI device controller ] // [ SCSI device controller ]
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#pragma once #pragma once
@ -43,100 +43,66 @@ public:
#ifdef RASCSI #ifdef RASCSI
SCSIDEV(); SCSIDEV();
#else #else
SCSIDEV(Device *dev); SCSIDEV(Device *dev); // Constructor
#endif // RASCSI #endif // RASCSI
// Constructor
void FASTCALL Reset(); void FASTCALL Reset(); // Device Reset
// Device Reset
// 外部API // 外部API
BUS::phase_t FASTCALL Process(); BUS::phase_t FASTCALL Process(); // Run
// Run
void FASTCALL SyncTransfer(BOOL enable) { scsi.syncenable = enable; } void FASTCALL SyncTransfer(BOOL enable) { scsi.syncenable = enable; } // Synchronouse transfer enable setting
// Synchronouse transfer enable setting
// Other // Other
BOOL FASTCALL IsSASI() const {return FALSE;} BOOL FASTCALL IsSASI() const {return FALSE;} // SASI Check
// SASI Check BOOL FASTCALL IsSCSI() const {return TRUE;} // SCSI check
BOOL FASTCALL IsSCSI() const {return TRUE;}
// SCSI check
private: private:
// Phase // Phase
void FASTCALL BusFree(); void FASTCALL BusFree(); // Bus free phase
// Bus free phase void FASTCALL Selection(); // Selection phase
void FASTCALL Selection(); void FASTCALL Execute(); // Execution phase
// Selection phase void FASTCALL MsgOut(); // Message out phase
void FASTCALL Execute(); void FASTCALL Error(); // Common erorr handling
// Execution phase
void FASTCALL MsgOut();
// Message out phase
void FASTCALL Error();
// Common erorr handling
// commands // commands
void FASTCALL CmdInquiry(); void FASTCALL CmdInquiry(); // INQUIRY command
// INQUIRY command void FASTCALL CmdModeSelect(); // MODE SELECT command
void FASTCALL CmdModeSelect(); void FASTCALL CmdReserve6(); // RESERVE(6) command
// MODE SELECT command void FASTCALL CmdReserve10(); // RESERVE(10) command
void FASTCALL CmdModeSense(); void FASTCALL CmdRelease6(); // RELEASE(6) command
// MODE SENSE command void FASTCALL CmdRelease10(); // RELEASE(10) command
void FASTCALL CmdStartStop(); void FASTCALL CmdModeSense(); // MODE SENSE command
// START STOP UNIT command void FASTCALL CmdStartStop(); // START STOP UNIT command
void FASTCALL CmdSendDiag(); void FASTCALL CmdSendDiag(); // SEND DIAGNOSTIC command
// SEND DIAGNOSTIC command void FASTCALL CmdRemoval(); // PREVENT/ALLOW MEDIUM REMOVAL command
void FASTCALL CmdRemoval(); void FASTCALL CmdReadCapacity(); // READ CAPACITY command
// PREVENT/ALLOW MEDIUM REMOVAL command void FASTCALL CmdRead10(); // READ(10) command
void FASTCALL CmdReadCapacity(); void FASTCALL CmdWrite10(); // WRITE(10) command
// READ CAPACITY command void FASTCALL CmdSeek10(); // SEEK(10) command
void FASTCALL CmdRead10(); void FASTCALL CmdVerify(); // VERIFY command
// READ(10) command void FASTCALL CmdSynchronizeCache(); // SYNCHRONIZE CACHE command
void FASTCALL CmdWrite10(); void FASTCALL CmdReadDefectData10(); // READ DEFECT DATA(10) command
// WRITE(10) command void FASTCALL CmdReadToc(); // READ TOC command
void FASTCALL CmdSeek10(); void FASTCALL CmdPlayAudio10(); // PLAY AUDIO(10) command
// SEEK(10) command void FASTCALL CmdPlayAudioMSF(); // PLAY AUDIO MSF command
void FASTCALL CmdVerify(); void FASTCALL CmdPlayAudioTrack(); // PLAY AUDIO TRACK INDEX command
// VERIFY command void FASTCALL CmdModeSelect10(); // MODE SELECT(10) command
void FASTCALL CmdSynchronizeCache(); void FASTCALL CmdModeSense10(); // MODE SENSE(10) command
// SYNCHRONIZE CACHE command void FASTCALL CmdGetMessage10(); // GET MESSAGE(10) command
void FASTCALL CmdReadDefectData10(); void FASTCALL CmdSendMessage10(); // SEND MESSAGE(10) command
// READ DEFECT DATA(10) command
void FASTCALL CmdReadToc();
// READ TOC command
void FASTCALL CmdPlayAudio10();
// PLAY AUDIO(10) command
void FASTCALL CmdPlayAudioMSF();
// PLAY AUDIO MSF command
void FASTCALL CmdPlayAudioTrack();
// PLAY AUDIO TRACK INDEX command
void FASTCALL CmdModeSelect10();
// MODE SELECT(10) command
void FASTCALL CmdModeSense10();
// MODE SENSE(10) command
void FASTCALL CmdGetMessage10();
// GET MESSAGE(10) command
void FASTCALL CmdSendMessage10();
// SEND MESSAGE(10) command
// データ転送 // データ転送
void FASTCALL Send(); void FASTCALL Send(); // Send data
// Send data #ifndef RASCSI
#ifndef RASCSI void FASTCALL SendNext(); // Continue sending data
void FASTCALL SendNext(); #endif // RASCSI
// Continue sending data void FASTCALL Receive(); // Receive data
#endif // RASCSI #ifndef RASCSI
void FASTCALL Receive(); void FASTCALL ReceiveNext(); // Continue receiving data
// Receive data #endif // RASCSI
#ifndef RASCSI BOOL FASTCALL XferMsg(DWORD msg); // Data transfer message
void FASTCALL ReceiveNext();
// Continue receiving data
#endif // RASCSI
BOOL FASTCALL XferMsg(DWORD msg);
// Data transfer message
scsi_t scsi; scsi_t scsi; // Internal data
// Internal data
}; };