⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inst.cc

📁 sdcc是为51等小型嵌入式cpu设计的c语言编译器支持数种不同类型的cpu
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* * Simulator of microcontrollers (inst.cc) * * Copyright (C) 1999,2002 Drotos Daniel, Talker Bt. * * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu * Other contributors include: *   Karl Bongers karl@turbobit.com, *   Johan Knol johan.knol@iduna.nl * *//* This file is part of microcontroller simulator: ucsim.UCSIM is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.UCSIM is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with UCSIM; see the file COPYING.  If not, write to the FreeSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA02111-1307, USA. *//*@1@*/#include "ddconfig.h"#include <stdlib.h>// local#include "glob.h"#include "xacl.h"#include "regsxa.h"#define NOTDONE_ASSERT { printf("**********Instr not done at %d!\n", __LINE__); }void cl_xa::store1(t_addr addr, unsigned char val){  if (addr < 0x2000) {    set_idata1(addr, val);  } else {    set_xdata1(addr, val);  }}void cl_xa::store2(t_addr addr, unsigned short val){  if (addr < 0x2000) {    set_idata2(addr, val);  } else {    set_xdata2(addr, val);  }}unsigned char cl_xa::get1(t_addr addr){  if (addr < 0x2000) {    return get_idata1(addr);  } else {    return get_xdata1(addr);  }}unsigned short cl_xa::get2(t_addr addr){  if (addr < 0x2000) {    return get_idata2(addr);  } else {    return get_xdata2(addr);  }}int cl_xa::get_reg(int word_flag, unsigned int index){  int result;  if (word_flag) {    result = get_word_direct(index);  }  else {    result = get_byte_direct(index);  }  return result;}bool cl_xa::get_bit(int bit) {  short offset=0;  unsigned char result;  if (bit>=0x200) {    // in sfr space    bit-=0x200;    offset=0x400;  }  result = get_byte_direct(offset + (bit/8)) & (1 << (bit%8));  return result;}void cl_xa::set_bit(int bit, int value) {  int i;  short offset=0;  if (bit>=0x200) {    // in sfr space    bit-=0x200;    offset=0x400;  }  i = get_byte_direct(offset + (bit/8));  if (value) {    set_byte_direct(offset + (bit/8), i | (1 << (bit%8)) );  } else {    set_byte_direct(offset + (bit/8), i & ~(1 << (bit%8)) );  }}#define RI_F0 ((code >> 4) & 0xf)#define RI_70 ((code >> 4) & 0x7)#define RI_0F (code & 0xf)#define RI_07 (code & 0x7)int cl_xa::inst_ADD(uint code, int operands){#undef FUNC1#define FUNC1 add1#undef FUNC2#define FUNC2 add2#include "inst_gen.cc"  return(resGO);}int cl_xa::inst_ADDC(uint code, int operands){#undef FUNC1#define FUNC1 addc1#undef FUNC2#define FUNC2 addc2#include "inst_gen.cc"  return(resGO);}int cl_xa::inst_ADDS(uint code, int operands){  NOTDONE_ASSERT;  return(resGO);}int cl_xa::inst_AND(uint code, int operands){#undef FUNC1#define FUNC1 and1#undef FUNC2#define FUNC2 and2#include "inst_gen.cc"  return(resGO);}/* logical AND bit with Carry flag */int cl_xa::inst_ANL(uint code, int operands){ unsigned char flags; unsigned short bitAddr = (code&0x03 << 8) + fetch(); flags = get_psw();  if (flags & BIT_C) {    /* have work to do */    switch(operands) {      case CY_BIT :        if (!get_bit(bitAddr)) {          set_psw(flags & ~BIT_C);        }      break;      case CY_NOTBIT :        if (get_bit(bitAddr)) {          set_psw(flags & ~BIT_C);        }      break;    }  }  return(resGO);}/* arithmetic shift left */int cl_xa::inst_ASL(uint code, int operands){  unsigned int dst, cnt;  unsigned char flags;  /* ASL, dest, count    while (count != 0)      C = dest.80H; dest <<= 1; if sign chg then set V=1      this is a confusing one...  */  flags = get_psw();  flags &= ~BIT_ALL; /* clear these bits */  switch(operands) {    //{0,0xc150,0xf300,' ',2,ASL, REG_REG         }, //  ASL Rd, Rs                 1 1 0 0 S S 0 1  d d d d s s s s    case REG_REG :      cnt = reg1(RI_0F) & 0x1f;      switch (code & 0xc00) {        case 0: // byte          dst = reg1(RI_F0);          dst <<= cnt;          set_reg1(RI_F0,dst);          if (dst & 0x100)            flags |= BIT_C;          if ((dst & 0xff) == 0)            flags |= BIT_Z;        break;        case 1: // word          dst = reg2(RI_F0);          dst <<= cnt;          set_reg2(RI_F0,dst);          if (dst & 0x10000)            flags |= BIT_C;          if ((dst & 0xffff) == 0)            flags |= BIT_Z;        break;        case 2: // ?          // not really sure about the encoding here..          NOTDONE_ASSERT;        break;        case 3:  // dword          //dst = reg4(RI_F0);          dst = reg2(RI_F0) | (reg2(RI_F0 + 2) << 16);          if ((cnt != 0) && (dst & (0x80000000 >> (cnt-1)))) {            flags |= BIT_C;          }          dst <<= cnt;          set_reg2(RI_F0,dst & 0xffff);          set_reg2(RI_F0+2, (dst>>16) & 0xffff);          if (dst == 0)            flags |= BIT_Z;        break;      }    break;    case REG_DATA4 :    case REG_DATA5 :      switch (code & 0xc00) {        case 0: // byte          dst = reg1(RI_F0);          cnt = operands & 0x0f;          dst <<= cnt;          set_reg1(RI_F0,dst);          if (dst & 0x100)            flags |= BIT_C;          if ((dst & 0xff) == 0)            flags |= BIT_Z;        break;        case 1: // word          dst = reg2(RI_F0);          cnt = operands & 0x0f;          dst <<= cnt;          set_reg2(RI_F0,dst);          if (dst & 0x10000)            flags |= BIT_C;          if ((dst & 0xffff) == 0)            flags |= BIT_Z;        break;        case 2: // ?          // not really sure about the encoding here..          NOTDONE_ASSERT;        break;        case 3:  // dword          dst = reg1(RI_F0 & 0xe);          cnt = operands & 0x1f;          if ((cnt != 0) && (dst & (0x80000000 >> (cnt-1)))) {            flags |= BIT_C;          }          dst <<= cnt;          set_reg2(RI_F0,dst & 0xffff);          set_reg2(RI_F0+2, (dst>>16) & 0xffff);          if (dst == 0)            flags |= BIT_Z;        break;      }    break;  }  set_psw(flags);  return(resGO);}/* arithmetic shift right */int cl_xa::inst_ASR(uint code, int operands){  unsigned int dst, cnt;  unsigned char flags;  /* ASR, dest, count    while (count != 0)      C = dest.0; dest >>= 1;      this is a confusing one...  */  flags = get_psw();  flags &= ~BIT_ALL; /* clear these bits */  switch(operands) {    case REG_REG :      cnt = reg1(RI_0F) & 0x1f;      switch (code & 0xc00) {        case 0: // byte          dst = reg1(RI_F0);          if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))            flags |= BIT_C;          if (dst & 0x01)            flags |= BIT_C;          dst >>= cnt;          set_reg1(RI_F0,dst);          if ((dst & 0xff) == 0)            flags |= BIT_Z;        break;        case 1: // word          dst = reg2(RI_F0);          if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))            flags |= BIT_C;          dst >>= cnt;          set_reg2(RI_F0,dst);          if ((dst & 0xffff) == 0)            flags |= BIT_Z;        break;        case 2: // ?          // not really sure about the encoding here..          NOTDONE_ASSERT;        break;        case 3:  // dword          dst = reg2(RI_F0) | (reg2(RI_F0 + 2) << 16);          if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))            flags |= BIT_C;          dst >>= cnt;          set_reg2(RI_F0,dst & 0xffff);          set_reg2(RI_F0+2, (dst>>16) & 0xffff);          if (dst == 0)            flags |= BIT_Z;        break;      }    break;    case REG_DATA4 :    case REG_DATA5 :      switch (code & 0xc00) {        case 0: // byte          dst = reg1(RI_F0);          cnt = operands & 0x0f;          if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))            flags |= BIT_C;          dst >>= cnt;          set_reg1(RI_F0,dst);          if ((dst & 0xff) == 0)            flags |= BIT_Z;        break;        case 1: // word          dst = reg2(RI_F0);          cnt = operands & 0x0f;          if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))            flags |= BIT_C;          dst >>= cnt;          set_reg2(RI_F0,dst);          if ((dst & 0xffff) == 0)            flags |= BIT_Z;        break;        case 2: // ?          // not really sure about the encoding here..          NOTDONE_ASSERT;        break;        case 3:  // dword          dst = reg1(RI_F0 & 0xe);          cnt = operands & 0x1f;          if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))            flags |= BIT_C;          dst >>= cnt;          set_reg2(RI_F0,dst & 0xffff);          set_reg2(RI_F0+2, (dst>>16) & 0xffff);          if (dst == 0)            flags |= BIT_Z;        break;      }    break;  }  set_psw(flags);  return(resGO);}int cl_xa::inst_BCC(uint code, int operands){  short jmpAddr = fetch1()*2;  if (!(get_psw() & BIT_C)) {    PC=(PC+jmpAddr)&0xfffffe;  }  return(resGO);}int cl_xa::inst_BCS(uint code, int operands){  short jmpAddr = fetch1()*2;  if (get_psw() & BIT_C) {    PC=(PC+jmpAddr)&0xfffffe;  }  return(resGO);}int cl_xa::inst_BEQ(uint code, int operands){  short jmpAddr = fetch1()*2;  if (get_psw() & BIT_Z) {    PC=(PC+jmpAddr)&0xfffffe;  }  return(resGO);}int cl_xa::inst_BG(uint code, int operands){  short jmpAddr = fetch1()*2;  short flags=get_psw();  bool Z=flags&BIT_Z, C=flags&BIT_C;  if (!(Z|C)) {    PC=(PC+jmpAddr)&0xfffffe;  }  return(resGO);}int cl_xa::inst_BGE(uint code, int operands){  short jmpAddr = fetch1()*2;  short flags=get_psw();  bool N=flags&BIT_N, V=flags&BIT_V;  if (!(N^V)) {    PC=(PC+jmpAddr)&0xfffffe;  }  return(resGO);}int cl_xa::inst_BGT(uint code, int operands){  short jmpAddr = fetch1()*2;  short flags=get_psw();  bool Z=flags&BIT_Z, N=flags&BIT_N, V=flags&BIT_V;  if (!((Z|N)^V)) {    PC=(PC+jmpAddr)&0xfffffe;  }  return(resGO);}int cl_xa::inst_BKPT(uint code, int operands){  NOTDONE_ASSERT;  return(resGO);}int cl_xa::inst_BL(uint code, int operands){  short jmpAddr = fetch1()*2;  short flags=get_psw();  bool Z=flags&BIT_Z, C=flags&BIT_C;  if (Z|C) {    PC=(PC+jmpAddr)&0xfffffe;  }  return(resGO);}int cl_xa::inst_BLE(uint code, int operands){  short jmpAddr = fetch1()*2;  short flags=get_psw();  bool Z=flags&BIT_Z, N=flags&BIT_N, V=flags&BIT_V;  if ((Z|N)^V) {    PC=(PC+jmpAddr)&0xfffffe;  }  return(resGO);}int cl_xa::inst_BLT(uint code, int operands){  short jmpAddr = fetch1()*2;  short flags=get_psw();  bool N=flags&BIT_N, V=flags&BIT_V;  if (N^V) {    PC=(PC+jmpAddr)&0xfffffe;  }  return(resGO);}int cl_xa::inst_BMI(uint code, int operands){  short jmpAddr = fetch1()*2;  if (get_psw()&BIT_N) {    PC=(PC+jmpAddr)&0xfffffe;  }  return(resGO);}int cl_xa::inst_BNE(uint code, int operands){  short jmpAddr = fetch1()*2;  if (!(get_psw()&BIT_Z)) {    PC=(PC+jmpAddr)&0xfffffe;  }  return(resGO);}int cl_xa::inst_BNV(uint code, int operands){  short jmpAddr = fetch1()*2;  if (!(get_psw()&BIT_V)) {    PC=(PC+jmpAddr)&0xfffffe;  }  return(resGO);}int cl_xa::inst_BOV(uint code, int operands){  short jmpAddr = fetch1()*2;  if (get_psw()&BIT_V) {    PC=(PC+jmpAddr)&0xfffffe;  }  return(resGO);}int cl_xa::inst_BPL(uint code, int operands){  short jmpAddr = fetch1()*2;  if (!(get_psw()&BIT_N)) {    PC=(PC+jmpAddr)&0xfffffe;  }  return(resGO);}int cl_xa::inst_BR(uint code, int operands){  short jmpAddr = fetch1()*2;  PC=(PC+jmpAddr)&0xfffffe;  return(resGO);}int cl_xa::inst_CALL(uint code, int operands){  int jmpaddr;  unsigned int sp;  bool pageZero=get_scr()&1;  switch(operands) {    case REL16:    {      jmpaddr = (signed short)fetch2();      sp = get_sp() - (pageZero ? 2 : 4);      set_sp(sp);      store2(sp, PC&0xffff);      if (!pageZero) {	store2(sp+2, (PC>>16)&0xff);      }      jmpaddr *= 2;      PC = (PC + jmpaddr) & 0xfffffe;    }    break;    case IREG:    {      sp = get_sp() - (pageZero ? 2 : 4);      set_sp(sp);      store2(sp, PC&0xffff);      if (!pageZero) {	store2(sp+2, (PC>>16)&0xff);      }      jmpaddr = reg2(RI_07);      jmpaddr *= 2;      PC = (PC + jmpaddr) & 0xfffffe;    }    break;  }  return(resGO);}int cl_xa::inst_CJNE(uint code, int operands){  switch(operands) {    case REG_DIRECT_REL8:    {       // update C,N,Z       if (code & 0x800) {  // word op         int result;         int src = get_word_direct( ((code & 0x7)<<4) | fetch1());         int addr = (fetch1() * 2);         int dst = reg2(RI_F0);         unsigned char flags;         flags = get_psw();         flags &= ~BIT_ALL; /* clear these bits */         result = dst - src;         if (result == 0) flags |= BIT_Z;         if (result > 0xffff) flags |= BIT_C;         if (dst < src) flags |= BIT_N;         set_psw(flags);         if (flags & BIT_Z)           PC += addr;       } else {         int result;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -