#include "stypes.h"
#include "glob.h"
+/* this needs to match enum definition in glob.h */
char *op_mnemonic_str[] = {
"BAD_OPCODE",
"ADD",
"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
{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
{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
{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
{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
{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
{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
{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}
};
#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,
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 ,
DIRECT_REL8,
REL8,
- REL16,
+ REL16
};
// table of dissassembled instructions
uint code, mask;
char branch;
uchar length;
-// enum op_mnemonic mnemonic;
-// enum op_operands operands;
int mnemonic;
int operands;
};
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);
}
#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
}
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
}
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);
}
/* 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 */
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) { \
// 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
--------------------------------------------------------------------
#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 */
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;
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