mirror of
https://github.com/gligli/nulldc-360.git
synced 2025-04-02 11:11:56 -04:00
707 lines
No EOL
9.9 KiB
C
707 lines
No EOL
9.9 KiB
C
/*
|
|
sh4 base core
|
|
most of it is (very) old
|
|
could use many cleanups, lets hope someone does them
|
|
*/
|
|
|
|
//this file contains (almost) all load/stores !
|
|
|
|
//mov.b @(R0,<REG_M>),<REG_N>
|
|
rsh4op(i0000_nnnn_mmmm_1100)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ReadMemBOS8(r[n],r[0],r[m]);
|
|
}
|
|
|
|
//mov.w @(R0,<REG_M>),<REG_N>
|
|
rsh4op(i0000_nnnn_mmmm_1101)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ReadMemBOS16(r[n],r[0],r[m]);
|
|
}
|
|
|
|
//mov.l @(R0,<REG_M>),<REG_N>
|
|
rsh4op(i0000_nnnn_mmmm_1110)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ReadMemBOU32(r[n],r[0],r[m]);
|
|
}
|
|
|
|
//mov.b <REG_M>,@(R0,<REG_N>)
|
|
rsh4op(i0000_nnnn_mmmm_0100)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
WriteMemBOU8(r[0],r[n], r[m]);
|
|
}
|
|
|
|
//mov.w <REG_M>,@(R0,<REG_N>)
|
|
rsh4op(i0000_nnnn_mmmm_0101)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
WriteMemBOU16(r[0] , r[n], r[m]);
|
|
}
|
|
|
|
//mov.l <REG_M>,@(R0,<REG_N>)
|
|
rsh4op(i0000_nnnn_mmmm_0110)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
WriteMemBOU32(r[0], r[n], r[m]);
|
|
}
|
|
|
|
//
|
|
// 1xxx
|
|
|
|
//mov.l <REG_M>,@(<disp>,<REG_N>)
|
|
rsh4op(i0001_nnnn_mmmm_iiii)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
u32 disp = GetImm4(op);
|
|
|
|
WriteMemBOU32(r[n] , (disp <<2), r[m]);
|
|
}
|
|
|
|
//
|
|
// 2xxx
|
|
|
|
//mov.b <REG_M>,@<REG_N>
|
|
rsh4op(i0010_nnnn_mmmm_0000)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
WriteMemU8(r[n],r[m] );
|
|
}
|
|
|
|
// mov.w <REG_M>,@<REG_N>
|
|
rsh4op(i0010_nnnn_mmmm_0001)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
WriteMemU16(r[n],r[m]);
|
|
}
|
|
|
|
// mov.l <REG_M>,@<REG_N>
|
|
rsh4op(i0010_nnnn_mmmm_0010)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
WriteMemU32(r[n],r[m]);
|
|
}
|
|
|
|
// mov.b <REG_M>,@-<REG_N>
|
|
rsh4op(i0010_nnnn_mmmm_0100)
|
|
{
|
|
//iNimp("mov.b <REG_M>,@-<REG_N>");
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
WriteMemBOU8(r[n],(u32)-1,r[m]);
|
|
r[n]--;
|
|
}
|
|
|
|
//mov.w <REG_M>,@-<REG_N>
|
|
rsh4op(i0010_nnnn_mmmm_0101)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
WriteMemBOU16(r[n],(u32)-2,r[m]);
|
|
r[n] -= 2;
|
|
}
|
|
|
|
//mov.l <REG_M>,@-<REG_N>
|
|
rsh4op(i0010_nnnn_mmmm_0110)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
WriteMemBOU32(r[n],(u32)-4,r[m]);
|
|
r[n] -= 4;
|
|
}
|
|
|
|
//
|
|
// 4xxx
|
|
|
|
//sts.l FPUL,@-<REG_N>
|
|
rsh4op(i0100_nnnn_0101_0010)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
WriteMemBOU32(r[n],(u32)-4,fpul);
|
|
r[n] -= 4;
|
|
}
|
|
|
|
//sts.l MACH,@-<REG_N>
|
|
rsh4op(i0100_nnnn_0000_0010)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
WriteMemBOU32(r[n],(u32)-4,mac.h);
|
|
r[n] -= 4;
|
|
}
|
|
|
|
//sts.l MACL,@-<REG_N>
|
|
rsh4op(i0100_nnnn_0001_0010)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
WriteMemBOU32(r[n],(u32)-4, mac.l);
|
|
r[n] -= 4;
|
|
}
|
|
|
|
//sts.l PR,@-<REG_N>
|
|
rsh4op(i0100_nnnn_0010_0010)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
WriteMemBOU32(r[n],(u32)-4,pr);
|
|
r[n] -= 4;
|
|
}
|
|
|
|
//sts.l DBR,@-<REG_N>
|
|
rsh4op(i0100_nnnn_1111_0010)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
WriteMemBOU32(r[n],(u32)-4,dbr);
|
|
r[n] -= 4;
|
|
}
|
|
|
|
//stc.l GBR,@-<REG_N>
|
|
rsh4op(i0100_nnnn_0001_0011)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
WriteMemBOU32(r[n],(u32)-4, gbr);
|
|
r[n] -= 4;
|
|
}
|
|
|
|
//stc.l VBR,@-<REG_N>
|
|
rsh4op(i0100_nnnn_0010_0011)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
WriteMemBOU32(r[n],(u32)-4, vbr);
|
|
r[n] -= 4;
|
|
}
|
|
|
|
//stc.l SSR,@-<REG_N>
|
|
rsh4op(i0100_nnnn_0011_0011)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
WriteMemBOU32(r[n],(u32)-4, ssr);
|
|
r[n] -= 4;
|
|
}
|
|
|
|
//stc.l SGR,@-<REG_N>
|
|
rsh4op(i0100_nnnn_0011_0010)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
WriteMemBOU32(r[n],(u32)-4, sgr);
|
|
r[n] -= 4;
|
|
}
|
|
|
|
//stc.l SPC,@-<REG_N>
|
|
rsh4op(i0100_nnnn_0100_0011)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
WriteMemBOU32(r[n],(u32)-4, spc);
|
|
r[n] -= 4;
|
|
}
|
|
|
|
//stc RM_BANK,@-<REG_N>
|
|
rsh4op(i0100_nnnn_1mmm_0011)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op) & 0x07;
|
|
|
|
WriteMemBOU32(r[n],(u32)-4, r_bank[m]);
|
|
r[n] -= 4;
|
|
}
|
|
|
|
//lds.l @<REG_N>+,MACH
|
|
rsh4op(i0100_nnnn_0000_0110)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ReadMemU32(mac.h,r[n]);
|
|
r[n] += 4;
|
|
}
|
|
|
|
//lds.l @<REG_N>+,MACL
|
|
rsh4op(i0100_nnnn_0001_0110)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ReadMemU32(mac.l,r[n]);
|
|
r[n] += 4;
|
|
}
|
|
|
|
//lds.l @<REG_N>+,PR
|
|
rsh4op(i0100_nnnn_0010_0110)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ReadMemU32(pr,r[n]);
|
|
r[n] += 4;
|
|
}
|
|
|
|
|
|
//lds.l @<REG_N>+,FPUL
|
|
rsh4op(i0100_nnnn_0101_0110)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ReadMemU32(fpul,r[n]);
|
|
r[n] += 4;
|
|
}
|
|
|
|
//lds.l @<REG_N>+,DBR
|
|
rsh4op(i0100_nnnn_1111_0110)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ReadMemU32(dbr,r[n]);
|
|
r[n] += 4;
|
|
}
|
|
|
|
|
|
//ldc.l @<REG_N>+,GBR
|
|
rsh4op(i0100_nnnn_0001_0111)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ReadMemU32(gbr,r[n]);
|
|
r[n] += 4;
|
|
}
|
|
|
|
|
|
//ldc.l @<REG_N>+,VBR
|
|
rsh4op(i0100_nnnn_0010_0111)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ReadMemU32(vbr,r[n]);
|
|
r[n] += 4;
|
|
}
|
|
|
|
|
|
//ldc.l @<REG_N>+,SSR
|
|
rsh4op(i0100_nnnn_0011_0111)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ReadMemU32(ssr,r[n]);
|
|
r[n] += 4;
|
|
}
|
|
|
|
//ldc.l @<REG_N>+,SGR
|
|
rsh4op(i0100_nnnn_0011_0110)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ReadMemU32(sgr,r[n]);
|
|
r[n] += 4;
|
|
}
|
|
|
|
//ldc.l @<REG_N>+,SPC
|
|
rsh4op(i0100_nnnn_0100_0111)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
ReadMemU32(spc,r[n]);
|
|
r[n] += 4;
|
|
}
|
|
|
|
|
|
//ldc.l @<REG_N>+,RM_BANK
|
|
rsh4op(i0100_nnnn_1mmm_0111)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op) & 7;
|
|
|
|
ReadMemU32(r_bank[m],r[n]);
|
|
r[n] += 4;
|
|
}
|
|
|
|
//
|
|
// 5xxx
|
|
|
|
//mov.l @(<disp>,<REG_M>),<REG_N>
|
|
rsh4op(i0101_nnnn_mmmm_iiii)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
u32 disp = GetImm4(op) << 2;
|
|
|
|
ReadMemBOU32(r[n],r[m],disp);
|
|
}
|
|
|
|
//
|
|
// 6xxx
|
|
|
|
//mov.b @<REG_M>,<REG_N>
|
|
rsh4op(i0110_nnnn_mmmm_0000)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ReadMemS8(r[n],r[m]);
|
|
}
|
|
|
|
//mov.w @<REG_M>,<REG_N>
|
|
rsh4op(i0110_nnnn_mmmm_0001)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ReadMemS16(r[n] ,r[m]);
|
|
}
|
|
|
|
//mov.l @<REG_M>,<REG_N>
|
|
rsh4op(i0110_nnnn_mmmm_0010)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ReadMemU32(r[n],r[m]);
|
|
}
|
|
|
|
//mov.b @<REG_M>+,<REG_N>
|
|
rsh4op(i0110_nnnn_mmmm_0100)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ReadMemS8(r[n],r[m]);
|
|
if (n != m)
|
|
r[m] += 1;
|
|
}
|
|
|
|
//mov.w @<REG_M>+,<REG_N>
|
|
rsh4op(i0110_nnnn_mmmm_0101)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ReadMemS16(r[n],r[m]);
|
|
if (n != m)
|
|
r[m] += 2;
|
|
}
|
|
|
|
//mov.l @<REG_M>+,<REG_N>
|
|
rsh4op(i0110_nnnn_mmmm_0110)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ReadMemU32(r[n],r[m]);
|
|
if (n != m)
|
|
r[m] += 4;
|
|
}
|
|
|
|
//
|
|
//8xxx
|
|
|
|
//mov.b R0,@(<disp>,<REG_M>)
|
|
rsh4op(i1000_0000_mmmm_iiii)
|
|
{
|
|
u32 n = GetM(op);
|
|
u32 disp = GetImm4(op);
|
|
|
|
WriteMemBOU8(r[n],disp,r[0]);
|
|
}
|
|
|
|
// mov.w R0,@(<disp>,<REG_M>)
|
|
rsh4op(i1000_0001_mmmm_iiii)
|
|
{
|
|
u32 disp = GetImm4(op);
|
|
u32 m = GetM(op);
|
|
|
|
WriteMemBOU16(r[m] , (disp << 1),r[0]);
|
|
}
|
|
|
|
// mov.b @(<disp>,<REG_M>),R0
|
|
rsh4op(i1000_0100_mmmm_iiii)
|
|
{
|
|
u32 disp = GetImm4(op);
|
|
u32 m = GetM(op);
|
|
|
|
ReadMemBOS8(r[0] ,r[m] , disp);
|
|
}
|
|
|
|
// mov.w @(<disp>,<REG_M>),R0
|
|
rsh4op(i1000_0101_mmmm_iiii)
|
|
{
|
|
u32 disp = GetImm4(op);
|
|
u32 m = GetM(op);
|
|
|
|
ReadMemBOS16(r[0],r[m] , (disp << 1));
|
|
}
|
|
|
|
//
|
|
// 9xxx
|
|
|
|
//mov.w @(<disp>,PC),<REG_N>
|
|
rsh4op(i1001_nnnn_iiii_iiii)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 disp = (GetImm8(op));
|
|
|
|
ReadMemS16(r[n],(disp<<1) + pc + 4);
|
|
}
|
|
|
|
//
|
|
// Cxxx
|
|
// mov.b R0,@(<disp>,GBR)
|
|
rsh4op(i1100_0000_iiii_iiii)
|
|
{
|
|
u32 disp = GetImm8(op);
|
|
|
|
WriteMemBOU8(gbr, disp, r[0]);
|
|
}
|
|
|
|
// mov.w R0,@(<disp>,GBR)
|
|
rsh4op(i1100_0001_iiii_iiii)
|
|
{
|
|
u32 disp = GetImm8(op);
|
|
|
|
WriteMemBOU16(gbr , (disp << 1), r[0]);
|
|
}
|
|
|
|
// mov.l R0,@(<disp>,GBR)
|
|
rsh4op(i1100_0010_iiii_iiii)
|
|
{
|
|
u32 disp = (GetImm8(op));
|
|
|
|
WriteMemBOU32(gbr,(disp << 2), r[0]);
|
|
}
|
|
|
|
// mov.b @(<disp>,GBR),R0
|
|
rsh4op(i1100_0100_iiii_iiii)
|
|
{
|
|
u32 disp = GetImm8(op);
|
|
|
|
ReadMemBOS8(r[0],gbr,disp);
|
|
}
|
|
|
|
// mov.w @(<disp>,GBR),R0
|
|
rsh4op(i1100_0101_iiii_iiii)
|
|
{
|
|
u32 disp = GetImm8(op);
|
|
|
|
ReadMemBOS16(r[0],gbr,(disp<<1));
|
|
}
|
|
|
|
// mov.l @(<disp>,GBR),R0
|
|
rsh4op(i1100_0110_iiii_iiii)
|
|
{
|
|
u32 disp = GetImm8(op);
|
|
|
|
ReadMemBOU32(r[0],gbr,(disp<<2));
|
|
}
|
|
|
|
//
|
|
// Dxxx
|
|
|
|
// mov.l @(<disp>,PC),<REG_N>
|
|
rsh4op(i1101_nnnn_iiii_iiii)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 disp = (GetImm8(op));
|
|
|
|
ReadMemU32(r[n],(disp<<2) + (pc & 0xFFFFFFFC) + 4);
|
|
}
|
|
|
|
//
|
|
// Exxx
|
|
|
|
//movca.l R0, @<REG_N>
|
|
rsh4op(i0000_nnnn_1100_0011)
|
|
{
|
|
u32 n = GetN(op);
|
|
|
|
WriteMemU32(r[n],r[0]);
|
|
}
|
|
|
|
#ifdef _INTERPRETER_COMPILE_
|
|
//All memory opcodes are here
|
|
//fmov.s @(R0,<REG_M>),<FREG_N>
|
|
sh4op(i1111_nnnn_mmmm_0110)
|
|
{
|
|
if (fpscr.SZ == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ReadMemU32(fr_hex[n],r[m] + r[0]);
|
|
}
|
|
else
|
|
{
|
|
u32 n = (op >> 8) & 0x0E;
|
|
u32 m = GetM(op);
|
|
if (((op >> 8) & 0x1) == 0)
|
|
{
|
|
ReadMemU64(fr_hex[n],r[m] + r[0]);
|
|
}
|
|
else
|
|
{
|
|
ReadMemU64(xf_hex[n],r[m] + r[0]);
|
|
}
|
|
}
|
|
}
|
|
|
|
//fmov.s <FREG_M>,@(R0,<REG_N>)
|
|
sh4op(i1111_nnnn_mmmm_0111)
|
|
{
|
|
if (fpscr.SZ == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
WriteMem32(r[0] + r[n], fr_hex[m]);
|
|
}
|
|
else
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = (op >> 4) & 0x0E;
|
|
if (((op >> 4) & 0x1) == 0)
|
|
{
|
|
WriteMemU64(r[n] + r[0],fr_hex[m]);
|
|
}
|
|
else
|
|
{
|
|
WriteMemU64(r[n] + r[0],xf_hex[m]);
|
|
}
|
|
}
|
|
}
|
|
|
|
//fmov.s @<REG_M>,<FREG_N>
|
|
sh4op(i1111_nnnn_mmmm_1000)
|
|
{
|
|
if (fpscr.SZ == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
ReadMemU32(fr_hex[n],r[m]);
|
|
}
|
|
else
|
|
{
|
|
u32 n = (op >> 8) & 0x0E;
|
|
u32 m = GetM(op);
|
|
if (((op >> 8) & 0x1) == 0)
|
|
{
|
|
ReadMemU64(fr_hex[n],r[m]);
|
|
}
|
|
else
|
|
{
|
|
ReadMemU64(xf_hex[n],r[m]);
|
|
}
|
|
}
|
|
}
|
|
|
|
//fmov.s @<REG_M>+,<FREG_N>
|
|
sh4op(i1111_nnnn_mmmm_1001)
|
|
{
|
|
if (fpscr.SZ == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
ReadMemU32(fr_hex[n],r[m]);
|
|
r[m] += 4;
|
|
}
|
|
else
|
|
{
|
|
u32 n = (op >> 8) & 0x0E;
|
|
u32 m = GetM(op);
|
|
if (((op >> 8) & 0x1) == 0)
|
|
{
|
|
ReadMemU64(fr_hex[n],r[m]);
|
|
}
|
|
else
|
|
{
|
|
ReadMemU64(xf_hex[n],r[m] );
|
|
}
|
|
r[m] += 8;
|
|
}
|
|
}
|
|
|
|
//fmov.s <FREG_M>,@<REG_N>
|
|
sh4op(i1111_nnnn_mmmm_1010)
|
|
{
|
|
if (fpscr.SZ == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
WriteMemU32(r[n], fr_hex[m]);
|
|
}
|
|
else
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = (op >> 4) & 0x0E;
|
|
|
|
if (((op >> 4) & 0x1) == 0)
|
|
{
|
|
WriteMemU64(r[n], fr_hex[m]);
|
|
}
|
|
else
|
|
{
|
|
WriteMemU64(r[n], xf_hex[m]);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
//fmov.s <FREG_M>,@-<REG_N>
|
|
sh4op(i1111_nnnn_mmmm_1011)
|
|
{
|
|
if (fpscr.SZ == 0)
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = GetM(op);
|
|
|
|
u32 ea = r[n] - 4;
|
|
|
|
WriteMemU32(ea, fr_hex[m]);
|
|
|
|
r[n] = ea;
|
|
}
|
|
else
|
|
{
|
|
u32 n = GetN(op);
|
|
u32 m = (op >> 4) & 0x0E;
|
|
|
|
u32 ea = r[n] - 8;
|
|
if (((op >> 4) & 0x1) == 0)
|
|
{
|
|
WriteMemU64(ea , fr_hex[m]);
|
|
}
|
|
else
|
|
{
|
|
WriteMemU64(ea , xf_hex[m]);
|
|
}
|
|
|
|
r[n] = ea;
|
|
}
|
|
}
|
|
|
|
#endif |