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
53 /*******************************************************************/
57 * Base type of HC08 controllers
60 cl_hc08::cl_hc08(class cl_sim *asim):
69 cl_uc::init(); /* Memories now exist */
73 rom= address_space(MEM_ROM_ID);
74 // ram= mem(MEM_XRAM);
77 // zero out ram(this is assumed in regression tests)
78 for (int i=0x80; i<0x8000; i++) {
79 ram->set((t_addr) i, 0);
102 cl_hc08::id_string(void)
104 return("unspecified HC08");
109 * Making elements of the controller
113 cl_hc08::get_mem_size(enum mem_class type)
117 case MEM_ROM: return(0x10000);
118 case MEM_XRAM: return(0x10000);
121 return(cl_uc::get_mem_size(type));
125 cl_hc08::mk_hw_elements(void)
128 /* t_uc::mk_hw() does nothing */
132 cl_hc08::make_memories(void)
134 class cl_address_space *as;
136 as= new cl_address_space("rom", 0, 0x10000, 8);
138 address_spaces->add(as);
140 class cl_address_decoder *ad;
141 class cl_memory_chip *chip;
143 chip= new cl_memory_chip("rom_chip", 0x10000, 8);
146 ad= new cl_address_decoder(as= address_space("rom"), chip, 0, 0xffff, 0);
148 as->decoders->add(ad);
154 * Help command interpreter
158 cl_hc08::dis_tbl(void)
163 /*struct name_entry *
164 cl_hc08::sfr_tbl(void)
169 /*struct name_entry *
170 cl_hc08::bit_tbl(void)
177 cl_hc08::inst_length(t_addr addr)
182 s = get_disasm_info(addr, &len, NULL, NULL);
188 cl_hc08::inst_branch(t_addr addr)
193 s = get_disasm_info(addr, NULL, &b, NULL);
199 cl_hc08::longest_inst(void)
206 cl_hc08::get_disasm_info(t_addr addr,
216 int start_addr = addr;
217 struct dis_entry *dis_e;
219 code= get_mem(MEM_ROM_ID, addr++);
223 case 0x9e: /* ESC code to sp relative op-codes */
224 code= get_mem(MEM_ROM_ID, addr++);
226 while ((code & disass_hc08_9e[i].mask) != disass_hc08_9e[i].code &&
227 disass_hc08_9e[i].mnemonic)
229 dis_e = &disass_hc08_9e[i];
230 b= disass_hc08_9e[i].mnemonic;
232 len += (disass_hc08_9e[i].length + 1);
237 while ((code & disass_hc08[i].mask) != disass_hc08[i].code &&
238 disass_hc08[i].mnemonic)
240 dis_e = &disass_hc08[i];
241 b= disass_hc08[i].mnemonic;
243 len += (disass_hc08[i].length);
248 *ret_branch = dis_e->branch;
253 *immed_offset = immed_n;
254 else *immed_offset = (addr - start_addr);
267 cl_hc08::disass(t_addr addr, char *sep)
269 char work[256], temp[20];
270 char *buf, *p, *b, *t;
272 int immed_offset = 0;
276 b = get_disasm_info(addr, &len, NULL, &immed_offset);
279 buf= (char*)malloc(30);
280 strcpy(buf, "UNKNOWN/INVALID");
291 case 's': // s signed byte immediate
292 sprintf(temp, "#%d", (char)get_mem(MEM_ROM_ID, addr+immed_offset));
295 case 'w': // w word immediate operand
296 sprintf(temp, "#0x%04x",
297 (uint)((get_mem(MEM_ROM_ID, addr+immed_offset)<<8) |
298 (get_mem(MEM_ROM_ID, addr+immed_offset+1))) );
302 case 'b': // b byte immediate operand
303 sprintf(temp, "#0x%02x", (uint)get_mem(MEM_ROM_ID, addr+immed_offset));
306 case 'x': // x extended addressing
307 sprintf(temp, "0x%04x",
308 (uint)((get_mem(MEM_ROM_ID, addr+immed_offset)<<8) |
309 (get_mem(MEM_ROM_ID, addr+immed_offset+1))) );
313 case 'd': // d direct addressing
314 sprintf(temp, "*0x%02x", (uint)get_mem(MEM_ROM_ID, addr+immed_offset));
317 case '2': // 2 word index offset
318 sprintf(temp, "0x%04x",
319 (uint)((get_mem(MEM_ROM_ID, addr+immed_offset)<<8) |
320 (get_mem(MEM_ROM_ID, addr+immed_offset+1))) );
324 case '1': // b byte index offset
325 sprintf(temp, "0x%02x", (uint)get_mem(MEM_ROM_ID, addr+immed_offset));
328 case 'p': // b byte index offset
329 sprintf(temp, "0x%04x",
331 +(char)get_mem(MEM_ROM_ID, addr+immed_offset));
347 p= strchr(work, ' ');
354 buf= (char *)malloc(6+strlen(p)+1);
356 buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1);
357 for (p= work, b= buf; *p != ' '; p++, b++)
363 while (strlen(buf) < 6)
374 cl_hc08::print_regs(class cl_console_base *con)
376 con->dd_printf("V--HINZC Flags= 0x%02x %3d %c ",
377 regs.P, regs.P, isprint(regs.P)?regs.P:'.');
378 con->dd_printf("A= 0x%02x %3d %c\n",
379 regs.A, regs.A, isprint(regs.A)?regs.A:'.');
380 con->dd_printf("%c--%c%c%c%c%c ",
381 (regs.P&BIT_V)?'1':'0',
382 (regs.P&BIT_H)?'1':'0',
383 (regs.P&BIT_I)?'1':'0',
384 (regs.P&BIT_N)?'1':'0',
385 (regs.P&BIT_Z)?'1':'0',
386 (regs.P&BIT_C)?'1':'0');
387 con->dd_printf(" H= 0x%02x %3d %c ",
388 regs.H, regs.H, isprint(regs.H)?regs.H:'.');
389 con->dd_printf("X= 0x%02x %3d %c\n",
390 regs.X, regs.X, isprint(regs.X)?regs.X:'.');
391 con->dd_printf("SP= 0x%04x [SP+1]= %02x %3d %c\n",
392 regs.SP, ram->get(regs.SP+1), ram->get(regs.SP+1),
393 isprint(ram->get(regs.SP+1))?ram->get(regs.SP+1):'.');
395 print_disass(PC, con);
403 cl_hc08::exec_inst(void)
414 return(resBREAKPOINT);
416 switch ((code >> 4) & 0xf) {
417 case 0x0: return(inst_bittestsetclear(code, false));
418 case 0x1: return(inst_bitsetclear(code, false));
419 case 0x2: return(inst_condbranch(code, false));
425 switch (code & 0xf) {
426 case 0x0: return(inst_neg(code, false));
427 case 0x1: return(inst_cbeq(code, false));
430 case 0x42: return(inst_mul(code, false));
431 case 0x52: return(inst_div(code, false));
432 case 0x62: return(inst_nsa(code, false));
433 case 0x72: return(inst_daa(code, false));
434 default: return(resHALT);
436 case 0x3: return(inst_com(code, false));
437 case 0x4: return(inst_lsr(code, false));
440 case 0x35: return(inst_sthx(code, false));
442 case 0x55: return(inst_ldhx(code, false));
444 case 0x75: return(inst_cphx(code, false));
445 default: return(resHALT);
447 case 0x6: return(inst_ror(code, false));
448 case 0x7: return(inst_asr(code, false));
449 case 0x8: return(inst_lsl(code, false));
450 case 0x9: return(inst_rol(code, false));
451 case 0xa: return(inst_dec(code, false));
452 case 0xb: return(inst_dbnz(code, false));
453 case 0xc: return(inst_inc(code, false));
454 case 0xd: return(inst_tst(code, false));
460 case 0x7e: return(inst_mov(code, false));
461 default: return(resHALT);
463 case 0xf: return(inst_clr(code, false));
464 default: return(resHALT);
467 switch (code & 0xf) {
468 case 0x0: return(inst_rti(code, false));
469 case 0x1: return(inst_rts(code, false));
470 case 0x3: return(inst_swi(code, false));
472 case 0x5: return(inst_transfer(code, false));
478 case 0xb: return(inst_pushpull(code, false));
479 case 0xc: return(inst_clrh(code, false));
480 case 0xe: return(inst_stop(code, false));
481 case 0xf: return(inst_wait(code, false));
482 default: return(resHALT);
485 switch (code & 0xf) {
489 case 0x3: return(inst_condbranch(code, false));
493 case 0xf: return(inst_transfer(code, false));
497 case 0xb: return(inst_setclearflags(code, false));
498 case 0xc: return(inst_rsp(code, false));
499 case 0xd: return(inst_nop(code, false));
502 switch ((code >> 4) & 0xf) {
504 switch (code & 0xf) {
505 case 0x0: return(inst_neg(code, true));
506 case 0x1: return(inst_cbeq(code, true));
507 case 0x3: return(inst_com(code, true));
508 case 0x4: return(inst_lsr(code, true));
509 case 0x6: return(inst_ror(code, true));
510 case 0x7: return(inst_asr(code, true));
511 case 0x8: return(inst_lsl(code, true));
512 case 0x9: return(inst_rol(code, true));
513 case 0xa: return(inst_dec(code, true));
514 case 0xb: return(inst_dbnz(code, true));
515 case 0xc: return(inst_inc(code, true));
516 case 0xd: return(inst_tst(code, true));
517 case 0xf: return(inst_clr(code, true));
518 default: return(resHALT);
522 switch (code & 0xf) {
523 case 0x0: return(inst_sub(code, true));
524 case 0x1: return(inst_cmp(code, true));
525 case 0x2: return(inst_sbc(code, true));
526 case 0x3: return(inst_cpx(code, true));
527 case 0x4: return(inst_and(code, true));
528 case 0x5: return(inst_bit(code, true));
529 case 0x6: return(inst_lda(code, true));
530 case 0x7: return(inst_sta(code, true));
531 case 0x8: return(inst_eor(code, true));
532 case 0x9: return(inst_adc(code, true));
533 case 0xa: return(inst_ora(code, true));
534 case 0xb: return(inst_add(code, true));
535 case 0xc: return(resHALT);
536 case 0xd: putchar(regs.A); fflush(stdout); return(resGO);
537 case 0xe: return(inst_ldx(code, true));
538 case 0xf: return(inst_stx(code, true));
539 default: return(resHALT);
541 default: return(resHALT);
551 switch (code & 0xf) {
552 case 0x0: return(inst_sub(code, false));
553 case 0x1: return(inst_cmp(code, false));
554 case 0x2: return(inst_sbc(code, false));
555 case 0x3: return(inst_cpx(code, false));
556 case 0x4: return(inst_and(code, false));
557 case 0x5: return(inst_bit(code, false));
558 case 0x6: return(inst_lda(code, false));
561 return(inst_ais(code, false));
563 return(inst_sta(code, false));
564 case 0x8: return(inst_eor(code, false));
565 case 0x9: return(inst_adc(code, false));
566 case 0xa: return(inst_ora(code, false));
567 case 0xb: return(inst_add(code, false));
572 return(inst_jmp(code, false));
575 return(inst_bsr(code, false));
577 return(inst_jsr(code, false));
578 case 0xe: return(inst_ldx(code, false));
581 return(inst_aix(code, false));
583 return(inst_stx(code, false));
584 default: return(resHALT);
586 default: return(resHALT);
592 PC= get_mem_size(MEM_ROM_ID)-1;*/
593 PC= rom->inc_address(PC, -1);
595 sim->stop(resINV_INST);
600 /* End of hc08.src/hc08.cc */