Last active
March 22, 2023 08:33
-
-
Save resistcorp/14d05f0c51b209489424d13b8a0b3ba1 to your computer and use it in GitHub Desktop.
Assignment for the first "Computer Enhance" course. Instruction Decoding on the 8086
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "Basic"; | |
#import "File"; | |
main :: (){ | |
args := get_command_line_arguments(); | |
if(args.count < 2){ | |
print_err("no file to decode"); | |
print_err("args : %", args); | |
return; | |
} | |
file := args[1]; | |
file_contents, ok := read_entire_file(file); | |
if(!ok){ | |
print_err("unable to read file %", file); | |
return; | |
} | |
bytes : []u8 = cast([]u8)file_contents; | |
if(ADD_HEADER)//helps with unit tests | |
print("bits 16\n\n"); | |
ptr := 0; | |
while(ptr<bytes.count){ | |
b1 := bytes[ptr]; | |
b2 := bytes[ptr+1]; | |
opcode := b1>>2 & 0b111111; | |
D := b1&0b10 == 0b10; | |
W := b1&0b01 == 0b01; | |
// a lambda thingy | |
name := ifx (W) reg_name_w else reg_name; | |
mod := b2>>6 & 0b011; | |
reg := name(b2>>3 & 0b111); | |
rm := name(b2>>0 & 0b111); | |
//we don't check mod -- yet? | |
if(opcode & OP_MOV == OP_MOV){ | |
from := ifx D rm else reg; | |
to := ifx D reg else rm; | |
print("mov %, %\n", to, from); | |
}else{ | |
print_err("NOT A MOV 0b% \n", formatInt(opcode, base = 2, minimum_digits = 6)); | |
} | |
ptr+=2; | |
} | |
} | |
ADD_HEADER :: true; | |
OP_MOV :: 0b100010; | |
registers :: enum u8 { | |
al :: 0b000; | |
cl :: 0b001; | |
dl :: 0b010; | |
bl :: 0b011; | |
ah :: 0b100; | |
ch :: 0b101; | |
dh :: 0b110; | |
bh :: 0b111; | |
} | |
registersW :: enum u8 { | |
ax :: 0b000; | |
cx :: 0b001; | |
dx :: 0b010; | |
bx :: 0b011; | |
sp :: 0b100; | |
bp :: 0b101; | |
si :: 0b110; | |
di :: 0b111; | |
} | |
reg_name_w :: (reg : u8) -> string{ | |
return tprint("%", cast(registersW)reg); | |
} | |
reg_name :: (reg : u8) -> string{ | |
return tprint("%", cast(registers)reg); | |
} | |
print_err :: (format_string: string, args: .. Any){ | |
print(format_string, ..args, to_standard_error = true); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment