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/>.
29 #include "avr_flash.h"
30 #include "avr_watchdog.h"
33 const char * _sreg_bit_name = "cznvshti";
39 #define FONT_RED "\e[31m"
40 #define FONT_DEFAULT "\e[0m"
44 * Handle "touching" registers, marking them changed.
45 * This is used only for debugging purposes to be able to
46 * print the effects of each instructions on registers
48 #if CONFIG_SIMAVR_TRACE
52 #define REG_TOUCH(a, r) (a)->trace_data->touched[(r) >> 5] |= (1 << ((r) & 0x1f))
53 #define REG_ISTOUCHED(a, r) ((a)->trace_data->touched[(r) >> 5] & (1 << ((r) & 0x1f)))
56 * This allows a "special case" to skip instruction tracing when in these
57 * symbols since printf() is useful to have, but generates a lot of cycles.
59 int dont_trace(const char * name)
62 !strcmp(name, "uart_putchar") ||
63 !strcmp(name, "fputc") ||
64 !strcmp(name, "printf") ||
65 !strcmp(name, "vfprintf") ||
66 !strcmp(name, "__ultoa_invert") ||
67 !strcmp(name, "__prologue_saves__") ||
68 !strcmp(name, "__epilogue_restores__"));
73 #define STATE(_f, args...) { \
75 if (avr->trace_data->codeline && avr->trace_data->codeline[avr->pc>>1]) {\
76 const char * symn = avr->trace_data->codeline[avr->pc>>1]->symbol; \
77 int dont = 0 && dont_trace(symn);\
78 if (dont!=donttrace) { \
83 printf("%04x: %-25s " _f, avr->pc, symn, ## args);\
85 printf("%s: %04x: " _f, __FUNCTION__, avr->pc, ## args);\
88 #define SREG() if (avr->trace && donttrace == 0) {\
89 printf("%04x: \t\t\t\t\t\t\t\t\tSREG = ", avr->pc); \
90 for (int _sbi = 0; _sbi < 8; _sbi++)\
91 printf("%c", avr->sreg[_sbi] ? toupper(_sreg_bit_name[_sbi]) : '.');\
96 #define REG_TOUCH(a, r)
97 #define STATE(_f, args...)
101 void avr_core_watch_write(avr_t *avr, uint16_t addr, uint8_t v)
103 if (addr > avr->ramend) {
104 AVR_LOG(avr, LOG_ERROR, "CORE: *** Invalid write address PC=%04x SP=%04x O=%04x Address %04x=%02x out of ram\n",
105 avr->pc, _avr_sp_get(avr), avr->flash[avr->pc + 1] | (avr->flash[avr->pc]<<8), addr, v);
109 AVR_LOG(avr, LOG_ERROR, "CORE: *** Invalid write address PC=%04x SP=%04x O=%04x Address %04x=%02x low registers\n",
110 avr->pc, _avr_sp_get(avr), avr->flash[avr->pc + 1] | (avr->flash[avr->pc]<<8), addr, v);
115 * this checks that the current "function" is not doctoring the stack frame that is located
116 * higher on the stack than it should be. It's a sign of code that has overrun it's stack
117 * frame and is munching on it's own return address.
119 if (avr->trace_data->stack_frame_index > 1 && addr > avr->trace_data->stack_frame[avr->trace_data->stack_frame_index-2].sp) {
120 printf( FONT_RED "%04x : munching stack SP %04x, A=%04x <= %02x\n" FONT_DEFAULT, avr->pc, _avr_sp_get(avr), addr, v);
125 avr_gdb_handle_watchpoints(avr, addr, AVR_GDB_WATCH_WRITE);
131 uint8_t avr_core_watch_read(avr_t *avr, uint16_t addr)
133 if (addr > avr->ramend) {
134 AVR_LOG(avr, LOG_ERROR, FONT_RED "CORE: *** Invalid read address PC=%04x SP=%04x O=%04x Address %04x out of ram (%04x)\n" FONT_DEFAULT,
135 avr->pc, _avr_sp_get(avr), avr->flash[avr->pc + 1] | (avr->flash[avr->pc]<<8), addr, avr->ramend);
140 avr_gdb_handle_watchpoints(avr, addr, AVR_GDB_WATCH_READ);
143 return avr->data[addr];
147 * Set a register (r < 256)
148 * if it's an IO register (> 31) also (try to) call any callback that was
149 * registered to track changes to that register.
151 static inline void _avr_set_r(avr_t * avr, uint8_t r, uint8_t v)
156 avr->data[R_SREG] = v;
158 SET_SREG_FROM(avr, v);
162 uint8_t io = AVR_DATA_TO_IO(r);
164 avr->io[io].w.c(avr, r, v, avr->io[io].w.param);
167 if (avr->io[io].irq) {
168 avr_raise_irq(avr->io[io].irq + AVR_IOMEM_IRQ_ALL, v);
169 for (int i = 0; i < 8; i++)
170 avr_raise_irq(avr->io[io].irq + i, (v >> i) & 1);
177 * Stack pointer access
179 inline uint16_t _avr_sp_get(avr_t * avr)
181 return avr->data[R_SPL] | (avr->data[R_SPH] << 8);
184 inline void _avr_sp_set(avr_t * avr, uint16_t sp)
186 _avr_set_r(avr, R_SPL, sp);
187 _avr_set_r(avr, R_SPH, sp >> 8);
191 * Set any address to a value; split between registers and SRAM
193 static inline void _avr_set_ram(avr_t * avr, uint16_t addr, uint8_t v)
196 _avr_set_r(avr, addr, v);
198 avr_core_watch_write(avr, addr, v);
202 * Get a value from SRAM.
204 static inline uint8_t _avr_get_ram(avr_t * avr, uint16_t addr)
206 if (addr == R_SREG) {
208 * SREG is special it's reconstructed when read
209 * while the core itself uses the "shortcut" array
211 READ_SREG_INTO(avr, avr->data[R_SREG]);
213 } else if (addr > 31 && addr < 256) {
214 uint8_t io = AVR_DATA_TO_IO(addr);
217 avr->data[addr] = avr->io[io].r.c(avr, addr, avr->io[io].r.param);
219 if (avr->io[io].irq) {
220 uint8_t v = avr->data[addr];
221 avr_raise_irq(avr->io[io].irq + AVR_IOMEM_IRQ_ALL, v);
222 for (int i = 0; i < 8; i++)
223 avr_raise_irq(avr->io[io].irq + i, (v >> i) & 1);
226 return avr_core_watch_read(avr, addr);
230 * Stack push accessors. Push/pop 8 and 16 bits
232 static inline void _avr_push8(avr_t * avr, uint16_t v)
234 uint16_t sp = _avr_sp_get(avr);
235 _avr_set_ram(avr, sp, v);
236 _avr_sp_set(avr, sp-1);
239 static inline uint8_t _avr_pop8(avr_t * avr)
241 uint16_t sp = _avr_sp_get(avr) + 1;
242 uint8_t res = _avr_get_ram(avr, sp);
243 _avr_sp_set(avr, sp);
247 inline void _avr_push16(avr_t * avr, uint16_t v)
250 _avr_push8(avr, v >> 8);
253 static inline uint16_t _avr_pop16(avr_t * avr)
255 uint16_t res = _avr_pop8(avr) << 8;
256 res |= _avr_pop8(avr);
261 * "Pretty" register names
263 const char * reg_names[255] = {
264 [R_XH] = "XH", [R_XL] = "XL",
265 [R_YH] = "YH", [R_YL] = "YL",
266 [R_ZH] = "ZH", [R_ZL] = "ZL",
267 [R_SPH] = "SPH", [R_SPL] = "SPL",
272 const char * avr_regname(uint8_t reg)
274 if (!reg_names[reg]) {
277 sprintf(tt, "r%d", reg);
279 sprintf(tt, "io:%02x", reg);
280 reg_names[reg] = strdup(tt);
282 return reg_names[reg];
286 * Called when an invalid opcode is decoded
288 static void _avr_invalid_opcode(avr_t * avr)
290 #if CONFIG_SIMAVR_TRACE
291 printf( FONT_RED "*** %04x: %-25s Invalid Opcode SP=%04x O=%04x \n" FONT_DEFAULT,
292 avr->pc, avr->trace_data->codeline[avr->pc>>1]->symbol, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc+1]<<8));
294 AVR_LOG(avr, LOG_ERROR, FONT_RED "CORE: *** %04x: Invalid Opcode SP=%04x O=%04x \n" FONT_DEFAULT,
295 avr->pc, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc+1]<<8));
299 #if CONFIG_SIMAVR_TRACE
301 * Dump changed registers when tracing
303 void avr_dump_state(avr_t * avr)
305 if (!avr->trace || donttrace)
310 for (int r = 0; r < 3 && !doit; r++)
311 if (avr->trace_data->touched[r])
316 const int r16[] = { R_SPL, R_XL, R_YL, R_ZL };
317 for (int i = 0; i < 4; i++)
318 if (REG_ISTOUCHED(avr, r16[i]) || REG_ISTOUCHED(avr, r16[i]+1)) {
319 REG_TOUCH(avr, r16[i]);
320 REG_TOUCH(avr, r16[i]+1);
323 for (int i = 0; i < 3*32; i++)
324 if (REG_ISTOUCHED(avr, i)) {
325 printf("%s=%02x ", avr_regname(i), avr->data[i]);
331 #define get_r_d_10(o) \
332 const uint8_t r = ((o >> 5) & 0x10) | (o & 0xf); \
333 const uint8_t d = (o >> 4) & 0x1f;\
334 const uint8_t vd = avr->data[d], vr = avr->data[r];
335 #define get_r_dd_10(o) \
336 const uint8_t r = ((o >> 5) & 0x10) | (o & 0xf); \
337 const uint8_t d = (o >> 4) & 0x1f;\
338 const uint8_t vr = avr->data[r];
339 #define get_k_r16(o) \
340 const uint8_t r = 16 + ((o >> 4) & 0xf); \
341 const uint8_t k = ((o & 0x0f00) >> 4) | (o & 0xf);
344 * Add a "jump" address to the jump trace buffer
346 #if CONFIG_SIMAVR_TRACE
347 #define TRACE_JUMP()\
348 avr->trace_data->old[avr->trace_data->old_pci].pc = avr->pc;\
349 avr->trace_data->old[avr->trace_data->old_pci].sp = _avr_sp_get(avr);\
350 avr->trace_data->old_pci = (avr->trace_data->old_pci + 1) & (OLD_PC_SIZE-1);\
353 #define STACK_FRAME_PUSH()\
354 avr->trace_data->stack_frame[avr->trace_data->stack_frame_index].pc = avr->pc;\
355 avr->trace_data->stack_frame[avr->trace_data->stack_frame_index].sp = _avr_sp_get(avr);\
356 avr->trace_data->stack_frame_index++;
357 #define STACK_FRAME_POP()\
358 if (avr->trace_data->stack_frame_index > 0) \
359 avr->trace_data->stack_frame_index--;
361 #define STACK_FRAME_PUSH()
362 #define STACK_FRAME_POP()
364 #else /* CONFIG_SIMAVR_TRACE */
367 #define STACK_FRAME_PUSH()
368 #define STACK_FRAME_POP()
372 /****************************************************************************\
374 * Helper functions for calculating the status register bit values.
375 * See the Atmel data sheet for the instruction set for more info.
377 \****************************************************************************/
380 get_add_carry (uint8_t res, uint8_t rd, uint8_t rr, int b)
382 uint8_t resb = res >> b & 0x1;
383 uint8_t rdb = rd >> b & 0x1;
384 uint8_t rrb = rr >> b & 0x1;
385 return (rdb & rrb) | (rrb & ~resb) | (~resb & rdb);
389 get_add_overflow (uint8_t res, uint8_t rd, uint8_t rr)
391 uint8_t res7 = res >> 7 & 0x1;
392 uint8_t rd7 = rd >> 7 & 0x1;
393 uint8_t rr7 = rr >> 7 & 0x1;
394 return (rd7 & rr7 & ~res7) | (~rd7 & ~rr7 & res7);
398 get_sub_carry (uint8_t res, uint8_t rd, uint8_t rr, int b)
400 uint8_t resb = res >> b & 0x1;
401 uint8_t rdb = rd >> b & 0x1;
402 uint8_t rrb = rr >> b & 0x1;
403 return (~rdb & rrb) | (rrb & resb) | (resb & ~rdb);
407 get_sub_overflow (uint8_t res, uint8_t rd, uint8_t rr)
409 uint8_t res7 = res >> 7 & 0x1;
410 uint8_t rd7 = rd >> 7 & 0x1;
411 uint8_t rr7 = rr >> 7 & 0x1;
412 return (rd7 & ~rr7 & ~res7) | (~rd7 & rr7 & res7);
416 get_compare_carry (uint8_t res, uint8_t rd, uint8_t rr, int b)
418 uint8_t resb = (res >> b) & 0x1;
419 uint8_t rdb = (rd >> b) & 0x1;
420 uint8_t rrb = (rr >> b) & 0x1;
421 return (~rdb & rrb) | (rrb & resb) | (resb & ~rdb);
425 get_compare_overflow (uint8_t res, uint8_t rd, uint8_t rr)
427 res >>= 7; rd >>= 7; rr >>= 7;
428 /* The atmel data sheet says the second term is ~rd7 for CP
429 * but that doesn't make any sense. You be the judge. */
430 return (rd & ~rr & ~res) | (~rd & rr & res);
433 static inline int _avr_is_instruction_32_bits(avr_t * avr, avr_flashaddr_t pc)
435 uint16_t o = (avr->flash[pc] | (avr->flash[pc+1] << 8)) & 0xfc0f;
436 return o == 0x9200 || // STS ! Store Direct to Data Space
437 o == 0x9000 || // LDS Load Direct from Data Space
438 o == 0x940c || // JMP Long Jump
439 o == 0x940d || // JMP Long Jump
440 o == 0x940e || // CALL Long Call to sub
441 o == 0x940f; // CALL Long Call to sub
445 * Main opcode decoder
447 * The decoder was written by following the datasheet in no particular order.
448 * As I went along, I noticed "bit patterns" that could be used to factor opcodes
449 * However, a lot of these only became apparent later on, so SOME instructions
450 * (skip of bit set etc) are compact, and some could use some refactoring (the ALU
451 * ones scream to be factored).
452 * I assume that the decoder could easily be 2/3 of it's current size.
454 * + It lacks the "extended" XMega jumps.
455 * + It also doesn't check whether the core it's
456 * emulating is supposed to have the fancy instructions, like multiply and such.
458 * The number of cycles taken by instruction has been added, but might not be
461 avr_flashaddr_t avr_run_one(avr_t * avr)
463 #if CONFIG_SIMAVR_TRACE
465 * this traces spurious reset or bad jumps
467 if ((avr->pc == 0 && avr->cycle > 0) || avr->pc >= avr->codeend) {
472 avr->trace_data->touched[0] = avr->trace_data->touched[1] = avr->trace_data->touched[2] = 0;
475 uint32_t opcode = (avr->flash[avr->pc + 1] << 8) | avr->flash[avr->pc];
476 avr_flashaddr_t new_pc = avr->pc + 2; // future "default" pc
479 switch (opcode & 0xf000) {
482 case 0x0000: { // NOP
486 switch (opcode & 0xfc00) {
487 case 0x0400: { // CPC compare with carry 0000 01rd dddd rrrr
489 uint8_t res = vd - vr - avr->sreg[S_C];
490 STATE("cpc %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
493 avr->sreg[S_H] = get_compare_carry(res, vd, vr, 3);
494 avr->sreg[S_V] = get_compare_overflow(res, vd, vr);
495 avr->sreg[S_N] = (res >> 7) & 1;
496 avr->sreg[S_C] = get_compare_carry(res, vd, vr, 7);
497 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
500 case 0x0c00: { // ADD without carry 0000 11 rd dddd rrrr
502 uint8_t res = vd + vr;
504 STATE("lsl %s[%02x] = %02x\n", avr_regname(d), vd, res & 0xff);
506 STATE("add %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
508 _avr_set_r(avr, d, res);
509 avr->sreg[S_Z] = res == 0;
510 avr->sreg[S_H] = get_add_carry(res, vd, vr, 3);
511 avr->sreg[S_V] = get_add_overflow(res, vd, vr);
512 avr->sreg[S_N] = (res >> 7) & 1;
513 avr->sreg[S_C] = get_add_carry(res, vd, vr, 7);
514 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
517 case 0x0800: { // SBC subtract with carry 0000 10rd dddd rrrr
519 uint8_t res = vd - vr - avr->sreg[S_C];
520 STATE("sbc %s[%02x], %s[%02x] = %02x\n", avr_regname(d), avr->data[d], avr_regname(r), avr->data[r], res);
521 _avr_set_r(avr, d, res);
524 avr->sreg[S_H] = get_sub_carry(res, vd, vr, 3);
525 avr->sreg[S_V] = get_sub_overflow(res, vd, vr);
526 avr->sreg[S_N] = (res >> 7) & 1;
527 avr->sreg[S_C] = get_sub_carry(res, vd, vr, 7);
528 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
532 switch (opcode & 0xff00) {
533 case 0x0100: { // MOVW – Copy Register Word 0000 0001 dddd rrrr
534 uint8_t d = ((opcode >> 4) & 0xf) << 1;
535 uint8_t r = ((opcode) & 0xf) << 1;
536 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]);
537 _avr_set_r(avr, d, avr->data[r]);
538 _avr_set_r(avr, d+1, avr->data[r+1]);
540 case 0x0200: { // MULS – Multiply Signed 0000 0010 dddd rrrr
541 int8_t r = 16 + (opcode & 0xf);
542 int8_t d = 16 + ((opcode >> 4) & 0xf);
543 int16_t res = ((int8_t)avr->data[r]) * ((int8_t)avr->data[d]);
544 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);
545 _avr_set_r(avr, 0, res);
546 _avr_set_r(avr, 1, res >> 8);
547 avr->sreg[S_C] = (res >> 15) & 1;
548 avr->sreg[S_Z] = res == 0;
551 case 0x0300: { // MUL Multiply 0000 0011 fddd frrr
552 int8_t r = 16 + (opcode & 0x7);
553 int8_t d = 16 + ((opcode >> 4) & 0x7);
556 T(const char * name = "";)
557 switch (opcode & 0x88) {
558 case 0x00: // MULSU – Multiply Signed Unsigned 0000 0011 0ddd 0rrr
559 res = ((uint8_t)avr->data[r]) * ((int8_t)avr->data[d]);
563 case 0x08: // FMUL Fractional Multiply Unsigned 0000 0011 0ddd 1rrr
564 res = ((uint8_t)avr->data[r]) * ((uint8_t)avr->data[d]);
569 case 0x80: // FMULS – Multiply Signed 0000 0011 1ddd 0rrr
570 res = ((int8_t)avr->data[r]) * ((int8_t)avr->data[d]);
575 case 0x88: // FMULSU – Multiply Signed Unsigned 0000 0011 1ddd 1rrr
576 res = ((uint8_t)avr->data[r]) * ((int8_t)avr->data[d]);
583 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);
584 _avr_set_r(avr, 0, res);
585 _avr_set_r(avr, 1, res >> 8);
587 avr->sreg[S_Z] = res == 0;
590 default: _avr_invalid_opcode(avr);
598 switch (opcode & 0xfc00) {
599 case 0x1800: { // SUB without carry 0000 10 rd dddd rrrr
601 uint8_t res = vd - vr;
602 STATE("sub %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
603 _avr_set_r(avr, d, res);
604 avr->sreg[S_Z] = res == 0;
605 avr->sreg[S_H] = get_sub_carry(res, vd, vr, 3);
606 avr->sreg[S_V] = get_sub_overflow(res, vd, vr);
607 avr->sreg[S_N] = (res >> 7) & 1;
608 avr->sreg[S_C] = get_sub_carry(res, vd, vr, 7);
609 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
612 case 0x1000: { // CPSE Compare, skip if equal 0000 00 rd dddd rrrr
614 uint16_t res = vd == vr;
615 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");
617 if (_avr_is_instruction_32_bits(avr, new_pc)) {
618 new_pc += 4; cycle += 2;
620 new_pc += 2; cycle++;
624 case 0x1400: { // CP Compare 0000 01 rd dddd rrrr
626 uint8_t res = vd - vr;
627 STATE("cp %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
628 avr->sreg[S_Z] = res == 0;
629 avr->sreg[S_H] = get_compare_carry(res, vd, vr, 3);
630 avr->sreg[S_V] = get_compare_overflow(res, vd, vr);
631 avr->sreg[S_N] = res >> 7;
632 avr->sreg[S_C] = get_compare_carry(res, vd, vr, 7);
633 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
636 case 0x1c00: { // ADD with carry 0001 11 rd dddd rrrr
638 uint8_t res = vd + vr + avr->sreg[S_C];
640 STATE("rol %s[%02x] = %02x\n", avr_regname(d), avr->data[d], res);
642 STATE("addc %s[%02x], %s[%02x] = %02x\n", avr_regname(d), avr->data[d], avr_regname(r), avr->data[r], res);
644 _avr_set_r(avr, d, res);
645 avr->sreg[S_Z] = res == 0;
646 avr->sreg[S_H] = get_add_carry(res, vd, vr, 3);
647 avr->sreg[S_V] = get_add_overflow(res, vd, vr);
648 avr->sreg[S_N] = (res >> 7) & 1;
649 avr->sreg[S_C] = get_add_carry(res, vd, vr, 7);
650 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
653 default: _avr_invalid_opcode(avr);
658 switch (opcode & 0xfc00) {
659 case 0x2000: { // AND 0010 00rd dddd rrrr
661 uint8_t res = vd & vr;
663 STATE("tst %s[%02x]\n", avr_regname(d), avr->data[d]);
665 STATE("and %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
667 _avr_set_r(avr, d, res);
668 avr->sreg[S_Z] = res == 0;
669 avr->sreg[S_N] = (res >> 7) & 1;
671 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
674 case 0x2400: { // EOR 0010 01rd dddd rrrr
676 uint8_t res = vd ^ vr;
678 STATE("clr %s[%02x]\n", avr_regname(d), avr->data[d]);
680 STATE("eor %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
682 _avr_set_r(avr, d, res);
683 avr->sreg[S_Z] = res == 0;
684 avr->sreg[S_N] = (res >> 7) & 1;
686 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
689 case 0x2800: { // OR Logical OR 0010 10rd dddd rrrr
691 uint8_t res = vd | vr;
692 STATE("or %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
693 _avr_set_r(avr, d, res);
694 avr->sreg[S_Z] = res == 0;
695 avr->sreg[S_N] = (res >> 7) & 1;
697 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
700 case 0x2c00: { // MOV 0010 11rd dddd rrrr
703 STATE("mov %s, %s[%02x] = %02x\n", avr_regname(d), avr_regname(r), vr, res);
704 _avr_set_r(avr, d, res);
706 default: _avr_invalid_opcode(avr);
710 case 0x3000: { // CPI 0011 KKKK rrrr KKKK
712 uint8_t vr = avr->data[r];
713 uint8_t res = vr - k;
714 STATE("cpi %s[%02x], 0x%02x\n", avr_regname(r), vr, k);
716 avr->sreg[S_Z] = res == 0;
717 avr->sreg[S_H] = get_compare_carry(res, vr, k, 3);
718 avr->sreg[S_V] = get_compare_overflow(res, vr, k);
719 avr->sreg[S_N] = (res >> 7) & 1;
720 avr->sreg[S_C] = get_compare_carry(res, vr, k, 7);
721 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
725 case 0x4000: { // SBCI Subtract Immediate With Carry 0101 10 kkkk dddd kkkk
727 uint8_t vr = avr->data[r];
728 uint8_t res = vr - k - avr->sreg[S_C];
729 STATE("sbci %s[%02x], 0x%02x = %02x\n", avr_regname(r), avr->data[r], k, res);
730 _avr_set_r(avr, r, res);
733 avr->sreg[S_N] = (res >> 7) & 1;
734 avr->sreg[S_C] = (k + avr->sreg[S_C]) > vr;
735 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
739 case 0x5000: { // SUB Subtract Immediate 0101 10 kkkk dddd kkkk
741 uint8_t vr = avr->data[r];
742 uint8_t res = vr - k;
743 STATE("subi %s[%02x], 0x%02x = %02x\n", avr_regname(r), avr->data[r], k, res);
744 _avr_set_r(avr, r, res);
745 avr->sreg[S_Z] = res == 0;
746 avr->sreg[S_N] = (res >> 7) & 1;
747 avr->sreg[S_C] = k > vr;
748 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
752 case 0x6000: { // ORI aka SBR Logical AND with Immediate 0110 kkkk dddd kkkk
754 uint8_t res = avr->data[r] | k;
755 STATE("ori %s[%02x], 0x%02x\n", avr_regname(r), avr->data[r], k);
756 _avr_set_r(avr, r, res);
757 avr->sreg[S_Z] = res == 0;
758 avr->sreg[S_N] = (res >> 7) & 1;
760 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
764 case 0x7000: { // ANDI Logical AND with Immediate 0111 kkkk dddd kkkk
766 uint8_t res = avr->data[r] & k;
767 STATE("andi %s[%02x], 0x%02x\n", avr_regname(r), avr->data[r], k);
768 _avr_set_r(avr, r, res);
769 avr->sreg[S_Z] = res == 0;
770 avr->sreg[S_N] = (res >> 7) & 1;
772 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
778 switch (opcode & 0xd008) {
780 case 0x8000: { // LD (LDD) – Load Indirect using Z 10q0 qq0r rrrr 0qqq
781 uint16_t v = avr->data[R_ZL] | (avr->data[R_ZH] << 8);
782 uint8_t r = (opcode >> 4) & 0x1f;
783 uint8_t q = ((opcode & 0x2000) >> 8) | ((opcode & 0x0c00) >> 7) | (opcode & 0x7);
785 if (opcode & 0x0200) {
786 STATE("st (Z+%d[%04x]), %s[%02x]\n", q, v+q, avr_regname(r), avr->data[r]);
787 _avr_set_ram(avr, v+q, avr->data[r]);
789 STATE("ld %s, (Z+%d[%04x])=[%02x]\n", avr_regname(r), q, v+q, avr->data[v+q]);
790 _avr_set_r(avr, r, _avr_get_ram(avr, v+q));
792 cycle += 1; // 2 cycles, 3 for tinyavr
795 case 0x8008: { // LD (LDD) – Load Indirect using Y 10q0 qq0r rrrr 1qqq
796 uint16_t v = avr->data[R_YL] | (avr->data[R_YH] << 8);
797 uint8_t r = (opcode >> 4) & 0x1f;
798 uint8_t q = ((opcode & 0x2000) >> 8) | ((opcode & 0x0c00) >> 7) | (opcode & 0x7);
800 if (opcode & 0x0200) {
801 STATE("st (Y+%d[%04x]), %s[%02x]\n", q, v+q, avr_regname(r), avr->data[r]);
802 _avr_set_ram(avr, v+q, avr->data[r]);
804 STATE("ld %s, (Y+%d[%04x])=[%02x]\n", avr_regname(r), q, v+q, avr->data[v+q]);
805 _avr_set_r(avr, r, _avr_get_ram(avr, v+q));
807 cycle += 1; // 2 cycles, 3 for tinyavr
809 default: _avr_invalid_opcode(avr);
814 /* this is an annoying special case, but at least these lines handle all the SREG set/clear opcodes */
815 if ((opcode & 0xff0f) == 0x9408) {
816 uint8_t b = (opcode >> 4) & 7;
817 STATE("%s%c\n", opcode & 0x0080 ? "cl" : "se", _sreg_bit_name[b]);
818 avr->sreg[b] = (opcode & 0x0080) == 0;
820 } else switch (opcode) {
821 case 0x9588: { // SLEEP
823 /* Don't sleep if there are interrupts about to be serviced.
824 * Without this check, it was possible to incorrectly enter a state
825 * in which the cpu was sleeping and interrupts were disabled. For more
826 * details, see the commit message. */
827 if (!avr_has_pending_interrupts(avr) || !avr->sreg[S_I])
828 avr->state = cpu_Sleeping;
830 case 0x9598: { // BREAK
833 // if gdb is on, we break here as in here
834 // and we do so until gdb restores the instruction
835 // that was here before
836 avr->state = cpu_StepDone;
841 case 0x95a8: { // WDR
843 avr_ioctl(avr, AVR_IOCTL_WATCHDOG_RESET, 0);
845 case 0x95e8: { // SPM
847 avr_ioctl(avr, AVR_IOCTL_FLASH_SPM, 0);
849 case 0x9409: // IJMP Indirect jump 1001 0100 0000 1001
850 case 0x9419: // EIJMP Indirect jump 1001 0100 0001 1001 bit 4 is "indirect"
851 case 0x9509: // ICALL Indirect Call to Subroutine 1001 0101 0000 1001
852 case 0x9519: { // EICALL Indirect Call to Subroutine 1001 0101 0001 1001 bit 8 is "push pc"
853 int e = opcode & 0x10;
854 int p = opcode & 0x100;
856 _avr_invalid_opcode(avr);
857 uint16_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8);
859 z |= avr->data[avr->eind] << 16;
860 STATE("%si%s Z[%04x]\n", e?"e":"", p?"call":"jmp", z << 1);
863 _avr_push16(avr, new_pc >> 1);
870 case 0x9508: { // RET
871 new_pc = _avr_pop16(avr) << 1;
872 if (opcode & 0x10) // reti
875 STATE("ret%s\n", opcode & 0x10 ? "i" : "");
879 case 0x95c8: { // LPM Load Program Memory R0 <- (Z)
880 uint16_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8);
881 STATE("lpm %s, (Z[%04x])\n", avr_regname(0), z);
882 cycle += 2; // 3 cycles
883 _avr_set_r(avr, 0, avr->flash[z]);
885 case 0x9408:case 0x9418:case 0x9428:case 0x9438:case 0x9448:case 0x9458:case 0x9468:
887 { // BSET 1001 0100 0ddd 1000
888 uint8_t b = (opcode >> 4) & 7;
890 STATE("bset %c\n", _sreg_bit_name[b]);
893 case 0x9488:case 0x9498:case 0x94a8:case 0x94b8:case 0x94c8:case 0x94d8:case 0x94e8:
894 case 0x94f8: // bit 7 is 'clear vs set'
895 { // BCLR 1001 0100 1ddd 1000
896 uint8_t b = (opcode >> 4) & 7;
898 STATE("bclr %c\n", _sreg_bit_name[b]);
902 switch (opcode & 0xfe0f) {
903 case 0x9000: { // LDS Load Direct from Data Space, 32 bits
904 uint8_t r = (opcode >> 4) & 0x1f;
905 uint16_t x = (avr->flash[new_pc+1] << 8) | avr->flash[new_pc];
907 STATE("lds %s[%02x], 0x%04x\n", avr_regname(r), avr->data[r], x);
908 _avr_set_r(avr, r, _avr_get_ram(avr, x));
912 case 0x9004: { // LPM Load Program Memory 1001 000d dddd 01oo
913 uint16_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8);
914 uint8_t r = (opcode >> 4) & 0x1f;
916 STATE("lpm %s, (Z[%04x]%s)\n", avr_regname(r), z, opcode?"+":"");
917 _avr_set_r(avr, r, avr->flash[z]);
920 _avr_set_r(avr, R_ZH, z >> 8);
921 _avr_set_r(avr, R_ZL, z);
923 cycle += 2; // 3 cycles
926 case 0x9007: { // ELPM Extended Load Program Memory 1001 000d dddd 01oo
928 _avr_invalid_opcode(avr);
929 uint16_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8) | (avr->data[avr->rampz] << 16);
930 uint8_t r = (opcode >> 4) & 0x1f;
932 STATE("elpm %s, (Z[%02x:%04x]%s)\n", avr_regname(r), z >> 16, z&0xffff, opcode?"+":"");
933 _avr_set_r(avr, r, avr->flash[z]);
936 _avr_set_r(avr, avr->rampz, z >> 16);
937 _avr_set_r(avr, R_ZH, z >> 8);
938 _avr_set_r(avr, R_ZL, z);
940 cycle += 2; // 3 cycles
943 * Load store instructions
945 * 1001 00sr rrrr iioo
946 * s = 0 = load, 1 = store
947 * ii = 16 bits register index, 11 = Z, 10 = Y, 00 = X
948 * oo = 1) post increment, 2) pre-decrement
952 case 0x900e: { // LD Load Indirect from Data using X 1001 000r rrrr 11oo
954 uint8_t r = (opcode >> 4) & 0x1f;
955 uint16_t x = (avr->data[R_XH] << 8) | avr->data[R_XL];
956 STATE("ld %s, %sX[%04x]%s\n", avr_regname(r), op == 2 ? "--" : "", x, op == 1 ? "++" : "");
957 cycle++; // 2 cycles (1 for tinyavr, except with inc/dec 2)
959 _avr_set_r(avr, r, _avr_get_ram(avr, x));
961 _avr_set_r(avr, R_XH, x >> 8);
962 _avr_set_r(avr, R_XL, x);
966 case 0x920e: { // ST Store Indirect Data Space X 1001 001r rrrr 11oo
968 uint8_t r = (opcode >> 4) & 0x1f;
969 uint16_t x = (avr->data[R_XH] << 8) | avr->data[R_XL];
970 STATE("st %sX[%04x]%s, %s[%02x] \n", op == 2 ? "--" : "", x, op == 1 ? "++" : "", avr_regname(r), avr->data[r]);
971 cycle++; // 2 cycles, except tinyavr
973 _avr_set_ram(avr, x, avr->data[r]);
975 _avr_set_r(avr, R_XH, x >> 8);
976 _avr_set_r(avr, R_XL, x);
979 case 0x900a: { // LD Load Indirect from Data using Y 1001 000r rrrr 10oo
981 uint8_t r = (opcode >> 4) & 0x1f;
982 uint16_t y = (avr->data[R_YH] << 8) | avr->data[R_YL];
983 STATE("ld %s, %sY[%04x]%s\n", avr_regname(r), op == 2 ? "--" : "", y, op == 1 ? "++" : "");
984 cycle++; // 2 cycles, except tinyavr
986 _avr_set_r(avr, r, _avr_get_ram(avr, y));
988 _avr_set_r(avr, R_YH, y >> 8);
989 _avr_set_r(avr, R_YL, y);
992 case 0x920a: { // ST Store Indirect Data Space Y 1001 001r rrrr 10oo
994 uint8_t r = (opcode >> 4) & 0x1f;
995 uint16_t y = (avr->data[R_YH] << 8) | avr->data[R_YL];
996 STATE("st %sY[%04x]%s, %s[%02x]\n", op == 2 ? "--" : "", y, op == 1 ? "++" : "", avr_regname(r), avr->data[r]);
999 _avr_set_ram(avr, y, avr->data[r]);
1001 _avr_set_r(avr, R_YH, y >> 8);
1002 _avr_set_r(avr, R_YL, y);
1004 case 0x9200: { // STS ! Store Direct to Data Space, 32 bits
1005 uint8_t r = (opcode >> 4) & 0x1f;
1006 uint16_t x = (avr->flash[new_pc+1] << 8) | avr->flash[new_pc];
1008 STATE("sts 0x%04x, %s[%02x]\n", x, avr_regname(r), avr->data[r]);
1010 _avr_set_ram(avr, x, avr->data[r]);
1013 case 0x9002: { // LD Load Indirect from Data using Z 1001 001r rrrr 00oo
1014 int op = opcode & 3;
1015 uint8_t r = (opcode >> 4) & 0x1f;
1016 uint16_t z = (avr->data[R_ZH] << 8) | avr->data[R_ZL];
1017 STATE("ld %s, %sZ[%04x]%s\n", avr_regname(r), op == 2 ? "--" : "", z, op == 1 ? "++" : "");
1018 cycle++;; // 2 cycles, except tinyavr
1020 _avr_set_r(avr, r, _avr_get_ram(avr, z));
1022 _avr_set_r(avr, R_ZH, z >> 8);
1023 _avr_set_r(avr, R_ZL, z);
1026 case 0x9202: { // ST Store Indirect Data Space Z 1001 001r rrrr 00oo
1027 int op = opcode & 3;
1028 uint8_t r = (opcode >> 4) & 0x1f;
1029 uint16_t z = (avr->data[R_ZH] << 8) | avr->data[R_ZL];
1030 STATE("st %sZ[%04x]%s, %s[%02x] \n", op == 2 ? "--" : "", z, op == 1 ? "++" : "", avr_regname(r), avr->data[r]);
1031 cycle++; // 2 cycles, except tinyavr
1033 _avr_set_ram(avr, z, avr->data[r]);
1035 _avr_set_r(avr, R_ZH, z >> 8);
1036 _avr_set_r(avr, R_ZL, z);
1038 case 0x900f: { // POP 1001 000d dddd 1111
1039 uint8_t r = (opcode >> 4) & 0x1f;
1040 _avr_set_r(avr, r, _avr_pop8(avr));
1041 T(uint16_t sp = _avr_sp_get(avr);)
1042 STATE("pop %s (@%04x)[%02x]\n", avr_regname(r), sp, avr->data[sp]);
1045 case 0x920f: { // PUSH 1001 001d dddd 1111
1046 uint8_t r = (opcode >> 4) & 0x1f;
1047 _avr_push8(avr, avr->data[r]);
1048 T(uint16_t sp = _avr_sp_get(avr);)
1049 STATE("push %s[%02x] (@%04x)\n", avr_regname(r), avr->data[r], sp);
1052 case 0x9400: { // COM – One’s Complement
1053 uint8_t r = (opcode >> 4) & 0x1f;
1054 uint8_t res = 0xff - avr->data[r];
1055 STATE("com %s[%02x] = %02x\n", avr_regname(r), avr->data[r], res);
1056 _avr_set_r(avr, r, res);
1057 avr->sreg[S_Z] = res == 0;
1058 avr->sreg[S_N] = res >> 7;
1061 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
1064 case 0x9401: { // NEG – Two’s Complement
1065 uint8_t r = (opcode >> 4) & 0x1f;
1066 uint8_t rd = avr->data[r];
1067 uint8_t res = 0x00 - rd;
1068 STATE("neg %s[%02x] = %02x\n", avr_regname(r), rd, res);
1069 _avr_set_r(avr, r, res);
1070 avr->sreg[S_H] = ((res >> 3) | (rd >> 3)) & 1;
1071 avr->sreg[S_Z] = res == 0;
1072 avr->sreg[S_N] = res >> 7;
1073 avr->sreg[S_V] = res == 0x80;
1074 avr->sreg[S_C] = res != 0;
1075 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
1078 case 0x9402: { // SWAP – Swap Nibbles
1079 uint8_t r = (opcode >> 4) & 0x1f;
1080 uint8_t res = (avr->data[r] >> 4) | (avr->data[r] << 4) ;
1081 STATE("swap %s[%02x] = %02x\n", avr_regname(r), avr->data[r], res);
1082 _avr_set_r(avr, r, res);
1084 case 0x9403: { // INC – Increment
1085 uint8_t r = (opcode >> 4) & 0x1f;
1086 uint8_t res = avr->data[r] + 1;
1087 STATE("inc %s[%02x] = %02x\n", avr_regname(r), avr->data[r], res);
1088 _avr_set_r(avr, r, res);
1089 avr->sreg[S_Z] = res == 0;
1090 avr->sreg[S_N] = res >> 7;
1091 avr->sreg[S_V] = res == 0x7f;
1092 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
1095 case 0x9405: { // ASR – Arithmetic Shift Right 1001 010d dddd 0101
1096 uint8_t r = (opcode >> 4) & 0x1f;
1097 uint8_t vr = avr->data[r];
1098 uint8_t res = (vr >> 1) | (vr & 0x80);
1099 STATE("asr %s[%02x]\n", avr_regname(r), vr);
1100 _avr_set_r(avr, r, res);
1101 avr->sreg[S_Z] = res == 0;
1102 avr->sreg[S_C] = vr & 1;
1103 avr->sreg[S_N] = res >> 7;
1104 avr->sreg[S_V] = avr->sreg[S_N] ^ avr->sreg[S_C];
1105 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
1108 case 0x9406: { // LSR 1001 010d dddd 0110
1109 uint8_t r = (opcode >> 4) & 0x1f;
1110 uint8_t vr = avr->data[r];
1111 uint8_t res = vr >> 1;
1112 STATE("lsr %s[%02x]\n", avr_regname(r), vr);
1113 _avr_set_r(avr, r, res);
1114 avr->sreg[S_Z] = res == 0;
1115 avr->sreg[S_C] = vr & 1;
1117 avr->sreg[S_V] = avr->sreg[S_N] ^ avr->sreg[S_C];
1118 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
1121 case 0x9407: { // ROR 1001 010d dddd 0111
1122 uint8_t r = (opcode >> 4) & 0x1f;
1123 uint8_t vr = avr->data[r];
1124 uint8_t res = (avr->sreg[S_C] ? 0x80 : 0) | vr >> 1;
1125 STATE("ror %s[%02x]\n", avr_regname(r), vr);
1126 _avr_set_r(avr, r, res);
1127 avr->sreg[S_Z] = res == 0;
1128 avr->sreg[S_C] = vr & 1;
1130 avr->sreg[S_V] = avr->sreg[S_N] ^ avr->sreg[S_C];
1131 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
1134 case 0x940a: { // DEC – Decrement
1135 uint8_t r = (opcode >> 4) & 0x1f;
1136 uint8_t res = avr->data[r] - 1;
1137 STATE("dec %s[%02x] = %02x\n", avr_regname(r), avr->data[r], res);
1138 _avr_set_r(avr, r, res);
1139 avr->sreg[S_Z] = res == 0;
1140 avr->sreg[S_N] = res >> 7;
1141 avr->sreg[S_V] = res == 0x80;
1142 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
1146 case 0x940d: { // JMP Long Call to sub, 32 bits
1147 avr_flashaddr_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1);
1148 uint16_t x = (avr->flash[new_pc+1] << 8) | avr->flash[new_pc];
1150 STATE("jmp 0x%06x\n", a);
1156 case 0x940f: { // CALL Long Call to sub, 32 bits
1157 avr_flashaddr_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1);
1158 uint16_t x = (avr->flash[new_pc+1] << 8) | avr->flash[new_pc];
1160 STATE("call 0x%06x\n", a);
1162 _avr_push16(avr, new_pc >> 1);
1164 cycle += 3; // 4 cycles; FIXME 5 on devices with 22 bit PC
1170 switch (opcode & 0xff00) {
1171 case 0x9600: { // ADIW - Add Immediate to Word 1001 0110 KKdd KKKK
1172 uint8_t r = 24 + ((opcode >> 3) & 0x6);
1173 uint8_t k = ((opcode & 0x00c0) >> 2) | (opcode & 0xf);
1174 uint8_t rdl = avr->data[r], rdh = avr->data[r+1];
1175 uint32_t res = rdl | (rdh << 8);
1176 STATE("adiw %s:%s[%04x], 0x%02x\n", avr_regname(r), avr_regname(r+1), res, k);
1178 _avr_set_r(avr, r + 1, res >> 8);
1179 _avr_set_r(avr, r, res);
1180 avr->sreg[S_V] = ~(rdh >> 7) & ((res >> 15) & 1);
1181 avr->sreg[S_Z] = (res & 0xffff) == 0;
1182 avr->sreg[S_N] = (res >> 15) & 1;
1183 avr->sreg[S_C] = ~((res >> 15) & 1) & (rdh >> 7);
1184 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
1188 case 0x9700: { // SBIW - Subtract Immediate from Word 1001 0110 KKdd KKKK
1189 uint8_t r = 24 + ((opcode >> 3) & 0x6);
1190 uint8_t k = ((opcode & 0x00c0) >> 2) | (opcode & 0xf);
1191 uint8_t rdl = avr->data[r], rdh = avr->data[r+1];
1192 uint32_t res = rdl | (rdh << 8);
1193 STATE("sbiw %s:%s[%04x], 0x%02x\n", avr_regname(r), avr_regname(r+1), res, k);
1195 _avr_set_r(avr, r + 1, res >> 8);
1196 _avr_set_r(avr, r, res);
1197 avr->sreg[S_V] = (rdh >> 7) & (~(res >> 15) & 1);
1198 avr->sreg[S_Z] = (res & 0xffff) == 0;
1199 avr->sreg[S_N] = (res >> 15) & 1;
1200 avr->sreg[S_C] = ((res >> 15) & 1) & (~rdh >> 7);
1201 avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
1205 case 0x9800: { // CBI - Clear Bit in I/O Register 1001 1000 AAAA Abbb
1206 uint8_t io = ((opcode >> 3) & 0x1f) + 32;
1207 uint8_t b = opcode & 0x7;
1208 uint8_t res = _avr_get_ram(avr, io) & ~(1 << b);
1209 STATE("cbi %s[%04x], 0x%02x = %02x\n", avr_regname(io), avr->data[io], 1<<b, res);
1210 _avr_set_ram(avr, io, res);
1213 case 0x9900: { // SBIC - Skip if Bit in I/O Register is Cleared 1001 0111 AAAA Abbb
1214 uint8_t io = ((opcode >> 3) & 0x1f) + 32;
1215 uint8_t b = opcode & 0x7;
1216 uint8_t res = _avr_get_ram(avr, io) & (1 << b);
1217 STATE("sbic %s[%04x], 0x%02x\t; Will%s branch\n", avr_regname(io), avr->data[io], 1<<b, !res?"":" not");
1219 if (_avr_is_instruction_32_bits(avr, new_pc)) {
1220 new_pc += 4; cycle += 2;
1222 new_pc += 2; cycle++;
1226 case 0x9a00: { // SBI - Set Bit in I/O Register 1001 1000 AAAA Abbb
1227 uint8_t io = ((opcode >> 3) & 0x1f) + 32;
1228 uint8_t b = opcode & 0x7;
1229 uint8_t res = _avr_get_ram(avr, io) | (1 << b);
1230 STATE("sbi %s[%04x], 0x%02x = %02x\n", avr_regname(io), avr->data[io], 1<<b, res);
1231 _avr_set_ram(avr, io, res);
1234 case 0x9b00: { // SBIS - Skip if Bit in I/O Register is Set 1001 1011 AAAA Abbb
1235 uint8_t io = ((opcode >> 3) & 0x1f) + 32;
1236 uint8_t b = opcode & 0x7;
1237 uint8_t res = _avr_get_ram(avr, io) & (1 << b);
1238 STATE("sbis %s[%04x], 0x%02x\t; Will%s branch\n", avr_regname(io), avr->data[io], 1<<b, res?"":" not");
1240 if (_avr_is_instruction_32_bits(avr, new_pc)) {
1241 new_pc += 4; cycle += 2;
1243 new_pc += 2; cycle++;
1248 switch (opcode & 0xfc00) {
1249 case 0x9c00: { // MUL - Multiply Unsigned 1001 11rd dddd rrrr
1251 uint16_t res = vd * vr;
1252 STATE("mul %s[%02x], %s[%02x] = %04x\n", avr_regname(d), vd, avr_regname(r), vr, res);
1254 _avr_set_r(avr, 0, res);
1255 _avr_set_r(avr, 1, res >> 8);
1256 avr->sreg[S_Z] = res == 0;
1257 avr->sreg[S_C] = (res >> 15) & 1;
1260 default: _avr_invalid_opcode(avr);
1270 switch (opcode & 0xf800) {
1271 case 0xb800: { // OUT A,Rr 1011 1AAr rrrr AAAA
1272 uint8_t r = (opcode >> 4) & 0x1f;
1273 uint8_t A = ((((opcode >> 9) & 3) << 4) | ((opcode) & 0xf)) + 32;
1274 STATE("out %s, %s[%02x]\n", avr_regname(A), avr_regname(r), avr->data[r]);
1275 _avr_set_ram(avr, A, avr->data[r]);
1277 case 0xb000: { // IN Rd,A 1011 0AAr rrrr AAAA
1278 uint8_t r = (opcode >> 4) & 0x1f;
1279 uint8_t A = ((((opcode >> 9) & 3) << 4) | ((opcode) & 0xf)) + 32;
1280 STATE("in %s, %s[%02x]\n", avr_regname(r), avr_regname(A), avr->data[A]);
1281 _avr_set_r(avr, r, _avr_get_ram(avr, A));
1283 default: _avr_invalid_opcode(avr);
1288 // RJMP 1100 kkkk kkkk kkkk
1289 // int16_t o = ((int16_t)(opcode << 4)) >> 4; // CLANG BUG!
1290 int16_t o = ((int16_t)((opcode << 4)&0xffff)) >> 4;
1291 STATE("rjmp .%d [%04x]\n", o, new_pc + (o << 1));
1292 new_pc = new_pc + (o << 1);
1298 // RCALL 1100 kkkk kkkk kkkk
1299 // int16_t o = ((int16_t)(opcode << 4)) >> 4; // CLANG BUG!
1300 int16_t o = ((int16_t)((opcode << 4)&0xffff)) >> 4;
1301 STATE("rcall .%d [%04x]\n", o, new_pc + (o << 1));
1302 _avr_push16(avr, new_pc >> 1);
1303 new_pc = new_pc + (o << 1);
1305 // 'rcall .1' is used as a cheap "push 16 bits of room on the stack"
1312 case 0xe000: { // LDI Rd, K 1110 KKKK RRRR KKKK -- aka SER (LDI r, 0xff)
1313 uint8_t d = 16 + ((opcode >> 4) & 0xf);
1314 uint8_t k = ((opcode & 0x0f00) >> 4) | (opcode & 0xf);
1315 STATE("ldi %s, 0x%02x\n", avr_regname(d), k);
1316 _avr_set_r(avr, d, k);
1320 switch (opcode & 0xfe00) {
1324 case 0xf600: { // All the SREG branches
1325 int16_t o = ((int16_t)(opcode << 6)) >> 9; // offset
1326 uint8_t s = opcode & 7;
1327 int set = (opcode & 0x0400) == 0; // this bit means BRXC otherwise BRXS
1328 int branch = (avr->sreg[s] && set) || (!avr->sreg[s] && !set);
1329 const char *names[2][8] = {
1330 { "brcc", "brne", "brpl", "brvc", NULL, "brhc", "brtc", "brid"},
1331 { "brcs", "breq", "brmi", "brvs", NULL, "brhs", "brts", "brie"},
1333 if (names[set][s]) {
1334 STATE("%s .%d [%04x]\t; Will%s branch\n", names[set][s], o, new_pc + (o << 1), branch ? "":" not");
1336 STATE("%s%c .%d [%04x]\t; Will%s branch\n", set ? "brbs" : "brbc", _sreg_bit_name[s], o, new_pc + (o << 1), branch ? "":" not");
1339 cycle++; // 2 cycles if taken, 1 otherwise
1340 new_pc = new_pc + (o << 1);
1344 case 0xf900: { // BLD – Bit Store from T into a Bit in Register 1111 100r rrrr 0bbb
1345 uint8_t r = (opcode >> 4) & 0x1f; // register index
1346 uint8_t s = opcode & 7;
1347 uint8_t v = avr->data[r] | (avr->sreg[S_T] ? (1 << s) : 0);
1348 STATE("bld %s[%02x], 0x%02x = %02x\n", avr_regname(r), avr->data[r], 1 << s, v);
1349 _avr_set_r(avr, r, v);
1352 case 0xfb00:{ // BST – Bit Store into T from bit in Register 1111 100r rrrr 0bbb
1353 uint8_t r = (opcode >> 4) & 0x1f; // register index
1354 uint8_t s = opcode & 7;
1355 STATE("bst %s[%02x], 0x%02x\n", avr_regname(r), avr->data[r], 1 << s);
1356 avr->sreg[S_T] = (avr->data[r] >> s) & 1;
1360 case 0xfe00: { // SBRS/SBRC – Skip if Bit in Register is Set/Clear 1111 11sr rrrr 0bbb
1361 uint8_t r = (opcode >> 4) & 0x1f; // register index
1362 uint8_t s = opcode & 7;
1363 int set = (opcode & 0x0200) != 0;
1364 int branch = ((avr->data[r] & (1 << s)) && set) || (!(avr->data[r] & (1 << s)) && !set);
1365 STATE("%s %s[%02x], 0x%02x\t; Will%s branch\n", set ? "sbrs" : "sbrc", avr_regname(r), avr->data[r], 1 << s, branch ? "":" not");
1367 if (_avr_is_instruction_32_bits(avr, new_pc)) {
1368 new_pc += 4; cycle += 2;
1370 new_pc += 2; cycle++;
1374 default: _avr_invalid_opcode(avr);
1378 default: _avr_invalid_opcode(avr);
1381 avr->cycle += cycle;