Factor out get/set actions to reduce duplication, execute add,sub,cmp and check flags
This commit is contained in:
parent
863ccfc583
commit
266f7a7900
@ -5,36 +5,64 @@ import "core:fmt"
|
|||||||
import "core:math"
|
import "core:math"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
|
|
||||||
|
get_operand_value :: proc(operand: Operand) -> u16 {
|
||||||
|
#partial switch opr in operand {
|
||||||
|
case Immediate:
|
||||||
|
return opr.value
|
||||||
|
case RegisterId:
|
||||||
|
switch opr.access {
|
||||||
|
case .Low, .High:
|
||||||
|
val := opr.access == .Low ? registers[opr.id].value.low : registers[opr.id].value.high
|
||||||
|
return u16(val)
|
||||||
|
case .Full:
|
||||||
|
return registers[opr.id].value.full
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
set_register_value :: proc(reg_id: RegisterId, value: u16) {
|
||||||
|
switch reg_id.access {
|
||||||
|
case .Low:
|
||||||
|
registers[reg_id.id].value.low = u8(value)
|
||||||
|
case .High:
|
||||||
|
registers[reg_id.id].value.high = u8(value)
|
||||||
|
case .Full:
|
||||||
|
registers[reg_id.id].value.full = u16(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check_zero_flag :: proc(value: u16) {
|
||||||
|
CPU.flags.ZF = value == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
check_sign_flag :: proc(value: u16) {
|
||||||
|
CPU.flags.SF = value >> 15 == 1
|
||||||
|
}
|
||||||
|
|
||||||
execute_instruction :: proc(inst: Instruction) {
|
execute_instruction :: proc(inst: Instruction) {
|
||||||
|
if reg,ok := inst.dst.(RegisterId); ok {
|
||||||
#partial switch inst.opname {
|
#partial switch inst.opname {
|
||||||
case .MOV:
|
case .MOV:
|
||||||
if reg_id,ok := inst.dst.(RegisterId); ok {
|
src_val := get_operand_value(inst.src)
|
||||||
// val := registers[reg_id.id].value.full
|
set_register_value(reg, src_val)
|
||||||
#partial switch val in inst.src {
|
case .ADD:
|
||||||
case Immediate:
|
src_val := get_operand_value(inst.src)
|
||||||
if val.size == .Signed16 {
|
val := registers[reg.id].value.full + src_val
|
||||||
registers[reg_id.id].value.full = (u16)(val.value)
|
set_register_value(reg, val)
|
||||||
} else {
|
check_zero_flag(val)
|
||||||
value := u8(val.value & 0xFF)
|
check_sign_flag(val)
|
||||||
if reg_id.access == .Low {
|
case .SUB:
|
||||||
registers[reg_id.id].value.low = value
|
src_val := get_operand_value(inst.src)
|
||||||
} else {
|
val := registers[reg.id].value.full - src_val
|
||||||
registers[reg_id.id].value.high = value
|
set_register_value(reg, val)
|
||||||
}
|
check_zero_flag(val)
|
||||||
}
|
check_sign_flag(val)
|
||||||
case RegisterId:
|
case .CMP:
|
||||||
switch val.access {
|
src_val := get_operand_value(inst.src)
|
||||||
case .Low, .High:
|
val := registers[reg.id].value.full - src_val
|
||||||
value := val.access == .Low ? registers[val.id].value.low : registers[val.id].value.high
|
check_zero_flag(val)
|
||||||
if reg_id.access == .Low {
|
check_sign_flag(val)
|
||||||
registers[reg_id.id].value.low = value
|
|
||||||
} else {
|
|
||||||
registers[reg_id.id].value.high = value
|
|
||||||
}
|
|
||||||
case .Full:
|
|
||||||
registers[reg_id.id].value.full = registers[val.id].value.full
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,11 @@ registers := [?]Register {
|
|||||||
variable_port := registers[2]
|
variable_port := registers[2]
|
||||||
|
|
||||||
SEGMENT_REGISTER_START :: 8
|
SEGMENT_REGISTER_START :: 8
|
||||||
|
|
||||||
|
CPU := Cpu {
|
||||||
|
memory = make([dynamic]u8, 65536)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: I don't like this here
|
// TODO: I don't like this here
|
||||||
total_bytes_processed := 0
|
total_bytes_processed := 0
|
||||||
|
|
||||||
|
@ -19,5 +19,10 @@ do
|
|||||||
./sim8086 asm_files/${asm_listing}.bin registers | awk '{print $1 $4}' | sort > temp1
|
./sim8086 asm_files/${asm_listing}.bin registers | awk '{print $1 $4}' | sort > temp1
|
||||||
cat $asm_txt | awk '/Final registers/,0' | tail -n +2 | awk '{print $1 $2}' | sort > temp2
|
cat $asm_txt | awk '/Final registers/,0' | tail -n +2 | awk '{print $1 $2}' | sort > temp2
|
||||||
diff -U0 --color temp1 temp2
|
diff -U0 --color temp1 temp2
|
||||||
|
if [ $? -eq 1 ]; then
|
||||||
|
echo Listing $asm_listing Failed!
|
||||||
|
else
|
||||||
|
echo Listing $asm_listing Succeded!
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
rm temp1 temp2
|
rm temp1 temp2
|
||||||
|
10
types.odin
10
types.odin
@ -11,6 +11,11 @@ Register :: struct {
|
|||||||
code: u8,
|
code: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Flags :: struct {
|
||||||
|
ZF: bool,
|
||||||
|
SF: bool,
|
||||||
|
}
|
||||||
|
|
||||||
WordSize :: enum {
|
WordSize :: enum {
|
||||||
None,
|
None,
|
||||||
LastBit,
|
LastBit,
|
||||||
@ -126,3 +131,8 @@ Instruction :: struct {
|
|||||||
raw_data: []u8,
|
raw_data: []u8,
|
||||||
debug_msg: string,
|
debug_msg: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cpu :: struct {
|
||||||
|
flags: Flags,
|
||||||
|
memory: [dynamic]u8,
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user