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); } }
public static ushort SegmentSizePointer(ushort id) => PSystem.SegmentUnitPointer(id).Index(2);
public static ushort SegmentBlockPointer(ushort id) => PSystem.SegmentUnitPointer(id).Index(1);
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); } }
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); }
public static void Clear(ushort unit) { Debug.Assert(unit < DiskIO.MaxUnits); PSystem.IOError(0); }