Пример #1
0
        public static void MainMenu()
        {
            int choice = 0;

            while (true)
            {
                Console.WriteLine("1: to Assembly program:");
                Console.WriteLine("2: to Simulae code:");
                Console.Write("Input chioce: ");
                try
                {
                    choice = Convert.ToInt32(Console.ReadLine());
                }catch (Exception ex)
                {
                    Console.WriteLine("Invalid choice");
                    continue;
                }

                switch (choice)
                {
                case 1:
                {
                    string locl = "";
                    ASOL.Exec(@"c:\log\program.as", ref locl);
                    break;
                }

                case 2:
                {
                    string local = "";
                    SSOL.Exec(@"c:\log\program.mc", ref local);
                    break;
                }

                default:
                {
                    Console.WriteLine("Invalid input, repeat action.");
                    break;
                }
                }
            }
        }
Пример #2
0
        public static void Run(State state, string outFileName)
        {
            StreamWriter writer = null;

            try
            {
                writer = new StreamWriter(outFileName);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return;
            }
            Int64 arg0 = 0, arg1 = 0, arg2 = 0, addressField = 0;
            int   instructions = 0;
            Int64 opCode       = 0;
            Int64 maxMem       = -1;

            if (arg0 > RegisterIncreasing || arg1 > RegisterIncreasing)
            {
                RegisterIncreasing *= 2;
            }

            for (; ; instructions++)
            {
                PrintState(state, ref writer);
                if (state.pc < 0 || state.pc >= ASOL.MaxNumLabels)
                {
                    throw new Exception("pc went out of the memory range\n");
                }

                maxMem = (state.pc > maxMem) ? state.pc : maxMem;

                // make the following code easier to read
                opCode = state.mem[(Int64)state.pc] >> 36;
                arg0   = (state.mem[state.pc] >> 30) & 63;
                arg1   = (state.mem[state.pc] >> 24) & 63;
                arg2   = (state.mem[state.pc]) & 63;

                // for beg, lw, sw
                addressField = ConvertToNum(state.mem[state.pc] & 0xFFFFFF);
                if (addressField > RegisterIncreasing)
                {
                    RegisterIncreasing *= 2;
                }

                state.pc++;
                if (opCode == ASOL.Parse(ASOL.KeyWord.ADD))
                {
                    state.reg[arg2] = state.reg[arg0] + state.reg[arg1];
                }
                else if (opCode == ASOL.Parse(ASOL.KeyWord.NAND))
                {
                    state.reg[arg2] = ~(state.reg[arg0] & state.reg[arg1]);
                }
                else if (opCode == ASOL.Parse(ASOL.KeyWord.LW))
                {
                    if (state.reg[arg0] + addressField < 0 ||
                        state.reg[arg0] + addressField >= ASOL.MaxNumLabels)
                    {
                        throw new Exception("address out of bounds");
                    }
                    state.reg[arg1] = state.mem[state.reg[arg0] + addressField];
                    if (state.reg[arg0] + addressField > maxMem)
                    {
                        maxMem = state.reg[arg0] + addressField;
                    }
                }
                else if (opCode == ASOL.Parse(ASOL.KeyWord.SW))
                {
                    if (state.reg[arg0] + addressField < 0 ||
                        state.reg[arg0] + addressField >= ASOL.MaxNumLabels)
                    {
                        throw new Exception("address out of bounds");
                    }
                    state.mem[state.reg[arg0] + addressField] = state.reg[arg1];
                    if (state.reg[arg0] + addressField > maxMem)
                    {
                        maxMem = state.reg[arg0] + addressField;
                    }
                }
                else if (opCode == ASOL.Parse(ASOL.KeyWord.BEQ))
                {
                    if (state.reg[arg0] == state.reg[arg1])
                    {
                        state.pc += addressField;
                    }
                }
                else if (opCode == ASOL.Parse(ASOL.KeyWord.JARL))
                {
                    state.reg[arg1] = state.pc;
                    if (arg0 != 0)
                    {
                        state.pc = state.reg[arg0];
                    }
                    else
                    {
                        state.pc = 0;
                    }
                }
                else if (opCode == ASOL.Parse(ASOL.KeyWord.MUL))
                {
                    state.reg[arg2] = state.reg[arg0] * state.reg[arg1];
                }
                else if (opCode == ASOL.Parse(ASOL.KeyWord.HALT))
                {
                    writer.WriteLine("machine halted");
                    writer.WriteLine($"total of {instructions + 1} instructions executed");
                    writer.WriteLine("final state of machine:");
                    PrintState(state, ref writer);
                    writer.Close();
                    return;
                }
                // Додати і обміняти місцями
                else if (opCode == ASOL.Parse(ASOL.KeyWord.XADD))
                {
                    arg2            = state.mem[state.pc - 1] & 0xFFFFFF;
                    state.mem[arg2] = state.reg[arg0] + state.reg[arg1];
                    Int64 temp = state.reg[arg0];
                    state.reg[arg0] = state.reg[arg1]; state.reg[arg1] = temp;

                    AbsouluteAddrReg.Add(arg2);
                }
                // Знакове ділення і оьмін операндів місцями
                else if (opCode == ASOL.Parse(ASOL.KeyWord.XIDIV))
                {
                    arg2            = state.mem[state.pc - 1] & 0xFFFFFF;
                    state.mem[arg2] = state.reg[arg0] / state.reg[arg1];
                    Int64 temp = state.reg[arg0];
                    state.reg[arg0] = state.reg[arg1]; state.reg[arg1] = temp;

                    AbsouluteAddrReg.Add(arg2);
                }
                // Віднімання і обмін операндів місцями
                else if (opCode == ASOL.Parse(ASOL.KeyWord.XSUB))
                {
                    arg2            = state.mem[state.pc - 1] & 0xFFFFFF;
                    state.mem[arg2] = state.reg[arg0] - state.reg[arg1];
                    Int64 temp = state.reg[arg0];
                    state.reg[arg0] = state.reg[arg1]; state.reg[arg1] = temp;

                    AbsouluteAddrReg.Add(arg2);
                }

                // Додавання по модулю 2
                else if (opCode == ASOL.Parse(ASOL.KeyWord.XOR))
                {
                    state.reg[arg2] = state.reg[arg0] ^ state.reg[arg1];
                }
                // порівння regA == regB
                else if (opCode == ASOL.Parse(ASOL.KeyWord.CMPE))
                {
                    if (state.reg[arg1] == state.reg[arg0])
                    {
                        state.reg[arg2] = 1;
                    }
                    else
                    {
                        state.reg[arg2] = 0;
                    }
                }
                // арифметичний зсув вправо
                else if (opCode == ASOL.Parse(ASOL.KeyWord.SAR))
                {
                    state.reg[arg2] = state.reg[arg0] >> (int)state.reg[arg1];
                }
                #region with_CF
                else if (opCode == ASOL.Parse(ASOL.KeyWord.ADC))
                {
                    state.reg[arg2] = state.reg[arg1] + state.reg[arg0] + state.CarryFlag;
                    if (state.reg[arg2] > 140737488355327)
                    {
                        state.CarryFlag = 1;
                    }
                }
                else if (opCode == ASOL.Parse(ASOL.KeyWord.SBB))
                {
                    state.reg[arg2] = state.reg[arg0] - state.reg[arg1] - state.CarryFlag;
                    if (state.reg[arg2] < -140737488355328)
                    {
                        state.CarryFlag = 1;
                    }
                }
                else if (opCode == ASOL.Parse(ASOL.KeyWord.RCR))
                {
                    Int64 localArg = state.reg[arg0];
                    // Зсув циклічний вправо через carry flag
                    for (int i = 0; i < state.reg[arg1]; i++)
                    {
                        // перевірити молодший розряд
                        Int64 firstDigit = localArg & (Int64)1;

                        localArg = localArg >> 1;

                        localArg = localArg & 0x7FFFFFFFFFFFFFFF;
                        if (state.CarryFlag == 1)
                        {
                            localArg = localArg | 0x800000000000;
                        }
                        state.CarryFlag = firstDigit;
                    }
                    state.reg[arg2] = localArg;
                }
                #endregion
                else if (opCode == ASOL.Parse(ASOL.KeyWord.JML))
                {
                    if (state.reg[arg0] < state.reg[arg1])
                    {
                        state.pc += addressField;
                    }
                }
                else if (opCode == ASOL.Parse(ASOL.KeyWord.JMA))
                {
                    if (state.reg[arg0] > state.reg[arg1])
                    {
                        state.pc += addressField;
                    }
                }
                else if (opCode == ASOL.Parse(ASOL.KeyWord.CLCF))
                {
                    state.CarryFlag = 0;
                }
                else
                {
                    writer.WriteLine($"illegal opcode {opCode}");
                    throw new Exception($"illegal opcode {opCode}");
                    //Environment.Exit(1);
                }
            }
            writer.Close();
        }