Handle additional jumps for listing 50
This commit is contained in:
parent
99fd7fabd7
commit
0e90e2c23c
38
asm_files/list-0050.asm
Normal file
38
asm_files/list-0050.asm
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
; ========================================================================
|
||||||
|
;
|
||||||
|
; (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 50
|
||||||
|
; ========================================================================
|
||||||
|
|
||||||
|
bits 16
|
||||||
|
|
||||||
|
mov ax, 10
|
||||||
|
mov bx, 10
|
||||||
|
mov cx, 10
|
||||||
|
|
||||||
|
label_0:
|
||||||
|
cmp bx, cx
|
||||||
|
je label_1
|
||||||
|
|
||||||
|
add ax, 1
|
||||||
|
jp label_2
|
||||||
|
|
||||||
|
label_1:
|
||||||
|
sub bx, 5
|
||||||
|
jb label_3
|
||||||
|
|
||||||
|
label_2:
|
||||||
|
sub cx, 2
|
||||||
|
|
||||||
|
label_3:
|
||||||
|
loopnz label_0
|
37
asm_files/list-0050.txt
Normal file
37
asm_files/list-0050.txt
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
--- test\listing_0050_challenge_jumps execution ---
|
||||||
|
mov ax, 10 ; ax:0x0->0xa ip:0x0->0x3
|
||||||
|
mov bx, 10 ; bx:0x0->0xa ip:0x3->0x6
|
||||||
|
mov cx, 10 ; cx:0x0->0xa ip:0x6->0x9
|
||||||
|
cmp bx, cx ; ip:0x9->0xb flags:->PZ
|
||||||
|
je $+7 ; ip:0xb->0x12
|
||||||
|
sub bx, 5 ; bx:0xa->0x5 ip:0x12->0x15 flags:PZ->P
|
||||||
|
jb $+5 ; ip:0x15->0x17
|
||||||
|
sub cx, 2 ; cx:0xa->0x8 ip:0x17->0x1a flags:P->
|
||||||
|
loopnz $-17 ; cx:0x8->0x7 ip:0x1a->0x9
|
||||||
|
cmp bx, cx ; ip:0x9->0xb flags:->CAS
|
||||||
|
je $+7 ; ip:0xb->0xd
|
||||||
|
add ax, 1 ; ax:0xa->0xb ip:0xd->0x10 flags:CAS->
|
||||||
|
jp $+7 ; ip:0x10->0x12
|
||||||
|
sub bx, 5 ; bx:0x5->0x0 ip:0x12->0x15 flags:->PZ
|
||||||
|
jb $+5 ; ip:0x15->0x17
|
||||||
|
sub cx, 2 ; cx:0x7->0x5 ip:0x17->0x1a flags:PZ->P
|
||||||
|
loopnz $-17 ; cx:0x5->0x4 ip:0x1a->0x9
|
||||||
|
cmp bx, cx ; ip:0x9->0xb flags:P->CPAS
|
||||||
|
je $+7 ; ip:0xb->0xd
|
||||||
|
add ax, 1 ; ax:0xb->0xc ip:0xd->0x10 flags:CPAS->P
|
||||||
|
jp $+7 ; ip:0x10->0x17
|
||||||
|
sub cx, 2 ; cx:0x4->0x2 ip:0x17->0x1a flags:P->
|
||||||
|
loopnz $-17 ; cx:0x2->0x1 ip:0x1a->0x9
|
||||||
|
cmp bx, cx ; ip:0x9->0xb flags:->CPAS
|
||||||
|
je $+7 ; ip:0xb->0xd
|
||||||
|
add ax, 1 ; ax:0xc->0xd ip:0xd->0x10 flags:CPAS->
|
||||||
|
jp $+7 ; ip:0x10->0x12
|
||||||
|
sub bx, 5 ; bx:0x0->0xfffb ip:0x12->0x15 flags:->CAS
|
||||||
|
jb $+5 ; ip:0x15->0x1a
|
||||||
|
loopnz $-17 ; cx:0x1->0x0 ip:0x1a->0x1c
|
||||||
|
|
||||||
|
Final registers:
|
||||||
|
ax: 0x000d (13)
|
||||||
|
bx: 0xfffb (65531)
|
||||||
|
ip: 0x001c (28)
|
||||||
|
flags: CAS
|
@ -108,25 +108,33 @@ execute_instruction :: proc(cpu: ^Cpu, inst: Instruction) {
|
|||||||
check_carry_flag(cpu, dst_val, src_val, false)
|
check_carry_flag(cpu, dst_val, src_val, false)
|
||||||
}
|
}
|
||||||
} else if jmp_offset,ok := inst.src.(Jump); ok {
|
} else if jmp_offset,ok := inst.src.(Jump); ok {
|
||||||
|
jump: bool
|
||||||
#partial switch inst.opname {
|
#partial switch inst.opname {
|
||||||
case .JNZ, .JNE:
|
case .JNZ, .JNE: jump = !cpu.flags[.ZF]
|
||||||
if !cpu.flags[.ZF] {
|
case .JE, .JZ: jump = cpu.flags[.ZF]
|
||||||
|
case .JP, .JPE: jump = cpu.flags[.PF]
|
||||||
|
case .JB, .JNAE: jump = cpu.flags[.CF]
|
||||||
|
|
||||||
|
case .LOOPNZ, .LOOPNE:
|
||||||
|
cpu.registers[.cx].full -= 1
|
||||||
|
// According to this resource, the loopnz inst does not change any flags
|
||||||
|
// https://yassinebridi.github.io/asm-docs/8086_instruction_set.html#LOOPNZ
|
||||||
|
// check_zero_flag(cpu, cpu.registers[.cx].full)
|
||||||
|
jump = cpu.registers[.cx].full != 0 && !cpu.flags[.ZF]
|
||||||
|
}
|
||||||
|
if jump {
|
||||||
cpu.registers[.ip].full += i16(jmp_offset)
|
cpu.registers[.ip].full += i16(jmp_offset)
|
||||||
if jmp_offset < 0 {
|
|
||||||
cpu.registers[.ip].full -= i16(inst.bytes_read)
|
cpu.registers[.ip].full -= i16(inst.bytes_read)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
execute_instructions :: proc(cpu: ^Cpu, instructions: DecodedInstructions) {
|
execute_instructions :: proc(cpu: ^Cpu, instructions: DecodedInstructions) {
|
||||||
halt := false
|
halt := false
|
||||||
fmt.println(instructions.total_bytes_decoded)
|
|
||||||
for !halt && get_ip(cpu) < instructions.total_bytes_decoded {
|
for !halt && get_ip(cpu) < instructions.total_bytes_decoded {
|
||||||
inst,ok := instructions.inst_map[get_ip(cpu)]
|
inst,ok := instructions.inst_map[get_ip(cpu)]
|
||||||
if !ok {
|
if !ok {
|
||||||
// Something went wrong with a jump, most likely
|
panic("Something went wrong with a jump, most likely")
|
||||||
}
|
}
|
||||||
cpu.registers[.ip].full += i16(inst.bytes_read)
|
cpu.registers[.ip].full += i16(inst.bytes_read)
|
||||||
execute_instruction(cpu, inst)
|
execute_instruction(cpu, inst)
|
||||||
|
@ -106,6 +106,7 @@ Op :: enum {
|
|||||||
LOOP,
|
LOOP,
|
||||||
LOOPZ,
|
LOOPZ,
|
||||||
LOOPNZ,
|
LOOPNZ,
|
||||||
|
LOOPNE,
|
||||||
JCXZ,
|
JCXZ,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ main :: proc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cpu := Cpu {
|
cpu := Cpu {
|
||||||
memory = make([dynamic]u8, 65536),
|
memory = make([dynamic]u8, 1_048_576), // Exact num per the manual
|
||||||
}
|
}
|
||||||
|
|
||||||
execute_instructions(&cpu, decoded_insts)
|
execute_instructions(&cpu, decoded_insts)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user