M68kException.java
     1: //========================================================================================
     2: //  M68kException.java
     3: //    en:M68k exception
     4: //    ja:M68kの例外
     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: //  throwするオブジェクトは1個だけで個々の例外の情報は持たない
    15: //  例外の情報をフィールドに格納してからthrowする
    16: //  プログラムカウンタはバスエラーとアドレスエラーのときはpc0、それ以外はpcを用いる
    17: //----------------------------------------------------------------------------------------
    18: 
    19: package xeij;
    20: 
    21: import java.lang.*;  //Boolean,Character,Class,Comparable,Double,Exception,Float,IllegalArgumentException,Integer,Long,Math,Number,Object,Runnable,SecurityException,String,StringBuilder,System
    22: 
    23: public class M68kException extends Exception {
    24: 
    25:   public static final boolean M6E_DEBUG_ERROR = false;
    26: 
    27:   //特殊例外
    28:   public static final int M6E_INSTRUCTION_BREAK_POINT = -1;  //命令ブレークポイント
    29:   public static final int M6E_WAIT_EXCEPTION          = -2;  //待機例外
    30: 
    31:   //例外ベクタ番号
    32:   //  F=スタックされたPCは命令の先頭を指す
    33:   //  N=スタックされたPCは次の命令を指す
    34:   public static final int M6E_RESET_INITIAL_SSP              =  0;  //0000     012346  Reset Initial Interrupt Stack Pointer
    35:   public static final int M6E_RESET_INITIAL_PC               =  1;  //0004     012346  Reset Initial Program Counter
    36:   public static final int M6E_ACCESS_FAULT                   =  2;  //4008  F  012346  Access Fault アクセスフォルト
    37:   public static final int M6E_ADDRESS_ERROR                  =  3;  //200C  F  012346  Address Error アドレスエラー
    38:   public static final int M6E_ILLEGAL_INSTRUCTION            =  4;  //0010  F  012346  Illegal Instruction 不当命令
    39:   public static final int M6E_DIVIDE_BY_ZERO                 =  5;  //2014  N  012346  Integer Divide by Zero ゼロ除算
    40:   public static final int M6E_CHK_INSTRUCTION                =  6;  //2018  N  012346  CHK, CHK2 instructions CHK命令
    41:   public static final int M6E_TRAPV_INSTRUCTION              =  7;  //201C  N  012346  FTRAPcc, TRAPcc, TRAPV instructions TRAPV命令
    42:   public static final int M6E_PRIVILEGE_VIOLATION            =  8;  //0020  F  012346  Privilege Violation 特権違反
    43:   public static final int M6E_TRACE                          =  9;  //2024  N  012346  Trace トレース
    44:   public static final int M6E_LINE_1010_EMULATOR             = 10;  //0028  F  012346  Line 1010 Emulator (Unimplemented A-Line opcode) ライン1010エミュレータ(SXコール)
    45:   public static final int M6E_LINE_1111_EMULATOR             = 11;  //002C  F  012346  Line 1111 Emulator (Unimplemented F-Line opcode) ライン1111エミュレータ(DOSコール,FEファンクションコール)
    46:   public static final int M6E_FP_UNIMPLEMENTED_INSTRUCTION   = 11;  //202C  N  -----6  未実装浮動小数点命令
    47:   public static final int M6E_FP_DISABLED                    = 11;  //402C  N  -----6  浮動小数点無効
    48:   public static final int M6E_EMULATOR_INTERRUPT             = 12;  //0030  N  -----S  エミュレータ割り込み
    49:   public static final int M6E_COPROCESSOR_PROTOCOL_VIOLATION = 13;  //0034     ---C--  コプロセッサプロトコル違反
    50:   public static final int M6E_FORMAT_ERROR                   = 14;  //0038  F  -12346  フォーマットエラー
    51:   public static final int M6E_UNINITIALIZED_INTERRUPT        = 15;  //003C  N  012346  未初期化割り込み
    52:   public static final int M6E_SPURIOUS_INTERRUPT             = 24;  //0060  N  012346  スプリアス割り込み
    53:   public static final int M6E_LEVEL_1_INTERRUPT_AUTOVECTOR   = 25;  //0064  N  012346  レベル1割り込みオートベクタ(FDC,FDD,ハードディスク,プリンタ)
    54:   public static final int M6E_LEVEL_2_INTERRUPT_AUTOVECTOR   = 26;  //0068  N  012346  レベル2割り込みオートベクタ(拡張I/Oスロット)
    55:   public static final int M6E_LEVEL_3_INTERRUPT_AUTOVECTOR   = 27;  //006C  N  012346  レベル3割り込みオートベクタ(DMAコントローラ転送終了など)
    56:   public static final int M6E_LEVEL_4_INTERRUPT_AUTOVECTOR   = 28;  //0070  N  012346  レベル4割り込みオートベクタ(拡張I/Oスロット)
    57:   public static final int M6E_LEVEL_5_INTERRUPT_AUTOVECTOR   = 29;  //0074  N  012346  レベル5割り込みオートベクタ(SCC RS-232C,マウス)
    58:   public static final int M6E_LEVEL_6_INTERRUPT_AUTOVECTOR   = 30;  //0078  N  012346  レベル6割り込みオートベクタ(MFP 各種タイマ,KEY,同期など)
    59:   public static final int M6E_LEVEL_7_INTERRUPT_AUTOVECTOR   = 31;  //007C  N  012346  レベル7割り込みオートベクタ(NMI)
    60:   public static final int M6E_TRAP_0_INSTRUCTION_VECTOR      = 32;  //0080  N  012346  TRAP#0命令ベクタ
    61:   public static final int M6E_TRAP_1_INSTRUCTION_VECTOR      = 33;  //0084  N  012346  TRAP#1命令ベクタ(MPCM,BGDRV)
    62:   public static final int M6E_TRAP_2_INSTRUCTION_VECTOR      = 34;  //0088  N  012346  TRAP#2命令ベクタ(PCM8)
    63:   public static final int M6E_TRAP_3_INSTRUCTION_VECTOR      = 35;  //008C  N  012346  TRAP#3命令ベクタ(ZMUSIC,ZMSC3,MIDDRV)
    64:   public static final int M6E_TRAP_4_INSTRUCTION_VECTOR      = 36;  //0090  N  012346  TRAP#4命令ベクタ(MXDRV,MADRV,MLD,MCDRV)
    65:   public static final int M6E_TRAP_5_INSTRUCTION_VECTOR      = 37;  //0094  N  012346  TRAP#5命令ベクタ(CDC)
    66:   public static final int M6E_TRAP_6_INSTRUCTION_VECTOR      = 38;  //0098  N  012346  TRAP#6命令ベクタ
    67:   public static final int M6E_TRAP_7_INSTRUCTION_VECTOR      = 39;  //009C  N  012346  TRAP#7命令ベクタ
    68:   public static final int M6E_TRAP_8_INSTRUCTION_VECTOR      = 40;  //00A0  N  012346  TRAP#8命令ベクタ(ROMデバッガがブレークポイントに使用)M6E_
    69:   public static final int M6E_TRAP_9_INSTRUCTION_VECTOR      = 41;  //00A4  N  012346  TRAP#9命令ベクタ(デバッガがブレークポイントに使用)
    70:   public static final int M6E_TRAP_10_INSTRUCTION_VECTOR     = 42;  //00A8  N  012346  TRAP#10命令ベクタ(POWER OFFまたはリセット)
    71:   public static final int M6E_TRAP_11_INSTRUCTION_VECTOR     = 43;  //00AC  N  012346  TRAP#11命令ベクタ(BREAK)
    72:   public static final int M6E_TRAP_12_INSTRUCTION_VECTOR     = 44;  //00B0  N  012346  TRAP#12命令ベクタ(COPY)
    73:   public static final int M6E_TRAP_13_INSTRUCTION_VECTOR     = 45;  //00B4  N  012346  TRAP#13命令ベクタ(^C)
    74:   public static final int M6E_TRAP_14_INSTRUCTION_VECTOR     = 46;  //00B8  N  012346  TRAP#14命令ベクタ(エラー表示)
    75:   public static final int M6E_TRAP_15_INSTRUCTION_VECTOR     = 47;  //00BC  N  012346  TRAP#15命令ベクタ(IOCSコール)
    76:   public static final int M6E_FP_BRANCH_SET_UNORDERED        = 48;  //00C0  F  --CC46  浮動小数点比較不能状態での分岐またはセット
    77:   public static final int M6E_FP_INEXACT_RESULT              = 49;  //00C4  N  --CC46  浮動小数点不正確な結果
    78:   //                                                                     30C4  N
    79:   public static final int M6E_FP_DIVIDE_BY_ZERO              = 50;  //00C8  N  --CC46  浮動小数点ゼロによる除算
    80:   public static final int M6E_FP_UNDERFLOW                   = 51;  //00CC  N  --CC46  浮動小数点アンダーフロー
    81:   //                                                                     30CC  N
    82:   public static final int M6E_FP_OPERAND_ERROR               = 52;  //00D0  N  --CC46  浮動小数点オペランドエラー
    83:   //                                                                     30D0  N
    84:   public static final int M6E_FP_OVERFLOW                    = 53;  //00D4  N  --CC46  浮動小数点オーバーフロー
    85:   //                                                                     30D4  N
    86:   public static final int M6E_FP_SIGNALING_NAN               = 54;  //00D8  N  --CC46  浮動小数点シグナリングNAN
    87:   //                                                                     30D8  N
    88:   public static final int M6E_FP_UNSUPPORTED_DATA_TYPE       = 55;  //00DC  N  ----46  浮動小数点未実装データ型(pre- 非正規化数)
    89:   //                                                                     20DC  N  ----46  浮動小数点未実装データ型(パックトデシマル)
    90:   //                                                                     30DC  N  ----46  浮動小数点未実装データ型(post- 非正規化数)
    91:   public static final int M6E_MMU_CONFIGULATION_ERROR        = 56;  // 0E0  N  --M3--  MMUコンフィギュレーションエラー
    92:   public static final int M6E_MMU_ILLEGAL_OPERATION_ERROR    = 57;  // 0E4     --M---  MMU不当操作エラー
    93:   public static final int M6E_MMU_ACCESS_LEVEL_VIOLATION     = 58;  // 0E8     --M---  MMUアクセスレベル違反
    94:   //  未実装実効アドレス(MC68060)
    95:   //    ベクタ番号60、フォーマット0。PCは例外を発生させた命令
    96:   //      Fop.X #<data>,FPn
    97:   //      Fop.P #<data>,FPn
    98:   //      FMOVEM.L #<data>,#<data>,FPSR/FPIAR
    99:   //      FMOVEM.L #<data>,#<data>,FPCR/FPIAR
   100:   //      FMOVEM.L #<data>,#<data>,FPCR/FPSR
   101:   //      FMOVEM.L #<data>,#<data>,#<data>,FPCR/FPSR/FPIAR
   102:   //      FMOVEM.X <ea>,Dn
   103:   //      FMOVEM.X Dn,<ea>
   104:   public static final int M6E_UNIMPLEMENTED_EFFECTIVE        = 60;  //00F0  F  -----6  未実装実効アドレス
   105:   //  未実装整数命令(MC68060)
   106:   //    ベクタ番号61、フォーマット0。PCは例外を発生させた命令
   107:   //      MULU.L <ea>,Dh:Dl
   108:   //      MULS.L <ea>,Dh:Dl
   109:   //      DIVU.L <ea>,Dr:Dq
   110:   //      DIVS.L <ea>,Dr:Dq
   111:   //      CAS2.W Dc1:Dc2,Du1:Du2,(Rn1):(Rn2)
   112:   //      CAS2.L Dc1:Dc2,Du1:Du2,(Rn1):(Rn2)
   113:   //      CHK2.B <ea>,Rn
   114:   //      CHK2.W <ea>,Rn
   115:   //      CHK2.L <ea>,Rn
   116:   //      CMP2.B <ea>,Rn
   117:   //      CMP2.W <ea>,Rn
   118:   //      CMP2.L <ea>,Rn
   119:   //      CAS.W Dc,Du,<ea> (misaligned <ea>)
   120:   //      CAS.L Dc,Du,<ea> (misaligned <ea>)
   121:   //      MOVEP.W (d16,Ar),Dq
   122:   //      MOVEP.L (d16,Ar),Dq
   123:   //      MOVEP.W Dq,(d16,Ar)
   124:   //      MOVEP.L Dq,(d16,Ar)
   125:   public static final int M6E_UNIMPLEMENTED_INSTRUCTION      = 61;  //00F4  F  -----6  未実装整数命令
   126: 
   127:   public static final String[] M6E_ERROR_NAME = {
   128:     "undefined exception #0",  //0
   129:     "undefined exception #1",  //1
   130:     "Access fault",  //2
   131:     "Address error",  //3
   132:     "Illegal instruction",  //4
   133:     "Divide by zero",  //5
   134:     "CHK instruction",  //6
   135:     "Trapv instruction",  //7
   136:     "Privilege violation",  //8
   137:     "Trace",  //9
   138:     "Line 1010 emulator",  //10
   139:     "Line 1111 emulator",  //11
   140:     "Emulator interrupt",  //12
   141:     "Coprocessor protocol violation",  //13
   142:     "Format error",  //14
   143:     "Uninitialized interrupt",  //15
   144:     "undefined exception #16",  //16
   145:     "undefined exception #17",  //17
   146:     "undefined exception #18",  //18
   147:     "undefined exception #19",  //19
   148:     "undefined exception #20",  //20
   149:     "undefined exception #21",  //21
   150:     "undefined exception #22",  //22
   151:     "undefined exception #23",  //23
   152:     "Spurious interrupt",  //24
   153:     "Level 1 interrupt autovector",  //25
   154:     "Level 2 interrupt autovector",  //26
   155:     "Level 3 interrupt autovector",  //27
   156:     "Level 4 interrupt autovector",  //28
   157:     "Level 5 interrupt autovector",  //29
   158:     "Level 6 interrupt autovector",  //30
   159:     "Level 7 interrupt autovector",  //31
   160:     "TRAP #0 instruction vector",  //32
   161:     "TRAP #1 instruction vector",  //33
   162:     "TRAP #2 instruction vector",  //34
   163:     "TRAP #3 instruction vector",  //35
   164:     "TRAP #4 instruction vector",  //36
   165:     "TRAP #5 instruction vector",  //37
   166:     "TRAP #6 instruction vector",  //38
   167:     "TRAP #7 instruction vector",  //39
   168:     "TRAP #8 instruction vector",  //40
   169:     "TRAP #9 instruction vector",  //41
   170:     "TRAP #10 instruction vector",  //42
   171:     "TRAP #11 instruction vector",  //43
   172:     "TRAP #12 instruction vector",  //44
   173:     "TRAP #13 instruction vector",  //45
   174:     "TRAP #14 instruction vector",  //46
   175:     "TRAP #15 instruction vector",  //47
   176:     "FP branch/set on unordered ",  //48
   177:     "FP inexact result",  //49
   178:     "FP divide by zero",  //50
   179:     "FP underflow",  //51
   180:     "FP operand error",  //52
   181:     "FP overflow",  //53
   182:     "FP signaling NAN",  //54
   183:     "FP unsupported data type",  //55
   184:     "MMU configulation error",  //56
   185:     "MMU illegal operation error",  //57
   186:     "MMU access level violation",  //58
   187:     "undefined exception #59",  //59
   188:     "Unimplemented effective address",  //60
   189:     "Unimplemented instruction",  //61
   190:     "undefined exception #62",  //62
   191:     "undefined exception #63",  //63
   192:   };
   193: 
   194:   public static M68kException m6eSignal;  //throwする唯一のインスタンス
   195:   public static int m6eNumber;  //ベクタ番号。0~255
   196:   public static int m6eAddress;  //アクセスアドレス
   197:   public static int m6eDirection;  //転送方向。0=WRITE,1=READ
   198:   public static int m6eSize;  //オペレーションサイズ。0=BYTE,1=WORD,2=LONG
   199: 
   200:   //  MC68060のページフォルトに関する考察
   201:   //    ページフォルトが発生すると、プレデクリメントとポストインクリメントによるアドレスレジスタの変化がすべてキャンセルされる
   202:   //      MOVE.B (A0)+,(A0)+またはMOVE.B -(A0),-(A0)でソースまたはデスティネーションでページフォルトが発生したとき、
   203:   //      どの組み合わせでもA0は命令開始時の値のままアクセスフォルトハンドラに移行する
   204:   //    RTEでページフォルトを発生させた命令に復帰すると、ソースをリードするところからやり直す
   205:   //      MOVE.B <mem>,<mem>のデスティネーションのライトでページフォルトが発生したとき、ソースのリードが2回行われる
   206:   //      これはMC68060ユーザーズマニュアルの7.10 BUS SYNCHRONIZATIONに書かれており、
   207:   //      060turboでも、ページフォルトのハンドラでソースを書き換えると結果に反映されることから、リードが再実行されていることを確認できる
   208:   //      リードすると値が変化する可能性のあるデバイスから非常駐の可能性のあるページに転送するとき、MOVE.B <mem>,<mem>を使ってはいけない
   209:   //        http://cache.freescale.com/files/32bit/doc/ref_manual/MC68060UM.pdf
   210: 
   211:   //  FSLW  Fault Status Long Word
   212:   //      31  30  29  28  27  26  25  24  23  22  21  20  19  18  17  16  15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
   213:   //    ┏━━━━━━━┯━┯━┯━┯━━━┯━━━┯━━━┯━━━━━┯━┯━┯━┯━┯━┯━┯━┯━┯━┯━┯━┯━┯━┯━┯━┯━┓
   214:   //    ┃              │MA│  │LK│  RW  │ SIZE │  TT  │    TM    │IO│PBE SBE PTA PTB IL│PF│SP│WP│TWE RE│WE│TTR BPE    SEE┃
   215:   //    ┗━━━━━━━┷━┷━┷━┷━━━┷━━━┷━━━┷━━━━━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┛
   216:   public static final int M6E_FSLW_MISALIGNED         = 1 << 27;  //MA    Misaligned Access
   217:   public static final int M6E_FSLW_LOCKED             = 1 << 25;  //LK    Locked Transfer
   218:   public static final int M6E_FSLW_READ_AND_WRITE     = 3 << 23;  //RW    Read and Write
   219:   public static final int M6E_FSLW_RW_WRITE           = 1 << 23;  //        Write
   220:   public static final int M6E_FSLW_RW_READ            = 2 << 23;  //        Read
   221:   public static final int M6E_FSLW_RW_MODIFY          = 3 << 23;  //        Read-Modify-Write
   222:   public static final int M6E_FSLW_TRANSFER_SIZE      = 3 << 21;  //SIZE  Transfer Size
   223:   public static final int M6E_FSLW_SIZE_LONG          = 0 << 21;  //        Long    マニュアルが間違っているので注意
   224:   public static final int M6E_FSLW_SIZE_BYTE          = 1 << 21;  //        Byte    マニュアルが間違っているので注意
   225:   public static final int M6E_FSLW_SIZE_WORD          = 2 << 21;  //        Word    マニュアルが間違っているので注意
   226:   public static final int M6E_FSLW_SIZE_QUAD          = 3 << 21;  //        Double Precision or MOVE16
   227:   public static final int M6E_FSLW_TRANSFER_TYPE      = 3 << 19;  //TT    Transfer Type
   228:   public static final int M6E_FSLW_TT_NORMAL          = 0 << 19;  //        Normal Access
   229:   public static final int M6E_FSLW_TT_MOVE16          = 1 << 19;  //        MOVE16 Access
   230:   public static final int M6E_FSLW_TT_ALTERNATE       = 2 << 19;  //        Alternate Logical Function Code Access, Debug Access
   231:   public static final int M6E_FSLW_TT_ACKNOWLEDGE     = 3 << 19;  //        Acknowledge Access, Low-Power Stop Broadcast
   232:   public static final int M6E_FSLW_TRANSFER_MODIFIER  = 7 << 16;  //TM    Transfer Modifier
   233:   public static final int M6E_FSLW_TM_CACHE_PUSH      = 0 << 16;  //        Data Cache Push Access
   234:   public static final int M6E_FSLW_TM_USER_DATA       = 1 << 16;  //        User Data Access
   235:   public static final int M6E_FSLW_TM_USER_CODE       = 2 << 16;  //        User Code Access
   236:   public static final int M6E_FSLW_TM_MMU_DATA        = 3 << 16;  //        MMU Table Search Data Access
   237:   public static final int M6E_FSLW_TM_MMU_CODE        = 4 << 16;  //        MMU Table Search Code Access
   238:   public static final int M6E_FSLW_TM_SUPER_DATA      = 5 << 16;  //        Supervisor Data Access
   239:   public static final int M6E_FSLW_TM_SUPER_CODE      = 6 << 16;  //        Supervisor Code Access
   240:   public static final int M6E_FSLW_TM_DATA            = 1 << 16;  //        Data Access
   241:   public static final int M6E_FSLW_TM_CODE            = 2 << 16;  //        Code Access
   242:   public static final int M6E_FSLW_TM_SUPERVISOR      = 4 << 16;  //        Supervisor Access
   243:   public static final int M6E_FSLW_INSTRUCTION        = 1 << 15;  //IO    Instruction or Operand
   244:   public static final int M6E_FSLW_IOMA_FIRST         = 0 << 15 | 0 << 27;  //Fault occurred on the first access of a misaligned transfer, or to the only access of an aligned transfer
   245:   public static final int M6E_FSLW_IOMA_SECOND        = 0 << 15 | 1 << 27;  //Fault occurred on the second or later access of a misaligned transfer
   246:   public static final int M6E_FSLW_IOMA_OPWORD        = 1 << 15 | 0 << 27;  //Fault occurred on an instruction opword fetch
   247:   public static final int M6E_FSLW_IOMA_EXWORD        = 1 << 15 | 1 << 27;  //Fault occurred on a fetch of an extension word
   248:   public static final int M6E_FSLW_PUSH_BUFFER        = 1 << 14;  //PBE   Push Buffer Bus Error
   249:   public static final int M6E_FSLW_STORE_BUFFER       = 1 << 13;  //SBE   Store Buffer Bus Error
   250:   public static final int M6E_FSLW_ROOT_DESCRIPTOR    = 1 << 12;  //PTA   Pointer A Fault
   251:   public static final int M6E_FSLW_POINTER_DESCRIPTOR = 1 << 11;  //PTB   Pointer B Fault
   252:   public static final int M6E_FSLW_INDIRECT_LEVEL     = 1 << 10;  //IL    Indirect Level Fault
   253:   public static final int M6E_FSLW_PAGE_FAULT         = 1 <<  9;  //PF    Page Fault
   254:   public static final int M6E_FSLW_SUPERVISOR_PROTECT = 1 <<  8;  //SP    Supervisor Protect
   255:   public static final int M6E_FSLW_WRITE_PROTECT      = 1 <<  7;  //WP    Write Protect
   256:   public static final int M6E_FSLW_TABLE_SEARCH       = 1 <<  6;  //TWE   Bus Error on Table Search
   257:   public static final int M6E_FSLW_BUS_ERROR_ON_READ  = 1 <<  5;  //RE    Bus Error on Read
   258:   public static final int M6E_FSLW_BUS_ERROR_ON_WRITE = 1 <<  4;  //WE    Bus Error on Write
   259:   public static final int M6E_FSLW_TRANSPARENT        = 1 <<  3;  //TTR   TTR Hit
   260:   public static final int M6E_FSLW_BRANCH_PREDICTION  = 1 <<  2;  //BPE   Branch Prediction Error
   261:   public static final int M6E_FSLW_SOFTWARE_EMULATION = 1 <<  0;  //SEE   Software Emulation Error
   262: 
   263:   public static int m6eFSLW;
   264: 
   265:   //アドレスレジスタの増分
   266:   //  実効アドレスの計算でポストインクリメントまたはプレデクリメントのとき、
   267:   //  アドレスレジスタを更新してそのままにするとページフォルトを起こした命令を再実行することができない
   268:   //  MOVE.L (A0)+,(d16,A0)などでデスティネーションの実効アドレスの計算にソースの結果を反映させる必要があるので、
   269:   //  アドレスレジスタは更新しておいてページフォルトのときだけ命令開始時の値に巻き戻す
   270:   //  CMPM.L (A0)+,(A1)+やSUBX.L -(A0),-(A1)などでは複数の増分を並べるかまたは積まなければならない
   271:   //    m6eIncremented += (long) offset << (r << 3);
   272:   //  で積むことにする
   273:   //  巻き戻すとき負数に注意する
   274:   public static long m6eIncremented;
   275: 
   276:   public static final String[] M6E_FSLW_TEXT_IOMA = {
   277:     "IO=0,MA=0  First access of a misaligned transfer or only access of an aligned transfer",
   278:     "IO=0,MA=1  Second or later access of a misaligned transfer",
   279:     "IO=1,MA=0  Instruction opword fetch",
   280:     "IO=1,MA=1  Fetch of an extension word",
   281:   };
   282:   public static final String[] M6E_FSLW_TEXT_LK = {
   283:     "LK=0       Not locked",
   284:     "LK=1       Locked",
   285:   };
   286:   public static final String[] M6E_FSLW_TEXT_RW = {
   287:     "RW=0       Undefined, reserved",
   288:     "RW=1       Write",
   289:     "RW=2       Read",
   290:     "RW=3       Read-Modify-Write",
   291:   };
   292:   public static final String[] M6E_FSLW_TEXT_SIZE = {
   293:     "SIZE=0     Byte",
   294:     "SIZE=1     Word",
   295:     "SIZE=2     Long",
   296:     "SIZE=3     Double precision or MOVE16",
   297:   };
   298:   public static final String[] M6E_FSLW_TEXT_TT = {
   299:     "TT=0       Normal access",
   300:     "TT=1       MOVE16 access",
   301:     "TT=2       Alternate or debug access",
   302:     "TT=3       Acknowledge or LPSTOP broadcast",
   303:   };
   304:   public static final String[] M6E_FSLW_TEXT_TM = {
   305:     "TM=0       Data cache push access",
   306:     "TM=1       User data or MOVE16 access",
   307:     "TM=2       User code access",
   308:     "TM=3       MMU table search data access",
   309:     "TM=4       MMU table search code access",
   310:     "TM=5       Supervisor data access",
   311:     "TM=6       Supervisor code access",
   312:     "TM=7       Reserved",
   313:     //"TM=0       Logical function code 0",
   314:     //"TM=1       Debug access",
   315:     //"TM=2       Reserved",
   316:     //"TM=3       Logical function code 3",
   317:     //"TM=4       Logical function code 4",
   318:     //"TM=5       Debug pipe control mode access",
   319:     //"TM=6       Debug pipe control mode access",
   320:     //"TM=7       Logical function code 7",
   321:   };
   322:   public static final String[] M6E_FSLW_TEXT_CAUSE = {
   323:     "SEE=1      Software emulation error",  //0
   324:     "",  //1
   325:     "BPE=1      Branch prediction error",  //2
   326:     "TTR=1      TTR hit",  //3
   327:     "WE=1       Bus error on write",  //4
   328:     "RE=1       Bus error on read",  //5
   329:     "TWE=1      Bus error on table search",  //6
   330:     "WP=1       Write protect",  //7
   331:     "SP=1       Supervisor protect",  //8
   332:     "PF=1       Page fault",  //9
   333:     "IL=1       Indirect level fault",  //10
   334:     "PTB=1      Pointer B fault",  //11
   335:     "PTA=1      Pointer A fault",  //12
   336:     "SBE=1      Store buffer bus error",  //13
   337:     "PBE=1      Push buffer bus error",  //14
   338:   };
   339: 
   340:   public static String m6eToString6 () {
   341:     StringBuilder sb = new StringBuilder ();
   342:     int supervisor = m6eFSLW & M6E_FSLW_TM_SUPERVISOR;
   343:     int instruction = m6eFSLW & M6E_FSLW_TM_CODE;
   344:     if (0 <= m6eNumber && m6eNumber < M6E_ERROR_NAME.length) {
   345:       sb.append (M6E_ERROR_NAME[m6eNumber]);
   346:     } else {
   347:       sb.append ("undefined exception #").append (m6eNumber);
   348:     }
   349:     XEiJ.fmtHex8 (sb.append (" at PC=$"), XEiJ.regPC0).append ("($");
   350:     int pa = MC68060.mmuTranslatePeek (XEiJ.regPC0, supervisor, 1);
   351:     if ((XEiJ.regPC0 ^ pa) == 1) {
   352:       sb.append ("????????");
   353:     } else {
   354:       XEiJ.fmtHex8 (sb, pa);
   355:     }
   356:     XEiJ.fmtHex4 (sb.append ("), SR=$"), XEiJ.regSRT1 | XEiJ.regSRS | XEiJ.regSRI | XEiJ.regCCR);
   357:     //              111111111122222222223333333333444444444455555555556666
   358:     //    0123456789012345678901234567890123456789012345678901234567890123
   359:     if (0b0011011101000000000000000000000000000000000000000000000000000000L << m6eNumber < 0L) {  //FORMAT $2,$4
   360:       if ((m6eFSLW & (M6E_FSLW_BUS_ERROR_ON_READ | M6E_FSLW_BUS_ERROR_ON_WRITE)) != 0) {  //バスエラーのとき。m6eAddressは物理アドレス
   361:         XEiJ.fmtHex8 (sb.append ("\n  Fault or effective address is EA=($"), m6eAddress).append (')');
   362:       } else {  //バスエラーでないとき。m6eAddressは論理アドレス
   363:         XEiJ.fmtHex8 (sb.append ("\n  Fault or effective address is EA=$"), m6eAddress).append ("($");
   364:         pa = MC68060.mmuTranslatePeek (m6eAddress, supervisor, instruction);
   365:         if ((m6eAddress ^ pa) == 1) {
   366:           sb.append ("????????");
   367:         } else {
   368:           XEiJ.fmtHex8 (sb, pa);
   369:         }
   370:         sb.append (')');
   371:       }
   372:     }
   373:     if (m6eNumber == M6E_ACCESS_FAULT) {  //FORMAT $4
   374:       XEiJ.fmtHex8 (sb.append ("\n  Fault status long word is FSLW=$"), m6eFSLW);
   375:       sb.append ("\n  Fault was caused by:");
   376:       for (int i = 14; i >= 0; i--) {
   377:         if ((m6eFSLW & (1 << i)) != 0) {
   378:           sb.append ("\n    ").append (M6E_FSLW_TEXT_CAUSE[i]);
   379:         }
   380:       }
   381:       sb.append ("\n  Fault occured on:\n    ")
   382:         .append (M6E_FSLW_TEXT_IOMA[(m6eFSLW & M6E_FSLW_INSTRUCTION) >>> 15 - 1 | (m6eFSLW & M6E_FSLW_MISALIGNED) >>> 27])
   383:           .append ("\n    ").append (M6E_FSLW_TEXT_LK[(m6eFSLW & M6E_FSLW_LOCKED) >>> 25])
   384:             .append ("\n    ").append (M6E_FSLW_TEXT_RW[(m6eFSLW & M6E_FSLW_READ_AND_WRITE) >>> 23])
   385:               .append ("\n    ").append (M6E_FSLW_TEXT_SIZE[(m6eFSLW & M6E_FSLW_TRANSFER_SIZE) >>> 21])
   386:                 .append ("\n    ").append (M6E_FSLW_TEXT_TT[(m6eFSLW & M6E_FSLW_TRANSFER_TYPE) >>> 19])
   387:                   .append ("\n    ").append (M6E_FSLW_TEXT_TM[(m6eFSLW & M6E_FSLW_TRANSFER_MODIFIER) >>> 16]);
   388:     }
   389:     return sb.toString ();
   390:   }  //m6eToString6()
   391: 
   392: }  //class M68kException
   393: 
   394: 
   395: