RS232CTerminal.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13: package xeij;
14:
15: import java.awt.datatransfer.*;
16: import java.awt.event.*;
17: import java.io.*;
18: import java.net.*;
19: import java.nio.*;
20: import java.nio.channels.*;
21: import java.nio.charset.*;
22: import java.util.*;
23: import java.util.zip.*;
24: import javax.swing.*;
25: import javax.swing.event.*;
26:
27: import com.fazecast.jSerialComm.*;
28:
29: public class RS232CTerminal {
30:
31: public static final int TRM_MAX_OUTPUT_LENGTH = 1024 * 256;
32: public static final int TRM_CUT_OUTPUT_LENGTH = TRM_MAX_OUTPUT_LENGTH + 1024 * 16;
33:
34:
35: public static JFrame trmFrame;
36: public static ScrollTextArea trmBoard;
37: public static JPopupMenu trmPopupMenu;
38: public static JMenuItem trmPopupCutMenuItem;
39: public static JMenuItem trmPopupCopyMenuItem;
40: public static JMenuItem trmPopupPasteMenuItem;
41: public static JMenuItem trmPopupSelectAllMenuItem;
42: public static JMenuItem trmPopupSendCtrlCMenuItem;
43: public static StringBuilder trmOutputBuilder;
44: public static int trmOutputEnd;
45: public static int trmOutputSJIS1;
46:
47:
48: public static SerialPort[] trmPortArray;
49: public static int trmNumberOfPorts;
50:
51:
52: public static int trmRows;
53: public static String[] trmRowName;
54: public static int[] trmRowToCol;
55:
56: public static int trmNumberOfAUXs;
57:
58:
59: public static int trmCols;
60: public static String[] trmColName;
61: public static int[] trmColToRow;
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92: static class Connection implements SerialPortDataListener {
93: int row;
94: int col;
95: int index;
96: String text;
97: boolean connected;
98: JCheckBox checkBox;
99: Box box;
100:
101:
102: ByteQueue row2colQueue;
103: ByteQueue col2rowQueue;
104: boolean row2colReset;
105: boolean col2rowReset;
106:
107:
108: @Override public int getListeningEvents () {
109: return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
110: }
111: @Override public void serialEvent (SerialPortEvent spe) {
112: if (spe.getEventType () != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
113: return;
114: }
115: SerialPort port = spe.getSerialPort ();
116: for (;;) {
117: int k = Math.min (port.bytesAvailable (),
118: row2colQueue.unused ());
119: if (k == 0) {
120: break;
121: }
122: byte[] b = new byte[k];
123: port.readBytes (b, k);
124: row2colQueue.write (b, 0, k);
125: }
126: }
127:
128:
129: boolean polling;
130: Thread row2colThread;
131: Thread col2rowThread;
132:
133:
134: class TerminalThread extends Thread {
135: @Override public void run () {
136: ByteQueue queue = (col == 0 ? row2colQueue : col2rowQueue);
137: while (polling) {
138: if (col == 0 ? row2colReset : col2rowReset) {
139: if (col == 0) {
140: row2colReset = false;
141: } else {
142: col2rowReset = false;
143: }
144: queue.clear ();
145: } else {
146: for (int k = queue.used (); k != 0; k = queue.used ()) {
147: byte[] b = new byte[k];
148: queue.read (b, 0, k);
149: for (int i = 0; i < k; i++) {
150: trmPrintSJIS (b[i] & 0xff);
151: }
152: }
153: }
154: try {
155: Thread.sleep (100);
156: } catch (InterruptedException ie) {
157: }
158: }
159: }
160: }
161:
162:
163: class SerialPortThread extends Thread {
164: @Override public void run () {
165: SerialPort port = trmPortArray[row - 1];
166: ByteQueue queue = col2rowQueue;
167: while (polling) {
168: if (col2rowReset) {
169: col2rowReset = false;
170: queue.clear ();
171: port.flushIOBuffers ();
172: } else {
173: for (int k = queue.used (); k != 0; k = queue.used ()) {
174: byte[] b = new byte[k];
175: queue.read (b, 0, k);
176: port.writeBytes (b, k);
177: }
178: }
179: try {
180: Thread.sleep (10);
181: } catch (InterruptedException ie) {
182: }
183: }
184: }
185: }
186:
187:
188: class TCPIPThread extends Thread {
189: @Override public void run () {
190: ByteQueue queue = col2rowQueue;
191: while (polling) {
192: if (col2rowReset) {
193: col2rowReset = false;
194: queue.clear ();
195: } else {
196: for (int k = queue.used (); k != 0; k = queue.used ()) {
197: byte[] b = new byte[k];
198: queue.read (b, 0, k);
199: trmTcpipWrite (b, 0, k);
200: }
201: }
202: try {
203: Thread.sleep (10);
204: } catch (InterruptedException ie) {
205: }
206: }
207: }
208: }
209:
210: }
211:
212:
213:
214:
215:
216:
217:
218: public static final String TRM_TCPIP_DEFAULT_HOST = "0.0.0.0";
219: public static final int TRM_TCPIP_DEFAULT_PORT = 54321;
220: public static String trmTcpipHost;
221: public static int trmTcpipPort;
222: public static boolean trmTcpipUTF8;
223: public static DecimalSpinner trmTcpipSpinner;
224: public static JCheckBox trmTcpipCheckBox;
225: public static ByteBuffer trmTcpipReadBuffer;
226: public static CompletionHandler<Integer, Void> trmTcpipReadHander;
227: public static CompletionHandler<AsynchronousSocketChannel, Void> trmTcpipAcceptHandler;
228: public static ByteQueue trmTcpipReadQueue;
229: public static SocketAddress trmTcpipPortAddress;
230: public static AsynchronousServerSocketChannel trmTcpipPortChannel;
231: public static final int TRM_TCPIP_BUFFER_SIZE = 4096;
232: public static AsynchronousSocketChannel trmTcpipSessionChannel;
233: public static SocketAddress trmTcpipClientAddress;
234: public static int trmTcpipToUTF8Pool;
235: public static int trmTcpipToSJISPool;
236:
237:
238:
239: public static void trmTcpipInit () {
240:
241: trmTcpipHost = Settings.sgsGetString ("tcpiphost");
242: if (trmTcpipHost.equals ("")) {
243: trmTcpipHost = TRM_TCPIP_DEFAULT_HOST;
244: }
245: trmTcpipPort = Settings.sgsGetInt ("tcpipport", TRM_TCPIP_DEFAULT_PORT);
246: if (trmTcpipPort < 0 || 65535 < trmTcpipPort) {
247: trmTcpipPort = TRM_TCPIP_DEFAULT_PORT;
248: }
249: trmTcpipUTF8 = Settings.sgsGetOnOff ("tcpiputf8");
250:
251: trmTcpipSpinner = ComponentFactory.createDecimalSpinner (
252: trmTcpipPort, 0, 65535, 1, 0,
253: new ChangeListener () {
254: @Override public void stateChanged (ChangeEvent ce) {
255: trmTcpipPort = trmTcpipSpinner.getIntValue ();
256: }
257: });
258:
259: trmTcpipCheckBox = ComponentFactory.createCheckBox (
260: trmTcpipUTF8, "UTF-8",
261: new ActionListener () {
262: @Override public void actionPerformed (ActionEvent ae) {
263: trmTcpipUTF8 = trmTcpipCheckBox.isSelected ();
264: }
265: });
266:
267: trmTcpipReadBuffer = ByteBuffer.allocate (TRM_TCPIP_BUFFER_SIZE);
268:
269: trmTcpipReadHander = new CompletionHandler<Integer, Void> () {
270:
271: @Override public void completed (Integer bytesRead, Void a) {
272: int l = (int) bytesRead;
273: if (l == -1) {
274: trmTcpipCloseSession (true);
275: return;
276: }
277: byte[] b = new byte[l];
278: int o = 0;
279: trmTcpipReadBuffer.flip ();
280: trmTcpipReadBuffer.get (b, o, l);
281: if (false) {
282: for (int i = 0; i < l; i++) {
283: System.out.printf ("%02x ", 0xff & b[o + i]);
284: }
285: System.out.println ();
286: }
287: byte[] bb = b;
288: int ll = l;
289: if (trmTcpipUTF8) {
290:
291: int pool = trmTcpipToSJISPool;
292: bb = new byte[2 * l];
293: ll = 0;
294: for (int i = 0; i < l; i++) {
295: int u = (pool << 8) | (0xff & b[o + i]);
296: if ((u & 0xffffffe0) == 0x000000c0 ||
297: (u & 0xfffffff0) == 0x000000e0 ||
298: (u & 0xfffff0c0) == 0x0000e080 ||
299: (u & 0xfffffff8) == 0x000000f0 ||
300: (u & 0xfffff8c0) == 0x0000f080 ||
301: (u & 0xfff8c0c0) == 0x00f08080) {
302: pool = u;
303: continue;
304: }
305: pool = 0;
306: if ((u & 0xffffff80) == 0x00000000) {
307: } else if ((u & 0xffffe0c0) == 0x0000c080) {
308: u = ((u & 0x00001f00) >> 2) | (u & 0x0000003f);
309: } else if ((u & 0xfff0c0c0) == 0x00e08080) {
310: u = ((u & 0x000f0000) >> 4) | ((u & 0x00003f00) >> 2) | (u & 0x0000003f);
311: } else if ((u & 0xf8c0c0c0) == 0xf0808080) {
312: u = ((u & 0x07000000) >> 6) | ((u & 0x003f0000) >> 4) | ((u & 0x00003f00) >> 2) | (u & 0x0000003f);
313: if (0x10ffff < u) {
314: u = '※';
315: } else if (0x00ffff < u) {
316:
317:
318:
319:
320:
321: u = '※';
322: }
323: } else {
324: u = '※';
325: }
326: int s = CharacterCode.chrCharToSJIS[u];
327: if (s == 0 && u != 0) {
328: s = 0x81a6;
329: }
330: if (0x00ff < s) {
331: bb[ll++] = (byte) (s >> 8);
332: }
333: bb[ll++] = (byte) s;
334: }
335: trmTcpipToSJISPool = pool;
336: }
337: trmTcpipReadQueue.write (bb, 0, ll);
338:
339: if (trmTcpipSessionChannel != null) {
340: trmTcpipReadBuffer.clear ();
341: trmTcpipSessionChannel.read (trmTcpipReadBuffer, null, trmTcpipReadHander);
342: }
343: }
344:
345: @Override public void failed (Throwable t, Void a) {
346: String message = t.getMessage ();
347: if (message != null) {
348: System.err.println (message);
349: }
350: trmTcpipCloseSession (true);
351: }
352: };
353:
354: trmTcpipAcceptHandler = new CompletionHandler<AsynchronousSocketChannel, Void> () {
355:
356: @Override public void completed (AsynchronousSocketChannel sessionChannel, Void a) {
357: trmTcpipSessionChannel = sessionChannel;
358:
359: trmTcpipToUTF8Pool = 0;
360: trmTcpipToSJISPool = 0;
361: try {
362: trmTcpipClientAddress = trmTcpipSessionChannel.getRemoteAddress ();
363: } catch (IOException ioe) {
364: ioe.printStackTrace ();
365: }
366: System.out.println (Multilingual.mlnJapanese ?
367: trmTcpipClientAddress + " と接続しました" :
368: trmTcpipClientAddress + " connected");
369:
370: if (trmTcpipSessionChannel != null) {
371: trmTcpipReadBuffer.clear ();
372: trmTcpipSessionChannel.read (trmTcpipReadBuffer, null, trmTcpipReadHander);
373: }
374: }
375:
376: @Override public void failed (Throwable t, Void a) {
377: String message = t.getMessage ();
378: if (message != null) {
379: System.err.println (message);
380: }
381: trmTcpipClosePort ();
382: }
383: };
384: }
385:
386:
387:
388: public static void trmTcpipTini () {
389:
390: Settings.sgsPutString ("tcpiphost", trmTcpipHost);
391: Settings.sgsPutInt ("tcpipport", trmTcpipPort);
392: Settings.sgsPutOnOff ("tcpiputf8", trmTcpipUTF8);
393: }
394:
395:
396:
397:
398: public static boolean trmTcpipOpenPort (ByteQueue readQueue) {
399: trmTcpipReadQueue = readQueue;
400: trmTcpipPortAddress = new InetSocketAddress (trmTcpipHost, trmTcpipPort);
401:
402: try {
403: trmTcpipPortChannel = AsynchronousServerSocketChannel.open ().bind (trmTcpipPortAddress);
404: } catch (IOException ioe) {
405: ioe.printStackTrace ();
406: System.out.println (Multilingual.mlnJapanese ?
407: trmTcpipPortAddress + " を開けません" :
408: trmTcpipPortAddress + " not opened");
409: return false;
410: }
411: System.out.println (Multilingual.mlnJapanese ?
412: trmTcpipPortAddress + " を開きました" :
413: trmTcpipPortAddress + " opened");
414:
415: if (trmTcpipPortChannel != null) {
416: trmTcpipPortChannel.accept (null, trmTcpipAcceptHandler);
417: }
418: return true;
419: }
420:
421:
422:
423: public static void trmTcpipClosePort () {
424: if (trmTcpipPortAddress != null) {
425: System.out.println (Multilingual.mlnJapanese ?
426: trmTcpipPortAddress + " を閉じました" :
427: trmTcpipPortAddress + " closed");
428: trmTcpipPortAddress = null;
429: }
430:
431: if (trmTcpipPortChannel != null &&
432: trmTcpipPortChannel.isOpen ()) {
433: try {
434: trmTcpipPortChannel.close ();
435: } catch (IOException ioe) {
436: ioe.printStackTrace ();
437: }
438: }
439: trmTcpipPortChannel = null;
440:
441: trmTcpipCloseSession (false);
442: }
443:
444:
445:
446:
447:
448:
449: public static void trmTcpipWrite (byte[] b, int o, int l) {
450: if (trmTcpipSessionChannel != null) {
451: byte[] bb = b;
452: int ll = l;
453: if (trmTcpipUTF8) {
454:
455: int pool = trmTcpipToUTF8Pool;
456: bb = new byte[3 * l];
457: ll = 0;
458: for (int i = 0; i < l; i++) {
459: int s = (pool << 8) | (0xff & b[o + i]);
460: if ((0x0080 <= s && s <= 0x009f) || (0x00e0 <= s && s <= 0x00ff)) {
461: pool = s;
462: continue;
463: }
464: pool = 0;
465: int u = CharacterCode.chrSJISToChar[s];
466: if (u == 0 && s != 0) {
467: u = '\ufffd';
468: }
469: if (u <= 0x007f) {
470: bb[ll++] = (byte) u;
471: } else if (u <= 0x07ff) {
472: bb[ll++] = (byte) (0xc0 | (u >> 6));
473: bb[ll++] = (byte) (0x80 | (u & 0x3f));
474: } else {
475: bb[ll++] = (byte) (0xe0 | (u >> 12));
476: bb[ll++] = (byte) (0x80 | ((u >> 6) & 0x3f));
477: bb[ll++] = (byte) (0x80 | (u & 0x3f));
478: }
479: }
480: trmTcpipToUTF8Pool = pool;
481: }
482: ByteBuffer buffer = ByteBuffer.allocate (ll);
483: buffer.put (bb, 0, ll);
484: buffer.flip ();
485: try {
486: trmTcpipSessionChannel.write (buffer).get ();
487: } catch (Throwable t) {
488: String message = t.getMessage ();
489: if (message != null) {
490: System.err.println (message);
491: }
492: trmTcpipCloseSession (true);
493: }
494: }
495: }
496:
497:
498:
499:
500: public static void trmTcpipCloseSession (boolean reconnect) {
501: if (trmTcpipSessionChannel == null) {
502: return;
503: }
504: if (trmTcpipClientAddress != null) {
505: System.out.println (Multilingual.mlnJapanese ?
506: trmTcpipClientAddress + " との接続を閉じました" :
507: trmTcpipClientAddress + " disconnected");
508: trmTcpipClientAddress = null;
509: }
510:
511: try {
512: trmTcpipSessionChannel.close ();
513: } catch (IOException ioe) {
514: ioe.printStackTrace ();
515: }
516: trmTcpipSessionChannel = null;
517: if (reconnect) {
518:
519: if (trmTcpipPortChannel != null) {
520: trmTcpipPortChannel.accept (null, trmTcpipAcceptHandler);
521: }
522: }
523: }
524:
525:
526:
527:
528:
529:
530:
531:
532:
533:
534:
535:
536:
537:
538:
539: public static boolean trmAUXFlowControlRTS;
540: public static boolean trmAUXFlowControlXON;
541: public static boolean trmAUXNotReceiving;
542:
543:
544: public static int trmAUXDataBuffer;
545: public static boolean trmAUXDataAvailable;
546:
547:
548:
549: public static int trmAUXReadData () {
550: trmAUXDataAvailable = false;
551: return trmAUXDataBuffer;
552: }
553:
554:
555:
556: public static void trmAUXWriteData (int data) {
557: int col = 1;
558: int row = trmColToRow[col];
559: if (row < 0) {
560: return;
561: }
562: data &= 0xff;
563: if (trmAUXFlowControlXON) {
564: if (data == 0x11) {
565: trmAUXNotReceiving = false;
566: return;
567: } else if (data == 0x13) {
568: trmAUXNotReceiving = true;
569: return;
570: }
571: }
572: trmConnectionArray[trmCols * row + col - 1].col2rowQueue.write (data);
573:
574: trmAUXSendEmpty = false;
575: TickerQueue.tkqAdd (trmAUXSendTicker, XEiJ.mpuClockTime + Z8530.scc1aInterval);
576: }
577:
578:
579:
580:
581: public static void trmAUXSetNotReceiving (boolean notReceiving) {
582: trmAUXNotReceiving = notReceiving;
583: }
584:
585:
586:
587:
588:
589:
590:
591: public static int trmAUXReadCommand () {
592: return (trmAUXConnection == null ?
593: (0 << 5 |
594: 0 << 3 |
595: 0 << 2 |
596: 0 << 0) :
597: (1 << 5 |
598: 1 << 3 |
599: (trmAUXSendEmpty ? 1 << 2 : 0 << 2) |
600: (trmAUXDataAvailable ? 1 << 0 : 0 << 0)));
601: }
602:
603:
604:
605:
606:
607:
608:
609:
610:
611:
612:
613: public static boolean trmAUXSendEmpty;
614: public static final TickerQueue.Ticker trmAUXSendTicker = new TickerQueue.Ticker () {
615: @Override protected void tick () {
616: trmAUXSendEmpty = true;
617: if (Z8530.scc1aSendMask != 0) {
618: Z8530.scc1aSendRR3 = Z8530.SCC_1A_SEND_MASK;
619: Z8530.scc1aSendRequest = Z8530.SCC_1A_SEND_MASK;
620: XEiJ.mpuIRR |= XEiJ.MPU_SCC_INTERRUPT_MASK;
621: }
622: }
623: };
624:
625:
626: public static Connection trmAUXConnection;
627: public static final TickerQueue.Ticker trmAUXTicker = new TickerQueue.Ticker () {
628: @Override protected void tick () {
629: long interval = XEiJ.TMR_FREQ / 1000 * 1;
630: ByteQueue queue = trmAUXConnection.row2colQueue;
631: if (trmAUXConnection.row2colReset) {
632: trmAUXConnection.row2colReset = false;
633: queue.clear ();
634: } else if (!trmAUXNotReceiving &&
635: queue.used () != 0) {
636: trmAUXDataBuffer = queue.read ();
637: trmAUXDataAvailable = true;
638: if (Z8530.scc1aReceiveMask != 0 &&
639: Z8530.scc1aReceiveRR3 == 0) {
640: Z8530.scc1aReceiveRR3 = Z8530.SCC_1A_RECEIVE_MASK;
641: Z8530.scc1aReceiveRequest = Z8530.SCC_1A_RECEIVE_MASK;
642: XEiJ.mpuIRR |= XEiJ.MPU_SCC_INTERRUPT_MASK;
643: }
644: interval = Z8530.scc1aInterval;
645: }
646: TickerQueue.tkqAdd (trmAUXTicker, XEiJ.mpuClockTime + interval);
647: }
648: };
649:
650: public static int trmRSDRV202Head;
651: public static int trmTMSIO031Head;
652: public static int trmBSIO021Head;
653:
654:
655:
656:
657:
658:
659:
660:
661: public static final TickerQueue.Ticker trmAUXFlowControlTicker = new TickerQueue.Ticker () {
662: @Override protected void tick () {
663: int set232c = MC68060.mmuPeekLongData (0x04c0, 1);
664: int modeAddress = (0x00fc0000 <= set232c && set232c < 0x01000000 ? 0x0926 :
665: set232c == trmRSDRV202Head + 0x03ba ? trmRSDRV202Head + 0x0ab2 :
666: set232c == trmTMSIO031Head + 0x0210 ? trmTMSIO031Head + 0x0a42 :
667: set232c == trmBSIO021Head + 0x013A ? trmBSIO021Head + 0x074a :
668: 0);
669: if (modeAddress == 0) {
670: return;
671: }
672: int mode = MC68060.mmuPeekWordZeroData (modeAddress, 1);
673: if (mode == 0x0000 || mode == 0xffff) {
674: return;
675: }
676: boolean rts = (mode & 0x0080) != 0;
677: boolean xon = !rts && (mode & 0x0200) != 0;
678: if (trmAUXFlowControlRTS == rts &&
679: trmAUXFlowControlXON == xon) {
680: return;
681: }
682: trmAUXFlowControlRTS = rts;
683: trmAUXFlowControlXON = xon;
684: if (false) {
685: System.out.printf ("flowcontrol=%s\n", rts ? "rts" : xon ? "xon" : "none");
686: }
687: int row = trmColToRow[1];
688: SerialPort port = row < 1 || trmNumberOfPorts < row ? null : trmPortArray[row - 1];
689: if (port != null) {
690: port.setFlowControl (rts ? (SerialPort.FLOW_CONTROL_RTS_ENABLED |
691: SerialPort.FLOW_CONTROL_CTS_ENABLED) :
692: xon ? (SerialPort.FLOW_CONTROL_XONXOFF_IN_ENABLED |
693: SerialPort.FLOW_CONTROL_XONXOFF_OUT_ENABLED) :
694: SerialPort.FLOW_CONTROL_DISABLED);
695: }
696: }
697: };
698:
699:
700:
701: public static void trmAUXReset () {
702: if (trmAUXConnection != null) {
703: TickerQueue.tkqRemove (trmAUXFlowControlTicker);
704:
705: trmAUXConnection.row2colReset = true;
706: trmAUXConnection.col2rowReset = true;
707: }
708: }
709:
710:
711: public static Connection[] trmConnectionArray;
712: public static Box trmConnectionBox;
713: public static ActionListener trmConnectionListener;
714: public static boolean trmRefreshEnabled;
715: public static JButton trmRefreshButton;
716:
717: public static boolean trmSettingsEnabled;
718: public static String[] trmBaudRateArray;
719: public static int trmBaudRateIndex;
720: public static String[] trmDataBitsArray;
721: public static int trmDataBitsIndex;
722: public static String[] trmParityArray;
723: public static int trmParityIndex;
724: public static String[] trmStopBitsArray;
725: public static int trmStopBitsIndex;
726: public static String[] trmFlowControlArray;
727: public static int trmFlowControlIndex;
728: public static JComboBox<String> trmBaudRateComboBox;
729: public static JComboBox<String> trmDataBitsComboBox;
730: public static JComboBox<String> trmParityComboBox;
731: public static JComboBox<String> trmStopBitsComboBox;
732: public static JComboBox<String> trmFlowControlComboBox;
733:
734: public static boolean trmSendEnabled;
735: public static JButton trmSendButton;
736: public static JFileChooser trmSendFileChooser;
737: public static JDialog trmSendDialog;
738: public static SendThread trmSendThread;
739:
740: public static JTextField trmAdditionalTextField;
741:
742:
743:
744: public static void trmInitConnection () {
745:
746: trmBaudRateArray = new String[] { "75", "150", "300", "600", "1200", "2400", "4800", "9600", "19200", "31250", "38400", "50000", "57600", "76800", "115200", "230400" };
747: trmBaudRateIndex = 10;
748: trmDataBitsArray = new String[] { "B5", "B6", "B7", "B8" };
749: trmDataBitsIndex = 3;
750: trmParityArray = new String[] { "PN", "PO", "PE" };
751: trmParityIndex = 0;
752: trmStopBitsArray = new String[] { "S1", "S1.5", "S2" };
753: trmStopBitsIndex = 0;
754: trmFlowControlArray = new String[] { "NONE", "XON", "RTS" };
755: trmFlowControlIndex = 2;
756: trmBaudRateComboBox = null;
757: trmDataBitsComboBox = null;
758: trmParityComboBox = null;
759: trmStopBitsComboBox = null;
760: trmFlowControlComboBox = null;
761:
762: for (String keyword : Settings.sgsGetString ("terminalsettings").split ("/")) {
763: for (int i = 0; i < trmBaudRateArray.length; i++) {
764: if (trmBaudRateArray[i].equals (keyword)) {
765: trmBaudRateIndex = i;
766: break;
767: }
768: }
769: for (int i = 0; i < trmDataBitsArray.length; i++) {
770: if (trmDataBitsArray[i].equals (keyword)) {
771: trmDataBitsIndex = i;
772: break;
773: }
774: }
775: for (int i = 0; i < trmParityArray.length; i++) {
776: if (trmParityArray[i].equals (keyword)) {
777: trmParityIndex = i;
778: break;
779: }
780: }
781: for (int i = 0; i < trmStopBitsArray.length; i++) {
782: if (trmStopBitsArray[i].equals (keyword)) {
783: trmStopBitsIndex = i;
784: break;
785: }
786: }
787: for (int i = 0; i < trmFlowControlArray.length; i++) {
788: if (trmFlowControlArray[i].equals (keyword)) {
789: trmFlowControlIndex = i;
790: break;
791: }
792: }
793: }
794:
795: trmSendButton = null;
796: trmSendFileChooser = null;
797: trmSendDialog = null;
798: trmSendThread = null;
799:
800: trmPortArray = new SerialPort[0];
801: trmNumberOfPorts = 0;
802:
803: trmRows = 1;
804: trmRowName = new String[1];
805: trmRowName[0] = "Terminal";
806: trmRowToCol = new int[1];
807: Arrays.fill (trmRowToCol, -1);
808:
809: trmNumberOfAUXs = 0;
810:
811: trmCols = 1;
812: trmColName = new String[1];
813: trmColName[0] = "Terminal";
814: trmColToRow = new int[1];
815: Arrays.fill (trmColToRow, -1);
816:
817: {
818: String text = Settings.sgsGetString ("additionalport");
819: try {
820: text = URLDecoder.decode (text, "UTF-8");
821: } catch (UnsupportedEncodingException uee) {
822: text = "";
823: }
824: trmAdditionalTextField = ComponentFactory.createTextField (text, 30);
825: }
826:
827: trmTcpipInit ();
828:
829: trmConnectionArray = new Connection[0];
830: trmConnectionBox = ComponentFactory.createVerticalBox (
831: Box.createVerticalGlue (),
832: ComponentFactory.createHorizontalBox (
833: Multilingual.mlnText (
834: ComponentFactory.createLabel ("Additional port "),
835: "ja", "追加ポート "
836: ),
837: trmAdditionalTextField,
838: Multilingual.mlnText (
839: ComponentFactory.createLabel (" TCP/IP port "),
840: "ja", " TCP/IP ポート "
841: ),
842: trmTcpipSpinner,
843: Box.createHorizontalStrut (5),
844: trmTcpipCheckBox,
845: Box.createHorizontalGlue ()
846: )
847: );
848: trmConnectionListener = new ActionListener () {
849: @Override public void actionPerformed (ActionEvent ae) {
850: String command = ae.getActionCommand ();
851: for (Connection connection : trmConnectionArray) {
852: if (connection.text.equals (command)) {
853: if (connection.connected) {
854: trmDisconnect (connection);
855: } else {
856: trmConnect (connection);
857: }
858: break;
859: }
860: }
861: }
862: };
863: trmRefreshEnabled = false;
864: trmRefreshButton = null;
865: trmSettingsEnabled = false;
866: trmSendEnabled = false;
867:
868: trmUpdateConnection ();
869:
870: HashSet<String> map = new HashSet<String> ();
871: for (String encodedText : Settings.sgsGetString ("rs232cconnection").split ("/")) {
872: try {
873: map.add (URLDecoder.decode (encodedText, "UTF-8"));
874: } catch (UnsupportedEncodingException uee) {
875: }
876: }
877: for (Connection connection : trmConnectionArray) {
878: if (map.contains (connection.text)) {
879: trmConnect (connection);
880: }
881: }
882: }
883:
884:
885:
886: public static void trmTiniConnection () {
887:
888: {
889: StringBuilder sb = new StringBuilder ();
890: for (Connection connection : trmConnectionArray) {
891: if (connection.connected) {
892: if (sb.length () != 0) {
893: sb.append ('/');
894: }
895: try {
896: sb.append (URLEncoder.encode (connection.text, "UTF-8"));
897: } catch (UnsupportedEncodingException uee) {
898: }
899: }
900: }
901: Settings.sgsPutString ("rs232cconnection", sb.toString ());
902: }
903:
904: {
905: String text = trmAdditionalTextField.getText ();
906: try {
907: text = URLEncoder.encode (text, "UTF-8");
908: } catch (UnsupportedEncodingException uee) {
909: text = "";
910: }
911: Settings.sgsPutString ("additionalport", text);
912: }
913:
914: trmTcpipTini ();
915:
916: {
917: StringBuilder sb = new StringBuilder ();
918: sb.append (trmBaudRateArray[trmBaudRateIndex]);
919: sb.append ('/');
920: sb.append (trmDataBitsArray[trmDataBitsIndex]);
921: sb.append ('/');
922: sb.append (trmParityArray[trmParityIndex]);
923: sb.append ('/');
924: sb.append (trmStopBitsArray[trmStopBitsIndex]);
925: sb.append ('/');
926: sb.append (trmFlowControlArray[trmFlowControlIndex]);
927: Settings.sgsPutString ("terminalsettings", sb.toString ());
928: }
929:
930: for (Connection connection : trmConnectionArray) {
931: trmDisconnect (connection);
932: }
933: }
934:
935:
936:
937: public static boolean trmIsConnectionUpdatable () {
938: for (Connection connection : trmConnectionArray) {
939: if (connection.row != 0 &&
940: connection.connected) {
941: return false;
942: }
943: }
944: return true;
945: }
946:
947:
948:
949: public static void trmUpdateConnection () {
950:
951: if (!trmIsConnectionUpdatable ()) {
952: return;
953: }
954:
955: ArrayList<SerialPort> portList = new ArrayList<SerialPort> ();
956: for (SerialPort port : SerialPort.getCommPorts ()) {
957: int vid = port.getVendorID ();
958: int pid = port.getProductID ();
959: portList.add (port);
960: }
961: for (String descriptor : trmAdditionalTextField.getText ().split (",")) {
962: descriptor = descriptor.trim ();
963: if (!descriptor.equals ("")) {
964: try {
965: SerialPort port = SerialPort.getCommPort (descriptor);
966: if (port != null) {
967: if (false) {
968: for (SerialPort anotherPort : portList) {
969: if (port.getDescriptivePortName ().equals (anotherPort.getDescriptivePortName ())) {
970: port = null;
971: break;
972: }
973: }
974: }
975: if (port != null) {
976: portList.add (port);
977: }
978: } else {
979: System.out.println (descriptor + " not found");
980: }
981: } catch (SerialPortInvalidPortException spipe) {
982: System.out.println (spipe.toString ());
983: }
984: }
985: }
986: trmNumberOfPorts = portList.size ();
987: trmPortArray = portList.toArray (new SerialPort[trmNumberOfPorts]);
988:
989: trmRows = 1 + trmNumberOfPorts + 1;
990: trmRowName = new String[trmRows];
991: trmRowName[0] = "Terminal";
992: for (int row = 1; row < trmRows - 1; row++) {
993: SerialPort port = trmPortArray[row - 1];
994: trmRowName[row] = port.getSystemPortName () + "(" + port.getPortDescription () + ")";
995: }
996: trmRowName[trmRows - 1] = "TCP/IP";
997: trmRowToCol = new int[trmRows];
998: Arrays.fill (trmRowToCol, -1);
999:
1000: trmNumberOfAUXs = 1;
1001:
1002: trmCols = 1 + trmNumberOfAUXs;
1003: trmColName = new String[trmCols];
1004: trmColName[0] = "Terminal";
1005: for (int col = 1; col < trmCols; col++) {
1006: trmColName[col] = col == 1 ? "AUX" : "AUX" + col;
1007: }
1008: trmColToRow = new int[trmCols];
1009: Arrays.fill (trmColToRow, -1);
1010:
1011: for (int index = trmConnectionArray.length - 1; 0 <= index; index--) {
1012: trmConnectionBox.remove (index);
1013: }
1014: trmConnectionArray = new Connection[trmCols * trmRows - 1];
1015: for (int row = 0; row < trmRows; row++) {
1016: for (int col = 0; col < trmCols; col++) {
1017: if (col == 0 && row == 0) {
1018: continue;
1019: }
1020: Connection connection = new Connection ();
1021: connection.row = row;
1022: connection.col = col;
1023: connection.index = trmCols * row + col - 1;
1024: connection.text = trmRowName[row] + " ⇔ " + trmColName[col];
1025: connection.connected = false;
1026: connection.checkBox =
1027: ComponentFactory.createCheckBox (connection.connected, connection.text, trmConnectionListener);
1028: connection.box =
1029: ComponentFactory.createHorizontalBox (
1030: connection.checkBox,
1031: Box.createHorizontalGlue ());
1032: trmConnectionArray[connection.index] = connection;
1033: trmConnectionBox.add (connection.box, connection.index);
1034: }
1035: }
1036: trmUpdateComponents ();
1037: trmConnectionBox.validate ();
1038: }
1039:
1040:
1041:
1042:
1043:
1044: public static void trmUpdateComponents () {
1045: boolean updatable = true;
1046: boolean configurable = false;
1047: boolean transferable = false;
1048: for (Connection connection : trmConnectionArray) {
1049: if (connection.connected) {
1050: connection.checkBox.setEnabled (true);
1051: if (connection.row != trmRows - 1 &&
1052: 0 < connection.row) {
1053: updatable = false;
1054: if (connection.col == 0) {
1055: configurable = true;
1056: }
1057: }
1058: if (connection.row == 0 ||
1059: connection.col == 0) {
1060: transferable = true;
1061: }
1062: } else {
1063: connection.checkBox.setEnabled (trmIsConnectable (connection));
1064: }
1065: }
1066: trmRefreshEnabled = updatable;
1067: if (trmRefreshButton != null) {
1068: trmRefreshButton.setEnabled (updatable);
1069: }
1070: trmSettingsEnabled = configurable;
1071: trmSendEnabled = transferable;
1072: if (trmBaudRateComboBox != null) {
1073: trmBaudRateComboBox.setEnabled (configurable);
1074: trmDataBitsComboBox.setEnabled (configurable);
1075: trmParityComboBox.setEnabled (configurable);
1076: trmStopBitsComboBox.setEnabled (configurable);
1077: trmFlowControlComboBox.setEnabled (configurable);
1078: trmSendButton.setEnabled (transferable);
1079: }
1080: }
1081:
1082:
1083:
1084: public static boolean trmIsConnectable (Connection connection) {
1085: if (!connection.connected) {
1086: for (Connection connection2 : trmConnectionArray) {
1087: if (connection != connection2 &&
1088: connection2.connected &&
1089: (((connection.row == 0 || connection.col == 0) &&
1090: (connection2.row == 0 || connection2.col == 0)) ||
1091: connection.row == connection2.row ||
1092: connection.col == connection2.col)) {
1093: return false;
1094: }
1095: }
1096: }
1097: return true;
1098: }
1099:
1100:
1101:
1102: public static void trmConnect (Connection connection) {
1103:
1104: if (connection.connected ||
1105: !trmIsConnectable (connection)) {
1106: return;
1107: }
1108:
1109: connection.connected = true;
1110: connection.checkBox.setSelected (true);
1111: trmRowToCol[connection.row] = connection.col;
1112: trmColToRow[connection.col] = connection.row;
1113: trmUpdateComponents ();
1114:
1115: connection.row2colQueue = new ByteQueue ();
1116: connection.col2rowQueue = new ByteQueue ();
1117: if (connection.row == trmRows - 1) {
1118:
1119: if (!trmTcpipOpenPort (connection.row2colQueue)) {
1120:
1121:
1122: }
1123: } else if (0 < connection.row) {
1124:
1125: SerialPort port = trmPortArray[connection.row - 1];
1126: port.openPort ();
1127: System.out.println (Multilingual.mlnJapanese ?
1128: connection.text + " を開きました" :
1129: connection.text + " opened");
1130: port.setComPortTimeouts (SerialPort.TIMEOUT_WRITE_BLOCKING | SerialPort.TIMEOUT_READ_BLOCKING, 0, 0);
1131: port.setFlowControl (SerialPort.FLOW_CONTROL_DISABLED);
1132:
1133: trmReflectSettings (connection.col);
1134:
1135: port.addDataListener (connection);
1136: }
1137:
1138: connection.polling = true;
1139: connection.row2colThread = (connection.col == 0 ? connection.new TerminalThread () :
1140: null);
1141: connection.col2rowThread = (connection.row == 0 ? connection.new TerminalThread () :
1142: connection.row == trmRows - 1 ? connection.new TCPIPThread () :
1143: connection.new SerialPortThread ());
1144: for (int i = 0; i < 2; i++) {
1145: Thread thread = (i == 0 ? connection.row2colThread : connection.col2rowThread);
1146: if (thread != null) {
1147: thread.start ();
1148: }
1149: }
1150:
1151: if (connection.col == 1) {
1152: trmAUXNotReceiving = false;
1153: trmAUXDataBuffer = 0;
1154: trmAUXDataAvailable = false;
1155: trmAUXConnection = connection;
1156: TickerQueue.tkqAdd (trmAUXTicker, XEiJ.mpuClockTime + XEiJ.TMR_FREQ / 1000 * 1);
1157:
1158: trmAUXSendEmpty = true;
1159: }
1160: }
1161:
1162:
1163:
1164: public static void trmDisconnect (Connection connection) {
1165:
1166: if (!connection.connected) {
1167: return;
1168: }
1169:
1170: connection.connected = false;
1171: connection.checkBox.setSelected (connection.connected);
1172: trmRowToCol[connection.row] = -1;
1173: trmColToRow[connection.col] = -1;
1174: trmUpdateComponents ();
1175:
1176: if (trmAUXConnection != null) {
1177: TickerQueue.tkqRemove (trmAUXTicker);
1178: trmAUXConnection = null;
1179: }
1180:
1181: connection.polling = false;
1182: for (int i = 0; i < 2; i++) {
1183: Thread thread = (i == 0 ? connection.row2colThread : connection.col2rowThread);
1184: if (thread != null) {
1185: connection.row2colThread = null;
1186: if (thread.isAlive ()) {
1187: thread.interrupt ();
1188: try {
1189: thread.join ();
1190: } catch (InterruptedException ie) {
1191: }
1192: }
1193: }
1194: }
1195:
1196: if (connection.col == 1) {
1197: TickerQueue.tkqRemove (trmAUXSendTicker);
1198: }
1199: if (connection.row == trmRows - 1) {
1200:
1201: trmTcpipClosePort ();
1202: } else if (0 < connection.row) {
1203: SerialPort port = trmPortArray[connection.row - 1];
1204:
1205: port.removeDataListener ();
1206:
1207: port.closePort ();
1208: System.out.println (Multilingual.mlnJapanese ?
1209: connection.text + " を閉じました" :
1210: connection.text + " closed");
1211: }
1212:
1213: connection.row2colQueue.clear ();
1214: connection.col2rowQueue.clear ();
1215: connection.row2colQueue = null;
1216: connection.col2rowQueue = null;
1217: }
1218:
1219:
1220:
1221: public static void trmSetBaudRate (int index) {
1222: if (0 <= index && index < trmBaudRateArray.length) {
1223: trmBaudRateIndex = index;
1224: trmReflectSettings (0);
1225: }
1226: }
1227:
1228:
1229:
1230: public static void trmSetDataBits (int index) {
1231: if (0 <= index && index < trmDataBitsArray.length) {
1232: trmDataBitsIndex = index;
1233: trmReflectSettings (0);
1234: }
1235: }
1236:
1237:
1238:
1239: public static void trmSetParity (int index) {
1240: if (0 <= index && index < trmParityArray.length) {
1241: trmParityIndex = index;
1242: trmReflectSettings (0);
1243: }
1244: }
1245:
1246:
1247:
1248: public static void trmSetStopBits (int index) {
1249: if (0 <= index && index < trmStopBitsArray.length) {
1250: trmStopBitsIndex = index;
1251: trmReflectSettings (0);
1252: }
1253: }
1254:
1255:
1256:
1257: public static void trmSetFlowControl (int index) {
1258: if (0 <= index && index < trmFlowControlArray.length) {
1259: trmFlowControlIndex = index;
1260: trmReflectSettings (0);
1261: }
1262: }
1263:
1264:
1265:
1266: public static void trmReflectSettings (int col) {
1267: int row = trmColToRow[col];
1268: SerialPort port = row < 1 || trmNumberOfPorts < row ? null : trmPortArray[row - 1];
1269: if (col == 0) {
1270: String baudRate = trmBaudRateArray[trmBaudRateIndex];
1271: String dataBits = trmDataBitsArray[trmDataBitsIndex];
1272: String stopBits = trmStopBitsArray[trmStopBitsIndex];
1273: String parity = trmParityArray[trmParityIndex];
1274: String flowControl = trmFlowControlArray[trmFlowControlIndex];
1275: if (port != null) {
1276: port.setComPortParameters (Integer.parseInt (baudRate, 10),
1277: Integer.parseInt (dataBits.substring (1), 10),
1278: stopBits.equals ("S1.5") ? SerialPort.ONE_POINT_FIVE_STOP_BITS :
1279: stopBits.equals ("S2") ? SerialPort.TWO_STOP_BITS : SerialPort.ONE_STOP_BIT,
1280: parity.equals ("PO") ? SerialPort.ODD_PARITY :
1281: parity.equals ("PE") ? SerialPort.EVEN_PARITY : SerialPort.NO_PARITY);
1282: port.setFlowControl (flowControl.equals ("RTS") ? (SerialPort.FLOW_CONTROL_RTS_ENABLED |
1283: SerialPort.FLOW_CONTROL_CTS_ENABLED) :
1284: flowControl.equals ("XON") ? (SerialPort.FLOW_CONTROL_XONXOFF_IN_ENABLED |
1285: SerialPort.FLOW_CONTROL_XONXOFF_OUT_ENABLED) :
1286: SerialPort.FLOW_CONTROL_DISABLED);
1287: }
1288: } else if (col == 1) {
1289: double rate = Z8530.sccFreq / (double) ((Z8530.scc1aBaudRateGen + 2) << (Z8530.scc1aClockModeShift + 1));
1290: double bits = (1.0 +
1291: (Z8530.scc1aRxBits == 0 ? 5.0 :
1292: Z8530.scc1aRxBits == 1 ? 7.0 :
1293: Z8530.scc1aRxBits == 2 ? 6.0 : 8.0) +
1294: ((Z8530.scc1aParity & 1) == 0 ? 0.0 : 1.0) +
1295: (Z8530.scc1aStop == 0 ? 0.0 :
1296: Z8530.scc1aStop == 1 ? 1.0 :
1297: Z8530.scc1aStop == 2 ? 1.5 : 2.0));
1298: double interval = bits / rate;
1299: if (false) {
1300: System.out.printf ("%08x baudrate=%.3fbps interval=%.3fus\n", XEiJ.regPC0, rate, interval * 1e+6);
1301: }
1302: Z8530.scc1aInterval = Math.round (interval * (double) XEiJ.TMR_FREQ);
1303:
1304: if (port != null) {
1305: port.setComPortParameters ((int) Math.round (rate),
1306: Z8530.scc1aRxBits == 0b00 ? 5 :
1307: Z8530.scc1aRxBits == 0b01 ? 7 :
1308: Z8530.scc1aRxBits == 0b10 ? 6 : 8,
1309: Z8530.scc1aStop == 0b10 ? SerialPort.ONE_POINT_FIVE_STOP_BITS :
1310: Z8530.scc1aStop == 0b11 ? SerialPort.TWO_STOP_BITS : SerialPort.ONE_STOP_BIT,
1311: Z8530.scc1aParity == 0b01 ? SerialPort.ODD_PARITY :
1312: Z8530.scc1aParity == 0b11 ? SerialPort.EVEN_PARITY : SerialPort.NO_PARITY);
1313: }
1314:
1315:
1316: TickerQueue.tkqAdd (trmAUXFlowControlTicker, XEiJ.mpuClockTime + XEiJ.TMR_FREQ * 500 / 1000000);
1317: } else {
1318:
1319: }
1320: }
1321:
1322:
1323:
1324:
1325: public static void trmInit () {
1326: trmFrame = null;
1327: trmBoard = null;
1328: trmPopupMenu = null;
1329: trmPopupCutMenuItem = null;
1330: trmPopupCopyMenuItem = null;
1331: trmPopupPasteMenuItem = null;
1332: trmPopupSelectAllMenuItem = null;
1333: trmPopupSendCtrlCMenuItem = null;
1334: trmOutputBuilder = new StringBuilder ();
1335: trmOutputEnd = 0;
1336: trmOutputSJIS1 = 0;
1337:
1338: trmInitConnection ();
1339: trmReset ();
1340: }
1341:
1342: public static void trmReset () {
1343: trmRSDRV202Head = 0;
1344: trmTMSIO031Head = 0;
1345: trmBSIO021Head = 0;
1346: trmAUXFlowControlXON = false;
1347: trmAUXFlowControlRTS = false;
1348: }
1349:
1350:
1351:
1352: public static void trmTini () {
1353: trmTiniConnection ();
1354: }
1355:
1356:
1357:
1358:
1359: public static void trmMake () {
1360:
1361:
1362: trmBoard = ComponentFactory.createScrollTextArea (
1363: trmOutputBuilder.toString (),
1364: 650, 350,
1365: true);
1366: trmOutputBuilder = null;
1367: trmBoard.setUnderlineCursorOn (true);
1368: trmBoard.setLineWrap (true);
1369: trmBoard.addDocumentListener (new DocumentListener () {
1370: @Override public void changedUpdate (DocumentEvent de) {
1371: }
1372: @Override public void insertUpdate (DocumentEvent de) {
1373: if (de.getOffset () < trmOutputEnd) {
1374: trmOutputEnd += de.getLength ();
1375: }
1376: }
1377: @Override public void removeUpdate (DocumentEvent de) {
1378: if (de.getOffset () < trmOutputEnd) {
1379: trmOutputEnd -= Math.min (de.getLength (), trmOutputEnd - de.getOffset ());
1380: }
1381: }
1382: });
1383: trmBoard.addKeyListener (new KeyAdapter () {
1384: @Override public void keyPressed (KeyEvent ke) {
1385: int keyCode = ke.getKeyCode ();
1386: if (keyCode == KeyEvent.VK_ENTER) {
1387: ke.consume ();
1388: trmEnter ();
1389: } else if (keyCode == KeyEvent.VK_PAUSE) {
1390: ke.consume ();
1391: trmSendString ("\u0003");
1392: }
1393: }
1394: });
1395:
1396:
1397: ActionListener popupActionListener = new ActionListener () {
1398: @Override public void actionPerformed (ActionEvent ae) {
1399: switch (ae.getActionCommand ()) {
1400: case "Cut":
1401: trmCut ();
1402: break;
1403: case "Copy":
1404: trmCopy ();
1405: break;
1406: case "Paste":
1407: trmPaste ();
1408: break;
1409: case "Select All":
1410: trmSelectAll ();
1411: break;
1412: case "Send ^C":
1413: trmSendString ("\u0003");
1414: break;
1415: }
1416: }
1417: };
1418: trmPopupMenu = ComponentFactory.createPopupMenu (
1419: trmPopupCutMenuItem = Multilingual.mlnText (
1420: ComponentFactory.createMenuItem ("Cut", 'T', popupActionListener),
1421: "ja", "切り取り"),
1422: trmPopupCopyMenuItem = Multilingual.mlnText (
1423: ComponentFactory.createMenuItem ("Copy", 'C', popupActionListener),
1424: "ja", "コピー"),
1425: trmPopupPasteMenuItem = Multilingual.mlnText (
1426: ComponentFactory.createMenuItem ("Paste", 'P', popupActionListener),
1427: "ja", "貼り付け"),
1428: ComponentFactory.createHorizontalSeparator (),
1429: trmPopupSelectAllMenuItem = Multilingual.mlnText (
1430: ComponentFactory.createMenuItem ("Select All", 'A', popupActionListener),
1431: "ja", "すべて選択"),
1432: ComponentFactory.createHorizontalSeparator (),
1433: trmPopupSendCtrlCMenuItem = Multilingual.mlnText (
1434: ComponentFactory.createMenuItem ("Send ^C", popupActionListener),
1435: "ja", "^C 送信")
1436: );
1437: trmBoard.addMouseListener (new MouseAdapter () {
1438: @Override public void mousePressed (MouseEvent me) {
1439: trmShowPopup (me);
1440: }
1441: @Override public void mouseReleased (MouseEvent me) {
1442: trmShowPopup (me);
1443: }
1444: });
1445:
1446:
1447: ActionListener listener = new ActionListener () {
1448: @Override public void actionPerformed (ActionEvent ae) {
1449: Object source = ae.getSource ();
1450: String command = ae.getActionCommand ();
1451: switch (command) {
1452: case "Refresh":
1453: trmUpdateConnection ();
1454: break;
1455: case "Baud rate":
1456: trmSetBaudRate (((JComboBox) source).getSelectedIndex ());
1457: break;
1458: case "Data bits":
1459: trmSetDataBits (((JComboBox) source).getSelectedIndex ());
1460: break;
1461: case "Parity":
1462: trmSetParity (((JComboBox) source).getSelectedIndex ());
1463: break;
1464: case "Stop bits":
1465: trmSetStopBits (((JComboBox) source).getSelectedIndex ());
1466: break;
1467: case "Flow control":
1468: trmSetFlowControl (((JComboBox) source).getSelectedIndex ());
1469: break;
1470: case "Send file":
1471: trmSendFile ();
1472: break;
1473: case "7.3728MHz":
1474: Z8530.sccFreq = ((JCheckBox) source).isSelected () ? 7372800.0 : 5000000.0;
1475: break;
1476: default:
1477: System.out.println ("unknown action command " + command);
1478: }
1479: }
1480: };
1481:
1482:
1483: trmRefreshButton =
1484: ComponentFactory.setEnabled (
1485: Multilingual.mlnText (
1486: ComponentFactory.createButton ("Refresh", listener),
1487: "ja", "更新"),
1488: trmRefreshEnabled);
1489: trmBaudRateComboBox =
1490: ComponentFactory.setEnabled (
1491: Multilingual.mlnToolTipText (
1492: ComponentFactory.createComboBox (
1493: trmBaudRateIndex, "Baud rate", listener, trmBaudRateArray),
1494: "ja", "ボーレート"),
1495: trmSettingsEnabled);
1496: trmDataBitsComboBox =
1497: ComponentFactory.setEnabled (
1498: Multilingual.mlnToolTipText (
1499: ComponentFactory.createComboBox (
1500: trmDataBitsIndex, "Data bits", listener, trmDataBitsArray),
1501: "ja", "データビット"),
1502: trmSettingsEnabled);
1503: trmParityComboBox =
1504: ComponentFactory.setEnabled (
1505: Multilingual.mlnToolTipText (
1506: ComponentFactory.createComboBox (
1507: trmParityIndex, "Parity", listener, trmParityArray),
1508: "ja", "パリティ"),
1509: trmSettingsEnabled);
1510: trmStopBitsComboBox =
1511: ComponentFactory.setEnabled (
1512: Multilingual.mlnToolTipText (
1513: ComponentFactory.createComboBox (
1514: trmStopBitsIndex, "Stop bits", listener, trmStopBitsArray),
1515: "ja", "ストップビット"),
1516: trmSettingsEnabled);
1517: trmFlowControlComboBox =
1518: ComponentFactory.setEnabled (
1519: Multilingual.mlnToolTipText (
1520: ComponentFactory.createComboBox (
1521: trmFlowControlIndex, "Flow control", listener, trmFlowControlArray),
1522: "ja", "フロー制御"),
1523: trmSettingsEnabled);
1524: trmSendButton =
1525: ComponentFactory.setEnabled (
1526: Multilingual.mlnText (
1527: ComponentFactory.createButton ("Send file", listener),
1528: "ja", "ファイル送信"),
1529: trmSendEnabled);
1530:
1531:
1532: trmFrame = Multilingual.mlnTitle (
1533: ComponentFactory.createRestorableSubFrame (
1534: Settings.SGS_TRM_FRAME_KEY,
1535: "RS-232C and terminal",
1536: null,
1537: ComponentFactory.createVerticalSplitPane (
1538: ComponentFactory.createVerticalBox (
1539: Multilingual.mlnTitledBorder (
1540: ComponentFactory.setTitledLineBorder (
1541: ComponentFactory.createHorizontalBox (
1542: Box.createHorizontalStrut (5),
1543: ComponentFactory.createVerticalBox (
1544: Box.createVerticalGlue (),
1545: trmRefreshButton,
1546: Box.createVerticalGlue ()
1547: ),
1548: Box.createHorizontalStrut (10),
1549: trmConnectionBox,
1550: Box.createHorizontalGlue ()
1551: ),
1552: "Connection"),
1553: "ja", "接続"),
1554: ComponentFactory.createHorizontalBox (
1555: Multilingual.mlnTitledBorder (
1556: ComponentFactory.setTitledLineBorder (
1557: ComponentFactory.createHorizontalBox (
1558: Box.createHorizontalStrut (5),
1559: trmBaudRateComboBox,
1560: trmDataBitsComboBox,
1561: trmParityComboBox,
1562: trmStopBitsComboBox,
1563: trmFlowControlComboBox,
1564: Box.createHorizontalStrut (5)
1565: ),
1566: "Communication Settings"),
1567: "ja", "通信設定"),
1568: Multilingual.mlnTitledBorder (
1569: ComponentFactory.setTitledLineBorder (
1570: ComponentFactory.createHorizontalBox (
1571: Box.createHorizontalStrut (5),
1572: trmSendButton,
1573: Box.createHorizontalStrut (5)
1574: ),
1575: "Transfer"),
1576: "ja", "転送"),
1577: Box.createHorizontalGlue (),
1578: Multilingual.mlnTitledBorder (
1579: ComponentFactory.setTitledLineBorder (
1580: ComponentFactory.createHorizontalBox (
1581: Box.createHorizontalStrut (5),
1582: ComponentFactory.createCheckBox (Z8530.sccFreq == 7372800.0, "7.3728MHz", listener),
1583: Box.createHorizontalStrut (5)
1584: ),
1585: "Modification"),
1586: "ja", "改造")
1587: )
1588: ),
1589: ComponentFactory.createVerticalBox (
1590: Multilingual.mlnTitledBorder (
1591: ComponentFactory.setTitledLineBorder (trmBoard, "Terminal"),
1592: "ja", "ターミナル")
1593: )
1594: )
1595: ),
1596: "ja", "RS-232C とターミナル");
1597:
1598: }
1599:
1600:
1601:
1602:
1603: public static void trmShowPopup (MouseEvent me) {
1604: if (me.isPopupTrigger ()) {
1605:
1606: boolean enableCutAndCopy = XEiJ.clpClipboard != null && trmBoard.getSelectionStart () != trmBoard.getSelectionEnd ();
1607: ComponentFactory.setEnabled (trmPopupCutMenuItem, enableCutAndCopy);
1608: ComponentFactory.setEnabled (trmPopupCopyMenuItem, enableCutAndCopy);
1609:
1610: ComponentFactory.setEnabled (trmPopupPasteMenuItem, XEiJ.clpClipboard != null && XEiJ.clpClipboard.isDataFlavorAvailable (DataFlavor.stringFlavor));
1611:
1612: ComponentFactory.setEnabled (trmPopupSelectAllMenuItem, XEiJ.clpClipboard != null);
1613:
1614: ComponentFactory.setEnabled (trmPopupSendCtrlCMenuItem,
1615: trmRowToCol[0] == 1 ||
1616: 0 < trmColToRow[0]);
1617:
1618: trmPopupMenu.show (me.getComponent (), me.getX (), me.getY ());
1619: }
1620: }
1621:
1622:
1623:
1624: public static void trmCut () {
1625: if (XEiJ.clpClipboard != null) {
1626:
1627: XEiJ.clpClipboardString = trmBoard.getSelectedText ();
1628: try {
1629: XEiJ.clpClipboard.setContents (XEiJ.clpStringContents, XEiJ.clpClipboardOwner);
1630: XEiJ.clpIsClipboardOwner = true;
1631: } catch (Exception e) {
1632: return;
1633: }
1634:
1635: trmBoard.replaceRange ("", trmBoard.getSelectionStart (), trmBoard.getSelectionEnd ());
1636: }
1637: }
1638:
1639:
1640:
1641: public static void trmCopy () {
1642: if (XEiJ.clpClipboard != null) {
1643:
1644: String selectedText = trmBoard.getSelectedText ();
1645: if (selectedText != null) {
1646: XEiJ.clpClipboardString = selectedText;
1647: try {
1648: XEiJ.clpClipboard.setContents (XEiJ.clpStringContents, XEiJ.clpClipboardOwner);
1649: XEiJ.clpIsClipboardOwner = true;
1650: } catch (Exception e) {
1651: return;
1652: }
1653: }
1654: }
1655: }
1656:
1657:
1658:
1659: public static void trmPaste () {
1660: if (XEiJ.clpClipboard != null) {
1661:
1662: String string = null;
1663: try {
1664: string = (String) XEiJ.clpClipboard.getData (DataFlavor.stringFlavor);
1665: } catch (Exception e) {
1666: return;
1667: }
1668:
1669: trmBoard.replaceRange (string, trmBoard.getSelectionStart (), trmBoard.getSelectionEnd ());
1670: }
1671: }
1672:
1673:
1674:
1675: public static void trmSelectAll () {
1676: if (XEiJ.clpClipboard != null) {
1677:
1678: trmBoard.selectAll ();
1679: }
1680: }
1681:
1682:
1683: public static void trmStart () {
1684: if (RestorableFrame.rfmGetOpened (Settings.SGS_TRM_FRAME_KEY)) {
1685: trmOpen ();
1686: }
1687: }
1688:
1689:
1690:
1691: public static void trmOpen () {
1692: if (trmFrame == null) {
1693: trmMake ();
1694: }
1695: XEiJ.pnlExitFullScreen (false);
1696: trmFrame.setVisible (true);
1697: }
1698:
1699:
1700:
1701:
1702: public static void trmPrintSJIS (int d) {
1703: d &= 0xff;
1704: if (trmOutputSJIS1 != 0) {
1705: if (0x40 <= d && d != 0x7f && d <= 0xfc) {
1706: int c = CharacterCode.chrSJISToChar[trmOutputSJIS1 << 8 | d];
1707: if (c != 0) {
1708: trmPrintChar (c);
1709: } else {
1710:
1711: trmPrintChar ('[');
1712: trmPrintChar (XEiJ.fmtHexc (trmOutputSJIS1 >> 4));
1713: trmPrintChar (XEiJ.fmtHexc (trmOutputSJIS1 & 15));
1714: trmPrintChar (XEiJ.fmtHexc (d >> 4));
1715: trmPrintChar (XEiJ.fmtHexc (d & 15));
1716: trmPrintChar (']');
1717: }
1718: trmOutputSJIS1 = 0;
1719: return;
1720: }
1721:
1722:
1723: trmPrintChar ('[');
1724: trmPrintChar (XEiJ.fmtHexc (trmOutputSJIS1 >> 4));
1725: trmPrintChar (XEiJ.fmtHexc (trmOutputSJIS1 & 15));
1726: trmPrintChar (']');
1727: trmOutputSJIS1 = 0;
1728: }
1729: if (0x81 <= d && d <= 0x9f || 0xe0 <= d && d <= 0xef) {
1730: trmOutputSJIS1 = d;
1731: } else {
1732: int c = CharacterCode.chrSJISToChar[d];
1733: if (c != 0) {
1734: trmPrintChar (c);
1735: } else {
1736:
1737: trmPrintChar ('[');
1738: trmPrintChar (XEiJ.fmtHexc (d >> 4));
1739: trmPrintChar (XEiJ.fmtHexc (d & 15));
1740: trmPrintChar (']');
1741: }
1742: }
1743: }
1744:
1745:
1746:
1747: public static void trmPrintChar (int c) {
1748: if (c == 0x08) {
1749: if (trmOutputEnd > 0) {
1750: if (trmBoard != null) {
1751: trmBoard.replaceRange ("", trmOutputEnd - 1, trmOutputEnd);
1752: trmOutputEnd--;
1753: trmBoard.setCaretPosition (trmOutputEnd);
1754: } else {
1755: trmOutputBuilder.delete (trmOutputEnd - 1, trmOutputEnd);
1756: trmOutputEnd--;
1757: }
1758: }
1759: } else if (c >= 0x20 && c != 0x7f || c == 0x09 || c == 0x0a) {
1760: if (trmBoard != null) {
1761: trmBoard.insert (String.valueOf ((char) c), trmOutputEnd);
1762: trmOutputEnd++;
1763: if (trmOutputEnd >= TRM_CUT_OUTPUT_LENGTH) {
1764: trmBoard.replaceRange ("", 0, trmOutputEnd - TRM_MAX_OUTPUT_LENGTH);
1765: trmOutputEnd = TRM_MAX_OUTPUT_LENGTH;
1766: }
1767: trmBoard.setCaretPosition (trmOutputEnd);
1768: } else {
1769: trmOutputBuilder.append ((char) c);
1770: trmOutputEnd++;
1771: if (trmOutputEnd >= TRM_CUT_OUTPUT_LENGTH) {
1772: trmOutputBuilder.delete (0, trmOutputEnd - TRM_MAX_OUTPUT_LENGTH);
1773: trmOutputEnd = TRM_MAX_OUTPUT_LENGTH;
1774: }
1775: }
1776: }
1777: }
1778:
1779:
1780:
1781:
1782:
1783: public static void trmPrint (String s) {
1784: if (s == null) {
1785: return;
1786: }
1787: if (trmFrame != null) {
1788: trmBoard.insert (s, trmOutputEnd);
1789: trmOutputEnd += s.length ();
1790: if (trmOutputEnd >= TRM_CUT_OUTPUT_LENGTH) {
1791: trmBoard.replaceRange ("", 0, trmOutputEnd - TRM_MAX_OUTPUT_LENGTH);
1792: trmOutputEnd = TRM_MAX_OUTPUT_LENGTH;
1793: }
1794: trmBoard.setCaretPosition (trmOutputEnd);
1795: } else {
1796: trmOutputBuilder.append (s);
1797: trmOutputEnd += s.length ();
1798: if (trmOutputEnd >= TRM_CUT_OUTPUT_LENGTH) {
1799: trmOutputBuilder.delete (0, trmOutputEnd - TRM_MAX_OUTPUT_LENGTH);
1800: trmOutputEnd = TRM_MAX_OUTPUT_LENGTH;
1801: }
1802: }
1803: }
1804:
1805:
1806:
1807:
1808:
1809: public static void trmPrintln (String s) {
1810: trmPrint (s);
1811: trmPrintChar ('\n');
1812: }
1813:
1814:
1815:
1816: public static void trmEnter () {
1817: String text = trmBoard.getText ();
1818: int length = text.length ();
1819: int outputLineStart = text.lastIndexOf ('\n', trmOutputEnd - 1) + 1;
1820: int caretLineStart = text.lastIndexOf ('\n', trmBoard.getCaretPosition () - 1) + 1;
1821: if (outputLineStart <= caretLineStart) {
1822: trmBoard.replaceRange ("", trmOutputEnd, length);
1823: trmSendString (text.substring (trmOutputEnd, length) + "\r");
1824: } else if (outputLineStart < trmOutputEnd) {
1825: String prompt = text.substring (outputLineStart, trmOutputEnd);
1826: int caretLineEnd = text.indexOf ('\n', caretLineStart);
1827: if (caretLineEnd == -1) {
1828: caretLineEnd = length;
1829: }
1830: String line = text.substring (caretLineStart, caretLineEnd);
1831: int start = line.indexOf (prompt);
1832: if (start >= 0) {
1833: trmOutputEnd = length;
1834: if (text.charAt (trmOutputEnd - 1) != '\n') {
1835: trmBoard.insert ("\n", trmOutputEnd);
1836: trmOutputEnd++;
1837: if (trmOutputEnd >= TRM_CUT_OUTPUT_LENGTH) {
1838: trmBoard.replaceRange ("", 0, trmOutputEnd - TRM_MAX_OUTPUT_LENGTH);
1839: trmOutputEnd = TRM_MAX_OUTPUT_LENGTH;
1840: }
1841: }
1842: trmBoard.setCaretPosition (trmOutputEnd);
1843: trmSendString (line.substring (start + prompt.length ()) + "\r");
1844: }
1845: }
1846: }
1847:
1848:
1849:
1850: public static void trmSendString (String s) {
1851: int l = s.length ();
1852: if (l == 0) {
1853: return;
1854: }
1855: byte[] b = new byte[l * 2];
1856: int k = 0;
1857: for (int i = 0; i < l; i++) {
1858: int c = CharacterCode.chrCharToSJIS[s.charAt (i)];
1859: if (0x00ff < c) {
1860: b[k++] = (byte) (c >> 8);
1861: }
1862: b[k++] = (byte) c;
1863: }
1864: if (trmRowToCol[0] == 1) {
1865: int row = 0;
1866: int col = 1;
1867: trmConnectionArray[trmCols * row + col - 1].row2colQueue.write (b, 0, k);
1868: } else if (0 < trmColToRow[0]) {
1869: int row = trmColToRow[0];
1870: int col = 0;
1871: trmConnectionArray[trmCols * row + col - 1].col2rowQueue.write (b, 0, k);
1872: }
1873: }
1874:
1875:
1876:
1877:
1878:
1879: public static void trmSendFile () {
1880: if (trmSendDialog == null) {
1881: ActionListener listener = new ActionListener () {
1882: @Override public void actionPerformed (ActionEvent ae) {
1883: switch (ae.getActionCommand ()) {
1884: case JFileChooser.APPROVE_SELECTION:
1885: case "Send":
1886: trmSendDialog.setVisible (false);
1887: File file = trmSendFileChooser.getSelectedFile ();
1888: if (file != null) {
1889: trmSendThread = new SendThread (file);
1890: trmSendThread.start ();
1891: }
1892: break;
1893: case JFileChooser.CANCEL_SELECTION:
1894: case "Cancel":
1895: trmSendDialog.setVisible (false);
1896: break;
1897: }
1898: }
1899: };
1900: trmSendFileChooser = new JFileChooser (new File ("a.txt"));
1901: trmSendFileChooser.setMultiSelectionEnabled (false);
1902: trmSendFileChooser.setControlButtonsAreShown (false);
1903: trmSendFileChooser.addActionListener (listener);
1904: trmSendDialog =
1905: Multilingual.mlnTitle (
1906: ComponentFactory.createModalDialog (
1907: trmFrame,
1908: "Send file",
1909: ComponentFactory.createBorderPanel (
1910: 0, 0,
1911: ComponentFactory.createVerticalBox (
1912: trmSendFileChooser,
1913: ComponentFactory.createHorizontalBox (
1914: Box.createHorizontalStrut (12),
1915: Box.createHorizontalGlue (),
1916: Multilingual.mlnText (
1917: ComponentFactory.createLabel (
1918: "Prepare COMMAND.X with CTTY AUX"),
1919: "ja", "COMMAND.X を CTTY AUX で準備して"),
1920: Box.createHorizontalStrut (12),
1921: Multilingual.mlnText (
1922: ComponentFactory.createButton ("Send", KeyEvent.VK_S, listener),
1923: "ja", "送信"),
1924: Box.createHorizontalStrut (12),
1925: Multilingual.mlnText (
1926: ComponentFactory.createButton ("Cancel", KeyEvent.VK_C, listener),
1927: "ja", "キャンセル"),
1928: Box.createHorizontalStrut (12)
1929: ),
1930: Box.createVerticalStrut (12)
1931: )
1932: )
1933: ),
1934: "ja", "ファイル送信");
1935: }
1936: XEiJ.pnlExitFullScreen (true);
1937: trmSendDialog.setVisible (true);
1938: }
1939:
1940:
1941:
1942:
1943:
1944:
1945:
1946: static class SendThread extends Thread {
1947: File file;
1948: SendThread (File file) {
1949: this.file = file;
1950: }
1951: @Override public void run () {
1952: trmSendProcess (file);
1953: }
1954: }
1955:
1956:
1957:
1958: static byte[] load (File file) {
1959: if (!file.isFile ()) {
1960: return null;
1961: }
1962: int len = (int) file.length ();
1963: if (len == 0) {
1964: return null;
1965: }
1966: byte[] buf = new byte[len];
1967: try (BufferedInputStream bis = new BufferedInputStream (new FileInputStream (file))) {
1968: if (bis.read (buf) != len) {
1969: return null;
1970: }
1971: } catch (IOException ioe) {
1972: return null;
1973: }
1974: return buf;
1975: }
1976:
1977:
1978:
1979: static class BitWriter {
1980:
1981: byte[] buffer;
1982: int byteIndex;
1983: int bitIndex;
1984: int bitCount;
1985:
1986:
1987:
1988: BitWriter () {
1989: buffer = new byte[16];
1990: byteIndex = 0;
1991: bitIndex = -1;
1992: bitCount = 0;
1993: }
1994:
1995:
1996:
1997:
1998: void writeByte (int data) {
1999: if (byteIndex == buffer.length) {
2000: byte[] temporary = new byte[byteIndex * 2];
2001: System.arraycopy (buffer, 0,
2002: temporary, 0,
2003: byteIndex);
2004: buffer = temporary;
2005: }
2006: buffer[byteIndex++] = (byte) data;
2007: }
2008:
2009:
2010:
2011:
2012:
2013: void writeBits (int width, int data) {
2014: while (width != 0) {
2015: if (bitCount == 0) {
2016: if (byteIndex == buffer.length) {
2017: byte[] temporary = new byte[byteIndex * 2];
2018: System.arraycopy (buffer, 0,
2019: temporary, 0,
2020: byteIndex);
2021: buffer = temporary;
2022: }
2023: bitIndex = byteIndex;
2024: bitCount = 8;
2025: buffer[byteIndex++] = 0;
2026: }
2027: data &= (1 << width) - 1;
2028: int n = Math.min (bitCount, width);
2029: bitCount -= n;
2030: width -= n;
2031: buffer[bitIndex] |= (byte) ((data >>> width) << bitCount);
2032: }
2033: }
2034:
2035:
2036:
2037: byte[] getBuffer () {
2038: return buffer;
2039: }
2040:
2041:
2042:
2043: int getLength () {
2044: return byteIndex;
2045: }
2046:
2047: }
2048:
2049: static class DIC {
2050: int ptr;
2051: int len;
2052: }
2053:
2054:
2055:
2056:
2057:
2058: static byte[] compress (byte[] inpbuf, int dicbit) {
2059: int dicsiz = 1 << dicbit;
2060:
2061: DIC[] dicbuf = new DIC[dicsiz];
2062: for (int pag = 0; pag < dicsiz; pag++) {
2063: dicbuf[pag] = new DIC ();
2064: dicbuf[pag].ptr = 0;
2065: dicbuf[pag].len = 0;
2066: }
2067: int dicent = 0;
2068:
2069: int inplen = inpbuf.length;
2070: BitWriter bw = new BitWriter ();
2071: bw.writeBits (24, inplen);
2072:
2073: bw.writeBits (4, dicbit);
2074:
2075: int inpptr = 0;
2076: while (inpptr < inplen) {
2077:
2078: int dicpag = -1;
2079: int dicptr = -1;
2080: int diclen = 0;
2081: int fstchr = inpbuf[inpptr] & 255;
2082: for (int pag = 0; pag < dicsiz; pag++) {
2083: int len = dicbuf[pag].len;
2084: if (diclen < len &&
2085: inpptr + len + 1 <= inplen) {
2086: int ptr = dicbuf[pag].ptr;
2087: cmp:
2088: if (fstchr == (inpbuf[ptr] & 255)) {
2089: for (int i = 1; i < len; i++) {
2090: if (inpbuf[inpptr + i] != inpbuf[ptr + i]) {
2091: break cmp;
2092: }
2093: }
2094: dicpag = pag;
2095: dicptr = ptr;
2096: diclen = len;
2097: }
2098: }
2099: }
2100: if (diclen == 0) {
2101: bw.writeBits (1, 0);
2102: } else {
2103: bw.writeBits (1, 1);
2104: bw.writeBits (dicbit, dicpag);
2105: }
2106: int chr = inpbuf[inpptr + diclen] & 255;
2107:
2108: bw.writeByte (chr);
2109:
2110: diclen++;
2111:
2112: dicbuf[dicent].ptr = inpptr;
2113: dicbuf[dicent].len = diclen;
2114: dicent++;
2115: if (dicent == dicsiz) {
2116: dicent = 0;
2117: }
2118:
2119: inpptr += diclen;
2120: }
2121:
2122: byte[] outbuf = bw.getBuffer ();
2123: int outlen = bw.getLength ();
2124: if (outbuf.length != outlen) {
2125: byte[] tmpbuf = new byte[outlen];
2126: System.arraycopy (outbuf, 0, tmpbuf, 0, outlen);
2127: outbuf = tmpbuf;
2128: }
2129: return outbuf;
2130: }
2131:
2132:
2133:
2134:
2135:
2136:
2137:
2138:
2139:
2140:
2141: public static byte[] encode (byte[] src) {
2142: int r = src.length;
2143: int q = r / 62;
2144: r -= 62 * q;
2145: if (r != 0) {
2146: r = ((r + 2 + 3) & -4) - 2;
2147: if (src.length < 62 * q + r) {
2148: byte[] tmp = new byte[62 * q + r];
2149: System.arraycopy (src, 0, tmp, 0, src.length);
2150: src = tmp;
2151: }
2152: }
2153: byte[] dst = new byte[64 * q + (r == 0 ? 0 : r + 2)];
2154: int[] w = new int[16];
2155: for (int i = 0; 64 * i < dst.length; i++) {
2156: int n = Math.min (64, dst.length - 64 * i) / 4;
2157:
2158: for (int k = 0; k < n - 1; k++) {
2159: w[k] = ((src[62 * i + 4 * k + 0] & 255) << 24 |
2160: (src[62 * i + 4 * k + 1] & 255) << 16 |
2161: (src[62 * i + 4 * k + 2] & 255) << 8 |
2162: (src[62 * i + 4 * k + 3] & 255));
2163: }
2164: w[n - 1] = ((src[62 * i + 4 * (n - 1) + 0] & 255) << 24 |
2165: (src[62 * i + 4 * (n - 1) + 1] & 255) << 16);
2166:
2167: for (int k = 0; k < n; k++) {
2168: if ((w[k] & 0x80000000) != 0) {
2169: w[k] &= 0x7fffffff;
2170: w[n - 1] |= 1 << (15 - k);
2171: }
2172: }
2173:
2174: for (int k = 0; k < n; k++) {
2175: int t3 = w[k];
2176: int t2 = t3 / 224;
2177: t3 -= 224 * t2;
2178: int t1 = t2 / 224;
2179: t2 -= 224 * t1;
2180: int t0 = t1 / 224;
2181: t1 -= 224 * t0;
2182: dst[64 * i + 4 * k + 0] = (byte) (32 + t0);
2183: dst[64 * i + 4 * k + 1] = (byte) (32 + t1);
2184: dst[64 * i + 4 * k + 2] = (byte) (32 + t2);
2185: dst[64 * i + 4 * k + 3] = (byte) (32 + t3);
2186: }
2187: }
2188: return dst;
2189: }
2190:
2191:
2192:
2193: public static void trmSendProcess (File file) {
2194:
2195: byte[] fileData = load (file);
2196: if (fileData == null) {
2197: return;
2198: }
2199: if (0x00ffff00 < fileData.length) {
2200: return;
2201: }
2202:
2203:
2204:
2205: byte[] step3Data = new byte[adotr3.length +
2206: 24 +
2207: 4 +
2208: 4 +
2209: 4 +
2210: fileData.length];
2211: int index3 = 0;
2212:
2213: System.arraycopy (adotr3, 0,
2214: step3Data, index3,
2215: adotr3.length);
2216: index3 += adotr3.length;
2217:
2218:
2219:
2220:
2221:
2222: String name = file.getName ();
2223: {
2224: byte[] b = new byte[2 * name.length ()];
2225: int k = 0;
2226: int p = -1;
2227: for (int i = 0; i < name.length (); i++) {
2228: int c = CharacterCode.chrCharToSJIS[name.charAt (i)];
2229: if (c == 0) {
2230: return;
2231: }
2232: if (c <= ' ' || c == ':' || c == '*' || c == '?' ||
2233: c == '\\' || c == '/' || (c == '-' && k == 0) ||
2234: c == '"' || c == '\'' || c == '+' || c == ';' ||
2235: c == '<' || c == '=' || c == '>' ||
2236: c == '[' || c == ']' || c == '|') {
2237: return;
2238: }
2239: if (c == '.') {
2240: if (p < 0) {
2241: p = k;
2242: } else {
2243: return;
2244: }
2245: }
2246: if (0x00ff < c) {
2247: b[k++] = (byte) (c >> 8);
2248: }
2249: b[k++] = (byte) c;
2250: if (p < 0 ? 18 < k : p + 1 + 3 < k) {
2251: return;
2252: }
2253: }
2254: for (int i = 0; i < k; i++) {
2255: step3Data[index3++] = b[i];
2256: }
2257: for (int i = k; i < 24; i++) {
2258: step3Data[index3++] = 0;
2259: }
2260: }
2261:
2262: {
2263: long dttm = DnT.dntDttmCmil (file.lastModified () + RP5C15.rtcCmilGap);
2264: int date = DnT.dntYearDttm (dttm) - 1980 << 9 | DnT.dntMontDttm (dttm) << 5 | DnT.dntMdayDttm (dttm);
2265: int time = DnT.dntHourDttm (dttm) << 11 | DnT.dntMinuDttm (dttm) << 5 | DnT.dntSecoDttm (dttm) >> 1;
2266: step3Data[index3++] = (byte) (date >> 8);
2267: step3Data[index3++] = (byte) date;
2268: step3Data[index3++] = (byte) (time >> 8);
2269: step3Data[index3++] = (byte) time;
2270: }
2271:
2272: {
2273: CRC32 crc32 = new CRC32 ();
2274: crc32.update (fileData, 0, fileData.length);
2275: int t = (int) crc32.getValue ();
2276: step3Data[index3++] = (byte) (t >> 24);
2277: step3Data[index3++] = (byte) (t >> 16);
2278: step3Data[index3++] = (byte) (t >> 8);
2279: step3Data[index3++] = (byte) (t);
2280: }
2281:
2282: {
2283: int t = fileData.length;
2284: step3Data[index3++] = (byte) (t >> 24);
2285: step3Data[index3++] = (byte) (t >> 16);
2286: step3Data[index3++] = (byte) (t >> 8);
2287: step3Data[index3++] = (byte) (t);
2288: }
2289:
2290: System.arraycopy (fileData, 0,
2291: step3Data, index3,
2292: fileData.length);
2293: index3 += fileData.length;
2294:
2295:
2296:
2297: byte[] step3DataCompressed = null;
2298: int dicbit = 0;
2299:
2300:
2301:
2302:
2303: for (int i = 8; i <= 10; i++) {
2304: byte[] t = compress (step3Data, i);
2305: if (step3DataCompressed == null ||
2306: t.length < step3DataCompressed.length) {
2307: step3DataCompressed = t;
2308: dicbit = i;
2309: }
2310: }
2311: byte[] step2Data = new byte[adotr2.length + step3DataCompressed.length];
2312: int index2 = 0;
2313:
2314: System.arraycopy (adotr2, 0,
2315: step2Data, index2,
2316: adotr2.length);
2317: index2 += adotr2.length;
2318:
2319: System.arraycopy (step3DataCompressed, 0,
2320: step2Data, index2,
2321: step3DataCompressed.length);
2322: index2 += step3DataCompressed.length;
2323:
2324:
2325:
2326: byte[] step3DataEncoded = encode (step3Data);
2327: byte[] step2DataEncoded = encode (step2Data);
2328: byte[] step1Data;
2329: if (step3DataEncoded.length <= step2DataEncoded.length) {
2330: step1Data = new byte[adotr1.length + step3DataEncoded.length + 1];
2331: int index1 = 0;
2332: System.arraycopy (adotr1, 0,
2333: step1Data, index1,
2334: adotr1.length);
2335: index1 += adotr1.length;
2336: System.arraycopy (step3DataEncoded, 0,
2337: step1Data, index1,
2338: step3DataEncoded.length);
2339: index1 += step3DataEncoded.length;
2340: step1Data[index1++] = 0x1a;
2341: if (false) {
2342: System.out.printf (" original: %d bytes (%.1f%%)\n",
2343: fileData.length,
2344: 100.0);
2345: System.out.printf (" generator concatenated: %d bytes (%.1f%%)\n",
2346: step3Data.length,
2347: 100.0 * (double) step3Data.length / (double) fileData.length);
2348: System.out.printf (" encoded: %d bytes (%.1f%%)\n",
2349: step3DataEncoded.length,
2350: 100.0 * (double) step3DataEncoded.length / (double) fileData.length);
2351: System.out.printf (" decoder concatenated: %d bytes (%.1f%%)\n",
2352: step1Data.length,
2353: 100.0 * (double) step1Data.length / (double) fileData.length);
2354: }
2355: } else {
2356: step1Data = new byte[adotr1.length + step2DataEncoded.length + 1];
2357: int index1 = 0;
2358: System.arraycopy (adotr1, 0,
2359: step1Data, index1,
2360: adotr1.length);
2361: index1 += adotr1.length;
2362: System.arraycopy (step2DataEncoded, 0,
2363: step1Data, index1,
2364: step2DataEncoded.length);
2365: index1 += step2DataEncoded.length;
2366: step1Data[index1++] = 0x1a;
2367: if (false) {
2368: System.out.printf (" original: %d bytes (%.1f%%)\n",
2369: fileData.length,
2370: 100.0);
2371: System.out.printf (" generator concatenated: %d bytes (%.1f%%)\n",
2372: step3Data.length,
2373: 100.0 * (double) step3Data.length / (double) fileData.length);
2374: System.out.printf (" compressed: %d bytes (%.1f%%) (%d bits dictionary)\n",
2375: step3DataCompressed.length,
2376: 100.0 * (double) step3DataCompressed.length / (double) fileData.length,
2377: dicbit);
2378: System.out.printf ("decompressor concatenated: %d bytes (%.1f%%)\n",
2379: step2Data.length,
2380: 100.0 * (double) step2Data.length / (double) fileData.length);
2381: System.out.printf (" encoded: %d bytes (%.1f%%)\n",
2382: step2DataEncoded.length,
2383: 100.0 * (double) step2DataEncoded.length / (double) fileData.length);
2384: System.out.printf (" decoder concatenated: %d bytes (%.1f%%)\n",
2385: step1Data.length,
2386: 100.0 * (double) step1Data.length / (double) fileData.length);
2387: }
2388: }
2389: if (false) {
2390: int l = step1Data.length;
2391: System.out.printf ("step1Data %d bytes\n", l);
2392: for (int i = 0; i < l; i++) {
2393: if ((i & 15) == 0) {
2394: System.out.printf ("%08x", i);
2395: }
2396: System.out.printf (" %02x", step1Data[i] & 255);
2397: if ((i & 15) == 15) {
2398: System.out.println ();
2399: }
2400: }
2401: if ((l & 15) != 0) {
2402: System.out.println ();
2403: }
2404: }
2405:
2406: trmSendString (String.format (
2407: "rem a.r/%s %d/%d %.1f%%\rcopy aux a.r\r",
2408: name, step1Data.length, fileData.length,
2409: 100.0 * (double) step1Data.length / (double) fileData.length));
2410: try {
2411: Thread.sleep (1000);
2412: } catch (InterruptedException ie) {
2413: }
2414: if (trmRowToCol[0] == 1) {
2415: int row = 0;
2416: int col = 1;
2417: trmConnectionArray[trmCols * row + col - 1].row2colQueue.write (step1Data, 0, step1Data.length);
2418: } else if (0 < trmColToRow[0]) {
2419: int row = trmColToRow[0];
2420: int col = 0;
2421: trmConnectionArray[trmCols * row + col - 1].col2rowQueue.write (step1Data, 0, step1Data.length);
2422: }
2423: try {
2424: Thread.sleep (1000);
2425: } catch (InterruptedException ie) {
2426: }
2427: trmSendString ("a.r\r");
2428: }
2429:
2430:
2431: public static final byte[] adotr1 = "B\202G\373 h\324\211\304|\377\374(B\"Kx@\330\213B\200\320\214\220\204\223\201\300\201\330\200$I\"<\337\337\337\340\322\233B\200v( @\347\210\220\210\353\210\341\231\320\201Q\301\220\201\342Kd\354\"\300\267\304e\3322!B\200\322A\342\220\321\232\265\311e\364\267\314e\266A\372\377\370t\370N\360\" BAVAp\254NO".getBytes (XEiJ.ISO_8859_1);
2432:
2433: public static final byte[] adotr2 = "p\1\320\211\300|\377\376\"@|\0~\0E\372\0\372r\30a\0\0\322&\0\326\211p\1\320\203\300|\377\376*@r\4a\0\0\276g\0\0\246\30\0z\b\351\255\332\215\377\201\"\5\222\200/\1/\0\377JP\217J\200ktp\0 M \300 \300\261\305e\370(I,M\265\311dvr\1a\0\0\206f\b,\314p\1,\300`0\22\4av\347\210 u\b\0 5\b\4gVR\200\"\0\322\214\262\203bL,\314,\300U\200H@H@\30\330Q\310\377\374H@Q\310\377\364\30\332\275\305f\2,M\271\303e\260p\372N\373\2\16r\3p\254NO IN\320\377\t\377\0Hz\0\4`\366out of memory\r\n\0Hz\0\4`\340data error\r\n\0\0p\0J\7f\4\34\32P\7\24\1\264\7c\2\24\7\20\6\345\250\345.\236\2\222\2f\344\340\210Nu".getBytes (XEiJ.ISO_8859_1);
2434:
2435: public static final byte[] adotr3 = "E\372\1\2&*\0 G\352\0$ \13\320\203R\200\300|\377\376(@K\354\4\0\377\201\"\r\222\200/\1/\0\377JP\217J\200k\0\0\230 Lr\0 \1t\7\342\210d\6\n\200\355\270\203 Q\312\377\364 \300R\1d\350\"Lp\0\"\3 KF\200`\22HAt\0\24\30\261\2\340\210\345J$1(\0\265\200Q\311\377\356HAQ\311\377\346F\200\260\252\0\34f`?<\0 /\n\377<\\\217J\200kd/\3/\13?\0\377@\"\0/j\0\30\0\2\377\207\377>O\357\0\n\262\203g\b/\n\377AX\217`@/\n\377\tHz\0\6\377\t\377\0 created\r\n\0\0Hz\0\4`\352out of memory\r\n\0Hz\0\4`\324crc error\r\n\0Hz\0\4`\302cannot write\r\n\0\0".getBytes (XEiJ.ISO_8859_1);
2436:
2437: }