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)
181 get_disasm_info(addr, &len, NULL, NULL);
187 cl_hc08::inst_branch(t_addr addr)
191 get_disasm_info(addr, NULL, &b, NULL);
197 cl_hc08::longest_inst(void)
204 cl_hc08::get_disasm_info(t_addr addr,
209 const char *b = NULL;
214 int start_addr = addr;
215 struct dis_entry *dis_e;
217 code= get_mem(MEM_ROM_ID, addr++);
221 case 0x9e: /* ESC code to sp relative op-codes */
222 code= get_mem(MEM_ROM_ID, addr++);
224 while ((code & disass_hc08_9e[i].mask) != disass_hc08_9e[i].code &&
225 disass_hc08_9e[i].mnemonic)
227 dis_e = &disass_hc08_9e[i];
228 b= disass_hc08_9e[i].mnemonic;
230 len += (disass_hc08_9e[i].length + 1);
235 while ((code & disass_hc08[i].mask) != disass_hc08[i].code &&
236 disass_hc08[i].mnemonic)
238 dis_e = &disass_hc08[i];
239 b= disass_hc08[i].mnemonic;
241 len += (disass_hc08[i].length);
246 *ret_branch = dis_e->branch;
251 *immed_offset = immed_n;
252 else *immed_offset = (addr - start_addr);
265 cl_hc08::disass(t_addr addr, const char *sep)
267 char work[256], temp[20];
271 int immed_offset = 0;
275 b = get_disasm_info(addr, &len, NULL, &immed_offset);
278 buf= (char*)malloc(30);
279 strcpy(buf, "UNKNOWN/INVALID");
290 case 's': // s signed byte immediate
291 sprintf(temp, "#%d", (char)get_mem(MEM_ROM_ID, addr+immed_offset));
294 case 'w': // w word immediate operand
295 sprintf(temp, "#0x%04x",
296 (uint)((get_mem(MEM_ROM_ID, addr+immed_offset)<<8) |
297 (get_mem(MEM_ROM_ID, addr+immed_offset+1))) );
301 case 'b': // b byte immediate operand
302 sprintf(temp, "#0x%02x", (uint)get_mem(MEM_ROM_ID, addr+immed_offset));
305 case 'x': // x extended addressing
306 sprintf(temp, "0x%04x",
307 (uint)((get_mem(MEM_ROM_ID, addr+immed_offset)<<8) |
308 (get_mem(MEM_ROM_ID, addr+immed_offset+1))) );
312 case 'd': // d direct addressing
313 sprintf(temp, "*0x%02x", (uint)get_mem(MEM_ROM_ID, addr+immed_offset));
316 case '2': // 2 word index offset
317 sprintf(temp, "0x%04x",
318 (uint)((get_mem(MEM_ROM_ID, addr+immed_offset)<<8) |
319 (get_mem(MEM_ROM_ID, addr+immed_offset+1))) );
323 case '1': // b byte index offset
324 sprintf(temp, "0x%02x", (uint)get_mem(MEM_ROM_ID, addr+immed_offset));
327 case 'p': // b byte index offset
328 sprintf(temp, "0x%04x",
330 +(char)get_mem(MEM_ROM_ID, addr+immed_offset));
346 p= strchr(work, ' ');
353 buf= (char *)malloc(6+strlen(p)+1);
355 buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1);
356 for (p= work, t= buf; *p != ' '; p++, t++)
362 while (strlen(buf) < 6)
373 cl_hc08::print_regs(class cl_console_base *con)
375 con->dd_printf("V--HINZC Flags= 0x%02x %3d %c ",
376 regs.P, regs.P, isprint(regs.P)?regs.P:'.');
377 con->dd_printf("A= 0x%02x %3d %c\n",
378 regs.A, regs.A, isprint(regs.A)?regs.A:'.');
379 con->dd_printf("%c--%c%c%c%c%c ",
380 (regs.P&BIT_V)?'1':'0',
381 (regs.P&BIT_H)?'1':'0',
382 (regs.P&BIT_I)?'1':'0',
383 (regs.P&BIT_N)?'1':'0',
384 (regs.P&BIT_Z)?'1':'0',
385 (regs.P&BIT_C)?'1':'0');
386 con->dd_printf(" H= 0x%02x %3d %c ",
387 regs.H, regs.H, isprint(regs.H)?regs.H:'.');
388 con->dd_printf("X= 0x%02x %3d %c\n",
389 regs.X, regs.X, isprint(regs.X)?regs.X:'.');
390 con->dd_printf("SP= 0x%04x [SP+1]= %02x %3d %c\n",
391 regs.SP, ram->get(regs.SP+1), ram->get(regs.SP+1),
392 isprint(ram->get(regs.SP+1))?ram->get(regs.SP+1):'.');
394 print_disass(PC, con);
402 cl_hc08::exec_inst(void)
413 return(resBREAKPOINT);
415 switch ((code >> 4) & 0xf) {
416 case 0x0: return(inst_bittestsetclear(code, false));
417 case 0x1: return(inst_bitsetclear(code, false));
418 case 0x2: return(inst_condbranch(code, false));
424 switch (code & 0xf) {
425 case 0x0: return(inst_neg(code, false));
426 case 0x1: return(inst_cbeq(code, false));
429 case 0x42: return(inst_mul(code, false));
430 case 0x52: return(inst_div(code, false));
431 case 0x62: return(inst_nsa(code, false));
432 case 0x72: return(inst_daa(code, false));
433 default: return(resHALT);
435 case 0x3: return(inst_com(code, false));
436 case 0x4: return(inst_lsr(code, false));
439 case 0x35: return(inst_sthx(code, false));
441 case 0x55: return(inst_ldhx(code, false));
443 case 0x75: return(inst_cphx(code, false));
444 default: return(resHALT);
446 case 0x6: return(inst_ror(code, false));
447 case 0x7: return(inst_asr(code, false));
448 case 0x8: return(inst_lsl(code, false));
449 case 0x9: return(inst_rol(code, false));
450 case 0xa: return(inst_dec(code, false));
451 case 0xb: return(inst_dbnz(code, false));
452 case 0xc: return(inst_inc(code, false));
453 case 0xd: return(inst_tst(code, false));
459 case 0x7e: return(inst_mov(code, false));
460 default: return(resHALT);
462 case 0xf: return(inst_clr(code, false));
463 default: return(resHALT);
466 switch (code & 0xf) {
467 case 0x0: return(inst_rti(code, false));
468 case 0x1: return(inst_rts(code, false));
469 case 0x3: return(inst_swi(code, false));
471 case 0x5: return(inst_transfer(code, false));
477 case 0xb: return(inst_pushpull(code, false));
478 case 0xc: return(inst_clrh(code, false));
479 case 0xe: return(inst_stop(code, false));
480 case 0xf: return(inst_wait(code, false));
481 default: return(resHALT);
484 switch (code & 0xf) {
488 case 0x3: return(inst_condbranch(code, false));
492 case 0xf: return(inst_transfer(code, false));
496 case 0xb: return(inst_setclearflags(code, false));
497 case 0xc: return(inst_rsp(code, false));
498 case 0xd: return(inst_nop(code, false));
501 switch ((code >> 4) & 0xf) {
503 switch (code & 0xf) {
504 case 0x0: return(inst_neg(code, true));
505 case 0x1: return(inst_cbeq(code, true));
506 case 0x3: return(inst_com(code, true));
507 case 0x4: return(inst_lsr(code, true));
508 case 0x6: return(inst_ror(code, true));
509 case 0x7: return(inst_asr(code, true));
510 case 0x8: return(inst_lsl(code, true));
511 case 0x9: return(inst_rol(code, true));
512 case 0xa: return(inst_dec(code, true));
513 case 0xb: return(inst_dbnz(code, true));
514 case 0xc: return(inst_inc(code, true));
515 case 0xd: return(inst_tst(code, true));
516 case 0xf: return(inst_clr(code, true));
517 default: return(resHALT);
521 switch (code & 0xf) {
522 case 0x0: return(inst_sub(code, true));
523 case 0x1: return(inst_cmp(code, true));
524 case 0x2: return(inst_sbc(code, true));
525 case 0x3: return(inst_cpx(code, true));
526 case 0x4: return(inst_and(code, true));
527 case 0x5: return(inst_bit(code, true));
528 case 0x6: return(inst_lda(code, true));
529 case 0x7: return(inst_sta(code, true));
530 case 0x8: return(inst_eor(code, true));
531 case 0x9: return(inst_adc(code, true));
532 case 0xa: return(inst_ora(code, true));
533 case 0xb: return(inst_add(code, true));
534 case 0xc: return(resHALT);
535 case 0xd: putchar(regs.A); fflush(stdout); return(resGO);
536 case 0xe: return(inst_ldx(code, true));
537 case 0xf: return(inst_stx(code, true));
538 default: return(resHALT);
540 default: return(resHALT);
550 switch (code & 0xf) {
551 case 0x0: return(inst_sub(code, false));
552 case 0x1: return(inst_cmp(code, false));
553 case 0x2: return(inst_sbc(code, false));
554 case 0x3: return(inst_cpx(code, false));
555 case 0x4: return(inst_and(code, false));
556 case 0x5: return(inst_bit(code, false));
557 case 0x6: return(inst_lda(code, false));
560 return(inst_ais(code, false));
562 return(inst_sta(code, false));
563 case 0x8: return(inst_eor(code, false));
564 case 0x9: return(inst_adc(code, false));
565 case 0xa: return(inst_ora(code, false));
566 case 0xb: return(inst_add(code, false));
571 return(inst_jmp(code, false));
574 return(inst_bsr(code, false));
576 return(inst_jsr(code, false));
577 case 0xe: return(inst_ldx(code, false));
580 return(inst_aix(code, false));
582 return(inst_stx(code, false));
583 default: return(resHALT);
585 default: return(resHALT);
591 PC= get_mem_size(MEM_ROM_ID)-1;*/
592 PC= rom->inc_address(PC, -1);
594 sim->stop(resINV_INST);
599 /* End of hc08.src/hc08.cc */