+ `INSN_ALU_A: begin
+ case(opcode[5:3])
+ `INSN_alu_RLCA: begin
+ registers[`REG_A] <= {registers[`REG_A][6:0],registers[`REG_A][7]};
+ registers[`REG_F] <= {registers[`REG_F][7:5],registers[`REG_A][7],registers[`REG_F][3:0]};
+ end
+ `INSN_alu_RRCA: begin
+ registers[`REG_A] <= {registers[`REG_A][0],registers[`REG_A][7:1]};
+ registers[`REG_F] <= {registers[`REG_F][7:5],registers[`REG_A][0],registers[`REG_F][3:0]};
+ end
+ `INSN_alu_RLA: begin
+ registers[`REG_A] <= {registers[`REG_A][6:0],registers[`REG_F][4]};
+ registers[`REG_F] <= {registers[`REG_F][7:5],registers[`REG_A][7],registers[`REG_F][3:0]};
+ end
+ `INSN_alu_RRA: begin
+ registers[`REG_A] <= {registers[`REG_A][4],registers[`REG_A][7:1]};
+ registers[`REG_F] <= {registers[`REG_F][7:5],registers[`REG_A][0],registers[`REG_F][3:0]};
+ end
+ `INSN_alu_CPL: begin
+ registers[`REG_A] <= ~registers[`REG_A];
+ registers[`REG_F] <= {registers[`REG_F][7],1'b1,1'b1,registers[`REG_F][4:0]};
+ end
+ `INSN_alu_SCF: begin
+ registers[`REG_F] <= {registers[`REG_F][7:5],1'b1,registers[`REG_F][3:0]};
+ end
+ `INSN_alu_CCF: begin
+ registers[`REG_F] <= {registers[`REG_F][7:5],~registers[`REG_F][4],registers[`REG_F][3:0]};
+ end
+ endcase
+ end
+ `INSN_NOP: begin /* NOP! */ end
+ `INSN_RST: begin
+ case (cycle)
+ 0: begin /* type F */ end
+ 1: begin /* type F */ end
+ 2: begin /* type F */ end
+ 3: {registers[`REG_SPH],registers[`REG_SPL]} <=
+ {registers[`REG_SPH],registers[`REG_SPL]}-2;
+ endcase
+ end
+ `INSN_RET,`INSN_RETCC: begin
+ case (cycle)
+ 0: if (opcode[0]) // i.e., not RETCC
+ cycle <= 1; // Skip cycle 1; it gets incremented on the next round.
+ 1: begin /* Nothing need happen here. */ end
+ 2: registers[`REG_PCL] <= rdata;
+ 3: registers[`REG_PCH] <= rdata;
+ 4: begin
+ {registers[`REG_SPH],registers[`REG_SPL]} <=
+ {registers[`REG_SPH],registers[`REG_SPL]} + 2;
+ if (opcode[4] && opcode[0]) /* RETI */
+ ie <= 1;
+ end
+ endcase
+ end
+ `INSN_CALL,`INSN_CALLCC: begin
+ case (cycle)
+ 0: begin /* type F */ end
+ 1: tmp <= rdata; // tmp contains newpcl
+ 2: tmp2 <= rdata; // tmp2 contains newpch
+ 3: begin /* type F */ end
+ 4: registers[`REG_PCH] <= tmp2;
+ 5: begin
+ {registers[`REG_SPH],registers[`REG_SPL]} <=
+ {registers[`REG_SPH],registers[`REG_SPL]} - 2;
+ registers[`REG_PCL] <= tmp;
+ end
+ endcase
+ end
+ `INSN_JP_imm,`INSN_JPCC_imm: begin
+ case (cycle)
+ 0: begin /* type F */ end
+ 1: tmp <= rdata; // tmp contains newpcl
+ 2: tmp2 <= rdata; // tmp2 contains newpch
+ 3: {registers[`REG_PCH],registers[`REG_PCL]} <=
+ {tmp2,tmp};
+ endcase
+ end
+ `INSN_JP_HL: begin
+ {registers[`REG_PCH],registers[`REG_PCL]} <=
+ {registers[`REG_H],registers[`REG_L]};
+ end
+ `INSN_JR_imm,`INSN_JRCC_imm: begin
+ case (cycle)
+ 0: begin /* type F */ end
+ 1: tmp <= rdata;
+ 2: {registers[`REG_PCH],registers[`REG_PCL]} <=
+ {registers[`REG_PCH],registers[`REG_PCL]} +
+ {tmp[7]?8'hFF:8'h00,tmp};
+ endcase
+ end
+ `INSN_INCDEC16: begin
+ case (cycle)
+ 0: {tmp,tmp2} <= {tmp,tmp2} +
+ (opcode[3] ? 16'hFFFF : 16'h0001);
+ 1: begin
+ case (opcode[5:4])
+ `INSN_reg16_BC: begin
+ registers[`REG_B] <= tmp;
+ registers[`REG_C] <= tmp2;
+ end
+ `INSN_reg16_DE: begin
+ registers[`REG_D] <= tmp;
+ registers[`REG_E] <= tmp2;
+ end
+ `INSN_reg16_HL: begin
+ registers[`REG_H] <= tmp;
+ registers[`REG_L] <= tmp2;
+ end
+ `INSN_reg16_SP: begin
+ registers[`REG_SPH] <= tmp;
+ registers[`REG_SPL] <= tmp2;
+ end
+ endcase
+ end
+ endcase
+ end
+ `INSN_VOP_INTR: begin
+ case (cycle)
+ 0: begin end
+ 1: begin end
+ 2: begin
+ ie <= 0;
+ {registers[`REG_PCH],registers[`REG_PCL]} <=
+ {8'b0,jaddr};
+ {registers[`REG_SPH],registers[`REG_SPL]} <=
+ {registers[`REG_SPH],registers[`REG_SPL]} - 2;
+ end
+ endcase
+ end
+ `INSN_DI: ie <= 0;
+ `INSN_EI: iedelay <= 1;
+ default:
+ $stop;