1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-28 22:29:36 +00:00

Attempts to provide a data out phase.

This commit is contained in:
Thomas Harte 2019-08-22 23:16:58 -04:00
parent faec516a2c
commit 2d82855f26
7 changed files with 150 additions and 19 deletions

View File

@ -21,7 +21,7 @@ struct Target: public ::Analyser::Static::Target {
MacPlus
};
Model model = Model::Mac512ke;
Model model = Model::MacPlus;
};
}

View File

@ -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_;

View File

@ -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 */,

View 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;
}

View 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 */

View File

@ -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 */

View File

@ -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_);
}