/// <summary> /// Sets up the annotations for the current machine. /// </summary> public void SetupMachineAnnotations() { // --- Read ROM annotations var spectrumVm = Parent.SpectrumVm; RomPageAnnotations = new Dictionary <int, DisassemblyAnnotation>(); RomAnnotationFiles = new Dictionary <int, string>(); var romConfig = spectrumVm.RomConfiguration; var roms = romConfig.NumberOfRoms; for (var i = 0; i < roms; i++) { var annFile = spectrumVm.RomProvider.GetAnnotationResourceName(romConfig.RomName, roms == 1 ? -1 : i); var annData = spectrumVm.RomProvider.LoadRomAnnotations(romConfig.RomName, roms == 1 ? -1 : i); DisassemblyAnnotation.Deserialize(annData, out var annotation); RomPageAnnotations.Add(i, annotation); RomAnnotationFiles.Add(i, annFile); } // --- Read the initial RAM annotations RamBankAnnotations = new Dictionary <int, DisassemblyAnnotation>(); SpectNetPackage.Default.CodeManager.AnnotationFileChanged += OnAnnotationFileChanged; OnAnnotationFileChanged(null, EventArgs.Empty); // --- Register Disassembly providers to use if (RomPageAnnotations.TryGetValue(romConfig.Spectrum48RomIndex, out var spectrumRomAnn)) { Z80Disassembler.SetProvider <ISpectrum48RomLabelProvider>( new Spectrum48RomLabelProvider(spectrumRomAnn)); } }
/// <summary> /// Loads the ROM information for the specified workspace /// </summary> private static void LoadRom(WorkspaceInfo workspace) { var rom = workspace.RomItem; if (rom == null) { return; } var romAnnotationFile = Path.Combine( Path.GetDirectoryName(rom.Filename), Path.GetFileNameWithoutExtension(rom.Filename)) + ".disann"; if (!File.Exists(romAnnotationFile)) { return; } // --- Get the contents of the annotation file var serialized = File.ReadAllText(romAnnotationFile); var annotations = DisassemblyAnnotation.Deserialize(serialized); workspace.RomInfo = new RomInfo { MemorySections = new List <MemorySection>(annotations.MemoryMap), LoadBytesInvalidHeaderAddress = annotations.Literals .FirstOrDefault(kvp => kvp.Value.Contains("$LoadBytesInvalidHeaderAddress")).Key, LoadBytesResumeAddress = annotations.Literals .FirstOrDefault(kvp => kvp.Value.Contains("$LoadBytesResumeAddress")).Key, LoadBytesRoutineAddress = annotations.Literals .FirstOrDefault(kvp => kvp.Value.Contains("$LoadBytesRoutineAddress")).Key, SaveBytesRoutineAddress = annotations.Literals .FirstOrDefault(kvp => kvp.Value.Contains("$SaveBytesRoutineAddress")).Key, SaveBytesResumeAddress = annotations.Literals .FirstOrDefault(kvp => kvp.Value.Contains("$SaveBytesResumeAddress")).Key, TokenTableAddress = annotations.Literals .FirstOrDefault(kvp => kvp.Value.Contains("$TokenTableAddress")).Key, TokenCount = annotations.Literals .FirstOrDefault(kvp => kvp.Value.Contains("$TokenCount")).Key, TokenOffset = annotations.Literals .FirstOrDefault(kvp => kvp.Value.Contains("$TokenOffset")).Key, TokenTable = new List <string>() }; // --- Get the content of the ROM file using (var stream = new StreamReader(rom.Filename).BaseStream) { stream.Seek(0, SeekOrigin.Begin); var bytes = new byte[stream.Length]; stream.Read(bytes, 0, bytes.Length); workspace.RomInfo.RomBytes = bytes; } // --- Read the list of tokens from the ROM ReadTokenTable(workspace.RomInfo); }
public void SerializationWorksAsExpected() { // --- Arrange var dc = new DisassemblyAnnotation(); dc.SetLabel(0x0100, "FirstLabel"); dc.SetLabel(0x0200, "SecondLabel"); dc.SetComment(0x0100, "FirstComment"); dc.SetComment(0x0200, "SecondComment"); dc.SetPrefixComment(0x0100, "FirstPrefixComment"); dc.SetPrefixComment(0x0200, "SecondPrefixComment"); dc.AddLiteral(0x0000, "Entry"); dc.AddLiteral(0x0000, "Start"); dc.AddLiteral(0x0028, "Calculator"); dc.MemoryMap.Add(new MemorySection(0x0000, 0x3BFF)); dc.MemoryMap.Add(new MemorySection(0x3C00, 0x3FFF, MemorySectionType.ByteArray)); dc.SetLiteralReplacement(0x100, "Entry"); dc.SetLiteralReplacement(0x1000, "Calculator"); // --- Act var serialized = dc.Serialize(); DisassemblyAnnotation.Deserialize(serialized, out var back); // --- Assert dc.Labels.Count.ShouldBe(back.Labels.Count); foreach (var item in dc.Labels) { back.Labels[item.Key].ShouldBe(item.Value); } dc.Comments.Count.ShouldBe(back.Comments.Count); foreach (var item in dc.Comments) { back.Comments[item.Key].ShouldBe(item.Value); } dc.PrefixComments.Count.ShouldBe(back.PrefixComments.Count); foreach (var item in dc.PrefixComments) { back.PrefixComments[item.Key].ShouldBe(item.Value); } dc.Literals.Count.ShouldBe(back.Literals.Count); foreach (var item in dc.Literals) { back.Literals[item.Key].ForEach(v => dc.Literals[item.Key].ShouldContain(v)); dc.Literals[item.Key].ForEach(v => back.Literals[item.Key].ShouldContain(v)); } dc.LiteralReplacements.Count.ShouldBe(back.LiteralReplacements.Count); foreach (var item in dc.LiteralReplacements) { back.LiteralReplacements[item.Key].ShouldBe(item.Value); } dc.MemoryMap.Count.ShouldBe(back.MemoryMap.Count); for (var i = 0; i < dc.MemoryMap.Count; i++) { dc.MemoryMap[i].ShouldBe(back.MemoryMap[i]); } }
/// <summary> /// Restores the annotations from the ROM annotation and current project /// annotation files. /// </summary> public void RestoreAnnotations() { if (RomAnnotationFile != null) { var romSerialized = File.ReadAllText(RomAnnotationFile); RomAnnotations = DisassemblyAnnotation.Deserialize(romSerialized); } if (ProjectAnnotationFile != null) { var projectSerialized = File.ReadAllText(ProjectAnnotationFile); ProjectAnnotations = DisassemblyAnnotation.Deserialize(projectSerialized); } Remerge(); }
/// <summary> /// Execute loading and processing the file /// </summary> /// <param name="fileName">The name of the file to load</param> protected override void LoadFile(string fileName) { // --- Read the .disann file _contents = File.ReadAllText(fileName); if (DisassemblyAnnotation.DeserializeBankAnnotations(_contents, out var anns)) { _annotations = anns; } else { _annotations = new Dictionary <int, DisassemblyAnnotation>(); if (DisassemblyAnnotation.Deserialize(_contents, out var single)) { _annotations.Add(0, single); } } }
/// <summary> /// Gets the content of the ROM specified by its resource name /// </summary> /// <param name="romResourceName">ROM resource name</param> /// <returns>Content of the ROM</returns> public RomInfo LoadRom(string romResourceName) { RomInfo result; // --- Obtain the ROM annotations var resMan = GetFileResource(ResourceAssembly, romResourceName, ".disann"); if (resMan == null) { throw new InvalidOperationException($"Input stream for the '{romResourceName}' .disann file not found."); } using (var reader = new StreamReader(resMan)) { var serialized = reader.ReadToEnd(); var annotations = DisassemblyAnnotation.Deserialize(serialized); result = new RomInfo { MemorySections = new List <MemorySection>(annotations.MemoryMap), Annotations = annotations, LoadBytesInvalidHeaderAddress = annotations.Literals.FirstOrDefault(kvp => kvp.Value.Contains("$LoadBytesInvalidHeaderAddress")).Key, LoadBytesResumeAddress = annotations.Literals.FirstOrDefault(kvp => kvp.Value.Contains("$LoadBytesResumeAddress")).Key, LoadBytesRoutineAddress = annotations.Literals.FirstOrDefault(kvp => kvp.Value.Contains("$LoadBytesRoutineAddress")).Key, SaveBytesRoutineAddress = annotations.Literals.FirstOrDefault(kvp => kvp.Value.Contains("$SaveBytesRoutineAddress")).Key, SaveBytesResumeAddress = annotations.Literals.FirstOrDefault(kvp => kvp.Value.Contains("$SaveBytesResumeAddress")).Key, MainExecAddress = annotations.Literals.FirstOrDefault(kvp => kvp.Value.Contains("$MainExecAddress")).Key }; } // --- Obtain the ROM contents resMan = GetFileResource(ResourceAssembly, romResourceName, ".rom"); if (resMan == null) { throw new InvalidOperationException($"Input stream for the '{romResourceName}' .rom file not found."); } using (var stream = new StreamReader(resMan).BaseStream) { stream.Seek(0, SeekOrigin.Begin); var bytes = new byte[stream.Length]; stream.Read(bytes, 0, bytes.Length); result.RomBytes = bytes; } return(result); }