/[gxemul]/trunk/src/cpus/cpu_avr.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/cpus/cpu_avr.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 23 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 24 by dpavlin, Mon Oct 8 16:19:56 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2006  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_avr.c,v 1.7 2005/11/13 00:14:07 debug Exp $   *  $Id: cpu_avr.c,v 1.18 2006/06/16 18:31:25 debug Exp $
29   *   *
30   *  Atmel AVR (8-bit) CPU emulation.   *  Atmel AVR (8-bit) CPU emulation.
31   */   */
# Line 58  Line 58 
58  int avr_cpu_new(struct cpu *cpu, struct memory *mem, struct machine *machine,  int avr_cpu_new(struct cpu *cpu, struct memory *mem, struct machine *machine,
59          int cpu_id, char *cpu_type_name)          int cpu_id, char *cpu_type_name)
60  {  {
61          if (strcasecmp(cpu_type_name, "AVR") != 0)          int type = 0;
62    
63            if (strcasecmp(cpu_type_name, "AVR") == 0 ||
64                strcasecmp(cpu_type_name, "AVR16") == 0 ||
65                strcasecmp(cpu_type_name, "AT90S2313") == 0 ||
66                strcasecmp(cpu_type_name, "AT90S8515") == 0)
67                    type = 16;
68            if (strcasecmp(cpu_type_name, "AVR22") == 0)
69                    type = 22;
70    
71            if (type == 0)
72                  return 0;                  return 0;
73    
74          cpu->memory_rw = avr_memory_rw;          cpu->memory_rw = avr_memory_rw;
# Line 70  int avr_cpu_new(struct cpu *cpu, struct Line 80  int avr_cpu_new(struct cpu *cpu, struct
80    
81          cpu->byte_order = EMUL_LITTLE_ENDIAN;          cpu->byte_order = EMUL_LITTLE_ENDIAN;
82    
83          cpu->cd.avr.pc_mask = 0xffff;          cpu->cd.avr.is_22bit = (type == 22);
84            cpu->cd.avr.pc_mask = cpu->cd.avr.is_22bit? 0x3fffff : 0xffff;
85    
86            cpu->cd.avr.sram_mask = 0xff;   /*  256 bytes ram  */
87            cpu->cd.avr.sp = cpu->cd.avr.sram_mask - 2;
88    
89          /*  Only show name and caches etc for CPU nr 0 (in SMP machines):  */          /*  Only show name and caches etc for CPU nr 0 (in SMP machines):  */
90          if (cpu_id == 0) {          if (cpu_id == 0) {
# Line 88  int avr_cpu_new(struct cpu *cpu, struct Line 102  int avr_cpu_new(struct cpu *cpu, struct
102   */   */
103  void avr_cpu_list_available_types(void)  void avr_cpu_list_available_types(void)
104  {  {
105          debug("AVR\n");          debug("AVR\tAVR16\tAVR22\n");
         /*  TODO  */  
106  }  }
107    
108    
# Line 98  void avr_cpu_list_available_types(void) Line 111  void avr_cpu_list_available_types(void)
111   */   */
112  void avr_cpu_dumpinfo(struct cpu *cpu)  void avr_cpu_dumpinfo(struct cpu *cpu)
113  {  {
114          /*  TODO  */          debug(" (%i-bit program counter)\n",
115          debug("\n");              cpu->cd.avr.is_22bit? 22 : 16);
116  }  }
117    
118    
# Line 131  void avr_cpu_register_dump(struct cpu *c Line 144  void avr_cpu_register_dump(struct cpu *c
144                  debug("%c", cpu->cd.avr.sreg & AVR_SREG_N? 'N' : 'n');                  debug("%c", cpu->cd.avr.sreg & AVR_SREG_N? 'N' : 'n');
145                  debug("%c", cpu->cd.avr.sreg & AVR_SREG_Z? 'Z' : 'z');                  debug("%c", cpu->cd.avr.sreg & AVR_SREG_Z? 'Z' : 'z');
146                  debug("%c", cpu->cd.avr.sreg & AVR_SREG_C? 'C' : 'c');                  debug("%c", cpu->cd.avr.sreg & AVR_SREG_C? 'C' : 'c');
147                  debug("  pc = 0x%04x", x, (int)cpu->pc);                  if (cpu->cd.avr.is_22bit)
148                            debug("  pc = 0x%06x", (int)cpu->pc);
149                    else
150                            debug("  pc = 0x%04x", (int)cpu->pc);
151                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");
152    
153                  for (i=0; i<N_AVR_REGS; i++) {                  for (i=0; i<N_AVR_REGS; i++) {
154                          if ((i % 4) == 0)                          int r = (i >> 3) + ((i & 7) << 2);
155                                  debug("cpu%i:\t", x);                          if ((i % 8) == 0)
156                          debug("r%02i = 0x%02x", i, cpu->cd.avr.r[i]);                                  debug("cpu%i:", x);
157                          debug((i % 4) == 3? "\n" : "   ");                          debug(" r%02i=0x%02x", r, cpu->cd.avr.r[r]);
158                            if ((i % 8) == 7)
159                                    debug("\n");
160                  }                  }
161    
162                    debug("cpu%i: x=%i, y=%i, z=%i, sp=0x%04x\n", x,
163                        (int)(int16_t)(cpu->cd.avr.r[27]*256 + cpu->cd.avr.r[26]),
164                        (int)(int16_t)(cpu->cd.avr.r[29]*256 + cpu->cd.avr.r[28]),
165                        (int)(int16_t)(cpu->cd.avr.r[31]*256 + cpu->cd.avr.r[30]),
166                        cpu->cd.avr.sp);
167          }          }
168    
169          debug("cpu%i: nr of instructions: %lli\n", x,          debug("cpu%i: nr of instructions: %lli\n", x,
# Line 180  void avr_cpu_register_match(struct machi Line 204  void avr_cpu_register_match(struct machi
204    
205    
206  /*  /*
207     *  avr_cpu_tlbdump():
208     *
209     *  Called from the debugger to dump the TLB in a readable format.
210     *  x is the cpu number to dump, or -1 to dump all CPUs.
211     *
212     *  If rawflag is nonzero, then the TLB contents isn't formated nicely,
213     *  just dumped.
214     */
215    void avr_cpu_tlbdump(struct machine *m, int x, int rawflag)
216    {
217    }
218    
219    
220    /*
221     *  avr_cpu_gdb_stub():
222     *
223     *  Execute a "remote GDB" command. Returns a newly allocated response string
224     *  on success, NULL on failure.
225     */
226    char *avr_cpu_gdb_stub(struct cpu *cpu, char *cmd)
227    {
228            fatal("avr_cpu_gdb_stub(): TODO\n");
229            return NULL;
230    }
231    
232    
233    /*
234   *  avr_cpu_interrupt():   *  avr_cpu_interrupt():
235   */   */
236  int avr_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)  int avr_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)
# Line 219  static void print_spaces(int len) { int Line 270  static void print_spaces(int len) { int
270   *  cpu->pc for relative addresses.   *  cpu->pc for relative addresses.
271   */   */
272  int avr_cpu_disassemble_instr(struct cpu *cpu, unsigned char *ib,  int avr_cpu_disassemble_instr(struct cpu *cpu, unsigned char *ib,
273          int running, uint64_t dumpaddr, int bintrans)          int running, uint64_t dumpaddr)
274  {  {
275          uint64_t offset;          uint64_t offset;
276          int len = 0, addr, iw, rd, rr, imm;          int len = 0, addr, iw, rd, rr, imm;
# Line 246  int avr_cpu_disassemble_instr(struct cpu Line 297  int avr_cpu_disassemble_instr(struct cpu
297          if ((iw & 0xffff) == 0x0000) {          if ((iw & 0xffff) == 0x0000) {
298                  print_spaces(len);                  print_spaces(len);
299                  debug("nop\n");                  debug("nop\n");
300          } else if ((iw & 0xfc00) == 0x0c00) {          } else if ((iw & 0xff00) == 0x0100) {
301                    print_spaces(len);
302                    rd = (iw >> 3) & 30;
303                    rr = (iw << 1) & 30;
304                    debug("movw\tr%i:r%i,r%i:r%i\n", rd+1, rd, rr+1, rr);
305            } else if ((iw & 0xff00) == 0x0200) {
306                    print_spaces(len);
307                    rd = ((iw >> 4) & 15) + 16;
308                    rr = (iw & 15) + 16;
309                    debug("muls\tr%i,r%i\n", rd, rr);
310            } else if ((iw & 0xff88) == 0x0300) {
311                    print_spaces(len);
312                    rd = ((iw >> 4) & 7) + 16;
313                    rr = (iw & 7) + 16;
314                    debug("mulsu\tr%i,r%i\n", rd, rr);
315            } else if ((iw & 0xff88) == 0x0308) {
316                    print_spaces(len);
317                    rd = ((iw >> 4) & 7) + 16;
318                    rr = (iw & 7) + 16;
319                    debug("fmul\tr%i,r%i\n", rd, rr);
320            } else if ((iw & 0xff88) == 0x0380) {
321                    print_spaces(len);
322                    rd = ((iw >> 4) & 7) + 16;
323                    rr = (iw & 7) + 16;
324                    debug("fmuls\tr%i,r%i\n", rd, rr);
325            } else if ((iw & 0xff88) == 0x0388) {
326                    print_spaces(len);
327                    rd = ((iw >> 4) & 7) + 16;
328                    rr = (iw & 7) + 16;
329                    debug("fmulsu\tr%i,r%i\n", rd, rr);
330            } else if ((iw & 0xec00) == 0x0400) {
331                    print_spaces(len);
332                    rd = (iw & 0x1f0) >> 4;
333                    rr = ((iw & 0x200) >> 5) | (iw & 0xf);
334                    debug("cp%s\tr%i,r%i\n", iw & 0x1000? "" : "c", rd, rr);
335            } else if ((iw & 0xec00) == 0x0800) {
336                  print_spaces(len);                  print_spaces(len);
337                  rd = (iw & 0x1f0) >> 4;                  rd = (iw & 0x1f0) >> 4;
338                  rr = ((iw & 0x200) >> 5) | (iw & 0xf);                  rr = ((iw & 0x200) >> 5) | (iw & 0xf);
339                  debug("add\tr%i,r%i\n", rd, rr);                  debug("%s\tr%i,r%i\n", iw & 0x1000? "sub" : "sbc", rd, rr);
340          } else if ((iw & 0xfc00) == 0x1c00) {          } else if ((iw & 0xec00) == 0x0c00) {
341                  print_spaces(len);                  print_spaces(len);
342                  rd = (iw & 0x1f0) >> 4;                  rd = (iw & 0x1f0) >> 4;
343                  rr = ((iw & 0x200) >> 5) | (iw & 0xf);                  rr = ((iw & 0x200) >> 5) | (iw & 0xf);
344                  debug("adc\tr%i,r%i\n", rd, rr);                  debug("%s\tr%i,r%i\n", iw & 0x1000? "adc" : "add", rd, rr);
345            } else if ((iw & 0xfc00) == 0x1000) {
346                    print_spaces(len);
347                    rd = (iw & 0x1f0) >> 4;
348                    rr = ((iw & 0x200) >> 5) | (iw & 0xf);
349                    debug("cpse\tr%i,r%i\n", rd, rr);
350          } else if ((iw & 0xfc00) == 0x2000) {          } else if ((iw & 0xfc00) == 0x2000) {
351                  print_spaces(len);                  print_spaces(len);
352                  rd = (iw & 0x1f0) >> 4;                  rd = (iw & 0x1f0) >> 4;
353                  rr = ((iw & 0x200) >> 5) | (iw & 0xf);                  rr = ((iw & 0x200) >> 5) | (iw & 0xf);
354                  debug("and\tr%i,r%i\n", rd, rr);                  debug("and\tr%i,r%i\n", rd, rr);
355            } else if ((iw & 0xfc00) == 0x2400) {
356                    print_spaces(len);
357                    rd = (iw & 0x1f0) >> 4;
358                    rr = ((iw & 0x200) >> 5) | (iw & 0xf);
359                    debug("eor\tr%i,r%i\n", rd, rr);
360            } else if ((iw & 0xfc00) == 0x2800) {
361                    print_spaces(len);
362                    rd = (iw & 0x1f0) >> 4;
363                    rr = ((iw & 0x200) >> 5) | (iw & 0xf);
364                    debug("or\tr%i,r%i\n", rd, rr);
365          } else if ((iw & 0xfc00) == 0x2c00) {          } else if ((iw & 0xfc00) == 0x2c00) {
366                  print_spaces(len);                  print_spaces(len);
367                  rd = (iw & 0x1f0) >> 4;                  rd = (iw & 0x1f0) >> 4;
368                  rr = ((iw & 0x200) >> 5) | (iw & 0xf);                  rr = ((iw & 0x200) >> 5) | (iw & 0xf);
369                  debug("mov\tr%i,r%i\n", rd, rr);                  debug("mov\tr%i,r%i\n", rd, rr);
370            } else if ((iw & 0xf000) == 0x3000) {
371                    print_spaces(len);
372                    rd = ((iw >> 4) & 15) + 16;
373                    imm = ((iw >> 4) & 0xf0) + (iw & 15);
374                    debug("cpi\tr%i,0x%x\n", rd, imm);
375            } else if ((iw & 0xf000) == 0x4000) {
376                    print_spaces(len);
377                    rd = ((iw >> 4) & 15) + 16;
378                    imm = ((iw >> 4) & 0xf0) + (iw & 15);
379                    debug("sbci\tr%i,0x%x\n", rd, imm);
380            } else if ((iw & 0xf000) == 0x5000) {
381                    print_spaces(len);
382                    rd = ((iw >> 4) & 15) + 16;
383                    imm = ((iw >> 4) & 0xf0) + (iw & 15);
384                    debug("subi\tr%i,0x%x\n", rd, imm);
385            } else if ((iw & 0xe000) == 0x6000) {
386                    print_spaces(len);
387                    rd = ((iw >> 4) & 15) + 16;
388                    imm = ((iw >> 4) & 0xf0) + (iw & 15);
389                    debug("%s\tr%i,0x%x\n", iw & 0x1000? "andi" : "ori", rd, imm);
390          } else if ((iw & 0xfe0f) == 0x8000) {          } else if ((iw & 0xfe0f) == 0x8000) {
391                  print_spaces(len);                  print_spaces(len);
392                  rd = (iw >> 4) & 31;                  rd = (iw >> 4) & 31;
# Line 274  int avr_cpu_disassemble_instr(struct cpu Line 395  int avr_cpu_disassemble_instr(struct cpu
395                  print_spaces(len);                  print_spaces(len);
396                  rd = (iw >> 4) & 31;                  rd = (iw >> 4) & 31;
397                  debug("ld\tr%i,Y\n", rd);                  debug("ld\tr%i,Y\n", rd);
398            } else if ((iw & 0xfe0f) == 0x8208) {
399                    print_spaces(len);
400                    rd = (iw >> 4) & 31;
401                    debug("st\tY,r%i\n", rd);
402          } else if ((iw & 0xfe0f) == 0x900c) {          } else if ((iw & 0xfe0f) == 0x900c) {
403                  print_spaces(len);                  print_spaces(len);
404                  rd = (iw >> 4) & 31;                  rd = (iw >> 4) & 31;
# Line 282  int avr_cpu_disassemble_instr(struct cpu Line 407  int avr_cpu_disassemble_instr(struct cpu
407                  print_spaces(len);                  print_spaces(len);
408                  rd = (iw >> 4) & 31;                  rd = (iw >> 4) & 31;
409                  debug("%s\tr%i\n", iw & 0x200? "push" : "pop", rd);                  debug("%s\tr%i\n", iw & 0x200? "push" : "pop", rd);
410          } else if ((iw & 0xfe0f) == 0x9200) {          } else if ((iw & 0xfe0f) == 0x9000) {
411                  print_two(ib, &len);                  print_two(ib, &len);
412                  addr = (ib[3] << 8) + ib[2];                  addr = (ib[3] << 8) + ib[2];
413                  print_spaces(len);                  print_spaces(len);
414                  debug("sts\t0x%x,r%i\n", addr, (iw & 0x1f0) >> 4);                  if (iw & 0x200)
415                            debug("sts\t0x%x,r%i\n", addr, (iw & 0x1f0) >> 4);
416                    else
417                            debug("lds\tr%i,0x%x\n", (iw & 0x1f0) >> 4, addr);
418            } else if ((iw & 0xfe0f) == 0x9209) {
419                    print_spaces(len);
420                    rr = (iw >> 4) & 31;
421                    debug("st\tY+,r%i\n", rr);
422            } else if ((iw & 0xfe0f) == 0x920a) {
423                    print_spaces(len);
424                    rr = (iw >> 4) & 31;
425                    debug("st\t-Y,r%i\n", rr);
426            } else if ((iw & 0xfe0f) == 0x9401) {
427                    print_spaces(len);
428                    rd = (iw >> 4) & 31;
429                    debug("neg\tr%i\n", rd);
430          } else if ((iw & 0xfe0f) == 0x9402) {          } else if ((iw & 0xfe0f) == 0x9402) {
431                  print_spaces(len);                  print_spaces(len);
432                  rd = (iw >> 4) & 31;                  rd = (iw >> 4) & 31;
433                  debug("swap\tr%i\n", rd);                  debug("swap\tr%i\n", rd);
434            } else if ((iw & 0xfe0f) == 0x9403) {
435                    print_spaces(len);
436                    rd = (iw >> 4) & 31;
437                    debug("inc\tr%i\n", rd);
438          } else if ((iw & 0xff0f) == 0x9408) {          } else if ((iw & 0xff0f) == 0x9408) {
439                  print_spaces(len);                  print_spaces(len);
440                  rd = (iw >> 4) & 7;                  rd = (iw >> 4) & 7;
441                  debug("%s%c\n", iw & 0x80? "cl" : "se", sreg_names[rd]);                  debug("%s%c\n", iw & 0x80? "cl" : "se", sreg_names[rd]);
442            } else if ((iw & 0xfe0f) == 0x940a) {
443                    print_spaces(len);
444                    rd = (iw >> 4) & 31;
445                    debug("dec\tr%i\n", rd);
446            } else if ((iw & 0xff8f) == 0x9408) {
447                    print_spaces(len);
448                    debug("bset\t%i\n", (iw >> 4) & 7);
449            } else if ((iw & 0xff8f) == 0x9488) {
450                    print_spaces(len);
451                    debug("bclr\t%i\n", (iw >> 4) & 7);
452          } else if ((iw & 0xffef) == 0x9508) {          } else if ((iw & 0xffef) == 0x9508) {
453                  /*  ret and reti  */                  /*  ret and reti  */
454                  print_spaces(len);                  print_spaces(len);
# Line 302  int avr_cpu_disassemble_instr(struct cpu Line 456  int avr_cpu_disassemble_instr(struct cpu
456          } else if ((iw & 0xffff) == 0x9588) {          } else if ((iw & 0xffff) == 0x9588) {
457                  print_spaces(len);                  print_spaces(len);
458                  debug("sleep\n");                  debug("sleep\n");
459            } else if ((iw & 0xffff) == 0x9598) {
460                    print_spaces(len);
461                    debug("break\n");
462          } else if ((iw & 0xffff) == 0x95a8) {          } else if ((iw & 0xffff) == 0x95a8) {
463                  print_spaces(len);                  print_spaces(len);
464                  debug("wdr\n");                  debug("wdr\n");
465            } else if ((iw & 0xffef) == 0x95c8) {
466                    print_spaces(len);
467                    debug("%slpm\n", iw & 0x0010? "e" : "");
468          } else if ((iw & 0xff00) == 0x9600) {          } else if ((iw & 0xff00) == 0x9600) {
469                  print_spaces(len);                  print_spaces(len);
470                  imm = ((iw & 0xc0) >> 2) | (iw & 0xf);                  imm = ((iw & 0xc0) >> 2) | (iw & 0xf);
471                  rd = ((iw >> 4) & 3) * 2 + 24;                  rd = ((iw >> 4) & 3) * 2 + 24;
472                  debug("adiw\tr%i:r%i,0x%x\n", rd, rd+1, imm);                  debug("adiw\tr%i:r%i,0x%x\n", rd, rd+1, imm);
473            } else if ((iw & 0xfd00) == 0x9800) {
474                    print_spaces(len);
475                    imm = iw & 7;
476                    rd = (iw >> 3) & 31;    /*  A  */
477                    debug("%sbi\t0x%x,%i\n", iw & 0x0200? "s" : "c", rd, imm);
478            } else if ((iw & 0xfd00) == 0x9900) {
479                    print_spaces(len);
480                    imm = iw & 7;
481                    rd = (iw >> 3) & 31;    /*  A  */
482                    debug("sbi%s\t0x%x,%i\n", iw & 0x0200? "s" : "c", rd, imm);
483            } else if ((iw & 0xf000) == 0xb000) {
484                    print_spaces(len);
485                    imm = ((iw & 0x600) >> 5) | (iw & 0xf);
486                    rr = (iw >> 4) & 31;
487                    if (iw & 0x800)
488                            debug("out\t0x%x,r%i\n", imm, rr);
489                    else
490                            debug("in\tr%i,0x%x\n", rr, imm);
491          } else if ((iw & 0xe000) == 0xc000) {          } else if ((iw & 0xe000) == 0xc000) {
492                  print_spaces(len);                  print_spaces(len);
493                  addr = (int16_t)((iw & 0xfff) << 4);                  addr = (int16_t)((iw & 0xfff) << 4);
# Line 320  int avr_cpu_disassemble_instr(struct cpu Line 498  int avr_cpu_disassemble_instr(struct cpu
498                  rd = ((iw >> 4) & 0xf) + 16;                  rd = ((iw >> 4) & 0xf) + 16;
499                  imm = ((iw >> 4) & 0xf0) | (iw & 0xf);                  imm = ((iw >> 4) & 0xf0) | (iw & 0xf);
500                  debug("ldi\tr%i,0x%x\n", rd, imm);                  debug("ldi\tr%i,0x%x\n", rd, imm);
501            } else if ((iw & 0xfc00) == 0xf000) {
502                    print_spaces(len);
503                    addr = (iw >> 3) & 0x7f;
504                    if (addr >= 64)
505                            addr -= 128;
506                    addr = (addr + 1) * 2 + dumpaddr;
507                    debug("brbs\t%c,0x%x\n", sreg_names[iw & 7], addr);
508            } else if ((iw & 0xfc00) == 0xf400) {
509                    print_spaces(len);
510                    addr = (iw >> 3) & 0x7f;
511                    if (addr >= 64)
512                            addr -= 128;
513                    addr = (addr + 1) * 2 + dumpaddr;
514                    debug("brbc\t%c,0x%x\n", sreg_names[iw & 7], addr);
515            } else if ((iw & 0xfc08) == 0xfc00) {
516                    print_spaces(len);
517                    rr = (iw >> 4) & 31;
518                    imm = iw & 7;
519                    debug("sbr%s\tr%i,%i\n", iw & 0x0200 ? "s" : "c", rr, imm);
520          } else {          } else {
521                  print_spaces(len);                  print_spaces(len);
522                  debug("UNIMPLEMENTED 0x%04x\n", iw);                  debug("UNIMPLEMENTED 0x%04x\n", iw);

Legend:
Removed from v.23  
changed lines
  Added in v.24

  ViewVC Help
Powered by ViewVC 1.1.26