perfaware/part1: Remove unused defns, tidy up code
This commit is contained in:
		
							parent
							
								
									d7b6598b1c
								
							
						
					
					
						commit
						68486e8855
					
				
							
								
								
									
										217
									
								
								part1/sim8086.c
									
									
									
									
									
								
							
							
						
						
									
										217
									
								
								part1/sim8086.c
									
									
									
									
									
								
							@ -7,31 +7,8 @@
 | 
				
			|||||||
#include <stdarg.h>
 | 
					#include <stdarg.h>
 | 
				
			||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct S86_Buffer S86_Buffer;
 | 
					// NOTE: Macros
 | 
				
			||||||
struct S86_Buffer {
 | 
					// ============================================================================
 | 
				
			||||||
    char *data;
 | 
					 | 
				
			||||||
    size_t size;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct S86_Str8 S86_Str8;
 | 
					 | 
				
			||||||
struct S86_Str8 {
 | 
					 | 
				
			||||||
    char *data;
 | 
					 | 
				
			||||||
    size_t size;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct S86_Globals S86_Globals;
 | 
					 | 
				
			||||||
struct S86_Globals {
 | 
					 | 
				
			||||||
    HANDLE stdout_handle;
 | 
					 | 
				
			||||||
    bool   write_to_console;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct S86_BufferIterator {
 | 
					 | 
				
			||||||
    S86_Buffer buffer;
 | 
					 | 
				
			||||||
    size_t     index;
 | 
					 | 
				
			||||||
} S86_BufferIterator;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
S86_Globals s86_globals;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define S86_STRINGIFY2(token) #token
 | 
					#define S86_STRINGIFY2(token) #token
 | 
				
			||||||
#define S86_STRINGIFY(token) S86_STRINGIFY2(token)
 | 
					#define S86_STRINGIFY(token) S86_STRINGIFY2(token)
 | 
				
			||||||
#define S86_ASSERT(expr)                                                                         \
 | 
					#define S86_ASSERT(expr)                                                                         \
 | 
				
			||||||
@ -41,9 +18,38 @@ S86_Globals s86_globals;
 | 
				
			|||||||
    }                                                                                            \
 | 
					    }                                                                                            \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define S86_ARRAY_UCOUNT(array) sizeof((array)) / sizeof((array)[0])
 | 
					#define S86_ARRAY_UCOUNT(array) sizeof((array)) / sizeof((array)[0])
 | 
				
			||||||
 | 
					#define S86_CAST(Type) (Type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NOTE: Globals
 | 
				
			||||||
 | 
					// ============================================================================
 | 
				
			||||||
 | 
					typedef struct S86_Globals {
 | 
				
			||||||
 | 
					    HANDLE stdout_handle;
 | 
				
			||||||
 | 
					    bool   write_to_console;
 | 
				
			||||||
 | 
					} S86_Globals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					S86_Globals s86_globals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NOTE: Strings
 | 
				
			||||||
 | 
					// ============================================================================
 | 
				
			||||||
 | 
					typedef struct S86_Str8 {
 | 
				
			||||||
 | 
					    char *data;
 | 
				
			||||||
 | 
					    size_t size;
 | 
				
			||||||
 | 
					} S86_Str8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define S86_STR8(string) (S86_Str8){.data = (string), .size = S86_ARRAY_UCOUNT(string) - 1 }
 | 
					#define S86_STR8(string) (S86_Str8){.data = (string), .size = S86_ARRAY_UCOUNT(string) - 1 }
 | 
				
			||||||
#define S86_STR8_FMT(string) (int)((string).size), (string).data
 | 
					#define S86_STR8_FMT(string) (int)((string).size), (string).data
 | 
				
			||||||
#define S86_CAST(Type) (Type)
 | 
					
 | 
				
			||||||
 | 
					// NOTE: Buffer
 | 
				
			||||||
 | 
					// ============================================================================
 | 
				
			||||||
 | 
					typedef struct S86_Buffer {
 | 
				
			||||||
 | 
					    char *data;
 | 
				
			||||||
 | 
					    size_t size;
 | 
				
			||||||
 | 
					} S86_Buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct S86_BufferIterator {
 | 
				
			||||||
 | 
					    S86_Buffer buffer;
 | 
				
			||||||
 | 
					    size_t     index;
 | 
				
			||||||
 | 
					} S86_BufferIterator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool S86_BufferIsValid(S86_Buffer buffer);
 | 
					bool S86_BufferIsValid(S86_Buffer buffer);
 | 
				
			||||||
S86_BufferIterator S86_BufferIteratorInit(S86_Buffer buffer);
 | 
					S86_BufferIterator S86_BufferIteratorInit(S86_Buffer buffer);
 | 
				
			||||||
@ -51,11 +57,82 @@ bool S86_BufferIteratorHasMoreBytes(S86_BufferIterator it);
 | 
				
			|||||||
uint8_t S86_BufferIteratorPeekByte(S86_BufferIterator it);
 | 
					uint8_t S86_BufferIteratorPeekByte(S86_BufferIterator it);
 | 
				
			||||||
uint8_t S86_BufferIteratorNextByte(S86_BufferIterator *it);
 | 
					uint8_t S86_BufferIteratorNextByte(S86_BufferIterator *it);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NOTE: File
 | 
				
			||||||
 | 
					// ============================================================================
 | 
				
			||||||
S86_Buffer S86_FileRead(char const *file_path);
 | 
					S86_Buffer S86_FileRead(char const *file_path);
 | 
				
			||||||
void S86_FileFree(S86_Buffer buffer);
 | 
					void S86_FileFree(S86_Buffer buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NOTE: Print
 | 
				
			||||||
 | 
					// ============================================================================
 | 
				
			||||||
void S86_PrintLn(S86_Str8 string);
 | 
					void S86_PrintLn(S86_Str8 string);
 | 
				
			||||||
void S86_PrintLnFmt(char const *fmt, ...);
 | 
					void S86_PrintLnFmt(char const *fmt, ...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NOTE: Sim8086
 | 
				
			||||||
 | 
					// ============================================================================
 | 
				
			||||||
 | 
					typedef enum S86_InstructionType {
 | 
				
			||||||
 | 
					    S86_InstructionType_MOVRegOrMemToOrFromReg,
 | 
				
			||||||
 | 
					    S86_InstructionType_MOVImmediateToRegOrMem,
 | 
				
			||||||
 | 
					    S86_InstructionType_MOVImmediateToReg,
 | 
				
			||||||
 | 
					    S86_InstructionType_MOVMemToAccum,
 | 
				
			||||||
 | 
					    S86_InstructionType_MOVAccumToMem,
 | 
				
			||||||
 | 
					    S86_InstructionType_MOVRegOrMemToSegReg,
 | 
				
			||||||
 | 
					    S86_InstructionType_MOVSegRegToRegOrMem,
 | 
				
			||||||
 | 
					    S86_InstructionType_Count,
 | 
				
			||||||
 | 
					} S86_InstructionType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Bit patterns and masks for decoding 8086 assembly. 8086 opcodes can be up
 | 
				
			||||||
 | 
					/// to 2 bytes long and mixed with instruction specific control bits. These
 | 
				
			||||||
 | 
					/// masks isolate the opcode bits from the bits can be checked after masking
 | 
				
			||||||
 | 
					/// the binary instruction stream.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// Instructions that do not have opcode bits in the 2nd byte will have the mask
 | 
				
			||||||
 | 
					/// set to 0.
 | 
				
			||||||
 | 
					typedef struct S86_Instruction {
 | 
				
			||||||
 | 
					    uint8_t op_mask0;
 | 
				
			||||||
 | 
					    uint8_t op_bits0;
 | 
				
			||||||
 | 
					    uint8_t op_mask1;
 | 
				
			||||||
 | 
					    uint8_t op_bits1;
 | 
				
			||||||
 | 
					} S86_Instruction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					S86_Instruction const S86_INSTRUCTIONS[S86_InstructionType_Count] = {
 | 
				
			||||||
 | 
					    [S86_InstructionType_MOVRegOrMemToOrFromReg] = {.op_mask0 = 0b1111'1100,
 | 
				
			||||||
 | 
					                                                    .op_bits0 = 0b1000'1000,
 | 
				
			||||||
 | 
					                                                    .op_mask1 = 0b0000'0000,
 | 
				
			||||||
 | 
					                                                    .op_bits1 = 0b0000'0000},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [S86_InstructionType_MOVImmediateToRegOrMem] = {.op_mask0 = 0b1111'1110,
 | 
				
			||||||
 | 
					                                                    .op_bits0 = 0b1100'0110,
 | 
				
			||||||
 | 
					                                                    .op_mask1 = 0b0011'1000,
 | 
				
			||||||
 | 
					                                                    .op_bits1 = 0b0000'0000},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [S86_InstructionType_MOVImmediateToReg]      = {.op_mask0 = 0b1111'0000,
 | 
				
			||||||
 | 
					                                                    .op_bits0 = 0b1011'0000,
 | 
				
			||||||
 | 
					                                                    .op_mask1 = 0b0000'0000,
 | 
				
			||||||
 | 
					                                                    .op_bits1 = 0b0000'0000},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [S86_InstructionType_MOVMemToAccum]          = {.op_mask0 = 0b1111'1110,
 | 
				
			||||||
 | 
					                                                    .op_bits0 = 0b1010'0000,
 | 
				
			||||||
 | 
					                                                    .op_mask1 = 0b0000'0000,
 | 
				
			||||||
 | 
					                                                    .op_bits1 = 0b0000'0000},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [S86_InstructionType_MOVAccumToMem]          = {.op_mask0 = 0b1111'1110,
 | 
				
			||||||
 | 
					                                                    .op_bits0 = 0b1010'0010,
 | 
				
			||||||
 | 
					                                                    .op_mask1 = 0b0000'0000,
 | 
				
			||||||
 | 
					                                                    .op_bits1 = 0b0000'0000},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [S86_InstructionType_MOVRegOrMemToSegReg]    = {.op_mask0 = 0b1111'1111,
 | 
				
			||||||
 | 
					                                                    .op_bits0 = 0b1000'1110,
 | 
				
			||||||
 | 
					                                                    .op_mask1 = 0b0010'0000,
 | 
				
			||||||
 | 
					                                                    .op_bits1 = 0b0000'0000},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [S86_InstructionType_MOVSegRegToRegOrMem]    = {.op_mask0 = 0b1111'1111,
 | 
				
			||||||
 | 
					                                                    .op_bits0 = 0b1000'1100,
 | 
				
			||||||
 | 
					                                                    .op_mask1 = 0b0010'0000,
 | 
				
			||||||
 | 
					                                                    .op_bits1 = 0b0000'0000},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NOTE: Implementation
 | 
				
			||||||
 | 
					// ============================================================================
 | 
				
			||||||
bool S86_BufferIsValid(S86_Buffer buffer)
 | 
					bool S86_BufferIsValid(S86_Buffer buffer)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    bool result = buffer.data && buffer.size;
 | 
					    bool result = buffer.data && buffer.size;
 | 
				
			||||||
@ -208,76 +285,25 @@ void S86_PrintLnFmt(char const *fmt, ...)
 | 
				
			|||||||
    va_end(args);
 | 
					    va_end(args);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum S86_ModEncoding S86_ModEncoding;
 | 
					 | 
				
			||||||
enum S86_ModEncoding {
 | 
					 | 
				
			||||||
    S86_ModEncoding_MemModeNoDisplace = 0b00,
 | 
					 | 
				
			||||||
    S86_ModEncoding_MemMode8          = 0b01,
 | 
					 | 
				
			||||||
    S86_ModEncoding_MemMode16         = 0b10,
 | 
					 | 
				
			||||||
    S86_ModEncoding_RegisterMode      = 0b11,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef enum S86_InstructionType S86_InstructionType;
 | 
					 | 
				
			||||||
enum S86_InstructionType {
 | 
					 | 
				
			||||||
    S86_InstructionType_MOVRegOrMemToOrFromReg,
 | 
					 | 
				
			||||||
    S86_InstructionType_MOVImmediateToRegOrMem,
 | 
					 | 
				
			||||||
    S86_InstructionType_MOVImmediateToReg,
 | 
					 | 
				
			||||||
    S86_InstructionType_MOVMemToAccum,
 | 
					 | 
				
			||||||
    S86_InstructionType_MOVAccumToMem,
 | 
					 | 
				
			||||||
    S86_InstructionType_MOVRegOrMemToSegReg,
 | 
					 | 
				
			||||||
    S86_InstructionType_MOVSegRegToRegOrMem,
 | 
					 | 
				
			||||||
    S86_InstructionType_Count,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct S86_Instruction S86_Instruction;
 | 
					 | 
				
			||||||
struct S86_Instruction {
 | 
					 | 
				
			||||||
    uint8_t op_mask0;
 | 
					 | 
				
			||||||
    uint8_t op_bits0;
 | 
					 | 
				
			||||||
    uint8_t op_mask1;
 | 
					 | 
				
			||||||
    uint8_t op_bits1;
 | 
					 | 
				
			||||||
} S86_INSTRUCTIONS[S86_InstructionType_Count] = {
 | 
					 | 
				
			||||||
    [S86_InstructionType_MOVRegOrMemToOrFromReg] = {.op_mask0 = 0b1111'1100,
 | 
					 | 
				
			||||||
                                                    .op_bits0 = 0b1000'1000,
 | 
					 | 
				
			||||||
                                                    .op_mask1 = 0b0000'0000,
 | 
					 | 
				
			||||||
                                                    .op_bits1 = 0b0000'0000},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [S86_InstructionType_MOVImmediateToRegOrMem] = {.op_mask0 = 0b1111'1110,
 | 
					 | 
				
			||||||
                                                    .op_bits0 = 0b1100'0110,
 | 
					 | 
				
			||||||
                                                    .op_mask1 = 0b0011'1000,
 | 
					 | 
				
			||||||
                                                    .op_bits1 = 0b0000'0000},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [S86_InstructionType_MOVImmediateToReg]      = {.op_mask0 = 0b1111'0000,
 | 
					 | 
				
			||||||
                                                    .op_bits0 = 0b1011'0000,
 | 
					 | 
				
			||||||
                                                    .op_mask1 = 0b0000'0000,
 | 
					 | 
				
			||||||
                                                    .op_bits1 = 0b0000'0000},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [S86_InstructionType_MOVMemToAccum]          = {.op_mask0 = 0b1111'1110,
 | 
					 | 
				
			||||||
                                                    .op_bits0 = 0b1010'0000,
 | 
					 | 
				
			||||||
                                                    .op_mask1 = 0b0000'0000,
 | 
					 | 
				
			||||||
                                                    .op_bits1 = 0b0000'0000},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [S86_InstructionType_MOVAccumToMem]          = {.op_mask0 = 0b1111'1110,
 | 
					 | 
				
			||||||
                                                    .op_bits0 = 0b1010'0010,
 | 
					 | 
				
			||||||
                                                    .op_mask1 = 0b0000'0000,
 | 
					 | 
				
			||||||
                                                    .op_bits1 = 0b0000'0000},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [S86_InstructionType_MOVRegOrMemToSegReg]    = {.op_mask0 = 0b1111'1111,
 | 
					 | 
				
			||||||
                                                    .op_bits0 = 0b1000'1110,
 | 
					 | 
				
			||||||
                                                    .op_mask1 = 0b0010'0000,
 | 
					 | 
				
			||||||
                                                    .op_bits1 = 0b0000'0000},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [S86_InstructionType_MOVSegRegToRegOrMem]    = {.op_mask0 = 0b1111'1111,
 | 
					 | 
				
			||||||
                                                    .op_bits0 = 0b1000'1100,
 | 
					 | 
				
			||||||
                                                    .op_mask1 = 0b0010'0000,
 | 
					 | 
				
			||||||
                                                    .op_bits1 = 0b0000'0000},
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main(int argc, char **argv)
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    // NOTE: Argument handling
 | 
				
			||||||
 | 
					    // =========================================================================
 | 
				
			||||||
    if (argc != 2) {
 | 
					    if (argc != 2) {
 | 
				
			||||||
        S86_PrintLn(S86_STR8("usage: sim8086.exe <binary asm file>"));
 | 
					        S86_PrintLn(S86_STR8("usage: sim8086.exe <binary asm file>"));
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char const *file_path = argv[1];
 | 
				
			||||||
 | 
					    S86_Buffer buffer     = S86_FileRead(file_path);
 | 
				
			||||||
 | 
					    if (!S86_BufferIsValid(buffer)) {
 | 
				
			||||||
 | 
					        S86_PrintLnFmt("File read failed [path=\"%s\"]", argv[1], buffer.size);
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // NOTE: Sim8086
 | 
				
			||||||
 | 
					    // =========================================================================
 | 
				
			||||||
 | 
					    // Mapping from a 'reg' encoding to the register name.
 | 
				
			||||||
    S86_Str8 const REGISTER_FIELD_ENCODING[2][8] = {
 | 
					    S86_Str8 const REGISTER_FIELD_ENCODING[2][8] = {
 | 
				
			||||||
        [0b0] =
 | 
					        [0b0] =
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@ -303,13 +329,8 @@ int main(int argc, char **argv)
 | 
				
			|||||||
             },
 | 
					             },
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    char const *file_path = argv[1];
 | 
					    // NOTE: Decode assembly
 | 
				
			||||||
    S86_Buffer buffer     = S86_FileRead(file_path);
 | 
					    // =========================================================================
 | 
				
			||||||
    if (!S86_BufferIsValid(buffer)) {
 | 
					 | 
				
			||||||
        S86_PrintLnFmt("File read failed [path=\"%s\"]", argv[1], buffer.size);
 | 
					 | 
				
			||||||
        return -1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    S86_PrintLn(S86_STR8("bits 16"));
 | 
					    S86_PrintLn(S86_STR8("bits 16"));
 | 
				
			||||||
    S86_BufferIterator buffer_it = S86_BufferIteratorInit(buffer);
 | 
					    S86_BufferIterator buffer_it = S86_BufferIteratorInit(buffer);
 | 
				
			||||||
    while (S86_BufferIteratorHasMoreBytes(buffer_it)) {
 | 
					    while (S86_BufferIteratorHasMoreBytes(buffer_it)) {
 | 
				
			||||||
@ -326,7 +347,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
             instruction_type == S86_InstructionType_Count && instruction_index < S86_ARRAY_UCOUNT(S86_INSTRUCTIONS);
 | 
					             instruction_type == S86_InstructionType_Count && instruction_index < S86_ARRAY_UCOUNT(S86_INSTRUCTIONS);
 | 
				
			||||||
             instruction_index++)
 | 
					             instruction_index++)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            S86_Instruction *item = S86_INSTRUCTIONS + instruction_index;
 | 
					            S86_Instruction const *item = S86_INSTRUCTIONS + instruction_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // NOTE: Check first instruction byte
 | 
					            // NOTE: Check first instruction byte
 | 
				
			||||||
            // =================================================================
 | 
					            // =================================================================
 | 
				
			||||||
@ -354,7 +375,9 @@ int main(int argc, char **argv)
 | 
				
			|||||||
        // =================================================================
 | 
					        // =================================================================
 | 
				
			||||||
        S86_ASSERT(op_code_size > 0 && op_code_size <= S86_ARRAY_UCOUNT(op_code_bytes));
 | 
					        S86_ASSERT(op_code_size > 0 && op_code_size <= S86_ARRAY_UCOUNT(op_code_bytes));
 | 
				
			||||||
        S86_ASSERT(instruction_type != S86_InstructionType_Count && "Unknown instruction");
 | 
					        S86_ASSERT(instruction_type != S86_InstructionType_Count && "Unknown instruction");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        switch (instruction_type) {
 | 
					        switch (instruction_type) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            case S86_InstructionType_MOVRegOrMemToOrFromReg: {
 | 
					            case S86_InstructionType_MOVRegOrMemToOrFromReg: {
 | 
				
			||||||
                // NOTE: Instruction does not have opcode bits in the 2nd byte
 | 
					                // NOTE: Instruction does not have opcode bits in the 2nd byte
 | 
				
			||||||
                S86_ASSERT(op_code_size == 1);
 | 
					                S86_ASSERT(op_code_size == 1);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user