Started implementing the 8086 simulation
This commit is contained in:
		
							
								
								
									
										8
									
								
								8086_sim/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								8086_sim/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
			
		||||
							
								
								
									
										46
									
								
								8086_sim/include/aliases.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								8086_sim/include/aliases.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
#ifndef ALIASES_H
 | 
			
		||||
#define ALIASES_H
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
							
								
								
									
										11
									
								
								8086_sim/include/reg_access.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								8086_sim/include/reg_access.h
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
							
								
								
									
										54
									
								
								8086_sim/include/sim86.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								8086_sim/include/sim86.h
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
							
								
								
									
										92
									
								
								8086_sim/include/sim86_instruction.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								8086_sim/include/sim86_instruction.h
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
							
								
								
									
										65
									
								
								8086_sim/include/sim86_instruction_table.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								8086_sim/include/sim86_instruction_table.h
									
									
									
									
									
										Normal file
									
								
							@@ -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;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										250
									
								
								8086_sim/include/sim86_instruction_table.inl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										250
									
								
								8086_sim/include/sim86_instruction_table.inl
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
							
								
								
									
										21
									
								
								8086_sim/include/sim86_lib.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								8086_sim/include/sim86_lib.h
									
									
									
									
									
										Normal file
									
								
							@@ -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);
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								8086_sim/lib/libsim86.so
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								8086_sim/lib/libsim86.so
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								8086_sim/listing_0043_immediate_movs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								8086_sim/listing_0043_immediate_movs
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										27
									
								
								8086_sim/listing_0043_immediate_movs.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								8086_sim/listing_0043_immediate_movs.asm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
; ========================================================================
 | 
			
		||||
;
 | 
			
		||||
; (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 further information
 | 
			
		||||
;
 | 
			
		||||
; ========================================================================
 | 
			
		||||
 | 
			
		||||
; ========================================================================
 | 
			
		||||
; LISTING 43
 | 
			
		||||
; ========================================================================
 | 
			
		||||
 | 
			
		||||
bits 16
 | 
			
		||||
 | 
			
		||||
mov ax, 1
 | 
			
		||||
mov bx, 2
 | 
			
		||||
mov cx, 3
 | 
			
		||||
mov dx, 4
 | 
			
		||||
 | 
			
		||||
mov sp, 5
 | 
			
		||||
mov bp, 6
 | 
			
		||||
mov si, 7
 | 
			
		||||
mov di, 8
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								8086_sim/listing_0044_register_movs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								8086_sim/listing_0044_register_movs
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										32
									
								
								8086_sim/listing_0044_register_movs.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								8086_sim/listing_0044_register_movs.asm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
; ========================================================================
 | 
			
		||||
;
 | 
			
		||||
; (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 further information
 | 
			
		||||
;
 | 
			
		||||
; ========================================================================
 | 
			
		||||
 | 
			
		||||
; ========================================================================
 | 
			
		||||
; LISTING 44
 | 
			
		||||
; ========================================================================
 | 
			
		||||
 | 
			
		||||
bits 16
 | 
			
		||||
 | 
			
		||||
mov ax, 1
 | 
			
		||||
mov bx, 2
 | 
			
		||||
mov cx, 3
 | 
			
		||||
mov dx, 4
 | 
			
		||||
 | 
			
		||||
mov sp, ax
 | 
			
		||||
mov bp, bx
 | 
			
		||||
mov si, cx
 | 
			
		||||
mov di, dx
 | 
			
		||||
 | 
			
		||||
mov dx, sp
 | 
			
		||||
mov cx, bp
 | 
			
		||||
mov bx, si
 | 
			
		||||
mov ax, di
 | 
			
		||||
							
								
								
									
										1
									
								
								8086_sim/listing_0045_challenge_register_movs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								8086_sim/listing_0045_challenge_register_movs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
<EFBFBD>""<22>DD<44>ff<66><66><EFBFBD><EFBFBD>Ўێ<D08E>
 | 
			
		||||
							
								
								
									
										43
									
								
								8086_sim/listing_0045_challenge_register_movs.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								8086_sim/listing_0045_challenge_register_movs.asm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
; ========================================================================
 | 
			
		||||
;
 | 
			
		||||
; (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 further information
 | 
			
		||||
;
 | 
			
		||||
; ========================================================================
 | 
			
		||||
 | 
			
		||||
; ========================================================================
 | 
			
		||||
; LISTING 45
 | 
			
		||||
; ========================================================================
 | 
			
		||||
 | 
			
		||||
bits 16
 | 
			
		||||
 | 
			
		||||
mov ax, 0x2222
 | 
			
		||||
mov bx, 0x4444
 | 
			
		||||
mov cx, 0x6666
 | 
			
		||||
mov dx, 0x8888
 | 
			
		||||
 | 
			
		||||
mov ss, ax
 | 
			
		||||
mov ds, bx
 | 
			
		||||
mov es, cx
 | 
			
		||||
 | 
			
		||||
mov al, 0x11
 | 
			
		||||
mov bh, 0x33
 | 
			
		||||
mov cl, 0x55
 | 
			
		||||
mov dh, 0x77
 | 
			
		||||
 | 
			
		||||
mov ah, bl
 | 
			
		||||
mov cl, dh
 | 
			
		||||
 | 
			
		||||
mov ss, ax
 | 
			
		||||
mov ds, bx
 | 
			
		||||
mov es, cx
 | 
			
		||||
 | 
			
		||||
mov sp, ss
 | 
			
		||||
mov bp, ds
 | 
			
		||||
mov si, es
 | 
			
		||||
mov di, dx
 | 
			
		||||
							
								
								
									
										52
									
								
								8086_sim/reg_access.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								8086_sim/reg_access.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
#include "include/reg_access.h"
 | 
			
		||||
#include "include/aliases.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#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)];
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								8086_sim/sim86
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								8086_sim/sim86
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										97
									
								
								8086_sim/sim86.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								8086_sim/sim86.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
#include "include/aliases.h"
 | 
			
		||||
#include "include/reg_access.h"
 | 
			
		||||
#include "include/sim86_lib.h"
 | 
			
		||||
#include <bits/types/FILE.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								8086_sim/test
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								8086_sim/test
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										33
									
								
								8086_sim/test.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								8086_sim/test.asm
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
		Reference in New Issue
	
	Block a user