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 */
77 rom= address_space(MEM_ROM_ID);
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 */
136 cl_hc08::make_memories(void)
138 class cl_address_space *as;
140 as= new cl_address_space("rom", 0, 0x10000, 8);
142 address_spaces->add(as);
144 class cl_address_decoder *ad;
145 class cl_memory_chip *chip;
147 chip= new cl_memory_chip("rom_chip", 0x10000, 8);
150 ad= new cl_address_decoder(as= address_space("rom"), chip, 0, 0xffff, 0);
152 as->decoders->add(ad);
158 * Help command interpreter
162 cl_hc08::dis_tbl(void)
167 /*struct name_entry *
168 cl_hc08::sfr_tbl(void)
173 /*struct name_entry *
174 cl_hc08::bit_tbl(void)
181 cl_hc08::inst_length(t_addr addr)
186 s = get_disasm_info(addr, &len, NULL, NULL);
192 cl_hc08::inst_branch(t_addr addr)
197 s = get_disasm_info(addr, NULL, &b, NULL);
203 cl_hc08::longest_inst(void)
210 cl_hc08::get_disasm_info(t_addr addr,
220 int start_addr = addr;
221 struct dis_entry *dis_e;
223 code= get_mem(MEM_ROM_ID, addr++);
227 case 0x9e: /* ESC code to sp relative op-codes */
228 code= get_mem(MEM_ROM_ID, addr++);
230 while ((code & disass_hc08_9e[i].mask) != disass_hc08_9e[i].code &&
231 disass_hc08_9e[i].mnemonic)
233 dis_e = &disass_hc08_9e[i];
234 b= disass_hc08_9e[i].mnemonic;
236 len += (disass_hc08_9e[i].length + 1);
241 while ((code & disass_hc08[i].mask) != disass_hc08[i].code &&
242 disass_hc08[i].mnemonic)
244 dis_e = &disass_hc08[i];
245 b= disass_hc08[i].mnemonic;
247 len += (disass_hc08[i].length);
252 *ret_branch = dis_e->branch;
257 *immed_offset = immed_n;
258 else *immed_offset = (addr - start_addr);
271 cl_hc08::disass(t_addr addr, char *sep)
273 char work[256], temp[20];
274 char *buf, *p, *b, *t;
276 int immed_offset = 0;
280 b = get_disasm_info(addr, &len, NULL, &immed_offset);
283 buf= (char*)malloc(30);
284 strcpy(buf, "UNKNOWN/INVALID");
295 case 's': // s signed byte immediate
296 sprintf(temp, "#%d", (char)get_mem(MEM_ROM_ID, addr+immed_offset));
299 case 'w': // w word immediate operand
300 sprintf(temp, "#0x%04x",
301 (uint)((get_mem(MEM_ROM_ID, addr+immed_offset)<<8) |
302 (get_mem(MEM_ROM_ID, addr+immed_offset+1))) );
306 case 'b': // b byte immediate operand
307 sprintf(temp, "#0x%02x", (uint)get_mem(MEM_ROM_ID, addr+immed_offset));
310 case 'x': // x extended addressing
311 sprintf(temp, "0x%04x",
312 (uint)((get_mem(MEM_ROM_ID, addr+immed_offset)<<8) |
313 (get_mem(MEM_ROM_ID, addr+immed_offset+1))) );
317 case 'd': // d direct addressing
318 sprintf(temp, "*0x%02x", (uint)get_mem(MEM_ROM_ID, addr+immed_offset));
321 case '2': // 2 word index offset
322 sprintf(temp, "0x%04x",
323 (uint)((get_mem(MEM_ROM_ID, addr+immed_offset)<<8) |
324 (get_mem(MEM_ROM_ID, addr+immed_offset+1))) );
328 case '1': // b byte index offset
329 sprintf(temp, "0x%02x", (uint)get_mem(MEM_ROM_ID, addr+immed_offset));
332 case 'p': // b byte index offset
333 sprintf(temp, "0x%04x",
335 +(char)get_mem(MEM_ROM_ID, addr+immed_offset));
351 p= strchr(work, ' ');
358 buf= (char *)malloc(6+strlen(p)+1);
360 buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1);
361 for (p= work, b= buf; *p != ' '; p++, b++)
367 while (strlen(buf) < 6)
378 cl_hc08::print_regs(class cl_console *con)
380 con->dd_printf("V--HINZC Flags= 0x%02x %3d %c ",
381 regs.P, regs.P, isprint(regs.P)?regs.P:'.');
382 con->dd_printf("A= 0x%02x %3d %c\n",
383 regs.A, regs.A, isprint(regs.A)?regs.A:'.');
384 con->dd_printf("%c--%c%c%c%c%c ",
385 (regs.P&BIT_V)?'1':'0',
386 (regs.P&BIT_H)?'1':'0',
387 (regs.P&BIT_I)?'1':'0',
388 (regs.P&BIT_N)?'1':'0',
389 (regs.P&BIT_Z)?'1':'0',
390 (regs.P&BIT_C)?'1':'0');
391 con->dd_printf(" H= 0x%02x %3d %c ",
392 regs.H, regs.H, isprint(regs.H)?regs.H:'.');
393 con->dd_printf("X= 0x%02x %3d %c\n",
394 regs.X, regs.X, isprint(regs.X)?regs.X:'.');
395 con->dd_printf("SP= 0x%04x [SP+1]= %02x %3d %c\n",
396 regs.SP, ram->get(regs.SP+1), ram->get(regs.SP+1),
397 isprint(ram->get(regs.SP+1))?ram->get(regs.SP+1):'.');
399 print_disass(PC, con);
407 cl_hc08::exec_inst(void)
418 return(resBREAKPOINT);
420 switch ((code >> 4) & 0xf) {
421 case 0x0: return(inst_bittestsetclear(code, FALSE));
422 case 0x1: return(inst_bitsetclear(code, FALSE));
423 case 0x2: return(inst_condbranch(code, FALSE));
429 switch (code & 0xf) {
430 case 0x0: return(inst_neg(code, FALSE));
431 case 0x1: return(inst_cbeq(code, FALSE));
434 case 0x42: return(inst_mul(code, FALSE));
435 case 0x52: return(inst_div(code, FALSE));
436 case 0x62: return(inst_nsa(code, FALSE));
437 case 0x72: return(inst_daa(code, FALSE));
438 default: return(resHALT);
440 case 0x3: return(inst_com(code, FALSE));
441 case 0x4: return(inst_lsr(code, FALSE));
444 case 0x35: return(inst_sthx(code, FALSE));
446 case 0x55: return(inst_ldhx(code, FALSE));
448 case 0x75: return(inst_cphx(code, FALSE));
449 default: return(resHALT);
451 case 0x6: return(inst_ror(code, FALSE));
452 case 0x7: return(inst_asr(code, FALSE));
453 case 0x8: return(inst_lsl(code, FALSE));
454 case 0x9: return(inst_rol(code, FALSE));
455 case 0xa: return(inst_dec(code, FALSE));
456 case 0xb: return(inst_dbnz(code, FALSE));
457 case 0xc: return(inst_inc(code, FALSE));
458 case 0xd: return(inst_tst(code, FALSE));
464 case 0x7e: return(inst_mov(code, FALSE));
465 default: return(resHALT);
467 case 0xf: return(inst_clr(code, FALSE));
468 default: return(resHALT);
471 switch (code & 0xf) {
472 case 0x0: return(inst_rti(code, FALSE));
473 case 0x1: return(inst_rts(code, FALSE));
474 case 0x3: return(inst_swi(code, FALSE));
476 case 0x5: return(inst_transfer(code, FALSE));
482 case 0xb: return(inst_pushpull(code, FALSE));
483 case 0xc: return(inst_clrh(code, FALSE));
484 case 0xe: return(inst_stop(code, FALSE));
485 case 0xf: return(inst_wait(code, FALSE));
486 default: return(resHALT);
489 switch (code & 0xf) {
493 case 0x3: return(inst_condbranch(code, FALSE));
497 case 0xf: return(inst_transfer(code, FALSE));
501 case 0xb: return(inst_setclearflags(code, FALSE));
502 case 0xc: return(inst_rsp(code, FALSE));
503 case 0xd: return(inst_nop(code, FALSE));
506 switch ((code >> 4) & 0xf) {
508 switch (code & 0xf) {
509 case 0x0: return(inst_neg(code, TRUE));
510 case 0x1: return(inst_cbeq(code, TRUE));
511 case 0x3: return(inst_com(code, TRUE));
512 case 0x4: return(inst_lsr(code, TRUE));
513 case 0x6: return(inst_ror(code, TRUE));
514 case 0x7: return(inst_asr(code, TRUE));
515 case 0x8: return(inst_lsl(code, TRUE));
516 case 0x9: return(inst_rol(code, TRUE));
517 case 0xa: return(inst_dec(code, TRUE));
518 case 0xb: return(inst_dbnz(code, TRUE));
519 case 0xc: return(inst_inc(code, TRUE));
520 case 0xd: return(inst_tst(code, TRUE));
521 case 0xf: return(inst_clr(code, TRUE));
522 default: return(resHALT);
526 switch (code & 0xf) {
527 case 0x0: return(inst_sub(code, TRUE));
528 case 0x1: return(inst_cmp(code, TRUE));
529 case 0x2: return(inst_sbc(code, TRUE));
530 case 0x3: return(inst_cpx(code, TRUE));
531 case 0x4: return(inst_and(code, TRUE));
532 case 0x5: return(inst_bit(code, TRUE));
533 case 0x6: return(inst_lda(code, TRUE));
534 case 0x7: return(inst_sta(code, TRUE));
535 case 0x8: return(inst_eor(code, TRUE));
536 case 0x9: return(inst_adc(code, TRUE));
537 case 0xa: return(inst_ora(code, TRUE));
538 case 0xb: return(inst_add(code, TRUE));
539 case 0xc: return(resHALT);
540 case 0xd: putchar(regs.A); fflush(stdout); return(resGO);
541 case 0xe: return(inst_ldx(code, TRUE));
542 case 0xf: return(inst_stx(code, TRUE));
543 default: return(resHALT);
545 default: return(resHALT);
555 switch (code & 0xf) {
556 case 0x0: return(inst_sub(code, FALSE));
557 case 0x1: return(inst_cmp(code, FALSE));
558 case 0x2: return(inst_sbc(code, FALSE));
559 case 0x3: return(inst_cpx(code, FALSE));
560 case 0x4: return(inst_and(code, FALSE));
561 case 0x5: return(inst_bit(code, FALSE));
562 case 0x6: return(inst_lda(code, FALSE));
565 return(inst_ais(code, FALSE));
567 return(inst_sta(code, FALSE));
568 case 0x8: return(inst_eor(code, FALSE));
569 case 0x9: return(inst_adc(code, FALSE));
570 case 0xa: return(inst_ora(code, FALSE));
571 case 0xb: return(inst_add(code, FALSE));
576 return(inst_jmp(code, FALSE));
579 return(inst_bsr(code, FALSE));
581 return(inst_jsr(code, FALSE));
582 case 0xe: return(inst_ldx(code, FALSE));
585 return(inst_aix(code, FALSE));
587 return(inst_stx(code, FALSE));
588 default: return(resHALT);
590 default: return(resHALT);
596 PC= get_mem_size(MEM_ROM_ID)-1;*/
597 PC= rom->inc_address(PC, -1);
599 sim->stop(resINV_INST);
604 /* End of hc08.src/hc08.cc */