Ejemplo n.º 1
0
        /// <summary>
        ///     The DisasmP function is used to disassemble a p-code opcode from
        ///     memory, into the given buffer.
        /// </summary>
        /// <param name="buffer">The buffer to print the opcode into.</param>
        /// <param name="segNo">The segment number the code is within</param>
        /// <param name="ipcBase">The procedure base address (enter_ic).</param>
        /// <param name="ipc">
        ///     The instruction counter (address within segment) of the
        ///     instruction to disassemble.
        /// </param>
        /// <param name="jTab">
        ///     The jump table (procedure attributes) of the procedure being
        ///     executed, or disassembled.
        /// </param>
        /// <param name="sp">Stack pointer (?)</param>
        /// <returns></returns>
        public static ushort DisasmP(StringBuilder buffer, ushort segNo, ushort ipcBase, ushort ipc, ushort jTab,
                                     ushort sp)
        {
            var opCode = Memory.ReadByte(ipcBase, (short)ipc++);
            var s      = PTrace.instructions[opCode];
            int val;

            foreach (var ch in s)
            {
                switch (ch)
                {
                case 'A':
                    // CXP Arguments
                {
                    int seg  = Memory.ReadByte(ipcBase, (short)ipc++);
                    int proc = Memory.ReadByte(ipcBase, (short)ipc++);
                    buffer.AppendFormat("{0},{1} ", seg, proc);
                    buffer.Append(PTrace.ProcName(seg, proc, sp));
                }
                break;

                case 'B':
                    val = Memory.ReadByte(ipcBase, (short)ipc++);
                    if ((val & 0x80) != 0)
                    {
                        val = ((val & 0x7f) << 8) + Memory.ReadByte(ipcBase, (short)ipc++);
                    }
                    buffer.Append(val);
                    break;

                case 'C':
                    val = Memory.ReadByte(ipcBase, (short)ipc++);
                    buffer.AppendFormat("{0} ", val);
                    buffer.Append(PTrace.ProcName(segNo, val, sp));
                    break;

                case 'D':
                case 'U':
                    val = Memory.ReadByte(ipcBase, (short)ipc++);
                    buffer.Append(val);
                    break;

                case 'P':
                    if (sp != 0)
                    {
                        buffer.Append(PTrace.PString(PTrace.ReadStack(sp, 0)));
                    }
                    break;

                case 'S':
                    val = Memory.ReadByte(ipcBase, (short)ipc++);
                    if ((val & 0x80) != 0)
                    {
                        val = -(0x100 - val);
                    }
                    buffer.Append(val);
                    break;

                case 'T':
                    val = Memory.ReadByte(ipcBase, (short)ipc++);
                    switch (val)
                    {
                    case 2:
                        buffer.Append("real");
                        break;

                    case 4:
                        buffer.Append("string");
                        break;

                    case 6:
                        buffer.Append("boolean");
                        break;

                    case 8:
                        buffer.Append("set");
                        break;

                    case 10:
                        val = Memory.ReadByte(ipcBase, (short)ipc++);
                        if ((val & 0x80) != 0)
                        {
                            val = ((val & 0x7f) << 8) + Memory.ReadByte(ipcBase, (short)ipc++);
                        }
                        buffer.AppendFormat("byte array, {0} bytes", val);
                        break;

                    case 12:
                        val = Memory.ReadByte(ipcBase, (short)ipc++);
                        if ((val & 0x80) != 0)
                        {
                            val = ((val & 0x7f) << 8) + Memory.ReadByte(ipcBase, (short)ipc++);
                        }
                        buffer.AppendFormat("{0} words", val);
                        break;

                    default:
                        buffer.Append(val);
                        break;
                    }
                    break;

                case 'W':
                    val  = Memory.ReadByte(ipcBase, (short)ipc++);
                    val |= Memory.ReadByte(ipcBase, (short)ipc++) << 8;
                    buffer.Append(val);
                    break;

                case 'R':     // case arguments
                {
                    ipc = (ushort)(ipc + 1 & ~1);
                    int min = Memory.ReadByte(ipcBase, (short)ipc++);
                    min |= Memory.ReadByte(ipcBase, (short)ipc++) << 8;
                    int max = Memory.ReadByte(ipcBase, (short)ipc++);
                    max |= Memory.ReadByte(ipcBase, (short)ipc++) << 8;
                    ipc++;
                    int defaultVal = Memory.ReadByte(ipcBase, (short)ipc++);
                    if ((defaultVal & 0x80) != 0)     // less than zero?
                    {
                        defaultVal = -(0x100 - defaultVal);
                        defaultVal = -defaultVal;
                        defaultVal = Memory.ReadByte(jTab, -2) +
                                     (Memory.ReadByte(jTab, -1) << 8) + 2 -
                                     (Memory.ReadByte(jTab, (short)-defaultVal) +
                                      (Memory.ReadByte(jTab, (short)(-defaultVal + 1)) << 8) + defaultVal);
                    }
                    else
                    {
                        defaultVal = ipc + defaultVal;
                    }
                    buffer.AppendFormat("{0},{1},{2}  ", min, max, defaultVal);

                    while (min < max + 1)
                    {
                        val  = Memory.ReadByte(ipcBase, (short)ipc++);
                        val |= Memory.ReadByte(ipcBase, (short)ipc++) << 8;
                        buffer.AppendFormat(",{0}", ipc - 2 - val);

                        min++;
                    }
                }
                break;

                case 'Q':
                    val = Memory.ReadByte(ipcBase, (short)ipc++);
                    switch (val)
                    {
                    case 1:
                        buffer.Append("new");
                        break;

                    case 2:
                        buffer.Append("Moveleft");
                        break;

                    case 3:
                        buffer.Append("Moveright");
                        break;

                    case 4:
                        buffer.Append("exit");
                        break;

                    case 5:
                        buffer.Append("unitread");
                        break;

                    case 6:
                        buffer.Append("unitwrite");
                        break;

                    case 7:
                        buffer.Append("idsearch");
                        break;

                    case 8:
                        buffer.Append("treesearch");
                        break;

                    case 9:
                        buffer.Append("time");
                        break;

                    case 10:
                        buffer.Append("fillchar");
                        break;

                    case 11:
                        buffer.AppendFormat("scan");
                        break;

                    case 12:
                        buffer.Append("unitstat");
                        break;

                    case 21:
                        buffer.Append("load_segment");
                        break;

                    case 22:
                        buffer.Append("unload_segment");
                        break;

                    case 32:
                        buffer.Append("mark");
                        break;

                    case 33:
                        buffer.Append("release");
                        break;

                    case 34:
                        buffer.Append("ioresult");
                        break;

                    case 35:
                        buffer.Append("unitbusy");
                        break;

                    case 37:
                        buffer.Append("unitwait");
                        break;

                    case 38:
                        buffer.Append("unitclear");
                        break;

                    case 39:
                        buffer.Append("halt");
                        break;

                    case 40:
                        buffer.Append("memavail");
                        break;

                    default:
                        buffer.Append(val);
                        break;
                    }
                    break;

                case 'J':
                    val = Memory.ReadByte(ipcBase, (short)ipc++);
                    if ((val & 0x80) != 0)     /* less than zero? */
                    {
                        val = -(0x100 - val);
                        val = -val;

                        val = Memory.ReadByte(jTab, -2) +
                              (Memory.ReadByte(jTab, -1) << 8) + 2 -
                              (Memory.ReadByte(jTab, (short)-val) +
                               (Memory.ReadByte(jTab, (short)(-val + 1)) << 8) + val);
                    }
                    else
                    {
                        val = ipc + val;
                    }
                    buffer.Append(val);
                    break;

                case 'V':
                    break;

                case 'X':
                    val = Memory.ReadByte(ipcBase, (short)ipc++);
                    buffer.Append(val);

                    ipc = (ushort)(ipc + 1 & ~1);
                    while (val-- != 0)
                    {
                        var w = Memory.ReadByte(ipcBase, (short)ipc) + (Memory.ReadByte(ipcBase,
                                                                                        (short)(ipc + 1)) << 8);
                        ipc += 2;
                        buffer.AppendFormat(",{0:X4}", w);
                    }
                    break;

                case 'Y':
                    val = Memory.ReadByte(ipcBase, (short)ipc++);
                    buffer.AppendFormat("{0},'", val);

                    while (val-- != 0)
                    {
                        buffer.Append((char)Memory.ReadByte(ipcBase, (short)ipc++));
                    }
                    buffer.Append('\'');
                    break;

                case 'Z':
                    val = Memory.ReadByte(ipcBase, (short)ipc++);
                    buffer.Append(val);

                    ipc = (ushort)(ipc + 1 & ~1);
                    while (val-- != 0)
                    {
                        buffer.AppendFormat(",{0:X2}", Memory.ReadByte(ipcBase, (short)ipc));
                        ipc++;
                    }
                    break;

                default:
                    buffer.Append(ch);
                    break;
                }
            }
            return(ipc);
        }
Ejemplo n.º 2
0
        private static string ProcName(int seg, int proc, ushort sp)
        {
            if (seg != 0)
            {
                return(string.Empty);
            }
            StringBuilder sb = new();

            switch (proc)
            {
            case 5:
                sb.Append("Rewrite");
                if (sp == 0)
                {
                    break;
                }
                sb.Append('(');
                sb.Append(PTrace.PString(PTrace.ReadStack(sp, 2)));
                sb.Append(')');
                break;

            case 6:
                sb.Append("Close");
                break;

            case 7:
                sb.Append("Get");
                break;

            case 8:
                sb.Append("Put");
                break;

            case 10:
                sb.Append("Eof");
                break;

            case 11:
                sb.Append("Eoln");
                break;

            case 12:
                sb.Append("ReadInteger");
                break;

            case 13:
                sb.Append("WriteInteger");
                break;

            case 16:
                sb.Append("ReadChar");
                break;

            case 17:
                sb.Append("WriteChar");
                break;

            case 18:
                sb.Append("ReadString");
                break;

            case 19:
                sb.Append("WriteString");
                if (sp == 0)
                {
                    break;
                }
                sb.Append('(');
                sb.Append(PTrace.PString(PTrace.ReadStack(sp, 1)));
                sb.Append(')');
                break;

            case 21:
                sb.Append("ReadLn");
                break;

            case 22:
                sb.Append("WriteLn");
                break;

            case 23:
                sb.Append("Concat");
                if (sp == 0)
                {
                    break;
                }
                sb.Append('(');
                sb.Append(PTrace.PString(PTrace.ReadStack(sp, 2)));
                sb.Append(',');
                sb.Append(PTrace.PString(PTrace.ReadStack(sp, 1)));
                sb.Append(')');
                break;

            case 24:
                sb.Append("Insert");
                if (sp == 0)
                {
                    break;
                }
                sb.Append('(');
                sb.Append(PTrace.PString(PTrace.ReadStack(sp, 3)));
                sb.Append(',');
                sb.Append(PTrace.PString(PTrace.ReadStack(sp, 2)));
                sb.AppendFormat(", {0})", PTrace.ReadStack(sp, 0));
                break;

            case 25:
                sb.Append("Copy");
                if (sp == 0)
                {
                    break;
                }
                sb.Append('(');
                sb.Append(PTrace.PString(PTrace.ReadStack(sp, 3)));
                sb.AppendFormat(", {0}, {1})", PTrace.ReadStack(sp, 1), PTrace.ReadStack(sp, 0));
                break;

            case 26:
                sb.Append("Delete");
                if (sp == 0)
                {
                    break;
                }
                sb.Append('(');
                sb.Append(PTrace.PString(PTrace.ReadStack(sp, 2)));
                sb.AppendFormat(", {0}, {1})", PTrace.ReadStack(sp, 1), PTrace.ReadStack(sp, 0));
                break;

            case 27:
                sb.Append("Pos");
                if (sp == 0)
                {
                    break;
                }
                sb.Append('(');
                sb.Append(PTrace.PString(PTrace.ReadStack(sp, 3)));
                sb.Append(',');
                sb.Append(PTrace.PString(PTrace.ReadStack(sp, 2)));
                sb.Append(')');
                break;

            case 28:
                sb.Append("BlockRead/BlockWrite");
                break;

            case 29:
                sb.Append("GotoXY");
                if (sp != 0)
                {
                    sb.AppendFormat("( {0}, {1})", PTrace.ReadStack(sp, 1), PTrace.ReadStack(sp, 0));
                }
                break;
            }
            return(sb.ToString());
        }