Esempio n. 1
0
File: SoC.cs Progetto: mfkiwl/Cores
        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];
            }
        }