SRAM.java
     1: //========================================================================================
     2: //  SRAM.java
     3: //    en:SRAM
     4: //    ja:SRAM
     5: //  Copyright (C) 2003-2023 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: package xeij;
    14: 
    15: import java.awt.event.*;  //ActionEvent,ActionListener
    16: import java.io.*;  //File
    17: import java.util.*;  //Arrays
    18: import javax.swing.*;  //JMenu,JRadioButtonMenuItem
    19: 
    20: public class SRAM {
    21: 
    22:   public static int smrSramSizeRequest;  //SRAMのサイズ。16384,32768,65536のいずれか
    23:   public static int smrSramCurrentSize;  //現在のSRAMのサイズ。16384,32768,65536のいずれか
    24: 
    25:   public static String smrSramName;  //SRAMイメージファイル名
    26: 
    27:   public static int smrBootDevice;  //起動デバイス。0x00ed0018。0x0000=STD,0x9070~0x9370=FDn,0x8000~0x8f00=HDn,0xa000=ROM,0xb000=RAM,-1=設定しない
    28:   public static int smrROMBootHandle;  //ROM起動ハンドル。0x00ed000c。-1=設定しない
    29:   public static int smrRAMBootAddress;  //RAM起動アドレス。0x00ed0010。-1=設定しない
    30: 
    31:   public static int smrRepeatDelay;  //リピート開始。0x00ed003a。-1=設定しない,0..15=200+100*n(ms)
    32:   public static int smrRepeatInterval;  //リピート間隔。0x00ed003b。-1=設定しない,0..15=30+5*n^2(ms)
    33:   public static boolean smrWriteEnableOn;  //true=SRAM書き込み可
    34: 
    35:   //-romdb
    36:   public static boolean smrROMDBOn;  //ROMデバッガ起動フラグ
    37: 
    38:   //-setmemorysize
    39:   public static boolean smrModifyMemorySizeOn;  //SRAMにあるメモリサイズを修正する
    40: 
    41:   //-srambuserror
    42:   public static boolean smrSRAMBusErrorOn;  //SRAMへの書き込み時のバスエラー
    43: 
    44:   public static JMenu smrRepeatDelayMenu;  //リピート開始メニュー
    45:   public static JMenu smrRepeatIntervalMenu;  //リピート間隔メニュー
    46:   public static JMenuItem smrROMDBMenuItem;  //ROMデバッガ起動フラグ
    47:   public static JMenuItem smrModifyMemorySizeMenuItem;  //メモリサイズ修正
    48:   public static JMenu smrMenu;  //SRAMメニュー
    49:   public static JMenu smrBootMenu;  //起動デバイスメニュー
    50:   public static JRadioButtonMenuItem smrSTDMenuItem;
    51: 
    52:   //smrInit ()
    53:   //  SRAMを初期化する
    54:   public static void smrInit () {
    55: 
    56:     //-sramsize
    57:     int sizeKB = Settings.sgsGetInt ("sramsize");  //SRAMのサイズ
    58:     smrSramSizeRequest = (sizeKB == 16 ||
    59:                           sizeKB == 32 ||
    60:                           sizeKB == 64 ? sizeKB << 10 : 16 << 10);
    61:     smrSramCurrentSize = smrSramSizeRequest;
    62:     System.out.printf (Multilingual.mlnJapanese ?
    63:                        "SRAM のサイズは %dKB です\n" :
    64:                        "SRAM size is %dKB\n",
    65:                        smrSramSizeRequest >> 10);
    66: 
    67:     boolean initialized = false;
    68: 
    69:     //-sram
    70:     smrSramName = "";
    71:     if (!initialized) {
    72:       smrSramName = Settings.sgsGetString ("sram");  //SRAMイメージファイル名
    73:       if (smrSramName.length () != 0) {
    74:         byte[] array = XEiJ.rscGetFile (smrSramName, smrSramSizeRequest);
    75:         if (array != null) {
    76:           System.arraycopy (array, 0, MainMemory.mmrM8, 0x00ed0000, smrSramSizeRequest);
    77:           if (smrSramSizeRequest < 64 << 10) {
    78:             Arrays.fill (MainMemory.mmrM8, 0x00ed0000 + smrSramSizeRequest, 0x00ed0000 + (64 << 10), (byte) 0);  //範囲外をゼロクリアする
    79:           }
    80:           initialized = true;
    81:         }
    82:       }
    83:     }
    84: 
    85:     //-sramdata
    86:     //  マジックの有無に関係なく復元する
    87:     if (!initialized) {
    88:       byte[] array = Settings.sgsGetData ("sramdata");  //SRAMの内容(gzip+base64)
    89:       if (array.length != 0) {  //復元するデータがある
    90:         System.out.println (Multilingual.mlnJapanese ?
    91:                             "SRAM のデータを復元します" :
    92:                             "SRAM data is restored");
    93:         System.arraycopy (array, 0, MainMemory.mmrM8, 0x00ed0000, Math.min (array.length, smrSramSizeRequest));
    94:         if (array.length < smrSramSizeRequest) {
    95:           Arrays.fill (MainMemory.mmrM8, 0x00ed0000 + array.length, 0x00ed0000 + smrSramSizeRequest, (byte) 0);  //復元されなかった部分をゼロクリアする
    96:         }
    97:         if (smrSramSizeRequest < 64 << 10) {
    98:           Arrays.fill (MainMemory.mmrM8, 0x00ed0000 + smrSramSizeRequest, 0x00ed0000 + (64 << 10), (byte) 0);  //範囲外をゼロクリアする
    99:         }
   100:         initialized = true;
   101:       }
   102:     }
   103: 
   104:     if (!initialized) {
   105:       System.out.println (Multilingual.mlnJapanese ?
   106:                           "SRAM をゼロクリアします" :
   107:                           "SRAM is zero-cleared");
   108:       Arrays.fill (MainMemory.mmrM8, 0x00ed0000, 0x00ed0000 + (64 << 10), (byte) 0);  //ゼロクリアする
   109:       initialized = true;
   110:     }
   111: 
   112:     //-keydly
   113:     int repeatDelay = Settings.sgsGetInt ("keydly");
   114:     smrRepeatDelay = -1 <= repeatDelay && repeatDelay <= 15 ? repeatDelay : -1;
   115: 
   116:     //-keyrep
   117:     int repeatInterval = Settings.sgsGetInt ("keyrep");
   118:     smrRepeatInterval = -1 <= repeatInterval && repeatInterval <= 15 ? repeatInterval : -1;
   119: 
   120:     //-romdb
   121:     smrROMDBOn = Settings.sgsGetOnOff ("romdb");
   122: 
   123:     //-modifymemorysize
   124:     smrModifyMemorySizeOn = Settings.sgsGetOnOff ("modifymemorysize");
   125: 
   126:     //-srambuserror
   127:     smrSRAMBusErrorOn = Settings.sgsGetOnOff ("srambuserror");
   128: 
   129:     //-boot
   130:     smrParseBootDevice (Settings.sgsGetString ("boot"));
   131: 
   132:   }  //smrInit
   133: 
   134:   //smrTini ()
   135:   //  SRAMの後始末
   136:   public static void smrTini () {
   137: 
   138:     //-sramsize
   139:     Settings.sgsPutInt ("sramsize", smrSramSizeRequest >> 10);
   140: 
   141:     //-sram
   142:     Settings.sgsPutString ("sram", smrSramName);
   143: 
   144:     //-sramdata
   145:     //  マジックの有無に関係なく保存する
   146:     //  常に64KB保存する
   147:     Settings.sgsPutData ("sramdata", MainMemory.mmrM8, 0x00ed0000, 64 << 10);
   148: 
   149:     //-keydly
   150:     Settings.sgsPutInt ("keydly", smrRepeatDelay);  //リピート開始
   151: 
   152:     //-keyrep
   153:     Settings.sgsPutInt ("keyrep", smrRepeatInterval);  //リピート間隔
   154: 
   155:     //-romdb
   156:     Settings.sgsPutOnOff ("romdb", smrROMDBOn);
   157: 
   158:     //-modifymemorysize
   159:     Settings.sgsPutOnOff ("modifymemorysize", smrModifyMemorySizeOn);
   160: 
   161:     //-srambuserror
   162:     Settings.sgsPutOnOff ("srambuserror", smrSRAMBusErrorOn);
   163: 
   164:     //-boot
   165:     Settings.sgsPutString ("boot",
   166:                            smrBootDevice == -1 ? "default" :
   167:                            smrBootDevice == 0x0000 ? "std" :
   168:                            (smrBootDevice & 0xf000) == 0x9000 ? "fd" + (smrBootDevice >> 8 & 3) :
   169:                            (smrBootDevice & 0xf000) == 0x8000 ? "hd" + (smrBootDevice >> 8 & 15) :
   170:                            smrBootDevice == 0xa000 ?
   171:                            (smrROMBootHandle & ~(7 << 2)) == SPC.SPC_HANDLE_EX ? "sc" + (smrROMBootHandle >> 2 & 7) :
   172:                            (smrROMBootHandle & ~(7 << 2)) == SPC.SPC_HANDLE_IN ? "sc" + (smrROMBootHandle >> 2 & 7) :
   173:                            smrROMBootHandle == HFS.HFS_BOOT_HANDLE ? "hf" + HFS.hfsBootUnit :
   174:                            String.format ("rom$%08X", smrROMBootHandle) :
   175:                            smrBootDevice == 0xb000 ? String.format ("ram$%08X", smrRAMBootAddress) :
   176:                            "");
   177: 
   178:   }
   179: 
   180:   public static void smrMakeMenu () {
   181: 
   182:     //アクションリスナー
   183:     ActionListener listener = new ActionListener () {
   184:       @Override public void actionPerformed (ActionEvent ae) {
   185:         Object source = ae.getSource ();
   186:         String command = ae.getActionCommand ();
   187:         switch (command) {
   188:           //ROMデバッガ起動フラグ
   189:         case "ROM debugger start flag":  //ROM デバッガ起動フラグ
   190:           smrROMDBOn = ((JCheckBoxMenuItem) source).isSelected ();
   191:           break;
   192:           //メモリサイズ修正
   193:         case "Modify the memory size in SRAM":  //SRAM にあるメモリサイズを修正する
   194:           smrModifyMemorySizeOn = ((JCheckBoxMenuItem) source).isSelected ();
   195:           break;
   196:           //SRAMメニュー
   197:         case "Zero-clear":  //SRAM をゼロクリア
   198:           smrClear ();
   199:           break;
   200:         case "Import":  //SRAM をインポート
   201:           smrLoad ();
   202:           break;
   203:         case "Export":  //SRAM をエクスポート
   204:           smrSave ();
   205:           break;
   206:         case "16KB":
   207:           smrSramSizeRequest = 16384;
   208:           break;
   209:         case "32KB":
   210:           smrSramSizeRequest = 32768;
   211:           break;
   212:         case "64KB":
   213:           smrSramSizeRequest = 65536;
   214:           break;
   215:         case "Bus error when writing to SRAM":  //SRAM への書き込み時のバスエラー
   216:           smrSRAMBusErrorOn = ((JCheckBoxMenuItem) source).isSelected ();
   217:           break;
   218:         default:
   219:           System.out.println ("unknown action command " + command);
   220:         }
   221:       }
   222:     };
   223: 
   224:     //リピート開始メニュー
   225:     ActionListener delayListener = new ActionListener () {
   226:       @Override public void actionPerformed (ActionEvent ae) {
   227:         String command = ae.getActionCommand ();
   228:         switch (command) {
   229:         case "Follow settings in SWITCH.X":  //SWITCH.X の設定に従う
   230:           smrRepeatDelay = -1;
   231:           Keyboard.kbdSetRepeatDelay (MainMemory.mmrRbs (0x00ed003a));
   232:           break;
   233:         case (200 + 100 *  0) + "ms":
   234:         case (200 + 100 *  1) + "ms":
   235:         case (200 + 100 *  2) + "ms":
   236:         case (200 + 100 *  3) + "ms":
   237:         case (200 + 100 *  4) + "ms":
   238:         case (200 + 100 *  5) + "ms":
   239:         case (200 + 100 *  6) + "ms":
   240:         case (200 + 100 *  7) + "ms":
   241:         case (200 + 100 *  8) + "ms":
   242:         case (200 + 100 *  9) + "ms":
   243:         case (200 + 100 * 10) + "ms":
   244:         case (200 + 100 * 11) + "ms":
   245:         case (200 + 100 * 12) + "ms":
   246:         case (200 + 100 * 13) + "ms":
   247:         case (200 + 100 * 14) + "ms":
   248:         case (200 + 100 * 15) + "ms":
   249:           {
   250:             int ms = Integer.parseInt (command.substring (0, command.length () - 2));  //200..1700
   251:             //perl optdiv.pl 1500 100
   252:             //  x/100==x*1311>>>17 (0<=x<=4698) [1500*1311==1966500]
   253:             smrRepeatDelay = (ms - 200) * 1311 >>> 17;  //0..15
   254:             Keyboard.kbdSetRepeatDelay (smrRepeatDelay);
   255:             MainMemory.mmrWb (0x00ed003a, smrRepeatDelay);
   256:           }
   257:           break;
   258:         default:
   259:           System.out.println ("unknown action command " + command);
   260:         }
   261:       }
   262:     };
   263:     ButtonGroup delayGroup = new ButtonGroup ();
   264:     smrRepeatDelayMenu =
   265:       Multilingual.mlnText (
   266:         ComponentFactory.createMenu (
   267:           "Repeat delay",
   268:           Multilingual.mlnText (
   269:             ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay == -1, "Follow settings in SWITCH.X", delayListener),
   270:             "ja", "SWITCH.X の設定に従う"),
   271:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay ==  0, (200 + 100 *  0) + "ms", delayListener),
   272:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay ==  1, (200 + 100 *  1) + "ms", delayListener),
   273:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay ==  2, (200 + 100 *  2) + "ms", delayListener),
   274:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay ==  3, (200 + 100 *  3) + "ms", delayListener),
   275:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay ==  4, (200 + 100 *  4) + "ms", delayListener),
   276:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay ==  5, (200 + 100 *  5) + "ms", delayListener),
   277:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay ==  6, (200 + 100 *  6) + "ms", delayListener),
   278:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay ==  7, (200 + 100 *  7) + "ms", delayListener),
   279:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay ==  8, (200 + 100 *  8) + "ms", delayListener),
   280:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay ==  9, (200 + 100 *  9) + "ms", delayListener),
   281:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay == 10, (200 + 100 * 10) + "ms", delayListener),
   282:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay == 11, (200 + 100 * 11) + "ms", delayListener),
   283:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay == 12, (200 + 100 * 12) + "ms", delayListener),
   284:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay == 13, (200 + 100 * 13) + "ms", delayListener),
   285:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay == 14, (200 + 100 * 14) + "ms", delayListener),
   286:           ComponentFactory.createRadioButtonMenuItem (delayGroup, smrRepeatDelay == 15, (200 + 100 * 15) + "ms", delayListener)
   287:           ),
   288:         "ja", "リピート開始");
   289: 
   290:     //リピート間隔メニュー
   291:     ActionListener intervalListener = new ActionListener () {
   292:       @Override public void actionPerformed (ActionEvent ae) {
   293:         String command = ae.getActionCommand ();
   294:         switch (command) {
   295:         case "Follow settings in SWITCH.X":  //SWITCH.X の設定に従う
   296:           smrRepeatInterval =  -1;
   297:           Keyboard.kbdSetRepeatInterval (MainMemory.mmrRbs (0x00ed003b));
   298:           break;
   299:         case (30 + 5 *  0 *  0) + "ms":
   300:         case (30 + 5 *  1 *  1) + "ms":
   301:         case (30 + 5 *  2 *  2) + "ms":
   302:         case (30 + 5 *  3 *  3) + "ms":
   303:         case (30 + 5 *  4 *  4) + "ms":
   304:         case (30 + 5 *  5 *  5) + "ms":
   305:         case (30 + 5 *  6 *  6) + "ms":
   306:         case (30 + 5 *  7 *  7) + "ms":
   307:         case (30 + 5 *  8 *  8) + "ms":
   308:         case (30 + 5 *  9 *  9) + "ms":
   309:         case (30 + 5 * 10 * 10) + "ms":
   310:         case (30 + 5 * 11 * 11) + "ms":
   311:         case (30 + 5 * 12 * 12) + "ms":
   312:         case (30 + 5 * 13 * 13) + "ms":
   313:         case (30 + 5 * 14 * 14) + "ms":
   314:         case (30 + 5 * 15 * 15) + "ms":
   315:           {
   316:             int ms = Integer.parseInt (command.substring (0, command.length () - 2));  //30..1155
   317:             //perl optdiv.pl 1125 5
   318:             //  x/5==x*1639>>>13 (0<=x<=2733) [1125*1639==1843875]
   319:             smrRepeatInterval = (int) Math.sqrt ((double) ((ms - 30) * 1639 >>> 13));  //0..15
   320:             Keyboard.kbdSetRepeatInterval (smrRepeatInterval);
   321:             MainMemory.mmrWb (0x00ed003b, smrRepeatInterval);
   322:           }
   323:           break;
   324:         default:
   325:           System.out.println ("unknown action command " + command);
   326:         }
   327:       }
   328:     };
   329:     ButtonGroup intervalGroup = new ButtonGroup ();
   330:     smrRepeatIntervalMenu =
   331:       Multilingual.mlnText (
   332:         ComponentFactory.createMenu (
   333:           "Repeat interval",
   334:           Multilingual.mlnText (
   335:             ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval == -1, "Follow settings in SWITCH.X", intervalListener),
   336:             "ja", "SWITCH.X の設定に従う"),
   337:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval ==  0, (30 + 5 *  0 *  0) + "ms", intervalListener),
   338:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval ==  1, (30 + 5 *  1 *  1) + "ms", intervalListener),
   339:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval ==  2, (30 + 5 *  2 *  2) + "ms", intervalListener),
   340:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval ==  3, (30 + 5 *  3 *  3) + "ms", intervalListener),
   341:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval ==  4, (30 + 5 *  4 *  4) + "ms", intervalListener),
   342:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval ==  5, (30 + 5 *  5 *  5) + "ms", intervalListener),
   343:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval ==  6, (30 + 5 *  6 *  6) + "ms", intervalListener),
   344:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval ==  7, (30 + 5 *  7 *  7) + "ms", intervalListener),
   345:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval ==  8, (30 + 5 *  8 *  8) + "ms", intervalListener),
   346:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval ==  9, (30 + 5 *  9 *  9) + "ms", intervalListener),
   347:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval == 10, (30 + 5 * 10 * 10) + "ms", intervalListener),
   348:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval == 11, (30 + 5 * 11 * 11) + "ms", intervalListener),
   349:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval == 12, (30 + 5 * 12 * 12) + "ms", intervalListener),
   350:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval == 13, (30 + 5 * 13 * 13) + "ms", intervalListener),
   351:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval == 14, (30 + 5 * 14 * 14) + "ms", intervalListener),
   352:           ComponentFactory.createRadioButtonMenuItem (intervalGroup, smrRepeatInterval == 15, (30 + 5 * 15 * 15) + "ms", intervalListener)
   353:           ),
   354:         "ja", "リピート間隔");
   355: 
   356:     //ROMデバッガ起動フラグ
   357:     smrROMDBMenuItem =
   358:       Multilingual.mlnText (ComponentFactory.createCheckBoxMenuItem (smrROMDBOn, "ROM debugger start flag", listener), "ja", "ROM デバッガ起動フラグ");
   359: 
   360:     //メモリサイズ修正
   361:     smrModifyMemorySizeMenuItem =
   362:       Multilingual.mlnText (
   363:         ComponentFactory.createCheckBoxMenuItem (smrModifyMemorySizeOn, "Modify the memory size in SRAM", listener),
   364:         "ja", "SRAM にあるメモリサイズを修正する");
   365: 
   366:     //SRAMメニュー
   367:     ButtonGroup sizeGroup = new ButtonGroup ();
   368:     smrMenu =
   369:       ComponentFactory.createMenu (
   370:         "SRAM",
   371:         Multilingual.mlnText (
   372:           ComponentFactory.createMenuItem ("Zero-clear", listener),
   373:           "ja", "ゼロクリア"),
   374:         Multilingual.mlnText (
   375:           ComponentFactory.createMenuItem ("Import", listener),
   376:           "ja", "インポート"),
   377:         Multilingual.mlnText (
   378:           ComponentFactory.createMenuItem ("Export", listener),
   379:           "ja", "エクスポート"),
   380:         ComponentFactory.createHorizontalSeparator (),
   381:         Multilingual.mlnText (
   382:           ComponentFactory.createRadioButtonMenuItem (sizeGroup, smrSramSizeRequest >> 10 == 16, "16KB", listener),
   383:           "ja", "16KB"),
   384:         Multilingual.mlnText (
   385:           ComponentFactory.createRadioButtonMenuItem (sizeGroup, smrSramSizeRequest >> 10 == 32, "32KB", listener),
   386:           "ja", "32KB"),
   387:         Multilingual.mlnText (
   388:           ComponentFactory.createRadioButtonMenuItem (sizeGroup, smrSramSizeRequest >> 10 == 64, "64KB", listener),
   389:           "ja", "64KB"),
   390:         ComponentFactory.createHorizontalSeparator (),
   391:         Multilingual.mlnText (
   392:           ComponentFactory.createCheckBoxMenuItem (smrSRAMBusErrorOn, "Bus error when writing to SRAM", listener),
   393:           "ja", "SRAM への書き込み時のバスエラー")
   394:         );
   395: 
   396:     //起動デバイスメニュー
   397:     ButtonGroup bootGroup = new ButtonGroup ();
   398:     ActionListener bootListener = new ActionListener () {
   399:       @Override public void actionPerformed (ActionEvent ae) {
   400:         String command = ae.getActionCommand ();
   401:         smrParseBootDevice (
   402:           command.startsWith ("FDD ") ? "fd" + command.substring (4) :
   403:           command.startsWith ("SASI ") ? "hd" + command.substring (5) :
   404:           command.startsWith ("SCSI ") ? "sc" + command.substring (5) :
   405:           command.startsWith ("HFS ") ? "hf" + command.substring (4) :
   406:           command.equals ("STD") ? "std" :
   407:           "default");
   408:         if (smrBootDevice != -1) {  //メニューで起動デバイスが既定以外に設定されたとき
   409:           XEiJ.mpuSavedBootDevice = -1;  //保存されている起動デバイスを消す
   410:           XEiJ.mpuSavedROMBootHandle = -1;
   411:         }
   412:       }
   413:     };
   414:     JMenu bootMenuFDD = ComponentFactory.createMenu ("FDD");
   415:     for (int u = 0; u < FDC.FDC_MAX_UNITS; u++) {
   416:       bootMenuFDD.add (ComponentFactory.createRadioButtonMenuItem (
   417:         bootGroup, smrBootDevice == 0x9070 + (u << 8),
   418:         "FDD " + u, bootListener));
   419:     }
   420:     JMenu bootMenuSASI = ComponentFactory.createMenu ("SASI");
   421:     for (int u = 0; u < 16; u++) {
   422:       bootMenuSASI.add (ComponentFactory.createRadioButtonMenuItem (
   423:         bootGroup, smrBootDevice == 0x8000 + (u << 8),
   424:         "SASI " + u, bootListener));
   425:     }
   426:     JMenu bootMenuSCSI = ComponentFactory.createMenu ("SCSI");
   427:     for (int u = 0; u < 8; u++) {
   428:       bootMenuSCSI.add (ComponentFactory.createRadioButtonMenuItem (
   429:         bootGroup, smrBootDevice == 0xa000 && (smrROMBootHandle == SPC.SPC_HANDLE_EX + (u << 2) ||
   430:                                                smrROMBootHandle == SPC.SPC_HANDLE_IN + (u << 2)), "SCSI " + u, bootListener));
   431:     }
   432:     JMenu bootMenuHFS = ComponentFactory.createMenu ("HFS");
   433:     for (int u = 0; u < HFS.HFS_MAX_UNITS; u++) {
   434:       bootMenuHFS.add (ComponentFactory.createRadioButtonMenuItem (
   435:         bootGroup, smrBootDevice == 0xa000 && smrROMBootHandle == HFS.HFS_BOOT_HANDLE && HFS.hfsBootUnit == u,
   436:         "HFS " + u, bootListener));
   437:     }
   438:     smrBootMenu =
   439:       Multilingual.mlnText (
   440:         ComponentFactory.createMenu (
   441:           "Boot device",
   442:           Multilingual.mlnText (
   443:             ComponentFactory.createRadioButtonMenuItem (bootGroup, smrBootDevice == -1, "Follow settings in SWITCH.X", bootListener),
   444:             "ja", "SWITCH.X の設定に従う"),
   445:           smrSTDMenuItem = ComponentFactory.createRadioButtonMenuItem (bootGroup, smrBootDevice == 0x0000, "STD", bootListener),
   446:           bootMenuFDD,
   447:           bootMenuSASI,
   448:           bootMenuSCSI,
   449:           bootMenuHFS
   450:           ),
   451:         "ja", "起動デバイス");
   452: 
   453:   }  //smrInit()
   454: 
   455:   //smrParseBootDevice ()
   456:   //  起動デバイスの設定を読み取る
   457:   public static void smrParseBootDevice (String boot) {
   458:     smrBootDevice = -1;  //起動デバイス
   459:     smrROMBootHandle = -1;  //ROM起動ハンドル
   460:     smrRAMBootAddress = -1;  //RAM起動アドレス
   461:     boot = boot.toLowerCase ();
   462:     if (boot.equals ("std")) {  //std
   463:       smrBootDevice = 0x0000;  //STD 起動
   464:     } else if (boot.startsWith ("fd")) {  //fdN
   465:       int u = XEiJ.fmtParseInt (boot, 2, 0, FDC.FDC_MAX_UNITS - 1, FDC.FDC_MAX_UNITS);  //起動ユニット番号
   466:       if (u < FDC.FDC_MAX_UNITS) {
   467:         smrBootDevice = 0x9070 + (u << 8);  //FDD起動
   468:       }
   469:     } else if (boot.startsWith ("hd")) {  //hdN
   470:       int u = XEiJ.fmtParseInt (boot, 2, 0, 15, 16);  //起動ユニット番号
   471:       if (u < 16) {
   472:         smrBootDevice = 0x8000 + (u << 8);  //SASI起動
   473:       }
   474:     } else if (boot.startsWith ("sc")) {  //scN
   475:       int u = XEiJ.fmtParseInt (boot, 2, 0, 7, 8);
   476:       if (u < 8) {
   477:         smrBootDevice = 0xa000;  //ROM起動
   478:         smrROMBootHandle = SPC.SPC_HANDLE_EX + ((u & 7) << 2);  //仮に拡張SCSI起動にしておく。リセットしたとき拡張SCSIがなければ内蔵SCSIに読み替えられる
   479:       }
   480:     } else if (boot.startsWith ("hf")) {  //hfN
   481:       int u = XEiJ.fmtParseInt (boot, 2, 0, HFS.HFS_MAX_UNITS - 1, HFS.HFS_MAX_UNITS);  //起動ユニット番号
   482:       if (u < HFS.HFS_MAX_UNITS) {
   483:         HFS.hfsBootUnit = u;
   484:         smrBootDevice = 0xa000;  //ROM起動
   485:         smrROMBootHandle = HFS.HFS_BOOT_HANDLE;  //IPL起動ハンドル
   486:       }
   487:     } else if (boot.startsWith ("rom$")) {  //rom$X
   488:       int handle = XEiJ.fmtParseIntRadix (boot, 3, 0, 0x00ffffff, 0x01000000, 16);  //起動ハンドル
   489:       if (handle < 0x01000000) {
   490:         smrBootDevice = 0xa000;  //ROM起動
   491:         smrROMBootHandle = handle;
   492:       }
   493:     } else if (boot.startsWith ("ram$")) {  //ram$X
   494:       int handle = XEiJ.fmtParseIntRadix (boot, 3, 0, 0x00ffffff, 0x01000000, 16);  //起動ハンドル
   495:       if (handle < 0x01000000) {
   496:         smrBootDevice = 0xb000;  //RAM起動
   497:         smrRAMBootAddress = handle;
   498:       }
   499:     }
   500:   }  //smrParseBootDevice(String)
   501: 
   502:   //smrReset ()
   503:   //  SRAMリセット
   504:   //  ここでROMも上書きする
   505:   //  ROMを初期化してから呼び出すこと
   506:   //  SPC.spcReset()よりも後であること
   507:   public static void smrReset () {
   508:     smrWriteEnableOn = false;
   509: 
   510:     //SRAMの容量を変更する
   511:     {
   512:       smrSramCurrentSize = smrSramSizeRequest;
   513:       XEiJ.busSuper (MemoryMappedDevice.MMD_SMR, 0x00ed0000, 0x00ed0000 + smrSramSizeRequest);  //SMR SRAM
   514:       if (smrSramSizeRequest < 65536) {
   515:         XEiJ.busSuper (MemoryMappedDevice.MMD_NUL, 0x00ed0000 + smrSramSizeRequest, 0x00ed0000 + 65536);  //空き
   516:       }
   517:       System.out.printf (Multilingual.mlnJapanese ?
   518:                          "SRAM の容量は %dKB ($%08X-$%08X) です\n" :
   519:                          "Capacity of SRAM is %dKB ($%08X-$%08X)\n",
   520:                          smrSramCurrentSize >> 10, 0x00ed0000, 0x00ed0000 + smrSramCurrentSize - 1);
   521:     }
   522: 
   523:     //ROM起動ハンドルを調整する
   524:     //  ROM起動ハンドルが内蔵SCSIを指しているが内蔵SCSIがないとき
   525:     //    拡張SCSIがあるとき
   526:     //      ROM起動ハンドルを拡張SCSIにする
   527:     //    拡張SCSIがないとき
   528:     //      ROM起動ハンドルを消す
   529:     //      ROM起動のとき
   530:     //        STD起動にする
   531:     //  ROM起動ハンドルが拡張SCSIを指しているが拡張SCSIがないとき
   532:     //    内蔵SCSIがあるとき
   533:     //      ROM起動ハンドルを内蔵SCSIにする
   534:     //    内蔵SCSIがないとき
   535:     //      ROM起動ハンドルを消す
   536:     //      ROM起動のとき
   537:     //        STD起動にする
   538:     //  ROM起動ハンドルがHFSを指しているがHFSのディレクトリが設定されていないとき
   539:     //    ROM起動ハンドルを消す
   540:     //    ROM起動のとき
   541:     //      STD起動にする
   542:     //起動デバイス
   543:     if ((smrROMBootHandle & ~(7 << 2)) == SPC.SPC_HANDLE_IN && !SPC.spcSCSIINOn) {  //ROM起動ハンドルが内蔵SCSIを指しているが内蔵SCSIがないとき
   544:       if (SPC.spcSCSIEXOn) {  //拡張SCSIがあるとき
   545:         smrROMBootHandle = SPC.SPC_HANDLE_EX + (smrROMBootHandle & (7 << 2));  //ROM起動ハンドルを拡張SCSIにする
   546:         //MainMemory.mmrWb (0x00ed0070, MainMemory.mmrRbs (0x00ed0070) | 0x08);  //拡張フラグをセットする
   547:       } else {  //拡張SCSIがないとき
   548:         smrROMBootHandle = 0x00e80400;  //ROM起動ハンドルを消す
   549:         if (smrBootDevice == 0xa000) {  //ROM起動のとき
   550:           smrBootDevice = 0x0000;  //STD起動にする
   551:           smrSTDMenuItem.setSelected (true);
   552:         }
   553:       }
   554:     }
   555:     if ((smrROMBootHandle & ~(7 << 2)) == SPC.SPC_HANDLE_EX && !SPC.spcSCSIEXOn) {  //ROM起動ハンドルが拡張SCSIを指しているが拡張SCSIがないとき
   556:       if (SPC.spcSCSIINOn) {  //内蔵SCSIがあるとき
   557:         smrROMBootHandle = SPC.SPC_HANDLE_IN + (smrROMBootHandle & (7 << 2));  //ROM起動ハンドルを内蔵SCSIにする
   558:         //MainMemory.mmrWb (0x00ed0070, MainMemory.mmrRbs (0x00ed0070) & ~0x08);  //拡張フラグをクリアする
   559:       } else {  //内蔵SCSIがないとき
   560:         smrROMBootHandle = 0x00e80400;  //ROM起動ハンドルを消す
   561:         if (smrBootDevice == 0xa000) {  //ROM起動のとき
   562:           smrBootDevice = 0x0000;  //STD起動にする
   563:           smrSTDMenuItem.setSelected (true);
   564:         }
   565:       }
   566:     }
   567:     if (smrROMBootHandle == HFS.HFS_BOOT_HANDLE &&  //ROM起動ハンドルがHFSを指しているが
   568:         (!HFS.hfsUnitArray[HFS.hfsBootUnit].abuConnected ||
   569:          !HFS.hfsUnitArray[HFS.hfsBootUnit].abuInserted)) {  //HFSのディレクトリが設定されていないとき
   570:       smrROMBootHandle = 0x00e80400;  //ROM起動ハンドルを消す
   571:       if (smrBootDevice == 0xa000) {  //ROM起動のとき
   572:         smrBootDevice = 0x0000;  //STD起動にする
   573:         smrSTDMenuItem.setSelected (true);
   574:       }
   575:     }
   576:     //ここから再起動
   577:     if ((XEiJ.mpuROMBootHandle & ~(7 << 2)) == SPC.SPC_HANDLE_IN && !SPC.spcSCSIINOn) {  //ROM起動ハンドルが内蔵SCSIを指しているが内蔵SCSIがないとき
   578:       if (SPC.spcSCSIEXOn) {  //拡張SCSIがあるとき
   579:         XEiJ.mpuROMBootHandle = SPC.SPC_HANDLE_EX + (XEiJ.mpuROMBootHandle & (7 << 2));  //ROM起動ハンドルを拡張SCSIにする
   580:         //MainMemory.mmrWb (0x00ed0070, MainMemory.mmrRbs (0x00ed0070) | 0x08);  //拡張フラグをセットする
   581:       } else {  //拡張SCSIがないとき
   582:         XEiJ.mpuROMBootHandle = 0x00e80400;  //ROM起動ハンドルを消す
   583:         if (XEiJ.mpuBootDevice == 0xa000) {  //ROM起動のとき
   584:           XEiJ.mpuBootDevice = 0x0000;  //STD起動にする
   585:         }
   586:       }
   587:     }
   588:     if ((XEiJ.mpuROMBootHandle & ~(7 << 2)) == SPC.SPC_HANDLE_EX && !SPC.spcSCSIEXOn) {  //ROM起動ハンドルが拡張SCSIを指しているが拡張SCSIがないとき
   589:       if (SPC.spcSCSIINOn) {  //内蔵SCSIがあるとき
   590:         XEiJ.mpuROMBootHandle = SPC.SPC_HANDLE_IN + (XEiJ.mpuROMBootHandle & (7 << 2));  //ROM起動ハンドルを内蔵SCSIにする
   591:         //MainMemory.mmrWb (0x00ed0070, MainMemory.mmrRbs (0x00ed0070) & ~0x08);  //拡張フラグをクリアする
   592:       } else {  //内蔵SCSIがないとき
   593:         XEiJ.mpuROMBootHandle = 0x00e80400;  //ROM起動ハンドルを消す
   594:         if (XEiJ.mpuBootDevice == 0xa000) {  //ROM起動のとき
   595:           XEiJ.mpuBootDevice = 0x0000;  //STD起動にする
   596:         }
   597:       }
   598:     }
   599:     if (XEiJ.mpuROMBootHandle == HFS.HFS_BOOT_HANDLE &&  //ROM起動ハンドルがHFSを指しているが
   600:         (!HFS.hfsUnitArray[HFS.hfsBootUnit].abuConnected ||
   601:          !HFS.hfsUnitArray[HFS.hfsBootUnit].abuInserted)) {  //HFSのディレクトリが設定されていないとき
   602:       XEiJ.mpuROMBootHandle = 0x00e80400;  //ROM起動ハンドルを消す
   603:       if (XEiJ.mpuBootDevice == 0xa000) {  //ROM起動のとき
   604:         XEiJ.mpuBootDevice = 0x0000;  //STD起動にする
   605:       }
   606:     }
   607: 
   608:     smrOverride ();
   609: 
   610:   }  //smrReset()
   611: 
   612:   //smrOverride ()
   613:   //  SRAMの設定を上書きする
   614:   //  ここから再起動もSRAMに上書きする
   615:   public static void smrOverride () {
   616:     if (MainMemory.mmrRls (0x00ed0000) == 0x82773638 &&  //X68
   617:         MainMemory.mmrRls (0x00ed0004) == 0x30303057) {  //000W  初期化されている。初期化されていないときに上書きしても意味がない
   618:       //メモリサイズ
   619:       if (smrModifyMemorySizeOn) {
   620:         int memorySizeAddress = 0x00ed0008;
   621:         int memorySizeOld = MainMemory.mmrRls (memorySizeAddress);
   622:         int memorySizeNew = MainMemory.mmrMemorySizeCurrent;
   623:         if (memorySizeOld != memorySizeNew) {
   624:           MainMemory.mmrWl (memorySizeAddress, memorySizeNew);
   625:           System.out.printf (Multilingual.mlnJapanese ?
   626:                              "SRAM にあるメモリサイズを %dMB から %dMB に変更しました\n" :
   627:                              "Changed the memory size in SRAM from %dMB to %dMB\n",
   628:                              memorySizeOld >> 20,
   629:                              memorySizeNew >> 20);
   630:         }
   631:       }
   632:       //ROM起動ハンドル
   633:       int romHandleAddress = 0x00ed000c;
   634:       int romHandleOld = MainMemory.mmrRls (romHandleAddress);
   635:       int romHandleNew = XEiJ.mpuROMBootHandle != -1 ? XEiJ.mpuROMBootHandle : smrROMBootHandle;
   636:       if (romHandleNew != -1 &&
   637:           romHandleOld != romHandleNew) {
   638:         MainMemory.mmrWl (romHandleAddress, romHandleNew);
   639:         System.out.printf (Multilingual.mlnJapanese ?
   640:                            "SRAM にある ROM 起動ハンドルを $%08X から $%08X に変更しました\n" :
   641:                            "Changed the ROM boot handle in SRAM from $%08X to $%08X\n",
   642:                            romHandleOld,
   643:                            romHandleNew);
   644:       }
   645:       //RAM起動アドレス
   646:       int ramAddressAddress = 0x00ed0010;
   647:       int ramAddressOld = MainMemory.mmrRls (ramAddressAddress);
   648:       int ramAddressNew = smrRAMBootAddress;
   649:       if (ramAddressNew != -1 &&
   650:           ramAddressOld != ramAddressNew) {
   651:         MainMemory.mmrWl (ramAddressAddress, ramAddressNew);
   652:         System.out.printf (Multilingual.mlnJapanese ?
   653:                            "SRAM にある RAM 起動アドレスを $%08X から $%08X に変更しました\n" :
   654:                            "Changed the RAM boot address in SRAM from $%08X to $%08X\n",
   655:                            ramAddressOld,
   656:                            ramAddressNew);
   657:       }
   658:       //起動デバイス
   659:       int deviceAddress = 0x00ed0018;
   660:       int deviceOld = MainMemory.mmrRwz (deviceAddress);
   661:       int deviceNew = XEiJ.mpuBootDevice != -1 ? XEiJ.mpuBootDevice : smrBootDevice;
   662:       if (deviceNew != -1 &&
   663:           deviceOld != deviceNew) {
   664:         MainMemory.mmrWw (deviceAddress, deviceNew);
   665:         System.out.printf (Multilingual.mlnJapanese ?
   666:                            "SRAM にある起動デバイスを %s から %s に変更しました\n" :
   667:                            "Changed the boot device in SRAM from %s to %s\n",
   668:                            smrBootDescription (romHandleOld, ramAddressOld, deviceOld),
   669:                            smrBootDescription (romHandleNew, ramAddressNew, deviceNew));
   670:       }
   671:       //リピート開始
   672:       int repeatDelayAddress = 0x00ed003a;
   673:       int repeatDelayOld = MainMemory.mmrRbz (repeatDelayAddress);
   674:       int repeatDelayNew = smrRepeatDelay;
   675:       if (repeatDelayNew != -1 &&
   676:           repeatDelayOld != repeatDelayNew) {
   677:         MainMemory.mmrWb (repeatDelayAddress, repeatDelayNew);
   678:         System.out.printf (Multilingual.mlnJapanese ?
   679:                            "SRAM にあるリピート開始を %dms から %dms に変更しました\n" :
   680:                            "Changed the repeat delay in SRAM from %dms to %dms\n",
   681:                            200 + 100 * (repeatDelayOld & 15),
   682:                            200 + 100 * (repeatDelayNew & 15));
   683:       }
   684:       //リピート間隔
   685:       int repeatIntervalAddress = 0x00ed003b;
   686:       int repeatIntervalOld = MainMemory.mmrRbz (repeatIntervalAddress);
   687:       int repeatIntervalNew = smrRepeatInterval;
   688:       if (repeatIntervalNew != -1 &&
   689:           repeatIntervalOld != repeatIntervalNew) {
   690:         MainMemory.mmrWb (repeatIntervalAddress, repeatIntervalNew);
   691:         System.out.printf (Multilingual.mlnJapanese ?
   692:                            "SRAM にあるリピート間隔を %dms から %dms に変更しました\n" :
   693:                            "Changed the repeat interval in SRAM from %dms to %dms\n",
   694:                            30 + 5 * (repeatDelayOld & 15),
   695:                            30 + 5 * (repeatDelayNew & 15));
   696:       }
   697:       //ROMデバッガ起動フラグ
   698:       int romdbAddress = 0x00ed0058;
   699:       int romdbOld = MainMemory.mmrRbz (romdbAddress);
   700:       int romdbNew = ((XEiJ.currentModel.getIPLROM () == 130 &&
   701:                        !(XEiJ.currentAccelerator == XEiJ.ACCELERATOR_060TURBO ||
   702:                          XEiJ.currentAccelerator == XEiJ.ACCELERATOR_060TURBOPRO) &&
   703:                        !ROM.romIPLROM16On &&  //IPLROM 1.3で
   704:                        ROM.romROM30Data == null) ? 0x00 :  //ROM30.DATが指定されていないとき、ROMデバッガがないので常にOFF
   705:                       smrROMDBOn ? 0xff : 0x00);
   706:       if (romdbOld != romdbNew) {
   707:         MainMemory.mmrWb (romdbAddress, romdbNew);
   708:         if (romdbNew == 0x00) {
   709:           System.out.printf (Multilingual.mlnJapanese ?
   710:                              "SRAM にある ROM デバッガ起動フラグを OFF にしました\n" :
   711:                              "Turned off the ROM debugger startup flag in SRAM\n");
   712:         } else {
   713:           System.out.printf (Multilingual.mlnJapanese ?
   714:                              "SRAM にある ROM デバッガ起動フラグを ON にしました\n" :
   715:                              "Turned on the ROM debugger startup flag in SRAM\n");
   716:         }
   717:       }
   718:       //SASIハードディスクの最大数
   719:       int hdMaxAddress = 0x00ed005a;
   720:       int hdMaxOld = MainMemory.mmrRbz (hdMaxAddress);
   721:       int hdMaxNew = SPC.spcSCSIINOn ? 0 : HDC.hdcHDMax;
   722:       if (hdMaxOld != hdMaxNew) {
   723:         MainMemory.mmrWb (hdMaxAddress, hdMaxNew);
   724:         System.out.printf (Multilingual.mlnJapanese ?
   725:                            "SRAM にある SASI ハードディスクの最大数を %d から %d に変更しました\n" :
   726:                            "Changed the maximum number of SASI hard disks in SRAM from %d to %d\n",
   727:                            hdMaxOld, hdMaxNew);
   728:       }
   729:     }
   730:     //「ここから再起動」をキャンセルする
   731:     //XEiJ.mpuBootDevice = -1;
   732:     //XEiJ.mpuROMBootHandle = -1;
   733:   }
   734: 
   735:   //s = smrBootDescription (code, romHandle, ramAddress)
   736:   //  device      $00ED0018  起動デバイス
   737:   //                           $0000  STD  FD→HD→ROM→RAM
   738:   //                           $8xxx  HD
   739:   //                           $9xxx  FD
   740:   //                           $Axxx  ROM  ROM起動ハンドルからROM起動アドレスを取り出して呼び出す
   741:   //                                       ROM起動ハンドルがバスエラーになるときはSTDで起動する
   742:   //                           $Bxxx  RAM  RAM起動アドレスを呼び出す。先頭が$60でなければならない
   743:   //  romHandle   $00ED000C  ROM起動ハンドル
   744:   //  ramAddress  $00ED0010  RAM起動アドレス
   745:   public static String smrBootDescription (int romHandle, int ramAddress, int device) {
   746:     switch (device & 0xf000) {
   747:     case 0x8000:
   748:       return "HD" + (device >> 8 & 15);
   749:     case 0x9000:
   750:       return "2HD" + (device >> 8 & 3);
   751:     case 0xa000:
   752:       return ((romHandle & ~(7 << 2)) == SPC.SPC_HANDLE_IN ? "SCSI" + ((romHandle >> 2) & 7) :   //内蔵SCSI
   753:               (romHandle & ~(7 << 2)) == SPC.SPC_HANDLE_EX ? "SCSI" + ((romHandle >> 2) & 7) :   //拡張SCSI
   754:               "ROM$" + XEiJ.fmtHex6 (romHandle));
   755:     case 0xb000:
   756:       return "RAM$" + XEiJ.fmtHex6 (ramAddress);
   757:     default:
   758:       return "STD";
   759:     }
   760:   }
   761: 
   762:   //smrClear ()
   763:   //  SRAMクリア
   764:   public static void smrClear () {
   765:     if (JOptionPane.showConfirmDialog (
   766:       XEiJ.frmFrame,
   767:       Multilingual.mlnJapanese ? "SRAM をクリアしますか?" : "Do you want to clear SRAM?",
   768:       Multilingual.mlnJapanese ? "確認" : "Confirmation",
   769:       JOptionPane.YES_NO_OPTION,
   770:       JOptionPane.PLAIN_MESSAGE) == JOptionPane.YES_OPTION) {
   771:       Arrays.fill (MainMemory.mmrM8, 0x00ed0000, 0x00ed0000 + 65536, (byte) 0x00);
   772:     }
   773:   }  //smrClear()
   774: 
   775:   //smrLoad ()
   776:   //  SRAM読み込み
   777:   public static void smrLoad () {
   778:     JFileChooser2 fileChooser = new JFileChooser2 ();
   779:     fileChooser.setFileFilter (new javax.swing.filechooser.FileFilter () {  //java.io.FileFilterと紛らわしい
   780:       @Override public boolean accept (File file) {
   781:         String name = file.getName ();
   782:         String upperName = name.toUpperCase ();
   783:         return (file.isDirectory () ||
   784:                 (file.isFile () &&
   785:                  upperName.startsWith ("SRAM")));
   786:       }
   787:       @Override public String getDescription () {
   788:         return (Multilingual.mlnJapanese ?
   789:                 "SRAM データファイル (SRAM*.*)" :
   790:                 "SRAM data files (SRAM*.*)");
   791:       }
   792:     });
   793:     if (fileChooser.showOpenDialog (null) == JFileChooser.APPROVE_OPTION) {
   794:       File file = fileChooser.getSelectedFile ();
   795:       String name = file.getPath ();
   796:       if (!smrLoadData (name)) {  //読み込めなかった
   797:         JOptionPane.showMessageDialog (null,
   798:                                        Multilingual.mlnJapanese ?
   799:                                        name + " のサイズが違います" :
   800:                                        name + " has wrong size");
   801:         return;
   802:       }
   803:     }
   804:   }  //smrLoad()
   805: 
   806:   //success = smrLoadData (name)
   807:   //  SRAMのイメージファイルを読み込む
   808:   public static boolean smrLoadData (String name) {
   809:     byte[] array = XEiJ.rscGetFile (name, smrSramSizeRequest);
   810:     if (array != null) {  //読み込めた
   811:       System.arraycopy (array, 0, MainMemory.mmrM8, 0x00ed0000, smrSramSizeRequest);  //SRAMにコピーする
   812:       if (smrSramSizeRequest < 65536) {
   813:         Arrays.fill (MainMemory.mmrM8, 0x00ed0000 + smrSramSizeRequest, 0x00ed0000 + 65536, (byte) 0x00);  //空き
   814:       }
   815:       return true;
   816:     }
   817:     return false;
   818:   }
   819: 
   820:   //smrSave ()
   821:   //  SRAM書き出し
   822:   public static void smrSave () {
   823:     JFileChooser2 fileChooser = new JFileChooser2 ();
   824:     fileChooser.setFileFilter (new javax.swing.filechooser.FileFilter () {  //java.io.FileFilterと紛らわしい
   825:       @Override public boolean accept (File file) {
   826:         String name = file.getName ();
   827:         String upperName = name.toUpperCase ();
   828:         return (file.isDirectory () ||
   829:                 (file.isFile () &&
   830:                  upperName.startsWith ("SRAM")));
   831:       }
   832:       @Override public String getDescription () {
   833:         return (Multilingual.mlnJapanese ?
   834:                 "SRAM データファイル (SRAM*.*)" :
   835:                 "SRAM data files (SRAM*.*)");
   836:       }
   837:     });
   838:     if (fileChooser.showSaveDialog (null) == JFileChooser.APPROVE_OPTION) {
   839:       XEiJ.rscPutFile (fileChooser.getSelectedFile ().getPath (), MainMemory.mmrM8, 0x00ed0000, smrSramSizeRequest);
   840:     }
   841:   }  //smrSave()
   842: 
   843: }  //class SRAM