2018-05-03 13:47:57 +00:00
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
//
|
2022-10-08 17:26:04 +00:00
|
|
|
|
// X68000 EMULATOR "XM6"
|
2018-05-03 13:47:57 +00:00
|
|
|
|
//
|
2022-10-08 17:26:04 +00:00
|
|
|
|
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
|
|
|
|
// Copyright (C) 2014-2020 GIMONS
|
|
|
|
|
// Copyright (C) 2022 Uwe Seimet
|
2022-12-03 04:20:27 +00:00
|
|
|
|
// Copyright (C) 2022 akuker
|
2018-05-03 13:47:57 +00:00
|
|
|
|
//
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
2022-10-04 15:23:42 +00:00
|
|
|
|
#include "bus.h"
|
2018-05-03 13:47:57 +00:00
|
|
|
|
|
2022-09-21 06:27:51 +00:00
|
|
|
|
using namespace std;
|
2022-11-06 18:44:44 +00:00
|
|
|
|
using namespace scsi_defs;
|
2022-09-21 06:27:51 +00:00
|
|
|
|
|
2022-11-02 14:36:19 +00:00
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Get the number of bytes for a command
|
|
|
|
|
//
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
int BUS::GetCommandByteCount(uint8_t opcode)
|
|
|
|
|
{
|
2022-11-06 18:44:44 +00:00
|
|
|
|
const auto& mapping = command_mapping.find(static_cast<scsi_command>(opcode));
|
|
|
|
|
|
|
|
|
|
return mapping != command_mapping.end() ? mapping->second.first : 0;
|
2022-11-02 14:36:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-05-03 13:47:57 +00:00
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
//
|
2020-07-05 16:47:17 +00:00
|
|
|
|
// Phase Acquisition
|
2018-05-03 13:47:57 +00:00
|
|
|
|
//
|
|
|
|
|
//---------------------------------------------------------------------------
|
2022-12-03 04:20:27 +00:00
|
|
|
|
phase_t BUS::GetPhase()
|
2018-05-03 13:47:57 +00:00
|
|
|
|
{
|
2020-07-05 16:47:17 +00:00
|
|
|
|
// Selection Phase
|
2018-05-03 13:47:57 +00:00
|
|
|
|
if (GetSEL()) {
|
2022-09-21 06:27:51 +00:00
|
|
|
|
return phase_t::selection;
|
2018-05-03 13:47:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-07-05 16:47:17 +00:00
|
|
|
|
// Bus busy phase
|
2018-05-03 13:47:57 +00:00
|
|
|
|
if (!GetBSY()) {
|
2022-09-21 06:27:51 +00:00
|
|
|
|
return phase_t::busfree;
|
2018-05-03 13:47:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-07-05 16:47:17 +00:00
|
|
|
|
// Get target phase from bus signal line
|
2022-10-08 17:26:04 +00:00
|
|
|
|
int mci = GetMSG() ? 0b100 : 0b000;
|
|
|
|
|
mci |= GetCD() ? 0b010 : 0b000;
|
|
|
|
|
mci |= GetIO() ? 0b001 : 0b000;
|
2018-05-03 13:47:57 +00:00
|
|
|
|
return GetPhase(mci);
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-19 12:31:06 +00:00
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Determine Phase String phase enum
|
|
|
|
|
//
|
|
|
|
|
//---------------------------------------------------------------------------
|
2022-10-04 15:23:42 +00:00
|
|
|
|
const char* BUS::GetPhaseStrRaw(phase_t current_phase) {
|
|
|
|
|
const auto& it = phase_str_mapping.find(current_phase);
|
|
|
|
|
return it != phase_str_mapping.end() ? it->second : "INVALID";
|
2020-10-19 12:31:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-14 15:03:25 +00:00
|
|
|
|
// Phase Table
|
|
|
|
|
// Reference Table 8: https://www.staff.uni-mainz.de/tacke/scsi/SCSI2-06.html
|
|
|
|
|
// This determines the phase based upon the Msg, C/D and I/O signals.
|
2018-05-03 13:47:57 +00:00
|
|
|
|
//
|
2023-11-14 15:03:25 +00:00
|
|
|
|
// |MSG|C/D|I/O| Phase
|
|
|
|
|
// | 0 | 0 | 0 | DATA OUT
|
|
|
|
|
// | 0 | 0 | 1 | DATA IN
|
|
|
|
|
// | 0 | 1 | 0 | COMMAND
|
|
|
|
|
// | 0 | 1 | 1 | STATUS
|
|
|
|
|
// | 1 | 0 | 0 | RESERVED
|
|
|
|
|
// | 1 | 0 | 1 | RESERVED
|
|
|
|
|
// | 1 | 1 | 0 | MESSAGE OUT
|
|
|
|
|
// | 1 | 1 | 1 | MESSAGE IN
|
2022-12-03 04:20:27 +00:00
|
|
|
|
const array<phase_t, 8> BUS::phase_table = {
|
2023-11-14 15:03:25 +00:00
|
|
|
|
phase_t::dataout,
|
|
|
|
|
phase_t::datain,
|
|
|
|
|
phase_t::command,
|
|
|
|
|
phase_t::status,
|
|
|
|
|
phase_t::reserved,
|
|
|
|
|
phase_t::reserved,
|
|
|
|
|
phase_t::msgout,
|
|
|
|
|
phase_t::msgin
|
2020-10-19 12:31:06 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
//
|
2022-10-04 15:23:42 +00:00
|
|
|
|
// Phase string to phase mapping
|
2020-10-19 12:31:06 +00:00
|
|
|
|
//
|
|
|
|
|
//---------------------------------------------------------------------------
|
2022-12-03 04:20:27 +00:00
|
|
|
|
const unordered_map<phase_t, const char*> BUS::phase_str_mapping = {
|
2022-10-04 15:23:42 +00:00
|
|
|
|
{ phase_t::busfree, "busfree" },
|
|
|
|
|
{ phase_t::arbitration, "arbitration" },
|
|
|
|
|
{ phase_t::selection, "selection" },
|
|
|
|
|
{ phase_t::reselection, "reselection" },
|
|
|
|
|
{ phase_t::command, "command" },
|
|
|
|
|
{ phase_t::datain, "datain" },
|
|
|
|
|
{ phase_t::dataout, "dataout" },
|
|
|
|
|
{ phase_t::status, "status" },
|
|
|
|
|
{ phase_t::msgin, "msgin" },
|
|
|
|
|
{ phase_t::msgout, "msgout" },
|
|
|
|
|
{ phase_t::reserved, "reserved" }
|
2018-05-03 13:47:57 +00:00
|
|
|
|
};
|