97 unsigned id =
t->getAttributeValueAsInt(
"id", 0);
100 "Invalid SCSI id: ",
id,
101 " (should be 0..", MAX_DEV - 1,
')');
107 auto type =
t->getChildData(
"type");
108 if (type ==
"SCSIHD") {
109 dev[
id] = std::make_unique<SCSIHD>(conf, buffer,
111 }
else if (type ==
"SCSILS120") {
112 dev[
id] = std::make_unique<SCSILS120>(conf, buffer,
119 for (
auto& d : dev) {
120 if (!d) d = std::make_unique<DummySCSIDevice>();
132 void MB89352::disconnect()
135 assert(targetId < MAX_DEV);
136 dev[targetId]->disconnect();
150 void MB89352::softReset()
154 for (
auto i :
xrange(2, 15)) {
158 memset(cdb, 0,
sizeof(cdb));
177 for (
auto& d : dev) {
183 void MB89352::setACKREQ(
byte& value)
208 value = buffer[bufIdx];
214 buffer[bufIdx] = value;
223 counter = (value < 0x20) ? 6 : ((value < 0xA0) ? 10 : 12);
231 value = dev[targetId]->getStatusCode();
236 value = dev[targetId]->msgIn();
241 msgin |= dev[targetId]->msgOut(value);
251 void MB89352::resetACKREQ()
273 if (blockCounter > 0) {
274 counter = dev[targetId]->dataIn(blockCounter);
290 counter = dev[targetId]->dataOut(blockCounter);
307 counter = dev[targetId]->executeCmd(cdb, phase, blockCounter);
407 if (isTransfer && (tc > 0)) {
425 if (isTransfer && (tc > 0)) {
455 for (
auto& d : dev) {
509 assert(targetId < MAX_DEV);
512 if ( dev[targetId]->isSelected()) {
583 tc = (tc & 0xFFFF00) + (value << 0);
587 tc = (tc & 0xFF00FF) + (value << 8);
591 tc = (tc & 0x00FFFF) + (value << 16);
615 bool flag = !(value & 0xE0);
616 if (flag != isEnabled) {
629 byte MB89352::getSSTS()
const
669 counter = dev[targetId]->executingCmd(phase, blockCounter);
703 if (isTransfer && (tc > 0)) {
720 return (tc >> 16) & 0xFF;
722 return (tc >> 8) & 0xFF;
724 return (tc >> 0) & 0xFF;
732 static constexpr std::initializer_list<enum_string<SCSI::Phase>> phaseInfo = {
748 template<
typename Archive>
751 ar.serialize_blob(
"buffer", buffer.
data(), buffer.
size());
752 char tag[8] = {
'd',
'e',
'v',
'i',
'c',
'e',
'X', 0 };
754 tag[6] = char(
'0' + i);
755 ar.serializePolymorphic(tag, *d);
757 ar.serialize(
"bufIdx", bufIdx,
760 "blockCounter", blockCounter,
763 "nextPhase", nextPhase,
765 "targetId", targetId);
766 ar.serialize_blob(
"registers", regs,
sizeof(regs));
767 ar.serialize(
"rst", rst,
769 "isEnabled", isEnabled,
771 "isTransfer", isTransfer,
773 ar.serialize_blob(
"cdb", cdb,
sizeof(cdb));
const XMLElement * getXML() const
void writeDREG(byte value)
byte peekRegister(byte reg) const
void writeRegister(byte reg, byte value)
byte readRegister(byte reg)
void reset(bool scsireset)
void serialize(Archive &ar, unsigned version)
MB89352(const DeviceConfig &config)
static constexpr unsigned BUFFER_SIZE
static constexpr unsigned MODE_MEGASCSI
static constexpr unsigned MODE_SCSI2
ChildRange getChildren() const
constexpr auto enumerate(Iterable &&iterable)
Heavily inspired by Nathan Reed's blog post: Python-Like enumerate() In C++17 http://reedbeta....
This file implemented 3 utility functions:
constexpr byte REG_TEMPWR
constexpr byte INTS_ResetCondition
constexpr byte CMD_Set_ACK_REQ
constexpr byte PSNS_MSGOUT
constexpr byte PSNS_SELECTION
SERIALIZE_ENUM(CassettePlayer::State, stateInfo)
constexpr byte INTS_CommandComplete
constexpr byte CMD_ResetATN
constexpr byte CMD_TransferPause
constexpr byte PSNS_MSGIN
constexpr byte PSNS_STATUS
constexpr byte CMD_Reset_ACK_REQ
constexpr byte CMD_SetATN
constexpr byte PSNS_DATAIN
constexpr byte INTS_TimeOut
constexpr byte INTS_ServiceRequited
constexpr byte CMD_Select
constexpr KeyMatrixPosition x
Keyboard bindings.
constexpr byte INTS_ReSelected
constexpr byte INTS_Disconnected
constexpr byte INTS_Selected
constexpr byte PSNS_COMMAND
constexpr byte PSNS_DATAOUT
constexpr byte CMD_BusRelease
constexpr byte INTS_SPC_HardError
constexpr byte CMD_Transfer
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
constexpr auto xrange(T e)