From 96d13813037cbceab7cfafec45a0842471bc11b0 Mon Sep 17 00:00:00 2001 From: Abdelrahman Said Date: Wed, 29 Mar 2023 01:28:37 +0100 Subject: [PATCH] Started implementing the 8086 simulation --- 8086_sim/Makefile | 8 + 8086_sim/include/aliases.h | 46 ++++ 8086_sim/include/reg_access.h | 11 + 8086_sim/include/sim86.h | 54 ++++ 8086_sim/include/sim86_instruction.h | 92 +++++++ 8086_sim/include/sim86_instruction_table.h | 65 +++++ 8086_sim/include/sim86_instruction_table.inl | 250 ++++++++++++++++++ 8086_sim/include/sim86_lib.h | 21 ++ 8086_sim/lib/libsim86.so | Bin 0 -> 46080 bytes 8086_sim/listing_0043_immediate_movs | Bin 0 -> 24 bytes 8086_sim/listing_0043_immediate_movs.asm | 27 ++ 8086_sim/listing_0044_register_movs | Bin 0 -> 28 bytes 8086_sim/listing_0044_register_movs.asm | 32 +++ 8086_sim/listing_0045_challenge_register_movs | 1 + .../listing_0045_challenge_register_movs.asm | 43 +++ 8086_sim/reg_access.cpp | 52 ++++ 8086_sim/sim86 | Bin 0 -> 31808 bytes 8086_sim/sim86.cpp | 97 +++++++ 8086_sim/test | Bin 0 -> 48 bytes 8086_sim/test.asm | 33 +++ 20 files changed, 832 insertions(+) create mode 100644 8086_sim/Makefile create mode 100644 8086_sim/include/aliases.h create mode 100644 8086_sim/include/reg_access.h create mode 100644 8086_sim/include/sim86.h create mode 100644 8086_sim/include/sim86_instruction.h create mode 100644 8086_sim/include/sim86_instruction_table.h create mode 100644 8086_sim/include/sim86_instruction_table.inl create mode 100644 8086_sim/include/sim86_lib.h create mode 100644 8086_sim/lib/libsim86.so create mode 100644 8086_sim/listing_0043_immediate_movs create mode 100644 8086_sim/listing_0043_immediate_movs.asm create mode 100644 8086_sim/listing_0044_register_movs create mode 100644 8086_sim/listing_0044_register_movs.asm create mode 100644 8086_sim/listing_0045_challenge_register_movs create mode 100644 8086_sim/listing_0045_challenge_register_movs.asm create mode 100644 8086_sim/reg_access.cpp create mode 100644 8086_sim/sim86 create mode 100644 8086_sim/sim86.cpp create mode 100644 8086_sim/test create mode 100644 8086_sim/test.asm diff --git a/8086_sim/Makefile b/8086_sim/Makefile new file mode 100644 index 0000000..e9addcf --- /dev/null +++ b/8086_sim/Makefile @@ -0,0 +1,8 @@ +CC=clang++ +CFLAGS=-g -O0 -Wall -Wextra +LIBS=-Wl,-rpath,./lib -L./lib -lsim86 +SRC=*.cpp +OUT=sim86 + +all: + $(CC) $(CFLAGS) $(LIBS) $(SRC) -o $(OUT) diff --git a/8086_sim/include/aliases.h b/8086_sim/include/aliases.h new file mode 100644 index 0000000..68592a2 --- /dev/null +++ b/8086_sim/include/aliases.h @@ -0,0 +1,46 @@ +#ifndef ALIASES_H +#define ALIASES_H + +#include + +#ifndef u8 +#define u8 uint8_t +#endif // !u8 + +#ifndef u16 +#define u16 uint16_t +#endif // !u16 + +#ifndef u32 +#define u32 uint32_t +#endif // !u32 + +#ifndef u64 +#define u64 uint64_t +#endif // !u64 + +#ifndef i8 +#define i8 int8_t +#endif // !i8 + +#ifndef i16 +#define i16 int16_t +#endif // !i16 + +#ifndef i32 +#define i32 int32_t +#endif // !i32 + +#ifndef i64 +#define i64 int64_t +#endif // !i64 + +#ifndef f32 +#define f32 float +#endif // !f32 + +#ifndef f64 +#define f64 double +#endif // !f64 + +#endif // !ALIASES_H diff --git a/8086_sim/include/reg_access.h b/8086_sim/include/reg_access.h new file mode 100644 index 0000000..d6a3d1a --- /dev/null +++ b/8086_sim/include/reg_access.h @@ -0,0 +1,11 @@ +#ifndef REG_ACCESS_H +#define REG_ACCESS_H + +#include "aliases.h" +#include "sim86_instruction.h" + +void set_register(register_access reg, u16 new_value); +u16 get_register(register_access reg); +const char *get_register_name(register_access reg); + +#endif // !REG_ACCESS_H diff --git a/8086_sim/include/sim86.h b/8086_sim/include/sim86.h new file mode 100644 index 0000000..891194c --- /dev/null +++ b/8086_sim/include/sim86.h @@ -0,0 +1,54 @@ +/* ======================================================================== + + (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 + + ======================================================================== */ + +#ifndef SIM86_H +#define SIM86_H + +#ifndef u8 +typedef char unsigned u8; +#endif // !u8 + +#ifndef u16 +typedef short unsigned u16; +#endif // !u16 + +#ifndef u32 +typedef int unsigned u32; +#endif // !u32 + +#ifndef u64 +typedef long long unsigned u64; +#endif // u64 + +#ifndef s8 +typedef char s8; +#endif // !s8 + +#ifndef s16 +typedef short s16; +#endif // !s16 + +#ifndef s32 +typedef int s32; +#endif // !s32 + +#ifndef s64 +typedef long long s64; +#endif // !s64 + +typedef s32 b32; + +#define ArrayCount(Array) (sizeof(Array) / sizeof((Array)[0])) + +static u32 const SIM86_VERSION = 3; + +#endif // !SIM86_H diff --git a/8086_sim/include/sim86_instruction.h b/8086_sim/include/sim86_instruction.h new file mode 100644 index 0000000..6de2c6e --- /dev/null +++ b/8086_sim/include/sim86_instruction.h @@ -0,0 +1,92 @@ +/* ======================================================================== + + (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 + + ======================================================================== */ + +#ifndef SIM86_INST_H +#define SIM86_INST_H + +#include "sim86.h" + +enum operation_type : u32 { + Op_None, + +#define INST(Mnemonic, ...) Op_##Mnemonic, +#define INSTALT(...) +#include "sim86_instruction_table.inl" + + Op_Count, +}; + +enum instruction_flag : u32 { + Inst_Lock = 0x1, + Inst_Rep = 0x2, + Inst_Segment = 0x4, + Inst_Wide = 0x8, + Inst_Far = 0x10, +}; + +struct register_access { + u32 Index; // Index in the register table + u32 Offset; // High vs Low bits + u32 Count; // How many bytes are accessed +}; + +struct effective_address_term { + register_access Register; + s32 Scale; +}; + +enum effective_address_flag : u32 { + Address_ExplicitSegment = 0x1, +}; +struct effective_address_expression { + effective_address_term Terms[2]; + u32 ExplicitSegment; + s32 Displacement; + u32 Flags; +}; + +enum immediate_flag : u32 { + Immediate_RelativeJumpDisplacement = 0x1, +}; +struct immediate { + s32 Value; + u32 Flags; +}; + +enum operand_type : u32 { + Operand_None, + Operand_Register, + Operand_Memory, + Operand_Immediate, +}; +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]; + + u32 SegmentOverride; +}; + +#endif // !SIM86_INST_H diff --git a/8086_sim/include/sim86_instruction_table.h b/8086_sim/include/sim86_instruction_table.h new file mode 100644 index 0000000..045e4b0 --- /dev/null +++ b/8086_sim/include/sim86_instruction_table.h @@ -0,0 +1,65 @@ +/* ======================================================================== + + (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 "sim86.h" +#include "sim86_instruction.h" + +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/8086_sim/include/sim86_instruction_table.inl b/8086_sim/include/sim86_instruction_table.inl new file mode 100644 index 0000000..1323b95 --- /dev/null +++ b/8086_sim/include/sim86_instruction_table.inl @@ -0,0 +1,250 @@ +/* ======================================================================== + + (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, Encoding, ...) {Op_##Mnemonic, Encoding, __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)}) +INSTALT(push, {B(01010), REG, ImpW(1)}) +INSTALT(push, {B(000), SR, B(110), ImpW(1)}) + +INST(pop, {B(10001111), MOD, B(000), RM, ImpW(1)}) +INSTALT(pop, {B(01011), REG, ImpW(1)}) +INSTALT(pop, {B(000), SR, B(111), ImpW(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}) +INSTALT(inc, {B(01000), REG, ImpW(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}) +INSTALT(dec, {B(01001), REG, ImpW(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)}) +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)}) +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)}) +INSTALT(retf, {B(11001010), DATA, DATA_IF_W, ImpW(1)}) + +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/8086_sim/include/sim86_lib.h b/8086_sim/include/sim86_lib.h new file mode 100644 index 0000000..0ce1fe6 --- /dev/null +++ b/8086_sim/include/sim86_lib.h @@ -0,0 +1,21 @@ +/* ======================================================================== + + (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 "sim86.h" +#include "sim86_instruction.h" +#include "sim86_instruction_table.h" + +extern "C" u32 Sim86_GetVersion(void); +extern "C" void Sim86_Decode8086Instruction(u32 SourceSize, u8 *Source, instruction *Dest); +extern "C" char const *Sim86_RegisterNameFromOperand(register_access *RegAccess); +extern "C" char const *Sim86_MnemonicFromOperationType(operation_type Type); +extern "C" void Sim86_Get8086InstructionTable(instruction_table *Dest); \ No newline at end of file diff --git a/8086_sim/lib/libsim86.so b/8086_sim/lib/libsim86.so new file mode 100644 index 0000000000000000000000000000000000000000..47e0f286d05fc807af77ac5bb480813f4972b42d GIT binary patch literal 46080 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 QMznwy7F?SR3Wg&4KZ8(Xv;Y7A literal 0 HcmV?d00001 diff --git a/8086_sim/listing_0043_immediate_movs b/8086_sim/listing_0043_immediate_movs new file mode 100644 index 0000000000000000000000000000000000000000..a965538a95c17ecdbf161ddb888849f8a3dd0fa1 GIT binary patch literal 24 gcmdnN$grD + +#define REGISTER_COUNT 13 + +static u16 registers[REGISTER_COUNT] = {0}; + +void set_register(register_access reg, u16 new_value) { + if (reg.Count == 2) { + registers[reg.Index] = new_value; + return; + } + + u16 shift = (u16)(reg.Offset) * (u16)sizeof(u8); + u16 mask = 0xff00; + + registers[reg.Index] &= (mask >> shift); + registers[reg.Index] |= (new_value << shift); +} + +u16 get_register(register_access reg) { + if (reg.Count == 2) { + return registers[reg.Index]; + } + + // TODO (Abdelrahman): Implement this + return 0; +} + +const char *get_register_name(register_access reg) { + // clang-format off + static const char *register_names[REGISTER_COUNT][3] = { + {"NONE", "NONE", "NONE"}, + {"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"}, + }; + // clang-format on + + return register_names[reg.Index] + [(reg.Count == 2) ? 2 : (reg.Offset & reg.Count)]; +} diff --git a/8086_sim/sim86 b/8086_sim/sim86 new file mode 100644 index 0000000000000000000000000000000000000000..30946de97f527f04c1168746ff0ab97d99057773 GIT binary patch literal 31808 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 W;lGK0TMhevq#Ya5P*sJiNcLZf-Wl5f literal 0 HcmV?d00001 diff --git a/8086_sim/sim86.cpp b/8086_sim/sim86.cpp new file mode 100644 index 0000000..9229eec --- /dev/null +++ b/8086_sim/sim86.cpp @@ -0,0 +1,97 @@ +#include "include/aliases.h" +#include "include/reg_access.h" +#include "include/sim86_lib.h" +#include +#include +#include + +void decode_operand(instruction_operand operand); +void mov_to_register(const register_access ®, + const instruction_operand &source); + +int main(int argc, char *argv[]) { + if (argc < 2) { + printf("Usage: sim86 BINARY_FILE\n"); + return 1; + } + + const char *filename = argv[1]; + + printf("Filename: %s\n", filename); + + FILE *fp = fopen(filename, "rb"); + if (!fp) { + printf("Failed to open file %s\n", filename); + } + + fseek(fp, 0, SEEK_END); + + u32 size = ftell(fp); + + fseek(fp, 0, SEEK_SET); + + u8 buffer[size + 1]; + memset((void *)buffer, 0, size + 1); + + fread((void *)buffer, sizeof(u8), size, fp); + + fclose(fp); + + instruction_table table; + Sim86_Get8086InstructionTable(&table); + + u32 offset = 0; + + while (offset < size) { + instruction decoded; + Sim86_Decode8086Instruction(size - offset, buffer + offset, &decoded); + + if (decoded.Op) { + offset += decoded.Size; + + if (decoded.Op == Op_mov) { + instruction_operand dest = decoded.Operands[0]; + instruction_operand source = decoded.Operands[1]; + + if (dest.Type == Operand_Register) { + mov_to_register(dest.Register, source); + printf("%s: 0x%04x\n", get_register_name(dest.Register), + get_register(dest.Register)); + } + } + } + } + + return 0; +} + +void decode_operand(instruction_operand operand) { + switch (operand.Type) { + case Operand_Register: + printf("Register operand: %d, %d, %d\n", operand.Register.Index, + operand.Register.Offset, operand.Register.Count); + break; + case Operand_Memory: + // printf("Memory operand\n"); + break; + case Operand_Immediate: + // printf("Immediate operand\n"); + break; + default: + break; + } +} + +void mov_to_register(const register_access ®, + const instruction_operand &source) { + switch (source.Type) { + case Operand_Immediate: + set_register(reg, source.Immediate.Value); + break; + case Operand_Register: + set_register(reg, get_register(source.Register)); + break; + default: + break; + } +} diff --git a/8086_sim/test b/8086_sim/test new file mode 100644 index 0000000000000000000000000000000000000000..bcf840781f28744bc5e6869ff5746c4fab94562b GIT binary patch literal 48 wcmV~$IRZd15CFjWf3a^7LAHBX2s4)=i(-wc;kzI0CPGJ;Q#;t literal 0 HcmV?d00001 diff --git a/8086_sim/test.asm b/8086_sim/test.asm new file mode 100644 index 0000000..f2c7474 --- /dev/null +++ b/8086_sim/test.asm @@ -0,0 +1,33 @@ +bits 16 + +mov al, 0 +mov ah, 0 +mov ax, 0 + +mov bl, 0 +mov bh, 0 +mov bx, 0 + +mov cl, 0 +mov ch, 0 +mov cx, 0 + +mov dl, 0 +mov dh, 0 +mov dx, 0 + +mov sp, 0 + +mov bp, 0 + +mov si, 0 + +mov di, 0 + +mov es, ax + +mov cs, ax + +mov ss, ax + +mov ds, ax