%%
(ad|sb|breg(in|de))c, and, (or|st|ld|t[bxy]|p[hl])a, xor, (ls|ro)[lr], mul, div, asr, cmp {
reg = &cpu->a;
}
(ld|st|cp|in|de|ta|p[hl])b {
reg = &cpu->b;
}
(ld|st|cp|in|de|t[ays]|p[hl])x {
reg = &cpu->x;
}
(ld|st|cp|in|de|t[ax]|p[hl])y {
reg = &cpu->y;
}
txs {
reg = &cpu->sp;
}
cps, (cl|se)[cio], clv, b(po|n[ge]|[cv][sc]|eq|r[ak]), p[hl]p {
reg = &cpu->ps;
}
ta[bxy] {
reg2 = &cpu->a;
}
tba, ~breg(div) {
reg2 = &cpu->b;
}
tx[ay], breg(div) {
reg2 = &cpu->x;
}
ty[ax] {
reg2 = &cpu->y;
}
tsx {
reg2 = &cpu->sp;
}
ld[abxy] {
*reg = value;
update_flags_nz(value);
}
st[abxy] {
value = *reg;
write(value, addr, rs);
}
(in|de)[cbxy] {
if (addr_mode == impl) {
value = *reg;
}
if (inst.match[0] == in) {
++value;
} else if (inst.match[0] == de) {
--value;
}
if (addr_mode != impl) {
msb = rs*8;
write(value, addr, rs);
} else {
*reg = value;
}
update_flags_nz(value);
}
ph[abxyp] {
if (inst == php) {
rs = 0;
}
push(*reg, rs);
}
pl[abxyp] {
if (inst == plp) {
rs = 0;
}
*reg = pull(rs);
}
/*
ora, and, xor {
switch (inst) {
case and: sum = *reg & value; break;
case ora: sum = *reg | value; break;
case xor: sum = *reg ^ value; break;
}
*reg = sum;
update_flags_nz(sum);
}
*/
ora {
sum = *reg | value;
*reg = sum;
update_flags_nz(sum);
}
and {
sum = *reg & value;
*reg = sum;
update_flags_nz(sum);
}
xor {
sum = *reg ^ value;
*reg = sum;
update_flags_nz(sum);
}
(se|cl)c {
cpu->ps.C = (inst == sec);
}
(se|cl)i {
cpu->ps.I = (inst == sei);
}
(se|cl)o {
if (ext == base && mode == base) {
cpu->ps.O = (inst == seo);
}
}
clv {
cpu->ps.V = 0;
}
cps {
cpu->ps = 0;
}
b(po|ng) {
cpu->pc = jump(addr, cpu->pc, get_flag(inst, bpo, cpu->ps.N));
}
bc[sc] {
cpu->pc = jump(addr, cpu->pc, get_flag(inst, bcs, cpu->ps.C));
}
b(ne|eq) {
cpu->pc = jump(addr, cpu->pc, get_flag(inst, beq, cpu->ps.Z));
}
bv[sc] {
cpu->pc = jump(addr, cpu->pc, get_flag(inst, bvs, cpu->ps.V));
}
bra, j(mp|sr) {
if (inst == jsr) {
push(cpu->pc, (rs) ? rs : 7);
}
cpu->pc = jump(addr, cpu->pc, 1);
}
intr(irq|nmi|reset), brk, wai {
if (inst == nmi) {
addr = 0xFFA0;
} else if (inst == reset) {
addr = 0xFFC0;
} else if (inst == irq) {
addr = 0xFFE0;
} else {
addr = 0xFFF0;
}
if (inst != reset) {
if (!cpu->is_wait) {
push(cpu->pc, 7);
push(cpu->ps, 0);
cpu->ps.I = 1;
}
cpu->is_wait = (inst == wai);
}
if (inst != wai) {
addr = read(addr, 7);
cpu->pc = jump(addr, cpu->pc, 1);
}
}
rt[si] {
if (inst == rti) {
cpu->ps = pull(0);
}
cpu->pc = pull(7);
}
(ad|sb)c {
if (inst == sbc) {
value = ~value;
}
*reg = adc(*reg, value, cpu->ps.C);
}
c(mp|p[bxy]) {
adc(*reg, ~value, 1);
}
(asr|ls[lr]) {
if (inst == lsl) {
sum = (value < msb) ? shift(*reg, value, 0, <<) : 0;
cpu->ps.C = (*reg >> (msb-(value+!value))) & 1;
} else {
if (inst == asr) {
sign = -(uint64_t)(*reg >> (msb-1)) << (msb-1)-value;
}
sum = (value < msb) ? shift(*reg, value, sign, >>) : 0;
cpu->ps.C = (*reg >> (value-(value != 0))) & 1;
}
}
ro[lr] {
if (inst == rol) {
rotate(sum, *reg, value, <<, >>, cpu->ps.C, cpu->ps.C << (value-1));
cpu->ps.C = (*reg >> (msb-(value+!value))) & 1;
} else {
rotate(sum, *reg, value, >>, <<, cpu->ps.C << (msb-1), cpu->ps.C << (msb-value));
cpu->ps.C = (*reg >> (value-(value != 0))) & 1;
}
}
mul {
*reg = mul(*reg, value);
}
div {
*reg = div(*reg, value, reg2);
}
t(a[bxy]|ba|x[ays]|y[ax]|sx) {
*reg = *reg2;
update_flags_nz(*reg);
}
%%