mirror of
https://github.com/TomHarte/CLK.git
synced 2026-04-26 19:17:52 +00:00
Generalise 'Registers'.
This commit is contained in:
@@ -8,20 +8,21 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "InstructionSets/x86/Descriptors.hpp"
|
||||
#include "InstructionSets/x86/MachineStatus.hpp"
|
||||
#include "InstructionSets/x86/Model.hpp"
|
||||
#include "Descriptors.hpp"
|
||||
#include "MachineStatus.hpp"
|
||||
#include "Model.hpp"
|
||||
|
||||
#include "Numeric/RegisterSizes.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace PCCompatible {
|
||||
namespace InstructionSet::x86 {
|
||||
|
||||
template <InstructionSet::x86::Model>
|
||||
template <Model>
|
||||
struct Registers;
|
||||
|
||||
template <>
|
||||
struct Registers<InstructionSet::x86::Model::i8086> {
|
||||
struct Registers<Model::i8086> {
|
||||
public:
|
||||
static constexpr bool is_32bit = false;
|
||||
|
||||
@@ -59,7 +60,7 @@ public:
|
||||
uint16_t cs() const { return segments_[Source::CS]; }
|
||||
uint16_t ds() const { return segments_[Source::DS]; }
|
||||
uint16_t ss() const { return segments_[Source::SS]; }
|
||||
uint16_t segment(const InstructionSet::x86::Source segment) const {
|
||||
uint16_t segment(const Source segment) const {
|
||||
return segments_[segment];
|
||||
}
|
||||
|
||||
@@ -69,8 +70,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
using Source = InstructionSet::x86::Source;
|
||||
|
||||
CPU::RegisterPair16 ax_;
|
||||
CPU::RegisterPair16 cx_;
|
||||
CPU::RegisterPair16 dx_;
|
||||
@@ -81,20 +80,17 @@ private:
|
||||
uint16_t si_;
|
||||
uint16_t di_;
|
||||
uint16_t ip_;
|
||||
InstructionSet::x86::SegmentRegisterSet<uint16_t> segments_;
|
||||
SegmentRegisterSet<uint16_t> segments_;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Registers<InstructionSet::x86::Model::i80186>: public Registers<InstructionSet::x86::Model::i8086> {};
|
||||
struct Registers<Model::i80186>: public Registers<Model::i8086> {};
|
||||
|
||||
template <>
|
||||
struct Registers<InstructionSet::x86::Model::i80286>: public Registers<InstructionSet::x86::Model::i80186> {
|
||||
struct Registers<Model::i80286>: public Registers<Model::i80186> {
|
||||
public:
|
||||
using DescriptorTable = InstructionSet::x86::DescriptorTable;
|
||||
using DescriptorTablePointer = InstructionSet::x86::DescriptorTablePointer;
|
||||
|
||||
void reset() {
|
||||
Registers<InstructionSet::x86::Model::i80186>::reset();
|
||||
Registers<Model::i80186>::reset();
|
||||
machine_status_ = 0;
|
||||
interrupt_ = DescriptorTablePointer{
|
||||
.limit = 256 * 4,
|
||||
@@ -105,7 +101,7 @@ public:
|
||||
uint16_t msw() const { return machine_status_; }
|
||||
void set_msw(const uint16_t msw) {
|
||||
machine_status_ =
|
||||
(machine_status_ & InstructionSet::x86::MachineStatus::ProtectedModeEnable) |
|
||||
(machine_status_ & MachineStatus::ProtectedModeEnable) |
|
||||
msw;
|
||||
}
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
|
||||
#include "LinearMemory.hpp"
|
||||
#include "ProcessorByModel.hpp"
|
||||
#include "Registers.hpp"
|
||||
#include "Segments.hpp"
|
||||
#include "SegmentedMemory.hpp"
|
||||
|
||||
#include "InstructionSets/x86/Registers.hpp"
|
||||
|
||||
#include "Analyser/Static/PCCompatible/Target.hpp"
|
||||
#include "Outputs/Log.hpp"
|
||||
|
||||
@@ -23,7 +24,7 @@ template <Analyser::Static::PCCompatible::Model model>
|
||||
class CPUControl {
|
||||
public:
|
||||
CPUControl(
|
||||
Registers<processor_model(model)> ®isters,
|
||||
InstructionSet::x86::Registers<processor_model(model)> ®isters,
|
||||
Segments<processor_model(model)> &segments,
|
||||
SegmentedMemory<processor_model(model)> &segmented_memory,
|
||||
LinearMemory<processor_model(model)> &linear_memory
|
||||
@@ -59,7 +60,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Registers<processor_model(model)> ®isters_;
|
||||
InstructionSet::x86::Registers<processor_model(model)> ®isters_;
|
||||
Segments<processor_model(model)> &segments_;
|
||||
SegmentedMemory<processor_model(model)> &segmented_memory_;
|
||||
LinearMemory<processor_model(model)> &linear_memory_;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "InstructionSets/x86/Flags.hpp"
|
||||
#include "InstructionSets/x86/Instruction.hpp"
|
||||
#include "InstructionSets/x86/Perform.hpp"
|
||||
#include "InstructionSets/x86/Registers.hpp"
|
||||
|
||||
#include "Components/8255/i8255.hpp"
|
||||
|
||||
@@ -507,7 +508,7 @@ class FlowController {
|
||||
static constexpr auto x86_model = processor_model(model);
|
||||
|
||||
public:
|
||||
FlowController(Registers<x86_model> ®isters, Segments<x86_model> &segments) :
|
||||
FlowController(InstructionSet::x86::Registers<x86_model> ®isters, Segments<x86_model> &segments) :
|
||||
registers_(registers), segments_(segments) {}
|
||||
|
||||
// Requirements for perform.
|
||||
@@ -554,7 +555,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Registers<x86_model> ®isters_;
|
||||
InstructionSet::x86::Registers<x86_model> ®isters_;
|
||||
Segments<x86_model> &segments_;
|
||||
bool should_repeat_ = false;
|
||||
bool halted_ = false;
|
||||
@@ -990,7 +991,7 @@ private:
|
||||
}
|
||||
|
||||
InstructionSet::x86::Flags flags;
|
||||
Registers<x86_model> registers;
|
||||
InstructionSet::x86::Registers<x86_model> registers;
|
||||
|
||||
LinearMemory<x86_model> linear_memory;
|
||||
Segments<x86_model> segments;
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
#include "InstructionSets/x86/AccessType.hpp"
|
||||
#include "InstructionSets/x86/Descriptors.hpp"
|
||||
#include "InstructionSets/x86/Model.hpp"
|
||||
#include "InstructionSets/x86/Registers.hpp"
|
||||
|
||||
#include "LinearMemory.hpp"
|
||||
#include "Registers.hpp"
|
||||
#include "Segments.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -23,7 +23,7 @@ namespace PCCompatible {
|
||||
// TODO: the following need to apply linear memory semantics, including potential A20 wrapping.
|
||||
template <InstructionSet::x86::Model model> struct ProgramFetcher {
|
||||
std::pair<const uint8_t *, size_t> next_code(
|
||||
const Registers<model> ®isters,
|
||||
const InstructionSet::x86::Registers<model> ®isters,
|
||||
const Segments<model> &segments,
|
||||
LinearMemory<model> &linear_memory
|
||||
) const {
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
using AccessType = InstructionSet::x86::AccessType;
|
||||
|
||||
SegmentedMemory(
|
||||
Registers<model> ®isters,
|
||||
InstructionSet::x86::Registers<model> ®isters,
|
||||
const Segments<model> &segments,
|
||||
LinearMemory<model> &linear_memory
|
||||
) :
|
||||
@@ -116,7 +116,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Registers<model> ®isters_;
|
||||
InstructionSet::x86::Registers<model> ®isters_;
|
||||
const Segments<model> &segments_;
|
||||
LinearMemory<model> &linear_memory_;
|
||||
ProgramFetcher<model> program_fetcher_;
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
using AccessType = InstructionSet::x86::AccessType;
|
||||
|
||||
SegmentedMemory(
|
||||
Registers<model> ®isters,
|
||||
InstructionSet::x86::Registers<model> ®isters,
|
||||
const Segments<model> &segments,
|
||||
LinearMemory<model> &linear_memory
|
||||
) : registers_(registers), segments_(segments), linear_memory_(linear_memory) {}
|
||||
@@ -140,7 +140,7 @@ public:
|
||||
//
|
||||
void preauthorise_stack_write(const uint32_t size) {
|
||||
const auto &descriptor = segments_.descriptors[InstructionSet::x86::Source::SS];
|
||||
descriptor.authorise<InstructionSet::x86::AccessType::Write, uint16_t>(
|
||||
descriptor.template authorise<InstructionSet::x86::AccessType::Write, uint16_t>(
|
||||
uint16_t(registers_.sp() - size),
|
||||
uint16_t(registers_.sp())
|
||||
);
|
||||
@@ -209,147 +209,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Registers<model> ®isters_;
|
||||
InstructionSet::x86::Registers<model> ®isters_;
|
||||
const Segments<model> &segments_;
|
||||
LinearMemory<model> &linear_memory_;
|
||||
ProgramFetcher<model> program_fetcher_;
|
||||
Mode mode_ = Mode::Real;
|
||||
};
|
||||
|
||||
//template <InstructionSet::x86::Model model>
|
||||
//class SegmentedMemory {
|
||||
// using AccessType = InstructionSet::x86::AccessType;
|
||||
// using Mode = InstructionSet::x86::Mode;
|
||||
//
|
||||
// // Constructor.
|
||||
// SegmentedMemory(
|
||||
// Registers<model> ®isters,
|
||||
// const Segments<model> &segments,
|
||||
// LinearMemory<model> &linear_memory
|
||||
// ) :
|
||||
// registers_(registers), segments_(segments), linear_memory_(linear_memory) {}
|
||||
//
|
||||
// //
|
||||
// // Preauthorisation call-ins. Since only an 8088 is currently modelled, all accesses are implicitly authorised.
|
||||
// //
|
||||
// void preauthorise_stack_write([[maybe_unused]] uint32_t length) {}
|
||||
// void preauthorise_stack_read([[maybe_unused]] uint32_t length) {}
|
||||
// void preauthorise_read([[maybe_unused]] InstructionSet::x86::Source segment, [[maybe_unused]] uint16_t start, [[maybe_unused]] uint32_t length) {}
|
||||
// void preauthorise_read([[maybe_unused]] uint32_t start, [[maybe_unused]] uint32_t length) {}
|
||||
// void preauthorise_write([[maybe_unused]] InstructionSet::x86::Source segment, [[maybe_unused]] uint16_t start, [[maybe_unused]] uint32_t length) {}
|
||||
// void preauthorise_write([[maybe_unused]] uint32_t start, [[maybe_unused]] uint32_t length) {}
|
||||
//
|
||||
// void set_mode(const Mode mode) {
|
||||
// mode_ = mode;
|
||||
// }
|
||||
//
|
||||
// //
|
||||
// // Access call-ins.
|
||||
// //
|
||||
//
|
||||
// // Accesses an address based on segment:offset.
|
||||
// template <typename IntT, AccessType type>
|
||||
// typename InstructionSet::x86::Accessor<IntT, type>::type access(
|
||||
// const InstructionSet::x86::Source segment,
|
||||
// const uint16_t offset
|
||||
// ) {
|
||||
// const auto &descriptor = segments_.descriptors[segment];
|
||||
// return linear_memory_.access<IntT, type>(
|
||||
// , ds, ds)
|
||||
//
|
||||
// }
|
||||
//
|
||||
// //
|
||||
// // Direct read and write.
|
||||
// //
|
||||
// template <typename IntT>
|
||||
// void preauthorised_write(
|
||||
// const InstructionSet::x86::Source segment,
|
||||
// const uint16_t offset,
|
||||
// const IntT value
|
||||
// ) {
|
||||
// linear_memory_.access<IntT, AccessType::Write>(
|
||||
//
|
||||
// // Bytes can be written without further ado.
|
||||
// if constexpr (std::is_same_v<IntT, uint8_t>) {
|
||||
// memory[address(segment, offset) & 0xf'ffff] = value;
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // Words that straddle the segment end must be split in two.
|
||||
// if(offset == 0xffff) {
|
||||
// memory[address(segment, offset) & 0xf'ffff] = uint8_t(value & 0xff);
|
||||
// memory[address(segment, 0x0000) & 0xf'ffff] = uint8_t(value >> 8);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// const uint32_t target = address(segment, offset) & 0xf'ffff;
|
||||
//
|
||||
// // Words that straddle the end of physical RAM must also be split in two.
|
||||
// if(target == 0xf'ffff) {
|
||||
// memory[0xf'ffff] = uint8_t(value & 0xff);
|
||||
// memory[0x0'0000] = uint8_t(value >> 8);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // It's safe just to write then.
|
||||
// *reinterpret_cast<IntT *>(&memory[target]) = value;
|
||||
// }
|
||||
//
|
||||
// template <typename IntT>
|
||||
// IntT preauthorised_read(
|
||||
// const InstructionSet::x86::Source segment,
|
||||
// const uint16_t offset
|
||||
// ) {
|
||||
// // Bytes can be written without further ado.
|
||||
// if constexpr (std::is_same_v<IntT, uint8_t>) {
|
||||
// return memory[address(segment, offset) & 0xf'ffff];
|
||||
// }
|
||||
//
|
||||
// // Words that straddle the segment end must be split in two.
|
||||
// if(offset == 0xffff) {
|
||||
// return IntT(
|
||||
// memory[address(segment, offset) & 0xf'ffff] |
|
||||
// memory[address(segment, 0x0000) & 0xf'ffff] << 8
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// const uint32_t target = address(segment, offset) & 0xf'ffff;
|
||||
//
|
||||
// // Words that straddle the end of physical RAM must also be split in two.
|
||||
// if(target == 0xf'ffff) {
|
||||
// return IntT(
|
||||
// memory[0xf'ffff] |
|
||||
// memory[0x0'0000] << 8
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// // It's safe just to write then.
|
||||
// return *reinterpret_cast<IntT *>(&memory[target]);
|
||||
// }
|
||||
//
|
||||
// //
|
||||
// // Helper for instruction fetch.
|
||||
// //
|
||||
// std::pair<const uint8_t *, size_t> next_code() const {
|
||||
// const uint32_t start =
|
||||
// segments_.descriptors[InstructionSet::x86::Source::CS].to_linear(registers_.ip()) & 0xf'ffff;
|
||||
// return std::make_pair(&memory[start], 0x10'000 - start);
|
||||
// }
|
||||
//
|
||||
// std::pair<const uint8_t *, size_t> start_code() const {
|
||||
// return std::make_pair(memory.data(), 0x10'000);
|
||||
// }
|
||||
//
|
||||
//private:
|
||||
// Registers<model> ®isters_;
|
||||
// const Segments<model> &segments_;
|
||||
// LinearMemory<model> &linear_memory_;
|
||||
// Mode mode_ = Mode::Real;
|
||||
//
|
||||
// uint32_t address(const InstructionSet::x86::Source segment, const uint16_t offset) const {
|
||||
// return segments_.descriptors[segment].to_linear(offset);
|
||||
// }
|
||||
//};
|
||||
|
||||
}
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "LinearMemory.hpp"
|
||||
#include "Registers.hpp"
|
||||
|
||||
#include "InstructionSets/x86/AccessType.hpp"
|
||||
#include "InstructionSets/x86/Descriptors.hpp"
|
||||
#include "InstructionSets/x86/Instruction.hpp"
|
||||
#include "InstructionSets/x86/Mode.hpp"
|
||||
#include "InstructionSets/x86/Model.hpp"
|
||||
#include "InstructionSets/x86/Registers.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
@@ -26,7 +26,7 @@ namespace PCCompatible {
|
||||
template <InstructionSet::x86::Model model>
|
||||
class Segments {
|
||||
public:
|
||||
Segments(const Registers<model> ®isters, const LinearMemory<model> &memory) :
|
||||
Segments(const InstructionSet::x86::Registers<model> ®isters, const LinearMemory<model> &memory) :
|
||||
registers_(registers), memory_(memory) {}
|
||||
|
||||
using Descriptor = InstructionSet::x86::SegmentDescriptor;
|
||||
@@ -162,7 +162,7 @@ private:
|
||||
}
|
||||
|
||||
Mode mode_ = Mode::Real;
|
||||
const Registers<model> ®isters_;
|
||||
const InstructionSet::x86::Registers<model> ®isters_;
|
||||
const LinearMemory<model> &memory_;
|
||||
Descriptor last_descriptor_;
|
||||
|
||||
|
||||
@@ -1256,7 +1256,6 @@
|
||||
4238200F2B17CBC800964EFE /* Target.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = "<group>"; };
|
||||
423820102B17CBC800964EFE /* StaticAnalyser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StaticAnalyser.cpp; sourceTree = "<group>"; };
|
||||
423820132B1A235200964EFE /* SegmentedMemory.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = SegmentedMemory.hpp; sourceTree = "<group>"; };
|
||||
423820142B1A23C200964EFE /* Registers.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Registers.hpp; sourceTree = "<group>"; };
|
||||
423820152B1A23E100964EFE /* Segments.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Segments.hpp; sourceTree = "<group>"; };
|
||||
423820422B1A90BE00964EFE /* PCBooter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCBooter.cpp; sourceTree = "<group>"; };
|
||||
423820432B1A90BE00964EFE /* PCBooter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = PCBooter.hpp; sourceTree = "<group>"; };
|
||||
@@ -1734,6 +1733,7 @@
|
||||
4B7BA03823CEB8D200B98D9E /* DiskController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DiskController.hpp; sourceTree = "<group>"; };
|
||||
4B7BA03E23D55E7900B98D9E /* CRC.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRC.hpp; sourceTree = "<group>"; };
|
||||
4B7BA03F23D55E7900B98D9E /* LFSR.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LFSR.hpp; sourceTree = "<group>"; };
|
||||
4B7BD24F2E2F1C6D00FDAEC9 /* Registers.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Registers.hpp; sourceTree = "<group>"; };
|
||||
4B7C681427517A59001671EC /* Sprites.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Sprites.cpp; sourceTree = "<group>"; };
|
||||
4B7C681527517A59001671EC /* Sprites.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Sprites.hpp; sourceTree = "<group>"; };
|
||||
4B7C6818275196E8001671EC /* MouseJoystick.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MouseJoystick.cpp; sourceTree = "<group>"; };
|
||||
@@ -2582,7 +2582,6 @@
|
||||
4267A9C82B0D4EC2008A59BB /* PIC.hpp */,
|
||||
4267A9C72B0C26FA008A59BB /* PIT.hpp */,
|
||||
4B1FBE1F2D77AAC500BAC888 /* ProcessorByModel.hpp */,
|
||||
423820142B1A23C200964EFE /* Registers.hpp */,
|
||||
42EB81252B21788200429AF4 /* RTC.hpp */,
|
||||
423820132B1A235200964EFE /* SegmentedMemory.hpp */,
|
||||
423820152B1A23E100964EFE /* Segments.hpp */,
|
||||
@@ -5384,6 +5383,7 @@
|
||||
4B8671EB2D8FABA0009E1610 /* Mode.hpp */,
|
||||
4BE3C69527CBC540000EAD28 /* Model.hpp */,
|
||||
42437B352ACF0AA2006DFED1 /* Perform.hpp */,
|
||||
4B7BD24F2E2F1C6D00FDAEC9 /* Registers.hpp */,
|
||||
4B25BC1E2DDD64AA002044CA /* TaskStateSegment.hpp */,
|
||||
42437B372ACF2798006DFED1 /* Implementation */,
|
||||
);
|
||||
|
||||
@@ -34,75 +34,8 @@ namespace {
|
||||
constexpr char TestSuiteHome[] = "/Users/thomasharte/Projects/8088/v1";
|
||||
|
||||
using Flags = InstructionSet::x86::Flags;
|
||||
struct Registers {
|
||||
public:
|
||||
// static constexpr bool is_32bit = false;
|
||||
using Registers = InstructionSet::x86::Registers<InstructionSet::x86::Model::i8086>;
|
||||
|
||||
uint8_t &al() { return ax_.halves.low; }
|
||||
uint8_t &ah() { return ax_.halves.high; }
|
||||
uint16_t &ax() { return ax_.full; }
|
||||
|
||||
CPU::RegisterPair16 &axp() { return ax_; }
|
||||
|
||||
uint8_t &cl() { return cx_.halves.low; }
|
||||
uint8_t &ch() { return cx_.halves.high; }
|
||||
uint16_t &cx() { return cx_.full; }
|
||||
|
||||
uint8_t &dl() { return dx_.halves.low; }
|
||||
uint8_t &dh() { return dx_.halves.high; }
|
||||
uint16_t &dx() { return dx_.full; }
|
||||
|
||||
uint8_t &bl() { return bx_.halves.low; }
|
||||
uint8_t &bh() { return bx_.halves.high; }
|
||||
uint16_t &bx() { return bx_.full; }
|
||||
|
||||
uint16_t &sp() { return sp_; }
|
||||
uint16_t &bp() { return bp_; }
|
||||
uint16_t &si() { return si_; }
|
||||
uint16_t &di() { return di_; }
|
||||
|
||||
uint16_t &ip() { return ip_; }
|
||||
|
||||
uint16_t &es() { return es_; }
|
||||
uint16_t &cs() { return cs_; }
|
||||
uint16_t &ds() { return ds_; }
|
||||
uint16_t &ss() { return ss_; }
|
||||
|
||||
const uint16_t es() const { return es_; }
|
||||
const uint16_t cs() const { return cs_; }
|
||||
const uint16_t ds() const { return ds_; }
|
||||
const uint16_t ss() const { return ss_; }
|
||||
|
||||
bool operator ==(const Registers &rhs) const {
|
||||
return
|
||||
ax_.full == rhs.ax_.full &&
|
||||
cx_.full == rhs.cx_.full &&
|
||||
dx_.full == rhs.dx_.full &&
|
||||
bx_.full == rhs.bx_.full &&
|
||||
sp_ == rhs.sp_ &&
|
||||
bp_ == rhs.bp_ &&
|
||||
si_ == rhs.si_ &&
|
||||
di_ == rhs.di_ &&
|
||||
es_ == rhs.es_ &&
|
||||
cs_ == rhs.cs_ &&
|
||||
ds_ == rhs.ds_ &&
|
||||
si_ == rhs.si_ &&
|
||||
ip_ == rhs.ip_;
|
||||
}
|
||||
|
||||
private:
|
||||
CPU::RegisterPair16 ax_;
|
||||
CPU::RegisterPair16 cx_;
|
||||
CPU::RegisterPair16 dx_;
|
||||
CPU::RegisterPair16 bx_;
|
||||
|
||||
uint16_t sp_;
|
||||
uint16_t bp_;
|
||||
uint16_t si_;
|
||||
uint16_t di_;
|
||||
uint16_t es_, cs_, ds_, ss_;
|
||||
uint16_t ip_;
|
||||
};
|
||||
class Segments {
|
||||
public:
|
||||
Segments(const Registers ®isters) : registers_(registers) {}
|
||||
|
||||
Reference in New Issue
Block a user