/// <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));
            }
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        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]);
            }
        }
Пример #4
0
        /// <summary>
        /// Saves the contents of annotations
        /// </summary>
        public void SaveAnnotations(DisassemblyAnnotation annotation, string filename)
        {
            if (annotation == null || filename == null)
            {
                return;
            }

            var annotationData = annotation.Serialize();

            File.WriteAllText(filename, annotationData);
        }
        public void ConstructorWorksAsExpected()
        {
            // --- Act
            var dc = new DisassemblyAnnotation();

            // --- Assert
            dc.Labels.Count.ShouldBe(0);
            dc.Comments.Count.ShouldBe(0);
            dc.PrefixComments.Count.ShouldBe(0);
            dc.Literals.Count.ShouldBe(0);
        }
Пример #6
0
 /// <summary>
 /// Remerges annotations
 /// </summary>
 private void Remerge()
 {
     MergedAnnotations = new DisassemblyAnnotation();
     if (RomAnnotationFile != null)
     {
         MergedAnnotations.Merge(RomAnnotations);
     }
     if (ProjectAnnotations != null)
     {
         MergedAnnotations.Merge(ProjectAnnotations);
     }
 }
        public void CreateLabelDoesNotSaveInvalidLabel()
        {
            // --- Arrange
            const string LABEL = "My$$Label$$";
            var          dc    = new DisassemblyAnnotation();

            // --- Act
            var result = dc.SetLabel(0x1000, LABEL);

            // --- Assert
            result.ShouldBe(false);
            dc.Labels.Count.ShouldBe(0);
        }
        public void CreateLabelTruncatesTooLongLabel()
        {
            // --- Arrange
            const string LABEL = "Label012345678901234567890123456789";
            var          dc    = new DisassemblyAnnotation();

            // --- Act
            var result = dc.SetLabel(0x1000, LABEL);

            // --- Assert
            result.ShouldBe(true);
            dc.Labels.Count.ShouldBe(1);
            dc.Labels[0x1000].ShouldBe(LABEL.Substring(0, DisassemblyAnnotation.MAX_LABEL_LENGTH));
        }
        public void CreateReplacementWorksAsExpected()
        {
            // --- Arrange
            const string REPLACEMENT = "MyReplacement";
            var          dc          = new DisassemblyAnnotation();

            // --- Act
            var result = dc.SetLiteralReplacement(0x1000, REPLACEMENT);

            // --- Assert
            result.ShouldBe(true);
            dc.LiteralReplacements.Count.ShouldBe(1);
            dc.LiteralReplacements[0x1000].ShouldBe(REPLACEMENT);
        }
Пример #10
0
 /// <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();
 }
        public void CreateLabelWorksAsExpected()
        {
            // --- Arrange
            const string LABEL = "MyLabel";
            var          dc    = new DisassemblyAnnotation();

            // --- Act
            var result = dc.SetLabel(0x1000, LABEL);

            // --- Assert
            result.ShouldBe(true);
            dc.Labels.Count.ShouldBe(1);
            dc.Labels[0x1000].ShouldBe(LABEL);
        }
        public void CreatePrefixCommentWorksAsExpected()
        {
            // --- Arrange
            const string COMMENT = "MyComment";
            var          dc      = new DisassemblyAnnotation();

            // --- Act
            var result = dc.SetPrefixComment(0x1000, COMMENT);

            // --- Assert
            result.ShouldBe(true);
            dc.PrefixComments.Count.ShouldBe(1);
            dc.PrefixComments[0x1000].ShouldBe(COMMENT);
        }
        public void CreatePrefixCommentHandlesNoRemove()
        {
            // --- Arrange
            const string COMMENT = "MyComment";
            var          dc      = new DisassemblyAnnotation();

            dc.SetPrefixComment(0x1000, COMMENT);

            // --- Act
            var result = dc.SetPrefixComment(0x2000, null);

            // --- Assert
            result.ShouldBe(false);
            dc.PrefixComments.Count.ShouldBe(1);
        }
        public void CreatePrefixCommentRemovesWhitespaceComment()
        {
            // --- Arrange
            const string COMMENT = "MyComment";
            var          dc      = new DisassemblyAnnotation();

            dc.SetPrefixComment(0x1000, COMMENT);

            // --- Act
            var result = dc.SetPrefixComment(0x1000, "   \t\t \r ");

            // --- Assert
            result.ShouldBe(true);
            dc.PrefixComments.Count.ShouldBe(0);
        }
        public void CreateReplacementRemovesWhitespaceReplacement()
        {
            // --- Arrange
            const string REPLACEMENT = "MyReplacement";
            var          dc          = new DisassemblyAnnotation();

            dc.SetLiteralReplacement(0x1000, REPLACEMENT);

            // --- Act
            var result = dc.SetLiteralReplacement(0x1000, "   ");

            // --- Assert
            result.ShouldBe(true);
            dc.LiteralReplacements.Count.ShouldBe(0);
        }
        public void CreateLabelHandlesNoRemove()
        {
            // --- Arrange
            const string LABEL = "MyLabel";
            var          dc    = new DisassemblyAnnotation();

            dc.SetLabel(0x1000, LABEL);

            // --- Act
            var result = dc.SetLabel(0x2000, null);

            // --- Assert
            result.ShouldBe(false);
            dc.Labels.Count.ShouldBe(1);
        }
        public void CreateLabelRemovesWhitespaceLabel()
        {
            // --- Arrange
            const string LABEL = "MyLabel";
            var          dc    = new DisassemblyAnnotation();

            dc.SetLabel(0x1000, LABEL);

            // --- Act
            var result = dc.SetLabel(0x1000, "   \t\t \r ");

            // --- Assert
            result.ShouldBe(true);
            dc.Labels.Count.ShouldBe(0);
        }
        public void CreateReplacementHandlesNoRemove()
        {
            // --- Arrange
            const string REPLACEMENT = "MyReplacement";
            var          dc          = new DisassemblyAnnotation();

            dc.SetLiteralReplacement(0x1000, REPLACEMENT);

            // --- Act
            var result = dc.SetComment(0x2000, null);

            // --- Assert
            result.ShouldBe(false);
            dc.LiteralReplacements.Count.ShouldBe(1);
        }
        public void ApplyLiteralCanRemoveReplacement()
        {
            // --- Arrange
            const string REPLACEMENT = "MyReplacement";
            var          dc          = new DisassemblyAnnotation();

            dc.SetLiteralReplacement(0x1000, REPLACEMENT);

            // --- Act
            var result = dc.ApplyLiteral(0x1000, 0x0000, null);

            // --- Assert
            result.ShouldBeNull();
            dc.LiteralReplacements.Count.ShouldBe(0);
        }
        public void CreateCommentRemovesNullComment()
        {
            // --- Arrange
            const string COMMENT = "MyComment";
            var          dc      = new DisassemblyAnnotation();

            dc.SetComment(0x1000, COMMENT);

            // --- Act
            var result = dc.SetComment(0x1000, null);

            // --- Assert
            result.ShouldBe(true);
            dc.Comments.Count.ShouldBe(0);
        }
        public void RemoveLiteralWorksAsExpected()
        {
            // --- Arrange
            const string LABEL = "MyLabel";
            var          dc    = new DisassemblyAnnotation();

            dc.AddLiteral(0x1000, LABEL);

            // --- Act
            var result = dc.RemoveLiteral(0x1000, LABEL);

            // --- Assert
            result.ShouldBe(true);
            dc.Literals.Count.ShouldBe(0);
        }
Пример #22
0
        public void GenerateSpectrum48Annotations()
        {
            // --- Arrange
            var dc = new DisassemblyAnnotation();

            dc.MemoryMap.Add(new MemorySection(0x0000, 0x3BFF));
            dc.MemoryMap.Add(new MemorySection(0x3C00, 0x3FFF));
            dc.AddLiteral(0x04C2, "$SaveBytesRoutineAddress");
            dc.AddLiteral(0x0000, "$SaveBytesResumeAddress");
            dc.AddLiteral(0x056C, "$LoadBytesRoutineAddress");
            dc.AddLiteral(0x05E2, "$LoadBytesResumeAddress");
            dc.AddLiteral(0x05B6, "$LoadBytesInvalidHeaderAddress");

            // --- Act
            Console.WriteLine(dc.Serialize());
        }
        public void CreateLabelForbidsDuplicateLabelName()
        {
            // --- Arrange
            const string LABEL = "MyLabel";
            var          dc    = new DisassemblyAnnotation();

            dc.SetLabel(0x1000, LABEL);

            // --- Act
            var result = dc.SetLabel(0x1100, LABEL);

            // --- Assert
            result.ShouldBe(false);
            dc.Labels.Count.ShouldBe(1);
            dc.Labels[0x1000].ShouldBe(LABEL);
        }
        public void ApplyLiteralCreatesNewSymbol()
        {
            // --- Arrange
            const string REPLACEMENT = "MyReplacement";
            var          dc          = new DisassemblyAnnotation();

            // --- Act
            var result = dc.ApplyLiteral(0x1000, 0x2000, REPLACEMENT);

            // --- Assert
            result.ShouldBeNull();
            dc.Literals[0x2000].Count.ShouldBe(1);
            dc.Literals[0x2000][0].ShouldBe(REPLACEMENT);
            dc.LiteralReplacements.Count.ShouldBe(1);
            dc.LiteralReplacements[0x1000].ShouldBe(REPLACEMENT);
        }
Пример #25
0
 /// <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);
         }
     }
 }
        public void CreateCommentOverwritesExistingComment()
        {
            // --- Arrange
            const string COMMENT  = "MyComment";
            const string COMMENT2 = "MyComment2";
            var          dc       = new DisassemblyAnnotation();

            dc.SetComment(0x1000, COMMENT);

            // --- Act
            var result = dc.SetComment(0x1000, COMMENT2);

            // --- Assert
            result.ShouldBe(true);
            dc.Comments.Count.ShouldBe(1);
            dc.Comments[0x1000].ShouldBe(COMMENT2);
        }
        public void CreateLabelOverwritesExistingLabel()
        {
            // --- Arrange
            const string LABEL  = "MyLabel";
            const string LABEL2 = "MyLabel2";
            var          dc     = new DisassemblyAnnotation();

            dc.SetLabel(0x1000, LABEL);

            // --- Act
            var result = dc.SetLabel(0x1000, LABEL2);

            // --- Assert
            result.ShouldBe(true);
            dc.Labels.Count.ShouldBe(1);
            dc.Labels[0x1000].ShouldBe(LABEL2);
        }
        public void AddLiteralWorksAsExpected()
        {
            // --- Arrange
            const string LABEL = "MyLabel";
            var          dc    = new DisassemblyAnnotation();

            // --- Act
            var result = dc.AddLiteral(0x1000, LABEL);

            // --- Assert
            result.ShouldBe(true);
            dc.Literals.Count.ShouldBe(1);
            var literals = dc.Literals[0x1000];

            literals.Count.ShouldBe(1);
            literals.ShouldContain(l => l == LABEL);
        }
Пример #29
0
        /// <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);
        }
        /// <summary>
        /// Updates the RAM annotation file according to changes
        /// </summary>
        private void OnAnnotationFileChanged(object sender, EventArgs eventArgs)
        {
            var project = SpectNetPackage.Default.ActiveProject;
            var annFile = project?.DefaultAnnotationItem
                          ?? project?.AnnotationProjectItems?.FirstOrDefault();

            RamBankAnnotations.Clear();
            if (annFile == null)
            {
                return;
            }

            RamBankAnnotationFile = annFile.Filename;
            var disAnn = File.ReadAllText(annFile.Filename);

            DisassemblyAnnotation.DeserializeBankAnnotations(disAnn, out var annotations);
            RamBankAnnotations = annotations;
        }