From b31d7490b2d318d742cdd20a44003655cc565613 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Sun, 26 Apr 2026 22:13:42 -0700 Subject: [PATCH] Add indirect jump --- sim/verilog6502_32bit_test.py | 53 ++++++++++++++++++++++++++++++++--- src/cpu_65c02.v | 19 +++++++++---- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/sim/verilog6502_32bit_test.py b/sim/verilog6502_32bit_test.py index 02332cd..575c7df 100644 --- a/sim/verilog6502_32bit_test.py +++ b/sim/verilog6502_32bit_test.py @@ -287,10 +287,55 @@ async def test_absolute_x_indirect(dut): (0x00000205, False, None), # addr 2 (0x00000206, False, None), # addr 3 (0xdeadbef0, False, None), # addr 0 - (0xdeadbef1, False, None), # addr 0 - (0xdeadbef2, False, None), # addr 0 - (0xdeadbef3, False, None), # addr 0 - (0xbeefb055, False, None), # + (0xdeadbef1, False, None), # addr 1 + (0xdeadbef2, False, None), # addr 2 + (0xdeadbef3, False, None), # addr 3 + (0xbeefb055, False, None), # target + ] + + await check_instruction_sequence(dut, expected_cpu_outputs) + + +@cocotb.test +async def test_indirect(dut): + cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start()) + cocotb.start_soon(handle_memory(dut)) + + write_dword(0xfffffff4, 0x200) + + # jmp ($deadbeef) + write_bytes(0x200, [0x6c, 0xef, 0xbe, 0xad, 0xde]) + write_byte(0xbeefb055, 0xcb) + + write_dword(0xdeadbeef, 0xbeefb055) + + dut.RDY.value = Immediate(1) + + dut.reset.value = Immediate(1) + for _ in range(10): + await RisingEdge(dut.clk) + dut.reset.value = 0 + + expected_cpu_outputs = [ + None, # ignore reset sequence + None, + None, + None, + None, + None, + None, + None, + None, + (0x00000200, False, None), # jmp ($deadbeef) + (0x00000201, False, None), # addr 0 + (0x00000202, False, None), # addr 1 + (0x00000203, False, None), # addr 2 + (0x00000204, False, None), # addr 3 + (0xdeadbeef, False, None), # addr 0 + (0xdeadbef0, False, None), # addr 1 + (0xdeadbef1, False, None), # addr 2 + (0xdeadbef2, False, None), # addr 3 + (0xbeefb055, False, None), # target ] await check_instruction_sequence(dut, expected_cpu_outputs) diff --git a/src/cpu_65c02.v b/src/cpu_65c02.v index a1a890c..de8b6bd 100644 --- a/src/cpu_65c02.v +++ b/src/cpu_65c02.v @@ -134,7 +134,7 @@ wire [7:0] P = { N, V, 2'b11, D, I, Z, C }; * instruction decoder/sequencer */ -reg [5:0] state; +reg [6:0] state; /* * control signals @@ -272,7 +272,9 @@ parameter ABSX3 = 7'd61, // TODO ABSX4 = 7'd62, // TODO JMPIX3 = 7'd63, // TODO - JMPIX4 = 7'd64; // TODO + JMPIX4 = 7'd64, // TODO + JMPI2 = 7'd65, // TODO + JMPI3 = 7'd66; // TODO `ifdef SIM @@ -342,6 +344,8 @@ always @* JMP3: statename = "JMP3"; JMPI0: statename = "JMPI0"; JMPI1: statename = "JMPI1"; + JMPI2: statename = "JMPI2"; + JMPI3: statename = "JMPI3"; JMPIX0: statename = "JMPIX0"; JMPIX1: statename = "JMPIX1"; JMPIX2: statename = "JMPIX2"; @@ -371,7 +375,7 @@ always @* JMP3, - JMPI1, + JMPI3, JMPIX3, JSR3, RTS3, @@ -412,7 +416,10 @@ always @* BRA0, BRA2, BRK5, + JMPI0, JMPI1, + JMPI2, + JMPI3, JMP0, JMP1, JMP2, @@ -449,7 +456,7 @@ always @* INDX3, INDY2, JMP3, - JMPI1, + JMPI3, RTI4, ABS3: AB = { DIMUX, ADD, alu_sr_0, alu_sr_1}; @@ -1123,7 +1130,9 @@ always @(posedge clk or posedge reset) JMP3 : state <= DECODE; JMPI0 : state <= JMPI1; - JMPI1 : state <= JMP0; + JMPI1 : state <= JMPI2; + JMPI2 : state <= JMPI3; + JMPI3 : state <= JMP0; BRK0 : state <= BRK1; BRK1 : state <= BRK2;