Compare commits
2 Commits
0e90e2c23c
...
11ccfe78a9
Author | SHA1 | Date | |
---|---|---|---|
11ccfe78a9 | |||
948960e8f5 |
30
asm_files/list-0051.asm
Normal file
30
asm_files/list-0051.asm
Normal file
@ -0,0 +1,30 @@
|
||||
; ========================================================================
|
||||
;
|
||||
; (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]
|
18
asm_files/list-0051.txt
Normal file
18
asm_files/list-0051.txt
Normal file
@ -0,0 +1,18 @@
|
||||
--- 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)
|
@ -99,13 +99,13 @@ parse_operand :: proc(inst: InstructionInfo, opinfo: OperandInfo, data: []u8, pr
|
||||
op = (DirectAddress)(get_i16(data[2:]))
|
||||
processed^ += 2
|
||||
} else {
|
||||
op = MemoryAddr{ addr_id = rm , displacement = None{} }
|
||||
op = MemoryAddr{ addr_id = rm }
|
||||
}
|
||||
} else if mod == 1 {
|
||||
op = MemoryAddr{ addr_id = rm , displacement = (i8)(data[2]) }
|
||||
op = MemoryAddr{ addr_id = rm , displacement_value = (i16)(data[2]) , displacement_size = .Signed8 }
|
||||
processed^ += 1
|
||||
} else if mod == 2 {
|
||||
op = MemoryAddr{ addr_id = rm , displacement = get_i16(data[2:]) }
|
||||
op = MemoryAddr{ addr_id = rm , displacement_value = get_i16(data[2:]) , displacement_size = .Signed16 }
|
||||
processed^ += 2
|
||||
} else if mod == 3 {
|
||||
if word {
|
||||
|
@ -11,7 +11,6 @@ get_ip :: proc(cpu: ^Cpu) -> int { return int(cpu.registers[.ip].full) }
|
||||
get_operand_value :: proc(cpu: ^Cpu, operand: Operand) -> i16 {
|
||||
#partial switch opr in operand {
|
||||
case Immediate:
|
||||
// fmt.printfln("0x%4x %d", i16(opr.value), opr.value)
|
||||
return i16(opr.value)
|
||||
case RegisterId:
|
||||
reg_val := cpu.registers[opr.name]
|
||||
@ -21,6 +20,9 @@ get_operand_value :: proc(cpu: ^Cpu, operand: Operand) -> i16 {
|
||||
case .Full:
|
||||
return i16(reg_val.full)
|
||||
}
|
||||
case DirectAddress:
|
||||
value := i16(u16(cpu.memory[opr+1] << 8) | u16(cpu.memory[opr]))
|
||||
return value
|
||||
}
|
||||
return 0
|
||||
}
|
||||
@ -107,6 +109,32 @@ execute_instruction :: proc(cpu: ^Cpu, inst: Instruction) {
|
||||
check_auxiliary_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 {
|
||||
jump: bool
|
||||
#partial switch inst.opname {
|
||||
|
@ -39,17 +39,9 @@ calculate_effective_address :: proc(r_m: u8) -> string {
|
||||
|
||||
get_memory_string :: proc(memoryAddr: MemoryAddr, has_segment: Maybe(RegisterId)) -> string {
|
||||
disp: string
|
||||
switch value in memoryAddr.displacement {
|
||||
case None:
|
||||
disp = ""
|
||||
case Disp8:
|
||||
if value != 0 {
|
||||
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))
|
||||
}
|
||||
value := memoryAddr.displacement_value
|
||||
if value != 0 {
|
||||
disp = fmt.aprintf(" %s %d", value > 0 ? "+" : "-", math.abs(value))
|
||||
}
|
||||
seg_string: string
|
||||
if segreg, ok := has_segment.?; ok {
|
||||
@ -59,21 +51,6 @@ get_memory_string :: proc(memoryAddr: MemoryAddr, has_segment: Maybe(RegisterId)
|
||||
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 {
|
||||
low_names := [?]string{"al", "cl", "dl", "bl"}
|
||||
high_names := [?]string{"ah", "ch", "dh", "bh"}
|
||||
|
@ -44,7 +44,7 @@ main :: proc() {
|
||||
}
|
||||
|
||||
cpu := Cpu {
|
||||
memory = make([dynamic]u8, 1_048_576), // Exact num per the manual
|
||||
memory = make([dynamic]u8, 1024 * 1024), // 1,048,576
|
||||
}
|
||||
|
||||
execute_instructions(&cpu, decoded_insts)
|
||||
|
10
types.odin
10
types.odin
@ -46,13 +46,6 @@ WordSize :: enum {
|
||||
}
|
||||
|
||||
None :: struct {}
|
||||
Disp8 :: i8
|
||||
Disp16 :: i16
|
||||
Displacement :: union {
|
||||
None,
|
||||
Disp8,
|
||||
Disp16
|
||||
}
|
||||
|
||||
RegisterAccess :: enum {
|
||||
Full,
|
||||
@ -75,7 +68,8 @@ Immediate :: struct {
|
||||
}
|
||||
MemoryAddr :: struct {
|
||||
addr_id: u8,
|
||||
displacement: Displacement,
|
||||
displacement_value: i16,
|
||||
displacement_size: ImmediateSize,
|
||||
}
|
||||
DirectAddress :: distinct i16
|
||||
Jump :: distinct i8
|
||||
|
Loading…
x
Reference in New Issue
Block a user