Started implementing the 8086 simulation
This commit is contained in:
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user