summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/saturn/saturnds.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/saturn/saturnds.c')
-rw-r--r--trunk/src/emu/cpu/saturn/saturnds.c1486
1 files changed, 1486 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/saturn/saturnds.c b/trunk/src/emu/cpu/saturn/saturnds.c
new file mode 100644
index 00000000000..e0889250027
--- /dev/null
+++ b/trunk/src/emu/cpu/saturn/saturnds.c
@@ -0,0 +1,1486 @@
+/*****************************************************************************
+ *
+ * saturnds.c
+ * portable saturn emulator interface
+ * (hp calculators)
+ *
+ * Copyright Peter Trauner, all rights reserved.
+ *
+ * Modified by Antoine Mine'
+ *
+ * - This source code is released as freeware for non-commercial purposes.
+ * - You are free to use and redistribute this code in modified or
+ * unmodified form, provided you list me in the credits.
+ * - If you modify this source code, you must add a notice to each modified
+ * source file that it has been changed. If you're a nice person, you
+ * will clearly mark each change too. :)
+ * - If you wish to use this for commercial purposes, please contact me at
+ * peter.trauner@jk.uni-linz.ac.at
+ * - The author of this copywritten work reserves the right to change the
+ * terms of its usage and license at any time, including retroactively
+ * - This entire notice must remain in the source code.
+ *
+ *****************************************************************************/
+
+#include "emu.h"
+#include "debugger.h"
+
+#include "saturn.h"
+
+#define SATURN_HP_MNEMONICS
+
+#if defined SATURN_HP_MNEMONICS
+// class/hp mnemonics
+static int set=0;
+#else
+// readable/normal mnemonics
+static int set=1;
+#endif
+
+#define P "P"
+#define WP "WP"
+#define XS "XS"
+#define X "X"
+#define S "S"
+#define M "M"
+#define B "B"
+#define W "W"
+#define A "A"
+
+static const char *const adr_b[]=
+{ P, WP, XS, X, S, M, B, W };
+
+static const char *const adr_af[]=
+{ P, WP, XS, X, S, M, B, W, 0, 0, 0, 0, 0, 0, 0, A };
+
+static const char *const adr_a[]=
+ { P, WP, XS, X, S, M, B, W };
+
+static const char number_2_hex[]=
+{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+#define SATURN_PEEKOP_DIS8(v) v = (INT8)( oprom[pos] | ( oprom[pos+1] << 4 ) ); pos+= 2;
+
+#define SATURN_PEEKOP_DIS12(v) v = oprom[pos] | ( oprom[pos+1] << 4 ) | ( oprom[pos+2] << 8 ); \
+ pos += 3; \
+ if ( v & 0x0800 ) v = -0x1000 + v;
+
+#define SATURN_PEEKOP_DIS16(v) v = (INT16)( oprom[pos] | ( oprom[pos+1] << 4 ) | ( oprom[pos+2] << 8 ) | ( oprom[pos+3] << 12 ) ); pos += 4;
+
+#define SATURN_PEEKOP_ADR(v) v = oprom[pos] | ( oprom[pos+1] << 4 ) | ( oprom[pos+2] << 8 ) | ( oprom[pos+3] << 12 ) | ( oprom[pos+4] << 16 ); pos += 5;
+
+
+// don't split branch and return, source relies on this ordering
+typedef enum
+{
+ Return, ReturnSetXM, ReturnSetCarry, ReturnClearCarry, ReturnFromInterrupt,
+ jump3,jump4,jump,
+ call3,call4,call,
+ branchCarrySet, returnCarrySet,
+ branchCarryClear, returnCarryClear,
+
+ outCS, outC, inA, inC,
+ unconfig, config, Cid, shutdown, cp1, reset, buscc,
+ CcopyP, PcopyC, sreq, CswapP,
+
+ inton, AloadImm, buscb,
+ clearAbit, setAbit,
+ branchAbitclear, returnAbitclear,
+ branchAbitset, returnAbitset,
+ clearCbit, setCbit,
+ branchCbitclear, returnCbitclear,
+ branchCbitset, returnCbitset,
+ PCloadA, buscd, PCloadC, intoff, rsi,
+
+ jumpA, jumpC, PCcopyA, PCcopyC, AcopyPC, CcopyPC,
+
+ clearHST,
+ branchHSTclear, returnHSTclear,
+
+ clearBitST, setBitST,
+ branchSTclear, returnSTclear,
+ branchSTset, returnSTset,
+
+
+ branchPdiffers, returnPdiffers,
+ branchPequals, returnPequals,
+
+ branchAequalsB, returnAequalsB,
+ branchBequalsC, returnBequalsC,
+ branchAequalsC, returnAequalsC,
+ branchCequalsD, returnCequalsD,
+ branchAdiffersB, returnAdiffersB,
+ branchBdiffersC, returnBdiffersC,
+ branchAdiffersC, returnAdiffersC,
+ branchCdiffersD, returnCdiffersD,
+ branchAzero, returnAzero,
+ branchBzero, returnBzero,
+ branchCzero, returnCzero,
+ branchDzero, returnDzero,
+ branchAnotzero, returnAnotzero,
+ branchBnotzero, returnBnotzero,
+ branchCnotzero, returnCnotzero,
+ branchDnotzero, returnDnotzero,
+
+ branchAgreaterB, returnAgreaterB,
+ branchBgreaterC, returnBgreaterC,
+ branchCgreaterA, returnCgreaterA,
+ branchDgreaterC, returnDgreaterC,
+ branchAlowerB, returnAlowerB,
+ branchBlowerC, returnBlowerC,
+ branchClowerA, returnClowerA,
+ branchDlowerC, returnDlowerC,
+ branchAnotlowerB, returnAnotlowerB,
+ branchBnotlowerC, returnBnotlowerC,
+ branchCnotlowerA, returnCnotlowerA,
+ branchDnotlowerC, returnDnotlowerC,
+ branchAnotgreaterB, returnAnotgreaterB,
+ branchBnotgreaterC, returnBnotgreaterC,
+ branchCnotgreaterA, returnCnotgreaterA,
+ branchDnotgreaterC, returnDnotgreaterC,
+
+ SetHexMode, SetDecMode,
+ PushC, PopC,
+
+ D0loadImm2, D0loadImm4, D0loadImm5,
+ D1loadImm2, D1loadImm4, D1loadImm5,
+ PloadImm, CloadImm,
+
+ clearST,
+ CcopyST, STcopyC,
+ swapCST,
+
+ incP, decP,
+
+ R0copyA, R1copyA, R2copyA, R3copyA, R4copyA,
+ R0copyC, R1copyC, R2copyC, R3copyC, R4copyC,
+
+ AcopyR0, AcopyR1, AcopyR2, AcopyR3, AcopyR4,
+ CcopyR0, CcopyR1, CcopyR2, CcopyR3, CcopyR4,
+
+ D0copyA, D1copyA, D0copyC, D1copyC,
+ D0copyAShort, D1copyAShort, D0copyCShort, D1copyCShort, // other class mnemonic
+
+ SwapAR0, SwapAR1, SwapAR2, SwapAR3, SwapAR4,
+ SwapCR0, SwapCR1, SwapCR2, SwapCR3, SwapCR4,
+
+ SwapAD0, SwapAD1, SwapCD0, SwapCD1,
+ SwapAD0Short, SwapAD1Short, SwapCD0Short, SwapCD1Short, // other class mnemonic
+
+ D0storeA, D1storeA, D0storeC, D1storeC,
+ AloadD0, AloadD1, CloadD0, CloadD1,
+
+ D0addImm, D1addImm, D0subImm, D1subImm,
+ AaddImm, BaddImm, CaddImm, DaddImm,
+ AsubImm, BsubImm, CsubImm, DsubImm,
+
+ AandB, BandC, CandA, DandC, BandA, CandB, AandC, CandD,
+ AorB, BorC, CorA, DorC, BorA, CorB, AorC, CorD,
+
+ Ashiftrightbit, Bshiftrightbit, Cshiftrightbit, Dshiftrightbit,
+
+ AshiftleftCarry, BshiftleftCarry, CshiftleftCarry, DshiftleftCarry,
+ AshiftrightCarry, BshiftrightCarry, CshiftrightCarry, DshiftrightCarry,
+
+ AaddB, BaddC, CaddA, DaddC, AaddA, BaddB, CaddC, DaddD,
+ BaddA, CaddB, AaddC, CaddD, decA, decB, decC, decD,
+
+ AsubB, BsubC, CsubA, DsubC, incA, incB, incC, incD,
+ BsubA, CsubB, AsubC, CsubD, AsubnB, BsubnC, CsubnA, DsubnC,
+
+ clearA, clearB, clearC, clearD,
+ AcopyB, BcopyC, CcopyA, DcopyC, BcopyA, CcopyB, AcopyC, CcopyD,
+ AswapB, BswapC, CswapA, DswapC,
+
+ Ashiftleft, Bshiftleft, Cshiftleft, Dshiftleft,
+ Ashiftright, Bshiftright, Cshiftright, Dshiftright,
+ negateA, negateB, negateC, negateD,
+ notA, notB, notC, notD
+
+} MNEMONICS;
+
+static const struct {
+ const char *name[2];
+} mnemonics[]={
+ { { "rtn", "RET" } },
+ { { "rtnsXM", "RETSETXM" } },
+ { { "rtnsC", "RETSETC" } },
+ { { "rtncC", "RETCLRC" } },
+ { { "rti", "RETI" } },
+ { { "goto %05x", "JUMP.3 %05x" } },
+ { { "goto %05x", "JUMP.4 %05x" } },
+ { { "goto %05x", "JUMP %05x" } },
+ { { "gosub %05x", "CALL.3 %05x" } },
+ { { "gosub %05x", "CALL.4 %05x" } },
+ { { "gosub %05x", "CALL %05x" } },
+ { { "goC %05x", "BRCS %05x" } },
+ { { "rtnC", "RETCS" } },
+ { { "gonC %05x", "BRCC %05x" } },
+ { { "rtnnC", "RETCC" } },
+
+ { { "OUT=CS", "OUT.S C" } },
+ { { "OUT=C", "OUT.X C" } },
+ { { "A=IN", "IN.4 A" } },
+ { { "C=IN", "IN.4 C" } },
+ { { "uncnfg", "UNCNFG" } },
+ { { "config", "CONFIG" } },
+ { { "C=id", "MOVE.A ID,C" } },
+ { { "!shutdn", "!SHUTDN" } },
+ { { "C+P+1", "ADD.A P+1,C" } },
+ { { "reset", "RESET" } },
+ { { "!buscc", "!BUSCC" } },
+ { { "C=P %x", "MOVE.1 P,C,%x" } },
+ { { "P=C %x", "MOVE.1 C,%x,P" } },
+ { { "!sreq?", "!SREQ" } },
+ { { "CPex %x", "SWAP.1 P,C,%x" } },
+
+ { { "!inton", "!INTON" } },
+ { { "LA %-2x %s", "MOVE.P%-2x %s,A" } },
+ { { "!buscb", "!BUSCB" } },
+ { { "Abit=0 %x", "CLRB %x,A" } },
+ { { "Abit=1 %x", "SETB %x,A" } },
+ { { "?Abit=0 %x,%05x", "BRBC %x,A,%05x" } },
+ { { "?Abit=0 %x,rtn", "RETBC %x,A" } },
+ { { "?Abit=1 %x,%05x", "BRBS %x,A,%05x" } },
+ { { "?Abit=1 %x,rtn", "RETBS %x,A" } },
+ { { "Cbit=0 %x", "CLRB %x,C" } },
+ { { "Cbit=1 %x", "SETB %x,C" } },
+ { { "?Cbit=0 %x,%05x", "BRBC %x,C,%05x" } },
+ { { "?Cbit=0 %x,rtn", "RETBC %x,C" } },
+ { { "?Cbit=1 %x,%05x", "BRBS %x,C,%05x" } },
+ { { "?Cbit=1 %x,rtn", "RETBS %x,C" } },
+ { { "PC=(A)", "JUMP.A @A" } },
+ { { "!buscd", "!BUSCD" } },
+ { { "PC=(C)", "JUMP.A @C" } },
+ { { "!intoff", "!INTOFF" } },
+ { { "!rsi", "!RSI" } },
+
+ { { "PC=A", "JUMP.A A" } },
+ { { "PC=C", "JUMP.A C" } },
+ { { "A=PC", "MOVE.A PC,A" } },
+ { { "C=PC", "MOVE.A PC,C" } },
+ { { "APCex", "SWAP.A A,PC" } },
+ { { "CPCex", "SWAP.A C,PC" } },
+
+ { { "HST=0 %x", "CLRHST %x" } },
+ { { "?HST=0 %x,%05x", "BRBCHST %x,%05x" } },
+ { { "?HST=0 %x,rtn", "RETBCHST %x" } },
+ { { "ST=0 %x", "CLRB %x,ST" } },
+ { { "ST=1 %x", "SETB %x,ST" } },
+ { { "?ST=0 %x,%05x", "BRBC ST,%x,%05x" } },
+ { { "?ST=0 %x,rtn", "RETBC ST,%x" } },
+ { { "?ST=1 %x,%05x", "BRBS ST,%x,%05x" } },
+ { { "?ST=1 %x,rtn", "RETBS ST,%x" } },
+ { { "?P# %x,%05x", "BRNE P,%x,%05x" } },
+ { { "?P# %x,rtn", "RETNE P,%x" } },
+ { { "?P= %x,%05x", "BREQ P,%x,%05x" } },
+ { { "?P= %x,rtn", "RETEQ P,%x" } },
+
+ { { "?A=B %s,%05x", "BREQ.%-2s A,B,%05x" } },
+ { { "?A=B %s,rtn", "RETEQ.%-2s A,B" } },
+ { { "?B=C %s,%05x", "BREQ.%-2s B,C,%05x" } },
+ { { "?B=C %s,rtn", "RETEQ.%-2s B,C" } },
+ { { "?A=C %s,%05x", "BREQ.%-2s A,C,%05x" } },
+ { { "?A=C %s,rtn", "RETEQ.%-2s A,C" } },
+ { { "?C=D %s,%05x", "BREQ.%-2s C,D,%05x" } },
+ { { "?C=D %s,rtn", "RETEQ.%-2s C,D" } },
+ { { "?A#B %s,%05x", "BRNE.%-2s A,B,%05x" } },
+ { { "?A#B %s,rtn", "RETNE.%-2s A,B" } },
+ { { "?B#C %s,%05x", "BRNE.%-2s B,C,%05x" } },
+ { { "?B#C %s,rtn", "RETNE.%-2s B,C" } },
+ { { "?A#C %s,%05x", "BRNE.%-2s A,C,%05x" } },
+ { { "?A#C %s,rtn", "RETNE.%-2s A,C" } },
+ { { "?C#D %s,%05x", "BRNE.%-2s C,D,%05x" } },
+ { { "?C#D %s,rtn", "RETNE.%-2s C,D" } },
+ { { "?A=0 %s,%05x", "BRZ.%-2s A,%05x" } },
+ { { "?A=0 %s,rtn", "RETZ.%-2s A" } },
+ { { "?B=0 %s,%05x", "BRZ.%-2s B,%05x" } },
+ { { "?B=0 %s,rtn", "RETZ.%-2s B" } },
+ { { "?C=0 %s,%05x", "BRZ.%-2s C,%05x" } },
+ { { "?C=0 %s,rtn", "RETZ.%-2s C" } },
+ { { "?D=0 %s,%05x", "BRZ.%-2s D,%05x" } },
+ { { "?D=0 %s,rtn", "RETZ.%-2s D" } },
+ { { "?A#0 %s,%05x", "BRNZ.%-2s A,%05x" } },
+ { { "?A#0 %s,rtn", "RETNZ.%-2s A" } },
+ { { "?B#0 %s,%05x", "BRNZ.%-2s B,%05x" } },
+ { { "?B#0 %s,rtn", "RETNZ.%-2s B" } },
+ { { "?C#0 %s,%05x", "BRNZ.%-2s C,%05x" } },
+ { { "?C#0 %s,rtn", "RETNZ.%-2s C" } },
+ { { "?D#0 %s,%05x", "BRNZ.%-2s D,%05x" } },
+ { { "?D#0 %s,rtn", "RETNZ.%-2s D" } },
+
+ { { "?A>B %s,%05x", "BRGT.%-2s A,B,%05x" } },
+ { { "?A>B %s,rtn", "RETGT.%-2s A,B" } },
+ { { "?B>C %s,%05x", "BRGT.%-2s B,C,%05x" } },
+ { { "?B>C %s,rtn", "RETGT.%-2s B,C" } },
+ { { "?C>A %s,%05x", "BRGT.%-2s C,A,%05x" } },
+ { { "?C>A %s,rtn", "RETGT.%-2s C,A" } },
+ { { "?D>C %s,%05x", "BRGT.%-2s D,C,%05x" } },
+ { { "?D>C %s,rtn", "RETGT.%-2s D,C" } },
+ { { "?A<B %s,%05x", "BRLT.%-2s A,B,%05x" } },
+ { { "?A<B %s,rtn", "RETLT.%-2s A,B" } },
+ { { "?B<C %s,%05x", "BRLT.%-2s B,C,%05x" } },
+ { { "?B<C %s,rtn", "RETLT.%-2s B,C" } },
+ { { "?C<A %s,%05x", "BRLT.%-2s C,A,%05x" } },
+ { { "?C<A %s,rtn", "RETLT.%-2s C,A" } },
+ { { "?D<C %s,%05x", "BRLT.%-2s D,C,%05x" } },
+ { { "?D<C %s,rtn", "RETLT.%-2s D,C" } },
+ { { "?A>=B %s,%05x", "BRGE.%-2s A,B,%05x" } },
+ { { "?A>=B %s,rtn", "RETGE.%-2s A,B" } },
+ { { "?B>=C %s,%05x", "BRGE.%-2s B,C,%05x" } },
+ { { "?B>=C %s,rtn", "RETGE.%-2s B,C" } },
+ { { "?C>=A %s,%05x", "BRGE.%-2s C,A,%05x" } },
+ { { "?C>=A %s,rtn", "RETGE.%-2s C,A" } },
+ { { "?D>=C %s,%05x", "BRGE.%-2s D,C,%05x" } },
+ { { "?D>=C %s,rtn", "RETGE.%-2s D,C" } },
+ { { "?A<=B %s,%05x", "BRLE.%-2s A,B,%05x" } },
+ { { "?A<=B %s,rtn", "RETLE.%-2s A,B" } },
+ { { "?B<=C %s,%05x", "BRLE.%-2s B,C,%05x" } },
+ { { "?B<=C %s,rtn", "RETLE.%-2s B,C" } },
+ { { "?C<=A %s,%05x", "BRLE.%-2s C,A,%05x" } },
+ { { "?C<=A %s,rtn", "RETLE.%-2s C,A" } },
+ { { "?D<=C %s,%05x", "BRLE.%-2s D,C,%05x" } },
+ { { "?D<=C %s,rtn", "RETLE.%-2s D,C" } },
+
+ { { "sethex", "SETHEX" } },
+ { { "setdec", "SETDEC" } },
+ { { "RSTK=C", "PUSH.A C" } },
+ { { "C=RSTK", "POP.A C" } },
+
+ // load immediate
+ { { "D0= %02x", "MOVE.2 %02x,D0" } },
+ { { "D0= %04x", "MOVE.4 %04x,D0" } },
+ { { "D0= %05x", "MOVE.5 %05x,D0" } },
+
+ { { "D1= %02x", "MOVE.2 %02x,D1" } },
+ { { "D1= %04x", "MOVE.4 %04x,D1" } },
+ { { "D1= %05x", "MOVE.5 %05x,D1" } },
+
+ { { "P= %x", "MOVE %x,P" } },
+ { { "lC %-2x %s", "MOVE.P%-2x %s,C" } },
+
+ { { "clrST", "CLR.X ST" } },
+ { { "C=ST", "MOVE.X ST,C" } },
+ { { "ST=C", "MOVE.X C,ST" } },
+ { { "CSTex", "SWAP.X C,ST" } },
+
+ { { "P=P+1", "INC P" } },
+ { { "P=P-1", "DEC P" } },
+
+ // copy
+ { { "R0=A %s", "MOVE.%-2s A,R0" } },
+ { { "R1=A %s", "MOVE.%-2s A,R1" } },
+ { { "R2=A %s", "MOVE.%-2s A,R2" } },
+ { { "R3=A %s", "MOVE.%-2s A,R3" } },
+ { { "R4=A %s", "MOVE.%-2s A,R4" } },
+
+ { { "R0=C %s", "MOVE.%-2s C,R0" } },
+ { { "R1=C %s", "MOVE.%-2s C,R1" } },
+ { { "R2=C %s", "MOVE.%-2s C,R2" } },
+ { { "R3=C %s", "MOVE.%-2s C,R3" } },
+ { { "R4=C %s", "MOVE.%-2s C,R4" } },
+
+ { { "A=R0 %s", "MOVE.%-2s R0,A" } },
+ { { "A=R1 %s", "MOVE.%-2s R1,A" } },
+ { { "A=R2 %s", "MOVE.%-2s R2,A" } },
+ { { "A=R3 %s", "MOVE.%-2s R3,A" } },
+ { { "A=R4 %s", "MOVE.%-2s R4,A" } },
+
+ { { "C=R0 %s", "MOVE.%-2s R0,C" } },
+ { { "C=R1 %s", "MOVE.%-2s R1,C" } },
+ { { "C=R2 %s", "MOVE.%-2s R2,C" } },
+ { { "C=R3 %s", "MOVE.%-2s R3,C" } },
+ { { "C=R4 %s", "MOVE.%-2s R4,C" } },
+
+ { { "D0=A", "MOVE.A A,D0" } },
+ { { "D1=A", "MOVE.A A,D1" } },
+ { { "D0=C", "MOVE.A C,D0" } },
+ { { "D1=C", "MOVE.A C,D1" } },
+ { { "D0=As", "MOVE.S A,D0" } },
+ { { "D1=As", "MOVE.S A,D1" } },
+ { { "D0=Cs", "MOVE.S C,D0" } },
+ { { "D1=Cs", "MOVE.S C,D1" } },
+
+ // swap operations
+ { { "AR0ex %s", "SWAP.%-2s A,R0" } },
+ { { "AR1ex %s", "SWAP.%-2s A,R1" } },
+ { { "AR2ex %s", "SWAP.%-2s A,R2" } },
+ { { "AR3ex %s", "SWAP.%-2s A,R3" } },
+ { { "AR4ex %s", "SWAP.%-2s A,R4" } },
+
+ { { "CR0ex %s", "SWAP.%-2s C,R0" } },
+ { { "CR1ex %s", "SWAP.%-2s C,R1" } },
+ { { "CR2ex %s", "SWAP.%-2s C,R2" } },
+ { { "CR3ex %s", "SWAP.%-2s C,R3" } },
+ { { "CR4ex %s", "SWAP.%-2s C,R4" } },
+
+ { { "AD0ex", "SWAP.A A,D0" } },
+ { { "AD1ex", "SWAP.A A,D1" } },
+ { { "CD0ex", "SWAP.A C,D0" } },
+ { { "CD1ex", "SWAP.A C,D1" } },
+ { { "AD0xs", "SWAP.S A,D0" } },
+ { { "AD1xs", "SWAP.S A,D1" } },
+ { { "CD0xs", "SWAP.S C,D0" } },
+ { { "CD1xs", "SWAP.S C,D1" } },
+
+ // store
+ { { "Dat0=A %s", "MOVE.%-2s A,@D0" } },
+ { { "Dat1=A %s", "MOVE.%-2s A,@D0" } },
+ { { "Dat0=C %s", "MOVE.%-2s C,@D0" } },
+ { { "Dat1=C %s", "MOVE.%-2s C,@D0" } },
+
+ // load
+ { { "A=Dat0 %s", "MOVE.%-2s @D0,A" } },
+ { { "A=Dat1 %s", "MOVE.%-2s @D0,A" } },
+ { { "C=Dat0 %s", "MOVE.%-2s @D0,C" } },
+ { { "C=Dat1 %s", "MOVE.%-2s @D0,C" } },
+
+ // add/sub immediate
+ { { "D0=D0+ %x", "ADD.A %x,D0" } },
+ { { "D1=D1+ %x", "ADD.A %x,D1" } },
+ { { "D0=D0- %x", "SUB.A %x,D0" } },
+ { { "D1=D1- %x", "SUB.A %x,D1" } },
+
+ { { "A=A+ %s,%x", "ADD.%-2s %x,A" } },
+ { { "B=B+ %s,%x", "ADD.%-2s %x,B" } },
+ { { "C=C+ %s,%x", "ADD.%-2s %x,C" } },
+ { { "D=D+ %s,%x", "ADD.%-2s %x,D" } },
+ { { "A=A- %s,%x", "SUB.%-2s %x,A" } },
+ { { "B=B- %s,%x", "SUB.%-2s %x,B" } },
+ { { "C=C- %s,%x", "SUB.%-2s %x,C" } },
+ { { "D=D- %s,%x", "SUB.%-2s %x,D" } },
+
+ { { "A=A&B %s", "AND.%-2s B,A" } },
+ { { "B=B&C %s", "AND.%-2s C,B" } },
+ { { "C=C&A %s", "AND.%-2s A,C" } },
+ { { "D=D&C %s", "AND.%-2s C,D" } },
+ { { "B=B&A %s", "AND.%-2s A,B" } },
+ { { "C=C&B %s", "AND.%-2s B,C" } },
+ { { "A=A&C %s", "AND.%-2s C,A" } },
+ { { "C=C&D %s", "AND.%-2s D,C" } },
+
+ { { "A=A!B %s", "OR.%-2s B,A" } },
+ { { "B=B!C %s", "OR.%-2s C,B" } },
+ { { "C=C!A %s", "OR.%-2s A,C" } },
+ { { "D=D!C %s", "OR.%-2s C,D" } },
+ { { "B=B!A %s", "OR.%-2s A,B" } },
+ { { "C=C!B %s", "OR.%-2s B,C" } },
+ { { "A=A!C %s", "OR.%-2s C,A" } },
+ { { "C=C!D %s", "OR.%-2s D,C" } },
+
+ { { "Asrb %s", "SRB.%-2s A" } },
+ { { "Bsrb %s", "SRB.%-2s B" } },
+ { { "Csrb %s", "SRB.%-2s C" } },
+ { { "Dsrb %s", "SRB.%-2s D" } },
+
+ { { "Aslc %s", "RLN.%-2s A" } },
+ { { "Bslc %s", "RLN.%-2s B" } },
+ { { "Cslc %s", "RLN.%-2s C" } },
+ { { "Dslc %s", "RLN.%-2s D" } },
+ { { "Asrc %s", "RRN.%-2s A" } },
+ { { "Bsrc %s", "RRN.%-2s B" } },
+ { { "Csrc %s", "RRN.%-2s C" } },
+ { { "Dsrc %s", "RRN.%-2s D" } },
+
+ { { "A=A+B %s", "ADD.%-2s B,A" } },
+ { { "B=B+C %s", "ADD.%-2s C,B" } },
+ { { "C=C+A %s", "ADD.%-2s A,C" } },
+ { { "D=D+C %s", "ADD.%-2s C,D" } },
+ { { "A=A+A %s", "ADD.%-2s A,A" } },
+ { { "B=B+B %s", "ADD.%-2s B,B" } },
+ { { "C=C+C %s", "ADD.%-2s C,C" } },
+ { { "D=D+C %s", "ADD.%-2s D,D" } },
+ { { "B=B+A %s", "ADD.%-2s A,B" } },
+ { { "C=C+B %s", "ADD.%-2s B,C" } },
+ { { "A=A+C %s", "ADD.%-2s C,A" } },
+ { { "C=C+D %s", "ADD.%-2s D,C" } },
+ { { "A=A-1 %s", "DEC.%-2s A" } },
+ { { "B=B-1 %s", "DEC.%-2s B" } },
+ { { "C=C-1 %s", "DEC.%-2s C" } },
+ { { "D=D-1 %s", "DEC.%-2s D" } },
+
+ { { "A=A-B %s", "ADD.%-2s B,A" } },
+ { { "B=B-C %s", "ADD.%-2s C,B" } },
+ { { "C=C-A %s", "ADD.%-2s A,C" } },
+ { { "D=D-C %s", "ADD.%-2s C,D" } },
+ { { "A=A+1 %s", "INC.%-2s A" } },
+ { { "B=B+1 %s", "INC.%-2s B" } },
+ { { "C=C+1 %s", "INC.%-2s C" } },
+ { { "D=D+1 %s", "INC.%-2s D" } },
+ { { "B=B-A %s", "SUB.%-2s A,B" } },
+ { { "C=C-B %s", "SUB.%-2s B,C" } },
+ { { "A=A-C %s", "SUB.%-2s C,A" } },
+ { { "C=C-D %s", "SUB.%-2s D,C" } },
+ { { "A=B-A %s", "SUBN.%-2s B,A" } },
+ { { "B=C-B %s", "SUBN.%-2s C,B" } },
+ { { "C=A-C %s", "SUBN.%-2s A,C" } },
+ { { "D=C-D %s", "SUBN.%-2s C,D" } },
+
+ { { "A=0 %s", "CLR.%-2s A" } },
+ { { "B=0 %s", "CLR.%-2s B" } },
+ { { "C=0 %s", "CLR.%-2s C" } },
+ { { "D=0 %s", "CLR.%-2s D" } },
+ { { "A=B %s", "MOVE.%-2s B,A" } },
+ { { "B=C %s", "MOVE.%-2s C,B" } },
+ { { "C=A %s", "MOVE.%-2s A,C" } },
+ { { "D=C %s", "MOVE.%-2s C,D" } },
+ { { "B=A %s", "MOVE.%-2s A,B" } },
+ { { "C=B %s", "MOVE.%-2s B,C" } },
+ { { "A=C %s", "MOVE.%-2s C,A" } },
+ { { "C=D %s", "MOVE.%-2s D,C" } },
+ { { "ABex %s", "SWAP.%-2s A,B" } },
+ { { "BCex %s", "SWAP.%-2s B,C" } },
+ { { "ACex %s", "SWAP.%-2s A,C" } },
+ { { "CDex %s", "SWAP.%-2s C,D" } },
+
+ { { "Asl %s", "SLN.%-2s A" } },
+ { { "Bsl %s", "SLN.%-2s B" } },
+ { { "Csl %s", "SLN.%-2s C" } },
+ { { "Dsl %s", "SLN.%-2s D" } },
+ { { "Asr %s", "SRN.%-2s A" } },
+ { { "Bsr %s", "SRN.%-2s B" } },
+ { { "Csr %s", "SRN.%-2s C" } },
+ { { "Dsr %s", "SRN.%-2s D" } },
+ { { "A=-A %s", "NEG.%-2s A" } },
+ { { "B=-B %s", "NEG.%-2s B" } },
+ { { "C=-C %s", "NEG.%-2s C" } },
+ { { "D=-D %s", "NEG.%-2s D" } },
+ { { "A=-A-1 %s", "NOT.%-2s A" } },
+ { { "B=-B-1 %s", "NOT.%-2s B" } },
+ { { "C=-C-1 %s", "NOT.%-2s C" } },
+ { { "D=-D-1 %s", "NOT.%-2s D" } }
+
+};
+
+enum _opcode_sel
+{
+ Complete=-1,
+ Illegal,
+ Opcode0, Opcode0E, Opcode0Ea,
+ Opcode1, Opcode10, Opcode11, Opcode12, Opcode13, Opcode14, Opcode15,
+ Opcode8, Opcode80, Opcode808, Opcode8081,
+ Opcode81, Opcode818, Opcode818a, Opcode819, Opcode819a,
+ Opcode81A, Opcode81Aa, Opcode81Aa0,Opcode81Aa1, Opcode81Aa2, Opcode81B,
+ Opcode8A, Opcode8B,
+ Opcode9, Opcode9a, Opcode9b,
+ OpcodeA, OpcodeAa, OpcodeAb,
+ OpcodeB, OpcodeBa, OpcodeBb,
+ OpcodeC,
+ OpcodeD,
+ OpcodeE,
+ OpcodeF
+};
+typedef enum _opcode_sel opcode_sel;
+
+enum _opcode_adr
+{
+ AdrNone,
+ AdrAF, AdrA, AdrB, AdrCount,
+ BranchReturn, TestBranchRet, ImmBranch,
+ ABranchReturn, // address field A
+ xBranchReturn, // address field specified in previous opcode entry
+ Imm, ImmCount, ImmCload, Imm2, Imm4, Imm5,
+ Dis3, Dis3Call, Dis4, Dis4Call, Abs,
+ FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW, FieldA,
+ AdrImmCount
+};
+typedef enum _opcode_adr opcode_adr;
+
+typedef struct
+{
+ opcode_sel sel;
+ opcode_adr adr;
+ MNEMONICS mnemonic;
+} OPCODE;
+
+static const char *field_2_string(int adr_enum)
+{
+ switch (adr_enum) {
+ case FieldP: return P;
+ case FieldWP: return WP;
+ case FieldXS: return XS;
+ case FieldX: return X;
+ case FieldS: return S;
+ case FieldM: return M;
+ case FieldB: return B;
+ case FieldW: return W;
+ case FieldA: return A;
+ }
+ return 0;
+}
+
+static const OPCODE opcodes[][0x10]= {
+ {
+ // first digit
+ { Opcode0 },
+ { Opcode1 },
+ { Complete, Imm, PloadImm },
+ { Complete, ImmCload, CloadImm },
+ { Complete, BranchReturn, branchCarrySet},
+ { Complete, BranchReturn, branchCarryClear },
+ { Complete, Dis3, jump3 },
+ { Complete, Dis3Call, call3 },
+ { Opcode8 },
+ { Opcode9 },
+ { OpcodeA },
+ { OpcodeB },
+ { OpcodeC },
+ { OpcodeD },
+ { OpcodeE },
+ { OpcodeF }
+ }, { // 0
+ { Complete, AdrNone, ReturnSetXM },
+ { Complete, AdrNone, Return },
+ { Complete, AdrNone, ReturnSetCarry },
+ { Complete, AdrNone, ReturnClearCarry },
+ { Complete, AdrNone, SetHexMode },
+ { Complete, AdrNone, SetDecMode },
+ { Complete, AdrNone, PushC },
+ { Complete, AdrNone, PopC },
+ { Complete, AdrNone, clearST },
+ { Complete, AdrNone, CcopyST },
+ { Complete, AdrNone, STcopyC },
+ { Complete, AdrNone, swapCST },
+ { Complete, AdrNone, incP },
+ { Complete, AdrNone, decP },
+ { Opcode0E },
+ { Complete, AdrNone, ReturnFromInterrupt }
+ }, { //0E
+ { Opcode0Ea, AdrAF },
+ { Opcode0Ea, AdrAF },
+ { Opcode0Ea, AdrAF },
+ { Opcode0Ea, AdrAF },
+ { Opcode0Ea, AdrAF },
+ { Opcode0Ea, AdrAF },
+ { Opcode0Ea, AdrAF },
+ { Opcode0Ea, AdrAF },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Opcode0Ea, AdrAF }
+ }, { //0Ea
+ { Complete, AdrNone, AandB },
+ { Complete, AdrNone, BandC },
+ { Complete, AdrNone, CandA },
+ { Complete, AdrNone, DandC },
+ { Complete, AdrNone, BandA },
+ { Complete, AdrNone, CandB },
+ { Complete, AdrNone, AandC },
+ { Complete, AdrNone, CandD },
+ { Complete, AdrNone, AorB },
+ { Complete, AdrNone, BorC },
+ { Complete, AdrNone, CorA },
+ { Complete, AdrNone, DorC },
+ { Complete, AdrNone, BorA },
+ { Complete, AdrNone, CorB },
+ { Complete, AdrNone, AorC },
+ { Complete, AdrNone, CorD }
+ }, { //1
+ { Opcode10 },
+ { Opcode11 },
+ { Opcode12 },
+ { Opcode13 },
+ { Opcode14 },
+ { Opcode15 },
+ { Complete, ImmCount, D0addImm },
+ { Complete, ImmCount, D1addImm },
+ { Complete, ImmCount, D0subImm },
+ { Complete, Imm2, D0loadImm2 },
+ { Complete, Imm4, D0loadImm4 },
+ { Complete, Imm5, D0loadImm5 },
+ { Complete, ImmCount, D1subImm },
+ { Complete, Imm2, D1loadImm2 },
+ { Complete, Imm4, D1loadImm4 },
+ { Complete, Imm5, D1loadImm5 }
+ }, { //10
+ { Complete, FieldW, R0copyA },
+ { Complete, FieldW, R1copyA },
+ { Complete, FieldW, R2copyA },
+ { Complete, FieldW, R3copyA },
+ { Complete, FieldW, R4copyA },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Complete, FieldW, R0copyC },
+ { Complete, FieldW, R1copyC },
+ { Complete, FieldW, R2copyC },
+ { Complete, FieldW, R3copyC },
+ { Complete, FieldW, R4copyC },
+ { Illegal },
+ { Illegal },
+ { Illegal }
+ }, { //11
+ { Complete, FieldW, AcopyR0 },
+ { Complete, FieldW, AcopyR1 },
+ { Complete, FieldW, AcopyR2 },
+ { Complete, FieldW, AcopyR3 },
+ { Complete, FieldW, AcopyR4 },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Complete, FieldW, CcopyR0 },
+ { Complete, FieldW, CcopyR1 },
+ { Complete, FieldW, CcopyR2 },
+ { Complete, FieldW, CcopyR3 },
+ { Complete, FieldW, CcopyR4 },
+ { Illegal },
+ { Illegal },
+ { Illegal }
+ }, { //12
+ { Complete, FieldW, SwapAR0 },
+ { Complete, FieldW, SwapAR1 },
+ { Complete, FieldW, SwapAR2 },
+ { Complete, FieldW, SwapAR3 },
+ { Complete, FieldW, SwapAR4 },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Complete, FieldW, SwapCR0 },
+ { Complete, FieldW, SwapCR1 },
+ { Complete, FieldW, SwapCR2 },
+ { Complete, FieldW, SwapCR3 },
+ { Complete, FieldW, SwapCR4 },
+ { Illegal },
+ { Illegal },
+ { Illegal }
+ }, { //13
+ { Complete, FieldA, D0copyA },
+ { Complete, FieldA, D1copyA },
+ { Complete, FieldA, SwapAD0 },
+ { Complete, FieldA, SwapAD1 },
+ { Complete, FieldA, D0copyC },
+ { Complete, FieldA, D1copyC },
+ { Complete, FieldA, SwapCD0 },
+ { Complete, FieldA, SwapCD1 },
+ { Complete, FieldS, D0copyAShort },
+ { Complete, FieldS, D1copyAShort },
+ { Complete, FieldS, SwapAD0Short },
+ { Complete, FieldS, SwapAD1Short },
+ { Complete, FieldS, D0copyCShort },
+ { Complete, FieldS, D1copyCShort },
+ { Complete, FieldS, SwapCD0Short },
+ { Complete, FieldS, SwapCD1Short }
+ }, { //14
+ { Complete, FieldA, D0storeA },
+ { Complete, FieldA, D1storeA },
+ { Complete, FieldA, AloadD0 },
+ { Complete, FieldA, AloadD1 },
+ { Complete, FieldA, D0storeC },
+ { Complete, FieldA, D1storeC },
+ { Complete, FieldA, CloadD0 },
+ { Complete, FieldA, CloadD1 },
+ { Complete, FieldB, D0storeA },
+ { Complete, FieldB, D1storeA },
+ { Complete, FieldB, AloadD0 },
+ { Complete, FieldB, AloadD1 },
+ { Complete, FieldB, D0storeC },
+ { Complete, FieldB, D1storeC },
+ { Complete, FieldB, CloadD0 },
+ { Complete, FieldB, CloadD1 }
+ }, { //15
+ { Complete, AdrA, D0storeA },
+ { Complete, AdrA, D1storeA },
+ { Complete, AdrA, AloadD0 },
+ { Complete, AdrA, AloadD1 },
+ { Complete, AdrA, D0storeC },
+ { Complete, AdrA, D1storeC },
+ { Complete, AdrA, CloadD0 },
+ { Complete, AdrA, CloadD1 },
+ { Complete, AdrCount, D0storeA },
+ { Complete, AdrCount, D1storeA },
+ { Complete, AdrCount, AloadD0 },
+ { Complete, AdrCount, AloadD1 },
+ { Complete, AdrCount, D0storeC },
+ { Complete, AdrCount, D1storeC },
+ { Complete, AdrCount, CloadD0 },
+ { Complete, AdrCount, CloadD1 },
+ }, { //8
+ { Opcode80 },
+ { Opcode81 },
+ { Complete, Imm, clearHST },
+ { Complete, TestBranchRet, branchHSTclear },
+ { Complete, Imm, clearBitST },
+ { Complete, Imm, setBitST },
+ { Complete, TestBranchRet, branchSTclear },
+ { Complete, TestBranchRet, branchSTset },
+ { Complete, TestBranchRet, branchPdiffers},
+ { Complete, TestBranchRet, branchPequals},
+ { Opcode8A },
+ { Opcode8B },
+ { Complete, Dis4, jump4 },
+ { Complete, Abs, jump },
+ { Complete, Dis4Call, call4 },
+ { Complete, Abs, call }
+ }, { //80
+ { Complete, AdrNone, outCS },
+ { Complete, AdrNone, outC },
+ { Complete, AdrNone, inA },
+ { Complete, AdrNone, inC },
+ { Complete, AdrNone, unconfig },
+ { Complete, AdrNone, config },
+ { Complete, AdrNone, Cid },
+ { Complete, AdrNone, shutdown },
+ { Opcode808 },
+ { Complete, AdrNone, cp1 },
+ { Complete, AdrNone, reset },
+ { Complete, AdrNone, buscc },
+ { Complete, Imm, CcopyP },
+ { Complete, Imm, PcopyC },
+ { Complete, AdrNone, sreq },
+ { Complete, Imm, CswapP }
+ }, { //808
+ { Complete, AdrNone, inton },
+ { Opcode8081 },
+ { Complete, ImmCload, AloadImm },
+ { Complete, AdrNone, buscb },
+ { Complete, Imm, clearAbit },
+ { Complete, Imm, setAbit },
+ { Complete, TestBranchRet, branchAbitclear },
+ { Complete, TestBranchRet, branchAbitset },
+ { Complete, Imm, clearCbit },
+ { Complete, Imm, setCbit },
+ { Complete, TestBranchRet, branchCbitclear },
+ { Complete, TestBranchRet, branchCbitset },
+ { Complete, AdrNone, PCloadA },
+ { Complete, AdrNone, buscd },
+ { Complete, AdrNone, PCloadC },
+ { Complete, AdrNone, intoff }
+ }, { //8081
+ { Complete, AdrNone, rsi },
+ //! rest illegal
+ }, { //81
+ { Complete, FieldW, AshiftleftCarry },
+ { Complete, FieldW, BshiftleftCarry },
+ { Complete, FieldW, CshiftleftCarry },
+ { Complete, FieldW, DshiftleftCarry },
+ { Complete, FieldW, AshiftrightCarry },
+ { Complete, FieldW, BshiftrightCarry },
+ { Complete, FieldW, CshiftrightCarry },
+ { Complete, FieldW, DshiftrightCarry },
+ { Opcode818 },
+ { Opcode819 },
+ { Opcode81A },
+ { Opcode81B },
+ { Complete, FieldW, Ashiftrightbit },
+ { Complete, FieldW, Bshiftrightbit },
+ { Complete, FieldW, Cshiftrightbit },
+ { Complete, FieldW, Dshiftrightbit }
+ }, { //818
+ { Opcode818a, AdrAF },
+ { Opcode818a, AdrAF },
+ { Opcode818a, AdrAF },
+ { Opcode818a, AdrAF },
+ { Opcode818a, AdrAF },
+ { Opcode818a, AdrAF },
+ { Opcode818a, AdrAF },
+ { Opcode818a, AdrAF },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Opcode818a, AdrAF },
+ }, { //818a
+ { Complete, AdrImmCount, AaddImm },
+ { Complete, AdrImmCount, BaddImm },
+ { Complete, AdrImmCount, CaddImm },
+ { Complete, AdrImmCount, DaddImm },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Complete, AdrImmCount, AsubImm },
+ { Complete, AdrImmCount, BsubImm },
+ { Complete, AdrImmCount, CsubImm },
+ { Complete, AdrImmCount, DsubImm },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ }, { //819
+ { Opcode819a, AdrAF },
+ { Opcode819a, AdrAF },
+ { Opcode819a, AdrAF },
+ { Opcode819a, AdrAF },
+ { Opcode819a, AdrAF },
+ { Opcode819a, AdrAF },
+ { Opcode819a, AdrAF },
+ { Opcode819a, AdrAF }, //?
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Opcode819a, AdrAF },
+ }, { //819a }
+ { Complete, AdrNone, Ashiftright },
+ { Complete, AdrNone, Bshiftright },
+ { Complete, AdrNone, Cshiftright },
+ { Complete, AdrNone, Dshiftright },
+ //! rest illegal
+ }, { //81A
+ { Opcode81Aa, AdrAF },
+ { Opcode81Aa, AdrAF },
+ { Opcode81Aa, AdrAF },
+ { Opcode81Aa, AdrAF },
+ { Opcode81Aa, AdrAF },
+ { Opcode81Aa, AdrAF },
+ { Opcode81Aa, AdrAF },
+ { Opcode81Aa, AdrAF },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Opcode81Aa, AdrAF },
+ }, { //81Aa
+ { Opcode81Aa0 },
+ { Opcode81Aa1 },
+ { Opcode81Aa2 },
+ //! rest illegal
+ }, { //81Aa0
+ { Complete, AdrNone, R0copyA },
+ { Complete, AdrNone, R1copyA },
+ { Complete, AdrNone, R2copyA },
+ { Complete, AdrNone, R3copyA },
+ { Complete, AdrNone, R4copyA },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Complete, AdrNone, R0copyC },
+ { Complete, AdrNone, R1copyC },
+ { Complete, AdrNone, R2copyC },
+ { Complete, AdrNone, R3copyC },
+ { Complete, AdrNone, R4copyC },
+ { Illegal },
+ { Illegal },
+ { Illegal }
+ }, { //81Aa1
+ { Complete, AdrNone, AcopyR0 },
+ { Complete, AdrNone, AcopyR1 },
+ { Complete, AdrNone, AcopyR2 },
+ { Complete, AdrNone, AcopyR3 },
+ { Complete, AdrNone, AcopyR4 },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Complete, AdrNone, CcopyR0 },
+ { Complete, AdrNone, CcopyR1 },
+ { Complete, AdrNone, CcopyR2 },
+ { Complete, AdrNone, CcopyR3 },
+ { Complete, AdrNone, CcopyR4 },
+ { Illegal },
+ { Illegal },
+ { Illegal }
+ }, { //81Aa2
+ { Complete, AdrNone, SwapAR0 },
+ { Complete, AdrNone, SwapAR1 },
+ { Complete, AdrNone, SwapAR2 },
+ { Complete, AdrNone, SwapAR3 },
+ { Complete, AdrNone, SwapAR4 },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Complete, AdrNone, SwapCR0 },
+ { Complete, AdrNone, SwapCR1 },
+ { Complete, AdrNone, SwapCR2 },
+ { Complete, AdrNone, SwapCR3 },
+ { Complete, AdrNone, SwapCR4 },
+ { Illegal },
+ { Illegal },
+ { Illegal }
+ }, { //81B
+ { Illegal },
+ { Illegal },
+ { Complete, AdrNone, jumpA },
+ { Complete, AdrNone, jumpC },
+ { Complete, AdrNone, PCcopyA },
+ { Complete, AdrNone, PCcopyC },
+ { Complete, AdrNone, AcopyPC },
+ { Complete, AdrNone, CcopyPC },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal },
+ { Illegal }
+ }, { //8A
+ { Complete, ABranchReturn, branchAequalsB },
+ { Complete, ABranchReturn, branchBequalsC },
+ { Complete, ABranchReturn, branchAequalsC },
+ { Complete, ABranchReturn, branchCequalsD },
+ { Complete, ABranchReturn, branchAdiffersB },
+ { Complete, ABranchReturn, branchBdiffersC },
+ { Complete, ABranchReturn, branchAdiffersC },
+ { Complete, ABranchReturn, branchCdiffersD },
+ { Complete, ABranchReturn, branchAzero },
+ { Complete, ABranchReturn, branchBzero },
+ { Complete, ABranchReturn, branchCzero },
+ { Complete, ABranchReturn, branchDzero },
+ { Complete, ABranchReturn, branchAnotzero },
+ { Complete, ABranchReturn, branchBnotzero },
+ { Complete, ABranchReturn, branchCnotzero },
+ { Complete, ABranchReturn, branchDnotzero }
+ }, { //8B
+ { Complete, ABranchReturn, branchAgreaterB },
+ { Complete, ABranchReturn, branchBgreaterC },
+ { Complete, ABranchReturn, branchCgreaterA },
+ { Complete, ABranchReturn, branchDgreaterC },
+ { Complete, ABranchReturn, branchAlowerB },
+ { Complete, ABranchReturn, branchBlowerC },
+ { Complete, ABranchReturn, branchClowerA },
+ { Complete, ABranchReturn, branchDlowerC },
+ { Complete, ABranchReturn, branchAnotlowerB },
+ { Complete, ABranchReturn, branchBnotlowerC },
+ { Complete, ABranchReturn, branchCnotlowerA },
+ { Complete, ABranchReturn, branchDnotlowerC },
+ { Complete, ABranchReturn, branchAnotgreaterB },
+ { Complete, ABranchReturn, branchBnotgreaterC },
+ { Complete, ABranchReturn, branchCnotgreaterA },
+ { Complete, ABranchReturn, branchDnotgreaterC }
+ }, { //9
+ { Opcode9a, AdrA },
+ { Opcode9a, AdrA },
+ { Opcode9a, AdrA },
+ { Opcode9a, AdrA },
+ { Opcode9a, AdrA },
+ { Opcode9a, AdrA },
+ { Opcode9a, AdrA },
+ { Opcode9a, AdrA },
+ { Opcode9b, AdrB },
+ { Opcode9b, AdrB },
+ { Opcode9b, AdrB },
+ { Opcode9b, AdrB },
+ { Opcode9b, AdrB },
+ { Opcode9b, AdrB },
+ { Opcode9b, AdrB },
+ { Opcode9b, AdrB },
+ }, { //9a
+ { Complete, xBranchReturn, branchAequalsB },
+ { Complete, xBranchReturn, branchBequalsC },
+ { Complete, xBranchReturn, branchAequalsC },
+ { Complete, xBranchReturn, branchCequalsD },
+ { Complete, xBranchReturn, branchAdiffersB },
+ { Complete, xBranchReturn, branchBdiffersC },
+ { Complete, xBranchReturn, branchAdiffersC },
+ { Complete, xBranchReturn, branchCdiffersD },
+ { Complete, xBranchReturn, branchAzero },
+ { Complete, xBranchReturn, branchBzero },
+ { Complete, xBranchReturn, branchCzero },
+ { Complete, xBranchReturn, branchDzero },
+ { Complete, xBranchReturn, branchAnotzero },
+ { Complete, xBranchReturn, branchBnotzero },
+ { Complete, xBranchReturn, branchCnotzero },
+ { Complete, xBranchReturn, branchDnotzero }
+ }, { //9b
+ { Complete, xBranchReturn, branchAgreaterB },
+ { Complete, xBranchReturn, branchBgreaterC },
+ { Complete, xBranchReturn, branchCgreaterA },
+ { Complete, xBranchReturn, branchDgreaterC },
+ { Complete, xBranchReturn, branchAlowerB },
+ { Complete, xBranchReturn, branchBlowerC },
+ { Complete, xBranchReturn, branchClowerA },
+ { Complete, xBranchReturn, branchDlowerC },
+ { Complete, xBranchReturn, branchAnotlowerB },
+ { Complete, xBranchReturn, branchBnotlowerC },
+ { Complete, xBranchReturn, branchCnotlowerA },
+ { Complete, xBranchReturn, branchDnotlowerC },
+ { Complete, xBranchReturn, branchAnotgreaterB },
+ { Complete, xBranchReturn, branchBnotgreaterC },
+ { Complete, xBranchReturn, branchCnotgreaterA },
+ { Complete, xBranchReturn, branchDnotgreaterC }
+ }, { //A
+ { OpcodeAa, AdrA },
+ { OpcodeAa, AdrA },
+ { OpcodeAa, AdrA },
+ { OpcodeAa, AdrA },
+ { OpcodeAa, AdrA },
+ { OpcodeAa, AdrA },
+ { OpcodeAa, AdrA },
+ { OpcodeAa, AdrA },
+ { OpcodeAb, AdrB },
+ { OpcodeAb, AdrB },
+ { OpcodeAb, AdrB },
+ { OpcodeAb, AdrB },
+ { OpcodeAb, AdrB },
+ { OpcodeAb, AdrB },
+ { OpcodeAb, AdrB },
+ { OpcodeAb, AdrB },
+ }, { //Aa
+ { Complete, AdrNone, AaddB },
+ { Complete, AdrNone, BaddC },
+ { Complete, AdrNone, CaddA },
+ { Complete, AdrNone, DaddC },
+ { Complete, AdrNone, AaddA },
+ { Complete, AdrNone, BaddB },
+ { Complete, AdrNone, CaddC },
+ { Complete, AdrNone, DaddD },
+ { Complete, AdrNone, BaddA },
+ { Complete, AdrNone, CaddB },
+ { Complete, AdrNone, AaddC },
+ { Complete, AdrNone, CaddD },
+ { Complete, AdrNone, decA },
+ { Complete, AdrNone, decB },
+ { Complete, AdrNone, decC },
+ { Complete, AdrNone, decD },
+ }, { //Ab
+ { Complete, AdrNone, clearA },
+ { Complete, AdrNone, clearB },
+ { Complete, AdrNone, clearC },
+ { Complete, AdrNone, clearD },
+ { Complete, AdrNone, AcopyB },
+ { Complete, AdrNone, BcopyC },
+ { Complete, AdrNone, CcopyA },
+ { Complete, AdrNone, DcopyC },
+ { Complete, AdrNone, BcopyA },
+ { Complete, AdrNone, CcopyB },
+ { Complete, AdrNone, AcopyC },
+ { Complete, AdrNone, CcopyD },
+ { Complete, AdrNone, AswapB },
+ { Complete, AdrNone, BswapC },
+ { Complete, AdrNone, CswapA },
+ { Complete, AdrNone, DswapC }
+ }, { //B
+ { OpcodeBa, AdrA },
+ { OpcodeBa, AdrA },
+ { OpcodeBa, AdrA },
+ { OpcodeBa, AdrA },
+ { OpcodeBa, AdrA },
+ { OpcodeBa, AdrA },
+ { OpcodeBa, AdrA },
+ { OpcodeBa, AdrA },
+ { OpcodeBb, AdrB },
+ { OpcodeBb, AdrB },
+ { OpcodeBb, AdrB },
+ { OpcodeBb, AdrB },
+ { OpcodeBb, AdrB },
+ { OpcodeBb, AdrB },
+ { OpcodeBb, AdrB },
+ { OpcodeBb, AdrB },
+ }, { //Ba
+ { Complete, AdrNone, AsubB },
+ { Complete, AdrNone, BsubC },
+ { Complete, AdrNone, CsubA },
+ { Complete, AdrNone, DsubC },
+ { Complete, AdrNone, incA },
+ { Complete, AdrNone, incB },
+ { Complete, AdrNone, incC },
+ { Complete, AdrNone, incD },
+ { Complete, AdrNone, BsubA },
+ { Complete, AdrNone, CsubB },
+ { Complete, AdrNone, AsubC },
+ { Complete, AdrNone, CsubD },
+ { Complete, AdrNone, AsubnB },
+ { Complete, AdrNone, BsubnC },
+ { Complete, AdrNone, CsubnA },
+ { Complete, AdrNone, DsubnC },
+ }, { //Bb
+ { Complete, AdrNone, Ashiftleft },
+ { Complete, AdrNone, Bshiftleft },
+ { Complete, AdrNone, Cshiftleft },
+ { Complete, AdrNone, Dshiftleft },
+ { Complete, AdrNone, Ashiftright },
+ { Complete, AdrNone, Bshiftright },
+ { Complete, AdrNone, Cshiftright },
+ { Complete, AdrNone, Dshiftright },
+ { Complete, AdrNone, negateA },
+ { Complete, AdrNone, negateB },
+ { Complete, AdrNone, negateC },
+ { Complete, AdrNone, negateD },
+ { Complete, AdrNone, notA },
+ { Complete, AdrNone, notB },
+ { Complete, AdrNone, notC },
+ { Complete, AdrNone, notD }
+ }, { //C
+ { Complete, FieldA, AaddB },
+ { Complete, FieldA, BaddC },
+ { Complete, FieldA, CaddA },
+ { Complete, FieldA, DaddC },
+ { Complete, FieldA, AaddA },
+ { Complete, FieldA, BaddB },
+ { Complete, FieldA, CaddC },
+ { Complete, FieldA, DaddD },
+ { Complete, FieldA, BaddA },
+ { Complete, FieldA, CaddB },
+ { Complete, FieldA, AaddC },
+ { Complete, FieldA, CaddD },
+ { Complete, FieldA, decA },
+ { Complete, FieldA, decB },
+ { Complete, FieldA, decC },
+ { Complete, FieldA, decD }
+ }, { //D
+ { Complete, FieldA, clearA },
+ { Complete, FieldA, clearB },
+ { Complete, FieldA, clearC },
+ { Complete, FieldA, clearD },
+ { Complete, FieldA, AcopyB },
+ { Complete, FieldA, BcopyC },
+ { Complete, FieldA, CcopyA },
+ { Complete, FieldA, DcopyC },
+ { Complete, FieldA, BcopyA },
+ { Complete, FieldA, CcopyB },
+ { Complete, FieldA, AcopyC },
+ { Complete, FieldA, CcopyD },
+ { Complete, FieldA, AswapB },
+ { Complete, FieldA, BswapC },
+ { Complete, FieldA, CswapA },
+ { Complete, FieldA, DswapC }
+ }, { //E
+ { Complete, FieldA, AsubB },
+ { Complete, FieldA, BsubC },
+ { Complete, FieldA, CsubA },
+ { Complete, FieldA, DsubC },
+ { Complete, FieldA, incA },
+ { Complete, FieldA, incB },
+ { Complete, FieldA, incC },
+ { Complete, FieldA, incD },
+ { Complete, FieldA, BsubA },
+ { Complete, FieldA, CsubB },
+ { Complete, FieldA, AsubC },
+ { Complete, FieldA, CsubD },
+ { Complete, FieldA, AsubnB },
+ { Complete, FieldA, BsubnC },
+ { Complete, FieldA, CsubnA },
+ { Complete, FieldA, DsubnC }
+ }, { //F
+ { Complete, FieldA, Ashiftleft },
+ { Complete, FieldA, Bshiftleft },
+ { Complete, FieldA, Cshiftleft },
+ { Complete, FieldA, Dshiftleft },
+ { Complete, FieldA, Ashiftright },
+ { Complete, FieldA, Bshiftright },
+ { Complete, FieldA, Cshiftright },
+ { Complete, FieldA, Dshiftright },
+ { Complete, FieldA, negateA },
+ { Complete, FieldA, negateB },
+ { Complete, FieldA, negateC },
+ { Complete, FieldA, negateD },
+ { Complete, FieldA, notA },
+ { Complete, FieldA, notB },
+ { Complete, FieldA, notC },
+ { Complete, FieldA, notD }
+ }
+};
+
+static const int field_adr_af[]=
+{ FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW, 0, 0, 0, 0, 0, 0, 0, FieldA };
+
+static const int field_adr_a[]=
+{ FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW};
+
+static const int field_adr_b[]=
+{ FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW };
+
+CPU_DISASSEMBLE( saturn )
+{
+ int adr=0;
+
+ int cont=1; // operation still not complete disassembled
+ char bin[10]; int binsize=0; // protocollizing fetched nibbles
+ char number[17];
+ const OPCODE *level=opcodes[0]; //pointer to current digit
+ int op; // currently fetched nibble
+ int pos = 0;
+
+ int i,c,v;
+
+ while (cont)
+ {
+ op = oprom[pos++] & 0xf;
+ level+=op;
+ switch (level->sel) {
+ case Illegal:
+ cont=0;
+ bin[binsize++]=number_2_hex[op];
+ bin[binsize]=0;
+ sprintf(buffer, "???%s",bin);
+ break;
+ default:
+ bin[binsize++]=number_2_hex[op];
+ switch (level->adr) {
+ case AdrNone: break;
+ case AdrA:
+ adr=field_adr_a[op];
+ break;
+ case AdrAF:
+ adr=field_adr_af[op];
+ break;
+ case AdrB:
+ adr=field_adr_b[op&7];
+ break;
+ default:
+ cont = 0;
+ bin[binsize++]=number_2_hex[op];
+ bin[binsize]=0;
+ sprintf(buffer, "???%s",bin);
+ break;
+ }
+ break;
+ case Complete:
+ cont=0;
+ switch (level->adr==AdrNone?adr:level->adr) {
+ case AdrNone:
+ strcpy(buffer, mnemonics[level->mnemonic].name[set]);
+ break;
+ case Imm:
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], oprom[pos++]);
+ break;
+ case ImmCount:
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], oprom[pos++]+1);
+ break;
+ case AdrImmCount:
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], field_2_string(adr), oprom[pos++]+1);
+ break;
+ case AdrCount: // mnemonics have string %s for address field
+ snprintf(number,sizeof(number),"%x",oprom[pos++]+1);
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], number);
+ break;
+ case Imm2:
+ v=oprom[pos++];
+ v|=oprom[pos++]<<4;
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], v);
+ break;
+ case Imm4:
+ v=oprom[pos++];
+ v|=oprom[pos++]<<4;
+ v|=oprom[pos++]<<8;
+ v|=oprom[pos++]<<12;
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], v);
+ break;
+ case Imm5:
+ v=oprom[pos++];
+ v|=oprom[pos++]<<4;
+ v|=oprom[pos++]<<8;
+ v|=oprom[pos++]<<12;
+ v|=oprom[pos++]<<16;
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], v);
+ break;
+ case ImmCload:
+ c=i=oprom[pos++] & 0xf;
+ number[i+1]=0;
+ for (;i>=0; i--) number[i]=number_2_hex[oprom[pos++] & 0xf];
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], c+1, number);
+ break;
+ case Dis3:
+ SATURN_PEEKOP_DIS12(v);
+ c=(pc+pos-3+v)&0xfffff;
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], c );
+ break;
+ case Dis3Call:
+ SATURN_PEEKOP_DIS12(v);
+ c=(pc+pos+v)&0xfffff;
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], c );
+ break;
+ case Dis4:
+ SATURN_PEEKOP_DIS16(v);
+ c=(pc+pos-4+v)&0xfffff;
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], c );
+ break;
+ case Dis4Call:
+ SATURN_PEEKOP_DIS16(v);
+ c=(pc+pos+v)&0xfffff;
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], c );
+ break;
+ case Abs:
+ SATURN_PEEKOP_ADR(v);
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], v );
+ break;
+ case BranchReturn:
+ SATURN_PEEKOP_DIS8(v);
+ if (v==0) {
+ strcpy(buffer, mnemonics[level->mnemonic+1].name[set]);
+ } else {
+ c=(pc+pos-2+v)&0xfffff;
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], c);
+ }
+ break;
+ case ABranchReturn:
+ SATURN_PEEKOP_DIS8(v);
+ if (v==0) {
+ sprintf(buffer, mnemonics[level->mnemonic+1].name[set], A);
+ } else {
+ c=(pc+pos-2+v)&0xfffff;
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], A, c);
+ }
+ break;
+ case xBranchReturn:
+ SATURN_PEEKOP_DIS8(v);
+ if (v==0) {
+ sprintf(buffer, mnemonics[level->mnemonic+1].name[set], field_2_string(adr));
+ } else {
+ c=(pc+pos-2+v)&0xfffff;
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], field_2_string(adr), c);
+ }
+ break;
+ case TestBranchRet:
+ i=oprom[pos++];
+ SATURN_PEEKOP_DIS8(v);
+ if (v==0) {
+ sprintf(buffer, mnemonics[level->mnemonic+1].name[set], i);
+ } else {
+ c=(pc+pos-2+v)&0xfffff;
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], i, c);
+ }
+ break;
+ case ImmBranch:
+ i=oprom[pos++];
+ SATURN_PEEKOP_DIS8(v);
+ c=(pc+pos-2+v)&0xfffff;
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], i, c);
+ break;
+ case FieldP:
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], P );
+ break;
+ case FieldWP:
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], WP );
+ break;
+ case FieldXS:
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], XS );
+ break;
+ case FieldX:
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], X );
+ break;
+ case FieldS:
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], S );
+ break;
+ case FieldM:
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], M );
+ break;
+ case FieldB:
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], B );
+ break;
+ case FieldA:
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], A );
+ break;
+ case FieldW:
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], W );
+ break;
+ case AdrA:
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], adr_a[oprom[pos++] & 0x7] );
+ break;
+ case AdrAF:
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], adr_af[oprom[pos++] & 0xf] );
+ break;
+ case AdrB:
+ sprintf(buffer, mnemonics[level->mnemonic].name[set], adr_b[oprom[pos++] & 0x7] );
+ break;
+ }
+ break;
+ }
+ level = opcodes[level->sel];
+ }
+
+ return pos;
+}