mirror of
https://github.com/gligli/nulldc-360.git
synced 2025-04-02 11:11:56 -04:00
205 lines
No EOL
3.8 KiB
C
205 lines
No EOL
3.8 KiB
C
/*
|
|
sh4 base core
|
|
most of it is (very) old
|
|
could use many cleanups, lets hope someone does them
|
|
*/
|
|
|
|
//Specialised version for recompiler ;)
|
|
#ifdef SH4_REC
|
|
#include "sh4_cpu_branch_rec.h"
|
|
#else
|
|
|
|
//braf <REG_N>
|
|
sh4op(i0000_nnnn_0010_0011)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 newpc = r[n] + pc + 2;//pc +2 is done after
|
|
ExecuteDelayslot(); //WARN : r[n] can change here
|
|
pc = newpc;
|
|
}
|
|
//bsrf <REG_N>
|
|
sh4op(i0000_nnnn_0000_0011)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 newpc = r[n] + pc +2;//pc +2 is done after
|
|
pr = pc + 4; //after delayslot
|
|
ExecuteDelayslot(); //WARN : pr and r[n] can change here
|
|
pc = newpc;
|
|
}
|
|
|
|
|
|
//rte
|
|
sh4op(i0000_0000_0010_1011)
|
|
{
|
|
//iNimp("rte");
|
|
//sr.SetFull(ssr);
|
|
u32 newpc = spc;//+2 is added after instruction
|
|
bool intrr=ExecuteDelayslot_RTE();
|
|
pc = newpc -2;
|
|
|
|
if (intrr)
|
|
{
|
|
//FIXME olny if interrupts got on .. :P
|
|
pc+=2;
|
|
UpdateINTC();
|
|
pc-=2;
|
|
}
|
|
}
|
|
|
|
|
|
//rts
|
|
sh4op(i0000_0000_0000_1011)
|
|
{
|
|
// printf("rts %08x\n",pr);
|
|
u32 newpc=pr;//+2 is added after instruction
|
|
ExecuteDelayslot(); //WARN : pr can change here
|
|
pc=newpc-2;
|
|
}
|
|
|
|
|
|
// bf <bdisp8>
|
|
sh4op(i1000_1011_iiii_iiii)
|
|
{//ToDo : Check Me [26/4/05] | Check DELAY SLOT [28/1/06]
|
|
if (sr.GetT()==0)
|
|
{
|
|
//direct jump
|
|
pc = (u32)((GetSImm8(op))*2 + 4 + pc );
|
|
pc-=2;
|
|
}
|
|
}
|
|
|
|
|
|
// bf.s <bdisp8>
|
|
sh4op(i1000_1111_iiii_iiii)
|
|
{
|
|
if (sr.GetT()==0)
|
|
{
|
|
//delay 1 instruction
|
|
u32 newpc=(u32) ( (GetSImm8(op)<<1) + pc+2);//pc+2 is done after
|
|
ExecuteDelayslot();
|
|
pc = newpc;
|
|
}
|
|
}
|
|
|
|
|
|
// bt <bdisp8>
|
|
sh4op(i1000_1001_iiii_iiii)
|
|
{
|
|
if (sr.GetT()==1)
|
|
{
|
|
//direct jump
|
|
pc = (u32) ( (GetSImm8(op)<<1) + pc+2);
|
|
}
|
|
}
|
|
|
|
|
|
// bt.s <bdisp8>
|
|
sh4op(i1000_1101_iiii_iiii)
|
|
{
|
|
if (sr.GetT() == 1)
|
|
{
|
|
//delay 1 instruction
|
|
u32 newpc=(u32) ( (GetSImm8(op)<<1) + pc+2);//pc+2 is done after
|
|
ExecuteDelayslot();
|
|
pc = newpc;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// bra <bdisp12>
|
|
sh4op(i1010_iiii_iiii_iiii)
|
|
{//ToDo : Check Me [26/4/05] | Check ExecuteDelayslot [28/1/06]
|
|
//delay 1 jump imm12
|
|
u32 newpc =(u32) (( ((s16)((GetImm12(op))<<4)) >>3) + pc + 4);//(s16<<4,>>4(-1*2))
|
|
ExecuteDelayslot();
|
|
pc=newpc-2;
|
|
}
|
|
// bsr <bdisp12>
|
|
sh4op(i1011_iiii_iiii_iiii)
|
|
{//ToDo : Check Me [26/4/05] | Check new delay slot code [28/1/06]
|
|
//iNimp("bsr <bdisp12>");
|
|
u32 disp = GetImm12(op);
|
|
pr = pc + 4;
|
|
// printf("bsr %08x\n",pr);
|
|
//delay 1 opcode
|
|
u32 newpc = (u32)((((s16)(disp<<4)) >> 3) + pc + 4);
|
|
|
|
ExecuteDelayslot();
|
|
pc=newpc-2;
|
|
}
|
|
|
|
// trapa #<imm>
|
|
sh4op(i1100_0011_iiii_iiii)
|
|
{
|
|
//dlog("trapa 0x%X\n",(GetImm8(op) << 2));
|
|
CCN_TRA = (GetImm8(op) << 2);
|
|
Do_Exeption(0,0x160,0x100);
|
|
}
|
|
//jmp @<REG_N>
|
|
sh4op(i0100_nnnn_0010_1011)
|
|
{ //ToDo : Check Me [26/4/05] | Check new delay slot code [28/1/06]
|
|
u32 n = GetN(op);
|
|
//delay 1 instruction
|
|
u32 newpc=r[n];
|
|
ExecuteDelayslot();
|
|
pc=newpc-2;//+2 is done after
|
|
}
|
|
|
|
|
|
//jsr @<REG_N>
|
|
sh4op(i0100_nnnn_0000_1011)
|
|
{//ToDo : Check This [26/4/05] | Check new delay slot code [28/1/06]
|
|
u32 n = GetN(op);
|
|
|
|
pr = pc + 4;
|
|
// printf("jsr %08x\n",pr);
|
|
//delay one
|
|
u32 newpc= r[n];
|
|
ExecuteDelayslot(); //WARN : pr can change here
|
|
|
|
pc=newpc-2;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//sleep
|
|
sh4op(i0000_0000_0001_1011)
|
|
{
|
|
//iNimp("Sleep");
|
|
//just wait for an Interrupt
|
|
//while on sleep the precition of Interrupt timing is not the same as when cpu is running :)
|
|
sh4_sleeping=true;
|
|
int i=0,s=1;
|
|
|
|
pc+=2;//so that Interrupt return is on next opcode
|
|
while (!UpdateSystem())//448
|
|
{
|
|
if (i++>1000)
|
|
{
|
|
s=0;
|
|
break;
|
|
}
|
|
}
|
|
//if not Interrupted , we must rexecute the sleep
|
|
if (s==0)
|
|
pc-=2;// re execute sleep
|
|
|
|
pc-=2;//+2 is applied after opcode
|
|
|
|
|
|
sh4_sleeping=false;
|
|
}
|
|
|
|
//TODO : Fix this
|
|
#include "gui/base.h"
|
|
sh4op(sh4_bpt_op)
|
|
{
|
|
sh4_cpu->Stop();
|
|
pc-=2;//pew pew
|
|
}
|
|
#endif |