// license:BSD-3-Clause // copyright-holders:Peter Trauner,Antoine Mine /***************************************************************************** * * saturnds.c * portable saturn emulator interface * (hp calculators) * *****************************************************************************/ #include "emu.h" #include "saturnds.h" #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" const char *const saturn_disassembler::adr_b[]= { P, WP, XS, X, S, M, B, W }; const char *const saturn_disassembler::adr_af[]= { P, WP, XS, X, S, M, B, W, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, A }; const char *const saturn_disassembler::adr_a[]= { P, WP, XS, X, S, M, B, W }; const char saturn_disassembler::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_t)( opcodes.r8(pos) | ( opcodes.r8(pos+1) << 4 ) ); pos+= 2; #define SATURN_PEEKOP_DIS12(v) v = opcodes.r8(pos) | ( opcodes.r8(pos+1) << 4 ) | ( opcodes.r8(pos+2) << 8 ); \ pos += 3; \ if ( v & 0x0800 ) v = -0x1000 + v; #define SATURN_PEEKOP_DIS16(v) v = (int16_t)( opcodes.r8(pos) | ( opcodes.r8(pos+1) << 4 ) | ( opcodes.r8(pos+2) << 8 ) | ( opcodes.r8(pos+3) << 12 ) ); pos += 4; #define SATURN_PEEKOP_ADR(v) v = opcodes.r8(pos) | ( opcodes.r8(pos+1) << 4 ) | ( opcodes.r8(pos+2) << 8 ) | ( opcodes.r8(pos+3) << 12 ) | ( opcodes.r8(pos+4) << 16 ); pos += 5; const char *const saturn_disassembler::mnemonics[][2] = { { "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" } }; const char *saturn_disassembler::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 nullptr; } const saturn_disassembler::OPCODE saturn_disassembler::opcs[][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, xconfig }, { 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 } } }; const int saturn_disassembler::field_adr_af[]= { FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW, 0, 0, 0, 0, 0, 0, 0, FieldA }; const int saturn_disassembler::field_adr_a[]= { FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW}; const int saturn_disassembler::field_adr_b[]= { FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW }; saturn_disassembler::saturn_disassembler(config *conf) : m_config(conf) { } u32 saturn_disassembler::opcode_alignment() const { return 1; } offs_t saturn_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { 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=opcs[0]; //pointer to current digit int op; // currently fetched nibble offs_t pos = pc; int i,c,v; int mnemonics_bank = m_config->get_nonstandard_mnemonics_mode() ? 1 : 0; while (cont) { op = opcodes.r8(pos++) & 0xf; level+=op; switch (level->sel) { case Illegal: cont=0; bin[binsize++]=number_2_hex[op]; bin[binsize]=0; util::stream_format(stream, "???%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; util::stream_format(stream, "???%s",bin); break; } break; case Complete: cont=0; switch (level->adr==AdrNone?adr:level->adr) { case AdrNone: stream << mnemonics[level->mnemonic][mnemonics_bank]; break; case Imm: util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], opcodes.r8(pos++)); break; case ImmCount: util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], opcodes.r8(pos++)+1); break; case AdrImmCount: util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], field_2_string(adr), opcodes.r8(pos++)+1); break; case AdrCount: // mnemonics have string %s for address field snprintf(number,sizeof(number),"%x",opcodes.r8(pos++)+1); util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], number); break; case Imm2: v=opcodes.r8(pos++); v|=opcodes.r8(pos++)<<4; util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v); break; case Imm4: v=opcodes.r8(pos++); v|=opcodes.r8(pos++)<<4; v|=opcodes.r8(pos++)<<8; v|=opcodes.r8(pos++)<<12; util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v); break; case Imm5: v=opcodes.r8(pos++); v|=opcodes.r8(pos++)<<4; v|=opcodes.r8(pos++)<<8; v|=opcodes.r8(pos++)<<12; v|=opcodes.r8(pos++)<<16; util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v); break; case ImmCload: c=i=opcodes.r8(pos++) & 0xf; number[i+1]=0; for (;i>=0; i--) number[i]=number_2_hex[opcodes.r8(pos++) & 0xf]; util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c+1, number); break; case Dis3: SATURN_PEEKOP_DIS12(v); c=(pc+pos-3+v)&0xfffff; util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c ); break; case Dis3Call: SATURN_PEEKOP_DIS12(v); c=(pc+pos+v)&0xfffff; util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c ); break; case Dis4: SATURN_PEEKOP_DIS16(v); c=(pc+pos-4+v)&0xfffff; util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c ); break; case Dis4Call: SATURN_PEEKOP_DIS16(v); c=(pc+pos+v)&0xfffff; util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c ); break; case Abs: SATURN_PEEKOP_ADR(v); util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v ); break; case BranchReturn: SATURN_PEEKOP_DIS8(v); if (v==0) { stream << mnemonics[level->mnemonic+1][mnemonics_bank]; } else { c=(pc+pos-2+v)&0xfffff; util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c); } break; case ABranchReturn: SATURN_PEEKOP_DIS8(v); if (v==0) { util::stream_format(stream, mnemonics[level->mnemonic+1][mnemonics_bank], A); } else { c=(pc+pos-2+v)&0xfffff; util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], A, c); } break; case xBranchReturn: SATURN_PEEKOP_DIS8(v); if (v==0) { util::stream_format(stream, mnemonics[level->mnemonic+1][mnemonics_bank], field_2_string(adr)); } else { c=(pc+pos-2+v)&0xfffff; util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], field_2_string(adr), c); } break; case TestBranchRet: i=opcodes.r8(pos++); SATURN_PEEKOP_DIS8(v); if (v==0) { util::stream_format(stream, mnemonics[level->mnemonic+1][mnemonics_bank], i); } else { c=(pc+pos-2+v)&0xfffff; util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], i, c); } break; case ImmBranch: i=opcodes.r8(pos++); SATURN_PEEKOP_DIS8(v); c=(pc+pos-2+v)&0xfffff; util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], i, c); break; case FieldP: util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], P ); break; case FieldWP: util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], WP ); break; case FieldXS: util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], XS ); break; case FieldX: util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], X ); break; case FieldS: util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], S ); break; case FieldM: util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], M ); break; case FieldB: util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], B ); break; case FieldA: util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], A ); break; case FieldW: util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], W ); break; case AdrA: util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], adr_a[opcodes.r8(pos++) & 0x7] ); break; case AdrAF: util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], adr_af[opcodes.r8(pos++) & 0xf] ); break; case AdrB: util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], adr_b[opcodes.r8(pos++) & 0x7] ); break; } break; } level = opcs[level->sel]; } return pos - pc; }