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> ibpPointTable;
137:
138: public static InstructionBreakRecord[] ibpHashTable;
139:
140:
141:
142: public static void ibpInit () {
143: ibpUserMap = new MemoryMappedDevice[XEiJ.BUS_PAGE_COUNT];
144: ibpSuperMap = new MemoryMappedDevice[XEiJ.BUS_PAGE_COUNT];
145: Arrays.fill (ibpUserMap, MemoryMappedDevice.MMD_NUL);
146: Arrays.fill (ibpSuperMap, MemoryMappedDevice.MMD_NUL);
147: ibpOp1UserMap = XEiJ.busUserMap;
148: ibpOp1SuperMap = XEiJ.busSuperMap;
149: ibpOp1MemoryMap = ibpOp1SuperMap;
150: ibpPointTable = new TreeMap<Integer,InstructionBreakRecord> ();
151: ibpHashTable = new InstructionBreakRecord[IBP_HASH_SIZE];
152: }
153:
154:
155:
156: public static void ibpReset () {
157: for (InstructionBreakRecord r : ibpPointTable.values ()) {
158: r.ibrValue = 0;
159: r.ibrTarget = r.ibrThreshold < 0 ? 0 : r.ibrThreshold;
160: }
161: }
162:
163:
164:
165: public static void ibpAddWaitPoint (int logicalAddress, int supervisor, WaitInstruction waitInstruction) {
166: TreeMap<Integer,InstructionBreakRecord> pointTable = ibpPointTable;
167: InstructionBreakRecord r = pointTable.get (logicalAddress);
168: if (r == null) {
169: r = ibpPut (logicalAddress, supervisor, 0, 0x7fffffff, null);
170: }
171: r.ibrWaitInstruction = waitInstruction;
172: }
173:
174:
175:
176: public static void ibpRemoveWaitPoint (int logicalAddress, int supervisor) {
177: TreeMap<Integer,InstructionBreakRecord> pointTable = ibpPointTable;
178: InstructionBreakRecord r = pointTable.get (logicalAddress);
179: if (r != null) {
180: r.ibrWaitInstruction = null;
181: if (r.ibrThreshold == 0x7fffffff) {
182: ibpRemove (logicalAddress, supervisor);
183: }
184: }
185: }
186:
187:
188:
189:
190: public static void ibpInstant (int logicalAddress, int supervisor) {
191: TreeMap<Integer,InstructionBreakRecord> pointTable = ibpPointTable;
192: InstructionBreakRecord r = pointTable.get (logicalAddress);
193: if (r == null) {
194: ibpPut (logicalAddress, supervisor, 0, -1, null);
195: } else {
196: r.ibrTarget = r.ibrLogicalAddress == logicalAddress ? r.ibrValue + 1 : r.ibrValue;
197: }
198: }
199:
200:
201:
202:
203:
204: public static InstructionBreakRecord ibpPut (int logicalAddress, int supervisor, int value, int threshold,
205: ExpressionEvaluator.ExpressionElement scriptElement) {
206: int physicalAddress = MC68060.mmuTranslatePeek (logicalAddress, supervisor, 0);
207: if ((logicalAddress ^ physicalAddress) == 1) {
208: return null;
209: }
210: TreeMap<Integer,InstructionBreakRecord> pointTable = ibpPointTable;
211: InstructionBreakRecord r = pointTable.get (logicalAddress);
212: if (r == null) {
213:
214: if (pointTable.isEmpty ()) {
215: ibpOp1SuperMap = ibpSuperMap;
216: ibpOp1UserMap = ibpUserMap;
217: ibpOp1MemoryMap = XEiJ.regSRS != 0 ? ibpOp1SuperMap : ibpOp1UserMap;
218: }
219:
220: r = new InstructionBreakRecord ();
221: r.ibrLogicalAddress = logicalAddress;
222: r.ibrPhysicalAddress = physicalAddress;
223:
224: pointTable.put (logicalAddress, r);
225:
226: {
227: InstructionBreakRecord[] hashTable = ibpHashTable;
228: int h = physicalAddress >>> 1 & IBP_HASH_MASK;
229: r.ibrNext = hashTable[h];
230: hashTable[h] = r;
231: }
232:
233: {
234: int p = physicalAddress >>> XEiJ.BUS_PAGE_BITS;
235: ibpSuperMap[p] = MemoryMappedDevice.MMD_IBP;
236: ibpUserMap[p] = MemoryMappedDevice.MMD_IBP;
237: }
238: }
239: r.ibrValue = value;
240: r.ibrTarget = threshold < 0 ? 0 : threshold;
241: r.ibrThreshold = threshold;
242: r.ibrWaitInstruction = null;
243: r.ibrScriptElement = scriptElement;
244: return r;
245: }
246:
247:
248:
249: public static void ibpRemove (int logicalAddress, int supervisor) {
250: int physicalAddress = MC68060.mmuTranslatePeek (logicalAddress, supervisor, 0);
251: if ((logicalAddress ^ physicalAddress) == 1) {
252: return;
253: }
254: TreeMap<Integer,InstructionBreakRecord> pointTable = ibpPointTable;
255: InstructionBreakRecord r = pointTable.get (logicalAddress);
256: if (r != null) {
257:
258: {
259: InstructionBreakRecord[] hashTable = ibpHashTable;
260: int h = physicalAddress >>> 1 & IBP_HASH_MASK;
261: InstructionBreakRecord t = hashTable[h];
262: if (t == r) {
263: hashTable[h] = r.ibrNext;
264: } else {
265: for (; t.ibrNext != r; t = t.ibrNext) {
266: }
267: t.ibrNext = r.ibrNext;
268: }
269: r.ibrNext = null;
270: }
271:
272: {
273: int p = physicalAddress >>> XEiJ.BUS_PAGE_BITS;
274: boolean more = false;
275: for (InstructionBreakRecord t : pointTable.values ()) {
276: if (t.ibrPhysicalAddress >>> XEiJ.BUS_PAGE_BITS == p) {
277: more = true;
278: break;
279: }
280: }
281: ibpSuperMap[p] = more ? MemoryMappedDevice.MMD_IBP : XEiJ.busSuperMap[p];
282: ibpUserMap[p] = more ? MemoryMappedDevice.MMD_IBP : XEiJ.busUserMap[p];
283: }
284:
285: pointTable.remove (logicalAddress);
286:
287: if (pointTable.isEmpty ()) {
288: ibpOp1SuperMap = XEiJ.busSuperMap;
289: ibpOp1UserMap = XEiJ.busUserMap;
290: ibpOp1MemoryMap = XEiJ.regSRS != 0 ? ibpOp1SuperMap : ibpOp1UserMap;
291: }
292: }
293: }
294:
295: }
296:
297:
298: