OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

[/] [thor/] [trunk/] [software/] [emuThor/] [source/] [clsThor.cpp] - Diff between revs 30 and 32

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 30 Rev 32
Line 8... Line 8...
{
{
        pc = 0xFFFFFFFFFFFC0000LL;
        pc = 0xFFFFFFFFFFFC0000LL;
        tick = 0;
        tick = 0;
        gp[0] = 0;
        gp[0] = 0;
        ca[0] = 0;
        ca[0] = 0;
 
        StatusHWI = true;
 
        StatusDBG = false;
 
        StatusEXL = 0;
 
        string_pc = 0;
 
}
 
 
 
bool clsThor::IsKM()
 
{
 
        return StatusHWI || (StatusEXL > 0) || StatusDBG;
 
}
 
 
 
unsigned __int64 clsThor::ReadByte(int ad) { return system1->ReadByte(ad); };
 
unsigned __int64 clsThor::ReadChar(int ad) { return system1->ReadChar(ad); };
 
unsigned __int64 clsThor::ReadHalf(int ad) { return system1->ReadHalf(ad); };
 
unsigned __int64 clsThor::Read(int ad) { return system1->Read(ad); };
 
 
 
 
 
int clsThor::GetMode()
 
{
 
        if (StatusHWI)
 
                return mode = 1;
 
        if (StatusDBG)
 
                return mode = 3;
 
        if (StatusEXL)
 
                return mode = 2;
 
        return mode = 0;
 
}
 
 
 
__int64 clsThor::GetGP(int rg)
 
{
 
        if (rg < 0 || rg > 63)
 
                return 0xDEADEADDEADDEAD;
 
        switch(rg) {
 
        case 0: return 0; // ignore update to r0.
 
        case 27:
 
                rg = rg + GetMode();
 
                // Fall through
 
        default:
 
                return gp[rg];
 
        }
 
}
 
 
 
 
 
void clsThor::SetGP(int rg, __int64 val)
 
{
 
        if (rg < 0 || rg > 63)
 
                return;
 
        switch(rg) {
 
        case 0:  ;       // ignore update to r0.
 
        case 27:
 
                rg = rg + GetMode();
 
                // Fall through
 
        default:
 
                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)
{
{
Line 24... Line 79...
                *disp &= 0xFF;
                *disp &= 0xFF;
                *disp |= imm;
                *disp |= imm;
        }
        }
}
}
 
 
 
// 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)
 
{
 
        if (Ra) *Ra = b1 & 0x3f;
 
        if (Rb) *Rb = (b1 >> 6) | ((b2 & 0xf) << 2);
 
        if (Rt) *Rt = ((b2 & 0xF0) >> 4) | (( b3 & 3) << 4);
 
        if (Sg) *Sg = (b3 >> 5) & 7;
 
        if (Sc) *Sc = 1 << ((b3 >> 2) & 3);
 
}
 
 
 
int clsThor::WriteMask(int ad, int sz)
 
{
 
        switch(sz) {
 
        case 0:  return 1 << (ad & 7);
 
        case 1: return 3 << (ad & 6);
 
        case 2: return (ad & 4) ? 0xF0 : 0x0F;
 
        case 3: return 0xFF;
 
        }
 
}
 
 
 
__int64 clsThor::GetSpr(int Sprn)
 
{
 
        __int64 tmp;
 
        int nn;
 
 
 
        if (Sprn < 16) {
 
                return pr[Sprn];
 
        }
 
        else if (Sprn < 32) {
 
                Sprn -= 16;
 
                return ca[Sprn];
 
        }
 
        else if (Sprn < 40) {
 
                return seg_base[Sprn-32];
 
        }
 
        else if (Sprn < 48) {
 
                return seg_limit[Sprn-32];
 
        }
 
        else {
 
                switch(Sprn) {
 
                case 50:        return tick; break;
 
                case 51:        return lc; break;
 
                case 52:
 
                        tmp = 0;
 
                        for (nn = 0; nn < 16; nn++) {
 
                                tmp |= pr[nn] << (nn * 4);
 
                        }
 
                        return tmp;
 
                case 60:        return bir; break;
 
                case 61:
 
                        switch(bir) {
 
                        case 0: return dbad0; break;
 
                        case 1: return dbad1; break;
 
                        case 2: return dbad2; break;
 
                        case 3: return dbad3; break;
 
                        case 4: return dbctrl; break;
 
                        case 5: return dbstat; break;
 
                        }
 
                }
 
        }
 
        return 0xDEADDEADDEADDEAD;
 
}
 
 
 
void clsThor::SetSpr(int Sprn, __int64 val)
 
{
 
        int nn;
 
 
 
        if (Sprn < 16)
 
                pr[Sprn] = val;
 
        else if (Sprn < 32) {
 
                Sprn -= 16;
 
                ca[Sprn] = val;
 
                ca[0] = 0;
 
                ca[15] = pc;
 
        }
 
        else if (Sprn < 40) {
 
                seg_base[Sprn-32] = val & 0xFFFFFFFFFFFFF000LL;
 
        }
 
        else if (Sprn < 48) {
 
                seg_limit[Sprn-32] = val & 0xFFFFFFFFFFFFF000LL;
 
        }
 
        else {
 
                switch(Sprn) {
 
                case 51:        lc = val; break;
 
                case 52:
 
                        for (nn = 0; nn < 16; nn++) {
 
                                pr[nn] = (val >> (nn * 4)) & 0xF;
 
                        }
 
                        break;
 
                case 60:        bir = val & 0xFFLL; break;
 
                case 61:
 
                        switch(bir) {
 
                        case 0: dbad0 = val; break;
 
                        case 1: dbad1 = val; break;
 
                        case 2: dbad2 = val; break;
 
                        case 3: dbad3 = val; break;
 
                        case 4: dbctrl = val; break;
 
                        case 5: dbstat = val; break;
 
                        }
 
                }
 
        }
 
}
 
 
 
int clsThor::GetBit(__int64 a, int b)
 
{
 
        return (a >> b) & 1;
 
}
 
 
 
void clsThor::SetBit(__int64 *a, int b)
 
{
 
        *a |= (1 << b);
 
}
 
 
 
void clsThor::ClearBit(__int64 *a, int 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;
        int Sprn,Sg,Sc;
        int b1, b2, b3, b4;
        int b1, b2, b3, b4;
        int nn;
        int nn;
        __int64 dat;
        __int64 dat;
 
        unsigned __int64 overflow;
 
        unsigned __int64 carry;
 
        unsigned __int64 a,b,res;
 
 
 
        for (nn = 39; nn >= 0; nn--)
 
                pcs[nn] = pcs[nn-1];
 
        pcs[0] = pc;
 
        if (IRQActive()) {
 
                StatusHWI = true;
 
                if (string_pc)
 
                        ca[14] = string_pc;
 
                else
 
                        ca[14] = pc;
 
                pc = ca[12] + (vecno << 4);
 
                ca[15] = pc;
 
        }
        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++;
        for (nn = 39; nn >= 0; nn--)
 
                pcs[nn] = pcs[nn-1];
 
        pcs[0] = pc;
 
        switch (pred) {
        switch (pred) {
        case 0x00:      // BRK instruction
        case 0x00:      // BRK instruction
 
                isRunning = false;
                return;
                return;
        case 0x10:      // NOP
        case 0x10:      // NOP
                return;
                return;
        case 0x20:
        case 0x20:
                imm = ReadByte(pc) << 8;
                imm = ReadByte(pc) << 8;
Line 172... Line 358...
                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 (gp[Ra]==0)
                        if (GetGP(Ra)==0)
                                pr[Pn] |= 1;
                                pr[Pn] |= 1;
                        if ((signed)gp[Ra] < (signed)0)
                        if ((signed)GetGP(Ra) < (signed)0)
                                pr[Pn] |= 2;
                                pr[Pn] |= 2;
                }
                }
                imm_prefix = false;
                imm_prefix = false;
                return;
                return;
        }
        }
        else 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 (gp[Ra]==gp[Rb])
                        if (GetGP(Ra)==GetGP(Rb))
                                pr[Pn] |= 1;
                                pr[Pn] |= 1;
                        if ((signed)gp[Ra] < (signed)gp[Rb])
                        if (GetGP(Ra) < GetGP(Rb))
                                pr[Pn] |= 2;
                                pr[Pn] |= 2;
                        if (gp[Ra] < gp[Rb])
                        if ((unsigned __int64)GetGP(Ra) < (unsigned __int64)GetGP(Rb))
                                pr[Pn] |= 4;
                                pr[Pn] |= 4;
                }
                }
                imm_prefix = false;
                imm_prefix = false;
                return;
                return;
        }
        }
        else 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) {
Line 217... Line 403...
                                if (imm & 0x200)
                                if (imm & 0x200)
                                        imm |= 0xFFFFFFFFFFFFFE00LL;
                                        imm |= 0xFFFFFFFFFFFFFE00LL;
                        }
                        }
                        Pn = opcode & 0x0f;
                        Pn = opcode & 0x0f;
                        pr[Pn] = 0;
                        pr[Pn] = 0;
                        if (gp[Ra]==imm)
                        if (GetGP(Ra)==imm)
                                pr[Pn] |= 1;
                                pr[Pn] |= 1;
                        if ((signed)gp[Ra] < (signed)imm)
                        if (GetGP(Ra) < (signed)imm)
                                pr[Pn] |= 2;
                                pr[Pn] |= 2;
                        if (gp[Ra] < imm)
                        if ((unsigned __int64)GetGP(Ra) < (unsigned __int64)imm)
                                pr[Pn] |= 4;
                                pr[Pn] |= 4;
                }
                }
                imm_prefix = false;
                imm_prefix = false;
                return;
                return;
        }
        }
        else 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)
Line 239... Line 425...
                        pc = pc + disp;
                        pc = pc + disp;
                }
                }
                imm_prefix = false;
                imm_prefix = false;
                return;
                return;
        }
        }
        else {
 
                switch(opcode) {
                switch(opcode) {
                case ADDUI:
 
 
        case _2ADDUI:
                        b1 = ReadByte(pc);
                        b1 = ReadByte(pc);
                        pc++;
                        pc++;
                        b2 = ReadByte(pc);
                        b2 = ReadByte(pc);
                        pc++;
                        pc++;
                        b3 = ReadByte(pc);
                        b3 = ReadByte(pc);
Line 259... Line 445...
                                else {
                                else {
                                        imm = (b3 << 4) | ((b2 >> 4) & 0xF);
                                        imm = (b3 << 4) | ((b2 >> 4) & 0xF);
                                        if (imm & 0x800)
                                        if (imm & 0x800)
                                                imm |= 0xFFFFFFFFFFFFF000LL;
                                                imm |= 0xFFFFFFFFFFFFF000LL;
                                }
                                }
                                gp[Rt] = gp[Ra] + imm;
                        SetGP(Rt,(GetGP(Ra)<<1) + imm);
                                gp[0] = 0;
 
                        }
                        }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case ADDUIS:
        case _4ADDUI:
                        b1 = ReadByte(pc);
                        b1 = ReadByte(pc);
                        pc++;
                        pc++;
                        b2 = ReadByte(pc);
                        b2 = ReadByte(pc);
                        pc++;
                        pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
                        if (ex) {
                        if (ex) {
                                Ra = b1 & 0x3f;
                                Ra = b1 & 0x3f;
                                Rt = Ra;
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
                                if (imm_prefix) {
                                if (imm_prefix) {
                                        imm |= ((b2 << 2)&0xFC) | ((b1 >> 6) & 0x3);
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
                                }
                                }
                                else {
                                else {
                                        imm = ((b2 << 2)&0x3FC) | ((b1 >> 6) & 0x3);
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
                                        if (imm & 0x200)
                                if (imm & 0x800)
                                                imm |= 0xFFFFFFFFFFFFFE00LL;
                                        imm |= 0xFFFFFFFFFFFFF000LL;
                                }
                                }
                                gp[Rt] = gp[Ra] + imm;
                        SetGP(Rt,(GetGP(Ra)<<2) + imm);
                                gp[0] = 0;
 
                        }
                        }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case JSR:
        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++;
                        b4 = ReadByte(pc);
 
                        pc++;
 
                        if (ex) {
                        if (ex) {
                                Ct = b1 & 0x0F;
                        Ra = b1 & 0x3f;
                                Cr = (b1 & 0xF0) >> 4;
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
                                if (Ct != 0)
 
                                        ca[Ct] = pc;
 
                                disp = (b3 << 16) | (b2 << 8) | b1;
 
                                if (disp & 0x800000)
 
                                        disp |= 0xFFFFFFFFFF000000LL;
 
                                if (imm_prefix) {
                                if (imm_prefix) {
                                        disp &= 0xFF;
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
                                        disp |= imm;
 
                                }
                                }
                                ca[15] = pc;
                        else {
                                pc = disp + ca[Cr];
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
 
                                if (imm & 0x800)
 
                                        imm |= 0xFFFFFFFFFFFFF000LL;
                        }
                        }
 
                        SetGP(Rt,(GetGP(Ra)<<3) + imm);
 
                }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case JSRS:
        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) {
                                Ct = b1 & 0x0F;
                        Ra = b1 & 0x3f;
                                Cr = (b1 & 0xF0) >> 4;
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
                                ca[Ct] = pc;
 
                                ca[0] = 0;
 
                                disp = (b3 << 8) | b2;
 
                                if (disp & 0x8000)
 
                                        disp |= 0xFFFFFFFFFFFF0000LL;
 
                                if (imm_prefix) {
                                if (imm_prefix) {
                                        disp &= 0xFFLL;
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
                                        disp |= imm;
 
                                }
                                }
                                ca[15] = pc;
                        else {
                                pc = disp + ca[Cr] - 5;
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
 
                                if (imm & 0x800)
 
                                        imm |= 0xFFFFFFFFFFFFF000LL;
                        }
                        }
 
                        SetGP(Rt,(GetGP(Ra)<<4) + imm);
 
                }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case JSRR:
        /* ToDo: add overflow exception */
 
        case ADDI:
                        b1 = ReadByte(pc);
                        b1 = ReadByte(pc);
                        pc++;
                        pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
                        if (ex) {
                        if (ex) {
                                Ct = b1 & 0x0F;
                        Ra = b1 & 0x3f;
                                Cr = (b1 & 0xF0) >> 4;
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
                                if (Ct != 0)
 
                                        ca[Ct] = pc;
 
                                disp = 0;
 
                                if (imm_prefix) {
                                if (imm_prefix) {
                                        disp &= 0xFF;
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
                                        disp |= imm;
 
                                }
                                }
                                ca[15] = pc;
                        else {
                                pc = disp + ca[Cr];
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
 
                                if (imm & 0x800)
 
                                        imm |= 0xFFFFFFFFFFFFF000LL;
 
                        }
 
                        a = GetGP(Ra);
 
                        b = imm;
 
                        res = a + b;
 
                        // overflow = 
 
                        SetGP(Rt,res);
                        }
                        }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case LDIS:
        case ADDUI:
                        b1 = ReadByte(pc);
                        b1 = ReadByte(pc);
                        pc++;
                        pc++;
                        b2 = ReadByte(pc);
                        b2 = ReadByte(pc);
                        pc++;
                        pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
                        if (ex) {
                        if (ex) {
                                Sprn = b1 & 0x3f;
                        Ra = b1 & 0x3f;
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
                                if (imm_prefix) {
                                if (imm_prefix) {
                                        imm |= ((b2 << 2) & 0xFF) | ((b1 >> 6) & 3);
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
                                }
                                }
                                else {
                                else {
                                        imm = ((b2 << 2) & 0x3FF) | ((b1 >> 6) & 3);
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
                                        if (imm & 0x200)
                                if (imm & 0x800)
                                                imm |= 0xFFFFFFFFFFFFFE00LL;
                                        imm |= 0xFFFFFFFFFFFFF000LL;
                                }
                                }
                                if (Sprn < 16) {
                        SetGP(Rt,GetGP(Ra) + imm);
                                        pr[Sprn] = imm & 0xF;
 
                                }
                                }
                                else if (Sprn < 32) {
 
                                        ca[Sprn-16] = imm;
 
                                        ca[0] = 0;
 
                                        ca[15] = pc;
                                        ca[15] = pc;
                                }
 
                                else if (Sprn < 40) {
 
                                        seg_base[Sprn-32] = imm & 0xFFFFFFFFFFFFF000LL;
 
                                }
 
                                else if (Sprn < 48) {
 
                                        seg_limit[Sprn-40] = imm & 0xFFFFFFFFFFFFF000LL;
 
                                }
 
                                else {
 
                                        switch(Sprn) {
 
                                        case 51:        lc = imm; break;
 
                                        case 52:
 
                                                for (nn = 0; nn < 16; nn++) {
 
                                                        pr[nn] = (imm >> (nn * 4)) & 0xF;
 
                                                }
 
                                                break;
 
                                        case 60:        bir = imm & 0xFFLL; break;
 
                                        case 61:
 
                                                switch(bir) {
 
                                                case 0: dbad0 = imm; break;
 
                                                case 1: dbad1 = imm; break;
 
                                                case 2: dbad2 = imm; break;
 
                                                case 3: dbad3 = imm; break;
 
                                                case 4: dbctrl = imm; break;
 
                                                case 5: dbstat = imm; break;
 
                                                }
 
                                        }
 
                                }
 
                        }
 
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case LDI:
        case ADDUIS:
                        b1 = ReadByte(pc);
                        b1 = ReadByte(pc);
                        pc++;
                        pc++;
                        b2 = ReadByte(pc);
                        b2 = ReadByte(pc);
                        pc++;
                        pc++;
                        if (ex) {
                        if (ex) {
                                Rt = b1 & 0x3f;
                        Ra = b1 & 0x3f;
 
                        Rt = Ra;
                                if (imm_prefix) {
                                if (imm_prefix) {
                                        imm |= ((b2 << 2) & 0xFF) | ((b1 >> 6) & 3);
                                imm |= ((b2 << 2)&0xFC) | ((b1 >> 6) & 0x3);
                                }
                                }
                                else {
                                else {
                                        imm = ((b2 << 2) & 0x3FF) | ((b1 >> 6) & 3);
                                imm = ((b2 << 2)&0x3FC) | ((b1 >> 6) & 0x3);
                                        if (imm & 0x200)
                                        if (imm & 0x200)
                                                imm |= 0xFFFFFFFFFFFFFE00LL;
                                                imm |= 0xFFFFFFFFFFFFFE00LL;
                                }
                                }
                                gp[Rt] = imm;
                        SetGP(Rt,GetGP(Ra) + imm);
                        }
                        }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case LH:
        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;
                                Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
                                Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
                                dRn(b1,b2,b3,&Ra,&Sg,&disp);
                        if (imm_prefix) {
                                ea = (unsigned __int64) disp + seg_base[Sg] + gp[Ra];
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
                                dat = system1->Read(ea);
                        }
                                if (ea & 4)
                        else {
                                        dat = (dat >> 32);
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
                                if (ea & 2)
                                if (imm & 0x800)
                                        dat = (dat >> 16);
                                        imm |= 0xFFFFFFFFFFFFF000LL;
                                dat &= 0xFFFF;
                        }
                                if (dat & 0x8000LL)
                        SetGP(Rt,GetGP(Ra) & imm);
                                        dat |= 0xFFFFFFFFFFFF0000LL;
 
                                gp[Rt] = dat;
 
                                gp[0] = 0;
                                gp[0] = 0;
                        }
                        }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case BITI:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        unsigned __int64 res;
 
                        Ra = b1 & 0x3f;
 
                        Pn = ((b2 & 0x3) << 2) | (( b1 >> 6) & 3);
 
                        if (imm_prefix) {
 
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
 
                        }
 
                        else {
 
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
 
                                if (imm & 0x800)
 
                                        imm |= 0xFFFFFFFFFFFFF000LL;
 
                        }
 
                        res = GetGP(Ra) & imm;
 
                        pr[Pn] = 0;
 
                        if (res == 0)
 
                                pr[Pn] |= 1;
 
                        if (res & 0x8000000000000000LL)
 
                                pr[Pn] |= 2;
 
                        if (res & 1)
 
                                pr[Pn] |= 4;
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case CLI:
 
                if (ex) {
 
                        imcd = 3;
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                break;
 
 
 
        case DIVI:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ra = b1 & 0x3f;
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        if (imm_prefix) {
 
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
 
                        }
 
                        else {
 
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
 
                                if (imm & 0x800)
 
                                        imm |= 0xFFFFFFFFFFFFF000LL;
 
                        }
 
                        SetGP(Rt,GetGP(Ra) / imm);
 
                        gp[0] = 0;
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case DIVUI:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ra = b1 & 0x3f;
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        if (imm_prefix) {
 
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
 
                        }
 
                        else {
 
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
 
                                if (imm & 0x800)
 
                                        imm |= 0xFFFFFFFFFFFFF000LL;
 
                        }
 
                        SetGP(Rt,(unsigned __int64)GetGP(Ra) / (unsigned __int64)imm);
 
                        gp[0] = 0;
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case EORI:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ra = b1 & 0x3f;
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        if (imm_prefix) {
 
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
 
                        }
 
                        else {
 
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
 
                                if (imm & 0x800)
 
                                        imm |= 0xFFFFFFFFFFFFF000LL;
 
                        }
 
                        SetGP(Rt,GetGP(Ra) ^ imm);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case INT:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ct = b1 & 0xF;
 
                        Cr = b1 >> 4;
 
                        // Normal INT stores the address of the interrupted instruction.
 
                        // However if the target register indicates a system call or
 
                        // debug interrupt, then the address of the following
 
                        // instruction is stored.
 
                        if (!(Ct==11 || Ct==13))
 
                                pc -= 4;
 
                        ca[Ct] = pc;
 
                        ca[0] = 0;
 
                        pc = (b2 << 4) + ca[Cr];
 
                        if (Ct==11)
 
                                StatusDBG = true;
 
                        else if (Ct==13) {
 
                                if (StatusEXL < 255)
 
                                        StatusEXL++;
 
                        }
 
                        else
 
                                StatusHWI = true;
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case JSR:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                b4 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ct = b1 & 0x0F;
 
                        Cr = (b1 & 0xF0) >> 4;
 
                        if (Ct != 0)
 
                                ca[Ct] = pc;
 
                        disp = (b4 << 16) | (b3 << 8) | b2;
 
                        if (disp & 0x800000)
 
                                disp |= 0xFFFFFFFFFF000000LL;
 
                        if (imm_prefix) {
 
                                disp &= 0xFF;
 
                                disp |= imm;
 
                        }
 
                        if (Cr==15)
 
                                pc = disp + pc - 6;
 
                        else
 
                                pc = disp + ca[Cr];
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case JSRI:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        int Sz;
 
                        unsigned __int64 dat;
 
                        Ra = b1 & 0x3f;
 
                        Ct = (b1 >> 6) | ((b2 << 2) & 0xf);
 
                        Sz = (b2 & 0xC) >> 2;
 
                        Sg = (b3 >> 5);
 
                        if (Ct != 0)
 
                                ca[Ct] = pc;
 
                        disp = ((b3 & 0x1f) << 4) | (b2 >> 4);
 
                        if (disp & 0x100)
 
                                disp |= 0xFFFFFFFFFFFFFE00LL;
 
                        if (imm_prefix) {
 
                                disp &= 0xFF;
 
                                disp |= imm;
 
                        }
 
                        switch(Sz) {
 
                        case 1:
 
                                dat = ReadChar(disp + seg_base[Sg] + GetGP(Ra)*2);
 
                                dat &= 0xFFFFLL;
 
                                pc = pc & 0xFFFF0000;
 
                                pc |= dat;
 
                                break;
 
                        case 2:
 
                                dat = ReadHalf(disp + seg_base[Sg] + GetGP(Ra)*4);
 
                                dat &= 0xFFFFFFFFLL;
 
                                pc = dat;
 
                                break;
 
                        case 3:
 
                                dat = Read(disp + seg_base[Sg] + GetGP(Ra)*8);
 
                                pc = dat;
 
                                break;
 
                        }
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case JSRS:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ct = b1 & 0x0F;
 
                        Cr = (b1 & 0xF0) >> 4;
 
                        ca[Ct] = pc;
 
                        ca[0] = 0;
 
                        disp = (b3 << 8) | b2;
 
                        if (disp & 0x8000)
 
                                disp |= 0xFFFFFFFFFFFF0000LL;
 
                        if (imm_prefix) {
 
                                disp &= 0xFFLL;
 
                                disp |= imm;
 
                        }
 
                        if (Cr==15)
 
                                pc = disp + pc - 5;
 
                        else
 
                                pc = disp + ca[Cr];
 
                        if (Ct != 0)
 
                                sub_depth++;
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case JSRR:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ct = b1 & 0x0F;
 
                        Cr = (b1 & 0xF0) >> 4;
 
                        if (Ct != 0)
 
                                ca[Ct] = pc;
 
                        disp = 0;
 
                        if (imm_prefix) {
 
                                disp &= 0xFF;
 
                                disp |= imm;
 
                        }
 
                        pc = disp + ca[Cr];
 
                        if (Ct != 0)
 
                                sub_depth++;
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case LB:
 
        case LVB:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
 
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
 
                        dat = system1->Read(ea);
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        if (ea & 2)
 
                                dat = (dat >> 16);
 
                        if (ea & 1)
 
                                dat = (dat >> 8);
 
                        dat &= 0xFFLL;
 
                        if (dat & 0x80LL)
 
                                dat |= 0xFFFFFFFFFFFFFF00LL;
 
                        SetGP(Rt,dat);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case LBU:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
 
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
 
                        dat = system1->Read(ea);
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        if (ea & 2)
 
                                dat = (dat >> 16);
 
                        if (ea & 1)
 
                                dat = (dat >> 8);
 
                        dat &= 0xFFLL;
 
                        SetGP(Rt,dat);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case LBX:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
 
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
 
                        dat = system1->Read(ea);
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        if (ea & 2)
 
                                dat = (dat >> 16);
 
                        if (ea & 1)
 
                                dat = (dat >> 8);
 
                        dat &= 0xFFLL;
 
                        if (dat & 0x80LL)
 
                                dat |= 0xFFFFFFFFFFFFFF00LL;
 
                        SetGP(Rt,dat);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case LBUX:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
 
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
 
                        dat = system1->Read(ea);
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        if (ea & 2)
 
                                dat = (dat >> 16);
 
                        if (ea & 1)
 
                                dat = (dat >> 8);
 
                        dat &= 0xFFLL;
 
                        SetGP(Rt,dat);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case LC:
 
        case LVC:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
 
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
 
                        dat = system1->Read(ea);
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        if (ea & 2)
 
                                dat = (dat >> 16);
 
                        dat &= 0xFFFF;
 
                        if (dat & 0x8000LL)
 
                                dat |= 0xFFFFFFFFFFFF0000LL;
 
                        SetGP(Rt,dat);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case LCX:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
 
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
 
                        dat = system1->Read(ea);
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        if (ea & 2)
 
                                dat = (dat >> 16);
 
                        dat &= 0xFFFF;
 
                        if (dat & 0x8000LL)
 
                                dat |= 0xFFFFFFFFFFFF0000LL;
 
                        SetGP(Rt,dat);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case LCU:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
 
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
 
                        dat = system1->Read(ea);
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        if (ea & 2)
 
                                dat = (dat >> 16);
 
                        dat &= 0xFFFFLL;
 
                        SetGP(Rt,dat);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case LCUX:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
 
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
 
                        dat = system1->Read(ea);
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        if (ea & 2)
 
                                dat = (dat >> 16);
 
                        dat &= 0xFFFF;
 
                        SetGP(Rt,dat);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case LDIS:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Sprn = b1 & 0x3f;
 
                        if (imm_prefix) {
 
                                imm |= ((b2 << 2) & 0xFF) | ((b1 >> 6) & 3);
 
                        }
 
                        else {
 
                                imm = ((b2 << 2) & 0x3FF) | ((b1 >> 6) & 3);
 
                                if (imm & 0x200)
 
                                        imm |= 0xFFFFFFFFFFFFFE00LL;
 
                        }
 
                        if (Sprn < 16) {
 
                                pr[Sprn] = imm & 0xF;
 
                        }
 
                        else if (Sprn < 32) {
 
                                ca[Sprn-16] = imm;
 
                                ca[0] = 0;
 
                                ca[15] = pc;
 
                        }
 
                        else if (Sprn < 40) {
 
                                seg_base[Sprn-32] = imm & 0xFFFFFFFFFFFFF000LL;
 
                        }
 
                        else if (Sprn < 48) {
 
                                seg_limit[Sprn-40] = imm & 0xFFFFFFFFFFFFF000LL;
 
                        }
 
                        else {
 
                                switch(Sprn) {
 
                                case 51:        lc = imm; break;
 
                                case 52:
 
                                        for (nn = 0; nn < 16; nn++) {
 
                                                pr[nn] = (imm >> (nn * 4)) & 0xF;
 
                                        }
 
                                        break;
 
                                case 60:        bir = imm & 0xFFLL; break;
 
                                case 61:
 
                                        switch(bir) {
 
                                        case 0: dbad0 = imm; break;
 
                                        case 1: dbad1 = imm; break;
 
                                        case 2: dbad2 = imm; break;
 
                                        case 3: dbad3 = imm; break;
 
                                        case 4: dbctrl = imm; break;
 
                                        case 5: dbstat = imm; break;
 
                                        }
 
                                }
 
                        }
 
                }
 
                imm_prefix = false;
 
                ca[15] = pc;
 
                return;
 
 
 
        case LDI:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Rt = b1 & 0x3f;
 
                        if (imm_prefix) {
 
                                imm |= ((b2 << 2) & 0xFF) | ((b1 >> 6) & 3);
 
                        }
 
                        else {
 
                                imm = ((b2 << 2) & 0x3FF) | ((b1 >> 6) & 3);
 
                                if (imm & 0x200)
 
                                        imm |= 0xFFFFFFFFFFFFFE00LL;
 
                        }
 
                        SetGP(Rt,imm);
 
                }
 
                imm_prefix = false;
 
                ca[15] = pc;
 
                return;
 
 
 
        case LH:
 
        case LVH:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
 
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
 
                        dat = system1->Read(ea);
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        dat &= 0xFFFFFFFFLL;
 
                        if (dat & 0x80000000LL)
 
                                dat |= 0xFFFFFFFF00000000LL;
 
                        SetGP(Rt,dat);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case LHX:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
 
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
 
                        dat = system1->Read(ea);
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        dat &= 0xFFFFFFFFLL;
 
                        if (dat & 0x80000000LL)
 
                                dat |= 0xFFFFFFFF00000000LL;
 
                        SetGP(Rt,dat);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case LHU:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
 
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
 
                        dat = system1->Read(ea);
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        dat &= 0xFFFFFFFFLL;
 
                        SetGP(Rt,dat);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case LHUX:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
 
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
 
                        dat = system1->Read(ea);
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        dat &= 0xFFFFFFFFLL;
 
                        SetGP(Rt,dat);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case LLA:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
 
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
 
                        SetGP(Rt,ea);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case LOGIC:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ra = b1 & 0x3f;
 
                        Rb = ((b2 << 2) & 0x3c) | (b1 >> 6);
 
                        Rt = (b2 >> 4) | ((b3 & 0x3) << 4);
 
                        func = b3 >> 2;
 
                        switch(func) {
 
                        case AND:
 
                                SetGP(Rt, GetGP(Ra) & GetGP(Rb));
 
                                break;
 
                        case OR:
 
                                SetGP(Rt, GetGP(Ra) | GetGP(Rb));
 
                                break;
 
                        case EOR:
 
                                SetGP(Rt, GetGP(Ra) ^ GetGP(Rb));
 
                                break;
 
                        case NAND:
 
                                SetGP(Rt, ~(GetGP(Ra) & GetGP(Rb)));
 
                                break;
 
                        case NOR:
 
                                SetGP(Rt, ~(GetGP(Ra) | GetGP(Rb)));
 
                                break;
 
                        case ENOR:
 
                                SetGP(Rt, ~(GetGP(Ra) ^ GetGP(Rb)));
 
                                break;
 
                        case ANDC:
 
                                SetGP(Rt, GetGP(Ra) & ~GetGP(Rb));
 
                                break;
 
                        case ORC:
 
                                SetGP(Rt, GetGP(Ra) | ~GetGP(Rb));
 
                                break;
 
                        }
 
                }
 
                ca[15] = pc;
 
                imm_prefix = 0;
 
                return;
 
 
 
        case LOOP:
 
                disp = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        if (disp & 0x80LL)
 
                                disp |= 0xFFFFFFFFFFFFFF00LL;
 
                        if (lc > 0) {
 
                                lc--;
 
                                pc = pc + disp;
 
                        }
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case LW:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
 
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
 
                        dat = system1->Read(ea);
 
                        /*
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        if (ea & 2)
 
                                dat = (dat >> 16);
 
                        */
 
                        SetGP(Rt,dat);
 
                }
 
                imm_prefix = false;
 
                ca[15] = pc;
 
                return;
 
 
 
        case LVWAR:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
 
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
 
                        dat = system1->Read(ea,1);
 
                        /*
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        if (ea & 2)
 
                                dat = (dat >> 16);
 
                        */
 
                        SetGP(Rt,dat);
 
                }
 
                imm_prefix = false;
 
                ca[15] = pc;
 
                return;
 
 
 
        case LWS:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
 
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
 
                        dat = system1->Read(ea);
 
                        /*
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        if (ea & 2)
 
                                dat = (dat >> 16);
 
                        if (ea & 1)
 
                                dat = (dat >> 8);
 
                        */
 
                        SetSpr(Rt, dat);
 
                }
 
                imm_prefix = false;
 
                ca[15] = pc;
 
                return;
 
 
 
        case LWX:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
 
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
 
                        dat = system1->Read(ea);
 
                        /*
 
                        if (ea & 4)
 
                                dat = (dat >> 32);
 
                        if (ea & 2)
 
                                dat = (dat >> 16);
 
                        */
 
                        SetGP(Rt,dat);
 
                }
 
                imm_prefix = false;
 
                ca[15] = pc;
 
                return;
 
 
 
        // Memory synchronization primitives are not useful to the software ISA
 
        // emulator. They are treated like NOP's.
 
        case MEMSB:
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                break;
 
 
 
        case MEMDB:
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                break;
 
 
 
        case MFSPR:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Sprn = b1 & 0x3f;
 
                        Rt = ((b2 & 0xF) << 2) | ((b1 >> 6) & 3);
 
                        SetGP(Rt,GetSpr(Sprn));
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case MODI:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ra = b1 & 0x3f;
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        if (imm_prefix) {
 
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
 
                        }
 
                        else {
 
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
 
                                if (imm & 0x800)
 
                                        imm |= 0xFFFFFFFFFFFFF000LL;
 
                        }
 
                        SetGP(Rt,GetGP(Ra) % imm);
 
                        gp[0] = 0;
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case MODUI:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ra = b1 & 0x3f;
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        if (imm_prefix) {
 
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
 
                        }
 
                        else {
 
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
 
                                if (imm & 0x800)
 
                                        imm |= 0xFFFFFFFFFFFFF000LL;
 
                        }
 
                        SetGP(Rt,(unsigned __int64) GetGP(Ra) % (unsigned __int64)imm);
 
                        gp[0] = 0;
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case GRPA7:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ra = b1 & 0x3f;
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        switch(b2 >> 4) {
 
                        case ABS:
 
                                SetGP(Rt, GetGP(Ra) < 0 ? -GetGP(Ra) : GetGP(Ra));
 
                                break;
 
                        case COM:
 
                                SetGP(Rt, ~GetGP(Ra));
 
                                break;
 
                        case MOV:
 
                                SetGP(Rt, GetGP(Ra));
 
                                break;
 
                        case NEG:
 
                                SetGP(Rt, -GetGP(Ra));
 
                                break;
 
                        case NOT:
 
                                SetGP(Rt, !GetGP(Ra));
 
                                break;
 
                        case SGN:
 
                                SetGP(Rt, (GetGP(Ra) == 0) ? 0 : (GetGP(Ra) < 0) ? -1 : 1);
 
                                break;
 
                        case SXB:
 
                                dat = GetGP(Ra);
 
                                if (dat & 0x80LL)
 
                                        dat |= 0xFFFFFFFFFFFFFF80LL;
 
                                SetGP(Rt,dat);
 
                                break;
 
                        case SXC:
 
                                dat = GetGP(Ra);
 
                                if (dat & 0x8000LL)
 
                                        dat |= 0xFFFFFFFFFFFF8000LL;
 
                                SetGP(Rt,dat);
 
                                break;
 
                        case SXH:
 
                                dat = GetGP(Ra);
 
                                if (dat & 0x80000000LL)
 
                                        dat |= 0xFFFFFFFF80000000LL;
 
                                SetGP(Rt,dat);
 
                                break;
 
                        case ZXB:
 
                                dat = GetGP(Ra);
 
                                dat &= 0xFFLL;
 
                                SetGP(Rt,dat);
 
                                break;
 
                        case ZXC:
 
                                dat = GetGP(Ra);
 
                                dat &= 0xFFFFLL;
 
                                SetGP(Rt,dat);
 
                                break;
 
                        case ZXH:
 
                                dat = GetGP(Ra);
 
                                dat &= 0xFFFFFFFFLL;
 
                                SetGP(Rt,dat);
 
                                break;
 
                        }
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case MTSPR:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ra = b1 & 0x3f;
 
                        Sprn = ((b2 & 0xF) << 2) | ((b1 >> 6) & 3);
 
                        SetSpr(Sprn, GetGP(Ra));
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case MULI:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ra = b1 & 0x3f;
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        if (imm_prefix) {
 
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
 
                        }
 
                        else {
 
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
 
                                if (imm & 0x800)
 
                                        imm |= 0xFFFFFFFFFFFFF000LL;
 
                        }
 
                        SetGP(Rt,GetGP(Ra) * imm);
 
                        gp[0] = 0;
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case MULUI:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ra = b1 & 0x3f;
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        if (imm_prefix) {
 
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
 
                        }
 
                        else {
 
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
 
                                if (imm & 0x800)
 
                                        imm |= 0xFFFFFFFFFFFFF000LL;
 
                        }
 
                        SetGP(Rt,(unsigned __int64)GetGP(Ra) * (unsigned __int64)imm);
 
                        gp[0] = 0;
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case ORI:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ra = b1 & 0x3f;
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        if (imm_prefix) {
 
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
 
                        }
 
                        else {
 
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
 
                                if (imm & 0x800)
 
                                        imm |= 0xFFFFFFFFFFFFF000LL;
 
                        }
 
                        SetGP(Rt,GetGP(Ra) | imm);
 
                        gp[0] = 0;
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case R1:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ra = b1 & 0x3f;
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        switch(b2 >> 4) {
 
                        case CPUID:
 
                                switch(Ra) {
 
                                case 0:  SetGP(Rt,0x0002LL); break;      // Processor ID
 
                                case 2: SetGP(Rt,0x4e4F5254494E4966LL); break;  // "Finitron"
 
                                case 3: SetGP(Rt,0x00LL); break;
 
                                case 4: SetGP(Rt,0x36346249547373LL); break;    // 64BitSS
 
                                case 5: SetGP(Rt,0x00LL); break;
 
                                case 6: SetGP(Rt,0x524F4A74LL); break;  // "Thor"
 
                                case 7: SetGP(Rt, 0x00LL); break;
 
                                case 8: SetGP(Rt, 0x316ELL); break;             // "M1"
 
                                case 9: SetGP(Rt, 0x1235LL); break;
 
                                case 10:        SetGP(Rt,0x00LL); break;
 
                                case 11:        SetGP(Rt,0x0000400000008000LL); break;  // 16k,32k cache size
 
                                default:        SetGP(Rt,0x00LL); break;
 
                                }
 
                        case REDOR:     SetGP(Rt, GetGP(Ra) != 0); break;
 
                        case REDAND:    SetGP(Rt, GetGP(Ra)==0xFFFFFFFFFFFFFFFFLL); break;
 
                        case PAR:       break; /* ToDo */
 
                        }
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case P1:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        int bita,bitb,bitt;
 
                        Ra = (b1 & 0x3f) >> 2;
 
                        bita = b1 & 3;
 
                        a = GetBit(pr[Ra],bita);
 
                        Rb = (b2 & 0xf);
 
                        bitb = b1 >> 6;
 
                        b = GetBit(pr[Rb],bitb);
 
                        Rt = (b2 >> 6) | ((b3 & 3) << 2);
 
                        bitt = (b2 >> 4) & 3;
 
                        switch(b3 >> 2) {
 
                        case PAND:
 
                                res = a & b;
 
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
 
                                break;
 
                        case POR:
 
                                res = a | b;
 
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
 
                                break;
 
                        case PEOR:
 
                                res = a ^ b;
 
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
 
                                break;
 
                        case PNAND:
 
                                res = !(a & b);
 
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
 
                                break;
 
                        case PNOR:
 
                                res = !(a | b);
 
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
 
                                break;
 
                        case PENOR:
 
                                res = !(a ^ b);
 
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
 
                                break;
 
                        case PANDC:
 
                                res = a & !b;
 
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
 
                                break;
 
                        case PORC:
 
                                res = a | !b;
 
                                if (res) SetBit((__int64 *)&pr[Rt],bitt); else ClearBit((__int64 *)&pr[Rt],bitt);
 
                                break;
 
                        }
 
                }
 
                ca[15] = pc;
 
                imm_prefix = 0;
 
                return;
 
 
 
        case RR:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Ra = b1 & 0x3f;
 
                        Rb = ((b2 << 2) & 0x3c) | (b1 >> 6);
 
                        Rt = (b2 >> 4) | ((b3 & 0x3) << 4);
 
                        func = b3 >> 2;
 
                        switch(func) {
 
                        case ADD:
 
                        case ADDU:
 
                                SetGP(Rt,(unsigned __int64)GetGP(Ra) + (unsigned __int64)GetGP(Rb));
 
                                break;
 
                        case SUB:
 
                        case SUBU:
 
                                SetGP(Rt,(unsigned __int64)GetGP(Ra) - (unsigned __int64)GetGP(Rb));
 
                                break;
 
                        case MUL:
 
                                SetGP(Rt,GetGP(Ra) * GetGP(Rb));
 
                                break;
 
                        case DIV:
 
                                SetGP(Rt,GetGP(Ra) / GetGP(Rb));
 
                                break;
 
                        case MOD:
 
                                SetGP(Rt,GetGP(Ra) % GetGP(Rb));
 
                                break;
 
                        case MULU:
 
                                SetGP(Rt,(unsigned __int64)GetGP(Ra) * (unsigned __int64)GetGP(Rb));
 
                                break;
 
                        case DIVU:
 
                                SetGP(Rt,(unsigned __int64)GetGP(Ra) / (unsigned __int64)GetGP(Rb));
 
                                break;
 
                        case MODU:
 
                                SetGP(Rt,(unsigned __int64)GetGP(Ra) % (unsigned __int64)GetGP(Rb));
 
                                break;
 
                        case _2ADDU:
 
                                SetGP(Rt,(GetGP(Ra) << 1) + GetGP(Rb));
 
                                break;
 
                        case _4ADDU:
 
                                SetGP(Rt,(GetGP(Ra) << 2) + GetGP(Rb));
 
                                break;
 
                        case _8ADDU:
 
                                SetGP(Rt,(GetGP(Ra) << 3) + GetGP(Rb));
 
                                break;
 
                        case _16ADDU:
 
                                SetGP(Rt,(GetGP(Ra) << 4) + GetGP(Rb));
 
                                break;
 
                        }
 
                }
 
                ca[15] = pc;
 
                imm_prefix = 0;
 
                return;
 
 
 
        case RTD:
 
                if (ex) {
 
                        StatusDBG = false;
 
                        pc = ca[11];
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case RTE:
 
                if (ex) {
 
                        if (StatusEXL > 0)
 
                                StatusEXL--;
 
                        pc = ca[13];
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        case RTI:
 
                if (ex) {
 
                        im = 0;
 
                        StatusHWI = false;
 
                        pc = ca[14];
 
                }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case LLA:
        case RTS:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                if (ex) {
 
                        Cr = (b1 & 0xF0) >> 4;
 
                        pc = ca[Cr] + (b1 & 0x0F);
 
                        if (sub_depth > 0) sub_depth--;
 
                }
 
                ca[15] = pc;
 
                imm_prefix = 0;
 
                return;
 
 
 
        case RTSQ:
 
                if (ex) {
 
                        pc = ca[1];
 
                        if (sub_depth > 0) sub_depth--;
 
                }
 
                ca[15] = pc;
 
                imm_prefix = 0;
 
                return;
 
 
 
        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) {
                                Rt = ((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] + gp[Ra];
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
                                gp[Rt] = ea;
                        system1->Write(ea,GetGP(Rb),(0x1 << (ea & 7)) & 0xFF);
                                gp[0] = 0;
 
                        }
                        }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case LOGIC:
        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) {
                                Ra = b1 & 0x3f;
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
                                Rb = ((b2 << 2) & 0x3c) | (b1 >> 6);
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
                                Rt = (b2 >> 4) | ((b3 & 0x3) << 4);
                        system1->Write(ea,GetGP(Rt),(0x1 << (ea & 7)) & 0xFF);
                                func = b3 >> 2;
 
                                switch(func) {
 
                                case OR:
 
                                        gp[Rt] = gp[Ra] | gp[Rb];
 
                                        gp[0] = 0;
 
                                        break;
 
                                }
 
                        }
                        }
                        imm_prefix = 0;
                ca[15] = pc;
 
                imm_prefix = false;
                        return;
                        return;
 
 
                case LOOP:
        case SC:
                        disp = ReadByte(pc);
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
                        pc++;
                        pc++;
                        if (ex) {
                        if (ex) {
                                if (disp & 0x80LL)
                        Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
                                        disp |= 0xFFFFFFFFFFFFFF00LL;
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
                                if (lc > 0) {
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
                                        lc--;
                        system1->Write(ea,GetGP(Rb),(0x3 << (ea & 7)) & 0xFF);
                                        pc = pc + disp;
 
                                }
 
                        }
                        }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case MFSPR:
        case SCX:
                        b1 = ReadByte(pc);
                        b1 = ReadByte(pc);
                        pc++;
                        pc++;
                        b2 = ReadByte(pc);
                        b2 = ReadByte(pc);
                        pc++;
                        pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
                        if (ex) {
                        if (ex) {
                                Sprn = b1 & 0x3f;
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
                                Rt = ((b2 & 0xF) << 2) | ((b1 >> 6) & 3);
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
                                if (Sprn < 16) {
                        system1->Write(ea,GetGP(Rt),(0x3 << (ea & 7)) & 0xFF);
                                        gp[Rt] = pr[Sprn];
 
                                        gp[0] = 0;
 
                                }
 
                                else if (Sprn < 32) {
 
                                        Sprn -= 16;
 
                                        gp[Rt] = ca[Sprn];
 
                                        gp[0] = 0;
 
                                }
 
                                else if (Sprn < 40) {
 
                                        gp[Rt] = seg_base[Sprn-32];
 
                                        gp[0] = 0;
 
                                }
 
                                else if (Sprn < 48) {
 
                                        gp[Rt] = seg_limit[Sprn-32];
 
                                        gp[0] = 0;
 
                                }
                                }
                                else {
                ca[15] = pc;
                                        switch(Sprn) {
                imm_prefix = false;
                                        case 50:        gp[Rt] = tick; gp[0] = 0; break;
                return;
                                        case 51:        gp[Rt] = lc; gp[0] = 0; break;
 
                                        case 52:
        case SEI:
                                                gp[Rt] = 0;
                if (ex) {
                                                for (nn = 0; nn < 16; nn++) {
                        im = 1;
                                                        gp[Rt] |= pr[nn] << (nn * 4);
 
                                                }
                                                }
                                                gp[0] = 0;
                ca[15] = pc;
 
                imm_prefix = false;
                                                break;
                                                break;
                                        case 60:        gp[Rt] = bir; gp[0] = 0; break;
 
                                        case 61:
        case SH:
                                                switch(bir) {
                b1 = ReadByte(pc);
                                                case 0: gp[Rt] = dbad0; gp[0] = 0; break;
                pc++;
                                                case 1: gp[Rt] = dbad1;  gp[0] = 0; break;
                b2 = ReadByte(pc);
                                                case 2: gp[Rt] = dbad2;  gp[0] = 0; break;
                pc++;
                                                case 3: gp[Rt] = dbad3;  gp[0] = 0; break;
                b3 = ReadByte(pc);
                                                case 4: gp[Rt] = dbctrl;  gp[0] = 0; break;
                pc++;
                                                case 5: gp[Rt] = dbstat;  gp[0] = 0; break;
                if (ex) {
                                                }
                        Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
                                        }
                        dRn(b1,b2,b3,&Ra,&Sg,&disp);
                                }
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
 
                        system1->Write(ea,GetGP(Rb),(0xF << (ea & 7)) & 0xFF);
                        }
                        }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case MOV:
        case SHX:
                        b1 = ReadByte(pc);
                        b1 = ReadByte(pc);
                        pc++;
                        pc++;
                        b2 = ReadByte(pc);
                        b2 = ReadByte(pc);
                        pc++;
                        pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
                        if (ex) {
                        if (ex) {
                                Ra = b1 & 0x3f;
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
                                Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
                                gp[Rt] = gp[Ra];
                        system1->Write(ea,GetGP(Rt),(0xF << (ea & 7)) & 0xFF);
                                gp[0] = 0;
 
                        }
                        }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case MTSPR:
        case SHIFT:
                        b1 = ReadByte(pc);
                        b1 = ReadByte(pc);
                        pc++;
                        pc++;
                        b2 = ReadByte(pc);
                        b2 = ReadByte(pc);
                        pc++;
                        pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
                        if (ex) {
                        if (ex) {
 
                        unsigned __int64 a,b;
                                Ra = b1 & 0x3f;
                                Ra = b1 & 0x3f;
                                Sprn = ((b2 & 0xF) << 2) | ((b1 >> 6) & 3);
                        Rb = ((b2 << 2) & 0x3c) | (b1 >> 6);
                                if (Sprn < 16)
                        Rt = (b2 >> 4) | ((b3 & 0x3) << 4);
                                        pr[Sprn] = gp[Ra];
                        func = b3 >> 2;
                                else if (Sprn < 32) {
                        switch(func) {
                                        Sprn -= 16;
                        case SHL:
                                        ca[Sprn] = gp[Ra];
                        case SHLU:
                                        ca[0] = 0;
                                SetGP(Rt, GetGP(Ra) << (GetGP(Rb) & 0x3f));
                                        ca[15] = pc;
                                break;
                                }
                        case SHR:
                                else if (Sprn < 40) {
                                SetGP(Rt, GetGP(Ra) >> (GetGP(Rb) & 0x3f));
                                        seg_base[Sprn-32] = gp[Ra] & 0xFFFFFFFFFFFFF000LL;
                                break;
                                }
                        case ROL:
                                else if (Sprn < 48) {
                                a = (unsigned __int64)GetGP(Ra) << (GetGP(Rb) & 0x3f);
                                        seg_limit[Sprn-32] = gp[Ra] & 0xFFFFFFFFFFFFF000LL;
                                b = (unsigned __int64)GetGP(Ra) >> (64-(GetGP(Rb) & 0x3f));
                                }
                                SetGP(Rt, (unsigned __int64)a|b);
                                else {
                                break;
                                        switch(Sprn) {
                        case ROR:
                                        case 51:        lc = gp[Ra]; break;
                                a = (unsigned __int64)GetGP(Ra) >> (GetGP(Rb) & 0x3f);
                                        case 52:
                                b = (unsigned __int64)GetGP(Ra) << (64-(GetGP(Rb) & 0x3f));
                                                for (nn = 0; nn < 16; nn++) {
                                SetGP(Rt, (unsigned __int64)a|b);
                                                        pr[nn] = (gp[Ra] >> (nn * 4)) & 0xF;
                                break;
                                                }
                        case SHLI:
 
                        case SHLUI:
 
                                SetGP(Rt, GetGP(Ra) << Rb);
 
                                break;
 
                        case SHRI:
 
                                SetGP(Rt, GetGP(Ra) >> Rb);
 
                                break;
 
                        case SHRUI:
 
                                SetGP(Rt, (unsigned __int64)GetGP(Ra) >> Rb);
 
                                break;
 
                        case ROLI:
 
                                a = (unsigned __int64)GetGP(Ra) << Rb;
 
                                b = (unsigned __int64)GetGP(Ra) >> (64-Rb);
 
                                SetGP(Rt, (unsigned __int64)a|b);
 
                                break;
 
                        case RORI:
 
                                a = (unsigned __int64)GetGP(Ra) >> Rb;
 
                                b = (unsigned __int64)GetGP(Ra) << (64-Rb);
 
                                SetGP(Rt, (unsigned __int64)a|b);
                                                break;
                                                break;
                                        case 60:        bir = gp[Ra] & 0xFFLL; break;
 
                                        case 61:
 
                                                switch(bir) {
 
                                                case 0: dbad0 = gp[Ra]; break;
 
                                                case 1: dbad1 = gp[Ra]; break;
 
                                                case 2: dbad2 = gp[Ra]; break;
 
                                                case 3: dbad3 = gp[Ra]; break;
 
                                                case 4: dbctrl = gp[Ra]; break;
 
                                                case 5: dbstat = gp[Ra]; break;
 
                                                }
 
                                        }
 
                                }
                                }
                        }
                        }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case RR:
        // 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.
 
        // So for now, it's a NOP.
 
        case STP:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                return;
 
 
 
        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
                                Ra = b1 & 0x3f;
                                Ra = b1 & 0x3f;
                                Rb = ((b2 << 2) & 0x3c) | (b1 >> 6);
                        Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
                                Rt = (b2 >> 4) | ((b3 & 0x3) << 4);
                        do {
                                func = b3 >> 2;
                                Sg = b3 >> 5;
                                switch(func) {
                                ea = GetGP(Ra) + seg_base[Sg];
                                case _2ADDU:
                                switch((b3 >> 2) & 3) {
                                        gp[Rt] = (gp[Ra] << 1) + gp[Rb];
                                case 0:
                                        gp[0] = 0;
                                        dat = GetGP(Rb) & 0xFFLL;
 
                                        dat = (dat << 56) | (dat << 48) | (dat << 40) | (dat << 32)
 
                                                | (dat << 24) | (dat << 16) | (dat << 8) | dat;
 
                                        SetGP(Ra,GetGP(Ra) + ((b3&16) ? -1 : 1));
 
                                        system1->Write(ea,dat,WriteMask(ea,0),0);
                                        break;
                                        break;
                                case _4ADDU:
                                case 1:
                                        gp[Rt] = (gp[Ra] << 2) + gp[Rb];
                                        dat = GetGP(Rb) & 0xFFFFLL;
                                        gp[0] = 0;
                                        dat = (dat << 48) | (dat << 32)
 
                                                | (dat << 16) | dat;
 
                                        SetGP(Ra,GetGP(Ra) + ((b3&16) ? -2 : 2));
 
                                        system1->Write(ea,dat,WriteMask(ea,1),0);
                                        break;
                                        break;
                                case _8ADDU:
                                case 2:
                                        gp[Rt] = (gp[Ra] << 3) + gp[Rb];
                                        dat = GetGP(Rb) & 0xFFFFFFFFLL;
                                        gp[0] = 0;
                                        dat = (dat << 32) | dat;
 
                                        SetGP(Ra,GetGP(Ra) + ((b3&16) ? -4 : 4));
 
                                        system1->Write(ea,dat,WriteMask(ea,2),0);
                                        break;
                                        break;
                                case _16ADDU:
                                case 3:
                                        gp[Rt] = (gp[Ra] << 4) + gp[Rb];
                                        dat = GetGP(Rb);
                                        gp[0] = 0;
                                        SetGP(Ra,GetGP(Ra) + ((b3&16) ? -8 : 8));
 
                                        system1->Write(ea,dat,WriteMask(ea,3),0);
 
                                        break;
 
                                }
 
                                if (lc==0) {
 
                                        string_pc = 0;
                                        break;
                                        break;
                                }
                                }
 
                                lc--;
 
                        } while (!IRQActive());
                        }
                        }
                        imm_prefix = 0;
                ca[15] = pc;
 
                imm_prefix = false;
                        return;
                        return;
 
 
                case RTS:
        /* ToDo: cause overflow exception */
 
        case SUBI:
                        b1 = ReadByte(pc);
                        b1 = ReadByte(pc);
                        pc++;
                        pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
                        if (ex) {
                        if (ex) {
                                Cr = (b1 & 0xF0) >> 4;
                        Ra = b1 & 0x3f;
                                pc = ca[Cr] + (b1 & 0x0F);
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        if (imm_prefix) {
 
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
                        }
                        }
                        imm_prefix = 0;
                        else {
 
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
 
                                if (imm & 0x800)
 
                                        imm |= 0xFFFFFFFFFFFFF000LL;
 
                        }
 
                        SetGP(Rt,GetGP(Ra) - imm);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
                        return;
                        return;
 
 
                case RTSQ:
        case SUBUI:
 
                b1 = ReadByte(pc);
 
                pc++;
 
                b2 = ReadByte(pc);
 
                pc++;
 
                b3 = ReadByte(pc);
 
                pc++;
                        if (ex) {
                        if (ex) {
                                pc = ca[1];
                        Ra = b1 & 0x3f;
 
                        Rt = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
 
                        if (imm_prefix) {
 
                                imm |= ((b3 << 4)&0xF0) | ((b2 >> 4) & 0xF);
                        }
                        }
                        imm_prefix = 0;
                        else {
 
                                imm = (b3 << 4) | ((b2 >> 4) & 0xF);
 
                                if (imm & 0x800)
 
                                        imm |= 0xFFFFFFFFFFFFF000LL;
 
                        }
 
                        SetGP(Rt,GetGP(Ra) - imm);
 
                }
 
                ca[15] = pc;
 
                imm_prefix = false;
                        return;
                        return;
 
 
                case SB:
        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] + gp[Ra];
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
                                system1->Write(ea,gp[Rb],(0x1 << (ea & 7)) & 0xFF);
                        system1->Write(ea,GetGP(Rb),(0xFF << (ea & 7)) & 0xFF);
                        }
                        }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case SC:
        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] + gp[Ra];
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
                                system1->Write(ea,gp[Rb],(0x3 << (ea & 7)) & 0xFF);
                        system1->Write(ea,GetGP(Rb),(0xFF << (ea & 7)) & 0xFF,1);
                        }
                        }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case SH:
        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] + gp[Ra];
                        ea = (unsigned __int64) disp + seg_base[Sg] + GetGP(Ra);
                                system1->Write(ea,gp[Rb],(0xF << (ea & 7)) & 0xFF);
                        system1->Write(ea,GetSpr(Rb),(0xFF << (ea & 7)) & 0xFF);
                        }
                        }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case SHIFT:
        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) {
                                Ra = b1 & 0x3f;
                        ndx(b1,b2,b3,&Ra,&Rb,&Rt,&Sg,&Sc);
                                Rb = ((b2 << 2) & 0x3c) | (b1 >> 6);
                        ea = (unsigned __int64) seg_base[Sg] + GetGP(Ra) + GetGP(Rb) * Sc;
                                Rt = (b2 >> 4) | ((b3 & 0x3) << 4);
                        system1->Write(ea,GetGP(Rt),(0xFF << (ea & 7)) & 0xFF);
                                func = b3 >> 2;
 
                                switch(func) {
 
                                case SHL:
 
                                        gp[Rt] = (gp[Ra] << (gp[Rb] & 0x3f));
 
                                        gp[0] = 0;
 
                                        break;
 
                                case SHLI:
 
                                        gp[Rt] = (gp[Ra] << Rb);
 
                                        gp[0] = 0;
 
                                        break;
 
                                }
 
                        }
                        }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case STP:
        // The SYNC instruction is a pipeline control. The pipeline is
 
        // not emulated by this emulator. So it's treated as a NOP.
 
        case SYNC:
 
                ca[15] = pc;
 
                imm_prefix = false;
 
                break;
 
 
 
        case SYS:
                        b1 = ReadByte(pc);
                        b1 = ReadByte(pc);
                        pc++;
                        pc++;
                        b2 = ReadByte(pc);
                        b2 = ReadByte(pc);
                        pc++;
                        pc++;
 
                if (ex) {
 
                        Ct = b1 & 0xF;
 
                        Cr = b1 >> 4;
 
                        ca[Ct] = pc;
 
                        ca[0] = 0;
 
                        pc = (b2 << 4) + ca[Cr];
 
                        if (Ct==11)
 
                                StatusDBG = true;
 
                        else if (StatusEXL < 255)
 
                                StatusEXL++;
 
                }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                case SW:
        // The TLB isn't implemented yet. the boot rom currently just
 
        // sets up the TLB registers and then leaves it disabled.
 
        case TLB:
                        b1 = ReadByte(pc);
                        b1 = ReadByte(pc);
                        pc++;
                        pc++;
                        b2 = ReadByte(pc);
                        b2 = ReadByte(pc);
                        pc++;
                        pc++;
                        b3 = ReadByte(pc);
 
                        pc++;
 
                        if (ex) {
                        if (ex) {
                                Rb = ((b2 & 0xF) << 2) | (( b1 >> 6) & 3);
                        ;
                                dRn(b1,b2,b3,&Ra,&Sg,&disp);
 
                                ea = (unsigned __int64) disp + seg_base[Sg] + gp[Ra];
 
                                system1->Write(ea,gp[Rb],(0xFF << (ea & 7)) & 0xFF);
 
                        }
                        }
 
                ca[15] = pc;
                        imm_prefix = false;
                        imm_prefix = false;
                        return;
                        return;
 
 
                }
                }
        }
        }
}
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.