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:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101: package xeij;
102:
103: import java.lang.*;
104: import java.util.*;
105:
106: public class InstructionBreakPoint {
107:
108: public static final boolean IBP_ON = true;
109:
110:
111: public static final int IBP_HASH_BITS = 8;
112: public static final int IBP_HASH_SIZE = 1 << IBP_HASH_BITS;
113: public static final int IBP_HASH_MASK = IBP_HASH_SIZE - 1;
114:
115:
116: public static MemoryMappedDevice[] ibpUserMap;
117: public static MemoryMappedDevice[] ibpSuperMap;
118:
119: public static MemoryMappedDevice[] ibpOp1UserMap;
120: public static MemoryMappedDevice[] ibpOp1SuperMap;
121: public static MemoryMappedDevice[] ibpOp1MemoryMap;
122:
123:
124: public static class InstructionBreakRecord {
125: public int ibrLogicalAddress;
126: public int ibrPhysicalAddress;
127: public int ibrThreshold;
128: public int ibrValue;
129: public int ibrTarget;
130: public InstructionBreakRecord ibrNext;
131: public ExpressionEvaluator.ExpressionElement ibrScriptElement;
132: public WaitInstruction ibrWaitInstruction;
133: }
134:
135:
136: public static TreeMap<Integer,InstructionBreakRecord> ibpUserPointTable;
137: public static TreeMap<Integer,InstructionBreakRecord> ibpSuperPointTable;
138:
139: public static InstructionBreakRecord[] ibpUserHashTable;
140: public static InstructionBreakRecord[] ibpSuperHashTable;
141:
142:
143:
144: public static void ibpInit () {
145: if (IBP_ON) {
146: ibpUserMap = new MemoryMappedDevice[XEiJ.BUS_PAGE_COUNT];
147: ibpSuperMap = new MemoryMappedDevice[XEiJ.BUS_PAGE_COUNT];
148: Arrays.fill (ibpUserMap, MemoryMappedDevice.MMD_NUL);
149: Arrays.fill (ibpSuperMap, MemoryMappedDevice.MMD_NUL);
150: ibpOp1UserMap = XEiJ.busUserMap;
151: ibpOp1SuperMap = XEiJ.busSuperMap;
152: ibpOp1MemoryMap = ibpOp1SuperMap;
153: ibpUserPointTable = new TreeMap<Integer,InstructionBreakRecord> ();
154: ibpSuperPointTable = new TreeMap<Integer,InstructionBreakRecord> ();
155: ibpUserHashTable = new InstructionBreakRecord[IBP_HASH_SIZE];
156: ibpSuperHashTable = new InstructionBreakRecord[IBP_HASH_SIZE];
157: }
158: }
159:
160:
161:
162: public static void ibpReset () {
163: if (IBP_ON) {
164: for (InstructionBreakRecord r : ibpUserPointTable.values ()) {
165: r.ibrValue = 0;
166: r.ibrTarget = r.ibrThreshold < 0 ? 0 : r.ibrThreshold;
167: }
168: for (InstructionBreakRecord r : ibpSuperPointTable.values ()) {
169: r.ibrValue = 0;
170: r.ibrTarget = r.ibrThreshold < 0 ? 0 : r.ibrThreshold;
171: }
172: }
173: }
174:
175:
176:
177: public static void ibpAddWaitPoint (int logicalAddress, int supervisor, WaitInstruction waitInstruction) {
178: if (IBP_ON) {
179: TreeMap<Integer,InstructionBreakRecord> pointTable = supervisor != 0 ? ibpSuperPointTable : ibpUserPointTable;
180: InstructionBreakRecord r = pointTable.get (logicalAddress);
181: if (r == null) {
182: ibpPut (logicalAddress, supervisor, 0, 0x7fffffff, null);
183: }
184: r.ibrWaitInstruction = waitInstruction;
185: }
186: }
187:
188:
189:
190: public static void ibpRemoveWaitPoint (int logicalAddress, int supervisor) {
191: if (IBP_ON) {
192: TreeMap<Integer,InstructionBreakRecord> pointTable = supervisor != 0 ? ibpSuperPointTable : ibpUserPointTable;
193: InstructionBreakRecord r = pointTable.get (logicalAddress);
194: if (r != null) {
195: r.ibrWaitInstruction = null;
196: if (r.ibrThreshold == 0x7fffffff) {
197: ibpRemove (logicalAddress, supervisor);
198: }
199: }
200: }
201: }
202:
203:
204:
205:
206: public static void ibpInstant (int logicalAddress, int supervisor) {
207: if (IBP_ON) {
208: TreeMap<Integer,InstructionBreakRecord> pointTable = supervisor != 0 ? ibpSuperPointTable : ibpUserPointTable;
209: InstructionBreakRecord r = pointTable.get (logicalAddress);
210: if (r == null) {
211: ibpPut (logicalAddress, supervisor, 0, -1, null);
212: } else {
213: r.ibrTarget = r.ibrLogicalAddress == logicalAddress ? r.ibrValue + 1 : r.ibrValue;
214: }
215: }
216: }
217:
218:
219:
220:
221:
222: public static void ibpPut (int logicalAddress, int supervisor, int value, int threshold,
223: ExpressionEvaluator.ExpressionElement scriptElement) {
224: if (IBP_ON) {
225: int physicalAddress = MC68060.mmuTranslatePeek (logicalAddress, supervisor, 0);
226: if ((logicalAddress ^ physicalAddress) == 1) {
227: return;
228: }
229: TreeMap<Integer,InstructionBreakRecord> pointTable = supervisor != 0 ? ibpSuperPointTable : ibpUserPointTable;
230: InstructionBreakRecord r = pointTable.get (logicalAddress);
231: if (r == null) {
232:
233: if (pointTable.isEmpty ()) {
234: if (supervisor != 0) {
235: ibpOp1SuperMap = ibpSuperMap;
236: } else {
237: ibpOp1UserMap = ibpUserMap;
238: }
239: ibpOp1MemoryMap = XEiJ.regSRS != 0 ? ibpOp1SuperMap : ibpOp1UserMap;
240: }
241:
242: r = new InstructionBreakRecord ();
243: r.ibrLogicalAddress = logicalAddress;
244: r.ibrPhysicalAddress = physicalAddress;
245:
246: pointTable.put (logicalAddress, r);
247:
248: {
249: InstructionBreakRecord[] hashTable = supervisor != 0 ? ibpSuperHashTable : ibpUserHashTable;
250: int h = physicalAddress >>> 1 & IBP_HASH_MASK;
251: r.ibrNext = hashTable[h];
252: hashTable[h] = r;
253: }
254:
255: {
256: int p = physicalAddress >>> XEiJ.BUS_PAGE_BITS;
257: if (supervisor != 0) {
258: ibpSuperMap[p] = MemoryMappedDevice.MMD_IBP;
259: } else {
260: ibpUserMap[p] = MemoryMappedDevice.MMD_IBP;
261: }
262: }
263: }
264: r.ibrValue = value;
265: r.ibrTarget = threshold < 0 ? 0 : threshold;
266: r.ibrThreshold = threshold;
267: r.ibrWaitInstruction = null;
268: r.ibrScriptElement = scriptElement;
269: }
270: }
271:
272:
273:
274: public static void ibpRemove (int logicalAddress, int supervisor) {
275: if (IBP_ON) {
276: int physicalAddress = MC68060.mmuTranslatePeek (logicalAddress, supervisor, 0);
277: if ((logicalAddress ^ physicalAddress) == 1) {
278: return;
279: }
280: TreeMap<Integer,InstructionBreakRecord> pointTable = supervisor != 0 ? ibpSuperPointTable : ibpUserPointTable;
281: InstructionBreakRecord r = pointTable.get (logicalAddress);
282: if (r != null) {
283:
284: {
285: InstructionBreakRecord[] hashTable = supervisor != 0 ? ibpSuperHashTable : ibpUserHashTable;
286: int h = physicalAddress >>> 1 & IBP_HASH_MASK;
287: InstructionBreakRecord t = hashTable[h];
288: if (t == r) {
289: hashTable[h] = r.ibrNext;
290: } else {
291: for (; t.ibrNext != r; t = t.ibrNext) {
292: }
293: t.ibrNext = r.ibrNext;
294: }
295: r.ibrNext = null;
296: }
297:
298: {
299: int p = physicalAddress >>> XEiJ.BUS_PAGE_BITS;
300: boolean more = false;
301: for (InstructionBreakRecord t : pointTable.values ()) {
302: if (t.ibrPhysicalAddress >>> XEiJ.BUS_PAGE_BITS == p) {
303: more = true;
304: break;
305: }
306: }
307: if (supervisor != 0) {
308: ibpSuperMap[p] = more ? MemoryMappedDevice.MMD_IBP : XEiJ.busSuperMap[p];
309: } else {
310: ibpUserMap[p] = more ? MemoryMappedDevice.MMD_IBP : XEiJ.busUserMap[p];
311: }
312: }
313:
314: pointTable.remove (logicalAddress);
315:
316: if (pointTable.isEmpty ()) {
317: if (supervisor != 0) {
318: ibpOp1SuperMap = XEiJ.busSuperMap;
319: } else {
320: ibpOp1UserMap = XEiJ.busUserMap;
321: }
322: ibpOp1MemoryMap = XEiJ.regSRS != 0 ? ibpOp1SuperMap : ibpOp1UserMap;
323: }
324: }
325: }
326: }
327:
328: }
329:
330:
331: