X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=sim%2Fucsim%2Fxa.src%2Fxa.cc;h=35be697abb7abb3572b0d9a66ac5b0227ac9fe89;hb=f27da39dbcab5678aca6d8462f1cc37a643f37e9;hp=9e65740fa816b1a85b3959a7c45b8a6f03a6fa91;hpb=67ef4a56378ca7fe6415a0612c39d63d030f9a41;p=fw%2Fsdcc diff --git a/sim/ucsim/xa.src/xa.cc b/sim/ucsim/xa.src/xa.cc index 9e65740f..35be697a 100644 --- a/sim/ucsim/xa.src/xa.cc +++ b/sim/ucsim/xa.src/xa.cc @@ -6,7 +6,7 @@ * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu * Other contributors include: * Karl Bongers karl@turbobit.com, - * Johan Knol + * Johan Knol johan.knol@iduna.nl */ /* This file is part of microcontroller simulator: ucsim. @@ -45,7 +45,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "glob.h" #include "regsxa.h" - /* * Base type of xa controllers */ @@ -60,19 +59,36 @@ int cl_xa::init(void) { cl_uc::init(); /* Memories now exist */ - ram= mem(MEM_XRAM); - rom= mem(MEM_ROM); - - wmem_direct = (TYPE_UWORD *) &mem_direct[0]; + 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*2, 0x100); + 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) { @@ -83,18 +99,21 @@ cl_xa::id_string(void) /* * Making elements of the controller */ - +/* t_addr cl_xa::get_mem_size(enum mem_class type) { switch(type) { - case MEM_ROM: return(0x10000); + 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)); } +*/ void cl_xa::mk_hw_elements(void) @@ -103,6 +122,60 @@ cl_xa::mk_hw_elements(void) /* t_uc::mk_hw() does nothing */ } +void +cl_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 @@ -117,18 +190,15 @@ cl_xa::dis_tbl(void) return(glob_disass_xa); } -/*struct name_entry * -cl_xa::sfr_tbl(void) +struct name_entry *cl_xa::sfr_tbl(void) { - return(0); -}*/ + return(sfr_tabXA51); +} -/*struct name_entry * -cl_xa::bit_tbl(void) +struct name_entry *cl_xa::bit_tbl(void) { - //FIXME - return(0); -}*/ + return(bit_tabXA51); +} int cl_xa::inst_length(t_addr addr) @@ -156,8 +226,42 @@ cl_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 - +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. |--------------------------------------------------------------------*/ int cl_xa::get_disasm_info(t_addr addr, @@ -173,14 +277,14 @@ cl_xa::get_disasm_info(t_addr addr, int i; int start_addr = addr; - code= get_mem(MEM_ROM, 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, addr++); + 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) @@ -227,7 +331,9 @@ static char *b_reg_strs[] = { "R7l", "R7h"}; /*-------------------------------------------------------------------- -disass - +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) @@ -274,33 +380,33 @@ cl_xa::disass(t_addr addr, char *sep) reg_strs[((code >> 4) & 0xf)] ); break; case REG_IREGOFF8 : - sprintf(parm_str, "%s,[%s+%02d]", + sprintf(parm_str, "%s,[%s+%02x]", reg_strs[((code >> 4) & 0xf)], w_reg_strs[(code & 0x7)], - get_mem(MEM_ROM, addr+immed_offset)); + get_mem(MEM_ROM_ID, addr+immed_offset)); ++immed_offset; break; case IREGOFF8_REG : - sprintf(parm_str, "[%s+%02d],%s", + sprintf(parm_str, "[%s+%02x],%s", w_reg_strs[(code & 0x7)], - get_mem(MEM_ROM, addr+immed_offset), + get_mem(MEM_ROM_ID, addr+immed_offset), reg_strs[((code >> 4) & 0xf)] ); ++immed_offset; break; case REG_IREGOFF16 : - sprintf(parm_str, "%s,[%s+%04d]", + sprintf(parm_str, "%s,[%s+%04x]", reg_strs[((code >> 4) & 0xf)], w_reg_strs[(code & 0x7)], - (short)((get_mem(MEM_ROM, addr+immed_offset+1)) | - (get_mem(MEM_ROM, addr+immed_offset)<<8)) ); + (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+%04d],%s", + sprintf(parm_str, "[%s+%04x],%s", w_reg_strs[(code & 0x7)], - (short)((get_mem(MEM_ROM, addr+immed_offset+1)) | - (get_mem(MEM_ROM, addr+immed_offset)<<8)), + (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; @@ -316,102 +422,106 @@ cl_xa::disass(t_addr addr, char *sep) reg_strs[((code >> 4) & 0xf)] ); break; case DIRECT_REG : - sprintf(parm_str, "0x%03x,%s", - ((code & 0x7) << 8) | get_mem(MEM_ROM, addr+immed_offset), + 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,0x%03x", - reg_strs[((code >> 4) & 0xf)], - ((code & 0x7) << 8) + get_mem(MEM_ROM, addr+immed_offset) ); + 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, addr+immed_offset) ); + 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, addr+immed_offset+1)) | - (get_mem(MEM_ROM, addr+immed_offset)<<8)) ); + (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, addr+immed_offset) ); + 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, addr+immed_offset+1)) | - (get_mem(MEM_ROM, addr+immed_offset)<<8)) ); + (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, addr+immed_offset) ); + 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, addr+immed_offset+1)) | - (get_mem(MEM_ROM, addr+immed_offset)<<8)) ); + (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+%02d], 0x%02x", + sprintf(parm_str, "[%s+%02x], 0x%02x", w_reg_strs[((code >> 4) & 0x7)], - get_mem(MEM_ROM, addr+immed_offset), - get_mem(MEM_ROM, addr+immed_offset+1) ); + 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+%02d], 0x%04x", + sprintf(parm_str, "[%s+%02x], 0x%04x", w_reg_strs[((code >> 4) & 0x7)], - get_mem(MEM_ROM, addr+immed_offset), - (short)((get_mem(MEM_ROM, addr+immed_offset+2)) | - (get_mem(MEM_ROM, addr+immed_offset+1)<<8)) ); + 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+%04d], 0x%02x", + sprintf(parm_str, "[%s+%04x], 0x%02x", w_reg_strs[((code >> 4) & 0x7)], - (short)((get_mem(MEM_ROM, addr+immed_offset+1)) | - (get_mem(MEM_ROM, addr+immed_offset+0)<<8)), - get_mem(MEM_ROM, addr+immed_offset+2) ); + (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; case IREGOFF16_DATA16 : - sprintf(parm_str, "[%s+%04d], 0x%04x", + sprintf(parm_str, "[%s+%04x], 0x%04x", w_reg_strs[((code >> 4) & 0x7)], - (short)((get_mem(MEM_ROM, addr+immed_offset+1)) | - (get_mem(MEM_ROM, addr+immed_offset+0)<<8)), - (short)((get_mem(MEM_ROM, addr+immed_offset+3)) | - (get_mem(MEM_ROM, addr+immed_offset+2)<<8)) ); + (short)((get_mem(MEM_ROM_ID, addr+immed_offset+1)) | + (get_mem(MEM_ROM_ID, addr+immed_offset+0)<<8)), + (short)((get_mem(MEM_ROM_ID, addr+immed_offset+3)) | + (get_mem(MEM_ROM_ID, addr+immed_offset+2)<<8)) ); immed_offset += 4; break; case DIRECT_DATA8 : - sprintf(parm_str, "0x%03x,#0x%02x", - ((code & 0x0070) << 4) | get_mem(MEM_ROM, addr+immed_offset), - get_mem(MEM_ROM, addr+immed_offset+1)); + sprintf(parm_str, "%s,#0x%02x", + get_dir_name(((code & 0x0070) << 4) | + get_mem(MEM_ROM_ID, addr+immed_offset)), + get_mem(MEM_ROM_ID, addr+immed_offset+1)); immed_offset += 3; break; case DIRECT_DATA16 : - sprintf(parm_str, "%0x03x,#0x%04x", - ((code & 0x0070) << 4) | get_mem(MEM_ROM, addr+immed_offset), - get_mem(MEM_ROM, addr+immed_offset+2) + - (get_mem(MEM_ROM, addr+immed_offset+1)<<8)); + sprintf(parm_str, "%s,#0x%04x", + get_dir_name(((code & 0x0070) << 4) | + get_mem(MEM_ROM_ID, addr+immed_offset)), + get_mem(MEM_ROM_ID, addr+immed_offset+2) + + (get_mem(MEM_ROM_ID, addr+immed_offset+1)<<8)); immed_offset += 3; break; @@ -419,12 +529,20 @@ cl_xa::disass(t_addr addr, char *sep) case NO_OPERANDS : // for NOP strcpy(parm_str, ""); break; - case C_BIT : - strcpy(parm_str, "C_BIT"); + case CY_BIT : + sprintf(parm_str, "C,%s", + get_bit_name(((code&0x0003)<<8) + get_mem(MEM_ROM_ID, addr+2))); + break; + case BIT_CY : + sprintf(parm_str, "%s,C", + get_bit_name(((code&0x0003)<<8) + get_mem(MEM_ROM_ID, addr+2))); break; case REG_DATA4 : strcpy(parm_str, "REG_DATA4"); break; + case REG_DATA5 : + strcpy(parm_str, "REG_DATA5"); + break; case IREG_DATA4 : strcpy(parm_str, "IREG_DATA4"); break; @@ -438,90 +556,184 @@ cl_xa::disass(t_addr addr, char *sep) strcpy(parm_str, "IREGOFF16_DATA4"); break; case DIRECT_DATA4 : - strcpy(parm_str, "DIRECT_DATA4"); + sprintf(parm_str, "%s,#0x%x", + get_dir_name(((code & 0x70)<<4) | + get_mem(MEM_ROM_ID, addr+2)), + code&0x0f); break; - case DIRECT_ALONE : - sprintf(parm_str, "0x%03x", - ((code & 0x007) << 4) + get_mem(MEM_ROM, addr+2)); + case DIRECT : + sprintf(parm_str, "%s", + get_dir_name(((code & 0x007) << 4) + + get_mem(MEM_ROM_ID, addr+2))); break; - case REG_ALONE : + case REG : sprintf(parm_str, "%s", reg_strs[((code >> 4) & 0xf)] ); break; - case IREG_ALONE : + case IREG : sprintf(parm_str, "[%s]", reg_strs[((code >> 4) & 0xf)] ); break; case BIT_ALONE : - sprintf(parm_str, "0x%03x", - ((code&0x0003)<<8) + get_mem(MEM_ROM, addr+2)); + sprintf(parm_str, "%s", + get_bit_name(((code&0x0003)<<8) + get_mem(MEM_ROM_ID, addr+2))); break; case BIT_REL8 : - sprintf(parm_str, "0x%03x,0x%04x", - ((code&0x0003)<<8) + get_mem(MEM_ROM, addr+2), - ((signed char)get_mem(MEM_ROM, addr+3)*2+addr+len)&0xfffe); + sprintf(parm_str, "%s,0x%04x", + get_bit_name((code&0x0003)<<8) + get_mem(MEM_ROM_ID, addr+2), + ((signed char)get_mem(MEM_ROM_ID, addr+3)*2+addr+len)&0xfffe); break; + case DATA4: + sprintf(parm_str, "#0x%02x", code&0x0f); + break; case ADDR24 : - strcpy(parm_str, "ADDR24"); + sprintf(parm_str, "0x%06x", + (get_mem(MEM_ROM_ID, addr+3)<<16) + + (get_mem(MEM_ROM_ID, addr+1)<<8) + + get_mem(MEM_ROM_ID, addr+2)); + break; break; case REG_REL8 : - //strcpy(parm_str, "REG_REL8"); sprintf(parm_str, "%s,0x%04x", reg_strs[(code>>4) & 0xf], - ((signed char)get_mem(MEM_ROM, addr+2)*2+addr+len)&0xfffe); + ((signed char)get_mem(MEM_ROM_ID, addr+2)*2+addr+len)&0xfffe); break; case DIRECT_REL8 : - strcpy(parm_str, "DIRECT_REL8"); + sprintf(parm_str, "%s,0x%04x", + get_dir_name(((code&0x07)<<8) + + get_mem(MEM_ROM_ID, addr+2)), + ((signed char)get_mem(MEM_ROM_ID, addr+2)*2+addr+len)&0xfffe); + break; + case REG_USP: + sprintf(parm_str, "REG_USP"); + break; + case USP_REG: + sprintf(parm_str, "USP_REG"); break; - case REL8 : - //strcpy(parm_str, "REL8"); sprintf(parm_str, "0x%04x", - ((signed char)get_mem(MEM_ROM, addr+1)*2+addr+len)&0xfffe); + ((signed char)get_mem(MEM_ROM_ID, addr+1)*2+addr+len)&0xfffe); break; case REL16 : - //strcpy(parm_str, "REL16"); sprintf(parm_str, "0x%04x", - ((signed short)((get_mem(MEM_ROM, addr+1)<<8) + get_mem(MEM_ROM, addr+2))*2+addr+len)&0xfffe); - break; - - case RLIST : - strcpy(parm_str, "RLIST"); + ((signed short)((get_mem(MEM_ROM_ID, addr+1)<<8) + get_mem(MEM_ROM_ID, addr+2))*2+addr+len)&0xfffe); + break; + + case RLIST : { + /* TODO: the list should be comma reperated + and maybe for POP the list should be reversed */ + unsigned char rlist=code&0xff; + parm_str[0]='\0'; + if (code&0x0800) { // word list + if (code&0x4000) { // R8-R15 + if (rlist&0x80) strcat (parm_str, "R15 "); + if (rlist&0x40) strcat (parm_str, "R14"); + if (rlist&0x20) strcat (parm_str, "R13 "); + if (rlist&0x10) strcat (parm_str, "R12 "); + if (rlist&0x08) strcat (parm_str, "R11 "); + if (rlist&0x04) strcat (parm_str, "R10 "); + if (rlist&0x02) strcat (parm_str, "R9 "); + if (rlist&0x01) strcat (parm_str, "R8 "); + } else { // R7-R0 + if (rlist&0x80) strcat (parm_str, "R7 "); + if (rlist&0x40) strcat (parm_str, "R6 "); + if (rlist&0x20) strcat (parm_str, "R5 "); + if (rlist&0x10) strcat (parm_str, "R4 "); + if (rlist&0x08) strcat (parm_str, "R3 "); + if (rlist&0x04) strcat (parm_str, "R2 "); + if (rlist&0x02) strcat (parm_str, "R1 "); + if (rlist&0x01) strcat (parm_str, "R0 "); + } + } else { // byte list + if (code&0x4000) { //R7h-R4l + if (rlist&0x80) strcat (parm_str, "R7h "); + if (rlist&0x40) strcat (parm_str, "R7l "); + if (rlist&0x20) strcat (parm_str, "R6h "); + if (rlist&0x10) strcat (parm_str, "R6l "); + if (rlist&0x08) strcat (parm_str, "R5h "); + if (rlist&0x04) strcat (parm_str, "R5l "); + if (rlist&0x02) strcat (parm_str, "R4h "); + if (rlist&0x01) strcat (parm_str, "R4l "); + } else { // R3h-R0l + if (rlist&0x80) strcat (parm_str, "R3h "); + if (rlist&0x40) strcat (parm_str, "R3l "); + if (rlist&0x20) strcat (parm_str, "R2h "); + if (rlist&0x10) strcat (parm_str, "R2l "); + if (rlist&0x08) strcat (parm_str, "R1h "); + if (rlist&0x04) strcat (parm_str, "R1l "); + if (rlist&0x02) strcat (parm_str, "R0h "); + if (rlist&0x01) strcat (parm_str, "R0l "); + } + } + } break; case REG_DIRECT_REL8 : - sprintf(parm_str, "%s,0x%02x,0x%02x", + sprintf(parm_str, "%s,%s,0x%02x", reg_strs[((code >> 4) & 0xf)], - ((code & 0x7) << 8) + get_mem(MEM_ROM, addr+immed_offset), - (get_mem(MEM_ROM, addr+immed_offset+1) * 2) & 0xfffe ); + get_dir_name(((code & 0x7) << 8) + + get_mem(MEM_ROM_ID, addr+immed_offset)), + ((signed char) get_mem(MEM_ROM_ID, addr+immed_offset+1) * 2) & 0xfffe ); break; case REG_DATA8_REL8 : - sprintf(parm_str, "%s,#0x%04x,0x%02x", + sprintf(parm_str, "%s,#0x%02x,0x%02x", reg_strs[((code >> 4) & 0xf)], - get_mem(MEM_ROM, addr+immed_offset), - (get_mem(MEM_ROM, addr+immed_offset+1) * 2) & 0xfffe ); + get_mem(MEM_ROM_ID, addr+immed_offset+1), + ((signed char)get_mem(MEM_ROM_ID, addr+immed_offset) * 2) & 0xfffe ); break; case REG_DATA16_REL8 : - sprintf(parm_str, "%s,#0x%02x,0x%02x", - w_reg_strs[((code >> 4) & 0x7)*2], - get_mem(MEM_ROM, addr+immed_offset+1) + - (get_mem(MEM_ROM, addr+immed_offset+0)<<8), - (get_mem(MEM_ROM, addr+immed_offset+2) * 2) & 0xfffe ); + sprintf(parm_str, "%s,#0x%04x,0x%02x", + w_reg_strs[(code >> 4) & 0xf], + get_mem(MEM_ROM_ID, addr+immed_offset+2) + + (get_mem(MEM_ROM_ID, addr+immed_offset+1)<<8), + ((signed char)get_mem(MEM_ROM_ID, addr+immed_offset) * 2) & 0xfffe ); break; case IREG_DATA8_REL8 : - sprintf(parm_str, "[%s],#0x%04x,0x%02x", + sprintf(parm_str, "[%s],#0x%02x,0x%02x", reg_strs[((code >> 4) & 0x7)], - get_mem(MEM_ROM, addr+immed_offset), - (get_mem(MEM_ROM, addr+immed_offset+1) * 2) & 0xfffe ); + get_mem(MEM_ROM_ID, addr+immed_offset+1), + ((signed char)get_mem(MEM_ROM_ID, addr+immed_offset) * 2) & 0xfffe ); break; case IREG_DATA16_REL8 : - sprintf(parm_str, "[%s],#0x%02x,0x%02x", - w_reg_strs[((code >> 4) & 0x7)*2], - get_mem(MEM_ROM, addr+immed_offset+1) + - (get_mem(MEM_ROM, addr+immed_offset+0)<<8), - (get_mem(MEM_ROM, addr+immed_offset+2) * 2) & 0xfffe ); + sprintf(parm_str, "[%s],#0x%04x,0x%02x", + w_reg_strs[(code >> 4) & 0x7], + get_mem(MEM_ROM_ID, addr+immed_offset+2) + + (get_mem(MEM_ROM_ID, addr+immed_offset+1)<<8), + ((signed char)get_mem(MEM_ROM_ID, addr+immed_offset) * 2) & 0xfffe ); break; + case A_APLUSDPTR : + strcpy(parm_str, "A, [A+DPTR]"); + break; + + case A_APLUSPC : + strcpy(parm_str, "A, [A+PC]"); + break; + + case REG_REGOFF8 : + sprintf(parm_str, "%s,%s+0x%02x", + w_reg_strs[(code >> 4) & 0x7], + w_reg_strs[code & 0x7], + get_mem(MEM_ROM_ID, addr+immed_offset)); + break; + + case REG_REGOFF16 : + sprintf(parm_str, "%s,%s+0x%02x", + w_reg_strs[(code >> 4) & 0x7], + w_reg_strs[code & 0x7], + get_mem(MEM_ROM_ID, addr+immed_offset+1) + + (get_mem(MEM_ROM_ID, addr+immed_offset+0)<<8)); + break; + + case A_PLUSDPTR : + strcpy(parm_str, "[A+DPTR]"); + break; + + case IIREG : + sprintf(parm_str, "[[%s]]", + w_reg_strs[(code & 0x7)]); + break; + default: strcpy(parm_str, "???"); break; @@ -541,6 +753,7 @@ cl_xa::disass(t_addr addr, char *sep) buf= (char *)malloc(6+strlen(p)+1); else buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1); + for (p= work, b= buf; *p != ' '; p++, b++) *b= *p; p++; @@ -557,7 +770,8 @@ cl_xa::disass(t_addr addr, char *sep) } /*-------------------------------------------------------------------- - print_regs - + print_regs - Print the registers, flags and other useful information. + Used to print a status line while stepping through the code. |--------------------------------------------------------------------*/ void cl_xa::print_regs(class cl_console *con) @@ -565,30 +779,29 @@ cl_xa::print_regs(class cl_console *con) unsigned char flags; flags = get_psw(); - con->dd_printf("CA---VNZ Flags: %02x ", flags); + con->dd_printf("CA---VNZ | ", flags); con->dd_printf("R0:%04x R1:%04x R2:%04x R3:%04x\n", - get_reg(1,0), get_reg(1,2), get_reg(1,4), get_reg(1,6)); + reg2(0), reg2(1), reg2(2), reg2(3)); - con->dd_printf("%c%c---%c%c%c ", + con->dd_printf("%c%c---%c%c%c | ", (flags & BIT_C)?'1':'0', (flags & BIT_AC)?'1':'0', (flags & BIT_V)?'1':'0', (flags & BIT_N)?'1':'0', (flags & BIT_Z)?'1':'0'); - con->dd_printf("R4:%04x R5:%04x R6:%04x R7(SP):%04x ES:%04x DS:%04x\n", - get_reg(1,8), get_reg(1,10), get_reg(1,12), get_reg(1,14), 0, 0); + con->dd_printf("R4:%04x R5:%04x R6:%04x SP:%04x ES:%04x DS:%04x\n", + reg2(4), reg2(5), reg2(6), reg2(7), 0, 0); print_disass(PC, con); } -/* - * Execution - */ - -int -cl_xa::exec_inst(void) +/*-------------------------------------------------------------------- + exec_inst - Called to implement simulator execution of 1 instruction + at the current PC(program counter) address. +|--------------------------------------------------------------------*/ +int cl_xa::exec_inst(void) { t_mem code1; uint code; @@ -606,7 +819,7 @@ cl_xa::exec_inst(void) code = (code1 << 8); i= 0; while ( ((code & disass_xa[i].mask) != disass_xa[i].code || - ((disass_xa[i].mask & 0x00ff) != 0)) /* one byte op code */ + (!disass_xa[i].is1byte)) /* not a one byte op code */ && disass_xa[i].mnemonic != BAD_OPCODE) i++; @@ -632,46 +845,122 @@ cl_xa::exec_inst(void) return inst_ADD(code, operands); case ADDC: return inst_ADDC(code, operands); - case SUB: - return inst_SUB(code, operands); - case SUBB: - return inst_SUBB(code, operands); - case CMP: - return inst_CMP(code, operands); - case AND: - return inst_AND(code, operands); - case OR: - return inst_OR(code, operands); - case XOR: - return inst_XOR(code, operands); case ADDS: return inst_ADDS(code, operands); - case NEG: - return inst_NEG(code, operands); - case SEXT: - return inst_SEXT(code, operands); - case MUL: - return inst_MUL(code, operands); + case AND: + return inst_AND(code, operands); + case ANL: + return inst_ANL(code, operands); + case ASL: + return inst_ASL(code, operands); + case ASR: + return inst_ASR(code, operands); + case BCC: + return inst_BCC(code, operands); + case BCS: + return inst_BCS(code, operands); + case BEQ: + return inst_BEQ(code, operands); + case BG: + return inst_BG(code, operands); + case BGE: + return inst_BGE(code, operands); + case BGT: + return inst_BGT(code, operands); + case BKPT: + return inst_BKPT(code, operands); + case BL: + return inst_BL(code, operands); + case BLE: + return inst_BLE(code, operands); + case BLT: + return inst_BLT(code, operands); + case BMI: + return inst_BMI(code, operands); + case BNE: + return inst_BNE(code, operands); + case BNV: + return inst_BNV(code, operands); + case BOV: + return inst_BOV(code, operands); + case BPL: + return inst_BPL(code, operands); + case BR: + return inst_BR(code, operands); + case CALL: + return inst_CALL(code, operands); + case CJNE: + return inst_CJNE(code, operands); + case CLR: + return inst_CLR(code, operands); + case CMP: + return inst_CMP(code, operands); + case CPL: + return inst_CPL(code, operands); + case DA: + return inst_DA(code, operands); case DIV_w : case DIV_d : case DIVU_b: case DIVU_w: case DIVU_d: return inst_DIV(code, operands); - case DA: - return inst_DA(code, operands); - case ASL: - return inst_ASL(code, operands); - case ASR: - return inst_ASR(code, operands); + case DJNZ: + return inst_DJNZ(code, operands); + case FCALL: + return inst_FCALL(code, operands); + case FJMP: + return inst_FJMP(code, operands); + case JB: + return inst_JB(code, operands); + case JBC: + return inst_JBC(code, operands); + case JMP: + return inst_JMP(code, operands); + case JNB: + return inst_JNB(code, operands); + case JNZ: + return inst_JNZ(code, operands); + case JZ: + return inst_JZ(code, operands); case LEA: return inst_LEA(code, operands); - case CPL: - return inst_CPL(code, operands); case LSR: return inst_LSR(code, operands); + case MOV: + return inst_MOV(code, operands); + case MOVC: + return inst_MOVC(code, operands); + case MOVS: + return inst_MOVS(code, operands); + case MOVX: + return inst_MOVX(code, operands); + case MUL_w: + case MULU_b: + case MULU_w: + return inst_MUL(code, operands); + case NEG: + return inst_NEG(code, operands); + case NOP: + return inst_NOP(code, operands); case NORM: return inst_NORM(code, operands); + case OR: + return inst_OR(code, operands); + case ORL: + return inst_ORL(code, operands); + case POP: + case POPU: + return inst_POP(code, operands); + case PUSH: + case PUSHU: + return inst_PUSH(code, operands); + case RESET: + return inst_RESET(code, operands); + case RET: + return inst_RET(code, operands); + case RETI: + return inst_RETI(code, operands); case RL: return inst_RL(code, operands); case RLC: @@ -680,69 +969,31 @@ cl_xa::exec_inst(void) return inst_RR(code, operands); case RRC: return inst_RRC(code, operands); - case MOVS: - return inst_MOVS(code, operands); - case MOVC: - return inst_MOVC(code, operands); - case MOVX: - return inst_MOVX(code, operands); - case PUSH: - return inst_PUSH(code, operands); - case POP: - return inst_POP(code, operands); - case XCH: - return inst_XCH(code, operands); case SETB: return inst_SETB(code, operands); - case CLR: - return inst_CLR(code, operands); - case MOV: - return inst_MOV(code, operands); - case ANL: - return inst_ANL(code, operands); - case ORL: - return inst_ORL(code, operands); - case BEQ: - return inst_BEQ(code, operands); - case BR: - return inst_BR(code, operands); - case JMP: - return inst_JMP(code, operands); - case CALL: - return inst_CALL(code, operands); - case RET: - return inst_RET(code, operands); - case BCC: - return inst_Bcc(code, operands); - case JB: - return inst_JB(code, operands); - case JNB: - return inst_JNB(code, operands); - case CJNE: - return inst_CJNE(code, operands); - case DJNZ: - return inst_DJNZ(code, operands); - case JZ: - return inst_JZ(code, operands); - case JNZ: - return inst_JNZ(code, operands); - case NOP: - return inst_NOP(code, operands); - case BKPT: - return inst_BKPT(code, operands); + case SEXT: + return inst_SEXT(code, operands); + case SUB: + return inst_SUB(code, operands); + case SUBB: + return inst_SUBB(code, operands); case TRAP: return inst_TRAP(code, operands); - case RESET: - return inst_RESET(code, operands); + case XCH: + return inst_XCH(code, operands); + case XOR: + return inst_XOR(code, operands); + case BAD_OPCODE: default: break; } - if (PC) + /*if (PC) PC--; else - PC= get_mem_size(MEM_ROM)-1; + PC= get_mem_size(MEM_ROM_ID)-1;*/ + PC= rom->inc_address(PC, -1); //tick(-clock_per_cycle()); sim->stop(resINV_INST); return(resINV_INST);