`define INSN_LD_reg_imm16 8'b00xx0001
`define INSN_LD_SP_HL 8'b11111001
`define INSN_PUSH_reg 8'b11xx0101
-`define INSN_POP_reg 8'b11xx0001
+`define INSN_POP_reg 8'b11xx0001
+`define INSN_LDH_AC 8'b111x0010 // Either LDH A,(C) or LDH (C),A
+`define INSN_LDx_AHL 8'b001xx010 // LDD/LDI A,(HL) / (HL),A
+
`define INSN_reg_A 3'b111
`define INSN_reg_B 3'b000
`define INSN_reg_C 3'b001
assign busdata = buswr ? buswdata : 8'bzzzzzzzz;
initial begin
- registers[ 0] = 0;
- registers[ 1] = 0;
- registers[ 2] = 0;
- registers[ 3] = 0;
- registers[ 4] = 0;
- registers[ 5] = 0;
- registers[ 6] = 0;
- registers[ 7] = 0;
- registers[ 8] = 0;
- registers[ 9] = 0;
- registers[10] = 0;
- registers[11] = 0;
+ registers[ 0] <= 0;
+ registers[ 1] <= 0;
+ registers[ 2] <= 0;
+ registers[ 3] <= 0;
+ registers[ 4] <= 0;
+ registers[ 5] <= 0;
+ registers[ 6] <= 0;
+ registers[ 7] <= 0;
+ registers[ 8] <= 0;
+ registers[ 9] <= 0;
+ registers[10] <= 0;
+ registers[11] <= 0;
end
always @(posedge clk)
end
endcase
end
+ `INSN_LDH_AC: begin
+ case (cycle)
+ 0: begin
+ address <= {8'hFF,registers[`REG_C]};
+ if (opcode[4]) begin // LD A,(C)
+ rd <= 1;
+ end else begin
+ wr <= 1;
+ wdata <= registers[`REG_A];
+ end
+ end
+ 1: begin
+ `EXEC_NEWCYCLE;
+ `EXEC_INC_PC;
+ end
+ endcase
+ end
+ `INSN_LDx_AHL: begin
+ case (cycle)
+ 0: begin
+ address <= {registers[`REG_H],registers[`REG_L]};
+ if (opcode[3]) begin // LDx A, (HL)
+ rd <= 1;
+ end else begin
+ wr <= 1;
+ wdata <= registers[`REG_A];
+ end
+ end
+ 1: begin
+ `EXEC_NEWCYCLE;
+ `EXEC_INC_PC;
+ end
+ endcase
+ end
default:
$stop;
endcase
`INSN_PUSH_reg: begin /* PUSH is 16 cycles! */
case (cycle)
0: begin
- {registers[`REG_SPH],registers[`REG_SPL]} =
+ {registers[`REG_SPH],registers[`REG_SPL]} <=
{registers[`REG_SPH],registers[`REG_SPL]} - 1;
cycle <= 1;
end
1: begin
- {registers[`REG_SPH],registers[`REG_SPL]} =
+ {registers[`REG_SPH],registers[`REG_SPL]} <=
{registers[`REG_SPH],registers[`REG_SPL]} - 1;
cycle <= 2;
end
case (cycle)
0: begin
cycle <= 1;
- {registers[`REG_SPH],registers[`REG_SPL]} =
+ {registers[`REG_SPH],registers[`REG_SPL]} <=
{registers[`REG_SPH],registers[`REG_SPL]} + 1;
end
1: begin
`INSN_stack_DE: registers[`REG_E] <= rdata;
`INSN_stack_HL: registers[`REG_L] <= rdata;
endcase
- {registers[`REG_SPH],registers[`REG_SPL]} =
+ {registers[`REG_SPH],registers[`REG_SPL]} <=
{registers[`REG_SPH],registers[`REG_SPL]} + 1;
cycle <= 2;
end
cycle <= 0;
end
endcase
- end
+ end
+ `INSN_LDH_AC: begin
+ case (cycle)
+ 0: cycle <= 1;
+ 1: begin
+ cycle <= 0;
+ if (opcode[4])
+ registers[`REG_A] <= rdata;
+ end
+ endcase
+ end
+ `INSN_LDx_AHL: begin
+ case (cycle)
+ 0: cycle <= 1;
+ 1: begin
+ cycle <= 0;
+ if (opcode[3])
+ registers[`REG_A] <= rdata;
+ {registers[`REG_H],registers[`REG_L]} <=
+ opcode[4] ? // if set, LDD, else LDI
+ ({registers[`REG_H],registers[`REG_L]} - 1) :
+ ({registers[`REG_H],registers[`REG_L]} + 1);
+ end
+ endcase
+ end
endcase
state <= `STATE_FETCH;
end