diff --git a/sim/verilog6502_32bit_test.py b/sim/verilog6502_32bit_test.py index fd9ad00..66859bf 100644 --- a/sim/verilog6502_32bit_test.py +++ b/sim/verilog6502_32bit_test.py @@ -539,7 +539,73 @@ async def test_jsr(dut): await check_instruction_sequence(dut, expected_cpu_outputs) -# @cocotb.test +@cocotb.test +async def test_rti(dut): + cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start()) + cocotb.start_soon(handle_memory(dut)) + + write_dword(0xfffffff4, 0x200) + write_dword(0xfffffffc, 0x300) + + + # @0x200 + # ldx #$ff + # txs + # brk + # wai + # @0x300 + # rti + + write_bytes(0x200, [0xa2, 0xff, 0x9a, 0x00, 0x00, 0xcb]) # BRK is technically a 2 byte instruction + write_bytes(0x300, [0x40]) + + 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), # ldx #$ff + (0x00000201, False, None), # immediate + (0x00000202, False, None), # txs + (0x00000203, False, None), # txs + (0x00000203, False, None), # brk + (0x00000204, False, None), # brk + (0x000001ff, True, 0x00), # brk 31-24 + (0x000001fe, True, 0x00), # brk 13-16 + (0x000001fd, True, 0x02), # brk 15-08 + (0x000001fc, True, 0x05), # brk 07-00 + (0x000001fb, True, 0xb4), # brk flags + (0xfffffffc, False, None), # vector + (0xfffffffd, False, None), # vector + (0xfffffffe, False, None), # vector + (0xffffffff, False, None), # vector + (0x00000300, False, None), # rti + (0x00000301, False, None), # rti + (0x000001fa, False, None), # rti + (0x000001fb, False, None), # rti + (0x000001fc, False, None), # rti + (0x000001fd, False, None), # rti + (0x000001fe, False, None), # rti + (0x000001ff, False, None), # rti + (0x00000205, False, None), # wai + ] + + await check_instruction_sequence(dut, expected_cpu_outputs) + + +@cocotb.test async def test_adc(dut): cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start()) cocotb.start_soon(handle_memory(dut)) diff --git a/src/cpu_65c02.v b/src/cpu_65c02.v index cdb2eb0..e371654 100644 --- a/src/cpu_65c02.v +++ b/src/cpu_65c02.v @@ -257,7 +257,7 @@ parameter RTI1 = 7'd38, // RTI - read P from stack RTI2 = 7'd39, // RTI - read PCL from stack RTI3 = 7'd40, // RTI - read PCH from stack - RTI4 = 7'd41, // RTI - read PCH from stack + RTI6 = 7'd41, // RTI - read PCH from stack RTS0 = 7'd42, // RTS - send S to ALU (+1) RTS1 = 7'd43, // RTS - read PCL from stack RTS2 = 7'd44, // RTS - write PCL to ALU, read PCH @@ -292,7 +292,9 @@ parameter JSR6 = 7'd74, JSR7 = 7'd75, RTS3 = 7'd76, - RTS4 = 7'd77; + RTS4 = 7'd77, + RTI4 = 7'd78, + RTI5 = 7'd79; `ifdef SIM @@ -352,6 +354,8 @@ always @* RTI2: statename = "RTI2"; RTI3: statename = "RTI3"; RTI4: statename = "RTI4"; + RTI5: statename = "RTI5"; + RTI6: statename = "RTI6"; RTS0: statename = "RTS0"; RTS1: statename = "RTS1"; RTS2: statename = "RTS2"; @@ -406,10 +410,10 @@ always @* JMP3, JMPI3, JMPIX3, - JSR7: PC_temp = { DIMUX, ADD, alu_sr_0, alu_sr_1}; + JSR7, + RTI6: PC_temp = { DIMUX, ADD, alu_sr_0, alu_sr_1}; - RTS5, - RTI4: PC_temp = { DIMUX, ADD, alu_sr_0, alu_sr_1} + 2; + RTS5: PC_temp = { DIMUX, ADD, alu_sr_0, alu_sr_1} + 2; BRA1: PC_temp = { ABR[15:8], ADD }; @@ -459,7 +463,7 @@ always @* JSR4, JSR5, JSR6, - RTI4, + RTI6, RTS3, RTS4, RTS5: PC_inc = 1; @@ -493,7 +497,7 @@ always @* INDX5, JMP3, JMPI3, - RTI4, + RTI6, ABS3: AB = { DIMUX, ADD, alu_sr_0, alu_sr_1}; BRA2, @@ -520,6 +524,8 @@ always @* RTI1, RTI2, RTI3, + RTI4, + RTI5, BRK2, BRK3, BRK4: AB = { 16'h0, STACKPAGE, ADD }; @@ -644,7 +650,7 @@ always @* PULL1, RTS4, - RTI3, + RTI5, BRK5, JSR0, JSR4 : write_register = 1; @@ -740,7 +746,7 @@ always @* PULL1, PUSH1, RTI0, - RTI3, + RTI5, RTS0, RTS4 : regsel = SEL_S; @@ -780,7 +786,9 @@ end always @* begin case ( state ) RTS2, - RTS3: sr_sel = SR_DI; + RTS3, + RTI3, + RTI4: sr_sel = SR_DI; default: sr_sel = SR_ALU; endcase @@ -788,7 +796,8 @@ end always @*begin case ( state) - RTS4: alu_sr_enable = 0; + RTS4, + RTI5: alu_sr_enable = 0; default: alu_sr_enable = 1; endcase end @@ -855,6 +864,8 @@ always @* RTS3, RTI1, RTI2, + RTI3, + RTI4, BRK1, BRK2, BRK3, @@ -904,6 +915,8 @@ always @* RTI0, RTI1, RTI2, + RTI3, + RTI4, REG, JSR0, JSR1, @@ -913,6 +926,8 @@ always @* BRK0, BRK1, BRK2, + BRK3, + BRK4, PUSH0, PUSH1, PULL0, @@ -956,6 +971,8 @@ always @* RTI0, RTI1, RTI2, + RTI3, + RTI4, RTS0, RTS1, RTS2, @@ -1219,7 +1236,9 @@ always @(posedge clk or posedge reset) RTI1 : state <= RTI2; RTI2 : state <= RTI3; RTI3 : state <= RTI4; - RTI4 : state <= DECODE; + RTI4 : state <= RTI5; + RTI5 : state <= RTI6; + RTI6 : state <= DECODE; RTS0 : state <= RTS1; RTS1 : state <= RTS2; @@ -1268,7 +1287,7 @@ always @(posedge clk or posedge reset) REG, PUSH1, PULL2, - RTI4, + RTI6, JMP3, BRA2 : SYNC <= 1'b1; default: SYNC <= 1'b0;