From bffe3ffa25e4f321c40117074ae1d5f51d9368f9 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 27 Nov 2023 23:05:37 -0500 Subject: [PATCH] Add an 8272 results phase. --- Components/8272/CommandDecoder.hpp | 50 +++++++------- Components/8272/Results.hpp | 65 +++++++++++++++++++ Components/8272/Status.hpp | 3 +- Components/8272/i8272.cpp | 1 - Machines/PCCompatible/PCCompatible.cpp | 29 +++++++-- .../Clock Signal.xcodeproj/project.pbxproj | 2 + 6 files changed, 118 insertions(+), 32 deletions(-) create mode 100644 Components/8272/Results.hpp diff --git a/Components/8272/CommandDecoder.hpp b/Components/8272/CommandDecoder.hpp index f745723d1..362d210ed 100644 --- a/Components/8272/CommandDecoder.hpp +++ b/Components/8272/CommandDecoder.hpp @@ -15,33 +15,33 @@ namespace Intel::i8272 { +enum class Command { + ReadData = 0x06, + ReadDeletedData = 0x0c, + + WriteData = 0x05, + WriteDeletedData = 0x09, + + ReadTrack = 0x02, + ReadID = 0x0a, + FormatTrack = 0x0d, + + ScanLow = 0x11, + ScanLowOrEqual = 0x19, + ScanHighOrEqual = 0x1d, + + Recalibrate = 0x07, + Seek = 0x0f, + + SenseInterruptStatus = 0x08, + Specify = 0x03, + SenseDriveStatus = 0x04, + + Invalid = 0x00, +}; + class CommandDecoder { public: - enum class Command { - ReadData = 0x06, - ReadDeletedData = 0x0c, - - WriteData = 0x05, - WriteDeletedData = 0x09, - - ReadTrack = 0x02, - ReadID = 0x0a, - FormatTrack = 0x0d, - - ScanLow = 0x11, - ScanLowOrEqual = 0x19, - ScanHighOrEqual = 0x1d, - - Recalibrate = 0x07, - Seek = 0x0f, - - SenseInterruptStatus = 0x08, - Specify = 0x03, - SenseDriveStatus = 0x04, - - Invalid = 0x00, - }; - /// Add a byte to the current command. void push_back(uint8_t byte) { command_.push_back(byte); diff --git a/Components/8272/Results.hpp b/Components/8272/Results.hpp new file mode 100644 index 000000000..0241b7e6d --- /dev/null +++ b/Components/8272/Results.hpp @@ -0,0 +1,65 @@ +// +// Results.hpp +// Clock Signal +// +// Created by Thomas Harte on 27/11/2023. +// Copyright © 2023 Thomas Harte. All rights reserved. +// + +#ifndef Results_hpp +#define Results_hpp + +#include "CommandDecoder.hpp" +#include "Status.hpp" + +namespace Intel::i8272 { + +class Results { + public: + /// Serialises the response to Command::Invalid and Command::SenseInterruptStatus when no interrupt source was found. + void serialise_none() { + result_ = { 0x80 }; + } + + /// Serialises the response to Command::SenseInterruptStatus for a found drive. + void serialise(const Status &status, uint8_t cylinder) { + result_ = { cylinder, status[0] }; + } + + /// Serialises the seven-byte response to Command::SenseDriveStatus. + void serialise(uint8_t flags, uint8_t drive_side) { + result_ = { uint8_t(flags | drive_side) }; + } + + /// Serialises the response to: + /// + /// * Command::ReadData; + /// * Command::ReadDeletedData; + /// * Command::WriteData; + /// * Command::WriteDeletedData; + /// * Command::ReadID; + /// * Command::ReadTrack; + /// * Command::FormatTrack; + /// * Command::ScanLow; and + /// * Command::ScanHighOrEqual. + void serialise(const Status &status, uint8_t cylinder, uint8_t head, uint8_t sector, uint8_t size) { + result_ = { size, sector, head, cylinder, status[2], status[1], status[0] }; + } + + /// @returns @c true if all result bytes are exhausted; @c false otherwise. + bool empty() const { return result_.empty(); } + + /// @returns The next byte of the result. + uint8_t next() { + const uint8_t next = result_.back(); + result_.pop_back(); + return next; + } + + private: + std::vector result_; +}; + +} + +#endif /* Results_hpp */ diff --git a/Components/8272/Status.hpp b/Components/8272/Status.hpp index f758f7ee4..e0b216615 100644 --- a/Components/8272/Status.hpp +++ b/Components/8272/Status.hpp @@ -60,9 +60,8 @@ enum class Status3: uint8_t { Fault = 0x80, WriteProtected = 0x40, Ready = 0x20, - Track9 = 0x10, + Track0 = 0x10, TwoSided = 0x08, - HeadAddress = 0x04, UnitSelect = 0x03, }; diff --git a/Components/8272/i8272.cpp b/Components/8272/i8272.cpp index 374637042..519a435fd 100644 --- a/Components/8272/i8272.cpp +++ b/Components/8272/i8272.cpp @@ -268,7 +268,6 @@ void i8272::posit_event(int event_type) { } // Jump to the proper place. - using Command = CommandDecoder::Command; switch(command_.command()) { case Command::ReadData: case Command::ReadDeletedData: diff --git a/Machines/PCCompatible/PCCompatible.cpp b/Machines/PCCompatible/PCCompatible.cpp index 2f6d3294b..065c4ecbc 100644 --- a/Machines/PCCompatible/PCCompatible.cpp +++ b/Machines/PCCompatible/PCCompatible.cpp @@ -21,6 +21,7 @@ #include "../../Components/6845/CRTC6845.hpp" #include "../../Components/8255/i8255.hpp" #include "../../Components/8272/CommandDecoder.hpp" +#include "../../Components/8272/Results.hpp" #include "../../Components/8272/Status.hpp" #include "../../Components/AudioToggle/AudioToggle.hpp" @@ -70,20 +71,39 @@ class FloppyController { decoder_.push_back(value); if(decoder_.has_command()) { - using Command = Intel::i8272::CommandDecoder::Command; + using Command = Intel::i8272::Command; switch(decoder_.command()) { default: printf("TODO: implement FDC command %d\n", uint8_t(decoder_.command())); break; -// case Command::Invalid: -// break; + case Command::Invalid: + results_.serialise_none(); + break; + + case Command::SenseInterruptStatus: + results_.serialise_none(); + break; + } + + if(!results_.empty()) { + using MainStatus = Intel::i8272::MainStatus; + status_.set(MainStatus::DataIsToProcessor, true); + status_.set(MainStatus::DataReady, true); } } } uint8_t read() { - // TODO: is anything being serialised? + using MainStatus = Intel::i8272::MainStatus; + if(status_.get(MainStatus::DataIsToProcessor)) { + const uint8_t result = results_.next(); + if(results_.empty()) { + status_.set(MainStatus::DataIsToProcessor, false); + } + return result; + } + return 0x80; } @@ -102,6 +122,7 @@ class FloppyController { Intel::i8272::CommandDecoder decoder_; Intel::i8272::Status status_; + Intel::i8272::Results results_; }; class KeyboardController { diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index ac2b4a45e..9085363c4 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -1127,6 +1127,7 @@ /* Begin PBXFileReference section */ 4238200B2B1295AD00964EFE /* Status.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Status.hpp; sourceTree = ""; }; + 4238200C2B15998800964EFE /* Results.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Results.hpp; sourceTree = ""; }; 423BDC492AB24699008E37B6 /* 8088Tests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = 8088Tests.mm; sourceTree = ""; }; 42437B342ACF02A9006DFED1 /* Flags.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Flags.hpp; sourceTree = ""; }; 42437B352ACF0AA2006DFED1 /* Perform.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Perform.hpp; sourceTree = ""; }; @@ -4556,6 +4557,7 @@ 4267A9CB2B113958008A59BB /* CommandDecoder.hpp */, 4BBC951D1F368D83008F4C34 /* i8272.hpp */, 4238200B2B1295AD00964EFE /* Status.hpp */, + 4238200C2B15998800964EFE /* Results.hpp */, ); path = 8272; sourceTree = "";