2 * Simulator of microcontrollers (avr.cc)
4 * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
6 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
10 /* This file is part of microcontroller simulator: ucsim.
12 UCSIM is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 UCSIM is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with UCSIM; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
50 * Base type of AVR microcontrollers
53 cl_avr::cl_avr(class cl_sim *asim):
63 cl_uc::init(); /* Memories now exist */
64 ram= address_space(MEM_IRAM_ID);
65 rom= address_space(MEM_ROM_ID);
70 cl_avr::id_string(void)
72 return("unspecified AVR");
77 * Making elements of the controller
81 cl_avr::get_mem_size(enum mem_class type)
85 case MEM_ROM: return(8*1024);
86 case MEM_IRAM: return(0x10000);
90 //return(cl_uc::get_mem_size(type));
95 cl_avr::get_mem_width(enum mem_class type)
99 return(cl_uc::get_mem_width(type));
104 cl_avr::mk_hw_elements(void)
107 /* t_uc::mk_hw() does nothing */
108 hws->add(o= new cl_port(this));
114 cl_avr::make_memories(void)
116 class cl_address_space *as;
118 rom= as= new cl_address_space(MEM_ROM_ID, 0, 0x10000, 16);
120 address_spaces->add(as);
121 ram= as= new cl_address_space(MEM_IRAM_ID, 0, 0x10000, 8);
123 address_spaces->add(as);
125 class cl_address_decoder *ad;
126 class cl_memory_chip *chip;
128 chip= new cl_memory_chip("rom_chip", 0x10000, 16);
131 ad= new cl_address_decoder(as= rom/*address_space(MEM_ROM_ID)*/,
134 as->decoders->add(ad);
137 chip= new cl_memory_chip("iram_chip", 0x80, 8);
140 ad= new cl_address_decoder(as= ram/*address_space(MEM_IRAM_ID)*/,
143 as->decoders->add(ad);
149 * Help command interpreter
153 cl_avr::dis_tbl(void)
159 cl_avr::sfr_tbl(void)
165 cl_avr::bit_tbl(void)
172 cl_avr::disass(t_addr addr, char *sep)
174 char work[256], temp[20];
175 char *buf, *p, *b, *t;
181 code= get_mem(MEM_ROM_ID, addr);
183 while ((code & dis_tbl()[i].mask) != dis_tbl()[i].code &&
184 dis_tbl()[i].mnemonic)
186 if (dis_tbl()[i].mnemonic == NULL)
188 buf= (char*)malloc(30);
189 strcpy(buf, "UNKNOWN/INVALID");
192 b= dis_tbl()[i].mnemonic;
201 case 'd': // Rd .... ...d dddd .... 0<=d<=31
202 if (!get_name(data= (code&0x01f0)>>4, sfr_tbl(), temp))
203 sprintf(temp, "r%d", data);
205 case 'D': // Rd .... .... dddd .... 16<=d<=31
206 if (!get_name(data= 16+((code&0xf0)>>4), sfr_tbl(), temp))
207 sprintf(temp, "r%d", data);
209 case 'K': // K .... KKKK .... KKKK 0<=K<=255
210 sprintf(temp, "%d", ((code&0xf00)>>4)|(code&0xf));
212 case 'r': // Rr .... ..r. .... rrrr 0<=r<=31
213 if (!get_name(data= ((code&0x0200)>>5)|(code&0x000f),
215 sprintf(temp, "r%d", data);
217 case '2': // Rdl .... .... ..dd .... dl= {24,26,28,30}
218 if (!get_name(data= 24+(2*((code&0x0030)>>4)),
220 sprintf(temp, "r%d", data);
222 case '6': // K .... .... KK.. KKKK 0<=K<=63
223 sprintf(temp, "%d", ((code&0xc0)>>2)|(code&0xf));
225 case 's': // s .... .... .sss .... 0<=s<=7
226 sprintf(temp, "%d", (code&0x70)>>4);
228 case 'b': // b .... .... .... .bbb 0<=b<=7
229 sprintf(temp, "%d", code&0x7);
231 case 'k': // k .... ..kk kkkk k... -64<=k<=+63
233 int k= (code&0x3f8)>>3;
236 sprintf(temp, "0x%06x", k+1+(signed int)addr);
239 case 'A': // k .... ...k kkkk ...k 0<=k<=64K
240 // kkkk kkkk kkkk kkkk 0<=k<=4M
241 sprintf(temp, "0x%06x",
242 (((code&0x1f0)>>3)|(code&1))*0x10000+
243 (uint)get_mem(MEM_ROM_ID, addr+1));
245 case 'P': // P .... .... pppp p... 0<=P<=31
246 data= (code&0xf8)>>3;
247 if (!get_name(data+0x20, sfr_tbl(), temp))
248 sprintf(temp, "%d", data);
250 case 'p': // P .... .PP. .... PPPP 0<=P<=63
251 data= ((code&0x600)>>5)|(code&0xf);
252 if (!get_name(data+0x20, sfr_tbl(), temp))
253 sprintf(temp, "%d", data);
255 case 'q': // q ..q. qq.. .... .qqq 0<=q<=63
257 ((code&0x2000)>>8)|((code&0xc00)>>7)|(code&7));
259 case 'R': // k SRAM address on second word 0<=k<=65535
260 sprintf(temp, "0x%06x", (uint)get_mem(MEM_ROM_ID, addr+1));
262 case 'a': // k .... kkkk kkkk kkkk -2k<=k<=2k
267 sprintf(temp, "0x%06"_A_"x",
268 rom->validate_address(k+1+(signed int)addr));
284 p= strchr(work, ' ');
291 buf= (char *)malloc(6+strlen(p)+1);
293 buf= (char *)malloc((p-work)+strlen(sep)+strlen(p)+1);
294 for (p= work, b= buf; *p != ' '; p++, b++)
300 while (strlen(buf) < 6)
311 cl_avr::print_regs(class cl_console *con)
313 uchar data, sreg= ram->get(SREG);
316 ram->dump(0, 31, 16, con);
318 con->dd_printf("ITHSVNZC SREG= 0x%02x %3d %c\n",
319 sreg, sreg, isprint(sreg)?sreg:'.');
320 con->dd_printf("%c%c%c%c%c%c%c%c ",
321 (sreg&BIT_I)?'1':'0',
322 (sreg&BIT_T)?'1':'0',
323 (sreg&BIT_H)?'1':'0',
324 (sreg&BIT_S)?'1':'0',
325 (sreg&BIT_V)?'1':'0',
326 (sreg&BIT_N)?'1':'0',
327 (sreg&BIT_Z)?'1':'0',
328 (sreg&BIT_C)?'1':'0');
329 con->dd_printf("SP = 0x%06x\n", ram->get(SPH)*256+ram->get(SPL));
331 x= ram->get(XH)*256 + ram->get(XL);
333 con->dd_printf("X= 0x%04x [X]= 0x%02x %3d %c ", x,
334 data, data, isprint(data)?data:'.');
335 y= ram->get(YH)*256 + ram->get(YL);
337 con->dd_printf("Y= 0x%04x [Y]= 0x%02x %3d %c ", y,
338 data, data, isprint(data)?data:'.');
339 z= ram->get(ZH)*256 + ram->get(ZL);
341 con->dd_printf("Z= 0x%04x [Z]= 0x%02x %3d %c\n", z,
342 data, data, isprint(data)?data:'.');
344 print_disass(PC, con);
353 cl_avr::exec_inst(void)
359 return(resBREAKPOINT);
366 return(eicall(code));
367 case 0x9508: case 0x9528: case 0x9548: case 0x9568:
369 case 0x9518: case 0x9538: case 0x9558: case 0x9578:
374 return(elpm(code)); // in some devices equal to lpm
413 case 0x9588: case 0x9598:
415 case 0x95a8: case 0x95b8:
418 switch (code & 0xf000)
420 case 0x3000: return(cpi_Rd_K(code));
421 case 0x4000: return(sbci_Rd_K(code));
422 case 0x5000: return(subi_Rd_K(code));
423 case 0x6000: return(ori_Rd_K(code));
424 case 0x7000: return(andi_Rd_K(code));
425 case 0xc000: return(rjmp_k(code));
426 case 0xd000: return(rcall_k(code));
427 case 0xe000: return(ldi_Rd_K(code));
429 switch (code & 0xf000)
434 switch (code & 0xfc00)
438 switch (code & 0xff00)
440 case 0x0100: return(movw_Rd_Rr(code));
441 case 0x0200: return(muls_Rd_Rr(code));
444 switch (code & 0xff88)
446 case 0x0300: return(mulsu_Rd_Rr(code));
447 case 0x0308: return(fmul_Rd_Rr(code));
448 case 0x0380: return(fmuls_Rd_Rr(code));
449 case 0x0388: return(fmulsu_Rd_Rr(code));
457 case 0x0400: return(cpc_Rd_Rr(code));
458 case 0x0800: return(sbc_Rd_Rr(code));
459 case 0x0c00: return(add_Rd_Rr(code));
466 switch (code & 0xfc00)
468 case 0x1000: return(cpse_Rd_Rr(code));
469 case 0x1400: return(cp_Rd_Rr(code));
470 case 0x1800: return(sub_Rd_Rr(code));
471 case 0x1c00: return(adc_Rd_Rr(code));
478 switch (code & 0xfc00)
480 case 0x2000: return(and_Rd_Rr(code));
481 case 0x2400: return(eor_Rd_Rr(code));
482 case 0x2800: return(or_Rd_Rr(code));
483 case 0x2c00: return(mov_Rd_Rr(code));
490 switch (code &0xf208)
492 case 0x8000: return(ldd_Rd_Z_q(code));
493 case 0x8008: return(ldd_Rd_Y_q(code));
494 case 0x8200: return(std_Z_q_Rr(code));
495 case 0x8208: return(std_Y_q_Rr(code));
502 if ((code & 0xff0f) == 0x9509)
504 if ((code & 0xff0f) == 0x9409)
506 if ((code & 0xff00) == 0x9600)
507 return(adiw_Rdl_K(code));
508 if ((code & 0xff00) == 0x9700)
509 return(sbiw_Rdl_K(code));
510 switch (code & 0xfc00)
514 switch (code & 0xfe0f)
516 case 0x9000: return(lds_Rd_k(code));
517 case 0x9001: return(ld_Rd_ZS(code));
518 case 0x9002: return(ld_Rd_SZ(code));
519 case 0x9004: return(lpm_Rd_Z(code));
520 case 0x9005: return(lpm_Rd_ZS(code));
521 case 0x9006: return(elpm_Rd_Z(code));
522 case 0x9007: return(elpm_Rd_ZS(code));
523 case 0x9009: return(ld_Rd_YS(code));
524 case 0x900a: return(ld_Rd_SY(code));
525 case 0x900c: return(ld_Rd_X(code));
526 case 0x900d: return(ld_Rd_XS(code));
527 case 0x900e: return(ld_Rd_SX(code));
528 case 0x900f: return(pop_Rd(code));
529 case 0x9200: return(sts_k_Rr(code));
530 case 0x9201: return(st_ZS_Rr(code));
531 case 0x9202: return(st_SZ_Rr(code));
532 case 0x9209: return(st_YS_Rr(code));
533 case 0x920a: return(st_SY_Rr(code));
534 case 0x920c: return(st_X_Rr(code));
535 case 0x920d: return(st_XS_Rr(code));
536 case 0x920e: return(st_SX_Rr(code));
537 case 0x920f: return(push_Rr(code));
543 switch (code & 0xfe0f)
545 case 0x9400: return(com_Rd(code));
546 case 0x9401: return(neg_Rd(code));
547 case 0x9402: return(swap_Rd(code));
548 case 0x9403: return(inc_Rd(code));
549 case 0x9405: return(asr_Rd(code));
550 case 0x9406: return(lsr_Rd(code));
551 case 0x9407: return(ror_Rd(code));
552 case 0x940a: return(dec_Rd(code));
553 case 0x940c: case 0x940d: return(jmp_k(code));
554 case 0x940e: case 0x940f: return(call_k(code));
560 switch (code & 0xff00)
562 case 0x9800: return(cbi_A_b(code));
563 case 0x9900: return(sbic_P_b(code));
564 case 0x9a00: return(sbi_A_b(code));
565 case 0x9b00: return(sbis_P_b(code));
569 case 0x9c00: return(mul_Rd_Rr(code));
576 switch (code &0xf208)
578 case 0xa000: return(ldd_Rd_Z_q(code));
579 case 0xa008: return(ldd_Rd_Y_q(code));
580 case 0xa200: return(std_Z_q_Rr(code));
581 case 0xa208: return(std_Y_q_Rr(code));
588 switch (code & 0xf800)
590 case 0xb000: return(in_Rd_A(code));
591 case 0xb800: return(out_A_Rr(code));
598 switch (code & 0xff0f)
600 case 0xef0f: return(ser_Rd(code));
607 switch (code & 0xfc00)
609 case 0xf000: return(brbs_s_k(code));
610 case 0xf400: return(brbc_s_k(code));
611 case 0xf800: case 0xfc00:
613 switch (code & 0xfe08)
615 case 0xf800: return(bld_Rd_b(code));
616 case 0xfa00: return(bst_Rd_b(code));
617 case 0xfc00: case 0xfc08: return(sbrc_Rr_b(code));
618 case 0xfe00: case 0xfe08: return(sbrs_Rr_b(code));
629 PC= get_mem_size(MEM_ROM_ID)-1;*/
630 class cl_error_unknown_code *e= new cl_error_unknown_code(this);
633 PC= rom->inc_address(PC, -1);
634 //tick(-clock_per_cycle());
635 sim->stop(resINV_INST);
644 cl_avr::push_data(t_mem data)
651 sp= 0xffff & (256*sph + spl);
652 data= ram->write(sp, data);
656 ram->write(SPL, spl);
657 ram->write(SPH, sph);
662 cl_avr::push_addr(t_addr addr)
665 t_mem spl, sph, al, ah;
669 sp= 0xffff & (256*sph + spl);
671 ah= (addr>>8) & 0xff;
678 ram->write(SPL, spl);
679 ram->write(SPH, sph);
684 cl_avr::pop_data(t_mem *data)
693 *data= ram->read(sp);
696 ram->write(SPL, spl);
697 ram->write(SPH, sph);
703 cl_avr::pop_addr(t_addr *addr)
706 t_mem spl, sph, al, ah;
718 ram->write(SPL, spl);
719 ram->write(SPH, sph);
726 * Set Z, N, V, S bits of SREG after logic instructions and some others
730 cl_avr::set_zn0s(t_mem data)
732 t_mem sreg= ram->get(SREG) & ~BIT_V;
739 sreg|= (BIT_N|BIT_S);
741 sreg&= ~(BIT_N|BIT_S);
742 ram->set(SREG, sreg);
746 /* End of avr.src/avr.cc */