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

📄 xa.cc

📁 sdcc是为51等小型嵌入式cpu设计的c语言编译器支持数种不同类型的cpu
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* * Simulator of microcontrollers (xa.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 <stdio.h>#include <stdlib.h>#include <ctype.h>#include "i_string.h"// prj#include "pobjcl.h"// sim#include "simcl.h"// local#include "xacl.h"#include "glob.h"#include "regsxa.h"/* * Base type of xa controllers */cl_xa::cl_xa(class cl_sim *asim):  cl_uc(asim){  type= CPU_XA;}intcl_xa::init(void){  cl_uc::init(); /* Memories now exist */  ram= address_space(MEM_XRAM_ID);  rom= address_space(MEM_ROM_ID);  /* set SCR to osc/4, native XA mode, flat 24 */  set_scr(0);  /* initialize SP to 100H */  set_reg2(7, 0x100);  /* set PSW from reset vector */  set_psw(getcode2(0));  /* set PC from reset vector */  PC = getcode2(2);  printf("The XA Simulator is in development, UNSTABLE, DEVELOPERS ONLY!\n");  return(0);}/*class cl_m *cl_xa::mk_mem(enum mem_class type, char *class_name){  class cl_m *m= cl_uc::mk_mem(type, class_name);  if (type == MEM_SFR)    sfr= m;  if (type == MEM_IRAM)    iram= m;  return(m);}*/char *cl_xa::id_string(void){  return("unspecified XA");}/* * Making elements of the controller *//*t_addrcl_xa::get_mem_size(enum mem_class type){  switch(type)    {    case MEM_IRAM: return(0x2000);    case MEM_SFR:  return(0x2000);    case MEM_ROM:  return(0x10000);    case MEM_XRAM: return(0x10000);    default: return(0);    } return(cl_uc::get_mem_size(type));}*/voidcl_xa::mk_hw_elements(void){  //class cl_base *o;  /* t_uc::mk_hw() does nothing */}voidcl_xa::make_memories(void){  class cl_address_space *as;  as= rom= new cl_address_space("rom", 0, 0x10000, 8);  as->init();  address_spaces->add(as);  as= iram= new cl_address_space("iram", 0, 0x2000, 8);  as->init();  address_spaces->add(as);  as= sfr= new cl_address_space("sfr", 0x0, 0x2000, 8);  as->init();  address_spaces->add(as);  as= ram= new cl_address_space("xram", 0, 0x10000, 8);  as->init();  address_spaces->add(as);  class cl_address_decoder *ad;  class cl_memory_chip *chip;  chip= new cl_memory_chip("rom_chip", 0x10000, 8);  chip->init();  memchips->add(chip);  ad= new cl_address_decoder(as= address_space("rom"), chip, 0, 0xffff, 0);  ad->init();  as->decoders->add(ad);  ad->activate(0);  chip= new cl_memory_chip("iram_chip", 0x2000, 8);  chip->init();  memchips->add(chip);  ad= new cl_address_decoder(as= address_space("iram"), chip, 0, 0x1fff, 0);  ad->init();  as->decoders->add(ad);  ad->activate(0);  chip= new cl_memory_chip("xram_chip", 0x10000, 8);  chip->init();  memchips->add(chip);  ad= new cl_address_decoder(as= address_space("xram"), chip, 0, 0xffff, 0);  ad->init();  as->decoders->add(ad);  ad->activate(0);  chip= new cl_memory_chip("sfr_chip", 0x2000, 8);  chip->init();  memchips->add(chip);  ad= new cl_address_decoder(as= address_space("sfr"), chip, 0x0, 0x1fff, 0);  ad->init();  as->decoders->add(ad);  ad->activate(0);}/* * Help command interpreter */struct dis_entry *cl_xa::dis_tbl(void){  // this should be unused, we need to make main prog code  // independent of any array thing.  printf("ERROR - Using disass[] table in XA sim code!\n");  return(glob_disass_xa);}struct name_entry *cl_xa::sfr_tbl(void){  return(sfr_tabXA51);}struct name_entry *cl_xa::bit_tbl(void){  return(bit_tabXA51);}intcl_xa::inst_length(t_addr addr){  int len = 0;  get_disasm_info(addr, &len, NULL, NULL, NULL, NULL);  return len;}intcl_xa::inst_branch(t_addr addr){  int b;  get_disasm_info(addr, NULL, &b, NULL, NULL, NULL);  return b;}intcl_xa::longest_inst(void){  return 6;}static char dir_name[64];char *cl_xa::get_dir_name(short addr) {  if (!get_name(addr, sfr_tbl(), dir_name)) {    sprintf (dir_name, "0x%03x", addr);  }  return dir_name;}static char bit_name[64];char *cl_xa::get_bit_name(short addr) {  if (!get_name(addr, bit_tbl(), bit_name)) {    sprintf (bit_name, "0x%03x", addr);  }  return bit_name;}/*--------------------------------------------------------------------get_disasm_info - Given an address, return information about the opcode  which resides there.  addr - address of opcode we want information on.  ret_len - return length of opcode.  ret_branch - return a character which indicates if we are    a branching opcode.  Used by main app to implement "Next"    function which steps over functions.  immed_offset - return a number which represents the number of bytes    offset to where any immediate data is(tail end of opcode).  Used    for printing disassembly.  operands - return a key indicating the form of the operands,    used for printing the disassembly.  mnemonic - return a key indicating the mnemonic of the instruction.  Return value: Return the operand code formed by either the single  byte opcode or 2 bytes of the opcode for multi-byte opcodes.  Note: Any of the return pointer parameters can be set to NULL to    indicate the caller does not want the information.|--------------------------------------------------------------------*/intcl_xa::get_disasm_info(t_addr addr,                       int *ret_len,                       int *ret_branch,                       int *immed_offset,                       int *parms,                       int *mnemonic){  uint code;  int len = 0;  int immed_n = 0;  int i;  int start_addr = addr;  code= get_mem(MEM_ROM_ID, addr++);  if (code == 0x00) {    i= 0;    while (disass_xa[i].mnemonic != NOP)      i++;  } else {    len = 2;    code = (code << 8) | get_mem(MEM_ROM_ID, addr++);    i= 0;    while ((code & disass_xa[i].mask) != disass_xa[i].code &&           disass_xa[i].mnemonic != BAD_OPCODE)      i++;  }  if (ret_len)    *ret_len = disass_xa[i].length;  if (ret_branch)   *ret_branch = disass_xa[i].branch;  if (immed_offset) {    if (immed_n > 0)         *immed_offset = immed_n;    else *immed_offset = (addr - start_addr);  }  if (parms) {    *parms = disass_xa[i].operands;  }  if (mnemonic) {    *mnemonic = disass_xa[i].mnemonic;  }  return code;}static char *w_reg_strs[] = { "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"};static char *b_reg_strs[] = { "R0l", "R0h", "R1l", "R1h", "R2l", "R2h", "R3l", "R3h", "R4l", "R4h", "R5l", "R5h", "R6l", "R6h", "R7l", "R7h"};/*--------------------------------------------------------------------disass - Disassemble an opcode.    addr - address of opcode to disassemble/print.    sep - optionally points to string(tab) to use as separator.|--------------------------------------------------------------------*/char *cl_xa::disass(t_addr addr, char *sep){  char work[256], parm_str[40];  char *buf, *p, *b;  int code;  int len = 0;  int immed_offset = 0;  int operands;  int mnemonic;  char **reg_strs;  p= work;  code = get_disasm_info(addr, &len, NULL, &immed_offset, &operands, &mnemonic);  if (mnemonic == BAD_OPCODE) {    buf= (char*)malloc(30);    strcpy(buf, "UNKNOWN/INVALID");    return(buf);  }  if (code & 0x0800)    reg_strs = w_reg_strs;  else    reg_strs = b_reg_strs;  switch(operands) {     // the repeating common parameter encoding for ADD, ADDC, SUB, AND...    case REG_REG :      sprintf(parm_str, "%s,%s",              reg_strs[((code >> 4) & 0xf)],              reg_strs[(code & 0xf)]);    break;    case REG_IREG :      sprintf(parm_str, "%s,[%s]",              reg_strs[((code >> 4) & 0xf)],              w_reg_strs[(code & 0xf)]);    break;    case IREG_REG :      sprintf(parm_str, "[%s],%s",              w_reg_strs[(code & 0x7)],              reg_strs[((code >> 4) & 0xf)] );    break;    case REG_IREGOFF8 :      sprintf(parm_str, "%s,[%s+%02x]",              reg_strs[((code >> 4) & 0xf)],              w_reg_strs[(code & 0x7)],              get_mem(MEM_ROM_ID, addr+immed_offset));      ++immed_offset;    break;    case IREGOFF8_REG :      sprintf(parm_str, "[%s+%02x],%s",              w_reg_strs[(code & 0x7)],              get_mem(MEM_ROM_ID, addr+immed_offset),              reg_strs[((code >> 4) & 0xf)] );      ++immed_offset;    break;    case REG_IREGOFF16 :      sprintf(parm_str, "%s,[%s+%04x]",              reg_strs[((code >> 4) & 0xf)],              w_reg_strs[(code & 0x7)],              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+1)) |                     (get_mem(MEM_ROM_ID, addr+immed_offset)<<8)) );      ++immed_offset;      ++immed_offset;    break;    case IREGOFF16_REG :      sprintf(parm_str, "[%s+%04x],%s",              w_reg_strs[(code & 0x7)],              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+1)) |                     (get_mem(MEM_ROM_ID, addr+immed_offset)<<8)),              reg_strs[((code >> 4) & 0xf)] );      ++immed_offset;      ++immed_offset;    break;    case REG_IREGINC :      sprintf(parm_str, "%s,[%s+]",              reg_strs[((code >> 4) & 0xf)],              w_reg_strs[(code & 0xf)]);    break;    case IREGINC_REG :      sprintf(parm_str, "[%s+],%s",              w_reg_strs[(code & 0x7)],              reg_strs[((code >> 4) & 0xf)] );    break;    case DIRECT_REG :      sprintf(parm_str, "%s,%s",              get_dir_name(((code & 0x7) << 8) | 			   get_mem(MEM_ROM_ID, addr+immed_offset)),              reg_strs[((code >> 4) & 0xf)] );      ++immed_offset;    break;    case REG_DIRECT :      sprintf(parm_str, "%s,%s",	      reg_strs[((code >> 4) & 0xf)],               get_dir_name(((code & 0x7) << 8) | 			   get_mem(MEM_ROM_ID, addr+immed_offset)));      ++immed_offset;    break;    case REG_DATA8 :      sprintf(parm_str, "%s,#0x%02x",              b_reg_strs[((code >> 4) & 0xf)],              get_mem(MEM_ROM_ID, addr+immed_offset) );      ++immed_offset;    break;    case REG_DATA16 :      sprintf(parm_str, "%s,#0x%04x",              reg_strs[((code >> 4) & 0xf)],              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+1)) |                     (get_mem(MEM_ROM_ID, addr+immed_offset)<<8)) );      ++immed_offset;      ++immed_offset;    break;    case IREG_DATA8 :      sprintf(parm_str, "[%s], 0x%02x",              w_reg_strs[((code >> 4) & 0x7)],              get_mem(MEM_ROM_ID, addr+immed_offset) );      ++immed_offset;    break;    case IREG_DATA16 :      sprintf(parm_str, "[%s], 0x%04x",              w_reg_strs[((code >> 4) & 0x7)],              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+1)) |                     (get_mem(MEM_ROM_ID, addr+immed_offset)<<8)) );      ++immed_offset;      ++immed_offset;    break;    case IREGINC_DATA8 :      sprintf(parm_str, "[%s+], 0x%02x",              w_reg_strs[((code >> 4) & 0x7)],              get_mem(MEM_ROM_ID, addr+immed_offset) );      ++immed_offset;    break;    case IREGINC_DATA16 :      sprintf(parm_str, "[%s+], 0x%04x",              w_reg_strs[((code >> 4) & 0x7)],              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+1)) |                     (get_mem(MEM_ROM_ID, addr+immed_offset)<<8)) );      ++immed_offset;      ++immed_offset;    break;    case IREGOFF8_DATA8 :      sprintf(parm_str, "[%s+%02x], 0x%02x",              w_reg_strs[((code >> 4) & 0x7)],              get_mem(MEM_ROM_ID, addr+immed_offset),              get_mem(MEM_ROM_ID, addr+immed_offset+1) );      immed_offset += 2;    break;    case IREGOFF8_DATA16 :      sprintf(parm_str, "[%s+%02x], 0x%04x",              w_reg_strs[((code >> 4) & 0x7)],              get_mem(MEM_ROM_ID, addr+immed_offset),              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+2)) |                     (get_mem(MEM_ROM_ID, addr+immed_offset+1)<<8)) );      immed_offset += 3;    break;    case IREGOFF16_DATA8 :      sprintf(parm_str, "[%s+%04x], 0x%02x",              w_reg_strs[((code >> 4) & 0x7)],              (short)((get_mem(MEM_ROM_ID, addr+immed_offset+1)) |                     (get_mem(MEM_ROM_ID, addr+immed_offset+0)<<8)),              get_mem(MEM_ROM_ID, addr+immed_offset+2) );      immed_offset += 3;    break;

⌨️ 快捷键说明

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