fx9860-emulator-playground/scripts/generated/instructions.c

2054 lines
47 KiB
C

#include "../headers/instructions/instructions.h"
// Returns a pointer to the function that implements the corresponding instruction
void (*get_instruction_impl(uint16_t instruction))(cpu_t*, uint16_t) {
uint8_t high = (instruction >> 12) & 0x0F;
uint8_t high8 = instruction >> 8;
uint8_t low = instruction & 0x0F;
uint8_t low8 = instruction & 0xFF;
if (instruction == 0b0000000000101000) return CLRMAC;
if (instruction == 0b0000000001001000) return CLRS;
if (instruction == 0b0000000000001000) return CLRT;
if (instruction == 0b0000000000011001) return DIV0U;
if (instruction == 0b0000000000001001) return NOP;
if (instruction == 0b0000000000101011) return RTE;
if (instruction == 0b0000000000001011) return RTS;
if (instruction == 0b0000000001011000) return SETS;
if (instruction == 0b0000000000011000) return SETT;
if (high8 == 0b11001001) return ANDI;
if (high8 == 0b11001101) return ANDM;
if (high8 == 0b10001011) return BF;
if (high8 == 0b10001111) return BFS;
if (high8 == 0b10001001) return BT;
if (high8 == 0b10001101) return BTS;
if (high8 == 0b10001000) return CMPIM;
if (high8 == 0b11000100) return MOVBLG;
if (high8 == 0b11000101) return MOVWLG;
if (high8 == 0b11000110) return MOVLLG;
if (high8 == 0b11000000) return MOVBSG;
if (high8 == 0b11000001) return MOVWSG;
if (high8 == 0b11000010) return MOVLSG;
if (high8 == 0b10000000) return MOVBS4;
if (high8 == 0b10000001) return MOVWS4;
if (high8 == 0b10000100) return MOVBL4;
if (high8 == 0b10000101) return MOVWL4;
if (high8 == 0b11000111) return MOVA;
if (high8 == 0b11001011) return ORI;
if (high8 == 0b11001111) return ORM;
if (high8 == 0b11001000) return TSTI;
if (high8 == 0b11001100) return TSTM;
if (high8 == 0b11001010) return XORI;
if (high8 == 0b11001110) return XORM;
if (high == 0b0111) return ADDI;
if (high == 0b1010) return BRA;
if (high == 0b1110) return MOVI;
if (high == 0b1001) return MOVWI;
if (high == 0b1101) return MOVLI;
if (high == 0b0001) return MOVLS4;
if (high == 0b0101) return MOVLL4;
if (high == 0b1011) return BSR;
if (high == 0b0100) {
if (low8 == 0b00010101) return CMPPL;
if (low8 == 0b00010001) return CMPPZ;
if (low8 == 0b00010000) return DT;
if (low8 == 0b00101011) return JMP;
if (low8 == 0b00011110) return LDCGBR;
if (low8 == 0b00101110) return LDCVBR;
if (low8 == 0b00111010) return LDCSGR;
if (low8 == 0b00111110) return LDCSSR;
if (low8 == 0b01001110) return LDCSPC;
if (low8 == 0b11111010) return LDCDBR;
if (low8 == 0b00010111) return LDCMGBR;
if (low8 == 0b00100111) return LDCMVBR;
if (low8 == 0b00110110) return LDCMSGR;
if (low8 == 0b00110111) return LDCMSSR;
if (low8 == 0b01000111) return LDCMSPC;
if (low8 == 0b11110110) return LDCMDBR;
if (low8 == 0b00001010) return LDSMACH;
if (low8 == 0b00011010) return LDSMACL;
if (low8 == 0b00101010) return LDSPR;
if (low8 == 0b00000110) return LDSMMACH;
if (low8 == 0b00010110) return LDSMMACL;
if (low8 == 0b00100110) return LDSMPR;
if (low8 == 0b00100100) return ROTCL;
if (low8 == 0b00100101) return ROTCR;
if (low8 == 0b00000100) return ROTL;
if (low8 == 0b00000101) return ROTR;
if (low8 == 0b00100000) return SHAL;
if (low8 == 0b00100001) return SHAR;
if (low8 == 0b00000000) return SHLL;
if (low8 == 0b00001000) return SHLL2;
if (low8 == 0b00011000) return SHLL8;
if (low8 == 0b00101000) return SHLL16;
if (low8 == 0b00000001) return SHLR;
if (low8 == 0b00001001) return SHLR2;
if (low8 == 0b00011001) return SHLR8;
if (low8 == 0b00101001) return SHLR16;
if (low8 == 0b00010011) return STCMGBR;
if (low8 == 0b00100011) return STCMVBR;
if (low8 == 0b00110011) return STCMSSR;
if (low8 == 0b01000011) return STCMSPC;
if (low8 == 0b00110010) return STCMSGR;
if (low8 == 0b11110010) return STCMDBR;
if (low8 == 0b00000010) return STSMMACH;
if (low8 == 0b00010010) return STSMMACL;
if (low8 == 0b00100010) return STSMPR;
if (low8 == 0b00011011) return TAS;
if (low8 == 0b00001011) return JSR;
}
if (high == 0b0000) {
if (low8 == 0b00100011) return BRAF;
if (low8 == 0b00101001) return MOVT;
if (low8 == 0b10000011) return PREF;
if (low8 == 0b00010010) return STCGBR;
if (low8 == 0b00100010) return STCVBR;
if (low8 == 0b00110010) return STCSSR;
if (low8 == 0b01000010) return STCSPC;
if (low8 == 0b00111010) return STCSGR;
if (low8 == 0b11111010) return STCDBR;
if (low8 == 0b00001010) return STSMACH;
if (low8 == 0b00011010) return STSMACL;
if (low8 == 0b00101010) return STSPR;
if (low8 == 0b00000011) return BSRF;
}
if (high == 0b0110) {
if (low == 0b1110) return EXTSB;
if (low == 0b1111) return EXTSW;
if (low == 0b1100) return EXTUB;
if (low == 0b1101) return EXTUW;
if (low == 0b0011) return MOV;
if (low == 0b0000) return MOVBL;
if (low == 0b0001) return MOVWL;
if (low == 0b0010) return MOVLL;
if (low == 0b0100) return MOVBP;
if (low == 0b0101) return MOVWP;
if (low == 0b0110) return MOVLP;
if (low == 0b1011) return NEG;
if (low == 0b1010) return NEGC;
if (low == 0b0111) return NOT;
if (low == 0b1000) return SWAPB;
if (low == 0b1001) return SWAPW;
}
if (high == 0b0010) {
if (low == 0b1001) return AND;
if (low == 0b1100) return CMPSTR;
if (low == 0b0111) return DIV0S;
if (low == 0b0000) return MOVBS;
if (low == 0b0001) return MOVWS;
if (low == 0b0010) return MOVLS;
if (low == 0b0100) return MOVBM;
if (low == 0b0101) return MOVWM;
if (low == 0b0110) return MOVLM;
if (low == 0b1111) return MULS;
if (low == 0b1110) return MULU;
if (low == 0b1011) return OR;
if (low == 0b1000) return TST;
if (low == 0b1010) return XOR;
if (low == 0b1101) return XTRCT;
}
if (high == 0b0011) {
if (low == 0b1100) return ADD;
if (low == 0b1110) return ADDC;
if (low == 0b1111) return ADDV;
if (low == 0b0000) return CMPEQ;
if (low == 0b0011) return CMPGE;
if (low == 0b0111) return CMPGT;
if (low == 0b0110) return CMPHI;
if (low == 0b0010) return CMPHS;
if (low == 0b0100) return DIV1;
if (low == 0b1101) return DMULS;
if (low == 0b0101) return DMULU;
if (low == 0b1000) return SUB;
if (low == 0b1010) return SUBC;
if (low == 0b1011) return SUBV;
}
if (high == 0b0000) {
if (low == 0b1111) return MACL_;
if (low == 0b0100) return MOVBS0;
if (low == 0b0101) return MOVWS0;
if (low == 0b0110) return MOVLS0;
if (low == 0b1100) return MOVBL0;
if (low == 0b1101) return MOVWL0;
if (low == 0b1110) return MOVLL0;
if (low == 0b0111) return MULL;
}
if (high == 0b0100) {
if (low == 0b1111) return MACW;
if (low == 0b1100) return SHAD;
if (low == 0b1101) return SHLD;
}
print_binary(instruction, 16);
critical_error(" => Unknown instruction: 0x%04X\n", instruction);
}
struct SR0 {
unsigned long dummy0:22;
unsigned long M0:1;
unsigned long Q0:1;
unsigned long I0:4;
unsigned long dummy1:2;
unsigned long S0:1;
unsigned long T0:1;
};
#define M ((*(struct SR0 *)(&SR)).M0)
#define Q ((*(struct SR0 *)(&SR)).Q0)
#define S ((*(struct SR0 *)(&SR)).S0)
#define T ((*(struct SR0 *)(&SR)).T0)
#define SR cpu->sr
#define GBR cpu->gbr
#define SGR cpu->sgr
#define VBR cpu->vbr
#define SSR cpu->ssr
#define SPC cpu->spc
#define DBR cpu->dbr
#define PC cpu->pc
#define PR cpu->pr
#define R cpu->r
#define R0 cpu->r[0]
#define MACH cpu->mach
#define MACL cpu->macl
#define Read_Byte(addr) mem_read(cpu, addr, 1)
#define Read_Word(addr) mem_read(cpu, addr, 2)
#define Read_Long(addr) mem_read(cpu, addr, 4)
#define Write_Byte(addr, data) mem_write(cpu, addr, data, 1)
#define Write_Word(addr, data) mem_write(cpu, addr, data, 2)
#define Write_Long(addr, data) mem_write(cpu, addr, data, 4)
#define Delay_Slot(pc_next) \
uint32_t pc_save = cpu->pc; \
cpu->pc = pc_next; \
run_next_instruction(cpu); \
cpu->pc = pc_save;
#define is_32bit_instruction(addr) is_32bit_instruction_impl(cpu, addr)
int is_32bit_instruction_impl(cpu_t* cpu, int addr) {
// TODO
return 0;
}
// ADD / Rm,Rn - 0011nnnnmmmm1100
void ADD(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] += R[m];
PC += 2;
}
// ADDI / #imm,Rn - 0111nnnniiiiiiii
void ADDI(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long i = instruction & 0xFF;
if ((i&0x80)==0)
R[n] += (0x000000FF & (long)i);
else R[n] += (0xFFFFFF00 | (long)i);
PC += 2;
}
// ADDC / Rm,Rn - 0011nnnnmmmm1110
void ADDC(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
unsigned long tmp0,tmp1;
tmp1 = R[n] + R[m];
tmp0 = R[n];
R[n] = tmp1 + T;
if (tmp0>tmp1) T = 1;
else T = 0;
if (tmp1>R[n]) T = 1;
PC += 2;
}
// ADDV / Rm,Rn - 0011nnnnmmmm1111
void ADDV(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
long dest,src,ans;
if ((long)R[n]>=0) dest = 0;
else dest = 1;
if ((long)R[m]>=0) src = 0;
else src = 1;
src += dest;
R[n] += R[m];
if ((long)R[n]>=0) ans = 0;
else ans = 1;
ans += dest;
if (src==0 || src==2) {
if (ans==1) T = 1;
else T = 0;
}
else T = 0;
PC += 2;
}
// AND / Rm,Rn - 0010nnnnmmmm1001
void AND(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] &= R[m];
PC += 2;
}
// ANDI / #imm,R0 - 11001001iiiiiiii
void ANDI(cpu_t* cpu, uint16_t instruction) {
long i = instruction & 0xFF;
R[0] &= (0x000000FF & (long)i);
PC += 2;
}
// ANDM / #imm,@(R0,GBR) - 11001101iiiiiiii
void ANDM(cpu_t* cpu, uint16_t instruction) {
long i = instruction & 0xFF;
long temp;
temp = (long)Read_Byte(GBR+R[0]);
temp &= (0x000000FF & (long)i);
Write_Byte(GBR+R[0],temp);
PC += 2;
}
// BF / label - 10001011dddddddd
void BF(cpu_t* cpu, uint16_t instruction) {
int d = instruction & 0xFF;
int disp;
if ((d&0x80)==0)
disp = (0x000000FF & d);
else disp = (0xFFFFFF00 | d);
if (T==0)
PC = PC+4+(disp<<1);
else PC += 2;
}
// BFS / label - 10001111dddddddd
void BFS(cpu_t* cpu, uint16_t instruction) {
int d = instruction & 0xFF;
int disp;
unsigned int temp;
temp = PC;
if ((d&0x80)==0)
disp = (0x000000FF & d);
else disp = (0xFFFFFF00 | d);
if (T==0)
PC = PC + 4 + (disp<<1);
else PC += 4;
Delay_Slot(temp+2);
}
// BRA / label - 1010dddddddddddd
void BRA(cpu_t* cpu, uint16_t instruction) {
int d = instruction & 0xFFF;
int disp;
unsigned int temp;
temp = PC;
if ((d&0x800)==0)
disp = (0x00000FFF & d);
else disp = (0xFFFFF000 | d);
PC = PC + 4 + (disp<<1);
Delay_Slot(temp+2);
}
// BRAF / Rn - 0000nnnn00100011
void BRAF(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
unsigned int temp;
temp = PC;
PC = PC + 4 + R[n];
Delay_Slot(temp+2);
}
// BT / label - 10001001dddddddd
void BT(cpu_t* cpu, uint16_t instruction) {
int d = instruction & 0xFF;
int disp;
if ((d&0x80)==0)
disp = (0x000000FF & d);
else disp = (0xFFFFFF00 | d);
if (T==1)
PC = PC + 4 + (disp<<1);
else PC += 2;
}
// BTS / label - 10001101dddddddd
void BTS(cpu_t* cpu, uint16_t instruction) {
int d = instruction & 0xFF;
int disp;
unsigned temp;
temp = PC;
if ((d&0x80)==0)
disp = (0x000000FF & d);
else disp = (0xFFFFFF00 | d);
if (T==1)
PC = PC + 4 + (disp<<1);
else PC += 4;
Delay_Slot(temp+2);
}
// CLRMAC / 0 - 0000000000101000
void CLRMAC(cpu_t* cpu, uint16_t instruction) {
MACH = 0;
MACL = 0;
PC += 2;
}
// CLRS / 0 - 0000000001001000
void CLRS(cpu_t* cpu, uint16_t instruction) {
S = 0;
PC += 2;
}
// CLRT / 0 - 0000000000001000
void CLRT(cpu_t* cpu, uint16_t instruction) {
T = 0;
PC += 2;
}
// CMPEQ / Rm,Rn - 0011nnnnmmmm0000
void CMPEQ(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
if (R[n]==R[m]) T = 1;
else T = 0;
PC += 2;
}
// CMPGE / Rm,Rn - 0011nnnnmmmm0011
void CMPGE(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
if ((long)R[n]>=(long)R[m]) T = 1;
else T = 0;
PC += 2;
}
// CMPGT / Rm,Rn - 0011nnnnmmmm0111
void CMPGT(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
if ((long)R[n]>(long)R[m]) T = 1;
else T = 0;
PC += 2;
}
// CMPHI / Rm,Rn - 0011nnnnmmmm0110
void CMPHI(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
if ((unsigned long)R[n]>(unsigned long)R[m]) T = 1;
else T = 0;
PC += 2;
}
// CMPHS / Rm,Rn - 0011nnnnmmmm0010
void CMPHS(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
if ((unsigned long)R[n]>=(unsigned long)R[m]) T = 1;
else T = 0;
PC += 2;
}
// CMPPL / Rn - 0100nnnn00010101
void CMPPL(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
if ((long)R[n]>0) T = 1;
else T = 0;
PC += 2;
}
// CMPPZ / Rn - 0100nnnn00010001
void CMPPZ(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
if ((long)R[n]>=0) T = 1;
else T = 0;
PC += 2;
}
// CMPSTR / Rm,Rn - 0010nnnnmmmm1100
void CMPSTR(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
unsigned long temp;
long HH,HL,LH,LL;
temp=R[n]^R[m];
HH = (temp & 0xFF000000) >> 24;
HL = (temp & 0x00FF0000) >> 16;
LH = (temp & 0x0000FF00) >> 8;
LL = temp & 0x000000FF;
HH = HH && HL && LH && LL;
if (HH==0) T = 1;
else T = 0;
PC += 2;
}
// CMPIM / #imm,R0 - 10001000iiiiiiii
void CMPIM(cpu_t* cpu, uint16_t instruction) {
long i = instruction & 0xFF;
long imm;
if ((i&0x80)==0) imm=(0x000000FF & (long) i);
else imm=(0xFFFFFF00 | (long) i);
if (R[0]==imm) T = 1;
else T = 0;
PC += 2;
}
// DIV0S / Rm,Rn - 0010nnnnmmmm0111
void DIV0S(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
if ((R[n] & 0x80000000)==0) Q = 0;
else Q = 1;
if ((R[m] & 0x80000000)==0) M = 0;
else M = 1;
T = !(M==Q);
PC += 2;
}
// DIV0U / 0 - 0000000000011001
void DIV0U(cpu_t* cpu, uint16_t instruction) {
M = Q = T = 0;
PC += 2;
}
// DIV1 / Rm,Rn - 0011nnnnmmmm0100
void DIV1(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
unsigned long tmp0, tmp2;
unsigned char old_q, tmp1;
old_q = Q;
Q = (unsigned char)((0x80000000 & R[n])!=0);
tmp2 = R[m];
R[n] <<= 1;
R[n] |= (unsigned long)T;
switch(old_q){
case 0:switch(M){
case 0:tmp0 = R[n];
R[n] -= tmp2;
tmp1 = (R[n]>tmp0);
switch(Q){
case 0:Q = tmp1;
break;
case 1:Q = (unsigned char)(tmp1==0);
break;
}
break;
case 1:tmp0 = R[n];
R[n] += tmp2;
tmp1 = (R[n]<tmp0);
switch(Q){
case 0:Q = (unsigned char)(tmp1==0);
break;
case 1:Q = tmp1;
break;
}
break;
}
break;
case 1:switch(M){
case 0:tmp0 = R[n];
R[n] += tmp2;
tmp1 = (R[n]<tmp0);
switch(Q){
case 0:Q = tmp1;
break;
case 1:Q = (unsigned char)(tmp1==0);
break;
}
break;
case 1:tmp0 = R[n];
R[n] -= tmp2;
tmp1 = (R[n]>tmp0);
switch(Q){
case 0:Q = (unsigned char)(tmp1==0);
break;
case 1:Q = tmp1;
break;
}
break;
}
break;
}
T = (Q==M);
PC += 2;
}
// DMULS / Rm,Rn - 0011nnnnmmmm1101
void DMULS(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
unsigned long RnL,RnH,RmL,RmH,Res0,Res1,Res2;
unsigned long temp0,temp1,temp2,temp3;
long tempm,tempn,fnLmL;
tempn = (long)R[n];
tempm = (long)R[m];
if (tempn<0) tempn = 0 - tempn;
if (tempm<0) tempm = 0 - tempm;
if ((long)(R[n]^R[m])<0) fnLmL = -1;
else fnLmL = 0;
temp1 = (unsigned long)tempn;
temp2 = (unsigned long)tempm;
RnL = temp1&0x0000FFFF;
RnH = (temp1>>16)&0x0000FFFF;
RmL = temp2&0x0000FFFF;
RmH = (temp2>>16)&0x0000FFFF;
temp0 = RmL*RnL;
temp1 = RmH*RnL;
temp2 = RmL*RnH;
temp3 = RmH*RnH;
Res2 = 0;
Res1 = temp1+temp2;
if (Res1<temp1) Res2 += 0x00010000;
temp1 = (Res1<<16)&0xFFFF0000;
Res0 = temp0 + temp1;
if (Res0<temp0) Res2++;
Res2 = Res2 + ((Res1>>16)&0x0000FFFF) + temp3;
if (fnLmL<0) {
Res2 = ~
Res2;
if (Res0==0)
Res2++;
else
Res0 = (~
Res0) + 1;
}
MACH = Res2;
MACL = Res0;
PC +=2;
}
// DMULU / Rm,Rn - 0011nnnnmmmm0101
void DMULU(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
unsigned long RnL,RnH,RmL,RmH,Res0,Res1,Res2;
unsigned long temp0,temp1,temp2,temp3;
RnL = R[n] & 0x0000FFFF;
RnH = (R[n]>>16) & 0x0000FFFF;
RmL = R[m] & 0x0000FFFF;
RmH = (R[m]>>16) & 0x0000FFFF;
temp0 = RmL*RnL;
temp1 = RmH*RnL;
temp2 = RmL*RnH;
temp3 = RmH*RnH;
Res2 = 0;
Res1 = temp1 + temp2;
if (Res1<temp1) Res2 += 0x00010000;
temp1 = (Res1<<16) & 0xFFFF0000;
Res0 = temp0 + temp1;
if (Res0<temp0) Res2++;
Res2 = Res2 + ((Res1>>16)&0x0000FFFF) + temp3;
MACH = Res2;
MACL = Res0;
PC += 2;
}
// DT / Rn - 0100nnnn00010000
void DT(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
R[n]--;
if (R[n]==0) T = 1;
else T = 0;
PC += 2;
}
// EXTSB / Rm,Rn - 0110nnnnmmmm1110
void EXTSB(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = R[m];
if ((R[m] & 0x00000080)==0) R[n] &=0x000000FF;
else R[n] |= 0xFFFFFF00;
PC += 2;
}
// EXTSW / Rm,Rn - 0110nnnnmmmm1111
void EXTSW(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = R[m];
if ((R[m] & 0x00008000)==0) R[n] &=0x0000FFFF;
else R[n] |= 0xFFFF0000;
PC += 2;
}
// EXTUB / Rm,Rn - 0110nnnnmmmm1100
void EXTUB(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = R[m];
R[n] &= 0x000000FF;
PC += 2;
}
// EXTUW / Rm,Rn - 0110nnnnmmmm1101
void EXTUW(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = R[m];
R[n] &= 0x0000FFFF;
PC += 2;
}
// JMP / @Rn - 0100nnnn00101011
void JMP(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
unsigned int temp;
temp = PC;
PC = R[n];
Delay_Slot(temp+2);
}
// LDCGBR / Rm,GBR - 0100mmmm00011110
void LDCGBR(cpu_t* cpu, uint16_t instruction) {
int m = (instruction >> 8) & 0xF;
GBR = R[m];
PC += 2;
}
// LDCVBR / Rm,VBR - 0100mmmm00101110
void LDCVBR(cpu_t* cpu, uint16_t instruction) {
int m = (instruction >> 8) & 0xF;
VBR = R[m];
PC += 2;
}
// LDCSGR / Rm,SGR - 0100mmmm00111010
void LDCSGR(cpu_t* cpu, uint16_t instruction) {
int m = (instruction >> 8) & 0xF;
SGR = R[m];
PC += 2;
}
// LDCSSR / Rm,SSR - 0100mmmm00111110
void LDCSSR(cpu_t* cpu, uint16_t instruction) {
int m = (instruction >> 8) & 0xF;
SSR = R[m],
PC += 2;
}
// LDCSPC / Rm,SPC - 0100mmmm01001110
void LDCSPC(cpu_t* cpu, uint16_t instruction) {
int m = (instruction >> 8) & 0xF;
SPC = R[m];
PC += 2;
}
// LDCDBR / Rm,DBR - 0100mmmm11111010
void LDCDBR(cpu_t* cpu, uint16_t instruction) {
int m = (instruction >> 8) & 0xF;
DBR = R[m];
PC += 2;
}
// LDCMGBR / @Rm+,GBR - 0100mmmm00010111
void LDCMGBR(cpu_t* cpu, uint16_t instruction) {
int m = (instruction >> 8) & 0xF;
GBR=Read_Long(R[m]);
R[m] += 4;
PC += 2;
}
// LDCMVBR / @Rm+,VBR - 0100mmmm00100111
void LDCMVBR(cpu_t* cpu, uint16_t instruction) {
int m = (instruction >> 8) & 0xF;
VBR = Read_Long(R[m]);
R[m] += 4;
PC += 2;
}
// LDCMSGR / @Rm+,SGR - 0100mmmm00110110
void LDCMSGR(cpu_t* cpu, uint16_t instruction) {
int m = (instruction >> 8) & 0xF;
SGR = Read_Long(R[m]);
R[m] += 4;
PC += 2;
}
// LDCMSSR / @Rm+,SSR - 0100mmmm00110111
void LDCMSSR(cpu_t* cpu, uint16_t instruction) {
int m = (instruction >> 8) & 0xF;
SSR=Read_Long(R[m]);
R[m] += 4;
PC += 2;
}
// LDCMSPC / @Rm+,SPC - 0100mmmm01000111
void LDCMSPC(cpu_t* cpu, uint16_t instruction) {
int m = (instruction >> 8) & 0xF;
SPC = Read_Long(R[m]);
R[m] += 4;
PC += 2;
}
// LDCMDBR / @Rm+,DBR - 0100mmmm11110110
void LDCMDBR(cpu_t* cpu, uint16_t instruction) {
int m = (instruction >> 8) & 0xF;
DBR = Read_Long(R[m]);
R[m] += 4;
PC += 2;
}
// LDSMACH / Rm,MACH - 0100mmmm00001010
void LDSMACH(cpu_t* cpu, uint16_t instruction) {
long m = (instruction >> 8) & 0xF;
MACH = R[m];
PC += 2;
}
// LDSMACL / Rm,MACL - 0100mmmm00011010
void LDSMACL(cpu_t* cpu, uint16_t instruction) {
long m = (instruction >> 8) & 0xF;
MACL = R[m];
PC += 2;
}
// LDSPR / Rm,PR - 0100mmmm00101010
void LDSPR(cpu_t* cpu, uint16_t instruction) {
long m = (instruction >> 8) & 0xF;
PR = R[m];
PC += 2;
}
// LDSMMACH / @Rm+,MACH - 0100mmmm00000110
void LDSMMACH(cpu_t* cpu, uint16_t instruction) {
long m = (instruction >> 8) & 0xF;
MACH = Read_Long(R[m]);
R[m] += 4;
PC += 2;
}
// LDSMMACL / @Rm+,MACL - 0100mmmm00010110
void LDSMMACL(cpu_t* cpu, uint16_t instruction) {
long m = (instruction >> 8) & 0xF;
MACL = Read_Long(R[m]);
R[m] += 4;
PC += 2;
}
// LDSMPR / @Rm+,PR - 0100mmmm00100110
void LDSMPR(cpu_t* cpu, uint16_t instruction) {
long m = (instruction >> 8) & 0xF;
PR = Read_Long(R[m]);
R[m] += 4;
PC += 2;
}
// MACL_ / @Rm+,@Rn+ - 0000nnnnmmmm1111
void MACL_(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
unsigned long RnL,RnH,RmL,RmH,Res0,Res1,Res2;
unsigned long temp0,temp1,temp2,temp3;
long tempm,tempn,fnLmL;
tempn = (long)Read_Long(R[n]);
R[n] += 4;
tempm = (long)Read_Long(R[m]);
R[m] += 4;
if ((long)(tempn^tempm)<0) fnLmL = -1;
else fnLmL = 0;
if (tempn<0) tempn = 0-tempn;
if (tempm<0) tempm = 0-tempm;
temp1 = (unsigned long)tempn;
temp2 = (unsigned long)tempm;
RnL = temp1&0x0000FFFF;
RnH = (temp1>>16) & 0x0000FFFF;
RmL = temp2 & 0x0000FFFF;
RmH = (temp2>>16) & 0x0000FFFF;
temp0 = RmL*RnL;
temp1 = RmH*RnL;
temp2 = RmL*RnH;
temp3 = RmH*RnH;
Res2 = 0;
Res1 = temp1 + temp2;
if (Res1<temp1) Res2 += 0x00010000;
temp1 =(Res1<<16) & 0xFFFF0000;
Res0 = temp0 + temp1;
if (Res0<temp0) Res2++;
Res2 = Res2 + ((Res1>>16) & 0x0000FFFF) + temp3;
if(fnLmL<0){
Res2 = ~
Res2;
if (Res0==0) Res2++;
else Res0 = (~
Res0)+1;
}
if(S==1){
Res0 = MACL + Res0;
if (MACL>Res0) Res2++;
if (MACH & 0x00008000);
else Res2 += MACH|0xFFFF0000;
Res2 += MACH&0x00007FFF;
if(((long)Res2<0)&&(Res2 < 0xFFFF8000)){
Res2 = 0xFFFF8000;
Res0 = 0x00000000;
}
if(((long)Res2>0)&&(Res2 > 0x00007FFF)){
Res2 = 0x00007FFF;
Res0 = 0xFFFFFFFF;
};
MACH = (Res2 & 0x0000FFFF)|(MACH & 0xFFFF0000);
MACL = Res0;
}
else {
Res0 = MACL + Res0;
if (MACL>Res0) Res2++;
Res2 += MACH;
MACH = Res2;
MACL = Res0;
}
PC += 2;
}
// MACW / @Rm+,@Rn+ - 0100nnnnmmmm1111
void MACW(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
long tempm,tempn,dest,src,ans;
unsigned long templ;
tempn = (long)Read_Word(R[n]);
R[n] += 2;
tempm = (long)Read_Word(R[m]);
R[m] += 2;
templ = MACL;
tempm = ((long)(short)tempn*(long)(short)tempm);
if ((long)MACL>=0) dest = 0;
else dest = 1;
if ((long)tempm>=0) {
src = 0;
tempn = 0;
}
else {
src = 1;
tempn = 0xFFFFFFFF;
}
src += dest;
MACL += tempm;
if ((long)MACL>=0) ans = 0;
else ans = 1;
ans += dest;
if (S==1) {
if (ans==1) {
if (src==0) MACL = 0x7FFFFFFF;
if (src==2) MACL = 0x80000000;
}
}
else {
MACH += tempn;
if (templ>MACL) MACH += 1;
}
PC += 2;
}
// MOV / Rm,Rn - 0110nnnnmmmm0011
void MOV(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = R[m];
PC += 2;
}
// MOVBS / Rm,@Rn - 0010nnnnmmmm0000
void MOVBS(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
Write_Byte(R[n],R[m]);
PC += 2;
}
// MOVWS / Rm,@Rn - 0010nnnnmmmm0001
void MOVWS(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
Write_Word(R[n],R[m]);
PC += 2;
}
// MOVLS / Rm,@Rn - 0010nnnnmmmm0010
void MOVLS(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
Write_Long(R[n],R[m]);
PC += 2;
}
// MOVBL / @Rm,Rn - 0110nnnnmmmm0000
void MOVBL(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = (long)Read_Byte(R[m]);
if ((R[n]&0x80)==0) R[n] &= 0x000000FF;
else R[n] |= 0xFFFFFF00;
PC += 2;
}
// MOVWL / @Rm,Rn - 0110nnnnmmmm0001
void MOVWL(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = (long)Read_Word(R[m]);
if ((R[n]&0x8000)==0) R[n] &= 0x0000FFFF;
else R[n] |= 0xFFFF0000;
PC += 2;
}
// MOVLL / @Rm,Rn - 0110nnnnmmmm0010
void MOVLL(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = Read_Long(R[m]);
PC += 2;
}
// MOVBM / Rm,@-Rn - 0010nnnnmmmm0100
void MOVBM(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
Write_Byte(R[n]-1,R[m]);
R[n] -= 1;
PC += 2;
}
// MOVWM / Rm,@-Rn - 0010nnnnmmmm0101
void MOVWM(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
Write_Word(R[n]-2,R[m]);
R[n] -= 2;
PC += 2;
}
// MOVLM / Rm,@-Rn - 0010nnnnmmmm0110
void MOVLM(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
Write_Long(R[n]-4,R[m]);
R[n] -= 4;
PC += 2;
}
// MOVBP / @Rm+,Rn - 0110nnnnmmmm0100
void MOVBP(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = (long)Read_Byte(R[m]);
if ((R[n]&0x80)==0) R[n] &= 0x000000FF;
else R[n] |= 0xFFFFFF00;
if (n!=m) R[m] += 1;
PC += 2;
}
// MOVWP / @Rm+,Rn - 0110nnnnmmmm0101
void MOVWP(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = (long)Read_Word(R[m]);
if ((R[n]&0x8000)==0) R[n] &= 0x0000FFFF;
else R[n] |= 0xFFFF0000;
if (n!=m) R[m] += 2;
PC += 2;
}
// MOVLP / @Rm+,Rn - 0110nnnnmmmm0110
void MOVLP(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = Read_Long(R[m]);
if (n!=m) R[m] += 4;
PC += 2;
}
// MOVBS0 / Rm,@(R0,Rn) - 0000nnnnmmmm0100
void MOVBS0(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
Write_Byte(R[n]+R[0],R[m]);
PC += 2;
}
// MOVWS0 / Rm,@(R0,Rn) - 0000nnnnmmmm0101
void MOVWS0(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
Write_Word(R[n]+R[0],R[m]);
PC+=2;
}
// MOVLS0 / Rm,@(R0,Rn) - 0000nnnnmmmm0110
void MOVLS0(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
Write_Long(R[n]+R[0],R[m]);
PC += 2;
}
// MOVBL0 / @(R0,Rm),Rn - 0000nnnnmmmm1100
void MOVBL0(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = (long)Read_Byte(R[m]+R[0]);
if ((R[n]&0x80)==0) R[n] &= 0x000000FF;
else R[n] |= 0xFFFFFF00;
PC += 2;
}
// MOVWL0 / @(R0,Rm),Rn - 0000nnnnmmmm1101
void MOVWL0(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = (long)Read_Word(R[m]+R[0]);
if ((R[n]&0x8000)==0) R[n] &= 0x0000FFFF;
else R[n] |= 0xFFFF0000;
PC += 2;
}
// MOVLL0 / @(R0,Rm),Rn - 0000nnnnmmmm1110
void MOVLL0(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = Read_Long(R[m]+R[0]);
PC += 2;
}
// MOVI / #imm,Rn - 1110nnnniiiiiiii
void MOVI(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
int i = instruction & 0xFF;
if ((i&0x80)==0) R[n] = (0x000000FF & i);
else R[n] = (0xFFFFFF00 | i);
PC += 2;
}
// MOVWI / @(disp*,PC),Rn - 1001nnnndddddddd
void MOVWI(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
int d = instruction & 0xFF;
unsigned int disp;
disp = (unsigned int)(0x000000FF & d);
R[n] = (int)Read_Word(PC+4+(disp<<1));
if ((R[n]&0x8000)==0) R[n] &= 0x0000FFFF;
else R[n] |= 0xFFFF0000;
PC += 2;
}
// MOVLI / @(disp*,PC),Rn - 1101nnnndddddddd
void MOVLI(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
int d = instruction & 0xFF;
unsigned int disp;
disp = (unsigned int)(0x000000FF & (int)d);
R[n] = Read_Long((PC & 0xFFFFFFFC)+4+(disp<<2));
PC += 2;
}
// MOVBLG / @(disp*,GBR),R0 - 11000100dddddddd
void MOVBLG(cpu_t* cpu, uint16_t instruction) {
int d = instruction & 0xFF;
unsigned int disp;
disp = (unsigned int)(0x000000FF & d);
R[0] = (int)Read_Byte(GBR+disp);
if ((R[0]&0x80)==0) R[0] &= 0x000000FF;
else R[0] |= 0xFFFFFF00;
PC += 2;
}
// MOVWLG / @(disp*,GBR),R0 - 11000101dddddddd
void MOVWLG(cpu_t* cpu, uint16_t instruction) {
int d = instruction & 0xFF;
unsigned int disp;
disp = (unsigned int)(0x000000FF & d);
R[0] = (int)Read_Word(GBR+(disp<<1));
if ((R[0]&0x8000)==0) R[0] &= 0x0000FFFF;
else R[0] |= 0xFFFF0000;
PC += 2;
}
// MOVLLG / @(disp*,GBR),R0 - 11000110dddddddd
void MOVLLG(cpu_t* cpu, uint16_t instruction) {
int d = instruction & 0xFF;
unsigned int disp;
disp = (unsigned int)(0x000000FF & d);
R[0] = Read_Long(GBR+(disp<<2));
PC += 2;
}
// MOVBSG / R0,@(disp*,GBR) - 11000000dddddddd
void MOVBSG(cpu_t* cpu, uint16_t instruction) {
int d = instruction & 0xFF;
unsigned int disp;
disp = (unsigned int)(0x000000FF & d);
Write_Byte(GBR+disp,R[0]);
PC += 2;
}
// MOVWSG / R0,@(disp*,GBR) - 11000001dddddddd
void MOVWSG(cpu_t* cpu, uint16_t instruction) {
int d = instruction & 0xFF;
unsigned int disp;
disp = (unsigned int)(0x000000FF & d);
Write_Word(GBR+(disp<<1),R[0]);
PC += 2;
}
// MOVLSG / R0,@(disp*,GBR) - 11000010dddddddd
void MOVLSG(cpu_t* cpu, uint16_t instruction) {
int d = instruction & 0xFF;
unsigned int disp;
disp = (unsigned int)(0x000000FF & (long)d);
Write_Long(GBR+(disp<<2),R[0]);
PC += 2;
}
// MOVBS4 / R0,@(disp*,Rn) - 10000000nnnndddd
void MOVBS4(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 4) & 0xF;
long d = instruction & 0xF;
long disp;
disp = (0x0000000F & (long)d);
Write_Byte(R[n]+disp,R[0]);
PC += 2;
}
// MOVWS4 / R0,@(disp*,Rn) - 10000001nnnndddd
void MOVWS4(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 4) & 0xF;
long d = instruction & 0xF;
long disp;
disp = (0x0000000F & (long)d);
Write_Word(R[n]+(disp<<1),R[0]);
PC += 2;
}
// MOVLS4 / Rm,@(disp*,Rn) - 0001nnnnmmmmdddd
void MOVLS4(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
long d = instruction & 0xF;
long disp;
disp = (0x0000000F & (long)d);
Write_Long(R[n]+(disp<<2),R[m]);
PC += 2;
}
// MOVBL4 / @(disp*,Rm),R0 - 10000100mmmmdddd
void MOVBL4(cpu_t* cpu, uint16_t instruction) {
long m = (instruction >> 4) & 0xF;
long d = instruction & 0xF;
long disp;
disp = (0x0000000F & (long)d);
R[0] = Read_Byte(R[m]+disp);
if ((R[0]&0x80)==0) R[0] &= 0x000000FF;
else R[0] |= 0xFFFFFF00;
PC += 2;
}
// MOVWL4 / @(disp*,Rm),R0 - 10000101mmmmdddd
void MOVWL4(cpu_t* cpu, uint16_t instruction) {
long m = (instruction >> 4) & 0xF;
long d = instruction & 0xF;
long disp;
disp = (0x0000000F & (long)d);
R[0] = Read_Word(R[m]+(disp<<1));
if ((R[0]&0x8000)==0) R[0] &= 0x0000FFFF;
else R[0] |= 0xFFFF0000;
PC += 2;
}
// MOVLL4 / @(disp*,Rm),Rn - 0101nnnnmmmmdddd
void MOVLL4(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
long d = instruction & 0xF;
long disp;
disp = (0x0000000F & (long)d);
R[n] = Read_Long(R[m]+(disp<<2));
PC += 2;
}
// MOVA / @(disp*,PC),R0 - 11000111dddddddd
void MOVA(cpu_t* cpu, uint16_t instruction) {
int d = instruction & 0xFF;
unsigned int disp;
disp = (unsigned int)(0x000000FF & d);
R[0] = (PC&0xFFFFFFFC) + 4 + (disp<<2);
PC += 2;
}
// MOVT / Rn - 0000nnnn00101001
void MOVT(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
R[n] = (0x00000001 & SR);
PC += 2;
}
// MULL / Rm,Rn - 0000nnnnmmmm0111
void MULL(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
MACL = R[n]*R[m];
PC += 2;
}
// MULS / Rm,Rn - 0010nnnnmmmm1111
void MULS(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
MACL = ((long)(short)R[n]*(long)(short)R[m]);
PC += 2;
}
// MULU / Rm,Rn - 0010nnnnmmmm1110
void MULU(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
MACL = (unsigned long)(unsigned short)R[n]*
(unsigned long)(unsigned short)R[m];
PC += 2;
}
// NEG / Rm,Rn - 0110nnnnmmmm1011
void NEG(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = 0-R[m];
PC += 2;
}
// NEGC / Rm,Rn - 0110nnnnmmmm1010
void NEGC(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
unsigned long temp;
temp = 0-R[m];
R[n] = temp-T;
if (0<temp) T = 1;
else T = 0;
if (temp<R[n]) T = 1;
PC += 2;
}
// NOP / No - 0000000000001001
void NOP(cpu_t* cpu, uint16_t instruction) {
PC += 2;
}
// NOT / Rm,Rn - 0110nnnnmmmm0111
void NOT(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] = ~R[m];
PC += 2;
}
// OR / Rm,Rn - 0010nnnnmmmm1011
void OR(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] |= R[m];
PC += 2;
}
// ORI / #imm,R0 - 11001011iiiiiiii
void ORI(cpu_t* cpu, uint16_t instruction) {
long i = instruction & 0xFF;
R[0] |= (0x000000FF & (long)i);
PC += 2;
}
// ORM / #imm,@(R0,GBR) - 11001111iiiiiiii
void ORM(cpu_t* cpu, uint16_t instruction) {
long i = instruction & 0xFF;
long temp;
temp = (long)Read_Byte(GBR+R[0]);
temp |= (0x000000FF & (long)i);
Write_Byte(GBR+R[0],temp);
PC += 2;
}
// PREF / @Rn - 0000nnnn10000011
void PREF(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
PC += 2;
}
// ROTCL / Rn - 0100nnnn00100100
void ROTCL(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long temp;
if ((R[n] & 0x80000000)==0) temp=0;
else temp = 1;
R[n] <<= 1;
if (T==1) R[n] |= 0x00000001;
else R[n] &= 0xFFFFFFFE;
if (temp==1) T = 1;
else T = 0;
PC += 2;
}
// ROTCR / Rn - 0100nnnn00100101
void ROTCR(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long temp;
if ((R[n] & 0x00000001)==0) temp = 0;
else temp = 1;
R[n] >>= 1;
if (T==1) R[n] |= 0x80000000;
else R[n] &= 0x7FFFFFFF;
if (temp==1) T = 1;
else T = 0;
PC += 2;
}
// ROTL / Rn - 0100nnnn00000100
void ROTL(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
if ((R[n]&0x80000000)==0) T = 0;
else T = 1;
R[n] <<= 1;
if (T==1) R[n] |= 0x00000001;
else R[n] &= 0xFFFFFFFE;
PC += 2;
}
// ROTR / Rn - 0100nnnn00000101
void ROTR(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
if ((R[n] & 0x00000001)==0) T = 0;
else T = 1;
R[n] >>= 1;
if (T==1) R[n] |= 0x80000000;
else R[n] &= 0x7FFFFFFF;
PC += 2;
}
// RTE / SSR - 0000000000101011
void RTE(cpu_t* cpu, uint16_t instruction) {
unsigned int temp;
temp = PC;
SR = SSR;
PC = SPC;
Delay_Slot(temp+2);
}
// RTS / PR - 0000000000001011
void RTS(cpu_t* cpu, uint16_t instruction) {
unsigned int temp;
temp = PC;
PC = PR;
Delay_Slot(temp+2);
}
// SETS / 1 - 0000000001011000
void SETS(cpu_t* cpu, uint16_t instruction) {
S = 1;
PC += 2;
}
// SETT / 1 - 0000000000011000
void SETT(cpu_t* cpu, uint16_t instruction) {
T = 1;
PC += 2;
}
// SHAD / Rm,Rn - 0100nnnnmmmm1100
void SHAD(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
int m = (instruction >> 4) & 0xF;
int sgn = R[m] & 0x80000000;
if (sgn==0)
R[n] <<= (R[m] & 0x1F);
else if ((R[m] & 0x1F) == 0) {
if ((R[n] & 0x80000000) == 0)
R[n] = 0;
else
R[n] = 0xFFFFFFFF;
}
else
R[n] = (long)R[n] >> ((~R[m] & 0x1F)+1);
PC += 2;
}
// SHAL / Rn - 0100nnnn00100000
void SHAL(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
if ((R[n]&0x80000000)==0) T = 0;
else T = 1;
R[n] <<= 1;
PC += 2;
}
// SHAR / Rn - 0100nnnn00100001
void SHAR(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long temp;
if ((R[n]&0x00000001)==0) T = 0;
else T = 1;
if ((R[n]&0x80000000)==0) temp = 0;
else temp = 1;
R[n] >>= 1;
if (temp==1) R[n] |= 0x80000000;
else R[n] &= 0x7FFFFFFF;
PC += 2;
}
// SHLD / Rm,Rn - 0100nnnnmmmm1101
void SHLD(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
int m = (instruction >> 4) & 0xF;
int sgn = R[m] & 0x80000000;
if (sgn == 0)
R[n] <<= (R[m] & 0x1F);
else if ((R[m] & 0x1F) == 0)
R[n] = 0;
else
R[n] = (unsigned)R[n] >> ((~R[m] & 0x1F)+1);
PC += 2;
}
// SHLL / Rn - 0100nnnn00000000
void SHLL(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
if ((R[n]&0x80000000)==0) T = 0;
else T = 1;
R[n] <<= 1;
PC += 2;
}
// SHLL2 / Rn - 0100nnnn00001000
void SHLL2(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
R[n] <<= 2;
PC += 2;
}
// SHLL8 / Rn - 0100nnnn00011000
void SHLL8(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
R[n] <<= 8;
PC += 2;
}
// SHLL16 / Rn - 0100nnnn00101000
void SHLL16(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
R[n] <<= 16;
PC += 2;
}
// SHLR / Rn - 0100nnnn00000001
void SHLR(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
if ((R[n] & 0x00000001)==0) T = 0;
else T = 1;
R[n] >>= 1;
R[n] &= 0x7FFFFFFF;
PC += 2;
}
// SHLR2 / Rn - 0100nnnn00001001
void SHLR2(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
R[n] >>= 2;
R[n] &= 0x3FFFFFFF;
PC += 2;
}
// SHLR8 / Rn - 0100nnnn00011001
void SHLR8(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
R[n] >>= 8;
R[n] &= 0x00FFFFFF;
PC += 2;
}
// SHLR16 / Rn - 0100nnnn00101001
void SHLR16(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
R[n] >>= 16;
R[n] &= 0x0000FFFF;
PC += 2;
}
// STCGBR / GBR,Rn - 0000nnnn00010010
void STCGBR(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] = GBR;
PC += 2;
}
// STCVBR / VBR,Rn - 0000nnnn00100010
void STCVBR(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] = VBR;
PC += 2;
}
// STCSSR / SSR,Rn - 0000nnnn00110010
void STCSSR(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] = SSR;
PC += 2;
}
// STCSPC / SPC,Rn - 0000nnnn01000010
void STCSPC(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] = SPC;
PC += 2;
}
// STCSGR / SGR,Rn - 0000nnnn00111010
void STCSGR(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] = SGR;
PC += 2;
}
// STCDBR / DBR,Rn - 0000nnnn11111010
void STCDBR(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] = DBR;
PC += 2;
}
// STCMGBR / GBR,@-Rn - 0100nnnn00010011
void STCMGBR(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] -= 4;
Write_Long(R[n],GBR);
PC += 2;
}
// STCMVBR / VBR,@-Rn - 0100nnnn00100011
void STCMVBR(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] -= 4;
Write_Long(R[n],VBR);
PC += 2;
}
// STCMSSR / SSR,@-Rn - 0100nnnn00110011
void STCMSSR(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] -= 4;
Write_Long(R[n],SSR);
PC += 2;
}
// STCMSPC / SPC,@-Rn - 0100nnnn01000011
void STCMSPC(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] -= 4;
Write_Long(R[n],SPC);
PC += 2;
}
// STCMSGR / SGR,@-Rn - 0100nnnn00110010
void STCMSGR(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] -= 4;
Write_Long(R[n],SGR);
PC += 2;
}
// STCMDBR / DBR,@-Rn - 0100nnnn11110010
void STCMDBR(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] -= 4;
Write_Long(R[n],DBR);
PC += 2;
}
// STSMACH / MACH,Rn - 0000nnnn00001010
void STSMACH(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] = MACH;
PC += 2;
}
// STSMACL / MACL,Rn - 0000nnnn00011010
void STSMACL(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] = MACL;
PC += 2;
}
// STSPR / PR,Rn - 0000nnnn00101010
void STSPR(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] = PR;
PC += 2;
}
// STSMMACH / MACH,@-Rn - 0100nnnn00000010
void STSMMACH(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] -= 4;
Write_Long(R[n],MACH);
PC += 2;
}
// STSMMACL / MACL,@-Rn - 0100nnnn00010010
void STSMMACL(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] -= 4;
Write_Long(R[n],MACL);
PC += 2;
}
// STSMPR / PR,@-Rn - 0100nnnn00100010
void STSMPR(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
R[n] -= 4;
Write_Long(R[n],PR);
PC += 2;
}
// SUB / Rm,Rn - 0011nnnnmmmm1000
void SUB(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] -= R[m];
PC += 2;
}
// SUBC / Rm,Rn - 0011nnnnmmmm1010
void SUBC(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
unsigned long tmp0,tmp1;
tmp1 = R[n] - R[m];
tmp0 = R[n];
R[n] = tmp1 - T;
if (tmp0<tmp1) T = 1;
else T = 0;
if (tmp1<R[n]) T = 1;
PC += 2;
}
// SUBV / Rm,Rn - 0011nnnnmmmm1011
void SUBV(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
long dest,src,ans;
if ((long)R[n]>=0) dest = 0;
else dest = 1;
if ((long)R[m]>=0) src = 0;
else src = 1;
src += dest;
R[n] -= R[m];
if ((long)R[n]>=0) ans = 0;
else ans = 1;
ans += dest;
if (src==1) {
if (ans==1) T = 1;
else T = 0;
}
else T = 0;
PC += 2;
}
// SWAPB / Rm,Rn - 0110nnnnmmmm1000
void SWAPB(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
unsigned long temp0,temp1;
temp0 = R[m] & 0xFFFF0000;
temp1 = (R[m] & 0x000000FF) << 8;
R[n] = (R[m] & 0x0000FF00) >> 8;
R[n] = R[n] | temp1 | temp0;
PC += 2;
}
// SWAPW / Rm,Rn - 0110nnnnmmmm1001
void SWAPW(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
unsigned long temp;
temp = (R[m]>>16)&0x0000FFFF;
R[n] = R[m]<<16;
R[n] |= temp;
PC += 2;
}
// TAS / @Rn - 0100nnnn00011011
void TAS(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
int temp;
temp = (int)Read_Byte(R[n]); /* Bus Lock */
if (temp==0) T = 1;
else T = 0;
temp |= 0x00000080;
Write_Byte(R[n],temp); /* Bus unlock */
PC += 2;
}
// TST / Rm,Rn - 0010nnnnmmmm1000
void TST(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
if ((R[n]&R[m])==0) T = 1;
else T = 0;
PC += 2;
}
// TSTI / #imm,R0 - 11001000iiiiiiii
void TSTI(cpu_t* cpu, uint16_t instruction) {
long i = instruction & 0xFF;
long temp;
temp = R[0]&(0x000000FF & (long)i);
if (temp==0) T = 1;
else T = 0;
PC += 2;
}
// TSTM / #imm,@(R0,GBR) - 11001100iiiiiiii
void TSTM(cpu_t* cpu, uint16_t instruction) {
long i = instruction & 0xFF;
long temp;
temp = (long)Read_Byte(GBR+R[0]);
temp &= (0x000000FF & (long)i);
if (temp==0) T = 1;
else T = 0;
PC += 2;
}
// XOR / Rm,Rn - 0010nnnnmmmm1010
void XOR(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
R[n] ^= R[m];
PC += 2;
}
// XORI / #imm,R0 - 11001010iiiiiiii
void XORI(cpu_t* cpu, uint16_t instruction) {
long i = instruction & 0xFF;
R[0] ^= (0x000000FF & (long)i);
PC += 2;
}
// XORM / #imm,@(R0,GBR) - 11001110iiiiiiii
void XORM(cpu_t* cpu, uint16_t instruction) {
long i = instruction & 0xFF;
int temp;
temp = (long)Read_Byte(GBR+R[0]);
temp ^= (0x000000FF &(long)i);
Write_Byte(GBR+R[0],temp);
PC += 2;
}
// XTRCT / Rm,Rn - 0010nnnnmmmm1101
void XTRCT(cpu_t* cpu, uint16_t instruction) {
long n = (instruction >> 8) & 0xF;
long m = (instruction >> 4) & 0xF;
unsigned long temp;
temp = (R[m]<<16) & 0xFFFF0000;
R[n] = (R[n]>>16) & 0x0000FFFF;
R[n] |= temp;
PC += 2;
}
// BSR / label - 1011dddddddddddd
void BSR(cpu_t* cpu, uint16_t instruction) {
int d = instruction & 0xFFF;
int disp;
unsigned int temp;
temp = PC;
if((d&0x800) == 0)
disp = (0x00000FFF & d);
else disp = (0xFFFFF000 | d);
if(is_32bit_instruction(temp+2))
PR = PC + 6;
else PR = PC + 4;
PC = PC + 4 + (disp << 1);
Delay_Slot(temp + 2);
}
// BSRF / Rn - 0000nnnn00000011
void BSRF(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
unsigned int temp;
temp = PC;
if(is_32bit_instruction(temp+2))
PR = PC +6;
else PR = PC + 4;
PC = PC + 4 + R[n];
Delay_Slot(temp+2);
}
// JSR / @Rn - 0100nnnn00001011
void JSR(cpu_t* cpu, uint16_t instruction) {
int n = (instruction >> 8) & 0xF;
unsigned int temp;
temp = PC;
if(is_32bit_instruction(temp+2))
PR = PC +6;
else PR = PC + 4;
PC = R[n];
Delay_Slot(temp+2);
}