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: if (d == 0xff) {
1256: dmaCOC[i] = 0;
1257: dmaBLC[i] = 0;
1258: dmaNDT[i] = 0;
1259: dmaERR[i] = 0;
1260: }
1261: return;
1262: case DMA_CER:
1263:
1264: return;
1265: case DMA_DCR:
1266: if (dmaACT[i] != 0) {
1267: dmaErrorExit (i, DMA_TIMING_ERROR);
1268: return;
1269: }
1270: dmaXRM[i] = d & DMA_XRM;
1271: dmaDTYP[i] = d & DMA_DTYP;
1272: dmaDPS[i] = d & DMA_DPS;
1273: dmaDACValue[i] = (dmaDAC[i] == DMA_INC_DAR ? 1 : dmaDAC[i] == DMA_DEC_DAR ? -1 : 0) * (dmaDPS[i] == DMA_PORT_8_BIT ? 2 : 1);
1274: dmaPCL[i] = d & DMA_PCL;
1275: return;
1276: case DMA_OCR:
1277: dmaDIR[i] = d & DMA_DIR;
1278: dmaBTD[i] = d & DMA_BTD;
1279: dmaSIZE[i] = d & DMA_SIZE;
1280: dmaCHAIN[i] = d & DMA_CHAIN;
1281: dmaREQG[i] = d & DMA_REQG;
1282: return;
1283: case DMA_SCR:
1284: if (dmaACT[i] != 0) {
1285: dmaErrorExit (i, DMA_TIMING_ERROR);
1286: return;
1287: }
1288: dmaMAC[i] = d & DMA_MAC;
1289: dmaMACValue[i] = dmaMAC[i] == DMA_INC_MAR ? 1 : dmaMAC[i] == DMA_DEC_MAR ? -1 : 0;
1290: dmaDAC[i] = d & DMA_DAC;
1291: dmaDACValue[i] = (dmaDAC[i] == DMA_INC_DAR ? 1 : dmaDAC[i] == DMA_DEC_DAR ? -1 : 0) * (dmaDPS[i] == DMA_PORT_8_BIT ? 2 : 1);
1292: return;
1293: case DMA_CCR:
1294: if (dmaHLT[i] != (d & DMA_HLT)) {
1295: dmaHalt (i, (d & DMA_HLT));
1296: }
1297: dmaITE[i] = d & DMA_ITE;
1298:
1299: if ((d & DMA_CNT) != 0) {
1300: if ((dmaACT[i] == 0 && (d & DMA_STR) == 0) || dmaBLC[i] != 0) {
1301: dmaErrorExit (i, DMA_TIMING_ERROR);
1302: return;
1303: }
1304: if (dmaCHAIN[i] != DMA_NO_CHAINING) {
1305: dmaErrorExit (i, DMA_CONFIGURATION_ERROR);
1306: return;
1307: }
1308: dmaCNT[i] = DMA_CNT;
1309: }
1310:
1311: if ((d & DMA_SAB) != 0) {
1312:
1313: dmaCOC[i] = 0;
1314: dmaBLC[i] = 0;
1315: dmaNDT[i] = 0;
1316: dmaHLT[i] = 0;
1317: dmaCNT[i] = 0;
1318: if (dmaACT[i] != 0 || (d & DMA_STR) != 0) {
1319: dmaErrorExit (i, DMA_SOFTWARE_ABORT);
1320: }
1321: return;
1322: }
1323:
1324: if ((d & DMA_STR) != 0) {
1325: dmaStart (i);
1326: }
1327: return;
1328: case DMA_MTC:
1329: if (dmaACT[i] != 0) {
1330: dmaErrorExit (i, DMA_TIMING_ERROR);
1331: return;
1332: }
1333: dmaMTC[i] = d << 8 | (dmaMTC[i] & 0xff);
1334: return;
1335: case DMA_MTC + 1:
1336: if (dmaACT[i] != 0) {
1337: dmaErrorExit (i, DMA_TIMING_ERROR);
1338: return;
1339: }
1340: dmaMTC[i] = (dmaMTC[i] & ~0xff) | d;
1341: return;
1342: case DMA_MAR:
1343: if (dmaACT[i] != 0) {
1344: dmaErrorExit (i, DMA_TIMING_ERROR);
1345: return;
1346: }
1347: dmaMAR[i] = d << 24 | (dmaMAR[i] & ~(0xff << 24));
1348: return;
1349: case DMA_MAR + 1:
1350: if (dmaACT[i] != 0) {
1351: dmaErrorExit (i, DMA_TIMING_ERROR);
1352: return;
1353: }
1354: dmaMAR[i] = d << 16 | (dmaMAR[i] & ~(0xff << 16));
1355: return;
1356: case DMA_MAR + 2:
1357: if (dmaACT[i] != 0) {
1358: dmaErrorExit (i, DMA_TIMING_ERROR);
1359: return;
1360: }
1361: dmaMAR[i] = (dmaMAR[i] & ~(0xff << 8)) | d << 8;
1362: return;
1363: case DMA_MAR + 3:
1364: if (dmaACT[i] != 0) {
1365: dmaErrorExit (i, DMA_TIMING_ERROR);
1366: return;
1367: }
1368: dmaMAR[i] = (dmaMAR[i] & ~0xff) | d;
1369: return;
1370: case DMA_DAR:
1371: if (dmaACT[i] != 0) {
1372: dmaErrorExit (i, DMA_TIMING_ERROR);
1373: return;
1374: }
1375: dmaDAR[i] = d << 24 | (dmaDAR[i] & ~(0xff << 24));
1376: return;
1377: case DMA_DAR + 1:
1378: if (dmaACT[i] != 0) {
1379: dmaErrorExit (i, DMA_TIMING_ERROR);
1380: return;
1381: }
1382: dmaDAR[i] = d << 16 | (dmaDAR[i] & ~(0xff << 16));
1383: return;
1384: case DMA_DAR + 2:
1385: if (dmaACT[i] != 0) {
1386: dmaErrorExit (i, DMA_TIMING_ERROR);
1387: return;
1388: }
1389: dmaDAR[i] = (dmaDAR[i] & ~(0xff << 8)) | d << 8;
1390: return;
1391: case DMA_DAR + 3:
1392: if (dmaACT[i] != 0) {
1393: dmaErrorExit (i, DMA_TIMING_ERROR);
1394: return;
1395: }
1396: dmaDAR[i] = (dmaDAR[i] & ~0xff) | d;
1397: return;
1398: case DMA_BTC:
1399: dmaBTC[i] = d << 8 | (dmaBTC[i] & 0xff);
1400: return;
1401: case DMA_BTC + 1:
1402: dmaBTC[i] = (dmaBTC[i] & ~0xff) | d;
1403: return;
1404: case DMA_BAR:
1405: dmaBAR[i] = d << 24 | (dmaBAR[i] & ~(0xff << 24));
1406: return;
1407: case DMA_BAR + 1:
1408: dmaBAR[i] = d << 16 | (dmaBAR[i] & ~(0xff << 16));
1409: return;
1410: case DMA_BAR + 2:
1411: dmaBAR[i] = (dmaBAR[i] & ~(0xff << 8)) | d << 8;
1412: return;
1413: case DMA_BAR + 3:
1414: dmaBAR[i] = (dmaBAR[i] & ~0xff) | d;
1415: return;
1416: case DMA_NIV:
1417: dmaNIV[i] = d;
1418: return;
1419: case DMA_EIV:
1420: dmaEIV[i] = d;
1421: return;
1422: case DMA_MFC:
1423: if (dmaACT[i] != 0) {
1424: dmaErrorExit (i, DMA_TIMING_ERROR);
1425: return;
1426: }
1427: dmaMFC[i] = d & DMA_FC2;
1428: if (DataBreakPoint.DBP_ON) {
1429: dmaMFCMap[i] = dmaMFC[i] == 0 ? DataBreakPoint.dbpUserMap : DataBreakPoint.dbpSuperMap;
1430: } else {
1431: dmaMFCMap[i] = dmaMFC[i] == 0 ? XEiJ.busUserMap : XEiJ.busSuperMap;
1432: }
1433: return;
1434: case DMA_CPR:
1435: dmaCP[i] = d & DMA_CP;
1436: return;
1437: case DMA_DFC:
1438: if (dmaACT[i] != 0) {
1439: dmaErrorExit (i, DMA_TIMING_ERROR);
1440: return;
1441: }
1442: dmaDFC[i] = d & DMA_FC2;
1443: if (DataBreakPoint.DBP_ON) {
1444: dmaDFCMap[i] = dmaDFC[i] == 0 ? DataBreakPoint.dbpUserMap : DataBreakPoint.dbpSuperMap;
1445: } else {
1446: dmaDFCMap[i] = dmaDFC[i] == 0 ? XEiJ.busUserMap : XEiJ.busSuperMap;
1447: }
1448: return;
1449: case DMA_BFC:
1450: dmaBFC[i] = d & DMA_FC2;
1451: if (DataBreakPoint.DBP_ON) {
1452: dmaBFCMap[i] = dmaBFC[i] == 0 ? DataBreakPoint.dbpUserMap : DataBreakPoint.dbpSuperMap;
1453: } else {
1454: dmaBFCMap[i] = dmaBFC[i] == 0 ? XEiJ.busUserMap : XEiJ.busSuperMap;
1455: }
1456: return;
1457: default:
1458: return;
1459: }
1460: }
1461:
1462: public static void dmaWriteWord (int a, int d) {
1463: d = (char) d;
1464: int al = a & 0xff;
1465: int i = al >> 6;
1466: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
1467: System.out.printf ("%d %08x dmaWw(0x%08x,0x%04x)\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1468: }
1469: switch (al & 0x3f) {
1470: case DMA_MTC:
1471: if (dmaACT[i] != 0) {
1472: dmaErrorExit (i, DMA_TIMING_ERROR);
1473: } else {
1474: dmaMTC[i] = d;
1475: }
1476: return;
1477: case DMA_MAR:
1478: if (dmaACT[i] != 0) {
1479: dmaErrorExit (i, DMA_TIMING_ERROR);
1480: } else {
1481: dmaMAR[i] = d << 16 | (char) dmaMAR[i];
1482: }
1483: return;
1484: case DMA_MAR + 2:
1485: if (dmaACT[i] != 0) {
1486: dmaErrorExit (i, DMA_TIMING_ERROR);
1487: } else {
1488: dmaMAR[i] = (dmaMAR[i] & ~0xffff) | d;
1489: }
1490: return;
1491: case DMA_DAR:
1492: if (dmaACT[i] != 0) {
1493: dmaErrorExit (i, DMA_TIMING_ERROR);
1494: } else {
1495: dmaDAR[i] = d << 16 | (char) dmaDAR[i];
1496: }
1497: return;
1498: case DMA_DAR + 2:
1499: if (dmaACT[i] != 0) {
1500: dmaErrorExit (i, DMA_TIMING_ERROR);
1501: } else {
1502: dmaDAR[i] = (dmaDAR[i] & ~0xffff) | d;
1503: }
1504: return;
1505: case DMA_BTC:
1506: dmaBTC[i] = (char) d;
1507: return;
1508: case DMA_BAR:
1509: dmaBAR[i] = d << 16 | (char) dmaBAR[i];
1510: return;
1511: case DMA_BAR + 2:
1512: dmaBAR[i] = (dmaBAR[i] & ~0xffff) | d;
1513: return;
1514: default:
1515: dmaWriteByte (a, d >> 8);
1516: dmaWriteByte (a + 1, d);
1517: }
1518: }
1519:
1520: public static void dmaWriteLong (int a, int d) {
1521: int al = a & 0xff;
1522: int i = al >> 6;
1523: if (DMA_DEBUG_TRACE != 0 && (DMA_DEBUG_TRACE & 1 << i) != 0) {
1524: System.out.printf ("%d %08x dmaWl(0x%08x,0x%08x)\n", XEiJ.mpuClockTime, XEiJ.regPC0, a, d);
1525: }
1526: switch (al & 0x3f) {
1527: case DMA_MAR:
1528: if (dmaACT[i] != 0) {
1529: dmaErrorExit (i, DMA_TIMING_ERROR);
1530: } else {
1531: dmaMAR[i] = d;
1532: if (DMA_ALERT_HIMEM) {
1533: if ((d & 0xff000000) != 0 && Model.MPU_MC68020 <= XEiJ.currentMPU) {
1534: System.out.printf ("%08x DMA_MAR[%d]=%08X\n", XEiJ.regPC0, i, d);
1535: }
1536: }
1537: }
1538: return;
1539: case DMA_DAR:
1540: if (dmaACT[i] != 0) {
1541: dmaErrorExit (i, DMA_TIMING_ERROR);
1542: } else {
1543: dmaDAR[i] = d;
1544: if (DMA_ALERT_HIMEM) {
1545: if ((d & 0xff000000) != 0 && Model.MPU_MC68020 <= XEiJ.currentMPU) {
1546: System.out.printf ("%08x DMA_DAR[%d]=%08X\n", XEiJ.regPC0, i, d);
1547: }
1548: }
1549: }
1550: return;
1551: case DMA_BAR:
1552: dmaBAR[i] = d;
1553: if (DMA_ALERT_HIMEM) {
1554: if ((d & 0xff000000) != 0 && Model.MPU_MC68020 <= XEiJ.currentMPU) {
1555: System.out.printf ("%08x DMA_BAR[%d]=%08X\n", XEiJ.regPC0, i, d);
1556: }
1557: }
1558: return;
1559: default:
1560: dmaWriteWord (a, d >> 16);
1561: dmaWriteWord (a + 2, d);
1562: }
1563: }
1564:
1565:
1566:
1567: }
1568:
1569:
1570: