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