Ejemplo n.º 1
0
        public static void Stat(ushort unit)
        {
            Debug.Assert(unit < DiskIO.MaxUnits);
            var u = DiskIO.unitTable[unit];

            if (u == null || u.Fd == null && u.Data == null)
            {
                PSystem.IOError(9);
            }
            else
            {
                PSystem.IOError(0);
            }
        }
Ejemplo n.º 2
0
 public static ushort SegmentSizePointer(ushort id) => PSystem.SegmentUnitPointer(id).Index(2);
Ejemplo n.º 3
0
 public static ushort SegmentBlockPointer(ushort id) => PSystem.SegmentUnitPointer(id).Index(1);
Ejemplo n.º 4
0
        public static void Process(ushort entryPoint)
        {
            var op = (DecimalOps)Stack.Pop();

            switch (op)
            {
            case DecimalOps.Adjust:
            {
                var newLen = Stack.Pop();
                var len    = Stack.Pop() & 0xFF;
                var sign   = Stack.Pop();
                if (len < newLen)
                {
                    while (len++ < newLen)
                    {
                        Stack.Push(0);
                    }
                }
                else
                {
                    while (len-- > newLen)
                    {
                        Stack.Pop();
                    }
                }
                Stack.Push(sign);
            }
            break;

            case DecimalOps.Add:
            {
                LongInteger.Pop(out var arg2);
                LongInteger.Pop(out var arg1);
                LongInteger.Add(ref arg1, ref arg2, out var result);
                LongInteger.Push(ref result);
            }
            break;

            case DecimalOps.Subtract:
            {
                LongInteger.Pop(out var arg2);
                LongInteger.Pop(out var arg1);
                LongInteger.Subtract(ref arg1, ref arg2, out var result);
                LongInteger.Push(ref result);
            }
            break;

            case DecimalOps.Negate:
            {
                var len  = Stack.Pop();
                var sign = Stack.Pop() == 0 ? 1 : 0;
                Stack.Push((ushort)(sign != 0 ? 0xFF : 0));
                Stack.Push(len);
            }
            break;

            case DecimalOps.Multiply:
            {
                LongInteger.Pop(out var arg2);
                LongInteger.Pop(out var arg1);
                LongInteger.Multiply(ref arg1, ref arg2, out var result);
                LongInteger.Push(ref result);
            }
            break;

            case DecimalOps.Divide:
            {
                LongInteger.Pop(out var arg2);
                LongInteger.Pop(out var arg1);
                if (!LongInteger.Divide(ref arg1, ref arg2, out var result))
                {
                    throw new ExecutionException(ExecutionErrorCode.DivideByZero);
                }
                LongInteger.Push(ref result);
            }
            break;

            case DecimalOps.Str:
            {
                Stack.Pop();
                var strAddress = Stack.Pop();
                var intLen     = Stack.Pop();
                var sign       = Stack.Pop();

                short idx = 0;

                if (sign != 0)
                {
                    Memory.WriteByte(strAddress, ++idx, (byte)'-');
                }

                var suppress = true;

                while (intLen-- > 0)
                {
                    var w = Stack.Pop();
                    for (var i = 0; i < 4; i++)
                    {
                        var digit = (byte)(w >> 4 * i & 0xF);
                        if (suppress && digit <= 0)
                        {
                            continue;
                        }
                        Memory.WriteByte(strAddress, ++idx, (byte)(digit + (byte)'0'));
                        suppress = false;
                    }
                }
                if (suppress)
                {
                    Memory.WriteByte(strAddress, ++idx, (byte)'0');
                }

                Memory.WriteByte(strAddress, 0, (byte)idx);
            }
            break;

            case DecimalOps.Compare:
            {
                var cmp = Stack.Pop();

                LongInteger.Pop(out var arg2);
                LongInteger.Pop(out var arg1);
                var result = LongInteger.Compare(ref arg1, ref arg2);
                switch (cmp)
                {
                case 8:         // <
                    Stack.Push(PSystem.Boolean(result < 0));
                    break;

                case 9:         // <=
                    Stack.Push(PSystem.Boolean(result <= 0));
                    break;

                case 10:         // >=
                    Stack.Push(PSystem.Boolean(result >= 0));
                    break;

                case 11:         // >
                    Stack.Push(PSystem.Boolean(result > 0));
                    break;

                case 12:         // !=
                    Stack.Push(PSystem.Boolean(result != 0));
                    break;

                case 13:         // ==
                    Stack.Push(PSystem.Boolean(result == 0));
                    break;

                default:
                    throw new ExecutionException(ExecutionErrorCode.UnimplementedInstruction);
                }
            }
            break;

            case DecimalOps.ConvertTos:
            {
                var val  = Stack.PopInteger();
                var sign = val < 0;
                if (!sign)
                {
                    val = (short)-val;
                }

                for (var i = 0; i < 2; i++)
                {
                    ushort w = 0;
                    for (var j = 0; j < 4; j++)
                    {
                        w    = (ushort)((w << 4) - val % 10);
                        val /= 10;
                    }
                    Stack.Push(w);
                }
                Stack.Push((ushort)(sign ? 0xFF : 0));
                Stack.Push(3);
            }
            break;

            case DecimalOps.Truncate:
            {
                LongInteger.Pop(out var arg1);

                var result = arg1.Value.Aggregate <byte, short>(0, (current, t) => (short)(current * 10 - t));

                if (arg1.Sign == BcSign.Minus)
                {
                    Stack.Push(result);
                }
                else
                {
                    Stack.Push((short)-result);
                }
            }
            break;

            //case DecimalOps.ConvertTosM1:
            default:
                throw new ExecutionException(ExecutionErrorCode.UnimplementedInstruction);
            }
        }
Ejemplo n.º 5
0
        public static void Read(ushort unit, ushort address, short addressOffset, ushort len, ushort blockNo)
        {
            var offset = blockNo * 512u;
            var track  = blockNo / 8;
            var sector = (blockNo & 7) * 2;

            Debug.Assert(unit < DiskIO.MaxUnits);
            var u = DiskIO.unitTable[unit];

            if (u == null || u.Fd == null && u.Data == null)
            {
                PSystem.IOError(9);
                return;
            }
            if (offset + len > u.Size)
            {
                PSystem.IOError(64);
                return;
            }

            while (len != 0)
            {
                var size = 256;
                var sec  = sector;
                if (len < size)
                {
                    size = len;
                }
                //if (u.Translate != null)
                //    sec = u.Translate[sector];
                int i;
                if (u.Data != null)
                {
                    for (i = 0; i < size; i++)
                    {
                        Memory.WriteByte
                        (
                            address,
                            (short)(addressOffset + i),
                            u.Data[(track * 16 + sec) * 256 + i]
                        );
                    }
                }
                else if (u.Fd != null)
                {
                    var  buf = new byte[256];
                    bool failed;
                    try
                    {
                        u.Fd.Seek((track * 16 + sec) * 256, SeekOrigin.Begin);
                        failed = u.Fd.Read(buf, 0, size) < size;
                    }
                    catch
                    {
                        failed = true;
                    }

                    if (failed)
                    {
                        PSystem.IOError(64);
                        return;
                    }

                    for (i = 0; i < size; i++)
                    {
                        Memory.WriteByte(address, (short)(addressOffset + i), buf[i]);
                    }
                }

                addressOffset += (short)size;
                len           -= (ushort)size;
                sector++;
                if (sector < 16)
                {
                    continue;
                }
                track++;
                sector = 0;
            }
            PSystem.IOError(0);
        }
Ejemplo n.º 6
0
 public static void Clear(ushort unit)
 {
     Debug.Assert(unit < DiskIO.MaxUnits);
     PSystem.IOError(0);
 }