summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
Diffstat (limited to 'src/code')
-rwxr-xr-xsrc/code/build.sh42
-rw-r--r--src/code/reference_decoder/sim86.h27
-rw-r--r--src/code/reference_decoder/sim86_decode.cpp303
-rw-r--r--src/code/reference_decoder/sim86_decode.h35
-rw-r--r--src/code/reference_decoder/sim86_instruction.cpp84
-rw-r--r--src/code/reference_decoder/sim86_instruction.h109
-rw-r--r--src/code/reference_decoder/sim86_instruction_table.cpp27
-rw-r--r--src/code/reference_decoder/sim86_instruction_table.h60
-rw-r--r--src/code/reference_decoder/sim86_instruction_table.inl250
-rw-r--r--src/code/reference_decoder/sim86_lib.cpp73
-rw-r--r--src/code/reference_decoder/sim86_memory.cpp66
-rw-r--r--src/code/reference_decoder/sim86_memory.h28
-rw-r--r--src/code/reference_decoder/sim86_text_table.cpp57
-rw-r--r--src/code/shared_library_test.cpp69
-rw-r--r--src/code/sim86.cpp375
-rw-r--r--src/code/sim86.h53
-rw-r--r--src/code/sim86_shared.h285
17 files changed, 0 insertions, 1943 deletions
diff --git a/src/code/build.sh b/src/code/build.sh
deleted file mode 100755
index 87a5b85..0000000
--- a/src/code/build.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/sh
-
-ThisDir="$(dirname "$(readlink -f "$0")")"
-cd "$ThisDir"
-
-Compiler="clang"
-
-CompilerFlags="
--g
--fdiagnostics-absolute-paths
--nostdinc++
--DSIM86_INTERNAL
--fsanitize=undefined
-"
-
-WarningFlags="
--Wall
--Wextra
--Wno-unused-label
--Wno-unused-variable
--Wno-unused-function
--Wno-unused-but-set-variable
--Wno-missing-field-initializers
--Wno-write-strings
-"
-
-Libs="./reference_decoder/sim86_lib.cpp"
-
-if false
-then
- Source="./shared_library_test.cpp"
- printf '%s\n' "$Source"
- $Compiler $CompilerFlags $WarningFlags \
- -o ../build/shared_library_test \
- $Libs $Source
-fi
-
-Source="sim86.cpp"
-printf '%s\n' "$Source"
-$Compiler $CompilerFlags $WarningFlags \
- -o ../build/sim86 \
- $Libs $Source
diff --git a/src/code/reference_decoder/sim86.h b/src/code/reference_decoder/sim86.h
deleted file mode 100644
index b065a0e..0000000
--- a/src/code/reference_decoder/sim86.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* ========================================================================
-
- (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Please see https://computerenhance.com for more information
-
- ======================================================================== */
-
-typedef char unsigned u8;
-typedef short unsigned u16;
-typedef int unsigned u32;
-typedef long long unsigned u64;
-
-typedef char s8;
-typedef short s16;
-typedef int s32;
-typedef long long s64;
-
-typedef s32 b32;
-
-#define ArrayCount(Array) (sizeof(Array) / sizeof((Array)[0]))
-
-static u32 const SIM86_VERSION = 4;
diff --git a/src/code/reference_decoder/sim86_decode.cpp b/src/code/reference_decoder/sim86_decode.cpp
deleted file mode 100644
index dc084d5..0000000
--- a/src/code/reference_decoder/sim86_decode.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-/* ========================================================================
-
- (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Please see https://computerenhance.com for more information
-
- ======================================================================== */
-
-struct decode_context
-{
- u32 DefaultSegment;
- u32 AdditionalFlags;
-};
-
-static instruction_operand GetRegOperand(u32 IntelRegIndex, b32 Wide)
-{
- // NOTE(casey): This maps Intel's REG and RM field encodings for registers to our encoding for registers.
- register_access RegTable[][2] =
- {
- {{Register_a, 0, 1}, {Register_a, 0, 2}},
- {{Register_c, 0, 1}, {Register_c, 0, 2}},
- {{Register_d, 0, 1}, {Register_d, 0, 2}},
- {{Register_b, 0, 1}, {Register_b, 0, 2}},
- {{Register_a, 1, 1}, {Register_sp, 0, 2}},
- {{Register_c, 1, 1}, {Register_bp, 0, 2}},
- {{Register_d, 1, 1}, {Register_si, 0, 2}},
- {{Register_b, 1, 1}, {Register_di, 0, 2}},
- };
-
- instruction_operand Result = {};
- Result.Type = Operand_Register;
- Result.Register = RegTable[IntelRegIndex & 0x7][(Wide != 0)];
-
- return Result;
-}
-
-// NOTE(casey): ParseDataValue is not a real function, it's basically just a macro that is used in
-// TryParse. It should never be called otherwise, but that is not something you can do in C++.
-// In other languages it would be a "local function".
-static u32 ParseDataValue(segmented_access *Access, b32 Exists, b32 Wide, b32 SignExtended)
-{
- u32 Result = {};
-
- if(Exists)
- {
- if(Wide)
- {
- u8 D0 = *AccessMemory(*Access, 0);
- u8 D1 = *AccessMemory(*Access, 1);
- Result = (D1 << 8) | D0;
- Access->SegmentOffset += 2;
- }
- else
- {
- Result = *AccessMemory(*Access);
- if(SignExtended)
- {
- Result = (s32)*(s8 *)&Result;
- }
- Access->SegmentOffset += 1;
- }
- }
-
- return Result;
-}
-
-static instruction TryDecode(decode_context *Context, instruction_encoding *Inst, segmented_access At)
-{
- instruction Dest = {};
- b32 Has[Bits_Count] = {};
- u32 Bits[Bits_Count] = {};
- b32 Valid = true;
-
- u64 StartingAddress = GetAbsoluteAddressOf(At);
-
- u8 BitsPendingCount = 0;
- u8 BitsPending = 0;
- for(u32 BitsIndex = 0; Valid && (BitsIndex < ArrayCount(Inst->Bits)); ++BitsIndex)
- {
- instruction_bits TestBits = Inst->Bits[BitsIndex];
- if(TestBits.Usage == Bits_End)
- {
- // NOTE(casey): That's the end of the instruction format.
- break;
- }
-
- u32 ReadBits = TestBits.Value;
- if(TestBits.BitCount != 0)
- {
- if(BitsPendingCount == 0)
- {
- BitsPendingCount = 8;
- BitsPending = *AccessMemory(At);
- ++At.SegmentOffset;
- }
-
- // NOTE(casey): If this assert fires, it means we have an error in our table,
- // since there are no 8086 instructions that have bit values straddling a
- // byte boundary.
- assert(TestBits.BitCount <= BitsPendingCount);
-
- BitsPendingCount -= TestBits.BitCount;
- ReadBits = BitsPending;
- ReadBits >>= BitsPendingCount;
- ReadBits &= ~(0xff << TestBits.BitCount);
- }
-
- if(TestBits.Usage == Bits_Literal)
- {
- // NOTE(casey): This is a "required" sequence
- Valid = Valid && (ReadBits == TestBits.Value);
- }
- else
- {
- Bits[TestBits.Usage] |= (ReadBits << TestBits.Shift);
- Has[TestBits.Usage] = true;
- }
- }
-
- if(Valid)
- {
- u32 Mod = Bits[Bits_MOD];
- u32 RM = Bits[Bits_RM];
- u32 W = Bits[Bits_W];
- b32 S = Bits[Bits_S];
- b32 D = Bits[Bits_D];
-
- b32 HasDirectAddress = ((Mod == 0b00) && (RM == 0b110));
- Has[Bits_Disp] = ((Has[Bits_Disp]) || (Mod == 0b10) || (Mod == 0b01) || HasDirectAddress);
-
- b32 DisplacementIsW = ((Bits[Bits_DispAlwaysW]) || (Mod == 0b10) || HasDirectAddress);
- b32 DataIsW = ((Bits[Bits_WMakesDataW]) && !S && W);
-
- Bits[Bits_Disp] |= ParseDataValue(&At, Has[Bits_Disp], DisplacementIsW, (!DisplacementIsW));
- Bits[Bits_Data] |= ParseDataValue(&At, Has[Bits_Data], DataIsW, S);
-
- Dest.Op = Inst->Op;
- Dest.Flags = Context->AdditionalFlags;
- Dest.Address = StartingAddress;
- Dest.Size = GetAbsoluteAddressOf(At) - StartingAddress;
- Dest.SegmentOverride = Context->DefaultSegment;
-
- if(W)
- {
- Dest.Flags |= Inst_Wide;
- }
-
- if(Bits[Bits_Far])
- {
- Dest.Flags |= Inst_Far;
- }
-
- if(Bits[Bits_Z])
- {
- Dest.Flags |= Inst_RepNE;
- }
-
- u32 Disp = Bits[Bits_Disp];
- s16 Displacement = (s16)Disp;
-
- instruction_operand *RegOperand = &Dest.Operands[D ? 0 : 1];
- instruction_operand *ModOperand = &Dest.Operands[D ? 1 : 0];
-
- if(Has[Bits_SR])
- {
- *RegOperand = RegisterOperand(Register_es + (Bits[Bits_SR] & 0x3), 2);
- }
-
- if(Has[Bits_REG])
- {
- *RegOperand = GetRegOperand(Bits[Bits_REG], W);
- }
-
- if(Has[Bits_MOD])
- {
- if(Mod == 0b11)
- {
- *ModOperand = GetRegOperand(RM, W || (Bits[Bits_RMRegAlwaysW]));
- }
- else
- {
- register_mapping_8086 IntelTerm0[8] = { Register_b, Register_b, Register_bp, Register_bp, Register_si, Register_di, Register_bp, Register_b};
- register_mapping_8086 IntelTerm1[8] = {Register_si, Register_di, Register_si, Register_di};
-
- u32 I = RM&0x7;
- register_mapping_8086 Term0 = IntelTerm0[I];
- register_mapping_8086 Term1 = IntelTerm1[I];
- if((Mod == 0b00) && (RM == 0b110))
- {
- Term0 = {};
- Term1 = {};
- }
-
- *ModOperand = EffectiveAddressOperand(RegisterAccess(Term0, 0, 2), RegisterAccess(Term1, 0, 2), Displacement);
- }
- }
-
- if(Has[Bits_Data] && Has[Bits_Disp] && !Has[Bits_MOD])
- {
- Dest.Operands[0] = IntersegmentAddressOperand(Bits[Bits_Data], Bits[Bits_Disp]);
- }
- else
- {
- //
- // NOTE(casey): Because there are some strange opcodes that do things like have an immediate as
- // a _destination_ ("out", for example), I define immediates and other "additional operands" to
- // go in "whatever slot was not used by the reg and mod fields".
- //
-
- instruction_operand *LastOperand = &Dest.Operands[0];
- if(LastOperand->Type)
- {
- LastOperand = &Dest.Operands[1];
- }
-
- if(Bits[Bits_RelJMPDisp])
- {
- *LastOperand = ImmediateOperand(Displacement, Immediate_RelativeJumpDisplacement);
- }
- else if(Has[Bits_Data])
- {
- *LastOperand = ImmediateOperand(Bits[Bits_Data]);
- }
- else if(Has[Bits_V])
- {
- if(Bits[Bits_V])
- {
- *LastOperand = RegisterOperand(Register_c, 1);
- }
- else
- {
- *LastOperand = ImmediateOperand(1);
- }
- }
- }
- }
-
- return Dest;
-}
-
-static instruction DecodeInstruction(instruction_table Table, segmented_access At)
-{
- /* TODO(casey): Hmm. It seems like this is a very inefficient way to parse
- instructions, isn't it? For every instruction, we check every entry in the
- table until we find a match. Is this bad design? Or did the person who wrote
- it know what they were doing, and has a plan for how it can be optimized
- later? Only time will tell... :) */
-
- decode_context Context = {};
- instruction Result = {};
-
- u32 StartingAddress = GetAbsoluteAddressOf(At);
- u32 TotalSize = 0;
- while(TotalSize < Table.MaxInstructionByteCount)
- {
- Result = {};
- for(u32 Index = 0; Index < Table.EncodingCount; ++Index)
- {
- instruction_encoding Inst = Table.Encodings[Index];
- Result = TryDecode(&Context, &Inst, At);
- if(Result.Op)
- {
- At.SegmentOffset += Result.Size;
- TotalSize += Result.Size;
- break;
- }
- }
-
- if(Result.Op == Op_lock)
- {
- Context.AdditionalFlags |= Inst_Lock;
- }
- else if(Result.Op == Op_rep)
- {
- Context.AdditionalFlags |= Inst_Rep | (Result.Flags & Inst_RepNE);
- }
- else if(Result.Op == Op_segment)
- {
- Context.AdditionalFlags |= Inst_Segment;
- Context.DefaultSegment = Result.Operands[1].Register.Index;
- }
- else
- {
- break;
- }
- }
-
- if(TotalSize <= Table.MaxInstructionByteCount)
- {
- Result.Address = StartingAddress;
- Result.Size = TotalSize;
- }
- else
- {
- Result = {};
- }
-
- return Result;
-}
diff --git a/src/code/reference_decoder/sim86_decode.h b/src/code/reference_decoder/sim86_decode.h
deleted file mode 100644
index 534ce2d..0000000
--- a/src/code/reference_decoder/sim86_decode.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* ========================================================================
-
- (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Please see https://computerenhance.com for more information
-
- ======================================================================== */
-
-enum register_mapping_8086
-{
- Register_none,
-
- Register_a,
- Register_b,
- Register_c,
- Register_d,
- Register_sp,
- Register_bp,
- Register_si,
- Register_di,
- Register_es,
- Register_cs,
- Register_ss,
- Register_ds,
- Register_ip,
- Register_flags,
-
- Register_count,
-};
-
-static instruction DecodeInstruction(instruction_table Table, segmented_access At);
diff --git a/src/code/reference_decoder/sim86_instruction.cpp b/src/code/reference_decoder/sim86_instruction.cpp
deleted file mode 100644
index 34fcf1f..0000000
--- a/src/code/reference_decoder/sim86_instruction.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/* ========================================================================
-
- (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Please see https://computerenhance.com for more information
-
- ======================================================================== */
-
-static b32 OperandIsType(instruction Instruction, u32 Index, operand_type Type)
-{
- b32 Result = (Instruction.Operands[Index].Type == Type);
- return Result;
-}
-
-static instruction_operand GetOperand(instruction Instruction, u32 Index)
-{
- assert(Index < ArrayCount(Instruction.Operands));
- instruction_operand Result = Instruction.Operands[Index];
- return Result;
-}
-
-static register_access RegisterAccess(u32 Index, u32 Offset, u32 Count)
-{
- register_access Result = {};
-
- Result.Index = Index;
- Result.Offset = Offset;
- Result.Count = Count;
-
- return Result;
-}
-
-static instruction_operand IntersegmentAddressOperand(u32 Segment, s32 Displacement)
-{
- instruction_operand Result = {};
-
- Result.Type = Operand_Memory;
- Result.Address.ExplicitSegment = Segment;
- Result.Address.Displacement = Displacement;
- Result.Address.Flags = Address_ExplicitSegment;
-
- return Result;
-}
-
-static instruction_operand EffectiveAddressOperand(register_access Term0, register_access Term1, s32 Displacement)
-{
- instruction_operand Result = {};
-
- Result.Type = Operand_Memory;
- Result.Address.Terms[0].Register = Term0;
- Result.Address.Terms[0].Scale = 1;
- Result.Address.Terms[1].Register = Term1;
- Result.Address.Terms[1].Scale = 1;
- Result.Address.Displacement = Displacement;
-
- return Result;
-}
-
-static instruction_operand RegisterOperand(u32 Index, u32 Count)
-{
- instruction_operand Result = {};
-
- Result.Type = Operand_Register;
- Result.Register.Index = Index;
- Result.Register.Offset = 0;
- Result.Register.Count = Count;
-
- return Result;
-}
-
-static instruction_operand ImmediateOperand(u32 Value, u32 Flags = 0)
-{
- instruction_operand Result = {};
-
- Result.Type = Operand_Immediate;
- Result.Immediate.Value = Value;
- Result.Immediate.Flags = Flags;
-
- return Result;
-}
diff --git a/src/code/reference_decoder/sim86_instruction.h b/src/code/reference_decoder/sim86_instruction.h
deleted file mode 100644
index 191635a..0000000
--- a/src/code/reference_decoder/sim86_instruction.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* ========================================================================
-
- (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Please see https://computerenhance.com for more information
-
- ======================================================================== */
-
-typedef u32 register_index;
-
-// NOTE(casey): To make it easier to compile with languages which do not
-// have auto-typedef'ing (like C, etc.), all types are manually typedef'd here.
-typedef struct register_access register_access;
-typedef struct effective_address_term effective_address_term;
-typedef struct effective_address_expression effective_address_expression;
-typedef struct immediate immediate;
-typedef struct instruction_operand instruction_operand;
-typedef struct instruction instruction;
-
-typedef enum operation_type : u32
-{
- Op_None,
-
-#define INST(Mnemonic, ...) Op_##Mnemonic,
-#define INSTALT(...)
-#include "sim86_instruction_table.inl"
-
- Op_Count,
-} operation_type;
-
-enum instruction_flag
-{
- Inst_Lock = 0x1,
- Inst_Rep = 0x2,
- Inst_Segment = 0x4,
- Inst_Wide = 0x8,
- Inst_Far = 0x10,
- Inst_RepNE = 0x20, // NOTE(casey): For user convenience, this will be set _in addition to_ Inst_Rep for REPNE/REPNZ
-};
-
-struct register_access
-{
- register_index Index;
- u32 Offset;
- u32 Count;
-};
-
-struct effective_address_term
-{
- register_access Register;
- s32 Scale;
-};
-
-enum effective_address_flag
-{
- Address_ExplicitSegment = 0x1,
-};
-struct effective_address_expression
-{
- effective_address_term Terms[2];
- u32 ExplicitSegment;
- s32 Displacement;
- u32 Flags;
-};
-
-enum immediate_flag
-{
- Immediate_RelativeJumpDisplacement = 0x1,
-};
-struct immediate
-{
- s32 Value;
- u32 Flags;
-};
-
-typedef enum operand_type : u32
-{
- Operand_None,
- Operand_Register,
- Operand_Memory,
- Operand_Immediate,
-} operand_type;
-struct instruction_operand
-{
- operand_type Type;
- union
- {
- effective_address_expression Address;
- register_access Register;
- immediate Immediate;
- };
-};
-
-struct instruction
-{
- u32 Address;
- u32 Size;
-
- operation_type Op;
- u32 Flags;
-
- instruction_operand Operands[2];
-
- register_index SegmentOverride;
-};
diff --git a/src/code/reference_decoder/sim86_instruction_table.cpp b/src/code/reference_decoder/sim86_instruction_table.cpp
deleted file mode 100644
index be3ec82..0000000
--- a/src/code/reference_decoder/sim86_instruction_table.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/* ========================================================================
-
- (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Please see https://computerenhance.com for more information
-
- ======================================================================== */
-
-static instruction_encoding InstructionTable8086[] =
-{
-#include "sim86_instruction_table.inl"
-};
-
-static instruction_table Get8086InstructionTable()
-{
- instruction_table Result = {};
-
- Result.EncodingCount = ArrayCount(InstructionTable8086);
- Result.Encodings = InstructionTable8086;
- Result.MaxInstructionByteCount = 15; // NOTE(casey): This is the "Intel-specified" maximum length of an instruction, including prefixes
-
- return Result;
-}
diff --git a/src/code/reference_decoder/sim86_instruction_table.h b/src/code/reference_decoder/sim86_instruction_table.h
deleted file mode 100644
index ed8aea8..0000000
--- a/src/code/reference_decoder/sim86_instruction_table.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* ========================================================================
-
- (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Please see https://computerenhance.com for more information
-
- ======================================================================== */
-
-enum instruction_bits_usage : u8
-{
- Bits_End, // NOTE(casey): The 0 value, indicating the end of the instruction encoding array
-
- Bits_Literal, // NOTE(casey): These are opcode bits that identify instructions
-
- // NOTE(casey): These bits correspond directly to the 8086 instruction manual
- Bits_D,
- Bits_S,
- Bits_W,
- Bits_V,
- Bits_Z,
- Bits_MOD,
- Bits_REG,
- Bits_RM,
- Bits_SR,
- Bits_Disp,
- Bits_Data,
-
- Bits_DispAlwaysW, // NOTE(casey): Tag for instructions where the displacement is always 16 bits
- Bits_WMakesDataW, // NOTE(casey): Tag for instructions where SW=01 makes the data field become 16 bits
- Bits_RMRegAlwaysW, // NOTE(casey): Tag for instructions where the register encoded in RM is always 16-bit width
- Bits_RelJMPDisp, // NOTE(casey): Tag for instructions that require address adjustment to go through NASM properly
- Bits_Far, // NOTE(casey): Tag for instructions that require a "far" keyword in their ASM to select the right opcode
-
- Bits_Count,
-};
-
-struct instruction_bits
-{
- instruction_bits_usage Usage;
- u8 BitCount;
- u8 Shift;
- u8 Value;
-};
-
-struct instruction_encoding
-{
- operation_type Op;
- instruction_bits Bits[16];
-};
-
-struct instruction_table
-{
- instruction_encoding *Encodings;
- u32 EncodingCount;
- u32 MaxInstructionByteCount;
-};
diff --git a/src/code/reference_decoder/sim86_instruction_table.inl b/src/code/reference_decoder/sim86_instruction_table.inl
deleted file mode 100644
index 576c0f6..0000000
--- a/src/code/reference_decoder/sim86_instruction_table.inl
+++ /dev/null
@@ -1,250 +0,0 @@
-/* ========================================================================
-
- (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Please see https://computerenhance.com for more information
-
- ======================================================================== */
-
-/*
- NOTE(casey): This instruction table is a direct translation of table 4-12 in the Intel 8086 manual.
- The macros are designed to allow direct transcription, without changing the order or manner
- of specification in the table in any way. Additional "implicit" versions of the macros are provided
- so that hard-coded fields can be supplied uniformly.
-
- The table is also designed to allow you to include it multiple times to "pull out" other things
- from the table, such as opcode mnemonics as strings or enums, etc.
-*/
-
-#ifndef INST
-#define INST(Mnemonic, ...) {Op_##Mnemonic, __VA_ARGS__},
-#endif
-
-#ifndef INSTALT
-#define INSTALT INST
-#endif
-
-#define B(Bits) {Bits_Literal, sizeof(#Bits)-1, 0, 0b##Bits}
-#define D {Bits_D, 1}
-#define S {Bits_S, 1}
-#define W {Bits_W, 1}
-#define V {Bits_V, 1}
-#define Z {Bits_Z, 1}
-
-#define XXX {Bits_Data, 3, 0}
-#define YYY {Bits_Data, 3, 3}
-#define RM {Bits_RM, 3}
-#define MOD {Bits_MOD, 2}
-#define REG {Bits_REG, 3}
-#define SR {Bits_SR, 2}
-
-#define ImpW(Value) {Bits_W, 0, 0, Value}
-#define ImpREG(Value) {Bits_REG, 0, 0, Value}
-#define ImpMOD(Value) {Bits_MOD, 0, 0, Value}
-#define ImpRM(Value) {Bits_RM, 0, 0, Value}
-#define ImpD(Value) {Bits_D, 0, 0, Value}
-#define ImpS(Value) {Bits_S, 0, 0, Value}
-
-#define DISP {Bits_Disp, 0, 0, 0}
-#define ADDR {Bits_Disp, 0, 0, 0}, {Bits_DispAlwaysW, 0, 0, 1}
-#define DATA {Bits_Data, 0, 0, 0}
-#define DATA_IF_W {Bits_WMakesDataW, 0, 0, 1}
-#define Flags(F) {F, 0, 0, 1}
-
-INST(mov, {B(100010), D, W, MOD, REG, RM})
-INSTALT(mov, {B(1100011), W, MOD, B(000), RM, DATA, DATA_IF_W, ImpD(0)})
-INSTALT(mov, {B(1011), W, REG, DATA, DATA_IF_W, ImpD(1)})
-INSTALT(mov, {B(1010000), W, ADDR, ImpREG(0), ImpMOD(0), ImpRM(0b110), ImpD(1)})
-INSTALT(mov, {B(1010001), W, ADDR, ImpREG(0), ImpMOD(0), ImpRM(0b110), ImpD(0)})
-INSTALT(mov, {B(100011), D, B(0), MOD, B(0), SR, RM, ImpW(1)}) // NOTE(casey): This collapses 2 entries in the 8086 table by adding an explicit D bit
-
-INST(push, {B(11111111), MOD, B(110), RM, ImpW(1), ImpD(1)})
-INSTALT(push, {B(01010), REG, ImpW(1), ImpD(1)})
-INSTALT(push, {B(000), SR, B(110), ImpW(1), ImpD(1)})
-
-INST(pop, {B(10001111), MOD, B(000), RM, ImpW(1), ImpD(1)})
-INSTALT(pop, {B(01011), REG, ImpW(1), ImpD(1)})
-INSTALT(pop, {B(000), SR, B(111), ImpW(1), ImpD(1)})
-
-INST(xchg, {B(1000011), W, MOD, REG, RM, ImpD(1)})
-INSTALT(xchg, {B(10010), REG, ImpMOD(0b11), ImpW(1), ImpRM(0)})
-
-INST(in, {B(1110010), W, DATA, ImpREG(0), ImpD(1)})
-INSTALT(in, {B(1110110), W, ImpREG(0), ImpD(1), ImpMOD(0b11), ImpRM(2), Flags(Bits_RMRegAlwaysW)})
-INST(out, {B(1110011), W, DATA, ImpREG(0), ImpD(0)})
-INSTALT(out, {B(1110111), W, ImpREG(0), ImpD(0), ImpMOD(0b11), ImpRM(2), Flags(Bits_RMRegAlwaysW)})
-
-INST(xlat, {B(11010111)})
-INST(lea, {B(10001101), MOD, REG, RM, ImpD(1), ImpW(1)})
-INST(lds, {B(11000101), MOD, REG, RM, ImpD(1), ImpW(1)})
-INST(les, {B(11000100), MOD, REG, RM, ImpD(1), ImpW(1)})
-INST(lahf, {B(10011111)})
-INST(sahf, {B(10011110)})
-INST(pushf, {B(10011100)})
-INST(popf, {B(10011101)})
-
-INST(add, {B(000000), D, W, MOD, REG, RM})
-INSTALT(add, {B(100000), S, W, MOD, B(000), RM, DATA, DATA_IF_W})
-INSTALT(add, {B(0000010), W, DATA, DATA_IF_W, ImpREG(0), ImpD(1)})
-
-INST(adc, {B(000100), D, W, MOD, REG, RM})
-INSTALT(adc, {B(100000), S, W, MOD, B(010), RM, DATA, DATA_IF_W})
-INSTALT(adc, {B(0001010), W, DATA, DATA_IF_W, ImpREG(0), ImpD(1)})
-
-INST(inc, {B(1111111), W, MOD, B(000), RM, ImpD(1)})
-INSTALT(inc, {B(01000), REG, ImpW(1), ImpD(1)})
-
-INST(aaa, {B(00110111)})
-INST(daa, {B(00100111)})
-
-INST(sub, {B(001010), D, W, MOD, REG, RM})
-INSTALT(sub, {B(100000), S, W, MOD, B(101), RM, DATA, DATA_IF_W})
-INSTALT(sub, {B(0010110), W, DATA, DATA_IF_W, ImpREG(0), ImpD(1)})
-
-INST(sbb, {B(000110), D, W, MOD, REG, RM})
-INSTALT(sbb, {B(100000), S, W, MOD, B(011), RM, DATA, DATA_IF_W})
-INSTALT(sbb, {B(0001110), W, DATA, DATA_IF_W, ImpREG(0), ImpD(1)})
-
-INST(dec, {B(1111111), W, MOD, B(001), RM, ImpD(1)})
-INSTALT(dec, {B(01001), REG, ImpW(1), ImpD(1)})
-
-INST(neg, {B(1111011), W, MOD, B(011), RM})
-
-INST(cmp, {B(001110), D, W, MOD, REG, RM})
-INSTALT(cmp, {B(100000), S, W, MOD, B(111), RM, DATA, DATA_IF_W})
-INSTALT(cmp, {B(0011110), W, DATA, DATA_IF_W, ImpREG(0), ImpD(1)}) // NOTE(casey): The manual table suggests this data is only 8-bit, but wouldn't it be 16 as well?
-
-INST(aas, {B(00111111)})
-INST(das, {B(00101111)})
-INST(mul, {B(1111011), W, MOD, B(100), RM, ImpS(0)})
-INST(imul, {B(1111011), W, MOD, B(101), RM, ImpS(1)})
-INST(aam, {B(11010100), B(00001010)}) // NOTE(casey): The manual says this has a DISP... but how could it? What for??
-INST(div, {B(1111011), W, MOD, B(110), RM, ImpS(0)})
-INST(idiv, {B(1111011), W, MOD, B(111), RM, ImpS(1)})
-INST(aad, {B(11010101), B(00001010)})
-INST(cbw, {B(10011000)})
-INST(cwd, {B(10011001)})
-
-INST(not, {B(1111011), W, MOD, B(010), RM})
-INST(shl, {B(110100), V, W, MOD, B(100), RM})
-INST(shr, {B(110100), V, W, MOD, B(101), RM})
-INST(sar, {B(110100), V, W, MOD, B(111), RM})
-INST(rol, {B(110100), V, W, MOD, B(000), RM})
-INST(ror, {B(110100), V, W, MOD, B(001), RM})
-INST(rcl, {B(110100), V, W, MOD, B(010), RM})
-INST(rcr, {B(110100), V, W, MOD, B(011), RM})
-
-INST(and, {B(001000), D, W, MOD, REG, RM})
-INSTALT(and, {B(1000000), W, MOD, B(100), RM, DATA, DATA_IF_W})
-INSTALT(and, {B(0010010), W, DATA, DATA_IF_W, ImpREG(0), ImpD(1)})
-
-INST(test, {B(1000010), W, MOD, REG, RM}) // NOTE(casey): The manual suggests there is a D flag here, but it doesn't appear to be true (it would conflict with xchg if it did)
-INSTALT(test, {B(1111011), W, MOD, B(000), RM, DATA, DATA_IF_W})
-INSTALT(test, {B(1010100), W, DATA, DATA_IF_W, ImpREG(0), ImpD(1)}) // NOTE(casey): The manual table suggests this data is only 8-bit, but it seems like it could be 16 too?
-
-INST(or, {B(000010), D, W, MOD, REG, RM})
-INSTALT(or, {B(1000000), W, MOD, B(001), RM, DATA, DATA_IF_W})
-INSTALT(or, {B(0000110), W, DATA, DATA_IF_W, ImpREG(0), ImpD(1)})
-
-INST(xor, {B(001100), D, W, MOD, REG, RM})
-INSTALT(xor, {B(1000000), W, MOD, B(110), RM, DATA, DATA_IF_W}) // NOTE(casey): The manual has conflicting information about this encoding, but I believe this is the correct binary pattern.
-INSTALT(xor, {B(0011010), W, DATA, DATA_IF_W, ImpREG(0), ImpD(1)})
-
-INST(rep, {B(1111001), Z})
-INST(movs, {B(1010010), W})
-INST(cmps, {B(1010011), W})
-INST(scas, {B(1010111), W})
-INST(lods, {B(1010110), W})
-INST(stos, {B(1010101), W})
-
-INST(call, {B(11101000), ADDR, Flags(Bits_RelJMPDisp)})
-INSTALT(call, {B(11111111), MOD, B(010), RM, ImpW(1)})
-INSTALT(call, {B(10011010), ADDR, DATA, DATA_IF_W, ImpW(1), Flags(Bits_Far)})
-INSTALT(call, {B(11111111), MOD, B(011), RM, ImpW(1), Flags(Bits_Far)})
-
-INST(jmp, {B(11101001), ADDR, Flags(Bits_RelJMPDisp)})
-INSTALT(jmp, {B(11101011), DISP, Flags(Bits_RelJMPDisp)})
-INSTALT(jmp, {B(11111111), MOD, B(100), RM, ImpW(1)})
-INSTALT(jmp, {B(11101010), ADDR, DATA, DATA_IF_W, ImpW(1), Flags(Bits_Far)})
-INSTALT(jmp, {B(11111111), MOD, B(101), RM, ImpW(1), Flags(Bits_Far)})
-
-// NOTE(casey): The actual Intel manual does not distinguish mnemonics RET and RETF,
-// but NASM needs this to reassemble properly, so we do.
-INST(ret, {B(11000011)})
-INSTALT(ret, {B(11000010), DATA, DATA_IF_W, ImpW(1)})
-INST(retf, {B(11001011), Flags(Bits_Far)})
-INSTALT(retf, {B(11001010), DATA, DATA_IF_W, ImpW(1), Flags(Bits_Far)})
-
-INST(je, {B(01110100), DISP, Flags(Bits_RelJMPDisp)})
-INST(jl, {B(01111100), DISP, Flags(Bits_RelJMPDisp)})
-INST(jle, {B(01111110), DISP, Flags(Bits_RelJMPDisp)})
-INST(jb, {B(01110010), DISP, Flags(Bits_RelJMPDisp)})
-INST(jbe, {B(01110110), DISP, Flags(Bits_RelJMPDisp)})
-INST(jp, {B(01111010), DISP, Flags(Bits_RelJMPDisp)})
-INST(jo, {B(01110000), DISP, Flags(Bits_RelJMPDisp)})
-INST(js, {B(01111000), DISP, Flags(Bits_RelJMPDisp)})
-INST(jne, {B(01110101), DISP, Flags(Bits_RelJMPDisp)})
-INST(jnl, {B(01111101), DISP, Flags(Bits_RelJMPDisp)})
-INST(jg, {B(01111111), DISP, Flags(Bits_RelJMPDisp)})
-INST(jnb, {B(01110011), DISP, Flags(Bits_RelJMPDisp)})
-INST(ja, {B(01110111), DISP, Flags(Bits_RelJMPDisp)})
-INST(jnp, {B(01111011), DISP, Flags(Bits_RelJMPDisp)})
-INST(jno, {B(01110001), DISP, Flags(Bits_RelJMPDisp)})
-INST(jns, {B(01111001), DISP, Flags(Bits_RelJMPDisp)})
-INST(loop, {B(11100010), DISP, Flags(Bits_RelJMPDisp)})
-INST(loopz, {B(11100001), DISP, Flags(Bits_RelJMPDisp)})
-INST(loopnz, {B(11100000), DISP, Flags(Bits_RelJMPDisp)})
-INST(jcxz, {B(11100011), DISP, Flags(Bits_RelJMPDisp)})
-
-INST(int, {B(11001101), DATA})
-INST(int3, {B(11001100)}) // TODO(casey): The manual does not suggest that this intrinsic has an "int3" mnemonic, but NASM thinks so
-
-INST(into, {B(11001110)})
-INST(iret, {B(11001111)})
-
-INST(clc, {B(11111000)})
-INST(cmc, {B(11110101)})
-INST(stc, {B(11111001)})
-INST(cld, {B(11111100)})
-INST(std, {B(11111101)})
-INST(cli, {B(11111010)})
-INST(sti, {B(11111011)})
-INST(hlt, {B(11110100)})
-INST(wait, {B(10011011)})
-INST(esc, {B(11011), XXX, MOD, YYY, RM})
-INST(lock, {B(11110000)})
-INST(segment, {B(001), SR, B(110)})
-
-#undef INST
-#undef INSTALT
-
-#undef B
-#undef D
-#undef S
-#undef W
-#undef V
-#undef Z
-
-#undef XXX
-#undef YYY
-#undef RM
-#undef MOD
-#undef REG
-#undef SR
-
-#undef ImpW
-#undef ImpREG
-#undef ImpMOD
-#undef ImpRM
-#undef ImpD
-#undef ImpS
-
-#undef DISP
-#undef ADDR
-#undef DATA
-#undef DATA_IF_W
-#undef Flags
diff --git a/src/code/reference_decoder/sim86_lib.cpp b/src/code/reference_decoder/sim86_lib.cpp
deleted file mode 100644
index 6971eb2..0000000
--- a/src/code/reference_decoder/sim86_lib.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/* ========================================================================
-
- (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Please see https://computerenhance.com for more information
-
- ======================================================================== */
-
-#define assert(...)
-
-#include "sim86.h"
-
-#include "sim86_instruction.h"
-#include "sim86_instruction_table.h"
-#include "sim86_memory.h"
-#include "sim86_decode.h"
-
-#include "sim86_instruction.cpp"
-#include "sim86_instruction_table.cpp"
-#include "sim86_memory.cpp"
-#include "sim86_decode.cpp"
-#include "sim86_text_table.cpp"
-
-extern "C" u32 Sim86_GetVersion(void)
-{
- u32 Result = SIM86_VERSION;
- return Result;
-}
-
-extern "C" void Sim86_Decode8086Instruction(u32 SourceSize, u8 *Source, instruction *Dest)
-{
- instruction_table Table = Get8086InstructionTable();
-
- // NOTE(casey): The 8086 decoder requires the ability to read up to 15 bytes (the maximum
- // allowable instruction size)
- assert(Table.MaxInstructionByteCount == 15);
- u8 GuardBuffer[16] = {};
- if(SourceSize < Table.MaxInstructionByteCount)
- {
- // NOTE(casey): I replaced the memcpy here with a manual copy to make it easier for
- // people compiling on things like WebAssembly who do not want to use Emscripten.
- for(u32 I = 0; I < SourceSize; ++I)
- {
- GuardBuffer[I] = Source[I];
- }
-
- Source = GuardBuffer;
- }
-
- segmented_access At = FixedMemoryPow2(4, Source);
- *Dest = DecodeInstruction(Table, At);
-}
-
-extern "C" char const *Sim86_RegisterNameFromOperand(register_access *RegAccess)
-{
- char const *Result = GetRegName(*RegAccess);
- return Result;
-}
-
-extern "C" char const *Sim86_MnemonicFromOperationType(operation_type Type)
-{
- char const *Result = GetMnemonic(Type);
- return Result;
-}
-
-extern "C" void Sim86_Get8086InstructionTable(instruction_table *Dest)
-{
- *Dest = Get8086InstructionTable();
-} \ No newline at end of file
diff --git a/src/code/reference_decoder/sim86_memory.cpp b/src/code/reference_decoder/sim86_memory.cpp
deleted file mode 100644
index 1d58ede..0000000
--- a/src/code/reference_decoder/sim86_memory.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/* ========================================================================
-
- (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Please see https://computerenhance.com for more information
-
- ======================================================================== */
-
-static u32 GetHighestAddress(segmented_access SegMem)
-{
- u32 Result = SegMem.Mask;
- return Result;
-}
-
-static u32 GetAbsoluteAddressOf(u32 Mask, u16 SegmentBase, u16 SegmentOffset, u16 AdditionalOffset)
-{
- u32 Result = (((u32)SegmentBase << 4) + (u32)(SegmentOffset + AdditionalOffset)) & Mask;
- return Result;
-}
-
-static u32 GetAbsoluteAddressOf(segmented_access SegMem, u16 Offset)
-{
- u32 Result = GetAbsoluteAddressOf(SegMem.Mask, SegMem.SegmentBase, SegMem.SegmentOffset, Offset);
- return Result;
-}
-
-static segmented_access MoveBaseBy(segmented_access Access, s32 Offset)
-{
- Access.SegmentOffset += Offset;
-
- segmented_access Result = Access;
-
- Result.SegmentBase += (Result.SegmentOffset >> 4);
- Result.SegmentOffset &= 0xf;
-
- assert(GetAbsoluteAddressOf(Result, 0) == GetAbsoluteAddressOf(Access, 0));
-
- return Result;
-}
-
-static u8 *AccessMemory(segmented_access SegMem, u16 Offset)
-{
- u32 AbsAddr = GetAbsoluteAddressOf(SegMem, Offset);
- u8 *Result = SegMem.Memory + AbsAddr;
- return Result;
-}
-
-static b32 IsValid(segmented_access SegMem)
-{
- b32 Result = (SegMem.Mask != 0);
- return Result;
-}
-
-static segmented_access FixedMemoryPow2(u32 SizePow2, u8 *Memory)
-{
- segmented_access Result = {};
-
- Result.Memory = Memory;
- Result.Mask = (1 << SizePow2) - 1;
-
- return Result;
-}
diff --git a/src/code/reference_decoder/sim86_memory.h b/src/code/reference_decoder/sim86_memory.h
deleted file mode 100644
index 4e790dc..0000000
--- a/src/code/reference_decoder/sim86_memory.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* ========================================================================
-
- (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Please see https://computerenhance.com for more information
-
- ======================================================================== */
-
-struct segmented_access
-{
- u8 *Memory;
- u32 Mask;
- u16 SegmentBase;
- u16 SegmentOffset;
-};
-
-static u32 GetHighestAddress(segmented_access SegMem);
-static u32 GetAbsoluteAddressOf(segmented_access SegMem, u16 Offset = 0);
-static segmented_access MoveBaseBy(segmented_access Access, s32 Offset);
-
-static u8 *AccessMemory(segmented_access SegMem, u16 Offset = 0);
-
-static b32 IsValid(segmented_access SegMem);
-static segmented_access FixedMemoryPow2(u32 SizePow2, u8 *Memory);
diff --git a/src/code/reference_decoder/sim86_text_table.cpp b/src/code/reference_decoder/sim86_text_table.cpp
deleted file mode 100644
index e90a649..0000000
--- a/src/code/reference_decoder/sim86_text_table.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/* ========================================================================
-
- (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Please see https://computerenhance.com for more information
-
- ======================================================================== */
-
-char const *OpcodeMnemonics[] =
-{
- "",
-
-#define INST(Mnemonic, ...) #Mnemonic,
-#define INSTALT(...)
-#include "sim86_instruction_table.inl"
-};
-
-static char const *GetMnemonic(operation_type Op)
-{
- char const *Result = "";
- if(Op < Op_Count)
- {
- Result = OpcodeMnemonics[Op];
- }
-
- return Result;
-}
-
-static char const *GetRegName(register_access Reg)
-{
- char const *Names[][3] =
- {
- {"", "", ""},
- {"al", "ah", "ax"},
- {"bl", "bh", "bx"},
- {"cl", "ch", "cx"},
- {"dl", "dh", "dx"},
- {"sp", "sp", "sp"},
- {"bp", "bp", "bp"},
- {"si", "si", "si"},
- {"di", "di", "di"},
- {"es", "es", "es"},
- {"cs", "cs", "cs"},
- {"ss", "ss", "ss"},
- {"ds", "ds", "ds"},
- {"ip", "ip", "ip"},
- {"flags", "flags", "flags"},
- {"", "", ""}
- };
-
- char const *Result = Names[Reg.Index % ArrayCount(Names)][(Reg.Count == 2) ? 2 : Reg.Offset&1];
- return Result;
-}
diff --git a/src/code/shared_library_test.cpp b/src/code/shared_library_test.cpp
deleted file mode 100644
index aef4fa1..0000000
--- a/src/code/shared_library_test.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* ========================================================================
-
- (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Please see https://computerenhance.com for more information
-
- ======================================================================== */
-
-#include <stdio.h>
-
-#include "sim86_shared.h"
-
-unsigned char ExampleDisassembly[247] =
-{
- 0x03, 0x18, 0x03, 0x5E, 0x00, 0x83, 0xC6, 0x02, 0x83, 0xC5, 0x02, 0x83, 0xC1, 0x08, 0x03, 0x5E,
- 0x00, 0x03, 0x4F, 0x02, 0x02, 0x7A, 0x04, 0x03, 0x7B, 0x06, 0x01, 0x18, 0x01, 0x5E, 0x00, 0x01,
- 0x5E, 0x00, 0x01, 0x4F, 0x02, 0x00, 0x7A, 0x04, 0x01, 0x7B, 0x06, 0x80, 0x07, 0x22, 0x83, 0x82,
- 0xE8, 0x03, 0x1D, 0x03, 0x46, 0x00, 0x02, 0x00, 0x01, 0xD8, 0x00, 0xE0, 0x05, 0xE8, 0x03, 0x04,
- 0xE2, 0x04, 0x09, 0x2B, 0x18, 0x2B, 0x5E, 0x00, 0x83, 0xEE, 0x02, 0x83, 0xED, 0x02, 0x83, 0xE9,
- 0x08, 0x2B, 0x5E, 0x00, 0x2B, 0x4F, 0x02, 0x2A, 0x7A, 0x04, 0x2B, 0x7B, 0x06, 0x29, 0x18, 0x29,
- 0x5E, 0x00, 0x29, 0x5E, 0x00, 0x29, 0x4F, 0x02, 0x28, 0x7A, 0x04, 0x29, 0x7B, 0x06, 0x80, 0x2F,
- 0x22, 0x83, 0x29, 0x1D, 0x2B, 0x46, 0x00, 0x2A, 0x00, 0x29, 0xD8, 0x28, 0xE0, 0x2D, 0xE8, 0x03,
- 0x2C, 0xE2, 0x2C, 0x09, 0x3B, 0x18, 0x3B, 0x5E, 0x00, 0x83, 0xFE, 0x02, 0x83, 0xFD, 0x02, 0x83,
- 0xF9, 0x08, 0x3B, 0x5E, 0x00, 0x3B, 0x4F, 0x02, 0x3A, 0x7A, 0x04, 0x3B, 0x7B, 0x06, 0x39, 0x18,
- 0x39, 0x5E, 0x00, 0x39, 0x5E, 0x00, 0x39, 0x4F, 0x02, 0x38, 0x7A, 0x04, 0x39, 0x7B, 0x06, 0x80,
- 0x3F, 0x22, 0x83, 0x3E, 0xE2, 0x12, 0x1D, 0x3B, 0x46, 0x00, 0x3A, 0x00, 0x39, 0xD8, 0x38, 0xE0,
- 0x3D, 0xE8, 0x03, 0x3C, 0xE2, 0x3C, 0x09, 0x75, 0x02, 0x75, 0xFC, 0x75, 0xFA, 0x75, 0xFC, 0x74,
- 0xFE, 0x7C, 0xFC, 0x7E, 0xFA, 0x72, 0xF8, 0x76, 0xF6, 0x7A, 0xF4, 0x70, 0xF2, 0x78, 0xF0, 0x75,
- 0xEE, 0x7D, 0xEC, 0x7F, 0xEA, 0x73, 0xE8, 0x77, 0xE6, 0x7B, 0xE4, 0x71, 0xE2, 0x79, 0xE0, 0xE2,
- 0xDE, 0xE1, 0xDC, 0xE0, 0xDA, 0xE3, 0xD8
-};
-
-int main(void)
-{
- u32 Version = Sim86_GetVersion();
- printf("Sim86 Version: %u (expected %u)\n", Version, SIM86_VERSION);
- if(Version != SIM86_VERSION)
- {
- printf("ERROR: Header file version doesn't match DLL.\n");
- return -1;
- }
-
- instruction_table Table;
- Sim86_Get8086InstructionTable(&Table);
- printf("8086 Instruction Instruction Encoding Count: %u\n", Table.EncodingCount);
-
- u32 Offset = 0;
- while(Offset < sizeof(ExampleDisassembly))
- {
- instruction Decoded;
- Sim86_Decode8086Instruction(sizeof(ExampleDisassembly) - Offset, ExampleDisassembly + Offset, &Decoded);
- if(Decoded.Op)
- {
- Offset += Decoded.Size;
- printf("Size:%u Op:%s Flags:0x%x\n", Decoded.Size, Sim86_MnemonicFromOperationType(Decoded.Op), Decoded.Flags);
- }
- else
- {
- printf("Unrecognized instruction\n");
- break;
- }
- }
-
- return 0;
-}
diff --git a/src/code/sim86.cpp b/src/code/sim86.cpp
deleted file mode 100644
index 1e4ddfa..0000000
--- a/src/code/sim86.cpp
+++ /dev/null
@@ -1,375 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-
-#include "sim86.h"
-#include "sim86_shared.h"
-
-global_variable u8 FlagToCharMapping[] = "CPAZSOIDT";
-global_variable u8 GlobalMemory[1*1024*1024] = {};
-
-internal void
-SetOrUnsetFlag(u32 *FlagsRegister, b32 Condition, flags_8086 Flag)
-{
- if(Condition)
- {
- *FlagsRegister |= Flag;
- }
- else
- {
- *FlagsRegister &= (~Flag);
- }
-}
-
-internal u32
-FlagsToString(char *Buffer, u32 Flags)
-{
- u32 Length = 0;
-
- for(u32 MappingIndex = 0;
- MappingIndex < ArrayCount(FlagToCharMapping);
- MappingIndex++)
- {
- u8 Char = FlagToCharMapping[MappingIndex];
- b32 IsBitSet = (Flags & 1);
- Flags >>= 1;
- if(IsBitSet)
- {
- Buffer[Length++] = Char;
- }
- }
-
- return Length;
-}
-
-internal void
-FlagsFromValue(u32 *FlagsRegister, u32 InstructionFlags, s32 Value)
-{
- u32 OldFlagsRegister = *FlagsRegister;
-
- u32 SignMask = (1 << ((InstructionFlags & Inst_Wide) ? 15 : 7));
- SetOrUnsetFlag(FlagsRegister, (Value & SignMask), Flag_Sign);
- SetOrUnsetFlag(FlagsRegister, (Value == 0), Flag_Zero);
-
- // NOTE(luca): Parity flag is set when in lower 8 bits have an even number of set bits.
- u32 OneBitsCount = 0;
- for(u32 BitsIndex = 0;
- BitsIndex < 8;
- BitsIndex++)
- {
- OneBitsCount += (Value & 1);
- Value >>= 1;
- }
- SetOrUnsetFlag(FlagsRegister, (!(OneBitsCount & 1)), Flag_Parity);
-
- // TODO(luca): Overflow flag
- // Were we adding positive numbers but produced a negative number?
-
- // TODO(luca): Carry flag
- // When twot numbers are added and the 17th bit would be set?
-
- // TODO(luca): Auxiliary carry flag
- // Carry for bottom 8 bits
- if(*FlagsRegister != OldFlagsRegister)
- {
- char OldFlagsString[ArrayCount(FlagToCharMapping)] = {};
- char FlagsString[ArrayCount(FlagToCharMapping)] = {};
- FlagsToString(OldFlagsString, OldFlagsRegister);
- FlagsToString(FlagsString, *FlagsRegister);
-
- printf(" flags:%s->%s", OldFlagsString, FlagsString);
- }
-}
-
-internal s32 *
-OperandToValue(s32 *Registers, u8 *Memory, instruction_operand *Operand)
-{
- s32 *Result = 0;
-
- if(0) {}
- else if(Operand->Type == Operand_Register)
- {
- Result = Registers + Operand->Register.Index;
- }
- else if(Operand->Type == Operand_Memory)
- {
- s32 CompleteDisplacement = Operand->Address.Displacement;
- Assert(Operand->Address.Terms[0].Register.Count == Operand->Address.Terms[1].Register.Count);
-
- u32 Count = Operand->Address.Terms[0].Register.Count;
- u32 Mask = ((u32)((-1)) >> (16 + (16 - Count*8)));
-
- CompleteDisplacement +=
- (Registers[Operand->Address.Terms[0].Register.Index] & Mask) +
- (Registers[Operand->Address.Terms[1].Register.Index] & Mask);
-
- Result = (s32 *)((u8 *)Memory + CompleteDisplacement);
- }
- else if(Operand->Type == Operand_Immediate)
- {
- Result = &Operand->Immediate.Value;
- }
- else if(Operand->Type != Operand_None)
- {
- Assert(0);
- }
-
- return Result;
-}
-
-internal void
-Run8086(psize MemorySize, u8 *Memory)
-{
- s32 Registers[Register_count] = {};
- u32 FlagsRegister = 0;
- u32 IPRegister = 0;
-
- while(IPRegister < MemorySize)
- {
- instruction Decoded;
- Sim86_Decode8086Instruction(MemorySize - IPRegister, Memory + IPRegister, &Decoded);
- if(Decoded.Op)
- {
- u32 OldIPRegister = IPRegister;
- IPRegister += Decoded.Size;
-
-#if SIM86_INTERNAL
- printf("Size:%u Op:%s Flags:0x%x ;", Decoded.Size, Sim86_MnemonicFromOperationType(Decoded.Op), Decoded.Flags);
-#endif
-
- instruction_operand *DestinationOperand = Decoded.Operands + 0;
- instruction_operand *SourceOperand = Decoded.Operands + 1;
-
- s32 *Destination = OperandToValue(Registers, Memory, DestinationOperand);
- s32 *Source = OperandToValue(Registers, Memory, SourceOperand);
-
- if(0) {}
- else if(Decoded.Op == Op_int3)
- {
- Assert(0);
- }
- else if(Decoded.Op == Op_mov)
- {
- s32 Old = *Destination;
- if(Decoded.Flags & Inst_Wide)
- {
- *(u16 *)Destination = *(u16 *)Source;
- }
- else
- {
- Assert((SourceOperand->Type == Operand_Immediate ||
- SourceOperand->Type == Operand_Memory) &&
- (SourceOperand->Register.Offset == 0));
- Assert((DestinationOperand->Type == Operand_Immediate || DestinationOperand->Type == Operand_Memory) && (DestinationOperand->Register.Offset == 0));
-
- u8 *SourceByte = (u8 *)Source + SourceOperand->Register.Offset;
- u8 *DestByte = (u8 *)Destination + DestinationOperand->Register.Offset;
-
- *DestByte = *SourceByte;
- }
-
-#if SIM86_INTERNAL
- if(DestinationOperand->Type == Operand_Register)
- {
- printf(" %s:0x%x->0x%x", Sim86_RegisterNameFromOperand(&DestinationOperand->Register),
- Old, *Destination);
- }
-#endif
- }
- else if(Decoded.Op == Op_cmp)
- {
- Assert(DestinationOperand->Type == Operand_Register);
- Assert(SourceOperand->Type == Operand_Register || SourceOperand->Type == Operand_Immediate);
-
- s32 Value = ((Decoded.Flags & Inst_Wide) ?
- (u16)((u16)*Destination - ((u16)*Source)) :
- (u8)((u8)*Destination - ((u8)*Source)));
-
- FlagsFromValue(&FlagsRegister, Decoded.Flags, Value);
- }
- else if(Decoded.Op == Op_sub)
- {
- Assert(DestinationOperand->Type == Operand_Register);
- Assert(SourceOperand->Type == Operand_Register || SourceOperand->Type == Operand_Immediate);
-
- s32 Old = *Destination;
- *Destination = ((Decoded.Flags & Inst_Wide) ?
- (u16)((u16)*Destination - ((u16)*Source)) :
- (u8)((u8)*Destination - ((u8)*Source)));
-
- printf(" %s:0x%x->0x%x",
- Sim86_RegisterNameFromOperand(&DestinationOperand->Register),
- Old, *Destination);
-
- FlagsFromValue(&FlagsRegister, Decoded.Flags, *Destination);
-
- }
- else if(Decoded.Op == Op_add)
- {
- Assert(DestinationOperand->Type == Operand_Register);
-
- s32 Old = *Destination;
-
- *Destination = ((Decoded.Flags & Inst_Wide) ?
- (u16)((u16)*Destination + ((u16)*Source)) :
- (u8)((u8)*Destination + ((u8)*Source)));
-
- printf(" %s:0x%x->0x%x",
- Sim86_RegisterNameFromOperand(&DestinationOperand->Register),
- Old, *Destination);
-
- FlagsFromValue(&FlagsRegister, Decoded.Flags, *Destination);
- }
- else if(Decoded.Op == Op_jne)
- {
- if(!(FlagsRegister & Flag_Zero))
- {
- IPRegister += *Destination;
- }
- }
- else if(Decoded.Op == Op_je)
- {
- if((FlagsRegister & Flag_Zero))
- {
- IPRegister += *Destination;
- }
- }
- else
- {
- Assert(0 && "Op not implemented yet.");
- }
-
-#if SIM86_INTERNAL
- printf(" ip:0x%x->0x%x", OldIPRegister, IPRegister);
-#endif
-
- }
- else
- {
- printf("Unrecognized instruction\n");
- break;
- }
-
-#if SIM86_INTERNAL
- printf("\n");
-#endif
-
- }
-
- printf("Final registers:\n");
- for(u32 RegisterIndex = Register_a;
- RegisterIndex < Register_ds + 1;
- RegisterIndex++)
- {
- register_access Register = {};
- Register.Index = RegisterIndex;
- Register.Offset = 0;
- Register.Count = 2;
-
- u32 Value = Registers[RegisterIndex];
- if(Value > 0)
- {
- printf(" %s: 0x%0x (%d)\n",
- Sim86_RegisterNameFromOperand(&Register),
- Value, Value);
- }
- }
- printf(" ip: 0x%04x (%d)\n", IPRegister, IPRegister);
-
- if(FlagsRegister)
- {
- char FlagsString[ArrayCount(FlagToCharMapping)] = {};
- FlagsToString(FlagsString, FlagsRegister);
- printf(" flags: %s\n", FlagsString);
- }
-}
-
-void PrintUsage(char *ExePath)
-{
- printf("usage: %s [-exec] <assembly>\n", ExePath);
-}
-
-int main(int ArgsCount, char *Args[])
-{
- u32 Version = Sim86_GetVersion();
-
-#if SIM86_INTERNAL
- printf("Sim86 Version: %u (expected %u)\n", Version, SIM86_VERSION);
-#endif
-
- if(Version != SIM86_VERSION)
- {
- printf("ERROR: Header file version doesn't match DLL.\n");
- return -1;
- }
-
- instruction_table Table;
- Sim86_Get8086InstructionTable(&Table);
-
-#if SIM86_INTERNAL
- printf("8086 Instruction Instruction Encoding Count: %u\n", Table.EncodingCount);
-#endif
-
- // print (default)
- // -exec (also execute the disassembled instructinos)
-
- b32 Execute = false;
- b32 Dump = false;
- char *FileName = 0;
- for(s32 ArgsIndex = 1;
- ArgsIndex < ArgsCount;
- ArgsIndex++)
- {
- char *Command = Args[ArgsIndex];
- if(0) {}
- else if(!strcmp(Command, "-exec"))
- {
- Execute = true;
- }
- else if(!strcmp(Command, "-dump"))
- {
- Dump = true;
- }
- else
- {
- FileName = Command;
- }
- }
-
- if(FileName)
- {
- FILE *File = fopen(FileName, "rb");
- if(File)
- {
- psize BytesWritten = fread(GlobalMemory, 1, sizeof(GlobalMemory), File);
- fclose(File);
-
- if(Execute)
- {
- printf("--- %s execution ---\n", FileName);
-
- Run8086(BytesWritten, GlobalMemory);
-
- if(Dump)
- {
- // NOTE(luca): We have to add ".data" or Gimp will throw an error.
- FILE *DumpFile = fopen("sim86_memory_0.data", "wb");
- fwrite(GlobalMemory, 1, sizeof(GlobalMemory), DumpFile);
- fclose(DumpFile);
- }
-
- }
- else
- {
- printf("ERROR: Disassembling not implemented yet.\n");
- }
-
- }
- else
- {
- printf("ERROR: Unable to open %s.\n", FileName);
- PrintUsage(Args[0]);
- }
- }
-
- return 0;
-}
diff --git a/src/code/sim86.h b/src/code/sim86.h
deleted file mode 100644
index 4778573..0000000
--- a/src/code/sim86.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* date = August 13th 2025 1:51 pm */
-
-#ifndef SIM86_H
-#define SIM86_H
-
-#define internal static
-#define global_variable static
-#define local_persist static
-
-typedef size_t psize;
-
-#define Assert(Expression) if(!(Expression)) { __asm__ volatile("int3"); }
-#define ArrayCount(Array) (sizeof(Array) / sizeof((Array)[0]))
-
-//~ Stolen from the decoder.
-enum register_mapping_8086
-{
- Register_none,
-
- Register_a,
- Register_b,
- Register_c,
- Register_d,
- Register_sp,
- Register_bp,
- Register_si,
- Register_di,
- Register_es,
- Register_cs,
- Register_ss,
- Register_ds,
- Register_ip,
- Register_flags,
-
- Register_count,
-};
-
-enum flags_8086
-{
- Flag_None = 0,
- Flag_Carry =(1 << 0),
- Flag_Parity =(1 << 1),
- Flag_AuxiliaryCarry =(1 << 2),
- Flag_Zero =(1 << 3),
- Flag_Sign =(1 << 4),
- Flag_Overflow =(1 << 5),
- Flag_Interrupt =(1 << 6),
- Flag_Direction =(1 << 7),
- Flag_Trap =(1 << 8),
- Flag_Count = 11,
-};
-
-#endif //SIM86_H
diff --git a/src/code/sim86_shared.h b/src/code/sim86_shared.h
deleted file mode 100644
index 7a54beb..0000000
--- a/src/code/sim86_shared.h
+++ /dev/null
@@ -1,285 +0,0 @@
-typedef char unsigned u8;
-typedef short unsigned u16;
-typedef int unsigned u32;
-typedef long long unsigned u64;
-
-typedef char s8;
-typedef short s16;
-typedef int s32;
-typedef long long s64;
-
-typedef s32 b32;
-
-static u32 const SIM86_VERSION = 4;
-typedef u32 register_index;
-
-typedef struct register_access register_access;
-typedef struct effective_address_term effective_address_term;
-typedef struct effective_address_expression effective_address_expression;
-typedef struct immediate immediate;
-typedef struct instruction_operand instruction_operand;
-typedef struct instruction instruction;
-
-typedef enum operation_type : u32
-{
- Op_None,
-
- Op_mov,
-
- Op_push,
-
- Op_pop,
-
- Op_xchg,
-
- Op_in,
-
- Op_out,
-
- Op_xlat,
- Op_lea,
- Op_lds,
- Op_les,
- Op_lahf,
- Op_sahf,
- Op_pushf,
- Op_popf,
-
- Op_add,
-
- Op_adc,
-
- Op_inc,
-
- Op_aaa,
- Op_daa,
-
- Op_sub,
-
- Op_sbb,
-
- Op_dec,
-
- Op_neg,
-
- Op_cmp,
-
- Op_aas,
- Op_das,
- Op_mul,
- Op_imul,
- Op_aam,
- Op_div,
- Op_idiv,
- Op_aad,
- Op_cbw,
- Op_cwd,
-
- Op_not,
- Op_shl,
- Op_shr,
- Op_sar,
- Op_rol,
- Op_ror,
- Op_rcl,
- Op_rcr,
-
- Op_and,
-
- Op_test,
-
- Op_or,
-
- Op_xor,
-
- Op_rep,
- Op_movs,
- Op_cmps,
- Op_scas,
- Op_lods,
- Op_stos,
-
- Op_call,
-
- Op_jmp,
-
- Op_ret,
-
- Op_retf,
-
- Op_je,
- Op_jl,
- Op_jle,
- Op_jb,
- Op_jbe,
- Op_jp,
- Op_jo,
- Op_js,
- Op_jne,
- Op_jnl,
- Op_jg,
- Op_jnb,
- Op_ja,
- Op_jnp,
- Op_jno,
- Op_jns,
- Op_loop,
- Op_loopz,
- Op_loopnz,
- Op_jcxz,
-
- Op_int,
- Op_int3,
-
- Op_into,
- Op_iret,
-
- Op_clc,
- Op_cmc,
- Op_stc,
- Op_cld,
- Op_std,
- Op_cli,
- Op_sti,
- Op_hlt,
- Op_wait,
- Op_esc,
- Op_lock,
- Op_segment,
-
- Op_Count,
-} operation_type;
-
-enum instruction_flag
-{
- Inst_Lock = 0x1,
- Inst_Rep = 0x2,
- Inst_Segment = 0x4,
- Inst_Wide = 0x8,
- Inst_Far = 0x10,
- Inst_RepNE = 0x20,
-};
-
-struct register_access
-{
- register_index Index;
- u32 Offset;
- u32 Count;
-};
-
-struct effective_address_term
-{
- register_access Register;
- s32 Scale;
-};
-
-enum effective_address_flag
-{
- Address_ExplicitSegment = 0x1,
-};
-struct effective_address_expression
-{
- effective_address_term Terms[2];
- u32 ExplicitSegment;
- s32 Displacement;
- u32 Flags;
-};
-
-enum immediate_flag
-{
- Immediate_RelativeJumpDisplacement = 0x1,
-};
-struct immediate
-{
- s32 Value;
- u32 Flags;
-};
-
-typedef enum operand_type : u32
-{
- Operand_None,
- Operand_Register,
- Operand_Memory,
- Operand_Immediate,
-} operand_type;
-struct instruction_operand
-{
- operand_type Type;
- union {
- effective_address_expression Address;
- register_access Register;
- immediate Immediate;
- };
-};
-
-struct instruction
-{
- u32 Address;
- u32 Size;
-
- operation_type Op;
- u32 Flags;
-
- instruction_operand Operands[2];
-
- register_index SegmentOverride;
-};
-enum instruction_bits_usage : u8
-{
- Bits_End,
-
- Bits_Literal,
-
- Bits_D,
- Bits_S,
- Bits_W,
- Bits_V,
- Bits_Z,
- Bits_MOD,
- Bits_REG,
- Bits_RM,
- Bits_SR,
- Bits_Disp,
- Bits_Data,
-
- Bits_DispAlwaysW,
- Bits_WMakesDataW,
- Bits_RMRegAlwaysW,
- Bits_RelJMPDisp,
- Bits_Far,
-
- Bits_Count,
-};
-
-struct instruction_bits
-{
- instruction_bits_usage Usage;
- u8 BitCount;
- u8 Shift;
- u8 Value;
-};
-
-struct instruction_encoding
-{
- operation_type Op;
- instruction_bits Bits[16];
-};
-
-struct instruction_table
-{
- instruction_encoding *Encodings;
- u32 EncodingCount;
- u32 MaxInstructionByteCount;
-};
-#ifdef __cplusplus
-extern "C"
-{
-#endif
- u32 Sim86_GetVersion(void);
- void Sim86_Decode8086Instruction(u32 SourceSize, u8 *Source, instruction *Dest);
- char const *Sim86_RegisterNameFromOperand(register_access *RegAccess);
- char const *Sim86_MnemonicFromOperationType(operation_type Type);
- void Sim86_Get8086InstructionTable(instruction_table *Dest);
-#ifdef __cplusplus
-}
-#endif