2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_xx() {
|
2010-12-28 06:03:02 +00:00
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_cb() {
|
|
|
|
exec_cb();
|
2010-12-29 11:03:42 +00:00
|
|
|
}
|
|
|
|
|
2010-12-28 06:03:02 +00:00
|
|
|
//8-bit load commands
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x, unsigned y> void LR35902::op_ld_r_r() {
|
2010-12-29 11:03:42 +00:00
|
|
|
r[x] = r[y];
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_ld_r_n() {
|
2010-12-28 06:03:02 +00:00
|
|
|
r[x] = op_read(r[PC]++);
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_ld_r_hl() {
|
2010-12-29 11:03:42 +00:00
|
|
|
r[x] = op_read(r[HL]);
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_ld_hl_r() {
|
2010-12-30 07:15:10 +00:00
|
|
|
op_write(r[HL], r[x]);
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ld_hl_n() {
|
2010-12-29 11:03:42 +00:00
|
|
|
op_write(r[HL], op_read(r[PC]++));
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_ld_a_rr() {
|
2010-12-30 07:15:10 +00:00
|
|
|
r[A] = op_read(r[x]);
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ld_a_nn() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 lo = op_read(r[PC]++);
|
|
|
|
uint8 hi = op_read(r[PC]++);
|
|
|
|
r[A] = op_read((hi << 8) | (lo << 0));
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_ld_rr_a() {
|
2010-12-30 07:15:10 +00:00
|
|
|
op_write(r[x], r[A]);
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ld_nn_a() {
|
2010-12-29 11:03:42 +00:00
|
|
|
uint8 lo = op_read(r[PC]++);
|
|
|
|
uint8 hi = op_read(r[PC]++);
|
|
|
|
op_write((hi << 8) | (lo << 0), r[A]);
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ld_a_ffn() {
|
2010-12-29 11:03:42 +00:00
|
|
|
r[A] = op_read(0xff00 + op_read(r[PC]++));
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ld_ffn_a() {
|
2010-12-29 11:03:42 +00:00
|
|
|
op_write(0xff00 + op_read(r[PC]++), r[A]);
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ld_a_ffc() {
|
2010-12-31 05:43:47 +00:00
|
|
|
r[A] = op_read(0xff00 + r[C]);
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ld_ffc_a() {
|
2010-12-29 11:03:42 +00:00
|
|
|
op_write(0xff00 + r[C], r[A]);
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ldi_hl_a() {
|
2010-12-30 07:15:10 +00:00
|
|
|
op_write(r[HL], r[A]);
|
|
|
|
r[HL]++;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ldi_a_hl() {
|
2010-12-29 11:03:42 +00:00
|
|
|
r[A] = op_read(r[HL]);
|
|
|
|
r[HL]++;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ldd_hl_a() {
|
2010-12-28 06:03:02 +00:00
|
|
|
op_write(r[HL], r[A]);
|
|
|
|
r[HL]--;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ldd_a_hl() {
|
2010-12-30 07:15:10 +00:00
|
|
|
r[A] = op_read(r[HL]);
|
|
|
|
r[HL]--;
|
|
|
|
}
|
|
|
|
|
2010-12-28 06:03:02 +00:00
|
|
|
//16-bit load commands
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_ld_rr_nn() {
|
2010-12-29 11:03:42 +00:00
|
|
|
r[x] = op_read(r[PC]++) << 0;
|
|
|
|
r[x] |= op_read(r[PC]++) << 8;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ld_nn_sp() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint16 addr = op_read(r[PC]++) << 0;
|
|
|
|
addr |= op_read(r[PC]++) << 8;
|
|
|
|
op_write(addr + 0, r[SP] >> 0);
|
|
|
|
op_write(addr + 1, r[SP] >> 8);
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ld_sp_hl() {
|
2010-12-30 07:15:10 +00:00
|
|
|
r[SP] = r[HL];
|
2010-12-31 05:43:47 +00:00
|
|
|
op_io();
|
2010-12-30 07:15:10 +00:00
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_push_rr() {
|
2010-12-29 11:03:42 +00:00
|
|
|
op_write(--r[SP], r[x] >> 8);
|
|
|
|
op_write(--r[SP], r[x] >> 0);
|
|
|
|
op_io();
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_pop_rr() {
|
2010-12-29 11:03:42 +00:00
|
|
|
r[x] = op_read(r[SP]++) << 0;
|
|
|
|
r[x] |= op_read(r[SP]++) << 8;
|
2010-12-28 06:03:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//8-bit arithmetic commands
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::opi_add_a(uint8 x) {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint16 rh = r[A] + x;
|
|
|
|
uint16 rl = (r[A] & 0x0f) + (x & 0x0f);
|
|
|
|
r[A] = rh;
|
|
|
|
r.f.z = (uint8)rh == 0;
|
2010-12-29 11:03:42 +00:00
|
|
|
r.f.n = 0;
|
2010-12-30 07:15:10 +00:00
|
|
|
r.f.h = rl > 0x0f;
|
|
|
|
r.f.c = rh > 0xff;
|
2010-12-29 11:03:42 +00:00
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_add_a_r() { opi_add_a(r[x]); }
|
|
|
|
void LR35902::op_add_a_n() { opi_add_a(op_read(r[PC]++)); }
|
|
|
|
void LR35902::op_add_a_hl() { opi_add_a(op_read(r[HL])); }
|
2010-12-30 07:15:10 +00:00
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::opi_adc_a(uint8 x) {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint16 rh = r[A] + x + r.f.c;
|
|
|
|
uint16 rl = (r[A] & 0x0f) + (x & 0x0f) + r.f.c;
|
|
|
|
r[A] = rh;
|
|
|
|
r.f.z = (uint8)rh == 0;
|
2010-12-29 11:03:42 +00:00
|
|
|
r.f.n = 0;
|
2010-12-30 07:15:10 +00:00
|
|
|
r.f.h = rl > 0x0f;
|
2010-12-31 05:43:47 +00:00
|
|
|
r.f.c = rh > 0xff;
|
2010-12-30 07:15:10 +00:00
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_adc_a_r() { opi_adc_a(r[x]); }
|
|
|
|
void LR35902::op_adc_a_n() { opi_adc_a(op_read(r[PC]++)); }
|
|
|
|
void LR35902::op_adc_a_hl() { opi_adc_a(op_read(r[HL])); }
|
2010-12-30 07:15:10 +00:00
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::opi_sub_a(uint8 x) {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint16 rh = r[A] - x;
|
|
|
|
uint16 rl = (r[A] & 0x0f) - (x & 0x0f);
|
|
|
|
r[A] = rh;
|
|
|
|
r.f.z = (uint8)rh == 0;
|
|
|
|
r.f.n = 1;
|
|
|
|
r.f.h = rl > 0x0f;
|
|
|
|
r.f.c = rh > 0xff;
|
2010-12-29 11:03:42 +00:00
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_sub_a_r() { opi_sub_a(r[x]); }
|
|
|
|
void LR35902::op_sub_a_n() { opi_sub_a(op_read(r[PC]++)); }
|
|
|
|
void LR35902::op_sub_a_hl() { opi_sub_a(op_read(r[HL])); }
|
2010-12-30 07:15:10 +00:00
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::opi_sbc_a(uint8 x) {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint16 rh = r[A] - x - r.f.c;
|
|
|
|
uint16 rl = (r[A] & 0x0f) - (x & 0x0f) - r.f.c;
|
|
|
|
r[A] = rh;
|
|
|
|
r.f.z = (uint8)rh == 0;
|
|
|
|
r.f.n = 1;
|
|
|
|
r.f.h = rl > 0x0f;
|
|
|
|
r.f.c = rh > 0xff;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_sbc_a_r() { opi_sbc_a(r[x]); }
|
|
|
|
void LR35902::op_sbc_a_n() { opi_sbc_a(op_read(r[PC]++)); }
|
|
|
|
void LR35902::op_sbc_a_hl() { opi_sbc_a(op_read(r[HL])); }
|
2010-12-30 07:15:10 +00:00
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::opi_and_a(uint8 x) {
|
2010-12-30 07:15:10 +00:00
|
|
|
r[A] &= x;
|
2010-12-29 11:03:42 +00:00
|
|
|
r.f.z = r[A] == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 1;
|
|
|
|
r.f.c = 0;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_and_a_r() { opi_and_a(r[x]); }
|
|
|
|
void LR35902::op_and_a_n() { opi_and_a(op_read(r[PC]++)); }
|
|
|
|
void LR35902::op_and_a_hl() { opi_and_a(op_read(r[HL])); }
|
2010-12-30 07:15:10 +00:00
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::opi_xor_a(uint8 x) {
|
2010-12-30 07:15:10 +00:00
|
|
|
r[A] ^= x;
|
2010-12-28 06:03:02 +00:00
|
|
|
r.f.z = r[A] == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = 0;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_xor_a_r() { opi_xor_a(r[x]); }
|
|
|
|
void LR35902::op_xor_a_n() { opi_xor_a(op_read(r[PC]++)); }
|
|
|
|
void LR35902::op_xor_a_hl() { opi_xor_a(op_read(r[HL])); }
|
2010-12-30 07:15:10 +00:00
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::opi_or_a(uint8 x) {
|
2010-12-30 07:15:10 +00:00
|
|
|
r[A] |= x;
|
2010-12-29 11:03:42 +00:00
|
|
|
r.f.z = r[A] == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = 0;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_or_a_r() { opi_or_a(r[x]); }
|
|
|
|
void LR35902::op_or_a_n() { opi_or_a(op_read(r[PC]++)); }
|
|
|
|
void LR35902::op_or_a_hl() { opi_or_a(op_read(r[HL])); }
|
2010-12-30 07:15:10 +00:00
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::opi_cp_a(uint8 x) {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint16 rh = r[A] - x;
|
|
|
|
uint16 rl = (r[A] & 0x0f) - (x & 0x0f);
|
|
|
|
r.f.z = (uint8)rh == 0;
|
2010-12-29 11:03:42 +00:00
|
|
|
r.f.n = 1;
|
2010-12-30 07:15:10 +00:00
|
|
|
r.f.h = rl > 0x0f;
|
2010-12-31 05:43:47 +00:00
|
|
|
r.f.c = rh > 0xff;
|
2010-12-29 11:03:42 +00:00
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_cp_a_r() { opi_cp_a(r[x]); }
|
|
|
|
void LR35902::op_cp_a_n() { opi_cp_a(op_read(r[PC]++)); }
|
|
|
|
void LR35902::op_cp_a_hl() { opi_cp_a(op_read(r[HL])); }
|
2010-12-30 07:15:10 +00:00
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_inc_r() {
|
2010-12-29 11:03:42 +00:00
|
|
|
r[x]++;
|
|
|
|
r.f.z = r[x] == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = (r[x] & 0x0f) == 0x00;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_inc_hl() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 n = op_read(r[HL]);
|
|
|
|
op_write(r[HL], ++n);
|
|
|
|
r.f.z = n == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = (n & 0x0f) == 0x00;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_dec_r() {
|
2010-12-28 06:03:02 +00:00
|
|
|
r[x]--;
|
|
|
|
r.f.z = r[x] == 0;
|
2010-12-29 11:03:42 +00:00
|
|
|
r.f.n = 1;
|
|
|
|
r.f.h = (r[x] & 0x0f) == 0x0f;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_dec_hl() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 n = op_read(r[HL]);
|
|
|
|
op_write(r[HL], --n);
|
|
|
|
r.f.z = n == 0;
|
|
|
|
r.f.n = 1;
|
|
|
|
r.f.h = (n & 0x0f) == 0x0f;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_daa() {
|
2010-12-31 05:43:47 +00:00
|
|
|
uint16 a = r[A];
|
2010-12-30 07:15:10 +00:00
|
|
|
if(r.f.n == 0) {
|
|
|
|
if(r.f.h || (a & 0x0f) > 0x09) a += 0x06;
|
2010-12-31 05:43:47 +00:00
|
|
|
if(r.f.c || (a ) > 0x9f) a += 0x60;
|
2010-12-30 07:15:10 +00:00
|
|
|
} else {
|
|
|
|
if(r.f.h) {
|
|
|
|
a -= 0x06;
|
|
|
|
if(r.f.c == 0) a &= 0xff;
|
|
|
|
}
|
|
|
|
if(r.f.c) a -= 0x60;
|
|
|
|
}
|
|
|
|
r[A] = a;
|
|
|
|
r.f.z = r[A] == 0;
|
|
|
|
r.f.h = 0;
|
2010-12-31 05:43:47 +00:00
|
|
|
r.f.c |= a & 0x100;
|
2010-12-30 07:15:10 +00:00
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_cpl() {
|
2010-12-29 11:03:42 +00:00
|
|
|
r[A] ^= 0xff;
|
|
|
|
r.f.n = 1;
|
|
|
|
r.f.h = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//16-bit arithmetic commands
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_add_hl_rr() {
|
2010-12-31 05:43:47 +00:00
|
|
|
op_io();
|
2010-12-29 11:03:42 +00:00
|
|
|
uint32 rb = (r[HL] + r[x]);
|
|
|
|
uint32 rn = (r[HL] & 0xfff) + (r[x] & 0xfff);
|
|
|
|
r[HL] = rb;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = rn > 0x0fff;
|
|
|
|
r.f.c = rb > 0xffff;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_inc_rr() {
|
2010-12-31 05:43:47 +00:00
|
|
|
op_io();
|
2010-12-29 11:03:42 +00:00
|
|
|
r[x]++;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_dec_rr() {
|
2010-12-31 05:43:47 +00:00
|
|
|
op_io();
|
2010-12-29 11:03:42 +00:00
|
|
|
r[x]--;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_add_sp_n() {
|
2010-12-31 05:43:47 +00:00
|
|
|
op_io();
|
|
|
|
op_io();
|
2010-12-30 07:15:10 +00:00
|
|
|
signed n = (int8)op_read(r[PC]++);
|
|
|
|
r.f.z = 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = ((r[SP] & 0x0f) + (n & 0x0f)) > 0x0f;
|
|
|
|
r.f.c = ((r[SP] & 0xff) + (n & 0xff)) > 0xff;
|
|
|
|
r[SP] += n;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ld_hl_sp_n() {
|
2010-12-31 05:43:47 +00:00
|
|
|
op_io();
|
2010-12-30 07:15:10 +00:00
|
|
|
signed n = (int8)op_read(r[PC]++);
|
|
|
|
r.f.z = 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = ((r[SP] & 0x0f) + (n & 0x0f)) > 0x0f;
|
|
|
|
r.f.c = ((r[SP] & 0xff) + (n & 0xff)) > 0xff;
|
|
|
|
r[HL] = r[SP] + n;
|
|
|
|
}
|
|
|
|
|
2010-12-29 11:03:42 +00:00
|
|
|
//rotate/shift commands
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_rlca() {
|
2010-12-30 07:15:10 +00:00
|
|
|
r[A] = (r[A] << 1) | (r[A] >> 7);
|
|
|
|
r.f.z = 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = r[A] & 0x01;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_rla() {
|
2010-12-30 07:15:10 +00:00
|
|
|
bool c = r[A] & 0x80;
|
2010-12-30 07:18:47 +00:00
|
|
|
r[A] = (r[A] << 1) | (r.f.c << 0);
|
2010-12-30 07:15:10 +00:00
|
|
|
r.f.z = 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = c;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_rrca() {
|
2010-12-30 07:15:10 +00:00
|
|
|
r[A] = (r[A] >> 1) | (r[A] << 7);
|
|
|
|
r.f.z = 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = r[A] & 0x80;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_rra() {
|
2010-12-30 07:15:10 +00:00
|
|
|
bool c = r[A] & 0x01;
|
2010-12-30 07:18:47 +00:00
|
|
|
r[A] = (r[A] >> 1) | (r.f.c << 7);
|
2010-12-30 07:15:10 +00:00
|
|
|
r.f.z = 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = c;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_rlc_r() {
|
2010-12-30 07:15:10 +00:00
|
|
|
r[x] = (r[x] << 1) | (r[x] >> 7);
|
|
|
|
r.f.z = r[x] == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = r[x] & 0x01;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_rlc_hl() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 n = op_read(r[HL]);
|
|
|
|
n = (n << 1) | (n >> 7);
|
|
|
|
op_write(r[HL], n);
|
|
|
|
r.f.z = n == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = n & 0x01;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_rl_r() {
|
2010-12-30 07:15:10 +00:00
|
|
|
bool c = r[x] & 0x80;
|
|
|
|
r[x] = (r[x] << 1) | (r.f.c << 0);
|
|
|
|
r.f.z = r[x] == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = c;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_rl_hl() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 n = op_read(r[HL]);
|
|
|
|
bool c = n & 0x80;
|
|
|
|
n = (n << 1) | (r.f.c << 0);
|
|
|
|
op_write(r[HL], n);
|
|
|
|
r.f.z = n == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = c;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_rrc_r() {
|
2010-12-30 07:15:10 +00:00
|
|
|
r[x] = (r[x] >> 1) | (r[x] << 7);
|
|
|
|
r.f.z = r[x] == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = r[x] & 0x80;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_rrc_hl() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 n = op_read(r[HL]);
|
|
|
|
n = (n >> 1) | (n << 7);
|
|
|
|
op_write(r[HL], n);
|
|
|
|
r.f.z = n == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = n & 0x80;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_rr_r() {
|
2010-12-30 07:15:10 +00:00
|
|
|
bool c = r[x] & 0x01;
|
|
|
|
r[x] = (r[x] >> 1) | (r.f.c << 7);
|
|
|
|
r.f.z = r[x] == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = c;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_rr_hl() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 n = op_read(r[HL]);
|
|
|
|
bool c = n & 0x01;
|
|
|
|
n = (n >> 1) | (r.f.c << 7);
|
|
|
|
op_write(r[HL], n);
|
|
|
|
r.f.z = n == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = c;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_sla_r() {
|
2010-12-30 07:15:10 +00:00
|
|
|
bool c = r[x] & 0x80;
|
|
|
|
r[x] <<= 1;
|
|
|
|
r.f.z = r[x] == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = c;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_sla_hl() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 n = op_read(r[HL]);
|
|
|
|
bool c = n & 0x80;
|
|
|
|
n <<= 1;
|
|
|
|
op_write(r[HL], n);
|
|
|
|
r.f.z = n == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = c;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_swap_r() {
|
2010-12-29 11:03:42 +00:00
|
|
|
r[x] = (r[x] << 4) | (r[x] >> 4);
|
|
|
|
r.f.z = r[x] == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = 0;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_swap_hl() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 n = op_read(r[HL]);
|
|
|
|
n = (n << 4) | (n >> 4);
|
|
|
|
op_write(r[HL], n);
|
|
|
|
r.f.z = n == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = 0;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_sra_r() {
|
2010-12-30 07:15:10 +00:00
|
|
|
bool c = r[x] & 0x01;
|
|
|
|
r[x] = (int8)r[x] >> 1;
|
|
|
|
r.f.z = r[x] == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = c;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_sra_hl() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 n = op_read(r[HL]);
|
|
|
|
bool c = n & 0x01;
|
|
|
|
n = (int8)n >> 1;
|
|
|
|
op_write(r[HL], n);
|
|
|
|
r.f.z = n == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = c;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x> void LR35902::op_srl_r() {
|
2010-12-30 07:15:10 +00:00
|
|
|
bool c = r[x] & 0x01;
|
|
|
|
r[x] >>= 1;
|
|
|
|
r.f.z = r[x] == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = c;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_srl_hl() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 n = op_read(r[HL]);
|
|
|
|
bool c = n & 0x01;
|
|
|
|
n >>= 1;
|
|
|
|
op_write(r[HL], n);
|
|
|
|
r.f.z = n == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = c;
|
|
|
|
}
|
|
|
|
|
2010-12-29 11:03:42 +00:00
|
|
|
//single-bit commands
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned b, unsigned x> void LR35902::op_bit_n_r() {
|
2010-12-29 11:03:42 +00:00
|
|
|
r.f.z = (r[x] & (1 << b)) == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 1;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned b> void LR35902::op_bit_n_hl() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 n = op_read(r[HL]);
|
|
|
|
r.f.z = (n & (1 << b)) == 0;
|
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 1;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned b, unsigned x> void LR35902::op_set_n_r() {
|
2010-12-29 11:03:42 +00:00
|
|
|
r[x] |= 1 << b;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned b> void LR35902::op_set_n_hl() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 n = op_read(r[HL]);
|
|
|
|
n |= 1 << b;
|
|
|
|
op_write(r[HL], n);
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned b, unsigned x> void LR35902::op_res_n_r() {
|
2010-12-29 11:03:42 +00:00
|
|
|
r[x] &= ~(1 << b);
|
2010-12-28 06:03:02 +00:00
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned b> void LR35902::op_res_n_hl() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 n = op_read(r[HL]);
|
|
|
|
n &= ~(1 << b);
|
|
|
|
op_write(r[HL], n);
|
|
|
|
}
|
|
|
|
|
2010-12-28 06:03:02 +00:00
|
|
|
//control commands
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ccf() {
|
2010-12-30 07:15:10 +00:00
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = !r.f.c;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_scf() {
|
2010-12-30 07:15:10 +00:00
|
|
|
r.f.n = 0;
|
|
|
|
r.f.h = 0;
|
|
|
|
r.f.c = 1;
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_nop() {
|
2010-12-28 06:03:02 +00:00
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_halt() {
|
|
|
|
r.halt = true;
|
|
|
|
while(r.halt == true) op_io();
|
2010-12-30 07:15:10 +00:00
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_stop() {
|
Update to v088r08 release.
byuu says:
From this WIP, I'm starting on the impossible task of
a declarative-based GUI, which I'm calling Ethos.
base/ becomes emulator/, and we add emulator/interface.hpp, which is
a base API that all emulation cores must implement in full.
(Right now, it's kind of a hybrid to work with the old GUI and the new
GUI at the same time, of course.)
Unlike the old interfaces, the new base class also provides all general
usability hooks: loading and saving files and states, cheat codes, etc.
The new interface also contains information and vector structs to
describe all possible loading methods, controller bindings, etc; and
gives names for them all.
The actual GUI in fact should not include eg <gba/gba.hpp> anymore.
Should speed up GUI compilation.
So the idea going forward is that ethos will build a list of emulators
right when the application starts up.
Once you've appended an emulator to that list, you're done. No more GUI
changes are needed to support that system.
The GUI will have code to parse the emulator interfaces list, and build
all the requisite GUI options dynamically, declarative style.
Ultimately, once the project is finished, the new GUI should look ~99%
identical to the current GUI. But it'll probably be a whole lot smaller.
2012-04-29 06:29:54 +00:00
|
|
|
if(stop()) return;
|
2012-04-26 10:51:13 +00:00
|
|
|
r.stop = true;
|
|
|
|
while(r.stop == true) op_io();
|
2010-12-30 07:15:10 +00:00
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_di() {
|
|
|
|
r.ime = 0;
|
2010-12-29 11:03:42 +00:00
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ei() {
|
|
|
|
r.ei = true;
|
|
|
|
//r.ime = 1;
|
2010-12-29 11:03:42 +00:00
|
|
|
}
|
|
|
|
|
2010-12-28 06:03:02 +00:00
|
|
|
//jump commands
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_jp_nn() {
|
2010-12-28 06:03:02 +00:00
|
|
|
uint8 lo = op_read(r[PC]++);
|
|
|
|
uint8 hi = op_read(r[PC]++);
|
|
|
|
r[PC] = (hi << 8) | (lo << 0);
|
|
|
|
op_io();
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_jp_hl() {
|
2010-12-29 11:03:42 +00:00
|
|
|
r[PC] = r[HL];
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x, bool y> void LR35902::op_jp_f_nn() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 lo = op_read(r[PC]++);
|
|
|
|
uint8 hi = op_read(r[PC]++);
|
|
|
|
if(r.f[x] == y) {
|
|
|
|
r[PC] = (hi << 8) | (lo << 0);
|
|
|
|
op_io();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_jr_n() {
|
2010-12-30 07:15:10 +00:00
|
|
|
int8 n = op_read(r[PC]++);
|
|
|
|
r[PC] += n;
|
|
|
|
op_io();
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x, bool y> void LR35902::op_jr_f_n() {
|
2010-12-28 06:03:02 +00:00
|
|
|
int8 n = op_read(r[PC]++);
|
|
|
|
if(r.f[x] == y) {
|
|
|
|
r[PC] += n;
|
|
|
|
op_io();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_call_nn() {
|
2010-12-29 11:03:42 +00:00
|
|
|
uint8 lo = op_read(r[PC]++);
|
|
|
|
uint8 hi = op_read(r[PC]++);
|
2010-12-30 07:15:10 +00:00
|
|
|
op_write(--r[SP], r[PC] >> 8);
|
|
|
|
op_write(--r[SP], r[PC] >> 0);
|
2010-12-29 11:03:42 +00:00
|
|
|
r[PC] = (hi << 8) | (lo << 0);
|
|
|
|
op_io();
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x, bool y> void LR35902::op_call_f_nn() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 lo = op_read(r[PC]++);
|
|
|
|
uint8 hi = op_read(r[PC]++);
|
|
|
|
if(r.f[x] == y) {
|
|
|
|
op_write(--r[SP], r[PC] >> 8);
|
|
|
|
op_write(--r[SP], r[PC] >> 0);
|
|
|
|
r[PC] = (hi << 8) | (lo << 0);
|
|
|
|
op_io();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_ret() {
|
2010-12-29 11:03:42 +00:00
|
|
|
uint8 lo = op_read(r[SP]++);
|
|
|
|
uint8 hi = op_read(r[SP]++);
|
|
|
|
r[PC] = (hi << 8) | (lo << 0);
|
|
|
|
op_io();
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned x, bool y> void LR35902::op_ret_f() {
|
2010-12-30 07:15:10 +00:00
|
|
|
op_io();
|
|
|
|
if(r.f[x] == y) {
|
|
|
|
uint8 lo = op_read(r[SP]++);
|
|
|
|
uint8 hi = op_read(r[SP]++);
|
|
|
|
r[PC] = (hi << 8) | (lo << 0);
|
|
|
|
op_io();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
void LR35902::op_reti() {
|
2010-12-30 07:15:10 +00:00
|
|
|
uint8 lo = op_read(r[SP]++);
|
|
|
|
uint8 hi = op_read(r[SP]++);
|
|
|
|
r[PC] = (hi << 8) | (lo << 0);
|
|
|
|
op_io();
|
2012-04-26 10:51:13 +00:00
|
|
|
r.ime = 1;
|
2010-12-30 07:15:10 +00:00
|
|
|
}
|
|
|
|
|
2012-04-26 10:51:13 +00:00
|
|
|
template<unsigned n> void LR35902::op_rst_n() {
|
2010-12-29 11:03:42 +00:00
|
|
|
op_write(--r[SP], r[PC] >> 8);
|
|
|
|
op_write(--r[SP], r[PC] >> 0);
|
|
|
|
r[PC] = n;
|
|
|
|
op_io();
|
|
|
|
}
|