From: Joshua Wise Date: Sun, 6 Apr 2008 07:03:30 +0000 (-0400) Subject: Split out more insns X-Git-Url: http://git.joshuawise.com/fpgaboy.git/commitdiff_plain/3ad960bdb71efcbb1dfd436163085da0d70eb699 Split out more insns --- diff --git a/GBZ80Core.v b/GBZ80Core.v index d556cd5..f41805a 100644 --- a/GBZ80Core.v +++ b/GBZ80Core.v @@ -194,68 +194,6 @@ module GBZ80Core( `define EXECUTE `include "allinsns.v" `undef EXECUTE - `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 - `INSN_ALU8: begin - if ((opcode[2:0] == `INSN_reg_dHL) && (cycle == 0)) begin - // fffffffff fuck your shit, read from (HL) :( - rd <= 1; - address <= {registers[`REG_H], registers[`REG_L]}; - end else begin - `EXEC_NEWCYCLE; - `EXEC_INC_PC; - case (opcode[2:0]) - `INSN_reg_A: tmp <= registers[`REG_A]; - `INSN_reg_B: tmp <= registers[`REG_B]; - `INSN_reg_C: tmp <= registers[`REG_C]; - `INSN_reg_D: tmp <= registers[`REG_D]; - `INSN_reg_E: tmp <= registers[`REG_E]; - `INSN_reg_H: tmp <= registers[`REG_H]; - `INSN_reg_L: tmp <= registers[`REG_L]; - `INSN_reg_dHL: tmp <= rdata; - endcase - end - end - `INSN_ALU_A: begin - `EXEC_NEWCYCLE; - `EXEC_INC_PC; - end - `INSN_NOP: begin - `EXEC_NEWCYCLE; - `EXEC_INC_PC; - end `INSN_RST: begin case (cycle) 0: begin @@ -463,147 +401,6 @@ module GBZ80Core( `define WRITEBACK `include "allinsns.v" `undef WRITEBACK - `INSN_LDH_AC: begin - case (cycle) - 0: begin /* Type F */ end - 1: if (opcode[4]) - registers[`REG_A] <= rdata; - endcase - end - `INSN_LDx_AHL: begin - case (cycle) - 0: begin /* Type F */ end - 1: begin - 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 - `INSN_ALU8: begin - if ((opcode[2:0] == `INSN_reg_dHL) && (cycle == 0)) begin - /* Sit on our asses. */ - end else begin /* Actually do the computation! */ - case (opcode[5:3]) - `INSN_alu_ADD: begin - registers[`REG_A] <= - registers[`REG_A] + tmp; - registers[`REG_F] <= - { /* Z */ ((registers[`REG_A] + tmp) == 0) ? 1'b1 : 1'b0, - /* N */ 1'b0, - /* H */ (({1'b0,registers[`REG_A][3:0]} + {1'b0,tmp[3:0]}) >> 4 == 1) ? 1'b1 : 1'b0, - /* C */ (({1'b0,registers[`REG_A]} + {1'b0,tmp}) >> 8 == 1) ? 1'b1 : 1'b0, - registers[`REG_F][3:0] - }; - end - `INSN_alu_ADC: begin - registers[`REG_A] <= - registers[`REG_A] + tmp + {7'b0,registers[`REG_F][4]}; - registers[`REG_F] <= - { /* Z */ ((registers[`REG_A] + tmp + {7'b0,registers[`REG_F][4]}) == 0) ? 1'b1 : 1'b0, - /* N */ 1'b0, - /* H */ (({1'b0,registers[`REG_A][3:0]} + {1'b0,tmp[3:0]} + {4'b0,registers[`REG_F][4]}) >> 4 == 1) ? 1'b1 : 1'b0, - /* C */ (({1'b0,registers[`REG_A]} + {1'b0,tmp} + {8'b0,registers[`REG_F][4]}) >> 8 == 1) ? 1'b1 : 1'b0, - registers[`REG_F][3:0] - }; - end - `INSN_alu_SUB: begin - registers[`REG_A] <= - registers[`REG_A] - tmp; - registers[`REG_F] <= - { /* Z */ ((registers[`REG_A] - tmp) == 0) ? 1'b1 : 1'b0, - /* N */ 1'b1, - /* H */ (({1'b0,registers[`REG_A][3:0]} - {1'b0,tmp[3:0]}) >> 4 == 1) ? 1'b1 : 1'b0, - /* C */ (({1'b0,registers[`REG_A]} - {1'b0,tmp}) >> 8 == 1) ? 1'b1 : 1'b0, - registers[`REG_F][3:0] - }; - end - `INSN_alu_SBC: begin - registers[`REG_A] <= - registers[`REG_A] - (tmp + {7'b0,registers[`REG_F][4]}); - registers[`REG_F] <= - { /* Z */ ((registers[`REG_A] - (tmp + {7'b0,registers[`REG_F][4]})) == 0) ? 1'b1 : 1'b0, - /* N */ 1'b1, - /* H */ (({1'b0,registers[`REG_A][3:0]} - ({1'b0,tmp[3:0]} + {4'b0,registers[`REG_F][4]})) >> 4 == 1) ? 1'b1 : 1'b0, - /* C */ (({1'b0,registers[`REG_A]} - ({1'b0,tmp} + {8'b0,registers[`REG_F][4]})) >> 8 == 1) ? 1'b1 : 1'b0, - registers[`REG_F][3:0] - }; - end - `INSN_alu_AND: begin - registers[`REG_A] <= - registers[`REG_A] & tmp; - registers[`REG_F] <= - { /* Z */ ((registers[`REG_A] & tmp) == 0) ? 1'b1 : 1'b0, - 3'b010, - registers[`REG_F][3:0] - }; - end - `INSN_alu_OR: begin - registers[`REG_A] <= - registers[`REG_A] | tmp; - registers[`REG_F] <= - { /* Z */ ((registers[`REG_A] | tmp) == 0) ? 1'b1 : 1'b0, - 3'b000, - registers[`REG_F][3:0] - }; - end - `INSN_alu_XOR: begin - registers[`REG_A] <= - registers[`REG_A] ^ tmp; - registers[`REG_F] <= - { /* Z */ ((registers[`REG_A] ^ tmp) == 0) ? 1'b1 : 1'b0, - 3'b000, - registers[`REG_F][3:0] - }; - end - `INSN_alu_CP: begin - registers[`REG_F] <= - { /* Z */ ((registers[`REG_A] - tmp) == 0) ? 1'b1 : 1'b0, - /* N */ 1'b1, - /* H */ (({1'b0,registers[`REG_A][3:0]} - {1'b0,tmp[3:0]}) >> 4 == 1) ? 1'b1 : 1'b0, - /* C */ (({1'b0,registers[`REG_A]} - {1'b0,tmp}) >> 8 == 1) ? 1'b1 : 1'b0, - registers[`REG_F][3:0] - }; - end - default: - $stop; - endcase - end - end - `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 diff --git a/allinsns.v b/allinsns.v index 7e92cd3..79d88aa 100644 --- a/allinsns.v +++ b/allinsns.v @@ -7,3 +7,8 @@ `include "insn_ld_sp_hl.v" `include "insn_push_reg.v" `include "insn_pop_reg.v" +`include "insn_ldh_ac.v" +`include "insn_ldx_ahl.v" +`include "insn_alu8.v" +`include "insn_alu_a.v" +`include "insn_nop.v" diff --git a/insn_alu8.v b/insn_alu8.v new file mode 100644 index 0000000..8470e27 --- /dev/null +++ b/insn_alu8.v @@ -0,0 +1,115 @@ +`ifdef EXECUTE + `INSN_ALU8: begin + if ((opcode[2:0] == `INSN_reg_dHL) && (cycle == 0)) begin + // fffffffff fuck your shit, read from (HL) :( + rd <= 1; + address <= {registers[`REG_H], registers[`REG_L]}; + end else begin + `EXEC_NEWCYCLE; + `EXEC_INC_PC; + case (opcode[2:0]) + `INSN_reg_A: tmp <= registers[`REG_A]; + `INSN_reg_B: tmp <= registers[`REG_B]; + `INSN_reg_C: tmp <= registers[`REG_C]; + `INSN_reg_D: tmp <= registers[`REG_D]; + `INSN_reg_E: tmp <= registers[`REG_E]; + `INSN_reg_H: tmp <= registers[`REG_H]; + `INSN_reg_L: tmp <= registers[`REG_L]; + `INSN_reg_dHL: tmp <= rdata; + endcase + end + end +`endif + +`ifdef WRITEBACK + `INSN_ALU8: begin + if ((opcode[2:0] == `INSN_reg_dHL) && (cycle == 0)) begin + /* Sit on our asses. */ + end else begin /* Actually do the computation! */ + case (opcode[5:3]) + `INSN_alu_ADD: begin + registers[`REG_A] <= + registers[`REG_A] + tmp; + registers[`REG_F] <= + { /* Z */ ((registers[`REG_A] + tmp) == 0) ? 1'b1 : 1'b0, + /* N */ 1'b0, + /* H */ (({1'b0,registers[`REG_A][3:0]} + {1'b0,tmp[3:0]}) >> 4 == 1) ? 1'b1 : 1'b0, + /* C */ (({1'b0,registers[`REG_A]} + {1'b0,tmp}) >> 8 == 1) ? 1'b1 : 1'b0, + registers[`REG_F][3:0] + }; + end + `INSN_alu_ADC: begin + registers[`REG_A] <= + registers[`REG_A] + tmp + {7'b0,registers[`REG_F][4]}; + registers[`REG_F] <= + { /* Z */ ((registers[`REG_A] + tmp + {7'b0,registers[`REG_F][4]}) == 0) ? 1'b1 : 1'b0, + /* N */ 1'b0, + /* H */ (({1'b0,registers[`REG_A][3:0]} + {1'b0,tmp[3:0]} + {4'b0,registers[`REG_F][4]}) >> 4 == 1) ? 1'b1 : 1'b0, + /* C */ (({1'b0,registers[`REG_A]} + {1'b0,tmp} + {8'b0,registers[`REG_F][4]}) >> 8 == 1) ? 1'b1 : 1'b0, + registers[`REG_F][3:0] + }; + end + `INSN_alu_SUB: begin + registers[`REG_A] <= + registers[`REG_A] - tmp; + registers[`REG_F] <= + { /* Z */ ((registers[`REG_A] - tmp) == 0) ? 1'b1 : 1'b0, + /* N */ 1'b1, + /* H */ (({1'b0,registers[`REG_A][3:0]} - {1'b0,tmp[3:0]}) >> 4 == 1) ? 1'b1 : 1'b0, + /* C */ (({1'b0,registers[`REG_A]} - {1'b0,tmp}) >> 8 == 1) ? 1'b1 : 1'b0, + registers[`REG_F][3:0] + }; + end + `INSN_alu_SBC: begin + registers[`REG_A] <= + registers[`REG_A] - (tmp + {7'b0,registers[`REG_F][4]}); + registers[`REG_F] <= + { /* Z */ ((registers[`REG_A] - (tmp + {7'b0,registers[`REG_F][4]})) == 0) ? 1'b1 : 1'b0, + /* N */ 1'b1, + /* H */ (({1'b0,registers[`REG_A][3:0]} - ({1'b0,tmp[3:0]} + {4'b0,registers[`REG_F][4]})) >> 4 == 1) ? 1'b1 : 1'b0, + /* C */ (({1'b0,registers[`REG_A]} - ({1'b0,tmp} + {8'b0,registers[`REG_F][4]})) >> 8 == 1) ? 1'b1 : 1'b0, + registers[`REG_F][3:0] + }; + end + `INSN_alu_AND: begin + registers[`REG_A] <= + registers[`REG_A] & tmp; + registers[`REG_F] <= + { /* Z */ ((registers[`REG_A] & tmp) == 0) ? 1'b1 : 1'b0, + 3'b010, + registers[`REG_F][3:0] + }; + end + `INSN_alu_OR: begin + registers[`REG_A] <= + registers[`REG_A] | tmp; + registers[`REG_F] <= + { /* Z */ ((registers[`REG_A] | tmp) == 0) ? 1'b1 : 1'b0, + 3'b000, + registers[`REG_F][3:0] + }; + end + `INSN_alu_XOR: begin + registers[`REG_A] <= + registers[`REG_A] ^ tmp; + registers[`REG_F] <= + { /* Z */ ((registers[`REG_A] ^ tmp) == 0) ? 1'b1 : 1'b0, + 3'b000, + registers[`REG_F][3:0] + }; + end + `INSN_alu_CP: begin + registers[`REG_F] <= + { /* Z */ ((registers[`REG_A] - tmp) == 0) ? 1'b1 : 1'b0, + /* N */ 1'b1, + /* H */ (({1'b0,registers[`REG_A][3:0]} - {1'b0,tmp[3:0]}) >> 4 == 1) ? 1'b1 : 1'b0, + /* C */ (({1'b0,registers[`REG_A]} - {1'b0,tmp}) >> 8 == 1) ? 1'b1 : 1'b0, + registers[`REG_F][3:0] + }; + end + default: + $stop; + endcase + end + end +`endif diff --git a/insn_alu_a.v b/insn_alu_a.v new file mode 100644 index 0000000..fe3315a --- /dev/null +++ b/insn_alu_a.v @@ -0,0 +1,39 @@ +`ifdef EXECUTE + `INSN_ALU_A: begin + `EXEC_NEWCYCLE; + `EXEC_INC_PC; + end +`endif + +`ifdef WRITEBACK + `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 +`endif diff --git a/insn_ldh_ac.v b/insn_ldh_ac.v new file mode 100644 index 0000000..146f10b --- /dev/null +++ b/insn_ldh_ac.v @@ -0,0 +1,30 @@ +`ifdef EXECUTE + `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 +`endif + +`ifdef WRITEBACK + `INSN_LDH_AC: begin + case (cycle) + 0: begin /* Type F */ end + 1: if (opcode[4]) + registers[`REG_A] <= rdata; + endcase + end +`endif + diff --git a/insn_ldx_ahl.v b/insn_ldx_ahl.v new file mode 100644 index 0000000..a16d6ba --- /dev/null +++ b/insn_ldx_ahl.v @@ -0,0 +1,35 @@ +`ifdef EXECUTE + `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 +`endif + +`ifdef WRITEBACK + `INSN_LDx_AHL: begin + case (cycle) + 0: begin /* Type F */ end + 1: begin + 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 +`endif diff --git a/insn_nop.v b/insn_nop.v new file mode 100644 index 0000000..2772a11 --- /dev/null +++ b/insn_nop.v @@ -0,0 +1,10 @@ +`ifdef EXECUTE + `INSN_NOP: begin + `EXEC_NEWCYCLE; + `EXEC_INC_PC; + end +`endif + +`ifdef WRITEBACK + `INSN_NOP: begin end +`endif