Compare commits

..

No commits in common. "11ccfe78a99cc6b494206c97697a0b9efd17629b" and "0e90e2c23c160e7b36feb96438b606267e041a9b" have entirely different histories.

7 changed files with 39 additions and 86 deletions

View File

@ -1,30 +0,0 @@
; ========================================================================
;
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Please see https://computerenhance.com for further information
;
; ========================================================================
; ========================================================================
; LISTING 51
; ========================================================================
bits 16
mov word [1000], 1
mov word [1002], 2
mov word [1004], 3
mov word [1006], 4
mov bx, 1000
mov word [bx + 4], 10
mov bx, word [1000]
mov cx, word [1002]
mov dx, word [1004]
mov bp, word [1006]

View File

@ -1,18 +0,0 @@
--- test\listing_0051_memory_mov execution ---
mov word [+1000], 1 ; ip:0x0->0x6
mov word [+1002], 2 ; ip:0x6->0xc
mov word [+1004], 3 ; ip:0xc->0x12
mov word [+1006], 4 ; ip:0x12->0x18
mov bx, 1000 ; bx:0x0->0x3e8 ip:0x18->0x1b
mov word [bx+4], 10 ; ip:0x1b->0x20
mov bx, [+1000] ; bx:0x3e8->0x1 ip:0x20->0x24
mov cx, [+1002] ; cx:0x0->0x2 ip:0x24->0x28
mov dx, [+1004] ; dx:0x0->0xa ip:0x28->0x2c
mov bp, [+1006] ; bp:0x0->0x4 ip:0x2c->0x30
Final registers:
bx: 0x0001 (1)
cx: 0x0002 (2)
dx: 0x000a (10)
bp: 0x0004 (4)
ip: 0x0030 (48)

View File

@ -99,13 +99,13 @@ parse_operand :: proc(inst: InstructionInfo, opinfo: OperandInfo, data: []u8, pr
op = (DirectAddress)(get_i16(data[2:])) op = (DirectAddress)(get_i16(data[2:]))
processed^ += 2 processed^ += 2
} else { } else {
op = MemoryAddr{ addr_id = rm } op = MemoryAddr{ addr_id = rm , displacement = None{} }
} }
} else if mod == 1 { } else if mod == 1 {
op = MemoryAddr{ addr_id = rm , displacement_value = (i16)(data[2]) , displacement_size = .Signed8 } op = MemoryAddr{ addr_id = rm , displacement = (i8)(data[2]) }
processed^ += 1 processed^ += 1
} else if mod == 2 { } else if mod == 2 {
op = MemoryAddr{ addr_id = rm , displacement_value = get_i16(data[2:]) , displacement_size = .Signed16 } op = MemoryAddr{ addr_id = rm , displacement = get_i16(data[2:]) }
processed^ += 2 processed^ += 2
} else if mod == 3 { } else if mod == 3 {
if word { if word {

View File

@ -11,6 +11,7 @@ get_ip :: proc(cpu: ^Cpu) -> int { return int(cpu.registers[.ip].full) }
get_operand_value :: proc(cpu: ^Cpu, operand: Operand) -> i16 { get_operand_value :: proc(cpu: ^Cpu, operand: Operand) -> i16 {
#partial switch opr in operand { #partial switch opr in operand {
case Immediate: case Immediate:
// fmt.printfln("0x%4x %d", i16(opr.value), opr.value)
return i16(opr.value) return i16(opr.value)
case RegisterId: case RegisterId:
reg_val := cpu.registers[opr.name] reg_val := cpu.registers[opr.name]
@ -20,9 +21,6 @@ get_operand_value :: proc(cpu: ^Cpu, operand: Operand) -> i16 {
case .Full: case .Full:
return i16(reg_val.full) return i16(reg_val.full)
} }
case DirectAddress:
value := i16(u16(cpu.memory[opr+1] << 8) | u16(cpu.memory[opr]))
return value
} }
return 0 return 0
} }
@ -109,32 +107,6 @@ execute_instruction :: proc(cpu: ^Cpu, inst: Instruction) {
check_auxiliary_carry_flag(cpu, dst_val, src_val, false) check_auxiliary_carry_flag(cpu, dst_val, src_val, false)
check_carry_flag(cpu, dst_val, src_val, false) check_carry_flag(cpu, dst_val, src_val, false)
} }
} else if addr,ok := inst.dst.(DirectAddress); ok {
#partial switch inst.opname {
case .MOV:
if imm,ok := inst.src.(Immediate); ok {
if imm.size == .Signed16 {
cpu.memory[addr] = u8(imm.value & 0x00FF)
cpu.memory[addr+1] = u8((u16(imm.value) & 0xFF00) >> 8)
} else {
cpu.memory[addr] = u8(imm.value)
}
}
}
} else if mem_addr,ok := inst.dst.(MemoryAddr); ok {
#partial switch inst.opname {
case .MOV:
if imm,ok := inst.src.(Immediate); ok {
// TODO: We need a function that returns the registers to check out
addr := cpu.registers[.bx].full + mem_addr.displacement_value
if imm.size == .Signed16 {
cpu.memory[addr] = u8(imm.value & 0x00FF)
cpu.memory[addr+1] = u8((u16(imm.value) & 0xFF00) >> 8)
} else {
cpu.memory[addr] = u8(imm.value)
}
}
}
} else if jmp_offset,ok := inst.src.(Jump); ok { } else if jmp_offset,ok := inst.src.(Jump); ok {
jump: bool jump: bool
#partial switch inst.opname { #partial switch inst.opname {

View File

@ -39,10 +39,18 @@ calculate_effective_address :: proc(r_m: u8) -> string {
get_memory_string :: proc(memoryAddr: MemoryAddr, has_segment: Maybe(RegisterId)) -> string { get_memory_string :: proc(memoryAddr: MemoryAddr, has_segment: Maybe(RegisterId)) -> string {
disp: string disp: string
value := memoryAddr.displacement_value switch value in memoryAddr.displacement {
case None:
disp = ""
case Disp8:
if value != 0 { if value != 0 {
disp = fmt.aprintf(" %s %d", value > 0 ? "+" : "-", math.abs(value)) disp = fmt.aprintf(" %s %d", value > 0 ? "+" : "-", math.abs(value))
} }
case Disp16:
if value != 0 {
disp = fmt.aprintf(" %s %d", value > 0 ? "+" : "-", math.abs(value))
}
}
seg_string: string seg_string: string
if segreg, ok := has_segment.?; ok { if segreg, ok := has_segment.?; ok {
seg_string = fmt.aprintf("%s:", get_register_name(segreg)) seg_string = fmt.aprintf("%s:", get_register_name(segreg))
@ -51,6 +59,21 @@ get_memory_string :: proc(memoryAddr: MemoryAddr, has_segment: Maybe(RegisterId)
return text return text
} }
get_displacement_string :: proc(displacement: Displacement) -> string {
disp := ""
#partial switch value in displacement {
case i8:
if value != 0 {
disp = fmt.aprintf(" %s %d", value > 0 ? "+" : "-", math.abs(value))
}
case i16:
if value != 0 {
disp = fmt.aprintf(" %s %d", value > 0 ? "+" : "-", math.abs(value))
}
}
return disp
}
get_register_name :: proc(reg_id: RegisterId) -> string { get_register_name :: proc(reg_id: RegisterId) -> string {
low_names := [?]string{"al", "cl", "dl", "bl"} low_names := [?]string{"al", "cl", "dl", "bl"}
high_names := [?]string{"ah", "ch", "dh", "bh"} high_names := [?]string{"ah", "ch", "dh", "bh"}

View File

@ -44,7 +44,7 @@ main :: proc() {
} }
cpu := Cpu { cpu := Cpu {
memory = make([dynamic]u8, 1024 * 1024), // 1,048,576 memory = make([dynamic]u8, 1_048_576), // Exact num per the manual
} }
execute_instructions(&cpu, decoded_insts) execute_instructions(&cpu, decoded_insts)

View File

@ -46,6 +46,13 @@ WordSize :: enum {
} }
None :: struct {} None :: struct {}
Disp8 :: i8
Disp16 :: i16
Displacement :: union {
None,
Disp8,
Disp16
}
RegisterAccess :: enum { RegisterAccess :: enum {
Full, Full,
@ -68,8 +75,7 @@ Immediate :: struct {
} }
MemoryAddr :: struct { MemoryAddr :: struct {
addr_id: u8, addr_id: u8,
displacement_value: i16, displacement: Displacement,
displacement_size: ImmediateSize,
} }
DirectAddress :: distinct i16 DirectAddress :: distinct i16
Jump :: distinct i8 Jump :: distinct i8