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