mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-28 06:29:37 +00:00
Attempts to provide a data out phase.
This commit is contained in:
parent
faec516a2c
commit
2d82855f26
@ -21,7 +21,7 @@ struct Target: public ::Analyser::Static::Target {
|
||||
MacPlus
|
||||
};
|
||||
|
||||
Model model = Model::Mac512ke;
|
||||
Model model = Model::MacPlus;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include "../../Storage/MassStorage/SCSI/SCSI.hpp"
|
||||
#include "../../Storage/MassStorage/SCSI/Target.hpp"
|
||||
#include "../../Storage/MassStorage/SCSI/DirectAccessDevice.hpp"
|
||||
#include "../../ClockReceiver/ClockReceiver.hpp"
|
||||
#include "../../ClockReceiver/ClockingHintSource.hpp"
|
||||
|
||||
@ -56,7 +56,7 @@ class NCR5380 final: public ClockingHint::Source {
|
||||
// TEMPORARY. For development expediency, the 5380 owns its own
|
||||
// SCSI bus and target. These will be moved out.
|
||||
SCSI::Bus bus_;
|
||||
SCSI::Target::Target<SCSI::Target::Executor> device_;
|
||||
SCSI::Target::Target<SCSI::DirectAccessDevice> device_;
|
||||
|
||||
const int clock_rate_;
|
||||
size_t device_id_;
|
||||
|
@ -636,6 +636,8 @@
|
||||
4BC751B21D157E61006C31D9 /* 6522Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC751B11D157E61006C31D9 /* 6522Tests.swift */; };
|
||||
4BC76E691C98E31700E6EF73 /* FIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */; };
|
||||
4BC76E6B1C98F43700E6EF73 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */; };
|
||||
4BC890D3230F86020025A55A /* DirectAccessDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC890D1230F86020025A55A /* DirectAccessDevice.cpp */; };
|
||||
4BC890D4230F86020025A55A /* DirectAccessDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC890D1230F86020025A55A /* DirectAccessDevice.cpp */; };
|
||||
4BC91B831D1F160E00884B76 /* CommodoreTAP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC91B811D1F160E00884B76 /* CommodoreTAP.cpp */; };
|
||||
4BC9DF4F1D04691600F44158 /* 6560.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9DF4D1D04691600F44158 /* 6560.cpp */; };
|
||||
4BC9E1EE1D23449A003FCEE4 /* 6502InterruptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9E1ED1D23449A003FCEE4 /* 6502InterruptTests.swift */; };
|
||||
@ -1436,6 +1438,8 @@
|
||||
4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FIRFilter.cpp; sourceTree = "<group>"; };
|
||||
4BC76E681C98E31700E6EF73 /* FIRFilter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FIRFilter.hpp; sourceTree = "<group>"; };
|
||||
4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||
4BC890D1230F86020025A55A /* DirectAccessDevice.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DirectAccessDevice.cpp; sourceTree = "<group>"; };
|
||||
4BC890D2230F86020025A55A /* DirectAccessDevice.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DirectAccessDevice.hpp; sourceTree = "<group>"; };
|
||||
4BC91B811D1F160E00884B76 /* CommodoreTAP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CommodoreTAP.cpp; sourceTree = "<group>"; };
|
||||
4BC91B821D1F160E00884B76 /* CommodoreTAP.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CommodoreTAP.hpp; sourceTree = "<group>"; };
|
||||
4BC9DF441D044FCA00F44158 /* ROMImages */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ROMImages; path = ../../../../ROMImages; sourceTree = "<group>"; };
|
||||
@ -2264,10 +2268,12 @@
|
||||
4B6AAEA5230E40250078E864 /* SCSI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B6AAEA8230E40250078E864 /* Target.cpp */,
|
||||
4BC890D1230F86020025A55A /* DirectAccessDevice.cpp */,
|
||||
4B6AAEA7230E40250078E864 /* SCSI.cpp */,
|
||||
4B6AAEA6230E40250078E864 /* Target.hpp */,
|
||||
4B6AAEA8230E40250078E864 /* Target.cpp */,
|
||||
4BC890D2230F86020025A55A /* DirectAccessDevice.hpp */,
|
||||
4B6AAEA9230E40250078E864 /* SCSI.hpp */,
|
||||
4B6AAEA6230E40250078E864 /* Target.hpp */,
|
||||
4B6AAEAA230E40250078E864 /* TargetImplementation.hpp */,
|
||||
);
|
||||
path = SCSI;
|
||||
@ -4005,6 +4011,7 @@
|
||||
4B055AEE1FAE9BBF0060FFFF /* Keyboard.cpp in Sources */,
|
||||
4B055AED1FAE9BA20060FFFF /* Z80Storage.cpp in Sources */,
|
||||
4B1B88BC202E2EC100B67DFF /* MultiKeyboardMachine.cpp in Sources */,
|
||||
4BC890D4230F86020025A55A /* DirectAccessDevice.cpp in Sources */,
|
||||
4B6AAEAE230E40250078E864 /* Target.cpp in Sources */,
|
||||
4BF437EF209D0F7E008CBD6B /* SegmentParser.cpp in Sources */,
|
||||
4B055AD11FAE9B030060FFFF /* Video.cpp in Sources */,
|
||||
@ -4161,6 +4168,7 @@
|
||||
4B6AAEA4230E3E1D0078E864 /* MassStorageDevice.cpp in Sources */,
|
||||
4B89452E201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
|
||||
4BD5D2682199148100DDF17D /* ScanTargetGLSLFragments.cpp in Sources */,
|
||||
4BC890D3230F86020025A55A /* DirectAccessDevice.cpp in Sources */,
|
||||
4B38F3481F2EC11D00D9235D /* AmstradCPC.cpp in Sources */,
|
||||
4B8FE2221DA19FB20090D3CE /* MachinePanel.swift in Sources */,
|
||||
4B4518A41F75FD1C00926311 /* OricMFMDSK.cpp in Sources */,
|
||||
|
21
Storage/MassStorage/SCSI/DirectAccessDevice.cpp
Normal file
21
Storage/MassStorage/SCSI/DirectAccessDevice.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
//
|
||||
// DirectAccessDevice.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 22/08/2019.
|
||||
// Copyright © 2019 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "DirectAccessDevice.hpp"
|
||||
|
||||
using namespace SCSI;
|
||||
|
||||
bool DirectAccessDevice::read(const Target::CommandState &state, Target::Responder &responder) {
|
||||
std::vector<uint8_t> data(512);
|
||||
|
||||
responder.send_data(std::move(data), [] (const Target::CommandState &state, Target::Responder &responder) {
|
||||
responder.end_command();
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
23
Storage/MassStorage/SCSI/DirectAccessDevice.hpp
Normal file
23
Storage/MassStorage/SCSI/DirectAccessDevice.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// DirectAccessDevice.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 22/08/2019.
|
||||
// Copyright © 2019 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SCSI_DirectAccessDevice_hpp
|
||||
#define SCSI_DirectAccessDevice_hpp
|
||||
|
||||
#include "Target.hpp"
|
||||
|
||||
namespace SCSI {
|
||||
|
||||
class DirectAccessDevice: public Target::Executor {
|
||||
public:
|
||||
bool read(const Target::CommandState &, Target::Responder &);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* SCSI_DirectAccessDevice_hpp */
|
@ -1,13 +1,13 @@
|
||||
//
|
||||
// DirectAccessDevice.hpp
|
||||
// Target.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 17/08/2019.
|
||||
// Copyright © 2019 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef DirectAccessDevice_hpp
|
||||
#define DirectAccessDevice_hpp
|
||||
#ifndef SCSI_Target_hpp
|
||||
#define SCSI_Target_hpp
|
||||
|
||||
#include "SCSI.hpp"
|
||||
|
||||
@ -154,7 +154,11 @@ template <typename Executor> class Target: public Bus::Observer, public Responde
|
||||
|
||||
enum class Phase {
|
||||
AwaitingSelection,
|
||||
Command
|
||||
Command,
|
||||
ReceivingData,
|
||||
SendingData,
|
||||
SendingStatus,
|
||||
SendingMessage
|
||||
} phase_ = Phase::AwaitingSelection;
|
||||
BusState bus_state_ = DefaultBusState;
|
||||
|
||||
@ -162,6 +166,11 @@ template <typename Executor> class Target: public Bus::Observer, public Responde
|
||||
std::vector<uint8_t> command_;
|
||||
size_t command_pointer_ = 0;
|
||||
bool dispatch_command();
|
||||
|
||||
std::vector<uint8_t> data_;
|
||||
size_t data_pointer_ = 0;
|
||||
|
||||
continuation next_function_;
|
||||
};
|
||||
|
||||
#import "TargetImplementation.hpp"
|
||||
@ -169,4 +178,4 @@ template <typename Executor> class Target: public Bus::Observer, public Responde
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DirectAccessDevice_hpp */
|
||||
#endif /* SCSI_Target_hpp */
|
||||
|
@ -35,13 +35,9 @@ template <typename Executor> void Target<Executor>::scsi_bus_did_change(Bus *, B
|
||||
(new_state & scsi_id_mask_) &&
|
||||
((new_state & (Line::SelectTarget | Line::Busy | Line::Input)) == Line::SelectTarget)
|
||||
) {
|
||||
printf("Selected\n");
|
||||
phase_ = Phase::Command;
|
||||
bus_state_ |= Line::Busy; // Initiate the command phase: request a command byte.
|
||||
bus_.set_device_output(scsi_bus_device_id_, bus_state_);
|
||||
} else {
|
||||
if(!(new_state & scsi_id_mask_)) printf("No ID mask\n");
|
||||
else printf("Not SEL|~BSY|~IO");
|
||||
}
|
||||
break;
|
||||
|
||||
@ -81,6 +77,42 @@ template <typename Executor> void Target<Executor>::scsi_bus_did_change(Bus *, B
|
||||
}
|
||||
bus_.set_device_output(scsi_bus_device_id_, bus_state_);
|
||||
break;
|
||||
|
||||
case Phase::ReceivingData:
|
||||
switch(new_state & (Line::Request | Line::Acknowledge)) {
|
||||
case Line::Request | Line::Acknowledge:
|
||||
bus_state_ &= ~Line::Request;
|
||||
|
||||
data_[data_pointer_] = uint8_t(new_state);
|
||||
++data_pointer_;
|
||||
if(data_pointer_ == data_.size()) {
|
||||
next_function_(CommandState(command_), *this);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0:
|
||||
bus_state_ |= Line::Request;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case Phase::SendingData:
|
||||
switch(new_state & (Line::Request | Line::Acknowledge)) {
|
||||
case Line::Request | Line::Acknowledge:
|
||||
bus_state_ &= ~(Line::Request | 0xff);
|
||||
|
||||
++data_pointer_;
|
||||
if(data_pointer_ == data_.size()) {
|
||||
next_function_(CommandState(command_), *this);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0:
|
||||
bus_state_ |= Line::Request;
|
||||
bus_state_ = (bus_state_ & ~0xff) | data_[data_pointer_];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,8 +175,46 @@ template <typename Executor> bool Target<Executor>::dispatch_command() {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Executor> void Target<Executor>::send_data(std::vector<uint8_t> &&data, continuation next) {}
|
||||
template <typename Executor> void Target<Executor>::receive_data(size_t length, continuation next) {}
|
||||
template <typename Executor> void Target<Executor>::send_status(Status, continuation next) {}
|
||||
template <typename Executor> void Target<Executor>::send_message(Message, continuation next) {}
|
||||
template <typename Executor> void Target<Executor>::end_command() {}
|
||||
template <typename Executor> void Target<Executor>::send_data(std::vector<uint8_t> &&data, continuation next) {
|
||||
// Data out phase: control and message all reset, input set.
|
||||
bus_state_ &= ~(Line::Control | Line::Input | Line::Message);
|
||||
bus_state_ |= Line::Input;
|
||||
phase_ = Phase::SendingData;
|
||||
data_ = std::move(data);
|
||||
data_pointer_ = 0;
|
||||
bus_.set_device_output(scsi_bus_device_id_, bus_state_);
|
||||
}
|
||||
|
||||
template <typename Executor> void Target<Executor>::receive_data(size_t length, continuation next) {
|
||||
// Data out phase: control, input and message all reset.
|
||||
bus_state_ &= ~(Line::Control | Line::Input | Line::Message);
|
||||
phase_ = Phase::ReceivingData;
|
||||
data_.resize(length);
|
||||
data_pointer_ = 0;
|
||||
bus_.set_device_output(scsi_bus_device_id_, bus_state_);
|
||||
}
|
||||
|
||||
template <typename Executor> void Target<Executor>::send_status(Status, continuation next) {
|
||||
// Status phase: message reset, control and input set.
|
||||
bus_state_ &= ~(Line::Control | Line::Input | Line::Message);
|
||||
bus_state_ |= Line::Input | Line::Control;
|
||||
phase_ = Phase::SendingStatus;
|
||||
bus_.set_device_output(scsi_bus_device_id_, bus_state_);
|
||||
}
|
||||
|
||||
template <typename Executor> void Target<Executor>::send_message(Message, continuation next) {
|
||||
// Message out phase: message and control set, input reset.
|
||||
bus_state_ &= ~(Line::Control | Line::Input | Line::Message);
|
||||
bus_state_ |= Line::Message | Line::Control;
|
||||
phase_ = Phase::SendingMessage;
|
||||
bus_.set_device_output(scsi_bus_device_id_, bus_state_);
|
||||
}
|
||||
|
||||
template <typename Executor> void Target<Executor>::end_command() {
|
||||
// TODO: was this a linked command?
|
||||
|
||||
// Release all bus lines and return to awaiting selection.
|
||||
phase_ = Phase::AwaitingSelection;
|
||||
bus_state_ = DefaultBusState;
|
||||
bus_.set_device_output(scsi_bus_device_id_, bus_state_);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user