1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Mesen.GUI.Debugger 8 { 9 public class CodeInfo 10 { 11 public int[] LineNumbers { get; private set; } 12 public string[] LineNumberNotes { get; private set; } 13 public char[] LineMemoryType { get; private set; } 14 public int[] AbsoluteLineNumbers { get; private set; } 15 public string[] CodeNotes { get; private set; } 16 public string[] CodeLines { get; private set; } 17 public HashSet<int> UnexecutedAddresses { get; private set; } 18 public HashSet<int> VerifiedDataAddresses { get; private set; } 19 public HashSet<int> SpeculativeCodeAddreses { get; private set; } 20 public Dictionary<int, string> CodeContent { get; private set; } 21 public Dictionary<int, string> CodeByteCode { get; private set; } 22 public string[] Addressing { get; private set; } 23 public string[] Comments { get; private set; } 24 public int[] LineIndentations { get; private set; } 25 CodeInfo(string code)26 public CodeInfo(string code) 27 { 28 string[] token = code.Split('\x1'); 29 30 int lineCount = token.Length / 8; 31 LineNumbers = new int[lineCount]; 32 LineNumberNotes = new string[lineCount]; 33 LineMemoryType = new char[lineCount]; 34 AbsoluteLineNumbers = new int[lineCount]; 35 CodeNotes = new string[lineCount]; 36 CodeLines = new string[lineCount]; 37 Addressing = new string[lineCount]; 38 Comments = new string[lineCount]; 39 LineIndentations = new int[lineCount]; 40 41 UnexecutedAddresses = new HashSet<int>(); 42 VerifiedDataAddresses = new HashSet<int>(); 43 SpeculativeCodeAddreses = new HashSet<int>(); 44 45 int tokenIndex = 0; 46 int lineNumber = 0; 47 48 while(tokenIndex < token.Length - 8) { 49 int relativeAddress = ParseHexAddress(token[tokenIndex + 1]); 50 51 //Flags: 52 //1: Executed code 53 //2: Speculative Code 54 //4: Indented line 55 switch(token[tokenIndex][0]) { 56 case '2': 57 SpeculativeCodeAddreses.Add(lineNumber); 58 LineIndentations[lineNumber] = 0; 59 break; 60 61 case '4': 62 UnexecutedAddresses.Add(lineNumber); 63 LineIndentations[lineNumber] = 20; 64 break; 65 66 case '6': 67 SpeculativeCodeAddreses.Add(lineNumber); 68 LineIndentations[lineNumber] = 20; 69 break; 70 71 case '5': 72 LineIndentations[lineNumber] = 20; 73 break; 74 75 case '8': 76 VerifiedDataAddresses.Add(lineNumber); 77 LineIndentations[lineNumber] = 0; 78 break; 79 80 case '9': 81 VerifiedDataAddresses.Add(lineNumber); 82 LineIndentations[lineNumber] = 20; 83 break; 84 85 default: 86 LineIndentations[lineNumber] = 0; 87 break; 88 } 89 90 LineNumbers[lineNumber] = relativeAddress; 91 LineMemoryType[lineNumber] = token[tokenIndex + 2][0]; 92 LineNumberNotes[lineNumber] = token[tokenIndex + 3]; 93 AbsoluteLineNumbers[lineNumber] = this.ParseHexAddress(token[tokenIndex + 3]); 94 CodeNotes[lineNumber] = token[tokenIndex + 4]; 95 CodeLines[lineNumber] = token[tokenIndex + 5]; 96 97 Addressing[lineNumber] = token[tokenIndex + 6]; 98 Comments[lineNumber] = token[tokenIndex + 7]; 99 100 101 lineNumber++; 102 tokenIndex += 8; 103 } 104 } 105 InitAssemblerValues()106 public void InitAssemblerValues() 107 { 108 if(CodeContent == null) { 109 CodeContent = new Dictionary<int, string>(LineNumbers.Length); 110 CodeByteCode = new Dictionary<int, string>(LineNumbers.Length); 111 112 for(int i = 0; i < LineNumbers.Length; i++) { 113 //Used by assembler 114 int relativeAddress = LineNumbers[i]; 115 CodeByteCode[relativeAddress] = CodeNotes[i]; 116 CodeContent[relativeAddress] = CodeLines[i]; 117 } 118 } 119 } 120 ParseHexAddress(string hexAddress)121 private int ParseHexAddress(string hexAddress) 122 { 123 if(string.IsNullOrWhiteSpace(hexAddress)) { 124 return -1; 125 } else { 126 return HexConverter.FromHex(hexAddress); 127 } 128 } 129 } 130 } 131