Commit e7806dd6 by Screwtape

Update to v102r27 release.

byuu says:

Changelog:

  - processor/gsu: minor code cleanup
  - processor/hg51b: renamed reg(Read,Write) to register(Read,Write)
  - processor/lr35902: minor code cleanup
  - processor/spc700: completed code cleanup (sans disassembler)
      - no longer uses internal global state inside instructions
  - processor/spc700: will no longer hang the emulator if stuck in a WAI
    (SLEEP) or STP (STOP) instruction
  - processor/spc700: fixed bug in handling of OR1 and AND1 instructions
  - processor/z80: minor code cleanup
  - sfc/dsp: revert to initializing registers to 0x00; save for
    ENDX=random(), FLG=0xe0 [Jonas Quinn]

Major testing of the SNES game library would be appreciated, now that
its CPU cores have all been revised.

We know the DSP registers read back as randomized data ... mostly, but
there are apparently internal latches, which we can't emulate with the
current DSP design. So until we know which registers have separate
internal state that actually *is* initialized, I'm going to play it safe
and not break more games.

Thanks again to Jonas Quinn for the continued research into this issue.

EDIT: that said ... `MD works if((ENDX&0x30) > 0)` is only a 3:4 chance
that the game will work. That seems pretty unlikely that the odds of it
working are that low, given hardware testing by others in the past :/ I
thought if worked if `PITCH != 0` before, which would have been way more
likely.

The two remaining CPU cores that need major cleanup efforts are the
LR35902 and ARM cores. Both are very large, complicated, annoying cores
that will probably be better off as full rewrites from scratch. I don't
think I want to delay v103 in trying to accomplish that, however.

So I think it'll be best to focus on allowing the Mega Drive core to not
lock when processors are frozen waiting on a response from other
processors during a save state operation. Then we should be good for a
new release.
parent 50411a17
Pipeline #9115621 failed with stage
in 15 minutes 0 seconds
......@@ -12,7 +12,7 @@ using namespace nall;
namespace Emulator {
static const string Name = "higan";
static const string Version = "102.26";
static const string Version = "102.27";
static const string Author = "byuu";
static const string License = "GPLv3";
static const string Website = "http://byuu.org/";
......
......@@ -2,10 +2,10 @@ auto GSU::disassembleOpcode(char* output) -> void {
*output = 0;
switch(regs.sfr.alt2 << 1 | regs.sfr.alt1 << 0) {
case 0: disassembleAlt0(output); break;
case 1: disassembleAlt1(output); break;
case 2: disassembleAlt2(output); break;
case 3: disassembleAlt3(output); break;
case 0: disassembleALT0(output); break;
case 1: disassembleALT1(output); break;
case 2: disassembleALT2(output); break;
case 3: disassembleALT3(output); break;
}
uint length = strlen(output);
......@@ -30,7 +30,7 @@ auto GSU::disassembleOpcode(char* output) -> void {
#define op1 read((regs.pbr << 16) + regs.r[15] + 0)
#define op2 read((regs.pbr << 16) + regs.r[15] + 1)
auto GSU::disassembleAlt0(char* output) -> void {
auto GSU::disassembleALT0(char* output) -> void {
char t[256] = "";
switch(op0) {
case (0x00): sprintf(t, "stop"); break;
......@@ -87,7 +87,7 @@ auto GSU::disassembleAlt0(char* output) -> void {
strcat(output, t);
}
auto GSU::disassembleAlt1(char* output) -> void {
auto GSU::disassembleALT1(char* output) -> void {
char t[256] = "";
switch(op0) {
case (0x00): sprintf(t, "stop"); break;
......@@ -144,7 +144,7 @@ auto GSU::disassembleAlt1(char* output) -> void {
strcat(output, t);
}
auto GSU::disassembleAlt2(char* output) -> void {
auto GSU::disassembleALT2(char* output) -> void {
char t[256] = "";
switch(op0) {
case (0x00): sprintf(t, "stop"); break;
......@@ -201,7 +201,7 @@ auto GSU::disassembleAlt2(char* output) -> void {
strcat(output, t);
}
auto GSU::disassembleAlt3(char* output) -> void {
auto GSU::disassembleALT3(char* output) -> void {
char t[256] = "";
switch(op0) {
case (0x00): sprintf(t, "stop"); break;
......
......@@ -7,8 +7,8 @@
namespace Processor {
#include "instruction.cpp"
#include "instructions.cpp"
#include "switch.cpp"
#include "serialization.cpp"
#include "disassembler.cpp"
......
......@@ -27,46 +27,46 @@ struct GSU {
auto power() -> void;
//instructions.cpp
auto op_add_adc(uint n);
auto op_alt1();
auto op_alt2();
auto op_alt3();
auto op_and_bic(uint n);
auto op_asr_div2();
auto op_branch(bool c);
auto op_cache();
auto op_color_cmode();
auto op_dec(uint n);
auto op_fmult_lmult();
auto op_from_moves(uint n);
auto op_getb();
auto op_getc_ramb_romb();
auto op_hib();
auto op_ibt_lms_sms(uint n);
auto op_inc(uint n);
auto op_iwt_lm_sm(uint n);
auto op_jmp_ljmp(uint n);
auto op_link(uint n);
auto op_load(uint n);
auto op_lob();
auto op_loop();
auto op_lsr();
auto op_merge();
auto op_mult_umult(uint n);
auto op_nop();
auto op_not();
auto op_or_xor(uint n);
auto op_plot_rpix();
auto op_rol();
auto op_ror();
auto op_sbk();
auto op_sex();
auto op_store(uint n);
auto op_stop();
auto op_sub_sbc_cmp(uint n);
auto op_swap();
auto op_to_move(uint n);
auto op_with(uint n);
auto instructionADD_ADC(uint n) -> void;
auto instructionALT1() -> void;
auto instructionALT2() -> void;
auto instructionALT3() -> void;
auto instructionAND_BIC(uint n) -> void;
auto instructionASR_DIV2() -> void;
auto instructionBranch(bool c) -> void;
auto instructionCACHE() -> void;
auto instructionCOLOR_CMODE() -> void;
auto instructionDEC(uint n) -> void;
auto instructionFMULT_LMULT() -> void;
auto instructionFROM_MOVES(uint n) -> void;
auto instructionGETB() -> void;
auto instructionGETC_RAMB_ROMB() -> void;
auto instructionHIB() -> void;
auto instructionIBT_LMS_SMS(uint n) -> void;
auto instructionINC(uint n) -> void;
auto instructionIWT_LM_SM(uint n) -> void;
auto instructionJMP_LJMP(uint n) -> void;
auto instructionLINK(uint n) -> void;
auto instructionLoad(uint n) -> void;
auto instructionLOB() -> void;
auto instructionLOOP() -> void;
auto instructionLSR() -> void;
auto instructionMERGE() -> void;
auto instructionMULT_UMULT(uint n) -> void;
auto instructionNOP() -> void;
auto instructionNOT() -> void;
auto instructionOR_XOR(uint n) -> void;
auto instructionPLOT_RPIX() -> void;
auto instructionROL() -> void;
auto instructionROR() -> void;
auto instructionSBK() -> void;
auto instructionSEX() -> void;
auto instructionStore(uint n) -> void;
auto instructionSTOP() -> void;
auto instructionSUB_SBC_CMP(uint n) -> void;
auto instructionSWAP() -> void;
auto instructionTO_MOVE(uint n) -> void;
auto instructionWITH(uint n) -> void;
//switch.cpp
auto instruction(uint8 opcode) -> void;
......@@ -76,10 +76,10 @@ struct GSU {
//disassembler.cpp
auto disassembleOpcode(char* output) -> void;
auto disassembleAlt0(char* output) -> void;
auto disassembleAlt1(char* output) -> void;
auto disassembleAlt2(char* output) -> void;
auto disassembleAlt3(char* output) -> void;
auto disassembleALT0(char* output) -> void;
auto disassembleALT1(char* output) -> void;
auto disassembleALT2(char* output) -> void;
auto disassembleALT3(char* output) -> void;
};
}
auto GSU::instruction(uint8 opcode) -> void {
#define op(id, name, ...) \
case id: return instruction##name(__VA_ARGS__); \
#define op4(id, name) \
case id+ 0: return instruction##name((uint4)opcode); \
case id+ 1: return instruction##name((uint4)opcode); \
case id+ 2: return instruction##name((uint4)opcode); \
case id+ 3: return instruction##name((uint4)opcode); \
#define op6(id, name) \
op4(id, name) \
case id+ 4: return instruction##name((uint4)opcode); \
case id+ 5: return instruction##name((uint4)opcode); \
#define op12(id, name) \
op6(id, name) \
case id+ 6: return instruction##name((uint4)opcode); \
case id+ 7: return instruction##name((uint4)opcode); \
case id+ 8: return instruction##name((uint4)opcode); \
case id+ 9: return instruction##name((uint4)opcode); \
case id+10: return instruction##name((uint4)opcode); \
case id+11: return instruction##name((uint4)opcode); \
#define op15(id, name) \
op12(id, name) \
case id+12: return instruction##name((uint4)opcode); \
case id+13: return instruction##name((uint4)opcode); \
case id+14: return instruction##name((uint4)opcode); \
#define op16(id, name) \
op15(id, name) \
case id+15: return instruction##name((uint4)opcode); \
switch(opcode) {
op (0x00, STOP)
op (0x01, NOP)
op (0x02, CACHE)
op (0x03, LSR)
op (0x04, ROL)
op (0x05, Branch, 1) //bra
op (0x06, Branch, (regs.sfr.s ^ regs.sfr.ov) == 0) //blt
op (0x07, Branch, (regs.sfr.s ^ regs.sfr.ov) == 1) //bge
op (0x08, Branch, regs.sfr.z == 0) //bne
op (0x09, Branch, regs.sfr.z == 1) //beq
op (0x0a, Branch, regs.sfr.s == 0) //bpl
op (0x0b, Branch, regs.sfr.s == 1) //bmi
op (0x0c, Branch, regs.sfr.cy == 0) //bcc
op (0x0d, Branch, regs.sfr.cy == 1) //bcs
op (0x0e, Branch, regs.sfr.ov == 0) //bvc
op (0x0f, Branch, regs.sfr.ov == 1) //bvs
op16(0x10, TO_MOVE)
op16(0x20, WITH)
op12(0x30, Store)
op (0x3c, LOOP)
op (0x3d, ALT1)
op (0x3e, ALT2)
op (0x3f, ALT3)
op12(0x40, Load)
op (0x4c, PLOT_RPIX)
op (0x4d, SWAP)
op (0x4e, COLOR_CMODE)
op (0x4f, NOT)
op16(0x50, ADD_ADC)
op16(0x60, SUB_SBC_CMP)
op (0x70, MERGE)
op15(0x71, AND_BIC)
op16(0x80, MULT_UMULT)
op (0x90, SBK)
op4 (0x91, LINK)
op (0x95, SEX)
op (0x96, ASR_DIV2)
op (0x97, ROR)
op6 (0x98, JMP_LJMP)
op (0x9e, LOB)
op (0x9f, FMULT_LMULT)
op16(0xa0, IBT_LMS_SMS)
op16(0xb0, FROM_MOVES)
op (0xc0, HIB)
op15(0xc1, OR_XOR)
op15(0xd0, INC)
op (0xdf, GETC_RAMB_ROMB)
op15(0xe0, DEC)
op (0xef, GETB)
op16(0xf0, IWT_LM_SM)
}
#undef op
#undef op4
#undef op6
#undef op12
#undef op15
#undef op16
}
//$00 stop
auto GSU::op_stop() {
auto GSU::instructionSTOP() -> void {
if(regs.cfgr.irq == 0) {
regs.sfr.irq = 1;
stop();
......@@ -10,12 +10,12 @@ auto GSU::op_stop() {
}
//$01 nop
auto GSU::op_nop() {
auto GSU::instructionNOP() -> void {
regs.reset();
}
//$02 cache
auto GSU::op_cache() {
auto GSU::instructionCACHE() -> void {
if(regs.cbr != (regs.r[15] & 0xfff0)) {
regs.cbr = regs.r[15] & 0xfff0;
flushCache();
......@@ -24,7 +24,7 @@ auto GSU::op_cache() {
}
//$03 lsr
auto GSU::op_lsr() {
auto GSU::instructionLSR() -> void {
regs.sfr.cy = (regs.sr() & 1);
regs.dr() = regs.sr() >> 1;
regs.sfr.s = (regs.dr() & 0x8000);
......@@ -33,7 +33,7 @@ auto GSU::op_lsr() {
}
//$04 rol
auto GSU::op_rol() {
auto GSU::instructionROL() -> void {
bool carry = (regs.sr() & 0x8000);
regs.dr() = (regs.sr() << 1) | regs.sfr.cy;
regs.sfr.s = (regs.dr() & 0x8000);
......@@ -53,14 +53,14 @@ auto GSU::op_rol() {
//$0d bcs e
//$0e bvc e
//$0f bvs e
auto GSU::op_branch(bool c) {
auto d = (int8)pipe();
if(c) regs.r[15] += d;
auto GSU::instructionBranch(bool take) -> void {
auto displacement = (int8)pipe();
if(take) regs.r[15] += displacement;
}
//$10-1f(b0) to rN
//$10-1f(b1) move rN
auto GSU::op_to_move(uint n) {
auto GSU::instructionTO_MOVE(uint n) -> void {
if(!regs.sfr.b) {
regs.dreg = n;
} else {
......@@ -70,7 +70,7 @@ auto GSU::op_to_move(uint n) {
}
//$20-2f with rN
auto GSU::op_with(uint n) {
auto GSU::instructionWITH(uint n) -> void {
regs.sreg = n;
regs.dreg = n;
regs.sfr.b = 1;
......@@ -78,7 +78,7 @@ auto GSU::op_with(uint n) {
//$30-3b(alt0) stw (rN)
//$30-3b(alt1) stb (rN)
auto GSU::op_store(uint n) {
auto GSU::instructionStore(uint n) -> void {
regs.ramaddr = regs.r[n];
writeRAMBuffer(regs.ramaddr, regs.sr());
if(!regs.sfr.alt1) writeRAMBuffer(regs.ramaddr ^ 1, regs.sr() >> 8);
......@@ -86,7 +86,7 @@ auto GSU::op_store(uint n) {
}
//$3c loop
auto GSU::op_loop() {
auto GSU::instructionLOOP() -> void {
regs.r[12]--;
regs.sfr.s = (regs.r[12] & 0x8000);
regs.sfr.z = (regs.r[12] == 0);
......@@ -95,19 +95,19 @@ auto GSU::op_loop() {
}
//$3d alt1
auto GSU::op_alt1() {
auto GSU::instructionALT1() -> void {
regs.sfr.b = 0;
regs.sfr.alt1 = 1;
}
//$3e alt2
auto GSU::op_alt2() {
auto GSU::instructionALT2() -> void {
regs.sfr.b = 0;
regs.sfr.alt2 = 1;
}
//$3f alt3
auto GSU::op_alt3() {
auto GSU::instructionALT3() -> void {
regs.sfr.b = 0;
regs.sfr.alt1 = 1;
regs.sfr.alt2 = 1;
......@@ -115,7 +115,7 @@ auto GSU::op_alt3() {
//$40-4b(alt0) ldw (rN)
//$40-4b(alt1) ldb (rN)
auto GSU::op_load(uint n) {
auto GSU::instructionLoad(uint n) -> void {
regs.ramaddr = regs.r[n];
regs.dr() = readRAMBuffer(regs.ramaddr);
if(!regs.sfr.alt1) regs.dr() |= readRAMBuffer(regs.ramaddr ^ 1) << 8;
......@@ -124,7 +124,7 @@ auto GSU::op_load(uint n) {
//$4c(alt0) plot
//$4c(alt1) rpix
auto GSU::op_plot_rpix() {
auto GSU::instructionPLOT_RPIX() -> void {
if(!regs.sfr.alt1) {
plot(regs.r[1], regs.r[2]);
regs.r[1]++;
......@@ -137,8 +137,8 @@ auto GSU::op_plot_rpix() {
}
//$4d swap
auto GSU::op_swap() {
regs.dr() = (regs.sr() >> 8) | (regs.sr() << 8);
auto GSU::instructionSWAP() -> void {
regs.dr() = regs.sr() >> 8 | regs.sr() << 8;
regs.sfr.s = (regs.dr() & 0x8000);
regs.sfr.z = (regs.dr() == 0);
regs.reset();
......@@ -146,7 +146,7 @@ auto GSU::op_swap() {
//$4e(alt0) color
//$4e(alt1) cmode
auto GSU::op_color_cmode() {
auto GSU::instructionCOLOR_CMODE() -> void {
if(!regs.sfr.alt1) {
regs.colr = color(regs.sr());
} else {
......@@ -156,7 +156,7 @@ auto GSU::op_color_cmode() {
}
//$4f not
auto GSU::op_not() {
auto GSU::instructionNOT() -> void {
regs.dr() = ~regs.sr();
regs.sfr.s = (regs.dr() & 0x8000);
regs.sfr.z = (regs.dr() == 0);
......@@ -167,7 +167,7 @@ auto GSU::op_not() {
//$50-5f(alt1) adc rN
//$50-5f(alt2) add #N
//$50-5f(alt3) adc #N
auto GSU::op_add_adc(uint n) {
auto GSU::instructionADD_ADC(uint n) -> void {
if(!regs.sfr.alt2) n = regs.r[n];
int r = regs.sr() + n + (regs.sfr.alt1 ? regs.sfr.cy : 0);
regs.sfr.ov = ~(regs.sr() ^ n) & (n ^ r) & 0x8000;
......@@ -182,7 +182,7 @@ auto GSU::op_add_adc(uint n) {
//$60-6f(alt1) sbc rN
//$60-6f(alt2) sub #N
//$60-6f(alt3) cmp rN
auto GSU::op_sub_sbc_cmp(uint n) {
auto GSU::instructionSUB_SBC_CMP(uint n) -> void {
if(!regs.sfr.alt2 || regs.sfr.alt1) n = regs.r[n];
int r = regs.sr() - n - (!regs.sfr.alt2 && regs.sfr.alt1 ? !regs.sfr.cy : 0);
regs.sfr.ov = (regs.sr() ^ n) & (regs.sr() ^ r) & 0x8000;
......@@ -194,7 +194,7 @@ auto GSU::op_sub_sbc_cmp(uint n) {
}
//$70 merge
auto GSU::op_merge() {
auto GSU::instructionMERGE() -> void {
regs.dr() = (regs.r[7] & 0xff00) | (regs.r[8] >> 8);
regs.sfr.ov = (regs.dr() & 0xc0c0);
regs.sfr.s = (regs.dr() & 0x8080);
......@@ -207,7 +207,7 @@ auto GSU::op_merge() {
//$71-7f(alt1) bic rN
//$71-7f(alt2) and #N
//$71-7f(alt3) bic #N
auto GSU::op_and_bic(uint n) {
auto GSU::instructionAND_BIC(uint n) -> void {
if(!regs.sfr.alt2) n = regs.r[n];
regs.dr() = regs.sr() & (regs.sfr.alt1 ? ~n : n);
regs.sfr.s = (regs.dr() & 0x8000);
......@@ -219,7 +219,7 @@ auto GSU::op_and_bic(uint n) {
//$80-8f(alt1) umult rN
//$80-8f(alt2) mult #N
//$80-8f(alt3) umult #N
auto GSU::op_mult_umult(uint n) {
auto GSU::instructionMULT_UMULT(uint n) -> void {
if(!regs.sfr.alt2) n = regs.r[n];
regs.dr() = (!regs.sfr.alt1 ? ((int8)regs.sr() * (int8)n) : ((uint8)regs.sr() * (uint8)n));
regs.sfr.s = (regs.dr() & 0x8000);
......@@ -229,20 +229,20 @@ auto GSU::op_mult_umult(uint n) {
}
//$90 sbk
auto GSU::op_sbk() {
auto GSU::instructionSBK() -> void {
writeRAMBuffer(regs.ramaddr ^ 0, regs.sr() >> 0);
writeRAMBuffer(regs.ramaddr ^ 1, regs.sr() >> 8);
regs.reset();
}
//$91-94 link #N
auto GSU::op_link(uint n) {
auto GSU::instructionLINK(uint n) -> void {
regs.r[11] = regs.r[15] + n;
regs.reset();
}
//$95 sex
auto GSU::op_sex() {
auto GSU::instructionSEX() -> void {
regs.dr() = (int8)regs.sr();
regs.sfr.s = (regs.dr() & 0x8000);
regs.sfr.z = (regs.dr() == 0);
......@@ -251,7 +251,7 @@ auto GSU::op_sex() {
//$96(alt0) asr
//$96(alt1) div2
auto GSU::op_asr_div2() {
auto GSU::instructionASR_DIV2() -> void {
regs.sfr.cy = (regs.sr() & 1);
regs.dr() = ((int16)regs.sr() >> 1) + (regs.sfr.alt1 ? ((regs.sr() + 1) >> 16) : 0);
regs.sfr.s = (regs.dr() & 0x8000);
......@@ -260,7 +260,7 @@ auto GSU::op_asr_div2() {
}
//$97 ror
auto GSU::op_ror() {
auto GSU::instructionROR() -> void {
bool carry = (regs.sr() & 1);
regs.dr() = (regs.sfr.cy << 15) | (regs.sr() >> 1);
regs.sfr.s = (regs.dr() & 0x8000);
......@@ -271,7 +271,7 @@ auto GSU::op_ror() {
//$98-9d(alt0) jmp rN
//$98-9d(alt1) ljmp rN
auto GSU::op_jmp_ljmp(uint n) {
auto GSU::instructionJMP_LJMP(uint n) -> void {
if(!regs.sfr.alt1) {
regs.r[15] = regs.r[n];
} else {
......@@ -284,7 +284,7 @@ auto GSU::op_jmp_ljmp(uint n) {
}
//$9e lob
auto GSU::op_lob() {
auto GSU::instructionLOB() -> void {
regs.dr() = regs.sr() & 0xff;
regs.sfr.s = (regs.dr() & 0x80);
regs.sfr.z = (regs.dr() == 0);
......@@ -293,7 +293,7 @@ auto GSU::op_lob() {
//$9f(alt0) fmult
//$9f(alt1) lmult
auto GSU::op_fmult_lmult() {
auto GSU::instructionFMULT_LMULT() -> void {
uint32 result = (int16)regs.sr() * (int16)regs.r[6];
if(regs.sfr.alt1) regs.r[4] = result;
regs.dr() = result >> 16;
......@@ -307,7 +307,7 @@ auto GSU::op_fmult_lmult() {
//$a0-af(alt0) ibt rN,#pp
//$a0-af(alt1) lms rN,(yy)
//$a0-af(alt2) sms (yy),rN
auto GSU::op_ibt_lms_sms(uint n) {
auto GSU::instructionIBT_LMS_SMS(uint n) -> void {
if(regs.sfr.alt1) {
regs.ramaddr = pipe() << 1;
uint8 lo = readRAMBuffer(regs.ramaddr ^ 0) << 0;
......@@ -324,7 +324,7 @@ auto GSU::op_ibt_lms_sms(uint n) {
//$b0-bf(b0) from rN
//$b0-bf(b1) moves rN
auto GSU::op_from_moves(uint n) {
auto GSU::instructionFROM_MOVES(uint n) -> void {
if(!regs.sfr.b) {
regs.sreg = n;
} else {
......@@ -337,7 +337,7 @@ auto GSU::op_from_moves(uint n) {
}
//$c0 hib
auto GSU::op_hib() {
auto GSU::instructionHIB() -> void {
regs.dr() = regs.sr() >> 8;
regs.sfr.s = (regs.dr() & 0x80);
regs.sfr.z = (regs.dr() == 0);
......@@ -348,7 +348,7 @@ auto GSU::op_hib() {
//$c1-cf(alt1) xor rN
//$c1-cf(alt2) or #N
//$c1-cf(alt3) xor #N
auto GSU::op_or_xor(uint n) {
auto GSU::instructionOR_XOR(uint n) -> void {
if(!regs.sfr.alt2) n = regs.r[n];
regs.dr() = (!regs.sfr.alt1 ? (regs.sr() | n) : (regs.sr() ^ n));
regs.sfr.s = (regs.dr() & 0x8000);
......@@ -357,7 +357,7 @@ auto GSU::op_or_xor(uint n) {
}
//$d0-de inc rN
auto GSU::op_inc(uint n) {
auto GSU::instructionINC(uint n) -> void {
regs.r[n]++;
regs.sfr.s = (regs.r[n] & 0x8000);
regs.sfr.z = (regs.r[n] == 0);
......@@ -367,7 +367,7 @@ auto GSU::op_inc(uint n) {
//$df(alt0) getc
//$df(alt2) ramb
//$df(alt3) romb
auto GSU::op_getc_ramb_romb() {
auto GSU::instructionGETC_RAMB_ROMB() -> void {
if(!regs.sfr.alt2) {
regs.colr = color(readROMBuffer());
} else if(!regs.sfr.alt1) {
......@@ -381,7 +381,7 @@ auto GSU::op_getc_ramb_romb() {
}
//$e0-ee dec rN
auto GSU::op_dec(uint n) {
auto GSU::instructionDEC(uint n) -> void {
regs.r[n]--;
regs.sfr.s = (regs.r[n] & 0x8000);
regs.sfr.z = (regs.r[n] == 0);
......@@ -392,7 +392,7 @@ auto GSU::op_dec(uint n) {
//$ef(alt1) getbh
//$ef(alt2) getbl
//$ef(alt3) getbs
auto GSU::op_getb() {
auto GSU::instructionGETB() -> void {
switch(regs.sfr.alt2 << 1 | regs.sfr.alt1 << 0) {
case 0: regs.dr() = readROMBuffer(); break;
case 1: regs.dr() = readROMBuffer() << 8 | (uint8)regs.sr(); break;
......@@ -405,7 +405,7 @@ auto GSU::op_getb() {
//$f0-ff(alt0) iwt rN,#xx
//$f0-ff(alt1) lm rN,(xx)
//$f0-ff(alt2) sm (xx),rN
auto GSU::op_iwt_lm_sm(uint n) {
auto GSU::instructionIWT_LM_SM(uint n) -> void {
if(regs.sfr.alt1) {
regs.ramaddr = pipe() << 0;
regs.ramaddr |= pipe() << 8;
......
auto GSU::instruction(uint8 opcode) -> void {
#define op(id, name, ...) \
case id: return op_##name(__VA_ARGS__); \
#define op4(id, name) \
case id+ 0: return op_##name((uint4)opcode); \
case id+ 1: return op_##name((uint4)opcode); \
case id+ 2: return op_##name((uint4)opcode); \
case id+ 3: return op_##name((uint4)opcode); \
#define op6(id, name) \
op4(id, name) \
case id+ 4: return op_##name((uint4)opcode); \
case id+ 5: return op_##name((uint4)opcode); \
#define op12(id, name) \
op6(id, name) \
case id+ 6: return op_##name((uint4)opcode); \
case id+ 7: return op_##name((uint4)opcode); \
case id+ 8: return op_##name((uint4)opcode); \
case id+ 9: return op_##name((uint4)opcode); \
case id+10: return op_##name((uint4)opcode); \
case id+11: return op_##name((uint4)opcode); \
#define op15(id, name) \
op12(id, name) \
case id+12: return op_##name((uint4)opcode); \
case id+13: return op_##name((uint4)opcode); \
case id+14: return op_##name((uint4)opcode); \
#define op16(id, name) \
op15(id, name) \
case id+15: return op_##name((uint4)opcode); \
switch(opcode) {
op (0x00, stop)
op (0x01, nop)
op (0x02, cache)
op (0x03, lsr)
op (0x04, rol)
op (0x05, branch, 1) //bra
op (0x06, branch, (regs.sfr.s ^ regs.sfr.ov) == 0) //blt
op (0x07, branch, (regs.sfr.s ^ regs.sfr.ov) == 1) //bge
op (0x08, branch, regs.sfr.z == 0) //bne
op (0x09, branch, regs.sfr.z == 1) //beq
op (0x0a, branch, regs.sfr.s == 0) //bpl
op (0x0b, branch, regs.sfr.s == 1) //bmi
op (0x0c, branch, regs.sfr.cy == 0) //bcc
op (0x0d, branch, regs.sfr.cy == 1) //bcs
op (0x0e, branch, regs.sfr.ov == 0) //bvc
op (0x0f, branch, regs.sfr.ov == 1) //bvs
op16(0x10, to_move)
op16(0x20, with)
op12(0x30, store)
op (0x3c, loop)
op (0x3d, alt1)
op (0x3e, alt2)
op (0x3f, alt3)
op12(0x40, load)
op (0x4c, plot_rpix)
op (0x4d, swap)
op (0x4e, color_cmode)
op (0x4f, not)
op16(0x50, add_adc)
op16(0x60, sub_sbc_cmp)
op (0x70, merge)
op15(0x71, and_bic)
op16(0x80, mult_umult)
op (0x90, sbk)
op4 (0x91, link)
op (0x95, sex)
op (0x96, asr_div2)
op (0x97, ror)
op6 (0x98, jmp_ljmp)
op (0x9e, lob)
op (0x9f, fmult_lmult)
op16(0xa0, ibt_lms_sms)
op16(0xb0, from_moves)
op (0xc0, hib)
op15(0xc1, or_xor)
op15(0xd0, inc)