#include "stdafx.h"
|
#include "stdafx.h"
|
#include "clsThor.h"
|
#include "clsThor.h"
|
#include "insn.h"
|
#include "insn.h"
|
|
|
extern clsSystem system1;
|
extern clsSystem system1;
|
|
|
void clsThor::Reset()
|
void clsThor::Reset()
|
{
|
{
|
pc = 0xFFFFFFFFFFFC0000LL;
|
pc = 0xFFFFFFFFFFFC0000LL;
|
tick = 0;
|
tick = 0;
|
gp[0] = 0;
|
gp[0] = 0;
|
ca[0] = 0;
|
ca[0] = 0;
|
StatusHWI = true;
|
StatusHWI = true;
|
StatusDBG = false;
|
StatusDBG = false;
|
StatusEXL = 0;
|
StatusEXL = 0;
|
string_pc = 0;
|
string_pc = 0;
|
}
|
}
|
|
|
bool clsThor::IsKM()
|
bool clsThor::IsKM()
|
{
|
{
|
return StatusHWI || (StatusEXL > 0) || StatusDBG;
|
return StatusHWI || (StatusEXL > 0) || StatusDBG;
|
}
|
}
|
|
|
unsigned __int64 clsThor::ReadByte(int ad) { return system1->ReadByte(ad); };
|
unsigned __int64 clsThor::ReadByte(int ad) { return system1->ReadByte(ad); };
|
unsigned __int64 clsThor::ReadChar(int ad) { return system1->ReadChar(ad); };
|
unsigned __int64 clsThor::ReadChar(int ad) { return system1->ReadChar(ad); };
|
unsigned __int64 clsThor::ReadHalf(int ad) { return system1->ReadHalf(ad); };
|
unsigned __int64 clsThor::ReadHalf(int ad) { return system1->ReadHalf(ad); };
|
unsigned __int64 clsThor::Read(int ad) { return system1->Read(ad); };
|
unsigned __int64 clsThor::Read(int ad) { return system1->Read(ad); };
|
|
|
|
|
int clsThor::GetMode()
|
int clsThor::GetMode()
|
{
|
{
|
if (StatusHWI)
|
if (StatusHWI)
|
return mode = 1;
|
return mode = 1;
|
if (StatusDBG)
|
if (StatusDBG)
|
return mode = 3;
|
return mode = 3;
|
if (StatusEXL)
|
if (StatusEXL)
|
return mode = 2;
|
return mode = 2;
|
return mode = 0;
|
return mode = 0;
|
}
|
}
|
|
|
__int64 clsThor::GetGP(int rg)
|
__int64 clsThor::GetGP(int rg)
|
{
|
{
|
if (rg < 0 || rg > 63)
|
if (rg < 0 || rg > 63)
|
return 0xDEADEADDEADDEAD;
|
return 0xDEADEADDEADDEAD;
|
switch(rg) {
|
switch(rg) {
|
case 0: return 0; // ignore update to r0.
|
case 0: return 0; // ignore update to r0.
|
case 27:
|
case 27:
|
rg = rg + GetMode();
|
rg = rg + GetMode();
|
// Fall through
|
// Fall through
|
default:
|
default:
|
return gp[rg];
|
return gp[rg];
|
}
|
}
|
}
|
}
|
|
|
|
|
void clsThor::SetGP(int rg, __int64 val)
|
void clsThor::SetGP(int rg, __int64 val)
|
{
|
{
|
if (rg < 0 || rg > 63)
|
if (rg < 0 || rg > 63)
|
return;
|
return;
|
switch(rg) {
|
switch(rg) {
|
case 0: ; // ignore update to r0.
|
case 0: ; // ignore update to r0.
|
case 27:
|
case 27:
|
rg = rg + GetMode();
|
rg = rg + GetMode();
|
// Fall through
|
// Fall through
|
default:
|
default:
|
gp[rg] = val;
|
gp[rg] = val;
|
}
|
}
|
}
|
}
|
|
|
// Compute d[Rn] address info
|
// Compute d[Rn] address info
|
void clsThor::dRn(int b1, int b2, int b3, int *Ra, int *Sg, __int64 *disp)
|
void clsThor::dRn(int b1, int b2, int b3, int *Ra, int *Sg, __int64 *disp)
|
{
|
{
|
if (Ra) *Ra = b1 & 0x3f;
|
if (Ra) *Ra = b1 & 0x3f;
|
if (Sg) *Sg = (b3 >> 5) & 7;
|
if (Sg) *Sg = (b3 >> 5) & 7;
|
if (disp) *disp = ((b2 >> 4) & 0xF) | ((b3 & 0x1f) << 4);
|
if (disp) *disp = ((b2 >> 4) & 0xF) | ((b3 & 0x1f) << 4);
|
if (*disp & 0x100)
|
if (*disp & 0x100)
|
*disp |= 0xFFFFFFFFFFFFFE00LL;
|
*disp |= 0xFFFFFFFFFFFFFE00LL;
|
if (imm_prefix) {
|
if (imm_prefix) {
|
*disp &= 0xFF;
|
*disp &= 0xFF;
|
*disp |= imm;
|
*disp |= imm;
|
}
|
}
|
}
|
}
|
|
|
// Compute [Rn+Rn*Sc] address info
|
// Compute [Rn+Rn*Sc] address info
|
void clsThor::ndx(int b1, int b2, int b3, int *Ra, int *Rb, int *Rt, int *Sg, int *Sc)
|
void clsThor::ndx(int b1, int b2, int b3, int *Ra, int *Rb, int *Rt, int *Sg, int *Sc)
|
{
|
{
|
if (Ra) *Ra = b1 & 0x3f;
|
if (Ra) *Ra = b1 & 0x3f;
|
if (Rb) *Rb = (b1 >> 6) | ((b2 & 0xf) << 2);
|
if (Rb) *Rb = (b1 >> 6) | ((b2 & 0xf) << 2);
|
if (Rt) *Rt = ((b2 & 0xF0) >> 4) | (( b3 & 3) << 4);
|
if (Rt) *Rt = ((b2 & 0xF0) >> 4) | (( b3 & 3) << 4);
|
if (Sg) *Sg = (b3 >> 5) & 7;
|
if (Sg) *Sg = (b3 >> 5) & 7;
|
if (Sc) *Sc = 1 << ((b3 >> 2) & 3);
|
if (Sc) *Sc = 1 << ((b3 >> 2) & 3);
|
}
|
}
|
|
|
int clsThor::WriteMask(int ad, int sz)
|
int clsThor::WriteMask(int ad, int sz)
|
{
|
{
|
switch(sz) {
|
switch(sz) {
|
case 0: return 1 << (ad & 7);
|
case 0: return 1 << (ad & 7);
|
case 1: return 3 << (ad & 6);
|
case 1: return 3 << (ad & 6);
|
case 2: return (ad & 4) ? 0xF0 : 0x0F;
|
case 2: return (ad & 4) ? 0xF0 : 0x0F;
|
case 3: return 0xFF;
|
case 3: return 0xFF;
|
}
|
}
|
}
|
}
|
|
|
__int64 clsThor::GetSpr(int Sprn)
|
__int64 clsThor::GetSpr(int Sprn)
|
{
|
{
|
__int64 tmp;
|
__int64 tmp;
|
int nn;
|
int nn;
|
|
|
if (Sprn < 16) {
|
if (Sprn < 16) {
|
return pr[Sprn];
|
return pr[Sprn];
|
}
|
}
|
else if (Sprn < 32) {
|
else if (Sprn < 32) {
|
Sprn -= 16;
|
Sprn -= 16;
|
return ca[Sprn];
|
return ca[Sprn];
|
}
|
}
|
else if (Sprn < 40) {
|
else if (Sprn < 40) {
|
return seg_base[Sprn-32];
|
return seg_base[Sprn-32];
|
}
|
}
|
else if (Sprn < 48) {
|
else if (Sprn < 48) {
|
return seg_limit[Sprn-32];
|
return seg_limit[Sprn-32];
|
}
|
}
|
else {
|
else {
|
switch(Sprn) {
|
switch(Sprn) {
|
case 50: return tick; break;
|
case 50: return tick; break;
|
case 51: return lc; break;
|
case 51: return lc; break;
|
case 52:
|
case 52:
|
tmp = 0;
|
tmp = 0;
|
for (nn = 0; nn < 16; nn++) {
|
for (nn = 0; nn < 16; nn++) {
|
tmp |= pr[nn] << (nn * 4);
|
tmp |= pr[nn] << (nn * 4);
|
}
|
}
|
return tmp;
|
return tmp;
|
case 60: return bir; break;
|
case 60: return bir; break;
|
case 61:
|
case 61:
|
switch(bir) {
|
switch(bir) {
|
case 0: return dbad0; break;
|
case 0: return dbad0; break;
|
case 1: return dbad1; break;
|
case 1: return dbad1; break;
|
case 2: return dbad2; break;
|
case 2: return dbad2; break;
|
case 3: return dbad3; break;
|
case 3: return dbad3; break;
|
case 4: return dbctrl; break;
|
case 4: return dbctrl; break;
|
case 5: return dbstat; break;
|
case 5: return dbstat; break;
|
}
|
}
|
}
|
}
|
}
|
}
|
return 0xDEADDEADDEADDEAD;
|
return 0xDEADDEADDEADDEAD;
|
}
|
}
|
|
|
void clsThor::SetSpr(int Sprn, __int64 val)
|
void clsThor::SetSpr(int Sprn, __int64 val)
|
{
|
{
|
int nn;
|
int nn;
|
|
|
if (Sprn < 16)
|
if (Sprn < 16)
|
pr[Sprn] = val;
|
pr[Sprn] = val;
|
else if (Sprn < 32) {
|
else if (Sprn < 32) {
|
Sprn -= 16;
|
Sprn -= 16;
|
ca[Sprn] = val;
|
ca[Sprn] = val;
|
ca[0] = 0;
|
ca[0] = 0;
|
ca[15] = pc;
|
ca[15] = pc;
|
}
|
}
|
else if (Sprn < 40) {
|
else if (Sprn < 40) {
|
seg_base[Sprn-32] = val & 0xFFFFFFFFFFFFF000LL;
|
seg_base[Sprn-32] = val & 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
else if (Sprn < 48) {
|
else if (Sprn < 48) {
|
seg_limit[Sprn-32] = val & 0xFFFFFFFFFFFFF000LL;
|
seg_limit[Sprn-32] = val & 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
else {
|
else {
|
switch(Sprn) {
|
switch(Sprn) {
|
case 51: lc = val; break;
|
case 51: lc = val; break;
|
case 52:
|
case 52:
|
for (nn = 0; nn < 16; nn++) {
|
for (nn = 0; nn < 16; nn++) {
|
pr[nn] = (val >> (nn * 4)) & 0xF;
|
pr[nn] = (val >> (nn * 4)) & 0xF;
|
}
|
}
|
break;
|
break;
|
case 60: bir = val & 0xFFLL; break;
|
case 60: bir = val & 0xFFLL; break;
|
case 61:
|
case 61:
|
switch(bir) {
|
switch(bir) {
|
case 0: dbad0 = val; break;
|
case 0: dbad0 = val; break;
|
case 1: dbad1 = val; break;
|
case 1: dbad1 = val; break;
|
case 2: dbad2 = val; break;
|
case 2: dbad2 = val; break;
|
case 3: dbad3 = val; break;
|
case 3: dbad3 = val; break;
|
case 4: dbctrl = val; break;
|
case 4: dbctrl = val; break;
|
case 5: dbstat = val; break;
|
case 5: dbstat = val; break;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
int clsThor::GetBit(__int64 a, int b)
|
int clsThor::GetBit(__int64 a, int b)
|
{
|
{
|
return (a >> b) & 1;
|
return (a >> b) & 1;
|
}
|
}
|
|
|
void clsThor::SetBit(__int64 *a, int b)
|
void clsThor::SetBit(__int64 *a, int b)
|
{
|
{
|
*a |= (1 << b);
|
*a |= (1 << b);
|
}
|
}
|
|
|
void clsThor::ClearBit(__int64 *a, int b)
|
void clsThor::ClearBit(__int64 *a, int b)
|
{
|
{
|
*a &= ~(1 << b);
|
*a &= ~(1 << b);
|
}
|
}
|
|
|
void clsThor::Step()
|
void clsThor::Step()
|
{
|
{
|
bool ex = true; // execute instruction
|
bool ex = true; // execute instruction
|
unsigned int opcode, func;
|
unsigned int opcode, func;
|
__int64 disp;
|
__int64 disp;
|
int Ra,Rb,Rc,Rt,Pn,Cr,Ct;
|
int Ra,Rb,Rc,Rt,Pn,Cr,Ct;
|
int Sprn,Sg,Sc;
|
int Sprn,Sg,Sc,Sz;
|
int b1, b2, b3, b4;
|
int b1, b2, b3, b4;
|
int nn;
|
int nn;
|
__int64 dat;
|
__int64 dat;
|
unsigned __int64 overflow;
|
unsigned __int64 overflow;
|
unsigned __int64 carry;
|
unsigned __int64 carry;
|
unsigned __int64 a,b,res;
|
unsigned __int64 a,b,res;
|
|
|
|
rts = false;
|
|
// Capture PC History, but only when the PC changes.
|
|
if (pcs[0] != pc) {
|
for (nn = 39; nn >= 0; nn--)
|
for (nn = 39; nn >= 0; nn--)
|
pcs[nn] = pcs[nn-1];
|
pcs[nn] = pcs[nn-1];
|
pcs[0] = pc;
|
pcs[0] = pc;
|
|
}
|
if (IRQActive()) {
|
if (IRQActive()) {
|
StatusHWI = true;
|
StatusHWI = true;
|
if (string_pc)
|
if (string_pc)
|
ca[14] = string_pc;
|
ca[14] = string_pc;
|
|
else {
|
|
// If a prefix was present, back up to the previous insn.
|
|
if (imm_prefix) {
|
|
ca[14] = pcs[1];
|
|
}
|
else
|
else
|
ca[14] = pc;
|
ca[14] = pc;
|
|
}
|
pc = ca[12] + (vecno << 4);
|
pc = ca[12] + (vecno << 4);
|
ca[15] = pc;
|
ca[15] = pc;
|
|
imm_prefix = false;
|
}
|
}
|
gp[0] = 0;
|
gp[0] = 0;
|
ca[0] = 0;
|
ca[0] = 0;
|
if (imcd > 0) {
|
if (imcd > 0) {
|
imcd--;
|
imcd--;
|
if (imcd==1)
|
if (imcd==1)
|
im = 0;
|
im = 0;
|
}
|
}
|
tick = tick + 1;
|
tick = tick + 1;
|
pred = ReadByte(pc);
|
pred = ReadByte(pc);
|
pc++;
|
pc++;
|
switch (pred) {
|
switch (pred) {
|
case 0x00: // BRK instruction
|
case 0x00: // BRK instruction
|
isRunning = false;
|
isRunning = false;
|
return;
|
return;
|
case 0x10: // NOP
|
case 0x10: // NOP
|
return;
|
return;
|
case 0x20:
|
case 0x20:
|
imm = ReadByte(pc) << 8;
|
imm = ReadByte(pc) << 8;
|
pc++;
|
pc++;
|
if (imm & 0x8000LL)
|
if (imm & 0x8000LL)
|
imm |= 0xFFFFFFFFFFFF0000LL;
|
imm |= 0xFFFFFFFFFFFF0000LL;
|
imm_prefix = true;
|
imm_prefix = true;
|
return;
|
return;
|
case 0x30:
|
case 0x30:
|
imm = ReadByte(pc) << 8;
|
imm = ReadByte(pc) << 8;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 16;
|
imm |= ReadByte(pc) << 16;
|
pc++;
|
pc++;
|
if (imm & 0x800000LL)
|
if (imm & 0x800000LL)
|
imm |= 0xFFFFFFFFFF000000LL;
|
imm |= 0xFFFFFFFFFF000000LL;
|
imm_prefix = true;
|
imm_prefix = true;
|
return;
|
return;
|
case 0x40:
|
case 0x40:
|
imm = ReadByte(pc) << 8;
|
imm = ReadByte(pc) << 8;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 16;
|
imm |= ReadByte(pc) << 16;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 24;
|
imm |= ReadByte(pc) << 24;
|
pc++;
|
pc++;
|
if (imm & 0x80000000LL)
|
if (imm & 0x80000000LL)
|
imm |= 0xFFFFFFFF00000000LL;
|
imm |= 0xFFFFFFFF00000000LL;
|
imm_prefix = true;
|
imm_prefix = true;
|
return;
|
return;
|
case 0x50:
|
case 0x50:
|
imm = ReadByte(pc) << 8;
|
imm = ReadByte(pc) << 8;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 16;
|
imm |= ReadByte(pc) << 16;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 24;
|
imm |= ReadByte(pc) << 24;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 32;
|
imm |= ReadByte(pc) << 32;
|
pc++;
|
pc++;
|
if (imm & 0x8000000000LL)
|
if (imm & 0x8000000000LL)
|
imm |= 0xFFFFFF0000000000LL;
|
imm |= 0xFFFFFF0000000000LL;
|
imm_prefix = true;
|
imm_prefix = true;
|
return;
|
return;
|
case 0x60:
|
case 0x60:
|
imm = ReadByte(pc) << 8;
|
imm = ReadByte(pc) << 8;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 16;
|
imm |= ReadByte(pc) << 16;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 24;
|
imm |= ReadByte(pc) << 24;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 32;
|
imm |= ReadByte(pc) << 32;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 40;
|
imm |= ReadByte(pc) << 40;
|
pc++;
|
pc++;
|
if (imm & 0x800000000000LL)
|
if (imm & 0x800000000000LL)
|
imm |= 0xFFFF000000000000LL;
|
imm |= 0xFFFF000000000000LL;
|
imm_prefix = true;
|
imm_prefix = true;
|
return;
|
return;
|
case 0x70:
|
case 0x70:
|
imm = ReadByte(pc) << 8;
|
imm = ReadByte(pc) << 8;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 16;
|
imm |= ReadByte(pc) << 16;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 24;
|
imm |= ReadByte(pc) << 24;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 32;
|
imm |= ReadByte(pc) << 32;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 40;
|
imm |= ReadByte(pc) << 40;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 48;
|
imm |= ReadByte(pc) << 48;
|
pc++;
|
pc++;
|
if (imm & 0x80000000000000LL)
|
if (imm & 0x80000000000000LL)
|
imm |= 0xFF00000000000000LL;
|
imm |= 0xFF00000000000000LL;
|
imm_prefix = true;
|
imm_prefix = true;
|
return;
|
return;
|
case 0x80:
|
case 0x80:
|
imm = ReadByte(pc) << 8;
|
imm = ReadByte(pc) << 8;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 16;
|
imm |= ReadByte(pc) << 16;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 24;
|
imm |= ReadByte(pc) << 24;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 32;
|
imm |= ReadByte(pc) << 32;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 40;
|
imm |= ReadByte(pc) << 40;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 48;
|
imm |= ReadByte(pc) << 48;
|
pc++;
|
pc++;
|
imm |= ReadByte(pc) << 56;
|
imm |= ReadByte(pc) << 56;
|
pc++;
|
pc++;
|
imm_prefix = true;
|
imm_prefix = true;
|
return;
|
return;
|
default: {
|
default: {
|
int rv;
|
int rv;
|
|
|
rv = pr[pred>>4];
|
rv = pr[pred>>4];
|
switch(pred & 15) {
|
switch(pred & 15) {
|
case PF: ex = false; break;
|
case PF: ex = false; break;
|
case PT: ex = true; break;
|
case PT: ex = true; break;
|
case PEQ: ex = rv & 1; break;
|
case PEQ: ex = rv & 1; break;
|
case PNE: ex = !(rv & 1); break;
|
case PNE: ex = !(rv & 1); break;
|
case PLE: ex = (rv & 1)||(rv & 2); break;
|
case PLE: ex = (rv & 1)||(rv & 2); break;
|
case PGT: ex = !((rv & 1)||(rv & 2)); break;
|
case PGT: ex = !((rv & 1)||(rv & 2)); break;
|
case PGE: ex = (rv & 2)==0; break;
|
case PGE: ex = (rv & 2)==0; break;
|
case PLT: ex = (rv & 2)!=0; break;
|
case PLT: ex = (rv & 2)!=0; break;
|
case PLEU: ex = (rv & 1)||(rv & 4); break;
|
case PLEU: ex = (rv & 1)||(rv & 4); break;
|
case PGTU: ex = !((rv & 1)||(rv & 4)); break;
|
case PGTU: ex = !((rv & 1)||(rv & 4)); break;
|
case PGEU: ex = (rv & 4)==0; break;
|
case PGEU: ex = (rv & 4)==0; break;
|
case PLTU: ex = (rv & 4)!=0; break;
|
case PLTU: ex = (rv & 4)!=0; break;
|
default: ex = false;
|
default: ex = false;
|
}
|
}
|
}
|
}
|
}
|
}
|
opcode = ReadByte(pc);
|
opcode = ReadByte(pc);
|
pc++;
|
pc++;
|
if ((opcode & 0xF0)==0x00) { // TST
|
if ((opcode & 0xF0)==0x00) { // TST
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Pn = opcode & 0x0f;
|
Pn = opcode & 0x0f;
|
pr[Pn] = 0;
|
pr[Pn] = 0;
|
if (GetGP(Ra)==0)
|
if (GetGP(Ra)==0)
|
pr[Pn] |= 1;
|
pr[Pn] |= 1;
|
if ((signed)GetGP(Ra) < (signed)0)
|
if ((signed)GetGP(Ra) < (signed)0)
|
pr[Pn] |= 2;
|
pr[Pn] |= 2;
|
}
|
}
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
}
|
}
|
if ((opcode & 0xF0)==0x10) { // CMP
|
if ((opcode & 0xF0)==0x10) { // CMP
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rb = ((b1 & 0xC0) >> 6) | ((b2 & 0x0f)<<2);
|
Rb = ((b1 & 0xC0) >> 6) | ((b2 & 0x0f)<<2);
|
Pn = opcode & 0x0f;
|
Pn = opcode & 0x0f;
|
pr[Pn] = 0;
|
pr[Pn] = 0;
|
if (GetGP(Ra)==GetGP(Rb))
|
if (GetGP(Ra)==GetGP(Rb))
|
pr[Pn] |= 1;
|
pr[Pn] |= 1;
|
if (GetGP(Ra) < GetGP(Rb))
|
if (GetGP(Ra) < GetGP(Rb))
|
pr[Pn] |= 2;
|
pr[Pn] |= 2;
|
if ((unsigned __int64)GetGP(Ra) < (unsigned __int64)GetGP(Rb))
|
if ((unsigned __int64)GetGP(Ra) < (unsigned __int64)GetGP(Rb))
|
pr[Pn] |= 4;
|
pr[Pn] |= 4;
|
}
|
}
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
}
|
}
|
if ((opcode & 0xF0)==0x20) { // CMPI
|
if ((opcode & 0xF0)==0x20) { // CMPI
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b2 << 2) & 0xFF) | ((b1 >> 6) & 3);
|
imm |= ((b2 << 2) & 0xFF) | ((b1 >> 6) & 3);
|
}
|
}
|
else {
|
else {
|
imm = ((b2 << 2) & 0x3FF) | ((b1 >> 6) & 3);
|
imm = ((b2 << 2) & 0x3FF) | ((b1 >> 6) & 3);
|
if (imm & 0x200)
|
if (imm & 0x200)
|
imm |= 0xFFFFFFFFFFFFFE00LL;
|
imm |= 0xFFFFFFFFFFFFFE00LL;
|
}
|
}
|
Pn = opcode & 0x0f;
|
Pn = opcode & 0x0f;
|
pr[Pn] = 0;
|
pr[Pn] = 0;
|
if (GetGP(Ra)==imm)
|
if (GetGP(Ra)==imm)
|
pr[Pn] |= 1;
|
pr[Pn] |= 1;
|
if (GetGP(Ra) < (signed)imm)
|
if (GetGP(Ra) < (signed)imm)
|
pr[Pn] |= 2;
|
pr[Pn] |= 2;
|
if ((unsigned __int64)GetGP(Ra) < (unsigned __int64)imm)
|
if ((unsigned __int64)GetGP(Ra) < (unsigned __int64)imm)
|
pr[Pn] |= 4;
|
pr[Pn] |= 4;
|
}
|
}
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
}
|
}
|
if ((opcode & 0xF0)==0x30) { // BR
|
if ((opcode & 0xF0)==0x30) { // BR
|
disp = ReadByte(pc);
|
disp = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
disp = disp | ((opcode & 0x0F) << 8);
|
disp = disp | ((opcode & 0x0F) << 8);
|
if (disp & 0x800)
|
if (disp & 0x800)
|
disp |= 0xFFFFFFFFFFFFF000LL;
|
disp |= 0xFFFFFFFFFFFFF000LL;
|
pc = pc + disp;
|
pc = pc + disp;
|
}
|
}
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
}
|
}
|
switch(opcode) {
|
switch(opcode) {
|
|
|
case _2ADDUI:
|
case _2ADDUI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,(GetGP(Ra)<<1) + imm);
|
SetGP(Rt,(GetGP(Ra)<<1) + imm);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case _4ADDUI:
|
case _4ADDUI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,(GetGP(Ra)<<2) + imm);
|
SetGP(Rt,(GetGP(Ra)<<2) + imm);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case _8ADDUI:
|
case _8ADDUI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,(GetGP(Ra)<<3) + imm);
|
SetGP(Rt,(GetGP(Ra)<<3) + imm);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case _16ADDUI:
|
case _16ADDUI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,(GetGP(Ra)<<4) + imm);
|
SetGP(Rt,(GetGP(Ra)<<4) + imm);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
/* ToDo: add overflow exception */
|
/* ToDo: add overflow exception */
|
case ADDI:
|
case ADDI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
a = GetGP(Ra);
|
a = GetGP(Ra);
|
b = imm;
|
b = imm;
|
res = a + b;
|
res = a + b;
|
// overflow =
|
// overflow =
|
SetGP(Rt,res);
|
SetGP(Rt,res);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case ADDUI:
|
case ADDUI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,GetGP(Ra) + imm);
|
SetGP(Rt,GetGP(Ra) + imm);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case ADDUIS:
|
case ADDUIS:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = Ra;
|
Rt = Ra;
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b2 << 2)&0xFC) | ((b1 >> 6) & 0x3);
|
imm |= ((b2 << 2)&0xFC) | ((b1 >> 6) & 0x3);
|
}
|
}
|
else {
|
else {
|
imm = ((b2 << 2)&0x3FC) | ((b1 >> 6) & 0x3);
|
imm = ((b2 << 2)&0x3FC) | ((b1 >> 6) & 0x3);
|
if (imm & 0x200)
|
if (imm & 0x200)
|
imm |= 0xFFFFFFFFFFFFFE00LL;
|
imm |= 0xFFFFFFFFFFFFFE00LL;
|
}
|
}
|
SetGP(Rt,GetGP(Ra) + imm);
|
SetGP(Rt,GetGP(Ra) + imm);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case ANDI:
|
case ANDI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,GetGP(Ra) & imm);
|
SetGP(Rt,GetGP(Ra) & imm);
|
gp[0] = 0;
|
gp[0] = 0;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case BITI:
|
case BITI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
unsigned __int64 res;
|
unsigned __int64 res;
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Pn = ((b2 & 0x3) << 2) | (( b1 >> 6) & 3);
|
Pn = ((b2 & 0x3) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
res = GetGP(Ra) & imm;
|
res = GetGP(Ra) & imm;
|
pr[Pn] = 0;
|
pr[Pn] = 0;
|
if (res == 0)
|
if (res == 0)
|
pr[Pn] |= 1;
|
pr[Pn] |= 1;
|
if (res & 0x8000000000000000LL)
|
if (res & 0x8000000000000000LL)
|
pr[Pn] |= 2;
|
pr[Pn] |= 2;
|
if (res & 1)
|
if (res & 1)
|
pr[Pn] |= 4;
|
pr[Pn] |= 4;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case CLI:
|
case CLI:
|
if (ex) {
|
if (ex) {
|
imcd = 3;
|
imcd = 3;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
break;
|
break;
|
|
|
case DIVI:
|
case DIVI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,GetGP(Ra) / imm);
|
SetGP(Rt,GetGP(Ra) / imm);
|
gp[0] = 0;
|
gp[0] = 0;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case DIVUI:
|
case DIVUI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,(unsigned __int64)GetGP(Ra) / (unsigned __int64)imm);
|
SetGP(Rt,(unsigned __int64)GetGP(Ra) / (unsigned __int64)imm);
|
gp[0] = 0;
|
gp[0] = 0;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case EORI:
|
case EORI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,GetGP(Ra) ^ imm);
|
SetGP(Rt,GetGP(Ra) ^ imm);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
|
case INC:
|
|
b1 = ReadByte(pc);
|
|
pc++;
|
|
b2 = ReadByte(pc);
|
|
pc++;
|
|
b3 = ReadByte(pc);
|
|
pc++;
|
|
b4 = ReadByte(pc);
|
|
pc++;
|
|
if (ex) {
|
|
int amt;
|
|
__int64 val;
|
|
Ra = b1 & 0x3f;
|
|
Sz = (b1 >> 6) | ((b2 & 1) << 2);
|
|
func = (b2 >> 1) & 7;
|
|
disp = (b2 >> 4) | ((b3 & 31) << 4);
|
|
if (disp & 0x100)
|
|
disp |= 0xFFFFFFFFFFFFFF00LL;
|
|
Sg = b3 >> 5;
|
|
amt = b4;
|
|
if (amt & 0x80)
|
|
amt |= 0xFFFFFFFFFFFFFF00LL;
|
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
|
switch(Sz&3) {
|
|
case 0: val = ReadByte(ea); break;
|
|
case 1: val = ReadChar(ea); break;
|
|
case 2: val = ReadHalf(ea); break;
|
|
case 3: val = Read(ea); break;
|
|
}
|
|
val = val + amt;
|
|
switch(Sz&3) {
|
|
case 0: system1->Write(ea,val,(0x1 << (ea & 7)) & 0xFF); break;
|
|
case 1: system1->Write(ea,val,(0x3 << (ea & 6)) & 0xFF); break;
|
|
case 2: system1->Write(ea,val,(0xF << (ea & 4)) & 0xFF); break;
|
|
case 3: system1->Write(ea,val,0xFF); break;
|
|
}
|
|
}
|
|
return;
|
|
|
case INT:
|
case INT:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ct = b1 & 0xF;
|
Ct = b1 & 0xF;
|
Cr = b1 >> 4;
|
Cr = b1 >> 4;
|
// Normal INT stores the address of the interrupted instruction.
|
// Normal INT stores the address of the interrupted instruction.
|
// However if the target register indicates a system call or
|
// However if the target register indicates a system call or
|
// debug interrupt, then the address of the following
|
// debug interrupt, then the address of the following
|
// instruction is stored.
|
// instruction is stored.
|
if (!(Ct==11 || Ct==13))
|
if (!(Ct==11 || Ct==13))
|
pc -= 4;
|
pc -= 4;
|
ca[Ct] = pc;
|
ca[Ct] = pc;
|
ca[0] = 0;
|
ca[0] = 0;
|
pc = (b2 << 4) + ca[Cr];
|
pc = (b2 << 4) + ca[Cr];
|
if (Ct==11)
|
if (Ct==11)
|
StatusDBG = true;
|
StatusDBG = true;
|
else if (Ct==13) {
|
else if (Ct==13) {
|
if (StatusEXL < 255)
|
if (StatusEXL < 255)
|
StatusEXL++;
|
StatusEXL++;
|
}
|
}
|
else
|
else
|
StatusHWI = true;
|
StatusHWI = true;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case JSR:
|
case JSR:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
b4 = ReadByte(pc);
|
b4 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ct = b1 & 0x0F;
|
Ct = b1 & 0x0F;
|
Cr = (b1 & 0xF0) >> 4;
|
Cr = (b1 & 0xF0) >> 4;
|
if (Ct != 0)
|
if (Ct != 0) {
|
ca[Ct] = pc;
|
ca[Ct] = pc;
|
|
sub_depth++;
|
|
}
|
disp = (b4 << 16) | (b3 << 8) | b2;
|
disp = (b4 << 16) | (b3 << 8) | b2;
|
if (disp & 0x800000)
|
if (disp & 0x800000)
|
disp |= 0xFFFFFFFFFF000000LL;
|
disp |= 0xFFFFFFFFFF000000LL;
|
if (imm_prefix) {
|
if (imm_prefix) {
|
disp &= 0xFF;
|
disp &= 0xFF;
|
disp |= imm;
|
disp |= imm;
|
}
|
}
|
if (Cr==15)
|
if (Cr==15)
|
pc = disp + pc - 6;
|
pc = disp + pc - 6;
|
else
|
else
|
pc = disp + ca[Cr];
|
pc = disp + ca[Cr];
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case JSRI:
|
case JSRI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
int Sz;
|
int Sz;
|
unsigned __int64 dat;
|
unsigned __int64 dat;
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Ct = (b1 >> 6) | ((b2 << 2) & 0xf);
|
Ct = (b1 >> 6) | ((b2 << 2) & 0xf);
|
Sz = (b2 & 0xC) >> 2;
|
Sz = (b2 & 0xC) >> 2;
|
Sg = (b3 >> 5);
|
Sg = (b3 >> 5);
|
if (Ct != 0)
|
if (Ct != 0) {
|
ca[Ct] = pc;
|
ca[Ct] = pc;
|
|
sub_depth++;
|
|
}
|
disp = ((b3 & 0x1f) << 4) | (b2 >> 4);
|
disp = ((b3 & 0x1f) << 4) | (b2 >> 4);
|
if (disp & 0x100)
|
if (disp & 0x100)
|
disp |= 0xFFFFFFFFFFFFFE00LL;
|
disp |= 0xFFFFFFFFFFFFFE00LL;
|
if (imm_prefix) {
|
if (imm_prefix) {
|
disp &= 0xFF;
|
disp &= 0xFF;
|
disp |= imm;
|
disp |= imm;
|
}
|
}
|
switch(Sz) {
|
switch(Sz) {
|
case 1:
|
case 1:
|
dat = ReadChar(disp + seg_base[Sg] + GetGP(Ra)*2);
|
dat = ReadChar(disp + seg_base[Sg] + GetGP(Ra)*2);
|
dat &= 0xFFFFLL;
|
dat &= 0xFFFFLL;
|
pc = pc & 0xFFFF0000;
|
pc = pc & 0xFFFF0000;
|
pc |= dat;
|
pc |= dat;
|
break;
|
break;
|
case 2:
|
case 2:
|
dat = ReadHalf(disp + seg_base[Sg] + GetGP(Ra)*4);
|
dat = ReadHalf(disp + seg_base[Sg] + GetGP(Ra)*4);
|
dat &= 0xFFFFFFFFLL;
|
dat &= 0xFFFFFFFFLL;
|
pc = dat;
|
pc = dat;
|
break;
|
break;
|
case 3:
|
case 3:
|
dat = Read(disp + seg_base[Sg] + GetGP(Ra)*8);
|
dat = Read(disp + seg_base[Sg] + GetGP(Ra)*8);
|
pc = dat;
|
pc = dat;
|
break;
|
break;
|
}
|
}
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case JSRS:
|
case JSRS:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ct = b1 & 0x0F;
|
Ct = b1 & 0x0F;
|
Cr = (b1 & 0xF0) >> 4;
|
Cr = (b1 & 0xF0) >> 4;
|
ca[Ct] = pc;
|
ca[Ct] = pc;
|
ca[0] = 0;
|
ca[0] = 0;
|
disp = (b3 << 8) | b2;
|
disp = (b3 << 8) | b2;
|
if (disp & 0x8000)
|
if (disp & 0x8000)
|
disp |= 0xFFFFFFFFFFFF0000LL;
|
disp |= 0xFFFFFFFFFFFF0000LL;
|
if (imm_prefix) {
|
if (imm_prefix) {
|
disp &= 0xFFLL;
|
disp &= 0xFFLL;
|
disp |= imm;
|
disp |= imm;
|
}
|
}
|
if (Cr==15)
|
if (Cr==15)
|
pc = disp + pc - 5;
|
pc = disp + pc - 5;
|
else
|
else
|
pc = disp + ca[Cr];
|
pc = disp + ca[Cr];
|
if (Ct != 0)
|
if (Ct != 0)
|
sub_depth++;
|
sub_depth++;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case JSRR:
|
case JSRR:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ct = b1 & 0x0F;
|
Ct = b1 & 0x0F;
|
Cr = (b1 & 0xF0) >> 4;
|
Cr = (b1 & 0xF0) >> 4;
|
if (Ct != 0)
|
if (Ct != 0)
|
ca[Ct] = pc;
|
ca[Ct] = pc;
|
disp = 0;
|
disp = 0;
|
if (imm_prefix) {
|
if (imm_prefix) {
|
disp &= 0xFF;
|
disp &= 0xFF;
|
disp |= imm;
|
disp |= imm;
|
}
|
}
|
pc = disp + ca[Cr];
|
pc = disp + ca[Cr];
|
if (Ct != 0)
|
if (Ct != 0)
|
sub_depth++;
|
sub_depth++;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case LB:
|
case LB:
|
case LVB:
|
case LVB:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
dat = system1->Read(ea);
|
dat = system1->Read(ea);
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
if (ea & 2)
|
if (ea & 2)
|
dat = (dat >> 16);
|
dat = (dat >> 16);
|
if (ea & 1)
|
if (ea & 1)
|
dat = (dat >> 8);
|
dat = (dat >> 8);
|
dat &= 0xFFLL;
|
dat &= 0xFFLL;
|
if (dat & 0x80LL)
|
if (dat & 0x80LL)
|
dat |= 0xFFFFFFFFFFFFFF00LL;
|
dat |= 0xFFFFFFFFFFFFFF00LL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case LBU:
|
case LBU:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
dat = system1->Read(ea);
|
dat = system1->Read(ea);
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
if (ea & 2)
|
if (ea & 2)
|
dat = (dat >> 16);
|
dat = (dat >> 16);
|
if (ea & 1)
|
if (ea & 1)
|
dat = (dat >> 8);
|
dat = (dat >> 8);
|
dat &= 0xFFLL;
|
dat &= 0xFFLL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case LBX:
|
case LBX:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
dat = system1->Read(ea);
|
dat = system1->Read(ea);
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
if (ea & 2)
|
if (ea & 2)
|
dat = (dat >> 16);
|
dat = (dat >> 16);
|
if (ea & 1)
|
if (ea & 1)
|
dat = (dat >> 8);
|
dat = (dat >> 8);
|
dat &= 0xFFLL;
|
dat &= 0xFFLL;
|
if (dat & 0x80LL)
|
if (dat & 0x80LL)
|
dat |= 0xFFFFFFFFFFFFFF00LL;
|
dat |= 0xFFFFFFFFFFFFFF00LL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case LBUX:
|
case LBUX:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
dat = system1->Read(ea);
|
dat = system1->Read(ea);
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
if (ea & 2)
|
if (ea & 2)
|
dat = (dat >> 16);
|
dat = (dat >> 16);
|
if (ea & 1)
|
if (ea & 1)
|
dat = (dat >> 8);
|
dat = (dat >> 8);
|
dat &= 0xFFLL;
|
dat &= 0xFFLL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case LC:
|
case LC:
|
case LVC:
|
case LVC:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
dat = system1->Read(ea);
|
dat = system1->Read(ea);
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
if (ea & 2)
|
if (ea & 2)
|
dat = (dat >> 16);
|
dat = (dat >> 16);
|
dat &= 0xFFFF;
|
dat &= 0xFFFF;
|
if (dat & 0x8000LL)
|
if (dat & 0x8000LL)
|
dat |= 0xFFFFFFFFFFFF0000LL;
|
dat |= 0xFFFFFFFFFFFF0000LL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case LCX:
|
case LCX:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
dat = system1->Read(ea);
|
dat = system1->Read(ea);
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
if (ea & 2)
|
if (ea & 2)
|
dat = (dat >> 16);
|
dat = (dat >> 16);
|
dat &= 0xFFFF;
|
dat &= 0xFFFF;
|
if (dat & 0x8000LL)
|
if (dat & 0x8000LL)
|
dat |= 0xFFFFFFFFFFFF0000LL;
|
dat |= 0xFFFFFFFFFFFF0000LL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case LCU:
|
case LCU:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
dat = system1->Read(ea);
|
dat = system1->Read(ea);
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
if (ea & 2)
|
if (ea & 2)
|
dat = (dat >> 16);
|
dat = (dat >> 16);
|
dat &= 0xFFFFLL;
|
dat &= 0xFFFFLL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case LCUX:
|
case LCUX:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
dat = system1->Read(ea);
|
dat = system1->Read(ea);
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
if (ea & 2)
|
if (ea & 2)
|
dat = (dat >> 16);
|
dat = (dat >> 16);
|
dat &= 0xFFFF;
|
dat &= 0xFFFF;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case LDIS:
|
case LDIS:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Sprn = b1 & 0x3f;
|
Sprn = b1 & 0x3f;
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b2 << 2) & 0xFF) | ((b1 >> 6) & 3);
|
imm |= ((b2 << 2) & 0xFF) | ((b1 >> 6) & 3);
|
}
|
}
|
else {
|
else {
|
imm = ((b2 << 2) & 0x3FF) | ((b1 >> 6) & 3);
|
imm = ((b2 << 2) & 0x3FF) | ((b1 >> 6) & 3);
|
if (imm & 0x200)
|
if (imm & 0x200)
|
imm |= 0xFFFFFFFFFFFFFE00LL;
|
imm |= 0xFFFFFFFFFFFFFE00LL;
|
}
|
}
|
if (Sprn < 16) {
|
if (Sprn < 16) {
|
pr[Sprn] = imm & 0xF;
|
pr[Sprn] = imm & 0xF;
|
}
|
}
|
else if (Sprn < 32) {
|
else if (Sprn < 32) {
|
ca[Sprn-16] = imm;
|
ca[Sprn-16] = imm;
|
ca[0] = 0;
|
ca[0] = 0;
|
ca[15] = pc;
|
ca[15] = pc;
|
}
|
}
|
else if (Sprn < 40) {
|
else if (Sprn < 40) {
|
seg_base[Sprn-32] = imm & 0xFFFFFFFFFFFFF000LL;
|
seg_base[Sprn-32] = imm & 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
else if (Sprn < 48) {
|
else if (Sprn < 48) {
|
seg_limit[Sprn-40] = imm & 0xFFFFFFFFFFFFF000LL;
|
seg_limit[Sprn-40] = imm & 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
else {
|
else {
|
switch(Sprn) {
|
switch(Sprn) {
|
case 51: lc = imm; break;
|
case 51: lc = imm; break;
|
case 52:
|
case 52:
|
for (nn = 0; nn < 16; nn++) {
|
for (nn = 0; nn < 16; nn++) {
|
pr[nn] = (imm >> (nn * 4)) & 0xF;
|
pr[nn] = (imm >> (nn * 4)) & 0xF;
|
}
|
}
|
break;
|
break;
|
case 60: bir = imm & 0xFFLL; break;
|
case 60: bir = imm & 0xFFLL; break;
|
case 61:
|
case 61:
|
switch(bir) {
|
switch(bir) {
|
case 0: dbad0 = imm; break;
|
case 0: dbad0 = imm; break;
|
case 1: dbad1 = imm; break;
|
case 1: dbad1 = imm; break;
|
case 2: dbad2 = imm; break;
|
case 2: dbad2 = imm; break;
|
case 3: dbad3 = imm; break;
|
case 3: dbad3 = imm; break;
|
case 4: dbctrl = imm; break;
|
case 4: dbctrl = imm; break;
|
case 5: dbstat = imm; break;
|
case 5: dbstat = imm; break;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
imm_prefix = false;
|
imm_prefix = false;
|
ca[15] = pc;
|
ca[15] = pc;
|
return;
|
return;
|
|
|
case LDI:
|
case LDI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rt = b1 & 0x3f;
|
Rt = b1 & 0x3f;
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b2 << 2) & 0xFF) | ((b1 >> 6) & 3);
|
imm |= ((b2 << 2) & 0xFF) | ((b1 >> 6) & 3);
|
}
|
}
|
else {
|
else {
|
imm = ((b2 << 2) & 0x3FF) | ((b1 >> 6) & 3);
|
imm = ((b2 << 2) & 0x3FF) | ((b1 >> 6) & 3);
|
if (imm & 0x200)
|
if (imm & 0x200)
|
imm |= 0xFFFFFFFFFFFFFE00LL;
|
imm |= 0xFFFFFFFFFFFFFE00LL;
|
}
|
}
|
SetGP(Rt,imm);
|
SetGP(Rt,imm);
|
}
|
}
|
imm_prefix = false;
|
imm_prefix = false;
|
ca[15] = pc;
|
ca[15] = pc;
|
return;
|
return;
|
|
|
case LH:
|
case LH:
|
case LVH:
|
case LVH:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
dat = system1->Read(ea);
|
dat = system1->Read(ea);
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
dat &= 0xFFFFFFFFLL;
|
dat &= 0xFFFFFFFFLL;
|
if (dat & 0x80000000LL)
|
if (dat & 0x80000000LL)
|
dat |= 0xFFFFFFFF00000000LL;
|
dat |= 0xFFFFFFFF00000000LL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case LHX:
|
case LHX:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
dat = system1->Read(ea);
|
dat = system1->Read(ea);
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
dat &= 0xFFFFFFFFLL;
|
dat &= 0xFFFFFFFFLL;
|
if (dat & 0x80000000LL)
|
if (dat & 0x80000000LL)
|
dat |= 0xFFFFFFFF00000000LL;
|
dat |= 0xFFFFFFFF00000000LL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case LHU:
|
case LHU:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
dat = system1->Read(ea);
|
dat = system1->Read(ea);
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
dat &= 0xFFFFFFFFLL;
|
dat &= 0xFFFFFFFFLL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case LHUX:
|
case LHUX:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
dat = system1->Read(ea);
|
dat = system1->Read(ea);
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
dat &= 0xFFFFFFFFLL;
|
dat &= 0xFFFFFFFFLL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case LLA:
|
case LLA:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
SetGP(Rt,ea);
|
SetGP(Rt,ea);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case LOGIC:
|
case LOGIC:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rb = ((b2 << 2) & 0x3c) | (b1 >> 6);
|
Rb = ((b2 << 2) & 0x3c) | (b1 >> 6);
|
Rt = (b2 >> 4) | ((b3 & 0x3) << 4);
|
Rt = (b2 >> 4) | ((b3 & 0x3) << 4);
|
func = b3 >> 2;
|
func = b3 >> 2;
|
switch(func) {
|
switch(func) {
|
case AND:
|
case AND:
|
SetGP(Rt, GetGP(Ra) & GetGP(Rb));
|
SetGP(Rt, GetGP(Ra) & GetGP(Rb));
|
break;
|
break;
|
case OR:
|
case OR:
|
SetGP(Rt, GetGP(Ra) | GetGP(Rb));
|
SetGP(Rt, GetGP(Ra) | GetGP(Rb));
|
break;
|
break;
|
case EOR:
|
case EOR:
|
SetGP(Rt, GetGP(Ra) ^ GetGP(Rb));
|
SetGP(Rt, GetGP(Ra) ^ GetGP(Rb));
|
break;
|
break;
|
case NAND:
|
case NAND:
|
SetGP(Rt, ~(GetGP(Ra) & GetGP(Rb)));
|
SetGP(Rt, ~(GetGP(Ra) & GetGP(Rb)));
|
break;
|
break;
|
case NOR:
|
case NOR:
|
SetGP(Rt, ~(GetGP(Ra) | GetGP(Rb)));
|
SetGP(Rt, ~(GetGP(Ra) | GetGP(Rb)));
|
break;
|
break;
|
case ENOR:
|
case ENOR:
|
SetGP(Rt, ~(GetGP(Ra) ^ GetGP(Rb)));
|
SetGP(Rt, ~(GetGP(Ra) ^ GetGP(Rb)));
|
break;
|
break;
|
case ANDC:
|
case ANDC:
|
SetGP(Rt, GetGP(Ra) & ~GetGP(Rb));
|
SetGP(Rt, GetGP(Ra) & ~GetGP(Rb));
|
break;
|
break;
|
case ORC:
|
case ORC:
|
SetGP(Rt, GetGP(Ra) | ~GetGP(Rb));
|
SetGP(Rt, GetGP(Ra) | ~GetGP(Rb));
|
break;
|
break;
|
}
|
}
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = 0;
|
imm_prefix = 0;
|
return;
|
return;
|
|
|
case LOOP:
|
case LOOP:
|
disp = ReadByte(pc);
|
disp = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
if (disp & 0x80LL)
|
if (disp & 0x80LL)
|
disp |= 0xFFFFFFFFFFFFFF00LL;
|
disp |= 0xFFFFFFFFFFFFFF00LL;
|
if (lc > 0) {
|
if (lc > 0) {
|
lc--;
|
lc--;
|
pc = pc + disp;
|
pc = pc + disp;
|
}
|
}
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case LW:
|
case LW:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
dat = system1->Read(ea);
|
dat = system1->Read(ea);
|
/*
|
/*
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
if (ea & 2)
|
if (ea & 2)
|
dat = (dat >> 16);
|
dat = (dat >> 16);
|
*/
|
*/
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
}
|
}
|
imm_prefix = false;
|
imm_prefix = false;
|
ca[15] = pc;
|
ca[15] = pc;
|
return;
|
return;
|
|
|
case LVWAR:
|
case LVWAR:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
dat = system1->Read(ea,1);
|
dat = system1->Read(ea,1);
|
/*
|
/*
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
if (ea & 2)
|
if (ea & 2)
|
dat = (dat >> 16);
|
dat = (dat >> 16);
|
*/
|
*/
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
}
|
}
|
imm_prefix = false;
|
imm_prefix = false;
|
ca[15] = pc;
|
ca[15] = pc;
|
return;
|
return;
|
|
|
case LWS:
|
case LWS:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
dat = system1->Read(ea);
|
dat = system1->Read(ea);
|
/*
|
/*
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
if (ea & 2)
|
if (ea & 2)
|
dat = (dat >> 16);
|
dat = (dat >> 16);
|
if (ea & 1)
|
if (ea & 1)
|
dat = (dat >> 8);
|
dat = (dat >> 8);
|
*/
|
*/
|
SetSpr(Rt, dat);
|
SetSpr(Rt, dat);
|
}
|
}
|
imm_prefix = false;
|
imm_prefix = false;
|
ca[15] = pc;
|
ca[15] = pc;
|
return;
|
return;
|
|
|
case LWX:
|
case LWX:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
dat = system1->Read(ea);
|
dat = system1->Read(ea);
|
/*
|
/*
|
if (ea & 4)
|
if (ea & 4)
|
dat = (dat >> 32);
|
dat = (dat >> 32);
|
if (ea & 2)
|
if (ea & 2)
|
dat = (dat >> 16);
|
dat = (dat >> 16);
|
*/
|
*/
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
}
|
}
|
imm_prefix = false;
|
imm_prefix = false;
|
ca[15] = pc;
|
ca[15] = pc;
|
return;
|
return;
|
|
|
// Memory synchronization primitives are not useful to the software ISA
|
// Memory synchronization primitives are not useful to the software ISA
|
// emulator. They are treated like NOP's.
|
// emulator. They are treated like NOP's.
|
case MEMSB:
|
case MEMSB:
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
break;
|
return;
|
|
|
case MEMDB:
|
case MEMDB:
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
break;
|
return;
|
|
|
case MFSPR:
|
case MFSPR:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Sprn = b1 & 0x3f;
|
Sprn = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | ((b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | ((b1 >> 6) & 3);
|
SetGP(Rt,GetSpr(Sprn));
|
SetGP(Rt,GetSpr(Sprn));
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case MODI:
|
case MODI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,GetGP(Ra) % imm);
|
SetGP(Rt,GetGP(Ra) % imm);
|
gp[0] = 0;
|
gp[0] = 0;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case MODUI:
|
case MODUI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,(unsigned __int64) GetGP(Ra) % (unsigned __int64)imm);
|
SetGP(Rt,(unsigned __int64) GetGP(Ra) % (unsigned __int64)imm);
|
gp[0] = 0;
|
gp[0] = 0;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case GRPA7:
|
case GRPA7:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
switch(b2 >> 4) {
|
switch(b2 >> 4) {
|
case ABS:
|
case ABS:
|
SetGP(Rt, GetGP(Ra) < 0 ? -GetGP(Ra) : GetGP(Ra));
|
SetGP(Rt, GetGP(Ra) < 0 ? -GetGP(Ra) : GetGP(Ra));
|
break;
|
break;
|
case COM:
|
case COM:
|
SetGP(Rt, ~GetGP(Ra));
|
SetGP(Rt, ~GetGP(Ra));
|
break;
|
break;
|
case MOV:
|
case MOV:
|
SetGP(Rt, GetGP(Ra));
|
SetGP(Rt, GetGP(Ra));
|
break;
|
break;
|
case NEG:
|
case NEG:
|
SetGP(Rt, -GetGP(Ra));
|
SetGP(Rt, -GetGP(Ra));
|
break;
|
break;
|
case NOT:
|
case NOT:
|
SetGP(Rt, !GetGP(Ra));
|
SetGP(Rt, !GetGP(Ra));
|
break;
|
break;
|
case SGN:
|
case SGN:
|
SetGP(Rt, (GetGP(Ra) == 0) ? 0 : (GetGP(Ra) < 0) ? -1 : 1);
|
SetGP(Rt, (GetGP(Ra) == 0) ? 0 : (GetGP(Ra) < 0) ? -1 : 1);
|
break;
|
break;
|
case SXB:
|
case SXB:
|
dat = GetGP(Ra);
|
dat = GetGP(Ra);
|
if (dat & 0x80LL)
|
if (dat & 0x80LL)
|
dat |= 0xFFFFFFFFFFFFFF80LL;
|
dat |= 0xFFFFFFFFFFFFFF80LL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
break;
|
break;
|
case SXC:
|
case SXC:
|
dat = GetGP(Ra);
|
dat = GetGP(Ra);
|
if (dat & 0x8000LL)
|
if (dat & 0x8000LL)
|
dat |= 0xFFFFFFFFFFFF8000LL;
|
dat |= 0xFFFFFFFFFFFF8000LL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
break;
|
break;
|
case SXH:
|
case SXH:
|
dat = GetGP(Ra);
|
dat = GetGP(Ra);
|
if (dat & 0x80000000LL)
|
if (dat & 0x80000000LL)
|
dat |= 0xFFFFFFFF80000000LL;
|
dat |= 0xFFFFFFFF80000000LL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
break;
|
break;
|
case ZXB:
|
case ZXB:
|
dat = GetGP(Ra);
|
dat = GetGP(Ra);
|
dat &= 0xFFLL;
|
dat &= 0xFFLL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
break;
|
break;
|
case ZXC:
|
case ZXC:
|
dat = GetGP(Ra);
|
dat = GetGP(Ra);
|
dat &= 0xFFFFLL;
|
dat &= 0xFFFFLL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
break;
|
break;
|
case ZXH:
|
case ZXH:
|
dat = GetGP(Ra);
|
dat = GetGP(Ra);
|
dat &= 0xFFFFFFFFLL;
|
dat &= 0xFFFFFFFFLL;
|
SetGP(Rt,dat);
|
SetGP(Rt,dat);
|
break;
|
break;
|
}
|
}
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case MTSPR:
|
case MTSPR:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Sprn = ((b2 & 0xF) << 2) | ((b1 >> 6) & 3);
|
Sprn = ((b2 & 0xF) << 2) | ((b1 >> 6) & 3);
|
SetSpr(Sprn, GetGP(Ra));
|
SetSpr(Sprn, GetGP(Ra));
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case MULI:
|
case MULI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,GetGP(Ra) * imm);
|
SetGP(Rt,GetGP(Ra) * imm);
|
gp[0] = 0;
|
gp[0] = 0;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case MULUI:
|
case MULUI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,(unsigned __int64)GetGP(Ra) * (unsigned __int64)imm);
|
SetGP(Rt,(unsigned __int64)GetGP(Ra) * (unsigned __int64)imm);
|
gp[0] = 0;
|
gp[0] = 0;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case ORI:
|
case ORI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,GetGP(Ra) | imm);
|
SetGP(Rt,GetGP(Ra) | imm);
|
gp[0] = 0;
|
gp[0] = 0;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case R1:
|
case R1:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
switch(b2 >> 4) {
|
switch(b2 >> 4) {
|
case CPUID:
|
case CPUID:
|
switch(Ra) {
|
switch(Ra) {
|
case 0: SetGP(Rt,0x0002LL); break; // Processor ID
|
case 0: SetGP(Rt,0x0000LL); break; // Processor ID
|
case 2: SetGP(Rt,0x4e4F5254494E4966LL); break; // "Finitron"
|
case 2: SetGP(Rt,0x4e4F5254494E4966LL); break; // "Finitron"
|
case 3: SetGP(Rt,0x00LL); break;
|
case 3: SetGP(Rt,0x00LL); break;
|
case 4: SetGP(Rt,0x36346249547373LL); break; // 64BitSS
|
case 4: SetGP(Rt,0x36346249547373LL); break; // 64BitSS
|
case 5: SetGP(Rt,0x00LL); break;
|
case 5: SetGP(Rt,0x00LL); break;
|
case 6: SetGP(Rt,0x524F4A74LL); break; // "Thor"
|
case 6: SetGP(Rt,0x524F4A74LL); break; // "Thor"
|
case 7: SetGP(Rt, 0x00LL); break;
|
case 7: SetGP(Rt, 0x00LL); break;
|
case 8: SetGP(Rt, 0x316ELL); break; // "M1"
|
case 8: SetGP(Rt, 0x316ELL); break; // "M1"
|
case 9: SetGP(Rt, 0x1235LL); break;
|
case 9: SetGP(Rt, 0x1235LL); break;
|
case 10: SetGP(Rt,0x00LL); break;
|
case 10: SetGP(Rt,0x00LL); break;
|
case 11: SetGP(Rt,0x0000400000008000LL); break; // 16k,32k cache size
|
case 11: SetGP(Rt,0x0000400000008000LL); break; // 16k,32k cache size
|
default: SetGP(Rt,0x00LL); break;
|
default: SetGP(Rt,0x00LL); break;
|
}
|
}
|
case REDOR: SetGP(Rt, GetGP(Ra) != 0); break;
|
case REDOR: SetGP(Rt, GetGP(Ra) != 0); break;
|
case REDAND: SetGP(Rt, GetGP(Ra)==0xFFFFFFFFFFFFFFFFLL); break;
|
case REDAND: SetGP(Rt, GetGP(Ra)==0xFFFFFFFFFFFFFFFFLL); break;
|
case PAR: break; /* ToDo */
|
case PAR: break; /* ToDo */
|
}
|
}
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case P1:
|
case P1:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
int bita,bitb,bitt;
|
int bita,bitb,bitt;
|
Ra = (b1 & 0x3f) >> 2;
|
Ra = (b1 & 0x3f) >> 2;
|
bita = b1 & 3;
|
bita = b1 & 3;
|
a = GetBit(pr[Ra],bita);
|
a = GetBit(pr[Ra],bita);
|
Rb = (b2 & 0xf);
|
Rb = (b2 & 0xf);
|
bitb = b1 >> 6;
|
bitb = b1 >> 6;
|
b = GetBit(pr[Rb],bitb);
|
b = GetBit(pr[Rb],bitb);
|
Rt = (b2 >> 6) | ((b3 & 3) << 2);
|
Rt = (b2 >> 6) | ((b3 & 3) << 2);
|
bitt = (b2 >> 4) & 3;
|
bitt = (b2 >> 4) & 3;
|
switch(b3 >> 2) {
|
switch(b3 >> 2) {
|
case PAND:
|
case PAND:
|
res = a & b;
|
res = a & b;
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
break;
|
break;
|
case POR:
|
case POR:
|
res = a | b;
|
res = a | b;
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
break;
|
break;
|
case PEOR:
|
case PEOR:
|
res = a ^ b;
|
res = a ^ b;
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
break;
|
break;
|
case PNAND:
|
case PNAND:
|
res = !(a & b);
|
res = !(a & b);
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
break;
|
break;
|
case PNOR:
|
case PNOR:
|
res = !(a | b);
|
res = !(a | b);
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
break;
|
break;
|
case PENOR:
|
case PENOR:
|
res = !(a ^ b);
|
res = !(a ^ b);
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
break;
|
break;
|
case PANDC:
|
case PANDC:
|
res = a & !b;
|
res = a & !b;
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
break;
|
break;
|
case PORC:
|
case PORC:
|
res = a | !b;
|
res = a | !b;
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
|
break;
|
break;
|
}
|
}
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = 0;
|
imm_prefix = 0;
|
return;
|
return;
|
|
|
case RR:
|
case RR:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rb = ((b2 << 2) & 0x3c) | (b1 >> 6);
|
Rb = ((b2 << 2) & 0x3c) | (b1 >> 6);
|
Rt = (b2 >> 4) | ((b3 & 0x3) << 4);
|
Rt = (b2 >> 4) | ((b3 & 0x3) << 4);
|
func = b3 >> 2;
|
func = b3 >> 2;
|
switch(func) {
|
switch(func) {
|
case ADD:
|
case ADD:
|
case ADDU:
|
case ADDU:
|
SetGP(Rt,(unsigned __int64)GetGP(Ra) + (unsigned __int64)GetGP(Rb));
|
SetGP(Rt,(unsigned __int64)GetGP(Ra) + (unsigned __int64)GetGP(Rb));
|
break;
|
break;
|
case SUB:
|
case SUB:
|
case SUBU:
|
case SUBU:
|
SetGP(Rt,(unsigned __int64)GetGP(Ra) - (unsigned __int64)GetGP(Rb));
|
SetGP(Rt,(unsigned __int64)GetGP(Ra) - (unsigned __int64)GetGP(Rb));
|
break;
|
break;
|
case MUL:
|
case MUL:
|
SetGP(Rt,GetGP(Ra) * GetGP(Rb));
|
SetGP(Rt,GetGP(Ra) * GetGP(Rb));
|
break;
|
break;
|
case DIV:
|
case DIV:
|
|
if (GetGP(Rb)==0) {
|
|
if (StatusEXL < 255)
|
|
StatusEXL++;
|
|
ca[13] = pc;
|
|
pc = ca[12] + (241 << 4);
|
|
ca[15] = pc;
|
|
}
|
|
else
|
SetGP(Rt,GetGP(Ra) / GetGP(Rb));
|
SetGP(Rt,GetGP(Ra) / GetGP(Rb));
|
break;
|
break;
|
case MOD:
|
case MOD:
|
|
if (GetGP(Rb)==0) {
|
|
if (StatusEXL < 255)
|
|
StatusEXL++;
|
|
ca[13] = pc;
|
|
pc = ca[12] + (241 << 4);
|
|
ca[15] = pc;
|
|
}
|
|
else
|
SetGP(Rt,GetGP(Ra) % GetGP(Rb));
|
SetGP(Rt,GetGP(Ra) % GetGP(Rb));
|
break;
|
break;
|
case MULU:
|
case MULU:
|
SetGP(Rt,(unsigned __int64)GetGP(Ra) * (unsigned __int64)GetGP(Rb));
|
SetGP(Rt,(unsigned __int64)GetGP(Ra) * (unsigned __int64)GetGP(Rb));
|
break;
|
break;
|
case DIVU:
|
case DIVU:
|
|
if (GetGP(Rb)==0)
|
|
SetGP(Rt,-1LL);
|
|
else
|
SetGP(Rt,(unsigned __int64)GetGP(Ra) / (unsigned __int64)GetGP(Rb));
|
SetGP(Rt,(unsigned __int64)GetGP(Ra) / (unsigned __int64)GetGP(Rb));
|
break;
|
break;
|
case MODU:
|
case MODU:
|
|
if (GetGP(Rb)==0)
|
|
SetGP(Rt,-1LL);
|
|
else
|
SetGP(Rt,(unsigned __int64)GetGP(Ra) % (unsigned __int64)GetGP(Rb));
|
SetGP(Rt,(unsigned __int64)GetGP(Ra) % (unsigned __int64)GetGP(Rb));
|
break;
|
break;
|
case _2ADDU:
|
case _2ADDU:
|
SetGP(Rt,(GetGP(Ra) << 1) + GetGP(Rb));
|
SetGP(Rt,(GetGP(Ra) << 1) + GetGP(Rb));
|
break;
|
break;
|
case _4ADDU:
|
case _4ADDU:
|
SetGP(Rt,(GetGP(Ra) << 2) + GetGP(Rb));
|
SetGP(Rt,(GetGP(Ra) << 2) + GetGP(Rb));
|
break;
|
break;
|
case _8ADDU:
|
case _8ADDU:
|
SetGP(Rt,(GetGP(Ra) << 3) + GetGP(Rb));
|
SetGP(Rt,(GetGP(Ra) << 3) + GetGP(Rb));
|
break;
|
break;
|
case _16ADDU:
|
case _16ADDU:
|
SetGP(Rt,(GetGP(Ra) << 4) + GetGP(Rb));
|
SetGP(Rt,(GetGP(Ra) << 4) + GetGP(Rb));
|
break;
|
break;
|
}
|
}
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = 0;
|
imm_prefix = 0;
|
return;
|
return;
|
|
|
case RTD:
|
case RTD:
|
if (ex) {
|
if (ex) {
|
StatusDBG = false;
|
StatusDBG = false;
|
pc = ca[11];
|
pc = ca[11];
|
|
rts = true;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case RTE:
|
case RTE:
|
if (ex) {
|
if (ex) {
|
if (StatusEXL > 0)
|
if (StatusEXL > 0)
|
StatusEXL--;
|
StatusEXL--;
|
pc = ca[13];
|
pc = ca[13];
|
|
rts = true;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case RTI:
|
case RTI:
|
if (ex) {
|
if (ex) {
|
im = 0;
|
imcd = 3;
|
StatusHWI = false;
|
StatusHWI = false;
|
pc = ca[14];
|
pc = ca[14];
|
|
rts = true;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case RTS:
|
case RTS:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Cr = (b1 & 0xF0) >> 4;
|
Cr = (b1 & 0xF0) >> 4;
|
pc = ca[Cr] + (b1 & 0x0F);
|
pc = ca[Cr] + (b1 & 0x0F);
|
|
rts = true;
|
if (sub_depth > 0) sub_depth--;
|
if (sub_depth > 0) sub_depth--;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = 0;
|
imm_prefix = 0;
|
return;
|
return;
|
|
|
case RTSQ:
|
case RTSQ:
|
if (ex) {
|
if (ex) {
|
pc = ca[1];
|
pc = ca[1];
|
|
rts = true;
|
if (sub_depth > 0) sub_depth--;
|
if (sub_depth > 0) sub_depth--;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = 0;
|
imm_prefix = 0;
|
return;
|
return;
|
|
|
case SB:
|
case SB:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
system1->Write(ea,GetGP(Rb),(0x1 << (ea & 7)) & 0xFF);
|
system1->Write(ea,GetGP(Rb),(0x1 << (ea & 7)) & 0xFF);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case SBX:
|
case SBX:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
system1->Write(ea,GetGP(Rt),(0x1 << (ea & 7)) & 0xFF);
|
system1->Write(ea,GetGP(Rt),(0x1 << (ea & 7)) & 0xFF);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case SC:
|
case SC:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
system1->Write(ea,GetGP(Rb),(0x3 << (ea & 7)) & 0xFF);
|
system1->Write(ea,GetGP(Rb),(0x3 << (ea & 7)) & 0xFF);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case SCX:
|
case SCX:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
system1->Write(ea,GetGP(Rt),(0x3 << (ea & 7)) & 0xFF);
|
system1->Write(ea,GetGP(Rt),(0x3 << (ea & 7)) & 0xFF);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case SEI:
|
case SEI:
|
if (ex) {
|
if (ex) {
|
im = 1;
|
im = 1;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
break;
|
break;
|
|
|
case SH:
|
case SH:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
system1->Write(ea,GetGP(Rb),(0xF << (ea & 7)) & 0xFF);
|
system1->Write(ea,GetGP(Rb),(0xF << (ea & 7)) & 0xFF);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case SHX:
|
case SHX:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
system1->Write(ea,GetGP(Rt),(0xF << (ea & 7)) & 0xFF);
|
system1->Write(ea,GetGP(Rt),(0xF << (ea & 7)) & 0xFF);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case SHIFT:
|
case SHIFT:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
unsigned __int64 a,b;
|
unsigned __int64 a,b;
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rb = ((b2 << 2) & 0x3c) | (b1 >> 6);
|
Rb = ((b2 << 2) & 0x3c) | (b1 >> 6);
|
Rt = (b2 >> 4) | ((b3 & 0x3) << 4);
|
Rt = (b2 >> 4) | ((b3 & 0x3) << 4);
|
func = b3 >> 2;
|
func = b3 >> 2;
|
switch(func) {
|
switch(func) {
|
case SHL:
|
case SHL:
|
case SHLU:
|
case SHLU:
|
SetGP(Rt, GetGP(Ra) << (GetGP(Rb) & 0x3f));
|
SetGP(Rt, GetGP(Ra) << (GetGP(Rb) & 0x3f));
|
break;
|
break;
|
case SHR:
|
case SHR:
|
SetGP(Rt, GetGP(Ra) >> (GetGP(Rb) & 0x3f));
|
SetGP(Rt, GetGP(Ra) >> (GetGP(Rb) & 0x3f));
|
break;
|
break;
|
case ROL:
|
case ROL:
|
a = (unsigned __int64)GetGP(Ra) << (GetGP(Rb) & 0x3f);
|
a = (unsigned __int64)GetGP(Ra) << (GetGP(Rb) & 0x3f);
|
b = (unsigned __int64)GetGP(Ra) >> (64-(GetGP(Rb) & 0x3f));
|
b = (unsigned __int64)GetGP(Ra) >> (64-(GetGP(Rb) & 0x3f));
|
SetGP(Rt, (unsigned __int64)a|b);
|
SetGP(Rt, (unsigned __int64)a|b);
|
break;
|
break;
|
case ROR:
|
case ROR:
|
a = (unsigned __int64)GetGP(Ra) >> (GetGP(Rb) & 0x3f);
|
a = (unsigned __int64)GetGP(Ra) >> (GetGP(Rb) & 0x3f);
|
b = (unsigned __int64)GetGP(Ra) << (64-(GetGP(Rb) & 0x3f));
|
b = (unsigned __int64)GetGP(Ra) << (64-(GetGP(Rb) & 0x3f));
|
SetGP(Rt, (unsigned __int64)a|b);
|
SetGP(Rt, (unsigned __int64)a|b);
|
break;
|
break;
|
case SHLI:
|
case SHLI:
|
case SHLUI:
|
case SHLUI:
|
SetGP(Rt, GetGP(Ra) << Rb);
|
SetGP(Rt, GetGP(Ra) << Rb);
|
break;
|
break;
|
case SHRI:
|
case SHRI:
|
SetGP(Rt, GetGP(Ra) >> Rb);
|
SetGP(Rt, GetGP(Ra) >> Rb);
|
break;
|
break;
|
case SHRUI:
|
case SHRUI:
|
SetGP(Rt, (unsigned __int64)GetGP(Ra) >> Rb);
|
SetGP(Rt, (unsigned __int64)GetGP(Ra) >> Rb);
|
break;
|
break;
|
case ROLI:
|
case ROLI:
|
a = (unsigned __int64)GetGP(Ra) << Rb;
|
a = (unsigned __int64)GetGP(Ra) << Rb;
|
b = (unsigned __int64)GetGP(Ra) >> (64-Rb);
|
b = (unsigned __int64)GetGP(Ra) >> (64-Rb);
|
SetGP(Rt, (unsigned __int64)a|b);
|
SetGP(Rt, (unsigned __int64)a|b);
|
break;
|
break;
|
case RORI:
|
case RORI:
|
a = (unsigned __int64)GetGP(Ra) >> Rb;
|
a = (unsigned __int64)GetGP(Ra) >> Rb;
|
b = (unsigned __int64)GetGP(Ra) << (64-Rb);
|
b = (unsigned __int64)GetGP(Ra) << (64-Rb);
|
SetGP(Rt, (unsigned __int64)a|b);
|
SetGP(Rt, (unsigned __int64)a|b);
|
break;
|
break;
|
}
|
}
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
// The stop instruction controls the clock rate. It's just about useless
|
// The stop instruction controls the clock rate. It's just about useless
|
// to try to emulate as the emulation rate is controlled by the user.
|
// to try to emulate as the emulation rate is controlled by the user.
|
// So for now, it's a NOP.
|
// So for now, it's a NOP.
|
case STP:
|
case STP:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case STSET:
|
case STSET:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
string_pc = pc - 5; // address of the string instruction
|
string_pc = pc - 5; // address of the string instruction
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
do {
|
do {
|
Sg = b3 >> 5;
|
Sg = b3 >> 5;
|
ea = GetGP(Ra) + seg_base[Sg];
|
ea = GetGP(Ra) + seg_base[Sg];
|
switch((b3 >> 2) & 3) {
|
switch((b3 >> 2) & 3) {
|
case 0:
|
case 0:
|
dat = GetGP(Rb) & 0xFFLL;
|
dat = GetGP(Rb) & 0xFFLL;
|
dat = (dat << 56) | (dat << 48) | (dat << 40) | (dat << 32)
|
dat = (dat << 56) | (dat << 48) | (dat << 40) | (dat << 32)
|
| (dat << 24) | (dat << 16) | (dat << 8) | dat;
|
| (dat << 24) | (dat << 16) | (dat << 8) | dat;
|
SetGP(Ra,GetGP(Ra) + ((b3&16) ? -1 : 1));
|
SetGP(Ra,GetGP(Ra) + ((b3&16) ? -1 : 1));
|
system1->Write(ea,dat,WriteMask(ea,0),0);
|
system1->Write(ea,dat,WriteMask(ea,0),0);
|
break;
|
break;
|
case 1:
|
case 1:
|
dat = GetGP(Rb) & 0xFFFFLL;
|
dat = GetGP(Rb) & 0xFFFFLL;
|
dat = (dat << 48) | (dat << 32)
|
dat = (dat << 48) | (dat << 32)
|
| (dat << 16) | dat;
|
| (dat << 16) | dat;
|
SetGP(Ra,GetGP(Ra) + ((b3&16) ? -2 : 2));
|
SetGP(Ra,GetGP(Ra) + ((b3&16) ? -2 : 2));
|
system1->Write(ea,dat,WriteMask(ea,1),0);
|
system1->Write(ea,dat,WriteMask(ea,1),0);
|
break;
|
break;
|
case 2:
|
case 2:
|
dat = GetGP(Rb) & 0xFFFFFFFFLL;
|
dat = GetGP(Rb) & 0xFFFFFFFFLL;
|
dat = (dat << 32) | dat;
|
dat = (dat << 32) | dat;
|
SetGP(Ra,GetGP(Ra) + ((b3&16) ? -4 : 4));
|
SetGP(Ra,GetGP(Ra) + ((b3&16) ? -4 : 4));
|
system1->Write(ea,dat,WriteMask(ea,2),0);
|
system1->Write(ea,dat,WriteMask(ea,2),0);
|
break;
|
break;
|
case 3:
|
case 3:
|
dat = GetGP(Rb);
|
dat = GetGP(Rb);
|
SetGP(Ra,GetGP(Ra) + ((b3&16) ? -8 : 8));
|
SetGP(Ra,GetGP(Ra) + ((b3&16) ? -8 : 8));
|
system1->Write(ea,dat,WriteMask(ea,3),0);
|
system1->Write(ea,dat,WriteMask(ea,3),0);
|
break;
|
break;
|
}
|
}
|
if (lc==0) {
|
if (lc==0) {
|
string_pc = 0;
|
string_pc = 0;
|
break;
|
break;
|
}
|
}
|
lc--;
|
lc--;
|
} while (!IRQActive());
|
} while (!IRQActive());
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
/* ToDo: cause overflow exception */
|
/* ToDo: cause overflow exception */
|
case SUBI:
|
case SUBI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,GetGP(Ra) - imm);
|
SetGP(Rt,GetGP(Ra) - imm);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case SUBUI:
|
case SUBUI:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ra = b1 & 0x3f;
|
Ra = b1 & 0x3f;
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
if (imm_prefix) {
|
if (imm_prefix) {
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
|
}
|
}
|
else {
|
else {
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
imm = (b3 << 4) | ((b2 >> 4) & 0xF);
|
if (imm & 0x800)
|
if (imm & 0x800)
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
imm |= 0xFFFFFFFFFFFFF000LL;
|
}
|
}
|
SetGP(Rt,GetGP(Ra) - imm);
|
SetGP(Rt,GetGP(Ra) - imm);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case SW:
|
case SW:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
system1->Write(ea,GetGP(Rb),(0xFF << (ea & 7)) & 0xFF);
|
system1->Write(ea,GetGP(Rb),(0xFF << (ea & 7)) & 0xFF);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case SWCR:
|
case SWCR:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
system1->Write(ea,GetGP(Rb),(0xFF << (ea & 7)) & 0xFF,1);
|
system1->Write(ea,GetGP(Rb),(0xFF << (ea & 7)) & 0xFF,1);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case SWS:
|
case SWS:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
dRn(b1,b2,b3,&Ra,&Sg,&disp);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
|
system1->Write(ea,GetSpr(Rb),(0xFF << (ea & 7)) & 0xFF);
|
system1->Write(ea,GetSpr(Rb),(0xFF << (ea & 7)) & 0xFF);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
case SWX:
|
case SWX:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
b3 = ReadByte(pc);
|
b3 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
|
system1->Write(ea,GetGP(Rt),(0xFF << (ea & 7)) & 0xFF);
|
system1->Write(ea,GetGP(Rt),(0xFF << (ea & 7)) & 0xFF);
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
// The SYNC instruction is a pipeline control. The pipeline is
|
// The SYNC instruction is a pipeline control. The pipeline is
|
// not emulated by this emulator. So it's treated as a NOP.
|
// not emulated by this emulator. So it's treated as a NOP.
|
case SYNC:
|
case SYNC:
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
break;
|
break;
|
|
|
case SYS:
|
case SYS:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
Ct = b1 & 0xF;
|
Ct = b1 & 0xF;
|
Cr = b1 >> 4;
|
Cr = b1 >> 4;
|
ca[Ct] = pc;
|
ca[Ct] = pc;
|
ca[0] = 0;
|
ca[0] = 0;
|
pc = (b2 << 4) + ca[Cr];
|
pc = (b2 << 4) + ca[Cr];
|
if (Ct==11)
|
if (Ct==11)
|
StatusDBG = true;
|
StatusDBG = true;
|
else if (StatusEXL < 255)
|
else if (StatusEXL < 255)
|
StatusEXL++;
|
StatusEXL++;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
// The TLB isn't implemented yet. the boot rom currently just
|
// The TLB isn't implemented yet. the boot rom currently just
|
// sets up the TLB registers and then leaves it disabled.
|
// sets up the TLB registers and then leaves it disabled.
|
case TLB:
|
case TLB:
|
b1 = ReadByte(pc);
|
b1 = ReadByte(pc);
|
pc++;
|
pc++;
|
b2 = ReadByte(pc);
|
b2 = ReadByte(pc);
|
pc++;
|
pc++;
|
if (ex) {
|
if (ex) {
|
;
|
;
|
}
|
}
|
ca[15] = pc;
|
ca[15] = pc;
|
imm_prefix = false;
|
imm_prefix = false;
|
return;
|
return;
|
|
|
}
|
}
|
}
|
}
|
|
|