mirror of
https://github.com/akuker/RASCSI.git
synced 2026-04-26 06:18:10 +00:00
Added command byte count to SCSI command mapping (#966)
* Extended mapping table with command byte count * Terminate early if command is unknown
This commit is contained in:
+4
-10
@@ -11,24 +11,18 @@
|
||||
#include "bus.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace scsi_defs;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Get the number of bytes for a command
|
||||
// TODO Add the byte count to the enum value/command name mapping and remove the comparisons
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int BUS::GetCommandByteCount(uint8_t opcode)
|
||||
{
|
||||
if (opcode == 0x88 || opcode == 0x8A || opcode == 0x8F || opcode == 0x91 || opcode == 0x9E || opcode == 0x9F) {
|
||||
return 16;
|
||||
} else if (opcode == 0xA0) {
|
||||
return 12;
|
||||
} else if (opcode >= 0x20 && opcode <= 0x7D) {
|
||||
return 10;
|
||||
} else {
|
||||
return 6;
|
||||
}
|
||||
const auto& mapping = command_mapping.find(static_cast<scsi_command>(opcode));
|
||||
|
||||
return mapping != command_mapping.end() ? mapping->second.first : 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
+2
-1
@@ -12,6 +12,7 @@
|
||||
#include "scsi.h"
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
using namespace std;
|
||||
@@ -97,7 +98,7 @@ public:
|
||||
virtual bool GetDP() const = 0; // Get parity signal
|
||||
|
||||
virtual uint32_t Acquire() = 0;
|
||||
virtual int CommandHandShake(uint8_t *buf) = 0;
|
||||
virtual int CommandHandShake(vector<uint8_t>&) = 0;
|
||||
virtual int ReceiveHandShake(uint8_t *buf, int count) = 0;
|
||||
virtual int SendHandShake(uint8_t *buf, int count, int delay_after_bytes) = 0;
|
||||
|
||||
|
||||
+15
-12
@@ -431,7 +431,7 @@ bool GPIOBUS::GetDP() const
|
||||
// Receive command handshake
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int GPIOBUS::CommandHandShake(uint8_t *buf)
|
||||
int GPIOBUS::CommandHandShake(vector<uint8_t>& buf)
|
||||
{
|
||||
GPIO_FUNCTION_TRACE
|
||||
// Only works in TARGET mode
|
||||
@@ -451,7 +451,7 @@ int GPIOBUS::CommandHandShake(uint8_t *buf)
|
||||
SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS);
|
||||
|
||||
// Get data
|
||||
*buf = GetDAT();
|
||||
buf[0] = GetDAT();
|
||||
|
||||
// Disable REQ signal
|
||||
SetSignal(PIN_REQ, OFF);
|
||||
@@ -480,7 +480,7 @@ int GPIOBUS::CommandHandShake(uint8_t *buf)
|
||||
// semantics. I fact, these semantics have become a standard in the Atari world.
|
||||
|
||||
// RaSCSI becomes ICD compatible by ignoring the prepended $1F byte before processing the CDB.
|
||||
if (*buf == 0x1F) {
|
||||
if (buf[0] == 0x1F) {
|
||||
SetSignal(PIN_REQ, ON);
|
||||
|
||||
ret = WaitSignal(PIN_ACK, ON);
|
||||
@@ -488,7 +488,7 @@ int GPIOBUS::CommandHandShake(uint8_t *buf)
|
||||
SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS);
|
||||
|
||||
// Get the actual SCSI command
|
||||
*buf = GetDAT();
|
||||
buf[0] = GetDAT();
|
||||
|
||||
SetSignal(PIN_REQ, OFF);
|
||||
|
||||
@@ -505,14 +505,20 @@ int GPIOBUS::CommandHandShake(uint8_t *buf)
|
||||
}
|
||||
}
|
||||
|
||||
const int command_byte_count = GetCommandByteCount(*buf);
|
||||
const int command_byte_count = GetCommandByteCount(buf[0]);
|
||||
if (command_byte_count == 0) {
|
||||
EnableIRQ();
|
||||
|
||||
// Increment buffer pointer
|
||||
buf++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
|
||||
int bytes_received;
|
||||
for (bytes_received = 1; bytes_received < command_byte_count; bytes_received++) {
|
||||
// Assert REQ signal
|
||||
++offset;
|
||||
|
||||
// Assert REQ signal
|
||||
SetSignal(PIN_REQ, ON);
|
||||
|
||||
// Wait for ACK signal
|
||||
@@ -522,7 +528,7 @@ int GPIOBUS::CommandHandShake(uint8_t *buf)
|
||||
SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS);
|
||||
|
||||
// Get data
|
||||
*buf = GetDAT();
|
||||
buf[offset] = GetDAT();
|
||||
|
||||
// Clear the REQ signal
|
||||
SetSignal(PIN_REQ, OFF);
|
||||
@@ -539,9 +545,6 @@ int GPIOBUS::CommandHandShake(uint8_t *buf)
|
||||
if (!ret) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Advance the buffer pointer to receive the next byte
|
||||
buf++;
|
||||
}
|
||||
|
||||
EnableIRQ();
|
||||
|
||||
+2
-1
@@ -15,6 +15,7 @@
|
||||
#include "scsi.h"
|
||||
#include "bus.h"
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/gpio.h>
|
||||
@@ -332,7 +333,7 @@ class GPIOBUS : public BUS
|
||||
// Set REQ signal
|
||||
bool GetDP() const override;
|
||||
// Get Data parity signal
|
||||
int CommandHandShake(uint8_t *buf) override;
|
||||
int CommandHandShake(vector<uint8_t>&) override;
|
||||
// Command receive handshake
|
||||
int ReceiveHandShake(uint8_t *buf, int count) override;
|
||||
// Data receive handshake
|
||||
|
||||
Reference in New Issue
Block a user