112 lines
2.8 KiB
Odin
112 lines
2.8 KiB
Odin
package sim_8086
|
|
|
|
import "core:os"
|
|
import "core:fmt"
|
|
import "core:math"
|
|
import "core:strings"
|
|
|
|
RIGHT_ALIGN_AMOUNT := 35
|
|
|
|
registers := [8]Register {
|
|
{fullname = "ax", bytename = "al", code = 0b000},
|
|
{fullname = "cx", bytename = "cl", code = 0b001},
|
|
{fullname = "dx", bytename = "dl", code = 0b010},
|
|
{fullname = "bx", bytename = "bl", code = 0b011},
|
|
{fullname = "sp", bytename = "ah", code = 0b100},
|
|
{fullname = "bp", bytename = "ch", code = 0b101},
|
|
{fullname = "si", bytename = "dh", code = 0b110},
|
|
{fullname = "di", bytename = "bh", code = 0b111},
|
|
}
|
|
|
|
segment_registers := [4]Register {
|
|
{fullname = "es", code = 0b000},
|
|
{fullname = "cs", code = 0b001},
|
|
{fullname = "ss", code = 0b010},
|
|
{fullname = "ds", code = 0b011},
|
|
}
|
|
|
|
variable_port := registers[2]
|
|
|
|
total_bytes_processed := 0
|
|
|
|
get_i16 :: proc(data: []u8) -> i16 {
|
|
return (i16)(data[1]) << 8 | (i16)(data[0])
|
|
}
|
|
|
|
operand_is :: proc($T: typeid, opr: Operand) -> bool {
|
|
_, ok := opr.(T)
|
|
return ok
|
|
}
|
|
|
|
get_repeat_op :: proc(data: u8) -> Repeat {
|
|
bits := (data & 0b1110) >> 1
|
|
w := (data & 0b1) == 1 ? "w" : "b"
|
|
rep: string
|
|
switch bits {
|
|
case 0b010: rep = "movs"
|
|
case 0b011: rep = "cmps"
|
|
case 0b101: rep = "stos"
|
|
case 0b110: rep = "lods"
|
|
case 0b111: rep = "scas"
|
|
}
|
|
return Repeat(fmt.aprintf("%s%s", rep, w))
|
|
}
|
|
|
|
try_find_instruction :: proc(b: u8) -> (InstructionInfo, bool) {
|
|
for inst in instructions {
|
|
if inst.encoding == (b & inst.mask) {
|
|
return inst, true
|
|
}
|
|
}
|
|
return InstructionInfo{}, false
|
|
}
|
|
|
|
main :: proc() {
|
|
f,err := os.open(os.args[1])
|
|
if err != os.ERROR_NONE {
|
|
fmt.eprintln("ERROR:", err)
|
|
os.exit(1)
|
|
}
|
|
defer os.close(f)
|
|
|
|
data := make([]u8, 1024)
|
|
bytes_read, err2 := os.read(f, data)
|
|
if err2 != nil {
|
|
// ...
|
|
os.exit(1)
|
|
}
|
|
|
|
// asdf :u16 = 0b00000110_11011101
|
|
// asdf2 :i16 = (i16)(asdf)
|
|
// fmt.printfln("%d", asdf2)
|
|
print_at_end := false
|
|
line_count := 0
|
|
instruction_list := make([dynamic]string, 0, 512)
|
|
instructions_list := make([dynamic]Instruction, 0, 512)
|
|
|
|
decode_data(&instructions_list, data[:], bytes_read)
|
|
|
|
for inst in instructions_list {
|
|
execute_instruction(inst)
|
|
}
|
|
|
|
if true {
|
|
print_reg :: proc(reg: Register) {
|
|
full := fmt.aprintf("%s (%s): %d ", reg.fullname, reg.bytename, reg.value.full)
|
|
hex := fmt.aprintf("0x%04x ", reg.value.full)
|
|
fmt.printf("%s %*[1]s %s %*[4]s %08b %08b",
|
|
full, 18 - len(full), "|", hex, 10 - len(hex), "|", reg.value.high, reg.value.low)
|
|
fmt.println()
|
|
}
|
|
for reg in registers {
|
|
print_reg(reg)
|
|
}
|
|
for reg in segment_registers {
|
|
print_reg(reg)
|
|
}
|
|
}
|
|
if false {
|
|
print_instructions_stdout(instructions_list[:])
|
|
}
|
|
}
|