mirror of
https://github.com/TomHarte/CLK.git
synced 2025-12-19 14:18:05 +00:00
Propagate mode change.
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "InstructionSets/x86/AccessType.hpp"
|
||||
#include "InstructionSets/x86/Descriptors.hpp"
|
||||
#include "InstructionSets/x86/Mode.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
@@ -91,7 +92,14 @@ void lmsw(
|
||||
read_t<uint16_t> source,
|
||||
ContextT &context
|
||||
) {
|
||||
assert(false);
|
||||
context.registers.set_msw(source);
|
||||
if(source & 1) {
|
||||
context.memory.set_mode(Mode::Protected286);
|
||||
context.segments.set_mode(Mode::Protected286);
|
||||
}
|
||||
|
||||
// TODO: all other bits. Anything?
|
||||
assert(!(source & ~1));
|
||||
}
|
||||
|
||||
template <DescriptorTable table, typename AddressT, typename InstructionT, typename ContextT>
|
||||
|
||||
18
InstructionSets/x86/Mode.hpp
Normal file
18
InstructionSets/x86/Mode.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// Mode.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 22/03/2025.
|
||||
// Copyright © 2025 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace InstructionSet::x86 {
|
||||
|
||||
enum class Mode {
|
||||
Real,
|
||||
Protected286,
|
||||
};
|
||||
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "Analyser/Static/PCCompatible/Target.hpp"
|
||||
#include "InstructionSets/x86/AccessType.hpp"
|
||||
#include "InstructionSets/x86/Mode.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
@@ -26,6 +27,7 @@ class Memory {
|
||||
|
||||
public:
|
||||
using AccessType = InstructionSet::x86::AccessType;
|
||||
using Mode = InstructionSet::x86::Mode;
|
||||
|
||||
// Constructor.
|
||||
Memory(Registers<x86_model> ®isters, const Segments<x86_model> &segments) :
|
||||
@@ -41,6 +43,10 @@ public:
|
||||
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.
|
||||
//
|
||||
@@ -183,6 +189,7 @@ private:
|
||||
std::array<uint8_t, 1024*1024> memory{0xff};
|
||||
Registers<x86_model> ®isters_;
|
||||
const Segments<x86_model> &segments_;
|
||||
Mode mode_ = Mode::Real;
|
||||
|
||||
uint32_t address(const InstructionSet::x86::Source segment, const uint16_t offset) const {
|
||||
return segments_.descriptors[segment].to_linear(offset) & 0xf'ffff;
|
||||
|
||||
@@ -92,6 +92,9 @@ public:
|
||||
}
|
||||
|
||||
uint16_t msw() const { return machine_status_; }
|
||||
void set_msw(const uint16_t msw) {
|
||||
machine_status_ = msw;
|
||||
}
|
||||
|
||||
using DescriptorTable = InstructionSet::x86::DescriptorTable;
|
||||
using DescriptorTableLocation = InstructionSet::x86::DescriptorTablePointer;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "Registers.hpp"
|
||||
|
||||
#include "InstructionSets/x86/Instruction.hpp"
|
||||
#include "InstructionSets/x86/Mode.hpp"
|
||||
#include "InstructionSets/x86/Model.hpp"
|
||||
|
||||
namespace PCCompatible {
|
||||
@@ -20,18 +21,24 @@ class Segments {
|
||||
public:
|
||||
Segments(const Registers<model> ®isters) : registers_(registers) {}
|
||||
|
||||
using Source = InstructionSet::x86::Source;
|
||||
using DescriptorTable = InstructionSet::x86::DescriptorTable;
|
||||
using Descriptor = InstructionSet::x86::Descriptor;
|
||||
using DescriptorTable = InstructionSet::x86::DescriptorTable;
|
||||
using Mode = InstructionSet::x86::Mode;
|
||||
using Source = InstructionSet::x86::Source;
|
||||
|
||||
/// Posted by @c perform after any operation which *might* have affected a segment register.
|
||||
void did_update(const Source segment) {
|
||||
if(!is_segment_register(segment)) return;
|
||||
assert(mode_ == Mode::Real);
|
||||
descriptors[segment].set_segment(registers_.segment(segment));
|
||||
}
|
||||
|
||||
void did_update(DescriptorTable) {}
|
||||
|
||||
void set_mode(const Mode mode) {
|
||||
mode_ = mode;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
did_update(Source::ES);
|
||||
did_update(Source::CS);
|
||||
@@ -46,6 +53,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Mode mode_ = Mode::Real;
|
||||
const Registers<model> ®isters_;
|
||||
};
|
||||
|
||||
|
||||
@@ -1760,6 +1760,7 @@
|
||||
4B85322922778E4200F26553 /* Comparative68000.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Comparative68000.hpp; sourceTree = "<group>"; };
|
||||
4B85322E2277ABDD00F26553 /* tos100.trace.txt.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; path = tos100.trace.txt.gz; sourceTree = "<group>"; };
|
||||
4B8671EA2D8B40D8009E1610 /* Descriptors.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Descriptors.hpp; sourceTree = "<group>"; };
|
||||
4B8671EB2D8FABA0009E1610 /* Mode.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Mode.hpp; sourceTree = "<group>"; };
|
||||
4B86E2591F8C628F006FAA45 /* Keyboard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Keyboard.cpp; sourceTree = "<group>"; };
|
||||
4B86E25A1F8C628F006FAA45 /* Keyboard.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Keyboard.hpp; sourceTree = "<group>"; };
|
||||
4B8805EE1DCFC99C003085B1 /* Acorn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Acorn.cpp; path = Parsers/Acorn.cpp; sourceTree = "<group>"; };
|
||||
@@ -5368,6 +5369,7 @@
|
||||
42437B342ACF02A9006DFED1 /* Flags.hpp */,
|
||||
4BEDA3DB25B2588F000C2DBD /* Instruction.hpp */,
|
||||
42437B392AD07465006DFED1 /* Interrupts.hpp */,
|
||||
4B8671EB2D8FABA0009E1610 /* Mode.hpp */,
|
||||
4BE3C69527CBC540000EAD28 /* Model.hpp */,
|
||||
42437B352ACF0AA2006DFED1 /* Perform.hpp */,
|
||||
42437B372ACF2798006DFED1 /* Implementation */,
|
||||
|
||||
Reference in New Issue
Block a user