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
54 /*******************************************************************/
58 * Base type of HC08 controllers
61 cl_hc08::cl_hc08(class cl_sim *asim):
70 cl_uc::init(); /* Memories now exist */
74 rom= address_space(MEM_ROM_ID);
75 // ram= mem(MEM_XRAM);
78 // zero out ram(this is assumed in regression tests)
79 for (int i=0x80; i<0x8000; i++) {
80 ram->set((t_addr) i, 0);
103 cl_hc08::id_string(void)
105 return("unspecified HC08");
110 * Making elements of the controller
114 cl_hc08::get_mem_size(enum mem_class type)
118 case MEM_ROM: return(0x10000);
119 case MEM_XRAM: return(0x10000);
122 return(cl_uc::get_mem_size(type));
126 cl_hc08::mk_hw_elements(void)
129 /* t_uc::mk_hw() does nothing */
133 cl_hc08::make_memories(void)
135 class cl_address_space *as;
137 as= new cl_address_space("rom", 0, 0x10000, 8);
139 address_spaces->add(as);
141 class cl_address_decoder *ad;
142 class cl_memory_chip *chip;
144 chip= new cl_memory_chip("rom_chip", 0x10000, 8);
147 ad= new cl_address_decoder(as= address_space("rom"), chip, 0, 0xffff, 0);
149 as->decoders->add(ad);
155 * Help command interpreter
159 cl_hc08::dis_tbl(void)
164 /*struct name_entry *
165 cl_hc08::sfr_tbl(void)
170 /*struct name_entry *
171 cl_hc08::bit_tbl(void)
178 cl_hc08::inst_length(t_addr addr)
183 s = get_disasm_info(addr, &len, NULL, NULL);
189 cl_hc08::inst_branch(t_addr addr)
194 s = get_disasm_info(addr, NULL, &b, NULL);
200 cl_hc08::longest_inst(void)
207 cl_hc08::get_disasm_info(t_addr addr,
217 int start_addr = addr;
218 struct dis_entry *dis_e;
220 code= get_mem(MEM_ROM_ID, addr++);
224 case 0x9e: /* ESC code to sp relative op-codes */
225 code= get_mem(MEM_ROM_ID, addr++);
227 while ((code & disass_hc08_9e[i].mask) != disass_hc08_9e[i].code &&
228 disass_hc08_9e[i].mnemonic)
230 dis_e = &disass_hc08_9e[i];
231 b= disass_hc08_9e[i].mnemonic;
233 len += (disass_hc08_9e[i].length + 1);
238 while ((code & disass_hc08[i].mask) != disass_hc08[i].code &&
239 disass_hc08[i].mnemonic)
241 dis_e = &disass_hc08[i];
242 b= disass_hc08[i].mnemonic;
244 len += (disass_hc08[i].length);
249 *ret_branch = dis_e->branch;
254 *immed_offset = immed_n;
255 else *immed_offset = (addr - start_addr);
268 cl_hc08::disass(t_addr addr, char *sep)
270 char work[256], temp[20];
271 char *buf, *p, *b, *t;
273 int immed_offset = 0;
277 b = get_disasm_info(addr, &len, NULL, &immed_offset);
280 buf= (char*)malloc(30);
281 strcpy(buf, "UNKNOWN/INVALID");
292 case 's': // s signed byte immediate
293 sprintf(temp, "#%d", (char)get_mem(MEM_ROM_ID, addr+immed_offset));
296 case 'w': // w word immediate operand
297 sprintf(temp, "#0x%04x",
298 (uint)((get_mem(MEM_ROM_ID, addr+immed_offset)<<8) |
299 (get_mem(MEM_ROM_ID, addr+immed_offset+1))) );
303 case 'b': // b byte immediate operand
304 sprintf(temp, "#0x%02x", (uint)get_mem(MEM_ROM_ID, addr+immed_offset));
307 case 'x': // x extended addressing
308 sprintf(temp, "0x%04x",
309 (uint)((get_mem(MEM_ROM_ID, addr+immed_offset)<<8) |
310 (get_mem(MEM_ROM_ID, addr+immed_offset+1))) );
314 case 'd': // d direct addressing
315 sprintf(temp, "*0x%02x", (uint)get_mem(MEM_ROM_ID, addr+immed_offset));
318 case '2': // 2 word index offset
319 sprintf(temp, "0x%04x",
320 (uint)((get_mem(MEM_ROM_ID, addr+immed_offset)<<8) |
321 (get_mem(MEM_ROM_ID, addr+immed_offset+1))) );
325 case '1': // b byte index offset
326 sprintf(temp, "0x%02x", (uint)get_mem(MEM_ROM_ID, addr+immed_offset));
329 case 'p': // b byte index offset
330 sprintf(temp, "0x%04x",
332 +(char)get_mem(MEM_ROM_ID, addr+immed_offset));
348 p= strchr(work, ' ');
355 buf= (char *)malloc(6+strlen(p)+1);
357 buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1);
358 for (p= work, b= buf; *p != ' '; p++, b++)
364 while (strlen(buf) < 6)
375 cl_hc08::print_regs(class cl_console *con)
377 con->dd_printf("V--HINZC Flags= 0x%02x %3d %c ",
378 regs.P, regs.P, isprint(regs.P)?regs.P:'.');
379 con->dd_printf("A= 0x%02x %3d %c\n",
380 regs.A, regs.A, isprint(regs.A)?regs.A:'.');
381 con->dd_printf("%c--%c%c%c%c%c ",
382 (regs.P&BIT_V)?'1':'0',
383 (regs.P&BIT_H)?'1':'0',
384 (regs.P&BIT_I)?'1':'0',
385 (regs.P&BIT_N)?'1':'0',
386 (regs.P&BIT_Z)?'1':'0',
387 (regs.P&BIT_C)?'1':'0');
388 con->dd_printf(" H= 0x%02x %3d %c ",
389 regs.H, regs.H, isprint(regs.H)?regs.H:'.');
390 con->dd_printf("X= 0x%02x %3d %c\n",
391 regs.X, regs.X, isprint(regs.X)?regs.X:'.');
392 con->dd_printf("SP= 0x%04x [SP+1]= %02x %3d %c\n",
393 regs.SP, ram->get(regs.SP+1), ram->get(regs.SP+1),
394 isprint(ram->get(regs.SP+1))?ram->get(regs.SP+1):'.');
396 print_disass(PC, con);
404 cl_hc08::exec_inst(void)
415 return(resBREAKPOINT);
417 switch ((code >> 4) & 0xf) {
418 case 0x0: return(inst_bittestsetclear(code, false));
419 case 0x1: return(inst_bitsetclear(code, false));
420 case 0x2: return(inst_condbranch(code, false));
426 switch (code & 0xf) {
427 case 0x0: return(inst_neg(code, false));
428 case 0x1: return(inst_cbeq(code, false));
431 case 0x42: return(inst_mul(code, false));
432 case 0x52: return(inst_div(code, false));
433 case 0x62: return(inst_nsa(code, false));
434 case 0x72: return(inst_daa(code, false));
435 default: return(resHALT);
437 case 0x3: return(inst_com(code, false));
438 case 0x4: return(inst_lsr(code, false));
441 case 0x35: return(inst_sthx(code, false));
443 case 0x55: return(inst_ldhx(code, false));
445 case 0x75: return(inst_cphx(code, false));
446 default: return(resHALT);
448 case 0x6: return(inst_ror(code, false));
449 case 0x7: return(inst_asr(code, false));
450 case 0x8: return(inst_lsl(code, false));
451 case 0x9: return(inst_rol(code, false));
452 case 0xa: return(inst_dec(code, false));
453 case 0xb: return(inst_dbnz(code, false));
454 case 0xc: return(inst_inc(code, false));
455 case 0xd: return(inst_tst(code, false));
461 case 0x7e: return(inst_mov(code, false));
462 default: return(resHALT);
464 case 0xf: return(inst_clr(code, false));
465 default: return(resHALT);
468 switch (code & 0xf) {
469 case 0x0: return(inst_rti(code, false));
470 case 0x1: return(inst_rts(code, false));
471 case 0x3: return(inst_swi(code, false));
473 case 0x5: return(inst_transfer(code, false));
479 case 0xb: return(inst_pushpull(code, false));
480 case 0xc: return(inst_clrh(code, false));
481 case 0xe: return(inst_stop(code, false));
482 case 0xf: return(inst_wait(code, false));
483 default: return(resHALT);
486 switch (code & 0xf) {
490 case 0x3: return(inst_condbranch(code, false));
494 case 0xf: return(inst_transfer(code, false));
498 case 0xb: return(inst_setclearflags(code, false));
499 case 0xc: return(inst_rsp(code, false));
500 case 0xd: return(inst_nop(code, false));
503 switch ((code >> 4) & 0xf) {
505 switch (code & 0xf) {
506 case 0x0: return(inst_neg(code, true));
507 case 0x1: return(inst_cbeq(code, true));
508 case 0x3: return(inst_com(code, true));
509 case 0x4: return(inst_lsr(code, true));
510 case 0x6: return(inst_ror(code, true));
511 case 0x7: return(inst_asr(code, true));
512 case 0x8: return(inst_lsl(code, true));
513 case 0x9: return(inst_rol(code, true));
514 case 0xa: return(inst_dec(code, true));
515 case 0xb: return(inst_dbnz(code, true));
516 case 0xc: return(inst_inc(code, true));
517 case 0xd: return(inst_tst(code, true));
518 case 0xf: return(inst_clr(code, true));
519 default: return(resHALT);
523 switch (code & 0xf) {
524 case 0x0: return(inst_sub(code, true));
525 case 0x1: return(inst_cmp(code, true));
526 case 0x2: return(inst_sbc(code, true));
527 case 0x3: return(inst_cpx(code, true));
528 case 0x4: return(inst_and(code, true));
529 case 0x5: return(inst_bit(code, true));
530 case 0x6: return(inst_lda(code, true));
531 case 0x7: return(inst_sta(code, true));
532 case 0x8: return(inst_eor(code, true));
533 case 0x9: return(inst_adc(code, true));
534 case 0xa: return(inst_ora(code, true));
535 case 0xb: return(inst_add(code, true));
536 case 0xc: return(resHALT);
537 case 0xd: putchar(regs.A); fflush(stdout); return(resGO);
538 case 0xe: return(inst_ldx(code, true));
539 case 0xf: return(inst_stx(code, true));
540 default: return(resHALT);
542 default: return(resHALT);
552 switch (code & 0xf) {
553 case 0x0: return(inst_sub(code, false));
554 case 0x1: return(inst_cmp(code, false));
555 case 0x2: return(inst_sbc(code, false));
556 case 0x3: return(inst_cpx(code, false));
557 case 0x4: return(inst_and(code, false));
558 case 0x5: return(inst_bit(code, false));
559 case 0x6: return(inst_lda(code, false));
562 return(inst_ais(code, false));
564 return(inst_sta(code, false));
565 case 0x8: return(inst_eor(code, false));
566 case 0x9: return(inst_adc(code, false));
567 case 0xa: return(inst_ora(code, false));
568 case 0xb: return(inst_add(code, false));
573 return(inst_jmp(code, false));
576 return(inst_bsr(code, false));
578 return(inst_jsr(code, false));
579 case 0xe: return(inst_ldx(code, false));
582 return(inst_aix(code, false));
584 return(inst_stx(code, false));
585 default: return(resHALT);
587 default: return(resHALT);
593 PC= get_mem_size(MEM_ROM_ID)-1;*/
594 PC= rom->inc_address(PC, -1);
596 sim->stop(resINV_INST);
601 /* End of hc08.src/hc08.cc */