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: dmaTransfer (i);
527: }
528: }
529:
530:
531:
532: public static void dmaContinue (int i) {
533: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
534: System.out.printf ("%d %08x dmaContinue(%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i);
535: }
536: if (dmaREQG[i] == DMA_AUTO_REQUEST) {
537: if (XEiJ.mpuClockTime < dmaBurstEnd) {
538:
539:
540:
541: dmaInnerClock[i] = dmaRequestTime[i];
542: TickerQueue.tkqAdd (dmaTickerArray[i], dmaInnerClock[i]);
543: } else {
544: dmaBurstStart += dmaBurstInterval;
545: if (dmaBurstStart < XEiJ.mpuClockTime) {
546: dmaBurstStart = XEiJ.mpuClockTime + dmaBurstInterval;
547: }
548: dmaBurstEnd = dmaBurstStart + dmaBurstSpan;
549:
550: dmaInnerClock[i] = dmaBurstStart;
551: TickerQueue.tkqAdd (dmaTickerArray[i], dmaInnerClock[i]);
552: }
553: } else if (dmaREQG[i] == DMA_AUTO_REQUEST_MAX) {
554:
555:
556:
557: dmaInnerClock[i] = dmaRequestTime[i];
558: TickerQueue.tkqAdd (dmaTickerArray[i], dmaInnerClock[i]);
559: }
560: }
561:
562:
563:
564: public static void dmaHalt (int i, int hlt) {
565: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
566: System.out.printf ("%d %08x dmaHalt(%d,%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i, hlt);
567: }
568: if ((~dmaHLT[i] & hlt) != 0) {
569: if (dmaACT[i] == 0) {
570: dmaErrorExit (i, DMA_TIMING_ERROR);
571: return;
572: }
573: dmaHLT[i] = DMA_HLT;
574: dmaRequestTime[i] = XEiJ.FAR_FUTURE;
575: if (dmaInnerClock[i] != XEiJ.FAR_FUTURE) {
576: dmaInnerClock[i] = XEiJ.FAR_FUTURE;
577: TickerQueue.tkqRemove (dmaTickerArray[i]);
578: }
579: } else if ((dmaHLT[i] & ~hlt) != 0) {
580: dmaHLT[i] = 0;
581: if (dmaACT[i] == 0) {
582: return;
583: }
584: dmaRequestTime[i] = XEiJ.mpuClockTime;
585: if (dmaREQG[i] == DMA_AUTO_REQUEST) {
586: dmaBurstStart = XEiJ.mpuClockTime;
587: dmaBurstEnd = dmaBurstStart + dmaBurstSpan;
588: }
589: dmaContinue (i);
590: }
591: }
592:
593:
594:
595:
596: public static void dmaComplete (int i) {
597: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
598: System.out.printf ("%d %08x dmaComplete(%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i);
599: }
600: dmaRequestTime[i] = XEiJ.FAR_FUTURE;
601: dmaCOC[i] = DMA_COC;
602: dmaERR[i] = 0;
603: dmaACT[i] = 0;
604: dmaSTR[i] = 0;
605: dmaCNT[i] = 0;
606: dmaSAB[i] = 0;
607: dmaErrorCode[i] = 0;
608: if (dmaITE[i] != 0) {
609: dmaInnerRequest[i << 1]++;
610: XEiJ.mpuIRR |= XEiJ.MPU_DMA_INTERRUPT_MASK;
611: }
612: if (dmaInnerClock[i] != XEiJ.FAR_FUTURE) {
613: dmaInnerClock[i] = XEiJ.FAR_FUTURE;
614: TickerQueue.tkqRemove (dmaTickerArray[i]);
615: }
616: }
617:
618:
619:
620:
621: public static void dmaErrorExit (int i, int code) {
622: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
623: System.out.printf ("%d %08x dmaErrorExit(%d,%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i, code);
624: }
625: dmaRequestTime[i] = XEiJ.FAR_FUTURE;
626: dmaCOC[i] = DMA_COC;
627: dmaERR[i] = DMA_ERR;
628: dmaACT[i] = 0;
629: dmaSTR[i] = 0;
630: dmaCNT[i] = 0;
631: dmaHLT[i] = 0;
632: dmaSAB[i] = 0;
633: dmaErrorCode[i] = code;
634: if (dmaITE[i] != 0) {
635: dmaInnerRequest[i << 1 | 1]++;
636: XEiJ.mpuIRR |= XEiJ.MPU_DMA_INTERRUPT_MASK;
637: }
638: if (dmaInnerClock[i] != XEiJ.FAR_FUTURE) {
639: dmaInnerClock[i] = XEiJ.FAR_FUTURE;
640: TickerQueue.tkqRemove (dmaTickerArray[i]);
641: }
642: }
643:
644:
645: public static void dmaFallPCL (int i) {
646: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
647: System.out.printf ("%d %08x dmaFallPCL(%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i);
648: }
649: if (dmaPCS[i] != 0) {
650: dmaPCS[i] = 0;
651: dmaPCT[i] = DMA_PCT;
652: }
653: }
654:
655:
656: public static void dmaRisePCL (int i) {
657: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
658: System.out.printf ("%d %08x dmaRisePCL(%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i);
659: }
660: dmaPCS[i] = DMA_PCS;
661: }
662:
663:
664:
665: public static void dmaFallREQ (int i) {
666: dmaFallREQ (i, 0);
667: }
668: public static void dmaFallREQ (int i, long time) {
669: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
670: System.out.printf ("%d %08x dmaFallREQ(%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i);
671: }
672: dmaReqPin[i] = 0;
673: if (dmaACT[i] != 0 &&
674: (dmaREQG[i] & (DMA_EXTERNAL_REQUEST & DMA_DUAL_REQUEST)) != 0) {
675:
676:
677: dmaInnerClock[i] = time != 0 ? time : XEiJ.mpuClockTime + XEiJ.dmaCycleUnit * 1;
678: TickerQueue.tkqAdd (dmaTickerArray[i], dmaInnerClock[i]);
679: }
680: }
681:
682:
683:
684: public static void dmaRiseREQ (int i) {
685: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
686: System.out.printf ("%d %08x dmaRiseREQ(%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i);
687: }
688: dmaReqPin[i] = 1;
689: dmaInnerClock[i] = XEiJ.FAR_FUTURE;
690: TickerQueue.tkqRemove (dmaTickerArray[i]);
691: }
692:
693:
694:
695: @SuppressWarnings ("fallthrough") public static void dmaTransfer (int i) {
696: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
697: System.out.printf ("%d %08x dmaTransfer(%d,0x%08x,0x%08x,%d)\n", XEiJ.mpuClockTime, XEiJ.regPC0, i,
698: dmaDIR[i] == DMA_MEMORY_TO_DEVICE ? dmaMAR[i] : dmaDAR[i],
699: dmaDIR[i] == DMA_MEMORY_TO_DEVICE ? dmaDAR[i] : dmaMAR[i],
700: dmaSIZE[i] == DMA_BYTE_SIZE || dmaSIZE[i] == DMA_UNPACKED_8_BIT ? 1 : dmaSIZE[i] == DMA_WORD_SIZE ? 2 : 4);
701: }
702: if (dmaHLT[i] != 0) {
703: return;
704: }
705: transfer:
706: {
707: int code = 0;
708: try {
709: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.dmaWaitTime : XEiJ.dmaNoWaitTime;
710: switch (dmaSIZE[i]) {
711: case DMA_BYTE_SIZE:
712: if (dmaDIR[i] == DMA_MEMORY_TO_DEVICE) {
713:
714: code = DMA_MEMORY_BUS_ERROR;
715: MemoryMappedDevice[] mm = dmaMFCMap[i];
716: int a = dmaMAR[i];
717: int ac = dmaMACValue[i];
718: int data = dmaMemoryCarry[i];
719: if (0 <= data) {
720: dmaMemoryCarry[i] = -1;
721: } else if ((a & 1) == 0 && ac == 1 && 2 <= dmaMTC[i]) {
722: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a);
723: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
724: dmaMemoryCarry[i] = data & 255;
725: data >>= 8;
726: } else if ((a & 1) != 0 && ac == -1 && 2 <= dmaMTC[i]) {
727: data = mm[(a - 1) >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a - 1);
728: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
729: dmaMemoryCarry[i] = data >> 8;
730: data &= 255;
731: } else {
732: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a);
733: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
734: }
735: dmaMAR[i] = a + ac;
736:
737: if (i == 2) {
738: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
739: MercuryUnit.mu4ExackStart ();
740: }
741: }
742:
743: code = DMA_DEVICE_BUS_ERROR;
744: mm = dmaDFCMap[i];
745: a = dmaDAR[i];
746: ac = dmaDACValue[i];
747: int carry = dmaDeviceCarry[i];
748: if (0 <= carry) {
749: if ((a & 1) != 0) {
750: data = carry << 8 | data;
751: mm[(a - 1) >>> XEiJ.BUS_PAGE_BITS].mmdWw (a - 1, data);
752: } else {
753: data = data << 8 | carry;
754: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWw (a, data);
755: }
756: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
757: dmaDeviceCarry[i] = -1;
758: } else if (((a & 1) == 0 ? ac == 1 : ac == -1) && 2 <= dmaMTC[i]) {
759: dmaDeviceCarry[i] = data;
760: } else {
761: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWb (a, data);
762: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
763: }
764: dmaDAR[i] = a + ac;
765: } else {
766:
767: if (i == 2) {
768: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
769: MercuryUnit.mu4ExackStart ();
770: }
771: }
772:
773: code = DMA_DEVICE_BUS_ERROR;
774: MemoryMappedDevice[] mm = dmaDFCMap[i];
775: int a = dmaDAR[i];
776: int ac = dmaDACValue[i];
777: int data = dmaDeviceCarry[i];
778: if (0 <= data) {
779: dmaDeviceCarry[i] = -1;
780: } else if ((a & 1) == 0 && ac == 1 && 2 <= dmaMTC[i]) {
781: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a);
782: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
783: dmaDeviceCarry[i] = data & 255;
784: data >>= 8;
785: } else if ((a & 1) != 0 && ac == -1 && 2 <= dmaMTC[i]) {
786: data = mm[(a - 1) >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a - 1);
787: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
788: dmaDeviceCarry[i] = data >> 8;
789: data &= 255;
790: } else {
791: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a);
792: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
793: }
794: dmaDAR[i] = a + ac;
795:
796: code = DMA_MEMORY_BUS_ERROR;
797: mm = dmaMFCMap[i];
798: a = dmaMAR[i];
799: ac = dmaMACValue[i];
800: int carry = dmaMemoryCarry[i];
801: if (0 <= carry) {
802: if ((a & 1) != 0) {
803: data = carry << 8 | data;
804: mm[(a - 1) >>> XEiJ.BUS_PAGE_BITS].mmdWw (a - 1, data);
805: } else {
806: data = data << 8 | carry;
807: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWw (a, data);
808: }
809: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
810: dmaMemoryCarry[i] = -1;
811: } else if (((a & 1) == 0 ? ac == 1 : ac == -1) && 2 <= dmaMTC[i]) {
812: dmaMemoryCarry[i] = data;
813: } else {
814: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWb (a, data);
815: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
816: }
817: dmaMAR[i] = a + ac;
818: }
819: break;
820:
821: case DMA_WORD_SIZE:
822: if (dmaDIR[i] == DMA_MEMORY_TO_DEVICE) {
823:
824: code = DMA_MEMORY_BUS_ERROR;
825: MemoryMappedDevice[] mm = dmaMFCMap[i];
826: int a = dmaMAR[i];
827: int ac = dmaMACValue[i];
828: if ((a & 1) != 0) {
829: dmaErrorExit (i, DMA_MEMORY_ADDRESS_ERROR);
830: break transfer;
831: }
832: int data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a);
833: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
834: dmaMAR[i] = a + ac * 2;
835:
836: if (i == 2) {
837: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
838: MercuryUnit.mu4ExackStart ();
839: }
840: }
841:
842: code = DMA_DEVICE_BUS_ERROR;
843: mm = dmaDFCMap[i];
844: a = dmaDAR[i];
845: ac = dmaDACValue[i];
846: if (dmaDPS[i] == DMA_PORT_8_BIT) {
847: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWb (a, data >> 8);
848: mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdWb (a + 2, data);
849: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles * 2;
850: } else {
851: if ((a & 1) != 0) {
852: dmaErrorExit (i, DMA_DEVICE_ADDRESS_ERROR);
853: break transfer;
854: }
855: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWw (a, data);
856: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
857: }
858: dmaDAR[i] = a + ac * 2;
859: } else {
860:
861: if (i == 2) {
862: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
863: MercuryUnit.mu4ExackStart ();
864: }
865: }
866:
867: code = DMA_DEVICE_BUS_ERROR;
868: MemoryMappedDevice[] mm = dmaDFCMap[i];
869: int a = dmaDAR[i];
870: int ac = dmaDACValue[i];
871: int data;
872: if (dmaDPS[i] == DMA_PORT_8_BIT) {
873: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a) << 8;
874: data |= mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a + 2);
875: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles * 2;
876: } else {
877: if ((a & 1) != 0) {
878: dmaErrorExit (i, DMA_DEVICE_ADDRESS_ERROR);
879: break transfer;
880: }
881: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a);
882: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
883: }
884: dmaDAR[i] = a + ac * 2;
885:
886: code = DMA_MEMORY_BUS_ERROR;
887: mm = dmaMFCMap[i];
888: a = dmaMAR[i];
889: ac = dmaMACValue[i];
890: if ((a & 1) != 0) {
891: dmaErrorExit (i, DMA_MEMORY_ADDRESS_ERROR);
892: break transfer;
893: }
894: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWw (a, data);
895: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
896: dmaMAR[i] = a + ac * 2;
897: }
898: break;
899:
900: case DMA_LONG_WORD_SIZE:
901: if (dmaDIR[i] == DMA_MEMORY_TO_DEVICE) {
902:
903: code = DMA_MEMORY_BUS_ERROR;
904: MemoryMappedDevice[] mm = dmaMFCMap[i];
905: int a = dmaMAR[i];
906: int ac = dmaMACValue[i];
907: if ((a & 1) != 0) {
908: dmaErrorExit (i, DMA_MEMORY_ADDRESS_ERROR);
909: break transfer;
910: }
911: int data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a) << 16;
912: data |= mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 2);
913: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles * 2;
914: dmaMAR[i] = a + ac * 4;
915:
916: if (i == 2) {
917: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
918: MercuryUnit.mu4ExackStart ();
919: }
920: }
921:
922: code = DMA_DEVICE_BUS_ERROR;
923: mm = dmaDFCMap[i];
924: a = dmaDAR[i];
925: ac = dmaDACValue[i];
926: if (dmaDPS[i] == DMA_PORT_8_BIT) {
927: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWb (a, data >> 24);
928: mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdWb (a + 2, data >> 16);
929: mm[(a + 4) >>> XEiJ.BUS_PAGE_BITS].mmdWb (a + 4, data >> 8);
930: mm[(a + 6) >>> XEiJ.BUS_PAGE_BITS].mmdWb (a + 6, data);
931: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles * 4;
932: } else {
933: if ((a & 1) != 0) {
934: dmaErrorExit (i, DMA_DEVICE_ADDRESS_ERROR);
935: break transfer;
936: }
937: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWw (a, data >> 16);
938: mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdWw (a + 2, data);
939: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles * 2;
940: }
941: dmaDAR[i] = a + ac * 4;
942: } else {
943:
944: if (i == 2) {
945: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
946: MercuryUnit.mu4ExackStart ();
947: }
948: }
949:
950: code = DMA_DEVICE_BUS_ERROR;
951: MemoryMappedDevice[] mm = dmaDFCMap[i];
952: int a = dmaDAR[i];
953: int ac = dmaDACValue[i];
954: int data;
955: if (dmaDPS[i] == DMA_PORT_8_BIT) {
956: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a) << 24;
957: data |= mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a + 2) << 16;
958: data |= mm[(a + 4) >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a + 4) << 8;
959: data |= mm[(a + 6) >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a + 6);
960: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles * 4;
961: } else {
962: if ((a & 1) != 0) {
963: dmaErrorExit (i, DMA_DEVICE_ADDRESS_ERROR);
964: break transfer;
965: }
966: data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a) << 16;
967: data |= mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 2);
968: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles * 2;
969: }
970: dmaDAR[i] = a + ac * 4;
971:
972: code = DMA_MEMORY_BUS_ERROR;
973: mm = dmaMFCMap[i];
974: a = dmaMAR[i];
975: ac = dmaMACValue[i];
976: if ((a & 1) != 0) {
977: dmaErrorExit (i, DMA_MEMORY_ADDRESS_ERROR);
978: break transfer;
979: }
980: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWw (a, data >> 16);
981: mm[(a + 2) >>> XEiJ.BUS_PAGE_BITS].mmdWw (a + 2, data);
982: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles * 2;
983: dmaMAR[i] = a + ac * 4;
984: }
985: break;
986:
987: case DMA_UNPACKED_8_BIT:
988: if (dmaDIR[i] == DMA_MEMORY_TO_DEVICE) {
989:
990: code = DMA_MEMORY_BUS_ERROR;
991: MemoryMappedDevice[] mm = dmaMFCMap[i];
992: int a = dmaMAR[i];
993: int ac = dmaMACValue[i];
994: int data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a);
995: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
996: dmaMAR[i] = a + ac;
997:
998: if (i == 2) {
999: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
1000: MercuryUnit.mu4ExackStart ();
1001: }
1002: }
1003:
1004: code = DMA_DEVICE_BUS_ERROR;
1005: mm = dmaDFCMap[i];
1006: a = dmaDAR[i];
1007: ac = dmaDACValue[i];
1008: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWb (a, data);
1009: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
1010: dmaDAR[i] = a + ac;
1011: } else {
1012:
1013: if (i == 2) {
1014: if (MercuryUnit.MU4_ON && MercuryUnit.mu4On) {
1015: MercuryUnit.mu4ExackStart ();
1016: }
1017: }
1018:
1019: code = DMA_DEVICE_BUS_ERROR;
1020: MemoryMappedDevice[] mm = dmaDFCMap[i];
1021: int a = dmaDAR[i];
1022: int ac = dmaDACValue[i];
1023: int data = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRbz (a);
1024: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles;
1025: dmaDAR[i] = a + ac;
1026:
1027: code = DMA_MEMORY_BUS_ERROR;
1028: mm = dmaMFCMap[i];
1029: a = dmaMAR[i];
1030: ac = dmaMACValue[i];
1031: mm[a >>> XEiJ.BUS_PAGE_BITS].mmdWb (a, data);
1032: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaWriteCycles;
1033: dmaMAR[i] = a + ac;
1034: }
1035: break;
1036: }
1037:
1038: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaAdditionalCycles[i];
1039: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
1040: } catch (M68kException e) {
1041: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
1042: dmaErrorExit (i, code);
1043: break transfer;
1044: }
1045: dmaMTC[i]--;
1046: if (dmaMTC[i] != 0) {
1047: dmaContinue (i);
1048: } else if (dmaCHAIN[i] == DMA_ARRAY_CHAINING) {
1049: if (dmaBTC[i] != 0) {
1050:
1051: try {
1052: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.dmaWaitTime : XEiJ.dmaNoWaitTime;
1053: MemoryMappedDevice[] mm = dmaBFCMap[i];
1054: int a = dmaBAR[i];
1055: dmaMAR[i] = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRws (a) << 16 | mm[a + 2 >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 2);
1056: dmaMTC[i] = mm[a + 4 >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 4);
1057: dmaBAR[i] += 6;
1058: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles * 3;
1059: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
1060: } catch (M68kException e) {
1061: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
1062: dmaErrorExit (i, DMA_BASE_BUS_ERROR);
1063: break transfer;
1064: }
1065: dmaBTC[i]--;
1066: if (dmaMTC[i] == 0) {
1067: dmaErrorExit (i, DMA_MEMORY_COUNT_ERROR);
1068: break transfer;
1069: }
1070: if ((dmaSIZE[i] == DMA_WORD_SIZE || dmaSIZE[i] == DMA_LONG_WORD_SIZE) && (dmaMAR[i] & 1) != 0) {
1071: dmaErrorExit (i, DMA_MEMORY_ADDRESS_ERROR);
1072: break transfer;
1073: }
1074: dmaContinue (i);
1075: } else {
1076: dmaBLC[i] = DMA_BLC;
1077: dmaNDT[i] = 0;
1078: dmaComplete (i);
1079: }
1080: } else if (dmaCHAIN[i] == DMA_LINK_ARRAY_CHAINING) {
1081: if (dmaBAR[i] != 0) {
1082: if ((dmaBAR[i] & 1) != 0) {
1083: dmaErrorExit (i, DMA_BASE_ADDRESS_ERROR);
1084: break transfer;
1085: }
1086: try {
1087: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.dmaWaitTime : XEiJ.dmaNoWaitTime;
1088: MemoryMappedDevice[] mm = dmaBFCMap[i];
1089: int a = dmaBAR[i];
1090: dmaMAR[i] = mm[a >>> XEiJ.BUS_PAGE_BITS].mmdRws (a) << 16 | mm[a + 2 >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 2);
1091: dmaMTC[i] = mm[a + 4 >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 4);
1092: dmaBAR[i] = mm[a + 6 >>> XEiJ.BUS_PAGE_BITS].mmdRws (a + 6) << 16 | mm[a + 8 >>> XEiJ.BUS_PAGE_BITS].mmdRwz (a + 8);
1093: XEiJ.mpuClockTime += XEiJ.dmaCycleUnit * dmaReadCycles * 5;
1094: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
1095: } catch (M68kException e) {
1096: XEiJ.busWaitTime = XEiJ.busWaitCycles ? XEiJ.mpuWaitTime : XEiJ.mpuNoWaitTime;
1097: dmaErrorExit (i, DMA_BASE_BUS_ERROR);
1098: break transfer;
1099: }
1100: if (dmaMTC[i] == 0) {
1101: dmaErrorExit (i, DMA_MEMORY_COUNT_ERROR);
1102: break transfer;
1103: }
1104: if ((dmaSIZE[i] == DMA_WORD_SIZE || dmaSIZE[i] == DMA_LONG_WORD_SIZE) && (dmaMAR[i] & 1) != 0) {
1105: dmaErrorExit (i, DMA_MEMORY_ADDRESS_ERROR);
1106: break transfer;
1107: }
1108: dmaContinue (i);
1109: } else {
1110: dmaBLC[i] = DMA_BLC;
1111: dmaNDT[i] = 0;
1112: dmaComplete (i);
1113: }
1114: } else if (dmaCNT[i] != 0) {
1115: dmaBLC[i] = DMA_BLC;
1116: dmaCNT[i] = 0;
1117: if (dmaITE[i] != 0) {
1118: dmaInnerRequest[i << 1]++;
1119: XEiJ.mpuIRR |= XEiJ.MPU_DMA_INTERRUPT_MASK;
1120: }
1121: dmaMTC[i] = dmaBTC[i];
1122: dmaMAR[i] = dmaBAR[i];
1123: if (dmaMTC[i] == 0) {
1124: dmaErrorExit (i, DMA_MEMORY_COUNT_ERROR);
1125: break transfer;
1126: }
1127: if ((dmaSIZE[i] == DMA_WORD_SIZE || dmaSIZE[i] == DMA_LONG_WORD_SIZE) && (dmaMAR[i] & 1) != 0) {
1128: dmaErrorExit (i, DMA_MEMORY_ADDRESS_ERROR);
1129: break transfer;
1130: }
1131: dmaContinue (i);
1132: } else {
1133: dmaBLC[i] = 0;
1134: dmaNDT[i] = 0;
1135: dmaComplete (i);
1136: }
1137: }
1138: }
1139:
1140:
1141:
1142: public static int dmaReadByte (int a) {
1143: int d;
1144: int al = a & 0xff;
1145: if (al == DMA_GCR) {
1146: d = dmaBT | dmaBR;
1147: if (DMA_DEBUG_TRACE != 0) {
1148: System.out.printf ("%d %08x dmaRbz(0x%08x)=0x%02x\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1149: }
1150: } else {
1151: int i = al >> 6;
1152: switch (al & 0x3f) {
1153: case DMA_CSR:
1154: d = dmaCOC[i] | dmaBLC[i] | dmaNDT[i] | dmaERR[i] | dmaACT[i] | dmaDIT[i] | dmaPCT[i] | dmaPCS[i];
1155: break;
1156: case DMA_CER:
1157: d = dmaErrorCode[i];
1158: break;
1159: case DMA_DCR:
1160: d = dmaXRM[i] | dmaDTYP[i] | dmaDPS[i] | dmaPCL[i];
1161: break;
1162: case DMA_OCR:
1163: d = dmaDIR[i] | dmaBTD[i] | dmaSIZE[i] | dmaCHAIN[i] | dmaREQG[i];
1164: break;
1165: case DMA_SCR:
1166: d = dmaMAC[i] | dmaDAC[i];
1167: break;
1168: case DMA_CCR:
1169: d = dmaSTR[i] | dmaCNT[i] | dmaHLT[i] | dmaSAB[i] | dmaITE[i];
1170: break;
1171: case DMA_MTC:
1172: d = dmaMTC[i] >> 8;
1173: break;
1174: case DMA_MTC + 1:
1175: d = dmaMTC[i] & 0xff;
1176: break;
1177: case DMA_MAR:
1178: d = dmaMAR[i] >>> 24;
1179: break;
1180: case DMA_MAR + 1:
1181: d = dmaMAR[i] >> 16 & 0xff;
1182: break;
1183: case DMA_MAR + 2:
1184: d = (char) dmaMAR[i] >> 8;
1185: break;
1186: case DMA_MAR + 3:
1187: d = dmaMAR[i] & 0xff;
1188: break;
1189: case DMA_DAR:
1190: d = dmaDAR[i] >>> 24;
1191: break;
1192: case DMA_DAR + 1:
1193: d = dmaDAR[i] >> 16 & 0xff;
1194: break;
1195: case DMA_DAR + 2:
1196: d = (char) dmaDAR[i] >> 8;
1197: break;
1198: case DMA_DAR + 3:
1199: d = dmaDAR[i] & 0xff;
1200: break;
1201: case DMA_BTC:
1202: d = dmaBTC[i] >> 8;
1203: break;
1204: case DMA_BTC + 1:
1205: d = dmaBTC[i] & 0xff;
1206: break;
1207: case DMA_BAR:
1208: d = dmaBAR[i] >>> 24;
1209: break;
1210: case DMA_BAR + 1:
1211: d = dmaBAR[i] >> 16 & 0xff;
1212: break;
1213: case DMA_BAR + 2:
1214: d = (char) dmaBAR[i] >> 8;
1215: break;
1216: case DMA_BAR + 3:
1217: d = dmaBAR[i] & 0xff;
1218: break;
1219: case DMA_NIV:
1220: d = dmaNIV[i];
1221: break;
1222: case DMA_EIV:
1223: d = dmaEIV[i];
1224: break;
1225: case DMA_MFC:
1226: d = dmaMFC[i];
1227: break;
1228: case DMA_CPR:
1229: d = dmaCP[i];
1230: break;
1231: case DMA_DFC:
1232: d = dmaDFC[i];
1233: break;
1234: case DMA_BFC:
1235: d = dmaBFC[i];
1236: break;
1237: default:
1238: d = 0;
1239: }
1240: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
1241: System.out.printf ("%d %08x dmaRbz(0x%08x)=0x%02x\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1242: }
1243: }
1244: return d;
1245: }
1246:
1247: public static int dmaReadWord (int a) {
1248: int d;
1249: int al = a & 0xff;
1250: int i = al >> 6;
1251: switch (al & 0x3f) {
1252: case DMA_MTC:
1253: d = dmaMTC[i];
1254: break;
1255: case DMA_MAR:
1256: d = dmaMAR[i] >>> 16;
1257: break;
1258: case DMA_MAR + 2:
1259: d = (char) dmaMAR[i];
1260: break;
1261: case DMA_DAR:
1262: d = dmaDAR[i] >>> 16;
1263: break;
1264: case DMA_DAR + 2:
1265: d = (char) dmaDAR[i];
1266: break;
1267: case DMA_BTC:
1268: d = dmaBTC[i];
1269: break;
1270: case DMA_BAR:
1271: d = dmaBAR[i] >>> 16;
1272: break;
1273: case DMA_BAR + 2:
1274: d = (char) dmaBAR[i];
1275: break;
1276: default:
1277: d = dmaReadByte (a) << 8 | dmaReadByte (a + 1);
1278: }
1279: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
1280: System.out.printf ("%d %08x dmaRwz(0x%08x)=0x%04x\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1281: }
1282: return d;
1283: }
1284:
1285: public static int dmaReadLong (int a) {
1286: a &= XEiJ.BUS_MOTHER_MASK;
1287: int d;
1288: int al = a & 0xff;
1289: int i = al >> 6;
1290: switch (al & 0x3f) {
1291: case DMA_MAR:
1292: d = dmaMAR[i];
1293: break;
1294: case DMA_DAR:
1295: d = dmaDAR[i];
1296: break;
1297: case DMA_BAR:
1298: d = dmaBAR[i];
1299: break;
1300: default:
1301: d = dmaReadWord (a) << 16 | dmaReadWord (a + 2);
1302: }
1303: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
1304: System.out.printf ("%d %08x dmaRls(0x%08x)=0x%08x\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1305: }
1306: return d;
1307: }
1308:
1309: public static void dmaWriteByte (int a, int d) {
1310: d &= 0xff;
1311: int al = a & 0xff;
1312: if (al == DMA_GCR) {
1313: if (DMA_DEBUG_TRACE != 0) {
1314: System.out.printf ("%d %08x dmaWb(0x%08x,0x%02x)\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1315: }
1316: dmaBT = d & DMA_BT;
1317: dmaBR = d & DMA_BR;
1318: dmaBurstSpan = XEiJ.dmaCycleUnit << (4 + (dmaBT >> 2));
1319: dmaBurstInterval = dmaBurstSpan << (1 + (dmaBR & 3));
1320: return;
1321: }
1322: int i = al >> 6;
1323: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
1324: System.out.printf ("%d %08x dmaWb(0x%08x,0x%02x)\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1325: }
1326: switch (al & 0x3f) {
1327: case DMA_CSR:
1328:
1329:
1330:
1331:
1332: if ((d & DMA_COC) != 0) {
1333: dmaCOC[i] = 0;
1334: }
1335: if ((d & DMA_PCT) != 0) {
1336: dmaPCT[i] = 0;
1337: }
1338: if ((d & DMA_BLC) != 0) {
1339: dmaBLC[i] = 0;
1340: }
1341: if ((d & DMA_NDT) != 0) {
1342: dmaNDT[i] = 0;
1343: }
1344: if ((d & DMA_ERR) != 0) {
1345: dmaERR[i] = 0;
1346: dmaErrorCode[i] = 0;
1347: }
1348: if ((d & DMA_DIT) != 0) {
1349: dmaDIT[i] = 0;
1350: }
1351: return;
1352: case DMA_CER:
1353:
1354: return;
1355: case DMA_DCR:
1356: if (dmaACT[i] != 0) {
1357: dmaErrorExit (i, DMA_TIMING_ERROR);
1358: return;
1359: }
1360: dmaXRM[i] = d & DMA_XRM;
1361: dmaDTYP[i] = d & DMA_DTYP;
1362: dmaDPS[i] = d & DMA_DPS;
1363: dmaDACValue[i] = (dmaDAC[i] == DMA_INC_DAR ? 1 : dmaDAC[i] == DMA_DEC_DAR ? -1 : 0) * (dmaDPS[i] == DMA_PORT_8_BIT ? 2 : 1);
1364: dmaPCL[i] = d & DMA_PCL;
1365: return;
1366: case DMA_OCR:
1367: dmaDIR[i] = d & DMA_DIR;
1368: dmaBTD[i] = d & DMA_BTD;
1369: dmaSIZE[i] = d & DMA_SIZE;
1370: dmaCHAIN[i] = d & DMA_CHAIN;
1371: dmaREQG[i] = d & DMA_REQG;
1372: return;
1373: case DMA_SCR:
1374: if (dmaACT[i] != 0) {
1375: dmaErrorExit (i, DMA_TIMING_ERROR);
1376: return;
1377: }
1378: dmaMAC[i] = d & DMA_MAC;
1379: dmaMACValue[i] = dmaMAC[i] == DMA_INC_MAR ? 1 : dmaMAC[i] == DMA_DEC_MAR ? -1 : 0;
1380: dmaDAC[i] = d & DMA_DAC;
1381: dmaDACValue[i] = (dmaDAC[i] == DMA_INC_DAR ? 1 : dmaDAC[i] == DMA_DEC_DAR ? -1 : 0) * (dmaDPS[i] == DMA_PORT_8_BIT ? 2 : 1);
1382: return;
1383: case DMA_CCR:
1384: if (dmaHLT[i] != (d & DMA_HLT)) {
1385: dmaHalt (i, (d & DMA_HLT));
1386: }
1387: dmaITE[i] = d & DMA_ITE;
1388:
1389: if ((d & DMA_CNT) != 0) {
1390: if ((dmaACT[i] == 0 && (d & DMA_STR) == 0) || dmaBLC[i] != 0) {
1391: dmaErrorExit (i, DMA_TIMING_ERROR);
1392: return;
1393: }
1394: if (dmaCHAIN[i] != DMA_NO_CHAINING) {
1395: dmaErrorExit (i, DMA_CONFIGURATION_ERROR);
1396: return;
1397: }
1398: dmaCNT[i] = DMA_CNT;
1399: }
1400:
1401: if ((d & DMA_SAB) != 0) {
1402:
1403: dmaCOC[i] = 0;
1404: dmaBLC[i] = 0;
1405: dmaNDT[i] = 0;
1406: dmaHLT[i] = 0;
1407: dmaCNT[i] = 0;
1408: if (dmaACT[i] != 0 || (d & DMA_STR) != 0) {
1409: dmaErrorExit (i, DMA_SOFTWARE_ABORT);
1410: }
1411: return;
1412: }
1413:
1414: if ((d & DMA_STR) != 0) {
1415: dmaStart (i);
1416: }
1417: return;
1418: case DMA_MTC:
1419: if (dmaACT[i] != 0) {
1420: dmaErrorExit (i, DMA_TIMING_ERROR);
1421: return;
1422: }
1423: dmaMTC[i] = d << 8 | (dmaMTC[i] & 0xff);
1424: return;
1425: case DMA_MTC + 1:
1426: if (dmaACT[i] != 0) {
1427: dmaErrorExit (i, DMA_TIMING_ERROR);
1428: return;
1429: }
1430: dmaMTC[i] = (dmaMTC[i] & ~0xff) | d;
1431: return;
1432: case DMA_MAR:
1433: if (dmaACT[i] != 0) {
1434: dmaErrorExit (i, DMA_TIMING_ERROR);
1435: return;
1436: }
1437: dmaMAR[i] = d << 24 | (dmaMAR[i] & ~(0xff << 24));
1438: return;
1439: case DMA_MAR + 1:
1440: if (dmaACT[i] != 0) {
1441: dmaErrorExit (i, DMA_TIMING_ERROR);
1442: return;
1443: }
1444: dmaMAR[i] = d << 16 | (dmaMAR[i] & ~(0xff << 16));
1445: return;
1446: case DMA_MAR + 2:
1447: if (dmaACT[i] != 0) {
1448: dmaErrorExit (i, DMA_TIMING_ERROR);
1449: return;
1450: }
1451: dmaMAR[i] = (dmaMAR[i] & ~(0xff << 8)) | d << 8;
1452: return;
1453: case DMA_MAR + 3:
1454: if (dmaACT[i] != 0) {
1455: dmaErrorExit (i, DMA_TIMING_ERROR);
1456: return;
1457: }
1458: dmaMAR[i] = (dmaMAR[i] & ~0xff) | d;
1459: return;
1460: case DMA_DAR:
1461: if (dmaACT[i] != 0) {
1462: dmaErrorExit (i, DMA_TIMING_ERROR);
1463: return;
1464: }
1465: dmaDAR[i] = d << 24 | (dmaDAR[i] & ~(0xff << 24));
1466: return;
1467: case DMA_DAR + 1:
1468: if (dmaACT[i] != 0) {
1469: dmaErrorExit (i, DMA_TIMING_ERROR);
1470: return;
1471: }
1472: dmaDAR[i] = d << 16 | (dmaDAR[i] & ~(0xff << 16));
1473: return;
1474: case DMA_DAR + 2:
1475: if (dmaACT[i] != 0) {
1476: dmaErrorExit (i, DMA_TIMING_ERROR);
1477: return;
1478: }
1479: dmaDAR[i] = (dmaDAR[i] & ~(0xff << 8)) | d << 8;
1480: return;
1481: case DMA_DAR + 3:
1482: if (dmaACT[i] != 0) {
1483: dmaErrorExit (i, DMA_TIMING_ERROR);
1484: return;
1485: }
1486: dmaDAR[i] = (dmaDAR[i] & ~0xff) | d;
1487: return;
1488: case DMA_BTC:
1489: dmaBTC[i] = d << 8 | (dmaBTC[i] & 0xff);
1490: return;
1491: case DMA_BTC + 1:
1492: dmaBTC[i] = (dmaBTC[i] & ~0xff) | d;
1493: return;
1494: case DMA_BAR:
1495: dmaBAR[i] = d << 24 | (dmaBAR[i] & ~(0xff << 24));
1496: return;
1497: case DMA_BAR + 1:
1498: dmaBAR[i] = d << 16 | (dmaBAR[i] & ~(0xff << 16));
1499: return;
1500: case DMA_BAR + 2:
1501: dmaBAR[i] = (dmaBAR[i] & ~(0xff << 8)) | d << 8;
1502: return;
1503: case DMA_BAR + 3:
1504: dmaBAR[i] = (dmaBAR[i] & ~0xff) | d;
1505: return;
1506: case DMA_NIV:
1507: dmaNIV[i] = d;
1508: return;
1509: case DMA_EIV:
1510: dmaEIV[i] = d;
1511: return;
1512: case DMA_MFC:
1513: if (dmaACT[i] != 0) {
1514: dmaErrorExit (i, DMA_TIMING_ERROR);
1515: return;
1516: }
1517: dmaMFC[i] = d & DMA_FC2;
1518: if (DataBreakPoint.DBP_ON) {
1519: dmaMFCMap[i] = dmaMFC[i] == 0 ? DataBreakPoint.dbpUserMap : DataBreakPoint.dbpSuperMap;
1520: } else {
1521: dmaMFCMap[i] = dmaMFC[i] == 0 ? XEiJ.busUserMap : XEiJ.busSuperMap;
1522: }
1523: return;
1524: case DMA_CPR:
1525: dmaCP[i] = d & DMA_CP;
1526: return;
1527: case DMA_DFC:
1528: if (dmaACT[i] != 0) {
1529: dmaErrorExit (i, DMA_TIMING_ERROR);
1530: return;
1531: }
1532: dmaDFC[i] = d & DMA_FC2;
1533: if (DataBreakPoint.DBP_ON) {
1534: dmaDFCMap[i] = dmaDFC[i] == 0 ? DataBreakPoint.dbpUserMap : DataBreakPoint.dbpSuperMap;
1535: } else {
1536: dmaDFCMap[i] = dmaDFC[i] == 0 ? XEiJ.busUserMap : XEiJ.busSuperMap;
1537: }
1538: return;
1539: case DMA_BFC:
1540: dmaBFC[i] = d & DMA_FC2;
1541: if (DataBreakPoint.DBP_ON) {
1542: dmaBFCMap[i] = dmaBFC[i] == 0 ? DataBreakPoint.dbpUserMap : DataBreakPoint.dbpSuperMap;
1543: } else {
1544: dmaBFCMap[i] = dmaBFC[i] == 0 ? XEiJ.busUserMap : XEiJ.busSuperMap;
1545: }
1546: return;
1547: default:
1548: return;
1549: }
1550: }
1551:
1552: public static void dmaWriteWord (int a, int d) {
1553: d = (char) d;
1554: int al = a & 0xff;
1555: int i = al >> 6;
1556: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
1557: System.out.printf ("%d %08x dmaWw(0x%08x,0x%04x)\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1558: }
1559: switch (al & 0x3f) {
1560: case DMA_MTC:
1561: if (dmaACT[i] != 0) {
1562: dmaErrorExit (i, DMA_TIMING_ERROR);
1563: } else {
1564: dmaMTC[i] = d;
1565: }
1566: return;
1567: case DMA_MAR:
1568: if (dmaACT[i] != 0) {
1569: dmaErrorExit (i, DMA_TIMING_ERROR);
1570: } else {
1571: dmaMAR[i] = d << 16 | (char) dmaMAR[i];
1572: }
1573: return;
1574: case DMA_MAR + 2:
1575: if (dmaACT[i] != 0) {
1576: dmaErrorExit (i, DMA_TIMING_ERROR);
1577: } else {
1578: dmaMAR[i] = (dmaMAR[i] & ~0xffff) | d;
1579: }
1580: return;
1581: case DMA_DAR:
1582: if (dmaACT[i] != 0) {
1583: dmaErrorExit (i, DMA_TIMING_ERROR);
1584: } else {
1585: dmaDAR[i] = d << 16 | (char) dmaDAR[i];
1586: }
1587: return;
1588: case DMA_DAR + 2:
1589: if (dmaACT[i] != 0) {
1590: dmaErrorExit (i, DMA_TIMING_ERROR);
1591: } else {
1592: dmaDAR[i] = (dmaDAR[i] & ~0xffff) | d;
1593: }
1594: return;
1595: case DMA_BTC:
1596: dmaBTC[i] = (char) d;
1597: return;
1598: case DMA_BAR:
1599: dmaBAR[i] = d << 16 | (char) dmaBAR[i];
1600: return;
1601: case DMA_BAR + 2:
1602: dmaBAR[i] = (dmaBAR[i] & ~0xffff) | d;
1603: return;
1604: default:
1605: dmaWriteByte (a, d >> 8);
1606: dmaWriteByte (a + 1, d);
1607: }
1608: }
1609:
1610: public static void dmaWriteLong (int a, int d) {
1611: int al = a & 0xff;
1612: int i = al >> 6;
1613: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
1614: System.out.printf ("%d %08x dmaWl(0x%08x,0x%08x)\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1615: }
1616: switch (al & 0x3f) {
1617: case DMA_MAR:
1618: if (dmaACT[i] != 0) {
1619: dmaErrorExit (i, DMA_TIMING_ERROR);
1620: } else {
1621: dmaMAR[i] = d;
1622: if (DMA_ALERT_HIMEM) {
1623: if ((d & 0xff000000) != 0 && Model.MPU_MC68020 <= XEiJ.currentMPU) {
1624: System.out.printf ("%08x DMA_MAR[%d]=%08X\n", XEiJ.regPC0, i, d);
1625: }
1626: }
1627: }
1628: return;
1629: case DMA_DAR:
1630: if (dmaACT[i] != 0) {
1631: dmaErrorExit (i, DMA_TIMING_ERROR);
1632: } else {
1633: dmaDAR[i] = d;
1634: if (DMA_ALERT_HIMEM) {
1635: if ((d & 0xff000000) != 0 && Model.MPU_MC68020 <= XEiJ.currentMPU) {
1636: System.out.printf ("%08x DMA_DAR[%d]=%08X\n", XEiJ.regPC0, i, d);
1637: }
1638: }
1639: }
1640: return;
1641: case DMA_BAR:
1642: dmaBAR[i] = d;
1643: if (DMA_ALERT_HIMEM) {
1644: if ((d & 0xff000000) != 0 && Model.MPU_MC68020 <= XEiJ.currentMPU) {
1645: System.out.printf ("%08x DMA_BAR[%d]=%08X\n", XEiJ.regPC0, i, d);
1646: }
1647: }
1648: return;
1649: default:
1650: dmaWriteWord (a, d >> 16);
1651: dmaWriteWord (a + 2, d);
1652: }
1653: }
1654:
1655:
1656:
1657: }
1658:
1659:
1660: