avr->data[r] = v;
}
+static inline void
+_avr_set_r16le(
+ avr_t * avr,
+ uint16_t r,
+ uint16_t v)
+{
+ _avr_set_r(avr, r, v);
+ _avr_set_r(avr, r + 1, v >> 8);
+}
+
+static inline void
+_avr_set_r16le_hl(
+ avr_t * avr,
+ uint16_t r,
+ uint16_t v)
+{
+ _avr_set_r(avr, r + 1, v >> 8);
+ _avr_set_r(avr, r , v);
+}
+
/*
* Stack pointer access
*/
inline void _avr_sp_set(avr_t * avr, uint16_t sp)
{
- _avr_set_r(avr, R_SPL, sp);
- _avr_set_r(avr, R_SPH, sp >> 8);
+ _avr_set_r16le(avr, R_SPL, sp);
}
/*
uint8_t d = ((opcode >> 4) & 0xf) << 1;
uint8_t r = ((opcode) & 0xf) << 1;
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]);
- _avr_set_r(avr, d, avr->data[r]);
- _avr_set_r(avr, d+1, avr->data[r+1]);
+ _avr_set_r16le(avr, d, _avr_data_read16le(avr, r));
} break;
case 0x0200: { // MULS -- Multiply Signed -- 0000 0010 dddd rrrr
int8_t r = 16 + (opcode & 0xf);
int8_t d = 16 + ((opcode >> 4) & 0xf);
int16_t res = ((int8_t)avr->data[r]) * ((int8_t)avr->data[d]);
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);
- _avr_set_r(avr, 0, res);
- _avr_set_r(avr, 1, res >> 8);
+ _avr_set_r16le(avr, 0, res);
avr->sreg[S_C] = (res >> 15) & 1;
avr->sreg[S_Z] = res == 0;
cycle++;
}
cycle++;
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);
- _avr_set_r(avr, 0, res);
- _avr_set_r(avr, 1, res >> 8);
+ _avr_set_r16le(avr, 0, res);
avr->sreg[S_C] = c;
avr->sreg[S_Z] = res == 0;
SREG();
_avr_set_r(avr, d, avr->flash[z]);
if (op) {
z++;
- _avr_set_r(avr, R_ZH, z >> 8);
- _avr_set_r(avr, R_ZL, z);
+ _avr_set_r16le_hl(avr, R_ZL, z);
}
cycle += 2; // 3 cycles
} break;
if (op) {
z++;
_avr_set_r(avr, avr->rampz, z >> 16);
- _avr_set_r(avr, R_ZH, z >> 8);
- _avr_set_r(avr, R_ZL, z);
+ _avr_set_r16le_hl(avr, R_ZL, z);
}
cycle += 2; // 3 cycles
} break;
if (op == 2) x--;
uint8_t vd = _avr_get_ram(avr, x);
if (op == 1) x++;
- _avr_set_r(avr, R_XH, x >> 8);
- _avr_set_r(avr, R_XL, x);
+ _avr_set_r16le_hl(avr, R_XL, x);
_avr_set_r(avr, d, vd);
} break;
case 0x920c:
if (op == 2) x--;
_avr_set_ram(avr, x, vd);
if (op == 1) x++;
- _avr_set_r(avr, R_XH, x >> 8);
- _avr_set_r(avr, R_XL, x);
+ _avr_set_r16le_hl(avr, R_XL, x);
} break;
case 0x9009:
case 0x900a: { // LD -- Load Indirect from Data using Y -- 1001 000d dddd 10oo
if (op == 2) y--;
uint8_t vd = _avr_get_ram(avr, y);
if (op == 1) y++;
- _avr_set_r(avr, R_YH, y >> 8);
- _avr_set_r(avr, R_YL, y);
+ _avr_set_r16le_hl(avr, R_YL, y);
_avr_set_r(avr, d, vd);
} break;
case 0x9209:
if (op == 2) y--;
_avr_set_ram(avr, y, vd);
if (op == 1) y++;
- _avr_set_r(avr, R_YH, y >> 8);
- _avr_set_r(avr, R_YL, y);
+ _avr_set_r16le_hl(avr, R_YL, y);
} break;
case 0x9200: { // STS -- Store Direct to Data Space, 32 bits -- 1001 0010 0000 0000
get_vd5(opcode);
if (op == 2) z--;
uint8_t vd = _avr_get_ram(avr, z);
if (op == 1) z++;
- _avr_set_r(avr, R_ZH, z >> 8);
- _avr_set_r(avr, R_ZL, z);
+ _avr_set_r16le_hl(avr, R_ZL, z);
_avr_set_r(avr, d, vd);
} break;
case 0x9201:
if (op == 2) z--;
_avr_set_ram(avr, z, vd);
if (op == 1) z++;
- _avr_set_r(avr, R_ZH, z >> 8);
- _avr_set_r(avr, R_ZL, z);
+ _avr_set_r16le_hl(avr, R_ZL, z);
} break;
case 0x900f: { // POP -- 1001 000d dddd 1111
get_d5(opcode);
get_vp2_k6(opcode);
uint16_t res = vp + k;
STATE("adiw %s:%s[%04x], 0x%02x\n", avr_regname(p), avr_regname(p + 1), vp, k);
- _avr_set_r(avr, p + 1, res >> 8);
- _avr_set_r(avr, p, res);
+ _avr_set_r16le_hl(avr, p, res);
avr->sreg[S_V] = ((~vp & res) >> 15) & 1;
avr->sreg[S_C] = ((~res & vp) >> 15) & 1;
_avr_flags_zns16(avr, res);
get_vp2_k6(opcode);
uint16_t res = vp - k;
STATE("sbiw %s:%s[%04x], 0x%02x\n", avr_regname(p), avr_regname(p + 1), vp, k);
- _avr_set_r(avr, p + 1, res >> 8);
- _avr_set_r(avr, p, res);
+ _avr_set_r16le_hl(avr, p, res);
avr->sreg[S_V] = ((vp & ~res) >> 15) & 1;
avr->sreg[S_C] = ((res & ~vp) >> 15) & 1;
_avr_flags_zns16(avr, res);
uint16_t res = vd * vr;
STATE("mul %s[%02x], %s[%02x] = %04x\n", avr_regname(d), vd, avr_regname(r), vr, res);
cycle++;
- _avr_set_r(avr, 0, res);
- _avr_set_r(avr, 1, res >> 8);
+ _avr_set_r16le(avr, 0, res);
avr->sreg[S_Z] = res == 0;
avr->sreg[S_C] = (res >> 15) & 1;
SREG();