Скачиваний:
21
Добавлен:
09.05.2014
Размер:
176.36 Кб
Скачать

Приложение №4. Исходный код ассемблера микрокоманд и сопутствующих утилит. Ассемблер микрокоманд

// BData.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace i8051

{

class Bit

{

byte fVal;

public Bit(byte b)

{

if (b > 1) throw new FormatException("Bit data format error!");

fVal = b;

}

public static implicit operator Bit(byte b)

{

return new Bit(b);

}

public static implicit operator Bit(int b)

{

return new Bit(Convert.ToByte(b));

}

public static implicit operator byte(Bit b)

{

return b.fVal;

}

public static implicit operator bool(Bit b)

{

return b.fVal > 0;

}

public static implicit operator Bit(bool b)

{

return new Bit(Convert.ToByte(b));

}

public override string ToString()

{

return fVal == 0 ? "0" : "1";

}

public void Set()

{

fVal = 1;

}

public void Clear()

{

fVal = 0;

}

}

class BData

{

Bit[] Bits;

int fCount;

int Length { get { return fCount; } }

public BData(int Count, Int64 Data)

{

fCount = Count;

Bits = new Bit[fCount];

for (int i = 0; i < fCount; i++)

{

Bits[i] = (byte)(Data % 2);

Data /= 2;

}

}

long GetNum()

{

int Result = 0;

for (int i = fCount-1; i >= 0; i--)

{

Result *= 2;

Result += Bits[i];

}

return Result;

}

#region ImplictByte

public static implicit operator BData(byte b)

{

return new BData(8, b);

}

public static implicit operator byte(BData b)

{

return (byte)b.GetNum();

}

#endregion

#region ImplictInt

public static implicit operator BData(int b)

{

return new BData(32, b);

}

public static implicit operator int(BData b)

{

return (int)b.GetNum();

}

#endregion

#region ImplictLong

public static implicit operator BData(long b)

{

return new BData(64, b);

}

public static implicit operator long(BData b)

{

return b.GetNum();

}

#endregion

public Bit this[int x]

{

get

{

if (x >= fCount || x < 0) throw new TypeAccessException("Invalid bit!");

return new Bit(Bits[x]);

}

set

{

if (x >= fCount || x < 0) throw new TypeAccessException("Invalid bit!");

Bits[x] = (byte)value;

}

}

public BData this[int From, int To]

{

get

{

if (From > To) { int t = From; From = To; To = t; }

if ((From >= fCount || From < 0) || (To >= fCount || To < 0)) throw new TypeAccessException("Invalid bit!");

BData Result = new BData(To - From + 1, 0);

for (int i = 0; i <= To - From; i++)

{

Result[i] = this[i + From];

}

return Result;

}

set

{

if (From > To) { int t = From; From = To; To = t; }

if ((From >= fCount || From < 0) || (To >= fCount || To < 0)) throw new TypeAccessException("Invalid bit!");

for (int i = 0; i <= To - From; i++)

{

this[i + From] = value[i];

}

}

}

public /*override*/ string ToString()

{

string S = "";

for (int i = 0; i < Bits.Length; i++)

{

S += Bits[i];

}

return S;

}

}

}

//

// i8051 microcode assembler

// Part of sci-reserching project at "Organisation of ECM"

// (C) C.c 2010 via gnu gpl

//

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

using i8051;

namespace i8051_mc_compiler

{

static class ArgConv

{

public static int Do(string a)

{

if (a.ToUpper().StartsWith("0X")) // hex

{

return int.Parse(a.Substring(2), System.Globalization.NumberStyles.HexNumber);

}

if (a.ToUpper().EndsWith("H")) // hex

{

return int.Parse(a.Substring(0, a.Length - 2), System.Globalization.NumberStyles.HexNumber);

}

if (a.ToUpper().EndsWith("B")) // bin

{

int res = 0;

for (int i = 0; i < a.Length - 1; i++)

{

res *= 2;

res += Convert.ToInt32(a[i] + "");

}

return res;

}

if (a.ToUpper().EndsWith("O")) // oct

{

int res = 0;

for (int i = 0; i < a.Length - 1; i++)

{

res *= 8;

res += Convert.ToInt32(a[i] + "");

}

return res;

}

return int.Parse(a);

}

}

class MCBlock

{

string fName;

int fBytes;

public BData Code;

public string Name { get { return fName; } }

public int Bytes { get { return fBytes; } }

public MCBlock(string Name, int Bytes)

{

fName = Name;

fBytes = Bytes;

Code = 0;

}

public void Reset()

{

Code = 0;

}

}

abstract class MCField

{

abstract public void Set(string Val);

abstract public string Name { get; }

}

class FlagField : MCField

{

string fName;

int fBit;

public MCBlock Block;

public override string Name { get { return fName; } }

public int Bit { get { return fBit; } }

public FlagField(string Name, int Bit, MCBlock Block)

{

this.Block = Block;

fName = Name;

fBit = Bit;

}

public override void Set(string S)

{

Block.Code[fBit] = 1;

}

}

class EnumField : MCField

{

string fName;

int fBitBeg, fBitEnd;

public MCBlock Block;

public override string Name { get { return fName; } }

string[] fEnum;

public EnumField(string Name, int BitBeg, int BitEnd, string Enum, MCBlock Block)

{

this.Block = Block;

fName = Name;

fEnum = Enum.Split(',');

fBitBeg = BitBeg;

fBitEnd = BitEnd;

}

public override void Set(string Val)

{

for (int i = 0; i < fEnum.Length; i++ )

if (fEnum[i].ToUpper() == Val.ToUpper())

{

Block.Code[fBitBeg, fBitEnd] = i;

return;

}

throw new Exception(String.Format("Incorrect value - \"{0}\" for \"{1}\" field!", Val, fName));

}

}

class ImmediateFiled : MCField

{

string fName;

int fBeg;

int fEnd;

MCBlock Block;

public override string Name

{

get { return fName; }

}

public override void Set(string Val)

{

Block.Code[fBeg, fEnd] = ArgConv.Do(Val);

}

public ImmediateFiled(string Name, int BegBit, int EndBit, MCBlock Block)

{

fName = Name;

fBeg = BegBit;

fEnd = EndBit;

this.Block = Block;

}

}

class Program

{

static List<MCBlock> MCBlocks = new List<MCBlock>();

static MCBlock Control, Alu, DataSfr, CodeXData, Bit, Const, __If;

static void InitBlocks()

{

Control = new MCBlock("Control", 2); MCBlocks.Add(Control);

__If = new MCBlock("If", 1); MCBlocks.Add(__If);

Alu = new MCBlock("Alu", 1); MCBlocks.Add(Alu);

DataSfr = new MCBlock("DataSfr", 4); MCBlocks.Add(DataSfr);

CodeXData = new MCBlock("CodeXData", 2); MCBlocks.Add(CodeXData);

Bit = new MCBlock("Bit", 1); MCBlocks.Add(Bit);

Const = new MCBlock("Const", 2); MCBlocks.Add(Const);

}

static List<MCField> Fields = new List<MCField>();

static void InitFields()

{

// Control

Fields.Add(new FlagField("ROMM++", 0, Control));

Fields.Add(new FlagField("SetInstruction", 1, Control));

Fields.Add(new FlagField("Goto", 2, Control));

Fields.Add(new ImmediateFiled("ROMM", 3, 12, Control));

// interrupts

Fields.Add(new FlagField("ClrIntFlag", 13, Control));

Fields.Add(new FlagField("EndInterrupt", 14, Control));

Fields.Add(new FlagField("IPCL->BusB", 15, Control));

// If

Fields.Add(new EnumField("If", 0, 4, "True,PSW.CF,PSW.OF,PSW.AF,WRK1.0,WRK1.1,WRK1.2,WRK1.3,WRK1.4,WRK1.5,WRK1.6,WRK1.7,ALU.CF,ALU.OF,ALU.AF,Wrk1Z,!IntrFlag", __If));

// Alu

Fields.Add(new FlagField("BusB->RA", 0, Alu));

Fields.Add(new FlagField("BusC->RB", 1, Alu));

Fields.Add(new FlagField("+Psw.cf", 2, Alu));

Fields.Add(new FlagField("-Psw.cf", 2, Alu));

Fields.Add(new FlagField("Alu->BusB", 3, Alu));

Fields.Add(new FlagField("AluPsw->BusB", 4, Alu));

Fields.Add(new EnumField("AluOp", 5, 7, "res,suba,subb,add,xor,or,and,set", Alu));

// CodeXData

Fields.Add(new FlagField("BusB->XData[ACX]", 3, CodeXData));

Fields.Add(new FlagField("BusB->PCL", 4, CodeXData));

Fields.Add(new FlagField("BusC->PCH", 5, CodeXData));

Fields.Add(new FlagField("PC++", 6, CodeXData));

Fields.Add(new FlagField("Alu->BusB", 3, CodeXData));

Fields.Add(new EnumField("BusB16", 7, 9, "Null,Code,XData,PCH,PCL,DPH,DPL,Null", CodeXData));

Fields.Add(new EnumField("BusC16", 10, 12, "Null,Code,XData,PCH,PCL,DPH,DPL,APCH", CodeXData));

Fields.Add(new EnumField("ACX", 13, 14, "PC,DPTR,Wrk2.Wrk1", CodeXData));

// DataSfr

Fields.Add(new FlagField("BusB->Data[BusA]", 0, DataSfr));

Fields.Add(new FlagField("BusB->Acc", 1, DataSfr));

Fields.Add(new FlagField("BusB->B", 2, DataSfr));

Fields.Add(new FlagField("BusB->SP", 3, DataSfr));

Fields.Add(new FlagField("SP++", 4, DataSfr));

Fields.Add(new FlagField("SP--", 5, DataSfr));

Fields.Add(new FlagField("BusB->PSW", 6, DataSfr));

Fields.Add(new FlagField("DPTR++", 7, DataSfr));

Fields.Add(new FlagField("BusB->DPL", 8, DataSfr));

Fields.Add(new FlagField("BusB->DPH", 9, DataSfr));

Fields.Add(new EnumField("BusB8", 10, 13, "Null,Wrk2,Wrk1,DPH,DPL,PSW,Data[BusA],SP,B,PswRLC,PswRRC,AccRLC,AccRRC,AccRR,AccRL,Acc", DataSfr));

Fields.Add(new FlagField("SetWrk1", 14, DataSfr));

Fields.Add(new FlagField("SetWrk2", 15, DataSfr));

Fields.Add(new EnumField("Wrk1Src", 16, 16, "BusB,BusC", DataSfr));

Fields.Add(new EnumField("Wrk2Src", 17, 17, "BusB,BusC", DataSfr));

Fields.Add(new EnumField("BusC8", 18, 21, "Null,Wrk2,Wrk1,Null,Null,Null,Null,Null,Null,Null,Null,Null,AccSwap,Acc,CRPsw,CR", DataSfr));

Fields.Add(new EnumField("BusA", 22, 24, "Null,AdBit,Bank+IR[2..0],Bank+IR[0],Acc,Wrk2,Wrk1,SP", DataSfr));

Fields.Add(new FlagField("MulAB", 25, DataSfr));

Fields.Add(new FlagField("DivAB", 26, DataSfr));

Fields.Add(new FlagField("MulPsw->BusB", 27, DataSfr));

Fields.Add(new FlagField("DivPsw->BusB", 28, DataSfr));

// Const

Fields.Add(new ImmediateFiled("BusBC", 0, 7, Const));

Fields.Add(new ImmediateFiled("BusCC", 8, 15, Const));

// Bit

Fields.Add(new FlagField("BusB->AdBit", 0, Bit));

Fields.Add(new FlagField("BusB->BitBuf", 1, Bit));

Fields.Add(new FlagField("!Bit", 2, Bit));

Fields.Add(new FlagField("BLU->BusB", 3, Bit));

Fields.Add(new EnumField("BitOp", 4, 6, "Null,Equal,Not,And,Or,Xor,Set,Set", Bit));

}

static string ProcessInstruction(string Line)

{

foreach (MCBlock Block in MCBlocks)

{

Block.Reset();

}

string[] MCOps = Line.Split(';');

foreach (string _MCOp in MCOps)

{

string MCOp = _MCOp;

if (MCOp == "") continue;

if (MCOp.Contains('@'))

{

int At = MCOp.IndexOf('@');

string Label = MCOp.Substring(At);

if (!Labels.ContainsKey(Label.ToUpper())) throw new Exception(String.Format("Label not found - {0}(line {1})", Label, nLine));

MCOp=MCOp.Remove(At);

MCOp = MCOp + Labels[Label.ToUpper()];

}

string[] sMCOp = MCOp.Split('=');

bool Found = false;

foreach (MCField Field in Fields)

{

if (Field.Name.ToUpper() == sMCOp[0].ToUpper())

{

string Val;

try { Val = sMCOp[1]; }

catch (Exception e) { Val = ""; }

Field.Set(Val);

Found = true;

}

}

if (!Found) throw new Exception(String.Format("Unknown field - {0}(line {1})", sMCOp[0], nLine));

}

string Res = "";

foreach (MCBlock Block in MCBlocks)

{

Res+=String.Format("{0:X" + Block.Bytes*2 + "}|", (int)Block.Code);

}

return Res;

}

static int nLine = 0;

static int ROMM = 0;

static Dictionary<string, int> Labels = new Dictionary<string,int>();

static string ProcessLine(string Line)

{

Line = Line.Split('#')[0];

string sLine = "";

foreach (string s in Line.Split(' ')) sLine += s;

return sLine;

}

static void PassOne(string[] Source)

{

nLine = 0;

ROMM = 0;

Labels.Clear();

foreach (string Line in Source)

{

nLine++;

string sLine = ProcessLine(Line);

while (sLine != "")

{

if (sLine.StartsWith("@"))

{

string Label = sLine.Split(':')[0];

if (sLine.Split(':').Length > 1) sLine = sLine.Split(':')[1];

else sLine = "";

Labels.Add(Label.ToUpper(), ROMM);

Console.WriteLine("Label {0} at 0x{1:x3}", Label, ROMM);

}

else

{

ROMM++;

sLine = "";

}

}

}

}

static List<string> PassTwo(string[] Source)

{

nLine = 0;

ROMM = 0;

List<string> Result = new List<string>();

Result.Add(Convert.ToString(MCBlocks.Count));

for (int i = 0; i < MCBlocks.Count; i++)

{

Result.Add(String.Format("{0} {1} {2}", i, MCBlocks[i].Bytes, MCBlocks[i].Name));

}

foreach (string Line in Source)

{

nLine++;

string sLine = ProcessLine(Line);

while (sLine != "")

{

if (sLine.StartsWith("@"))

{

string Label = sLine.Split(':')[0];

if (sLine.Split(':').Length > 1) sLine = sLine.Split(':')[1];

else sLine = "";

}

else

{

Result.Add(ProcessInstruction(sLine));

ROMM++;

sLine = "";

}

}

}

return Result;

}

static void WriteLabels(string FName)

{

StreamWriter LabelMap = File.CreateText(FName);

foreach (string Key in Labels.Keys)

{

LabelMap.WriteLine("{0}:{1:X3}", Key, Labels[Key]);

}

LabelMap.Close();

}

static void Main(string[] args)

{

Console.WriteLine("BloodEye microcode assembler for i8051");

Console.WriteLine("(C) C.c 2011\n");

InitBlocks();

InitFields();

if (args.Length < 1)

{

Console.WriteLine("Error: no input file specified!");

return;

}

string fname = args[0];

List<string> Source;

try

{

Source = System.IO.File.ReadAllLines(args[0]).ToList();

}

catch (Exception e)

{

Console.WriteLine("Error: Can't open file \""+ fname +"\"");

return;

}

Console.WriteLine(String.Format("Processing file \"{0}\" ({1} lines, {2} bytes)\n", fname, Source.Count, System.IO.File.Open(fname, System.IO.FileMode.Open).Length));

try

{

Console.WriteLine("Pass one...");

PassOne(Source.ToArray());

Console.WriteLine();

Console.WriteLine("Pass two...");

List<string> Output = PassTwo(Source.ToArray());

Console.WriteLine();

Console.WriteLine("Writing labelmap...");

WriteLabels(fname + ".labelmap");

File.WriteAllLines(fname + ".mcd", Output.ToArray());

Console.WriteLine("Done.\n");

}

catch (Exception e)

{

Console.WriteLine("Error: "+e.Message);

}

}

}

}

Соседние файлы в папке Отчет