Add indexed indirect
This commit is contained in:
@@ -339,3 +339,67 @@ async def test_indirect(dut):
|
||||
]
|
||||
|
||||
await check_instruction_sequence(dut, expected_cpu_outputs)
|
||||
|
||||
@cocotb.test
|
||||
async def test_indexed_indirect(dut):
|
||||
cocotb.start_soon(Clock(dut.clk, CLK_PERIOD, unit="ns").start())
|
||||
cocotb.start_soon(handle_memory(dut))
|
||||
|
||||
write_dword(0xfffffff4, 0x200)
|
||||
|
||||
# ldy #1
|
||||
# lda ($04),y
|
||||
# iny
|
||||
# inc
|
||||
# sta ($04),y
|
||||
write_bytes(0x200, [0xa0, 0x02])
|
||||
write_bytes(0x202, [0xb1, 0x04])
|
||||
write_bytes(0x204, [0xc8])
|
||||
write_bytes(0x205, [0x1a])
|
||||
write_bytes(0x206, [0x91, 0x04])
|
||||
write_byte(0x208, 0xcb)
|
||||
|
||||
write_dword(0x04, 0xabcdbeef)
|
||||
write_dword(0xabcdbeef+2, 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), # ldy #0
|
||||
(0x00000201, False, None), # Immediate
|
||||
(0x00000202, False, None), # lda ($04),y
|
||||
(0x00000203, False, None), # ZP index
|
||||
(0x00000004, False, None), # zp addr 0
|
||||
(0x00000005, False, None), # zp addr 1
|
||||
(0x00000006, False, None), # zp addr 2
|
||||
(0x00000007, False, None), # zp addr 3
|
||||
(0xabcdbef1, False, None), # fetch data
|
||||
(0x00000204, False, None), # iny
|
||||
(0x00000205, False, None), # iny
|
||||
(0x00000205, False, None), # inc
|
||||
(0x00000206, False, None), # inc
|
||||
(0x00000206, False, None), # sta ($04),y
|
||||
(0x00000207, False, None), # ZP index
|
||||
(0x00000004, False, None), # zp addr 0
|
||||
(0x00000005, False, None), # zp addr 1
|
||||
(0x00000006, False, None), # zp addr 2
|
||||
(0x00000007, False, None), # zp addr 3
|
||||
(0xabcdbef2, False, None), # store takes extra cycle
|
||||
(0xabcdbef2, True, 0xAB), # write data
|
||||
]
|
||||
|
||||
await check_instruction_sequence(dut, expected_cpu_outputs)
|
||||
@@ -67,6 +67,7 @@ output reg SYNC; // AB is first cycle of the intruction
|
||||
*/
|
||||
|
||||
reg [31:0] PC; // Program Counter
|
||||
reg abr_inc; // should increase address bus register
|
||||
reg [31:0] ABR; // Address Bus Register
|
||||
wire [7:0] ADD; // Adder Hold Register (registered in ALU)
|
||||
reg [7:0] alu_sr_0; // ALU output shift register 0
|
||||
@@ -226,10 +227,10 @@ parameter
|
||||
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
|
||||
INDY0 = 7'd18, // (ZP),Y - fetch ZP address, and send ZP to ALU (+1)
|
||||
INDY1 = 7'd19, // (ZP),Y - fetch at ZP+1, and send LSB to ALU (+Y)
|
||||
INDY2 = 7'd20, // (ZP),Y - fetch data, and send MSB to ALU (+Carry)
|
||||
INDY3 = 7'd21, // (ZP),Y) - fetch data (if page boundary crossed)
|
||||
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)
|
||||
INDY5 = 7'd21, // (ZP),Y) - fetch data (if page boundary crossed)
|
||||
JMP0 = 7'd22, // JMP - fetch PCL and hold
|
||||
JMP1 = 7'd23, // JMP - fetch PCH
|
||||
JMPI0 = 7'd24, // JMP IND - fetch LSB and send to ALU for delay (+0)
|
||||
@@ -274,7 +275,9 @@ parameter
|
||||
JMPIX3 = 7'd63, // TODO
|
||||
JMPIX4 = 7'd64, // TODO
|
||||
JMPI2 = 7'd65, // TODO
|
||||
JMPI3 = 7'd66; // 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)
|
||||
|
||||
`ifdef SIM
|
||||
|
||||
@@ -308,6 +311,8 @@ always @*
|
||||
INDY1: statename = "INDY1";
|
||||
INDY2: statename = "INDY2";
|
||||
INDY3: statename = "INDY3";
|
||||
INDY4: statename = "INDY4";
|
||||
INDY5: statename = "INDY5";
|
||||
READ: statename = "READ";
|
||||
WRITE: statename = "WRITE";
|
||||
FETCH: statename = "FETCH";
|
||||
@@ -454,14 +459,12 @@ always @*
|
||||
JMPIX3,
|
||||
ABSX3,
|
||||
INDX3,
|
||||
INDY2,
|
||||
JMP3,
|
||||
JMPI3,
|
||||
RTI4,
|
||||
ABS3: AB = { DIMUX, ADD, alu_sr_0, alu_sr_1};
|
||||
|
||||
BRA2,
|
||||
INDY3,
|
||||
JMPIX4,
|
||||
ABSX4: AB = { ADD, ABR[23:0] }; // TODO
|
||||
|
||||
@@ -485,7 +488,6 @@ always @*
|
||||
BRK3,
|
||||
BRK4: AB = { 16'h0, STACKPAGE, ADD };
|
||||
|
||||
INDY1,
|
||||
INDX1,
|
||||
ZPX1,
|
||||
INDX2: AB = { ZEROPAGE, ADD };
|
||||
@@ -495,8 +497,14 @@ always @*
|
||||
|
||||
REG,
|
||||
READ,
|
||||
INDY1,
|
||||
INDY2,
|
||||
INDY3,
|
||||
WRITE: AB = ABR;
|
||||
|
||||
INDY4: AB = {DIMUX, ADD, alu_sr_0, alu_sr_1};
|
||||
INDY5: AB = {ADD, ABR[23:0]};
|
||||
|
||||
default: AB = PC;
|
||||
endcase
|
||||
|
||||
@@ -509,9 +517,22 @@ always @(posedge clk)
|
||||
if( state != PUSH0 && state != PUSH1 && RDY &&
|
||||
state != PULL0 && state != PULL1 && state != PULL2 )
|
||||
begin
|
||||
ABR <= AB;
|
||||
if (abr_inc) begin
|
||||
ABR <= AB + 1;
|
||||
end else begin
|
||||
ABR <= AB;
|
||||
end
|
||||
end
|
||||
|
||||
always @* begin
|
||||
case( state )
|
||||
INDY0,
|
||||
INDY1,
|
||||
INDY2: abr_inc = 1;
|
||||
default: abr_inc = 0;
|
||||
endcase
|
||||
end
|
||||
|
||||
/*
|
||||
* Data Out MUX
|
||||
*/
|
||||
@@ -558,7 +579,7 @@ always @*
|
||||
WRITE: WE = 1;
|
||||
|
||||
INDX3, // only if doing a STA, STX or STY
|
||||
INDY3,
|
||||
INDY5,
|
||||
ABSX4,
|
||||
ABS3,
|
||||
ZPX1,
|
||||
@@ -1088,8 +1109,10 @@ always @(posedge clk or posedge reset)
|
||||
|
||||
INDY0 : state <= INDY1;
|
||||
INDY1 : state <= INDY2;
|
||||
INDY2 : state <= (CO | store) ? INDY3 : FETCH;
|
||||
INDY3 : state <= FETCH;
|
||||
INDY2 : state <= INDY3;
|
||||
INDY3 : state <= INDY4;
|
||||
INDY4 : state <= (CO | store) ? INDY5 : FETCH;
|
||||
INDY5 : state <= FETCH;
|
||||
|
||||
READ : state <= WRITE;
|
||||
WRITE : state <= FETCH;
|
||||
|
||||
Reference in New Issue
Block a user