2 * Simulator of microcontrollers (xa.cc)
4 * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
6 * Written by Karl Bongers karl@turbobit.com
8 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
12 /* This file is part of microcontroller simulator: ucsim.
14 UCSIM is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 UCSIM is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with UCSIM; see the file COPYING. If not, write to the Free
26 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
50 * Base type of xa controllers
53 cl_xa::cl_xa(class cl_sim *asim):
62 cl_uc::init(); /* Memories now exist */
66 wmem_direct = (TYPE_UWORD *) &mem_direct[0];
68 /* initialize SP to 100H */
71 printf("The XA Simulator is in development, UNSTABLE, DEVELOPERS ONLY!\n");
77 cl_xa::id_string(void)
79 return("unspecified XA");
84 * Making elements of the controller
88 cl_xa::get_mem_size(enum mem_class type)
92 case MEM_ROM: return(0x10000);
93 case MEM_XRAM: return(0x10000);
96 return(cl_uc::get_mem_size(type));
100 cl_xa::mk_hw_elements(void)
103 /* t_uc::mk_hw() does nothing */
108 * Help command interpreter
114 // this should be unused, we need to make main prog code
115 // independent of any array thing.
116 printf("ERROR - Using disass[] table in XA sim code!\n");
117 return(glob_disass_xa);
120 /*struct name_entry *
126 /*struct name_entry *
134 cl_xa::inst_length(t_addr addr)
138 get_disasm_info(addr, &len, NULL, NULL, NULL, NULL);
144 cl_xa::inst_branch(t_addr addr)
148 get_disasm_info(addr, NULL, &b, NULL, NULL, NULL);
154 cl_xa::longest_inst(void)
159 /*--------------------------------------------------------------------
161 |--------------------------------------------------------------------*/
163 cl_xa::get_disasm_info(t_addr addr,
174 int start_addr = addr;
176 code= get_mem(MEM_ROM, addr++);
179 while (disass_xa[i].mnemonic != NOP)
183 code = (code << 8) | get_mem(MEM_ROM, addr++);
185 while ((code & disass_xa[i].mask) != disass_xa[i].code &&
186 disass_xa[i].mnemonic != BAD_OPCODE)
191 *ret_len = disass_xa[i].length;
193 *ret_branch = disass_xa[i].branch;
196 *immed_offset = immed_n;
197 else *immed_offset = (addr - start_addr);
200 *parms = disass_xa[i].operands;
203 *mnemonic = disass_xa[i].mnemonic;
209 static char *w_reg_strs[] = {
219 static char *b_reg_strs[] = {
229 /*--------------------------------------------------------------------
231 |--------------------------------------------------------------------*/
233 cl_xa::disass(t_addr addr, char *sep)
235 char work[256], parm_str[40];
239 int immed_offset = 0;
246 code = get_disasm_info(addr, &len, NULL, &immed_offset, &operands, &mnemonic);
248 if (mnemonic == BAD_OPCODE) {
249 buf= (char*)malloc(30);
250 strcpy(buf, "UNKNOWN/INVALID");
255 reg_strs = w_reg_strs;
257 reg_strs = b_reg_strs;
260 // the repeating common parameter encoding for ADD, ADDC, SUB, AND...
262 sprintf(parm_str, "%s,%s",
263 reg_strs[((code >> 4) & 0xf)],
264 reg_strs[(code & 0xf)]);
267 sprintf(parm_str, "%s,[%s]",
268 reg_strs[((code >> 4) & 0xf)],
269 w_reg_strs[(code & 0xf)]);
272 sprintf(parm_str, "[%s],%s",
273 w_reg_strs[(code & 0x7)],
274 reg_strs[((code >> 4) & 0xf)] );
277 sprintf(parm_str, "%s,[%s+%02d]",
278 reg_strs[((code >> 4) & 0xf)],
279 w_reg_strs[(code & 0x7)],
280 get_mem(MEM_ROM, addr+immed_offset));
284 sprintf(parm_str, "[%s+%02d],%s",
285 w_reg_strs[(code & 0x7)],
286 get_mem(MEM_ROM, addr+immed_offset),
287 reg_strs[((code >> 4) & 0xf)] );
291 sprintf(parm_str, "%s,[%s+%04d]",
292 reg_strs[((code >> 4) & 0xf)],
293 w_reg_strs[(code & 0x7)],
294 (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
295 (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
300 sprintf(parm_str, "[%s+%04d],%s",
301 w_reg_strs[(code & 0x7)],
302 (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
303 (get_mem(MEM_ROM, addr+immed_offset)<<8)),
304 reg_strs[((code >> 4) & 0xf)] );
309 sprintf(parm_str, "%s,[%s+]",
310 reg_strs[((code >> 4) & 0xf)],
311 w_reg_strs[(code & 0xf)]);
314 sprintf(parm_str, "[%s+],%s",
315 w_reg_strs[(code & 0x7)],
316 reg_strs[((code >> 4) & 0xf)] );
319 sprintf(parm_str, "0x%04x,%s",
320 ((code & 0x3) << 8) | get_mem(MEM_ROM, addr+immed_offset),
321 reg_strs[((code >> 4) & 0xf)] );
325 sprintf(parm_str, "%s, @0x%04x",
326 reg_strs[((code >> 4) & 0xf)],
327 ((code & 0x3) << 8) | get_mem(MEM_ROM, addr+immed_offset) );
331 sprintf(parm_str, "%s, #%02d",
332 b_reg_strs[((code >> 4) & 0xf)],
333 get_mem(MEM_ROM, addr+immed_offset) );
337 sprintf(parm_str, "%s, #%04d",
338 reg_strs[((code >> 4) & 0xf)],
339 (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
340 (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
345 sprintf(parm_str, "[%s], 0x%02x",
346 w_reg_strs[((code >> 4) & 0x7)],
347 get_mem(MEM_ROM, addr+immed_offset) );
351 sprintf(parm_str, "[%s], 0x%04x",
352 w_reg_strs[((code >> 4) & 0x7)],
353 (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
354 (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
359 sprintf(parm_str, "[%s+], 0x%02x",
360 w_reg_strs[((code >> 4) & 0x7)],
361 get_mem(MEM_ROM, addr+immed_offset) );
364 case IREGINC_DATA16 :
365 sprintf(parm_str, "[%s+], 0x%04x",
366 w_reg_strs[((code >> 4) & 0x7)],
367 (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
368 (get_mem(MEM_ROM, addr+immed_offset)<<8)) );
372 case IREGOFF8_DATA8 :
373 sprintf(parm_str, "[%s+%02d], 0x%02x",
374 w_reg_strs[((code >> 4) & 0x7)],
375 get_mem(MEM_ROM, addr+immed_offset),
376 get_mem(MEM_ROM, addr+immed_offset+1) );
379 case IREGOFF8_DATA16 :
380 sprintf(parm_str, "[%s+%02d], 0x%04x",
381 w_reg_strs[((code >> 4) & 0x7)],
382 get_mem(MEM_ROM, addr+immed_offset),
383 (short)((get_mem(MEM_ROM, addr+immed_offset+2)) |
384 (get_mem(MEM_ROM, addr+immed_offset+1)<<8)) );
387 case IREGOFF16_DATA8 :
388 sprintf(parm_str, "[%s+%04d], 0x%02x",
389 w_reg_strs[((code >> 4) & 0x7)],
390 (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
391 (get_mem(MEM_ROM, addr+immed_offset+0)<<8)),
392 get_mem(MEM_ROM, addr+immed_offset+2) );
395 case IREGOFF16_DATA16 :
396 sprintf(parm_str, "[%s+%04d], 0x%04x",
397 w_reg_strs[((code >> 4) & 0x7)],
398 (short)((get_mem(MEM_ROM, addr+immed_offset+1)) |
399 (get_mem(MEM_ROM, addr+immed_offset+0)<<8)),
400 (short)((get_mem(MEM_ROM, addr+immed_offset+3)) |
401 (get_mem(MEM_ROM, addr+immed_offset+2)<<8)) );
405 sprintf(parm_str, "#%04d 0x%02x",
406 ((code & 0x3) << 8) | get_mem(MEM_ROM, addr+immed_offset),
407 get_mem(MEM_ROM, addr+immed_offset+1) );
411 sprintf(parm_str, "#%04d 0x%04x",
412 ((code & 0x3) << 8) | get_mem(MEM_ROM, addr+immed_offset),
413 (short)((get_mem(MEM_ROM, addr+immed_offset+2)) |
414 (get_mem(MEM_ROM, addr+immed_offset+1)<<8)) );
419 case NO_OPERANDS : // for NOP
420 strcpy(parm_str, "");
423 strcpy(parm_str, "C_BIT");
426 strcpy(parm_str, "REG_DATA4");
429 strcpy(parm_str, "IREG_DATA4");
432 strcpy(parm_str, "IREGINC_DATA4");
434 case IREGOFF8_DATA4 :
435 strcpy(parm_str, "IREGOFF8_DATA4");
437 case IREGOFF16_DATA4 :
438 strcpy(parm_str, "IREGOFF16_DATA4");
441 strcpy(parm_str, "DIRECT_DATA4");
445 sprintf(parm_str, "%s",
446 reg_strs[((code >> 4) & 0xf)] );
449 strcpy(parm_str, "ADDR24");
452 strcpy(parm_str, "REG_REL8");
455 strcpy(parm_str, "DIRECT_REL8");
458 strcpy(parm_str, "???");
462 sprintf(work, "%s %s",
463 op_mnemonic_str[ mnemonic ],
466 p= strchr(work, ' ');
473 buf= (char *)malloc(6+strlen(p)+1);
475 buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1);
476 for (p= work, b= buf; *p != ' '; p++, b++)
482 while (strlen(buf) < 6)
491 /*--------------------------------------------------------------------
493 |--------------------------------------------------------------------*/
495 cl_xa::print_regs(class cl_console *con)
500 con->dd_printf("CA---VNZ Flags: %02x ", flags);
501 con->dd_printf("R0:%04x R1:%04x R2:%04x R3:%04x\n",
502 get_reg(1,0), get_reg(1,2), get_reg(1,4), get_reg(1,6));
504 con->dd_printf("%c%c---%c%c%c ",
505 (flags & BIT_C)?'1':'0',
506 (flags & BIT_AC)?'1':'0',
507 (flags & BIT_V)?'1':'0',
508 (flags & BIT_N)?'1':'0',
509 (flags & BIT_Z)?'1':'0');
511 con->dd_printf("R4:%04x R5:%04x R6:%04x R7(SP):%04x ES:%04x DS:%04x\n",
512 get_reg(1,8), get_reg(1,10), get_reg(1,12), get_reg(1,14), 0, 0);
514 print_disass(PC, con);
523 cl_xa::exec_inst(void)
530 return(resBREAKPOINT);
533 if (code1 == 0) // nop, 1 byte instr
534 return(inst_NOP(code1));
537 return(resBREAKPOINT);
538 code = (code1 << 8) | code2;
541 while ((code & disass_xa[i].mask) != disass_xa[i].code &&
542 disass_xa[i].mnemonic != BAD_OPCODE)
545 code |= ((int)(disass_xa[i].operands)) << 16; // kludgy, tack on operands info
546 switch (disass_xa[i].mnemonic)
549 return inst_ADD(code);
551 return inst_ADDC(code);
553 return inst_SUB(code);
555 return inst_SUBB(code);
557 return inst_CMP(code);
559 return inst_AND(code);
561 return inst_OR(code);
563 return inst_XOR(code);
565 return inst_ADDS(code);
567 return inst_NEG(code);
569 return inst_SEXT(code);
571 return inst_MUL(code);
577 return inst_DIV(code);
579 return inst_DA(code);
581 return inst_ASL(code);
583 return inst_ASR(code);
585 return inst_LEA(code);
587 return inst_CPL(code);
589 return inst_LSR(code);
591 return inst_NORM(code);
593 return inst_RL(code);
595 return inst_RLC(code);
597 return inst_RR(code);
599 return inst_RRC(code);
601 return inst_MOVS(code);
603 return inst_MOVC(code);
605 return inst_MOVX(code);
607 return inst_PUSH(code);
609 return inst_POP(code);
611 return inst_XCH(code);
613 return inst_SETB(code);
615 return inst_CLR(code);
617 return inst_MOV(code);
619 return inst_ANL(code);
621 return inst_ORL(code);
623 return inst_BR(code);
625 return inst_JMP(code);
627 return inst_CALL(code);
629 return inst_RET(code);
631 return inst_Bcc(code);
633 return inst_JB(code);
635 return inst_JNB(code);
637 return inst_CJNE(code);
639 return inst_DJNZ(code);
641 return inst_JZ(code);
643 return inst_JNZ(code);
645 return inst_NOP(code);
647 return inst_BKPT(code);
649 return inst_TRAP(code);
651 return inst_RESET(code);
660 PC= get_mem_size(MEM_ROM)-1;
661 //tick(-clock_per_cycle());
662 sim->stop(resINV_INST);
667 /* End of xa.src/xa.cc */