From f8dc5b8ebc5ce9136797ed950d41e4bf67895c43 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 17 Sep 2023 17:05:19 -0400 Subject: [PATCH] Attempt to get close on index + base addresses. --- InstructionSets/x86/Instruction.cpp | 64 +++++++++++++++++++ InstructionSets/x86/Instruction.hpp | 2 + .../Clock Signal.xcodeproj/project.pbxproj | 10 ++- OSBindings/Mac/Clock SignalTests/8088Tests.mm | 37 +++++------ 4 files changed, 90 insertions(+), 23 deletions(-) create mode 100644 InstructionSets/x86/Instruction.cpp diff --git a/InstructionSets/x86/Instruction.cpp b/InstructionSets/x86/Instruction.cpp new file mode 100644 index 000000000..d7a8f5fac --- /dev/null +++ b/InstructionSets/x86/Instruction.cpp @@ -0,0 +1,64 @@ +// +// Instruction.cpp +// Clock Signal +// +// Created by Thomas Harte on 17/09/2023. +// Copyright © 2023 Thomas Harte. All rights reserved. +// + +#include "Instruction.hpp" + +using namespace InstructionSet::x86; + +std::string InstructionSet::x86::to_string(Source source, DataSize size) { + switch(source) { + case Source::eAX: { + constexpr char sizes[][4] = { "al", "ax", "eax", "?" }; + return sizes[static_cast(size)]; + } + case Source::eCX: { + constexpr char sizes[][4] = { "cl", "cx", "ecx", "?" }; + return sizes[static_cast(size)]; + } + case Source::eDX: { + constexpr char sizes[][4] = { "dl", "dx", "edx", "?" }; + return sizes[static_cast(size)]; + } + case Source::eBX: { + constexpr char sizes[][4] = { "bl", "bx", "ebx", "?" }; + return sizes[static_cast(size)]; + } + case Source::eSPorAH: { + constexpr char sizes[][4] = { "ah", "sp", "esp", "?" }; + return sizes[static_cast(size)]; + } + case Source::eBPorCH: { + constexpr char sizes[][4] = { "ch", "bp", "ebp", "?" }; + return sizes[static_cast(size)]; + } + case Source::eSIorDH: { + constexpr char sizes[][4] = { "dh", "si", "esi", "?" }; + return sizes[static_cast(size)]; + } + case Source::eDIorBH: { + constexpr char sizes[][4] = { "bh", "di", "edi", "?" }; + return sizes[static_cast(size)]; + } + + case Source::ES: return "es"; + case Source::CS: return "cs"; + case Source::SS: return "ss"; + case Source::DS: return "ds"; + case Source::FS: return "fd"; + case Source::GS: return "gs"; + + case Source::None: return "0"; + case Source::DirectAddress: return "DirectAccess"; + case Source::Immediate: return "Immediate"; + case Source::Indirect: return "Indirect"; + case Source::IndirectNoBase: return "IndirectNoBase"; + + default: return "???"; + } +} + diff --git a/InstructionSets/x86/Instruction.hpp b/InstructionSets/x86/Instruction.hpp index 2c6e7bd8a..a95cd44a6 100644 --- a/InstructionSets/x86/Instruction.hpp +++ b/InstructionSets/x86/Instruction.hpp @@ -11,6 +11,7 @@ #include #include +#include #include namespace InstructionSet::x86 { @@ -428,6 +429,7 @@ enum class Source: uint8_t { /// getter is used). IndirectNoBase = Indirect - 1, }; +std::string to_string(Source, DataSize); enum class Repetition: uint8_t { None, RepE, RepNE diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index eba4c39d0..7c3e287c4 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -299,6 +299,9 @@ 4B680CE223A5553100451D43 /* 68000ComparativeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B680CE123A5553100451D43 /* 68000ComparativeTests.mm */; }; 4B680CE423A555CA00451D43 /* 68000 Comparative Tests in Resources */ = {isa = PBXBuildFile; fileRef = 4B680CE323A555CA00451D43 /* 68000 Comparative Tests */; }; 4B683B012727BE700043E541 /* Amiga Blitter Tests in Resources */ = {isa = PBXBuildFile; fileRef = 4B683B002727BE6F0043E541 /* Amiga Blitter Tests */; }; + 4B69DEB62AB79E4F0055B217 /* Instruction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69DEB52AB79E4F0055B217 /* Instruction.cpp */; }; + 4B69DEB72AB79E4F0055B217 /* Instruction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69DEB52AB79E4F0055B217 /* Instruction.cpp */; }; + 4B69DEB82AB79E4F0055B217 /* Instruction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69DEB52AB79E4F0055B217 /* Instruction.cpp */; }; 4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69FB3B1C4D908A00B5F0AA /* Tape.cpp */; }; 4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */; }; 4B69FB461C4D950F00B5F0AA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B69FB451C4D950F00B5F0AA /* libz.tbd */; }; @@ -1441,6 +1444,7 @@ 4B680CE323A555CA00451D43 /* 68000 Comparative Tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "68000 Comparative Tests"; sourceTree = ""; }; 4B683B002727BE6F0043E541 /* Amiga Blitter Tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "Amiga Blitter Tests"; sourceTree = ""; }; 4B698D1A1FE768A100696C91 /* SampleSource.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = SampleSource.hpp; sourceTree = ""; }; + 4B69DEB52AB79E4F0055B217 /* Instruction.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Instruction.cpp; sourceTree = ""; }; 4B69FB3B1C4D908A00B5F0AA /* Tape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Tape.cpp; sourceTree = ""; }; 4B69FB3C1C4D908A00B5F0AA /* Tape.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Tape.hpp; sourceTree = ""; }; 4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TapeUEF.cpp; sourceTree = ""; }; @@ -4917,9 +4921,10 @@ isa = PBXGroup; children = ( 4BEDA3B925B25563000C2DBD /* Decoder.cpp */, + 4B69DEB52AB79E4F0055B217 /* Instruction.cpp */, + 4BE3C69327C793EF000EAD28 /* DataPointerResolver.hpp */, 4BEDA3B825B25563000C2DBD /* Decoder.hpp */, 4BEDA3DB25B2588F000C2DBD /* Instruction.hpp */, - 4BE3C69327C793EF000EAD28 /* DataPointerResolver.hpp */, 4BE3C69527CBC540000EAD28 /* Model.hpp */, ); path = x86; @@ -5762,6 +5767,7 @@ 4B055A931FAE85B50060FFFF /* BinaryDump.cpp in Sources */, 4B89452D201967B4007DE474 /* Tape.cpp in Sources */, 4B055AD61FAE9B130060FFFF /* MemoryFuzzer.cpp in Sources */, + 4B69DEB82AB79E4F0055B217 /* Instruction.cpp in Sources */, 4B055AC21FAE9AE30060FFFF /* KeyboardMachine.cpp in Sources */, 4B89453B201967B4007DE474 /* StaticAnalyser.cpp in Sources */, 4B055AEB1FAE9BA20060FFFF /* PartialMachineCycle.cpp in Sources */, @@ -5880,6 +5886,7 @@ 4B2B3A4C1F9B8FA70062DABF /* MemoryFuzzer.cpp in Sources */, 4B9EC0EA26B384080060A31F /* Keyboard.cpp in Sources */, 4B7913CC1DFCD80E00175A82 /* Video.cpp in Sources */, + 4B69DEB62AB79E4F0055B217 /* Instruction.cpp in Sources */, 4B7962A02819681F008130F9 /* Decoder.cpp in Sources */, 4BC57CD92436A62900FBC404 /* State.cpp in Sources */, 4BDA00E622E699B000AC3CD0 /* CSMachine.mm in Sources */, @@ -6223,6 +6230,7 @@ 4BDA7F8329C4EA28007A10A5 /* 6809OperationMapperTests.mm in Sources */, 4B778F5723A5F2BB0000D260 /* ZX8081.cpp in Sources */, 4B778F2F23A5F0B10000D260 /* ScanTarget.cpp in Sources */, + 4B69DEB72AB79E4F0055B217 /* Instruction.cpp in Sources */, 4BE90FFD22D5864800FB464D /* MacintoshVideoTests.mm in Sources */, 4B4F478A25367EDC004245B8 /* 65816AddressingTests.swift in Sources */, 4B778F0B23A5EC150000D260 /* TapeUEF.cpp in Sources */, diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index e4e697a61..1b3d15d41 100644 --- a/OSBindings/Mac/Clock SignalTests/8088Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/8088Tests.mm @@ -115,31 +115,22 @@ constexpr char TestSuiteHome[] = "/Users/thomasharte/Projects/ProcessorTests/808 std::string operand; using Source = InstructionSet::x86::Source; - switch(pointer.source()) { - case Source::eAX: return is_byte_operation ? "al" : "ax"; - case Source::eCX: return is_byte_operation ? "cl" : "cx"; - case Source::eDX: return is_byte_operation ? "dl" : "dx"; - case Source::eBX: return is_byte_operation ? "bl" : "bx"; - case Source::eSPorAH: return is_byte_operation ? "ah" : "sp"; - case Source::eBPorCH: return is_byte_operation ? "ch" : "bp"; - case Source::eSIorDH: return is_byte_operation ? "dh" : "si"; - case Source::eDIorBH: return is_byte_operation ? "bh" : "di"; - - case Source::ES: return "es"; - case Source::CS: return "cs"; - case Source::SS: return "ss"; - case Source::DS: return "ds"; - case Source::FS: return "fd"; - case Source::GS: return "gs"; + const Source source = pointer.source(); + switch(source) { + // to_string handles all direct register names correctly. + default: return InstructionSet::x86::to_string(source, instruction.operation_size()); case Source::Immediate: - return (std::stringstream() << std::setfill('0') << std::setw(4) << std::uppercase << std::hex << instruction.operand() << 'h').str(); + return (std::stringstream() << std::setfill('0') << std::setw(4) << std::uppercase << std::hex << instruction.operand() << 'h').str(); - default: break; - } - switch(pointer.index()) { - default: break; - case Source::eAX: operand += "ax"; break; + case Source::Indirect: + return (std::stringstream() << + '[' << + InstructionSet::x86::to_string(pointer.index(), data_size(instruction.address_size())) << '+' << + InstructionSet::x86::to_string(pointer.base(), data_size(instruction.address_size())) << '+' << + std::setfill('0') << std::setw(4) << std::uppercase << std::hex << instruction.offset() << 'h' << + ']' + ).str(); } return operand; @@ -163,6 +154,8 @@ constexpr char TestSuiteHome[] = "/Users/thomasharte/Projects/ProcessorTests/808 XCTAssertEqualObjects(objcOperation, test[@"name"]); if(![objcOperation isEqualToString:test[@"name"]]) { + to_string(decoded.second.destination(), decoded.second); + to_string(decoded.second.source(), decoded.second); return false; }