Fix a bug with the branch instructions not being able to move backward (offsets were unsigned)

master
Joey Pollack 2 years ago
parent 05fcb7b7f7
commit ecc7b9b73f

@ -7,6 +7,7 @@
{
"type": "lldb",
"request": "launch",
@ -59,7 +60,7 @@
"kind": "bin"
}
},
"args": ["simple_test_machine\\programs\\mult10.bin"],
"args": ["simple_test_machine\\programs\\hello.bin"],
"cwd": "${workspaceFolder}"
},
]

@ -1,37 +1,31 @@
# Load string into memory at the output address
0xA2, b'H', # LDX H
0x86, output_addr, # STX
0xA2, b'e', # LDX e
0x86, output_addr + 1, # STX
0xA2, b'l', # LDX l
0x86, output_addr + 2, # STX
0xA2, b'l', # LDX l
0x86, output_addr + 3, # STX
0xA2, b'o', # LDX o
0x86, output_addr + 4, # STX
0xA2, b' ', # LDX ' '
0x86, output_addr + 5, # STX
0xA2, b'w', # LDX w
0x86, output_addr + 6, # STX
0xA2, b'o', # LDX o
0x86, output_addr + 7, # STX
0xA2, b'r', # LDX r
0x86, output_addr + 8, # STX
0xA2, b'l', # LDX l
0x86, output_addr + 9, # STX
0xA2, b'd', # LDX d
0x86, output_addr + 10, # STX
0xA2, b'!', # LDX !
0x86, output_addr + 11, # STX
0xA2, 0x00, # LDX 0
0x86, output_addr + 12, # STX
# Set flag to do the print
0xA2, 0x01, # LDX 1
0x86, print_flag_addr, # STX
# End the program
0x60 # RTS
; hello world example
; for win2c64 by Aart Bik
; http://www.aartbik.com/
; Adapted for the RE6502 emulator simple test machine
strout .equ $00A0 ; console output address
print_flag .equ $009E ; console output address
main .org $0200 ; program load address for the simple test machine
ldx #0
loop lda text,x
sta strout,x
inx
cpx #11
bne loop
; null terminate the string
lda #0
sta strout,x
; Set flag to do the print
ldx #1 ; 0xA2, 0x01,
stx print_flag ; 0x86, 0x9E, ; Print string flag is at 0x9E
; End the program
rts ; 0x60
; Variables
text .byte "HELLO WORLD"

@ -1,5 +1,7 @@
; Multiply 7 with 10 and print the result
; For testing this program was assembled with c64 (using the -R option):
; https://www.aartbik.com/MISC/c64.html
; FAST MULTIPLY program from:
; http://6502.org/source/integers/fastx10.htm
@ -10,17 +12,18 @@ main LDA #7 ; load 7 into the accumulator
ASL ;again multiply by 2 (*8)
CLC
ADC TEMP ;as result, A = x*8 + x*2
; PRINT RESULT
STA $A0 ; 0x85, 0xA0, ; store A into the output addr
STA $A0 ; 0x85, 0xA0, ; store A into the console output address
LDX #0 ; 0xA2, 0x00, ; null terminator
STX $A1 ; 0x86, 0xA1, ; store null terminator to output addr + 1
; Set flag to do the print
LDX #1 ; 0xA2, 0x01,
STX $9F ; 0x86, 0x9F,
LDX #1 ; 0xA2, 0x01,
STX $9F ; 0x86, 0x9F, ; Print byte flag is at 0x9F
; End the program
RTS ; 0x60
; Variables
TEMP .byte 0

@ -581,7 +581,7 @@ impl Instructions
}
cpu.clear_flag(Flags::N);
if (cpu.x as u16 - cpu.working_data) & 0x80 > 0
if (cpu.x as i8 - cpu.working_data as i8) as u8 & 0x80 > 0
{
cpu.set_flag(Flags::N);
}
@ -596,7 +596,12 @@ impl Instructions
{
if cpu.check_flag(Flags::N) == 0
{
cpu.pc += cpu.working_data;
// The branch offset can be negative so we need to do some
// type juggling to make that work
let offset = cpu.working_data as i8; // allow the value to be negative
let offset_wide = offset as i16; // Expand to match the 2 byte pc while retaning the possible negative sign
let new_pc = cpu.pc as i16 + offset_wide; // Add the offset
cpu.pc = new_pc as u16; // Store the offset
}
}
@ -604,7 +609,10 @@ impl Instructions
{
if cpu.check_flag(Flags::N) != 0
{
cpu.pc += cpu.working_data;
let offset = cpu.working_data as i8;
let offset_wide = offset as i16;
let new_pc = cpu.pc as i16 + offset_wide;
cpu.pc = new_pc as u16;
}
}
@ -612,7 +620,10 @@ impl Instructions
{
if cpu.check_flag(Flags::V) == 0
{
cpu.pc += cpu.working_data;
let offset = cpu.working_data as i8;
let offset_wide = offset as i16;
let new_pc = cpu.pc as i16 + offset_wide;
cpu.pc = new_pc as u16;
}
}
@ -620,7 +631,10 @@ impl Instructions
{
if cpu.check_flag(Flags::V) != 0
{
cpu.pc += cpu.working_data;
let offset = cpu.working_data as i8;
let offset_wide = offset as i16;
let new_pc = cpu.pc as i16 + offset_wide;
cpu.pc = new_pc as u16;
}
}
@ -628,7 +642,10 @@ impl Instructions
{
if cpu.check_flag(Flags::C) == 0
{
cpu.pc += cpu.working_data;
let offset = cpu.working_data as i8;
let offset_wide = offset as i16;
let new_pc = cpu.pc as i16 + offset_wide;
cpu.pc = new_pc as u16;
}
}
@ -636,7 +653,10 @@ impl Instructions
{
if cpu.check_flag(Flags::C) != 0
{
cpu.pc += cpu.working_data;
let offset = cpu.working_data as i8;
let offset_wide = offset as i16;
let new_pc = cpu.pc as i16 + offset_wide;
cpu.pc = new_pc as u16;
}
}
@ -644,7 +664,10 @@ impl Instructions
{
if cpu.check_flag(Flags::Z) == 0
{
cpu.pc += cpu.working_data;
let offset = cpu.working_data as i8;
let offset_wide = offset as i16;
let new_pc = cpu.pc as i16 + offset_wide;
cpu.pc = new_pc as u16;
}
}
@ -652,7 +675,10 @@ impl Instructions
{
if cpu.check_flag(Flags::Z) != 0
{
cpu.pc += cpu.working_data;
let offset = cpu.working_data as i8;
let offset_wide = offset as i16;
let new_pc = cpu.pc as i16 + offset_wide;
cpu.pc = new_pc as u16;
}
}

@ -1,4 +1,9 @@
BUGS:
✔ Branch instructions seem to jump to the wrong place @done(24-01-22 19:08)
- looks like the offset should be able to be a negative value but it's not
General:
✔ Add unit tests for each instruction and address mode @done(23-11-07 19:57)
☐ Fully implement clock cycle tracking

Loading…
Cancel
Save