public static Int128 Rol(Int128 a, int amt) { int nn; Int128 aa = a.Clone(); for (; amt > 0; amt--) { for (nn = 0; nn < 4; nn++) { aa.digits[nn] <<= 1; } for (nn = 0; nn < 3; nn++) { if (aa.digits[nn] > 0xffffffffL) { aa.digits[nn] &= 0xffffffffL; aa.digits[nn + 1]++; } } if (aa.digits[nn] > 0xffffffffL) { aa.digits[0] |= 1; } aa.digits[nn] &= 0xffffffffL; } aa.mask(); return(aa); }
public static Int128 Convert(ulong nn) { Int128 a = new Int128(); a.digits[0] = (nn & 0xffffffffL); a.digits[1] = (nn >> 32); a.digits[2] = 0; a.digits[3] = 0; return(a); }
public static bool LT(Int128 a, Int128 b) { Int128 d; d = Sub(a, b); if (((d.digits[3] >> 31) & 1) != 0) { return(true); } return(false); }
public static Int128 Com(Int128 a) { int nn; Int128 aa = a.Clone(); for (nn = 0; nn < 4; nn++) { aa.digits[nn] = ~aa.digits[nn]; } return(aa); }
static string BranchTgt(Int64 instr, Int128 ip) { string str; Int64 tgt; tgt = ((instr >> 4) & 3) | (((instr >> 4) & 3) << 2) | ((instr >> 22) << 4); tgt = Int128.Add(ip, Int128.Convert(instr >> 22)).ToLong(); tgt &= -16L; tgt |= ((instr >> 4) & 3) | (((instr >> 4) & 3) << 2); str = "$" + Convert.ToString(tgt, 16).PadLeft(10, '0'); return(str); }
public static Int128 Xor(Int128 a, Int128 b) { int nn; Int128 sum = new Int128(); for (nn = 0; nn < 4; nn++) { sum.digits[nn] = a.digits[nn] ^ b.digits[nn]; } sum.mask(); return(sum); }
public Int128(string str) { int nn; Int128 a = FromHexString(str); digits = new ulong[4]; for (nn = 0; nn < 4; nn++) { digits[nn] = a.digits[nn]; } mask(); }
public Int128 Clone() { int nn; Int128 c; c = new Int128(); for (nn = 0; nn < 4; nn++) { c.digits[nn] = this.digits[nn]; } c.mask(); return(c); }
public Int128 FromHexString(string str) { Int128 a = new Int128(); int nn; for (nn = 0; nn < str.Length; nn++) { a = Shl(a, 4); a.digits[0] |= System.Convert.ToUInt64(str.Substring(nn, 1), 16); } a.mask(); return(a); }
public static bool EQ(Int128 a, Int128 b) { int nn; for (nn = 0; nn < 4; nn++) { if (a.digits[nn] != b.digits[nn]) { return(false); } } return(true); }
private nvioCpu.e_unitTypes GetUnit(Int128 ad) { nvioCpu.e_unitTypes unit0; nvioCpu.e_unitTypes unit1; nvioCpu.e_unitTypes unit2; Int128 bund; int tmp; bund = soc.IFetch(ad); tmp = (int)(bund.digits[3] >> 24) & 0x7f; if (tmp == 0x7D) { unit0 = nvioCpu.e_unitTypes.I; unit1 = nvioCpu.e_unitTypes.N; unit2 = nvioCpu.e_unitTypes.N; } else if (tmp == 0x7E) { unit0 = nvioCpu.e_unitTypes.F; unit1 = nvioCpu.e_unitTypes.N; unit2 = nvioCpu.e_unitTypes.N; } else if (tmp == 0x7F) { unit0 = nvioCpu.e_unitTypes.M; unit1 = nvioCpu.e_unitTypes.N; unit2 = nvioCpu.e_unitTypes.N; } else { tmp &= 63; unit0 = nvioCpu.unitx[tmp, 0]; unit1 = nvioCpu.unitx[tmp, 1]; unit2 = nvioCpu.unitx[tmp, 2]; } switch ((ad.digits[0] & 15)) { case 0: return(unit0); case 5: return(unit1); case 10: return(unit2); default: return(unit0); } }
public static Int128 Convert(bool b) { Int128 a = new Int128(); if (b) { a.digits[0] = 1; } else { a.digits[0] = 0; } return(a); }
public Int128 IFetch(Int128 adr) { ulong nn; Int128 j, k; ulong ad = adr.low(); if (1 == 1) { ad &= 0xfffffffffffffff0L; nn = ((ad - 0xFFFFFFFFFFC0000L) >> 4) & 0x3fffL; j = rom[nn].Clone(); return(j); } }
public static Int128 Mul(Int128 a, Int128 b) { Int128 aa = a.Clone(); Int128 p = new Int128(); int nn; for (nn = 0; nn < 128; nn++) { if (((aa.digits[3] >> 31) & 1) != 0) { p = Add(p, b); } p = Shl(p, 1); aa = Shl(aa, 1); } return(p); }
public static Int128 Sub(Int128 a, Int128 b) { int nn; Int128 dif = new Int128(); for (nn = 0; nn < 4; nn++) { dif.digits[nn] = a.digits[nn] - b.digits[nn]; } for (nn = 0; nn < 3; nn++) { if (dif.digits[nn] < 0L) { dif.digits[nn] &= 0xffffffffL; dif.digits[nn + 1]--; } } dif.mask(); return(dif); }
public static Int128 Add(Int128 a, Int128 b) { int nn; Int128 sum = new Int128(); for (nn = 0; nn < 4; nn++) { sum.digits[nn] = a.digits[nn] + b.digits[nn]; } for (nn = 0; nn < 3; nn++) { if (sum.digits[nn] > 0xffffffffL) { sum.digits[nn] &= 0xffffffffL; sum.digits[nn + 1]++; } } sum.mask(); return(sum); }
static string RII(UInt64 instr) { string str; Int128 rii = new Int128(); rii.digits[0] = (instr >> 16) & 0x7fffL; rii.digits[0] |= ((instr >> 33) & 0x7fL) << 15; rii.digits[1] = 0; rii.digits[2] = 0; rii.digits[3] = 0; if ((rii.digits[0] & 0x200000L) != 0) { rii.digits[0] |= 0xffC00000L; rii.digits[1] = 0xffffffffL; rii.digits[2] = 0xffffffffL; rii.digits[3] = 0xffffffffL; } str = rii.ToString80(); return(str); }
public Int128 ShrPair(Int128 hi, Int128 lo, int amt) { int nn; UInt64[] digits; Int128 aa = new Int128(); digits = new ulong[8]; Int128 reslo = lo.Clone(); Int128 reshi = hi.Clone(); digits[0] = lo.digits[0]; digits[1] = lo.digits[1]; digits[2] = lo.digits[2]; digits[3] = lo.digits[3]; digits[4] = hi.digits[0]; digits[5] = hi.digits[1]; digits[6] = hi.digits[2]; digits[7] = hi.digits[3]; for (; amt > 0; amt--) { for (nn = 7; nn > 0; nn--) { if ((digits[nn] & 1L) != 0) { digits[nn - 1] |= 0x100000000L; } } for (nn = 0; nn < 8; nn++) { digits[nn] >>= 1; } } aa.digits[0] = digits[0]; aa.digits[1] = digits[1]; aa.digits[2] = digits[2]; aa.digits[3] = digits[3]; aa.mask(); return(aa); }
public void LoadROM(string fname) { string[] lines; string s; int nn; int j, k, m; lines = System.IO.File.ReadAllLines(fname); nn = 0; foreach (string str in lines) { j = str.IndexOf('['); k = str.IndexOf(']'); if (j >= 0 && k >= 0) { nn = Convert.ToInt32(str.Substring(j + 1, k - j - 1), 10); if (nn > 16383) { continue; } m = str.IndexOf("256'h"); if (m >= 0) { j = m + 5; s = str.Substring(j, 32); rom[nn * 2 + 1] = new Int128(s); s = str.Substring(j + 32, 32); rom[nn * 2] = new Int128(s); } else { j = str.IndexOf('h'); k = str.IndexOf(';'); s = str.Substring(j + 1, k - j - 1); rom[nn] = new Int128(s); } } } }
public Int128 Read(Int128 adr) { ulong nn; Int128 j, k; ulong ad = adr.digits[0]; if (ad < 0x20000000L) { nn = (ad >> 4) & 0xfffffL; j = mainmem[nn].Clone(); k = mainmem[nn + 1].Clone(); j = j.ShrPair(k, j, (int)((adr.digits[0] & 15L) << 3)); return(j); } else if ((ad & 0xffffffffL) >= 0xff400000L && ((ad & 0xffffffffL) < 0xff410000L)) { nn = (ad >> 4) & 0xfffL; j = scratchmem[nn].Clone(); k = scratchmem[(nn + 1) & 0xfffL].Clone(); j = j.ShrPair(k, j, (int)((adr.digits[0] & 15L) << 3)); return(j); } else // ROM { nn = ((ad - 0xFFFFFFFFFFC0000L) >> 4) & 0x3fff; j = rom[nn].Clone(); if (nn + 1 > 16383) { k = Int128.Convert(0); } else { k = rom[nn + 1].Clone(); } j = j.ShrPair(k, j, (int)((ad & 15L) << 3)); return(j); } }
public SoC() { int nn; cpu = new nvioCpu(); rom = new Int128[16384]; mainmem = new Int128[4194304]; // 64 MB textmem = new long[65536]; scratchmem = new Int128[4096]; for (nn = 0; nn < 16384; nn++) { rom[nn] = new Int128(); } for (nn = 0; nn < 4194304; nn++) { mainmem[nn] = new Int128(); } for (nn = 0; nn < 4096; nn++) { scratchmem[nn] = new Int128(); } }
public static Int128 Asr(Int128 a, int amt) { int nn; Int128 aa = a.Clone(); for (; amt > 0; amt--) { for (nn = 3; nn > 0; nn--) { if ((aa.digits[nn] & 1L) != 0) { aa.digits[nn - 1] |= 0x100000000L; } } for (nn = 0; nn < 4; nn++) { aa.digits[nn] >>= 1; } aa.digits[nn - 1] |= (ulong)((aa.digits[nn - 1] >> 30) & 1) << 31; } aa.mask(); return(aa); }
private UInt64 GetInstr(Int128 ad) { Int128 ibundle; UInt64 insn0, insn1, insn2; ibundle = soc.IFetch(ad); insn0 = ibundle.digits[0]; insn0 |= ((ibundle.digits[1] & 0xffL) << 32); insn1 = ibundle.digits[1] >> 8; insn1 |= (ibundle.digits[2] << 24) & 0xffff000000L; insn2 = ibundle.digits[2] >> 16; insn2 |= (ibundle.digits[3] << 16) & 0xffffff0000L; switch (ad.digits[0] & 15) { case 0: return(insn0); case 5: return(insn1); case 10: return(insn2); default: return(insn0); } }
public static void ShlPair(Int128 a, ref Int128 aa, ref Int128 bb, int amt, int lsb = 0) { int nn; aa = a.Clone(); // bb = Int128.Convert(lsb!=0 ? -1 : 0); for (; amt > 0; amt--) { for (nn = 0; nn < 4; nn++) { aa.digits[nn] <<= 1; bb.digits[nn] <<= 1; } for (nn = 0; nn < 3; nn++) { if (aa.digits[nn] > 0xffffffffL) { aa.digits[nn] &= 0xffffffffL; aa.digits[nn + 1]++; } if (bb.digits[nn] > 0xffffffffL) { bb.digits[nn] &= 0xffffffffL; bb.digits[nn + 1]++; } } if (aa.digits[nn] > 0xffffffffL) { bb.digits[0]++; } aa.digits[0] |= (ulong)lsb; aa.mask(); bb.mask(); } }
public static string Disassemble(nvioCpu.e_unitTypes unit, Int64 instr, Int128 ip) { string str; UInt16 op4; UInt16 op6; UInt16 func5; Int16 Rd; Int16 Rs1; Int16 Rs2; Int16 Rs3; op4 = (UInt16)((instr >> 6) & 15L); func5 = (UInt16)((instr >> 35) & 31L); Rd = (Int16)(instr & 63); Rs1 = (Int16)((instr >> 10) & 63); Rs2 = (Int16)((instr >> 16) & 63); Rs3 = (Int16)((instr >> 22) & 63); str = ""; str = ip.ToString80().Substring(14, 6) + " "; switch (unit) { case nvioCpu.e_unitTypes.B: switch ((nvioCpu.e_bunit)op4) { case nvioCpu.e_bunit.CALL: str = str + "CALL "; str = str + CallTgt(instr); break; case nvioCpu.e_bunit.RET: str = str + "RET"; break; case nvioCpu.e_bunit.JMP: str = str + "JMP"; str = str + CallTgt(instr); break; case nvioCpu.e_bunit.Bcc: switch ((nvioCpu.e_bcond)(instr & 7)) { case nvioCpu.e_bcond.BEQ: str = str + "BEQ "; str = str + Regstr(Rs1) + "," + Regstr(Rs2) + "," + BranchTgt(instr, ip); break; case nvioCpu.e_bcond.BNE: str = str + "BNE "; str = str + Regstr(Rs1) + "," + Regstr(Rs2) + "," + BranchTgt(instr, ip); break; case nvioCpu.e_bcond.BLT: str = str + "BLT "; str = str + Regstr(Rs1) + "," + Regstr(Rs2) + "," + BranchTgt(instr, ip); break; default: str = str + "B?? "; str = str + Regstr(Rs1) + "," + Regstr(Rs2) + "," + BranchTgt(instr, ip); break; } break; } break; case nvioCpu.e_unitTypes.I: op6 = (UInt16)(((instr >> 6) & 15L) | (((instr >> 31) & 3L) << 4)); switch ((nvioCpu.e_iunit)op6) { case nvioCpu.e_iunit.R3E: return(nvioCpu.DisProcessR3((UInt64)instr, Rd, Rs1, Rs2, Rs3)); case nvioCpu.e_iunit.ADDI: str = str + "ADD "; str = str + Regstr(Rd) + "," + Regstr(Rs1) + "," + RII((UInt64)instr); break; } break; case nvioCpu.e_unitTypes.M: break; } return(str); }
public void Write(Int128 adr, Int128 val, int size) { ulong ad = adr.digits[0] | (adr.digits[1] << 32); Int128 j, k; Int128 s; Int128 mask = new Int128(); Int128 v = new Int128(); Int128 m, mlo, mhi; Int128 vlo, vhi; vlo = new Int128(); vhi = new Int128(); mlo = new Int128(); mhi = new Int128(); switch (size) { case 1: mask.digits[0] = 0xffffff00L; mask.digits[1] = 0xffffffffL; mask.digits[2] = 0xffffffffL; mask.digits[3] = 0xffffffffL; break; case 2: mask.digits[0] = 0xffff0000L; mask.digits[1] = 0xffffffffL; mask.digits[2] = 0xffffffffL; mask.digits[3] = 0xffffffffL; break; case 4: mask.digits[0] = 0x00000000L; mask.digits[1] = 0xffffffffL; mask.digits[2] = 0xffffffffL; mask.digits[3] = 0xffffffffL; break; case 5: mask.digits[0] = 0x00000000L; mask.digits[1] = 0xffffff00L; mask.digits[2] = 0xffffffffL; mask.digits[3] = 0xffffffffL; break; case 8: mask.digits[0] = 0x00000000L; mask.digits[1] = 0x00000000L; mask.digits[2] = 0xffffffffL; mask.digits[3] = 0xffffffffL; break; case 10: mask.digits[0] = 0x00000000L; mask.digits[1] = 0x00000000L; mask.digits[2] = 0xffff0000L; mask.digits[3] = 0xffffffffL; break; } if (ad < 0x20000000L) { s = Int128.Add(adr, Int128.Convert(size)); // Do we need to modify one or two memory bundles? if ((s.digits[0] & 0xfffffff0L) != (adr.digits[0] & 0xfffffff0L)) { s = Int128.Shr(adr, 4); j = mainmem[s.digits[0]].Clone(); k = mainmem[s.digits[0] + 1].Clone(); val = val.ZX80(); Int128.ShlPair(val, ref vlo, ref vhi, (int)((adr.digits[0] & 0xfL) * 8), 0); mhi = Int128.Convert(-1); Int128.ShlPair(mask, ref mlo, ref mhi, (int)((adr.digits[0] & 0xfL) * 8), 1); j = Int128.And(j, mlo); j = Int128.Or(j, vlo); k = Int128.And(k, mhi); k = Int128.Or(k, vhi); mainmem[s.digits[0]] = j; mainmem[s.digits[0] + 1] = k; } else { s = Int128.Shr(adr, 4); j = mainmem[s.digits[0]].Clone(); val = val.ZX80(); Int128.ShlPair(val, ref vlo, ref vhi, (int)((adr.digits[0] & 0xfL) * 8)); j = Int128.And(j, mlo); j = Int128.Or(j, vlo); mainmem[s.digits[0]] = j; } return; } else if ((ad & 0xffffffffL) >= 0xff400000L && (ad & 0xffffffffL) < 0xff410000L) { s = Int128.Add(adr, Int128.Convert(size)); // Do we need to modify one or two memory bundles? if ((s.digits[0] & 0xfffffff0L) != (adr.digits[0] & 0xfffffff0L)) { s = Int128.Shr(adr, 4); ad = (ad >> 4) & 0xfffL; j = scratchmem[ad].Clone(); k = scratchmem[(ad + 1) & 0xfffL].Clone(); val = val.ZX80(); Int128.ShlPair(val, ref vlo, ref vhi, (int)((adr.digits[0] & 0xfL) * 8), 0); mhi = Int128.Convert(-1); Int128.ShlPair(mask, ref mlo, ref mhi, (int)((adr.digits[0] & 0xfL) * 8), 1); j = Int128.And(j, mlo); j = Int128.Or(j, vlo); k = Int128.And(k, mhi); k = Int128.Or(k, vhi); scratchmem[ad] = j; scratchmem[(ad + 1) & 0xfffL] = k; } else { s = Int128.Shr(adr, 4); ad = (ad >> 4) & 0xfffL; j = scratchmem[ad].Clone(); val = val.ZX80(); Int128.ShlPair(val, ref vlo, ref vhi, (int)((adr.digits[0] & 0xfL) * 8)); j = Int128.And(j, mlo); j = Int128.Or(j, vlo); scratchmem[ad] = j; } return; } else if (ad >= 0xffffffffffd00000L && ad < 0xffffffffffd10000L) { textmem[(ad >> 3) & 0xffffL] = (long)(val.digits[0] | (val.digits[1] << 32)); } else if (ad == 0xffffffffffdc0600L) { leds = (int)val.digits[0]; } }
private void timer1_Tick(object sender, EventArgs e) { string str; int nn; Int128 ad = new Int128(textBox1.Text); Int128 dat; trackIP = checkBox1.Checked; if (trackIP) { ad = Int128.Sub(soc.cpu.ip, Int128.Convert(0x20)); } //dumpBox.Clear(); str = ""; nn = 0; for (nn = 0; nn < 50; nn++) { dat = soc.Read(ad); switch (dumpType) { case 0: switch (dumpStride) { case 1: str = str + Convert.ToString((long)ad.digits[0], 16).PadLeft(6, '0') + ": " + dat.ToString80().Substring(18, 2) + "\r\n"; break; case 2: str = str + Convert.ToString((long)ad.digits[0], 16).PadLeft(6, '0') + ": " + dat.ToString80().Substring(16, 4) + "\r\n"; break; case 4: str = str + Convert.ToString((long)ad.digits[0], 16).PadLeft(6, '0') + ": " + dat.ToString80().Substring(12, 8) + "\r\n"; break; case 5: str = str + Convert.ToString((long)ad.digits[0], 16).PadLeft(6, '0') + ": " + dat.ToString80().Substring(10, 10) + "\r\n"; break; case 8: str = str + Convert.ToString((long)ad.digits[0], 16).PadLeft(6, '0') + ": " + dat.ToString80().Substring(4, 16) + "\r\n"; break; case 10: str = str + Convert.ToString((long)ad.digits[0], 16).PadLeft(6, '0') + ": " + dat.ToString80() + "\r\n"; break; case 16: str = str + Convert.ToString((long)ad.digits[0], 16).PadLeft(6, '0') + ": " + dat.ToString128() + "\r\n"; break; } break; case 1: if (Int128.EQ(ad, soc.cpu.ip)) { str = str + "h"; } else { str = str + " "; } str = str + nvioCpu.Disassemble(soc.cpu.ibundle, GetUnit(ad), (Int64)GetInstr(ad), ad) + "\n"; break; } if (trackIP) { ad = nvioCpu.IncAd(ad, 5); } else { ad = Int128.Add(ad, Int128.Convert(dumpStride)); } } dmp.SetText(str); dmp.Invalidate(); ad = Int128.Sub(soc.cpu.regfile[(soc.cpu.regset << 6) | 63], Int128.Convert(40)); str = ""; for (nn = 0; nn < 25; nn++) { dat = soc.Read(ad); if (Int128.EQ(ad, soc.cpu.regfile[(soc.cpu.regset << 6) | 63])) { str = str + "h"; } else { str = str + " "; } str = str + Convert.ToString((long)ad.digits[0], 16).PadLeft(6, '0') + ": " + dat.ToString80() + "\r\n"; ad = Int128.Add(ad, Int128.Convert(10)); } stk.SetText(str); stk.Invalidate(); if (trackIP) { timer1.Interval = 10; } else { timer1.Interval = 100; } timer1.Enabled = trackIP; }