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/AccessType.hpp"
|
||||||
#include "InstructionSets/x86/Descriptors.hpp"
|
#include "InstructionSets/x86/Descriptors.hpp"
|
||||||
|
#include "InstructionSets/x86/Mode.hpp"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -91,7 +92,14 @@ void lmsw(
|
|||||||
read_t<uint16_t> source,
|
read_t<uint16_t> source,
|
||||||
ContextT &context
|
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>
|
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 "Analyser/Static/PCCompatible/Target.hpp"
|
||||||
#include "InstructionSets/x86/AccessType.hpp"
|
#include "InstructionSets/x86/AccessType.hpp"
|
||||||
|
#include "InstructionSets/x86/Mode.hpp"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
@@ -26,6 +27,7 @@ class Memory {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
using AccessType = InstructionSet::x86::AccessType;
|
using AccessType = InstructionSet::x86::AccessType;
|
||||||
|
using Mode = InstructionSet::x86::Mode;
|
||||||
|
|
||||||
// Constructor.
|
// Constructor.
|
||||||
Memory(Registers<x86_model> ®isters, const Segments<x86_model> &segments) :
|
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]] 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 preauthorise_write([[maybe_unused]] uint32_t start, [[maybe_unused]] uint32_t length) {}
|
||||||
|
|
||||||
|
void set_mode(const Mode mode) {
|
||||||
|
mode_ = mode;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Access call-ins.
|
// Access call-ins.
|
||||||
//
|
//
|
||||||
@@ -183,6 +189,7 @@ private:
|
|||||||
std::array<uint8_t, 1024*1024> memory{0xff};
|
std::array<uint8_t, 1024*1024> memory{0xff};
|
||||||
Registers<x86_model> ®isters_;
|
Registers<x86_model> ®isters_;
|
||||||
const Segments<x86_model> &segments_;
|
const Segments<x86_model> &segments_;
|
||||||
|
Mode mode_ = Mode::Real;
|
||||||
|
|
||||||
uint32_t address(const InstructionSet::x86::Source segment, const uint16_t offset) const {
|
uint32_t address(const InstructionSet::x86::Source segment, const uint16_t offset) const {
|
||||||
return segments_.descriptors[segment].to_linear(offset) & 0xf'ffff;
|
return segments_.descriptors[segment].to_linear(offset) & 0xf'ffff;
|
||||||
|
|||||||
@@ -92,6 +92,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint16_t msw() const { return machine_status_; }
|
uint16_t msw() const { return machine_status_; }
|
||||||
|
void set_msw(const uint16_t msw) {
|
||||||
|
machine_status_ = msw;
|
||||||
|
}
|
||||||
|
|
||||||
using DescriptorTable = InstructionSet::x86::DescriptorTable;
|
using DescriptorTable = InstructionSet::x86::DescriptorTable;
|
||||||
using DescriptorTableLocation = InstructionSet::x86::DescriptorTablePointer;
|
using DescriptorTableLocation = InstructionSet::x86::DescriptorTablePointer;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "Registers.hpp"
|
#include "Registers.hpp"
|
||||||
|
|
||||||
#include "InstructionSets/x86/Instruction.hpp"
|
#include "InstructionSets/x86/Instruction.hpp"
|
||||||
|
#include "InstructionSets/x86/Mode.hpp"
|
||||||
#include "InstructionSets/x86/Model.hpp"
|
#include "InstructionSets/x86/Model.hpp"
|
||||||
|
|
||||||
namespace PCCompatible {
|
namespace PCCompatible {
|
||||||
@@ -20,18 +21,24 @@ class Segments {
|
|||||||
public:
|
public:
|
||||||
Segments(const Registers<model> ®isters) : registers_(registers) {}
|
Segments(const Registers<model> ®isters) : registers_(registers) {}
|
||||||
|
|
||||||
using Source = InstructionSet::x86::Source;
|
|
||||||
using DescriptorTable = InstructionSet::x86::DescriptorTable;
|
|
||||||
using Descriptor = InstructionSet::x86::Descriptor;
|
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.
|
/// Posted by @c perform after any operation which *might* have affected a segment register.
|
||||||
void did_update(const Source segment) {
|
void did_update(const Source segment) {
|
||||||
if(!is_segment_register(segment)) return;
|
if(!is_segment_register(segment)) return;
|
||||||
|
assert(mode_ == Mode::Real);
|
||||||
descriptors[segment].set_segment(registers_.segment(segment));
|
descriptors[segment].set_segment(registers_.segment(segment));
|
||||||
}
|
}
|
||||||
|
|
||||||
void did_update(DescriptorTable) {}
|
void did_update(DescriptorTable) {}
|
||||||
|
|
||||||
|
void set_mode(const Mode mode) {
|
||||||
|
mode_ = mode;
|
||||||
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
did_update(Source::ES);
|
did_update(Source::ES);
|
||||||
did_update(Source::CS);
|
did_update(Source::CS);
|
||||||
@@ -46,6 +53,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Mode mode_ = Mode::Real;
|
||||||
const Registers<model> ®isters_;
|
const Registers<model> ®isters_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1760,6 +1760,7 @@
|
|||||||
4B85322922778E4200F26553 /* Comparative68000.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Comparative68000.hpp; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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 */,
|
42437B342ACF02A9006DFED1 /* Flags.hpp */,
|
||||||
4BEDA3DB25B2588F000C2DBD /* Instruction.hpp */,
|
4BEDA3DB25B2588F000C2DBD /* Instruction.hpp */,
|
||||||
42437B392AD07465006DFED1 /* Interrupts.hpp */,
|
42437B392AD07465006DFED1 /* Interrupts.hpp */,
|
||||||
|
4B8671EB2D8FABA0009E1610 /* Mode.hpp */,
|
||||||
4BE3C69527CBC540000EAD28 /* Model.hpp */,
|
4BE3C69527CBC540000EAD28 /* Model.hpp */,
|
||||||
42437B352ACF0AA2006DFED1 /* Perform.hpp */,
|
42437B352ACF0AA2006DFED1 /* Perform.hpp */,
|
||||||
42437B372ACF2798006DFED1 /* Implementation */,
|
42437B372ACF2798006DFED1 /* Implementation */,
|
||||||
|
|||||||
Reference in New Issue
Block a user