Creado opcodes.h que contiene macros para implementar facilmente series
authorslack <slack@0666ae3d-8926-0410-aeff-ae84559ff337>
Thu, 11 Jan 2007 01:33:56 +0000 (01:33 +0000)
committerslack <slack@0666ae3d-8926-0410-aeff-ae84559ff337>
Thu, 11 Jan 2007 01:33:56 +0000 (01:33 +0000)
de opcodes similares (p.e.: todos los LD A, reg)

Pasado el codigo existente a usar macros para evitar duplicacion
innecesaria de codigo.

AƱadido ADC.

git-svn-id: http://slack.codemaniacs.com/wenboi@2 0666ae3d-8926-0410-aeff-ae84559ff337

gbcore.cc
opcodes.h [new file with mode: 0644]

index 9ef4baadcfb94bb176a31baf34547f46b7236036..252a63a33220c54b76ec65802a6733e8fe2b1dcc 100644 (file)
--- a/gbcore.cc
+++ b/gbcore.cc
@@ -49,6 +49,7 @@ class GameBoy
 
        void set_flag(const u8 f) { regs.flags |= f; }
        void reset_flag(const u8 f) { regs.flags &= (~f); }
+       bool check_flag(const u8 f) { return (regs.flags & f != 0); }
 
        public:
        GameBoy(std::string rom_name);
@@ -72,6 +73,7 @@ void GameBoy::reset()
        regs.PC = 0x100;
 }
 
+#include "opcodes.h"
 
 void GameBoy::run_cycle()
 {
@@ -87,230 +89,28 @@ void GameBoy::run_cycle()
        switch(opcode)
        {
                // LD n, nn
-               case 0x76: // LD A,n
-                       regs.A = memory[regs.PC++];
-                       break;
-               case 0x06: // LD B,n
-                       regs.B = memory[regs.PC++];
-                       break;
-               case 0x0E: // LD C,n
-                       regs.C = memory[regs.PC++];
-                       break;
-               case 0x16: // LD D,n
-                       regs.D = memory[regs.PC++];
-                       break;
-               case 0x1E: // LD E,n
-                       regs.E = memory[regs.PC++];
-                       break;
-               case 0x26: // LD H,n
-                       regs.H = memory[regs.PC++];
-                       break;
-               case 0x2E: // LD L,n
-                       regs.L = memory[regs.PC++];
-                       break;
+               for_each_register(0x76, 0x06, 0x0E, 0x16, 0x1E, 0x26, 0x2E, LD_reg_nn)
 
                // LD r1,r2
-               case 0x7F: // LD A,A
-                       regs.A = regs.A;
-                       break;
-               case 0x78: // LD A,B
-                       regs.A = regs.B;
-                       break;
-               case 0x79: // LD A,C
-                       regs.A = regs.C;
-                       break;
-               case 0x7A: // LD A,D
-                       regs.A = regs.D;
-                       break;
-               case 0x7B: // LD A,E
-                       regs.A = regs.E;
-                       break;
-               case 0x7C: // LD A,H
-                       regs.A = regs.H;
-                       break;
-               case 0x7D: // LD A,L
-                       regs.A = regs.L;
-                       break;
-               case 0x7E: // LD A,(HL)
-                       regs.A = memory[regs.HL];
-                       break;
-
-               case 0x47: // LD B,A
-                       regs.B = regs.A;
-                       break;
-               case 0x40: // LD B,B
-                       regs.B = regs.B;
-                       break;
-               case 0x41: // LD B,C
-                       regs.B = regs.C;
-                       break;
-               case 0x42: // LD B,D
-                       regs.B = regs.D;
-                       break;
-               case 0x43: // LD B,E
-                       regs.B = regs.E;
-                       break;
-               case 0x44: // LD B,H
-                       regs.B = regs.H;
-                       break;
-               case 0x45: // LD B,L
-                       regs.B = regs.L;
-                       break;
-               case 0x46: // LD B,(HL)
-                       regs.B = memory[regs.HL];
-                       break;
-
-               case 0x4F: // LD C,A
-                       regs.C = regs.A;
-                       break;
-               case 0x48: // LD C,B
-                       regs.C = regs.B;
-                       break;
-               case 0x49: // LD C,C
-                       regs.C = regs.C;
-                       break;
-               case 0x4A: // LD C,D
-                       regs.C = regs.D;
-                       break;
-               case 0x4B: // LD C,E
-                       regs.C = regs.E;
-                       break;
-               case 0x4C: // LD C,H
-                       regs.C = regs.H;
-                       break;
-               case 0x4D: // LD C,L
-                       regs.C = regs.L;
-                       break;
-               case 0x4E: // LD C,(HL)
-                       regs.C = memory[regs.HL];
-                       break;
-
-               case 0x57: // LD D,A
-                       regs.D = regs.A;
-                       break;
-               case 0x50: // LD D,B
-                       regs.D = regs.B;
-                       break;
-               case 0x51: // LD D,C
-                       regs.D = regs.C;
-                       break;
-               case 0x52: // LD D,D
-                       regs.D = regs.D;
-                       break;
-               case 0x53: // LD D,E
-                       regs.D = regs.E;
-                       break;
-               case 0x54: // LD D,H
-                       regs.D = regs.H;
-                       break;
-               case 0x55: // LD D,L
-                       regs.D = regs.L;
-                       break;
-               case 0x56: // LD D,(HL)
-                       regs.D = memory[regs.HL];
-                       break;
-
-               case 0x5F: // LD E,A
-                       regs.E = regs.A;
-                       break;
-               case 0x58: // LD E,B
-                       regs.E = regs.D;
-                       break;
-               case 0x59: // LD E,C
-                       regs.E = regs.C;
-                       break;
-               case 0x5A: // LD E,D
-                       regs.E = regs.D;
-                       break;
-               case 0x5B: // LD E,E
-                       regs.E = regs.E;
-                       break;
-               case 0x5C: // LD E,H
-                       regs.E = regs.H;
-                       break;
-               case 0x5D: // LD E,L
-                       regs.E = regs.L;
-                       break;
-               case 0x5E: // LD E,(HL)
-                       regs.E = memory[regs.HL];
-                       break;
-
-               case 0x67: // LD H,A
-                       regs.H = regs.A;
-                       break;
-               case 0x60: // LD H,B
-                       regs.H = regs.B;
-                       break;
-               case 0x61: // LD H,C
-                       regs.H = regs.C;
-                       break;
-               case 0x62: // LD H,D
-                       regs.H = regs.D;
-                       break;
-               case 0x63: // LD H,E
-                       regs.H = regs.E;
-                       break;
-               case 0x64: // LD H,H
-                       regs.H = regs.H;
-                       break;
-               case 0x65: // LD H,L
-                       regs.H = regs.L;
-                       break;
-               case 0x66: // LD H,(HL)
-                       regs.H = memory[regs.HL];
-                       break;
-
-               case 0x6F: // LD L,A
-                       regs.L = regs.A;
-                       break;
-               case 0x68: // LD L,B
-                       regs.L = regs.D;
-                       break;
-               case 0x69: // LD L,C
-                       regs.L = regs.C;
-                       break;
-               case 0x6A: // LD L,D
-                       regs.L = regs.D;
-                       break;
-               case 0x6B: // LD L,E
-                       regs.L = regs.E;
-                       break;
-               case 0x6C: // LD L,H
-                       regs.L = regs.H;
-                       break;
-               case 0x6D: // LD L,L
-                       regs.L = regs.L;
-                       break;
-               case 0x6E: // LD L,(HL)
-                       regs.L = memory[regs.HL];
-                       break;
+               for_each_register(0x7F, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, LD_A_reg)
+               for_each_register(0x47, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, LD_B_reg)
+               for_each_register(0x4F, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, LD_C_reg)
+               for_each_register(0x57, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, LD_D_reg)
+               for_each_register(0x5F, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, LD_E_reg)
+               for_each_register(0x67, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, LD_H_reg)
+               for_each_register(0x6F, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, LD_L_reg)
+               
+               // LD reg, (HL)
+               for_each_register(0x7E, 0x46, 0x4E, 0x56, 0x5E, 0x66, 0x6E, LD_reg__HL_)
 
-               case 0x77: // LD (HL),A
-                       memory[regs.HL] = regs.A;
-                       break;
-               case 0x70: // LD (HL),B
-                       memory[regs.HL] = regs.B;
-                       break;
-               case 0x71: // LD (HL),C
-                       memory[regs.HL] = regs.C;
-                       break;
-               case 0x72: // LD (HL),D
-                       memory[regs.HL] = regs.D;
-                       break;
-               case 0x73: // LD (HL),E
-                       memory[regs.HL] = regs.E;
-                       break;
-               case 0x74: // LD (HL),H
-                       memory[regs.HL] = regs.H;
-                       break;
-               case 0x75: // LD (HL),L
-                       memory[regs.HL] = regs.L;
-                       break;
+               // LD (HL), reg
+               for_each_register(0x77, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, LD__HL__reg)
+               
                case 0x36: // LD (HL), n
                        memory[regs.HL] = memory[regs.PC++];
                        break;
                
-               // LD A, n
+               // LD A, mem
                case 0x0A: // LD A, (BC)
                        regs.A = memory[regs.BC];
                        break;
@@ -322,7 +122,7 @@ void GameBoy::run_cycle()
                        regs.PC+=2;
                        break;
                
-               // LD n, A
+               // LD mem, A
                case 0x02: // LD (BC), A
                        memory[regs.BC] = regs.A;
                        break;
@@ -422,185 +222,71 @@ void GameBoy::run_cycle()
                        }
 
                // PUSH nn
-               case 0xF5: // push AF
-                       memory[regs.SP-1] = regs.A;
-                       memory[regs.SP-2] = regs.flags;
-                       regs.SP -= 2;
-                       break;
-               case 0xC5: // push BC
-                       memory[regs.SP-1] = regs.B;
-                       memory[regs.SP-2] = regs.C;
-                       regs.SP -= 2;
-                       break;
-               case 0xD5: // push DE
-                       memory[regs.SP-1] = regs.D;
-                       memory[regs.SP-2] = regs.E;
-                       regs.SP -= 2;
-                       break;
-               case 0xE5: // push HL
-                       memory[regs.SP-1] = regs.H;
-                       memory[regs.SP-2] = regs.L;
-                       regs.SP -= 2;
-                       break;
+               PUSH(0xF5, A, flags)
+               PUSH(0xC5, B, C)
+               PUSH(0xD5, D, E)
+               PUSH(0xE5, H, L)
 
                // POP nn
-               case 0xF1: // pop AF
-                       regs.flags = memory[regs.SP];
-                       regs.A = memory[regs.SP+1];
-                       regs.SP += 2;
-                       break;
-               case 0xC1: // pop BC
-                       regs.C = memory[regs.SP];
-                       regs.B = memory[regs.SP+1];
-                       regs.SP += 2;
-                       break;
-               case 0xD1: // pop DE
-                       regs.E = memory[regs.SP];
-                       regs.D = memory[regs.SP+1];
-                       regs.SP += 2;
-                       break;
-               case 0xE1: // pop HL
-                       regs.L = memory[regs.SP];
-                       regs.H = memory[regs.SP+1];
-                       regs.SP += 2;
-                       break;
+               POP(0xF1, A, flags)
+               POP(0xC1, B, C)
+               POP(0xD1, D, E)
+               POP(0xE1, H, L)
 
                // 8-bit ALU
-               // ADD A, n
-               case 0x87: {// ADD A, A
-                       int res = regs.A + regs.A;
-                       int half_res = (regs.A & 0x0F) + (regs.A & 0x0F);
-                       
+               // ADD A,reg
+               for_each_register(0x87, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, ADD_A_reg)
+               
+               case 0x86: {// ADD A, (HL)
+                       int res = regs.A + memory[regs.HL];
+                       int half_res = (regs.A & 0x0F) + (memory[regs.HL] & 0x0F);
                        regs.A = static_cast<u8>(res);
-                       if (res > 0xFF)
-                               set_flag(CARRY_FLAG);
-                       reset_flag(ADD_SUB_FLAG);
-                       if (regs.A == 0)
-                               set_flag(ZERO_FLAG);
-
-                       if (half_res > 0x0F)
-                               set_flag(HALF_CARRY_FLAG);
-                       break;
-                       }
-               case 0x80: {// ADD A, B
-                       int res = regs.A + regs.B;
-                       int half_res = (regs.A & 0x0F) + (regs.B & 0x0F);
                        
-                       regs.A = static_cast<u8>(res);
-                       if (res > 0xFF)
-                               set_flag(CARRY_FLAG);
                        reset_flag(ADD_SUB_FLAG);
-                       if (regs.A == 0)
-                               set_flag(ZERO_FLAG);
-
-                       if (half_res > 0x0F)
-                               set_flag(HALF_CARRY_FLAG);
+                       if (res > 0xFF)      set_flag(CARRY_FLAG);
+                       if (regs.A == 0)     set_flag(ZERO_FLAG);
+                       if (half_res > 0x0F) set_flag(HALF_CARRY_FLAG);
                        break;
                        }
-               case 0x81: {// ADD A, C
-                       int res = regs.A + regs.C;
-                       int half_res = (regs.A & 0x0F) + (regs.C & 0x0F);
-                       
+               case 0xC6: {//ADD A, #
+                       int inm = memory[regs.PC++];
+                       int res = regs.A + inm;
+                       int half_res = (regs.A & 0x0F) + (inm & 0x0F);
                        regs.A = static_cast<u8>(res);
-                       if (res > 0xFF)
-                               set_flag(CARRY_FLAG);
-                       reset_flag(ADD_SUB_FLAG);
-                       if (regs.A == 0)
-                               set_flag(ZERO_FLAG);
-
-                       if (half_res > 0x0F)
-                               set_flag(HALF_CARRY_FLAG);
-                       break;
-                       }
-               case 0x82: {// ADD A, D
-                       int res = regs.A + regs.D;
-                       int half_res = (regs.A & 0x0F) + (regs.D & 0x0F);
                        
-                       regs.A = static_cast<u8>(res);
-                       if (res > 0xFF)
-                               set_flag(CARRY_FLAG);
                        reset_flag(ADD_SUB_FLAG);
-                       if (regs.A == 0)
-                               set_flag(ZERO_FLAG);
-
-                       if (half_res > 0x0F)
-                               set_flag(HALF_CARRY_FLAG);
+                       if (res > 0xFF)      set_flag(CARRY_FLAG);
+                       if (regs.A == 0)     set_flag(ZERO_FLAG);
+                       if (half_res > 0x0F) set_flag(HALF_CARRY_FLAG);
                        break;
                        }
-               case 0x83: {// ADD A, E
-                       int res = regs.A + regs.E;
-                       int half_res = (regs.A & 0x0F) + (regs.E & 0x0F);
-                       
-                       regs.A = static_cast<u8>(res);
-                       if (res > 0xFF)
-                               set_flag(CARRY_FLAG);
-                       reset_flag(ADD_SUB_FLAG);
-                       if (regs.A == 0)
-                               set_flag(ZERO_FLAG);
 
-                       if (half_res > 0x0F)
-                               set_flag(HALF_CARRY_FLAG);
-                       break;
-                       }
-               case 0x84: {// ADD A, H
-                       int res = regs.A + regs.H;
-                       int half_res = (regs.A & 0x0F) + (regs.H & 0x0F);
-                       
-                       regs.A = static_cast<u8>(res);
-                       if (res > 0xFF)
-                               set_flag(CARRY_FLAG);
-                       reset_flag(ADD_SUB_FLAG);
-                       if (regs.A == 0)
-                               set_flag(ZERO_FLAG);
+               // ADC A, n
+               for_each_register(0x8F, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, ADC_A_reg)
 
-                       if (half_res > 0x0F)
-                               set_flag(HALF_CARRY_FLAG);
-                       break;
-                       }
-               case 0x85: {// ADD A, L
-                       int res = regs.A + regs.L;
-                       int half_res = (regs.A & 0x0F) + (regs.L & 0x0F);
-                       
+               case 0x8E: {// ADC A, (HL)
+                       int carry = (check_flag(CARRY_FLAG)? 1 : 0);
+                       int res = regs.A + memory[regs.HL] + carry;
+                       int half_res = (regs.A & 0x0F) + (memory[regs.HL] & 0x0F) + carry;
                        regs.A = static_cast<u8>(res);
-                       if (res > 0xFF)
-                               set_flag(CARRY_FLAG);
-                       reset_flag(ADD_SUB_FLAG);
-                       if (regs.A == 0)
-                               set_flag(ZERO_FLAG);
-
-                       if (half_res > 0x0F)
-                               set_flag(HALF_CARRY_FLAG);
-                       break;
-                       }
-               case 0x86: {// ADD A, (HL)
-                       int res = regs.A + memory[regs.HL];
-                       int half_res = (regs.A & 0x0F) + (memory[regs.HL] & 0x0F);
                        
-                       regs.A = static_cast<u8>(res);
-                       if (res > 0xFF)
-                               set_flag(CARRY_FLAG);
                        reset_flag(ADD_SUB_FLAG);
-                       if (regs.A == 0)
-                               set_flag(ZERO_FLAG);
-
-                       if (half_res > 0x0F)
-                               set_flag(HALF_CARRY_FLAG);
+                       if (res > 0xFF)      set_flag(CARRY_FLAG);
+                       if (regs.A == 0)     set_flag(ZERO_FLAG);
+                       if (half_res > 0x0F) set_flag(HALF_CARRY_FLAG);
                        break;
                        }
-               case 0xC6: {//ADD A, #
+               case 0xCE: {//ADC A, #
+                       int carry = (check_flag(CARRY_FLAG)? 1 : 0);
                        int inm = memory[regs.PC++];
-                       int res = regs.A + inm;
-                       int half_res = (regs.A & 0x0F) + (inm & 0x0F);
-                       
+                       int res = regs.A + inm + carry;
+                       int half_res = (regs.A & 0x0F) + (inm & 0x0F) + carry;
                        regs.A = static_cast<u8>(res);
-                       if (res > 0xFF)
-                               set_flag(CARRY_FLAG);
+                       
                        reset_flag(ADD_SUB_FLAG);
-                       if (regs.A == 0)
-                               set_flag(ZERO_FLAG);
-
-                       if (half_res > 0x0F)
-                               set_flag(HALF_CARRY_FLAG);
+                       if (res > 0xFF)      set_flag(CARRY_FLAG);
+                       if (regs.A == 0)     set_flag(ZERO_FLAG);
+                       if (half_res > 0x0F) set_flag(HALF_CARRY_FLAG);
                        break;
                        }
 
@@ -608,6 +294,7 @@ void GameBoy::run_cycle()
 
 
 
+
                        
 
 
diff --git a/opcodes.h b/opcodes.h
new file mode 100644 (file)
index 0000000..6b13c41
--- /dev/null
+++ b/opcodes.h
@@ -0,0 +1,81 @@
+#define for_each_register(opA, opB, opC, opD, opE, opH, opL, macro) \
+       macro(opA, A) \
+       macro(opB, B) \
+        macro(opC, C) \
+        macro(opD, D) \
+       macro(opE, E) \
+       macro(opH, H) \
+       macro(opL, L)
+
+#define LD_reg_nn(opcode, reg) \
+       case opcode: \
+               regs.reg = memory[regs.PC++]; \
+               break;
+
+#define LD_reg_reg(opcode, reg1, reg2) \
+       case opcode: \
+               regs.reg1 = regs.reg2; \
+               break;
+
+#define LD_A_reg(opcode, reg2) LD_reg_reg(opcode, A, reg2)
+#define LD_B_reg(opcode, reg2) LD_reg_reg(opcode, B, reg2)
+#define LD_C_reg(opcode, reg2) LD_reg_reg(opcode, C, reg2)
+#define LD_D_reg(opcode, reg2) LD_reg_reg(opcode, D, reg2)
+#define LD_E_reg(opcode, reg2) LD_reg_reg(opcode, E, reg2)
+#define LD_H_reg(opcode, reg2) LD_reg_reg(opcode, H, reg2)
+#define LD_L_reg(opcode, reg2) LD_reg_reg(opcode, L, reg2)
+
+// LD reg, (HL)
+#define LD_reg__HL_(opcode, reg) \
+       case opcode: \
+               regs.reg = memory[regs.HL]; \
+               break;
+
+// LD (HL), reg
+#define LD__HL__reg(opcode, reg) \
+       case opcode: \
+               memory[regs.HL] = regs.reg; \
+               break;
+
+#define PUSH(opcode, regH, regL) \
+       case opcode: \
+               memory[regs.SP-1] = regs.regH; \
+               memory[regs.SP-2] = regs.regL; \
+               regs.SP -= 2; \
+               break;
+
+#define POP(opcode, regH, regL) \
+       case opcode: \
+               regs.regL = memory[regs.SP]; \
+               regs.regH = memory[regs.SP+1]; \
+               regs.SP += 2; \
+               break;
+
+#define ADD_A_reg(opcode, reg) \
+       case opcode: { \
+               int res = regs.A + regs.reg; \
+               int half_res = (regs.A & 0x0F) + (regs.reg & 0x0F); \
+               regs.A = static_cast<u8>(res); \
+               \
+               reset_flag(ADD_SUB_FLAG); \
+               if (res > 0xFF)      set_flag(CARRY_FLAG); \
+               if (regs.A == 0)     set_flag(ZERO_FLAG);  \
+               if (half_res > 0x0F) set_flag(HALF_CARRY_FLAG); \
+               break; \
+       }
+
+#define ADC_A_reg(opcode, reg) \
+       case opcode: { \
+               int carry = (check_flag(CARRY_FLAG)? 1 : 0); \
+               int res = regs.A + regs.reg + carry; \
+               int half_res = (regs.A & 0x0F) + (regs.reg & 0x0F) + carry; \
+               regs.A = static_cast<u8>(res); \
+               \
+               reset_flag(ADD_SUB_FLAG); \
+               if (res > 0xFF)      set_flag(CARRY_FLAG); \
+               if (regs.A == 0)     set_flag(ZERO_FLAG);  \
+               if (half_res > 0x0F) set_flag(HALF_CARRY_FLAG); \
+               break; \
+       }
+
+