diff --git a/.vscode/launch.json b/.vscode/launch.json index 789af46..0e4cd72 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -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}" }, ] diff --git a/simple_test_machine/programs/hello.asm b/simple_test_machine/programs/hello.asm index 90d920f..f216c02 100644 --- a/simple_test_machine/programs/hello.asm +++ b/simple_test_machine/programs/hello.asm @@ -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 \ No newline at end of file + +; 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" \ No newline at end of file diff --git a/simple_test_machine/programs/mult10.asm b/simple_test_machine/programs/mult10.asm index 004ad15..0ae4a8b 100644 --- a/simple_test_machine/programs/mult10.asm +++ b/simple_test_machine/programs/mult10.asm @@ -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 diff --git a/src/r6502/instructions.rs b/src/r6502/instructions.rs index 6793b00..634db5c 100644 --- a/src/r6502/instructions.rs +++ b/src/r6502/instructions.rs @@ -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; } } diff --git a/todo/todo.todo b/todo/todo.todo index 5d6a13c..ba490c1 100644 --- a/todo/todo.todo +++ b/todo/todo.todo @@ -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