4 Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
6 This file is part of simavr.
8 simavr is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 simavr is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with simavr. If not, see <http://www.gnu.org/licenses/>.
30 const char * _sreg_bit_name = "cznvshti";
33 * Handle "touching" registers, marking them changed.
34 * This is used only for debugging purposes to be able to
35 * print the effects of each instructions on registers
37 #define REG_TOUCH(a, r) (a)->touched[(r) >> 5] |= (1 << ((r) & 0x1f))
38 #define REG_ISTOUCHED(a, r) ((a)->touched[(r) >> 5] & (1 << ((r) & 0x1f)))
41 * This allows a "special case" to skip indtruction tracing when in these
42 * symbols. since printf() is useful to have, but generates a lot of cycles
44 int dont_trace(const char * name)
47 !strcmp(name, "uart_putchar") ||
48 !strcmp(name, "fputc") ||
49 !strcmp(name, "printf") ||
50 !strcmp(name, "vfprintf") ||
51 !strcmp(name, "__ultoa_invert") ||
52 !strcmp(name, "__prologue_saves__") ||
53 !strcmp(name, "__epilogue_restores__"));
58 #define STATE(_f, args...) { \
60 if (avr->codeline[avr->pc>>1]) {\
61 const char * symn = avr->codeline[avr->pc>>1]->symbol; \
62 int dont = 0 && dont_trace(symn);\
63 if (dont!=donttrace) { \
68 printf("%04x: %-25s " _f, avr->pc, symn, ## args);\
70 printf("%s: %04x: " _f, __FUNCTION__, avr->pc, ## args);\
73 #define SREG() if (avr->trace && donttrace == 0) {\
74 printf("%04x: \t\t\t\t\t\t\t\t\tSREG = ", avr->pc); \
75 for (int _sbi = 0; _sbi < 8; _sbi++)\
76 printf("%c", avr->sreg[_sbi] ? toupper(_sreg_bit_name[_sbi]) : '.');\
81 * Set a register (r < 256)
82 * if it's an IO regisrer (> 31) also (try to) call any callback that was
83 * registered to track changes to that register.
85 static inline void _avr_set_r(avr_t * avr, uint8_t r, uint8_t v)
92 for (int i = 0; i < 8; i++)
93 avr->sreg[i] = (avr->data[R_SREG] & (1 << i)) != 0;
97 uint8_t io = AVR_DATA_TO_IO(r);
99 avr->iow[io].w(avr, r, v, avr->iow[io].param);
107 * Stack pointer access
109 inline uint16_t _avr_sp_get(avr_t * avr)
111 return avr->data[R_SPL] | (avr->data[R_SPH] << 8);
114 inline void _avr_sp_set(avr_t * avr, uint16_t sp)
116 _avr_set_r(avr, R_SPL, sp);
117 _avr_set_r(avr, R_SPH, sp >> 8);
121 * Set any address to a value; split between registers and SRAM
123 static inline void _avr_set_ram(avr_t * avr, uint16_t addr, uint8_t v)
126 _avr_set_r(avr, addr, v);
128 avr_core_watch_write(avr, addr, v);
132 * Get a value from SRAM.
134 static inline uint8_t _avr_get_ram(avr_t * avr, uint16_t addr)
136 if (addr > 31 && addr < 256) {
137 uint8_t io = AVR_DATA_TO_IO(addr);
139 avr->data[addr] = avr->ior[io].r(avr, addr, avr->ior[io].param);
141 return avr_core_watch_read(avr, addr);
145 * Stack oush accessors. Push/pop 8 and 16 bits
147 static inline void _avr_push8(avr_t * avr, uint16_t v)
149 uint16_t sp = _avr_sp_get(avr);
150 _avr_set_ram(avr, sp, v);
151 _avr_sp_set(avr, sp-1);
154 static inline uint8_t _avr_pop8(avr_t * avr)
156 uint16_t sp = _avr_sp_get(avr) + 1;
157 uint8_t res = _avr_get_ram(avr, sp);
158 _avr_sp_set(avr, sp);
162 inline void _avr_push16(avr_t * avr, uint16_t v)
164 _avr_push8(avr, v >> 8);
168 static inline uint16_t _avr_pop16(avr_t * avr)
170 uint16_t res = _avr_pop8(avr);
171 res |= _avr_pop8(avr) << 8;
176 * "Pretty" register names
178 const char * reg_names[255] = {
179 [R_XH] = "XH", [R_XL] = "XL",
180 [R_YH] = "YH", [R_YL] = "YL",
181 [R_ZH] = "ZH", [R_ZL] = "ZL",
182 [R_SPH] = "SPH", [R_SPL] = "SPL",
187 const char * avr_regname(uint8_t reg)
189 if (!reg_names[reg]) {
192 sprintf(tt, "r%d", reg);
194 sprintf(tt, "io:%02x", reg);
195 reg_names[reg] = strdup(tt);
197 return reg_names[reg];
201 * Called when an invalid opcode is decoded
203 static void _avr_invalid_opcode(avr_t * avr)
205 printf("\e[31m*** %04x: %-25s Invalid Opcode SP=%04x O=%04x \e[0m\n",
206 avr->pc, avr->codeline[avr->pc>>1]->symbol, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc+1]<<8));
210 * Dump changed registers when tracing
212 void avr_dump_state(avr_t * avr)
214 if (!avr->trace || donttrace)
219 for (int r = 0; r < 3 && !doit; r++)
225 const int r16[] = { R_SPL, R_XL, R_YL, R_ZL };
226 for (int i = 0; i < 4; i++)
227 if (REG_ISTOUCHED(avr, r16[i]) || REG_ISTOUCHED(avr, r16[i]+1)) {
228 REG_TOUCH(avr, r16[i]);
229 REG_TOUCH(avr, r16[i]+1);
232 for (int i = 0; i < 3*32; i++)
233 if (REG_ISTOUCHED(avr, i)) {
234 printf("%s=%02x ", avr_regname(i), avr->data[i]);
239 #define get_r_d_10(o) \
240 const uint8_t r = ((o >> 5) & 0x10) | (o & 0xf); \
241 const uint8_t d = (o >> 4) & 0x1f;\
242 const uint8_t vd = avr->data[d], vr =avr->data[r];
243 #define get_k_r16(o) \
244 const uint8_t r = 16 + ((o >> 4) & 0xf); \
245 const uint8_t k = ((o & 0x0f00) >> 4) | (o & 0xf);
248 * Add a "jump" address to the jump trace buffer
250 #define TRACE_JUMP()\
251 avr->old[avr->old_pci].pc = avr->pc;\
252 avr->old[avr->old_pci].sp = _avr_sp_get(avr);\
253 avr->old_pci = (avr->old_pci + 1) & (OLD_PC_SIZE-1);\
256 #define STACK_FRAME_PUSH()\
257 avr->stack_frame[avr->stack_frame_index].pc = avr->pc;\
258 avr->stack_frame[avr->stack_frame_index].sp = _avr_sp_get(avr);\
259 avr->stack_frame_index++;
260 #define STACK_FRAME_POP()\
261 if (avr->stack_frame_index > 0) \
262 avr->stack_frame_index--;
264 #define STACK_FRAME_PUSH()
265 #define STACK_FRAME_POP()
268 /****************************************************************************\
270 * Helper functions for calculating the status register bit values.
271 * See the Atmel data sheet for the instuction set for more info.
273 \****************************************************************************/
276 get_add_carry (uint8_t res, uint8_t rd, uint8_t rr, int b)
278 uint8_t resb = res >> b & 0x1;
279 uint8_t rdb = rd >> b & 0x1;
280 uint8_t rrb = rr >> b & 0x1;
281 return (rdb & rrb) | (rrb & ~resb) | (~resb & rdb);
285 get_add_overflow (uint8_t res, uint8_t rd, uint8_t rr)
287 uint8_t res7 = res >> 7 & 0x1;
288 uint8_t rd7 = rd >> 7 & 0x1;
289 uint8_t rr7 = rr >> 7 & 0x1;
290 return (rd7 & rr7 & ~res7) | (~rd7 & ~rr7 & res7);
294 get_sub_carry (uint8_t res, uint8_t rd, uint8_t rr, int b)
296 uint8_t resb = res >> b & 0x1;
297 uint8_t rdb = rd >> b & 0x1;
298 uint8_t rrb = rr >> b & 0x1;
299 return (~rdb & rrb) | (rrb & resb) | (resb & ~rdb);
303 get_sub_overflow (uint8_t res, uint8_t rd, uint8_t rr)
305 uint8_t res7 = res >> 7 & 0x1;
306 uint8_t rd7 = rd >> 7 & 0x1;
307 uint8_t rr7 = rr >> 7 & 0x1;
308 return (rd7 & ~rr7 & ~res7) | (~rd7 & rr7 & res7);
312 get_compare_carry (uint8_t res, uint8_t rd, uint8_t rr, int b)
314 uint8_t resb = (res >> b) & 0x1;
315 uint8_t rdb = (rd >> b) & 0x1;
316 uint8_t rrb = (rr >> b) & 0x1;
317 return (~rdb & rrb) | (rrb & resb) | (resb & ~rdb);
321 get_compare_overflow (uint8_t res, uint8_t rd, uint8_t rr)
323 res >>= 7; rd >>= 7; rr >>= 7;
324 /* The atmel data sheet says the second term is ~rd7 for CP
325 * but that doesn't make any sense. You be the judge. */
326 return (rd & ~rr & ~res) | (~rd & rr & res);
329 static inline int _avr_is_instruction_32_bits(avr_t * avr, uint32_t pc)
331 uint16_t o = (avr->flash[pc] | (avr->flash[pc+1] << 8)) & 0xfc0f;
332 return o == 0x9200 || // STS ! Store Direct to Data Space
333 o == 0x9000 || // LDS Load Direct from Data Space
334 o == 0x940c || // JMP Long Jump
335 o == 0x940d || // JMP Long Jump
336 o == 0x940e || // CALL Long Call to sub
337 o == 0x940f; // CALL Long Call to sub
341 * Main opcode decoder
343 * The decoder was written by following the datasheet in no particular order.
344 * As I went along, I noticed "bit patterns" that could be used to factor opcodes
345 * However, a lot of these only becane apparent later on, so SOME instructions
346 * (skip of bit set etc) are compact, and some could use some refactoring (the ALU
347 * ones scream to be factored).
348 * I assume that the decoder could easily be 2/3 of it's current size.
350 * + It lacks the "extended" XMega jumps.
351 * + It also doesn't check wether the core it's
352 * emulating is suposed to have the fancy instructions, like multiply and such.
354 * for now all instructions take "one" cycle, the cycle+=<extra> needs to be added.
356 uint16_t avr_run_one(avr_t * avr)
359 * this traces spurious reset or bad jump/opcodes and dumps the last 32 "jumps" to track it down
361 if ((avr->pc == 0 && avr->cycle > 0) || avr->pc >= avr->codeend) {
367 uint32_t opcode = (avr->flash[avr->pc + 1] << 8) | avr->flash[avr->pc];
368 uint32_t new_pc = avr->pc + 2; // future "default" pc
371 avr->touched[0] = avr->touched[1] = avr->touched[2] = 0;
373 switch (opcode & 0xf000) {
376 case 0x0000: { // NOP
380 switch (opcode & 0xfc00) {
381 case 0x0400: { // CPC compare with carry 0000 01rd dddd rrrr
383 uint8_t res = vd - vr - avr->sreg[S_C];
384 STATE("cpc %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
387 avr->sreg[S_H] = get_compare_carry(res, vd, vr, 3);
388 avr->sreg[S_V] = get_compare_overflow(res, vd, vr);
389 avr->sreg[S_N] = (res >> 7) & 1;
390 avr->sreg[S_C] = get_compare_carry(res, vd, vr, 7);
391 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
394 case 0x0c00: { // ADD without carry 0000 11 rd dddd rrrr
396 uint8_t res = vd + vr;
398 STATE("lsl %s[%02x] = %02x\n", avr_regname(d), vd, res & 0xff);
400 STATE("add %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
402 _avr_set_r(avr, d, res);
403 avr->sreg[S_Z] = res == 0;
404 avr->sreg[S_H] = get_add_carry(res, vd, vr, 3);
405 avr->sreg[S_V] = get_add_overflow(res, vd, vr);
406 avr->sreg[S_N] = (res >> 7) & 1;
407 avr->sreg[S_C] = get_add_carry(res, vd, vr, 7);
408 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
411 case 0x0800: { // SBC substract with carry 0000 10rd dddd rrrr
413 uint8_t res = vd - vr - avr->sreg[S_C];
414 STATE("sbc %s[%02x], %s[%02x] = %02x\n", avr_regname(d), avr->data[d], avr_regname(r), avr->data[r], res);
415 _avr_set_r(avr, d, res);
418 avr->sreg[S_H] = get_sub_carry(res, vd, vr, 3);
419 avr->sreg[S_V] = get_sub_overflow(res, vd, vr);
420 avr->sreg[S_N] = (res >> 7) & 1;
421 avr->sreg[S_C] = get_sub_carry(res, vd, vr, 7);
422 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
426 switch (opcode & 0xff00) {
427 case 0x0100: { // MOVW – Copy Register Word 0000 0001 dddd rrrr
428 uint8_t d = ((opcode >> 4) & 0xf) << 1;
429 uint8_t r = ((opcode) & 0xf) << 1;
430 STATE("movw %s:%s, %s:%s[%02x%02x]\n", avr_regname(d), avr_regname(d+1), avr_regname(r), avr_regname(r+1), avr->data[r+1], avr->data[r]);
431 _avr_set_r(avr, d, avr->data[r]);
432 _avr_set_r(avr, d+1, avr->data[r+1]);
434 case 0x0200: { // MULS – Multiply Signed 0000 0010 dddd rrrr
435 int8_t r = opcode & 0xf;
436 int8_t d = (opcode >> 4) & 0xf;
437 int16_t res = ((int8_t)avr->data[r]) * ((int8_t)avr->data[d]);
438 STATE("muls %s[%d], %s[%02x] = %d\n", avr_regname(d), ((int8_t)avr->data[d]), avr_regname(r), ((int8_t)avr->data[r]), res);
439 _avr_set_r(avr, 0, res);
440 _avr_set_r(avr, 1, res >> 8);
441 avr->sreg[S_C] = (res >> 15) & 1;
442 avr->sreg[S_Z] = res == 0;
445 case 0x0300: { // multiplications
446 int8_t r = 16 + (opcode & 0x7);
447 int8_t d = 16 + ((opcode >> 4) & 0x7);
450 const char * name = "";
451 switch (opcode & 0x88) {
452 case 0x00: // MULSU – Multiply Signed Unsigned 0000 0011 0ddd 0rrr
453 res = ((uint8_t)avr->data[r]) * ((int8_t)avr->data[d]);
457 case 0x08: // FMUL Fractional Multiply Unsigned 0000 0011 0ddd 1rrr
458 res = ((uint8_t)avr->data[r]) * ((uint8_t)avr->data[d]);
463 case 0x80: // FMULS – Multiply Signed 0000 0011 1ddd 0rrr
464 res = ((int8_t)avr->data[r]) * ((int8_t)avr->data[d]);
469 case 0x88: // FMULSU – Multiply Signed Unsigned 0000 0011 1ddd 0rrr
470 res = ((uint8_t)avr->data[r]) * ((int8_t)avr->data[d]);
477 STATE("%s %s[%d], %s[%02x] = %d\n", name, avr_regname(d), ((int8_t)avr->data[d]), avr_regname(r), ((int8_t)avr->data[r]), res);
478 _avr_set_r(avr, 0, res);
479 _avr_set_r(avr, 1, res >> 8);
481 avr->sreg[S_Z] = res == 0;
484 default: _avr_invalid_opcode(avr);
492 switch (opcode & 0xfc00) {
493 case 0x1800: { // SUB without carry 0000 10 rd dddd rrrr
495 uint8_t res = vd - vr;
496 STATE("sub %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
497 _avr_set_r(avr, d, res);
498 avr->sreg[S_Z] = res == 0;
499 avr->sreg[S_H] = get_sub_carry(res, vd, vr, 3);
500 avr->sreg[S_V] = get_sub_overflow(res, vd, vr);
501 avr->sreg[S_N] = (res >> 7) & 1;
502 avr->sreg[S_C] = get_sub_carry(res, vd, vr, 7);
503 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
506 case 0x1000: { // CPSE Compare, skip if equal 0000 10 rd dddd rrrr
508 uint16_t res = vd == vr;
509 STATE("cpse %s[%02x], %s[%02x]\t; Will%s skip\n", avr_regname(d), avr->data[d], avr_regname(r), avr->data[r], res ? "":"not ");
511 if (_avr_is_instruction_32_bits(avr, new_pc)) {
512 new_pc += 4; cycle += 2;
514 new_pc += 2; cycle++;
518 case 0x1400: { // CP Compare 0000 10 rd dddd rrrr
520 uint8_t res = vd - vr;
521 STATE("cp %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
522 avr->sreg[S_Z] = res == 0;
523 avr->sreg[S_H] = get_compare_carry(res, vd, vr, 3);
524 avr->sreg[S_V] = get_compare_overflow(res, vd, vr);
525 avr->sreg[S_N] = res >> 7;
526 avr->sreg[S_C] = get_compare_carry(res, vd, vr, 7);
527 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
530 case 0x1c00: { // ADD with carry 0001 11 rd dddd rrrr
532 uint8_t res = vd + vr + avr->sreg[S_C];
534 STATE("rol %s[%02x] = %02x\n", avr_regname(d), avr->data[d], res);
536 STATE("addc %s[%02x], %s[%02x] = %02x\n", avr_regname(d), avr->data[d], avr_regname(r), avr->data[r], res);
538 _avr_set_r(avr, d, res);
539 avr->sreg[S_Z] = res == 0;
540 avr->sreg[S_H] = get_add_carry(res, vd, vr, 3);
541 avr->sreg[S_V] = get_add_overflow(res, vd, vr);
542 avr->sreg[S_N] = (res >> 7) & 1;
543 avr->sreg[S_C] = get_add_carry(res, vd, vr, 7);
544 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
547 default: _avr_invalid_opcode(avr);
552 switch (opcode & 0xfc00) {
553 case 0x2000: { // AND 0010 00rd dddd rrrr
555 uint8_t res = vd & vr;
557 STATE("tst %s[%02x]\n", avr_regname(d), avr->data[d]);
559 STATE("and %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
561 _avr_set_r(avr, d, res);
562 avr->sreg[S_Z] = res == 0;
563 avr->sreg[S_N] = (res >> 7) & 1;
565 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
568 case 0x2400: { // EOR 0010 01rd dddd rrrr
570 uint8_t res = vd ^ vr;
572 STATE("clr %s[%02x]\n", avr_regname(d), avr->data[d]);
574 STATE("eor %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
576 _avr_set_r(avr, d, res);
577 avr->sreg[S_Z] = res == 0;
578 avr->sreg[S_N] = (res >> 7) & 1;
580 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
583 case 0x2800: { // OR Logical OR 0010 10rd dddd rrrr
585 uint8_t res = vd | vr;
586 STATE("or %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
587 _avr_set_r(avr, d, res);
588 avr->sreg[S_Z] = res == 0;
589 avr->sreg[S_N] = (res >> 7) & 1;
591 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
594 case 0x2c00: { // MOV 0010 11rd dddd rrrr
597 STATE("mov %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
598 _avr_set_r(avr, d, res);
600 default: _avr_invalid_opcode(avr);
604 case 0x3000: { // CPI 0011 KKKK rrrr KKKK
606 uint8_t vr = avr->data[r];
607 uint8_t res = vr - k;
608 STATE("cpi %s[%02x], 0x%02x\n", avr_regname(r), vr, k);
610 avr->sreg[S_Z] = res == 0;
611 avr->sreg[S_H] = get_compare_carry(res, vr, k, 3);
612 avr->sreg[S_V] = get_compare_overflow(res, vr, k);
613 avr->sreg[S_N] = (res >> 7) & 1;
614 avr->sreg[S_C] = get_compare_carry(res, vr, k, 7);
615 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
619 case 0x4000: { // SBCI Subtract Immediate With Carry 0101 10 kkkk dddd kkkk
621 uint8_t vr = avr->data[r];
622 uint8_t res = vr - k - avr->sreg[S_C];
623 STATE("sbci %s[%02x], 0x%02x = %02x\n", avr_regname(r), avr->data[r], k, res);
624 _avr_set_r(avr, r, res);
625 avr->sreg[S_Z] = res == 0;
626 avr->sreg[S_N] = (res >> 7) & 1;
627 avr->sreg[S_C] = (k + avr->sreg[S_C]) > vr;
628 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
632 case 0x5000: { // SUB Subtract Immediate 0101 10 kkkk dddd kkkk
634 uint8_t vr = avr->data[r];
635 uint8_t res = vr - k;
636 STATE("subi %s[%02x], 0x%02x = %02x\n", avr_regname(r), avr->data[r], k, res);
637 _avr_set_r(avr, r, res);
638 avr->sreg[S_Z] = res == 0;
639 avr->sreg[S_N] = (res >> 7) & 1;
640 avr->sreg[S_C] = k > vr;
641 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
645 case 0x6000: { // ORI aka SBR Logical AND with Immediate 0110 kkkk dddd kkkk
647 uint8_t res = avr->data[r] | k;
648 STATE("ori %s[%02x], 0x%02x\n", avr_regname(r), avr->data[r], k);
649 _avr_set_r(avr, r, res);
650 avr->sreg[S_Z] = res == 0;
651 avr->sreg[S_N] = (res >> 7) & 1;
653 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
657 case 0x7000: { // ANDI Logical AND with Immediate 0111 kkkk dddd kkkk
659 uint8_t res = avr->data[r] & k;
660 STATE("andi %s[%02x], 0x%02x\n", avr_regname(r), avr->data[r], k);
661 _avr_set_r(avr, r, res);
662 avr->sreg[S_Z] = res == 0;
663 avr->sreg[S_N] = (res >> 7) & 1;
665 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
671 switch (opcode & 0xd008) {
673 case 0x8000: { // LD (LDD) – Load Indirect using Z 10q0 qq0r rrrr 0qqq
674 uint16_t v = avr->data[R_ZL] | (avr->data[R_ZH] << 8);
675 uint8_t r = (opcode >> 4) & 0x1f;
676 uint8_t q = ((opcode & 0x2000) >> 8) | ((opcode & 0x0c00) >> 7) | (opcode & 0x7);
678 if (opcode & 0x0200) {
679 STATE("st (Z+%d[%04x]), %s[%02x]\n", q, v+q, avr_regname(r), avr->data[r]);
680 _avr_set_ram(avr, v+q, avr->data[r]);
682 STATE("ld %s, (Z+%d[%04x])=[%02x]\n", avr_regname(r), q, v+q, avr->data[v+q]);
683 _avr_set_r(avr, r, _avr_get_ram(avr, v+q));
688 case 0x8008: { // LD (LDD) – Load Indirect using Y 10q0 qq0r rrrr 1qqq
689 uint16_t v = avr->data[R_YL] | (avr->data[R_YH] << 8);
690 uint8_t r = (opcode >> 4) & 0x1f;
691 uint8_t q = ((opcode & 0x2000) >> 8) | ((opcode & 0x0c00) >> 7) | (opcode & 0x7);
693 if (opcode & 0x0200) {
694 STATE("st (Y+%d[%04x]), %s[%02x]\n", q, v+q, avr_regname(r), avr->data[r]);
695 _avr_set_ram(avr, v+q, avr->data[r]);
697 STATE("ld %s, (Y+%d[%04x])=[%02x]\n", avr_regname(r), q, v+q, avr->data[v+q]);
698 _avr_set_r(avr, r, _avr_get_ram(avr, v+q));
702 default: _avr_invalid_opcode(avr);
707 /* this is an annoying special case, but at least these lines handle all the SREG set/clear opcodes */
708 if ((opcode & 0xff0f) == 0x9408) {
709 uint8_t b = (opcode >> 4) & 7;
710 STATE("%s%c\n", opcode & 0x0080 ? "cl" : "se", _sreg_bit_name[b]);
711 avr->sreg[b] = (opcode & 0x0080) == 0;
713 } else switch (opcode) {
714 case 0x9588: { // SLEEP
716 avr->state = cpu_Sleeping;
718 case 0x9598: { // BREAK
721 avr->state = cpu_StepDone;
723 case 0x95a8: { // WDR
726 case 0x9409: { // IJMP Indirect jump
727 uint16_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8);
728 STATE("ijmp Z[%04x]\n", z << 1);
733 case 0x9509: { // ICALL Indirect Call to Subroutine
734 uint16_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8);
735 STATE("icall Z[%04x]\n", z << 1);
736 _avr_push16(avr, new_pc >> 1);
743 case 0x9508: { // RET
744 new_pc = _avr_pop16(avr) << 1;
745 if (opcode & 0x10) // reti
748 STATE("ret%s\n", opcode & 0x10 ? "i" : "");
752 case 0x95c8: { // LPM Load Program Memory R0 <- (Z)
753 uint16_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8);
754 STATE("lpm %s, (Z[%04x])\n", avr_regname(0), z);
755 _avr_set_r(avr, 0, avr->flash[z]);
757 case 0x9408:case 0x9418:case 0x9428:case 0x9438:case 0x9448:case 0x9458:case 0x9468:
759 { // BSET 1001 0100 0ddd 1000
760 uint8_t b = (opcode >> 4) & 7;
762 STATE("bset %c\n", _sreg_bit_name[b]);
765 case 0x9488:case 0x9498:case 0x94a8:case 0x94b8:case 0x94c8:case 0x94d8:case 0x94e8:
767 { // BSET 1001 0100 0ddd 1000
768 uint8_t b = (opcode >> 4) & 7;
770 STATE("bclr %c\n", _sreg_bit_name[b]);
774 switch (opcode & 0xfe0f) {
775 case 0x9000: { // LDS Load Direct from Data Space, 32 bits
776 uint8_t r = (opcode >> 4) & 0x1f;
777 uint16_t x = (avr->flash[new_pc+1] << 8) | avr->flash[new_pc];
779 STATE("lds %s[%02x], 0x%04x\n", avr_regname(r), avr->data[r], x);
780 _avr_set_r(avr, r, _avr_get_ram(avr, x));
784 case 0x9004: { // LPM Load Program Memory 1001 000d dddd 01oo
785 uint16_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8);
786 uint8_t r = (opcode >> 4) & 0x1f;
788 STATE("lpm %s, (Z[%04x]%s)\n", avr_regname(r), z, opcode?"+":"");
789 _avr_set_r(avr, r, avr->flash[z]);
792 _avr_set_r(avr, R_ZH, z >> 8);
793 _avr_set_r(avr, R_ZL, z);
799 case 0x900e: { // LD Load Indirect from Data using X 1001 000r rrrr 11oo
801 uint8_t r = (opcode >> 4) & 0x1f;
802 uint16_t x = (avr->data[R_XH] << 8) | avr->data[R_XL];
803 STATE("ld %s, %sX[%04x]%s\n", avr_regname(r), op == 2 ? "--" : "", x, op == 1 ? "++" : "");
806 _avr_set_r(avr, r, _avr_get_ram(avr, x));
808 _avr_set_r(avr, R_XH, x >> 8);
809 _avr_set_r(avr, R_XL, x);
813 case 0x920e: { // ST Store Indirect Data Space X 1001 001r rrrr 11oo
815 uint8_t r = (opcode >> 4) & 0x1f;
816 uint16_t x = (avr->data[R_XH] << 8) | avr->data[R_XL];
817 STATE("st %sX[%04x]%s, %s[%02x] \n", op == 2 ? "--" : "", x, op == 1 ? "++" : "", avr_regname(r), avr->data[r]);
820 _avr_set_ram(avr, x, avr->data[r]);
822 _avr_set_r(avr, R_XH, x >> 8);
823 _avr_set_r(avr, R_XL, x);
826 case 0x900a: { // LD Load Indirect from Data using Y 1001 000r rrrr 10oo
828 uint8_t r = (opcode >> 4) & 0x1f;
829 uint16_t y = (avr->data[R_YH] << 8) | avr->data[R_YL];
830 STATE("ld %s, %sY[%04x]%s\n", avr_regname(r), op == 2 ? "--" : "", y, op == 1 ? "++" : "");
833 _avr_set_r(avr, r, _avr_get_ram(avr, y));
835 _avr_set_r(avr, R_YH, y >> 8);
836 _avr_set_r(avr, R_YL, y);
839 case 0x920a: { // ST Store Indirect Data Space Y 1001 001r rrrr 10oo
841 uint8_t r = (opcode >> 4) & 0x1f;
842 uint16_t y = (avr->data[R_YH] << 8) | avr->data[R_YL];
843 STATE("st %sY[%04x]%s, %s[%02x] \n", op == 2 ? "--" : "", y, op == 1 ? "++" : "", avr_regname(r), avr->data[r]);
846 _avr_set_ram(avr, y, avr->data[r]);
848 _avr_set_r(avr, R_YH, y >> 8);
849 _avr_set_r(avr, R_YL, y);
851 case 0x9200: { // STS ! Store Direct to Data Space, 32 bits
852 uint8_t r = (opcode >> 4) & 0x1f;
853 uint16_t x = (avr->flash[new_pc+1] << 8) | avr->flash[new_pc];
855 STATE("sts 0x%04x, %s[%02x]\n", x, avr_regname(r), avr->data[r]);
856 _avr_set_ram(avr, x, avr->data[r]);
859 case 0x9002: { // LD Load Indirect from Data using Z 1001 001r rrrr 00oo
861 uint8_t r = (opcode >> 4) & 0x1f;
862 uint16_t z = (avr->data[R_ZH] << 8) | avr->data[R_ZL];
863 STATE("ld %s, %sZ[%04x]%s\n", avr_regname(r), op == 2 ? "--" : "", z, op == 1 ? "++" : "");
865 _avr_set_r(avr, r, _avr_get_ram(avr, z));
867 _avr_set_r(avr, R_ZH, z >> 8);
868 _avr_set_r(avr, R_ZL, z);
871 case 0x9202: { // ST Store Indirect Data Space Z 1001 001r rrrr 00oo
873 uint8_t r = (opcode >> 4) & 0x1f;
874 uint16_t z = (avr->data[R_ZH] << 8) | avr->data[R_ZL];
875 STATE("st %sZ[%04x]%s, %s[%02x] \n", op == 2 ? "--" : "", z, op == 1 ? "++" : "", avr_regname(r), avr->data[r]);
877 _avr_set_ram(avr, z, avr->data[r]);
879 _avr_set_r(avr, R_ZH, z >> 8);
880 _avr_set_r(avr, R_ZL, z);
882 case 0x900f: { // POP 1001 000d dddd 1111
883 uint8_t r = (opcode >> 4) & 0x1f;
884 _avr_set_r(avr, r, _avr_pop8(avr));
885 uint16_t sp = _avr_sp_get(avr);
886 STATE("pop %s (@%04x)[%02x]\n", avr_regname(r), sp, avr->data[sp]);
889 case 0x920f: { // PUSH 1001 001d dddd 1111
890 uint8_t r = (opcode >> 4) & 0x1f;
891 _avr_push8(avr, avr->data[r]);
892 uint16_t sp = _avr_sp_get(avr);
893 STATE("push %s[%02x] (@%04x)\n", avr_regname(r), avr->data[r], sp);
896 case 0x9400: { // COM – One’s Complement
897 uint8_t r = (opcode >> 4) & 0x1f;
898 uint8_t res = 0xff - avr->data[r];
899 STATE("com %s[%02x] = %02x\n", avr_regname(r), avr->data[r], res);
900 _avr_set_r(avr, r, res);
901 avr->sreg[S_Z] = res == 0;
902 avr->sreg[S_N] = res >> 7;
905 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
908 case 0x9401: { // NEG – One’s Complement
909 uint8_t r = (opcode >> 4) & 0x1f;
910 uint8_t rd = avr->data[r];
911 uint8_t res = 0x00 - rd;
912 STATE("neg %s[%02x] = %02x\n", avr_regname(r), rd, res);
913 _avr_set_r(avr, r, res);
914 avr->sreg[S_H] = ((res >> 3) | (rd >> 3)) & 1;
915 avr->sreg[S_Z] = res == 0;
916 avr->sreg[S_N] = res >> 7;
917 avr->sreg[S_V] = res == 0x80;
918 avr->sreg[S_C] = res != 0;
919 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
922 case 0x9402: { // SWAP – Swap Nibbles
923 uint8_t r = (opcode >> 4) & 0x1f;
924 uint8_t res = (avr->data[r] >> 4) | (avr->data[r] << 4) ;
925 STATE("swap %s[%02x] = %02x\n", avr_regname(r), avr->data[r], res);
926 _avr_set_r(avr, r, res);
928 case 0x9403: { // INC – Increment
929 uint8_t r = (opcode >> 4) & 0x1f;
930 uint8_t res = avr->data[r] + 1;
931 STATE("inc %s[%02x] = %02x\n", avr_regname(r), avr->data[r], res);
932 _avr_set_r(avr, r, res);
933 avr->sreg[S_Z] = res == 0;
934 avr->sreg[S_N] = res >> 7;
935 avr->sreg[S_V] = res == 0x7f;
936 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
939 case 0x9405: { // ASR – Arithmetic Shift Right 1001 010d dddd 0101
940 uint8_t r = (opcode >> 4) & 0x1f;
941 uint8_t vr = avr->data[r];
942 uint8_t res = (vr >> 1) | (vr & 0x80);
943 STATE("asr %s[%02x]\n", avr_regname(r), vr);
944 _avr_set_r(avr, r, res);
945 avr->sreg[S_Z] = res == 0;
946 avr->sreg[S_C] = vr & 1;
947 avr->sreg[S_N] = res >> 7;
948 avr->sreg[S_V] = avr->sreg[S_N] ^ avr->sreg[S_C];
949 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
952 case 0x9406: { // LSR 1001 010d dddd 0110
953 uint8_t r = (opcode >> 4) & 0x1f;
954 uint8_t vr = avr->data[r];
955 uint8_t res = vr >> 1;
956 STATE("lsr %s[%02x]\n", avr_regname(r), vr);
957 _avr_set_r(avr, r, res);
958 avr->sreg[S_Z] = res == 0;
959 avr->sreg[S_C] = vr & 1;
961 avr->sreg[S_V] = avr->sreg[S_N] ^ avr->sreg[S_C];
962 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
965 case 0x9407: { // ROR 1001 010d dddd 0111
966 uint8_t r = (opcode >> 4) & 0x1f;
967 uint8_t vr = avr->data[r];
968 uint8_t res = (avr->sreg[S_C] ? 0x80 : 0) | vr >> 1;
969 STATE("ror %s[%02x]\n", avr_regname(r), vr);
970 _avr_set_r(avr, r, res);
971 avr->sreg[S_Z] = res == 0;
972 avr->sreg[S_C] = vr & 1;
974 avr->sreg[S_V] = avr->sreg[S_N] ^ avr->sreg[S_C];
975 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
978 case 0x940a: { // DEC – Decrement
979 uint8_t r = (opcode >> 4) & 0x1f;
980 uint8_t res = avr->data[r] - 1;
981 STATE("dec %s[%02x] = %02x\n", avr_regname(r), avr->data[r], res);
982 _avr_set_r(avr, r, res);
983 avr->sreg[S_Z] = res == 0;
984 avr->sreg[S_N] = res >> 7;
985 avr->sreg[S_V] = res == 0x80;
986 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
990 case 0x940d: { // JMP Long Call to sub, 32 bits
991 uint32_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1);
992 uint16_t x = (avr->flash[new_pc+1] << 8) | avr->flash[new_pc];
994 STATE("jmp 0x%06x\n", a);
1000 case 0x940f: { // CALL Long Call to sub, 32 bits
1001 uint32_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1);
1002 uint16_t x = (avr->flash[new_pc+1] << 8) | avr->flash[new_pc];
1004 STATE("call 0x%06x\n", a);
1006 _avr_push16(avr, new_pc >> 1);
1008 cycle += 3; // 4 cycles
1014 switch (opcode & 0xff00) {
1015 case 0x9600: { // ADIW - Add Immediate to Word 1001 0110 KKdd KKKK
1016 uint8_t r = 24 + ((opcode >> 3) & 0x6);
1017 uint8_t k = ((opcode & 0x00c0) >> 2) | (opcode & 0xf);
1018 uint8_t rdl = avr->data[r], rdh = avr->data[r+1];
1019 uint32_t res = rdl | (rdh << 8);
1020 STATE("adiw %s:%s[%04x], 0x%02x\n", avr_regname(r), avr_regname(r+1), res, k);
1022 _avr_set_r(avr, r + 1, res >> 8);
1023 _avr_set_r(avr, r, res);
1024 avr->sreg[S_V] = ~(rdh >> 7) & ((res >> 15) & 1);
1025 avr->sreg[S_Z] = (res & 0xffff) == 0;
1026 avr->sreg[S_N] = (res >> 15) & 1;
1027 avr->sreg[S_C] = ~((res >> 15) & 1) & (rdh >> 7);
1028 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
1032 case 0x9700: { // SBIW - Subtract Immediate from Word 1001 0110 KKdd KKKK
1033 uint8_t r = 24 + ((opcode >> 3) & 0x6);
1034 uint8_t k = ((opcode & 0x00c0) >> 2) | (opcode & 0xf);
1035 uint8_t rdl = avr->data[r], rdh = avr->data[r+1];
1036 uint32_t res = rdl | (rdh << 8);
1037 STATE("sbiw %s:%s[%04x], 0x%02x\n", avr_regname(r), avr_regname(r+1), res, k);
1039 _avr_set_r(avr, r + 1, res >> 8);
1040 _avr_set_r(avr, r, res);
1041 avr->sreg[S_V] = (rdh >> 7) & (~(res >> 15) & 1);
1042 avr->sreg[S_Z] = (res & 0xffff) == 0;
1043 avr->sreg[S_N] = (res >> 15) & 1;
1044 avr->sreg[S_C] = ((res >> 15) & 1) & (~rdh >> 7);
1045 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
1049 case 0x9800: { // CBI - Clear Bit in I/O Registe 1001 1000 AAAA Abbb
1050 uint8_t io = ((opcode >> 3) & 0x1f) + 32;
1051 uint8_t b = opcode & 0x7;
1052 uint8_t res = _avr_get_ram(avr, io) & ~(1 << b);
1053 STATE("cbi %s[%04x], 0x%02x = %02x\n", avr_regname(io), avr->data[io], 1<<b, res);
1054 _avr_set_ram(avr, io, res);
1057 case 0x9900: { // SBIC - Skip if Bit in I/O Register is Cleared 1001 0111 AAAA Abbb
1058 uint8_t io = ((opcode >> 3) & 0x1f) + 32;
1059 uint8_t b = opcode & 0x7;
1060 uint8_t res = _avr_get_ram(avr, io) & (1 << b);
1061 STATE("sbic %s[%04x], 0x%02x\t; Will%s branch\n", avr_regname(io), avr->data[io], 1<<b, !res?"":"not ");
1063 if (_avr_is_instruction_32_bits(avr, new_pc)) {
1064 new_pc += 4; cycle += 2;
1066 new_pc += 2; cycle++;
1070 case 0x9a00: { // SBI - Set Bit in I/O Register 1001 1000 AAAA Abbb
1071 uint8_t io = ((opcode >> 3) & 0x1f) + 32;
1072 uint8_t b = opcode & 0x7;
1073 uint8_t res = _avr_get_ram(avr, io) | (1 << b);
1074 STATE("sbi %s[%04x], 0x%02x = %02x\n", avr_regname(io), avr->data[io], 1<<b, res);
1075 _avr_set_ram(avr, io, res);
1078 case 0x9b00: { // SBIS - Skip if Bit in I/O Register is Cleared 1001 0111 AAAA Abbb
1079 uint8_t io = (opcode >> 3) & 0x1f;
1080 uint8_t b = opcode & 0x7;
1081 uint8_t res = _avr_get_ram(avr, io + 32) & (1 << b);
1082 STATE("sbis %s[%04x], 0x%02x\t; Will%s branch\n", avr_regname(io), avr->data[io], 1<<b, res?"":"not ");
1084 if (_avr_is_instruction_32_bits(avr, new_pc)) {
1085 new_pc += 4; cycle += 2;
1087 new_pc += 2; cycle++;
1092 switch (opcode & 0xfc00) {
1093 case 0x9c00: { // MUL - Multiply Unsigned 1001 11rd dddd rrrr
1095 uint16_t res = vd * vr;
1096 STATE("mul %s[%02x], %s[%02x] = %04x\n", avr_regname(d), vd, avr_regname(r), vr, res);
1097 _avr_set_r(avr, 0, res);
1098 _avr_set_r(avr, 1, res >> 8);
1099 avr->sreg[S_Z] = res == 0;
1100 avr->sreg[S_C] = (res >> 15) & 1;
1103 default: _avr_invalid_opcode(avr);
1113 switch (opcode & 0xf800) {
1114 case 0xb800: { // OUT A,Rr 1011 1AAr rrrr AAAA
1115 uint8_t r = (opcode >> 4) & 0x1f;
1116 uint8_t A = ((((opcode >> 9) & 3) << 4) | ((opcode) & 0xf)) + 32;
1117 STATE("out %s, %s[%02x]\n", avr_regname(A), avr_regname(r), avr->data[r]);
1118 // todo: store to IO register
1119 _avr_set_ram(avr, A, avr->data[r]);
1122 case 0xb000: { // IN Rd,A 1011 0AAr rrrr AAAA
1123 uint8_t r = (opcode >> 4) & 0x1f;
1124 uint8_t A = ((((opcode >> 9) & 3) << 4) | ((opcode) & 0xf)) + 32;
1125 STATE("in %s, %s[%02x]\n", avr_regname(r), avr_regname(A), avr->data[A]);
1126 // todo: get the IO register
1127 _avr_set_r(avr, r, _avr_get_ram(avr, A));
1129 default: _avr_invalid_opcode(avr);
1134 // RJMP 1100 kkkk kkkk kkkk
1135 short o = ((short)(opcode << 4)) >> 4;
1136 STATE("rjmp .%d [%04x]\n", o, new_pc + (o << 1));
1137 new_pc = new_pc + (o << 1);
1143 // RCALL 1100 kkkk kkkk kkkk
1144 short o = ((short)(opcode << 4)) >> 4;
1145 STATE("rcall .%d [%04x]\n", o, new_pc + (o << 1));
1146 _avr_push16(avr, new_pc >> 1);
1147 new_pc = new_pc + (o << 1);
1149 // 'rcall .1' is used as a cheap "push 16 bits of room on the stack"
1156 case 0xe000: { // LDI Rd, K 1110 KKKK RRRR KKKK -- aka SER (LDI r, 0xff)
1157 uint8_t d = 16 + ((opcode >> 4) & 0xf);
1158 uint8_t k = ((opcode & 0x0f00) >> 4) | (opcode & 0xf);
1159 STATE("ldi %s, 0x%02x\n", avr_regname(d), k);
1160 _avr_set_r(avr, d, k);
1164 switch (opcode & 0xfe00) {
1168 case 0xf600: { // All the SREG branches
1169 short o = ((short)(opcode << 6)) >> 9; // offset
1170 uint8_t s = opcode & 7;
1171 int set = (opcode & 0x0400) == 0; // this bit means BRXC otherwise BRXS
1172 int branch = (avr->sreg[s] && set) || (!avr->sreg[s] && !set);
1173 const char *names[2][8] = {
1174 { "brcc", "brne", "brpl", "brvc", NULL, "brhc", "brtc", "brid"},
1175 { "brcs", "breq", "brmi", "brvs", NULL, "brhs", "brts", "brie"},
1177 if (names[set][s]) {
1178 STATE("%s .%d [%04x]\t; Will%s branch\n", names[set][s], o, new_pc + (o << 1), branch ? "":" not");
1180 STATE("%s%c .%d [%04x]\t; Will%s branch\n", set ? "brbs" : "brbc", _sreg_bit_name[s], o, new_pc + (o << 1), branch ? "":" not");
1184 new_pc = new_pc + (o << 1);
1188 case 0xf900: { // BLD – Bit Store from T into a Bit in Register 1111 100r rrrr 0bbb
1189 uint8_t r = (opcode >> 4) & 0x1f; // register index
1190 uint8_t s = opcode & 7;
1191 uint8_t v = avr->data[r] | (avr->sreg[S_T] ? (1 << s) : 0);
1192 STATE("bld %s[%02x], 0x%02x = %02x\n", avr_regname(r), avr->data[r], 1 << s, v);
1193 _avr_set_r(avr, r, v);
1196 case 0xfb00:{ // BST – Bit Store into T from bit in Register 1111 100r rrrr 0bbb
1197 uint8_t r = (opcode >> 4) & 0x1f; // register index
1198 uint8_t s = opcode & 7;
1199 STATE("bst %s[%02x], 0x%02x\n", avr_regname(r), avr->data[r], 1 << s);
1200 avr->sreg[S_T] = (avr->data[r] >> s) & 1;
1204 case 0xfe00: { // SBRS/SBRC – Skip if Bit in Register is Set/Clear 1111 11sr rrrr 0bbb
1205 uint8_t r = (opcode >> 4) & 0x1f; // register index
1206 uint8_t s = opcode & 7;
1207 int set = (opcode & 0x0200) != 0;
1208 int branch = ((avr->data[r] & (1 << s)) && set) || (!(avr->data[r] & (1 << s)) && !set);
1209 STATE("%s %s[%02x], 0x%02x\t; Will%s branch\n", set ? "sbrs" : "sbrc", avr_regname(r), avr->data[r], 1 << s, branch ? "":" not");
1211 new_pc = new_pc + 2;
1213 default: _avr_invalid_opcode(avr);
1217 default: _avr_invalid_opcode(avr);
1220 avr->cycle += cycle;