Z8530.java
     1: //========================================================================================
     2: //  Z8530.java
     3: //    en:SCC -- Serial Communication Controller
     4: //    ja:SCC -- シリアルコミュニケーションコントローラ
     5: //  Copyright (C) 2003-2024 Makoto Kamada
     6: //
     7: //  This file is part of the XEiJ (X68000 Emulator in Java).
     8: //  You can use, modify and redistribute the XEiJ if the conditions are met.
     9: //  Read the XEiJ License for more details.
    10: //  https://stdkmd.net/xeij/
    11: //========================================================================================
    12: 
    13: //----------------------------------------------------------------------------------------
    14: //  マウス
    15: //    マウスイベントとマウスモーションイベントで取得したデータを返す
    16: //  RS-232C
    17: //    ターミナルに接続
    18: //----------------------------------------------------------------------------------------
    19: 
    20: package xeij;
    21: 
    22: import java.awt.event.*;  //ActionEvent,ActionListener,ComponentAdapter,ComponentEvent,ComponentListener,FocusAdapter,FocusEvent,FocusListener,InputEvent,KeyAdapter,KeyEvent,KeyListener,MouseAdapter,MouseEvent,MouseListener,MouseMotionAdapter,MouseWheelEvent,WindowAdapter,WindowEvent,WindowListener,WindowStateListener
    23: import java.lang.*;  //Boolean,Character,Class,Comparable,Double,Exception,Float,IllegalArgumentException,Integer,Long,Math,Number,Object,Runnable,SecurityException,String,StringBuilder,System
    24: import java.util.*;  //ArrayList,Arrays,Calendar,GregorianCalendar,HashMap,Map,Map.Entry,Timer,TimerTask,TreeMap
    25: import javax.swing.*;  //AbstractButton,AbstractSpinnerModel,Box,ButtonGroup,DefaultListModel,ImageIcon,JApplet,JButton,JCheckBox,JCheckBoxMenuItem,JComponent,JDialog,JFileChooser,JFrame,JLabel,JList,JMenu,JMenuBar,JMenuItem,JPanel,JRadioButton,JScrollPane,JSpinner,JTextArea,JTextField,JTextPane,JViewport,ScrollPaneConstants,SpinnerListModel,SpinnerNumberModel,SwingConstants,SwingUtilities,UIManager,UIDefaults,UnsupportedLookAndFeelException
    26: import javax.swing.event.*;  //CaretEvent,CaretListener,ChangeEvent,ChangeListener,DocumentEvent,DocumentListener,ListSelectionListener
    27: 
    28: public class Z8530 {
    29: 
    30:   public static final boolean SCC_DEBUG_ON = false;
    31:   public static int sccDebugOn;  //1=Port0B,2=Port1A,4=Interrupt
    32:   public static JMenu sccDebugMenu;
    33: 
    34:   public static double sccFreq = 5000000.0;  //SCCの動作周波数
    35: 
    36:   //ポート
    37:   public static final int SCC_0B_COMMAND = 0x00e98001;
    38:   public static final int SCC_0B_DATA    = 0x00e98003;
    39:   public static final int SCC_1A_COMMAND = 0x00e98005;
    40:   public static final int SCC_1A_DATA    = 0x00e98007;
    41: 
    42:   //割り込み
    43:   //  ベクタ
    44:   //    0  ポート0B送信バッファ空(マウス送信)
    45:   //    1  ポート0B外部/ステータス変化
    46:   //    2  ポート0B受信バッファフル(マウス受信)
    47:   //    3  ポート0B特別受信条件
    48:   //    4  ポート1A送信バッファ空(RS-232C送信)
    49:   //    5  ポート1A外部/ステータス変化
    50:   //    6  ポート1A受信バッファフル(RS-232C受信)
    51:   //    7  ポート1A特別受信条件
    52:   //  マスク
    53:   //    0x80  常に0
    54:   //    0x40  常に0
    55:   //    0x20  ポート1A受信バッファフル(RS-232C受信)
    56:   //    0x10  ポート1A送信バッファ空(RS-232C送信)
    57:   //    0x08  ポート1A外部/ステータス変化
    58:   //    0x04  ポート0B受信バッファフル(マウス受信)
    59:   //    0x02  ポート0B送信バッファ空(マウス送信)
    60:   //    0x01  ポート0B外部/ステータス変化
    61:   //  優先順位
    62:   //    高い  1A受信バッファフル(RS-232C受信)
    63:   //          1A送信バッファ空(RS-232C送信)
    64:   //          1A外部/ステータス変化
    65:   //          0B受信バッファフル(マウス受信)
    66:   //          0B送信バッファ空(マウス送信)
    67:   //    低い  0B外部/ステータス変化
    68:   //!!! マウス送信、外部/ステータス変化、特別受信条件の割り込みは未実装
    69:   public static int sccInterruptVector;  //非修飾ベクタ。WR2
    70:   public static int sccVectorInclude;  //WR9&0x11
    71:   //  マウス受信割り込み
    72:   public static final int SCC_0B_RECEIVE_VECTOR = 2;
    73:   public static final int SCC_0B_RECEIVE_MASK = 0x04;
    74:   public static int scc0bReceiveMask;  //マスク
    75:   public static int scc0bReceiveRR3;  //RR3のペンディングビット。割り込み発生でセット
    76:   public static int scc0bReceiveRequest;  //リクエスト。割り込み発生でセット、受け付けでクリア
    77:   public static int scc0bReceiveVector;  //修飾ベクタ
    78:   //  RS-232C受信割り込み
    79:   public static final int SCC_1A_RECEIVE_VECTOR = 6;
    80:   public static final int SCC_1A_RECEIVE_MASK = 0x20;
    81:   public static int scc1aReceiveMask;  //マスク
    82:   public static int scc1aReceiveRR3;  //RR3のペンディングビット。割り込み発生でセット、IUSリセットでクリア
    83:   public static int scc1aReceiveRequest;  //リクエスト。割り込み発生でセット、受け付けでクリア
    84:   public static int scc1aReceiveVector;  //修飾ベクタ
    85:   //  RS-232C送信割り込み
    86:   public static final int SCC_1A_SEND_VECTOR = 4;
    87:   public static final int SCC_1A_SEND_MASK = 0x10;
    88:   public static int scc1aSendMask;  //マスク
    89:   public static int scc1aSendRR3;  //RR3のペンディングビット。割り込み発生でセット
    90:   public static int scc1aSendRequest;  //リクエスト。割り込み発生でセット、受け付けでクリア
    91:   public static int scc1aSendVector;  //修飾ベクタ
    92: 
    93:   //ポート0B マウス
    94:   public static int scc0bRegisterNumber;
    95:   public static int scc0bRts;  //RTS(0または1)
    96:   public static int scc0bBaudRateGen;  //WR13<<8|WR12
    97:   public static int scc0bInputCounter;  //マウスデータのカウンタ。0~2
    98:   public static int scc0bData1;
    99:   public static int scc0bData2;
   100: 
   101:   public static final boolean SCC_FSX_MOUSE = true;  //true=SX-Windowをシームレスにする
   102:   public static int sccFSXMouseHook;  //FSX.Xのマウス受信データ処理ルーチンのアドレス
   103:   public static int sccFSXMouseWork;  //FSX.Xのマウスワークのアドレス
   104: 
   105:   //ポート1A RS-232C
   106:   public static final int SCC_1A_INPUT_BITS = 16;
   107:   public static final int SCC_1A_INPUT_SIZE = 1 << SCC_1A_INPUT_BITS;
   108:   public static final int SCC_1A_INPUT_MASK = SCC_1A_INPUT_SIZE - 1;
   109:   public static int scc1aRegisterNumber;
   110:   public static final int[] scc1aInputBuffer = new int[SCC_1A_INPUT_SIZE];  //RS-232C受信バッファ。データはゼロ拡張済み
   111:   public static int scc1aInputRead;  //RS-232C受信バッファから次に読み出すデータの位置。read==writeのときバッファエンプティ
   112:   public static int scc1aInputWrite;  //RS-232C受信バッファに次に書き込むデータの位置。(write+1&SCC_1A_INPUT_MASK)==readのときバッファフル
   113:   //  ボーレート
   114:   public static int scc1aBRGEnable;  //WR14のbit0。true=ボーレートジェネレータ動作
   115:   public static int scc1aClockModeShift;  //WR4のbit6-7。0=2^0,1=2^4,2=2^5,3=2^6
   116:   public static int scc1aBaudRateGen;  //WR13<<8|WR12
   117:   public static long scc1aInterval;  //転送間隔(XEiJ.TMR_FREQ単位)
   118:   //  通信設定
   119:   public static int scc1aRxBits;  //WR3のbit7-6。00=5bit,01=7bit,10=6bit,11=8bit。RR8の未使用ビットは1
   120:   public static int scc1aRxEnable;  //WR3のbit0。1=enable
   121:   public static int scc1aStop;  //WR4のbit3-2。01=s1,10=s1.5,11=s2
   122:   public static int scc1aParity;  //WR4のbit1-0。x0=pn,01=po,11=pe
   123:   public static int scc1aTxBits;  //WR5のbit6-5。00=1-5bit,01=7bit,10=6bit,11=8bit。1-5bitのとき1111000x,111000xx,11000xxx,1000xxxx,000xxxxx
   124:   public static int scc1aTxEnable;  //WR5のbit3。1=enable
   125: 
   126: 
   127:   //sccInit ()
   128:   //  初期化
   129:   public static void sccInit () {
   130: 
   131:     sccFreq = Settings.sgsGetInt ("sccfreq") == 7500000 ? 7500000.0 : 5000000.0;
   132: 
   133:     if (SCC_DEBUG_ON) {
   134:       sccDebugOn = 2;
   135:       sccDebugMenu = 
   136:         ComponentFactory.createMenu (
   137:           "SCC",
   138:           ComponentFactory.createCheckBoxMenuItem ((sccDebugOn & 1) != 0, "Port 0B", new ActionListener () {
   139:             @Override public void actionPerformed (ActionEvent ae) {
   140:               sccDebugOn = (sccDebugOn & ~1) | (((JCheckBoxMenuItem) ae.getSource ()).isSelected () ? 1 : 0);
   141:             }
   142:           }),
   143:           ComponentFactory.createCheckBoxMenuItem ((sccDebugOn & 2) != 0, "Port 1A", new ActionListener () {
   144:             @Override public void actionPerformed (ActionEvent ae) {
   145:               sccDebugOn = (sccDebugOn & ~2) | (((JCheckBoxMenuItem) ae.getSource ()).isSelected () ? 2 : 0);
   146:             }
   147:           }),
   148:           ComponentFactory.createCheckBoxMenuItem ((sccDebugOn & 4) != 0, "Interrupt", new ActionListener () {
   149:             @Override public void actionPerformed (ActionEvent ae) {
   150:               sccDebugOn = (sccDebugOn & ~4) | (((JCheckBoxMenuItem) ae.getSource ()).isSelected () ? 4 : 0);
   151:             }
   152:           })
   153:           );
   154:     }
   155: 
   156:     //scc1aInputBuffer = new int[SCC_1A_INPUT_SIZE];
   157: 
   158:     sccReset ();
   159: 
   160:   }  //sccInit()
   161: 
   162: 
   163:   //sccTini ()
   164:   //  後始末
   165:   public static void sccTini () {
   166:     Settings.sgsPutInt ("sccfreq", (int) sccFreq);
   167:   }
   168: 
   169: 
   170:   //リセット
   171:   public static void sccReset () {
   172:     //割り込み
   173:     sccInterruptVector = 0x00;
   174:     sccVectorInclude = 0x00;
   175:     scc0bReceiveMask = 0;
   176:     scc0bReceiveRR3 = 0;
   177:     scc0bReceiveRequest = 0;
   178:     scc0bReceiveVector = 0;
   179:     scc1aReceiveMask = 0;
   180:     scc1aReceiveRR3 = 0;
   181:     scc1aReceiveRequest = 0;
   182:     scc1aReceiveVector = 0;
   183:     scc1aSendMask = 0;
   184:     scc1aSendRR3 = 0;
   185:     scc1aSendRequest = 0;
   186:     scc1aSendVector = 0;
   187:     //マウス
   188:     scc0bRegisterNumber = 0;
   189:     scc0bRts = 0;
   190:     scc0bBaudRateGen = 31;  //4800bps。(5000000/2/16)/4800-2=30.552。(5000000/2/16)/(31+2)=4734.848=4800*0.986
   191:     scc0bInputCounter = 0;
   192:     scc0bData1 = 0;
   193:     scc0bData2 = 0;
   194:     if (SCC_FSX_MOUSE) {
   195:       sccFSXMouseHook = 0;
   196:       sccFSXMouseWork = 0;
   197:     }
   198:     //RS-232C
   199:     scc1aRegisterNumber = 0;
   200:     Arrays.fill (scc1aInputBuffer, 0);
   201:     scc1aInputRead = 0;
   202:     scc1aInputWrite = 0;
   203:     scc1aRxBits = 3;  //b8
   204:     scc1aRxEnable = 0;
   205:     scc1aStop = 1;  //s1
   206:     scc1aParity = 0;  //pn
   207:     scc1aTxBits = 3;
   208:     scc1aTxEnable = 0;
   209:     scc1aBRGEnable = 0;
   210:     scc1aClockModeShift = 4;  //1/16
   211:     scc1aBaudRateGen = 14;  //9600bps
   212:     double rate = sccFreq / (double) ((scc1aBaudRateGen + 2) << (scc1aClockModeShift + 1));
   213:     double bits = (1.0 +  //start
   214:                    (scc1aRxBits == 0 ? 5.0 :
   215:                     scc1aRxBits == 1 ? 7.0 :
   216:                     scc1aRxBits == 2 ? 6.0 : 8.0) +  //data
   217:                    ((scc1aParity & 1) == 0 ? 0.0 : 1.0) +  //parity
   218:                    (scc1aStop == 0 ? 0.0 :
   219:                     scc1aStop == 1 ? 1.0 :
   220:                     scc1aStop == 2 ? 1.5 : 2.0));  //stop
   221:     double interval = bits / rate;
   222:     scc1aInterval = Math.round (interval * (double) XEiJ.TMR_FREQ);
   223:     //
   224:     RS232CTerminal.trmAUXReset ();
   225:   }  //sccReset()
   226: 
   227:   //割り込み受付
   228:   //  コアが割り込み要求を受け付けたときに呼び出す
   229:   //  割り込みベクタ番号を返す
   230:   //  割り込み要求を取り下げる場合は0を返す
   231:   //  オートベクタを使用するデバイスはオートベクタの番号を返すこと
   232:   public static int sccAcknowledge () {
   233:     int d = 0;
   234:     //優先順位は固定
   235:     if (scc1aReceiveRequest != 0) {  //1A受信バッファフル(RS-232C受信)
   236:       scc1aReceiveRequest = 0;
   237:       d = scc1aReceiveVector;
   238:     } else if (scc1aSendRequest != 0) {  //1A送信バッファ空(RS-232C送信)
   239:       scc1aSendRequest = 0;
   240:       d = scc1aSendVector;
   241:     } else if (scc0bReceiveRequest != 0) {  //0B受信バッファフル(マウス受信)
   242:       scc0bReceiveRequest = 0;
   243:       d = scc0bReceiveVector;
   244:     }
   245:     if (SCC_DEBUG_ON && (sccDebugOn & 4) != 0) {
   246:       System.out.printf ("%08x sccAcknowledge()=0x%02x\n", XEiJ.regPC0, d);
   247:     }
   248:     return d;
   249:   }  //sccAcknowledge()
   250: 
   251:   //割り込み終了
   252:   //  コアが割り込み処理を終了したときに呼び出す
   253:   //  まだ処理されていない割り込みが残っていたら再度割り込み要求を出す
   254:   public static void sccDone () {
   255:     if (SCC_DEBUG_ON && (sccDebugOn & 4) != 0) {
   256:       System.out.printf ("%08x sccDone()\n", XEiJ.regPC0);
   257:     }
   258:     if ((scc1aReceiveRequest | scc1aSendRequest | scc0bReceiveRequest) != 0) {
   259:       XEiJ.mpuIRR |= XEiJ.MPU_SCC_INTERRUPT_MASK;
   260:     }
   261:   }  //sccDone()
   262: 
   263:   //sccUpdateVector ()
   264:   //  scc0bReceiveVector,scc1aReceiveVector,scc1aSendVectorを更新する
   265:   //  sccInterruptVector,sccVectorIncludeを更新したら呼び出す
   266:   public static void sccUpdateVector () {
   267:     if (sccVectorInclude == 0x00) {  //(WR9&0x01)==0x00
   268:       scc0bReceiveVector = sccInterruptVector;
   269:       scc1aReceiveVector = sccInterruptVector;
   270:       scc1aSendVector    = sccInterruptVector;
   271:     } else if (sccVectorInclude == 0x01) {  //(WR9&0x11)==0x01
   272:       int t = sccInterruptVector & 0b11110001;
   273:       scc0bReceiveVector = t | SCC_0B_RECEIVE_VECTOR << 1;
   274:       scc1aReceiveVector = t | SCC_1A_RECEIVE_VECTOR << 1;
   275:       scc1aSendVector    = t | SCC_1A_SEND_VECTOR << 1;
   276:     } else {  //(WR9&0x11)==0x11
   277:       int t = sccInterruptVector & 0b10001111;
   278:       scc0bReceiveVector = t | SCC_0B_RECEIVE_VECTOR << 4;
   279:       scc1aReceiveVector = t | SCC_1A_RECEIVE_VECTOR << 4;
   280:       scc1aSendVector    = t | SCC_1A_SEND_VECTOR << 4;
   281:     }
   282:     if (SCC_DEBUG_ON && (sccDebugOn & 4) != 0) {
   283:       System.out.printf ("scc0bReceiveVector=0x%02x\n", scc0bReceiveVector);
   284:       System.out.printf ("scc1aReceiveVector=0x%02x\n", scc1aReceiveVector);
   285:       System.out.printf ("scc1aSendVector=0x%02x\n", scc1aSendVector);
   286:     }
   287:   }  //sccUpdateVector()
   288: 
   289:   //d = sccReadByte (a, peek)
   290:   //  リードバイト
   291:   public static int sccReadByte (int a, boolean peek) {
   292:     XEiJ.mpuClockTime += XEiJ.busWaitTime.scc;
   293:     int d = 0;
   294:     switch (a & 7) {
   295:       //------------------------------------------------
   296:     case SCC_0B_COMMAND & 7:  //ポート0Bコマンド読み出し
   297:       switch (scc0bRegisterNumber) {
   298:       case 0:  //RR0
   299:         //  0x80  ブレークまたはアボート
   300:         //  0x40  送信アンダーラン
   301:         //  0x20  CTS(0=送信禁止,1=送信許可)
   302:         //  0x10  SYNC
   303:         //  0x08  DCD
   304:         //  0x04  送信バッファ空
   305:         //  0x02  ボーレートカウント0
   306:         //  0x01  受信バッファフル
   307:         d = scc0bInputCounter < 3 ? 0x25 : 0x24;
   308:         break;
   309:       case 2:  //RR2
   310:         //修飾割り込みベクタ
   311:         //  ポート0BのRR2はWR2に設定したベクタを割り込み要求で加工して返す
   312:         d = (scc1aReceiveRequest != 0 ? scc1aReceiveVector :  //1A受信バッファフル(RS-232C受信)
   313:              scc1aSendRequest != 0 ? scc1aSendVector :  //1A送信バッファ空(RS-232C送信)
   314:              scc0bReceiveRequest != 0 ? scc0bReceiveVector :  //0B受信バッファフル(マウス受信)
   315:              sccInterruptVector);
   316:         break;
   317:       case 3:  //RR3
   318:         //ポート0BのRR3は常に0
   319:         //  ポート0Bの割り込みペンディングを見るときはポート1AのRR3を参照する
   320:         //d = 0;
   321:         break;
   322:       case 12:  //RR12
   323:         d = scc0bBaudRateGen & 0xff;
   324:         break;
   325:       case 13:  //RR13
   326:         d = scc0bBaudRateGen >> 8 & 0xff;
   327:         break;
   328:       default:
   329:         if (SCC_DEBUG_ON && sccDebugOn != 0) {
   330:           System.out.println ("unimplemented register");
   331:         }
   332:       }
   333:       if (peek) {
   334:         break;
   335:       }
   336:       scc0bRegisterNumber = 0;
   337:       break;
   338:       //------------------------------------------------
   339:     case SCC_0B_DATA & 7:  //ポート0Bデータ読み出し(マウス受信)
   340:       if (scc0bInputCounter == 0) {  //1バイト目
   341:         d = Mouse.musExtraData;
   342:         if (XEiJ.mpuClockTime < Mouse.musWheelReleaseTime) {
   343:           d |= Mouse.musWheelButton;
   344:         }
   345:         if (peek) {
   346:           break;
   347:         }
   348:         Mouse.musExtraData = Mouse.musData;
   349:         if (!Mouse.musOnScreen) {  //ホストのマウスカーソルがスクリーン上にない
   350:           //Mouse.musShow ();
   351:           if (Mouse.musCursorNumber != 1 && Mouse.musCursorAvailable) {
   352:             Mouse.musCursorNumber = 1;
   353:             XEiJ.pnlPanel.setCursor (Mouse.musCursorArray[1]);  //ホストのマウスカーソルを表示する
   354:           }
   355:           scc0bData1 = scc0bData2 = 0;
   356:         } else if (Mouse.musSeamlessOn) {  //シームレス
   357:           int on, dx, dy, coeff = 256;
   358:           if (XEiJ.currentMPU < Model.MPU_MC68LC040) {  //MMUなし
   359:             if (SCC_FSX_MOUSE &&
   360:                 sccFSXMouseHook != 0 &&  //FSX.Xが常駐している
   361:                 MainMemory.mmrRls (0x0938) == sccFSXMouseHook) {  //マウス受信データ処理ルーチンがFSX.Xを指している。SX-Windowが動作中
   362:               on = MainMemory.mmrRws (sccFSXMouseWork + 0x2e) == 0 ? 1 : 0;  //SX-Windowのマウスカーソルの表示状態。Obscureのときは表示されているとみなす
   363:               int xy = MainMemory.mmrRls (sccFSXMouseWork + 0x0a);
   364:               dx = (xy >> 16) - CRTC.crtR10TxXPort;  //SX-Windowのマウスカーソルの見かけのX座標
   365:               dy = (short) xy - CRTC.crtR11TxYPort;  //SX-Windowのマウスカーソルの見かけのY座標
   366:               coeff = MainMemory.mmrRwz (sccFSXMouseWork + 0x04);  //ポインタの移動量。係数*256
   367:             } else {  //SX-Windowが動作中ではない
   368:               on = MainMemory.mmrRbs (0x0aa2);  //IOCSのマウスカーソルの表示状態
   369:               int xy = MainMemory.mmrRls (0x0ace);
   370:               dx = xy >> 16;  //IOCSのマウスカーソルのX座標
   371:               dy = (short) xy;  //IOCSのマウスカーソルのY座標
   372:             }
   373:           } else {  //MMUあり
   374:             if (SCC_FSX_MOUSE &&
   375:                 sccFSXMouseHook != 0 &&  //FSX.Xが常駐している
   376:                 MC68060.mmuPeekLongData (0x0938, 1) == sccFSXMouseHook) {  //マウス受信データ処理ルーチンがFSX.Xを指している。SX-Windowが動作中
   377:               on = MC68060.mmuPeekWordSignData (sccFSXMouseWork + 0x2e, 1) == 0 ? 1 : 0;  //SX-Windowのマウスカーソルの表示状態。Obscureのときは表示されているとみなす
   378:               int xy = MC68060.mmuPeekLongData (sccFSXMouseWork + 0x0a, 1);
   379:               dx = (xy >> 16) - CRTC.crtR10TxXPort;  //SX-Windowのマウスカーソルの見かけのX座標
   380:               dy = (short) xy - CRTC.crtR11TxYPort;  //SX-Windowのマウスカーソルの見かけのY座標
   381:               coeff = MC68060.mmuPeekWordZeroData (sccFSXMouseWork + 0x04, 1);  //ポインタの移動量。係数*256
   382:             } else {  //SX-Windowが動作中ではない
   383:               on = MC68060.mmuPeekByteSignData (0x0aa2, 1);  //IOCSのマウスカーソルの表示状態
   384:               int xy = MC68060.mmuPeekLongData (0x0ace, 1);
   385:               dx = xy >> 16;  //IOCSのマウスカーソルのX座標
   386:               dy = (short) xy;  //IOCSのマウスカーソルのY座標
   387:             }
   388:           }
   389:           dx = Mouse.musScreenX - dx;  //X方向の移動量
   390:           dy = Mouse.musScreenY - dy;  //Y方向の移動量
   391:           if (Mouse.musEdgeAccelerationOn) {  //縁部加速を行う
   392:             final int range = 10;  //加速領域の幅
   393:             final int speed = 10;  //移動速度
   394:             if (Mouse.musScreenX < range) {
   395:               dx = -speed;  //左へ
   396:             } else if (XEiJ.pnlScreenWidth - range <= Mouse.musScreenX) {
   397:               dx = speed;  //右へ
   398:             }
   399:             if (Mouse.musScreenY < range) {
   400:               dy = -speed;  //上へ
   401:             } else if (XEiJ.pnlScreenHeight - range <= Mouse.musScreenY) {
   402:               dy = speed;  //下へ
   403:             }
   404:           }
   405:           if (on != 0) {  //X68000のマウスカーソルが表示されている
   406:             //Mouse.musHide ();
   407:             if (Mouse.musCursorNumber != 0 && Mouse.musCursorAvailable) {
   408:               Mouse.musCursorNumber = 0;
   409:               XEiJ.pnlPanel.setCursor (Mouse.musCursorArray[0]);  //ホストのマウスカーソルを消す
   410:             }
   411:           } else {  //X68000のマウスカーソルが表示されていない
   412:             //Mouse.musShow ();
   413:             if (Mouse.musCursorNumber != 1 && Mouse.musCursorAvailable) {
   414:               Mouse.musCursorNumber = 1;
   415:               XEiJ.pnlPanel.setCursor (Mouse.musCursorArray[1]);  //ホストのマウスカーソルを表示する
   416:             }
   417:           }
   418:           if (coeff != 256 && coeff != 0) {
   419:             //SX-Windowのポインタの移動量の補正
   420:             dx = (dx << 8) / coeff;
   421:             dy = (dy << 8) / coeff;
   422:           }
   423:           //  Mouse.MUS_DEACCELERATION_TABLEの値が127を越えることはないのでシームレスでオーバーフローフラグがセットされることはない
   424:           //  rbzで返すので負数のときのゼロ拡張を忘れないこと
   425:           scc0bData1 = (dx == 0 ? 0 : dx >= 0 ?
   426:                         Mouse.MUS_DEACCELERATION_TABLE[Math.min (1024, dx)] :
   427:                         -Mouse.MUS_DEACCELERATION_TABLE[Math.min (1024, -dx)] & 0xff);
   428:           scc0bData2 = (dy == 0 ? 0 : dy >= 0 ?
   429:                         Mouse.MUS_DEACCELERATION_TABLE[Math.min (1024, dy)] :
   430:                         -Mouse.MUS_DEACCELERATION_TABLE[Math.min (1024, -dy)] & 0xff);
   431:         } else if (!XEiJ.frmIsActive) {  //エクスクルーシブだがフォーカスがない
   432:           //Mouse.musShow ();
   433:           if (Mouse.musCursorNumber != 1 && Mouse.musCursorAvailable) {
   434:             Mouse.musCursorNumber = 1;
   435:             XEiJ.pnlPanel.setCursor (Mouse.musCursorArray[1]);  //ホストのマウスカーソルを表示する
   436:           }
   437:           scc0bData1 = scc0bData2 = 0;
   438:           Mouse.musExclusiveStart = true;  //フォーカスを得たときエクスクルーシブに切り替えた直後のように振る舞う
   439:         } else {  //エクスクルーシブ
   440:           //Mouse.musHide ();
   441:           if (Mouse.musCursorNumber != 0 && Mouse.musCursorAvailable) {
   442:             Mouse.musCursorNumber = 0;
   443:             XEiJ.pnlPanel.setCursor (Mouse.musCursorArray[0]);  //ホストのマウスカーソルを消す
   444:           }
   445:           int ox = XEiJ.pnlScreenX1 + (XEiJ.pnlZoomWidth >> 1);  //画面の中央
   446:           int oy = XEiJ.pnlScreenY1 + (XEiJ.pnlZoomHeight >> 1);
   447:           XEiJ.rbtRobot.mouseMove (XEiJ.pnlGlobalX + ox, XEiJ.pnlGlobalY + oy);  //マウスカーソルを画面の中央に戻す
   448:           int dx = Mouse.musPanelX - ox;
   449:           int dy = Mouse.musPanelY - oy;
   450:           if (Mouse.musExclusiveStart) {  //エクスクルーシブに切り替えた直後
   451:             //エクスクルーシブに切り替えた直後の1回だけ相対位置を無視する
   452:             //  エクスクルーシブに切り替える直前にマウスカーソルが画面の中央から離れていると切り替えた瞬間に画面の端に飛んでしまう
   453:             dx = 0;
   454:             dy = 0;
   455:             Mouse.musExclusiveStart = false;
   456:           }
   457:           //  上下左右のレスポンスが非対称になると気持ち悪いので冗長に書く
   458:           //  rbzで返すので負数のときのゼロ拡張を忘れないこと
   459:           if (dx != 0) {
   460:             if (dx >= 0) {
   461:               //dx = dx * Mouse.musSpeedRatioX + 32768 >> 16;
   462:               dx = dx * Mouse.musSpeedRatioX >> 16;
   463:               if (127 < dx) {
   464:                 d |= 0x10;
   465:                 dx = 127;
   466:               }
   467:             } else {
   468:               //dx = -(-dx * Mouse.musSpeedRatioX + 32768 >> 16);
   469:               dx = -(-dx * Mouse.musSpeedRatioX >> 16);
   470:               if (dx < -128) {
   471:                 d |= 0x20;
   472:                 dx = -128;
   473:               }
   474:               dx &= 0xff;
   475:             }
   476:           }
   477:           if (dy != 0) {
   478:             if (dy >= 0) {
   479:               //dy = dy * Mouse.musSpeedRatioY + 32768 >> 16;
   480:               dy = dy * Mouse.musSpeedRatioY >> 16;
   481:               if (127 < dy) {
   482:                 d |= 0x40;
   483:                 dy = 127;
   484:               }
   485:             } else {
   486:               //dy = -(-dy * Mouse.musSpeedRatioY + 32768 >> 16);
   487:               dy = -(-dy * Mouse.musSpeedRatioY >> 16);
   488:               if (dy < -128) {
   489:                 d |= 0x80;
   490:                 dy = -128;
   491:               }
   492:               dy &= 0xff;
   493:             }
   494:           }
   495:           scc0bData1 = dx;
   496:           scc0bData2 = dy;
   497:         }  //if シームレス else エクスクルーシブ
   498:         scc0bInputCounter = 1;
   499:       } else if (scc0bInputCounter == 1) {  //2バイト目
   500:         d = scc0bData1;
   501:         if (peek) {
   502:           break;
   503:         }
   504:         scc0bInputCounter = 2;
   505:       } else if (scc0bInputCounter == 2) {  //3バイト目
   506:         d = scc0bData2;
   507:         if (peek) {
   508:           break;
   509:         }
   510:         scc0bInputCounter = 3;
   511:       }
   512:       break;
   513:       //------------------------------------------------
   514:     case SCC_1A_COMMAND & 7:  //ポート1Aコマンド読み出し
   515:       switch (scc1aRegisterNumber) {
   516:       case 0:  //RR0
   517:         //  bit7  Break/Abort
   518:         //  bit6  Tx Underrun/EOM
   519:         //  bit5  0=/CTS is High  相手が受信バッファに余裕がないから送るのやめてと言っている
   520:         //        1=/CTS is Low   相手が受信バッファに余裕があるから送っていいよと言っている
   521:         //  bit4  Sync/Hunt
   522:         //  bit3  DCD
   523:         //  bit2  Tx Buffer Empty(1=空)
   524:         //  bit1  Zero Count
   525:         //  bit0  Rx Character Available
   526:         d = RS232CTerminal.trmAUXReadCommand ();
   527:         break;
   528:       case 2:  //RR2
   529:         //非修飾割り込みベクタ
   530:         //  ポート1AのRR2はWR2に設定したベクタをそのまま返す
   531:         d = sccInterruptVector;
   532:         break;
   533:       case 3:  //RR3
   534:         //割り込みペンディング
   535:         //  RR3リクエストからインサービスまでの間セットされている
   536:         //  許可されていない割り込みのビットはセットされない
   537:         d = scc1aReceiveRR3 | scc1aSendRR3 | scc0bReceiveRR3;
   538:         break;
   539:       case 12:  //RR12
   540:         d = scc1aBaudRateGen & 0xff;
   541:         break;
   542:       case 13:  //RR13
   543:         d = scc1aBaudRateGen >> 8 & 0xff;
   544:         break;
   545:       default:
   546:         if (SCC_DEBUG_ON && sccDebugOn != 0) {
   547:           System.out.println ("unimplemented register");
   548:         }
   549:       }
   550:       if (peek) {
   551:         break;
   552:       }
   553:       scc1aRegisterNumber = 0;
   554:       break;
   555:       //------------------------------------------------
   556:     case SCC_1A_DATA & 7:  //ポート1Aデータ読み出し(RS-232C受信)
   557:       d = RS232CTerminal.trmAUXReadData ();
   558:       break;
   559:       //------------------------------------------------
   560:     default:
   561:       d = 0xff;
   562:     }
   563:     if (SCC_DEBUG_ON && ((a & 4) == 0 ? (sccDebugOn & 1) != 0 : (sccDebugOn & 2) != 0)) {
   564:       System.out.printf ("%08x sccRead(0x%08x)=0x%02x\n", XEiJ.regPC0, a, d);
   565:     }
   566:     return d;
   567:   }  //sccReadByte
   568: 
   569: 
   570: 
   571:   //sccWriteByte (a, d)
   572:   //  ライトバイト
   573:   public static void sccWriteByte (int a, int d) {
   574:     XEiJ.mpuClockTime += XEiJ.busWaitTime.scc;
   575:     d &= 0xff;
   576:     if (SCC_DEBUG_ON && ((a & 4) == 0 ? (sccDebugOn & 1) != 0 : (sccDebugOn & 2) != 0)) {
   577:       System.out.printf ("%08x sccWrite(0x%08x,0x%02x)\n", XEiJ.regPC0, a, d);
   578:     }
   579:     switch (a & 7) {
   580:       //------------------------------------------------
   581:     case SCC_0B_COMMAND & 7:  //ポート0Bコマンド書き込み
   582:       switch (scc0bRegisterNumber) {
   583:       case 0:  //WR0
   584:         if ((d & 0xf0) == 0) {  //レジスタ選択
   585:           scc0bRegisterNumber = d;
   586:         } else if (d == 0x38) {  //IUSリセット。割り込み処理が終了し、次の割り込みを受け付ける
   587:           if (scc0bReceiveRR3 != 0) {
   588:             scc0bReceiveRR3 = 0;
   589:             if (scc0bInputCounter < 3) {  //3バイト受信するまで割り込み要求を続ける
   590:               if (scc0bReceiveMask != 0) {
   591:                 scc0bReceiveRR3 = SCC_0B_RECEIVE_MASK;
   592:                 scc0bReceiveRequest = SCC_0B_RECEIVE_MASK;
   593:                 XEiJ.mpuIRR |= XEiJ.MPU_SCC_INTERRUPT_MASK;
   594:               }
   595:             }
   596:           }
   597:         } else if (d == 0x10) {  //ステータス割り込みリセット
   598:         } else if (d == 0x30) {  //エラーリセット
   599:         } else if (d == 0x80) {  //送信CRCジェネレータリセット
   600:         } else {
   601:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   602:             System.out.println ("unimplemented command");
   603:           }
   604:         }
   605:         return;
   606:       case 1:  //WR1
   607:         scc0bReceiveMask = (d & 0x18) != 0 ? SCC_0B_RECEIVE_MASK : 0;
   608:         if ((d & 0xec) != 0x00) {
   609:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   610:             System.out.println ("unimplemented interrupt mode");
   611:           }
   612:         }
   613:         break;
   614:       case 2:  //WR2
   615:         sccInterruptVector = d;  //割り込みベクタ
   616:         if (SCC_DEBUG_ON && sccDebugOn != 0) {
   617:           System.out.printf ("sccInterruptVector=0x%02x\n", sccInterruptVector);
   618:         }
   619:         sccUpdateVector ();
   620:         break;
   621:       case 3:  //WR3
   622:         if (d == 0xc0) {  //受信禁止
   623:         } else if (d == 0xc1) {  //受信許可
   624:         } else {
   625:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   626:             System.out.println ("unimplemented receiver configuration");
   627:           }
   628:         }
   629:         break;
   630:       case 4:  //WR4
   631:         break;
   632:       case 5:  //WR5
   633:         //  0x80  DTR
   634:         //  0x60  ビット長(0x00=5bit,0x20=7bit,0x40=6bit,0x60=8bit)
   635:         //  0x10  ブレーク
   636:         //  0x08  送信許可
   637:         //  0x04  CRC-16
   638:         //  0x02  RTS
   639:         //  0x01  送信CRC
   640:         {
   641:           int rts = d >> 1 & 1;
   642:           if ((~scc0bRts & rts) != 0) {  //RTS=0→1。MSCTRL=H→Lとなってマウスに送信要求が出される
   643:             scc0bInputCounter = 0;
   644:             //マウスデータ受信開始
   645:             if (scc0bReceiveMask != 0) {
   646:               scc0bReceiveRR3 = SCC_0B_RECEIVE_MASK;
   647:               scc0bReceiveRequest = SCC_0B_RECEIVE_MASK;
   648:               XEiJ.mpuIRR |= XEiJ.MPU_SCC_INTERRUPT_MASK;
   649:             }
   650:           }
   651:           scc0bRts = rts;
   652:           if ((d & 0x75) == 0x60) {
   653:           } else {
   654:             if (SCC_DEBUG_ON && sccDebugOn != 0) {
   655:               System.out.println ("unimplemented sender configuration");
   656:             }
   657:           }
   658:         }
   659:         break;
   660:       case 6:  //WR6
   661:         break;
   662:       case 7:  //WR7
   663:         break;
   664:       case 9:  //WR9
   665:         if ((d & 0xc0) == 0x40) {  //ポート0Bリセット
   666:           scc0bRts = 0;
   667:         } else if ((d & 0xc0) == 0x80) {  //ポート1Aリセット
   668:         } else if ((d & 0xc0) == 0xc0) {  //ハードウェアリセット
   669:           scc0bRts = 0;
   670:         }
   671:         sccVectorInclude = d & 0x11;
   672:         if (SCC_DEBUG_ON && sccDebugOn != 0) {
   673:           System.out.printf ("sccVectorInclude=0x%02x\n", sccVectorInclude);
   674:         }
   675:         sccUpdateVector ();
   676:         if ((d & 0x26) != 0x00) {
   677:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   678:             System.out.println ("unimplemented interrupt configuration");
   679:           }
   680:         }
   681:         break;
   682:       case 10:  //WR10
   683:         if (d == 0x00) {
   684:         } else {
   685:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   686:             System.out.println ("unimplemented SDLC configuration");
   687:           }
   688:         }
   689:         break;
   690:       case 11:  //WR11
   691:         if (d == 0x50) {  //TRxCは入力
   692:         } else if (d == 0x56) {  //TRxCからボーレートジェネレータを出力
   693:         } else {
   694:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   695:             System.out.println ("unimplemented clock control");
   696:           }
   697:         }
   698:         break;
   699:       case 12:  //WR12
   700:         scc0bBaudRateGen = (scc0bBaudRateGen & ~0xff) | d;
   701:         break;
   702:       case 13:  //WR13
   703:         scc0bBaudRateGen = d << 8 | (scc0bBaudRateGen & 0xff);
   704:         break;
   705:       case 14:  //WR14
   706:         if (d == 0x02) {  //ボーレートジェネレータ停止
   707:         } else if (d == 0x03) {  //ボーレートジェネレータ動作
   708:         } else {
   709:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   710:             System.out.println ("unimplemented DPLL configuration");
   711:           }
   712:         }
   713:         break;
   714:       case 15:  //WR15
   715:         if (d == 0x00) {
   716:         } else if (d == 0x80) {
   717:         } else if (d == 0x88) {
   718:         } else {
   719:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   720:             System.out.println ("unimplemented status interrupt configuration");
   721:           }
   722:         }
   723:         break;
   724:       default:
   725:         if (SCC_DEBUG_ON && sccDebugOn != 0) {
   726:           System.out.println ("unimplemented register");
   727:         }
   728:       }
   729:       scc0bRegisterNumber = 0;
   730:       return;
   731:       //------------------------------------------------
   732:     case SCC_0B_DATA & 7:  //ポート0Bデータ書き込み(マウス送信)
   733:       return;
   734:       //------------------------------------------------
   735:     case SCC_1A_COMMAND & 7:  //ポート1Aコマンド書き込み
   736:       switch (scc1aRegisterNumber) {
   737:       case 0:  //WR0
   738:         if ((d & 0xf0) == 0) {  //レジスタ選択
   739:           scc1aRegisterNumber = d;
   740:         } else if (d == 0x38) {  //IUSリセット。割り込み処理が終了し、次の割り込みを受け付ける
   741:           scc1aReceiveRR3 = 0;
   742:         } else if (d == 0x10) {  //ステータス割り込みリセット
   743:         } else if (d == 0x30) {  //エラーリセット
   744:         } else if (d == 0x80) {  //送信CRCジェネレータリセット
   745:         } else {
   746:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   747:             System.out.println ("unimplemented command");
   748:           }
   749:         }
   750:         return;
   751:       case 1:  //WR1
   752:         //  Z85C30UM 5-4
   753:         //  WR1
   754:         //    bit7    WAIT/DMA Request Enable
   755:         //    bit6    /WAIT/DMA Request Function
   756:         //    bit5    WAIT/DMA Request On Receive/Transmit
   757:         //    bit4-3  00=Rx Int Disable
   758:         //            01=Rx Int On First Character or Special Condition
   759:         //            10=Int On All Rx Characters or Special Condition
   760:         //            11=Rx Int On Special Condition Only
   761:         //    bit2    Parity is Special Condition
   762:         //    bit1    Tx Int Enable
   763:         //    bit0    Ext Int Enable
   764:         scc1aReceiveMask = (d & 0x18) != 0 ? SCC_1A_RECEIVE_MASK : 0;  //Rx Int Enable
   765:         scc1aSendMask = (d & 0x02) != 0 ? SCC_1A_SEND_MASK : 0;  //Tx Int Enable
   766:         if ((d & 0xe3) != 0x00) {
   767:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   768:             System.out.println ("unimplemented interrupt mode");
   769:           }
   770:         }
   771:         break;
   772:       case 2:  //WR2
   773:         sccInterruptVector = d;  //割り込みベクタ
   774:         if (SCC_DEBUG_ON && sccDebugOn != 0) {
   775:           System.out.printf ("sccInterruptVector=0x%02x\n", sccInterruptVector);
   776:         }
   777:         sccUpdateVector ();
   778:         break;
   779:       case 3:  //WR3
   780:         //  Z85C30UM 5-7
   781:         //  WR3
   782:         //    bit7-6  00=Rx 5 Bits/Character
   783:         //            01=Rx 7 Bits/Character
   784:         //            10=Rx 6 Bits/Character
   785:         //            10=Rx 8 Bits/Character
   786:         //    bit5    1=Auto Enables
   787:         //    bit4    1=Enter Hunt Mode
   788:         //    bit3    1=Rx CRC Enable
   789:         //    bit2    1=Address Search Mode (SDLC)
   790:         //    bit1    1=Sync Characster Load Inhibit
   791:         //    bit0    1=Rx Enable
   792:         if ((d & 0x3e) == 0x00) {
   793:           scc1aRxBits = d >> 6;
   794:         } else {
   795:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   796:             System.out.println ("unimplemented receiver configuration");
   797:           }
   798:         }
   799:         break;
   800:       case 4:  //WR4
   801:         //  Z85C30UM 5-8
   802:         //  WR4
   803:         //    bit7-6  00=X1 Clock Mode
   804:         //            01=X16 Clock Mode
   805:         //            10=X32 Clock Mode
   806:         //            11=X64 Clock Mode
   807:         //    bit5-4  00=8-Bit Sync Character
   808:         //            01=16-Bit Sync Character
   809:         //            10=SDLC Mode (01111110 Flag)
   810:         //            11=External Sync Mode
   811:         //    bit3-2  00=Sync Modes Enable
   812:         //            01=1 Stop Bit/Character
   813:         //            10=1 1/2 Stop Bits/Character
   814:         //            11=2 Stop Bits/Character
   815:         //    bit1    0=Parity ODD
   816:         //            1=Parity EVEN
   817:         //    bit0    1=Parity Enable
   818:         scc1aClockModeShift = d >> 6 == 0 ? 0 : (d >> 6) + 3;  //0=2^0,1=2^4,2=2^5,3=2^6
   819:         scc1aStop = d >> 2 & 3;
   820:         scc1aParity = d & 3;
   821:         break;
   822:       case 5:  //WR5
   823:         //  Z85C30UM 5-9
   824:         //  WR5
   825:         //    bit7    0=/DTR is High
   826:         //            1=/DTR is Low(準備完了)
   827:         //    bit6-5  00=Tx 5 Bits(Or Less)/Character
   828:         //            01=Tx 7 Bits/Character
   829:         //            10=Tx 6 Bits/Character
   830:         //            11=Tx 8 Bits/Character
   831:         //    bit4    1=Send Break
   832:         //    bit3    1=Tx Enable
   833:         //    bit2    0=SDLC
   834:         //            1=CRC-16
   835:         //    bit1    0=/RTS is High  自分が受信バッファに余裕がない(3/4)から送るのやめてと言う
   836:         //            1=/RTS is Low   自分が受信バッファに余裕がある(1/4)から送っていいよと言う
   837:         //    bit0    1=Tx CRC Enable
   838:         if ((d & 0x15) == 0x00) {
   839:           RS232CTerminal.trmAUXSetNotReceiving ((d & 0x02) == 0);
   840:           scc1aTxBits = d >> 5 & 3;
   841:           scc1aTxEnable = d >> 3 & 1;
   842:         } else {
   843:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   844:             System.out.println ("unimplemented sender configuration");
   845:           }
   846:         }
   847:         break;
   848:       case 6:  //WR6
   849:         break;
   850:       case 7:  //WR7
   851:         break;
   852:       case 9:  //WR9
   853:         if ((d & 0xc0) == 0x40) {  //ポート0Bリセット
   854:           scc0bRts = 0;
   855:         } else if ((d & 0xc0) == 0x80) {  //ポート1Aリセット
   856:           scc1aBRGEnable = 0;
   857:           scc1aRxEnable = 0;
   858:           scc1aTxEnable = 0;
   859:           RS232CTerminal.trmAUXReset ();
   860:         } else if ((d & 0xc0) == 0xc0) {  //ハードウェアリセット
   861:           scc0bRts = 0;
   862:           scc1aBRGEnable = 0;
   863:           scc1aRxEnable = 0;
   864:           scc1aTxEnable = 0;
   865:           RS232CTerminal.trmAUXReset ();
   866:         }
   867:         sccVectorInclude = d & 0x11;
   868:         if (SCC_DEBUG_ON && sccDebugOn != 0) {
   869:           System.out.printf ("sccVectorInclude=0x%02x\n", sccVectorInclude);
   870:         }
   871:         sccUpdateVector ();
   872:         if ((d & 0x2e) != 0x08) {
   873:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   874:             System.out.println ("unimplemented interrupt configuration");
   875:           }
   876:         }
   877:         break;
   878:       case 10:  //WR10
   879:         if (d == 0x00) {
   880:         } else {
   881:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   882:             System.out.println ("unimplemented SDLC configuration");
   883:           }
   884:         }
   885:         break;
   886:       case 11:  //WR11
   887:         if (d == 0x50) {  //TRxCは入力
   888:         } else if (d == 0x56) {  //TRxCからボーレートジェネレータを出力
   889:         } else {
   890:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   891:             System.out.println ("unimplemented clock control");
   892:           }
   893:         }
   894:         break;
   895:       case 12:  //WR12
   896:         //  Z85C30UM 5-18
   897:         //  WR12
   898:         //    bit7-0  Lower Byte Of Time Constant
   899:         //
   900:         //                                   5000000
   901:         //      WR13-WR12                Clock Frequency
   902:         //    Time Constant = -------------------------------------- - 2
   903:         //                    2 x (Desired Rate) x (BR Clock Period)
   904:         //                                            WR4 bit7-6
   905:         //
   906:         //    5000000/(2*(0+2)*16)=78125  76800*1.017
   907:         //    5000000/(2*(2+2)*16)=39062.5  38400*1.017
   908:         //    5000000/(2*(3+2)*16)=31250
   909:         //    5000000/(2*(6+2)*16)=19531.25  19200*1.017
   910:         //    5000000/(2*(14+2)*16)=9765.625  9600*1.017
   911:         //    5000000/(2*(30+2)*16)=4882.8125  4800*1.017
   912:         scc1aBaudRateGen = (scc1aBaudRateGen & ~0xff) | d;
   913:         break;
   914:       case 13:  //WR13
   915:         //  Z85C30UM 5-19
   916:         //  WR13
   917:         //    bit7-0  Upper Byte Of Time Constant
   918:         scc1aBaudRateGen = d << 8 | (scc1aBaudRateGen & 0xff);
   919:         break;
   920:       case 14:  //WR14
   921:         //  Z85C30UM 5-19
   922:         //  WR14
   923:         //    bit7-5  000=Null Command
   924:         //            001=Enter Search Mode
   925:         //            010=Reset Missing Clock
   926:         //            011=Disable DPLL
   927:         //            100=Set Source = BR Generator
   928:         //            101=Set Source = /RTxC
   929:         //            110=Set FM Mode
   930:         //            111=Set NRZI Mode
   931:         //    bit4    1=Local Loopback
   932:         //    bit3    1=Auto Echo
   933:         //    bit2    1=/DTR/Request Function
   934:         //    bit1    BR Generator Source
   935:         //            0=/RTxC pin or XTAL oscillator
   936:         //            1=SCC's PCLK input
   937:         //    bit0    1=BR Generator Enable
   938:         if ((d & 0xfe) == 0x02) {
   939:           scc1aBRGEnable = d & 1;
   940:           if (scc1aBRGEnable != 0) {  //1が書き込まれたとき
   941:             //本来は、ボーレートジェネレータのカウンタの初期値はゼロカウントまたはリセットでロードされる
   942:             //一般的に、
   943:             //動作間隔を決めるカウンタの初期値が上位と下位に分かれていて、ゼロカウントで初期値がロードされる仕組みのとき、
   944:             //上位または下位のどちらか一方を書き換えた直後にゼロカウントになると予期しない初期値がロードされてしまうので、
   945:             //カウンタを止めてから初期値を書き換えるのが作法である
   946:             //それならばボーレートジェネレータの再開をボーレート変更完了の合図として使えるはずだが、
   947:             //tmsio.xとbsio.xがカウンタを止めずにボーレートを変更してしまっているため、その方法が使えない
   948:             //ここではBaud Rate Generator Enableに1が書き込まれたら必ず設定を更新する
   949:             RS232CTerminal.trmReflectSettings (1);
   950:           }
   951:         } else {
   952:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   953:             System.out.println ("unimplemented DPLL configuration");
   954:           }
   955:         }
   956:         break;
   957:       case 15:  //WR15
   958:         //  Z85C30UM 5-20
   959:         //  WR15
   960:         //    bit7  Break/Abort IE
   961:         //    bit6  Tx Underrun/EOM IE
   962:         //    bit5  CTS IE
   963:         //    bit4  Sync/Hunt IE
   964:         //    bit3  DCD IE
   965:         //    bit2  SDLC FIFO Enable (Reserved on NMOS)
   966:         //    bit1  Zero Count IE
   967:         //    bit0  WR7' SDLC Feature Enable (Reserved on NMOS/CMOS)
   968:         if (d == 0x00) {
   969:         } else if (d == 0x80) {
   970:         } else if (d == 0x88) {
   971:         } else {
   972:           if (SCC_DEBUG_ON && sccDebugOn != 0) {
   973:             System.out.println ("unimplemented status interrupt configuration");
   974:           }
   975:         }
   976:         break;
   977:       default:
   978:         if (SCC_DEBUG_ON && sccDebugOn != 0) {
   979:           System.out.println ("unimplemented register");
   980:         }
   981:       }
   982:       scc1aRegisterNumber = 0;
   983:       return;
   984:       //------------------------------------------------
   985:     case SCC_1A_DATA & 7:  //ポート1Aデータ書き込み(RS-232C送信)
   986:       RS232CTerminal.trmAUXWriteData (d);
   987:       return;
   988:       //------------------------------------------------
   989:     default:
   990:       ;
   991:     }
   992:   }  //sccWriteByte
   993: 
   994: 
   995: 
   996: }  //class Z8530
   997: 
   998: 
   999: