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;
}
}
}