summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/se3208/se3208.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/se3208/se3208.c')
-rw-r--r--src/emu/cpu/se3208/se3208.c1952
1 files changed, 1952 insertions, 0 deletions
diff --git a/src/emu/cpu/se3208/se3208.c b/src/emu/cpu/se3208/se3208.c
new file mode 100644
index 00000000000..684c6150e48
--- /dev/null
+++ b/src/emu/cpu/se3208/se3208.c
@@ -0,0 +1,1952 @@
+#include "debugger.h"
+#include "se3208.h"
+
+/*
+ SE3208 CPU Emulator by ElSemi
+
+ For information about this CPU:
+ www.adc.co.kr
+
+*/
+
+typedef struct
+{
+ //GPR
+ UINT32 R[8];
+ //SPR
+ UINT32 PC;
+ UINT32 SR;
+ UINT32 SP;
+ UINT32 ER;
+ UINT32 PPC;
+
+ int (*irq_callback)(int irqline);
+ UINT8 IRQ;
+ UINT8 NMI;
+} _SE3208Context;
+
+#define FLAG_C 0x0080
+#define FLAG_V 0x0010
+#define FLAG_S 0x0020
+#define FLAG_Z 0x0040
+
+#define FLAG_M 0x0200
+#define FLAG_E 0x0800
+#define FLAG_AUT 0x1000
+#define FLAG_ENI 0x2000
+#define FLAG_NMI 0x4000
+
+static _SE3208Context Context;
+static int SE3208_ICount;
+
+#define CLRFLAG(f) Context.SR&=~(f);
+#define SETFLAG(f) Context.SR|=(f);
+#define TESTFLAG(f) (Context.SR&(f))
+
+#define EXTRACT(val,sbit,ebit) (((val)>>sbit)&((1<<((ebit-sbit)+1))-1))
+#define SEX8(val) ((val&0x80)?(val|0xFFFFFF00):(val&0xFF))
+#define SEX16(val) ((val&0x8000)?(val|0xFFFF0000):(val&0xFFFF))
+#define ZEX8(val) ((val)&0xFF)
+#define ZEX16(val) ((val)&0xFFFF)
+#define SEX(bits,val) ((val)&(1<<(bits-1))?((val)|(~((1<<bits)-1))):(val&((1<<bits)-1)))
+
+//Precompute the instruction decoding in a big table
+typedef void (*_OP)(UINT16 Opcode);
+#define INST(a) static void a(UINT16 Opcode)
+static _OP *OpTable=NULL;
+
+INLINE UINT32 read_dword_unaligned(UINT32 address)
+{
+ if (address & 3)
+ return program_read_byte_32le(address) | program_read_byte_32le(address+1)<<8 | program_read_byte_32le(address+2)<<16 | program_read_byte_32le(address+3)<<24;
+ else
+ return program_read_dword_32le(address);
+}
+
+INLINE UINT16 read_word_unaligned(UINT32 address)
+{
+ if (address & 1)
+ return program_read_byte_32le(address) | program_read_byte_32le(address+1)<<8;
+ else
+ return program_read_word_32le(address);
+}
+
+INLINE void write_dword_unaligned(UINT32 address, UINT32 data)
+{
+ if (address & 3)
+ {
+ program_write_byte_32le(address, data & 0xff);
+ program_write_byte_32le(address+1, (data>>8)&0xff);
+ program_write_byte_32le(address+2, (data>>16)&0xff);
+ program_write_byte_32le(address+3, (data>>24)&0xff);
+ }
+ else
+ {
+ program_write_dword_32le(address, data);
+ }
+}
+
+INLINE void write_word_unaligned(UINT32 address, UINT16 data)
+{
+ if (address & 1)
+ {
+ program_write_byte_32le(address, data & 0xff);
+ program_write_byte_32le(address+1, (data>>8)&0xff);
+ }
+ else
+ {
+ program_write_word_32le(address, data);
+ }
+}
+
+
+INLINE UINT8 SE3208_Read8(UINT32 addr)
+{
+ return program_read_byte_32le(addr);
+}
+
+INLINE UINT16 SE3208_Read16(UINT32 addr)
+{
+ return read_word_unaligned(addr);
+}
+
+INLINE UINT32 SE3208_Read32(UINT32 addr)
+{
+ return read_dword_unaligned(addr);
+}
+
+INLINE void SE3208_Write8(UINT32 addr,UINT8 val)
+{
+ program_write_byte_32le(addr,val);
+}
+
+INLINE void SE3208_Write16(UINT32 addr,UINT16 val)
+{
+ write_word_unaligned(addr,val);
+}
+
+INLINE void SE3208_Write32(UINT32 addr,UINT32 val)
+{
+ write_dword_unaligned(addr,val);
+}
+
+
+
+INLINE UINT32 AddWithFlags(UINT32 a,UINT32 b)
+{
+ UINT32 r=a+b;
+ CLRFLAG(FLAG_Z|FLAG_C|FLAG_V|FLAG_S);
+ if(!r)
+ SETFLAG(FLAG_Z);
+ if(r&0x80000000)
+ SETFLAG(FLAG_S);
+ if(((((a&b)|(~r&(a|b)))>>31))&1)
+ SETFLAG(FLAG_C);
+ if(((((a^r)&(b^r))>>31))&1)
+ SETFLAG(FLAG_V);
+ return r;
+}
+
+INLINE UINT32 SubWithFlags(UINT32 a,UINT32 b) //a-b
+{
+ UINT32 r=a-b;
+ CLRFLAG(FLAG_Z|FLAG_C|FLAG_V|FLAG_S);
+ if(!r)
+ SETFLAG(FLAG_Z);
+ if(r&0x80000000)
+ SETFLAG(FLAG_S);
+ if((((b&r)|(~a&(b|r)))>>31)&1)
+ SETFLAG(FLAG_C);
+ if((((b^a)&(r^a))>>31)&1)
+ SETFLAG(FLAG_V);
+ return r;
+}
+
+INLINE UINT32 AdcWithFlags(UINT32 a,UINT32 b)
+{
+ UINT32 C=(Context.SR&FLAG_C)?1:0;
+ UINT32 r=a+b+C;
+ CLRFLAG(FLAG_Z|FLAG_C|FLAG_V|FLAG_S);
+ if(!r)
+ SETFLAG(FLAG_Z);
+ if(r&0x80000000)
+ SETFLAG(FLAG_S);
+ if(((((a&b)|(~r&(a|b)))>>31))&1)
+ SETFLAG(FLAG_C);
+ if(((((a^r)&(b^r))>>31))&1)
+ SETFLAG(FLAG_V);
+ return r;
+
+}
+
+INLINE UINT32 SbcWithFlags(UINT32 a,UINT32 b)
+{
+ UINT32 C=(Context.SR&FLAG_C)?1:0;
+ UINT32 r=a-b-C;
+ CLRFLAG(FLAG_Z|FLAG_C|FLAG_V|FLAG_S);
+ if(!r)
+ SETFLAG(FLAG_Z);
+ if(r&0x80000000)
+ SETFLAG(FLAG_S);
+ if((((b&r)|(~a&(b|r)))>>31)&1)
+ SETFLAG(FLAG_C);
+ if((((b^a)&(r^a))>>31)&1)
+ SETFLAG(FLAG_V);
+ return r;
+}
+
+INLINE UINT32 MulWithFlags(UINT32 a,UINT32 b)
+{
+ INT64 r=(INT64) a*(INT64) b;
+ CLRFLAG(FLAG_V);
+ if(r>>32)
+ SETFLAG(FLAG_V);
+ return (UINT32) (r&0xffffffff);
+}
+
+INLINE UINT32 NegWithFlags(UINT32 a)
+{
+ return SubWithFlags(0,a);
+}
+
+INLINE UINT32 AsrWithFlags(UINT32 Val, UINT8 By)
+{
+ signed int v=(signed int) Val;
+ v>>=By;
+ CLRFLAG(FLAG_Z|FLAG_C|FLAG_V|FLAG_S);
+ if(!v)
+ SETFLAG(FLAG_Z);
+ if(v&0x80000000)
+ SETFLAG(FLAG_S);
+ if(Val&(1<<(By-1)))
+ SETFLAG(FLAG_C);
+ return (UINT32) v;
+}
+
+INLINE UINT32 LsrWithFlags(UINT32 Val, UINT8 By)
+{
+ UINT32 v=Val;
+ v>>=By;
+ CLRFLAG(FLAG_Z|FLAG_C|FLAG_V|FLAG_S);
+ if(!v)
+ SETFLAG(FLAG_Z);
+ if(v&0x80000000)
+ SETFLAG(FLAG_S);
+ if(Val&(1<<(By-1)))
+ SETFLAG(FLAG_C);
+ return v;
+}
+
+INLINE UINT32 AslWithFlags(UINT32 Val, UINT8 By)
+{
+ UINT32 v=Val;
+ v<<=By;
+ CLRFLAG(FLAG_Z|FLAG_C|FLAG_V|FLAG_S);
+ if(!v)
+ SETFLAG(FLAG_Z);
+ if(v&0x80000000)
+ SETFLAG(FLAG_S);
+ if(Val&(1<<(32-By)))
+ SETFLAG(FLAG_C);
+ return v;
+}
+
+
+INST(INVALIDOP)
+{
+ //assert(false);
+}
+
+INST(LDB)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,4);
+ UINT32 Index=EXTRACT(Opcode,5,7);
+ UINT32 SrcDst=EXTRACT(Opcode,8,10);
+ UINT32 Val;
+
+ if(Index)
+ Index=Context.R[Index];
+ else
+ Index=0;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ Val=SE3208_Read8(Index+Offset);
+ Context.R[SrcDst]=SEX8(Val);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(STB)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,4);
+ UINT32 Index=EXTRACT(Opcode,5,7);
+ UINT32 SrcDst=EXTRACT(Opcode,8,10);
+
+ if(Index)
+ Index=Context.R[Index];
+ else
+ Index=0;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ SE3208_Write8(Index+Offset,ZEX8(Context.R[SrcDst]));
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(LDS)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,4);
+ UINT32 Index=EXTRACT(Opcode,5,7);
+ UINT32 SrcDst=EXTRACT(Opcode,8,10);
+ UINT32 Val;
+
+ Offset<<=1;
+
+ if(Index)
+ Index=Context.R[Index];
+ else
+ Index=0;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ Val=SE3208_Read16(Index+Offset);
+ Context.R[SrcDst]=SEX16(Val);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(STS)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,4);
+ UINT32 Index=EXTRACT(Opcode,5,7);
+ UINT32 SrcDst=EXTRACT(Opcode,8,10);
+
+ Offset<<=1;
+
+ if(Index)
+ Index=Context.R[Index];
+ else
+ Index=0;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ SE3208_Write16(Index+Offset,ZEX16(Context.R[SrcDst]));
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(LD)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,4);
+ UINT32 Index=EXTRACT(Opcode,5,7);
+ UINT32 SrcDst=EXTRACT(Opcode,8,10);
+
+ Offset<<=2;
+
+ if(Index)
+ Index=Context.R[Index];
+ else
+ Index=0;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ Context.R[SrcDst]=SE3208_Read32(Index+Offset);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(ST)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,4);
+ UINT32 Index=EXTRACT(Opcode,5,7);
+ UINT32 SrcDst=EXTRACT(Opcode,8,10);
+
+ Offset<<=2;
+
+ if(Index)
+ Index=Context.R[Index];
+ else
+ Index=0;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ SE3208_Write32(Index+Offset,Context.R[SrcDst]);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(LDBU)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,4);
+ UINT32 Index=EXTRACT(Opcode,5,7);
+ UINT32 SrcDst=EXTRACT(Opcode,8,10);
+ UINT32 Val;
+
+ if(Index)
+ Index=Context.R[Index];
+ else
+ Index=0;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ Val=SE3208_Read8(Index+Offset);
+ Context.R[SrcDst]=ZEX8(Val);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(LDSU)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,4);
+ UINT32 Index=EXTRACT(Opcode,5,7);
+ UINT32 SrcDst=EXTRACT(Opcode,8,10);
+ UINT32 Val;
+
+ Offset<<=1;
+
+ if(Index)
+ Index=Context.R[Index];
+ else
+ Index=0;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ Val=SE3208_Read16(Index+Offset);
+ Context.R[SrcDst]=ZEX16(Val);
+
+ CLRFLAG(FLAG_E);
+}
+
+
+INST(LERI)
+{
+ UINT32 Imm=EXTRACT(Opcode,0,13);
+ if(TESTFLAG(FLAG_E))
+ Context.ER=(EXTRACT(Context.ER,0,17)<<14)|Imm;
+ else
+ Context.ER=SEX(14,Imm);
+
+
+ SETFLAG(FLAG_E);
+}
+
+INST(LDSP)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+ UINT32 Index=Context.SP;
+ UINT32 SrcDst=EXTRACT(Opcode,8,10);
+
+ Offset<<=2;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ Context.R[SrcDst]=SE3208_Read32(Index+Offset);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(STSP)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+ UINT32 Index=Context.SP;
+ UINT32 SrcDst=EXTRACT(Opcode,8,10);
+
+ Offset<<=2;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ SE3208_Write32(Index+Offset,Context.R[SrcDst]);
+
+ CLRFLAG(FLAG_E);
+}
+
+static void PushVal(UINT32 Val)
+{
+ Context.SP-=4;
+ SE3208_Write32(Context.SP,Val);
+}
+
+static UINT32 PopVal(void)
+{
+ UINT32 Val=SE3208_Read32(Context.SP);
+ Context.SP+=4;
+ return Val;
+}
+
+INST(PUSH)
+{
+ UINT32 Set=EXTRACT(Opcode,0,10);
+ if(Set&(1<<10))
+ PushVal(Context.PC);
+ if(Set&(1<<9))
+ PushVal(Context.SR);
+ if(Set&(1<<8))
+ PushVal(Context.ER);
+ if(Set&(1<<7))
+ PushVal(Context.R[7]);
+ if(Set&(1<<6))
+ PushVal(Context.R[6]);
+ if(Set&(1<<5))
+ PushVal(Context.R[5]);
+ if(Set&(1<<4))
+ PushVal(Context.R[4]);
+ if(Set&(1<<3))
+ PushVal(Context.R[3]);
+ if(Set&(1<<2))
+ PushVal(Context.R[2]);
+ if(Set&(1<<1))
+ PushVal(Context.R[1]);
+ if(Set&(1<<0))
+ PushVal(Context.R[0]);
+}
+
+INST(POP)
+{
+ UINT32 Set=EXTRACT(Opcode,0,10);
+ if(Set&(1<<0))
+ Context.R[0]=PopVal();
+ if(Set&(1<<1))
+ Context.R[1]=PopVal();
+ if(Set&(1<<2))
+ Context.R[2]=PopVal();
+ if(Set&(1<<3))
+ Context.R[3]=PopVal();
+ if(Set&(1<<4))
+ Context.R[4]=PopVal();
+ if(Set&(1<<5))
+ Context.R[5]=PopVal();
+ if(Set&(1<<6))
+ Context.R[6]=PopVal();
+ if(Set&(1<<7))
+ Context.R[7]=PopVal();
+ if(Set&(1<<8))
+ Context.ER=PopVal();
+ if(Set&(1<<9))
+ Context.SR=PopVal();
+ if(Set&(1<<10))
+ {
+ Context.PC=PopVal()-2; //PC automatically incresases by 2
+ change_pc(Context.PC+2);
+ }
+}
+
+INST(LEATOSP)
+{
+ UINT32 Offset=EXTRACT(Opcode,9,12);
+ UINT32 Index=EXTRACT(Opcode,3,5);
+
+ if(Index)
+ Index=Context.R[Index];
+ else
+ Index=0;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+ else
+ Offset=SEX(4,Offset);
+
+ Context.SP=Index+Offset;
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(LEAFROMSP)
+{
+ UINT32 Offset=EXTRACT(Opcode,9,12);
+ UINT32 Index=EXTRACT(Opcode,3,5);
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+ else
+ Offset=SEX(4,Offset);
+
+ Context.R[Index]=Context.SP+Offset;
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(LEASPTOSP)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+
+ Offset<<=2;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,23)<<8)|(Offset&0xff);
+ else
+ Offset=SEX(10,Offset);
+
+ Context.SP=Context.SP+Offset;
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(MOV)
+{
+ UINT32 Src=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,9,11);
+
+ Context.R[Dst]=Context.R[Src];
+}
+
+INST(LDI)
+{
+ UINT32 Dst=EXTRACT(Opcode,8,10);
+ UINT32 Imm=EXTRACT(Opcode,0,7);
+
+ if(TESTFLAG(FLAG_E))
+ Imm=(EXTRACT(Context.ER,0,27)<<4)|(Imm&0xf);
+ else
+ Imm=SEX8(Imm);
+
+ Context.R[Dst]=Imm;
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(LDBSP)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,3);
+ UINT32 Index=Context.SP;
+ UINT32 SrcDst=EXTRACT(Opcode,4,6);
+ UINT32 Val;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ Val=SE3208_Read8(Index+Offset);
+ Context.R[SrcDst]=SEX8(Val);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(STBSP)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,3);
+ UINT32 Index=Context.SP;
+ UINT32 SrcDst=EXTRACT(Opcode,4,6);
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ SE3208_Write8(Index+Offset,ZEX8(Context.R[SrcDst]));
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(LDSSP)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,3);
+ UINT32 Index=Context.SP;
+ UINT32 SrcDst=EXTRACT(Opcode,4,6);
+ UINT32 Val;
+
+ Offset<<=1;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ Val=SE3208_Read16(Index+Offset);
+ Context.R[SrcDst]=SEX16(Val);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(STSSP)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,3);
+ UINT32 Index=Context.SP;
+ UINT32 SrcDst=EXTRACT(Opcode,4,6);
+
+ Offset<<=1;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ SE3208_Write16(Index+Offset,ZEX16(Context.R[SrcDst]));
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(LDBUSP)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,3);
+ UINT32 Index=Context.SP;
+ UINT32 SrcDst=EXTRACT(Opcode,4,6);
+ UINT32 Val;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ Val=SE3208_Read8(Index+Offset);
+ Context.R[SrcDst]=ZEX8(Val);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(LDSUSP)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,3);
+ UINT32 Index=Context.SP;
+ UINT32 SrcDst=EXTRACT(Opcode,4,6);
+ UINT32 Val;
+
+ Offset<<=1;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf);
+
+ Val=SE3208_Read16(Index+Offset);
+ Context.R[SrcDst]=ZEX16(Val);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(ADDI)
+{
+ UINT32 Imm=EXTRACT(Opcode,9,12);
+ UINT32 Src=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+
+ if(TESTFLAG(FLAG_E))
+ Imm=(EXTRACT(Context.ER,0,27)<<4)|(Imm&0xf);
+ else
+ Imm=SEX(4,Imm);
+
+ Context.R[Dst]=AddWithFlags(Context.R[Src],Imm);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(SUBI)
+{
+ UINT32 Imm=EXTRACT(Opcode,9,12);
+ UINT32 Src=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+
+ if(TESTFLAG(FLAG_E))
+ Imm=(EXTRACT(Context.ER,0,27)<<4)|(Imm&0xf);
+ else
+ Imm=SEX(4,Imm);
+
+ Context.R[Dst]=SubWithFlags(Context.R[Src],Imm);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(ADCI)
+{
+ UINT32 Imm=EXTRACT(Opcode,9,12);
+ UINT32 Src=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+
+ if(TESTFLAG(FLAG_E))
+ Imm=(EXTRACT(Context.ER,0,27)<<4)|(Imm&0xf);
+ else
+ Imm=SEX(4,Imm);
+
+ Context.R[Dst]=AdcWithFlags(Context.R[Src],Imm);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(SBCI)
+{
+ UINT32 Imm=EXTRACT(Opcode,9,12);
+ UINT32 Src=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+
+ if(TESTFLAG(FLAG_E))
+ Imm=(EXTRACT(Context.ER,0,27)<<4)|(Imm&0xf);
+ else
+ Imm=SEX(4,Imm);
+
+ Context.R[Dst]=SbcWithFlags(Context.R[Src],Imm);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(ANDI)
+{
+ UINT32 Imm=EXTRACT(Opcode,9,12);
+ UINT32 Src=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+
+ if(TESTFLAG(FLAG_E))
+ Imm=(EXTRACT(Context.ER,0,27)<<4)|(Imm&0xf);
+ else
+ Imm=SEX(4,Imm);
+
+ Context.R[Dst]=Context.R[Src]&Imm;
+
+ CLRFLAG(FLAG_S|FLAG_Z|FLAG_E);
+ if(!Context.R[Dst])
+ SETFLAG(FLAG_Z);
+ if(Context.R[Dst]&0x80000000)
+ SETFLAG(FLAG_S);
+}
+
+INST(ORI)
+{
+ UINT32 Imm=EXTRACT(Opcode,9,12);
+ UINT32 Src=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+
+ if(TESTFLAG(FLAG_E))
+ Imm=(EXTRACT(Context.ER,0,27)<<4)|(Imm&0xf);
+ else
+ Imm=SEX(4,Imm);
+
+ Context.R[Dst]=Context.R[Src]|Imm;
+
+ CLRFLAG(FLAG_S|FLAG_Z|FLAG_E);
+ if(!Context.R[Dst])
+ SETFLAG(FLAG_Z);
+ if(Context.R[Dst]&0x80000000)
+ SETFLAG(FLAG_S);
+}
+
+INST(XORI)
+{
+ UINT32 Imm=EXTRACT(Opcode,9,12);
+ UINT32 Src=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+
+ if(TESTFLAG(FLAG_E))
+ Imm=(EXTRACT(Context.ER,0,27)<<4)|(Imm&0xf);
+ else
+ Imm=SEX(4,Imm);
+
+ Context.R[Dst]=Context.R[Src]^Imm;
+
+ CLRFLAG(FLAG_S|FLAG_Z|FLAG_E);
+ if(!Context.R[Dst])
+ SETFLAG(FLAG_Z);
+ if(Context.R[Dst]&0x80000000)
+ SETFLAG(FLAG_S);
+}
+
+INST(CMPI)
+{
+ UINT32 Imm=EXTRACT(Opcode,9,12);
+ UINT32 Src=EXTRACT(Opcode,3,5);
+
+ if(TESTFLAG(FLAG_E))
+ Imm=(EXTRACT(Context.ER,0,27)<<4)|(Imm&0xf);
+ else
+ Imm=SEX(4,Imm);
+
+ SubWithFlags(Context.R[Src],Imm);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(TSTI)
+{
+ UINT32 Imm=EXTRACT(Opcode,9,12);
+ UINT32 Src=EXTRACT(Opcode,3,5);
+ UINT32 Dst;
+
+ if(TESTFLAG(FLAG_E))
+ Imm=(EXTRACT(Context.ER,0,27)<<4)|(Imm&0xf);
+ else
+ Imm=SEX(4,Imm);
+
+ Dst=Context.R[Src]&Imm;
+
+ CLRFLAG(FLAG_S|FLAG_Z|FLAG_E);
+ if(!Dst)
+ SETFLAG(FLAG_Z);
+ if(Dst&0x80000000)
+ SETFLAG(FLAG_S);
+}
+
+INST(ADD)
+{
+ UINT32 Src2=EXTRACT(Opcode,9,11);
+ UINT32 Src1=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+
+ Context.R[Dst]=AddWithFlags(Context.R[Src1],Context.R[Src2]);
+}
+
+INST(SUB)
+{
+ UINT32 Src2=EXTRACT(Opcode,9,11);
+ UINT32 Src1=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+
+ Context.R[Dst]=SubWithFlags(Context.R[Src1],Context.R[Src2]);
+}
+
+INST(ADC)
+{
+ UINT32 Src2=EXTRACT(Opcode,9,11);
+ UINT32 Src1=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+
+ Context.R[Dst]=AdcWithFlags(Context.R[Src1],Context.R[Src2]);
+}
+
+INST(SBC)
+{
+ UINT32 Src2=EXTRACT(Opcode,9,11);
+ UINT32 Src1=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+
+ Context.R[Dst]=SbcWithFlags(Context.R[Src1],Context.R[Src2]);
+}
+
+INST(AND)
+{
+ UINT32 Src2=EXTRACT(Opcode,9,11);
+ UINT32 Src1=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+
+ Context.R[Dst]=Context.R[Src1]&Context.R[Src2];
+
+ CLRFLAG(FLAG_S|FLAG_Z);
+ if(!Context.R[Dst])
+ SETFLAG(FLAG_Z);
+ if(Context.R[Dst]&0x80000000)
+ SETFLAG(FLAG_S);
+}
+
+INST(OR)
+{
+ UINT32 Src2=EXTRACT(Opcode,9,11);
+ UINT32 Src1=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+
+ Context.R[Dst]=Context.R[Src1]|Context.R[Src2];
+
+ CLRFLAG(FLAG_S|FLAG_Z);
+ if(!Context.R[Dst])
+ SETFLAG(FLAG_Z);
+ if(Context.R[Dst]&0x80000000)
+ SETFLAG(FLAG_S);
+
+}
+
+INST(XOR)
+{
+ UINT32 Src2=EXTRACT(Opcode,9,11);
+ UINT32 Src1=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+
+ Context.R[Dst]=Context.R[Src1]^Context.R[Src2];
+
+ CLRFLAG(FLAG_S|FLAG_Z);
+ if(!Context.R[Dst])
+ SETFLAG(FLAG_Z);
+ if(Context.R[Dst]&0x80000000)
+ SETFLAG(FLAG_S);
+
+}
+
+INST(CMP)
+{
+ UINT32 Src2=EXTRACT(Opcode,9,11);
+ UINT32 Src1=EXTRACT(Opcode,3,5);
+
+ SubWithFlags(Context.R[Src1],Context.R[Src2]);
+}
+
+INST(TST)
+{
+ UINT32 Src2=EXTRACT(Opcode,9,11);
+ UINT32 Src1=EXTRACT(Opcode,3,5);
+ UINT32 Dst;
+
+ Dst=Context.R[Src1]&Context.R[Src2];
+
+ CLRFLAG(FLAG_S|FLAG_Z);
+ if(!Dst)
+ SETFLAG(FLAG_Z);
+ if(Dst&0x80000000)
+ SETFLAG(FLAG_S);
+}
+
+INST(MULS)
+{
+ UINT32 Src2=EXTRACT(Opcode,6,8);
+ UINT32 Src1=EXTRACT(Opcode,3,5);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+
+ Context.R[Dst]=MulWithFlags(Context.R[Src1],Context.R[Src2]);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(NEG)
+{
+ UINT32 Dst=EXTRACT(Opcode,9,11);
+ UINT32 Src=EXTRACT(Opcode,3,5);
+
+ Context.R[Dst]=NegWithFlags(Context.R[Src]);
+}
+
+INST(CALL)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+ Offset<<=1;
+ PushVal(Context.PC+2);
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(JV)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+ Offset<<=1;
+
+ if(TESTFLAG(FLAG_V))
+ {
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+ }
+
+ CLRFLAG(FLAG_E);
+
+}
+
+INST(JNV)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+ Offset<<=1;
+
+ if(!TESTFLAG(FLAG_V))
+ {
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+ }
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(JC)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+ Offset<<=1;
+
+ if(TESTFLAG(FLAG_C))
+ {
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+ }
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(JNC)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+ Offset<<=1;
+
+ if(!TESTFLAG(FLAG_C))
+ {
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+ }
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(JP)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+ Offset<<=1;
+
+ if(!TESTFLAG(FLAG_S))
+ {
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+ }
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(JM)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+ Offset<<=1;
+
+ if(TESTFLAG(FLAG_S))
+ {
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+ }
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(JNZ)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+ Offset<<=1;
+
+ if(!TESTFLAG(FLAG_Z))
+ {
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+ }
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(JZ)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+ Offset<<=1;
+
+ if(TESTFLAG(FLAG_Z))
+ {
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+ }
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(JGE)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+ UINT32 S=TESTFLAG(FLAG_S)?1:0;
+ UINT32 V=TESTFLAG(FLAG_V)?1:0;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+ Offset<<=1;
+
+ if(!(S^V))
+ {
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+ }
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(JLE)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+ UINT32 S=TESTFLAG(FLAG_S)?1:0;
+ UINT32 V=TESTFLAG(FLAG_V)?1:0;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+ Offset<<=1;
+
+ if(TESTFLAG(FLAG_Z) || (S^V))
+ {
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+ }
+ CLRFLAG(FLAG_E);
+}
+
+INST(JHI)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+ Offset<<=1;
+
+ if(!(TESTFLAG(FLAG_Z) || TESTFLAG(FLAG_C)))
+ {
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+ }
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(JLS)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+ Offset<<=1;
+
+ if(TESTFLAG(FLAG_Z) || TESTFLAG(FLAG_C))
+ {
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+ }
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(JGT)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+ UINT32 S=TESTFLAG(FLAG_S)?1:0;
+ UINT32 V=TESTFLAG(FLAG_V)?1:0;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+ Offset<<=1;
+
+ if(!(TESTFLAG(FLAG_Z) || (S^V)))
+ {
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+ }
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(JLT)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+ UINT32 S=TESTFLAG(FLAG_S)?1:0;
+ UINT32 V=TESTFLAG(FLAG_V)?1:0;
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+ Offset<<=1;
+
+ if(S^V)
+ {
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+ }
+
+ CLRFLAG(FLAG_E);
+}
+
+
+
+INST(JMP)
+{
+ UINT32 Offset=EXTRACT(Opcode,0,7);
+
+ if(TESTFLAG(FLAG_E))
+ Offset=(EXTRACT(Context.ER,0,22)<<8)|Offset;
+ else
+ Offset=SEX(8,Offset);
+
+ Offset<<=1;
+
+ Context.PC=Context.PC+Offset;
+ change_pc(Context.PC+2);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(JR)
+{
+ UINT32 Src=EXTRACT(Opcode,0,3);
+
+ Context.PC=Context.R[Src]-2;
+ change_pc(Context.PC+2);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(CALLR)
+{
+ UINT32 Src=EXTRACT(Opcode,0,3);
+ PushVal(Context.PC+2);
+ Context.PC=Context.R[Src]-2;
+ change_pc(Context.PC+2);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(ASR)
+{
+ UINT32 CS=Opcode&(1<<10);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+ UINT32 Imm=EXTRACT(Opcode,5,9);
+ UINT32 Cnt=EXTRACT(Opcode,5,7);
+
+ if(CS)
+ Context.R[Dst]=AsrWithFlags(Context.R[Dst],Context.R[Cnt]&0x1f);
+ else
+ Context.R[Dst]=AsrWithFlags(Context.R[Dst],Imm&0x1f);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(LSR)
+{
+ UINT32 CS=Opcode&(1<<10);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+ UINT32 Imm=EXTRACT(Opcode,5,9);
+ UINT32 Cnt=EXTRACT(Opcode,5,7);
+
+ if(CS)
+ Context.R[Dst]=LsrWithFlags(Context.R[Dst],Context.R[Cnt]&0x1f);
+ else
+ Context.R[Dst]=LsrWithFlags(Context.R[Dst],Imm&0x1f);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(ASL)
+{
+ UINT32 CS=Opcode&(1<<10);
+ UINT32 Dst=EXTRACT(Opcode,0,2);
+ UINT32 Imm=EXTRACT(Opcode,5,9);
+ UINT32 Cnt=EXTRACT(Opcode,5,7);
+
+ if(CS)
+ Context.R[Dst]=AslWithFlags(Context.R[Dst],Context.R[Cnt]&0x1f);
+ else
+ Context.R[Dst]=AslWithFlags(Context.R[Dst],Imm&0x1f);
+
+ CLRFLAG(FLAG_E);
+}
+
+INST(EXTB)
+{
+ UINT32 Dst=EXTRACT(Opcode,0,3);
+ UINT32 Val=Context.R[Dst];
+
+ Context.R[Dst]=SEX8(Val);
+
+ CLRFLAG(FLAG_S|FLAG_Z|FLAG_E);
+ if(!Context.R[Dst])
+ SETFLAG(FLAG_Z);
+ if(Context.R[Dst]&0x80000000)
+ SETFLAG(FLAG_S);
+
+}
+
+INST(EXTS)
+{
+ UINT32 Dst=EXTRACT(Opcode,0,3);
+ UINT32 Val=Context.R[Dst];
+
+ Context.R[Dst]=SEX16(Val);
+
+ CLRFLAG(FLAG_S|FLAG_Z|FLAG_E);
+ if(!Context.R[Dst])
+ SETFLAG(FLAG_Z);
+ if(Context.R[Dst]&0x80000000)
+ SETFLAG(FLAG_S);
+}
+
+INST(SET)
+{
+ UINT32 Imm=EXTRACT(Opcode,0,3);
+
+ Context.SR|=(1<<Imm);
+}
+
+INST(CLR)
+{
+ UINT32 Imm=EXTRACT(Opcode,0,3);
+
+ Context.SR&=~(1<<Imm);
+}
+
+INST(SWI)
+{
+ UINT32 Imm=EXTRACT(Opcode,0,3);
+
+ if(!TESTFLAG(FLAG_ENI))
+ return;
+ PushVal(Context.PC);
+ PushVal(Context.SR);
+
+ CLRFLAG(FLAG_ENI|FLAG_E|FLAG_M);
+
+ Context.PC=SE3208_Read32(4*Imm+0x40)-2;
+ change_pc(Context.PC+2);
+}
+
+INST(HALT)
+{
+// UINT32 Imm=EXTRACT(Opcode,0,3);
+
+// DEBUGMESSAGE("HALT\t0x%x",Imm);
+}
+
+INST(MVTC)
+{
+// UINT32 Imm=EXTRACT(Opcode,0,3);
+
+// DEBUGMESSAGE("MVTC\t%%R0,%%CR%d",Imm);
+}
+
+INST(MVFC)
+{
+// UINT32 Imm=EXTRACT(Opcode,0,3);
+
+// DEBUGMESSAGE("MVFC\t%%CR0%d,%%R0",Imm);
+}
+
+
+static _OP DecodeOp(UINT16 Opcode)
+{
+ switch(EXTRACT(Opcode,14,15))
+ {
+ case 0x0:
+ {
+ UINT8 Op=EXTRACT(Opcode,11,13);
+ switch(Op)
+ {
+ case 0x0:
+ return LDB;
+ case 0x1:
+ return LDS;
+ case 0x2:
+ return LD;
+ case 0x3:
+ return LDBU;
+ case 0x4:
+ return STB;
+ case 0x5:
+ return STS;
+ case 0x6:
+ return ST;
+ case 0x7:
+ return LDSU;
+ }
+ }
+ break;
+ case 0x1:
+ return LERI;
+ break;
+ case 0x2:
+ {
+ switch(EXTRACT(Opcode,11,13))
+ {
+ case 0:
+ return LDSP;
+ case 1:
+ return STSP;
+ case 2:
+ return PUSH;
+ case 3:
+ return POP;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8: //arith
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ switch(EXTRACT(Opcode,6,8))
+ {
+ case 0:
+ return ADDI;
+ case 1:
+ return ADCI;
+ case 2:
+ return SUBI;
+ case 3:
+ return SBCI;
+ case 4:
+ return ANDI;
+ case 5:
+ return ORI;
+ case 6:
+ return XORI;
+ case 7:
+ switch(EXTRACT(Opcode,0,2))
+ {
+ case 0:
+ return CMPI;
+ case 1:
+ return TSTI;
+ case 2:
+ return LEATOSP;
+ case 3:
+ return LEAFROMSP;
+ }
+ break;
+ }
+ break;
+ }
+ }
+ break;
+ case 3:
+ switch(EXTRACT(Opcode,12,13))
+ {
+ case 0:
+ switch(EXTRACT(Opcode,6,8))
+ {
+ case 0:
+ return ADD;
+ case 1:
+ return ADC;
+ case 2:
+ return SUB;
+ case 3:
+ return SBC;
+ case 4:
+ return AND;
+ case 5:
+ return OR;
+ case 6:
+ return XOR;
+ case 7:
+ switch(EXTRACT(Opcode,0,2))
+ {
+ case 0:
+ return CMP;
+ case 1:
+ return TST;
+ case 2:
+ return MOV;
+ case 3:
+ return NEG;
+ }
+ break;
+ }
+ break;
+ case 1: //Jumps
+ switch(EXTRACT(Opcode,8,11))
+ {
+ case 0x0:
+ return JNV;
+ case 0x1:
+ return JV;
+ case 0x2:
+ return JP;
+ case 0x3:
+ return JM;
+ case 0x4:
+ return JNZ;
+ case 0x5:
+ return JZ;
+ case 0x6:
+ return JNC;
+ case 0x7:
+ return JC;
+ case 0x8:
+ return JGT;
+ case 0x9:
+ return JLT;
+ case 0xa:
+ return JGE;
+ case 0xb:
+ return JLE;
+ case 0xc:
+ return JHI;
+ case 0xd:
+ return JLS;
+ case 0xe:
+ return JMP;
+ case 0xf:
+ return CALL;
+ }
+ break;
+ case 2:
+ if(Opcode&(1<<11))
+ return LDI;
+ else //SP Ops
+ {
+ if(Opcode&(1<<10))
+ {
+ switch(EXTRACT(Opcode,7,9))
+ {
+ case 0:
+ return LDBSP;
+ case 1:
+ return LDSSP;
+ case 3:
+ return LDBUSP;
+ case 4:
+ return STBSP;
+ case 5:
+ return STSSP;
+ case 7:
+ return LDSUSP;
+ }
+ }
+ else
+ {
+ if(Opcode&(1<<9))
+ {
+ return LEASPTOSP;
+ }
+ else
+ {
+ if(Opcode&(1<<8))
+ {
+
+ }
+ else
+ {
+ switch(EXTRACT(Opcode,4,7))
+ {
+ case 0:
+ return EXTB;
+ case 1:
+ return EXTS;
+ case 8:
+ return JR;
+ case 9:
+ return CALLR;
+ case 10:
+ return SET;
+ case 11:
+ return CLR;
+ case 12:
+ return SWI;
+ case 13:
+ return HALT;
+ }
+ }
+ }
+ }
+ }
+ break;
+ case 3:
+ switch(EXTRACT(Opcode,9,11))
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ switch(EXTRACT(Opcode,3,4))
+ {
+ case 0:
+ return ASR;
+ case 1:
+ return LSR;
+ case 2:
+ return ASL;
+ //case 3:
+ // return LSL;
+ }
+ break;
+ case 4:
+ return MULS;
+ case 6:
+ if(Opcode&(1<<3))
+ return MVFC;
+ else
+ return MVTC;
+ break;
+ }
+ break;
+ }
+ break;
+
+ }
+ return INVALIDOP;
+}
+
+
+static void BuildTable(void)
+{
+ int i;
+ if(!OpTable)
+ OpTable=malloc_or_die(sizeof(_OP)*0x10000);
+ for(i=0;i<0x10000;++i)
+ OpTable[i]=DecodeOp(i);
+}
+
+static void SE3208_Reset(void)
+{
+ int (*save_irqcallback)(int) = Context.irq_callback;
+ memset(&Context,0,sizeof(_SE3208Context));
+ Context.irq_callback = save_irqcallback;
+ Context.PC=SE3208_Read32(0);
+ Context.SR=0;
+ Context.IRQ=CLEAR_LINE;
+ Context.NMI=CLEAR_LINE;
+ change_pc(Context.PC+2);
+}
+
+static void SE3208_NMI(void)
+{
+ PushVal(Context.PC);
+ PushVal(Context.SR);
+
+ CLRFLAG(FLAG_NMI|FLAG_ENI|FLAG_E|FLAG_M);
+
+ Context.PC=SE3208_Read32(4);
+ change_pc(Context.PC+2);
+}
+
+static void SE3208_Interrupt(void)
+{
+ if(!TESTFLAG(FLAG_ENI))
+ return;
+
+ PushVal(Context.PC);
+ PushVal(Context.SR);
+
+ CLRFLAG(FLAG_ENI|FLAG_E|FLAG_M);
+
+
+ if(!(TESTFLAG(FLAG_AUT)))
+ Context.PC=SE3208_Read32(8);
+ else
+ Context.PC=SE3208_Read32(4*Context.irq_callback(0));
+ change_pc(Context.PC+2);
+}
+
+
+static int SE3208_Run(int cycles)
+{
+ SE3208_ICount=cycles;
+ do
+ {
+ UINT16 Opcode=cpu_readop16(WORD_XOR_LE(Context.PC));
+
+ CALL_MAME_DEBUG;
+
+ OpTable[Opcode](Opcode);
+ Context.PPC=Context.PC;
+ Context.PC+=2;
+ //Check interrupts
+ if(Context.NMI==ASSERT_LINE)
+ {
+ SE3208_NMI();
+ Context.NMI=CLEAR_LINE;
+ }
+ else if(Context.IRQ==ASSERT_LINE && TESTFLAG(FLAG_ENI))
+ {
+ SE3208_Interrupt();
+ }
+ --SE3208_ICount;
+ } while(SE3208_ICount>0);
+
+ return cycles-SE3208_ICount;
+}
+
+static void SE3208_Init(int index, int clock, const void *config, int (*irqcallback)(int))
+{
+ BuildTable();
+
+ Context.irq_callback = irqcallback;
+}
+
+static void SE3208_Exit(void)
+{
+ if(OpTable)
+ free(OpTable);
+}
+
+
+static void SE3208_get_context(void *dst)
+{
+ if(dst)
+ memcpy(dst,&Context,sizeof(Context));
+}
+
+static void SE3208_set_context(void *src)
+{
+ if(src)
+ memcpy(&Context,src,sizeof(Context));
+}
+
+static void set_irq_line(int line,int state)
+{
+ if(line==INPUT_LINE_NMI) //NMI
+ Context.NMI=state;
+ else
+ Context.IRQ=state;
+}
+
+
+static void SE3208_set_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are set as 64-bit signed integers --- */
+ case CPUINFO_INT_INPUT_STATE + SE3208_INT: set_irq_line(0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: set_irq_line(INPUT_LINE_NMI, info->i); break;
+
+ case CPUINFO_INT_REGISTER + SE3208_PC:
+ case CPUINFO_INT_PC: Context.PC = info->i; break;
+ case CPUINFO_INT_REGISTER + SE3208_SP:
+ case CPUINFO_INT_SP: Context.SP = info->i; break;
+ case CPUINFO_INT_REGISTER + SE3208_ER: Context.ER = info->i; break;
+ case CPUINFO_INT_REGISTER + SE3208_SR: Context.SR = info->i; break;
+ case CPUINFO_INT_REGISTER + SE3208_R0: Context.R[ 0] = info->i; break;
+ case CPUINFO_INT_REGISTER + SE3208_R1: Context.R[ 1] = info->i; break;
+ case CPUINFO_INT_REGISTER + SE3208_R2: Context.R[ 2] = info->i; break;
+ case CPUINFO_INT_REGISTER + SE3208_R3: Context.R[ 3] = info->i; break;
+ case CPUINFO_INT_REGISTER + SE3208_R4: Context.R[ 4] = info->i; break;
+ case CPUINFO_INT_REGISTER + SE3208_R5: Context.R[ 5] = info->i; break;
+ case CPUINFO_INT_REGISTER + SE3208_R6: Context.R[ 6] = info->i; break;
+ case CPUINFO_INT_REGISTER + SE3208_R7: Context.R[ 7] = info->i; break;
+ }
+}
+
+
+void SE3208_get_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(Context); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 1; break;
+ case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
+ case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_LE; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
+ case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 2; break;
+ case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 2; break;
+ case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
+ case CPUINFO_INT_MAX_CYCLES: info->i = 1; break;
+
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break;
+
+ case CPUINFO_INT_INPUT_STATE + SE3208_INT: info->i = Context.IRQ; break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: info->i = Context.NMI; break;
+
+ case CPUINFO_INT_PREVIOUSPC: info->i = Context.PPC; break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + SE3208_PC: info->i = Context.PC; break;
+ case CPUINFO_INT_REGISTER + SE3208_SP:
+ case CPUINFO_INT_SP: info->i = Context.SP; break;
+ case CPUINFO_INT_REGISTER + SE3208_SR: info->i = Context.SR; break;
+ case CPUINFO_INT_REGISTER + SE3208_ER: info->i = Context.ER; break;
+ case CPUINFO_INT_REGISTER + SE3208_R0: info->i = Context.R[ 0]; break;
+ case CPUINFO_INT_REGISTER + SE3208_R1: info->i = Context.R[ 1]; break;
+ case CPUINFO_INT_REGISTER + SE3208_R2: info->i = Context.R[ 2]; break;
+ case CPUINFO_INT_REGISTER + SE3208_R3: info->i = Context.R[ 3]; break;
+ case CPUINFO_INT_REGISTER + SE3208_R4: info->i = Context.R[ 4]; break;
+ case CPUINFO_INT_REGISTER + SE3208_R5: info->i = Context.R[ 5]; break;
+ case CPUINFO_INT_REGISTER + SE3208_R6: info->i = Context.R[ 6]; break;
+ case CPUINFO_INT_REGISTER + SE3208_R7: info->i = Context.R[ 7]; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_SET_INFO: info->setinfo = SE3208_set_info; break;
+ case CPUINFO_PTR_GET_CONTEXT: info->getcontext = SE3208_get_context; break;
+ case CPUINFO_PTR_SET_CONTEXT: info->setcontext = SE3208_set_context; break;
+ case CPUINFO_PTR_INIT: info->init = SE3208_Init; break;
+ case CPUINFO_PTR_RESET: info->reset = SE3208_Reset; break;
+ case CPUINFO_PTR_EXIT: info->exit = SE3208_Exit; break;
+ case CPUINFO_PTR_EXECUTE: info->execute = SE3208_Run; break;
+ case CPUINFO_PTR_BURN: info->burn = NULL; break;
+#ifdef MAME_DEBUG
+ case CPUINFO_PTR_DISASSEMBLE: info->disassemble = SE3208_Dasm; break;
+#endif /* MAME_DEBUG */
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &SE3208_ICount; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s, "SE3208"); break;
+ case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "Advanced Digital Chips Inc."); break;
+ case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.00"); break;
+ case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
+ case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright (c) 2005 ElSemi, all rights reserved."); break;
+
+ case CPUINFO_STR_FLAGS:
+ sprintf(info->s, "%c%c%c%c %c%c%c%c%c",
+ Context.SR&FLAG_C?'C':'.',
+ Context.SR&FLAG_V?'V':'.',
+ Context.SR&FLAG_S?'S':'.',
+ Context.SR&FLAG_Z?'Z':'.',
+
+ Context.SR&FLAG_M?'M':'.',
+ Context.SR&FLAG_E?'E':'.',
+ Context.SR&FLAG_AUT?'A':'.',
+ Context.SR&FLAG_ENI?'I':'.',
+ Context.SR&FLAG_NMI?'N':'.'
+
+ );
+
+ break;
+
+ case CPUINFO_STR_REGISTER + SE3208_PC: sprintf(info->s, "PC :%08X", Context.PC); break;
+ case CPUINFO_STR_REGISTER + SE3208_SR: sprintf(info->s, "SR :%08X", Context.SR); break;
+ case CPUINFO_STR_REGISTER + SE3208_ER: sprintf(info->s, "ER :%08X", Context.ER); break;
+ case CPUINFO_STR_REGISTER + SE3208_SP: sprintf(info->s, "SP :%08X", Context.SP); break;
+ case CPUINFO_STR_REGISTER + SE3208_R0: sprintf(info->s, "R0 :%08X", Context.R[ 0]); break;
+ case CPUINFO_STR_REGISTER + SE3208_R1: sprintf(info->s, "R1 :%08X", Context.R[ 1]); break;
+ case CPUINFO_STR_REGISTER + SE3208_R2: sprintf(info->s, "R2 :%08X", Context.R[ 2]); break;
+ case CPUINFO_STR_REGISTER + SE3208_R3: sprintf(info->s, "R3 :%08X", Context.R[ 3]); break;
+ case CPUINFO_STR_REGISTER + SE3208_R4: sprintf(info->s, "R4 :%08X", Context.R[ 4]); break;
+ case CPUINFO_STR_REGISTER + SE3208_R5: sprintf(info->s, "R5 :%08X", Context.R[ 5]); break;
+ case CPUINFO_STR_REGISTER + SE3208_R6: sprintf(info->s, "R6 :%08X", Context.R[ 6]); break;
+ case CPUINFO_STR_REGISTER + SE3208_R7: sprintf(info->s, "R7 :%08X", Context.R[ 7]); break;
+ case CPUINFO_STR_REGISTER + SE3208_PPC: sprintf(info->s, "PPC :%08X", Context.PPC); break;
+ }
+}
+