2010-08-09 13:28:56 +00:00
|
|
|
//$00 stop
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_stop() {
|
2010-08-09 13:28:56 +00:00
|
|
|
if(regs.cfgr.irq == 0) {
|
|
|
|
regs.sfr.irq = 1;
|
2012-04-29 06:16:44 +00:00
|
|
|
stop();
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
regs.sfr.g = 0;
|
|
|
|
regs.pipeline = 0x01;
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$01 nop
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_nop() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$02 cache
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_cache() {
|
2010-08-09 13:28:56 +00:00
|
|
|
if(regs.cbr != (regs.r[15] & 0xfff0)) {
|
|
|
|
regs.cbr = regs.r[15] & 0xfff0;
|
|
|
|
cache_flush();
|
|
|
|
}
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$03 lsr
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_lsr() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.sfr.cy = (regs.sr() & 1);
|
|
|
|
regs.dr() = regs.sr() >> 1;
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$04 rol
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_rol() {
|
2010-08-09 13:28:56 +00:00
|
|
|
bool carry = (regs.sr() & 0x8000);
|
|
|
|
regs.dr() = (regs.sr() << 1) | regs.sfr.cy;
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.cy = carry;
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$05 bra e
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_bra() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.r[15] += (int8)pipe();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$06 blt e
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_blt() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int e = (int8)pipe();
|
|
|
|
if((regs.sfr.s ^ regs.sfr.ov) == 0) regs.r[15] += e;
|
|
|
|
}
|
|
|
|
|
|
|
|
//$07 bge e
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_bge() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int e = (int8)pipe();
|
|
|
|
if((regs.sfr.s ^ regs.sfr.ov) == 1) regs.r[15] += e;
|
|
|
|
}
|
|
|
|
|
|
|
|
//$08 bne e
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_bne() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int e = (int8)pipe();
|
|
|
|
if(regs.sfr.z == 0) regs.r[15] += e;
|
|
|
|
}
|
|
|
|
|
|
|
|
//$09 beq e
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_beq() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int e = (int8)pipe();
|
|
|
|
if(regs.sfr.z == 1) regs.r[15] += e;
|
|
|
|
}
|
|
|
|
|
|
|
|
//$0a bpl e
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_bpl() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int e = (int8)pipe();
|
|
|
|
if(regs.sfr.s == 0) regs.r[15] += e;
|
|
|
|
}
|
|
|
|
|
|
|
|
//$0b bmi e
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_bmi() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int e = (int8)pipe();
|
|
|
|
if(regs.sfr.s == 1) regs.r[15] += e;
|
|
|
|
}
|
|
|
|
|
|
|
|
//$0c bcc e
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_bcc() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int e = (int8)pipe();
|
|
|
|
if(regs.sfr.cy == 0) regs.r[15] += e;
|
|
|
|
}
|
|
|
|
|
|
|
|
//$0d bcs e
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_bcs() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int e = (int8)pipe();
|
|
|
|
if(regs.sfr.cy == 1) regs.r[15] += e;
|
|
|
|
}
|
|
|
|
|
|
|
|
//$0e bvc e
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_bvc() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int e = (int8)pipe();
|
|
|
|
if(regs.sfr.ov == 0) regs.r[15] += e;
|
|
|
|
}
|
|
|
|
|
|
|
|
//$0f bvs e
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_bvs() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int e = (int8)pipe();
|
|
|
|
if(regs.sfr.ov == 1) regs.r[15] += e;
|
|
|
|
}
|
|
|
|
|
|
|
|
//$10-1f(b0): to rN
|
|
|
|
//$10-1f(b1): move rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_to_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
if(regs.sfr.b == 0) {
|
|
|
|
regs.dreg = n;
|
|
|
|
} else {
|
|
|
|
regs.r[n] = regs.sr();
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//$20-2f: with rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_with_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.sreg = n;
|
|
|
|
regs.dreg = n;
|
|
|
|
regs.sfr.b = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//$30-3b(alt0): stw (rN)
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_stw_ir() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.ramaddr = regs.r[n];
|
|
|
|
rambuffer_write(regs.ramaddr ^ 0, regs.sr() >> 0);
|
|
|
|
rambuffer_write(regs.ramaddr ^ 1, regs.sr() >> 8);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$30-3b(alt1): stb (rN)
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_stb_ir() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.ramaddr = regs.r[n];
|
|
|
|
rambuffer_write(regs.ramaddr, regs.sr());
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$3c loop
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_loop() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.r[12]--;
|
|
|
|
regs.sfr.s = (regs.r[12] & 0x8000);
|
|
|
|
regs.sfr.z = (regs.r[12] == 0);
|
|
|
|
if(!regs.sfr.z) regs.r[15] = regs.r[13];
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$3d alt1
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_alt1() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.sfr.b = 0;
|
|
|
|
regs.sfr.alt1 = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//$3e alt2
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_alt2() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.sfr.b = 0;
|
|
|
|
regs.sfr.alt2 = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//$3f alt3
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_alt3() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.sfr.b = 0;
|
|
|
|
regs.sfr.alt1 = 1;
|
|
|
|
regs.sfr.alt2 = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//$40-4b(alt0): ldw (rN)
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_ldw_ir() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.ramaddr = regs.r[n];
|
|
|
|
uint16_t data;
|
|
|
|
data = rambuffer_read(regs.ramaddr ^ 0) << 0;
|
|
|
|
data |= rambuffer_read(regs.ramaddr ^ 1) << 8;
|
|
|
|
regs.dr() = data;
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$40-4b(alt1): ldb (rN)
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_ldb_ir() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.ramaddr = regs.r[n];
|
|
|
|
regs.dr() = rambuffer_read(regs.ramaddr);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$4c(alt0): plot
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_plot() {
|
2010-08-09 13:28:56 +00:00
|
|
|
plot(regs.r[1], regs.r[2]);
|
|
|
|
regs.r[1]++;
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$4c(alt1): rpix
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_rpix() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = rpix(regs.r[1], regs.r[2]);
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$4d: swap
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_swap() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = (regs.sr() >> 8) | (regs.sr() << 8);
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$4e(alt0): color
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_color() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.colr = color(regs.sr());
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$4e(alt1): cmode
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_cmode() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.por = regs.sr();
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$4f: not
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_not() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = ~regs.sr();
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$50-5f(alt0): add rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_add_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int r = regs.sr() + regs.r[n];
|
|
|
|
regs.sfr.ov = ~(regs.sr() ^ regs.r[n]) & (regs.r[n] ^ r) & 0x8000;
|
|
|
|
regs.sfr.s = (r & 0x8000);
|
|
|
|
regs.sfr.cy = (r >= 0x10000);
|
|
|
|
regs.sfr.z = ((uint16_t)r == 0);
|
|
|
|
regs.dr() = r;
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$50-5f(alt1): adc rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_adc_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int r = regs.sr() + regs.r[n] + regs.sfr.cy;
|
|
|
|
regs.sfr.ov = ~(regs.sr() ^ regs.r[n]) & (regs.r[n] ^ r) & 0x8000;
|
|
|
|
regs.sfr.s = (r & 0x8000);
|
|
|
|
regs.sfr.cy = (r >= 0x10000);
|
|
|
|
regs.sfr.z = ((uint16_t)r == 0);
|
|
|
|
regs.dr() = r;
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$50-5f(alt2): add #N
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_add_i() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int r = regs.sr() + n;
|
|
|
|
regs.sfr.ov = ~(regs.sr() ^ n) & (n ^ r) & 0x8000;
|
|
|
|
regs.sfr.s = (r & 0x8000);
|
|
|
|
regs.sfr.cy = (r >= 0x10000);
|
|
|
|
regs.sfr.z = ((uint16_t)r == 0);
|
|
|
|
regs.dr() = r;
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$50-5f(alt3): adc #N
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_adc_i() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int r = regs.sr() + n + regs.sfr.cy;
|
|
|
|
regs.sfr.ov = ~(regs.sr() ^ n) & (n ^ r) & 0x8000;
|
|
|
|
regs.sfr.s = (r & 0x8000);
|
|
|
|
regs.sfr.cy = (r >= 0x10000);
|
|
|
|
regs.sfr.z = ((uint16_t)r == 0);
|
|
|
|
regs.dr() = r;
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$60-6f(alt0): sub rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_sub_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int r = regs.sr() - regs.r[n];
|
|
|
|
regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000;
|
|
|
|
regs.sfr.s = (r & 0x8000);
|
|
|
|
regs.sfr.cy = (r >= 0);
|
|
|
|
regs.sfr.z = ((uint16_t)r == 0);
|
|
|
|
regs.dr() = r;
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$60-6f(alt1): sbc rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_sbc_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int r = regs.sr() - regs.r[n] - !regs.sfr.cy;
|
|
|
|
regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000;
|
|
|
|
regs.sfr.s = (r & 0x8000);
|
|
|
|
regs.sfr.cy = (r >= 0);
|
|
|
|
regs.sfr.z = ((uint16_t)r == 0);
|
|
|
|
regs.dr() = r;
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$60-6f(alt2): sub #N
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_sub_i() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int r = regs.sr() - n;
|
|
|
|
regs.sfr.ov = (regs.sr() ^ n) & (regs.sr() ^ r) & 0x8000;
|
|
|
|
regs.sfr.s = (r & 0x8000);
|
|
|
|
regs.sfr.cy = (r >= 0);
|
|
|
|
regs.sfr.z = ((uint16_t)r == 0);
|
|
|
|
regs.dr() = r;
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$60-6f(alt3): cmp rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_cmp_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
int r = regs.sr() - regs.r[n];
|
|
|
|
regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000;
|
|
|
|
regs.sfr.s = (r & 0x8000);
|
|
|
|
regs.sfr.cy = (r >= 0);
|
|
|
|
regs.sfr.z = ((uint16_t)r == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$70: merge
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_merge() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = (regs.r[7] & 0xff00) | (regs.r[8] >> 8);
|
|
|
|
regs.sfr.ov = (regs.dr() & 0xc0c0);
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8080);
|
|
|
|
regs.sfr.cy = (regs.dr() & 0xe0e0);
|
|
|
|
regs.sfr.z = (regs.dr() & 0xf0f0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$71-7f(alt0): and rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_and_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = regs.sr() & regs.r[n];
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$71-7f(alt1): bic rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_bic_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = regs.sr() & ~regs.r[n];
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$71-7f(alt2): and #N
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_and_i() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = regs.sr() & n;
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$71-7f(alt3): bic #N
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_bic_i() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = regs.sr() & ~n;
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$80-8f(alt0): mult rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_mult_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = (int8)regs.sr() * (int8)regs.r[n];
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
2015-06-28 08:44:56 +00:00
|
|
|
if(!regs.cfgr.ms0) step(regs.clsr ? 1 : 2);
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//$80-8f(alt1): umult rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_umult_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = (uint8)regs.sr() * (uint8)regs.r[n];
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
2015-06-28 08:44:56 +00:00
|
|
|
if(!regs.cfgr.ms0) step(regs.clsr ? 1 : 2);
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//$80-8f(alt2): mult #N
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_mult_i() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = (int8)regs.sr() * (int8)n;
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
2015-06-28 08:44:56 +00:00
|
|
|
if(!regs.cfgr.ms0) step(regs.clsr ? 1 : 2);
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//$80-8f(alt3): umult #N
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_umult_i() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = (uint8)regs.sr() * (uint8)n;
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
2015-06-28 08:44:56 +00:00
|
|
|
if(!regs.cfgr.ms0) step(regs.clsr ? 1 : 2);
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//$90: sbk
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_sbk() {
|
2010-08-09 13:28:56 +00:00
|
|
|
rambuffer_write(regs.ramaddr ^ 0, regs.sr() >> 0);
|
|
|
|
rambuffer_write(regs.ramaddr ^ 1, regs.sr() >> 8);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$91-94: link #N
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_link() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.r[11] = regs.r[15] + n;
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$95: sex
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_sex() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = (int8)regs.sr();
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$96(alt0): asr
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_asr() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.sfr.cy = (regs.sr() & 1);
|
|
|
|
regs.dr() = (int16_t)regs.sr() >> 1;
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$96(alt1): div2
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_div2() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.sfr.cy = (regs.sr() & 1);
|
|
|
|
regs.dr() = ((int16_t)regs.sr() >> 1) + ((regs.sr() + 1) >> 16);
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$97: ror
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_ror() {
|
2010-08-09 13:28:56 +00:00
|
|
|
bool carry = (regs.sr() & 1);
|
|
|
|
regs.dr() = (regs.sfr.cy << 15) | (regs.sr() >> 1);
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.cy = carry;
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$98-9d(alt0): jmp rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_jmp_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.r[15] = regs.r[n];
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$98-9d(alt1): ljmp rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_ljmp_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.pbr = regs.r[n] & 0x7f;
|
|
|
|
regs.r[15] = regs.sr();
|
|
|
|
regs.cbr = regs.r[15] & 0xfff0;
|
|
|
|
cache_flush();
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$9e: lob
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_lob() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = regs.sr() & 0xff;
|
|
|
|
regs.sfr.s = (regs.dr() & 0x80);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$9f(alt0): fmult
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_fmult() {
|
2010-08-09 13:28:56 +00:00
|
|
|
uint32_t result = (int16_t)regs.sr() * (int16_t)regs.r[6];
|
|
|
|
regs.dr() = result >> 16;
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.cy = (result & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
2015-06-28 08:44:56 +00:00
|
|
|
step((regs.cfgr.ms0 ? 3 : 7) * (regs.clsr ? 1 : 2));
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//$9f(alt1): lmult
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_lmult() {
|
2010-08-09 13:28:56 +00:00
|
|
|
uint32_t result = (int16_t)regs.sr() * (int16_t)regs.r[6];
|
|
|
|
regs.r[4] = result;
|
|
|
|
regs.dr() = result >> 16;
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.cy = (result & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
2015-06-28 08:44:56 +00:00
|
|
|
step((regs.cfgr.ms0 ? 3 : 7) * (regs.clsr ? 1 : 2));
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//$a0-af(alt0): ibt rN,#pp
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_ibt_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.r[n] = (int8)pipe();
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$a0-af(alt1): lms rN,(yy)
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_lms_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.ramaddr = pipe() << 1;
|
|
|
|
uint16_t data;
|
|
|
|
data = rambuffer_read(regs.ramaddr ^ 0) << 0;
|
|
|
|
data |= rambuffer_read(regs.ramaddr ^ 1) << 8;
|
|
|
|
regs.r[n] = data;
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$a0-af(alt2): sms (yy),rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_sms_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.ramaddr = pipe() << 1;
|
|
|
|
rambuffer_write(regs.ramaddr ^ 0, regs.r[n] >> 0);
|
|
|
|
rambuffer_write(regs.ramaddr ^ 1, regs.r[n] >> 8);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$b0-bf(b0): from rN
|
|
|
|
//$b0-bf(b1): moves rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_from_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
if(regs.sfr.b == 0) {
|
|
|
|
regs.sreg = n;
|
|
|
|
} else {
|
|
|
|
regs.dr() = regs.r[n];
|
|
|
|
regs.sfr.ov = (regs.dr() & 0x80);
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//$c0: hib
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_hib() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = regs.sr() >> 8;
|
|
|
|
regs.sfr.s = (regs.dr() & 0x80);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$c1-cf(alt0): or rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_or_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = regs.sr() | regs.r[n];
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$c1-cf(alt1): xor rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_xor_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = regs.sr() ^ regs.r[n];
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$c1-cf(alt2): or #N
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_or_i() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = regs.sr() | n;
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$c1-cf(alt3): xor #N
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_xor_i() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = regs.sr() ^ n;
|
|
|
|
regs.sfr.s = (regs.dr() & 0x8000);
|
|
|
|
regs.sfr.z = (regs.dr() == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$d0-de: inc rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_inc_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.r[n]++;
|
|
|
|
regs.sfr.s = (regs.r[n] & 0x8000);
|
|
|
|
regs.sfr.z = (regs.r[n] == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$df(alt0): getc
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_getc() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.colr = color(rombuffer_read());
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$df(alt2): ramb
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_ramb() {
|
2010-08-09 13:28:56 +00:00
|
|
|
rambuffer_sync();
|
2015-06-28 08:44:56 +00:00
|
|
|
regs.rambr = regs.sr() & 0x01;
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$df(alt3): romb
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_romb() {
|
2010-08-09 13:28:56 +00:00
|
|
|
rombuffer_sync();
|
|
|
|
regs.rombr = regs.sr() & 0x7f;
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$e0-ee: dec rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_dec_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.r[n]--;
|
|
|
|
regs.sfr.s = (regs.r[n] & 0x8000);
|
|
|
|
regs.sfr.z = (regs.r[n] == 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$ef(alt0): getb
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_getb() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = rombuffer_read();
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$ef(alt1): getbh
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_getbh() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = (rombuffer_read() << 8) | (regs.sr() & 0x00ff);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$ef(alt2): getbl
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_getbl() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = (regs.sr() & 0xff00) | (rombuffer_read() << 0);
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$ef(alt3): getbs
|
2015-06-27 02:38:47 +00:00
|
|
|
auto GSU::op_getbs() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.dr() = (int8)rombuffer_read();
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$f0-ff(alt0): iwt rN,#xx
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_iwt_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
uint16_t data;
|
|
|
|
data = pipe() << 0;
|
|
|
|
data |= pipe() << 8;
|
|
|
|
regs.r[n] = data;
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$f0-ff(alt1): lm rN,(xx)
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_lm_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.ramaddr = pipe() << 0;
|
|
|
|
regs.ramaddr |= pipe() << 8;
|
|
|
|
uint16_t data;
|
|
|
|
data = rambuffer_read(regs.ramaddr ^ 0) << 0;
|
|
|
|
data |= rambuffer_read(regs.ramaddr ^ 1) << 8;
|
|
|
|
regs.r[n] = data;
|
|
|
|
regs.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
//$f0-ff(alt2): sm (xx),rN
|
2015-06-27 02:38:47 +00:00
|
|
|
template<int n>
|
|
|
|
auto GSU::op_sm_r() {
|
2010-08-09 13:28:56 +00:00
|
|
|
regs.ramaddr = pipe() << 0;
|
|
|
|
regs.ramaddr |= pipe() << 8;
|
|
|
|
rambuffer_write(regs.ramaddr ^ 0, regs.r[n] >> 0);
|
|
|
|
rambuffer_write(regs.ramaddr ^ 1, regs.r[n] >> 8);
|
|
|
|
regs.reset();
|
|
|
|
}
|