114 unsigned id =
t->getAttributeValueAsInt(
"id", 0);
117 " (should be 0..",
MAX_DEV - 1,
')');
123 auto type =
t->getChildData(
"type");
124 if (type ==
"SCSIHD") {
125 dev[
id] = std::make_unique<SCSIHD>(conf, buffer,
128 }
else if (type ==
"SCSILS120") {
129 dev[
id] = std::make_unique<SCSILS120>(conf, buffer,
137 for (
auto& d : dev) {
138 if (!d) d = std::make_unique<DummySCSIDevice>();
146 void WD33C93::disconnect()
150 dev[targetId]->disconnect();
160 void WD33C93::execCmd(
byte value)
172 memset(regs + 1, 0, 0x1a);
202 if (!devBusy && targetId <
MAX_DEV &&
203 dev[targetId]->isSelected()) {
205 dev[targetId]->msgOut(regs[
REG_TLUN] | 0x80);
208 counter = dev[targetId]->executeCmd(
209 ®s[
REG_CDB1], phase, blockCounter);
214 regs[
REG_TLUN] = dev[targetId]->getStatusCode();
215 dev[targetId]->msgIn();
248 latch = value & 0x1f;
262 tc = (tc & 0x00ffff) + (value << 16);
266 tc = (tc & 0xff00ff) + (value << 8);
270 tc = (tc & 0xffff00) + (value << 0);
284 buffer[bufIdx++] = value;
286 if (--counter == 0) {
287 counter = dev[targetId]->dataOut(blockCounter);
292 regs[
REG_TLUN] = dev[targetId]->getStatusCode();
293 dev[targetId]->msgIn();
309 latch = (latch + 1) & 0x1f;
317 counter = dev[targetId]->executingCmd(phase, blockCounter);
321 regs[
REG_TLUN] = dev[targetId]->getStatusCode();
322 dev[targetId]->msgIn();
358 rv = buffer[bufIdx++];
361 if (--counter == 0) {
362 if (blockCounter > 0) {
363 counter = dev[targetId]->dataIn(blockCounter);
369 regs[
REG_TLUN] = dev[targetId]->getStatusCode();
370 dev[targetId]->msgIn();
380 rv = (tc >> 16) & 0xff;
384 rv = (tc >> 8) & 0xff;
388 rv = (tc >> 0) & 0xff;
399 latch = (latch + 1) & 0x1f;
412 return (tc >> 16) & 0xff;
414 return (tc >> 8) & 0xff;
416 return (tc >> 0) & 0xff;
425 memset(regs, 0, 0x1b);
426 memset(regs + 0x1b, 0xff, 4);
434 for (
auto& d : dev) {
441 static constexpr std::initializer_list<enum_string<SCSI::Phase>> phaseInfo = {
457 template<
typename Archive>
460 ar.serialize_blob(
"buffer", buffer.
data(), buffer.
size());
461 char tag[8] = {
'd',
'e',
'v',
'i',
'c',
'e',
'X', 0 };
463 tag[6] = char(
'0' + i);
464 ar.serializePolymorphic(tag, *d);
466 ar.serialize(
"bufIdx", bufIdx,
468 "blockCounter", blockCounter,
472 "targetId", targetId);
473 ar.serialize_blob(
"registers", regs,
sizeof(regs));
474 ar.serialize(
"latch", latch,
const XMLElement * getXML() const
static constexpr unsigned BUFFER_SIZE
static constexpr unsigned MODE_NOVAXIS
static constexpr unsigned MODE_SCSI1
static constexpr unsigned MODE_UNITATTENTION
void serialize(Archive &ar, unsigned version)
void reset(bool scsireset)
byte peekAuxStatus() const
WD33C93(const DeviceConfig &config)
void writeCtrl(byte value)
void writeAdr(byte value)
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_CYLNO_LO
constexpr byte REG_SRC_ID
constexpr byte REG_DST_ID
constexpr byte REG_ADDR_3
constexpr byte SS_SEL_TIMEOUT
constexpr byte SS_RESET_ADV
constexpr byte REG_ADDR_LO
SERIALIZE_ENUM(CassettePlayer::State, stateInfo)
constexpr byte REG_CMD_PHASE
constexpr byte SS_DISCONNECT
constexpr unsigned MAX_DEV
constexpr byte REG_THEADS
constexpr byte REG_ADDR_HI
constexpr byte REG_TCYL_HI
constexpr byte REG_CONTROL
constexpr byte REG_AUX_STATUS
constexpr byte REG_CDBSIZE
constexpr byte REG_ADDR_2
constexpr byte REG_HEADNO
constexpr byte SS_XFER_END
constexpr byte REG_TCYL_LO
constexpr byte REG_CYLNO_HI
constexpr byte REG_OWN_ID
constexpr byte REG_SCSI_STATUS
constexpr byte REG_QUEUE_TAG
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)