From 2a4a067fe4e5860e8807b01334d37e7e8ea80519 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Sun, 21 Apr 2019 16:53:55 +0100 Subject: [PATCH] Add an (untested) implementation of an Intel hex file parser to the EightBit project. Ported directly from the C++ implementation. Signed-off-by: Adrian Conlon --- EightBit/Bus.cs | 79 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/EightBit/Bus.cs b/EightBit/Bus.cs index 3fecdb8..1251855 100644 --- a/EightBit/Bus.cs +++ b/EightBit/Bus.cs @@ -5,6 +5,8 @@ namespace EightBit { using System; + using System.Collections.Generic; + using System.IO; public abstract class Bus : IMapper { @@ -101,6 +103,69 @@ namespace EightBit public abstract void Initialize(); + protected static Dictionary> ParseHexFile(string path) + { + var returned = new Dictionary>(); + + using (var reader = File.OpenText(path)) + { + var eof = false; + while (!reader.EndOfStream && !eof) + { + var line = reader.ReadLine(); + + var colon = line.Substring(0, 1); + if (colon != ":") + { + throw new System.InvalidOperationException("Invalid hex file: line does not begin with a colon"); + } + + var countString = line.Substring(1, 2); + var count = Convert.ToByte(countString, 16); + + var addressString = line.Substring(3, 4); + var address = Convert.ToUInt16(addressString, 16); + + var recordTypeString = line.Substring(7, 2); + var recordType = Convert.ToByte(recordTypeString, 16); + + switch (recordType) + { + case 0x00: + { + var data = new List(count); + var requiredLength = 9 + 2 + (count * 2); + if (line.Length != requiredLength) + { + throw new InvalidOperationException("Invalid hex file: line is not the required length"); + } + + for (var i = 0; i < count; ++i) + { + var position = 9 + (i * 2); + var datumString = line.Substring(position, 2); + var datum = Convert.ToByte(datumString, 16); + data[i] = datum; + } + + returned[address] = data; + } + + break; + + case 0x01: + eof = true; + break; + + default: + throw new InvalidOperationException("Unhandled hex file record."); + } + } + } + + return returned; + } + protected virtual void OnWritingByte() => this.WritingByte?.Invoke(this, EventArgs.Empty); protected virtual void OnWrittenByte() => this.WrittenByte?.Invoke(this, EventArgs.Empty); @@ -128,7 +193,17 @@ namespace EightBit protected ref byte Reference(byte low, byte high) => ref this.Reference(new Register16(low, high).Word); - ////[[nodiscard]] static std::map> parseHexFile(std::string path); - ////void loadHexFile(std::string path); + protected void LoadHexFile(string path) + { + var chunks = ParseHexFile(path); + foreach (var chunk in chunks) + { + var address = chunk.Key; + var content = chunk.Value; + var mapped = this.Mapping(address); + var offset = address - mapped.Begin; + mapped.Memory.Load(content.ToArray(), offset); + } + } } }