mirror of https://github.com/duggerd/KFDtool.git
147 lines
4.6 KiB
C#
147 lines
4.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace KFDtool.BSL430
|
|
{
|
|
public class BinaryTextFileParser
|
|
{
|
|
/*
|
|
* This class takes in input a text file containing the binary
|
|
* code to be uploaded to the MSP430. It generates a list of
|
|
* CodeSection instances, each containg a portion of the code to be
|
|
* loaded.
|
|
*/
|
|
|
|
private const int RVECTOR = 0xFFFE;
|
|
|
|
// Outputs
|
|
public List<CodeSection> sections = new List<CodeSection>();
|
|
// After parsing, if file is indeed a program code, returns true. False otherwise.
|
|
private bool formatCorrect = true;
|
|
public bool IsFileFormatConform()
|
|
{
|
|
if (!formatCorrect)
|
|
return false;
|
|
|
|
if (sections.Count <= 0)
|
|
return false;
|
|
|
|
foreach (CodeSection section in sections)
|
|
{
|
|
if (section.binaryCode.Count() <= 0)
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public BinaryTextFileParser(string text)
|
|
{
|
|
try
|
|
{
|
|
StringReader strReader = new StringReader(text);
|
|
|
|
string line = strReader.ReadLine();
|
|
while (line != null)
|
|
{
|
|
// End of the text read
|
|
if (line.Contains("q"))
|
|
return;
|
|
|
|
else if (line.Contains("@"))
|
|
{
|
|
// Read the line
|
|
int address = readAddressLine(line);
|
|
|
|
// Create a new code section
|
|
sections.Add(new CodeSection());
|
|
sections.Last().StartAddress = address;
|
|
}
|
|
else
|
|
{
|
|
// Read the binary code
|
|
byte[] bLine = readBinaryCodeLine(line);
|
|
|
|
// Add this to the section
|
|
sections.Last().AppendBinaryCode(bLine);
|
|
}
|
|
|
|
line = strReader.ReadLine();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
formatCorrect = false;
|
|
}
|
|
}
|
|
|
|
public static BinaryTextFileParser FromTextFile(string filename)
|
|
{
|
|
string str = File.ReadAllText(filename);
|
|
return new BinaryTextFileParser(str);
|
|
}
|
|
|
|
// Returns the address (if found) of the program reset, contained in Reset Vector (0xFFFE)
|
|
public int ResetAddress()
|
|
{
|
|
foreach (CodeSection section in sections)
|
|
{
|
|
// If the section contains the reset vector
|
|
if (section.StartAddress <= RVECTOR &&
|
|
section.StartAddress + section.binaryCode.Length >= RVECTOR + 1)
|
|
{
|
|
byte[] address = new byte[4];
|
|
|
|
int i = RVECTOR - section.StartAddress;
|
|
address[0] = 0;
|
|
address[1] = 0;
|
|
address[2] = section.binaryCode[i + 1];
|
|
address[3] = section.binaryCode[i];
|
|
|
|
if (BitConverter.IsLittleEndian)
|
|
Array.Reverse(address);
|
|
|
|
return BitConverter.ToInt32(address, 0);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private byte[] readBinaryCodeLine(string line)
|
|
{
|
|
return StringToByteArray(line.Replace(" ", ""));
|
|
}
|
|
|
|
private int readAddressLine(string line)
|
|
{
|
|
string addressText = line.Replace("@", string.Empty);
|
|
|
|
int nbAdditionalCharacters = 8 - addressText.Length;
|
|
int i;
|
|
for (i = 0; i < nbAdditionalCharacters; i++)
|
|
addressText = "0" + addressText;
|
|
|
|
byte[] byteAddress = StringToByteArray(addressText);
|
|
|
|
if (BitConverter.IsLittleEndian)
|
|
Array.Reverse(byteAddress);
|
|
|
|
i = BitConverter.ToInt32(byteAddress, 0);
|
|
return i;
|
|
}
|
|
|
|
private static byte[] StringToByteArray(string hex)
|
|
{
|
|
return Enumerable.Range(0, hex.Length)
|
|
.Where(x => x % 2 == 0)
|
|
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
|
|
.ToArray();
|
|
}
|
|
}
|
|
}
|