mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Add an 8272 results phase.
This commit is contained in:
parent
993366ac5a
commit
bffe3ffa25
@ -15,33 +15,33 @@
|
|||||||
|
|
||||||
namespace Intel::i8272 {
|
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 {
|
class CommandDecoder {
|
||||||
public:
|
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.
|
/// Add a byte to the current command.
|
||||||
void push_back(uint8_t byte) {
|
void push_back(uint8_t byte) {
|
||||||
command_.push_back(byte);
|
command_.push_back(byte);
|
||||||
|
65
Components/8272/Results.hpp
Normal file
65
Components/8272/Results.hpp
Normal file
@ -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<uint8_t> result_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Results_hpp */
|
@ -60,9 +60,8 @@ enum class Status3: uint8_t {
|
|||||||
Fault = 0x80,
|
Fault = 0x80,
|
||||||
WriteProtected = 0x40,
|
WriteProtected = 0x40,
|
||||||
Ready = 0x20,
|
Ready = 0x20,
|
||||||
Track9 = 0x10,
|
Track0 = 0x10,
|
||||||
TwoSided = 0x08,
|
TwoSided = 0x08,
|
||||||
|
|
||||||
HeadAddress = 0x04,
|
HeadAddress = 0x04,
|
||||||
UnitSelect = 0x03,
|
UnitSelect = 0x03,
|
||||||
};
|
};
|
||||||
|
@ -268,7 +268,6 @@ void i8272::posit_event(int event_type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Jump to the proper place.
|
// Jump to the proper place.
|
||||||
using Command = CommandDecoder::Command;
|
|
||||||
switch(command_.command()) {
|
switch(command_.command()) {
|
||||||
case Command::ReadData:
|
case Command::ReadData:
|
||||||
case Command::ReadDeletedData:
|
case Command::ReadDeletedData:
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "../../Components/6845/CRTC6845.hpp"
|
#include "../../Components/6845/CRTC6845.hpp"
|
||||||
#include "../../Components/8255/i8255.hpp"
|
#include "../../Components/8255/i8255.hpp"
|
||||||
#include "../../Components/8272/CommandDecoder.hpp"
|
#include "../../Components/8272/CommandDecoder.hpp"
|
||||||
|
#include "../../Components/8272/Results.hpp"
|
||||||
#include "../../Components/8272/Status.hpp"
|
#include "../../Components/8272/Status.hpp"
|
||||||
#include "../../Components/AudioToggle/AudioToggle.hpp"
|
#include "../../Components/AudioToggle/AudioToggle.hpp"
|
||||||
|
|
||||||
@ -70,20 +71,39 @@ class FloppyController {
|
|||||||
decoder_.push_back(value);
|
decoder_.push_back(value);
|
||||||
|
|
||||||
if(decoder_.has_command()) {
|
if(decoder_.has_command()) {
|
||||||
using Command = Intel::i8272::CommandDecoder::Command;
|
using Command = Intel::i8272::Command;
|
||||||
switch(decoder_.command()) {
|
switch(decoder_.command()) {
|
||||||
default:
|
default:
|
||||||
printf("TODO: implement FDC command %d\n", uint8_t(decoder_.command()));
|
printf("TODO: implement FDC command %d\n", uint8_t(decoder_.command()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case Command::Invalid:
|
case Command::Invalid:
|
||||||
// break;
|
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() {
|
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;
|
return 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +122,7 @@ class FloppyController {
|
|||||||
|
|
||||||
Intel::i8272::CommandDecoder decoder_;
|
Intel::i8272::CommandDecoder decoder_;
|
||||||
Intel::i8272::Status status_;
|
Intel::i8272::Status status_;
|
||||||
|
Intel::i8272::Results results_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class KeyboardController {
|
class KeyboardController {
|
||||||
|
@ -1127,6 +1127,7 @@
|
|||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
4238200B2B1295AD00964EFE /* Status.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Status.hpp; sourceTree = "<group>"; };
|
4238200B2B1295AD00964EFE /* Status.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Status.hpp; sourceTree = "<group>"; };
|
||||||
|
4238200C2B15998800964EFE /* Results.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Results.hpp; sourceTree = "<group>"; };
|
||||||
423BDC492AB24699008E37B6 /* 8088Tests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = 8088Tests.mm; sourceTree = "<group>"; };
|
423BDC492AB24699008E37B6 /* 8088Tests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = 8088Tests.mm; sourceTree = "<group>"; };
|
||||||
42437B342ACF02A9006DFED1 /* Flags.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Flags.hpp; sourceTree = "<group>"; };
|
42437B342ACF02A9006DFED1 /* Flags.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Flags.hpp; sourceTree = "<group>"; };
|
||||||
42437B352ACF0AA2006DFED1 /* Perform.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Perform.hpp; sourceTree = "<group>"; };
|
42437B352ACF0AA2006DFED1 /* Perform.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Perform.hpp; sourceTree = "<group>"; };
|
||||||
@ -4556,6 +4557,7 @@
|
|||||||
4267A9CB2B113958008A59BB /* CommandDecoder.hpp */,
|
4267A9CB2B113958008A59BB /* CommandDecoder.hpp */,
|
||||||
4BBC951D1F368D83008F4C34 /* i8272.hpp */,
|
4BBC951D1F368D83008F4C34 /* i8272.hpp */,
|
||||||
4238200B2B1295AD00964EFE /* Status.hpp */,
|
4238200B2B1295AD00964EFE /* Status.hpp */,
|
||||||
|
4238200C2B15998800964EFE /* Results.hpp */,
|
||||||
);
|
);
|
||||||
path = 8272;
|
path = 8272;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user