public void SetBaseOffset(int baseOffset) { foreach (Pointer p in _lPointers) { // Our example label is SEQ_STUFF at the binary offset 0x1000, curBaseOffset is 0x500, baseOffset is 0x1800 // There is a pointer (p) to SEQ_STUFF at the binary offset 0x1DFC int oldPointer = EndianBitConverter.BytesToInt32(Binary, p.BinaryOffset, Endianness); // If there was a pointer to "SEQ_STUFF+4", the pointer would be 0x1504, at binary offset 0x1DFC int labelOffset = oldPointer - BaseOffset; // Then labelOffset is 0x1004 (SEQ_STUFF+4) byte[] newPointerBytes = EndianBitConverter.Int32ToBytes(baseOffset + labelOffset, Endianness); // b will contain {0x04, 0x28, 0x00, 0x00} [0x2804] (SEQ_STUFF+4 + baseOffset) for (int i = 0; i < 4; i++) { _bytes[p.BinaryOffset + i] = newPointerBytes[i]; // Copy the new pointer to binary offset 0x1DF4 } } BaseOffset = baseOffset; }
// Returns a status private string Read(string fileName) { if (_loaded.Contains(fileName)) { return($"{fileName} was already loaded"); } string[] file = File.ReadAllLines(fileName); _loaded.Add(fileName); for (int i = 0; i < file.Length; i++) { string line = file[i]; if (string.IsNullOrWhiteSpace(line)) { continue; // Skip empty lines } bool readingCMD = false; // If it's reading the command string cmd = null; var args = new List <string>(); string str = string.Empty; foreach (char c in line) { if (c == '@') // Ignore comments from this point { break; } else if (c == '.' && cmd == null) { readingCMD = true; } else if (c == ':') // Labels { if (!_labels.ContainsKey(str)) { _labels.Add(str, new Pair()); } _labels[str].Offset = _bytes.Count; str = string.Empty; } else if (char.IsWhiteSpace(c)) { if (readingCMD) // If reading the command, otherwise do nothing { cmd = str; readingCMD = false; str = string.Empty; } } else if (c == ',') { args.Add(str); str = string.Empty; } else { str += c; } } if (cmd == null) { continue; // Commented line } args.Add(str); // Add last string before the newline switch (cmd.ToLower()) { case "include": { try { Read(args[0].Replace("\"", string.Empty)); } catch { throw new IOException(string.Format(_fileErrorFormat, fileName, i, args[0], Environment.NewLine)); } break; } case "equ": { try { _defines.Add(args[0], ParseInt(args[1])); } catch { throw new ArithmeticException(string.Format(_mathErrorFormat, fileName, i, line, Environment.NewLine)); } break; } case "global": { if (!_labels.ContainsKey(args[0])) { _labels.Add(args[0], new Pair()); } _labels[args[0]].Global = true; break; } case "align": { int align = ParseInt(args[0]); for (int a = BinaryLength % align; a < align; a++) { _bytes.Add(0); } break; } case "byte": { try { foreach (string a in args) { _bytes.Add((byte)ParseInt(a)); } } catch { throw new ArithmeticException(string.Format(_mathErrorFormat, fileName, i, line, Environment.NewLine)); } break; } case "hword": { try { foreach (string a in args) { _bytes.AddRange(EndianBitConverter.Int16ToBytes((short)ParseInt(a), Endianness)); } } catch { throw new ArithmeticException(string.Format(_mathErrorFormat, fileName, i, line, Environment.NewLine)); } break; } case "int": case "word": { try { foreach (string a in args) { _bytes.AddRange(EndianBitConverter.Int32ToBytes(ParseInt(a), Endianness)); } } catch { throw new ArithmeticException(string.Format(_mathErrorFormat, fileName, i, line, Environment.NewLine)); } break; } case "end": { goto end; } case "section": // Ignore { break; } default: throw new NotSupportedException(string.Format(_cmdErrorFormat, fileName, i, cmd, Environment.NewLine)); } } end: return($"{fileName} loaded with no issues"); }