InstructionBreakPoint.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89: package xeij;
90:
91: import java.lang.*;
92: import java.util.*;
93:
94: public class InstructionBreakPoint {
95:
96: public static final boolean IBP_ON = true;
97:
98:
99: public static final int IBP_HASH_BITS = 8;
100: public static final int IBP_HASH_SIZE = 1 << IBP_HASH_BITS;
101: public static final int IBP_HASH_MASK = IBP_HASH_SIZE - 1;
102:
103:
104: public static MemoryMappedDevice[] ibpUserMap;
105: public static MemoryMappedDevice[] ibpSuperMap;
106:
107: public static MemoryMappedDevice[] ibpOp1UserMap;
108: public static MemoryMappedDevice[] ibpOp1SuperMap;
109: public static MemoryMappedDevice[] ibpOp1MemoryMap;
110:
111:
112: public static class InstructionBreakRecord {
113: public int ibrLogicalAddress;
114: public int ibrPhysicalAddress;
115: public int ibrThreshold;
116: public int ibrValue;
117: public int ibrTarget;
118: public InstructionBreakRecord ibrNext;
119: public ExpressionEvaluator.ExpressionElement ibrScriptElement;
120: }
121:
122:
123: public static TreeMap<Integer,InstructionBreakRecord> ibpUserPointTable;
124: public static TreeMap<Integer,InstructionBreakRecord> ibpSuperPointTable;
125:
126: public static InstructionBreakRecord[] ibpUserHashTable;
127: public static InstructionBreakRecord[] ibpSuperHashTable;
128:
129:
130:
131: public static void ibpInit () {
132: if (IBP_ON) {
133: ibpUserMap = new MemoryMappedDevice[XEiJ.BUS_PAGE_COUNT];
134: ibpSuperMap = new MemoryMappedDevice[XEiJ.BUS_PAGE_COUNT];
135: Arrays.fill (ibpUserMap, MemoryMappedDevice.MMD_NUL);
136: Arrays.fill (ibpSuperMap, MemoryMappedDevice.MMD_NUL);
137: ibpOp1UserMap = XEiJ.busUserMap;
138: ibpOp1SuperMap = XEiJ.busSuperMap;
139: ibpOp1MemoryMap = ibpOp1SuperMap;
140: ibpUserPointTable = new TreeMap<Integer,InstructionBreakRecord> ();
141: ibpSuperPointTable = new TreeMap<Integer,InstructionBreakRecord> ();
142: ibpUserHashTable = new InstructionBreakRecord[IBP_HASH_SIZE];
143: ibpSuperHashTable = new InstructionBreakRecord[IBP_HASH_SIZE];
144: }
145: }
146:
147:
148:
149: public static void ibpReset () {
150: if (IBP_ON) {
151: for (InstructionBreakRecord r : ibpUserPointTable.values ()) {
152: r.ibrValue = 0;
153: r.ibrTarget = r.ibrThreshold < 0 ? 0 : r.ibrThreshold;
154: }
155: for (InstructionBreakRecord r : ibpSuperPointTable.values ()) {
156: r.ibrValue = 0;
157: r.ibrTarget = r.ibrThreshold < 0 ? 0 : r.ibrThreshold;
158: }
159: }
160: }
161:
162:
163:
164:
165: public static void ibpInstant (int logicalAddress, int supervisor) {
166: if (IBP_ON) {
167: TreeMap<Integer,InstructionBreakRecord> pointTable = supervisor != 0 ? ibpSuperPointTable : ibpUserPointTable;
168: InstructionBreakRecord r = pointTable.get (logicalAddress);
169: if (r == null) {
170: ibpPut (logicalAddress, supervisor, 0, -1, null);
171: } else {
172: r.ibrTarget = r.ibrLogicalAddress == logicalAddress ? r.ibrValue + 1 : r.ibrValue;
173: }
174: }
175: }
176:
177:
178:
179:
180:
181: public static void ibpPut (int logicalAddress, int supervisor, int value, int threshold,
182: ExpressionEvaluator.ExpressionElement scriptElement) {
183: if (IBP_ON) {
184: int physicalAddress = MC68060.mmuTranslatePeek (logicalAddress, supervisor, 0);
185: if ((logicalAddress ^ physicalAddress) == 1) {
186: return;
187: }
188: TreeMap<Integer,InstructionBreakRecord> pointTable = supervisor != 0 ? ibpSuperPointTable : ibpUserPointTable;
189: InstructionBreakRecord r = pointTable.get (logicalAddress);
190: if (r == null) {
191:
192: if (pointTable.isEmpty ()) {
193: if (supervisor != 0) {
194: ibpOp1SuperMap = ibpSuperMap;
195: } else {
196: ibpOp1UserMap = ibpUserMap;
197: }
198: ibpOp1MemoryMap = XEiJ.regSRS != 0 ? ibpOp1SuperMap : ibpOp1UserMap;
199: }
200:
201: r = new InstructionBreakRecord ();
202: r.ibrLogicalAddress = logicalAddress;
203: r.ibrPhysicalAddress = physicalAddress;
204:
205: pointTable.put (logicalAddress, r);
206:
207: {
208: InstructionBreakRecord[] hashTable = supervisor != 0 ? ibpSuperHashTable : ibpUserHashTable;
209: int h = physicalAddress >>> 1 & IBP_HASH_MASK;
210: r.ibrNext = hashTable[h];
211: hashTable[h] = r;
212: }
213:
214: {
215: int p = physicalAddress >>> XEiJ.BUS_PAGE_BITS;
216: if (supervisor != 0) {
217: ibpSuperMap[p] = MemoryMappedDevice.MMD_IBP;
218: } else {
219: ibpUserMap[p] = MemoryMappedDevice.MMD_IBP;
220: }
221: }
222: }
223: r.ibrValue = value;
224: r.ibrTarget = threshold < 0 ? 0 : threshold;
225: r.ibrThreshold = threshold;
226: r.ibrScriptElement = scriptElement;
227: }
228: }
229:
230:
231:
232: public static void ibpRemove (int logicalAddress, int supervisor) {
233: if (IBP_ON) {
234: int physicalAddress = MC68060.mmuTranslatePeek (logicalAddress, supervisor, 0);
235: if ((logicalAddress ^ physicalAddress) == 1) {
236: return;
237: }
238: TreeMap<Integer,InstructionBreakRecord> pointTable = supervisor != 0 ? ibpSuperPointTable : ibpUserPointTable;
239: InstructionBreakRecord r = pointTable.get (logicalAddress);
240: if (r != null) {
241:
242: {
243: InstructionBreakRecord[] hashTable = supervisor != 0 ? ibpSuperHashTable : ibpUserHashTable;
244: int h = physicalAddress >>> 1 & IBP_HASH_MASK;
245: InstructionBreakRecord t = hashTable[h];
246: if (t == r) {
247: hashTable[h] = r.ibrNext;
248: } else {
249: for (; t.ibrNext != r; t = t.ibrNext) {
250: }
251: t.ibrNext = r.ibrNext;
252: }
253: r.ibrNext = null;
254: }
255:
256: {
257: int p = physicalAddress >>> XEiJ.BUS_PAGE_BITS;
258: boolean more = false;
259: for (InstructionBreakRecord t : pointTable.values ()) {
260: if (t.ibrPhysicalAddress >>> XEiJ.BUS_PAGE_BITS == p) {
261: more = true;
262: break;
263: }
264: }
265: if (supervisor != 0) {
266: ibpSuperMap[p] = more ? MemoryMappedDevice.MMD_IBP : XEiJ.busSuperMap[p];
267: } else {
268: ibpUserMap[p] = more ? MemoryMappedDevice.MMD_IBP : XEiJ.busUserMap[p];
269: }
270: }
271:
272: pointTable.remove (logicalAddress);
273:
274: if (pointTable.isEmpty ()) {
275: if (supervisor != 0) {
276: ibpOp1SuperMap = XEiJ.busSuperMap;
277: } else {
278: ibpOp1UserMap = XEiJ.busUserMap;
279: }
280: ibpOp1MemoryMap = XEiJ.regSRS != 0 ? ibpOp1SuperMap : ibpOp1UserMap;
281: }
282: }
283: }
284: }
285:
286: }
287:
288:
289: