xeij/Malfunction.java
//========================================================================================
//  Malfunction.java
//    en:Malfunction reproduction
//    ja:故障再現
//  Copyright (C) 2003-2026 Makoto Kamada
//
//  This file is part of the XEiJ (X68000 Emulator in Java).
//  You can use, modify and redistribute the XEiJ if the conditions are met.
//  Read the XEiJ License for more details.
//  https://stdkmd.net/xeij/
//========================================================================================

package xeij;

import java.awt.*;  //FlowLayout
import java.awt.event.*;  //ActionListener
import javax.swing.*;

class Malfunction {

  public static final boolean MLF_ON = false;

  //チップ
  static int mlfChipMask;

  //アドレス
  static int mlfAddressMask;  //zero|one
  static int mlfAddressZero;
  static int mlfAddressOne;

  //データ
  static int mlfDataMask;  //zero|one|random
  static int mlfDataClear;
  static int mlfDataSet;
  static int mlfDataRandom;

  //機種
  static final String[] MLF_MODEL_NAME = {
    "First gen",
    "XVI",
    "Compact",
    "X68030",
    "030 Compact",
  };
  static int mlfModelNumber;

  //IC
  static final String[][] MLF_IC_NAME = {
    //1st gen
    {
      "IC1", "IC2", "IC3", "IC4", "IC5", "IC6", "IC7", "IC8",
      "IC9", "IC10", "IC11", "IC12", "IC13", "IC14", "IC15", "IC16",
      "IC17", "IC19", "IC18", "IC20", "IC21", "IC23", "IC22", "IC24",
      "IC25", "IC27", "IC26", "IC28", "IC29", "IC31", "IC30", "IC32",
    },
    //XVI
    {
      "IC53", "IC54", "IC55", "IC56", "IC57", "IC58", "IC59", "IC60",
      "IC61", "IC62", "IC63", "IC64", "IC65", "IC66", "IC67", "IC68",
      "IC69", "IC70", "IC71", "IC72", "IC73", "IC74", "IC75", "IC76",
      "IC77", "IC78", "IC79", "IC80", "IC81", "IC82", "IC83", "IC84",
    },
    //Compact
    {
      "IC20", "IC24", "IC53", "IC57", "IC21", "IC25", "IC54", "IC58",
      "IC22", "IC26", "IC55", "IC59", "IC23", "IC27", "IC56", "IC60",
      "IC12", "IC14", "IC13", "IC15", "IC16", "IC18", "IC17", "IC19",
      "IC45", "IC47", "IC46", "IC48", "IC49", "IC51", "IC50", "IC52",
    },
    //X68030
    {
      "IC59", "IC61", "IC63", "IC65", "IC60", "IC62", "IC64", "IC66",
      "IC67", "IC69", "IC71", "IC73", "IC68", "IC70", "IC72", "IC74",
      "IC87", "IC89", "IC88", "IC90", "IC91", "IC93", "IC92", "IC94",
      "IC95", "IC97", "IC96", "IC98", "IC99", "IC101", "IC100", "IC102",
    },
    //030Compact
    {
      "IC19", "IC23", "IC47", "IC51", "IC20", "IC24", "IC48", "IC52",
      "IC21", "IC25", "IC49", "IC53", "IC22", "IC26", "IC50", "IC54",
      "IC11", "IC13", "IC12", "IC14", "IC15", "IC17", "IC16", "IC18",
      "IC39", "IC41", "IC40", "IC42", "IC43", "IC45", "IC44", "IC46",
    },
  };

  //コンポーネント
  static JFrame mlfFrame;  //ウインドウ
  static JTextField[] mlfChipTextField;  //チップテキストフィールド

  //mlfInit ()
  public static void mlfInit () {
    //チップ
    mlfChipMask = 0;
    //アドレス
    mlfAddressMask = 0;
    mlfAddressZero = 0;
    mlfAddressOne = 0;
    //データ
    mlfDataMask = 0b1111;
    mlfDataClear = 0;
    mlfDataSet = 0;
    mlfDataRandom = 0b1111;
    //機種
    mlfModelNumber = 0;
    //コンポーネント
    mlfFrame = null;
    mlfChipTextField = null;
  }  //mlfInit

  //mlfTini ()
  public static void mlfTini () {
  }  //mlfTini

  //mlfMake ()
  public static void mlfMake () {

    //アクションリスナー
    ActionListener listener = new ActionListener () {
      @Override public void actionPerformed (ActionEvent ae) {
        Object source = ae.getSource ();
        String command = ae.getActionCommand ();
        for (int k = 0; k < MLF_MODEL_NAME.length; k++) {
          if (command.equals (MLF_MODEL_NAME[k])) {
            mlfModelNumber = k;
            for (int i = 0; i < 32; i++) {
              mlfChipTextField[i].setText (MLF_IC_NAME[k][i]);
            }
            return;
          }
        }
        int c = command.charAt (0);
        if (c == 'i') {  //チップ
          int m = 1 << Integer.parseInt (command.substring (1));
          if (((JCheckBox) source).isSelected ()) {
            mlfChipMask |= m;
          } else {
            mlfChipMask &= ~m;
          }
        } else if (c == 'a') {  //アドレス Any
          int m = 1 << Integer.parseInt (command.substring (1));
          mlfAddressMask &= ~m;
          mlfAddressZero &= ~m;
          mlfAddressOne &= ~m;
        } else if (c == 'z') {  //アドレス Zero
          int m = 1 << Integer.parseInt (command.substring (1));
          mlfAddressMask |= m;
          mlfAddressZero |= m;
          mlfAddressOne &= ~m;
        } else if (c == 'o') {  //アドレス One
          int m = 1 << Integer.parseInt (command.substring (1));
          mlfAddressMask |= m;
          mlfAddressZero &= ~m;
          mlfAddressOne |= m;
        } else if (c == 'n') {  //データ Normal
          int m = 1 << Integer.parseInt (command.substring (1));
          mlfDataMask &= ~m;
          mlfDataClear &= ~m;
          mlfDataSet &= ~m;
          mlfDataRandom &= ~m;
        } else if (c == 'c') {  //データ Clear
          int m = 1 << Integer.parseInt (command.substring (1));
          mlfDataMask |= m;
          mlfDataClear |= m;
          mlfDataSet &= ~m;
          mlfDataRandom &= ~m;
        } else if (c == 's') {  //データ Set
          int m = 1 << Integer.parseInt (command.substring (1));
          mlfDataMask |= m;
          mlfDataClear &= ~m;
          mlfDataSet |= m;
          mlfDataRandom &= ~m;
        } else if (c == 'r') {  //データ Random
          int m = 1 << Integer.parseInt (command.substring (1));
          mlfDataMask |= m;
          mlfDataClear &= ~m;
          mlfDataSet &= ~m;
          mlfDataRandom |= m;
        } else {
          System.out.println ("unknown action command " + command);
        }  //switch command
      }  //actionPerformed
    };  //listener

    //チップパネル
    //     0   1        2   3-10       11
    //  0  0:-----------------------------
    //  1  1:  2:Model  3:     4:model  5:
    //  2  6:-----------------------------
    //  3  7:  8:TVRAM  9: 10-17:[]... 18:
    //  4  |   |        |  19-26:[]...  |
    //  5  |   |        |     27:-----  |
    //  6  |   |        |  28-35:[]...  |
    //  7  |   |        |  36-43:[]...  |
    //  8 44:-----------------------------
    //  9 45: 46:GVRAM 47: 48-55:[]... 56:
    // 10  |   |        |  57-64:[]...  |
    // 11  |   |        |     65:-----  |
    // 12  |   |        |  66-73:[]...  |
    // 13  |   |        |  74-81:[]...  |
    // 14 82:-----------------------------
    //modelパネル
    ButtonGroup modelGroup = new ButtonGroup ();
    JPanel modelPanel = ComponentFactory.createFlowPanel (
      FlowLayout.CENTER, 10, 0);
    for (int i = 0; i < MLF_MODEL_NAME.length; i++) {
      modelPanel.add (
        ComponentFactory.createRadioButton (
          modelGroup,
          i == mlfModelNumber,
          MLF_MODEL_NAME[i],
          listener));
    }
    //テキストフィールドとチェックボックス
    mlfChipTextField = new JTextField[32];
    JCheckBox[] chipCheckBox = new JCheckBox[32];
    for (int i = 0; i < 32; i++) {
      mlfChipTextField[i] =
        ComponentFactory.setHorizontalAlignment (
          ComponentFactory.setEditable (
            ComponentFactory.createTextField (
              MLF_IC_NAME[mlfModelNumber][i],
              6),
            false),
          JTextField.CENTER);
      chipCheckBox[i] = 
        ComponentFactory.setText (
          ComponentFactory.createCheckBox (
            (mlfChipMask & (1 << i)) != 0,  //mask!=0
            "i" + i,
            listener),
          "");
    }  //for i
    //オブジェクト
    Object[] chipObject = new Object[83];
    for (int i = 0; i < 83; i++) {
      chipObject[i] = (
        //横線
        i == 0 || i == 6 || i == 27 || i == 44 || i == 65 || i == 82 ?
        ComponentFactory.createHorizontalSeparator () :
        //縦線(隙間)
        i == 1 || i == 3 || i == 5 ||
        i == 7 || i == 9 || i == 18 ||
        i == 45 || i == 47 || i == 56 ?
        Box.createHorizontalStrut (10) :
        //ラベル
        i == 2 ? ComponentFactory.createLabel ("Model") :
        i == 8 ? ComponentFactory.createLabel ("TVRAM") :
        i == 46 ? ComponentFactory.createLabel ("GVRAM") :
        //機種パネル
        i == 4 ? modelPanel :
        //テキストフィールドとチェックボックス
        i <= 17 ? mlfChipTextField[i - 10] :
        i <= 26 ? chipCheckBox[i - 19] :
        i <= 35 ? mlfChipTextField[i - 28 + 8] :
        i <= 43 ? chipCheckBox[i - 36 + 8] :
        i <= 55 ? mlfChipTextField[i - 48 + 16] :
        i <= 64 ? chipCheckBox[i - 57 + 16] :
        i <= 73 ? mlfChipTextField[i - 66 + 24] :
        chipCheckBox[i - 74 + 24]);
    }  //for i
    //パネル
    JPanel chipPanel =
      ComponentFactory.createGridPanel (
        //colCount
        12,
        //rowCount
        15,
        //gridStyles
        "paddingLeft=3,paddingRight=3,center",
        //colStyles
        ";" +
        "italic",  //col=1 ラベル
        //rowStyles
        "colSpan=12,widen;;" +  //row=0 横線
        "colSpan=12,widen;;;" +  //row=2 横線
        "colSpan=8,widen;;;" +  //row=5 横線
        "colSpan=12,widen;;;" +  //row=8 横線
        "colSpan=8,widen;;;" +  //row=11 横線
        "colSpan=12,widen",  //row=14 横線
        //cellStyles
        ";" +
        "lengthen;;" +  //1: 縦線(隙間)
        "lengthen;" +  //3: 縦線(隙間)
        "colSpan=8;" +  //4: model
        "lengthen;;" +  //5: 縦線(隙間)
        "rowSpan=5,lengthen;" +  //7: 縦線(隙間)
        "rowSpan=5;" +  //8: TVRAM
        "rowSpan=5,lengthen;;;;;;;;;" +  //9: 縦線(隙間)
        "rowSpan=5,lengthen;;;;;;;;;;;;;;;;;;;;;;;;;;;" +  //18: 縦線(隙間)
        "rowSpan=5,lengthen;" +  //45: 縦線(隙間)
        "rowSpan=5;" +  //46: GVRAM
        "rowSpan=5,lengthen;;;;;;;;;" +  //47: 縦線(隙間)
        "rowSpan=5,lengthen",  //56: 縦線(隙間)
        chipObject);

    //アドレスパネル
    //     0   1       2    3-10       11  12-19        20
    //  0  0:----------------------------------------------
    //  1  1:  2:      3:      4:Row    5:     6:Column  7:
    //  2  |   |       |    8-15:15-8   |  16-23:7-0     |
    //  3 24:----------------------------------------------
    //  4 25: 26:Any  27:  28-35:[]... 36: 37-44:[]...  45:
    //  5  |  46:Zero  |   47-54:[]...  |  55-62:[]...   |
    //  6  |  63:One   |   64-71:[]...  |  72-79:[]...   |
    //  7 80:----------------------------------------------
    //ボタン
    ButtonGroup[] addressGroup = new ButtonGroup[16];
    JRadioButton[] addressButton = new JRadioButton[48];
    //Any
    for (int i = 0; i < 16; i++) {
      addressGroup[i] = new ButtonGroup ();
      addressButton[i] =
        ComponentFactory.setText (
          ComponentFactory.createRadioButton (
            addressGroup[i],
            (mlfAddressMask & (1 << i)) == 0,  //mask==0
            "a" + i,
            listener),
          "");
    }  //for i
    //Zero
    for (int i = 0; i < 16; i++) {
      addressButton[16 + i] =
        ComponentFactory.setText (
          ComponentFactory.createRadioButton (
            addressGroup[i],
            (mlfAddressZero & (1 << i)) != 0,  //zero!=0
            "z" + i,
            listener),
          "");
    }  //for i
    //One
    for (int i = 0; i < 16; i++) {
      addressButton[32 + i] =
        ComponentFactory.setText (
          ComponentFactory.createRadioButton (
            addressGroup[i],
            (mlfAddressOne & (1 << i)) != 0,  //one!=0
            "o" + i,
            listener),
          "");
    }  //for i
    //オブジェクト
    Object[] addressObject = new Object[81];
    for (int i = 0; i < 81; i++) {
      addressObject[i] = (
        //横線
        i == 0 || i == 24 || i == 80 ?
        ComponentFactory.createHorizontalSeparator () :
        //縦線(隙間)
        i == 1 || i == 3 || i == 5 || i == 7 ||
        i == 25 || i == 27 || i == 36 || i == 45 ?
        Box.createHorizontalStrut (10) :
        //ラベル
        i == 2 ? ComponentFactory.createLabel ("") :
        i == 4 ? ComponentFactory.createLabel ("Row") :
        i == 6 ? ComponentFactory.createLabel ("Column") :
        i == 26 ? ComponentFactory.createLabel ("Any") :
        i == 46 ? ComponentFactory.createLabel ("Zero") :
        i == 63 ? ComponentFactory.createLabel ("One") :
        i <= 23 ? ComponentFactory.createLabel (String.valueOf (23 - i)) :
        //ボタン
        addressButton[i <= 35 ? i - 28 :
                      i <= 44 ? i - 37 + 8 :
                      i <= 62 ? i - 47 + 16 :
                      i - 64 + 32]);
    }  //for i
    //パネル
    JPanel addressPanel =
      ComponentFactory.createGridPanel (
        //colCount
        21,
        //rowCount
        8,
        //gridStyles
        "paddingLeft=3,paddingRight=3,center",
        //colStyles
        ";" +
        "italic;",  //col=1 ラベル
        //rowStyles
        "colSpan=21,widen;" +  //row=0 横線
        "italic;" +  //row=1 ラベル
        "italic;" +  //row=2 ラベル
        "colSpan=21,widen;;;;" +  //row=3 横線
        "colSpan=21,widen",  //row=7 横線
        //cellStyles
        ";" +
        "rowSpan=2,lengthen;" +  //1: 縦線(隙間)
        "rowSpan=2;" +  //2:
        "rowSpan=2,lengthen;" +  //3: 縦線(隙間)
        "colSpan=8;" +  //4:Row
        "rowSpan=2,lengthen;" +  //5: 縦線(隙間)
        "colSpan=8;" +  //6:Column
        "rowSpan=2,lengthen;;;;;;;;;;;;;;;;;;" +  //7: 縦線(隙間)
        "rowSpan=3,lengthen;;" +  //25: 縦線(隙間)
        "rowSpan=3,lengthen;;;;;;;;;" +  //27: 縦線(隙間)
        "rowSpan=3,lengthen;;;;;;;;;" +  //36: 縦線(隙間)
        "rowSpan=3,lengthen",  //45: 縦線(隙間)
        addressObject);

    //データパネル
    //     0   1         2    3-6        7
    //  0  0:------------------------------
    //  1  1:  2:        3:   4-7:3-0    8:
    //  2  9:------------------------------
    //  3 10: 11:Normal 12: 13-16:[]... 17:
    //  4  |: 18:Clear   |  19-22:[]...  |
    //  5  |: 23:Set     |  24-27:[]...  |
    //  6  |: 28:Random  |  29-32:[]...  |
    //  7 33:------------------------------
    //ボタン
    ButtonGroup[] dataGroup = new ButtonGroup[4];
    JRadioButton[] dataButton = new JRadioButton[16];
    //Normal
    for (int i = 0; i < 4; i++) {
      dataGroup[i] = new ButtonGroup ();
      dataButton[i] =
        ComponentFactory.setText (
          ComponentFactory.createRadioButton (
            dataGroup[i],
            (mlfDataMask & (1 << i)) == 0,  //mask==0
            "n" + i,
            listener),
          "");
    }  //for i
    //Clear
    for (int i = 0; i < 4; i++) {
      dataGroup[i] = new ButtonGroup ();
      dataButton[4 + i] =
        ComponentFactory.setText (
          ComponentFactory.createRadioButton (
            dataGroup[i],
            (mlfDataClear & (1 << i)) != 0,  //clear!=0
            "c" + i,
            listener),
          "");
    }  //for i
    //Set
    for (int i = 0; i < 4; i++) {
      dataGroup[i] = new ButtonGroup ();
      dataButton[8 + i] =
        ComponentFactory.setText (
          ComponentFactory.createRadioButton (
            dataGroup[i],
            (mlfDataSet & (1 << i)) != 0,  //set!=0
            "s" + i,
            listener),
          "");
    }  //for i
    //Random
    for (int i = 0; i < 4; i++) {
      dataGroup[i] = new ButtonGroup ();
      dataButton[12 + i] =
        ComponentFactory.setText (
          ComponentFactory.createRadioButton (
            dataGroup[i],
            (mlfDataRandom & (1 << i)) != 0,  //random!=0
            "r" + i,
            listener),
          "");
    }  //for i
    //オブジェクト
    Object[] dataObject = new Object[34];
    for (int i = 0; i < 34; i++) {
      dataObject[i] = (
        //横線
        i == 0 || i == 9 || i == 33 ?
        ComponentFactory.createHorizontalSeparator () :
        //縦線(隙間)
        i == 1 || i == 3 || i == 8 ||
        i == 10 || i == 12 | i == 17 ?
        Box.createHorizontalStrut (10) :
        //ラベル
        i == 2 ? ComponentFactory.createLabel ("") :
        i == 11 ? ComponentFactory.createLabel ("Normal") :
        i == 18 ? ComponentFactory.createLabel ("Clear") :
        i == 23 ? ComponentFactory.createLabel ("Set") :
        i == 28 ? ComponentFactory.createLabel ("Random") :
        i <= 7 ? ComponentFactory.createLabel (String.valueOf (7 - i)) :
        //ボタン
        dataButton[i <= 16 ? i - 13 :
                   i <= 22 ? i - 19 + 4 :
                   i <= 27 ? i - 24 + 8 :
                   i - 29 + 12]);
    }  //for i
    //パネル
    JPanel dataPanel =
      ComponentFactory.createGridPanel (
        //colCount
        8,
        //rowCount
        8,
        //gridStyles
        "paddingLeft=3,paddingRight=3,center",
        //colStyles
        ";" +
        "italic;",  //col=1 ラベル
        //rowStyles
        "colSpan=8,widen;" +  //row=0 横線
        "italic;" +  //row=1 ラベル
        "colSpan=8,widen;;;;;" +  //row=2 横線
        "colSpan=8,widen",  //row=7 横線
        //cellStyles
        ";" +
        "lengthen;;" +  //1: 縦線(隙間)
        "lengthen;;;;;" +  //3: 縦線(隙間)
        "lengthen;;" +  //8: 縦線(隙間)
        "rowSpan=4,lengthen;;" +  //10: 縦線(隙間)
        "rowSpan=4,lengthen;;;;;" +  //12: 縦線(隙間)
        "rowSpan=4,lengthen",  //17: 縦線(隙間)
        dataObject);

    //ウインドウ
    mlfFrame = Multilingual.mlnTitle (
      ComponentFactory.createRestorableSubFrame (
        Settings.SGS_MLF_FRAME_KEY,
        "Malfunction reproduction",
        null,
        ComponentFactory.createVerticalBox (
          ComponentFactory.setPreferredSize (
            ComponentFactory.createScrollPane (
              ComponentFactory.setEmptyBorder (
                ComponentFactory.createVerticalBox (
                  ComponentFactory.createHorizontalBox (
                    Box.createHorizontalGlue (),
                    ComponentFactory.createLabel ("RAM chip"),
                    Box.createHorizontalGlue ()),
                  ComponentFactory.createHorizontalBox (
                    Box.createHorizontalGlue (),
                    chipPanel,
                    Box.createHorizontalGlue ()),
                  Box.createVerticalStrut (10),
                  ComponentFactory.createHorizontalBox (
                    Box.createHorizontalGlue (),
                    ComponentFactory.createLabel ("Address"),
                    Box.createHorizontalGlue ()),
                  ComponentFactory.createHorizontalBox (
                    Box.createHorizontalGlue (),
                    addressPanel,
                    Box.createHorizontalGlue ()),
                  Box.createVerticalStrut (10),
                  ComponentFactory.createHorizontalBox (
                    Box.createHorizontalGlue (),
                    ComponentFactory.createLabel ("Data"),
                    Box.createHorizontalGlue ()),
                  ComponentFactory.createHorizontalBox (
                    Box.createHorizontalGlue (),
                    dataPanel,
                    Box.createHorizontalGlue ())
                  ),  //createVerticalBox
                10, 10, 10, 10)  //setEmptyBorder
              ),  //createScrollPane
            750, 500),  //setPreferredSize
          Box.createVerticalGlue ()
          )  //createVerticalBox
        ),  //createRestorableSubFrame
      "ja", "故障再現");  //mlnTitle

  }  //mlfMake

  //mlfStart ()
  public static void mlfStart () {
    if (RestorableFrame.rfmGetOpened (Settings.SGS_MLF_FRAME_KEY)) {
      mlfOpen ();
    }
  }  //mlfStart()

  //mlfOpen ()
  public static void mlfOpen () {
    if (mlfFrame == null) {
      mlfMake ();
    }
    XEiJ.pnlExitFullScreen (false);
    mlfFrame.setVisible (true);
  }  //mlfOpen()



  //!!! 以下は推測のため誤りが含まれる可能性がある
  //
  //  回路図位置→チップ番号→TVRAM/GVRAM範囲(推測)
  //                        P0                              P1
  //          ┌──────┴───────┐┌──────┴───────┐
  //        ┌┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓
  //        │┃ #0 ┃┃ #1 ┃┃ #2 ┃┃ #3 ┃┃ #4 ┃┃ #5 ┃┃ #6 ┃┃ #7 ┃
  //        │┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛
  //  TVRAM ┤  0-3     4-7     8-11   12-15    0-3     4-7     8-11   12-15 
  //        │┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓
  //        │┃ #8 ┃┃ #9 ┃┃#10 ┃┃#11 ┃┃#12 ┃┃#13 ┃┃#14 ┃┃#15 ┃
  //        └┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛
  //          └──────┬───────┘└──────┬───────┘
  //                        P2                              P3
  //                        P0                              P1
  //          ┌──────┴───────┐┌──────┴───────┐
  //        ┌┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓
  //        │┃#16 ┃┃#17 ┃┃#18 ┃┃#19 ┃┃#20 ┃┃#21 ┃┃#22 ┃┃#23 ┃
  //        │┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛
  //  GVRAM ┤   NW      NE      SW      SE      NW      NE      SW      SE
  //        │┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓┏━━┓
  //        │┃#24 ┃┃#25 ┃┃#26 ┃┃#27 ┃┃#28 ┃┃#29 ┃┃#30 ┃┃#31 ┃
  //        └┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛┗━━┛
  //          └──────┬───────┘└──────┬───────┘
  //                        P2                              P3
  //
  //  TVRAM範囲→チップ番号とチップ内アドレス(推測)
  //                     +00               +01                  +7E               +7F
  //    00E00000   #3-0000  #2-0000  #1-0000  #0-0000 ..  #3-003F  #2-003F  #1-003F  #0-003F
  //          80   #3-0040  #2-0040  #1-0040  #0-0040 ..  #3-007F  #2-007F  #1-007F  #0-007F
  //         100   #3-0080  #2-0080  #1-0080  #0-0080 ..  #3-00BF  #2-00BF  #1-00BF  #0-00BF
  //         180   #3-00C0  #2-00C0  #1-00C0  #0-00C0 ..  #3-00FF  #2-00FF  #1-00FF  #0-00FF
  //         200   #3-0100  #2-0100  #1-0100  #0-0100 ..  #3-0100  #2-0100  #1-0100  #0-0100
  //                 :
  //       1FF80   #3-FFC0  #2-FFC0  #1-FFC0  #0-FFC0 ..  #3-FFFF  #2-FFFF  #1-FFFF  #0-FFFF
  //    00E20000   #7-0000  #6-0000  #5-0000  #4-0000 ..  #7-003F  #6-003F  #5-003F  #4-003F
  //                 :
  //               #7-FFC0  #6-FFC0  #5-FFC0  #4-FFC0 ..  #7-FFFF  #6-FFFF  #5-FFFF  #4-FFFF
  //    00E40000  #11-0000 #10-0000  #9-0000  #8-0000 .. #11-003F #10-003F  #9-003F  #8-003F
  //                 :
  //              #11-FFC0 #10-FFC0  #9-FFC0  #8-FFC0 .. #11-FFFF #10-FFFF  #9-FFFF  #8-FFFF
  //    00E60000  #15-0000 #14-0000 #13-0000 #12-0000 .. #15-003F #14-003F #13-003F #12-003F
  //                 :
  //              #15-FFC0 #14-FFC0 #13-FFC0 #12-FFC0 .. #15-FFFF #14-FFFF #13-FFFF #12-FFFF
  //
  //  GVRAM範囲(16色4ページ)→チップ番号とチップ内アドレス(推測)
  //                +000     +002     +004     +006        +3F8     +3FA     +3FC     +3FE
  //    00C00000  #16-0000 #17-0000 #16-0001 #17-0001 .. #16-00FE #17-00FE #16-00FF #17-00FF
  //         400  #18-0000 #19-0000 #18-0001 #19-0001 .. #18-00FE #19-00FE #18-00FF #19-00FF
  //         800  #16-0100 #17-0100 #16-0101 #17-0101 .. #16-01FE #17-01FE #16-01FF #17-01FF
  //         C00  #18-0100 #19-0100 #18-0101 #19-0101 .. #18-01FE #19-01FE #18-01FF #19-01FF
  //                 :
  //       7F800  #16-FF00 #17-FF00 #16-FF01 #17-FF01 .. #16-FFFE #17-FFFE #16-FFFF #17-FFFF
  //       7FC00  #18-FF00 #19-FF00 #18-FF01 #19-FF01 .. #18-FFFE #19-FFFE #18-FFFF #19-FFFF
  //    00C80000  #20-0000 #21-0000 #20-0001 #21-0001 .. #20-00FE #21-00FE #20-00FF #21-00FF
  //         400  #22-0000 #23-0000 #22-0001 #23-0001 .. #22-00FE #23-00FE #22-00FF #23-00FF
  //                 :
  //       FF800  #20-FF00 #21-FF00 #20-FF01 #21-FF01 .. #20-FFFE #21-FFFE #20-FFFF #21-FFFF
  //       FFC00  #22-FF00 #23-FF00 #22-FF01 #23-FF01 .. #22-FFFE #23-FFFE #22-FFFF #23-FFFF
  //    00D00000  #24-0000 #25-0000 #24-0001 #25-0001 .. #24-00FE #25-00FE #24-00FF #25-00FF
  //         400  #26-0000 #27-0000 #26-0001 #27-0001 .. #26-00FE #27-00FE #26-00FF #27-00FF
  //                 :
  //       7F800  #24-FF00 #25-FF00 #24-FF01 #25-FF01 .. #24-FFFE #25-FFFE #24-FFFF #25-FFFF
  //       7FC00  #26-FF00 #27-FF00 #26-FF01 #27-FF01 .. #26-FFFE #27-FFFE #26-FFFF #27-FFFF
  //    00D80000  #28-0000 #29-0000 #28-0001 #29-0001 .. #28-00FE #29-00FE #28-00FF #29-00FF
  //         400  #30-0000 #31-0000 #30-0001 #31-0001 .. #30-00FE #31-00FE #30-00FF #31-00FF
  //                 :
  //       FF800  #28-FF00 #29-FF00 #28-FF01 #29-FF01 .. #28-FFFE #29-FFFE #28-FFFF #29-FFFF
  //       FFC00  #30-FF00 #31-FF00 #30-FF01 #31-FF01 .. #30-FFFE #31-FFFE #30-FFFF #31-FFFF
  //



  //!!! 工事中

  //mlfRaster (dataY)
  //  VRAMにゴミをばらまく
  public static void mlfRaster (int dataY) {
    int my = (CRTC.crtR11TxYZero + dataY) & 1023;  //メモリY座標
    final int ba = 0x00e00000 + (0 << 17);  //ベースアドレス。プレーン0
    int sa = ba + 128 * my;  //開始アドレス
    int ea = sa + 128;  //終了アドレス
    for (int a = sa; a < ea; a += 2) {
      MainMemory.mmrM8[a] = (byte) (((random () >>> 24) & 0xf0) |  //bit15-12をノイズに
                                    (MainMemory.mmrM8[a] & 0x0f));  //bit11-8はそのまま
    }
  }  //mlfRaster

  private static int x = 123456789;
  private static int y = 362436069;
  private static int z = 521288629;
  private static int w = 88675123;
  private static int random () {
    int t = x ^ (x << 11);
    x = y;
    y = z;
    z = w;
    return w = (w ^ (w >>> 19)) ^ (t ^ (t >>> 8));
  }  //random

}  //class Malfunction