SUK.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13: package xeij;
14:
15: import java.awt.event.*;
16: import java.util.*;
17: import javax.swing.*;
18:
19: import com.fazecast.jSerialComm.*;
20:
21: public class SUK {
22:
23:
24: public static final boolean SUK_ON = false;
25: public static final boolean SUK_DEBUG = true;
26: public static boolean sukOnRequest;
27: public static boolean sukOn;
28: public static boolean sukExpansionRequest;
29: public static boolean sukExpansion;
30:
31:
32: public static final int SUK_VID = 0x04d8;
33: public static final int SUK_PID = 0xe6b2;
34: public static final int SUK_TRANSMISSION_QUEUE_SIZE = 65535;
35: public static final int SUK_RECEIVE_QUEUE_SIZE = 65535;
36: public static SerialPort sukPort1;
37: public static SerialPort sukPort2;
38: public static final byte[] sukCoreTemporary = new byte[65536];
39: public static final byte[] sukReceivingTemporary = new byte[65536];
40:
41:
42: public static JMenu sukMenu;
43: public static JCheckBoxMenuItem sukOnCheckBox;
44: public static JCheckBoxMenuItem sukExpansionCheckBox;
45:
46:
47: public static final int SPC_BDID = 0x01;
48: public static final int SPC_SCTL = 0x03;
49: public static final int SPC_SCTL_RD = 0b10000000;
50: public static final int SPC_SCTL_CR = 0b01000000;
51: public static final int SPC_SCTL_DM = 0b00100000;
52: public static final int SPC_SCTL_AE = 0b00010000;
53: public static final int SPC_SCTL_PE = 0b00001000;
54: public static final int SPC_SCTL_SE = 0b00000100;
55: public static final int SPC_SCTL_RE = 0b00000010;
56: public static final int SPC_SCTL_IE = 0b00000001;
57: public static final int SPC_SCMD = 0x05;
58: public static final int SPC_SCMD_CC = 0b11100000;
59: public static final int SPC_SCMD_CC_BR = 0b00000000;
60: public static final int SPC_SCMD_CC_SL = 0b00100000;
61: public static final int SPC_SCMD_CC_RA = 0b01000000;
62: public static final int SPC_SCMD_CC_SA = 0b01100000;
63: public static final int SPC_SCMD_CC_TR = 0b10000000;
64: public static final int SPC_SCMD_CC_TP = 0b10100000;
65: public static final int SPC_SCMD_CC_RR = 0b11000000;
66: public static final int SPC_SCMD_CC_SR = 0b11100000;
67: public static final int SPC_SCMD_RO = 0b00010000;
68: public static final int SPC_SCMD_IT = 0b00001000;
69: public static final int SPC_SCMD_PT = 0b00000100;
70: public static final int SPC_SCMD_TM = 0b00000001;
71: public static final int SPC_INTS = 0x09;
72: public static final int SPC_INTS_SL = 0b10000000;
73: public static final int SPC_INTS_RS = 0b01000000;
74: public static final int SPC_INTS_DC = 0b00100000;
75: public static final int SPC_INTS_CC = 0b00010000;
76: public static final int SPC_INTS_SR = 0b00001000;
77: public static final int SPC_INTS_TO = 0b00000100;
78: public static final int SPC_INTS_HE = 0b00000010;
79: public static final int SPC_INTS_RC = 0b00000001;
80: public static final int SPC_PSNS = 0x0b;
81: public static final int SPC_PSNS_REQ = 0b10000000;
82: public static final int SPC_PSNS_ACK = 0b01000000;
83: public static final int SPC_PSNS_ATN = 0b00100000;
84: public static final int SPC_PSNS_SEL = 0b00010000;
85: public static final int SPC_PSNS_BSY = 0b00001000;
86: public static final int SPC_SDGC = 0x0b;
87: public static final int SPC_SDGC_REQ = 0b10000000;
88: public static final int SPC_SDGC_ACK = 0b01000000;
89: public static final int SPC_SDGC_XFER = 0b00100000;
90: public static final int SPC_SDGC_BSY = 0b00001000;
91: public static final int SPC_SDGC_MSG = 0b00000100;
92: public static final int SPC_SDGC_CD = 0b00000010;
93: public static final int SPC_SDGC_IO = 0b00000001;
94: public static final int SPC_SSTS = 0x0d;
95: public static final int SPC_SSTS_INIT = 0b10000000;
96: public static final int SPC_SSTS_TARG = 0b01000000;
97: public static final int SPC_SSTS_BUSY = 0b00100000;
98: public static final int SPC_SSTS_TRIP = 0b00010000;
99: public static final int SPC_SSTS_RSIN = 0b00001000;
100: public static final int SPC_SSTS_TC0 = 0b00000100;
101: public static final int SPC_SSTS_DF = 0b00000010;
102: public static final int SPC_SSTS_DE = 0b00000001;
103: public static final int SPC_SERR = 0x0f;
104: public static final int SPC_SERR_DI = 0b10000000;
105: public static final int SPC_SERR_DO = 0b01000000;
106: public static final int SPC_SERR_XO = 0b00100000;
107: public static final int SPC_SERR_PE = 0b00001000;
108: public static final int SPC_SERR_ST = 0b00000010;
109: public static final int SPC_PCTL = 0x11;
110: public static final int SPC_PCTL_IE = 0b10000000;
111: public static final int SPC_PCTL_SR = 0b00000001;
112: public static final int SPC_PCTL_SR_R = 0b00000001;
113: public static final int SPC_PCTL_SR_S = 0b00000000;
114: public static final int SPC_MBC = 0x13;
115: public static final int SPC_DREG = 0x15;
116: public static final int SPC_TEMP = 0x17;
117: public static final int SPC_TCH = 0x19;
118: public static final int SPC_TCM = 0x1b;
119: public static final int SPC_TCL = 0x1d;
120: public static final int SPC_BYPASS = 0x1f;
121: public static final int SPC_PHASE_MASK = 0b00000111;
122: public static final int SPC_DATAOUT_PHASE = 0b00000000;
123: public static final int SPC_DATAIN_PHASE = 0b00000001;
124: public static final int SPC_CMDOUT_PHASE = 0b00000010;
125: public static final int SPC_STSIN_PHASE = 0b00000011;
126: public static final int SPC_MSGOUT_PHASE = 0b00000110;
127: public static final int SPC_MSGIN_PHASE = 0b00000111;
128: public static final byte[] sukRegister = new byte[32];
129:
130:
131:
132:
133: public static final int SUK_QUEUE_SIZE = 1048576;
134: public static final byte[] sukQueueArray = new byte[SUK_QUEUE_SIZE];
135: public static volatile int sukQueueWrite;
136: public static volatile int sukQueueRead;
137:
138:
139: public static volatile boolean sukRunning;
140: public static Thread sukThread;
141: public static boolean sukWaiting;
142:
143:
144: public static final int SUK_DATAIN_MODE = 0;
145: public static volatile int sukDatainStage;
146: public static volatile int sukDatainTotal;
147: public static volatile int sukDatainNotReceived;
148: public static volatile int sukDatainBlockNotReceived;
149: public static int sukDatainNotRead;
150:
151:
152:
153:
154:
155: public static final int SUK_POOL_SIZE = 65536;
156: public static final long SUK_POOL_SPAN = XEiJ.TMR_FREQ / 1000;
157: public static final byte[] sukPoolArray = new byte[SUK_POOL_SIZE];
158: public static int sukPoolIndex;
159: public static final TickerQueue.Ticker sukPoolTicker = new TickerQueue.Ticker () {
160: @Override protected void tick () {
161: sukPoolFlush ();
162: }
163: };
164:
165:
166:
167:
168:
169:
170:
171:
172:
173: public static int sukBypassNotTransmitted;
174:
175:
176:
177:
178:
179:
180:
181:
182: public static int sukBypassNotReceived;
183: public static int sukBypassNotRead;
184:
185:
186:
187:
188:
189:
190:
191: public static long sukWaitTimeNano;
192: public static int sukWaitTimeCounter;
193: public static final WaitInstruction sukWaitTimeInstruction = new WaitInstruction () {
194: @Override public boolean terminate () {
195: return ((sukWaitTimeCounter++ & 15) == 0 &&
196: 0 <= (System.nanoTime () - sukWaitTimeNano));
197: }
198: };
199:
200:
201:
202:
203:
204: public static int sukWaitQueueMTC;
205: public static int sukWaitQueueCounter;
206: public static final WaitInstruction sukWaitQueueInstruction = new WaitInstruction () {
207: @Override public boolean terminate () {
208: return ((sukWaitQueueCounter++ & 15) == 0 &&
209: sukWaitQueueMTC <= (sukQueueWrite - sukQueueRead));
210: }
211: };
212:
213:
214:
215: public static void sukInit () {
216: sukPort1 = null;
217: sukPort2 = null;
218: sukOnRequest = Settings.sgsGetOnOff ("suk");
219: sukOn = false;
220: sukExpansionRequest = Settings.sgsGetOnOff ("sukex");
221: sukExpansion = false;
222:
223: }
224:
225:
226:
227: public static void sukTini () {
228: Settings.sgsPutOnOff ("suk", sukOnRequest);
229: Settings.sgsPutOnOff ("sukex", sukExpansionRequest);
230: if (sukOn) {
231: sukDisconnect ();
232: sukOn = false;
233: }
234: }
235:
236:
237:
238: public static JMenu sukGetMenu () {
239: if (sukMenu == null) {
240: sukMenu = Multilingual.mlnText (
241: ComponentFactory.createMenu (
242: "SCSI Ukun Kai (experimental)",
243: sukOnCheckBox = Multilingual.mlnText (
244: ComponentFactory.createCheckBoxMenuItem (
245: sukOnRequest,
246: "Connect",
247: new ActionListener () {
248: @Override public void actionPerformed (ActionEvent ae) {
249: sukOnRequest = sukOnCheckBox.isSelected ();
250: }
251: }),
252: "ja", "接続"),
253: sukExpansionCheckBox = Multilingual.mlnText (
254: ComponentFactory.createCheckBoxMenuItem (
255: sukExpansionRequest,
256: "Expansion",
257: new ActionListener () {
258: @Override public void actionPerformed (ActionEvent ae) {
259: sukExpansionRequest = sukExpansionCheckBox.isSelected ();
260: }
261: }),
262: "ja", "拡張")
263: ),
264: "ja", "すかじー U 君改 (実験中)");
265: }
266: return sukMenu;
267: }
268:
269:
270:
271: public static void sukReset () {
272: if (sukOnRequest) {
273: if (!sukConnect ()) {
274: sukOnRequest = false;
275: sukOnCheckBox.setSelected (false);
276: }
277: } else {
278: sukDisconnect ();
279: }
280: sukOn = sukOnRequest;
281: sukExpansion = sukExpansionRequest;
282: }
283:
284:
285:
286: public static boolean sukConnect () {
287: if (sukPort1 != null) {
288: return true;
289: }
290:
291: SerialPort port1 = null;
292: SerialPort port2 = null;
293: for (SerialPort port : SerialPort.getCommPorts ()) {
294: if (port.getVendorID () == SUK_VID &&
295: port.getProductID () == SUK_PID) {
296: if (port1 == null) {
297: port1 = port;
298: } else if (port2 == null) {
299: port2 = port;
300: } else {
301:
302:
303: System.out.println (Multilingual.mlnJapanese ?
304: "すかじー U 君改のポートが多すぎます" :
305: "Too many MB89352 bridger");
306: return false;
307: }
308: }
309: }
310: if (port2 == null) {
311: System.out.println (Multilingual.mlnJapanese ?
312: "すかじー U 君改のポートが見つかりません" :
313: "MB89352 bridger not found");
314: return false;
315: }
316:
317: if (!port1.openPort (0, SUK_TRANSMISSION_QUEUE_SIZE, SUK_RECEIVE_QUEUE_SIZE)) {
318: System.out.println (Multilingual.mlnJapanese ?
319: "すかじー U 君改のポートを開けません" :
320: "Cannot open MB89352 bridger");
321: return false;
322: }
323: if (!port2.openPort (0, SUK_TRANSMISSION_QUEUE_SIZE, SUK_RECEIVE_QUEUE_SIZE)) {
324: port1.closePort ();
325: System.out.println (Multilingual.mlnJapanese ?
326: "すかじー U 君改のポートを開けません" :
327: "Cannot open MB89352 bridger");
328: return false;
329: }
330:
331:
332: port1.setComPortParameters (480000000, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);
333: port2.setComPortParameters (480000000, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);
334:
335:
336:
337: port1.setComPortTimeouts (SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 50, 0);
338: port2.setComPortTimeouts (SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 50, 0);
339:
340:
341: sukCoreTemporary[0] = 0x00;
342: sukCoreTemporary[1] = 0x00;
343: port1.writeBytes (sukCoreTemporary, 1, 0);
344: port1.readBytes (sukCoreTemporary, 1, 0);
345: port2.writeBytes (sukCoreTemporary, 1, 1);
346: port2.readBytes (sukCoreTemporary, 1, 1);
347: if (sukCoreTemporary[0] == 's' && sukCoreTemporary[1] == 'S') {
348: } else if (sukCoreTemporary[0] == 'S' && sukCoreTemporary[1] == 's') {
349:
350: SerialPort port = port1;
351: port1 = port2;
352: port2 = port;
353: } else {
354: port1.closePort ();
355: port2.closePort ();
356: System.out.println (Multilingual.mlnJapanese ?
357: "すかじー U 君改のポートを判別できません" :
358: "Unable to identify MB89352 bridger");
359: return false;
360: }
361:
362: sukCoreTemporary[0] = (byte) 0x80;
363: sukCoreTemporary[1] = (byte) 0xfe;
364: port1.writeBytes (sukCoreTemporary, 2);
365:
366: sukPort1 = port1;
367: sukPort2 = port2;
368: Arrays.fill (sukRegister, (byte) 0);
369: System.out.printf (Multilingual.mlnJapanese ?
370: "すかじー U 君改 (%s,%s) に接続しました\n" :
371: "MB89352 bridger (%s,%s) connected\n",
372: sukPort1.getSystemPortName (),
373: sukPort2.getSystemPortName ());
374:
375:
376: sukQueueWrite = 0;
377: sukQueueRead = 0;
378:
379:
380: sukRunning = true;
381: sukThread = new Thread () {
382: @Override public void run () {
383: while (sukRunning) {
384: if (sukDatainStage == 2 && sukDatainBlockNotReceived < 0) {
385: if (((short) sukDatainBlockNotReceived) < 0) {
386: int n = sukPort1.readBytes (sukReceivingTemporary, 2, 0);
387: if (n == 2) {
388: sukDatainBlockNotReceived = (0xff & sukReceivingTemporary[1]) << 8 | (0xff & sukReceivingTemporary[0]);
389: } else if (n == 1) {
390: sukDatainBlockNotReceived = 0xffff0000 + (0xff & sukReceivingTemporary[0]);
391: }
392: } else {
393: int n = sukPort1.readBytes (sukReceivingTemporary, 1, 1);
394: if (n == 1) {
395: sukDatainBlockNotReceived = (0xff & sukReceivingTemporary[1]) << 8 | (0xff & sukDatainBlockNotReceived);
396: }
397: }
398: } else {
399: int w = sukQueueWrite;
400: int f = SUK_QUEUE_SIZE - (w - sukQueueRead);
401: if (f == 0) {
402: System.out.printf ("%08x queue is full\n", XEiJ.regPC0);
403: break;
404: }
405: int i = w & (SUK_QUEUE_SIZE - 1);
406: int n = sukPort1.readBytes (sukQueueArray, Math.min (f, SUK_QUEUE_SIZE - i), i);
407: if (0 < n) {
408: w += n;
409: sukQueueWrite = w;
410: sukDatainNotReceived -= n;
411: if (sukDatainNotReceived < 0) {
412: System.out.printf ("%08x not received is negative\n", XEiJ.regPC0);
413: break;
414: }
415: sukDatainBlockNotReceived -= n;
416: if (sukDatainBlockNotReceived < 0) {
417: System.out.printf ("%08x block not received is negative\n", XEiJ.regPC0);
418: break;
419: }
420: if (sukDatainNotReceived != 0 && sukDatainBlockNotReceived == 0) {
421: if (SUK_DATAIN_MODE == 0) {
422: sukDatainBlockNotReceived = 0xffffffff;
423: sukReceivingTemporary[0] = 0x41;
424: sukPort1.writeBytes (sukReceivingTemporary, 1);
425: } else if (SUK_DATAIN_MODE == 1) {
426: if (sukDatainNotReceived < 512) {
427: sukDatainBlockNotReceived = sukDatainNotReceived;
428: Arrays.fill (sukReceivingTemporary, 0, sukDatainBlockNotReceived, (byte) SPC_DREG);
429: sukPort1.writeBytes (sukReceivingTemporary, sukDatainBlockNotReceived);
430: } else {
431: sukDatainBlockNotReceived = 0xffffffff;
432: sukReceivingTemporary[0] = 0x41;
433: sukPort1.writeBytes (sukReceivingTemporary, 1);
434: }
435: } else {
436: sukDatainBlockNotReceived = Math.min (512, sukDatainNotReceived);
437: Arrays.fill (sukReceivingTemporary, 0, sukDatainBlockNotReceived, (byte) SPC_DREG);
438: sukPort1.writeBytes (sukReceivingTemporary, sukDatainBlockNotReceived);
439: }
440: }
441: }
442: }
443: while (sukPort2.bytesAvailable () != 0) {
444: sukReceivingTemporary[0] = 0x00;
445: if (sukPort2.readBytes (sukReceivingTemporary, 1) != 0 &&
446: sukReceivingTemporary[0] == 'I') {
447: if (sukExpansion) {
448: XEiJ.eb2Interrupt (XEiJ.EB2_SPC_REQUEST);
449: } else {
450: IOInterrupt.ioiSpcFall ();
451: IOInterrupt.ioiSpcRise ();
452: }
453: }
454: }
455: }
456: }
457: };
458: sukThread.start ();
459: sukWaiting = false;
460:
461: sukDatainStage = 0;
462:
463:
464:
465: sukPoolIndex = 0;
466:
467: sukBypassNotTransmitted = 0;
468:
469: sukBypassNotReceived = 0;
470: sukBypassNotRead = 0;
471: return true;
472: }
473:
474:
475:
476: public static void sukDisconnect () {
477: if (sukPort1 == null) {
478: return;
479: }
480:
481: sukPort1.closePort ();
482: sukPort2.closePort ();
483: System.out.printf (Multilingual.mlnJapanese ?
484: "すかじー U 君改 (%s,%s) を切り離しました\n" :
485: "MB89352 bridger (%s,%s) disconnected\n",
486: sukPort1.getSystemPortName (),
487: sukPort2.getSystemPortName ());
488: sukPort1 = null;
489: sukPort2 = null;
490: }
491:
492:
493:
494: public static int sukPeek (int a) {
495: a &= 0x1f;
496: return 0xff & sukRegister[a];
497: }
498:
499:
500:
501: public static int sukRead (int a) throws M68kException {
502: a &= 0x1f;
503: if (sukDatainStage == 2) {
504: if (a == SPC_DREG) {
505: if ((sukQueueWrite - sukQueueRead) == 0) {
506: System.out.printf ("%08x receiving queue is empty\n", XEiJ.regPC0);
507: } else {
508:
509: int r = sukQueueRead;
510: sukRegister[a] = sukQueueArray[r++ & (SUK_QUEUE_SIZE - 1)];
511: sukQueueRead = r;
512:
513: sukDatainNotRead--;
514:
515: if (sukDatainNotRead == 0) {
516: if (SUK_DEBUG) {
517: System.out.printf ("%08x receiving in data-in-phase is complete\n", XEiJ.regPC0);
518: }
519: sukDatainStage = 0;
520: }
521: }
522: } else if (a == SPC_INTS) {
523: sukRegister[a] = 0x00;
524: } else if (a == SPC_SSTS) {
525: sukRegister[a] = (byte) (SPC_SSTS_INIT | SPC_SSTS_BUSY | SPC_SSTS_TRIP | (sukDatainNotRead < 8 ? 0 : SPC_SSTS_DF));
526: }
527: return 0xff & sukRegister[a];
528: }
529: if (sukDatainStage == 1 &&
530: (XEiJ.busWaitTime == XEiJ.mpuWaitTime || XEiJ.busWaitTime == XEiJ.mpuNoWaitTime) &&
531: a == SPC_DREG) {
532: if (SUK_DEBUG) {
533: System.out.printf ("%08x MPU has started receiving\n", XEiJ.regPC0);
534: }
535: sukDatainStage2 ();
536: int n = Math.min (512, sukDatainNotRead);
537: if (n <= (sukQueueWrite - sukQueueRead)) {
538: int r = sukQueueRead;
539: sukRegister[a] = sukQueueArray[r++ & (SUK_QUEUE_SIZE - 1)];
540: sukQueueRead = r;
541: sukDatainNotRead--;
542: if (sukDatainNotRead == 0) {
543: if (SUK_DEBUG) {
544: System.out.printf ("%08x receiving in data-in-phase is complete\n", XEiJ.regPC0);
545: }
546: sukDatainStage = 0;
547: }
548: return 0xff & sukRegister[a];
549: }
550: sukWaitQueueMTC = n;
551: sukWaitQueueCounter = 0;
552: InstructionBreakPoint.ibpAddWaitPoint (XEiJ.regPC0, XEiJ.regSRS, sukWaitQueueInstruction);
553: M68kException.m6eNumber = M68kException.M6E_WAIT_EXCEPTION;
554: throw M68kException.m6eSignal;
555: }
556:
557: if (XEiJ.busWaitTime == XEiJ.dmaWaitTime || XEiJ.busWaitTime == XEiJ.dmaNoWaitTime) {
558: System.out.printf ("%08x DMAC attempt to read while not in data-in-phase\n", XEiJ.regPC0);
559: return 0xff & sukRegister[a];
560: }
561:
562: if (sukBypassNotTransmitted != 0) {
563: System.out.printf ("%08x MPU attempt to read during transmitting bypass\n", XEiJ.regPC0);
564: return 0xff & sukRegister[a];
565: }
566: if (a == SPC_BYPASS) {
567: if (sukBypassNotReceived == 0) {
568: sukBypassNotReceived = 0xffffffff;
569: sukBypassNotRead = 0xffffffff;
570: } else {
571:
572: }
573: } else {
574: if (sukBypassNotReceived != 0) {
575: System.out.printf ("%08x MPU attempt to read a register other than bypass while receiving bypass\n", XEiJ.regPC0);
576: return 0xff & sukRegister[a];
577: }
578:
579: }
580:
581: if (1 <= (sukQueueWrite - sukQueueRead)) {
582: sukWaiting = false;
583: int r = sukQueueRead;
584: sukRegister[a] = sukQueueArray[r++ & (SUK_QUEUE_SIZE - 1)];
585: sukQueueRead = r;
586: return 0xff & sukRegister[a];
587: }
588: if (!sukWaiting) {
589: sukWaiting = true;
590: TickerQueue.tkqRemove (sukPoolTicker);
591: if (SUK_POOL_SIZE - 1 < sukPoolIndex) {
592: sukPoolFlush ();
593: }
594: sukPoolArray[sukPoolIndex++] = (byte) a;
595: sukPoolFlush ();
596: }
597:
598: sukWaitQueueMTC = 1;
599: sukWaitQueueCounter = 0;
600: InstructionBreakPoint.ibpAddWaitPoint (XEiJ.regPC0, XEiJ.regSRS, sukWaitQueueInstruction);
601: M68kException.m6eNumber = M68kException.M6E_WAIT_EXCEPTION;
602: throw M68kException.m6eSignal;
603: }
604:
605:
606:
607: public static void sukWrite (int a, int d) {
608: a &= 0x1f;
609: d &= 0xff;
610: if (a == SPC_BYPASS) {
611: if (sukBypassNotTransmitted == 0) {
612: sukPoolArray[sukPoolIndex++] = (byte) (0x80 + a);
613: sukPoolArray[sukPoolIndex++] = (byte) d;
614: sukBypassNotTransmitted = 0xffff0000 + d;
615: } else if (sukBypassNotTransmitted < 0) {
616: sukPoolArray[sukPoolIndex++] = (byte) d;
617: sukBypassNotTransmitted = d << 8 | (0xff & sukBypassNotTransmitted);
618: } else {
619: sukPoolArray[sukPoolIndex++] = (byte) d;
620: sukBypassNotTransmitted--;
621: }
622: } else {
623: if (sukBypassNotTransmitted != 0) {
624: return;
625: }
626: if (SUK_POOL_SIZE - 2 < sukPoolIndex) {
627: sukPoolFlush ();
628: }
629: sukPoolArray[sukPoolIndex++] = (byte) (0x80 + a);
630: sukPoolArray[sukPoolIndex++] = (byte) d;
631: }
632:
633: TickerQueue.tkqAdd (sukPoolTicker, XEiJ.mpuClockTime + SUK_POOL_SPAN);
634: sukRegister[a] = (byte) d;
635:
636: int us = (a == SPC_SCMD && (d & SPC_SCMD_RO) != 0 ? 250 :
637: a == SPC_SCMD && (d & SPC_SCMD_CC) == SPC_SCMD_CC_SL ? 50 :
638: a == SPC_INTS && (d & SPC_INTS_TO) != 0 ? 50 :
639: 0);
640: if (us != 0) {
641: sukPoolFlush ();
642:
643: sukWaitTimeNano = System.nanoTime () + us * 1000;
644: sukWaitTimeCounter = 0;
645: InstructionBreakPoint.ibpAddWaitPoint (XEiJ.regPC, XEiJ.regSRS, sukWaitTimeInstruction);
646: }
647:
648: if ((sukRegister[SPC_PCTL] & SPC_PHASE_MASK) == SPC_DATAIN_PHASE &&
649: a == SPC_SCMD && (d & SPC_SCMD_CC) == SPC_SCMD_CC_TR) {
650: if (SUK_DEBUG) {
651: System.out.printf ("%08x datain SPC start\n", XEiJ.regPC0);
652: }
653: sukDatainStage = 1;
654: }
655: }
656:
657:
658:
659: public static void sukPoolFlush () {
660: if (0 < sukPoolIndex) {
661: sukPort1.writeBytes (sukPoolArray, sukPoolIndex);
662: sukPoolIndex = 0;
663: }
664: }
665:
666:
667:
668:
669:
670:
671:
672: public static void sukDatainStage2 () {
673: sukDatainTotal = ((0xff & sukRegister[SPC_TCH]) << 16 |
674: (0xff & sukRegister[SPC_TCM]) << 8 |
675: (0xff & sukRegister[SPC_TCL]));
676: if (SUK.SUK_DEBUG) {
677: System.out.printf ("%08x receiving %d bytes in data-in-phase has started\n", XEiJ.regPC0, sukDatainTotal);
678: }
679: if (sukDatainTotal == 0) {
680: sukDatainStage = 0;
681: return;
682: }
683: sukDatainStage = 2;
684: sukDatainNotReceived = sukDatainTotal;
685: sukDatainNotRead = sukDatainTotal;
686: sukQueueRead = sukQueueWrite;
687: if (SUK_DATAIN_MODE == 0) {
688: sukDatainBlockNotReceived = 0xffffffff;
689: sukCoreTemporary[0] = 0x41;
690: sukPort1.writeBytes (sukCoreTemporary, 1);
691: } else if (SUK_DATAIN_MODE == 1) {
692: if (sukDatainNotReceived < 512) {
693: sukDatainBlockNotReceived = sukDatainNotReceived;
694: Arrays.fill (sukCoreTemporary, 0, sukDatainBlockNotReceived, (byte) SPC_DREG);
695: sukPort1.writeBytes (sukCoreTemporary, sukDatainBlockNotReceived);
696: } else {
697: sukDatainBlockNotReceived = 0xffffffff;
698: sukCoreTemporary[0] = 0x41;
699: sukPort1.writeBytes (sukCoreTemporary, 1);
700: }
701: } else {
702: sukDatainBlockNotReceived = Math.min (512, sukDatainNotReceived);
703: Arrays.fill (sukCoreTemporary, 0, sukDatainBlockNotReceived, (byte) SPC_DREG);
704: sukPort1.writeBytes (sukCoreTemporary, sukDatainBlockNotReceived);
705: }
706: }
707:
708: }