2 * Simulator of microcontrollers (hc08.cc)
4 * some hc08 code base from Karl Bongers karl@turbobit.com
6 * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
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
32 #include <stdarg.h> /* for va_list */
51 #define uint8 unsigned char
57 /*******************************************************************/
61 * Base type of HC08 controllers
64 cl_hc08::cl_hc08(class cl_sim *asim):
73 cl_uc::init(); /* Memories now exist */
78 // ram= mem(MEM_XRAM);
81 // zero out ram(this is assumed in regression tests)
82 for (int i=0x80; i<0x8000; i++) {
83 ram->set((t_addr) i, 0);
106 cl_hc08::id_string(void)
108 return("unspecified HC08");
113 * Making elements of the controller
117 cl_hc08::get_mem_size(enum mem_class type)
121 case MEM_ROM: return(0x10000);
122 case MEM_XRAM: return(0x10000);
125 return(cl_uc::get_mem_size(type));
129 cl_hc08::mk_hw_elements(void)
132 /* t_uc::mk_hw() does nothing */
137 * Help command interpreter
141 cl_hc08::dis_tbl(void)
146 /*struct name_entry *
147 cl_hc08::sfr_tbl(void)
152 /*struct name_entry *
153 cl_hc08::bit_tbl(void)
160 cl_hc08::inst_length(t_addr addr)
165 s = get_disasm_info(addr, &len, NULL, NULL);
171 cl_hc08::inst_branch(t_addr addr)
176 s = get_disasm_info(addr, NULL, &b, NULL);
182 cl_hc08::longest_inst(void)
189 cl_hc08::get_disasm_info(t_addr addr,
199 int start_addr = addr;
200 struct dis_entry *dis_e;
202 code= get_mem(MEM_ROM, addr++);
206 case 0x9e: /* ESC code to sp relative op-codes */
207 code= get_mem(MEM_ROM, addr++);
209 while ((code & disass_hc08_9e[i].mask) != disass_hc08_9e[i].code &&
210 disass_hc08_9e[i].mnemonic)
212 dis_e = &disass_hc08_9e[i];
213 b= disass_hc08_9e[i].mnemonic;
215 len += (disass_hc08_9e[i].length + 1);
220 while ((code & disass_hc08[i].mask) != disass_hc08[i].code &&
221 disass_hc08[i].mnemonic)
223 dis_e = &disass_hc08[i];
224 b= disass_hc08[i].mnemonic;
226 len += (disass_hc08[i].length);
231 *ret_branch = dis_e->branch;
236 *immed_offset = immed_n;
237 else *immed_offset = (addr - start_addr);
250 cl_hc08::disass(t_addr addr, char *sep)
252 char work[256], temp[20];
253 char *buf, *p, *b, *t;
255 int immed_offset = 0;
259 b = get_disasm_info(addr, &len, NULL, &immed_offset);
262 buf= (char*)malloc(30);
263 strcpy(buf, "UNKNOWN/INVALID");
274 case 's': // s signed byte immediate
275 sprintf(temp, "#%d", (char)get_mem(MEM_ROM, addr+immed_offset));
278 case 'w': // w word immediate operand
279 sprintf(temp, "#0x%04x",
280 (uint)((get_mem(MEM_ROM, addr+immed_offset)<<8) |
281 (get_mem(MEM_ROM, addr+immed_offset+1))) );
285 case 'b': // b byte immediate operand
286 sprintf(temp, "#0x%02x", (uint)get_mem(MEM_ROM, addr+immed_offset));
289 case 'x': // x extended addressing
290 sprintf(temp, "0x%04x",
291 (uint)((get_mem(MEM_ROM, addr+immed_offset)<<8) |
292 (get_mem(MEM_ROM, addr+immed_offset+1))) );
296 case 'd': // d direct addressing
297 sprintf(temp, "*0x%02x", (uint)get_mem(MEM_ROM, addr+immed_offset));
300 case '2': // 2 word index offset
301 sprintf(temp, "0x%04x",
302 (uint)((get_mem(MEM_ROM, addr+immed_offset)<<8) |
303 (get_mem(MEM_ROM, addr+immed_offset+1))) );
307 case '1': // b byte index offset
308 sprintf(temp, "0x%02x", (uint)get_mem(MEM_ROM, addr+immed_offset));
311 case 'p': // b byte index offset
312 sprintf(temp, "0x%04x",
314 +(char)get_mem(MEM_ROM, addr+immed_offset));
330 p= strchr(work, ' ');
337 buf= (char *)malloc(6+strlen(p)+1);
339 buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1);
340 for (p= work, b= buf; *p != ' '; p++, b++)
346 while (strlen(buf) < 6)
357 cl_hc08::print_regs(class cl_console *con)
359 con->dd_printf("V--HINZC Flags= 0x%02x %3d %c ",
360 regs.P, regs.P, isprint(regs.P)?regs.P:'.');
361 con->dd_printf("A= 0x%02x %3d %c\n",
362 regs.A, regs.A, isprint(regs.A)?regs.A:'.');
363 con->dd_printf("%c--%c%c%c%c%c ",
364 (regs.P&BIT_V)?'1':'0',
365 (regs.P&BIT_H)?'1':'0',
366 (regs.P&BIT_I)?'1':'0',
367 (regs.P&BIT_N)?'1':'0',
368 (regs.P&BIT_Z)?'1':'0',
369 (regs.P&BIT_C)?'1':'0');
370 con->dd_printf(" H= 0x%02x %3d %c ",
371 regs.H, regs.H, isprint(regs.H)?regs.H:'.');
372 con->dd_printf("X= 0x%02x %3d %c\n",
373 regs.X, regs.X, isprint(regs.X)?regs.X:'.');
374 con->dd_printf("SP= 0x%04x [SP+1]= %02x %3d %c\n",
375 regs.SP, ram->get(regs.SP+1), ram->get(regs.SP+1),
376 isprint(ram->get(regs.SP+1))?ram->get(regs.SP+1):'.');
378 print_disass(PC, con);
386 cl_hc08::exec_inst(void)
397 return(resBREAKPOINT);
399 switch ((code >> 4) & 0xf) {
400 case 0x0: return(inst_bittestsetclear(code, FALSE));
401 case 0x1: return(inst_bitsetclear(code, FALSE));
402 case 0x2: return(inst_condbranch(code, FALSE));
408 switch (code & 0xf) {
409 case 0x0: return(inst_neg(code, FALSE));
410 case 0x1: return(inst_cbeq(code, FALSE));
413 case 0x42: return(inst_mul(code, FALSE));
414 case 0x52: return(inst_div(code, FALSE));
415 case 0x62: return(inst_nsa(code, FALSE));
416 case 0x72: return(inst_daa(code, FALSE));
417 default: return(resHALT);
419 case 0x3: return(inst_com(code, FALSE));
420 case 0x4: return(inst_lsr(code, FALSE));
423 case 0x35: return(inst_sthx(code, FALSE));
425 case 0x55: return(inst_ldhx(code, FALSE));
427 case 0x75: return(inst_cphx(code, FALSE));
428 default: return(resHALT);
430 case 0x6: return(inst_ror(code, FALSE));
431 case 0x7: return(inst_asr(code, FALSE));
432 case 0x8: return(inst_lsl(code, FALSE));
433 case 0x9: return(inst_rol(code, FALSE));
434 case 0xa: return(inst_dec(code, FALSE));
435 case 0xb: return(inst_dbnz(code, FALSE));
436 case 0xc: return(inst_inc(code, FALSE));
437 case 0xd: return(inst_tst(code, FALSE));
443 case 0x7e: return(inst_mov(code, FALSE));
444 default: return(resHALT);
446 case 0xf: return(inst_clr(code, FALSE));
447 default: return(resHALT);
450 switch (code & 0xf) {
451 case 0x0: return(inst_rti(code, FALSE));
452 case 0x1: return(inst_rts(code, FALSE));
453 case 0x3: return(inst_swi(code, FALSE));
455 case 0x5: return(inst_transfer(code, FALSE));
461 case 0xb: return(inst_pushpull(code, FALSE));
462 case 0xc: return(inst_clrh(code, FALSE));
463 case 0xe: return(inst_stop(code, FALSE));
464 case 0xf: return(inst_wait(code, FALSE));
465 default: return(resHALT);
468 switch (code & 0xf) {
472 case 0x3: return(inst_condbranch(code, FALSE));
476 case 0xf: return(inst_transfer(code, FALSE));
480 case 0xb: return(inst_setclearflags(code, FALSE));
481 case 0xc: return(inst_rsp(code, FALSE));
482 case 0xd: return(inst_nop(code, FALSE));
485 switch ((code >> 4) & 0xf) {
487 switch (code & 0xf) {
488 case 0x0: return(inst_neg(code, TRUE));
489 case 0x1: return(inst_cbeq(code, TRUE));
490 case 0x3: return(inst_com(code, TRUE));
491 case 0x4: return(inst_lsr(code, TRUE));
492 case 0x6: return(inst_ror(code, TRUE));
493 case 0x7: return(inst_asr(code, TRUE));
494 case 0x8: return(inst_lsl(code, TRUE));
495 case 0x9: return(inst_rol(code, TRUE));
496 case 0xa: return(inst_dec(code, TRUE));
497 case 0xb: return(inst_dbnz(code, TRUE));
498 case 0xc: return(inst_inc(code, TRUE));
499 case 0xd: return(inst_tst(code, TRUE));
500 case 0xf: return(inst_clr(code, TRUE));
501 default: return(resHALT);
505 switch (code & 0xf) {
506 case 0x0: return(inst_sub(code, TRUE));
507 case 0x1: return(inst_cmp(code, TRUE));
508 case 0x2: return(inst_sbc(code, TRUE));
509 case 0x3: return(inst_cpx(code, TRUE));
510 case 0x4: return(inst_and(code, TRUE));
511 case 0x5: return(inst_bit(code, TRUE));
512 case 0x6: return(inst_lda(code, TRUE));
513 case 0x7: return(inst_sta(code, TRUE));
514 case 0x8: return(inst_eor(code, TRUE));
515 case 0x9: return(inst_adc(code, TRUE));
516 case 0xa: return(inst_ora(code, TRUE));
517 case 0xb: return(inst_add(code, TRUE));
518 case 0xc: return(resHALT);
519 case 0xd: putchar(regs.A); fflush(stdout); return(resGO);
520 case 0xe: return(inst_ldx(code, TRUE));
521 case 0xf: return(inst_stx(code, TRUE));
522 default: return(resHALT);
524 default: return(resHALT);
534 switch (code & 0xf) {
535 case 0x0: return(inst_sub(code, FALSE));
536 case 0x1: return(inst_cmp(code, FALSE));
537 case 0x2: return(inst_sbc(code, FALSE));
538 case 0x3: return(inst_cpx(code, FALSE));
539 case 0x4: return(inst_and(code, FALSE));
540 case 0x5: return(inst_bit(code, FALSE));
541 case 0x6: return(inst_lda(code, FALSE));
544 return(inst_ais(code, FALSE));
546 return(inst_sta(code, FALSE));
547 case 0x8: return(inst_eor(code, FALSE));
548 case 0x9: return(inst_adc(code, FALSE));
549 case 0xa: return(inst_ora(code, FALSE));
550 case 0xb: return(inst_add(code, FALSE));
555 return(inst_jmp(code, FALSE));
558 return(inst_bsr(code, FALSE));
560 return(inst_jsr(code, FALSE));
561 case 0xe: return(inst_ldx(code, FALSE));
564 return(inst_aix(code, FALSE));
566 return(inst_stx(code, FALSE));
567 default: return(resHALT);
569 default: return(resHALT);
575 PC= get_mem_size(MEM_ROM)-1;
577 sim->stop(resINV_INST);
582 /* End of hc08.src/hc08.cc */