diff --git a/sim/verilog6502_32bit_test.py b/sim/verilog6502_32bit_test.py index 21d084d..375acca 100644 --- a/sim/verilog6502_32bit_test.py +++ b/sim/verilog6502_32bit_test.py @@ -401,5 +401,73 @@ async def test_indexed_indirect(dut): (0xabcdbef2, False, None), # store takes extra cycle (0xabcdbef2, True, 0xAB), # write data ] - - await check_instruction_sequence(dut, expected_cpu_outputs) \ No newline at end of file + + await check_instruction_sequence(dut, expected_cpu_outputs) + +@cocotb.test +async def test_indirect_indexed(dut): + cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start()) + cocotb.start_soon(handle_memory(dut)) + + write_dword(0xfffffff4, 0x200) + + + # ldx #4 + # lda ($04,x) + # inc + # ldx #8 + # sta ($04,x) + write_bytes(0x200, [0xa2, 0x04]) + write_bytes(0x202, [0xa1, 0x04]) + write_bytes(0x204, [0x1a]) + write_bytes(0x205, [0xa2, 0x08]) + write_bytes(0x207, [0x81, 0x04]) + write_byte(0x209, 0xcb) + + write_dword(0x08, 0xfeedf00d) + write_dword(0x0c, 0xf00d600d) + + write_byte(0xfeedf00d, 0x69) + + 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 #4 + (0x00000201, False, None), # Immediate + (0x00000202, False, None), # lda ($04,x) + (0x00000203, False, None), # ZP index + (0x00000004, False, None), # Compute ZP index + (0x00000008, False, None), # zp addr 0 + (0x00000009, False, None), # zp addr 1 + (0x0000000a, False, None), # zp addr 2 + (0x0000000b, False, None), # zp addr 3 + (0xfeedf00d, False, None), # fetch data + (0x00000204, False, None), # iny + (0x00000205, False, None), # iny + (0x00000205, False, None), # inc + (0x00000206, False, None), # inc + (0x00000207, False, None), # sta ($04),y + (0x00000208, False, None), # ZP index + (0x00000004, False, None), # Compute ZP index + (0x0000000c, False, None), # zp addr 0 + (0x0000000d, False, None), # zp addr 1 + (0x0000000e, False, None), # zp addr 2 + (0x0000000f, False, None), # zp addr 3 + (0xf00d600d, True, 0x6a), # write data + ] + + await check_instruction_sequence(dut, expected_cpu_outputs) diff --git a/src/cpu_65c02.v b/src/cpu_65c02.v index 76e8eef..91e64a5 100644 --- a/src/cpu_65c02.v +++ b/src/cpu_65c02.v @@ -226,7 +226,7 @@ parameter INDX0 = 7'd14, // (ZP,X) - fetch ZP address, and send to ALU (+X) INDX1 = 7'd15, // (ZP,X) - fetch LSB at ZP+X, calculate ZP+X+1 INDX2 = 7'd16, // (ZP,X) - fetch MSB at ZP+X+1 - INDX3 = 7'd17, // (ZP,X) - fetch data + INDX5 = 7'd17, // (ZP,X) - fetch data INDY0 = 7'd18, // (ZP),Y - fetch ZP address INDY1 = 7'd19, // (ZP),Y - fetch at ZP+1, and send byte 0 to ALU (+Y) INDY2 = 7'd20, // (ZP),Y - fetch at ZP+2, and send byte 1 to ALU (+Carry) @@ -277,7 +277,10 @@ parameter JMPI2 = 7'd65, // TODO JMPI3 = 7'd66, // TODO INDY3 = 7'd67, // (ZP),Y - fetch at ZP+3, and send byte 2 to ALU (+Carry) - INDY4 = 7'd68; // (ZP),Y - fetch data, and send byte 3 to ALU (+Carry) + INDY4 = 7'd68, // (ZP),Y - fetch data, and send byte 3 to ALU (+Carry) + INDX3 = 7'd69, // (ZP,X) - fetch addr 2 at ZP+X+2 + INDX4 = 7'd70; // (ZP,X) - fetch addr 3 at ZP+X+3 + `ifdef SIM @@ -307,6 +310,8 @@ always @* INDX1: statename = "INDX1"; INDX2: statename = "INDX2"; INDX3: statename = "INDX3"; + INDX4: statename = "INDX4"; + INDX5: statename = "INDX5"; INDY0: statename = "INDY0"; INDY1: statename = "INDY1"; INDY2: statename = "INDY2"; @@ -458,7 +463,7 @@ always @* case( state ) JMPIX3, ABSX3, - INDX3, + INDX5, JMP3, JMPI3, RTI4, @@ -489,10 +494,10 @@ always @* BRK4: AB = { 16'h0, STACKPAGE, ADD }; INDX1, - ZPX1, - INDX2: AB = { ZEROPAGE, ADD }; + ZPX1: AB = { ZEROPAGE, ADD }; ZP0, + INDX0, INDY0: AB = { ZEROPAGE, DIMUX }; REG, @@ -500,6 +505,9 @@ always @* INDY1, INDY2, INDY3, + INDX2, + INDX3, + INDX4, WRITE: AB = ABR; INDY4: AB = {DIMUX, ADD, alu_sr_0, alu_sr_1}; @@ -528,7 +536,10 @@ always @* begin case( state ) INDY0, INDY1, - INDY2: abr_inc = 1; + INDY2, + INDX1, + INDX2, + INDX3: abr_inc = 1; default: abr_inc = 0; endcase end @@ -578,7 +589,7 @@ always @* PUSH1, WRITE: WE = 1; - INDX3, // only if doing a STA, STX or STY + INDX5, // only if doing a STA, STX or STY INDY5, ABSX4, ABS3, @@ -786,8 +797,7 @@ always @* BRK1, BRK2, BRK3, - BRK4, - INDX1: AI = ADD; + BRK4: AI = ADD; REG, ZPX0, @@ -829,7 +839,6 @@ always @* RTI0, RTI1, RTI2, - INDX1, REG, JSR0, JSR1, @@ -882,8 +891,7 @@ always @* RTI2, RTS0, RTS1, - INDY0, - INDX1: CI = 1; + INDY0: CI = 1; default: CI = 0; endcase @@ -1105,7 +1113,9 @@ always @(posedge clk or posedge reset) INDX0 : state <= INDX1; INDX1 : state <= INDX2; INDX2 : state <= INDX3; - INDX3 : state <= FETCH; + INDX3 : state <= INDX4; + INDX4 : state <= INDX5; + INDX5 : state <= FETCH; INDY0 : state <= INDY1; INDY1 : state <= INDY2;