using System; using System.Collections.Generic; using System.Globalization; namespace EVMKurs { class Program { #region vars /// /// Аккумулятор /// readonly static Register Akk = new Register(16); /// /// Регистр команд /// readonly static Register CommandReg = new Register(16); /// /// Память /// readonly static MemoryCell[] Memory = new MemoryCell[1024]; #endregion #region Anl /// /// Метод - эмулятор команды ANL /// /// Регистр назначения /// Регистр - участник операции /// Флаг косвенной адресации private static void Anl(Register a, Register b, bool isRef = false) { Anl(a, !isRef ? b.Value : Memory[b.Value].Value); } /// /// Метод - эмулятор команды ANL /// /// Регистр назначения /// Значение-участник или значение-адрес(в зависимости от isRef) /// Флаг является ли адресация косвенной private static void Anl(Register a, Int16 b, bool isRef = false) { if (!isRef) { a.Value = (Int16)(a.Value & b); } else { a.Value = (Int16)(a.Value & Memory[b].Value); } } #endregion #region JZ /// /// Метод - эмулятор команды JZ /// /// Адрес перехода private static void Jz(Int16 a) { if (Akk.Value == 0) CommandReg.Value = a; } #endregion #region DEC /// /// Метод-эмулятор команды DEC /// /// Регистр-участник /// Флаг косвенной адресации private static void Dec(Register a, bool isRef = false) { if (!isRef) { a--; } else { Dec(a.Value); } } /// /// Метод-эмулятор команды DEC /// /// Адрес ячейки-участницы private static void Dec(Int16 a) { Memory[a]--; } #endregion #region MOV /// /// Метод - эмулятор команды Mov /// /// Регистр назначения /// Регистр - участник операции /// Флаг косвенной адресации регистра а /// Флаг косвенной адресации регистра b private static void Mov(Register a, Register b, bool isARef = false, bool isBRef = false) { if (!isARef) { a.Value = !isBRef ? b.Value : Memory[b.Value].Value; return; } Memory[a.Value].Value = !isBRef ? b.Value : Memory[b.Value].Value; } /// /// Метод - эмулятор команды Mov /// /// Регистр назначения /// Константа - адрес, или константа-значение (в зависимости от isBRef) /// Флаг косвенной адресации регистра а /// Флаг косвенной адресации b private static void Mov(Register a, Int16 b, bool isARef = false, bool isBRef = false) { if (!isARef) { a.Value = !isBRef ? b : Memory[b].Value; return; } Memory[a.Value].Value = !isBRef ? b : Memory[b].Value; } #endregion static void Main(string[] args) { Console.WriteLine("*** Test MOV(akk, reg) ***"); Register reg = new Register(16,5); Akk.Value = 0; Console.WriteLine("Akk = " + Akk.Value); Console.WriteLine("Reg = " + reg.Value); Console.WriteLine("Execute MOV"); Mov(Akk, reg); Console.WriteLine("Akk = " + Akk.Value); Console.WriteLine(); Console.WriteLine("*** Test MOV(akk, @Reg) ***"); Memory[40] = new MemoryCell(16, 0); Console.WriteLine("Memory[40] = " + Memory[40].Value); reg.Value = 40; Console.WriteLine("Reg = " + reg.Value); Console.WriteLine("Execute MOV"); Mov(reg, Akk, true); Console.WriteLine("Memory[40] = " + Memory[40].Value); Console.WriteLine(); Console.WriteLine("*** Test negative value ***"); Akk.Value = -10; Console.WriteLine("Akk(10) = " + Akk.Value); Console.WriteLine("Akk(2) = " +Akk.GetValueWithCounting(2)); Console.WriteLine(); Console.WriteLine("*** Test DEC(reg) ***"); Akk.Value = 2; Console.WriteLine("Akk = " + Akk.Value); Console.WriteLine("Execute DEC"); Dec(Akk); Console.WriteLine("Akk = " + Akk.Value); Console.WriteLine(); Console.WriteLine("*** Test DEC(reg) reg = 0 ***"); Akk.Value = 0; Console.WriteLine("Akk = " + Akk.Value); Console.WriteLine("Execute DEC"); Dec(Akk); Console.WriteLine("Akk(16) = " + Akk.GetValueWithCounting(16)); Console.WriteLine(); Console.WriteLine("*** Test DEC(@Reg) ***"); Memory[1] = new MemoryCell(16, 10); Console.WriteLine("Memory[1] = " + Memory[1].Value); Akk.Value = 1; Console.WriteLine("Akk = " + Akk.Value); Console.WriteLine("Execute DEC"); Dec(Akk, true); Console.WriteLine("Memory[1] = " + Memory[1].Value); Console.WriteLine(); Console.WriteLine("*** Test DEC(Memory[i]) ***"); Console.WriteLine("Execute DEC"); Dec(1); Console.WriteLine("Memory[1] = " + Memory[1].Value); Console.WriteLine(); Console.WriteLine("*** Test JZ(15) ***"); Akk.Value = 0; Console.WriteLine("Akk = " + Akk.Value); Console.WriteLine("CommandReg = " + CommandReg.Value); Console.WriteLine("Execute JZ"); Jz(15); Console.WriteLine("CommandReg = " + CommandReg.Value); Console.WriteLine(); Console.WriteLine("*** Test ANL(reg, @reg) ***"); Memory[60] = new MemoryCell(16, 9); Console.WriteLine("Memory[60] = " + Memory[60].GetValueWithCounting(2)); Akk.Value = 5; Console.WriteLine("Akk = " + Akk.GetValueWithCounting(2)); reg.Value = 60; Console.WriteLine("Reg = " + reg.Value); Console.WriteLine("Execute ANL"); Anl(Akk,reg, true); Console.WriteLine("Akk = " + Akk.GetValueWithCounting(2)); Console.ReadLine(); } } /// /// Класс, представляющий ячейку памяти /// internal class MemoryCell { public static MemoryCell operator --(MemoryCell a) { if (a.Value == 0) a.Value = Int16.Parse(new string('f', (a.Capacity - 1) / 4), NumberStyles.AllowHexSpecifier); else a.Value--; return a; } private Int16 _value; /// /// Текущее значение регистра /// public Int16 Value { get { return _value; } set { if (Convert.ToString(value, 2).Length > Capacity) throw new Exception("Разрядность регистра меньше устанавливаемого занчения"); _value = value; } } /// /// Строковое представление значения регистра в соответствии с системой исчисления /// /// Основание системы исчисления /// Строковое представление значения регистра в соответствии с системой исчисления public string GetValueWithCounting(Int16 counting) { var tempResult = Convert.ToString(Value, counting); var charCounter = Capacity / (Int16)Math.Log(counting, 2); return tempResult.Length < charCounter ? string.Format("{0}{1}", new String('0', charCounter - tempResult.Length), tempResult) : tempResult.Substring(tempResult.Length - charCounter); } /// /// Разрядность регистра /// public byte Capacity { get; set; } /// /// Конструктор класса Register /// /// Разрядность регистра(до 32) public MemoryCell(byte capacity) { if (capacity > 32) throw new ArgumentOutOfRangeException("capacity"); Capacity = capacity; _value = 0; } public MemoryCell(byte capacity, Int16 value) : this(capacity) { Value = value; } } /// /// Класс, представляющий регистр /// internal class Register : MemoryCell { public Register(byte capacity) : base(capacity) { } public Register(byte capacity, Int16 value) : this(capacity) { Value = value; } public static Register operator --(Register a) { if (a.Value == 0) a.Value = Int16.Parse(new string('f', (a.Capacity - 1) / 4), NumberStyles.AllowHexSpecifier); else a.Value--; return a; } } }