diff --git a/sim/verilog6502_32bit_test.py b/sim/verilog6502_32bit_test.py index ace9288..da4740e 100644 --- a/sim/verilog6502_32bit_test.py +++ b/sim/verilog6502_32bit_test.py @@ -81,7 +81,8 @@ async def test_absolute(dut): write_dword(0xfffffff4, 0x200) - # lda #$abcd1234 + # lda $abcd1234 + # sta $50515253 # wai write_bytes(0x200, [0xad, 0x34, 0x12, 0xcd, 0xab]) write_bytes(0x205, [0x8d, 0x53, 0x52, 0x51, 0x50]) @@ -117,7 +118,77 @@ async def test_absolute(dut): (0x00000208, False, None), # Read address byte 2 (0x00000209, False, None), # Read address byte 3 (0x50515253, True, 0x55), # Write to absolute address - + ] + + for expected_output in expected_cpu_outputs: + await RisingEdge(dut.clk) + + if expected_output: + expected_addr, expected_we, expected_do = expected_output + dut_addr = int(dut.AB.value) + dut_we = bool(dut.WE.value) + dut_do = int(dut.DO.value) + + assert dut_addr == expected_addr + assert dut_we == expected_we + + if dut_we: + assert dut_do == expected_do + +@cocotb.test +async def test_absolute_x(dut): + cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start()) + cocotb.start_soon(handle_memory(dut)) + + write_dword(0xfffffff4, 0x200) + + # ldx #1 + # lda $abcd1234,x + # inx + # sta $01020304,x + # wai + write_bytes(0x200, [0xa2, 0x01]) + write_bytes(0x202, [0xbd, 0x34, 0x12, 0xcd, 0xab]) + write_bytes(0x207, [0xe8]) + write_bytes(0x208, [0x9d, 0x04, 0x03, 0x02, 0x01]) + + write_byte(0x20d, 0xcb) + write_byte(0xabcd1235, 0xaa) + + 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 #1 + (0x00000201, False, None), # Immediate + (0x00000202, False, None), # ldx $abcd1234,x + (0x00000203, False, None), # addr 0 + (0x00000204, False, None), # addr 1 + (0x00000205, False, None), # addr 2 + (0x00000206, False, None), # addr 3 + (0xabcd1235, False, None), # Read from address + (0x00000207, False, None), # inx + (0x00000208, False, None), # sta $01020304,x + (0x00000208, False, None), # store reg + (0x00000209, False, None), # addr 0 + (0x0000020a, False, None), # addr 1 + (0x0000020b, False, None), # addr 2 + (0x0000020c, False, None), # addr 3 + (0x01020306, False, None), # Write to address + (0x01020306, True, 0xaa), # Write to address ] for expected_output in expected_cpu_outputs: diff --git a/src/cpu_65c02.v b/src/cpu_65c02.v index 21cfa3b..e05ced5 100644 --- a/src/cpu_65c02.v +++ b/src/cpu_65c02.v @@ -268,7 +268,9 @@ parameter JMP2 = 6'd57, // TODO JMP3 = 6'd58, // TODO ABS2 = 6'd59, // TODO - ABS3 = 6'd60; // TODO + ABS3 = 6'd60, // TODO + ABSX3 = 6'd61, // TODO + ABSX4 = 6'd62; // TODO `ifdef SIM @@ -291,6 +293,8 @@ always @* ABSX0: statename = "ABSX0"; ABSX1: statename = "ABSX1"; ABSX2: statename = "ABSX2"; + ABSX3: statename = "ABSX3"; + ABSX4: statename = "ABSX4"; IND0: statename = "IND0"; INDX0: statename = "INDX0"; INDX1: statename = "INDX1"; @@ -396,6 +400,8 @@ always @* JMPIX0, JMPIX2, ABSX0, + ABSX1, + ABSX2, FETCH, BRA0, BRA2, @@ -433,7 +439,7 @@ parameter always @* case( state ) JMPIX1, - ABSX1, + ABSX3, INDX3, INDY2, JMP3, @@ -444,7 +450,7 @@ always @* BRA2, INDY3, JMPIX2, - ABSX2: AB = { ADD, ABR[7:0] }; // TODO + ABSX4: AB = { ADD, ABR[23:0] }; // TODO BRA1: AB = { ABR[15:8], ADD }; // TODO @@ -540,7 +546,7 @@ always @* INDX3, // only if doing a STA, STX or STY INDY3, - ABSX2, + ABSX4, ABS3, ZPX1, ZP0: WE = store; @@ -821,7 +827,9 @@ always @* INDY2, BRA1, JMPIX1, - ABSX1: CI = CO; + ABSX1, + ABSX2, + ABSX3: CI = CO; DECODE, ABS3: CI = 1'bx; @@ -1047,8 +1055,10 @@ always @(posedge clk or posedge reset) ABS3 : state <= write_back ? READ : FETCH; ABSX0 : state <= ABSX1; - ABSX1 : state <= (CO | store | write_back) ? ABSX2 : FETCH; - ABSX2 : state <= write_back ? READ : FETCH; + ABSX1 : state <= ABSX2; + ABSX2 : state <= ABSX3; + ABSX3 : state <= (CO | store | write_back) ? ABSX4 : FETCH; + ABSX4 : state <= write_back ? READ : FETCH; JMPIX0 : state <= JMPIX1; JMPIX1 : state <= CO ? JMPIX2 : JMP0;