/***************************************************************************** * * 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 enum MNEMONICS { 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 }; 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", "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 }; 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 }; struct OPCODE { opcode_sel sel; opcode_adr adr; MNEMONICS mnemonic; }; 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; }