HD63450.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13: package xeij;
14:
15: import java.lang.*;
16:
17: public class HD63450 {
18:
19:
20:
21: public static final int DMA_DEBUG_TRACE = 0b0000;
22:
23: public static final boolean DMA_ALERT_HIMEM = true;
24:
25:
26:
27:
28:
29:
30: public static final int DMA_CSR = 0x00;
31: public static final int DMA_COC = 0b10000000;
32: public static final int DMA_BLC = 0b01000000;
33: public static final int DMA_NDT = 0b00100000;
34: public static final int DMA_ERR = 0b00010000;
35: public static final int DMA_ACT = 0b00001000;
36: public static final int DMA_DIT = 0b00000100;
37: public static final int DMA_PCT = 0b00000010;
38: public static final int DMA_PCS = 0b00000001;
39:
40:
41: public static final int DMA_CER = 0x01;
42: public static final int DMA_ERROR_CODE = 0b00011111;
43: public static final int DMA_NO_ERROR = 0b00000000;
44: public static final int DMA_CONFIGURATION_ERROR = 0b00000001;
45: public static final int DMA_TIMING_ERROR = 0b00000010;
46: public static final int DMA_MEMORY_ADDRESS_ERROR = 0b00000101;
47: public static final int DMA_DEVICE_ADDRESS_ERROR = 0b00000110;
48: public static final int DMA_BASE_ADDRESS_ERROR = 0b00000111;
49: public static final int DMA_MEMORY_BUS_ERROR = 0b00001001;
50: public static final int DMA_DEVICE_BUS_ERROR = 0b00001010;
51: public static final int DMA_BASE_BUS_ERROR = 0b00001011;
52: public static final int DMA_MEMORY_COUNT_ERROR = 0b00001101;
53: public static final int DMA_BASE_COUNT_ERROR = 0b00001111;
54: public static final int DMA_EXTERNAL_ABORT = 0b00010000;
55: public static final int DMA_SOFTWARE_ABORT = 0b00010001;
56:
57:
58: public static final int DMA_DCR = 0x04;
59: public static final int DMA_XRM = 0b11000000;
60: public static final int DMA_BURST_TRANSFER = 0b00000000;
61: public static final int DMA_NO_HOLD_CYCLE_STEAL = 0b10000000;
62: public static final int DMA_HOLD_CYCLE_STEAL = 0b11000000;
63: public static final int DMA_DTYP = 0b00110000;
64: public static final int DMA_HD68000_COMPATIBLE = 0b00000000;
65: public static final int DMA_HD6800_COMPATIBLE = 0b00010000;
66: public static final int DMA_ACK_DEVICE = 0b00100000;
67: public static final int DMA_ACK_READY_DEVICE = 0b00110000;
68: public static final int DMA_DPS = 0b00001000;
69: public static final int DMA_PORT_8_BIT = 0b00000000;
70: public static final int DMA_PORT_16_BIT = 0b00001000;
71: public static final int DMA_PCL = 0b00000011;
72: public static final int DMA_STATUS_INPUT = 0b00000000;
73: public static final int DMA_STATUS_INPUT_INTERRUPT = 0b00000001;
74: public static final int DMA_EIGHTH_START_PULSE = 0b00000010;
75: public static final int DMA_ABORT_INPUT = 0b00000011;
76:
77:
78: public static final int DMA_OCR = 0x05;
79: public static final int DMA_DIR = 0b10000000;
80: public static final int DMA_MEMORY_TO_DEVICE = 0b00000000;
81: public static final int DMA_DEVICE_TO_MEMORY = 0b10000000;
82: public static final int DMA_BTD = 0b01000000;
83: public static final int DMA_SIZE = 0b00110000;
84: public static final int DMA_BYTE_SIZE = 0b00000000;
85: public static final int DMA_WORD_SIZE = 0b00010000;
86: public static final int DMA_LONG_WORD_SIZE = 0b00100000;
87: public static final int DMA_UNPACKED_8_BIT = 0b00110000;
88: public static final int DMA_CHAIN = 0b00001100;
89: public static final int DMA_NO_CHAINING = 0b00000000;
90: public static final int DMA_ARRAY_CHAINING = 0b00001000;
91: public static final int DMA_LINK_ARRAY_CHAINING = 0b00001100;
92: public static final int DMA_REQG = 0b00000011;
93: public static final int DMA_AUTO_REQUEST = 0b00000000;
94: public static final int DMA_AUTO_REQUEST_MAX = 0b00000001;
95: public static final int DMA_EXTERNAL_REQUEST = 0b00000010;
96: public static final int DMA_DUAL_REQUEST = 0b00000011;
97:
98:
99: public static final int DMA_SCR = 0x06;
100: public static final int DMA_MAC = 0b00001100;
101: public static final int DMA_STATIC_MAR = 0b00000000;
102: public static final int DMA_INC_MAR = 0b00000100;
103: public static final int DMA_DEC_MAR = 0b00001000;
104: public static final int DMA_DAC = 0b00000011;
105: public static final int DMA_STATIC_DAR = 0b00000000;
106: public static final int DMA_INC_DAR = 0b00000001;
107: public static final int DMA_DEC_DAR = 0b00000010;
108:
109:
110: public static final int DMA_CCR = 0x07;
111: public static final int DMA_STR = 0b10000000;
112: public static final int DMA_CNT = 0b01000000;
113: public static final int DMA_HLT = 0b00100000;
114: public static final int DMA_SAB = 0b00010000;
115: public static final int DMA_ITE = 0b00001000;
116:
117:
118: public static final int DMA_MTC = 0x0a;
119: public static final int DMA_MAR = 0x0c;
120: public static final int DMA_DAR = 0x14;
121: public static final int DMA_BTC = 0x1a;
122: public static final int DMA_BAR = 0x1c;
123:
124:
125: public static final int DMA_NIV = 0x25;
126: public static final int DMA_EIV = 0x27;
127:
128:
129: public static final int DMA_MFC = 0x29;
130: public static final int DMA_FC2 = 0b00000100;
131: public static final int DMA_FC1 = 0b00000010;
132: public static final int DMA_FC0 = 0b00000001;
133:
134:
135: public static final int DMA_CPR = 0x2d;
136: public static final int DMA_CP = 0b00000011;
137:
138:
139: public static final int DMA_DFC = 0x31;
140: public static final int DMA_BFC = 0x39;
141:
142:
143: public static final int DMA_GCR = 0xff;
144: public static final int DMA_BT = 0b00001100;
145: public static final int DMA_BR = 0b00000011;
146:
147:
148:
149: public static final int[] dmaPCS = new int[4];
150: public static final int[] dmaPCT = new int[4];
151: public static final int[] dmaDIT = new int[4];
152: public static final int[] dmaACT = new int[4];
153: public static final int[] dmaERR = new int[4];
154: public static final int[] dmaNDT = new int[4];
155: public static final int[] dmaBLC = new int[4];
156: public static final int[] dmaCOC = new int[4];
157: public static final int[] dmaErrorCode = new int[4];
158: public static final int[] dmaPCL = new int[4];
159: public static final int[] dmaDPS = new int[4];
160: public static final int[] dmaDTYP = new int[4];
161: public static final int[] dmaXRM = new int[4];
162: public static final int[] dmaREQG = new int[4];
163: public static final int[] dmaCHAIN = new int[4];
164: public static final int[] dmaSIZE = new int[4];
165: public static final int[] dmaBTD = new int[4];
166: public static final int[] dmaDIR = new int[4];
167: public static final int[] dmaDAC = new int[4];
168: public static final int[] dmaDACValue = new int[4];
169: public static final int[] dmaMAC = new int[4];
170: public static final int[] dmaMACValue = new int[4];
171: public static final int[] dmaITE = new int[4];
172: public static final int[] dmaSAB = new int[4];
173: public static final int[] dmaHLT = new int[4];
174: public static final int[] dmaCNT = new int[4];
175: public static final int[] dmaSTR = new int[4];
176: public static final int[] dmaMTC = new int[4];
177: public static final int[] dmaMAR = new int[4];
178: public static final int[] dmaDAR = new int[4];
179: public static final int[] dmaBTC = new int[4];
180: public static final int[] dmaBAR = new int[4];
181: public static final int[] dmaNIV = new int[4];
182: public static final int[] dmaEIV = new int[4];
183: public static final int[] dmaMFC = new int[4];
184: public static final MemoryMappedDevice[][] dmaMFCMap = new MemoryMappedDevice[4][];
185: public static final int[] dmaCP = new int[4];
186: public static final int[] dmaDFC = new int[4];
187: public static final MemoryMappedDevice[][] dmaDFCMap = new MemoryMappedDevice[4][];
188: public static final int[] dmaBFC = new int[4];
189: public static final MemoryMappedDevice[][] dmaBFCMap = new MemoryMappedDevice[4][];
190: public static int dmaBR;
191: public static int dmaBT;
192: public static long dmaBurstSpan;
193: public static long dmaBurstInterval;
194: public static long dmaBurstStart;
195: public static long dmaBurstEnd;
196: public static long[] dmaRequestTime = new long[4];
197:
198: public static final int[] dmaReqPin = new int[4];
199:
200:
201: public static final int[] dmaInnerRequest = new int[8];
202: public static final int[] dmaInnerAcknowleged = new int[8];
203:
204:
205: public static final long[] dmaInnerClock = new long[4];
206:
207:
208: public static final int[] dmaMemoryCarry = new int[4];
209: public static final int[] dmaDeviceCarry = new int[4];
210:
211:
212: public static final int[] dmaAdditionalCycles = new int[4];
213:
214:
215: public static int dmaReadCycles;
216: public static int dmaWriteCycles;
217:
218: public static final TickerQueue.Ticker[] dmaTickerArray = new TickerQueue.Ticker[] {
219: new TickerQueue.Ticker () {
220: @Override protected void tick () {
221: dmaTransfer (0);
222: }
223: },
224: new TickerQueue.Ticker () {
225: @Override protected void tick () {
226: dmaTransfer (1);
227: }
228: },
229: new TickerQueue.Ticker () {
230: @Override protected void tick () {
231: dmaTransfer (2);
232: }
233: },
234: new TickerQueue.Ticker () {
235: @Override protected void tick () {
236: dmaTransfer (3);
237: }
238: },
239: };
240:
241:
242:
243: public static void dmaInit () {
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288: dmaPCS[0] = 1;
289: dmaPCS[1] = 1;
290: dmaPCS[2] = 1;
291: dmaPCS[3] = 1;
292:
293: dmaReqPin[0] = 1;
294: dmaReqPin[1] = 1;
295: dmaReqPin[2] = 1;
296: dmaReqPin[3] = 1;
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307: dmaReset ();
308: }
309:
310:
311: public static void dmaReset () {
312:
313: for (int i = 0; i < 4; i++) {
314:
315: dmaPCT[i] = 0;
316: dmaDIT[i] = 0;
317: dmaACT[i] = 0;
318: dmaERR[i] = 0;
319: dmaNDT[i] = 0;
320: dmaBLC[i] = 0;
321: dmaCOC[i] = 0;
322: dmaErrorCode[i] = 0;
323: dmaPCL[i] = 0;
324: dmaDPS[i] = 0;
325: dmaDTYP[i] = 0;
326: dmaXRM[i] = 0;
327: dmaREQG[i] = 0;
328: dmaCHAIN[i] = 0;
329: dmaSIZE[i] = 0;
330: dmaBTD[i] = 0;
331: dmaDIR[i] = 0;
332: dmaDAC[i] = 0;
333: dmaDACValue[i] = 0;
334: dmaMAC[i] = 0;
335: dmaMACValue[i] = 0;
336: dmaITE[i] = 0;
337: dmaSAB[i] = 0;
338: dmaHLT[i] = 0;
339: dmaCNT[i] = 0;
340: dmaSTR[i] = 0;
341: dmaMTC[i] = 0;
342: dmaMAR[i] = 0;
343: dmaDAR[i] = 0;
344: dmaBTC[i] = 0;
345: dmaBAR[i] = 0;
346: dmaNIV[i] = 0x0f;
347: dmaEIV[i] = 0x0f;
348: dmaMFC[i] = 0;
349: if (DataBreakPoint.DBP_ON) {
350: dmaMFCMap[i] = DataBreakPoint.dbpUserMap;
351: } else {
352: dmaMFCMap[i] = XEiJ.busUserMap;
353: }
354: dmaCP[i] = 0;
355: dmaDFC[i] = 0;
356: if (DataBreakPoint.DBP_ON) {
357: dmaDFCMap[i] = DataBreakPoint.dbpUserMap;
358: } else {
359: dmaDFCMap[i] = XEiJ.busUserMap;
360: }
361: dmaBFC[i] = 0;
362: if (DataBreakPoint.DBP_ON) {
363: dmaBFCMap[i] = DataBreakPoint.dbpUserMap;
364: } else {
365: dmaBFCMap[i] = XEiJ.busUserMap;
366: }
367: dmaRequestTime[i] = XEiJ.FAR_FUTURE;
368: }
369: dmaBR = 0;
370: dmaBT = 0;
371: dmaBurstSpan = XEiJ.dmaCycleUnit << (4 + (dmaBT >> 2));
372: dmaBurstInterval = dmaBurstSpan << (1 + (dmaBR & 3));
373: dmaBurstStart = XEiJ.FAR_FUTURE;
374: dmaBurstEnd = 0L;
375:
376: for (int i = 0; i < 8; i++) {
377: dmaInnerRequest[i] = 0;
378: dmaInnerAcknowleged[i] = 0;
379: }
380:
381: for (int i = 0; i < 4; i++) {
382: dmaInnerClock[i] = XEiJ.FAR_FUTURE;
383: TickerQueue.tkqRemove (dmaTickerArray[i]);
384: }
385: }
386:
387:
388:
389:
390:
391:
392: public static int dmaAcknowledge () {
393: for (int i = 0; i < 8; i++) {
394: int request = dmaInnerRequest[i];
395: if (dmaInnerAcknowleged[i] != request) {
396: dmaInnerAcknowleged[i] = request;
397: return (i & 1) == 0 ? dmaNIV[i >> 1] : dmaEIV[i >> 1];
398: }
399: }
400: return 0;
401: }
402:
403:
404:
405:
406: public static void dmaDone () {
407: for (int i = 0; i < 8; i++) {
408: if (dmaInnerRequest[i] != dmaInnerAcknowleged[i]) {
409: XEiJ.mpuIRR |= XEiJ.MPU_DMA_INTERRUPT_MASK;
410: return;
411: }
412: }
413: }
414:
415:
416:
417: public static void dmaStart (int i) {
418: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
419: System.out.printf ("%d %08x dmaStart(%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i);
420: System.out.printf ("CSR=0x%02x,CER=0x%02x,DCR=0x%02x,OCR=0x%02x,SCR=0x%02x,CCR=0x%02x,MTC=0x%04x,MAR=0x%08x,DAR=0x%08x,BTC=0x%04x,BAR=0x%08x\n",
421: dmaCOC[i] | dmaBLC[i] | dmaNDT[i] | dmaERR[i] | dmaACT[i] | dmaDIT[i] | dmaPCT[i] | dmaPCS[i],
422: dmaErrorCode[i],
423: dmaXRM[i] | dmaDTYP[i] | dmaDPS[i] | dmaPCL[i],
424: dmaDIR[i] | dmaBTD[i] | dmaSIZE[i] | dmaCHAIN[i] | dmaREQG[i],
425: dmaMAC[i] | dmaDAC[i],
426: dmaSTR[i] | dmaCNT[i] | dmaHLT[i] | dmaSAB[i] | dmaITE[i],
427: dmaMTC[i], dmaMAR[i], dmaDAR[i], dmaBTC[i], dmaBAR[i]);
428: }
429:
430: if ((dmaCOC[i] | dmaBLC[i] | dmaNDT[i] | dmaERR[i] | dmaACT[i]) != 0) {
431: dmaErrorExit (i, DMA_TIMING_ERROR);
432: return;
433: }
434:
435: if (((dmaDTYP[i] == DMA_HD68000_COMPATIBLE || dmaDTYP[i] == DMA_HD6800_COMPATIBLE) &&
436: dmaDPS[i] == DMA_PORT_16_BIT && dmaSIZE[i] == DMA_BYTE_SIZE &&
437: (dmaREQG[i] == DMA_EXTERNAL_REQUEST || dmaREQG[i] == DMA_DUAL_REQUEST)) ||
438: dmaXRM[i] == 0b01000000 || dmaMAC[i] == 0b00001100 || dmaDAC[i] == 0b00000011 || dmaCHAIN[i] == 0b00000100 ||
439: (dmaSIZE[i] == 0b00000011 && !((dmaDTYP[i] == DMA_HD68000_COMPATIBLE || dmaDTYP[i] == DMA_HD6800_COMPATIBLE) && dmaDPS[i] == DMA_PORT_8_BIT))) {
440: dmaErrorExit (i, DMA_CONFIGURATION_ERROR);
441: return;
442: }
443: if (dmaDPS[i] == DMA_PORT_16_BIT &&
444: dmaSIZE[i] == DMA_UNPACKED_8_BIT) {
445: dmaErrorExit (i, DMA_CONFIGURATION_ERROR);
446: return;
447: }
448:
449: dmaMemoryCarry[i] = -1;
450: dmaDeviceCarry[i] = -1;
451:
452:
453: dmaRequestTime[i] = XEiJ.mpuClockTime;
454: dmaACT[i] = DMA_ACT;
455: if (dmaCHAIN[i] == DMA_ARRAY_CHAINING) {
456: if (dmaBTC[i] == 0) {
457: dmaErrorExit (i, DMA_BASE_COUNT_ERROR);
458: return;
459: }
460: if ((dmaBAR[i] & 1) != 0) {
461: dmaErrorExit (i, DMA_BASE_ADDRESS_ERROR);
462: return;
463: }
464: try {
465: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.dmaWaitTime : XEiJ.dmaNoWaitTime;
466: MemoryMappedDevice[] mm = dmaBFCMap[i];
467: int a = dmaBAR[i];
468: dmaMAR[i] = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRws (a) << 16 | mm[a + 2 >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 2);
469: dmaMTC[i] = mm[a + 4 >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 4);
470: dmaBAR[i] += 6;
471: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles * 3;
472: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
473: } catch (M68kException e) {
474: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
475: dmaErrorExit (i, DMA_BASE_BUS_ERROR);
476: return;
477: }
478: dmaBTC[i]--;
479: } else if (dmaCHAIN[i] == DMA_LINK_ARRAY_CHAINING) {
480: if ((dmaBAR[i] & 1) != 0) {
481: dmaErrorExit (i, DMA_BASE_ADDRESS_ERROR);
482: return;
483: }
484: try {
485: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.dmaWaitTime : XEiJ.dmaNoWaitTime;
486: MemoryMappedDevice[] mm = dmaBFCMap[i];
487: int a = dmaBAR[i];
488: dmaMAR[i] = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRws (a) << 16 | mm[a + 2 >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 2);
489: dmaMTC[i] = mm[a + 4 >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 4);
490: dmaBAR[i] = mm[a + 6 >>> XEiJ.BUS_PAGE_BITS].mmdRws (a + 6) << 16 | mm[a + 8 >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 8);
491: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles * 5;
492: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
493: } catch (M68kException e) {
494: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
495: dmaErrorExit (i, DMA_BASE_BUS_ERROR);
496: return;
497: }
498: }
499:
500:
501: if (dmaMTC[i] == 0) {
502: dmaErrorExit (i, DMA_MEMORY_COUNT_ERROR);
503: return;
504: }
505:
506:
507: dmaAdditionalCycles[i] = (dmaDPS[i] == DMA_PORT_8_BIT ?
508: dmaSIZE[i] == DMA_BYTE_SIZE ?
509: (dmaMAR[i] & 1) == 0 && dmaMACValue[i] == 0 ? 6 :
510: (dmaMAR[i] & 1) != 0 && dmaMACValue[i] == 0 ? 8 :
511: dmaDIR[i] == DMA_MEMORY_TO_DEVICE ? 8 : 10 :
512: dmaSIZE[i] == DMA_WORD_SIZE || dmaSIZE[i] == DMA_LONG_WORD_SIZE ?
513: dmaDIR[i] == DMA_MEMORY_TO_DEVICE ? 4 : 0 :
514: 0
515: :
516: dmaSIZE[i] == DMA_BYTE_SIZE ?
517: 4 +
518: ((dmaMAR[i] & 1) != 0 && dmaMACValue[i] == 0 ? 1 : 0) +
519: ((dmaDAR[i] & 1) != 0 && dmaDACValue[i] == 0 ? 1 : 0) :
520: 0);
521: if (dmaREQG[i] == DMA_AUTO_REQUEST) {
522: dmaBurstStart = XEiJ.mpuClockTime;
523: dmaBurstEnd = dmaBurstStart + dmaBurstSpan;
524: dmaTransfer (i);
525: } else if (dmaREQG[i] != DMA_EXTERNAL_REQUEST ||
526: dmaReqPin[i] == 0) {
527: dmaTransfer (i);
528: }
529: }
530:
531:
532:
533: public static void dmaContinue (int i) {
534: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
535: System.out.printf ("%d %08x dmaContinue(%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i);
536: }
537: if (dmaREQG[i] == DMA_AUTO_REQUEST) {
538: if (XEiJ.mpuClockTime < dmaBurstEnd) {
539:
540:
541:
542: dmaInnerClock[i] = dmaRequestTime[i];
543: TickerQueue.tkqAdd (dmaTickerArray[i], dmaInnerClock[i]);
544: } else {
545: dmaBurstStart += dmaBurstInterval;
546: if (dmaBurstStart < XEiJ.mpuClockTime) {
547: dmaBurstStart = XEiJ.mpuClockTime + dmaBurstInterval;
548: }
549: dmaBurstEnd = dmaBurstStart + dmaBurstSpan;
550:
551: dmaInnerClock[i] = dmaBurstStart;
552: TickerQueue.tkqAdd (dmaTickerArray[i], dmaInnerClock[i]);
553: }
554: } else if (dmaREQG[i] == DMA_AUTO_REQUEST_MAX) {
555:
556:
557:
558: dmaInnerClock[i] = dmaRequestTime[i];
559: TickerQueue.tkqAdd (dmaTickerArray[i], dmaInnerClock[i]);
560: }
561: }
562:
563:
564:
565: public static void dmaHalt (int i, int hlt) {
566: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
567: System.out.printf ("%d %08x dmaHalt(%d,%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i, hlt);
568: }
569: if ((~dmaHLT[i] & hlt) != 0) {
570: if (dmaACT[i] == 0) {
571: dmaErrorExit (i, DMA_TIMING_ERROR);
572: return;
573: }
574: dmaHLT[i] = DMA_HLT;
575: dmaRequestTime[i] = XEiJ.FAR_FUTURE;
576: if (dmaInnerClock[i] != XEiJ.FAR_FUTURE) {
577: dmaInnerClock[i] = XEiJ.FAR_FUTURE;
578: TickerQueue.tkqRemove (dmaTickerArray[i]);
579: }
580: } else if ((dmaHLT[i] & ~hlt) != 0) {
581: dmaHLT[i] = 0;
582: if (dmaACT[i] == 0) {
583: return;
584: }
585: dmaRequestTime[i] = XEiJ.mpuClockTime;
586: if (dmaREQG[i] == DMA_AUTO_REQUEST) {
587: dmaBurstStart = XEiJ.mpuClockTime;
588: dmaBurstEnd = dmaBurstStart + dmaBurstSpan;
589: }
590: dmaContinue (i);
591: }
592: }
593:
594:
595:
596:
597: public static void dmaComplete (int i) {
598: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
599: System.out.printf ("%d %08x dmaComplete(%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i);
600: }
601: dmaRequestTime[i] = XEiJ.FAR_FUTURE;
602: dmaCOC[i] = DMA_COC;
603: dmaERR[i] = 0;
604: dmaACT[i] = 0;
605: dmaSTR[i] = 0;
606: dmaCNT[i] = 0;
607: dmaSAB[i] = 0;
608: dmaErrorCode[i] = 0;
609: if (dmaITE[i] != 0) {
610: dmaInnerRequest[i << 1]++;
611: XEiJ.mpuIRR |= XEiJ.MPU_DMA_INTERRUPT_MASK;
612: }
613: if (dmaInnerClock[i] != XEiJ.FAR_FUTURE) {
614: dmaInnerClock[i] = XEiJ.FAR_FUTURE;
615: TickerQueue.tkqRemove (dmaTickerArray[i]);
616: }
617: }
618:
619:
620:
621:
622: public static void dmaErrorExit (int i, int code) {
623: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
624: System.out.printf ("%d %08x dmaErrorExit(%d,%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i, code);
625: }
626: dmaRequestTime[i] = XEiJ.FAR_FUTURE;
627: dmaCOC[i] = DMA_COC;
628: dmaERR[i] = DMA_ERR;
629: dmaACT[i] = 0;
630: dmaSTR[i] = 0;
631: dmaCNT[i] = 0;
632: dmaHLT[i] = 0;
633: dmaSAB[i] = 0;
634: dmaErrorCode[i] = code;
635: if (dmaITE[i] != 0) {
636: dmaInnerRequest[i << 1 | 1]++;
637: XEiJ.mpuIRR |= XEiJ.MPU_DMA_INTERRUPT_MASK;
638: }
639: if (dmaInnerClock[i] != XEiJ.FAR_FUTURE) {
640: dmaInnerClock[i] = XEiJ.FAR_FUTURE;
641: TickerQueue.tkqRemove (dmaTickerArray[i]);
642: }
643: }
644:
645:
646: public static void dmaFallPCL (int i) {
647: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
648: System.out.printf ("%d %08x dmaFallPCL(%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i);
649: }
650: if (dmaPCS[i] != 0) {
651: dmaPCS[i] = 0;
652: dmaPCT[i] = DMA_PCT;
653: }
654: }
655:
656:
657: public static void dmaRisePCL (int i) {
658: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
659: System.out.printf ("%d %08x dmaRisePCL(%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i);
660: }
661: dmaPCS[i] = DMA_PCS;
662: }
663:
664:
665:
666: public static void dmaFallREQ (int i) {
667: dmaFallREQ (i, 0);
668: }
669: public static void dmaFallREQ (int i, long time) {
670: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
671: System.out.printf ("%d %08x dmaFallREQ(%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i);
672: }
673: dmaReqPin[i] = 0;
674: if (dmaACT[i] != 0 &&
675: (dmaREQG[i] & (DMA_EXTERNAL_REQUEST & DMA_DUAL_REQUEST)) != 0) {
676:
677:
678: dmaInnerClock[i] = time != 0 ? time : XEiJ.mpuClockTime + XEiJ.dmaCycleUnit * 1;
679: TickerQueue.tkqAdd (dmaTickerArray[i], dmaInnerClock[i]);
680: }
681: }
682:
683:
684:
685: public static void dmaRiseREQ (int i) {
686: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
687: System.out.printf ("%d %08x dmaRiseREQ(%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i);
688: }
689: dmaReqPin[i] = 1;
690: dmaInnerClock[i] = XEiJ.FAR_FUTURE;
691: TickerQueue.tkqRemove (dmaTickerArray[i]);
692: }
693:
694:
695:
696: @SuppressWarnings ("fallthrough") public static void dmaTransfer (int i) {
697: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
698: System.out.printf ("%d %08x dmaTransfer(%d,0x%08x,0x%08x,%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i,
699: dmaDIR[i] == DMA_MEMORY_TO_DEVICE ? dmaMAR[i] : dmaDAR[i],
700: dmaDIR[i] == DMA_MEMORY_TO_DEVICE ? dmaDAR[i] : dmaMAR[i],
701: dmaSIZE[i] == DMA_BYTE_SIZE || dmaSIZE[i] == DMA_UNPACKED_8_BIT ? 1 : dmaSIZE[i] == DMA_WORD_SIZE ? 2 : 4);
702: }
703: if (dmaHLT[i] != 0) {
704: return;
705: }
706: transfer:
707: {
708: int code = 0;
709: try {
710: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.dmaWaitTime : XEiJ.dmaNoWaitTime;
711: switch (dmaSIZE[i]) {
712: case DMA_BYTE_SIZE:
713: if (dmaDIR[i] == DMA_MEMORY_TO_DEVICE) {
714:
715: code = DMA_MEMORY_BUS_ERROR;
716: MemoryMappedDevice[] mm = dmaMFCMap[i];
717: int a = dmaMAR[i];
718: int ac = dmaMACValue[i];
719: int data = dmaMemoryCarry[i];
720: if (0 <= data) {
721: dmaMemoryCarry[i] = -1;
722: } else if ((a & 1) == 0 && ac == 1 && 2 <= dmaMTC[i]) {
723: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a);
724: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
725: dmaMemoryCarry[i] = data & 255;
726: data >>= 8;
727: } else if ((a & 1) != 0 && ac == -1 && 2 <= dmaMTC[i]) {
728: data = mm[(a - 1) >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a - 1);
729: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
730: dmaMemoryCarry[i] = data >> 8;
731: data &= 255;
732: } else {
733: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a);
734: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
735: }
736: dmaMAR[i] = a + ac;
737:
738: if (i == 2) {
739: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
740: MercuryUnit.mu4ExackStart ();
741: }
742: }
743:
744: code = DMA_DEVICE_BUS_ERROR;
745: mm = dmaDFCMap[i];
746: a = dmaDAR[i];
747: ac = dmaDACValue[i];
748: int carry = dmaDeviceCarry[i];
749: if (0 <= carry) {
750: if ((a & 1) != 0) {
751: data = carry << 8 | data;
752: mm[(a - 1) >>> XEiJ.BUS_PAGE_BITS].mmdWw (a - 1, data);
753: } else {
754: data = data << 8 | carry;
755: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWw (a, data);
756: }
757: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
758: dmaDeviceCarry[i] = -1;
759: } else if (((a & 1) == 0 ? ac == 1 : ac == -1) && 2 <= dmaMTC[i]) {
760: dmaDeviceCarry[i] = data;
761: } else {
762: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWb (a, data);
763: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
764: }
765: dmaDAR[i] = a + ac;
766: } else {
767:
768: if (i == 2) {
769: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
770: MercuryUnit.mu4ExackStart ();
771: }
772: }
773:
774: code = DMA_DEVICE_BUS_ERROR;
775: MemoryMappedDevice[] mm = dmaDFCMap[i];
776: int a = dmaDAR[i];
777: int ac = dmaDACValue[i];
778: int data = dmaDeviceCarry[i];
779: if (0 <= data) {
780: dmaDeviceCarry[i] = -1;
781: } else if ((a & 1) == 0 && ac == 1 && 2 <= dmaMTC[i]) {
782: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a);
783: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
784: dmaDeviceCarry[i] = data & 255;
785: data >>= 8;
786: } else if ((a & 1) != 0 && ac == -1 && 2 <= dmaMTC[i]) {
787: data = mm[(a - 1) >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a - 1);
788: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
789: dmaDeviceCarry[i] = data >> 8;
790: data &= 255;
791: } else {
792: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a);
793: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
794: }
795: dmaDAR[i] = a + ac;
796:
797: code = DMA_MEMORY_BUS_ERROR;
798: mm = dmaMFCMap[i];
799: a = dmaMAR[i];
800: ac = dmaMACValue[i];
801: int carry = dmaMemoryCarry[i];
802: if (0 <= carry) {
803: if ((a & 1) != 0) {
804: data = carry << 8 | data;
805: mm[(a - 1) >>> XEiJ.BUS_PAGE_BITS].mmdWw (a - 1, data);
806: } else {
807: data = data << 8 | carry;
808: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWw (a, data);
809: }
810: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
811: dmaMemoryCarry[i] = -1;
812: } else if (((a & 1) == 0 ? ac == 1 : ac == -1) && 2 <= dmaMTC[i]) {
813: dmaMemoryCarry[i] = data;
814: } else {
815: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWb (a, data);
816: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
817: }
818: dmaMAR[i] = a + ac;
819: }
820: break;
821:
822: case DMA_WORD_SIZE:
823: if (dmaDIR[i] == DMA_MEMORY_TO_DEVICE) {
824:
825: code = DMA_MEMORY_BUS_ERROR;
826: MemoryMappedDevice[] mm = dmaMFCMap[i];
827: int a = dmaMAR[i];
828: int ac = dmaMACValue[i];
829: if ((a & 1) != 0) {
830: dmaErrorExit (i, DMA_MEMORY_ADDRESS_ERROR);
831: break transfer;
832: }
833: int data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a);
834: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
835: dmaMAR[i] = a + ac * 2;
836:
837: if (i == 2) {
838: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
839: MercuryUnit.mu4ExackStart ();
840: }
841: }
842:
843: code = DMA_DEVICE_BUS_ERROR;
844: mm = dmaDFCMap[i];
845: a = dmaDAR[i];
846: ac = dmaDACValue[i];
847: if (dmaDPS[i] == DMA_PORT_8_BIT) {
848: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWb (a, data >> 8);
849: mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdWb (a + 2, data);
850: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles * 2;
851: } else {
852: if ((a & 1) != 0) {
853: dmaErrorExit (i, DMA_DEVICE_ADDRESS_ERROR);
854: break transfer;
855: }
856: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWw (a, data);
857: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
858: }
859: dmaDAR[i] = a + ac * 2;
860: } else {
861:
862: if (i == 2) {
863: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
864: MercuryUnit.mu4ExackStart ();
865: }
866: }
867:
868: code = DMA_DEVICE_BUS_ERROR;
869: MemoryMappedDevice[] mm = dmaDFCMap[i];
870: int a = dmaDAR[i];
871: int ac = dmaDACValue[i];
872: int data;
873: if (dmaDPS[i] == DMA_PORT_8_BIT) {
874: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a) << 8;
875: data |= mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a + 2);
876: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles * 2;
877: } else {
878: if ((a & 1) != 0) {
879: dmaErrorExit (i, DMA_DEVICE_ADDRESS_ERROR);
880: break transfer;
881: }
882: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a);
883: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
884: }
885: dmaDAR[i] = a + ac * 2;
886:
887: code = DMA_MEMORY_BUS_ERROR;
888: mm = dmaMFCMap[i];
889: a = dmaMAR[i];
890: ac = dmaMACValue[i];
891: if ((a & 1) != 0) {
892: dmaErrorExit (i, DMA_MEMORY_ADDRESS_ERROR);
893: break transfer;
894: }
895: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWw (a, data);
896: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
897: dmaMAR[i] = a + ac * 2;
898: }
899: break;
900:
901: case DMA_LONG_WORD_SIZE:
902: if (dmaDIR[i] == DMA_MEMORY_TO_DEVICE) {
903:
904: code = DMA_MEMORY_BUS_ERROR;
905: MemoryMappedDevice[] mm = dmaMFCMap[i];
906: int a = dmaMAR[i];
907: int ac = dmaMACValue[i];
908: if ((a & 1) != 0) {
909: dmaErrorExit (i, DMA_MEMORY_ADDRESS_ERROR);
910: break transfer;
911: }
912: int data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a) << 16;
913: data |= mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 2);
914: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles * 2;
915: dmaMAR[i] = a + ac * 4;
916:
917: if (i == 2) {
918: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
919: MercuryUnit.mu4ExackStart ();
920: }
921: }
922:
923: code = DMA_DEVICE_BUS_ERROR;
924: mm = dmaDFCMap[i];
925: a = dmaDAR[i];
926: ac = dmaDACValue[i];
927: if (dmaDPS[i] == DMA_PORT_8_BIT) {
928: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWb (a, data >> 24);
929: mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdWb (a + 2, data >> 16);
930: mm[(a + 4) >>> XEiJ.BUS_PAGE_BITS].mmdWb (a + 4, data >> 8);
931: mm[(a + 6) >>> XEiJ.BUS_PAGE_BITS].mmdWb (a + 6, data);
932: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles * 4;
933: } else {
934: if ((a & 1) != 0) {
935: dmaErrorExit (i, DMA_DEVICE_ADDRESS_ERROR);
936: break transfer;
937: }
938: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWw (a, data >> 16);
939: mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdWw (a + 2, data);
940: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles * 2;
941: }
942: dmaDAR[i] = a + ac * 4;
943: } else {
944:
945: if (i == 2) {
946: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
947: MercuryUnit.mu4ExackStart ();
948: }
949: }
950:
951: code = DMA_DEVICE_BUS_ERROR;
952: MemoryMappedDevice[] mm = dmaDFCMap[i];
953: int a = dmaDAR[i];
954: int ac = dmaDACValue[i];
955: int data;
956: if (dmaDPS[i] == DMA_PORT_8_BIT) {
957: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a) << 24;
958: data |= mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a + 2) << 16;
959: data |= mm[(a + 4) >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a + 4) << 8;
960: data |= mm[(a + 6) >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a + 6);
961: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles * 4;
962: } else {
963: if ((a & 1) != 0) {
964: dmaErrorExit (i, DMA_DEVICE_ADDRESS_ERROR);
965: break transfer;
966: }
967: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a) << 16;
968: data |= mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 2);
969: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles * 2;
970: }
971: dmaDAR[i] = a + ac * 4;
972:
973: code = DMA_MEMORY_BUS_ERROR;
974: mm = dmaMFCMap[i];
975: a = dmaMAR[i];
976: ac = dmaMACValue[i];
977: if ((a & 1) != 0) {
978: dmaErrorExit (i, DMA_MEMORY_ADDRESS_ERROR);
979: break transfer;
980: }
981: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWw (a, data >> 16);
982: mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdWw (a + 2, data);
983: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles * 2;
984: dmaMAR[i] = a + ac * 4;
985: }
986: break;
987:
988: case DMA_UNPACKED_8_BIT:
989: if (dmaDIR[i] == DMA_MEMORY_TO_DEVICE) {
990:
991: code = DMA_MEMORY_BUS_ERROR;
992: MemoryMappedDevice[] mm = dmaMFCMap[i];
993: int a = dmaMAR[i];
994: int ac = dmaMACValue[i];
995: int data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a);
996: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
997: dmaMAR[i] = a + ac;
998:
999: if (i == 2) {
1000: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
1001: MercuryUnit.mu4ExackStart ();
1002: }
1003: }
1004:
1005: code = DMA_DEVICE_BUS_ERROR;
1006: mm = dmaDFCMap[i];
1007: a = dmaDAR[i];
1008: ac = dmaDACValue[i];
1009: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWb (a, data);
1010: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
1011: dmaDAR[i] = a + ac;
1012: } else {
1013:
1014: if (i == 2) {
1015: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
1016: MercuryUnit.mu4ExackStart ();
1017: }
1018: }
1019:
1020: code = DMA_DEVICE_BUS_ERROR;
1021: MemoryMappedDevice[] mm = dmaDFCMap[i];
1022: int a = dmaDAR[i];
1023: int ac = dmaDACValue[i];
1024: int data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a);
1025: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
1026: dmaDAR[i] = a + ac;
1027:
1028: code = DMA_MEMORY_BUS_ERROR;
1029: mm = dmaMFCMap[i];
1030: a = dmaMAR[i];
1031: ac = dmaMACValue[i];
1032: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWb (a, data);
1033: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
1034: dmaMAR[i] = a + ac;
1035: }
1036: break;
1037: }
1038:
1039: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaAdditionalCycles[i];
1040: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
1041: } catch (M68kException e) {
1042: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
1043: dmaErrorExit (i, code);
1044: break transfer;
1045: }
1046: dmaMTC[i]--;
1047: if (dmaMTC[i] != 0) {
1048: dmaContinue (i);
1049: } else if (dmaCHAIN[i] == DMA_ARRAY_CHAINING) {
1050: if (dmaBTC[i] != 0) {
1051:
1052: try {
1053: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.dmaWaitTime : XEiJ.dmaNoWaitTime;
1054: MemoryMappedDevice[] mm = dmaBFCMap[i];
1055: int a = dmaBAR[i];
1056: dmaMAR[i] = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRws (a) << 16 | mm[a + 2 >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 2);
1057: dmaMTC[i] = mm[a + 4 >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 4);
1058: dmaBAR[i] += 6;
1059: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles * 3;
1060: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
1061: } catch (M68kException e) {
1062: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
1063: dmaErrorExit (i, DMA_BASE_BUS_ERROR);
1064: break transfer;
1065: }
1066: dmaBTC[i]--;
1067: if (dmaMTC[i] == 0) {
1068: dmaErrorExit (i, DMA_MEMORY_COUNT_ERROR);
1069: break transfer;
1070: }
1071: if ((dmaSIZE[i] == DMA_WORD_SIZE || dmaSIZE[i] == DMA_LONG_WORD_SIZE) && (dmaMAR[i] & 1) != 0) {
1072: dmaErrorExit (i, DMA_MEMORY_ADDRESS_ERROR);
1073: break transfer;
1074: }
1075: dmaContinue (i);
1076: } else {
1077: dmaBLC[i] = DMA_BLC;
1078: dmaNDT[i] = 0;
1079: dmaComplete (i);
1080: }
1081: } else if (dmaCHAIN[i] == DMA_LINK_ARRAY_CHAINING) {
1082: if (dmaBAR[i] != 0) {
1083: if ((dmaBAR[i] & 1) != 0) {
1084: dmaErrorExit (i, DMA_BASE_ADDRESS_ERROR);
1085: break transfer;
1086: }
1087: try {
1088: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.dmaWaitTime : XEiJ.dmaNoWaitTime;
1089: MemoryMappedDevice[] mm = dmaBFCMap[i];
1090: int a = dmaBAR[i];
1091: dmaMAR[i] = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRws (a) << 16 | mm[a + 2 >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 2);
1092: dmaMTC[i] = mm[a + 4 >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 4);
1093: dmaBAR[i] = mm[a + 6 >>> XEiJ.BUS_PAGE_BITS].mmdRws (a + 6) << 16 | mm[a + 8 >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 8);
1094: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles * 5;
1095: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
1096: } catch (M68kException e) {
1097: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
1098: dmaErrorExit (i, DMA_BASE_BUS_ERROR);
1099: break transfer;
1100: }
1101: if (dmaMTC[i] == 0) {
1102: dmaErrorExit (i, DMA_MEMORY_COUNT_ERROR);
1103: break transfer;
1104: }
1105: if ((dmaSIZE[i] == DMA_WORD_SIZE || dmaSIZE[i] == DMA_LONG_WORD_SIZE) && (dmaMAR[i] & 1) != 0) {
1106: dmaErrorExit (i, DMA_MEMORY_ADDRESS_ERROR);
1107: break transfer;
1108: }
1109: dmaContinue (i);
1110: } else {
1111: dmaBLC[i] = DMA_BLC;
1112: dmaNDT[i] = 0;
1113: dmaComplete (i);
1114: }
1115: } else if (dmaCNT[i] != 0) {
1116: dmaBLC[i] = DMA_BLC;
1117: dmaCNT[i] = 0;
1118: if (dmaITE[i] != 0) {
1119: dmaInnerRequest[i << 1]++;
1120: XEiJ.mpuIRR |= XEiJ.MPU_DMA_INTERRUPT_MASK;
1121: }
1122: dmaMTC[i] = dmaBTC[i];
1123: dmaMAR[i] = dmaBAR[i];
1124: if (dmaMTC[i] == 0) {
1125: dmaErrorExit (i, DMA_MEMORY_COUNT_ERROR);
1126: break transfer;
1127: }
1128: if ((dmaSIZE[i] == DMA_WORD_SIZE || dmaSIZE[i] == DMA_LONG_WORD_SIZE) && (dmaMAR[i] & 1) != 0) {
1129: dmaErrorExit (i, DMA_MEMORY_ADDRESS_ERROR);
1130: break transfer;
1131: }
1132: dmaContinue (i);
1133: } else {
1134: dmaBLC[i] = 0;
1135: dmaNDT[i] = 0;
1136: dmaComplete (i);
1137: }
1138: }
1139: }
1140:
1141:
1142:
1143: public static int dmaReadByte (int a) {
1144: int d;
1145: int al = a & 0xff;
1146: if (al == DMA_GCR) {
1147: d = dmaBT | dmaBR;
1148: if (DMA_DEBUG_TRACE != 0) {
1149: System.out.printf ("%d %08x dmaRbz(0x%08x)=0x%02x\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1150: }
1151: } else {
1152: int i = al >> 6;
1153: switch (al & 0x3f) {
1154: case DMA_CSR:
1155: d = dmaCOC[i] | dmaBLC[i] | dmaNDT[i] | dmaERR[i] | dmaACT[i] | dmaDIT[i] | dmaPCT[i] | dmaPCS[i];
1156: break;
1157: case DMA_CER:
1158: d = dmaErrorCode[i];
1159: break;
1160: case DMA_DCR:
1161: d = dmaXRM[i] | dmaDTYP[i] | dmaDPS[i] | dmaPCL[i];
1162: break;
1163: case DMA_OCR:
1164: d = dmaDIR[i] | dmaBTD[i] | dmaSIZE[i] | dmaCHAIN[i] | dmaREQG[i];
1165: break;
1166: case DMA_SCR:
1167: d = dmaMAC[i] | dmaDAC[i];
1168: break;
1169: case DMA_CCR:
1170: d = dmaSTR[i] | dmaCNT[i] | dmaHLT[i] | dmaSAB[i] | dmaITE[i];
1171: break;
1172: case DMA_MTC:
1173: d = dmaMTC[i] >> 8;
1174: break;
1175: case DMA_MTC + 1:
1176: d = dmaMTC[i] & 0xff;
1177: break;
1178: case DMA_MAR:
1179: d = dmaMAR[i] >>> 24;
1180: break;
1181: case DMA_MAR + 1:
1182: d = dmaMAR[i] >> 16 & 0xff;
1183: break;
1184: case DMA_MAR + 2:
1185: d = (char) dmaMAR[i] >> 8;
1186: break;
1187: case DMA_MAR + 3:
1188: d = dmaMAR[i] & 0xff;
1189: break;
1190: case DMA_DAR:
1191: d = dmaDAR[i] >>> 24;
1192: break;
1193: case DMA_DAR + 1:
1194: d = dmaDAR[i] >> 16 & 0xff;
1195: break;
1196: case DMA_DAR + 2:
1197: d = (char) dmaDAR[i] >> 8;
1198: break;
1199: case DMA_DAR + 3:
1200: d = dmaDAR[i] & 0xff;
1201: break;
1202: case DMA_BTC:
1203: d = dmaBTC[i] >> 8;
1204: break;
1205: case DMA_BTC + 1:
1206: d = dmaBTC[i] & 0xff;
1207: break;
1208: case DMA_BAR:
1209: d = dmaBAR[i] >>> 24;
1210: break;
1211: case DMA_BAR + 1:
1212: d = dmaBAR[i] >> 16 & 0xff;
1213: break;
1214: case DMA_BAR + 2:
1215: d = (char) dmaBAR[i] >> 8;
1216: break;
1217: case DMA_BAR + 3:
1218: d = dmaBAR[i] & 0xff;
1219: break;
1220: case DMA_NIV:
1221: d = dmaNIV[i];
1222: break;
1223: case DMA_EIV:
1224: d = dmaEIV[i];
1225: break;
1226: case DMA_MFC:
1227: d = dmaMFC[i];
1228: break;
1229: case DMA_CPR:
1230: d = dmaCP[i];
1231: break;
1232: case DMA_DFC:
1233: d = dmaDFC[i];
1234: break;
1235: case DMA_BFC:
1236: d = dmaBFC[i];
1237: break;
1238: default:
1239: d = 0;
1240: }
1241: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
1242: System.out.printf ("%d %08x dmaRbz(0x%08x)=0x%02x\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1243: }
1244: }
1245: return d;
1246: }
1247:
1248: public static int dmaReadWord (int a) {
1249: int d;
1250: int al = a & 0xff;
1251: int i = al >> 6;
1252: switch (al & 0x3f) {
1253: case DMA_MTC:
1254: d = dmaMTC[i];
1255: break;
1256: case DMA_MAR:
1257: d = dmaMAR[i] >>> 16;
1258: break;
1259: case DMA_MAR + 2:
1260: d = (char) dmaMAR[i];
1261: break;
1262: case DMA_DAR:
1263: d = dmaDAR[i] >>> 16;
1264: break;
1265: case DMA_DAR + 2:
1266: d = (char) dmaDAR[i];
1267: break;
1268: case DMA_BTC:
1269: d = dmaBTC[i];
1270: break;
1271: case DMA_BAR:
1272: d = dmaBAR[i] >>> 16;
1273: break;
1274: case DMA_BAR + 2:
1275: d = (char) dmaBAR[i];
1276: break;
1277: default:
1278: d = dmaReadByte (a) << 8 | dmaReadByte (a + 1);
1279: }
1280: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
1281: System.out.printf ("%d %08x dmaRwz(0x%08x)=0x%04x\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1282: }
1283: return d;
1284: }
1285:
1286: public static int dmaReadLong (int a) {
1287: a &= XEiJ.BUS_MOTHER_MASK;
1288: int d;
1289: int al = a & 0xff;
1290: int i = al >> 6;
1291: switch (al & 0x3f) {
1292: case DMA_MAR:
1293: d = dmaMAR[i];
1294: break;
1295: case DMA_DAR:
1296: d = dmaDAR[i];
1297: break;
1298: case DMA_BAR:
1299: d = dmaBAR[i];
1300: break;
1301: default:
1302: d = dmaReadWord (a) << 16 | dmaReadWord (a + 2);
1303: }
1304: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
1305: System.out.printf ("%d %08x dmaRls(0x%08x)=0x%08x\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1306: }
1307: return d;
1308: }
1309:
1310: public static void dmaWriteByte (int a, int d) {
1311: d &= 0xff;
1312: int al = a & 0xff;
1313: if (al == DMA_GCR) {
1314: if (DMA_DEBUG_TRACE != 0) {
1315: System.out.printf ("%d %08x dmaWb(0x%08x,0x%02x)\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1316: }
1317: dmaBT = d & DMA_BT;
1318: dmaBR = d & DMA_BR;
1319: dmaBurstSpan = XEiJ.dmaCycleUnit << (4 + (dmaBT >> 2));
1320: dmaBurstInterval = dmaBurstSpan << (1 + (dmaBR & 3));
1321: return;
1322: }
1323: int i = al >> 6;
1324: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
1325: System.out.printf ("%d %08x dmaWb(0x%08x,0x%02x)\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1326: }
1327: switch (al & 0x3f) {
1328: case DMA_CSR:
1329:
1330:
1331:
1332:
1333: if ((d & DMA_COC) != 0) {
1334: dmaCOC[i] = 0;
1335: }
1336: if ((d & DMA_PCT) != 0) {
1337: dmaPCT[i] = 0;
1338: }
1339: if ((d & DMA_BLC) != 0) {
1340: dmaBLC[i] = 0;
1341: }
1342: if ((d & DMA_NDT) != 0) {
1343: dmaNDT[i] = 0;
1344: }
1345: if ((d & DMA_ERR) != 0) {
1346: dmaERR[i] = 0;
1347: dmaErrorCode[i] = 0;
1348: }
1349: if ((d & DMA_DIT) != 0) {
1350: dmaDIT[i] = 0;
1351: }
1352: return;
1353: case DMA_CER:
1354:
1355: return;
1356: case DMA_DCR:
1357: if (dmaACT[i] != 0) {
1358: dmaErrorExit (i, DMA_TIMING_ERROR);
1359: return;
1360: }
1361: dmaXRM[i] = d & DMA_XRM;
1362: dmaDTYP[i] = d & DMA_DTYP;
1363: dmaDPS[i] = d & DMA_DPS;
1364: dmaDACValue[i] = (dmaDAC[i] == DMA_INC_DAR ? 1 : dmaDAC[i] == DMA_DEC_DAR ? -1 : 0) * (dmaDPS[i] == DMA_PORT_8_BIT ? 2 : 1);
1365: dmaPCL[i] = d & DMA_PCL;
1366: return;
1367: case DMA_OCR:
1368: dmaDIR[i] = d & DMA_DIR;
1369: dmaBTD[i] = d & DMA_BTD;
1370: dmaSIZE[i] = d & DMA_SIZE;
1371: dmaCHAIN[i] = d & DMA_CHAIN;
1372: dmaREQG[i] = d & DMA_REQG;
1373: return;
1374: case DMA_SCR:
1375: if (dmaACT[i] != 0) {
1376: dmaErrorExit (i, DMA_TIMING_ERROR);
1377: return;
1378: }
1379: dmaMAC[i] = d & DMA_MAC;
1380: dmaMACValue[i] = dmaMAC[i] == DMA_INC_MAR ? 1 : dmaMAC[i] == DMA_DEC_MAR ? -1 : 0;
1381: dmaDAC[i] = d & DMA_DAC;
1382: dmaDACValue[i] = (dmaDAC[i] == DMA_INC_DAR ? 1 : dmaDAC[i] == DMA_DEC_DAR ? -1 : 0) * (dmaDPS[i] == DMA_PORT_8_BIT ? 2 : 1);
1383: return;
1384: case DMA_CCR:
1385: if (dmaHLT[i] != (d & DMA_HLT)) {
1386: dmaHalt (i, (d & DMA_HLT));
1387: }
1388: dmaITE[i] = d & DMA_ITE;
1389:
1390: if ((d & DMA_CNT) != 0) {
1391: if ((dmaACT[i] == 0 && (d & DMA_STR) == 0) || dmaBLC[i] != 0) {
1392: dmaErrorExit (i, DMA_TIMING_ERROR);
1393: return;
1394: }
1395: if (dmaCHAIN[i] != DMA_NO_CHAINING) {
1396: dmaErrorExit (i, DMA_CONFIGURATION_ERROR);
1397: return;
1398: }
1399: dmaCNT[i] = DMA_CNT;
1400: }
1401:
1402: if ((d & DMA_SAB) != 0) {
1403:
1404: dmaCOC[i] = 0;
1405: dmaBLC[i] = 0;
1406: dmaNDT[i] = 0;
1407: dmaHLT[i] = 0;
1408: dmaCNT[i] = 0;
1409: if (dmaACT[i] != 0 || (d & DMA_STR) != 0) {
1410: dmaErrorExit (i, DMA_SOFTWARE_ABORT);
1411: }
1412: return;
1413: }
1414:
1415: if ((d & DMA_STR) != 0) {
1416: dmaStart (i);
1417: }
1418: return;
1419: case DMA_MTC:
1420: if (dmaACT[i] != 0) {
1421: dmaErrorExit (i, DMA_TIMING_ERROR);
1422: return;
1423: }
1424: dmaMTC[i] = d << 8 | (dmaMTC[i] & 0xff);
1425: return;
1426: case DMA_MTC + 1:
1427: if (dmaACT[i] != 0) {
1428: dmaErrorExit (i, DMA_TIMING_ERROR);
1429: return;
1430: }
1431: dmaMTC[i] = (dmaMTC[i] & ~0xff) | d;
1432: return;
1433: case DMA_MAR:
1434: if (dmaACT[i] != 0) {
1435: dmaErrorExit (i, DMA_TIMING_ERROR);
1436: return;
1437: }
1438: dmaMAR[i] = d << 24 | (dmaMAR[i] & ~(0xff << 24));
1439: return;
1440: case DMA_MAR + 1:
1441: if (dmaACT[i] != 0) {
1442: dmaErrorExit (i, DMA_TIMING_ERROR);
1443: return;
1444: }
1445: dmaMAR[i] = d << 16 | (dmaMAR[i] & ~(0xff << 16));
1446: return;
1447: case DMA_MAR + 2:
1448: if (dmaACT[i] != 0) {
1449: dmaErrorExit (i, DMA_TIMING_ERROR);
1450: return;
1451: }
1452: dmaMAR[i] = (dmaMAR[i] & ~(0xff << 8)) | d << 8;
1453: return;
1454: case DMA_MAR + 3:
1455: if (dmaACT[i] != 0) {
1456: dmaErrorExit (i, DMA_TIMING_ERROR);
1457: return;
1458: }
1459: dmaMAR[i] = (dmaMAR[i] & ~0xff) | d;
1460: return;
1461: case DMA_DAR:
1462: if (dmaACT[i] != 0) {
1463: dmaErrorExit (i, DMA_TIMING_ERROR);
1464: return;
1465: }
1466: dmaDAR[i] = d << 24 | (dmaDAR[i] & ~(0xff << 24));
1467: return;
1468: case DMA_DAR + 1:
1469: if (dmaACT[i] != 0) {
1470: dmaErrorExit (i, DMA_TIMING_ERROR);
1471: return;
1472: }
1473: dmaDAR[i] = d << 16 | (dmaDAR[i] & ~(0xff << 16));
1474: return;
1475: case DMA_DAR + 2:
1476: if (dmaACT[i] != 0) {
1477: dmaErrorExit (i, DMA_TIMING_ERROR);
1478: return;
1479: }
1480: dmaDAR[i] = (dmaDAR[i] & ~(0xff << 8)) | d << 8;
1481: return;
1482: case DMA_DAR + 3:
1483: if (dmaACT[i] != 0) {
1484: dmaErrorExit (i, DMA_TIMING_ERROR);
1485: return;
1486: }
1487: dmaDAR[i] = (dmaDAR[i] & ~0xff) | d;
1488: return;
1489: case DMA_BTC:
1490: dmaBTC[i] = d << 8 | (dmaBTC[i] & 0xff);
1491: return;
1492: case DMA_BTC + 1:
1493: dmaBTC[i] = (dmaBTC[i] & ~0xff) | d;
1494: return;
1495: case DMA_BAR:
1496: dmaBAR[i] = d << 24 | (dmaBAR[i] & ~(0xff << 24));
1497: return;
1498: case DMA_BAR + 1:
1499: dmaBAR[i] = d << 16 | (dmaBAR[i] & ~(0xff << 16));
1500: return;
1501: case DMA_BAR + 2:
1502: dmaBAR[i] = (dmaBAR[i] & ~(0xff << 8)) | d << 8;
1503: return;
1504: case DMA_BAR + 3:
1505: dmaBAR[i] = (dmaBAR[i] & ~0xff) | d;
1506: return;
1507: case DMA_NIV:
1508: dmaNIV[i] = d;
1509: return;
1510: case DMA_EIV:
1511: dmaEIV[i] = d;
1512: return;
1513: case DMA_MFC:
1514: if (dmaACT[i] != 0) {
1515: dmaErrorExit (i, DMA_TIMING_ERROR);
1516: return;
1517: }
1518: dmaMFC[i] = d & DMA_FC2;
1519: if (DataBreakPoint.DBP_ON) {
1520: dmaMFCMap[i] = dmaMFC[i] == 0 ? DataBreakPoint.dbpUserMap : DataBreakPoint.dbpSuperMap;
1521: } else {
1522: dmaMFCMap[i] = dmaMFC[i] == 0 ? XEiJ.busUserMap : XEiJ.busSuperMap;
1523: }
1524: return;
1525: case DMA_CPR:
1526: dmaCP[i] = d & DMA_CP;
1527: return;
1528: case DMA_DFC:
1529: if (dmaACT[i] != 0) {
1530: dmaErrorExit (i, DMA_TIMING_ERROR);
1531: return;
1532: }
1533: dmaDFC[i] = d & DMA_FC2;
1534: if (DataBreakPoint.DBP_ON) {
1535: dmaDFCMap[i] = dmaDFC[i] == 0 ? DataBreakPoint.dbpUserMap : DataBreakPoint.dbpSuperMap;
1536: } else {
1537: dmaDFCMap[i] = dmaDFC[i] == 0 ? XEiJ.busUserMap : XEiJ.busSuperMap;
1538: }
1539: return;
1540: case DMA_BFC:
1541: dmaBFC[i] = d & DMA_FC2;
1542: if (DataBreakPoint.DBP_ON) {
1543: dmaBFCMap[i] = dmaBFC[i] == 0 ? DataBreakPoint.dbpUserMap : DataBreakPoint.dbpSuperMap;
1544: } else {
1545: dmaBFCMap[i] = dmaBFC[i] == 0 ? XEiJ.busUserMap : XEiJ.busSuperMap;
1546: }
1547: return;
1548: default:
1549: return;
1550: }
1551: }
1552:
1553: public static void dmaWriteWord (int a, int d) {
1554: d = (char) d;
1555: int al = a & 0xff;
1556: int i = al >> 6;
1557: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
1558: System.out.printf ("%d %08x dmaWw(0x%08x,0x%04x)\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1559: }
1560: switch (al & 0x3f) {
1561: case DMA_MTC:
1562: if (dmaACT[i] != 0) {
1563: dmaErrorExit (i, DMA_TIMING_ERROR);
1564: } else {
1565: dmaMTC[i] = d;
1566: }
1567: return;
1568: case DMA_MAR:
1569: if (dmaACT[i] != 0) {
1570: dmaErrorExit (i, DMA_TIMING_ERROR);
1571: } else {
1572: dmaMAR[i] = d << 16 | (char) dmaMAR[i];
1573: }
1574: return;
1575: case DMA_MAR + 2:
1576: if (dmaACT[i] != 0) {
1577: dmaErrorExit (i, DMA_TIMING_ERROR);
1578: } else {
1579: dmaMAR[i] = (dmaMAR[i] & ~0xffff) | d;
1580: }
1581: return;
1582: case DMA_DAR:
1583: if (dmaACT[i] != 0) {
1584: dmaErrorExit (i, DMA_TIMING_ERROR);
1585: } else {
1586: dmaDAR[i] = d << 16 | (char) dmaDAR[i];
1587: }
1588: return;
1589: case DMA_DAR + 2:
1590: if (dmaACT[i] != 0) {
1591: dmaErrorExit (i, DMA_TIMING_ERROR);
1592: } else {
1593: dmaDAR[i] = (dmaDAR[i] & ~0xffff) | d;
1594: }
1595: return;
1596: case DMA_BTC:
1597: dmaBTC[i] = (char) d;
1598: return;
1599: case DMA_BAR:
1600: dmaBAR[i] = d << 16 | (char) dmaBAR[i];
1601: return;
1602: case DMA_BAR + 2:
1603: dmaBAR[i] = (dmaBAR[i] & ~0xffff) | d;
1604: return;
1605: default:
1606: dmaWriteByte (a, d >> 8);
1607: dmaWriteByte (a + 1, d);
1608: }
1609: }
1610:
1611: public static void dmaWriteLong (int a, int d) {
1612: int al = a & 0xff;
1613: int i = al >> 6;
1614: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
1615: System.out.printf ("%d %08x dmaWl(0x%08x,0x%08x)\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1616: }
1617: switch (al & 0x3f) {
1618: case DMA_MAR:
1619: if (dmaACT[i] != 0) {
1620: dmaErrorExit (i, DMA_TIMING_ERROR);
1621: } else {
1622: dmaMAR[i] = d;
1623: if (DMA_ALERT_HIMEM) {
1624: if ((d & 0xff000000) != 0 && Model.MPU_MC68020 <= XEiJ.currentMPU) {
1625: System.out.printf ("%08x DMA_MAR[%d]=%08X\n", XEiJ.regPC0, i, d);
1626: }
1627: }
1628: }
1629: return;
1630: case DMA_DAR:
1631: if (dmaACT[i] != 0) {
1632: dmaErrorExit (i, DMA_TIMING_ERROR);
1633: } else {
1634: dmaDAR[i] = d;
1635: if (DMA_ALERT_HIMEM) {
1636: if ((d & 0xff000000) != 0 && Model.MPU_MC68020 <= XEiJ.currentMPU) {
1637: System.out.printf ("%08x DMA_DAR[%d]=%08X\n", XEiJ.regPC0, i, d);
1638: }
1639: }
1640: }
1641: return;
1642: case DMA_BAR:
1643: dmaBAR[i] = d;
1644: if (DMA_ALERT_HIMEM) {
1645: if ((d & 0xff000000) != 0 && Model.MPU_MC68020 <= XEiJ.currentMPU) {
1646: System.out.printf ("%08x DMA_BAR[%d]=%08X\n", XEiJ.regPC0, i, d);
1647: }
1648: }
1649: return;
1650: default:
1651: dmaWriteWord (a, d >> 16);
1652: dmaWriteWord (a + 2, d);
1653: }
1654: }
1655:
1656:
1657:
1658: }
1659:
1660:
1661: