work in progress
authorkbongers <kbongers@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 30 Jan 2002 05:22:09 +0000 (05:22 +0000)
committerkbongers <kbongers@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 30 Jan 2002 05:22:09 +0000 (05:22 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1875 4a8a32a2-be11-0410-ad9d-d568d2c75423

sim/ucsim/xa.src/glob.cc
sim/ucsim/xa.src/glob.h
sim/ucsim/xa.src/inst.cc
sim/ucsim/xa.src/instcl.h
sim/ucsim/xa.src/regsxa.h
sim/ucsim/xa.src/xa.cc
sim/ucsim/xa.src/xacl.h

index 527e29541a99ee1bfebcd922a627aaddaf177d07..566d07a21b7288a8e88a56b268c47799b93874e2 100644 (file)
@@ -32,6 +32,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "stypes.h"
 #include "glob.h"
 
+/* this needs to match enum definition in glob.h */
 char *op_mnemonic_str[] = {
 "BAD_OPCODE",
 "ADD",
@@ -91,42 +92,20 @@ char *op_mnemonic_str[] = {
 "RESET"
 "FCALL",
 "FJMP",
+"IREG",
 };
 
+/* this is junk, but we need to keep it until main ucSim code
+   is cleaned of dis_entry[] references. */
 struct dis_entry glob_disass_xa[]= {
   { 0x0000, 0x00ff, ' ', 1, "nop" },
   { 0x0000, 0x00, 0, 0, NULL}
 };
 
+/* plan: keep this list in same order as in User Guide(pg 106)
+   until all op-codes are defined.  Figure out how to make simulation
+   lookup fast later. */
 struct xa_dis_entry disass_xa[]= {
- {0x0000,0xffff,' ',1,NOP, NO_OPERANDS     }, //  NOP   0 0 0 0 0 0 0 0
- {0xff00,0xffff,' ',1,NOP, NO_OPERANDS     }, //  BRPT  1 1 1 1 1 1 1 1
-
- {0x0840,0xfffc,' ',3,ANL, C_BIT           }, //  ANL C, bit                 0 0 0 0 1 0 0 0  0 1 0 0 0 0 b b
- {0x0850,0xfffc,' ',3,ANL, C_NOTBIT        }, //  ANL C, /bit                0 0 0 0 1 0 0 0  0 1 0 1 0 0 b b
- {0x0850,0xfffc,' ',3,ASL, REG_REG         }, //  ASL Rd, Rs                 1 1 0 0 S S 0 1  d d d d s s s s
- {0x900c,0xf70f,' ',2,CPL, REG_ALONE       }, //  CPL Rd                     1 0 0 1 S 0 0 0  d d d d 1 0 1 0
- {0xe708,0xff00,' ',2,DIV_w, REG_REG       }, //  DIV.w Rd, Rs               1 1 1 0 0 1 1 1  d d d d s s s s
- {0xe80b,0xff0f,' ',3,DIV_w, REG_DATA8     }, //  DIV.w Rd, #data8           1 1 1 0 1 0 0 0  d d d d 1 0 1 1
- {0xef00,0xff10,' ',2,DIV_d, REG_REG       }, //  DIV.d Rd, Rs               1 1 1 0 1 1 1 1  d d d 0 s s s s
- {0xe909,0xff1f,' ',4,DIV_d, REG_DATA16    }, //  DIV.d Rd, #data16          1 1 1 0 1 0 0 1  d d d 0 1 0 0 1
- {0xe801,0xff0f,' ',3,DIVU_b, REG_DATA8    }, //  DIVU.b Rd, #data8          1 1 1 0 1 0 0 0  d d d d 0 0 0 1
- {0xe500,0xff00,' ',2,DIVU_w, REG_REG      }, //  DIVU.w Rd, Rs              1 1 1 0 0 1 0 1  d d d d s s s s
- {0xe803,0xff0f,' ',3,DIVU_w, REG_DATA8    }, //  DIVU.w Rd, #data8          1 1 1 0 1 0 0 0  d d d d 0 0 1 1
- {0xed00,0xff10,' ',2,DIVU_d, REG_REG      }, //  DIVU.d Rd, Rs              1 1 1 0 1 1 0 1  d d d 0 s s s s
- {0xe901,0xff1f,' ',4,DIVU_d, REG_DATA16   }, //  DIVU.d Rd, #data16         1 1 1 0 1 0 0 1  d d d 0 0 0 0 1
- {0x8708,0xf70f,' ',3,DJNZ,   REG_REL8     }, //  DJNZ Rd, rel8              1 0 0 0 S 1 1 1  d d d d 1 0 0 0
- {0xe208,0xf7f8,' ',4,DJNZ,   DIRECT_REL8  }, //  DJNZ direct, rel8          1 1 1 0 S 0 1 0  0 0 0 0 1 x x x
- {0xc400,0xff00,' ',4,FCALL,  ADDR24       }, //  FCALL addr24               1 1 0 0 0 1 0 0  
- {0xd400,0xff00,' ',4,FJMP,   ADDR24       }, //  FJMP addr24                1 1 0 1 0 1 0 0
-
- {0x1408,0xf780,' ',2,ADDS, REG_DATA4      }, // ADDS Rd, #data4             1 0 1 0 S 0 0 1  d d d d #data4
- {0x1408,0xf780,' ',2,ADDS, IREG_DATA4     }, // ADDS [Rd], #data4           1 0 1 0 S 0 1 0  0 d d d #data4
- {0x1408,0xf780,' ',2,ADDS, IREGINC_DATA4  }, // ADDS [Rd+], #data4          1 0 1 0 S 0 1 1  0 d d d #data4
- {0x1408,0xf780,' ',3,ADDS, IREGOFF8_DATA4 }, // ADDS [Rd+offset8], #data4   1 0 1 0 S 1 0 0  0 d d d #data4
- {0x1408,0xf780,' ',4,ADDS, IREGOFF16_DATA4}, // ADDS [Rd+offset16], #data4  1 0 1 0 S 1 0 1  0 d d d #data4
- {0x1408,0xf780,' ',3,ADDS, DIRECT_DATA4   }, // ADDS direct, #data4         1 0 1 0 S 1 1 0  0 x x x #data4
-
  {0x0100,0xf700,' ',2,ADD, REG_REG         },  // ADD Rd, Rs                 0 0 0 0 S 0 0 1  d d d d s s s s
  {0x0200,0xf708,' ',2,ADD, REG_IREG        },  // ADD Rd, [Rs]               0 0 0 0 S 0 1 0  d d d d 0 s s s
  {0x0208,0xf708,' ',2,ADD, IREG_REG        },  // ADD [Rd], Rs               0 0 0 0 S 0 1 0  s s s s 1 d d d
@@ -175,6 +154,13 @@ struct xa_dis_entry disass_xa[]= {
  {0x9601,0xff8f,' ',4,ADDC,DIRECT_DATA8    },  //ADDC direct, #data8         1 0 0 1 0 1 1 0  0 b b b 0 0 0 1
  {0x9e01,0xff8f,' ',5,ADDC,DIRECT_DATA16   },  //ADDC direct, #data16        1 0 0 1 1 1 1 0  0 b b b 0 0 0 1
 
+ {0x1408,0xf780,' ',2,ADDS, REG_DATA4      }, // ADDS Rd, #data4             1 0 1 0 S 0 0 1  d d d d #data4
+ {0x1408,0xf780,' ',2,ADDS, IREG_DATA4     }, // ADDS [Rd], #data4           1 0 1 0 S 0 1 0  0 d d d #data4
+ {0x1408,0xf780,' ',2,ADDS, IREGINC_DATA4  }, // ADDS [Rd+], #data4          1 0 1 0 S 0 1 1  0 d d d #data4
+ {0x1408,0xf780,' ',3,ADDS, IREGOFF8_DATA4 }, // ADDS [Rd+offset8], #data4   1 0 1 0 S 1 0 0  0 d d d #data4
+ {0x1408,0xf780,' ',4,ADDS, IREGOFF16_DATA4}, // ADDS [Rd+offset16], #data4  1 0 1 0 S 1 0 1  0 d d d #data4
+ {0x1408,0xf780,' ',3,ADDS, DIRECT_DATA4   }, // ADDS direct, #data4         1 0 1 0 S 1 1 0  0 x x x #data4
+
  {0x5100,0xf700,' ',2, AND,REG_REG         },  // AND Rd, Rs                 0 1 0 1 S 0 0 1  d d d d s s s s 
  {0x5200,0xf708,' ',2, AND,REG_IREG        },  // AND Rd, [Rs]               0 1 0 1 S 0 1 0  d d d d 0 s s s 
  {0x5208,0xf708,' ',2, AND,IREG_REG        },  // AND [Rd], Rs               0 1 0 1 S 0 1 0  s s s s 1 d d d 
@@ -199,6 +185,18 @@ struct xa_dis_entry disass_xa[]= {
  {0x9605,0xff8f,' ',4, AND,DIRECT_DATA8    },  // AND direct, #data8         1 0 0 1 0 1 1 0  0 b b b 0 1 0 1 
  {0x9e05,0xff8f,' ',5, AND,DIRECT_DATA16   },  // AND direct, #data16        1 0 0 1 0 1 1 0  1 b b b 0 1 0 1 
 
+ {0x0840,0xfffc,' ',3,ANL, C_BIT           }, //  ANL C, bit                 0 0 0 0 1 0 0 0  0 1 0 0 0 0 b b
+ {0x0850,0xfffc,' ',3,ANL, C_NOTBIT        }, //  ANL C, /bit                0 0 0 0 1 0 0 0  0 1 0 1 0 0 b b
+ {0x0850,0xfffc,' ',3,ASL, REG_REG         }, //  ASL Rd, Rs                 1 1 0 0 S S 0 1  d d d d s s s s
+/* ASR(3), BCC, BCS */
+ {0xf300,0xff00,' ',2,BEQ, REL8            }, //  BEQ rel8                   1 1 1 1 0 0 1 1  rel8
+/* BG, BGE, BGT */
+ {0xff00,0xff00,' ',1,BKPT, NO_OPERANDS    }, //  BKPT                       1 1 1 1 1 1 1 1
+/* BL, BLE, BLT, BMI, BNE, BNV, BOV, BPL, BR */
+ {0xc500,0xff00,' ',3,CALL, REL16          }, //  CALL rel16                 1 1 0 0 0 1 0 1  rel16
+ {0xc600,0xfff8,' ',2,CALL, IREG_ALONE     }, //  CALL [Rs]                  1 1 0 0 0 1 1 0  0 0 0 0 0 s s s
+/* CJNE(5), JNE, CLR */
+
  {0x4100,0xf700,' ',2,CMP, REG_REG         },  // CMP Rd, Rs                 0 1 0 0 S 0 0 1  d d d d s s s s
  {0x4200,0xf708,' ',2,CMP, REG_IREG        },  // CMP Rd, [Rs]               0 1 0 0 S 0 1 0  d d d d 0 s s s
  {0x4208,0xf708,' ',2,CMP, IREG_REG        },  // CMP [Rd], Rs               0 1 0 0 S 0 1 0  s s s s 1 d d d
@@ -223,6 +221,29 @@ struct xa_dis_entry disass_xa[]= {
  {0x9604,0xff8f,' ',4,CMP, DIRECT_DATA8    },  // CMP direct, #data8         1 0 0 1 0 1 1 0  0 b b b 0 1 0 0
  {0x9e04,0xff8f,' ',5,CMP, DIRECT_DATA16   },  // CMP direct, #data16        1 0 0 1 0 1 1 0  0 b b b 0 1 0 0
 
+ {0x900c,0xf70f,' ',2,CPL, REG_ALONE       }, //  CPL Rd                     1 0 0 1 S 0 0 0  d d d d 1 0 1 0
+   /* DA */
+ {0xe708,0xff00,' ',2,DIV_w, REG_REG       }, //  DIV.w Rd, Rs               1 1 1 0 0 1 1 1  d d d d s s s s
+ {0xe80b,0xff0f,' ',3,DIV_w, REG_DATA8     }, //  DIV.w Rd, #data8           1 1 1 0 1 0 0 0  d d d d 1 0 1 1
+ {0xef00,0xff10,' ',2,DIV_d, REG_REG       }, //  DIV.d Rd, Rs               1 1 1 0 1 1 1 1  d d d 0 s s s s
+ {0xe909,0xff1f,' ',4,DIV_d, REG_DATA16    }, //  DIV.d Rd, #data16          1 1 1 0 1 0 0 1  d d d 0 1 0 0 1
+ {0xe101,0xff00,' ',3,DIVU_b, REG_REG      }, //  DIVU.b Rd, Rs              1 1 1 0 0 0 0 1  d d d d s s s s
+ {0xe801,0xff0f,' ',3,DIVU_b, REG_DATA8    }, //  DIVU.b Rd, #data8          1 1 1 0 1 0 0 0  d d d d 0 0 0 1
+ {0xe500,0xff00,' ',2,DIVU_w, REG_REG      }, //  DIVU.w Rd, Rs              1 1 1 0 0 1 0 1  d d d d s s s s
+ {0xe803,0xff0f,' ',3,DIVU_w, REG_DATA8    }, //  DIVU.w Rd, #data8          1 1 1 0 1 0 0 0  d d d d 0 0 1 1
+ {0xed00,0xff10,' ',2,DIVU_d, REG_REG      }, //  DIVU.d Rd, Rs              1 1 1 0 1 1 0 1  d d d 0 s s s s
+ {0xe901,0xff1f,' ',4,DIVU_d, REG_DATA16   }, //  DIVU.d Rd, #data16         1 1 1 0 1 0 0 1  d d d 0 0 0 0 1
+
+ {0x8708,0xf70f,' ',3,DJNZ,   REG_REL8     }, //  DJNZ Rd, rel8              1 0 0 0 S 1 1 1  d d d d 1 0 0 0
+ {0xe208,0xf7f8,' ',4,DJNZ,   DIRECT_REL8  }, //  DJNZ direct, rel8          1 1 1 0 S 0 1 0  0 0 0 0 1 x x x
+
+ {0xc400,0xff00,' ',4,FCALL,  ADDR24       }, //  FCALL addr24               1 1 0 0 0 1 0 0  
+ {0xd400,0xff00,' ',4,FJMP,   ADDR24       }, //  FJMP addr24                1 1 0 1 0 1 0 0
+ /* JB, JBC */
+ {0xd670,0xfff8,' ',2, JMP,   IREG         }, //  JMP [Rs]                   1 1 0 1 0 1 1 0  0 1 1 1 0 s s s
+ {0xd500,0xff00,' ',3, JMP,   REL16        }, //  JMP rel16                  1 1 0 1 0 1 0 1  rel16
+ /* JMP(2), JNB, JNZ, JZ, LEA(2), LSR(3?)  */
+
  {0x8100,0xf700,' ',2,MOV, REG_REG         },  // MOV Rd, Rs                 1 0 0 0 S 0 0 1  d d d d s s s s
  {0x8200,0xf708,' ',2,MOV, REG_IREG        },  // MOV Rd, [Rs]               1 0 0 0 S 0 1 0  d d d d 0 s s s
  {0x8208,0xf708,' ',2,MOV, IREG_REG        },  // MOV [Rd], Rs               1 0 0 0 S 0 1 0  s s s s 1 d d d
@@ -246,7 +267,10 @@ struct xa_dis_entry disass_xa[]= {
  {0x9d08,0xff8f,' ',6,MOV, IREGOFF16_DATA16},  // MOV [Rd+offset16], #data16 1 0 0 1 1 1 0 1  0 d d d 1 0 0 0
  {0x9608,0xff8f,' ',4,MOV, DIRECT_DATA8    },  // MOV direct, #data8         1 0 0 1 0 1 1 0  0 b b b 1 0 0 0
  {0x9e08,0xff8f,' ',5,MOV, DIRECT_DATA16   },  // MOV direct, #data16        1 0 0 1 0 1 1 0  0 b b b 1 0 0 0
+   /* MOV(5), MOVC(3), MOVS(6), MOVX(2), MUL.x(6), NEG */
 
+ {0x0000,0xff00,' ',1,NOP, NO_OPERANDS     }, //  NOP                        0 0 0 0 0 0 0 0
+   /* NORM */
  {0x6100,0xf700,' ',2, OR, REG_REG         },  //  OR Rd, Rs                 0 1 1 0 S 0 0 1  d d d d s s s s
  {0x6200,0xf708,' ',2, OR, REG_IREG        },  //  OR Rd, [Rs]               0 1 1 0 S 0 1 0  d d d d 0 s s s
  {0x6208,0xf708,' ',2, OR, IREG_REG        },  //  OR [Rd], Rs               0 1 1 0 S 0 1 0  s s s s 1 d d d
@@ -270,6 +294,8 @@ struct xa_dis_entry disass_xa[]= {
  {0x9d06,0xff8f,' ',6, OR, IREGOFF16_DATA16},  //  OR [Rd+offset16], #data16 1 0 0 1 1 1 0 1  0 d d d 0 1 1 0
  {0x9606,0xff8f,' ',4, OR, DIRECT_DATA8    },  //  OR direct, #data8         1 0 0 1 0 1 1 0  0 b b b 0 1 1 0
  {0x9e06,0xff8f,' ',5, OR, DIRECT_DATA16   },  //  OR direct, #data16        1 0 0 1 0 1 1 0  0 b b b 0 1 1 0
+   /* ORL(2), POP(2), POPU(2), PUSH(2), PUSHU(2), RESET, RET, RETI,
+      RL, RLC, RR, RRC, SETB, SEXT */
 
  {0x2100,0xf700,' ',2,SUB, REG_REG         },  // SUB Rd, Rs                 0 0 1 0 S 0 0 1  d d d d s s s s
  {0x2200,0xf708,' ',2,SUB, REG_IREG        },  // SUB Rd, [Rs]               0 0 1 0 S 0 1 0  d d d d 0 s s s
@@ -318,6 +344,7 @@ struct xa_dis_entry disass_xa[]= {
  {0x9d03,0xff8f,' ',6,SUBB,IREGOFF16_DATA16},  //SUBB [Rd+offset16], #data16 1 0 0 1 1 1 0 1  0 d d d 0 0 1 1
  {0x9603,0xff8f,' ',4,SUBB,DIRECT_DATA8    },  //SUBB direct, #data8         1 0 0 1 0 1 1 0  0 b b b 0 0 1 1
  {0x9e03,0xff8f,' ',5,SUBB,DIRECT_DATA16   },  //SUBB direct, #data16        1 0 0 1 0 1 1 0  0 b b b 0 0 1 1
+   /* TRAP, XCH(3) */
 
  {0x7100,0xf700,' ',2,XOR, REG_REG         },  // XOR Rd, Rs                 0 1 1 1 S 0 0 1  d d d d s s s s
  {0x7200,0xf708,' ',2,XOR, REG_IREG        },  // XOR Rd, [Rs]               0 1 1 1 S 0 1 0  d d d d 0 s s s
@@ -343,11 +370,6 @@ struct xa_dis_entry disass_xa[]= {
  {0x9607,0xff8f,' ',4,XOR, DIRECT_DATA8    },  // XOR direct, #data8         1 0 0 1 0 1 1 0  0 b b b 0 1 1 1
  {0x9e07,0xff8f,' ',5,XOR, DIRECT_DATA16   },  // XOR direct, #data16        1 0 0 1 0 1 1 0  0 b b b 0 1 1 1
 
- {0xc500,0xff00,' ',3,CALL, REL16          },  // CALL rel16                 1 1 0 0 0 1 0 1  rel16
- {0xc600,0xfff8,' ',2,CALL, IREG_ALONE     },  // CALL [Rs]                  1 1 0 0 0 1 1 0  0 0 0 0 0 s s s
-
- {0xf300,0xff00,' ',2,BEQ, REL8            },  // BEQ rel8                   1 1 1 1 0 0 1 1  rel8
-
  {0x0000,0x0000,  0,1,BAD_OPCODE, REG_REG}
 };
 
index b8a4284e6c26b36d206286bb80219b81a2d98212..351e6976dc50bc4ca5a29b5e2ee198b018fc28de 100644 (file)
@@ -32,19 +32,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "stypes.h"
 
-
-#if 0
-enum {
-  REG,
-  IND_REG,
-  IND_REG_PLUS,
-  IND_REG_OFFSET,
-  DIRECT,
-  DATA8,
-  DATA16
-};
-#endif
-
+/* this needs to match char *op_mnemonic_str[] definition in glob.cc */
 enum {
 BAD_OPCODE=0,
 ADD,
@@ -104,12 +92,17 @@ TRAP,
 RESET,
 FCALL,
 FJMP,
+IREG,
 };
 
 extern char *op_mnemonic_str[];
 
+/* this classifies the operands and is used in the dissassembly
+   to print the operands.  Its also used in the simulation to characterize
+   the op-code function.
+ */   
 enum op_operands {
-   // the repeating common parameter encoding for ADD, ADDC, SUB, AND...
+   // the repeating parameter encoding for ADD, ADDC, SUB, SUBB, AND, XOR, ...
   REG_REG         ,
   REG_IREG        ,
   IREG_REG        ,
@@ -152,7 +145,7 @@ enum op_operands {
   DIRECT_REL8,
 
   REL8,
-  REL16,
+  REL16
 };
 
 // table of dissassembled instructions
@@ -161,8 +154,6 @@ struct xa_dis_entry
   uint  code, mask;
   char  branch;
   uchar length;
-//  enum op_mnemonic mnemonic;
-//  enum op_operands operands;
   int mnemonic;
   int operands;
 };
index 218ec440eec5399277e130653ca4fba0ee2f7750..cfb91214598f38e50ec6c62e74ca439d10840959 100644 (file)
@@ -37,21 +37,21 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 int
 cl_xa::get_reg(int word_flag, unsigned int index)
 {
-  if (index < 3) { /* banked */
+  //if (index < 3) { /* banked */
+  //  if (word_flag)
+  //    return get_word_direct(0x400+index);
+  //  else
+  //    return mem_direct[0x400+index];
+  //} else { /* non-banked */
     if (word_flag)
       return get_word_direct(0x400+index);
     else
       return mem_direct[0x400+index];
-  } else { /* non-banked */
-    if (word_flag)
-      return get_word_direct(0x400+index);
-    else
-      return mem_direct[0x400+index];
-  }
+  //}
 }
 
 int
-cl_xa::inst_NOP(uint code)
+cl_xa::inst_NOP(uint code, int operands)
 {
   return(resGO);
 }
@@ -62,10 +62,8 @@ cl_xa::inst_NOP(uint code)
 #define RI_07 (code & 0x7)
 
 int
-cl_xa::inst_ADD(uint code)
+cl_xa::inst_ADD(uint code, int operands)
 {
-  int operands = code >> 16;  // kludgy, param info
-
 #undef FUNC1
 #define FUNC1 add1
 #undef FUNC2
@@ -76,10 +74,8 @@ cl_xa::inst_ADD(uint code)
 }
 
 int
-cl_xa::inst_ADDC(uint code)
+cl_xa::inst_ADDC(uint code, int operands)
 {
-  int operands = code >> 16;  // kludgy, param info
-
 #undef FUNC1
 #define FUNC1 addc1
 #undef FUNC2
@@ -90,239 +86,291 @@ cl_xa::inst_ADDC(uint code)
 }
 
 int
-cl_xa::inst_SUB(uint code)
+cl_xa::inst_SUB(uint code, int operands)
 {
+#undef FUNC1
+#define FUNC1 sub1
+#undef FUNC2
+#define FUNC2 sub2
+#include "inst_gen.cc"
   return(resGO);
 }
 
 int
-cl_xa::inst_SUBB(uint code)
+cl_xa::inst_SUBB(uint code, int operands)
 {
+#undef FUNC1
+#define FUNC1 subb1
+#undef FUNC2
+#define FUNC2 subb2
+#include "inst_gen.cc"
   return(resGO);
 }
 
 int
-cl_xa::inst_CMP(uint code)
+cl_xa::inst_CMP(uint code, int operands)
 {
+#undef FUNC1
+#define FUNC1 cmp1
+#undef FUNC2
+#define FUNC2 cmp2
+#include "inst_gen.cc"
   return(resGO);
 }
 int
-cl_xa::inst_AND(uint code)
+cl_xa::inst_AND(uint code, int operands)
 {
+#undef FUNC1
+#define FUNC1 and1
+#undef FUNC2
+#define FUNC2 and2
+#include "inst_gen.cc"
   return(resGO);
 }
 int
-cl_xa::inst_OR(uint code)
+cl_xa::inst_OR(uint code, int operands)
 {
+#undef FUNC1
+#define FUNC1 or1
+#undef FUNC2
+#define FUNC2 or2
+#include "inst_gen.cc"
   return(resGO);
 }
 int
-cl_xa::inst_XOR(uint code)
+cl_xa::inst_XOR(uint code, int operands)
 {
+#undef FUNC1
+#define FUNC1 xor1
+#undef FUNC2
+#define FUNC2 xor2
+#include "inst_gen.cc"
   return(resGO);
 }
 int
-cl_xa::inst_ADDS(uint code)
+cl_xa::inst_ADDS(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_NEG(uint code)
+cl_xa::inst_NEG(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_SEXT(uint code)
+cl_xa::inst_SEXT(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_MUL(uint code)
+cl_xa::inst_MUL(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_DIV(uint code)
+cl_xa::inst_DIV(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_DA(uint code)
+cl_xa::inst_DA(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_ASL(uint code)
+cl_xa::inst_ASL(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_ASR(uint code)
+cl_xa::inst_ASR(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_LEA(uint code)
+cl_xa::inst_LEA(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_CPL(uint code)
+cl_xa::inst_CPL(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_LSR(uint code)
+cl_xa::inst_LSR(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_NORM(uint code)
+cl_xa::inst_NORM(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_RL(uint code)
+cl_xa::inst_RL(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_RLC(uint code)
+cl_xa::inst_RLC(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_RR(uint code)
+cl_xa::inst_RR(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_RRC(uint code)
+cl_xa::inst_RRC(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_MOVS(uint code)
+cl_xa::inst_MOVS(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_MOVC(uint code)
+cl_xa::inst_MOVC(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_MOVX(uint code)
+cl_xa::inst_MOVX(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_PUSH(uint code)
+cl_xa::inst_PUSH(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_POP(uint code)
+cl_xa::inst_POP(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_XCH(uint code)
+cl_xa::inst_XCH(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_SETB(uint code)
+cl_xa::inst_SETB(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_CLR(uint code)
+cl_xa::inst_CLR(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_MOV(uint code)
+cl_xa::inst_MOV(uint code, int operands)
 {
+#undef FUNC1
+#define FUNC1 mov1
+#undef FUNC2
+#define FUNC2 mov2
+#include "inst_gen.cc"
   return(resGO);
 }
 int
-cl_xa::inst_ANL(uint code)
+cl_xa::inst_ANL(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_ORL(uint code)
+cl_xa::inst_ORL(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_BR(uint code)
+cl_xa::inst_BR(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_JMP(uint code)
+cl_xa::inst_JMP(uint code, int operands)
 {
+  unsigned int jmpaddr;
+  short saddr;
+
+  switch(operands) {
+    case REL16:
+    {
+      saddr = fetch2();
+      jmpaddr = saddr;
+      jmpaddr *= 2;
+      PC = (PC + 3) + jmpaddr;
+    }
+    break;
+    case IREG:
+      PC = reg2(RI_07) & 0xfffe;  /* word aligned */
+    break;
+    /* fixme 2 more... */
+  }
   return(resGO);
 }
 int
-cl_xa::inst_CALL(uint code)
+cl_xa::inst_CALL(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_RET(uint code)
+cl_xa::inst_RET(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_Bcc(uint code)
+cl_xa::inst_Bcc(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_JB(uint code)
+cl_xa::inst_JB(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_JNB(uint code)
+cl_xa::inst_JNB(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_CJNE(uint code)
+cl_xa::inst_CJNE(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_DJNZ(uint code)
+cl_xa::inst_DJNZ(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_JZ(uint code)
+cl_xa::inst_JZ(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_JNZ(uint code)
+cl_xa::inst_JNZ(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_BKPT(uint code)
+cl_xa::inst_BKPT(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_TRAP(uint code)
+cl_xa::inst_TRAP(uint code, int operands)
 {
   return(resGO);
 }
 int
-cl_xa::inst_RESET(uint code)
+cl_xa::inst_RESET(uint code, int operands)
 {
   return(resGO);
 }
index eafb01f616df0c5fbe47d24e385d8bfea043719b..821a5becb8bf3757758016754445be1950f407d4 100644 (file)
@@ -1,54 +1,54 @@
 /* xa.src/instcl.h */
 
-  virtual int inst_NOP(uint code);
-  virtual int inst_ADD(uint code);
-  virtual int inst_ADDC(uint code);
-  virtual int inst_SUB(uint code);
-  virtual int inst_SUBB(uint code);
-  virtual int inst_CMP(uint code);
-  virtual int inst_AND(uint code);
-  virtual int inst_OR(uint code);
-  virtual int inst_XOR(uint code);
-  virtual int inst_ADDS(uint code);
-  virtual int inst_NEG(uint code);
-  virtual int inst_SEXT(uint code);
-  virtual int inst_MUL(uint code);
-  virtual int inst_DIV(uint code);
-  virtual int inst_DA(uint code);
-  virtual int inst_ASL(uint code);
-  virtual int inst_ASR(uint code);
-  virtual int inst_LEA(uint code);
-  virtual int inst_CPL(uint code);
-  virtual int inst_LSR(uint code);
-  virtual int inst_NORM(uint code);
-  virtual int inst_RL(uint code);
-  virtual int inst_RLC(uint code);
-  virtual int inst_RR(uint code);
-  virtual int inst_RRC(uint code);
-  virtual int inst_MOVS(uint code);
-  virtual int inst_MOVC(uint code);
-  virtual int inst_MOVX(uint code);
-  virtual int inst_PUSH(uint code);
-  virtual int inst_POP(uint code);
-  virtual int inst_XCH(uint code);
-  virtual int inst_SETB(uint code);
-  virtual int inst_CLR(uint code);
-  virtual int inst_MOV(uint code);
-  virtual int inst_ANL(uint code);
-  virtual int inst_ORL(uint code);
-  virtual int inst_BR(uint code);
-  virtual int inst_JMP(uint code);
-  virtual int inst_CALL(uint code);
-  virtual int inst_RET(uint code);
-  virtual int inst_Bcc(uint code);
-  virtual int inst_JB(uint code);
-  virtual int inst_JNB(uint code);
-  virtual int inst_CJNE(uint code);
-  virtual int inst_DJNZ(uint code);
-  virtual int inst_JZ(uint code);
-  virtual int inst_JNZ(uint code);
-  virtual int inst_BKPT(uint code);
-  virtual int inst_TRAP(uint code);
-  virtual int inst_RESET(uint code);
+  virtual int inst_NOP(uint code, int operands);
+  virtual int inst_ADD(uint code, int operands);
+  virtual int inst_ADDC(uint code, int operands);
+  virtual int inst_SUB(uint code, int operands);
+  virtual int inst_SUBB(uint code, int operands);
+  virtual int inst_CMP(uint code, int operands);
+  virtual int inst_AND(uint code, int operands);
+  virtual int inst_OR(uint code, int operands);
+  virtual int inst_XOR(uint code, int operands);
+  virtual int inst_ADDS(uint code, int operands);
+  virtual int inst_NEG(uint code, int operands);
+  virtual int inst_SEXT(uint code, int operands);
+  virtual int inst_MUL(uint code, int operands);
+  virtual int inst_DIV(uint code, int operands);
+  virtual int inst_DA(uint code, int operands);
+  virtual int inst_ASL(uint code, int operands);
+  virtual int inst_ASR(uint code, int operands);
+  virtual int inst_LEA(uint code, int operands);
+  virtual int inst_CPL(uint code, int operands);
+  virtual int inst_LSR(uint code, int operands);
+  virtual int inst_NORM(uint code, int operands);
+  virtual int inst_RL(uint code, int operands);
+  virtual int inst_RLC(uint code, int operands);
+  virtual int inst_RR(uint code, int operands);
+  virtual int inst_RRC(uint code, int operands);
+  virtual int inst_MOVS(uint code, int operands);
+  virtual int inst_MOVC(uint code, int operands);
+  virtual int inst_MOVX(uint code, int operands);
+  virtual int inst_PUSH(uint code, int operands);
+  virtual int inst_POP(uint code, int operands);
+  virtual int inst_XCH(uint code, int operands);
+  virtual int inst_SETB(uint code, int operands);
+  virtual int inst_CLR(uint code, int operands);
+  virtual int inst_MOV(uint code, int operands);
+  virtual int inst_ANL(uint code, int operands);
+  virtual int inst_ORL(uint code, int operands);
+  virtual int inst_BR(uint code, int operands);
+  virtual int inst_JMP(uint code, int operands);
+  virtual int inst_CALL(uint code, int operands);
+  virtual int inst_RET(uint code, int operands);
+  virtual int inst_Bcc(uint code, int operands);
+  virtual int inst_JB(uint code, int operands);
+  virtual int inst_JNB(uint code, int operands);
+  virtual int inst_CJNE(uint code, int operands);
+  virtual int inst_DJNZ(uint code, int operands);
+  virtual int inst_JZ(uint code, int operands);
+  virtual int inst_JNZ(uint code, int operands);
+  virtual int inst_BKPT(uint code, int operands);
+  virtual int inst_TRAP(uint code, int operands);
+  virtual int inst_RESET(uint code, int operands);
 
 /* End of xa.src/instcl.h */
index ee7134b4e1135a8bd00656cac664b59a8fd37122..72729827cb0211fd8c1b532ed03fe10e8bad1396 100644 (file)
@@ -37,6 +37,10 @@ struct t_regs
   int dummy;
 };
 
+/* macros suck, can we use inline functions instead
+   for the same effect? karl
+*/
+
 /* direct is a special code space for built-in ram and SFR, 1K size */
 #ifdef WORDS_BIGENDIAN
 #define set_word_direct(_index, _value) { \
@@ -106,13 +110,7 @@ struct t_regs
 
 // fixme: I don't know where the psw is kept, just want to compile...
 #define get_psw() ((TYPE_UWORD)(get_word_direct(0x400+(0x80*2))))
-
-/* we also need to set flags, this scheme no setup well to do this yet... */
-#define add1(_a, _b) ( (unsigned char)((_a) + (_b)) )
-#define add2(_a, _b) ( (unsigned short)((_a) + (_b)) )
-
-#define addc1(_a, _b) ( (unsigned char)((_a) + (_b)) )
-#define addc2(_a, _b) ( (unsigned short)((_a) + (_b)) )
+#define set_psw(_flags) set_word_direct(0x400+(0x80*2), _flags)
 
 #if 0
 --------------------------------------------------------------------
@@ -187,6 +185,7 @@ default SPs are set to 100H.  So first PUSH would go to FEH-FFH.
 #define BIT_V  0x04
 #define BIT_N  0x02
 #define BIT_Z  0x01
+#define BIT_ALL (BIT_C | BIT_AC | BIT_V | BIT_N | BIT_Z)
 
 #endif
 /* End of xa.src/regsxa.h */
index 67c3f671aa024dc950ceace31cab4d70d553a53d..9f214bdf47d083f7e765ebfe869dceb514c64d4b 100644 (file)
@@ -539,133 +539,148 @@ cl_xa::print_regs(class cl_console *con)
 int
 cl_xa::exec_inst(void)
 {
-  t_mem code1, code2;
+  t_mem code1;
   uint code;
   int i;
+  int operands;
 
   if (fetch(&code1))
     return(resBREAKPOINT);
   tick(1);
 
-  if (code1 == 0) // nop, 1 byte instr
-    return(inst_NOP(code1));
-
-  if (fetch(&code2))
-    return(resBREAKPOINT);
-  code = (code1 << 8) | code2;
+/* the following lookups make for a slow simulation, we will
+  figure out how to make it fast later... */
 
+  /* scan to see if its a 1 byte-opcode */
+  code = (code1 << 8);
   i= 0;
-  while ((code & disass_xa[i].mask) != disass_xa[i].code &&
+  while ( ((code & disass_xa[i].mask) != disass_xa[i].code ||
+           ((disass_xa[i].mask & 0x00ff) != 0)) /* one byte op code */
+                    &&
          disass_xa[i].mnemonic != BAD_OPCODE)
     i++;
 
-  code |= ((int)(disass_xa[i].operands)) << 16;  // kludgy, tack on operands info
+  if (disass_xa[i].mnemonic == BAD_OPCODE) {
+    /* hit the end of the list, must be a 2 or more byte opcode */
+    /* fetch another code byte and search the list again */
+      //if (fetch(&code2))  ?not sure if break allowed in middle of opcode?
+      //  return(resBREAKPOINT);
+    code |= fetch();  /* add 2nd opcode */
+
+    i= 0;
+    while ((code & disass_xa[i].mask) != disass_xa[i].code &&
+           disass_xa[i].mnemonic != BAD_OPCODE)
+      i++;
+    /* we should have found the opcode by now, if not invalid entry at eol */
+  }
+
+  operands = (int)(disass_xa[i].operands);
   switch (disass_xa[i].mnemonic)
   {
     case ADD:
-    return inst_ADD(code);
+    return inst_ADD(code, operands);
     case ADDC:
-    return inst_ADDC(code);
+    return inst_ADDC(code, operands);
     case SUB:
-    return inst_SUB(code);
+    return inst_SUB(code, operands);
     case SUBB:
-    return inst_SUBB(code);
+    return inst_SUBB(code, operands);
     case CMP:
-    return inst_CMP(code);
+    return inst_CMP(code, operands);
     case AND:
-    return inst_AND(code);
+    return inst_AND(code, operands);
     case OR:
-    return inst_OR(code);
+    return inst_OR(code, operands);
     case XOR:
-    return inst_XOR(code);
+    return inst_XOR(code, operands);
     case ADDS:
-    return inst_ADDS(code);
+    return inst_ADDS(code, operands);
     case NEG:
-    return inst_NEG(code);
+    return inst_NEG(code, operands);
     case SEXT:
-    return inst_SEXT(code);
+    return inst_SEXT(code, operands);
     case MUL:
-    return inst_MUL(code);
+    return inst_MUL(code, operands);
     case DIV_w :
     case DIV_d :
     case DIVU_b:
     case DIVU_w:
     case DIVU_d:
-    return inst_DIV(code);
+    return inst_DIV(code, operands);
     case DA:
-    return inst_DA(code);
+    return inst_DA(code, operands);
     case ASL:
-    return inst_ASL(code);
+    return inst_ASL(code, operands);
     case ASR:
-    return inst_ASR(code);
+    return inst_ASR(code, operands);
     case LEA:
-    return inst_LEA(code);
+    return inst_LEA(code, operands);
     case CPL:
-    return inst_CPL(code);
+    return inst_CPL(code, operands);
     case LSR:
-    return inst_LSR(code);
+    return inst_LSR(code, operands);
     case NORM:
-    return inst_NORM(code);
+    return inst_NORM(code, operands);
     case RL:
-    return inst_RL(code);
+    return inst_RL(code, operands);
     case RLC:
-    return inst_RLC(code);
+    return inst_RLC(code, operands);
     case RR:
-    return inst_RR(code);
+    return inst_RR(code, operands);
     case RRC:
-    return inst_RRC(code);
+    return inst_RRC(code, operands);
     case MOVS:
-    return inst_MOVS(code);
+    return inst_MOVS(code, operands);
     case MOVC:
-    return inst_MOVC(code);
+    return inst_MOVC(code, operands);
     case MOVX:
-    return inst_MOVX(code);
+    return inst_MOVX(code, operands);
     case PUSH:
-    return inst_PUSH(code);
+    return inst_PUSH(code, operands);
     case POP:
-    return inst_POP(code);
+    return inst_POP(code, operands);
     case XCH:
-    return inst_XCH(code);
+    return inst_XCH(code, operands);
     case SETB:
-    return inst_SETB(code);
+    return inst_SETB(code, operands);
     case CLR:
-    return inst_CLR(code);
+    return inst_CLR(code, operands);
     case MOV:
-    return inst_MOV(code);
+    return inst_MOV(code, operands);
     case ANL:
-    return inst_ANL(code);
+    return inst_ANL(code, operands);
     case ORL:
-    return inst_ORL(code);
+    return inst_ORL(code, operands);
     case BR:
-    return inst_BR(code);
+    return inst_BR(code, operands);
     case JMP:
-    return inst_JMP(code);
+    return inst_JMP(code, operands);
     case CALL:
-    return inst_CALL(code);
+    return inst_CALL(code, operands);
     case RET:
-    return inst_RET(code);
+    return inst_RET(code, operands);
     case Bcc:
-    return inst_Bcc(code);
+    return inst_Bcc(code, operands);
     case JB:
-    return inst_JB(code);
+    return inst_JB(code, operands);
     case JNB:
-    return inst_JNB(code);
+    return inst_JNB(code, operands);
     case CJNE:
-    return inst_CJNE(code);
+    return inst_CJNE(code, operands);
     case DJNZ:
-    return inst_DJNZ(code);
+    return inst_DJNZ(code, operands);
     case JZ:
-    return inst_JZ(code);
+    return inst_JZ(code, operands);
     case JNZ:
-    return inst_JNZ(code);
+    return inst_JNZ(code, operands);
     case NOP:
-    return inst_NOP(code);
+    return inst_NOP(code, operands);
     case BKPT:
-    return inst_BKPT(code);
+    return inst_BKPT(code, operands);
     case TRAP:
-    return inst_TRAP(code);
+    return inst_TRAP(code, operands);
     case RESET:
-    return inst_RESET(code);
+    return inst_RESET(code, operands);
     case BAD_OPCODE:
     default:
     break;
index e21d4f0e709cc15a47b4d87dcde62f5a9f37d025..5b330452f777735f375301aeaf410d9edb520f46 100644 (file)
@@ -79,8 +79,303 @@ public:
   virtual int get_reg(int word_flag, unsigned int index);
 
 #include "instcl.h"
-};
 
+  private :
+
+   /* following are macros which get substituted for FUNC1() and FUNC2()
+      in the inst.cc to form the body of ADD,ADDC,SUB,XOR,... */
+  /* can I put these in the .cc file and still have them do the inline thing? */
+  /*-------------------------------------
+    add - flags changed:C,AC,V,N,Z.
+  |---------------------------------------*/
+  inline unsigned char add1(unsigned char dst, unsigned char src)
+  {
+    unsigned int result;
+    unsigned char flags;
+    flags = get_psw();
+    flags &= ~BIT_ALL; /* clear these bits */
+    result = dst + src;
+    if (result == 0) flags |= BIT_Z;
+    if (result > 0xff) flags |= BIT_C;
+    if (result & 0x80) flags |= BIT_N;
+    /* fixme: do AC, V */
+    set_psw(flags);
+    return (unsigned char) result;
+  }
+
+  inline unsigned short add2(unsigned short dst, unsigned short src)
+  {
+    unsigned int result;
+    unsigned char flags;
+    flags = get_psw();
+    flags &= ~BIT_ALL; /* clear these bits */
+    result = dst + src;
+    if (result == 0) flags |= BIT_Z;
+    if (result > 0xff) flags |= BIT_C;
+    if (result & 0x80) flags |= BIT_N;
+    /* fixme: do AC, V */
+    set_psw(flags);
+    return (unsigned short) result;
+  }
+
+  /*-------------------------------------
+    addc - flags changed:C,AC,V,N,Z.
+  |---------------------------------------*/
+  inline unsigned char addc1(unsigned char dst, unsigned char src)
+  {
+    unsigned int result;
+    unsigned char flags;
+    flags = get_psw();
+    if (flags & BIT_C) {
+      flags &= ~BIT_ALL; /* clear these bits */
+      result = dst + src + 1;
+    } else {
+      flags &= ~BIT_ALL; /* clear these bits */
+      result = dst + src;
+    }
+    if (result == 0) flags |= BIT_Z;
+    if (result > 0xff) flags |= BIT_C;
+    if (result & 0x80) flags |= BIT_N;
+    /* fixme: do AC, V */
+    set_psw(flags);
+    return (unsigned char) result;
+  }
+
+  inline unsigned short addc2(unsigned short dst, unsigned short src)
+  {
+    unsigned int result;
+    unsigned char flags;
+    flags = get_psw();
+    flags &= ~BIT_ALL; /* clear these bits */
+    if (flags & BIT_C) {
+      flags &= ~BIT_ALL; /* clear these bits */
+      result = dst + src + 1;
+    } else {
+      flags &= ~BIT_ALL; /* clear these bits */
+      result = dst + src;
+    }
+    if (result == 0) flags |= BIT_Z;
+    if (result > 0xff) flags |= BIT_C;
+    if (result & 0x80) flags |= BIT_N;
+    /* fixme: do AC, V */
+    set_psw(flags);
+    return (unsigned short) result;
+  }
+
+  /*-------------------------------------
+    sub - flags changed:C,AC,V,N,Z.
+  |---------------------------------------*/
+  inline unsigned char sub1(unsigned char dst, unsigned char src)
+  {
+    unsigned int result;
+    unsigned char flags;
+    flags = get_psw();
+    flags &= ~BIT_ALL; /* clear these bits */
+    result = dst - src;
+    if (result == 0) flags |= BIT_Z;
+    if (result > 0xff) flags |= BIT_C;
+    if (dst < src) flags |= BIT_N;
+    /* fixme: do AC, V */
+    set_psw(flags);
+    return (unsigned char) result;
+  }
+
+  inline unsigned short sub2(unsigned short dst, unsigned short src)
+  {
+    unsigned int result;
+    unsigned char flags;
+    flags = get_psw();
+    flags &= ~BIT_ALL; /* clear these bits */
+    result = dst - src;
+    if (result == 0) flags |= BIT_Z;
+    if (result > 0xff) flags |= BIT_C;
+    if (dst < src) flags |= BIT_N;
+    /* fixme: do AC, V */
+    set_psw(flags);
+    return (unsigned short) result;
+  }
+
+  /*-------------------------------------
+    subb - flags changed:C,AC,V,N,Z.
+  |---------------------------------------*/
+  inline unsigned char subb1(unsigned char dst, unsigned char src)
+  {
+    unsigned int result;
+    unsigned char flags;
+    flags = get_psw();
+    if (flags & BIT_C) {
+      flags &= ~BIT_ALL; /* clear these bits */
+      result = dst - src - 1;
+    } else {
+      flags &= ~BIT_ALL; /* clear these bits */
+      result = dst - src;
+    }
+    if (result == 0) flags |= BIT_Z;
+    if (result > 0xff) flags |= BIT_C;
+    if (dst < src) flags |= BIT_N;
+    /* fixme: do AC, V */
+    set_psw(flags);
+    return (unsigned char) result;
+  }
+
+  inline unsigned short subb2(unsigned short dst, unsigned short src)
+  {
+    unsigned int result;
+    unsigned char flags;
+    flags = get_psw();
+    flags &= ~BIT_ALL; /* clear these bits */
+    if (flags & BIT_C) {
+      flags &= ~BIT_ALL; /* clear these bits */
+      result = dst - src - 1;
+    } else {
+      flags &= ~BIT_ALL; /* clear these bits */
+      result = dst - src;
+    }
+    if (result == 0) flags |= BIT_Z;
+    if (result > 0xff) flags |= BIT_C;
+    if (dst < src) flags |= BIT_N;
+    /* fixme: do AC, V */
+    set_psw(flags);
+    return (unsigned short) result;
+  }
+
+  /*-------------------------------------
+    cmp - flags changed:C,AC,V,N,Z.
+  |---------------------------------------*/
+  inline unsigned char cmp1(unsigned char dst, unsigned char src)
+  {
+    unsigned int result;
+    unsigned char flags;
+    flags = get_psw();
+    flags &= ~BIT_ALL; /* clear these bits */
+    result = dst - src;
+    if (result == 0) flags |= BIT_Z;
+    if (result > 0xff) flags |= BIT_C;
+    if (dst < src) flags |= BIT_N;
+    /* fixme: do AC, V */
+    set_psw(flags);
+    return (unsigned char) dst;
+  }
+
+  inline unsigned short cmp2(unsigned short dst, unsigned short src)
+  {
+    unsigned int result;
+    unsigned char flags;
+    flags = get_psw();
+    flags &= ~BIT_ALL; /* clear these bits */
+    result = dst - src;
+    if (result == 0) flags |= BIT_Z;
+    if (result > 0xff) flags |= BIT_C;
+    if (dst < src) flags |= BIT_N;
+    /* fixme: do AC, V */
+    set_psw(flags);
+    return (unsigned short) dst;
+  }
+
+  /*-------------------------------------
+    and - flags changed:N,Z.
+  |---------------------------------------*/
+  inline unsigned char and1(unsigned char dst, unsigned char src)
+  {
+    unsigned int result;
+    unsigned char flags;
+    flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+    result = dst & src;
+    if (result == 0) flags |= BIT_Z;
+    if (result & 0x80) flags |= BIT_N;
+    set_psw(flags);
+    return (unsigned char) result;
+  }
+
+  inline unsigned short and2(unsigned short dst, unsigned short src)
+  {
+    unsigned int result;
+    unsigned char flags;
+    flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+    result = dst & src;
+    if (result == 0) flags |= BIT_Z;
+    if (result & 0x80) flags |= BIT_N;
+    set_psw(flags);
+    return (unsigned short) result;
+  }
+
+  /*-------------------------------------
+    or - flags changed:N,Z.
+  |---------------------------------------*/
+  inline unsigned char or1(unsigned char dst, unsigned char src)
+  {
+    unsigned int result;
+    unsigned char flags;
+    flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+    result = dst | src;
+    if (result == 0) flags |= BIT_Z;
+    if (result & 0x80) flags |= BIT_N;
+    set_psw(flags);
+    return (unsigned char) result;
+  }
+
+  inline unsigned short or2(unsigned short dst, unsigned short src)
+  {
+    unsigned int result;
+    unsigned char flags;
+    flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+    result = dst | src;
+    if (result == 0) flags |= BIT_Z;
+    if (result & 0x80) flags |= BIT_N;
+    set_psw(flags);
+    return (unsigned short) result;
+  }
+
+  /*-------------------------------------
+    xor - flags changed:N,Z.
+  |---------------------------------------*/
+  inline unsigned char xor1(unsigned char dst, unsigned char src)
+  {
+    unsigned char flags;
+    flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+    dst ^= src;
+    if (dst == 0) flags |= BIT_Z;
+    if (dst & 0x80) flags |= BIT_N;
+    set_psw(flags);
+    return (unsigned char) dst;
+  }
+
+  inline unsigned short xor2(unsigned short dst, unsigned short src)
+  {
+    unsigned char flags;
+    flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+    dst ^= src;
+    if (dst == 0) flags |= BIT_Z;
+    if (dst & 0x8000) flags |= BIT_N;
+    set_psw(flags);
+    return (unsigned short) dst;
+  }
+
+  /*-------------------------------------
+    mov - flags changed:N,Z.
+  |---------------------------------------*/
+  inline unsigned char mov1(unsigned char dst, unsigned char src)
+  {
+    unsigned char flags;
+    flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+    dst = src;
+    if (dst == 0) flags |= BIT_Z;
+    if (dst & 0x80) flags |= BIT_N;
+    set_psw(flags);
+    return (unsigned char) dst;
+  }
+
+  inline unsigned short mov2(unsigned short dst, unsigned short src)
+  {
+    unsigned char flags;
+    flags = get_psw() & ~(BIT_N | BIT_Z); /* clear these bits */
+    dst = src;
+    if (dst == 0) flags |= BIT_Z;
+    if (dst & 0x8000) flags |= BIT_N;
+    set_psw(flags);
+    return (unsigned short) dst;
+  }
+};
 
 #endif