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

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

@ -1,5 +1,7 @@
; Multiply 7 with 10 and print the result ; 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: ; FAST MULTIPLY program from:
; http://6502.org/source/integers/fastx10.htm ; 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) ASL ;again multiply by 2 (*8)
CLC CLC
ADC TEMP ;as result, A = x*8 + x*2 ADC TEMP ;as result, A = x*8 + x*2
; PRINT RESULT ; 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 LDX #0 ; 0xA2, 0x00, ; null terminator
STX $A1 ; 0x86, 0xA1, ; store null terminator to output addr + 1 STX $A1 ; 0x86, 0xA1, ; store null terminator to output addr + 1
; Set flag to do the print ; Set flag to do the print
LDX #1 ; 0xA2, 0x01, LDX #1 ; 0xA2, 0x01,
STX $9F ; 0x86, 0x9F, STX $9F ; 0x86, 0x9F, ; Print byte flag is at 0x9F
; End the program ; End the program
RTS ; 0x60 RTS ; 0x60
; Variables
TEMP .byte 0 TEMP .byte 0

@ -581,7 +581,7 @@ impl Instructions
} }
cpu.clear_flag(Flags::N); 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); cpu.set_flag(Flags::N);
} }
@ -596,7 +596,12 @@ impl Instructions
{ {
if cpu.check_flag(Flags::N) == 0 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 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 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 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 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 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 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 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: General:
✔ Add unit tests for each instruction and address mode @done(23-11-07 19:57) ✔ Add unit tests for each instruction and address mode @done(23-11-07 19:57)
☐ Fully implement clock cycle tracking ☐ Fully implement clock cycle tracking

Loading…
Cancel
Save