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