xeij/MC68EC030.java (2/3)
1 2 3 //TPNNZ.W #<data> |A|--2346|-|--*--|-----| |0101_011_111_111_010-{data} [TRAPEQ.W #<data>]
//TPZE.W #<data> |A|--2346|-|--*--|-----| |0101_011_111_111_010-{data} [TRAPEQ.W #<data>]
//TRAPNNE.W #<data> |A|--2346|-|--*--|-----| |0101_011_111_111_010-{data} [TRAPEQ.W #<data>]
//TRAPNNZ.W #<data> |A|--2346|-|--*--|-----| |0101_011_111_111_010-{data} [TRAPEQ.W #<data>]
//TRAPZE.W #<data> |A|--2346|-|--*--|-----| |0101_011_111_111_010-{data} [TRAPEQ.W #<data>]
//TRAPEQ.L #<data> |-|--2346|-|--*--|-----| |0101_011_111_111_011-{data}
//TPEQ.L #<data> |A|--2346|-|--*--|-----| |0101_011_111_111_011-{data} [TRAPEQ.L #<data>]
//TPNNE.L #<data> |A|--2346|-|--*--|-----| |0101_011_111_111_011-{data} [TRAPEQ.L #<data>]
//TPNNZ.L #<data> |A|--2346|-|--*--|-----| |0101_011_111_111_011-{data} [TRAPEQ.L #<data>]
//TPZE.L #<data> |A|--2346|-|--*--|-----| |0101_011_111_111_011-{data} [TRAPEQ.L #<data>]
//TRAPNNE.L #<data> |A|--2346|-|--*--|-----| |0101_011_111_111_011-{data} [TRAPEQ.L #<data>]
//TRAPNNZ.L #<data> |A|--2346|-|--*--|-----| |0101_011_111_111_011-{data} [TRAPEQ.L #<data>]
//TRAPZE.L #<data> |A|--2346|-|--*--|-----| |0101_011_111_111_011-{data} [TRAPEQ.L #<data>]
//TRAPEQ |-|--2346|-|--*--|-----| |0101_011_111_111_100
//TPEQ |A|--2346|-|--*--|-----| |0101_011_111_111_100 [TRAPEQ]
//TPNNE |A|--2346|-|--*--|-----| |0101_011_111_111_100 [TRAPEQ]
//TPNNZ |A|--2346|-|--*--|-----| |0101_011_111_111_100 [TRAPEQ]
//TPZE |A|--2346|-|--*--|-----| |0101_011_111_111_100 [TRAPEQ]
//TRAPNNE |A|--2346|-|--*--|-----| |0101_011_111_111_100 [TRAPEQ]
//TRAPNNZ |A|--2346|-|--*--|-----| |0101_011_111_111_100 [TRAPEQ]
//TRAPZE |A|--2346|-|--*--|-----| |0101_011_111_111_100 [TRAPEQ]
public static void irpSeq () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea >> 3 == XEiJ.MMM_AR) { //DBEQ.W Dr,<label>
if (XEiJ.MPU_CC_EQ << XEiJ.regCCR < 0) {
//条件が成立しているので通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else {
//条件が成立していないのでデクリメント
int rrr = XEiJ.regOC & 7;
int t = XEiJ.regRn[rrr];
if ((short) t == 0) { //Drの下位16bitが0なので通過
XEiJ.mpuCycleCount += 14;
XEiJ.regRn[rrr] = t + 65535;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else { //Drの下位16bitが0でないのでジャンプ
XEiJ.mpuCycleCount += 10;
XEiJ.regRn[rrr] = t - 1; //下位16bitが0でないので上位16bitは変化しない
irpSetPC (XEiJ.regPC + XEiJ.busRws (XEiJ.regPC)); //pc==pc0+2
}
}
if (M30_DIV_ZERO_V_FLAG) {
m30DivZeroVFlag = !m30DivZeroVFlag;
}
} else if (ea < XEiJ.EA_AR) { //SEQ.B Dr
if (XEiJ.MPU_CC_EQ << XEiJ.regCCR < 0) { //セット
XEiJ.mpuCycleCount += 6;
XEiJ.regRn[ea] |= 0xff;
} else { //クリア
XEiJ.mpuCycleCount += 4;
XEiJ.regRn[ea] &= ~0xff;
}
} else if ((XEiJ.EAM_PW | XEiJ.EAM_PX | XEiJ.EAM_IM) << ea < 0L) { //TRAPEQ.W/TRAPEQ.L/TRAPEQ
int t = (ea & 3) + (ea & 1); //111_010→2,111_011→4,111_100→0
XEiJ.regPC += t;
if (XEiJ.MPU_CC_EQ << XEiJ.regCCR < 0) {
//条件が成立しているのでTRAPする
XEiJ.mpuCycleCount += t << 1;
M68kException.m6eAddress = XEiJ.regPC0; //アドレスは命令の先頭
M68kException.m6eNumber = M68kException.M6E_TRAPV_INSTRUCTION;
throw M68kException.m6eSignal;
} else {
//条件が成立していないのでTRAPしない
XEiJ.mpuCycleCount += 4 + (t << 1);
}
} else { //SEQ.B <mem>
XEiJ.mpuCycleCount += 8;
XEiJ.busWb (efaMltByte (ea), XEiJ.MPU_CC_EQ << XEiJ.regCCR >> 31);
}
} //irpSeq
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SVC.B <ea> |-|012346|-|---*-|-----|D M+-WXZ |0101_100_011_mmm_rrr
//SNVS.B <ea> |A|012346|-|---*-|-----|D M+-WXZ |0101_100_011_mmm_rrr [SVC.B <ea>]
//DBVC.W Dr,<label> |-|012346|-|---*-|-----| |0101_100_011_001_rrr-{offset}
//DBNVS.W Dr,<label> |A|012346|-|---*-|-----| |0101_100_011_001_rrr-{offset} [DBVC.W Dr,<label>]
//TRAPVC.W #<data> |-|--2346|-|---*-|-----| |0101_100_011_111_010-{data}
//TPNVS.W #<data> |A|--2346|-|---*-|-----| |0101_100_011_111_010-{data} [TRAPVC.W #<data>]
//TPVC.W #<data> |A|--2346|-|---*-|-----| |0101_100_011_111_010-{data} [TRAPVC.W #<data>]
//TRAPNVS.W #<data> |A|--2346|-|---*-|-----| |0101_100_011_111_010-{data} [TRAPVC.W #<data>]
//TRAPVC.L #<data> |-|--2346|-|---*-|-----| |0101_100_011_111_011-{data}
//TPNVS.L #<data> |A|--2346|-|---*-|-----| |0101_100_011_111_011-{data} [TRAPVC.L #<data>]
//TPVC.L #<data> |A|--2346|-|---*-|-----| |0101_100_011_111_011-{data} [TRAPVC.L #<data>]
//TRAPNVS.L #<data> |A|--2346|-|---*-|-----| |0101_100_011_111_011-{data} [TRAPVC.L #<data>]
//TRAPVC |-|--2346|-|---*-|-----| |0101_100_011_111_100
//TPNVS |A|--2346|-|---*-|-----| |0101_100_011_111_100 [TRAPVC]
//TPVC |A|--2346|-|---*-|-----| |0101_100_011_111_100 [TRAPVC]
//TRAPNVS |A|--2346|-|---*-|-----| |0101_100_011_111_100 [TRAPVC]
public static void irpSvc () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea >> 3 == XEiJ.MMM_AR) { //DBVC.W Dr,<label>
if (XEiJ.MPU_CC_VC << XEiJ.regCCR < 0) {
//条件が成立しているので通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else {
//条件が成立していないのでデクリメント
int rrr = XEiJ.regOC & 7;
int t = XEiJ.regRn[rrr];
if ((short) t == 0) { //Drの下位16bitが0なので通過
XEiJ.mpuCycleCount += 14;
XEiJ.regRn[rrr] = t + 65535;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else { //Drの下位16bitが0でないのでジャンプ
XEiJ.mpuCycleCount += 10;
XEiJ.regRn[rrr] = t - 1; //下位16bitが0でないので上位16bitは変化しない
irpSetPC (XEiJ.regPC + XEiJ.busRws (XEiJ.regPC)); //pc==pc0+2
}
}
if (M30_DIV_ZERO_V_FLAG) {
m30DivZeroVFlag = !m30DivZeroVFlag;
}
} else if (ea < XEiJ.EA_AR) { //SVC.B Dr
if (XEiJ.MPU_CC_VC << XEiJ.regCCR < 0) { //セット
XEiJ.mpuCycleCount += 6;
XEiJ.regRn[ea] |= 0xff;
} else { //クリア
XEiJ.mpuCycleCount += 4;
XEiJ.regRn[ea] &= ~0xff;
}
} else if ((XEiJ.EAM_PW | XEiJ.EAM_PX | XEiJ.EAM_IM) << ea < 0L) { //TRAPVC.W/TRAPVC.L/TRAPVC
int t = (ea & 3) + (ea & 1); //111_010→2,111_011→4,111_100→0
XEiJ.regPC += t;
if (XEiJ.MPU_CC_VC << XEiJ.regCCR < 0) {
//条件が成立しているのでTRAPする
XEiJ.mpuCycleCount += t << 1;
M68kException.m6eAddress = XEiJ.regPC0; //アドレスは命令の先頭
M68kException.m6eNumber = M68kException.M6E_TRAPV_INSTRUCTION;
throw M68kException.m6eSignal;
} else {
//条件が成立していないのでTRAPしない
XEiJ.mpuCycleCount += 4 + (t << 1);
}
} else { //SVC.B <mem>
XEiJ.mpuCycleCount += 8;
XEiJ.busWb (efaMltByte (ea), XEiJ.MPU_CC_VC << XEiJ.regCCR >> 31);
}
} //irpSvc
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SVS.B <ea> |-|012346|-|---*-|-----|D M+-WXZ |0101_100_111_mmm_rrr
//SNVC.B <ea> |A|012346|-|---*-|-----|D M+-WXZ |0101_100_111_mmm_rrr [SVS.B <ea>]
//DBVS.W Dr,<label> |-|012346|-|---*-|-----| |0101_100_111_001_rrr-{offset}
//DBNVC.W Dr,<label> |A|012346|-|---*-|-----| |0101_100_111_001_rrr-{offset} [DBVS.W Dr,<label>]
//TRAPVS.W #<data> |-|--2346|-|---*-|-----| |0101_100_111_111_010-{data}
//TPNVC.W #<data> |A|--2346|-|---*-|-----| |0101_100_111_111_010-{data} [TRAPVS.W #<data>]
//TPVS.W #<data> |A|--2346|-|---*-|-----| |0101_100_111_111_010-{data} [TRAPVS.W #<data>]
//TRAPNVC.W #<data> |A|--2346|-|---*-|-----| |0101_100_111_111_010-{data} [TRAPVS.W #<data>]
//TRAPVS.L #<data> |-|--2346|-|---*-|-----| |0101_100_111_111_011-{data}
//TPNVC.L #<data> |A|--2346|-|---*-|-----| |0101_100_111_111_011-{data} [TRAPVS.L #<data>]
//TPVS.L #<data> |A|--2346|-|---*-|-----| |0101_100_111_111_011-{data} [TRAPVS.L #<data>]
//TRAPNVC.L #<data> |A|--2346|-|---*-|-----| |0101_100_111_111_011-{data} [TRAPVS.L #<data>]
//TRAPVS |-|--2346|-|---*-|-----| |0101_100_111_111_100
//TPNVC |A|--2346|-|---*-|-----| |0101_100_111_111_100 [TRAPVS]
//TPVS |A|--2346|-|---*-|-----| |0101_100_111_111_100 [TRAPVS]
//TRAPNVC |A|--2346|-|---*-|-----| |0101_100_111_111_100 [TRAPVS]
public static void irpSvs () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea >> 3 == XEiJ.MMM_AR) { //DBVS.W Dr,<label>
if (XEiJ.MPU_CC_VS << XEiJ.regCCR < 0) {
//条件が成立しているので通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else {
//条件が成立していないのでデクリメント
int rrr = XEiJ.regOC & 7;
int t = XEiJ.regRn[rrr];
if ((short) t == 0) { //Drの下位16bitが0なので通過
XEiJ.mpuCycleCount += 14;
XEiJ.regRn[rrr] = t + 65535;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else { //Drの下位16bitが0でないのでジャンプ
XEiJ.mpuCycleCount += 10;
XEiJ.regRn[rrr] = t - 1; //下位16bitが0でないので上位16bitは変化しない
irpSetPC (XEiJ.regPC + XEiJ.busRws (XEiJ.regPC)); //pc==pc0+2
}
}
if (M30_DIV_ZERO_V_FLAG) {
m30DivZeroVFlag = !m30DivZeroVFlag;
}
} else if (ea < XEiJ.EA_AR) { //SVS.B Dr
if (XEiJ.MPU_CC_VS << XEiJ.regCCR < 0) { //セット
XEiJ.mpuCycleCount += 6;
XEiJ.regRn[ea] |= 0xff;
} else { //クリア
XEiJ.mpuCycleCount += 4;
XEiJ.regRn[ea] &= ~0xff;
}
} else if ((XEiJ.EAM_PW | XEiJ.EAM_PX | XEiJ.EAM_IM) << ea < 0L) { //TRAPVS.W/TRAPVS.L/TRAPVS
int t = (ea & 3) + (ea & 1); //111_010→2,111_011→4,111_100→0
XEiJ.regPC += t;
if (XEiJ.MPU_CC_VS << XEiJ.regCCR < 0) {
//条件が成立しているのでTRAPする
XEiJ.mpuCycleCount += t << 1;
M68kException.m6eAddress = XEiJ.regPC0; //アドレスは命令の先頭
M68kException.m6eNumber = M68kException.M6E_TRAPV_INSTRUCTION;
throw M68kException.m6eSignal;
} else {
//条件が成立していないのでTRAPしない
XEiJ.mpuCycleCount += 4 + (t << 1);
}
} else { //SVS.B <mem>
XEiJ.mpuCycleCount += 8;
XEiJ.busWb (efaMltByte (ea), XEiJ.MPU_CC_VS << XEiJ.regCCR >> 31);
}
} //irpSvs
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SPL.B <ea> |-|012346|-|-*---|-----|D M+-WXZ |0101_101_011_mmm_rrr
//SNMI.B <ea> |A|012346|-|-*---|-----|D M+-WXZ |0101_101_011_mmm_rrr [SPL.B <ea>]
//DBPL.W Dr,<label> |-|012346|-|-*---|-----| |0101_101_011_001_rrr-{offset}
//DBNMI.W Dr,<label> |A|012346|-|-*---|-----| |0101_101_011_001_rrr-{offset} [DBPL.W Dr,<label>]
//TRAPPL.W #<data> |-|--2346|-|-*---|-----| |0101_101_011_111_010-{data}
//TPNMI.W #<data> |A|--2346|-|-*---|-----| |0101_101_011_111_010-{data} [TRAPPL.W #<data>]
//TPPL.W #<data> |A|--2346|-|-*---|-----| |0101_101_011_111_010-{data} [TRAPPL.W #<data>]
//TRAPNMI.W #<data> |A|--2346|-|-*---|-----| |0101_101_011_111_010-{data} [TRAPPL.W #<data>]
//TRAPPL.L #<data> |-|--2346|-|-*---|-----| |0101_101_011_111_011-{data}
//TPNMI.L #<data> |A|--2346|-|-*---|-----| |0101_101_011_111_011-{data} [TRAPPL.L #<data>]
//TPPL.L #<data> |A|--2346|-|-*---|-----| |0101_101_011_111_011-{data} [TRAPPL.L #<data>]
//TRAPNMI.L #<data> |A|--2346|-|-*---|-----| |0101_101_011_111_011-{data} [TRAPPL.L #<data>]
//TRAPPL |-|--2346|-|-*---|-----| |0101_101_011_111_100
//TPNMI |A|--2346|-|-*---|-----| |0101_101_011_111_100 [TRAPPL]
//TPPL |A|--2346|-|-*---|-----| |0101_101_011_111_100 [TRAPPL]
//TRAPNMI |A|--2346|-|-*---|-----| |0101_101_011_111_100 [TRAPPL]
public static void irpSpl () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea >> 3 == XEiJ.MMM_AR) { //DBPL.W Dr,<label>
if (XEiJ.MPU_CC_PL << XEiJ.regCCR < 0) {
//条件が成立しているので通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else {
//条件が成立していないのでデクリメント
int rrr = XEiJ.regOC & 7;
int t = XEiJ.regRn[rrr];
if ((short) t == 0) { //Drの下位16bitが0なので通過
XEiJ.mpuCycleCount += 14;
XEiJ.regRn[rrr] = t + 65535;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else { //Drの下位16bitが0でないのでジャンプ
XEiJ.mpuCycleCount += 10;
XEiJ.regRn[rrr] = t - 1; //下位16bitが0でないので上位16bitは変化しない
irpSetPC (XEiJ.regPC + XEiJ.busRws (XEiJ.regPC)); //pc==pc0+2
}
}
if (M30_DIV_ZERO_V_FLAG) {
m30DivZeroVFlag = !m30DivZeroVFlag;
}
} else if (ea < XEiJ.EA_AR) { //SPL.B Dr
if (XEiJ.MPU_CC_PL << XEiJ.regCCR < 0) { //セット
XEiJ.mpuCycleCount += 6;
XEiJ.regRn[ea] |= 0xff;
} else { //クリア
XEiJ.mpuCycleCount += 4;
XEiJ.regRn[ea] &= ~0xff;
}
} else if ((XEiJ.EAM_PW | XEiJ.EAM_PX | XEiJ.EAM_IM) << ea < 0L) { //TRAPPL.W/TRAPPL.L/TRAPPL
int t = (ea & 3) + (ea & 1); //111_010→2,111_011→4,111_100→0
XEiJ.regPC += t;
if (XEiJ.MPU_CC_PL << XEiJ.regCCR < 0) {
//条件が成立しているのでTRAPする
XEiJ.mpuCycleCount += t << 1;
M68kException.m6eAddress = XEiJ.regPC0; //アドレスは命令の先頭
M68kException.m6eNumber = M68kException.M6E_TRAPV_INSTRUCTION;
throw M68kException.m6eSignal;
} else {
//条件が成立していないのでTRAPしない
XEiJ.mpuCycleCount += 4 + (t << 1);
}
} else { //SPL.B <mem>
XEiJ.mpuCycleCount += 8;
XEiJ.busWb (efaMltByte (ea), XEiJ.MPU_CC_PL << XEiJ.regCCR >> 31);
}
} //irpSpl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SMI.B <ea> |-|012346|-|-*---|-----|D M+-WXZ |0101_101_111_mmm_rrr
//SNPL.B <ea> |A|012346|-|-*---|-----|D M+-WXZ |0101_101_111_mmm_rrr [SMI.B <ea>]
//DBMI.W Dr,<label> |-|012346|-|-*---|-----| |0101_101_111_001_rrr-{offset}
//DBNPL.W Dr,<label> |A|012346|-|-*---|-----| |0101_101_111_001_rrr-{offset} [DBMI.W Dr,<label>]
//TRAPMI.W #<data> |-|--2346|-|-*---|-----| |0101_101_111_111_010-{data}
//TPMI.W #<data> |A|--2346|-|-*---|-----| |0101_101_111_111_010-{data} [TRAPMI.W #<data>]
//TPNPL.W #<data> |A|--2346|-|-*---|-----| |0101_101_111_111_010-{data} [TRAPMI.W #<data>]
//TRAPNPL.W #<data> |A|--2346|-|-*---|-----| |0101_101_111_111_010-{data} [TRAPMI.W #<data>]
//TRAPMI.L #<data> |-|--2346|-|-*---|-----| |0101_101_111_111_011-{data}
//TPMI.L #<data> |A|--2346|-|-*---|-----| |0101_101_111_111_011-{data} [TRAPMI.L #<data>]
//TPNPL.L #<data> |A|--2346|-|-*---|-----| |0101_101_111_111_011-{data} [TRAPMI.L #<data>]
//TRAPNPL.L #<data> |A|--2346|-|-*---|-----| |0101_101_111_111_011-{data} [TRAPMI.L #<data>]
//TRAPMI |-|--2346|-|-*---|-----| |0101_101_111_111_100
//TPMI |A|--2346|-|-*---|-----| |0101_101_111_111_100 [TRAPMI]
//TPNPL |A|--2346|-|-*---|-----| |0101_101_111_111_100 [TRAPMI]
//TRAPNPL |A|--2346|-|-*---|-----| |0101_101_111_111_100 [TRAPMI]
public static void irpSmi () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea >> 3 == XEiJ.MMM_AR) { //DBMI.W Dr,<label>
if (XEiJ.MPU_CC_MI << XEiJ.regCCR < 0) {
//条件が成立しているので通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else {
//条件が成立していないのでデクリメント
int rrr = XEiJ.regOC & 7;
int t = XEiJ.regRn[rrr];
if ((short) t == 0) { //Drの下位16bitが0なので通過
XEiJ.mpuCycleCount += 14;
XEiJ.regRn[rrr] = t + 65535;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else { //Drの下位16bitが0でないのでジャンプ
XEiJ.mpuCycleCount += 10;
XEiJ.regRn[rrr] = t - 1; //下位16bitが0でないので上位16bitは変化しない
irpSetPC (XEiJ.regPC + XEiJ.busRws (XEiJ.regPC)); //pc==pc0+2
}
}
if (M30_DIV_ZERO_V_FLAG) {
m30DivZeroVFlag = !m30DivZeroVFlag;
}
} else if (ea < XEiJ.EA_AR) { //SMI.B Dr
if (XEiJ.MPU_CC_MI << XEiJ.regCCR < 0) { //セット
XEiJ.mpuCycleCount += 6;
XEiJ.regRn[ea] |= 0xff;
} else { //クリア
XEiJ.mpuCycleCount += 4;
XEiJ.regRn[ea] &= ~0xff;
}
} else if ((XEiJ.EAM_PW | XEiJ.EAM_PX | XEiJ.EAM_IM) << ea < 0L) { //TRAPMI.W/TRAPMI.L/TRAPMI
int t = (ea & 3) + (ea & 1); //111_010→2,111_011→4,111_100→0
XEiJ.regPC += t;
if (XEiJ.MPU_CC_MI << XEiJ.regCCR < 0) {
//条件が成立しているのでTRAPする
XEiJ.mpuCycleCount += t << 1;
M68kException.m6eAddress = XEiJ.regPC0; //アドレスは命令の先頭
M68kException.m6eNumber = M68kException.M6E_TRAPV_INSTRUCTION;
throw M68kException.m6eSignal;
} else {
//条件が成立していないのでTRAPしない
XEiJ.mpuCycleCount += 4 + (t << 1);
}
} else { //SMI.B <mem>
XEiJ.mpuCycleCount += 8;
XEiJ.busWb (efaMltByte (ea), XEiJ.MPU_CC_MI << XEiJ.regCCR >> 31);
}
} //irpSmi
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SGE.B <ea> |-|012346|-|-*-*-|-----|D M+-WXZ |0101_110_011_mmm_rrr
//SNLT.B <ea> |A|012346|-|-*-*-|-----|D M+-WXZ |0101_110_011_mmm_rrr [SGE.B <ea>]
//DBGE.W Dr,<label> |-|012346|-|-*-*-|-----| |0101_110_011_001_rrr-{offset}
//DBNLT.W Dr,<label> |A|012346|-|-*-*-|-----| |0101_110_011_001_rrr-{offset} [DBGE.W Dr,<label>]
//TRAPGE.W #<data> |-|--2346|-|-*-*-|-----| |0101_110_011_111_010-{data}
//TPGE.W #<data> |A|--2346|-|-*-*-|-----| |0101_110_011_111_010-{data} [TRAPGE.W #<data>]
//TPNLT.W #<data> |A|--2346|-|-*-*-|-----| |0101_110_011_111_010-{data} [TRAPGE.W #<data>]
//TRAPNLT.W #<data> |A|--2346|-|-*-*-|-----| |0101_110_011_111_010-{data} [TRAPGE.W #<data>]
//TRAPGE.L #<data> |-|--2346|-|-*-*-|-----| |0101_110_011_111_011-{data}
//TPGE.L #<data> |A|--2346|-|-*-*-|-----| |0101_110_011_111_011-{data} [TRAPGE.L #<data>]
//TPNLT.L #<data> |A|--2346|-|-*-*-|-----| |0101_110_011_111_011-{data} [TRAPGE.L #<data>]
//TRAPNLT.L #<data> |A|--2346|-|-*-*-|-----| |0101_110_011_111_011-{data} [TRAPGE.L #<data>]
//TRAPGE |-|--2346|-|-*-*-|-----| |0101_110_011_111_100
//TPGE |A|--2346|-|-*-*-|-----| |0101_110_011_111_100 [TRAPGE]
//TPNLT |A|--2346|-|-*-*-|-----| |0101_110_011_111_100 [TRAPGE]
//TRAPNLT |A|--2346|-|-*-*-|-----| |0101_110_011_111_100 [TRAPGE]
public static void irpSge () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea >> 3 == XEiJ.MMM_AR) { //DBGE.W Dr,<label>
if (XEiJ.MPU_CC_GE << XEiJ.regCCR < 0) {
//条件が成立しているので通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else {
//条件が成立していないのでデクリメント
int rrr = XEiJ.regOC & 7;
int t = XEiJ.regRn[rrr];
if ((short) t == 0) { //Drの下位16bitが0なので通過
XEiJ.mpuCycleCount += 14;
XEiJ.regRn[rrr] = t + 65535;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else { //Drの下位16bitが0でないのでジャンプ
XEiJ.mpuCycleCount += 10;
XEiJ.regRn[rrr] = t - 1; //下位16bitが0でないので上位16bitは変化しない
irpSetPC (XEiJ.regPC + XEiJ.busRws (XEiJ.regPC)); //pc==pc0+2
}
}
if (M30_DIV_ZERO_V_FLAG) {
m30DivZeroVFlag = !m30DivZeroVFlag;
}
} else if (ea < XEiJ.EA_AR) { //SGE.B Dr
if (XEiJ.MPU_CC_GE << XEiJ.regCCR < 0) { //セット
XEiJ.mpuCycleCount += 6;
XEiJ.regRn[ea] |= 0xff;
} else { //クリア
XEiJ.mpuCycleCount += 4;
XEiJ.regRn[ea] &= ~0xff;
}
} else if ((XEiJ.EAM_PW | XEiJ.EAM_PX | XEiJ.EAM_IM) << ea < 0L) { //TRAPGE.W/TRAPGE.L/TRAPGE
int t = (ea & 3) + (ea & 1); //111_010→2,111_011→4,111_100→0
XEiJ.regPC += t;
if (XEiJ.MPU_CC_GE << XEiJ.regCCR < 0) {
//条件が成立しているのでTRAPする
XEiJ.mpuCycleCount += t << 1;
M68kException.m6eAddress = XEiJ.regPC0; //アドレスは命令の先頭
M68kException.m6eNumber = M68kException.M6E_TRAPV_INSTRUCTION;
throw M68kException.m6eSignal;
} else {
//条件が成立していないのでTRAPしない
XEiJ.mpuCycleCount += 4 + (t << 1);
}
} else { //SGE.B <mem>
XEiJ.mpuCycleCount += 8;
XEiJ.busWb (efaMltByte (ea), XEiJ.MPU_CC_GE << XEiJ.regCCR >> 31);
}
} //irpSge
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SLT.B <ea> |-|012346|-|-*-*-|-----|D M+-WXZ |0101_110_111_mmm_rrr
//SNGE.B <ea> |A|012346|-|-*-*-|-----|D M+-WXZ |0101_110_111_mmm_rrr [SLT.B <ea>]
//DBLT.W Dr,<label> |-|012346|-|-*-*-|-----| |0101_110_111_001_rrr-{offset}
//DBNGE.W Dr,<label> |A|012346|-|-*-*-|-----| |0101_110_111_001_rrr-{offset} [DBLT.W Dr,<label>]
//TRAPLT.W #<data> |-|--2346|-|-*-*-|-----| |0101_110_111_111_010-{data}
//TPLT.W #<data> |A|--2346|-|-*-*-|-----| |0101_110_111_111_010-{data} [TRAPLT.W #<data>]
//TPNGE.W #<data> |A|--2346|-|-*-*-|-----| |0101_110_111_111_010-{data} [TRAPLT.W #<data>]
//TRAPNGE.W #<data> |A|--2346|-|-*-*-|-----| |0101_110_111_111_010-{data} [TRAPLT.W #<data>]
//TRAPLT.L #<data> |-|--2346|-|-*-*-|-----| |0101_110_111_111_011-{data}
//TPLT.L #<data> |A|--2346|-|-*-*-|-----| |0101_110_111_111_011-{data} [TRAPLT.L #<data>]
//TPNGE.L #<data> |A|--2346|-|-*-*-|-----| |0101_110_111_111_011-{data} [TRAPLT.L #<data>]
//TRAPNGE.L #<data> |A|--2346|-|-*-*-|-----| |0101_110_111_111_011-{data} [TRAPLT.L #<data>]
//TRAPLT |-|--2346|-|-*-*-|-----| |0101_110_111_111_100
//TPLT |A|--2346|-|-*-*-|-----| |0101_110_111_111_100 [TRAPLT]
//TPNGE |A|--2346|-|-*-*-|-----| |0101_110_111_111_100 [TRAPLT]
//TRAPNGE |A|--2346|-|-*-*-|-----| |0101_110_111_111_100 [TRAPLT]
public static void irpSlt () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea >> 3 == XEiJ.MMM_AR) { //DBLT.W Dr,<label>
if (XEiJ.MPU_CC_LT << XEiJ.regCCR < 0) {
//条件が成立しているので通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else {
//条件が成立していないのでデクリメント
int rrr = XEiJ.regOC & 7;
int t = XEiJ.regRn[rrr];
if ((short) t == 0) { //Drの下位16bitが0なので通過
XEiJ.mpuCycleCount += 14;
XEiJ.regRn[rrr] = t + 65535;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else { //Drの下位16bitが0でないのでジャンプ
XEiJ.mpuCycleCount += 10;
XEiJ.regRn[rrr] = t - 1; //下位16bitが0でないので上位16bitは変化しない
irpSetPC (XEiJ.regPC + XEiJ.busRws (XEiJ.regPC)); //pc==pc0+2
}
}
if (M30_DIV_ZERO_V_FLAG) {
m30DivZeroVFlag = !m30DivZeroVFlag;
}
} else if (ea < XEiJ.EA_AR) { //SLT.B Dr
if (XEiJ.MPU_CC_LT << XEiJ.regCCR < 0) { //セット
XEiJ.mpuCycleCount += 6;
XEiJ.regRn[ea] |= 0xff;
} else { //クリア
XEiJ.mpuCycleCount += 4;
XEiJ.regRn[ea] &= ~0xff;
}
} else if ((XEiJ.EAM_PW | XEiJ.EAM_PX | XEiJ.EAM_IM) << ea < 0L) { //TRAPLT.W/TRAPLT.L/TRAPLT
int t = (ea & 3) + (ea & 1); //111_010→2,111_011→4,111_100→0
XEiJ.regPC += t;
if (XEiJ.MPU_CC_LT << XEiJ.regCCR < 0) {
//条件が成立しているのでTRAPする
XEiJ.mpuCycleCount += t << 1;
M68kException.m6eAddress = XEiJ.regPC0; //アドレスは命令の先頭
M68kException.m6eNumber = M68kException.M6E_TRAPV_INSTRUCTION;
throw M68kException.m6eSignal;
} else {
//条件が成立していないのでTRAPしない
XEiJ.mpuCycleCount += 4 + (t << 1);
}
} else { //SLT.B <mem>
XEiJ.mpuCycleCount += 8;
XEiJ.busWb (efaMltByte (ea), XEiJ.MPU_CC_LT << XEiJ.regCCR >> 31);
}
} //irpSlt
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SGT.B <ea> |-|012346|-|-***-|-----|D M+-WXZ |0101_111_011_mmm_rrr
//SNLE.B <ea> |A|012346|-|-***-|-----|D M+-WXZ |0101_111_011_mmm_rrr [SGT.B <ea>]
//DBGT.W Dr,<label> |-|012346|-|-***-|-----| |0101_111_011_001_rrr-{offset}
//DBNLE.W Dr,<label> |A|012346|-|-***-|-----| |0101_111_011_001_rrr-{offset} [DBGT.W Dr,<label>]
//TRAPGT.W #<data> |-|--2346|-|-***-|-----| |0101_111_011_111_010-{data}
//TPGT.W #<data> |A|--2346|-|-***-|-----| |0101_111_011_111_010-{data} [TRAPGT.W #<data>]
//TPNLE.W #<data> |A|--2346|-|-***-|-----| |0101_111_011_111_010-{data} [TRAPGT.W #<data>]
//TRAPNLE.W #<data> |A|--2346|-|-***-|-----| |0101_111_011_111_010-{data} [TRAPGT.W #<data>]
//TRAPGT.L #<data> |-|--2346|-|-***-|-----| |0101_111_011_111_011-{data}
//TPGT.L #<data> |A|--2346|-|-***-|-----| |0101_111_011_111_011-{data} [TRAPGT.L #<data>]
//TPNLE.L #<data> |A|--2346|-|-***-|-----| |0101_111_011_111_011-{data} [TRAPGT.L #<data>]
//TRAPNLE.L #<data> |A|--2346|-|-***-|-----| |0101_111_011_111_011-{data} [TRAPGT.L #<data>]
//TRAPGT |-|--2346|-|-***-|-----| |0101_111_011_111_100
//TPGT |A|--2346|-|-***-|-----| |0101_111_011_111_100 [TRAPGT]
//TPNLE |A|--2346|-|-***-|-----| |0101_111_011_111_100 [TRAPGT]
//TRAPNLE |A|--2346|-|-***-|-----| |0101_111_011_111_100 [TRAPGT]
public static void irpSgt () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea >> 3 == XEiJ.MMM_AR) { //DBGT.W Dr,<label>
if (XEiJ.MPU_CC_GT << XEiJ.regCCR < 0) {
//条件が成立しているので通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else {
//条件が成立していないのでデクリメント
int rrr = XEiJ.regOC & 7;
int t = XEiJ.regRn[rrr];
if ((short) t == 0) { //Drの下位16bitが0なので通過
XEiJ.mpuCycleCount += 14;
XEiJ.regRn[rrr] = t + 65535;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else { //Drの下位16bitが0でないのでジャンプ
XEiJ.mpuCycleCount += 10;
XEiJ.regRn[rrr] = t - 1; //下位16bitが0でないので上位16bitは変化しない
irpSetPC (XEiJ.regPC + XEiJ.busRws (XEiJ.regPC)); //pc==pc0+2
}
}
if (M30_DIV_ZERO_V_FLAG) {
m30DivZeroVFlag = !m30DivZeroVFlag;
}
} else if (ea < XEiJ.EA_AR) { //SGT.B Dr
if (XEiJ.MPU_CC_GT << XEiJ.regCCR < 0) { //セット
XEiJ.mpuCycleCount += 6;
XEiJ.regRn[ea] |= 0xff;
} else { //クリア
XEiJ.mpuCycleCount += 4;
XEiJ.regRn[ea] &= ~0xff;
}
} else if ((XEiJ.EAM_PW | XEiJ.EAM_PX | XEiJ.EAM_IM) << ea < 0L) { //TRAPGT.W/TRAPGT.L/TRAPGT
int t = (ea & 3) + (ea & 1); //111_010→2,111_011→4,111_100→0
XEiJ.regPC += t;
if (XEiJ.MPU_CC_GT << XEiJ.regCCR < 0) {
//条件が成立しているのでTRAPする
XEiJ.mpuCycleCount += t << 1;
M68kException.m6eAddress = XEiJ.regPC0; //アドレスは命令の先頭
M68kException.m6eNumber = M68kException.M6E_TRAPV_INSTRUCTION;
throw M68kException.m6eSignal;
} else {
//条件が成立していないのでTRAPしない
XEiJ.mpuCycleCount += 4 + (t << 1);
}
} else { //SGT.B <mem>
XEiJ.mpuCycleCount += 8;
XEiJ.busWb (efaMltByte (ea), XEiJ.MPU_CC_GT << XEiJ.regCCR >> 31);
}
} //irpSgt
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SLE.B <ea> |-|012346|-|-***-|-----|D M+-WXZ |0101_111_111_mmm_rrr
//SNGT.B <ea> |A|012346|-|-***-|-----|D M+-WXZ |0101_111_111_mmm_rrr [SLE.B <ea>]
//DBLE.W Dr,<label> |-|012346|-|-***-|-----| |0101_111_111_001_rrr-{offset}
//DBNGT.W Dr,<label> |A|012346|-|-***-|-----| |0101_111_111_001_rrr-{offset} [DBLE.W Dr,<label>]
//TRAPLE.W #<data> |-|--2346|-|-***-|-----| |0101_111_111_111_010-{data}
//TPLE.W #<data> |A|--2346|-|-***-|-----| |0101_111_111_111_010-{data} [TRAPLE.W #<data>]
//TPNGT.W #<data> |A|--2346|-|-***-|-----| |0101_111_111_111_010-{data} [TRAPLE.W #<data>]
//TRAPNGT.W #<data> |A|--2346|-|-***-|-----| |0101_111_111_111_010-{data} [TRAPLE.W #<data>]
//TRAPLE.L #<data> |-|--2346|-|-***-|-----| |0101_111_111_111_011-{data}
//TPLE.L #<data> |A|--2346|-|-***-|-----| |0101_111_111_111_011-{data} [TRAPLE.L #<data>]
//TPNGT.L #<data> |A|--2346|-|-***-|-----| |0101_111_111_111_011-{data} [TRAPLE.L #<data>]
//TRAPNGT.L #<data> |A|--2346|-|-***-|-----| |0101_111_111_111_011-{data} [TRAPLE.L #<data>]
//TRAPLE |-|--2346|-|-***-|-----| |0101_111_111_111_100
//TPLE |A|--2346|-|-***-|-----| |0101_111_111_111_100 [TRAPLE]
//TPNGT |A|--2346|-|-***-|-----| |0101_111_111_111_100 [TRAPLE]
//TRAPNGT |A|--2346|-|-***-|-----| |0101_111_111_111_100 [TRAPLE]
public static void irpSle () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea >> 3 == XEiJ.MMM_AR) { //DBLE.W Dr,<label>
if (XEiJ.MPU_CC_LE << XEiJ.regCCR < 0) {
//条件が成立しているので通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else {
//条件が成立していないのでデクリメント
int rrr = XEiJ.regOC & 7;
int t = XEiJ.regRn[rrr];
if ((short) t == 0) { //Drの下位16bitが0なので通過
XEiJ.mpuCycleCount += 14;
XEiJ.regRn[rrr] = t + 65535;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else { //Drの下位16bitが0でないのでジャンプ
XEiJ.mpuCycleCount += 10;
XEiJ.regRn[rrr] = t - 1; //下位16bitが0でないので上位16bitは変化しない
irpSetPC (XEiJ.regPC + XEiJ.busRws (XEiJ.regPC)); //pc==pc0+2
}
}
if (M30_DIV_ZERO_V_FLAG) {
m30DivZeroVFlag = !m30DivZeroVFlag;
}
} else if (ea < XEiJ.EA_AR) { //SLE.B Dr
if (XEiJ.MPU_CC_LE << XEiJ.regCCR < 0) { //セット
XEiJ.mpuCycleCount += 6;
XEiJ.regRn[ea] |= 0xff;
} else { //クリア
XEiJ.mpuCycleCount += 4;
XEiJ.regRn[ea] &= ~0xff;
}
} else if ((XEiJ.EAM_PW | XEiJ.EAM_PX | XEiJ.EAM_IM) << ea < 0L) { //TRAPLE.W/TRAPLE.L/TRAPLE
int t = (ea & 3) + (ea & 1); //111_010→2,111_011→4,111_100→0
XEiJ.regPC += t;
if (XEiJ.MPU_CC_LE << XEiJ.regCCR < 0) {
//条件が成立しているのでTRAPする
XEiJ.mpuCycleCount += t << 1;
M68kException.m6eAddress = XEiJ.regPC0; //アドレスは命令の先頭
M68kException.m6eNumber = M68kException.M6E_TRAPV_INSTRUCTION;
throw M68kException.m6eSignal;
} else {
//条件が成立していないのでTRAPしない
XEiJ.mpuCycleCount += 4 + (t << 1);
}
} else { //SLE.B <mem>
XEiJ.mpuCycleCount += 8;
XEiJ.busWb (efaMltByte (ea), XEiJ.MPU_CC_LE << XEiJ.regCCR >> 31);
}
} //irpSle
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BRA.W <label> |-|012346|-|-----|-----| |0110_000_000_000_000-{offset}
//JBRA.W <label> |A|012346|-|-----|-----| |0110_000_000_000_000-{offset} [BRA.W <label>]
//BRA.S <label> |-|012346|-|-----|-----| |0110_000_000_sss_sss (s is not equal to 0)
//JBRA.S <label> |A|012346|-|-----|-----| |0110_000_000_sss_sss (s is not equal to 0) [BRA.S <label>]
public static void irpBrasw () throws M68kException {
XEiJ.mpuCycleCount += 10;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //BRA.W
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //pc0+2+オフセット
} //irpBrasw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BRA.S <label> |-|012346|-|-----|-----| |0110_000_001_sss_sss
//JBRA.S <label> |A|012346|-|-----|-----| |0110_000_001_sss_sss [BRA.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BRA.S <label> |-|012346|-|-----|-----| |0110_000_010_sss_sss
//JBRA.S <label> |A|012346|-|-----|-----| |0110_000_010_sss_sss [BRA.S <label>]
public static void irpBras () throws M68kException {
XEiJ.mpuCycleCount += 10;
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} //irpBras
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BRA.S <label> |-|--2346|-|-----|-----| |0110_000_011_sss_sss (s is not equal to 63)
//JBRA.S <label> |A|--2346|-|-----|-----| |0110_000_011_sss_sss (s is not equal to 63) [BRA.S <label>]
//BRA.L <label> |-|--2346|-|-----|-----| |0110_000_011_111_111-{offset}
public static void irpBrasl () throws M68kException {
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //BRA.L
XEiJ.mpuCycleCount += 14;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //BRA.S
XEiJ.mpuCycleCount += 10;
}
irpSetPC (t + s); //pc0+2+オフセット
} //irpBrasl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BSR.W <label> |-|012346|-|-----|-----| |0110_000_100_000_000-{offset}
//JBSR.W <label> |A|012346|-|-----|-----| |0110_000_100_000_000-{offset} [BSR.W <label>]
//BSR.S <label> |-|012346|-|-----|-----| |0110_000_100_sss_sss (s is not equal to 0)
//JBSR.S <label> |A|012346|-|-----|-----| |0110_000_100_sss_sss (s is not equal to 0) [BSR.S <label>]
public static void irpBsrsw () throws M68kException {
XEiJ.mpuCycleCount += 18;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //BSR.W
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
XEiJ.busWl (XEiJ.regRn[15] -= 4, XEiJ.regPC); //pushl
irpSetPC (t + s); //pc0+2+オフセット
} //irpBsrsw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BSR.S <label> |-|012346|-|-----|-----| |0110_000_101_sss_sss
//JBSR.S <label> |A|012346|-|-----|-----| |0110_000_101_sss_sss [BSR.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BSR.S <label> |-|012346|-|-----|-----| |0110_000_110_sss_sss
//JBSR.S <label> |A|012346|-|-----|-----| |0110_000_110_sss_sss [BSR.S <label>]
public static void irpBsrs () throws M68kException {
XEiJ.mpuCycleCount += 18;
XEiJ.busWl (XEiJ.regRn[15] -= 4, XEiJ.regPC); //pushl
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} //irpBsrs
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BSR.S <label> |-|--2346|-|-----|-----| |0110_000_111_sss_sss (s is not equal to 63)
//JBSR.S <label> |A|--2346|-|-----|-----| |0110_000_111_sss_sss (s is not equal to 63) [BSR.S <label>]
//BSR.L <label> |-|--2346|-|-----|-----| |0110_000_111_111_111-{offset}
public static void irpBsrsl () throws M68kException {
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //BSR.L
XEiJ.mpuCycleCount += 22;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //BSR.S
XEiJ.mpuCycleCount += 18;
}
XEiJ.busWl (XEiJ.regRn[15] -= 4, XEiJ.regPC); //pushl
irpSetPC (t + s); //pc0+2+オフセット
} //irpBsrsl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BHI.W <label> |-|012346|-|--*-*|-----| |0110_001_000_000_000-{offset}
//BNLS.W <label> |A|012346|-|--*-*|-----| |0110_001_000_000_000-{offset} [BHI.W <label>]
//JBHI.W <label> |A|012346|-|--*-*|-----| |0110_001_000_000_000-{offset} [BHI.W <label>]
//JBNLS.W <label> |A|012346|-|--*-*|-----| |0110_001_000_000_000-{offset} [BHI.W <label>]
//BHI.S <label> |-|012346|-|--*-*|-----| |0110_001_000_sss_sss (s is not equal to 0)
//BNLS.S <label> |A|012346|-|--*-*|-----| |0110_001_000_sss_sss (s is not equal to 0) [BHI.S <label>]
//JBHI.S <label> |A|012346|-|--*-*|-----| |0110_001_000_sss_sss (s is not equal to 0) [BHI.S <label>]
//JBNLS.S <label> |A|012346|-|--*-*|-----| |0110_001_000_sss_sss (s is not equal to 0) [BHI.S <label>]
//JBLS.L <label> |A|012346|-|--*-*|-----| |0110_001_000_000_110-0100111011111001-{address} [BHI.S (*)+8;JMP <label>]
//JBNHI.L <label> |A|012346|-|--*-*|-----| |0110_001_000_000_110-0100111011111001-{address} [BHI.S (*)+8;JMP <label>]
public static void irpBhisw () throws M68kException {
if (XEiJ.MPU_CC_HI << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //Bcc.Wでジャンプ
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6200) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBhisw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BHI.S <label> |-|012346|-|--*-*|-----| |0110_001_001_sss_sss
//BNLS.S <label> |A|012346|-|--*-*|-----| |0110_001_001_sss_sss [BHI.S <label>]
//JBHI.S <label> |A|012346|-|--*-*|-----| |0110_001_001_sss_sss [BHI.S <label>]
//JBNLS.S <label> |A|012346|-|--*-*|-----| |0110_001_001_sss_sss [BHI.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BHI.S <label> |-|012346|-|--*-*|-----| |0110_001_010_sss_sss
//BNLS.S <label> |A|012346|-|--*-*|-----| |0110_001_010_sss_sss [BHI.S <label>]
//JBHI.S <label> |A|012346|-|--*-*|-----| |0110_001_010_sss_sss [BHI.S <label>]
//JBNLS.S <label> |A|012346|-|--*-*|-----| |0110_001_010_sss_sss [BHI.S <label>]
public static void irpBhis () throws M68kException {
if (XEiJ.MPU_CC_HI << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBhis
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BHI.S <label> |-|--2346|-|--*-*|-----| |0110_001_011_sss_sss (s is not equal to 63)
//BNLS.S <label> |A|--2346|-|--*-*|-----| |0110_001_011_sss_sss (s is not equal to 63) [BHI.S <label>]
//JBHI.S <label> |A|--2346|-|--*-*|-----| |0110_001_011_sss_sss (s is not equal to 63) [BHI.S <label>]
//JBNLS.S <label> |A|--2346|-|--*-*|-----| |0110_001_011_sss_sss (s is not equal to 63) [BHI.S <label>]
//BHI.L <label> |-|--2346|-|--*-*|-----| |0110_001_011_111_111-{offset}
//BNLS.L <label> |A|--2346|-|--*-*|-----| |0110_001_011_111_111-{offset} [BHI.L <label>]
public static void irpBhisl () throws M68kException {
if (XEiJ.MPU_CC_HI << XEiJ.regCCR < 0) { //Bccでジャンプ
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //Bcc.Lでジャンプ
XEiJ.mpuCycleCount += 14;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //Bcc.Sでジャンプ
XEiJ.mpuCycleCount += 10;
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x62ff) { //Bcc.Lで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 4; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBhisl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BLS.W <label> |-|012346|-|--*-*|-----| |0110_001_100_000_000-{offset}
//BNHI.W <label> |A|012346|-|--*-*|-----| |0110_001_100_000_000-{offset} [BLS.W <label>]
//JBLS.W <label> |A|012346|-|--*-*|-----| |0110_001_100_000_000-{offset} [BLS.W <label>]
//JBNHI.W <label> |A|012346|-|--*-*|-----| |0110_001_100_000_000-{offset} [BLS.W <label>]
//BLS.S <label> |-|012346|-|--*-*|-----| |0110_001_100_sss_sss (s is not equal to 0)
//BNHI.S <label> |A|012346|-|--*-*|-----| |0110_001_100_sss_sss (s is not equal to 0) [BLS.S <label>]
//JBLS.S <label> |A|012346|-|--*-*|-----| |0110_001_100_sss_sss (s is not equal to 0) [BLS.S <label>]
//JBNHI.S <label> |A|012346|-|--*-*|-----| |0110_001_100_sss_sss (s is not equal to 0) [BLS.S <label>]
//JBHI.L <label> |A|012346|-|--*-*|-----| |0110_001_100_000_110-0100111011111001-{address} [BLS.S (*)+8;JMP <label>]
//JBNLS.L <label> |A|012346|-|--*-*|-----| |0110_001_100_000_110-0100111011111001-{address} [BLS.S (*)+8;JMP <label>]
public static void irpBlssw () throws M68kException {
if (XEiJ.MPU_CC_LS << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //Bcc.Wでジャンプ
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6300) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBlssw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BLS.S <label> |-|012346|-|--*-*|-----| |0110_001_101_sss_sss
//BNHI.S <label> |A|012346|-|--*-*|-----| |0110_001_101_sss_sss [BLS.S <label>]
//JBLS.S <label> |A|012346|-|--*-*|-----| |0110_001_101_sss_sss [BLS.S <label>]
//JBNHI.S <label> |A|012346|-|--*-*|-----| |0110_001_101_sss_sss [BLS.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BLS.S <label> |-|012346|-|--*-*|-----| |0110_001_110_sss_sss
//BNHI.S <label> |A|012346|-|--*-*|-----| |0110_001_110_sss_sss [BLS.S <label>]
//JBLS.S <label> |A|012346|-|--*-*|-----| |0110_001_110_sss_sss [BLS.S <label>]
//JBNHI.S <label> |A|012346|-|--*-*|-----| |0110_001_110_sss_sss [BLS.S <label>]
public static void irpBlss () throws M68kException {
if (XEiJ.MPU_CC_LS << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBlss
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BLS.S <label> |-|--2346|-|--*-*|-----| |0110_001_111_sss_sss (s is not equal to 63)
//BNHI.S <label> |A|--2346|-|--*-*|-----| |0110_001_111_sss_sss (s is not equal to 63) [BLS.S <label>]
//JBLS.S <label> |A|--2346|-|--*-*|-----| |0110_001_111_sss_sss (s is not equal to 63) [BLS.S <label>]
//JBNHI.S <label> |A|--2346|-|--*-*|-----| |0110_001_111_sss_sss (s is not equal to 63) [BLS.S <label>]
//BLS.L <label> |-|--2346|-|--*-*|-----| |0110_001_111_111_111-{offset}
//BNHI.L <label> |A|--2346|-|--*-*|-----| |0110_001_111_111_111-{offset} [BLS.L <label>]
public static void irpBlssl () throws M68kException {
if (XEiJ.MPU_CC_LS << XEiJ.regCCR < 0) { //Bccでジャンプ
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //Bcc.Lでジャンプ
XEiJ.mpuCycleCount += 14;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //Bcc.Sでジャンプ
XEiJ.mpuCycleCount += 10;
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x63ff) { //Bcc.Lで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 4; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBlssl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BCC.W <label> |-|012346|-|----*|-----| |0110_010_000_000_000-{offset}
//BHS.W <label> |A|012346|-|----*|-----| |0110_010_000_000_000-{offset} [BCC.W <label>]
//BNCS.W <label> |A|012346|-|----*|-----| |0110_010_000_000_000-{offset} [BCC.W <label>]
//BNLO.W <label> |A|012346|-|----*|-----| |0110_010_000_000_000-{offset} [BCC.W <label>]
//JBCC.W <label> |A|012346|-|----*|-----| |0110_010_000_000_000-{offset} [BCC.W <label>]
//JBHS.W <label> |A|012346|-|----*|-----| |0110_010_000_000_000-{offset} [BCC.W <label>]
//JBNCS.W <label> |A|012346|-|----*|-----| |0110_010_000_000_000-{offset} [BCC.W <label>]
//JBNLO.W <label> |A|012346|-|----*|-----| |0110_010_000_000_000-{offset} [BCC.W <label>]
//BCC.S <label> |-|012346|-|----*|-----| |0110_010_000_sss_sss (s is not equal to 0)
//BHS.S <label> |A|012346|-|----*|-----| |0110_010_000_sss_sss (s is not equal to 0) [BCC.S <label>]
//BNCS.S <label> |A|012346|-|----*|-----| |0110_010_000_sss_sss (s is not equal to 0) [BCC.S <label>]
//BNLO.S <label> |A|012346|-|----*|-----| |0110_010_000_sss_sss (s is not equal to 0) [BCC.S <label>]
//JBCC.S <label> |A|012346|-|----*|-----| |0110_010_000_sss_sss (s is not equal to 0) [BCC.S <label>]
//JBHS.S <label> |A|012346|-|----*|-----| |0110_010_000_sss_sss (s is not equal to 0) [BCC.S <label>]
//JBNCS.S <label> |A|012346|-|----*|-----| |0110_010_000_sss_sss (s is not equal to 0) [BCC.S <label>]
//JBNLO.S <label> |A|012346|-|----*|-----| |0110_010_000_sss_sss (s is not equal to 0) [BCC.S <label>]
//JBCS.L <label> |A|012346|-|----*|-----| |0110_010_000_000_110-0100111011111001-{address} [BCC.S (*)+8;JMP <label>]
//JBLO.L <label> |A|012346|-|----*|-----| |0110_010_000_000_110-0100111011111001-{address} [BCC.S (*)+8;JMP <label>]
//JBNCC.L <label> |A|012346|-|----*|-----| |0110_010_000_000_110-0100111011111001-{address} [BCC.S (*)+8;JMP <label>]
//JBNHS.L <label> |A|012346|-|----*|-----| |0110_010_000_000_110-0100111011111001-{address} [BCC.S (*)+8;JMP <label>]
public static void irpBhssw () throws M68kException {
if (XEiJ.MPU_CC_HS << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //Bcc.Wでジャンプ
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6400) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBhssw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BCC.S <label> |-|012346|-|----*|-----| |0110_010_001_sss_sss
//BHS.S <label> |A|012346|-|----*|-----| |0110_010_001_sss_sss [BCC.S <label>]
//BNCS.S <label> |A|012346|-|----*|-----| |0110_010_001_sss_sss [BCC.S <label>]
//BNLO.S <label> |A|012346|-|----*|-----| |0110_010_001_sss_sss [BCC.S <label>]
//JBCC.S <label> |A|012346|-|----*|-----| |0110_010_001_sss_sss [BCC.S <label>]
//JBHS.S <label> |A|012346|-|----*|-----| |0110_010_001_sss_sss [BCC.S <label>]
//JBNCS.S <label> |A|012346|-|----*|-----| |0110_010_001_sss_sss [BCC.S <label>]
//JBNLO.S <label> |A|012346|-|----*|-----| |0110_010_001_sss_sss [BCC.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BCC.S <label> |-|012346|-|----*|-----| |0110_010_010_sss_sss
//BHS.S <label> |A|012346|-|----*|-----| |0110_010_010_sss_sss [BCC.S <label>]
//BNCS.S <label> |A|012346|-|----*|-----| |0110_010_010_sss_sss [BCC.S <label>]
//BNLO.S <label> |A|012346|-|----*|-----| |0110_010_010_sss_sss [BCC.S <label>]
//JBCC.S <label> |A|012346|-|----*|-----| |0110_010_010_sss_sss [BCC.S <label>]
//JBHS.S <label> |A|012346|-|----*|-----| |0110_010_010_sss_sss [BCC.S <label>]
//JBNCS.S <label> |A|012346|-|----*|-----| |0110_010_010_sss_sss [BCC.S <label>]
//JBNLO.S <label> |A|012346|-|----*|-----| |0110_010_010_sss_sss [BCC.S <label>]
public static void irpBhss () throws M68kException {
if (XEiJ.MPU_CC_HS << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBhss
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BCC.S <label> |-|--2346|-|----*|-----| |0110_010_011_sss_sss (s is not equal to 63)
//BHS.S <label> |A|--2346|-|----*|-----| |0110_010_011_sss_sss (s is not equal to 63) [BCC.S <label>]
//BNCS.S <label> |A|--2346|-|----*|-----| |0110_010_011_sss_sss (s is not equal to 63) [BCC.S <label>]
//BNLO.S <label> |A|--2346|-|----*|-----| |0110_010_011_sss_sss (s is not equal to 63) [BCC.S <label>]
//JBCC.S <label> |A|--2346|-|----*|-----| |0110_010_011_sss_sss (s is not equal to 63) [BCC.S <label>]
//JBHS.S <label> |A|--2346|-|----*|-----| |0110_010_011_sss_sss (s is not equal to 63) [BCC.S <label>]
//JBNCS.S <label> |A|--2346|-|----*|-----| |0110_010_011_sss_sss (s is not equal to 63) [BCC.S <label>]
//JBNLO.S <label> |A|--2346|-|----*|-----| |0110_010_011_sss_sss (s is not equal to 63) [BCC.S <label>]
//BCC.L <label> |-|--2346|-|----*|-----| |0110_010_011_111_111-{offset}
//BHS.L <label> |A|--2346|-|----*|-----| |0110_010_011_111_111-{offset} [BCC.L <label>]
//BNCS.L <label> |A|--2346|-|----*|-----| |0110_010_011_111_111-{offset} [BCC.L <label>]
//BNLO.L <label> |A|--2346|-|----*|-----| |0110_010_011_111_111-{offset} [BCC.L <label>]
public static void irpBhssl () throws M68kException {
if (XEiJ.MPU_CC_HS << XEiJ.regCCR < 0) { //Bccでジャンプ
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //Bcc.Lでジャンプ
XEiJ.mpuCycleCount += 14;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //Bcc.Sでジャンプ
XEiJ.mpuCycleCount += 10;
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x64ff) { //Bcc.Lで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 4; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBhssl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BCS.W <label> |-|012346|-|----*|-----| |0110_010_100_000_000-{offset}
//BLO.W <label> |A|012346|-|----*|-----| |0110_010_100_000_000-{offset} [BCS.W <label>]
//BNCC.W <label> |A|012346|-|----*|-----| |0110_010_100_000_000-{offset} [BCS.W <label>]
//BNHS.W <label> |A|012346|-|----*|-----| |0110_010_100_000_000-{offset} [BCS.W <label>]
//JBCS.W <label> |A|012346|-|----*|-----| |0110_010_100_000_000-{offset} [BCS.W <label>]
//JBLO.W <label> |A|012346|-|----*|-----| |0110_010_100_000_000-{offset} [BCS.W <label>]
//JBNCC.W <label> |A|012346|-|----*|-----| |0110_010_100_000_000-{offset} [BCS.W <label>]
//JBNHS.W <label> |A|012346|-|----*|-----| |0110_010_100_000_000-{offset} [BCS.W <label>]
//BCS.S <label> |-|012346|-|----*|-----| |0110_010_100_sss_sss (s is not equal to 0)
//BLO.S <label> |A|012346|-|----*|-----| |0110_010_100_sss_sss (s is not equal to 0) [BCS.S <label>]
//BNCC.S <label> |A|012346|-|----*|-----| |0110_010_100_sss_sss (s is not equal to 0) [BCS.S <label>]
//BNHS.S <label> |A|012346|-|----*|-----| |0110_010_100_sss_sss (s is not equal to 0) [BCS.S <label>]
//JBCS.S <label> |A|012346|-|----*|-----| |0110_010_100_sss_sss (s is not equal to 0) [BCS.S <label>]
//JBLO.S <label> |A|012346|-|----*|-----| |0110_010_100_sss_sss (s is not equal to 0) [BCS.S <label>]
//JBNCC.S <label> |A|012346|-|----*|-----| |0110_010_100_sss_sss (s is not equal to 0) [BCS.S <label>]
//JBNHS.S <label> |A|012346|-|----*|-----| |0110_010_100_sss_sss (s is not equal to 0) [BCS.S <label>]
//JBCC.L <label> |A|012346|-|----*|-----| |0110_010_100_000_110-0100111011111001-{address} [BCS.S (*)+8;JMP <label>]
//JBHS.L <label> |A|012346|-|----*|-----| |0110_010_100_000_110-0100111011111001-{address} [BCS.S (*)+8;JMP <label>]
//JBNCS.L <label> |A|012346|-|----*|-----| |0110_010_100_000_110-0100111011111001-{address} [BCS.S (*)+8;JMP <label>]
//JBNLO.L <label> |A|012346|-|----*|-----| |0110_010_100_000_110-0100111011111001-{address} [BCS.S (*)+8;JMP <label>]
public static void irpBlosw () throws M68kException {
if (XEiJ.MPU_CC_LO << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //Bcc.Wでジャンプ
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6500) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBlosw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BCS.S <label> |-|012346|-|----*|-----| |0110_010_101_sss_sss
//BLO.S <label> |A|012346|-|----*|-----| |0110_010_101_sss_sss [BCS.S <label>]
//BNCC.S <label> |A|012346|-|----*|-----| |0110_010_101_sss_sss [BCS.S <label>]
//BNHS.S <label> |A|012346|-|----*|-----| |0110_010_101_sss_sss [BCS.S <label>]
//JBCS.S <label> |A|012346|-|----*|-----| |0110_010_101_sss_sss [BCS.S <label>]
//JBLO.S <label> |A|012346|-|----*|-----| |0110_010_101_sss_sss [BCS.S <label>]
//JBNCC.S <label> |A|012346|-|----*|-----| |0110_010_101_sss_sss [BCS.S <label>]
//JBNHS.S <label> |A|012346|-|----*|-----| |0110_010_101_sss_sss [BCS.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BCS.S <label> |-|012346|-|----*|-----| |0110_010_110_sss_sss
//BLO.S <label> |A|012346|-|----*|-----| |0110_010_110_sss_sss [BCS.S <label>]
//BNCC.S <label> |A|012346|-|----*|-----| |0110_010_110_sss_sss [BCS.S <label>]
//BNHS.S <label> |A|012346|-|----*|-----| |0110_010_110_sss_sss [BCS.S <label>]
//JBCS.S <label> |A|012346|-|----*|-----| |0110_010_110_sss_sss [BCS.S <label>]
//JBLO.S <label> |A|012346|-|----*|-----| |0110_010_110_sss_sss [BCS.S <label>]
//JBNCC.S <label> |A|012346|-|----*|-----| |0110_010_110_sss_sss [BCS.S <label>]
//JBNHS.S <label> |A|012346|-|----*|-----| |0110_010_110_sss_sss [BCS.S <label>]
public static void irpBlos () throws M68kException {
if (XEiJ.MPU_CC_LO << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBlos
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BCS.S <label> |-|--2346|-|----*|-----| |0110_010_111_sss_sss (s is not equal to 63)
//BLO.S <label> |A|--2346|-|----*|-----| |0110_010_111_sss_sss (s is not equal to 63) [BCS.S <label>]
//BNCC.S <label> |A|--2346|-|----*|-----| |0110_010_111_sss_sss (s is not equal to 63) [BCS.S <label>]
//BNHS.S <label> |A|--2346|-|----*|-----| |0110_010_111_sss_sss (s is not equal to 63) [BCS.S <label>]
//JBCS.S <label> |A|--2346|-|----*|-----| |0110_010_111_sss_sss (s is not equal to 63) [BCS.S <label>]
//JBLO.S <label> |A|--2346|-|----*|-----| |0110_010_111_sss_sss (s is not equal to 63) [BCS.S <label>]
//JBNCC.S <label> |A|--2346|-|----*|-----| |0110_010_111_sss_sss (s is not equal to 63) [BCS.S <label>]
//JBNHS.S <label> |A|--2346|-|----*|-----| |0110_010_111_sss_sss (s is not equal to 63) [BCS.S <label>]
//BCS.L <label> |-|--2346|-|----*|-----| |0110_010_111_111_111-{offset}
//BLO.L <label> |A|--2346|-|----*|-----| |0110_010_111_111_111-{offset} [BCS.L <label>]
//BNCC.L <label> |A|--2346|-|----*|-----| |0110_010_111_111_111-{offset} [BCS.L <label>]
//BNHS.L <label> |A|--2346|-|----*|-----| |0110_010_111_111_111-{offset} [BCS.L <label>]
public static void irpBlosl () throws M68kException {
if (XEiJ.MPU_CC_LO << XEiJ.regCCR < 0) { //Bccでジャンプ
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //Bcc.Lでジャンプ
XEiJ.mpuCycleCount += 14;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //Bcc.Sでジャンプ
XEiJ.mpuCycleCount += 10;
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x65ff) { //Bcc.Lで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 4; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBlosl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BNE.W <label> |-|012346|-|--*--|-----| |0110_011_000_000_000-{offset}
//BNEQ.W <label> |A|012346|-|--*--|-----| |0110_011_000_000_000-{offset} [BNE.W <label>]
//BNZ.W <label> |A|012346|-|--*--|-----| |0110_011_000_000_000-{offset} [BNE.W <label>]
//BNZE.W <label> |A|012346|-|--*--|-----| |0110_011_000_000_000-{offset} [BNE.W <label>]
//JBNE.W <label> |A|012346|-|--*--|-----| |0110_011_000_000_000-{offset} [BNE.W <label>]
//JBNEQ.W <label> |A|012346|-|--*--|-----| |0110_011_000_000_000-{offset} [BNE.W <label>]
//JBNZ.W <label> |A|012346|-|--*--|-----| |0110_011_000_000_000-{offset} [BNE.W <label>]
//JBNZE.W <label> |A|012346|-|--*--|-----| |0110_011_000_000_000-{offset} [BNE.W <label>]
//BNE.S <label> |-|012346|-|--*--|-----| |0110_011_000_sss_sss (s is not equal to 0)
//BNEQ.S <label> |A|012346|-|--*--|-----| |0110_011_000_sss_sss (s is not equal to 0) [BNE.S <label>]
//BNZ.S <label> |A|012346|-|--*--|-----| |0110_011_000_sss_sss (s is not equal to 0) [BNE.S <label>]
//BNZE.S <label> |A|012346|-|--*--|-----| |0110_011_000_sss_sss (s is not equal to 0) [BNE.S <label>]
//JBNE.S <label> |A|012346|-|--*--|-----| |0110_011_000_sss_sss (s is not equal to 0) [BNE.S <label>]
//JBNEQ.S <label> |A|012346|-|--*--|-----| |0110_011_000_sss_sss (s is not equal to 0) [BNE.S <label>]
//JBNZ.S <label> |A|012346|-|--*--|-----| |0110_011_000_sss_sss (s is not equal to 0) [BNE.S <label>]
//JBNZE.S <label> |A|012346|-|--*--|-----| |0110_011_000_sss_sss (s is not equal to 0) [BNE.S <label>]
//JBEQ.L <label> |A|012346|-|--*--|-----| |0110_011_000_000_110-0100111011111001-{address} [BNE.S (*)+8;JMP <label>]
//JBNEQ.L <label> |A|012346|-|--*--|-----| |0110_011_000_000_110-0100111011111001-{address} [BNE.S (*)+8;JMP <label>]
//JBNNE.L <label> |A|012346|-|--*--|-----| |0110_011_000_000_110-0100111011111001-{address} [BNE.S (*)+8;JMP <label>]
//JBNNZ.L <label> |A|012346|-|--*--|-----| |0110_011_000_000_110-0100111011111001-{address} [BNE.S (*)+8;JMP <label>]
//JBNZ.L <label> |A|012346|-|--*--|-----| |0110_011_000_000_110-0100111011111001-{address} [BNE.S (*)+8;JMP <label>]
//JBNZE.L <label> |A|012346|-|--*--|-----| |0110_011_000_000_110-0100111011111001-{address} [BNE.S (*)+8;JMP <label>]
//JBZE.L <label> |A|012346|-|--*--|-----| |0110_011_000_000_110-0100111011111001-{address} [BNE.S (*)+8;JMP <label>]
public static void irpBnesw () throws M68kException {
if (XEiJ.MPU_CC_NE << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //Bcc.Wでジャンプ
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6600) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBnesw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BNE.S <label> |-|012346|-|--*--|-----| |0110_011_001_sss_sss
//BNEQ.S <label> |A|012346|-|--*--|-----| |0110_011_001_sss_sss [BNE.S <label>]
//BNZ.S <label> |A|012346|-|--*--|-----| |0110_011_001_sss_sss [BNE.S <label>]
//BNZE.S <label> |A|012346|-|--*--|-----| |0110_011_001_sss_sss [BNE.S <label>]
//JBNE.S <label> |A|012346|-|--*--|-----| |0110_011_001_sss_sss [BNE.S <label>]
//JBNEQ.S <label> |A|012346|-|--*--|-----| |0110_011_001_sss_sss [BNE.S <label>]
//JBNZ.S <label> |A|012346|-|--*--|-----| |0110_011_001_sss_sss [BNE.S <label>]
//JBNZE.S <label> |A|012346|-|--*--|-----| |0110_011_001_sss_sss [BNE.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BNE.S <label> |-|012346|-|--*--|-----| |0110_011_010_sss_sss
//BNEQ.S <label> |A|012346|-|--*--|-----| |0110_011_010_sss_sss [BNE.S <label>]
//BNZ.S <label> |A|012346|-|--*--|-----| |0110_011_010_sss_sss [BNE.S <label>]
//BNZE.S <label> |A|012346|-|--*--|-----| |0110_011_010_sss_sss [BNE.S <label>]
//JBNE.S <label> |A|012346|-|--*--|-----| |0110_011_010_sss_sss [BNE.S <label>]
//JBNEQ.S <label> |A|012346|-|--*--|-----| |0110_011_010_sss_sss [BNE.S <label>]
//JBNZ.S <label> |A|012346|-|--*--|-----| |0110_011_010_sss_sss [BNE.S <label>]
//JBNZE.S <label> |A|012346|-|--*--|-----| |0110_011_010_sss_sss [BNE.S <label>]
public static void irpBnes () throws M68kException {
if (XEiJ.MPU_CC_NE << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBnes
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BNE.S <label> |-|--2346|-|--*--|-----| |0110_011_011_sss_sss (s is not equal to 63)
//BNEQ.S <label> |A|--2346|-|--*--|-----| |0110_011_011_sss_sss (s is not equal to 63) [BNE.S <label>]
//BNZ.S <label> |A|--2346|-|--*--|-----| |0110_011_011_sss_sss (s is not equal to 63) [BNE.S <label>]
//BNZE.S <label> |A|--2346|-|--*--|-----| |0110_011_011_sss_sss (s is not equal to 63) [BNE.S <label>]
//JBNE.S <label> |A|--2346|-|--*--|-----| |0110_011_011_sss_sss (s is not equal to 63) [BNE.S <label>]
//JBNEQ.S <label> |A|--2346|-|--*--|-----| |0110_011_011_sss_sss (s is not equal to 63) [BNE.S <label>]
//JBNZ.S <label> |A|--2346|-|--*--|-----| |0110_011_011_sss_sss (s is not equal to 63) [BNE.S <label>]
//JBNZE.S <label> |A|--2346|-|--*--|-----| |0110_011_011_sss_sss (s is not equal to 63) [BNE.S <label>]
//BNE.L <label> |-|--2346|-|--*--|-----| |0110_011_011_111_111-{offset}
//BNEQ.L <label> |A|--2346|-|--*--|-----| |0110_011_011_111_111-{offset} [BNE.L <label>]
//BNZ.L <label> |A|--2346|-|--*--|-----| |0110_011_011_111_111-{offset} [BNE.L <label>]
//BNZE.L <label> |A|--2346|-|--*--|-----| |0110_011_011_111_111-{offset} [BNE.L <label>]
public static void irpBnesl () throws M68kException {
if (XEiJ.MPU_CC_NE << XEiJ.regCCR < 0) { //Bccでジャンプ
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //Bcc.Lでジャンプ
XEiJ.mpuCycleCount += 14;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //Bcc.Sでジャンプ
XEiJ.mpuCycleCount += 10;
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x66ff) { //Bcc.Lで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 4; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBnesl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BEQ.W <label> |-|012346|-|--*--|-----| |0110_011_100_000_000-{offset}
//BNNE.W <label> |A|012346|-|--*--|-----| |0110_011_100_000_000-{offset} [BEQ.W <label>]
//BNNZ.W <label> |A|012346|-|--*--|-----| |0110_011_100_000_000-{offset} [BEQ.W <label>]
//BZE.W <label> |A|012346|-|--*--|-----| |0110_011_100_000_000-{offset} [BEQ.W <label>]
//JBEQ.W <label> |A|012346|-|--*--|-----| |0110_011_100_000_000-{offset} [BEQ.W <label>]
//JBNNE.W <label> |A|012346|-|--*--|-----| |0110_011_100_000_000-{offset} [BEQ.W <label>]
//JBNNZ.W <label> |A|012346|-|--*--|-----| |0110_011_100_000_000-{offset} [BEQ.W <label>]
//JBZE.W <label> |A|012346|-|--*--|-----| |0110_011_100_000_000-{offset} [BEQ.W <label>]
//BEQ.S <label> |-|012346|-|--*--|-----| |0110_011_100_sss_sss (s is not equal to 0)
//BNNE.S <label> |A|012346|-|--*--|-----| |0110_011_100_sss_sss (s is not equal to 0) [BEQ.S <label>]
//BNNZ.S <label> |A|012346|-|--*--|-----| |0110_011_100_sss_sss (s is not equal to 0) [BEQ.S <label>]
//BZE.S <label> |A|012346|-|--*--|-----| |0110_011_100_sss_sss (s is not equal to 0) [BEQ.S <label>]
//JBEQ.S <label> |A|012346|-|--*--|-----| |0110_011_100_sss_sss (s is not equal to 0) [BEQ.S <label>]
//JBNNE.S <label> |A|012346|-|--*--|-----| |0110_011_100_sss_sss (s is not equal to 0) [BEQ.S <label>]
//JBNNZ.S <label> |A|012346|-|--*--|-----| |0110_011_100_sss_sss (s is not equal to 0) [BEQ.S <label>]
//JBZE.S <label> |A|012346|-|--*--|-----| |0110_011_100_sss_sss (s is not equal to 0) [BEQ.S <label>]
//JBNE.L <label> |A|012346|-|--*--|-----| |0110_011_100_000_110-0100111011111001-{address} [BEQ.S (*)+8;JMP <label>]
public static void irpBeqsw () throws M68kException {
if (XEiJ.MPU_CC_EQ << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //Bcc.Wでジャンプ
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6700) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBeqsw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BEQ.S <label> |-|012346|-|--*--|-----| |0110_011_101_sss_sss
//BNNE.S <label> |A|012346|-|--*--|-----| |0110_011_101_sss_sss [BEQ.S <label>]
//BNNZ.S <label> |A|012346|-|--*--|-----| |0110_011_101_sss_sss [BEQ.S <label>]
//BZE.S <label> |A|012346|-|--*--|-----| |0110_011_101_sss_sss [BEQ.S <label>]
//JBEQ.S <label> |A|012346|-|--*--|-----| |0110_011_101_sss_sss [BEQ.S <label>]
//JBNNE.S <label> |A|012346|-|--*--|-----| |0110_011_101_sss_sss [BEQ.S <label>]
//JBNNZ.S <label> |A|012346|-|--*--|-----| |0110_011_101_sss_sss [BEQ.S <label>]
//JBZE.S <label> |A|012346|-|--*--|-----| |0110_011_101_sss_sss [BEQ.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BEQ.S <label> |-|012346|-|--*--|-----| |0110_011_110_sss_sss
//BNNE.S <label> |A|012346|-|--*--|-----| |0110_011_110_sss_sss [BEQ.S <label>]
//BNNZ.S <label> |A|012346|-|--*--|-----| |0110_011_110_sss_sss [BEQ.S <label>]
//BZE.S <label> |A|012346|-|--*--|-----| |0110_011_110_sss_sss [BEQ.S <label>]
//JBEQ.S <label> |A|012346|-|--*--|-----| |0110_011_110_sss_sss [BEQ.S <label>]
//JBNNE.S <label> |A|012346|-|--*--|-----| |0110_011_110_sss_sss [BEQ.S <label>]
//JBNNZ.S <label> |A|012346|-|--*--|-----| |0110_011_110_sss_sss [BEQ.S <label>]
//JBZE.S <label> |A|012346|-|--*--|-----| |0110_011_110_sss_sss [BEQ.S <label>]
public static void irpBeqs () throws M68kException {
if (XEiJ.MPU_CC_EQ << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBeqs
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BEQ.S <label> |-|--2346|-|--*--|-----| |0110_011_111_sss_sss (s is not equal to 63)
//BNNE.S <label> |A|--2346|-|--*--|-----| |0110_011_111_sss_sss (s is not equal to 63) [BEQ.S <label>]
//BNNZ.S <label> |A|--2346|-|--*--|-----| |0110_011_111_sss_sss (s is not equal to 63) [BEQ.S <label>]
//BZE.S <label> |A|--2346|-|--*--|-----| |0110_011_111_sss_sss (s is not equal to 63) [BEQ.S <label>]
//JBEQ.S <label> |A|--2346|-|--*--|-----| |0110_011_111_sss_sss (s is not equal to 63) [BEQ.S <label>]
//JBNNE.S <label> |A|--2346|-|--*--|-----| |0110_011_111_sss_sss (s is not equal to 63) [BEQ.S <label>]
//JBNNZ.S <label> |A|--2346|-|--*--|-----| |0110_011_111_sss_sss (s is not equal to 63) [BEQ.S <label>]
//JBZE.S <label> |A|--2346|-|--*--|-----| |0110_011_111_sss_sss (s is not equal to 63) [BEQ.S <label>]
//BEQ.L <label> |-|--2346|-|--*--|-----| |0110_011_111_111_111-{offset}
//BNNE.L <label> |A|--2346|-|--*--|-----| |0110_011_111_111_111-{offset} [BEQ.L <label>]
//BNNZ.L <label> |A|--2346|-|--*--|-----| |0110_011_111_111_111-{offset} [BEQ.L <label>]
//BZE.L <label> |A|--2346|-|--*--|-----| |0110_011_111_111_111-{offset} [BEQ.L <label>]
public static void irpBeqsl () throws M68kException {
if (XEiJ.MPU_CC_EQ << XEiJ.regCCR < 0) { //Bccでジャンプ
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //Bcc.Lでジャンプ
XEiJ.mpuCycleCount += 14;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //Bcc.Sでジャンプ
XEiJ.mpuCycleCount += 10;
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x67ff) { //Bcc.Lで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 4; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBeqsl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BVC.W <label> |-|012346|-|---*-|-----| |0110_100_000_000_000-{offset}
//BNVS.W <label> |A|012346|-|---*-|-----| |0110_100_000_000_000-{offset} [BVC.W <label>]
//JBNVS.W <label> |A|012346|-|---*-|-----| |0110_100_000_000_000-{offset} [BVC.W <label>]
//JBVC.W <label> |A|012346|-|---*-|-----| |0110_100_000_000_000-{offset} [BVC.W <label>]
//BVC.S <label> |-|012346|-|---*-|-----| |0110_100_000_sss_sss (s is not equal to 0)
//BNVS.S <label> |A|012346|-|---*-|-----| |0110_100_000_sss_sss (s is not equal to 0) [BVC.S <label>]
//JBNVS.S <label> |A|012346|-|---*-|-----| |0110_100_000_sss_sss (s is not equal to 0) [BVC.S <label>]
//JBVC.S <label> |A|012346|-|---*-|-----| |0110_100_000_sss_sss (s is not equal to 0) [BVC.S <label>]
//JBNVC.L <label> |A|012346|-|---*-|-----| |0110_100_000_000_110-0100111011111001-{address} [BVC.S (*)+8;JMP <label>]
//JBVS.L <label> |A|012346|-|---*-|-----| |0110_100_000_000_110-0100111011111001-{address} [BVC.S (*)+8;JMP <label>]
public static void irpBvcsw () throws M68kException {
if (XEiJ.MPU_CC_VC << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //Bcc.Wでジャンプ
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6800) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBvcsw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BVC.S <label> |-|012346|-|---*-|-----| |0110_100_001_sss_sss
//BNVS.S <label> |A|012346|-|---*-|-----| |0110_100_001_sss_sss [BVC.S <label>]
//JBNVS.S <label> |A|012346|-|---*-|-----| |0110_100_001_sss_sss [BVC.S <label>]
//JBVC.S <label> |A|012346|-|---*-|-----| |0110_100_001_sss_sss [BVC.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BVC.S <label> |-|012346|-|---*-|-----| |0110_100_010_sss_sss
//BNVS.S <label> |A|012346|-|---*-|-----| |0110_100_010_sss_sss [BVC.S <label>]
//JBNVS.S <label> |A|012346|-|---*-|-----| |0110_100_010_sss_sss [BVC.S <label>]
//JBVC.S <label> |A|012346|-|---*-|-----| |0110_100_010_sss_sss [BVC.S <label>]
public static void irpBvcs () throws M68kException {
if (XEiJ.MPU_CC_VC << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBvcs
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BVC.S <label> |-|--2346|-|---*-|-----| |0110_100_011_sss_sss (s is not equal to 63)
//BNVS.S <label> |A|--2346|-|---*-|-----| |0110_100_011_sss_sss (s is not equal to 63) [BVC.S <label>]
//JBNVS.S <label> |A|--2346|-|---*-|-----| |0110_100_011_sss_sss (s is not equal to 63) [BVC.S <label>]
//JBVC.S <label> |A|--2346|-|---*-|-----| |0110_100_011_sss_sss (s is not equal to 63) [BVC.S <label>]
//BVC.L <label> |-|--2346|-|---*-|-----| |0110_100_011_111_111-{offset}
//BNVS.L <label> |A|--2346|-|---*-|-----| |0110_100_011_111_111-{offset} [BVC.L <label>]
public static void irpBvcsl () throws M68kException {
if (XEiJ.MPU_CC_VC << XEiJ.regCCR < 0) { //Bccでジャンプ
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //Bcc.Lでジャンプ
XEiJ.mpuCycleCount += 14;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //Bcc.Sでジャンプ
XEiJ.mpuCycleCount += 10;
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x68ff) { //Bcc.Lで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 4; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBvcsl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BVS.W <label> |-|012346|-|---*-|-----| |0110_100_100_000_000-{offset}
//BNVC.W <label> |A|012346|-|---*-|-----| |0110_100_100_000_000-{offset} [BVS.W <label>]
//JBNVC.W <label> |A|012346|-|---*-|-----| |0110_100_100_000_000-{offset} [BVS.W <label>]
//JBVS.W <label> |A|012346|-|---*-|-----| |0110_100_100_000_000-{offset} [BVS.W <label>]
//BVS.S <label> |-|012346|-|---*-|-----| |0110_100_100_sss_sss (s is not equal to 0)
//BNVC.S <label> |A|012346|-|---*-|-----| |0110_100_100_sss_sss (s is not equal to 0) [BVS.S <label>]
//JBNVC.S <label> |A|012346|-|---*-|-----| |0110_100_100_sss_sss (s is not equal to 0) [BVS.S <label>]
//JBVS.S <label> |A|012346|-|---*-|-----| |0110_100_100_sss_sss (s is not equal to 0) [BVS.S <label>]
//JBNVS.L <label> |A|012346|-|---*-|-----| |0110_100_100_000_110-0100111011111001-{address} [BVS.S (*)+8;JMP <label>]
//JBVC.L <label> |A|012346|-|---*-|-----| |0110_100_100_000_110-0100111011111001-{address} [BVS.S (*)+8;JMP <label>]
public static void irpBvssw () throws M68kException {
if (XEiJ.MPU_CC_VS << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //Bcc.Wでジャンプ
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6900) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBvssw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BVS.S <label> |-|012346|-|---*-|-----| |0110_100_101_sss_sss
//BNVC.S <label> |A|012346|-|---*-|-----| |0110_100_101_sss_sss [BVS.S <label>]
//JBNVC.S <label> |A|012346|-|---*-|-----| |0110_100_101_sss_sss [BVS.S <label>]
//JBVS.S <label> |A|012346|-|---*-|-----| |0110_100_101_sss_sss [BVS.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BVS.S <label> |-|012346|-|---*-|-----| |0110_100_110_sss_sss
//BNVC.S <label> |A|012346|-|---*-|-----| |0110_100_110_sss_sss [BVS.S <label>]
//JBNVC.S <label> |A|012346|-|---*-|-----| |0110_100_110_sss_sss [BVS.S <label>]
//JBVS.S <label> |A|012346|-|---*-|-----| |0110_100_110_sss_sss [BVS.S <label>]
public static void irpBvss () throws M68kException {
if (XEiJ.MPU_CC_VS << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBvss
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BVS.S <label> |-|--2346|-|---*-|-----| |0110_100_111_sss_sss (s is not equal to 63)
//BNVC.S <label> |A|--2346|-|---*-|-----| |0110_100_111_sss_sss (s is not equal to 63) [BVS.S <label>]
//JBNVC.S <label> |A|--2346|-|---*-|-----| |0110_100_111_sss_sss (s is not equal to 63) [BVS.S <label>]
//JBVS.S <label> |A|--2346|-|---*-|-----| |0110_100_111_sss_sss (s is not equal to 63) [BVS.S <label>]
//BVS.L <label> |-|--2346|-|---*-|-----| |0110_100_111_111_111-{offset}
//BNVC.L <label> |A|--2346|-|---*-|-----| |0110_100_111_111_111-{offset} [BVS.L <label>]
public static void irpBvssl () throws M68kException {
if (XEiJ.MPU_CC_VS << XEiJ.regCCR < 0) { //Bccでジャンプ
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //Bcc.Lでジャンプ
XEiJ.mpuCycleCount += 14;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //Bcc.Sでジャンプ
XEiJ.mpuCycleCount += 10;
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x69ff) { //Bcc.Lで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 4; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBvssl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BPL.W <label> |-|012346|-|-*---|-----| |0110_101_000_000_000-{offset}
//BNMI.W <label> |A|012346|-|-*---|-----| |0110_101_000_000_000-{offset} [BPL.W <label>]
//JBNMI.W <label> |A|012346|-|-*---|-----| |0110_101_000_000_000-{offset} [BPL.W <label>]
//JBPL.W <label> |A|012346|-|-*---|-----| |0110_101_000_000_000-{offset} [BPL.W <label>]
//BPL.S <label> |-|012346|-|-*---|-----| |0110_101_000_sss_sss (s is not equal to 0)
//BNMI.S <label> |A|012346|-|-*---|-----| |0110_101_000_sss_sss (s is not equal to 0) [BPL.S <label>]
//JBNMI.S <label> |A|012346|-|-*---|-----| |0110_101_000_sss_sss (s is not equal to 0) [BPL.S <label>]
//JBPL.S <label> |A|012346|-|-*---|-----| |0110_101_000_sss_sss (s is not equal to 0) [BPL.S <label>]
//JBMI.L <label> |A|012346|-|-*---|-----| |0110_101_000_000_110-0100111011111001-{address} [BPL.S (*)+8;JMP <label>]
//JBNPL.L <label> |A|012346|-|-*---|-----| |0110_101_000_000_110-0100111011111001-{address} [BPL.S (*)+8;JMP <label>]
public static void irpBplsw () throws M68kException {
if (XEiJ.MPU_CC_PL << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //Bcc.Wでジャンプ
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6a00) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBplsw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BPL.S <label> |-|012346|-|-*---|-----| |0110_101_001_sss_sss
//BNMI.S <label> |A|012346|-|-*---|-----| |0110_101_001_sss_sss [BPL.S <label>]
//JBNMI.S <label> |A|012346|-|-*---|-----| |0110_101_001_sss_sss [BPL.S <label>]
//JBPL.S <label> |A|012346|-|-*---|-----| |0110_101_001_sss_sss [BPL.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BPL.S <label> |-|012346|-|-*---|-----| |0110_101_010_sss_sss
//BNMI.S <label> |A|012346|-|-*---|-----| |0110_101_010_sss_sss [BPL.S <label>]
//JBNMI.S <label> |A|012346|-|-*---|-----| |0110_101_010_sss_sss [BPL.S <label>]
//JBPL.S <label> |A|012346|-|-*---|-----| |0110_101_010_sss_sss [BPL.S <label>]
public static void irpBpls () throws M68kException {
if (XEiJ.MPU_CC_PL << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBpls
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BPL.S <label> |-|--2346|-|-*---|-----| |0110_101_011_sss_sss (s is not equal to 63)
//BNMI.S <label> |A|--2346|-|-*---|-----| |0110_101_011_sss_sss (s is not equal to 63) [BPL.S <label>]
//JBNMI.S <label> |A|--2346|-|-*---|-----| |0110_101_011_sss_sss (s is not equal to 63) [BPL.S <label>]
//JBPL.S <label> |A|--2346|-|-*---|-----| |0110_101_011_sss_sss (s is not equal to 63) [BPL.S <label>]
//BPL.L <label> |-|--2346|-|-*---|-----| |0110_101_011_111_111-{offset}
//BNMI.L <label> |A|--2346|-|-*---|-----| |0110_101_011_111_111-{offset} [BPL.L <label>]
public static void irpBplsl () throws M68kException {
if (XEiJ.MPU_CC_PL << XEiJ.regCCR < 0) { //Bccでジャンプ
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //Bcc.Lでジャンプ
XEiJ.mpuCycleCount += 14;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //Bcc.Sでジャンプ
XEiJ.mpuCycleCount += 10;
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6aff) { //Bcc.Lで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 4; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBplsl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BMI.W <label> |-|012346|-|-*---|-----| |0110_101_100_000_000-{offset}
//BNPL.W <label> |A|012346|-|-*---|-----| |0110_101_100_000_000-{offset} [BMI.W <label>]
//JBMI.W <label> |A|012346|-|-*---|-----| |0110_101_100_000_000-{offset} [BMI.W <label>]
//JBNPL.W <label> |A|012346|-|-*---|-----| |0110_101_100_000_000-{offset} [BMI.W <label>]
//BMI.S <label> |-|012346|-|-*---|-----| |0110_101_100_sss_sss (s is not equal to 0)
//BNPL.S <label> |A|012346|-|-*---|-----| |0110_101_100_sss_sss (s is not equal to 0) [BMI.S <label>]
//JBMI.S <label> |A|012346|-|-*---|-----| |0110_101_100_sss_sss (s is not equal to 0) [BMI.S <label>]
//JBNPL.S <label> |A|012346|-|-*---|-----| |0110_101_100_sss_sss (s is not equal to 0) [BMI.S <label>]
//JBNMI.L <label> |A|012346|-|-*---|-----| |0110_101_100_000_110-0100111011111001-{address} [BMI.S (*)+8;JMP <label>]
//JBPL.L <label> |A|012346|-|-*---|-----| |0110_101_100_000_110-0100111011111001-{address} [BMI.S (*)+8;JMP <label>]
public static void irpBmisw () throws M68kException {
if (XEiJ.MPU_CC_MI << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //Bcc.Wでジャンプ
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6b00) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBmisw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BMI.S <label> |-|012346|-|-*---|-----| |0110_101_101_sss_sss
//BNPL.S <label> |A|012346|-|-*---|-----| |0110_101_101_sss_sss [BMI.S <label>]
//JBMI.S <label> |A|012346|-|-*---|-----| |0110_101_101_sss_sss [BMI.S <label>]
//JBNPL.S <label> |A|012346|-|-*---|-----| |0110_101_101_sss_sss [BMI.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BMI.S <label> |-|012346|-|-*---|-----| |0110_101_110_sss_sss
//BNPL.S <label> |A|012346|-|-*---|-----| |0110_101_110_sss_sss [BMI.S <label>]
//JBMI.S <label> |A|012346|-|-*---|-----| |0110_101_110_sss_sss [BMI.S <label>]
//JBNPL.S <label> |A|012346|-|-*---|-----| |0110_101_110_sss_sss [BMI.S <label>]
public static void irpBmis () throws M68kException {
if (XEiJ.MPU_CC_MI << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBmis
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BMI.S <label> |-|--2346|-|-*---|-----| |0110_101_111_sss_sss (s is not equal to 63)
//BNPL.S <label> |A|--2346|-|-*---|-----| |0110_101_111_sss_sss (s is not equal to 63) [BMI.S <label>]
//JBMI.S <label> |A|--2346|-|-*---|-----| |0110_101_111_sss_sss (s is not equal to 63) [BMI.S <label>]
//JBNPL.S <label> |A|--2346|-|-*---|-----| |0110_101_111_sss_sss (s is not equal to 63) [BMI.S <label>]
//BMI.L <label> |-|--2346|-|-*---|-----| |0110_101_111_111_111-{offset}
//BNPL.L <label> |A|--2346|-|-*---|-----| |0110_101_111_111_111-{offset} [BMI.L <label>]
public static void irpBmisl () throws M68kException {
if (XEiJ.MPU_CC_MI << XEiJ.regCCR < 0) { //Bccでジャンプ
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //Bcc.Lでジャンプ
XEiJ.mpuCycleCount += 14;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //Bcc.Sでジャンプ
XEiJ.mpuCycleCount += 10;
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6bff) { //Bcc.Lで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 4; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBmisl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BGE.W <label> |-|012346|-|-*-*-|-----| |0110_110_000_000_000-{offset}
//BNLT.W <label> |A|012346|-|-*-*-|-----| |0110_110_000_000_000-{offset} [BGE.W <label>]
//JBGE.W <label> |A|012346|-|-*-*-|-----| |0110_110_000_000_000-{offset} [BGE.W <label>]
//JBNLT.W <label> |A|012346|-|-*-*-|-----| |0110_110_000_000_000-{offset} [BGE.W <label>]
//BGE.S <label> |-|012346|-|-*-*-|-----| |0110_110_000_sss_sss (s is not equal to 0)
//BNLT.S <label> |A|012346|-|-*-*-|-----| |0110_110_000_sss_sss (s is not equal to 0) [BGE.S <label>]
//JBGE.S <label> |A|012346|-|-*-*-|-----| |0110_110_000_sss_sss (s is not equal to 0) [BGE.S <label>]
//JBNLT.S <label> |A|012346|-|-*-*-|-----| |0110_110_000_sss_sss (s is not equal to 0) [BGE.S <label>]
//JBLT.L <label> |A|012346|-|-*-*-|-----| |0110_110_000_000_110-0100111011111001-{address} [BGE.S (*)+8;JMP <label>]
//JBNGE.L <label> |A|012346|-|-*-*-|-----| |0110_110_000_000_110-0100111011111001-{address} [BGE.S (*)+8;JMP <label>]
public static void irpBgesw () throws M68kException {
if (XEiJ.MPU_CC_GE << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //Bcc.Wでジャンプ
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6c00) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBgesw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BGE.S <label> |-|012346|-|-*-*-|-----| |0110_110_001_sss_sss
//BNLT.S <label> |A|012346|-|-*-*-|-----| |0110_110_001_sss_sss [BGE.S <label>]
//JBGE.S <label> |A|012346|-|-*-*-|-----| |0110_110_001_sss_sss [BGE.S <label>]
//JBNLT.S <label> |A|012346|-|-*-*-|-----| |0110_110_001_sss_sss [BGE.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BGE.S <label> |-|012346|-|-*-*-|-----| |0110_110_010_sss_sss
//BNLT.S <label> |A|012346|-|-*-*-|-----| |0110_110_010_sss_sss [BGE.S <label>]
//JBGE.S <label> |A|012346|-|-*-*-|-----| |0110_110_010_sss_sss [BGE.S <label>]
//JBNLT.S <label> |A|012346|-|-*-*-|-----| |0110_110_010_sss_sss [BGE.S <label>]
public static void irpBges () throws M68kException {
if (XEiJ.MPU_CC_GE << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBges
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BGE.S <label> |-|--2346|-|-*-*-|-----| |0110_110_011_sss_sss (s is not equal to 63)
//BNLT.S <label> |A|--2346|-|-*-*-|-----| |0110_110_011_sss_sss (s is not equal to 63) [BGE.S <label>]
//JBGE.S <label> |A|--2346|-|-*-*-|-----| |0110_110_011_sss_sss (s is not equal to 63) [BGE.S <label>]
//JBNLT.S <label> |A|--2346|-|-*-*-|-----| |0110_110_011_sss_sss (s is not equal to 63) [BGE.S <label>]
//BGE.L <label> |-|--2346|-|-*-*-|-----| |0110_110_011_111_111-{offset}
//BNLT.L <label> |A|--2346|-|-*-*-|-----| |0110_110_011_111_111-{offset} [BGE.L <label>]
public static void irpBgesl () throws M68kException {
if (XEiJ.MPU_CC_GE << XEiJ.regCCR < 0) { //Bccでジャンプ
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //Bcc.Lでジャンプ
XEiJ.mpuCycleCount += 14;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //Bcc.Sでジャンプ
XEiJ.mpuCycleCount += 10;
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6cff) { //Bcc.Lで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 4; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBgesl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BLT.W <label> |-|012346|-|-*-*-|-----| |0110_110_100_000_000-{offset}
//BNGE.W <label> |A|012346|-|-*-*-|-----| |0110_110_100_000_000-{offset} [BLT.W <label>]
//JBLT.W <label> |A|012346|-|-*-*-|-----| |0110_110_100_000_000-{offset} [BLT.W <label>]
//JBNGE.W <label> |A|012346|-|-*-*-|-----| |0110_110_100_000_000-{offset} [BLT.W <label>]
//BLT.S <label> |-|012346|-|-*-*-|-----| |0110_110_100_sss_sss (s is not equal to 0)
//BNGE.S <label> |A|012346|-|-*-*-|-----| |0110_110_100_sss_sss (s is not equal to 0) [BLT.S <label>]
//JBLT.S <label> |A|012346|-|-*-*-|-----| |0110_110_100_sss_sss (s is not equal to 0) [BLT.S <label>]
//JBNGE.S <label> |A|012346|-|-*-*-|-----| |0110_110_100_sss_sss (s is not equal to 0) [BLT.S <label>]
//JBGE.L <label> |A|012346|-|-*-*-|-----| |0110_110_100_000_110-0100111011111001-{address} [BLT.S (*)+8;JMP <label>]
//JBNLT.L <label> |A|012346|-|-*-*-|-----| |0110_110_100_000_110-0100111011111001-{address} [BLT.S (*)+8;JMP <label>]
public static void irpBltsw () throws M68kException {
if (XEiJ.MPU_CC_LT << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //Bcc.Wでジャンプ
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6d00) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBltsw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BLT.S <label> |-|012346|-|-*-*-|-----| |0110_110_101_sss_sss
//BNGE.S <label> |A|012346|-|-*-*-|-----| |0110_110_101_sss_sss [BLT.S <label>]
//JBLT.S <label> |A|012346|-|-*-*-|-----| |0110_110_101_sss_sss [BLT.S <label>]
//JBNGE.S <label> |A|012346|-|-*-*-|-----| |0110_110_101_sss_sss [BLT.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BLT.S <label> |-|012346|-|-*-*-|-----| |0110_110_110_sss_sss
//BNGE.S <label> |A|012346|-|-*-*-|-----| |0110_110_110_sss_sss [BLT.S <label>]
//JBLT.S <label> |A|012346|-|-*-*-|-----| |0110_110_110_sss_sss [BLT.S <label>]
//JBNGE.S <label> |A|012346|-|-*-*-|-----| |0110_110_110_sss_sss [BLT.S <label>]
public static void irpBlts () throws M68kException {
if (XEiJ.MPU_CC_LT << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBlts
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BLT.S <label> |-|--2346|-|-*-*-|-----| |0110_110_111_sss_sss (s is not equal to 63)
//BNGE.S <label> |A|--2346|-|-*-*-|-----| |0110_110_111_sss_sss (s is not equal to 63) [BLT.S <label>]
//JBLT.S <label> |A|--2346|-|-*-*-|-----| |0110_110_111_sss_sss (s is not equal to 63) [BLT.S <label>]
//JBNGE.S <label> |A|--2346|-|-*-*-|-----| |0110_110_111_sss_sss (s is not equal to 63) [BLT.S <label>]
//BLT.L <label> |-|--2346|-|-*-*-|-----| |0110_110_111_111_111-{offset}
//BNGE.L <label> |A|--2346|-|-*-*-|-----| |0110_110_111_111_111-{offset} [BLT.L <label>]
public static void irpBltsl () throws M68kException {
if (XEiJ.MPU_CC_LT << XEiJ.regCCR < 0) { //Bccでジャンプ
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //Bcc.Lでジャンプ
XEiJ.mpuCycleCount += 14;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //Bcc.Sでジャンプ
XEiJ.mpuCycleCount += 10;
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6dff) { //Bcc.Lで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 4; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBltsl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BGT.W <label> |-|012346|-|-***-|-----| |0110_111_000_000_000-{offset}
//BNLE.W <label> |A|012346|-|-***-|-----| |0110_111_000_000_000-{offset} [BGT.W <label>]
//JBGT.W <label> |A|012346|-|-***-|-----| |0110_111_000_000_000-{offset} [BGT.W <label>]
//JBNLE.W <label> |A|012346|-|-***-|-----| |0110_111_000_000_000-{offset} [BGT.W <label>]
//BGT.S <label> |-|012346|-|-***-|-----| |0110_111_000_sss_sss (s is not equal to 0)
//BNLE.S <label> |A|012346|-|-***-|-----| |0110_111_000_sss_sss (s is not equal to 0) [BGT.S <label>]
//JBGT.S <label> |A|012346|-|-***-|-----| |0110_111_000_sss_sss (s is not equal to 0) [BGT.S <label>]
//JBNLE.S <label> |A|012346|-|-***-|-----| |0110_111_000_sss_sss (s is not equal to 0) [BGT.S <label>]
//JBLE.L <label> |A|012346|-|-***-|-----| |0110_111_000_000_110-0100111011111001-{address} [BGT.S (*)+8;JMP <label>]
//JBNGT.L <label> |A|012346|-|-***-|-----| |0110_111_000_000_110-0100111011111001-{address} [BGT.S (*)+8;JMP <label>]
public static void irpBgtsw () throws M68kException {
if (XEiJ.MPU_CC_GT << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //Bcc.Wでジャンプ
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6e00) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBgtsw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BGT.S <label> |-|012346|-|-***-|-----| |0110_111_001_sss_sss
//BNLE.S <label> |A|012346|-|-***-|-----| |0110_111_001_sss_sss [BGT.S <label>]
//JBGT.S <label> |A|012346|-|-***-|-----| |0110_111_001_sss_sss [BGT.S <label>]
//JBNLE.S <label> |A|012346|-|-***-|-----| |0110_111_001_sss_sss [BGT.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BGT.S <label> |-|012346|-|-***-|-----| |0110_111_010_sss_sss
//BNLE.S <label> |A|012346|-|-***-|-----| |0110_111_010_sss_sss [BGT.S <label>]
//JBGT.S <label> |A|012346|-|-***-|-----| |0110_111_010_sss_sss [BGT.S <label>]
//JBNLE.S <label> |A|012346|-|-***-|-----| |0110_111_010_sss_sss [BGT.S <label>]
public static void irpBgts () throws M68kException {
if (XEiJ.MPU_CC_GT << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBgts
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BGT.S <label> |-|--2346|-|-***-|-----| |0110_111_011_sss_sss (s is not equal to 63)
//BNLE.S <label> |A|--2346|-|-***-|-----| |0110_111_011_sss_sss (s is not equal to 63) [BGT.S <label>]
//JBGT.S <label> |A|--2346|-|-***-|-----| |0110_111_011_sss_sss (s is not equal to 63) [BGT.S <label>]
//JBNLE.S <label> |A|--2346|-|-***-|-----| |0110_111_011_sss_sss (s is not equal to 63) [BGT.S <label>]
//BGT.L <label> |-|--2346|-|-***-|-----| |0110_111_011_111_111-{offset}
//BNLE.L <label> |A|--2346|-|-***-|-----| |0110_111_011_111_111-{offset} [BGT.L <label>]
public static void irpBgtsl () throws M68kException {
if (XEiJ.MPU_CC_GT << XEiJ.regCCR < 0) { //Bccでジャンプ
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //Bcc.Lでジャンプ
XEiJ.mpuCycleCount += 14;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //Bcc.Sでジャンプ
XEiJ.mpuCycleCount += 10;
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6eff) { //Bcc.Lで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 4; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBgtsl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BLE.W <label> |-|012346|-|-***-|-----| |0110_111_100_000_000-{offset}
//BNGT.W <label> |A|012346|-|-***-|-----| |0110_111_100_000_000-{offset} [BLE.W <label>]
//JBLE.W <label> |A|012346|-|-***-|-----| |0110_111_100_000_000-{offset} [BLE.W <label>]
//JBNGT.W <label> |A|012346|-|-***-|-----| |0110_111_100_000_000-{offset} [BLE.W <label>]
//BLE.S <label> |-|012346|-|-***-|-----| |0110_111_100_sss_sss (s is not equal to 0)
//BNGT.S <label> |A|012346|-|-***-|-----| |0110_111_100_sss_sss (s is not equal to 0) [BLE.S <label>]
//JBLE.S <label> |A|012346|-|-***-|-----| |0110_111_100_sss_sss (s is not equal to 0) [BLE.S <label>]
//JBNGT.S <label> |A|012346|-|-***-|-----| |0110_111_100_sss_sss (s is not equal to 0) [BLE.S <label>]
//JBGT.L <label> |A|012346|-|-***-|-----| |0110_111_100_000_110-0100111011111001-{address} [BLE.S (*)+8;JMP <label>]
//JBNLE.L <label> |A|012346|-|-***-|-----| |0110_111_100_000_110-0100111011111001-{address} [BLE.S (*)+8;JMP <label>]
public static void irpBlesw () throws M68kException {
if (XEiJ.MPU_CC_LE << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == 0) { //Bcc.Wでジャンプ
XEiJ.regPC = t + 2;
s = XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6f00) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBlesw
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BLE.S <label> |-|012346|-|-***-|-----| |0110_111_101_sss_sss
//BNGT.S <label> |A|012346|-|-***-|-----| |0110_111_101_sss_sss [BLE.S <label>]
//JBLE.S <label> |A|012346|-|-***-|-----| |0110_111_101_sss_sss [BLE.S <label>]
//JBNGT.S <label> |A|012346|-|-***-|-----| |0110_111_101_sss_sss [BLE.S <label>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BLE.S <label> |-|012346|-|-***-|-----| |0110_111_110_sss_sss
//BNGT.S <label> |A|012346|-|-***-|-----| |0110_111_110_sss_sss [BLE.S <label>]
//JBLE.S <label> |A|012346|-|-***-|-----| |0110_111_110_sss_sss [BLE.S <label>]
//JBNGT.S <label> |A|012346|-|-***-|-----| |0110_111_110_sss_sss [BLE.S <label>]
public static void irpBles () throws M68kException {
if (XEiJ.MPU_CC_LE << XEiJ.regCCR < 0) { //Bccでジャンプ
XEiJ.mpuCycleCount += 10;
irpSetPC (XEiJ.regPC + (byte) XEiJ.regOC); //pc0+2+オフセット
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBles
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BLE.S <label> |-|--2346|-|-***-|-----| |0110_111_111_sss_sss (s is not equal to 63)
//BNGT.S <label> |A|--2346|-|-***-|-----| |0110_111_111_sss_sss (s is not equal to 63) [BLE.S <label>]
//JBLE.S <label> |A|--2346|-|-***-|-----| |0110_111_111_sss_sss (s is not equal to 63) [BLE.S <label>]
//JBNGT.S <label> |A|--2346|-|-***-|-----| |0110_111_111_sss_sss (s is not equal to 63) [BLE.S <label>]
//BLE.L <label> |-|--2346|-|-***-|-----| |0110_111_111_111_111-{offset}
//BNGT.L <label> |A|--2346|-|-***-|-----| |0110_111_111_111_111-{offset} [BLE.L <label>]
public static void irpBlesl () throws M68kException {
if (XEiJ.MPU_CC_LE << XEiJ.regCCR < 0) { //Bccでジャンプ
int t = XEiJ.regPC; //pc0+2
int s = (byte) XEiJ.regOC; //オフセット
if (s == -1) { //Bcc.Lでジャンプ
XEiJ.mpuCycleCount += 14;
XEiJ.regPC = t + 4;
s = XEiJ.busRlse (t); //pcls
} else { //Bcc.Sでジャンプ
XEiJ.mpuCycleCount += 10;
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6fff) { //Bcc.Lで通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 4; //オフセットを読み飛ばす。リードを省略
} else { //Bcc.Sで通過
XEiJ.mpuCycleCount += 8;
}
} //irpBlesl
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//IOCS <name> |A|012346|-|UUUUU|UUUUU| |0111_000_0dd_ddd_ddd-0100111001001111 [MOVEQ.L #<data>,D0;TRAP #15]
//MOVEQ.L #<data>,Dq |-|012346|-|-UUUU|-**00| |0111_qqq_0dd_ddd_ddd
public static void irpMoveq () throws M68kException {
XEiJ.mpuCycleCount += 4;
int z;
XEiJ.regRn[XEiJ.regOC >> 9 & 7] = z = (byte) XEiJ.regOC;
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
} //irpMoveq
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//MVS.B <ea>,Dq |-|------|-|-UUUU|-**00|D M+-WXZPI|0111_qqq_100_mmm_rrr (ISA_B)
//
//MVS.B <ea>,Dq
// バイトデータをロングに符号拡張してDqの全体を更新する
public static void irpMvsByte () throws M68kException {
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int z;
XEiJ.regRn[XEiJ.regOC >> 9 & 7] = z = ea < XEiJ.EA_AR ? (byte) XEiJ.regRn[ea] : XEiJ.busRbs (efaAnyByte (ea));
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
} //irpMvsByte
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//MVS.W <ea>,Dq |-|------|-|-UUUU|-**00|D M+-WXZPI|0111_qqq_101_mmm_rrr (ISA_B)
//
//MVS.W <ea>,Dq
// ワードデータをロングに符号拡張してDqの全体を更新する
public static void irpMvsWord () throws M68kException {
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int z;
XEiJ.regRn[XEiJ.regOC >> 9 & 7] = z = ea < XEiJ.EA_AR ? (short) XEiJ.regRn[ea] : XEiJ.busRws (efaAnyWord (ea));
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
} //irpMvsWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//MVZ.B <ea>,Dq |-|------|-|-UUUU|-0*00|D M+-WXZPI|0111_qqq_110_mmm_rrr (ISA_B)
//
//MVZ.B <ea>,Dq
// バイトデータをロングにゼロ拡張してDqの全体を更新する
public static void irpMvzByte () throws M68kException {
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int z;
XEiJ.regRn[XEiJ.regOC >> 9 & 7] = z = ea < XEiJ.EA_AR ? 0xff & XEiJ.regRn[ea] : XEiJ.busRbz (efaAnyByte (ea));
XEiJ.regCCR = XEiJ.REG_CCR_X & XEiJ.regCCR | (z == 0 ? XEiJ.REG_CCR_Z : 0);
} //irpMvzByte
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//MVZ.W <ea>,Dq |-|------|-|-UUUU|-0*00|D M+-WXZPI|0111_qqq_111_mmm_rrr (ISA_B)
//
//MVZ.W <ea>,Dq
// ワードデータをロングにゼロ拡張してDqの全体を更新する
public static void irpMvzWord () throws M68kException {
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int z;
XEiJ.regRn[XEiJ.regOC >> 9 & 7] = z = ea < XEiJ.EA_AR ? (char) XEiJ.regRn[ea] : XEiJ.busRwz (efaAnyWord (ea));
XEiJ.regCCR = XEiJ.REG_CCR_X & XEiJ.regCCR | (z == 0 ? XEiJ.REG_CCR_Z : 0);
} //irpMvzWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//OR.B <ea>,Dq |-|012346|-|-UUUU|-**00|D M+-WXZPI|1000_qqq_000_mmm_rrr
public static void irpOrToRegByte () throws M68kException {
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
XEiJ.regCCR = XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.MPU_TSTB_TABLE[255 & (XEiJ.regRn[XEiJ.regOC >> 9 & 7] |= 255 & (ea < XEiJ.EA_AR ? XEiJ.regRn[ea] : XEiJ.busRbs (efaAnyByte (ea))))]; //ccr_tst_byte。0拡張してからOR
} //irpOrToRegByte
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//OR.W <ea>,Dq |-|012346|-|-UUUU|-**00|D M+-WXZPI|1000_qqq_001_mmm_rrr
public static void irpOrToRegWord () throws M68kException {
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int z = (short) (XEiJ.regRn[XEiJ.regOC >> 9 & 7] |= ea < XEiJ.EA_AR ? (char) XEiJ.regRn[ea] : XEiJ.busRwz (efaAnyWord (ea))); //0拡張してからOR
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
} //irpOrToRegWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//OR.L <ea>,Dq |-|012346|-|-UUUU|-**00|D M+-WXZPI|1000_qqq_010_mmm_rrr
public static void irpOrToRegLong () throws M68kException {
int ea = XEiJ.regOC & 63;
int qqq = XEiJ.regOC >> 9 & 7;
int z;
if (ea < XEiJ.EA_AR) { //OR.L Dr,Dq
XEiJ.mpuCycleCount += 8;
XEiJ.regRn[qqq] = z = XEiJ.regRn[qqq] | XEiJ.regRn[ea];
} else { //OR.L <mem>,Dq
XEiJ.mpuCycleCount += ea == XEiJ.EA_IM ? 8 : 6; //ソースが#<data>のとき2増やす
XEiJ.regRn[qqq] = z = XEiJ.regRn[qqq] | XEiJ.busRls (efaAnyLong (ea));
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
} //irpOrToRegLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//DIVU.W <ea>,Dq |-|012346|-|-UUUU|-***0|D M+-WXZPI|1000_qqq_011_mmm_rrr
//
//DIVU.W <ea>,Dq
// M68000PRMでDIVU.Wのオーバーフローの条件が16bit符号あり整数と書かれているのは16bit符号なし整数の間違い
public static void irpDivuWord () throws M68kException {
// X 変化しない
// N ゼロ除算またはオーバーフローのとき不定。商が負のときセット。それ以外はクリア
// Z ゼロ除算またはオーバーフローのとき不定。商が0のときセット。それ以外はクリア
// V ゼロ除算のとき不定。オーバーフローのときセット。それ以外はクリア
// C 常にクリア
XEiJ.mpuCycleCount += 140; //最大
int ea = XEiJ.regOC & 63;
int qqq = XEiJ.regOC >> 9 & 7;
int y = ea < XEiJ.EA_AR ? (char) XEiJ.regRn[ea] : XEiJ.busRwz (efaAnyWord (ea)); //除数
int x = XEiJ.regRn[qqq]; //被除数
if (y == 0) { //ゼロ除算
//Dqは変化しない
XEiJ.regCCR = (XEiJ.regCCR & XEiJ.REG_CCR_X | //Xは変化しない
(x < 0 ? XEiJ.REG_CCR_N : 0) | //Nは被除数が負のときセット、さもなくばクリア
(x >> 16 == 0 ? XEiJ.REG_CCR_Z : 0) | //Zは被除数が$0000xxxxのときセット、さもなくばクリア
(M30_DIV_ZERO_V_FLAG && m30DivZeroVFlag ? XEiJ.REG_CCR_V : 0) //VはDIV/MULの正常終了後ゼロ除算までにDBccが奇数回実行されたときセット
); //Cは常にクリア
XEiJ.mpuCycleCount += 38 - 140 - 34;
M68kException.m6eAddress = XEiJ.regPC0; //アドレスは命令の先頭
M68kException.m6eNumber = M68kException.M6E_DIVIDE_BY_ZERO;
throw M68kException.m6eSignal;
}
//無理にintで符号なし除算をやろうとするよりもdoubleにキャストしてから割ったほうが速い
// intの除算をdoubleの除算器で行うプロセッサならばなおさら
//被除数を符号なし32ビットとみなすためlongを経由してdoubleに変換する
//doubleからlongやintへのキャストは小数点以下が切り捨てられ、オーバーフローは表現できる絶対値最大の値になる
//doubleから直接intに戻しているので0xffffffff/0x0001=0xffffffffが絶対値最大の0x7fffffffになってしまうが、
//DIVU.Wではオーバーフローになることに変わりはないのでよいことにする
// 符号なし32ビットの0xffffffffにしたいときは戻すときもlongを経由すればよい
int z = (int) ((double) ((long) x & 0xffffffffL) / (double) y); //商
if (z >>> 16 != 0) { //オーバーフローあり
//Dqは変化しない
XEiJ.regCCR = (XEiJ.regCCR & XEiJ.REG_CCR_X | //Xは変化しない
(x < 0 ? XEiJ.REG_CCR_N : 0) | //Nは被除数が負のときセット、さもなくばクリア
//Zは常にクリア
XEiJ.REG_CCR_V //Vは常にセット
); //Cは常にクリア
} else { //オーバーフローなし
XEiJ.regRn[qqq] = x - y * z << 16 | z; //余り<<16|商
z = (short) z;
XEiJ.regCCR = (XEiJ.regCCR & XEiJ.REG_CCR_X | //Xは変化しない
(z < 0 ? XEiJ.REG_CCR_N : 0) | //Nは商が負のときセット、さもなくばクリア
(z == 0 ? XEiJ.REG_CCR_Z : 0) //Zは商が0のときセット、さもなくばクリア
//Vは常にクリア
); //Cは常にクリア
} //if オーバーフローあり/オーバーフローなし
if (M30_DIV_ZERO_V_FLAG) {
m30DivZeroVFlag = false;
}
} //irpDivuWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SBCD.B Dr,Dq |-|012346|-|UUUUU|*U*U*| |1000_qqq_100_000_rrr
//SBCD.B -(Ar),-(Aq) |-|012346|-|UUUUU|*U*U*| |1000_qqq_100_001_rrr
//OR.B Dq,<ea> |-|012346|-|-UUUU|-**00| M+-WXZ |1000_qqq_100_mmm_rrr
public static void irpOrToMemByte () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea >= XEiJ.EA_MM) { //OR.B Dq,<ea>
XEiJ.mpuCycleCount += 8;
int a = efaMltByte (ea);
int z = XEiJ.regRn[XEiJ.regOC >> 9 & 7] | XEiJ.busRbs (a);
XEiJ.busWb (a, z);
XEiJ.regCCR = XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.MPU_TSTB_TABLE[255 & z]; //ccr_tst_byte
} else if (ea < XEiJ.EA_AR) { //SBCD.B Dr,Dq
int qqq = XEiJ.regOC >> 9 & 7;
XEiJ.mpuCycleCount += 6;
int x;
XEiJ.regRn[qqq] = ~0xff & (x = XEiJ.regRn[qqq]) | irpSbcd (x, XEiJ.regRn[ea]);
} else { //SBCD.B -(Ar),-(Aq)
XEiJ.mpuCycleCount += 18;
int y = XEiJ.busRbz (--XEiJ.regRn[ea]); //このr[ea]はアドレスレジスタ
int a = --XEiJ.regRn[(XEiJ.regOC >> 9) - (64 - 8)];
XEiJ.busWb (a, irpSbcd (XEiJ.busRbz (a), y));
}
} //irpOrToMemByte
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//PACK Dr,Dq,#<data> |-|--2346|-|-----|-----| |1000_qqq_101_000_rrr-{data}
//PACK -(Ar),-(Aq),#<data> |-|--2346|-|-----|-----| |1000_qqq_101_001_rrr-{data}
//OR.W Dq,<ea> |-|012346|-|-UUUU|-**00| M+-WXZ |1000_qqq_101_mmm_rrr
//
//PACK Dr,Dq,#<data>
//PACK -(Ar),-(Aq),#<data>
// PACK/UNPKは第1オペランドのソースと第2オペランドのデスティネーションのサイズが違う。パックされていない方がワードでされている方がバイト
// 10の位を4ビット右または左にシフトする。第3オペランドの補正値はワードでパックされていない方に加算する。CCRは変化しない
public static void irpOrToMemWord () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea >= XEiJ.EA_MM) { //OR.W Dq,<ea>
XEiJ.mpuCycleCount += 8;
int a = efaMltWord (ea);
int z = XEiJ.regRn[XEiJ.regOC >> 9 & 7] | XEiJ.busRws (a);
XEiJ.busWw (a, z);
XEiJ.regCCR = XEiJ.regCCR & XEiJ.REG_CCR_X | (char) z - 1 >> 31 & XEiJ.REG_CCR_Z | ((short) z < 0 ? XEiJ.REG_CCR_N : 0); //ccr_tst_word
} else if (ea < XEiJ.EA_AR) { //PACK Dr,Dq,#<data>
XEiJ.mpuCycleCount += 8;
int qqq = XEiJ.regOC >> 9 & 7;
int t;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
t = XEiJ.regRn[ea] + XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
t = XEiJ.regRn[ea] + XEiJ.busRwse (t); //pcws
}
XEiJ.regRn[qqq] = ~0xff & XEiJ.regRn[qqq] | t >> 4 & 0xf0 | t & 15;
} else { //PACK -(Ar),-(Aq),#<data>
XEiJ.mpuCycleCount += 16;
int t;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
t = XEiJ.busRws (XEiJ.regRn[ea] -= 2) + XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws。020以上なのでアドレスエラーは出ない
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
t = XEiJ.busRws (XEiJ.regRn[ea] -= 2) + XEiJ.busRwse (t); //pcws。020以上なのでアドレスエラーは出ない
}
XEiJ.busWb (--XEiJ.regRn[(XEiJ.regOC >> 9) - (64 - 8)], t >> 4 & 0xf0 | t & 15);
}
} //irpOrToMemWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//UNPK Dr,Dq,#<data> |-|--2346|-|-----|-----| |1000_qqq_110_000_rrr-{data}
//UNPK -(Ar),-(Aq),#<data> |-|--2346|-|-----|-----| |1000_qqq_110_001_rrr-{data}
//OR.L Dq,<ea> |-|012346|-|-UUUU|-**00| M+-WXZ |1000_qqq_110_mmm_rrr
//
//UNPK Dr,Dq,#<data>
//UNPK -(Ar),-(Aq),#<data>
// PACK/UNPKは第1オペランドのソースと第2オペランドのデスティネーションのサイズが違う。パックされていない方がワードでされている方がバイト
// 10の位を4ビット右または左にシフトする。第3オペランドの補正値はワードでパックされていない方に加算する。CCRは変化しない
public static void irpOrToMemLong () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea >= XEiJ.EA_MM) { //OR.L Dq,<ea>
XEiJ.mpuCycleCount += 12;
int a = efaMltLong (ea);
int z;
XEiJ.busWl (a, z = XEiJ.regRn[XEiJ.regOC >> 9 & 7] | XEiJ.busRls (a));
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
} else if (ea < XEiJ.EA_AR) { //UNPK Dr,Dq,#<data>
int qqq = XEiJ.regOC >> 9 & 7;
int t = XEiJ.regRn[ea];
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
XEiJ.regRn[qqq] = ~0xffff & XEiJ.regRn[qqq] | (char) ((t << 4 & 0x0f00 | t & 15) + XEiJ.busRwse ((XEiJ.regPC += 2) - 2)); //pcws
} else {
int s = XEiJ.regPC;
XEiJ.regPC = s + 2;
XEiJ.regRn[qqq] = ~0xffff & XEiJ.regRn[qqq] | (char) ((t << 4 & 0x0f00 | t & 15) + XEiJ.busRwse (s)); //pcws
}
} else { //UNPK -(Ar),-(Aq),#<data>
int t = XEiJ.busRbs (--XEiJ.regRn[ea]);
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
XEiJ.busWw (XEiJ.regRn[(XEiJ.regOC >> 9) - (64 - 8)] -= 2, (t << 4 & 0x0f00 | t & 15) + XEiJ.busRwse ((XEiJ.regPC += 2) - 2)); //pcws。020以上なのでアドレスエラーは出ない
} else {
int s = XEiJ.regPC;
XEiJ.regPC = s + 2;
XEiJ.busWw (XEiJ.regRn[(XEiJ.regOC >> 9) - (64 - 8)] -= 2, (t << 4 & 0x0f00 | t & 15) + XEiJ.busRwse (s)); //pcws。020以上なのでアドレスエラーは出ない
}
}
} //irpOrToMemLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//DIVS.W <ea>,Dq |-|012346|-|-UUUU|-***0|D M+-WXZPI|1000_qqq_111_mmm_rrr
//
//DIVS.W <ea>,Dq
// DIVSの余りの符号は被除数と一致
// M68000PRMでDIVS.Wのアドレッシングモードがデータ可変と書かれているのはデータの間違い
public static void irpDivsWord () throws M68kException {
// X 変化しない
// N ゼロ除算またはオーバーフローのとき不定。商が負のときセット。それ以外はクリア
// Z ゼロ除算またはオーバーフローのとき不定。商が0のときセット。それ以外はクリア
// V ゼロ除算のとき不定。オーバーフローのときセット。それ以外はクリア
// C 常にクリア
//divsの余りの符号は被除数と一致
//Javaの除算演算子の挙動
// 10 / 3 == 3 10 % 3 == 1 10 = 3 * 3 + 1
// 10 / -3 == -3 10 % -3 == 1 10 = -3 * -3 + 1
// -10 / 3 == -3 -10 % 3 == -1 -10 = 3 * -3 + -1
// -10 / -3 == 3 -10 % -3 == -1 -10 = -3 * 3 + -1
XEiJ.mpuCycleCount += 158; //最大
int ea = XEiJ.regOC & 63;
int qqq = XEiJ.regOC >> 9 & 7;
int y = ea < XEiJ.EA_AR ? (short) XEiJ.regRn[ea] : XEiJ.busRws (efaAnyWord (ea)); //除数
int x = XEiJ.regRn[qqq]; //被除数
if (y == 0) { //ゼロ除算
//Dqは変化しない
XEiJ.regCCR = (XEiJ.regCCR & XEiJ.REG_CCR_X | //Xは変化しない
//Nは常にクリア
XEiJ.REG_CCR_Z | //Zは常にセット
(M30_DIV_ZERO_V_FLAG && m30DivZeroVFlag ? XEiJ.REG_CCR_V : 0) //VはDIV/MULの正常終了後ゼロ除算までにDBccが奇数回実行されたときセット
); //Cは常にクリア
XEiJ.mpuCycleCount += 38 - 158 - 34;
M68kException.m6eAddress = XEiJ.regPC0; //アドレスは命令の先頭
M68kException.m6eNumber = M68kException.M6E_DIVIDE_BY_ZERO;
throw M68kException.m6eSignal;
}
int z = x / y; //商
if ((short) z != z) { //オーバーフローあり
//Dqは変化しない
XEiJ.regCCR = (XEiJ.regCCR & XEiJ.REG_CCR_X | //Xは変化しない
(x == 0x80000000 || (z & 0xffff0080) == 0x00000080 || (z & 0xffff0080) == 0xffff0080 ? XEiJ.REG_CCR_N : 0) | //Nは被除数が$80000000または商が$0000xxyyまたは$ffffxxyyでyyが負のときセット、さもなくばクリア
(z == 0x00008000 || (((z & 0xffff00ff) == 0x00000000 || (z & 0xffff00ff) == 0xffff0000) && (z & 0x0000ff00) != 0) ? XEiJ.REG_CCR_Z : 0) | //Zは商が$00008000または商が$0000xxyyまたは$ffffxxyyでxxが0でなくてyyが0のときセット、さもなくばクリア
XEiJ.REG_CCR_V //Vは常にセット
); //Cは常にクリア
} else { //オーバーフローなし
XEiJ.regRn[qqq] = x - y * z << 16 | (char) z; //Dqは余り<<16|商&$ffff
XEiJ.regCCR = (XEiJ.regCCR & XEiJ.REG_CCR_X | //Xは変化しない
(z < 0 ? XEiJ.REG_CCR_N : 0) | //Nは商が負のときセット、さもなくばクリア
(z == 0 ? XEiJ.REG_CCR_Z : 0) //Zは商が0のときセット、さもなくばクリア
//Vは常にクリア
); //Cは常にクリア
} //if オーバーフローあり/オーバーフローなし
if (M30_DIV_ZERO_V_FLAG) {
m30DivZeroVFlag = false;
}
} //irpDivsWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SUB.B <ea>,Dq |-|012346|-|UUUUU|*****|D M+-WXZPI|1001_qqq_000_mmm_rrr
public static void irpSubToRegByte () throws M68kException {
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int qqq = XEiJ.regOC >> 9 & 7;
int x, y, z;
y = ea < XEiJ.EA_AR ? XEiJ.regRn[ea] : XEiJ.busRbs (efaAnyByte (ea));
x = XEiJ.regRn[qqq];
z = x - y;
XEiJ.regRn[qqq] = ~255 & x | 255 & z;
XEiJ.regCCR = (XEiJ.MPU_TSTB_TABLE[255 & z] |
((x ^ y) & (x ^ z)) >> 6 & XEiJ.REG_CCR_V |
(byte) (x & (y ^ z) ^ (y | z)) >> 7 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_sub_byte
} //irpSubToRegByte
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SUB.W <ea>,Dq |-|012346|-|UUUUU|*****|DAM+-WXZPI|1001_qqq_001_mmm_rrr
public static void irpSubToRegWord () throws M68kException {
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int qqq = XEiJ.regOC >> 9 & 7;
int x, y, z;
y = ea < XEiJ.EA_MM ? XEiJ.regRn[ea] : XEiJ.busRws (efaAnyWord (ea)); //このr[ea]はデータレジスタまたはアドレスレジスタ
x = XEiJ.regRn[qqq];
z = x - y;
XEiJ.regRn[qqq] = ~65535 & x | (char) z;
XEiJ.regCCR = (z >> 12 & XEiJ.REG_CCR_N | (char) z - 1 >> 14 & XEiJ.REG_CCR_Z |
((x ^ y) & (x ^ z)) >> 14 & XEiJ.REG_CCR_V |
(short) (x & (y ^ z) ^ (y | z)) >> 15 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_sub_word
} //irpSubToRegWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SUB.L <ea>,Dq |-|012346|-|UUUUU|*****|DAM+-WXZPI|1001_qqq_010_mmm_rrr
public static void irpSubToRegLong () throws M68kException {
int ea = XEiJ.regOC & 63;
int qqq = XEiJ.regOC >> 9 & 7;
XEiJ.mpuCycleCount += ea < XEiJ.EA_MM || ea == XEiJ.EA_IM ? 8 : 6; //ソースが#<data>のとき2増やす
int x, y, z;
y = ea < XEiJ.EA_MM ? XEiJ.regRn[ea] : XEiJ.busRls (efaAnyLong (ea)); //このr[ea]はデータレジスタまたはアドレスレジスタ
x = XEiJ.regRn[qqq];
z = x - y;
XEiJ.regRn[qqq] = z;
XEiJ.regCCR = (z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) |
((x ^ y) & (x ^ z)) >> 30 & XEiJ.REG_CCR_V |
(x & (y ^ z) ^ (y | z)) >> 31 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_sub
} //irpSubToRegLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SUBA.W <ea>,Aq |-|012346|-|-----|-----|DAM+-WXZPI|1001_qqq_011_mmm_rrr
//SUB.W <ea>,Aq |A|012346|-|-----|-----|DAM+-WXZPI|1001_qqq_011_mmm_rrr [SUBA.W <ea>,Aq]
//CLR.W Ar |A|012346|-|-----|-----| A |1001_rrr_011_001_rrr [SUBA.W Ar,Ar]
//
//SUBA.W <ea>,Aq
// ソースを符号拡張してロングで減算する
public static void irpSubaWord () throws M68kException {
XEiJ.mpuCycleCount += 8;
int ea = XEiJ.regOC & 63;
int z = ea < XEiJ.EA_MM ? (short) XEiJ.regRn[ea] : XEiJ.busRws (efaAnyWord (ea)); //このr[ea]はデータレジスタまたはアドレスレジスタ。ここでAqが変化する可能性があることに注意
XEiJ.regRn[XEiJ.regOC >> 9 & 15] -= z; //r[op >> 9 & 15] -= ea < XEiJ.EA_MM ? (short) r[ea] : rws (efaAnyWord (ea));は不可
//ccrは変化しない
} //irpSubaWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SUBX.B Dr,Dq |-|012346|-|*UUUU|*****| |1001_qqq_100_000_rrr
//SUBX.B -(Ar),-(Aq) |-|012346|-|*UUUU|*****| |1001_qqq_100_001_rrr
//SUB.B Dq,<ea> |-|012346|-|UUUUU|*****| M+-WXZ |1001_qqq_100_mmm_rrr
public static void irpSubToMemByte () throws M68kException {
int ea = XEiJ.regOC & 63;
int a, x, y, z;
if (ea < XEiJ.EA_MM) {
if (ea < XEiJ.EA_AR) { //SUBX.B Dr,Dq
int qqq = XEiJ.regOC >> 9 & 7;
XEiJ.mpuCycleCount += 4;
y = XEiJ.regRn[ea];
x = XEiJ.regRn[qqq];
z = x - y - (XEiJ.regCCR >> 4); //Xの左側はすべて0なのでCCR_X&を省略
XEiJ.regRn[qqq] = ~255 & x | 255 & z;
} else { //SUBX.B -(Ar),-(Aq)
XEiJ.mpuCycleCount += 18;
y = XEiJ.busRbs (--XEiJ.regRn[ea]); //このr[ea]はアドレスレジスタ
a = --XEiJ.regRn[XEiJ.regOC >> 9 & 15]; //1qqq=aqq
x = XEiJ.busRbs (a);
z = x - y - (XEiJ.regCCR >> 4); //Xの左側はすべて0なのでCCR_X&を省略
XEiJ.busWb (a, z);
}
XEiJ.regCCR = (z >> 4 & XEiJ.REG_CCR_N | (255 & z) - 1 >> 6 & XEiJ.regCCR & XEiJ.REG_CCR_Z | //SUBXはZをクリアすることはあるがセットすることはない
((x ^ y) & (x ^ z)) >> 6 & XEiJ.REG_CCR_V |
(byte) (x & (y ^ z) ^ (y | z)) >> 7 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_subx_byte
} else { //SUB.B Dq,<ea>
XEiJ.mpuCycleCount += 8;
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7];
a = efaMltByte (ea);
x = XEiJ.busRbs (a);
z = x - y;
XEiJ.busWb (a, z);
XEiJ.regCCR = (XEiJ.MPU_TSTB_TABLE[255 & z] |
((x ^ y) & (x ^ z)) >> 6 & XEiJ.REG_CCR_V |
(byte) (x & (y ^ z) ^ (y | z)) >> 7 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_sub_byte
}
} //irpSubToMemByte
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SUBX.W Dr,Dq |-|012346|-|*UUUU|*****| |1001_qqq_101_000_rrr
//SUBX.W -(Ar),-(Aq) |-|012346|-|*UUUU|*****| |1001_qqq_101_001_rrr
//SUB.W Dq,<ea> |-|012346|-|UUUUU|*****| M+-WXZ |1001_qqq_101_mmm_rrr
public static void irpSubToMemWord () throws M68kException {
int ea = XEiJ.regOC & 63;
int a, x, y, z;
if (ea < XEiJ.EA_MM) {
if (ea < XEiJ.EA_AR) { //SUBX.W Dr,Dq
int qqq = XEiJ.regOC >> 9 & 7;
XEiJ.mpuCycleCount += 4;
y = XEiJ.regRn[ea];
x = XEiJ.regRn[qqq];
z = x - y - (XEiJ.regCCR >> 4); //Xの左側はすべて0なのでCCR_X&を省略
XEiJ.regRn[qqq] = ~65535 & x | (char) z;
} else { //SUBX.W -(Ar),-(Aq)
XEiJ.mpuCycleCount += 18;
y = XEiJ.busRws (XEiJ.regRn[ea] -= 2); //このr[ea]はアドレスレジスタ
a = XEiJ.regRn[XEiJ.regOC >> 9 & 15] -= 2;
x = XEiJ.busRws (a);
z = x - y - (XEiJ.regCCR >> 4); //Xの左側はすべて0なのでCCR_X&を省略
XEiJ.busWw (a, z);
}
XEiJ.regCCR = (z >> 12 & XEiJ.REG_CCR_N | (char) z - 1 >> 14 & XEiJ.regCCR & XEiJ.REG_CCR_Z | //ADDXはZをクリアすることはあるがセットすることはない
((x ^ y) & (x ^ z)) >> 14 & XEiJ.REG_CCR_V |
(short) (x & (y ^ z) ^ (y | z)) >> 15 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_subx_word
} else { //SUB.W Dq,<ea>
XEiJ.mpuCycleCount += 8;
y = (short) XEiJ.regRn[XEiJ.regOC >> 9 & 7];
a = efaMltWord (ea);
x = XEiJ.busRws (a);
z = x - y;
XEiJ.busWw (a, z);
XEiJ.regCCR = (z >> 12 & XEiJ.REG_CCR_N | (char) z - 1 >> 14 & XEiJ.REG_CCR_Z |
((x ^ y) & (x ^ z)) >> 14 & XEiJ.REG_CCR_V |
(short) (x & (y ^ z) ^ (y | z)) >> 15 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_sub_word
}
} //irpSubToMemWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SUBX.L Dr,Dq |-|012346|-|*UUUU|*****| |1001_qqq_110_000_rrr
//SUBX.L -(Ar),-(Aq) |-|012346|-|*UUUU|*****| |1001_qqq_110_001_rrr
//SUB.L Dq,<ea> |-|012346|-|UUUUU|*****| M+-WXZ |1001_qqq_110_mmm_rrr
public static void irpSubToMemLong () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea < XEiJ.EA_MM) {
int x;
int y;
int z;
if (ea < XEiJ.EA_AR) { //SUBX.L Dr,Dq
int qqq = XEiJ.regOC >> 9 & 7;
XEiJ.mpuCycleCount += 8;
XEiJ.regRn[qqq] = z = (x = XEiJ.regRn[qqq]) - (y = XEiJ.regRn[ea]) - (XEiJ.regCCR >> 4); //Xの左側はすべて0なのでCCR_X&を省略
} else { //SUBX.L -(Ar),-(Aq)
XEiJ.mpuCycleCount += 30;
y = XEiJ.busRls (XEiJ.regRn[ea] -= 4); //このr[ea]はアドレスレジスタ
int a = XEiJ.regRn[XEiJ.regOC >> 9 & 15] -= 4;
XEiJ.busWl (a, z = (x = XEiJ.busRls (a)) - y - (XEiJ.regCCR >> 4)); //Xの左側はすべて0なのでCCR_X&を省略
}
XEiJ.regCCR = (z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_Z : 0) |
((x ^ y) & (x ^ z)) >>> 31 << 1 |
(x & (y ^ z) ^ (y | z)) >> 31 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_subx
} else { //SUB.L Dq,<ea>
XEiJ.mpuCycleCount += 12;
int a = efaMltLong (ea);
int x;
int y;
int z;
XEiJ.busWl (a, z = (x = XEiJ.busRls (a)) - (y = XEiJ.regRn[XEiJ.regOC >> 9 & 7]));
XEiJ.regCCR = (z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) |
((x ^ y) & (x ^ z)) >>> 31 << 1 |
(x & (y ^ z) ^ (y | z)) >> 31 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_sub
}
} //irpSubToMemLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SUBA.L <ea>,Aq |-|012346|-|-----|-----|DAM+-WXZPI|1001_qqq_111_mmm_rrr
//SUB.L <ea>,Aq |A|012346|-|-----|-----|DAM+-WXZPI|1001_qqq_111_mmm_rrr [SUBA.L <ea>,Aq]
//CLR.L Ar |A|012346|-|-----|-----| A |1001_rrr_111_001_rrr [SUBA.L Ar,Ar]
public static void irpSubaLong () throws M68kException {
int ea = XEiJ.regOC & 63;
XEiJ.mpuCycleCount += ea < XEiJ.EA_MM || ea == XEiJ.EA_IM ? 8 : 6; //Dr/Ar/#<data>のとき8+、それ以外は6+
int z = ea < XEiJ.EA_MM ? XEiJ.regRn[ea] : XEiJ.busRls (efaAnyLong (ea)); //このr[ea]はデータレジスタまたはアドレスレジスタ。ここでAqが変化する可能性があることに注意
XEiJ.regRn[XEiJ.regOC >> 9 & 15] -= z; //r[op >> 9 & 15] -= ea < XEiJ.EA_MM ? r[ea] : rls (efaAnyLong (ea));は不可
//ccrは変化しない
} //irpSubaLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//SXCALL <name> |A|012346|-|UUUUU|*****| |1010_0dd_ddd_ddd_ddd [ALINE #<data>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ALINE #<data> |-|012346|-|UUUUU|*****| |1010_ddd_ddd_ddd_ddd (line 1010 emulator)
public static void irpAline () throws M68kException {
XEiJ.mpuCycleCount += 34;
if (XEiJ.MPU_INLINE_EXCEPTION) {
int save_sr = XEiJ.regSRT1 | XEiJ.regSRT0 | XEiJ.regSRS | XEiJ.regSRM | XEiJ.regSRI | XEiJ.regCCR;
int sp = XEiJ.regRn[15];
XEiJ.regSRT1 = XEiJ.regSRT0 = XEiJ.mpuTraceFlag = 0; //srのTビットを消す
if (XEiJ.regSRS == 0) { //ユーザモードのとき
XEiJ.regSRS = XEiJ.REG_SR_S; //スーパーバイザモードへ移行する
XEiJ.mpuUSP = sp; //USPを保存
sp = XEiJ.regSRM != 0 ? XEiJ.mpuMSP : XEiJ.mpuISP; //SSPを復元
if (DataBreakPoint.DBP_ON) {
DataBreakPoint.dbpMemoryMap = DataBreakPoint.dbpSuperMap; //スーパーバイザメモリマップに切り替える
} else {
XEiJ.busMemoryMap = XEiJ.busSuperMap; //スーパーバイザメモリマップに切り替える
}
if (InstructionBreakPoint.IBP_ON) {
InstructionBreakPoint.ibpOp1MemoryMap = InstructionBreakPoint.ibpOp1SuperMap;
}
}
XEiJ.regRn[15] = sp -= 8;
XEiJ.busWw (sp + 6, 0x0000 | M68kException.M6E_LINE_1010_EMULATOR << 2); //pushw。フォーマットとベクタオフセットをプッシュする
XEiJ.busWl (sp + 2, XEiJ.regPC0); //pushl。pcをプッシュする
XEiJ.busWw (sp, save_sr); //pushw。srをプッシュする
irpSetPC (XEiJ.busRlsf (XEiJ.mpuVBR + (M68kException.M6E_LINE_1010_EMULATOR << 2))); //例外ベクタを取り出してジャンプする
} else {
irpException (M68kException.M6E_LINE_1010_EMULATOR, XEiJ.regPC0, XEiJ.regSRT1 | XEiJ.regSRT0 | XEiJ.regSRS | XEiJ.regSRM | XEiJ.regSRI | XEiJ.regCCR, 0x0000, 0); //pcは命令の先頭
}
} //irpAline
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//CMP.B <ea>,Dq |-|012346|-|-UUUU|-****|D M+-WXZPI|1011_qqq_000_mmm_rrr
public static void irpCmpByte () throws M68kException {
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int x;
int y;
int z = (byte) ((x = (byte) XEiJ.regRn[XEiJ.regOC >> 9 & 7]) - (y = ea < XEiJ.EA_AR ? (byte) XEiJ.regRn[ea] : XEiJ.busRbs (efaAnyByte (ea))));
XEiJ.regCCR = (z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) |
((x ^ y) & (x ^ z)) >>> 31 << 1 |
(x & (y ^ z) ^ (y | z)) >>> 31); //ccr_cmp
} //irpCmpByte
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//CMP.W <ea>,Dq |-|012346|-|-UUUU|-****|DAM+-WXZPI|1011_qqq_001_mmm_rrr
public static void irpCmpWord () throws M68kException {
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int x;
int y;
int z = (short) ((x = (short) XEiJ.regRn[XEiJ.regOC >> 9 & 7]) - (y = ea < XEiJ.EA_MM ? (short) XEiJ.regRn[ea] : XEiJ.busRws (efaAnyWord (ea)))); //このr[ea]はデータレジスタまたはアドレスレジスタ
XEiJ.regCCR = (z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) |
((x ^ y) & (x ^ z)) >>> 31 << 1 |
(x & (y ^ z) ^ (y | z)) >>> 31); //ccr_cmp
} //irpCmpWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//CMP.L <ea>,Dq |-|012346|-|-UUUU|-****|DAM+-WXZPI|1011_qqq_010_mmm_rrr
public static void irpCmpLong () throws M68kException {
XEiJ.mpuCycleCount += 6;
int ea = XEiJ.regOC & 63;
int x;
int y;
int z = (x = XEiJ.regRn[XEiJ.regOC >> 9 & 7]) - (y = ea < XEiJ.EA_MM ? XEiJ.regRn[ea] : XEiJ.busRls (efaAnyLong (ea))); //このr[ea]はデータレジスタまたはアドレスレジスタ
XEiJ.regCCR = (z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) |
((x ^ y) & (x ^ z)) >>> 31 << 1 |
(x & (y ^ z) ^ (y | z)) >>> 31); //ccr_cmp
} //irpCmpLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//CMPA.W <ea>,Aq |-|012346|-|-UUUU|-****|DAM+-WXZPI|1011_qqq_011_mmm_rrr
//CMP.W <ea>,Aq |A|012346|-|-UUUU|-****|DAM+-WXZPI|1011_qqq_011_mmm_rrr [CMPA.W <ea>,Aq]
//
//CMPA.W <ea>,Aq
// ソースを符号拡張してロングで比較する
public static void irpCmpaWord () throws M68kException {
XEiJ.mpuCycleCount += 6;
int ea = XEiJ.regOC & 63;
//ソースを符号拡張してからロングで比較する
int y = ea < XEiJ.EA_MM ? (short) XEiJ.regRn[ea] : XEiJ.busRws (efaAnyWord (ea)); //このr[ea]はデータレジスタまたはアドレスレジスタ。ここでAqが変化する可能性があることに注意
int x;
int z = (x = XEiJ.regRn[XEiJ.regOC >> 9 & 15]) - y;
XEiJ.regCCR = (z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) |
((x ^ y) & (x ^ z)) >>> 31 << 1 |
(x & (y ^ z) ^ (y | z)) >>> 31); //ccr_cmp
} //irpCmpaWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//EOR.B Dq,<ea> |-|012346|-|-UUUU|-**00|D M+-WXZ |1011_qqq_100_mmm_rrr
//CMPM.B (Ar)+,(Aq)+ |-|012346|-|-UUUU|-****| |1011_qqq_100_001_rrr
public static void irpEorByte () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea >> 3 == XEiJ.MMM_AR) { //CMPM.B (Ar)+,(Aq)+
XEiJ.mpuCycleCount += 12;
int y = XEiJ.busRbs (XEiJ.regRn[ea]++); //このr[ea]はアドレスレジスタ
int x;
int z = (byte) ((x = XEiJ.busRbs (XEiJ.regRn[XEiJ.regOC >> 9 & 15]++)) - y);
XEiJ.regCCR = (z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) |
((x ^ y) & (x ^ z)) >>> 31 << 1 |
(x & (y ^ z) ^ (y | z)) >>> 31); //ccr_cmp
} else {
int qqq = XEiJ.regOC >> 9 & 7;
int z;
if (ea < XEiJ.EA_AR) { //EOR.B Dq,Dr
XEiJ.mpuCycleCount += 4;
z = XEiJ.regRn[ea] ^= 255 & XEiJ.regRn[qqq]; //0拡張してからEOR
} else { //EOR.B Dq,<mem>
XEiJ.mpuCycleCount += 8;
int a = efaMltByte (ea);
XEiJ.busWb (a, z = XEiJ.regRn[qqq] ^ XEiJ.busRbs (a));
}
XEiJ.regCCR = XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.MPU_TSTB_TABLE[255 & z]; //ccr_tst_byte
}
} //irpEorByte
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//EOR.W Dq,<ea> |-|012346|-|-UUUU|-**00|D M+-WXZ |1011_qqq_101_mmm_rrr
//CMPM.W (Ar)+,(Aq)+ |-|012346|-|-UUUU|-****| |1011_qqq_101_001_rrr
public static void irpEorWord () throws M68kException {
int ea = XEiJ.regOC & 63;
int rrr = XEiJ.regOC & 7;
int mmm = ea >> 3;
if (mmm == XEiJ.MMM_AR) { //CMPM.W (Ar)+,(Aq)+
XEiJ.mpuCycleCount += 12;
int y = XEiJ.busRws ((XEiJ.regRn[ea] += 2) - 2); //このr[ea]はアドレスレジスタ
int x;
int z = (short) ((x = XEiJ.busRws ((XEiJ.regRn[XEiJ.regOC >> 9 & 15] += 2) - 2)) - y);
XEiJ.regCCR = (z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) |
((x ^ y) & (x ^ z)) >>> 31 << 1 |
(x & (y ^ z) ^ (y | z)) >>> 31); //ccr_cmp
} else {
int qqq = XEiJ.regOC >> 9 & 7;
int z;
if (ea < XEiJ.EA_AR) { //EOR.W Dq,Dr
XEiJ.mpuCycleCount += 4;
z = XEiJ.regRn[rrr] ^= (char) XEiJ.regRn[qqq]; //0拡張してからEOR
} else { //EOR.W Dq,<mem>
XEiJ.mpuCycleCount += 8;
int a = efaMltWord (ea);
XEiJ.busWw (a, z = XEiJ.regRn[qqq] ^ XEiJ.busRws (a));
}
XEiJ.regCCR = XEiJ.regCCR & XEiJ.REG_CCR_X | (char) z - 1 >> 31 & XEiJ.REG_CCR_Z | ((short) z < 0 ? XEiJ.REG_CCR_N : 0); //ccr_tst_word
}
} //irpEorWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//EOR.L Dq,<ea> |-|012346|-|-UUUU|-**00|D M+-WXZ |1011_qqq_110_mmm_rrr
//CMPM.L (Ar)+,(Aq)+ |-|012346|-|-UUUU|-****| |1011_qqq_110_001_rrr
public static void irpEorLong () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea >> 3 == XEiJ.MMM_AR) { //CMPM.L (Ar)+,(Aq)+
XEiJ.mpuCycleCount += 20;
int y = XEiJ.busRls ((XEiJ.regRn[ea] += 4) - 4); //このr[ea]はアドレスレジスタ
int x;
int z = (x = XEiJ.busRls ((XEiJ.regRn[XEiJ.regOC >> 9 & 15] += 4) - 4)) - y;
XEiJ.regCCR = (z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) |
((x ^ y) & (x ^ z)) >>> 31 << 1 |
(x & (y ^ z) ^ (y | z)) >>> 31); //ccr_cmp
} else {
int qqq = XEiJ.regOC >> 9 & 7;
int z;
if (ea < XEiJ.EA_AR) { //EOR.L Dq,Dr
XEiJ.mpuCycleCount += 8;
XEiJ.regRn[ea] = z = XEiJ.regRn[ea] ^ XEiJ.regRn[qqq];
} else { //EOR.L Dq,<mem>
XEiJ.mpuCycleCount += 12;
int a = efaMltLong (ea);
XEiJ.busWl (a, z = XEiJ.busRls (a) ^ XEiJ.regRn[qqq]);
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
}
} //irpEorLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//CMPA.L <ea>,Aq |-|012346|-|-UUUU|-****|DAM+-WXZPI|1011_qqq_111_mmm_rrr
//CMP.L <ea>,Aq |A|012346|-|-UUUU|-****|DAM+-WXZPI|1011_qqq_111_mmm_rrr [CMPA.L <ea>,Aq]
public static void irpCmpaLong () throws M68kException {
XEiJ.mpuCycleCount += 6;
int ea = XEiJ.regOC & 63;
int y = ea < XEiJ.EA_MM ? XEiJ.regRn[ea] : XEiJ.busRls (efaAnyLong (ea)); //このr[ea]はデータレジスタまたはアドレスレジスタ。ここでAqが変化する可能性があることに注意
int x;
int z = (x = XEiJ.regRn[XEiJ.regOC >> 9 & 15]) - y;
XEiJ.regCCR = (z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) |
((x ^ y) & (x ^ z)) >>> 31 << 1 |
(x & (y ^ z) ^ (y | z)) >>> 31); //ccr_cmp
} //irpCmpaLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//AND.B <ea>,Dq |-|012346|-|-UUUU|-**00|D M+-WXZPI|1100_qqq_000_mmm_rrr
public static void irpAndToRegByte () throws M68kException {
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
XEiJ.regCCR = XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.MPU_TSTB_TABLE[255 & (XEiJ.regRn[XEiJ.regOC >> 9 & 7] &= ~255 | (ea < XEiJ.EA_AR ? XEiJ.regRn[ea] : XEiJ.busRbs (efaAnyByte (ea))))]; //ccr_tst_byte。1拡張してからAND
} //irpAndToRegByte
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//AND.W <ea>,Dq |-|012346|-|-UUUU|-**00|D M+-WXZPI|1100_qqq_001_mmm_rrr
public static void irpAndToRegWord () throws M68kException {
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int z = XEiJ.regRn[XEiJ.regOC >> 9 & 7] &= ~65535 | (ea < XEiJ.EA_AR ? XEiJ.regRn[ea] : XEiJ.busRws (efaAnyWord (ea))); //1拡張してからAND
XEiJ.regCCR = XEiJ.regCCR & XEiJ.REG_CCR_X | (char) z - 1 >> 31 & XEiJ.REG_CCR_Z | ((short) z < 0 ? XEiJ.REG_CCR_N : 0); //ccr_tst_word
} //irpAndToRegWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//AND.L <ea>,Dq |-|012346|-|-UUUU|-**00|D M+-WXZPI|1100_qqq_010_mmm_rrr
public static void irpAndToRegLong () throws M68kException {
int ea = XEiJ.regOC & 63;
int qqq = XEiJ.regOC >> 9 & 7;
int z;
if (ea < XEiJ.EA_AR) { //AND.L Dr,Dq
XEiJ.mpuCycleCount += 8;
z = XEiJ.regRn[qqq] &= XEiJ.regRn[ea];
} else { //AND.L <mem>,Dq
XEiJ.mpuCycleCount += ea == XEiJ.EA_IM ? 8 : 6; //ソースが#<data>のとき2増やす
z = XEiJ.regRn[qqq] &= XEiJ.busRls (efaAnyLong (ea));
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
} //irpAndToRegLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//MULU.W <ea>,Dq |-|012346|-|-UUUU|-***0|D M+-WXZPI|1100_qqq_011_mmm_rrr
public static void irpMuluWord () throws M68kException {
int ea = XEiJ.regOC & 63;
int qqq = XEiJ.regOC >> 9 & 7;
int y = ea < XEiJ.EA_AR ? (char) XEiJ.regRn[ea] : XEiJ.busRwz (efaAnyWord (ea));
//muluの所要サイクル数は38+2n
//nはソースに含まれる1の数
int s = y & 0x5555;
s += y - s >> 1;
int t = s & 0x3333;
t += s - t >> 2;
t += t >> 4;
XEiJ.mpuCycleCount += 38 + ((t & 15) + (t >> 8 & 15)) << 1; //38+2n
//XEiJ.mpuCycleCount += 38 + (Integer.bitCount (y) << 1); //少し遅くなる
int z;
XEiJ.regRn[qqq] = z = (char) XEiJ.regRn[qqq] * y; //積の下位32ビット。オーバーフローは無視
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
if (M30_DIV_ZERO_V_FLAG) {
m30DivZeroVFlag = false;
}
} //irpMuluWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ABCD.B Dr,Dq |-|012346|-|UUUUU|*U*U*| |1100_qqq_100_000_rrr
//ABCD.B -(Ar),-(Aq) |-|012346|-|UUUUU|*U*U*| |1100_qqq_100_001_rrr
//AND.B Dq,<ea> |-|012346|-|-UUUU|-**00| M+-WXZ |1100_qqq_100_mmm_rrr
public static void irpAndToMemByte () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea >= XEiJ.EA_MM) { //AND.B Dq,<ea>
XEiJ.mpuCycleCount += 8;
int a = efaMltByte (ea);
int z = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & XEiJ.busRbs (a);
XEiJ.busWb (a, z);
XEiJ.regCCR = XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.MPU_TSTB_TABLE[255 & z]; //ccr_tst_byte
} else if (ea < XEiJ.EA_AR) { //ABCD.B Dr,Dq
int qqq = XEiJ.regOC >> 9 & 7;
XEiJ.mpuCycleCount += 6;
XEiJ.regRn[qqq] = ~0xff & XEiJ.regRn[qqq] | irpAbcd (XEiJ.regRn[qqq], XEiJ.regRn[ea]);
} else { //ABCD.B -(Ar),-(Aq)
XEiJ.mpuCycleCount += 18;
int y = XEiJ.busRbz (--XEiJ.regRn[ea]); //このr[ea]はアドレスレジスタ
int a = --XEiJ.regRn[(XEiJ.regOC >> 9) - (96 - 8)];
XEiJ.busWb (a, irpAbcd (XEiJ.busRbz (a), y));
}
} //irpAndToMemByte
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//EXG.L Dq,Dr |-|012346|-|-----|-----| |1100_qqq_101_000_rrr
//EXG.L Aq,Ar |-|012346|-|-----|-----| |1100_qqq_101_001_rrr
//AND.W Dq,<ea> |-|012346|-|-UUUU|-**00| M+-WXZ |1100_qqq_101_mmm_rrr
public static void irpAndToMemWord () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea < XEiJ.EA_MM) { //EXG
XEiJ.mpuCycleCount += 6;
if (ea < XEiJ.EA_AR) { //EXG.L Dq,Dr
int qqq = XEiJ.regOC >> 9 & 7;
int t = XEiJ.regRn[qqq];
XEiJ.regRn[qqq] = XEiJ.regRn[ea];
XEiJ.regRn[ea] = t;
} else { //EXG.L Aq,Ar
int aqq = (XEiJ.regOC >> 9) - (96 - 8);
int t = XEiJ.regRn[aqq];
XEiJ.regRn[aqq] = XEiJ.regRn[ea]; //このr[ea]アドレスレジスタ
XEiJ.regRn[ea] = t; //このr[ea]はアドレスレジスタ
}
} else { //AND.W Dq,<ea>
XEiJ.mpuCycleCount += 8;
int a = efaMltWord (ea);
int z = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & XEiJ.busRws (a);
XEiJ.busWw (a, z);
XEiJ.regCCR = XEiJ.regCCR & XEiJ.REG_CCR_X | (char) z - 1 >> 31 & XEiJ.REG_CCR_Z | ((short) z < 0 ? XEiJ.REG_CCR_N : 0); //ccr_tst_word
}
} //irpAndToMemWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//EXG.L Dq,Ar |-|012346|-|-----|-----| |1100_qqq_110_001_rrr
//AND.L Dq,<ea> |-|012346|-|-UUUU|-**00| M+-WXZ |1100_qqq_110_mmm_rrr
public static void irpAndToMemLong () throws M68kException {
int ea = XEiJ.regOC & 63;
int qqq = XEiJ.regOC >> 9 & 7;
if (ea >> 3 == XEiJ.MMM_AR) { //EXG.L Dq,Ar
XEiJ.mpuCycleCount += 6;
int t = XEiJ.regRn[qqq];
XEiJ.regRn[qqq] = XEiJ.regRn[ea]; //このr[ea]はアドレスレジスタ
XEiJ.regRn[ea] = t; //このr[ea]はアドレスレジスタ
} else { //AND.L Dq,<ea>
XEiJ.mpuCycleCount += 12;
int a = efaMltLong (ea);
int z;
XEiJ.busWl (a, z = XEiJ.busRls (a) & XEiJ.regRn[qqq]);
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
}
} //irpAndToMemLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//MULS.W <ea>,Dq |-|012346|-|-UUUU|-***0|D M+-WXZPI|1100_qqq_111_mmm_rrr
public static void irpMulsWord () throws M68kException {
int ea = XEiJ.regOC & 63;
int qqq = XEiJ.regOC >> 9 & 7;
int y = ea < XEiJ.EA_AR ? (short) XEiJ.regRn[ea] : XEiJ.busRws (efaAnyWord (ea));
int t = y << 1 ^ y; //右側が1である0と右側が0または末尾である1は1、それ以外は0。ソースは符号拡張されているので上位16ビットはすべて0
//mulsの所要サイクル数は38+2n
//nはソースの末尾に0を付け加えた17ビットに含まれる10または01の数
int s = t & 0x5555;
s += t - s >> 1;
t = s & 0x3333;
t += s - t >> 2;
t += t >> 4;
XEiJ.mpuCycleCount += 38 + ((t & 15) + (t >> 8 & 15)) << 1; //38+2n
int z;
XEiJ.regRn[qqq] = z = (short) XEiJ.regRn[qqq] * y; //積の下位32ビット。オーバーフローは無視
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
if (M30_DIV_ZERO_V_FLAG) {
m30DivZeroVFlag = false;
}
} //irpMulsWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ADD.B <ea>,Dq |-|012346|-|UUUUU|*****|D M+-WXZPI|1101_qqq_000_mmm_rrr
public static void irpAddToRegByte () throws M68kException {
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int qqq = XEiJ.regOC >> 9 & 7;
int x, y, z;
y = ea < XEiJ.EA_AR ? XEiJ.regRn[ea] : XEiJ.busRbs (efaAnyByte (ea));
x = XEiJ.regRn[qqq];
z = x + y;
XEiJ.regRn[qqq] = ~255 & x | 255 & z;
XEiJ.regCCR = (XEiJ.MPU_TSTB_TABLE[255 & z] |
((x ^ z) & (y ^ z)) >> 6 & XEiJ.REG_CCR_V |
(byte) ((x | y) ^ (x ^ y) & z) >> 7 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_add_byte
} //irpAddToRegByte
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ADD.W <ea>,Dq |-|012346|-|UUUUU|*****|DAM+-WXZPI|1101_qqq_001_mmm_rrr
public static void irpAddToRegWord () throws M68kException {
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int qqq = XEiJ.regOC >> 9 & 7;
int x, y, z;
y = ea < XEiJ.EA_MM ? XEiJ.regRn[ea] : XEiJ.busRws (efaAnyWord (ea)); //このr[ea]はデータレジスタまたはアドレスレジスタ
x = XEiJ.regRn[qqq];
z = x + y;
XEiJ.regRn[qqq] = ~65535 & x | (char) z;
XEiJ.regCCR = (z >> 12 & XEiJ.REG_CCR_N | (char) z - 1 >> 14 & XEiJ.REG_CCR_Z |
((x ^ z) & (y ^ z)) >> 14 & XEiJ.REG_CCR_V |
(short) ((x | y) ^ (x ^ y) & z) >> 15 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_add_word
} //irpAddToRegWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ADD.L <ea>,Dq |-|012346|-|UUUUU|*****|DAM+-WXZPI|1101_qqq_010_mmm_rrr
public static void irpAddToRegLong () throws M68kException {
int ea = XEiJ.regOC & 63;
int qqq = XEiJ.regOC >> 9 & 7;
XEiJ.mpuCycleCount += ea < XEiJ.EA_MM || ea == XEiJ.EA_IM ? 8 : 6; //ソースが#<data>のとき2増やす
int x, y, z;
y = ea < XEiJ.EA_MM ? XEiJ.regRn[ea] : XEiJ.busRls (efaAnyLong (ea)); //このr[ea]はデータレジスタまたはアドレスレジスタ
x = XEiJ.regRn[qqq];
z = x + y;
XEiJ.regRn[qqq] = z;
XEiJ.regCCR = (z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) |
((x ^ z) & (y ^ z)) >> 30 & XEiJ.REG_CCR_V |
((x | y) ^ (x ^ y) & z) >> 31 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_add
} //irpAddToRegLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ADDA.W <ea>,Aq |-|012346|-|-----|-----|DAM+-WXZPI|1101_qqq_011_mmm_rrr
//ADD.W <ea>,Aq |A|012346|-|-----|-----|DAM+-WXZPI|1101_qqq_011_mmm_rrr [ADDA.W <ea>,Aq]
//
//ADDA.W <ea>,Aq
// ソースを符号拡張してロングで加算する
public static void irpAddaWord () throws M68kException {
XEiJ.mpuCycleCount += 8;
int ea = XEiJ.regOC & 63;
int z = ea < XEiJ.EA_MM ? (short) XEiJ.regRn[ea] : XEiJ.busRws (efaAnyWord (ea)); //このr[ea]はデータレジスタまたはアドレスレジスタ。ここでAqが変化する可能性があることに注意
XEiJ.regRn[XEiJ.regOC >> 9 & 15] += z; //r[op >> 9 & 15] += ea < XEiJ.EA_MM ? (short) r[ea] : rws (efaAnyWord (ea));は不可
//ccrは変化しない
} //irpAddaWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ADDX.B Dr,Dq |-|012346|-|*UUUU|*****| |1101_qqq_100_000_rrr
//ADDX.B -(Ar),-(Aq) |-|012346|-|*UUUU|*****| |1101_qqq_100_001_rrr
//ADD.B Dq,<ea> |-|012346|-|UUUUU|*****| M+-WXZ |1101_qqq_100_mmm_rrr
public static void irpAddToMemByte () throws M68kException {
int ea = XEiJ.regOC & 63;
int a, x, y, z;
if (ea < XEiJ.EA_MM) {
if (ea < XEiJ.EA_AR) { //ADDX.B Dr,Dq
int qqq = XEiJ.regOC >> 9 & 7;
XEiJ.mpuCycleCount += 4;
y = XEiJ.regRn[ea];
x = XEiJ.regRn[qqq];
z = x + y + (XEiJ.regCCR >> 4); //Xの左側はすべて0なのでCCR_X&を省略
XEiJ.regRn[qqq] = ~255 & x | 255 & z;
} else { //ADDX.B -(Ar),-(Aq)
XEiJ.mpuCycleCount += 18;
y = XEiJ.busRbs (--XEiJ.regRn[ea]); //このr[ea]はアドレスレジスタ
a = --XEiJ.regRn[XEiJ.regOC >> 9 & 15]; //1qqq=aqq
x = XEiJ.busRbs (a);
z = x + y + (XEiJ.regCCR >> 4); //Xの左側はすべて0なのでCCR_X&を省略
XEiJ.busWb (a, z);
}
XEiJ.regCCR = (z >> 4 & XEiJ.REG_CCR_N | (255 & z) - 1 >> 6 & XEiJ.regCCR & XEiJ.REG_CCR_Z | //ADDXはZをクリアすることはあるがセットすることはない
((x ^ z) & (y ^ z)) >> 6 & XEiJ.REG_CCR_V |
(byte) ((x | y) ^ (x ^ y) & z) >> 7 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_addx_byte
} else { //ADD.B Dq,<ea>
XEiJ.mpuCycleCount += 8;
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7];
a = efaMltByte (ea);
x = XEiJ.busRbs (a);
z = x + y;
XEiJ.busWb (a, z);
XEiJ.regCCR = (XEiJ.MPU_TSTB_TABLE[255 & z] |
((x ^ z) & (y ^ z)) >> 6 & XEiJ.REG_CCR_V |
(byte) ((x | y) ^ (x ^ y) & z) >> 7 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_add_byte
}
} //irpAddToMemByte
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ADDX.W Dr,Dq |-|012346|-|*UUUU|*****| |1101_qqq_101_000_rrr
//ADDX.W -(Ar),-(Aq) |-|012346|-|*UUUU|*****| |1101_qqq_101_001_rrr
//ADD.W Dq,<ea> |-|012346|-|UUUUU|*****| M+-WXZ |1101_qqq_101_mmm_rrr
public static void irpAddToMemWord () throws M68kException {
int ea = XEiJ.regOC & 63;
int a, x, y, z;
if (ea < XEiJ.EA_MM) {
if (ea < XEiJ.EA_AR) { //ADDX.W Dr,Dq
int qqq = XEiJ.regOC >> 9 & 7;
XEiJ.mpuCycleCount += 4;
y = XEiJ.regRn[ea];
x = XEiJ.regRn[qqq];
z = x + y + (XEiJ.regCCR >> 4); //Xの左側はすべて0なのでCCR_X&を省略
XEiJ.regRn[qqq] = ~65535 & x | (char) z;
} else { //ADDX.W -(Ar),-(Aq)
XEiJ.mpuCycleCount += 18;
y = XEiJ.busRws (XEiJ.regRn[ea] -= 2); //このr[ea]はアドレスレジスタ
a = XEiJ.regRn[XEiJ.regOC >> 9 & 15] -= 2;
x = XEiJ.busRws (a);
z = x + y + (XEiJ.regCCR >> 4); //Xの左側はすべて0なのでCCR_X&を省略
XEiJ.busWw (a, z);
}
XEiJ.regCCR = (z >> 12 & XEiJ.REG_CCR_N | (char) z - 1 >> 14 & XEiJ.regCCR & XEiJ.REG_CCR_Z | //ADDXはZをクリアすることはあるがセットすることはない
((x ^ z) & (y ^ z)) >> 14 & XEiJ.REG_CCR_V |
(short) ((x | y) ^ (x ^ y) & z) >> 15 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_addx_word
} else { //ADD.W Dq,<ea>
XEiJ.mpuCycleCount += 8;
a = efaMltWord (ea);
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7];
x = XEiJ.busRws (a);
z = x + y;
XEiJ.busWw (a, z);
XEiJ.regCCR = (z >> 12 & XEiJ.REG_CCR_N | (char) z - 1 >> 14 & XEiJ.REG_CCR_Z |
((x ^ z) & (y ^ z)) >> 14 & XEiJ.REG_CCR_V |
(short) ((x | y) ^ (x ^ y) & z) >> 15 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_add_word
}
} //irpAddToMemWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ADDX.L Dr,Dq |-|012346|-|*UUUU|*****| |1101_qqq_110_000_rrr
//ADDX.L -(Ar),-(Aq) |-|012346|-|*UUUU|*****| |1101_qqq_110_001_rrr
//ADD.L Dq,<ea> |-|012346|-|UUUUU|*****| M+-WXZ |1101_qqq_110_mmm_rrr
public static void irpAddToMemLong () throws M68kException {
int ea = XEiJ.regOC & 63;
if (ea < XEiJ.EA_MM) {
int x;
int y;
int z;
if (ea < XEiJ.EA_AR) { //ADDX.L Dr,Dq
int qqq = XEiJ.regOC >> 9 & 7;
XEiJ.mpuCycleCount += 8;
XEiJ.regRn[qqq] = z = (x = XEiJ.regRn[qqq]) + (y = XEiJ.regRn[ea]) + (XEiJ.regCCR >> 4); //Xの左側はすべて0なのでCCR_X&を省略
} else { //ADDX.L -(Ar),-(Aq)
XEiJ.mpuCycleCount += 30;
y = XEiJ.busRls (XEiJ.regRn[ea] -= 4); //このr[ea]はアドレスレジスタ
int a = XEiJ.regRn[XEiJ.regOC >> 9 & 15] -= 4;
XEiJ.busWl (a, z = (x = XEiJ.busRls (a)) + y + (XEiJ.regCCR >> 4)); //Xの左側はすべて0なのでCCR_X&を省略
}
XEiJ.regCCR = (z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_Z : 0) |
((x ^ z) & (y ^ z)) >>> 31 << 1 |
((x | y) ^ (x ^ y) & z) >> 31 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_addx
} else { //ADD.L Dq,<ea>
XEiJ.mpuCycleCount += 12;
int a = efaMltLong (ea);
int x;
int y;
int z;
XEiJ.busWl (a, z = (x = XEiJ.busRls (a)) + (y = XEiJ.regRn[XEiJ.regOC >> 9 & 7]));
XEiJ.regCCR = (z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) |
((x ^ z) & (y ^ z)) >>> 31 << 1 |
((x | y) ^ (x ^ y) & z) >> 31 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //ccr_add
}
} //irpAddToMemLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ADDA.L <ea>,Aq |-|012346|-|-----|-----|DAM+-WXZPI|1101_qqq_111_mmm_rrr
//ADD.L <ea>,Aq |A|012346|-|-----|-----|DAM+-WXZPI|1101_qqq_111_mmm_rrr [ADDA.L <ea>,Aq]
public static void irpAddaLong () throws M68kException {
int ea = XEiJ.regOC & 63;
XEiJ.mpuCycleCount += ea < XEiJ.EA_MM || ea == XEiJ.EA_IM ? 8 : 6; //Dr/Ar/#<data>のとき8+、それ以外は6+
int z = ea < XEiJ.EA_MM ? XEiJ.regRn[ea] : XEiJ.busRls (efaAnyLong (ea)); //このr[ea]はデータレジスタまたはアドレスレジスタ。ここでAqが変化する可能性があることに注意
XEiJ.regRn[XEiJ.regOC >> 9 & 15] += z; //r[op >> 9 & 15] += ea < XEiJ.EA_MM ? r[ea] : rls (efaAnyLong (ea));は不可
//ccrは変化しない
} //irpAddaLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ASR.B #<data>,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_000_000_rrr
//LSR.B #<data>,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_000_001_rrr
//ROXR.B #<data>,Dr |-|012346|-|*UUUU|***0*| |1110_qqq_000_010_rrr
//ROR.B #<data>,Dr |-|012346|-|-UUUU|-**0*| |1110_qqq_000_011_rrr
//ASR.B Dq,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_000_100_rrr
//LSR.B Dq,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_000_101_rrr
//ROXR.B Dq,Dr |-|012346|-|*UUUU|***0*| |1110_qqq_000_110_rrr
//ROR.B Dq,Dr |-|012346|-|-UUUU|-**0*| |1110_qqq_000_111_rrr
//ASR.B Dr |A|012346|-|UUUUU|***0*| |1110_001_000_000_rrr [ASR.B #1,Dr]
//LSR.B Dr |A|012346|-|UUUUU|***0*| |1110_001_000_001_rrr [LSR.B #1,Dr]
//ROXR.B Dr |A|012346|-|*UUUU|***0*| |1110_001_000_010_rrr [ROXR.B #1,Dr]
//ROR.B Dr |A|012346|-|-UUUU|-**0*| |1110_001_000_011_rrr [ROR.B #1,Dr]
//
//ASR.B #<data>,Dr
//ASR.B Dq,Dr
// 算術右シフトバイト
// ........................アイウエオカキク XNZVC
// 0 ........................アイウエオカキク Xア*00 Z=アイウエオカキク==0
// 1 ........................アアイウエオカキ クア*0ク Z=アイウエオカキ==0
// 2 ........................アアアイウエオカ キア*0キ Z=アイウエオカ==0
// 3 ........................アアアアイウエオ カア*0カ Z=アイウエオ==0
// 4 ........................アアアアアイウエ オア*0オ Z=アイウエ==0
// 5 ........................アアアアアアイウ エア*0エ Z=アイウ==0
// 6 ........................アアアアアアアイ ウア*0ウ Z=アイ==0
// 7 ........................アアアアアアアア イア*0イ Z=ア==0
// 8 ........................アアアアアアアア アア*0ア Z=ア==0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は最後に押し出されたビット
//
//LSR.B #<data>,Dr
//LSR.B Dq,Dr
// 論理右シフトバイト
// ........................アイウエオカキク XNZVC
// 0 ........................アイウエオカキク Xア*00 Z=アイウエオカキク==0
// 1 ........................0アイウエオカキ ク0*0ク Z=アイウエオカキ==0
// 2 ........................00アイウエオカ キ0*0キ Z=アイウエオカ==0
// 3 ........................000アイウエオ カ0*0カ Z=アイウエオ==0
// 4 ........................0000アイウエ オ0*0オ Z=アイウエ==0
// 5 ........................00000アイウ エ0*0エ Z=アイウ==0
// 6 ........................000000アイ ウ0*0ウ Z=アイ==0
// 7 ........................0000000ア イ0*0イ Z=ア==0
// 8 ........................00000000 ア010ア
// 9 ........................00000000 00100
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は最後に押し出されたビット
//
//ROR.B #<data>,Dr
//ROR.B Dq,Dr
// 右ローテートバイト
// ........................アイウエオカキク XNZVC
// 0 ........................アイウエオカキク Xア*00 Z=アイウエオカキク==0
// 1 ........................クアイウエオカキ Xク*0ク Z=アイウエオカキク==0
// :
// 7 ........................イウエオカキクア Xイ*0イ Z=アイウエオカキク==0
// 8 ........................アイウエオカキク Xア*0ア Z=アイウエオカキク==0
// CCR
// X 常に変化しない
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は結果の最上位ビット
//
//ROXR.B #<data>,Dr
//ROXR.B Dq,Dr
// 拡張右ローテートバイト
// ........................アイウエオカキク XNZVC
// 0 ........................アイウエオカキク Xア*0X Z=アイウエオカキク==0
// 1 ........................Xアイウエオカキ クX*0ク Z=アイウエオカキX==0
// 2 ........................クXアイウエオカ キク*0キ Z=アイウエオカクX==0
// 3 ........................キクXアイウエオ カキ*0カ Z=アイウエオキクX==0
// 4 ........................カキクXアイウエ オカ*0オ Z=アイウエカキクX==0
// 5 ........................オカキクXアイウ エオ*0エ Z=アイウオカキクX==0
// 6 ........................エオカキクXアイ ウエ*0ウ Z=アイエオカキクX==0
// 7 ........................ウエオカキクXア イウ*0イ Z=アウエオカキクX==0
// 8 ........................イウエオカキクX アイ*0ア Z=イウエオカキクX==0
// 9 ........................アイウエオカキク Xア*0X Z=アイウエオカキク==0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときXのコピー。他は最後に押し出されたビット
public static void irpXxrToRegByte () throws M68kException {
int rrr;
int x = XEiJ.regRn[rrr = XEiJ.regOC & 7];
int y;
int z;
int t;
switch (XEiJ.regOC >> 3 & 0b111_000 >> 3) {
case 0b000_000 >> 3: //ASR.B #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (t = (byte) x >> y) >> 1);
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b001_000 >> 3: //LSR.B #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = ~0xff & x | (z = (t = (0xff & x) >>> y) >>> 1);
XEiJ.regCCR = (z == 0 ? XEiJ.REG_CCR_Z : 0) | -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b010_000 >> 3: //ROXR.B #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
z = (XEiJ.regCCR & XEiJ.REG_CCR_X) << 7 - 4 | (0xff & x) >>> 1;
if (y == 1 - 1) { //y=data-1=1-1
t = x;
} else { //y=data-1=2-1~8-1
z = x << 9 - 1 - y | (t = z >>> y - (2 - 1)) >>> 1;
}
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (byte) z);
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b011_000 >> 3: //ROR.B #<data>,Dr
XEiJ.mpuCycleCount += 6 + ((y = XEiJ.regOC >> 9 & 7) << 1); //y=data&7
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (byte) (x << 8 - y | (0xff & x) >>> y));
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) | z >>> 7 & 1; //Xは変化しない。Cは結果の最上位ビット
break;
case 0b100_000 >> 3: //ASR.B Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
if (y == 0) { //y=data=0
z = (byte) x;
t = XEiJ.regCCR & XEiJ.REG_CCR_X; //Xは変化しない。Cはクリア
} else { //y=data=1~63
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (t = (byte) x >> (y <= 8 ? y - 1 : 7)) >> 1);
t = -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t;
break;
case 0b101_000 >> 3: //LSR.B Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
if (y == 0) { //y=data=0
z = (byte) x;
XEiJ.regCCR = XEiJ.regCCR & XEiJ.REG_CCR_X | (z < 0 ? XEiJ.REG_CCR_N : z == 0 ? XEiJ.REG_CCR_Z : 0); //Xは変化しない。Cはクリア
} else { //y=data=1~63
XEiJ.regRn[rrr] = ~0xff & x | (z = (t = y <= 8 ? (0xff & x) >>> y - 1 : 0) >>> 1);
XEiJ.regCCR = (z == 0 ? XEiJ.REG_CCR_Z : 0) | -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
}
break;
case 0b110_000 >> 3: //ROXR.B Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
//y %= 9;
y = (y & 7) - (y >> 3); //y=data=-7~7
y += y >> 3 & 9; //y=data=0~8
if (y == 0) { //y=data=0
z = (byte) x;
t = -(XEiJ.regCCR >> 4 & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //Xは変化しない。CはXのコピー
} else { //y=data=1~8
z = (XEiJ.regCCR & XEiJ.REG_CCR_X) << 7 - 4 | (0xff & x) >>> 1;
if (y == 1) { //y=data=1
t = x; //Cは最後に押し出されたビット
} else { //y=data=2~8
z = x << 9 - y | (t = z >>> y - 2) >>> 1;
}
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (byte) z);
t = -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t;
break;
case 0b111_000 >> 3: //ROR.B Dq,Dr
default:
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
if (y == 0) {
z = (byte) x;
t = 0; //Cはクリア
} else {
y &= 7; //y=data=0~7
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (byte) (x << 8 - y | (0xff & x) >>> y));
t = z >>> 7 & 1; //Cは結果の最上位ビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) | t; //Xは変化しない
}
} //irpXxrToRegByte
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ASR.W #<data>,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_001_000_rrr
//LSR.W #<data>,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_001_001_rrr
//ROXR.W #<data>,Dr |-|012346|-|*UUUU|***0*| |1110_qqq_001_010_rrr
//ROR.W #<data>,Dr |-|012346|-|-UUUU|-**0*| |1110_qqq_001_011_rrr
//ASR.W Dq,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_001_100_rrr
//LSR.W Dq,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_001_101_rrr
//ROXR.W Dq,Dr |-|012346|-|*UUUU|***0*| |1110_qqq_001_110_rrr
//ROR.W Dq,Dr |-|012346|-|-UUUU|-**0*| |1110_qqq_001_111_rrr
//ASR.W Dr |A|012346|-|UUUUU|***0*| |1110_001_001_000_rrr [ASR.W #1,Dr]
//LSR.W Dr |A|012346|-|UUUUU|***0*| |1110_001_001_001_rrr [LSR.W #1,Dr]
//ROXR.W Dr |A|012346|-|*UUUU|***0*| |1110_001_001_010_rrr [ROXR.W #1,Dr]
//ROR.W Dr |A|012346|-|-UUUU|-**0*| |1110_001_001_011_rrr [ROR.W #1,Dr]
//
//ASR.W #<data>,Dr
//ASR.W Dq,Dr
//ASR.W <ea>
// 算術右シフトワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*00 Z=アイウエオカキクケコサシスセソタ==0
// 1 ................アアイウエオカキクケコサシスセソ タア*0タ Z=アイウエオカキクケコサシスセソ==0
// :
// 15 ................アアアアアアアアアアアアアアアア イア*0イ Z=ア==0
// 16 ................アアアアアアアアアアアアアアアア アア*0ア Z=ア==0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は最後に押し出されたビット
//
//LSR.W #<data>,Dr
//LSR.W Dq,Dr
//LSR.W <ea>
// 論理右シフトワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*00 Z=アイウエオカキクケコサシスセソタ==0
// 1 ................0アイウエオカキクケコサシスセソ タ0*0タ Z=アイウエオカキクケコサシスセソ==0
// :
// 15 ................000000000000000ア イ0*0イ Z=ア==0
// 16 ................0000000000000000 ア010ア
// 17 ................0000000000000000 00100
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は最後に押し出されたビット
//
//ROR.W #<data>,Dr
//ROR.W Dq,Dr
//ROR.W <ea>
// 右ローテートワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*00 Z=アイウエオカキクケコサシスセソタ==0
// 1 ................タアイウエオカキクケコサシスセソ Xタ*0タ Z=アイウエオカキクケコサシスセソタ==0
// :
// 15 ................イウエオカキクケコサシスセソタア Xイ*0イ Z=アイウエオカキクケコサシスセソタ==0
// 16 ................アイウエオカキクケコサシスセソタ Xア*0ア Z=アイウエオカキクケコサシスセソタ==0
// CCR
// X 常に変化しない
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は結果の最上位ビット
//
//ROXR.W #<data>,Dr
//ROXR.W Dq,Dr
//ROXR.W <ea>
// 拡張右ローテートワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*0X Z=アイウエオカキクケコサシスセソタ==0
// 1 ................Xアイウエオカキクケコサシスセソ タX*0タ Z=アイウエオカキクケコサシスセソX==0
// 2 ................タXアイウエオカキクケコサシスセ ソタ*0ソ Z=アイウエオカキクケコサシスセタX==0
// :
// 15 ................ウエオカキクケコサシスセソタXア イウ*0イ Z=アウエオカキクケコサシスセソタX==0
// 16 ................イウエオカキクケコサシスセソタX アイ*0ア Z=イウエオカキクケコサシスセソタX==0
// 17 ................アイウエオカキクケコサシスセソタ Xア*0X Z=アイウエオカキクケコサシスセソタ==0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときXのコピー。他は最後に押し出されたビット
public static void irpXxrToRegWord () throws M68kException {
int rrr;
int x = XEiJ.regRn[rrr = XEiJ.regOC & 7];
int y;
int z;
int t;
switch (XEiJ.regOC >> 3 & 0b111_000 >> 3) {
case 0b000_000 >> 3: //ASR.W #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = ~0xffff & x | (char) (z = (t = (short) x >> y) >> 1);
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b001_000 >> 3: //LSR.W #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = ~0xffff & x | (z = (t = (char) x >>> y) >>> 1);
XEiJ.regCCR = (z == 0 ? XEiJ.REG_CCR_Z : 0) | -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b010_000 >> 3: //ROXR.W #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
z = (XEiJ.regCCR & XEiJ.REG_CCR_X) << 15 - 4 | (char) x >>> 1;
if (y == 1 - 1) { //y=data-1=1-1
t = x;
} else { //y=data-1=2-1~8-1
z = x << 17 - 1 - y | (t = z >>> y - (2 - 1)) >>> 1;
}
XEiJ.regRn[rrr] = ~0xffff & x | (char) (z = (short) z);
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b011_000 >> 3: //ROR.W #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = ~0xffff & x | (char) (z = (short) (x << 16 - 1 - y | (char) x >>> y + 1));
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) | z >>> 15 & 1; //Xは変化しない。Cは結果の最上位ビット
break;
case 0b100_000 >> 3: //ASR.W Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
if (y == 0) { //y=data=0
z = (short) x;
t = XEiJ.regCCR & XEiJ.REG_CCR_X; //Xは変化しない。Cはクリア
} else { //y=data=1~63
XEiJ.regRn[rrr] = ~0xffff & x | (char) (z = (t = (short) x >> (y <= 16 ? y - 1 : 15)) >> 1);
t = -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t;
break;
case 0b101_000 >> 3: //LSR.W Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
if (y == 0) { //y=data=0
z = (short) x;
XEiJ.regCCR = XEiJ.regCCR & XEiJ.REG_CCR_X | (z < 0 ? XEiJ.REG_CCR_N : z == 0 ? XEiJ.REG_CCR_Z : 0); //Xは変化しない。Cはクリア
} else { //y=data=1~63
XEiJ.regRn[rrr] = ~0xffff & x | (z = (t = y <= 16 ? (char) x >>> y - 1 : 0) >>> 1);
XEiJ.regCCR = (z == 0 ? XEiJ.REG_CCR_Z : 0) | -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
}
break;
case 0b110_000 >> 3: //ROXR.W Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
//y %= 17;
y = (y & 15) - (y >> 4); //y=data=-3~15
y += y >> 4 & 17; //y=data=0~16
if (y == 0) { //y=data=0
z = (short) x;
t = -(XEiJ.regCCR >> 4 & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //Xは変化しない。CはXのコピー
} else { //y=data=1~16
z = (XEiJ.regCCR & XEiJ.REG_CCR_X) << 15 - 4 | (char) x >>> 1;
if (y == 1) { //y=data=1
t = x; //Cは最後に押し出されたビット
} else { //y=data=2~16
z = x << 17 - y | (t = z >>> y - 2) >>> 1;
}
XEiJ.regRn[rrr] = ~0xffff & x | (char) (z = (short) z);
t = -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t;
break;
case 0b111_000 >> 3: //ROR.W Dq,Dr
default:
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
if (y == 0) {
z = (short) x;
t = 0; //Cはクリア
} else {
y &= 15; //y=data=0~15
XEiJ.regRn[rrr] = ~0xffff & x | (char) (z = (short) (x << 16 - y | (char) x >>> y));
t = z >>> 15 & 1; //Cは結果の最上位ビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) | t; //Xは変化しない
}
} //irpXxrToRegWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ASR.L #<data>,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_010_000_rrr
//LSR.L #<data>,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_010_001_rrr
//ROXR.L #<data>,Dr |-|012346|-|*UUUU|***0*| |1110_qqq_010_010_rrr
//ROR.L #<data>,Dr |-|012346|-|-UUUU|-**0*| |1110_qqq_010_011_rrr
//ASR.L Dq,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_010_100_rrr
//LSR.L Dq,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_010_101_rrr
//ROXR.L Dq,Dr |-|012346|-|*UUUU|***0*| |1110_qqq_010_110_rrr
//ROR.L Dq,Dr |-|012346|-|-UUUU|-**0*| |1110_qqq_010_111_rrr
//ASR.L Dr |A|012346|-|UUUUU|***0*| |1110_001_010_000_rrr [ASR.L #1,Dr]
//LSR.L Dr |A|012346|-|UUUUU|***0*| |1110_001_010_001_rrr [LSR.L #1,Dr]
//ROXR.L Dr |A|012346|-|*UUUU|***0*| |1110_001_010_010_rrr [ROXR.L #1,Dr]
//ROR.L Dr |A|012346|-|-UUUU|-**0*| |1110_001_010_011_rrr [ROR.L #1,Dr]
//
//ASR.L #<data>,Dr
//ASR.L Dq,Dr
// 算術右シフトロング
// アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ XNZVC
// 0 アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ Xア*00 Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// 1 アアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマ ミア*0ミ Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマ==0
// :
// 31 アアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアア イア*0イ Z=ア==0
// 32 アアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアア アア*0ア Z=ア==0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は最後に押し出されたビット
//
//LSR.L #<data>,Dr
//LSR.L Dq,Dr
// 論理右シフトロング
// アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ XNZVC
// 0 アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ Xア*00 Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// 1 0アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマ ミ0*0ミ Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマ==0
// :
// 31 0000000000000000000000000000000ア イ0*0イ Z=ア==0
// 32 00000000000000000000000000000000 ア010ア
// 33 00000000000000000000000000000000 00100
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は最後に押し出されたビット
//
//ROR.L #<data>,Dr
//ROR.L Dq,Dr
// 右ローテートロング
// アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ XNZVC
// 0 アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ Xア*00 Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// 1 ミアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマ Xミ*0ミ Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// :
// 31 イウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミア Xイ*0イ Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// 32 アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ Xア*0ア Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// CCR
// X 常に変化しない
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は結果の最上位ビット
//
//ROXR.L #<data>,Dr
//ROXR.L Dq,Dr
// 拡張右ローテートロング
// アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ XNZVC
// 0 アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ Xア*0X Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// 1 Xアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマ ミX*0ミ Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマX==0
// 2 ミXアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホ マミ*0マ Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホミX==0
// :
// 31 ウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミXア イウ*0イ Z=アウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミX==0
// 32 イウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミX アイ*0ア Z=イウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミX==0
// 33 アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ Xア*0X Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときXのコピー。他は最後に押し出されたビット
public static void irpXxrToRegLong () throws M68kException {
int rrr;
int x = XEiJ.regRn[rrr = XEiJ.regOC & 7];
int y;
int z;
int t;
switch (XEiJ.regOC >> 3 & 0b111_000 >> 3) {
case 0b000_000 >> 3: //ASR.L #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = z = (t = x >> y) >> 1;
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b001_000 >> 3: //LSR.L #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = z = (t = x >>> y) >>> 1;
XEiJ.regCCR = (z == 0 ? XEiJ.REG_CCR_Z : 0) | -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b010_000 >> 3: //ROXR.L #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
z = (XEiJ.regCCR & XEiJ.REG_CCR_X) << 31 - 4 | x >>> 1;
if (y == 1 - 1) { //y=data-1=1-1
t = x;
} else { //y=data-1=2-1~8-1
z = x << -y | (t = z >>> y - (2 - 1)) >>> 1; //Javaのシフト演算子は5ビットでマスクされるので33-1-yを-yに省略
}
XEiJ.regRn[rrr] = z;
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b011_000 >> 3: //ROR.L #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = z = x << ~y | x >>> y + 1; //Javaのシフト演算子は5ビットでマスクされるので32-1-yを~yに省略
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) | z >>> 31; //Xは変化しない。Cは結果の最上位ビット
break;
case 0b100_000 >> 3: //ASR.L Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
if (y == 0) { //y=data=0
z = x;
t = XEiJ.regCCR & XEiJ.REG_CCR_X; //Xは変化しない。Cはクリア
} else { //y=data=1~63
XEiJ.regRn[rrr] = z = (t = x >> (y <= 32 ? y - 1 : 31)) >> 1;
t = -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t;
break;
case 0b101_000 >> 3: //LSR.L Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
if (y == 0) { //y=data=0
z = x;
XEiJ.regCCR = XEiJ.regCCR & XEiJ.REG_CCR_X | (z < 0 ? XEiJ.REG_CCR_N : z == 0 ? XEiJ.REG_CCR_Z : 0); //Xは変化しない。Cはクリア
} else { //y=data=1~63
XEiJ.regRn[rrr] = z = (t = y <= 32 ? x >>> y - 1 : 0) >>> 1;
XEiJ.regCCR = (z == 0 ? XEiJ.REG_CCR_Z : 0) | -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
}
break;
case 0b110_000 >> 3: //ROXR.L Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
//y %= 33;
y -= 32 - y >> 6 & 33; //y=data=0~32
if (y == 0) { //y=data=0
z = x;
t = -(XEiJ.regCCR >> 4 & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //Xは変化しない。CはXのコピー
} else { //y=data=1~32
z = (XEiJ.regCCR & XEiJ.REG_CCR_X) << 31 - 4 | x >>> 1;
if (y == 1) { //y=data=1
t = x; //Cは最後に押し出されたビット
} else { //y=data=2~32
z = x << 33 - y | (t = z >>> y - 2) >>> 1;
}
XEiJ.regRn[rrr] = z;
t = -(t & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t;
break;
case 0b111_000 >> 3: //ROR.L Dq,Dr
default:
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
if (y == 0) {
z = x;
t = 0; //Cはクリア
} else {
y &= 31; //y=data=0~31
XEiJ.regRn[rrr] = z = x << -y | x >>> y; //Javaのシフト演算子は5ビットでマスクされるので32-yを-yに省略。y=32のときx|xになるが問題ない
t = z >>> 31; //Cは結果の最上位ビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) | t; //Xは変化しない
}
} //irpXxrToRegLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ASR.W <ea> |-|012346|-|UUUUU|***0*| M+-WXZ |1110_000_011_mmm_rrr
//
//ASR.W #<data>,Dr
//ASR.W Dq,Dr
//ASR.W <ea>
// 算術右シフトワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*00 Z=アイウエオカキクケコサシスセソタ==0
// 1 ................アアイウエオカキクケコサシスセソ タア*0タ Z=アイウエオカキクケコサシスセソ==0
// :
// 15 ................アアアアアアアアアアアアアアアア イア*0イ Z=ア==0
// 16 ................アアアアアアアアアアアアアアアア アア*0ア Z=ア==0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は最後に押し出されたビット
public static void irpAsrToMem () throws M68kException {
XEiJ.mpuCycleCount += 8;
int ea = XEiJ.regOC & 63;
int a = efaMltWord (ea);
int x = XEiJ.busRws (a);
int z = x >> 1;
XEiJ.busWw (a, z);
XEiJ.regCCR = ((z < 0 ? XEiJ.REG_CCR_N : 0) |
(z == 0 ? XEiJ.REG_CCR_Z : 0) |
-(x & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //XとCは最後に押し出されたビット
} //irpAsrToMem
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ASL.B #<data>,Dr |-|012346|-|UUUUU|*****| |1110_qqq_100_000_rrr
//LSL.B #<data>,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_100_001_rrr
//ROXL.B #<data>,Dr |-|012346|-|*UUUU|***0*| |1110_qqq_100_010_rrr
//ROL.B #<data>,Dr |-|012346|-|-UUUU|-**0*| |1110_qqq_100_011_rrr
//ASL.B Dq,Dr |-|012346|-|UUUUU|*****| |1110_qqq_100_100_rrr
//LSL.B Dq,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_100_101_rrr
//ROXL.B Dq,Dr |-|012346|-|*UUUU|***0*| |1110_qqq_100_110_rrr
//ROL.B Dq,Dr |-|012346|-|-UUUU|-**0*| |1110_qqq_100_111_rrr
//ASL.B Dr |A|012346|-|UUUUU|*****| |1110_001_100_000_rrr [ASL.B #1,Dr]
//LSL.B Dr |A|012346|-|UUUUU|***0*| |1110_001_100_001_rrr [LSL.B #1,Dr]
//ROXL.B Dr |A|012346|-|*UUUU|***0*| |1110_001_100_010_rrr [ROXL.B #1,Dr]
//ROL.B Dr |A|012346|-|-UUUU|-**0*| |1110_001_100_011_rrr [ROL.B #1,Dr]
//
//ASL.B #<data>,Dr
//ASL.B Dq,Dr
// 算術左シフトバイト
// ........................アイウエオカキク XNZVC
// 0 ........................アイウエオカキク Xア*00 Z=アイウエオカキク==0
// 1 ........................イウエオカキク0 アイ**ア Z=イウエオカキク==0,V=アイ!=0/-1
// :
// 7 ........................ク0000000 キク**キ Z=ク==0,V=アイウエオカキク!=0/-1
// 8 ........................00000000 ク01*ク V=アイウエオカキク!=0
// 9 ........................00000000 001*0 V=アイウエオカキク!=0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V ASRで元に戻せないときセット。他はクリア
// C countが0のときクリア。他は最後に押し出されたビット
//
//LSL.B #<data>,Dr
//LSL.B Dq,Dr
// 論理左シフトバイト
// ........................アイウエオカキク XNZVC
// 0 ........................アイウエオカキク Xア*00 Z=アイウエオカキク==0
// 1 ........................イウエオカキク0 アイ*0ア Z=イウエオカキク==0
// :
// 7 ........................ク0000000 キク*0キ Z=ク==0
// 8 ........................00000000 ク010ク
// 9 ........................00000000 00100
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は最後に押し出されたビット
//
//ROL.B #<data>,Dr
//ROL.B Dq,Dr
// 左ローテートバイト
// ........................アイウエオカキク XNZVC
// 0 ........................アイウエオカキク Xア*00 Z=アイウエオカキク==0
// 1 ........................イウエオカキクア Xイ*0ア Z=アイウエオカキク==0
// :
// 7 ........................クアイウエオカキ Xク*0キ Z=アイウエオカキク==0
// 8 ........................アイウエオカキク Xア*0ク Z=アイウエオカキク==0
// CCR
// X 常に変化しない
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は結果の最下位ビット
//
//ROXL.B #<data>,Dr
//ROXL.B Dq,Dr
// 拡張左ローテートバイト
// ........................アイウエオカキク XNZVC
// 0 ........................アイウエオカキク Xア*0X Z=アイウエオカキク==0
// 1 ........................イウエオカキクX アイ*0ア Z=イウエオカキクX==0
// 2 ........................ウエオカキクXア イウ*0イ Z=アウエオカキクX==0
// :
// 7 ........................クXアイウエオカ キク*0キ Z=アイウエオカクX==0
// 8 ........................Xアイウエオカキ クX*0ク Z=アイウエオカキX==0
// 9 ........................アイウエオカキク Xア*0X Z=アイウエオカキク==0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときXのコピー。他は最後に押し出されたビット
public static void irpXxlToRegByte () throws M68kException {
int rrr;
int x = XEiJ.regRn[rrr = XEiJ.regOC & 7];
int y;
int z;
int t;
switch (XEiJ.regOC >> 3 & 0b111_000 >> 3) {
case 0b000_000 >> 3: //ASL.B #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (byte) ((t = x << y) << 1));
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | (z >> y + 1 != (byte) x ? XEiJ.REG_CCR_V : 0) | (byte) t >> 7 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //VはASRで元に戻せないときセット。XとCは最後に押し出されたビット
break;
case 0b001_000 >> 3: //LSL.B #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (byte) ((t = x << y) << 1));
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | (byte) t >> 7 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b010_000 >> 3: //ROXL.B #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
z = x << 1 | XEiJ.regCCR >> 4 & 1;
if (y == 1 - 1) { //y=data-1=1-1
t = x;
} else { //y=data-1=2-1~8-1
z = (t = z << y - (2 - 1)) << 1 | (0xff & x) >>> 9 - 1 - y;
}
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (byte) z);
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | (byte) t >> 7 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b011_000 >> 3: //ROL.B #<data>,Dr
XEiJ.mpuCycleCount += 6 + ((y = XEiJ.regOC >> 9 & 7) << 1); //y=data&7
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (byte) (x << y | (0xff & x) >>> 8 - y));
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) | z & 1; //Xは変化しない。Cは結果の最下位ビット
break;
case 0b100_000 >> 3: //ASL.B Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
if (y <= 7) { //y=data=0~7
if (y == 0) { //y=data=0
z = (byte) x;
t = XEiJ.regCCR & XEiJ.REG_CCR_X; //Xは変化しない。VとCはクリア
} else { //y=data=1~7
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (byte) ((t = x << y - 1) << 1));
t = (z >> y != (byte) x ? XEiJ.REG_CCR_V : 0) | (byte) t >> 7 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //VはASRで元に戻せないときセット。XとCは最後に押し出されたビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t;
} else { //y=data=8~63
XEiJ.regRn[rrr] = ~0xff & x;
XEiJ.regCCR = XEiJ.REG_CCR_Z | ((byte) x != 0 ? XEiJ.REG_CCR_V : 0) | (y == 8 ? -(x & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C) : 0);
}
break;
case 0b101_000 >> 3: //LSL.B Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
if (y == 0) { //y=data=0
z = (byte) x;
t = XEiJ.regCCR & XEiJ.REG_CCR_X; //Xは変化しない。Cはクリア
} else { //y=data=1~63
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (byte) ((t = y <= 8 ? x << y - 1 : 0) << 1));
t = (byte) t >> 7 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t;
break;
case 0b110_000 >> 3: //ROXL.B Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
//y %= 9;
y = (y & 7) - (y >> 3); //y=data=-7~7
y += y >> 3 & 9; //y=data=0~8
if (y == 0) { //y=data=0
z = (byte) x;
t = -(XEiJ.regCCR >> 4 & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //Xは変化しない。CはXのコピー
} else { //y=data=1~8
z = x << 1 | XEiJ.regCCR >> 4 & 1;
if (y == 1) { //y=data=1
t = x; //Cは最後に押し出されたビット
} else { //y=data=2~8
z = (t = z << y - 2) << 1 | (0xff & x) >>> 9 - y;
}
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (byte) z);
t = (byte) t >> 7 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t;
break;
case 0b111_000 >> 3: //ROL.B Dq,Dr
default:
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
if (y == 0) {
z = (byte) x;
t = 0; //Cはクリア
} else {
y &= 7; //y=data=0~7
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (byte) (x << y | (0xff & x) >>> 8 - y));
t = z & 1; //Cは結果の最下位ビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) | t; //Xは変化しない
}
} //irpXxlToRegByte
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ASL.W #<data>,Dr |-|012346|-|UUUUU|*****| |1110_qqq_101_000_rrr
//LSL.W #<data>,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_101_001_rrr
//ROXL.W #<data>,Dr |-|012346|-|*UUUU|***0*| |1110_qqq_101_010_rrr
//ROL.W #<data>,Dr |-|012346|-|-UUUU|-**0*| |1110_qqq_101_011_rrr
//ASL.W Dq,Dr |-|012346|-|UUUUU|*****| |1110_qqq_101_100_rrr
//LSL.W Dq,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_101_101_rrr
//ROXL.W Dq,Dr |-|012346|-|*UUUU|***0*| |1110_qqq_101_110_rrr
//ROL.W Dq,Dr |-|012346|-|-UUUU|-**0*| |1110_qqq_101_111_rrr
//ASL.W Dr |A|012346|-|UUUUU|*****| |1110_001_101_000_rrr [ASL.W #1,Dr]
//LSL.W Dr |A|012346|-|UUUUU|***0*| |1110_001_101_001_rrr [LSL.W #1,Dr]
//ROXL.W Dr |A|012346|-|*UUUU|***0*| |1110_001_101_010_rrr [ROXL.W #1,Dr]
//ROL.W Dr |A|012346|-|-UUUU|-**0*| |1110_001_101_011_rrr [ROL.W #1,Dr]
//
//ASL.W #<data>,Dr
//ASL.W Dq,Dr
//ASL.W <ea>
// 算術左シフトワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*00 Z=アイウエオカキクケコサシスセソタ==0
// 1 ................イウエオカキクケコサシスセソタ0 アイ**ア Z=イウエオカキクケコサシスセソタ==0,V=アイ!=0/-1
// :
// 15 ................タ000000000000000 ソタ**ソ Z=タ==0,V=アイウエオカキクケコサシスセソタ!=0/-1
// 16 ................0000000000000000 タ01*タ V=アイウエオカキクケコサシスセソタ!=0
// 17 ................0000000000000000 001*0 V=アイウエオカキクケコサシスセソタ!=0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V ASRで元に戻せないときセット。他はクリア
// C countが0のときクリア。他は最後に押し出されたビット
//
//LSL.W #<data>,Dr
//LSL.W Dq,Dr
//LSL.W <ea>
// 論理左シフトワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*00 Z=アイウエオカキクケコサシスセソタ==0
// 1 ................イウエオカキクケコサシスセソタ0 アイ*0ア Z=イウエオカキクケコサシスセソタ==0
// :
// 15 ................タ000000000000000 ソタ*0ソ Z=タ==0
// 16 ................0000000000000000 タ010タ
// 17 ................0000000000000000 00100
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は最後に押し出されたビット
//
//ROL.W #<data>,Dr
//ROL.W Dq,Dr
//ROL.W <ea>
// 左ローテートワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*00 Z=アイウエオカキクケコサシスセソタ==0
// 1 ................イウエオカキクケコサシスセソタア Xイ*0ア Z=アイウエオカキクケコサシスセソタ==0
// :
// 15 ................タアイウエオカキクケコサシスセソ Xタ*0ソ Z=アイウエオカキクケコサシスセソタ==0
// 16 ................アイウエオカキクケコサシスセソタ Xア*0タ Z=アイウエオカキクケコサシスセソタ==0
// CCR
// X 常に変化しない
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は結果の最下位ビット
//
//ROXL.W #<data>,Dr
//ROXL.W Dq,Dr
//ROXL.W <ea>
// 拡張左ローテートワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*0X Z=アイウエオカキクケコサシスセソタ==0
// 1 ................イウエオカキクケコサシスセソタX アイ*0ア Z=イウエオカキクケコサシスセソタX==0
// 2 ................ウエオカキクケコサシスセソタXア イウ*0イ Z=アウエオカキクケコサシスセソタX==0
// :
// 15 ................タXアイウエオカキクケコサシスセ ソタ*0ソ Z=アイウエオカキクケコサシスセタX==0
// 16 ................Xアイウエオカキクケコサシスセソ タX*0タ Z=アイウエオカキクケコサシスセソX==0
// 17 ................アイウエオカキクケコサシスセソタ Xア*0X Z=アイウエオカキクケコサシスセソタ==0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときXのコピー。他は最後に押し出されたビット
public static void irpXxlToRegWord () throws M68kException {
int rrr;
int x = XEiJ.regRn[rrr = XEiJ.regOC & 7];
int y;
int z;
int t;
switch (XEiJ.regOC >> 3 & 0b111_000 >> 3) {
case 0b000_000 >> 3: //ASL.W #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = ~0xffff & x | (char) (z = (short) ((t = x << y) << 1));
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | (z >> y + 1 != (short) x ? XEiJ.REG_CCR_V : 0) | (short) t >> 15 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //VはASRで元に戻せないときセット。XとCは最後に押し出されたビット
break;
case 0b001_000 >> 3: //LSL.W #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = ~0xffff & x | (char) (z = (short) ((t = x << y) << 1));
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | (short) t >> 15 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b010_000 >> 3: //ROXL.W #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
z = x << 1 | XEiJ.regCCR >> 4 & 1;
if (y == 1 - 1) { //y=data-1=1-1
t = x;
} else { //y=data-1=2-1~8-1
z = (t = z << y - (2 - 1)) << 1 | (char) x >>> 17 - 1 - y;
}
XEiJ.regRn[rrr] = ~0xffff & x | (char) (z = (short) z);
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | (short) t >> 15 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b011_000 >> 3: //ROL.W #<data>,Dr
XEiJ.mpuCycleCount += 6 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = ~0xffff & x | (char) (z = (short) (x << y + 1 | (char) x >>> 16 - 1 - y));
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) | z & 1; //Xは変化しない。Cは結果の最下位ビット
break;
case 0b100_000 >> 3: //ASL.W Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
if (y <= 15) { //y=data=0~15
if (y == 0) { //y=data=0
z = (short) x;
t = XEiJ.regCCR & XEiJ.REG_CCR_X; //Xは変化しない。VとCはクリア
} else { //y=data=1~15
XEiJ.regRn[rrr] = ~0xffff & x | (char) (z = (short) ((t = x << y - 1) << 1));
t = (z >> y != (short) x ? XEiJ.REG_CCR_V : 0) | (short) t >> 15 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //VはASRで元に戻せないときセット。XとCは最後に押し出されたビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t;
} else { //y=data=16~63
XEiJ.regRn[rrr] = ~0xffff & x;
XEiJ.regCCR = XEiJ.REG_CCR_Z | ((short) x != 0 ? XEiJ.REG_CCR_V : 0) | (y == 16 ? -(x & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C) : 0);
}
break;
case 0b101_000 >> 3: //LSL.W Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
if (y == 0) { //y=data=0
z = (short) x;
t = XEiJ.regCCR & XEiJ.REG_CCR_X; //Xは変化しない。Cはクリア
} else { //y=data=1~63
XEiJ.regRn[rrr] = ~0xffff & x | (char) (z = (short) ((t = y <= 16 ? x << y - 1 : 0) << 1));
t = (short) t >> 15 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t;
break;
case 0b110_000 >> 3: //ROXL.W Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
//y %= 17;
y = (y & 15) - (y >> 4); //y=data=-3~15
y += y >> 4 & 17; //y=data=0~16
if (y == 0) { //y=data=0
z = (short) x;
t = -(XEiJ.regCCR >> 4 & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //Xは変化しない。CはXのコピー
} else { //y=data=1~16
z = x << 1 | XEiJ.regCCR >> 4 & 1;
if (y == 1) { //y=data=1
t = x; //Cは最後に押し出されたビット
} else { //y=data=2~16
z = (t = z << y - 2) << 1 | (char) x >>> 17 - y;
}
XEiJ.regRn[rrr] = ~0xffff & x | (char) (z = (short) z);
t = (short) t >> 15 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t;
break;
case 0b111_000 >> 3: //ROL.W Dq,Dr
default:
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 6 + (y << 1);
if (y == 0) {
z = (short) x;
t = 0; //Cはクリア
} else {
y &= 15; //y=data=0~15
XEiJ.regRn[rrr] = ~0xffff & x | (char) (z = (short) (x << y | (char) x >>> 16 - y));
t = z & 1; //Cは結果の最下位ビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) | t; //Xは変化しない
}
} //irpXxlToRegWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ASL.L #<data>,Dr |-|012346|-|UUUUU|*****| |1110_qqq_110_000_rrr
//LSL.L #<data>,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_110_001_rrr
//ROXL.L #<data>,Dr |-|012346|-|*UUUU|***0*| |1110_qqq_110_010_rrr
//ROL.L #<data>,Dr |-|012346|-|-UUUU|-**0*| |1110_qqq_110_011_rrr
//ASL.L Dq,Dr |-|012346|-|UUUUU|*****| |1110_qqq_110_100_rrr
//LSL.L Dq,Dr |-|012346|-|UUUUU|***0*| |1110_qqq_110_101_rrr
//ROXL.L Dq,Dr |-|012346|-|*UUUU|***0*| |1110_qqq_110_110_rrr
//ROL.L Dq,Dr |-|012346|-|-UUUU|-**0*| |1110_qqq_110_111_rrr
//ASL.L Dr |A|012346|-|UUUUU|*****| |1110_001_110_000_rrr [ASL.L #1,Dr]
//LSL.L Dr |A|012346|-|UUUUU|***0*| |1110_001_110_001_rrr [LSL.L #1,Dr]
//ROXL.L Dr |A|012346|-|*UUUU|***0*| |1110_001_110_010_rrr [ROXL.L #1,Dr]
//ROL.L Dr |A|012346|-|-UUUU|-**0*| |1110_001_110_011_rrr [ROL.L #1,Dr]
//
//ASL.L #<data>,Dr
//ASL.L Dq,Dr
// 算術左シフトロング
// アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ XNZVC
// 0 アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ Xア**0 Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// 1 イウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ0 アイ**ア Z=イウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0,V=アイ!=0/-1
// :
// 31 ミ0000000000000000000000000000000 マミ**マ Z=ミ==0,V=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ!=0/-1
// 32 00000000000000000000000000000000 ミ01*ミ V=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ!=0
// 33 00000000000000000000000000000000 001*0 V=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ!=0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V ASRで元に戻せないときセット。他はクリア
// C countが0のときクリア。他は最後に押し出されたビット
//
//LSL.L #<data>,Dr
//LSL.L Dq,Dr
// 論理左シフトロング
// アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ XNZVC
// 0 アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ Xア*00 Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// 1 イウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ0 アイ*0ア Z=イウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// :
// 31 ミ0000000000000000000000000000000 マミ*0マ Z=ミ==0
// 32 00000000000000000000000000000000 ミ010ミ
// 33 00000000000000000000000000000000 00100
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は最後に押し出されたビット
//
//ROL.L #<data>,Dr
//ROL.L Dq,Dr
// 左ローテートロング
// アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ XNZVC
// 0 アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ Xア*00 Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// 1 イウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミア Xイ*0ア Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// :
// 31 ミアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマ Xミ*0マ Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// 32 アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ Xア*0ミ Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// CCR
// X 常に変化しない
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は結果の最下位ビット
//
//ROXL.L #<data>,Dr
//ROXL.L Dq,Dr
// 拡張左ローテートロング
// アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ XNZVC
// 0 アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ Xア*0X Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// 1 イウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミX アイ*0ア Z=イウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミX==0
// 2 ウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミXア イウ*0イ Z=アウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミX==0
// :
// 31 ミXアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホ マミ*0マ Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホミX==0
// 32 Xアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマ ミX*0ミ Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマX==0
// 33 アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ Xア*0X Z=アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミ==0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときXのコピー。他は最後に押し出されたビット
public static void irpXxlToRegLong () throws M68kException {
int rrr;
int x = XEiJ.regRn[rrr = XEiJ.regOC & 7];
int y;
int z;
int t;
switch (XEiJ.regOC >> 3 & 0b111_000 >> 3) {
case 0b000_000 >> 3: //ASL.L #<data>,Dr
XEiJ.mpuCycleCount += 8 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = z = (t = x << y) << 1;
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | (z >> y + 1 != x ? XEiJ.REG_CCR_V : 0) | t >> 31 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //VはASRで元に戻せないときセット。XとCは最後に押し出されたビット
break;
case 0b001_000 >> 3: //LSL.L #<data>,Dr
XEiJ.mpuCycleCount += 8 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = z = (t = x << y) << 1;
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t >> 31 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b010_000 >> 3: //ROXL.L #<data>,Dr
XEiJ.mpuCycleCount += 8 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
z = x << 1 | XEiJ.regCCR >> 4 & 1;
if (y == 1 - 1) { //y=data-1=1-1
t = x;
} else { //y=data-1=2-1~8-1
z = (t = z << y - (2 - 1)) << 1 | x >>> -y; //Javaのシフト演算子は5ビットでマスクされるので33-1-yを-yに省略
}
XEiJ.regRn[rrr] = z;
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t >> 31 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b011_000 >> 3: //ROL.L #<data>,Dr
XEiJ.mpuCycleCount += 8 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = z = x << y + 1 | x >>> ~y; //Javaのシフト演算子は5ビットでマスクされるので32-1-yを~yに省略
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) | z & 1; //Xは変化しない。Cは結果の最下位ビット
break;
case 0b100_000 >> 3: //ASL.L Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 8 + (y << 1);
if (y <= 31) { //y=data=0~31
if (y == 0) { //y=data=0
z = x;
t = XEiJ.regCCR & XEiJ.REG_CCR_X; //Xは変化しない。VとCはクリア
} else { //y=data=1~31
XEiJ.regRn[rrr] = z = (t = x << y - 1) << 1;
t = (z >> y != x ? XEiJ.REG_CCR_V : 0) | t >> 31 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //VはASRで元に戻せないときセット。XとCは最後に押し出されたビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t;
} else { //y=data=32~63
XEiJ.regRn[rrr] = 0;
XEiJ.regCCR = XEiJ.REG_CCR_Z | (x != 0 ? XEiJ.REG_CCR_V : 0) | (y == 32 ? -(x & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C) : 0);
}
break;
case 0b101_000 >> 3: //LSL.L Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 8 + (y << 1);
if (y == 0) { //y=data=0
z = x;
t = XEiJ.regCCR & XEiJ.REG_CCR_X; //Xは変化しない。Cはクリア
} else { //y=data=1~63
XEiJ.regRn[rrr] = z = (t = y <= 32 ? x << y - 1 : 0) << 1;
t = t >> 31 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t;
break;
case 0b110_000 >> 3: //ROXL.L Dq,Dr
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 8 + (y << 1);
//y %= 33;
y -= 32 - y >> 6 & 33; //y=data=0~32
if (y == 0) { //y=data=0
z = x;
t = -(XEiJ.regCCR >> 4 & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //Xは変化しない。CはXのコピー
} else { //y=data=1~32
z = x << 1 | XEiJ.regCCR >> 4 & 1;
if (y == 1) { //y=data=1
t = x; //Cは最後に押し出されたビット
} else { //y=data=2~32
z = (t = z << y - 2) << 1 | x >>> 33 - y;
}
XEiJ.regRn[rrr] = z;
t = t >> 31 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.REG_CCR_Z : 0) | t;
break;
case 0b111_000 >> 3: //ROL.L Dq,Dr
default:
y = XEiJ.regRn[XEiJ.regOC >> 9 & 7] & 63; //y=0~63。Javaのシフト演算子は5ビットでマスクされることに注意
XEiJ.mpuCycleCount += 8 + (y << 1);
if (y == 0) {
z = x;
t = 0; //Cはクリア
} else {
XEiJ.regRn[rrr] = z = x << y | x >>> -y; //Javaのシフト演算子は5ビットでマスクされるのでy&31をyに、32-(y&31)を-yに省略。y=32のときx|xになるが問題ない
t = z & 1;
}
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X) | t; //Xは変化しない
}
} //irpXxlToRegLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ASL.W <ea> |-|012346|-|UUUUU|*****| M+-WXZ |1110_000_111_mmm_rrr
//
//ASL.W #<data>,Dr
//ASL.W Dq,Dr
//ASL.W <ea>
// 算術左シフトワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*00 Z=アイウエオカキクケコサシスセソタ==0
// 1 ................イウエオカキクケコサシスセソタ0 アイ**ア Z=イウエオカキクケコサシスセソタ==0,V=アイ!=0/-1
// :
// 15 ................タ000000000000000 ソタ**ソ Z=タ==0,V=アイウエオカキクケコサシスセソタ!=0/-1
// 16 ................0000000000000000 タ01*タ V=アイウエオカキクケコサシスセソタ!=0
// 17 ................0000000000000000 001*0 V=アイウエオカキクケコサシスセソタ!=0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V ASRで元に戻せないときセット。他はクリア
// C countが0のときクリア。他は最後に押し出されたビット
public static void irpAslToMem () throws M68kException {
XEiJ.mpuCycleCount += 8;
int ea = XEiJ.regOC & 63;
int a = efaMltWord (ea);
int x = XEiJ.busRws (a);
int z = (short) (x << 1);
XEiJ.busWw (a, z);
XEiJ.regCCR = ((z < 0 ? XEiJ.REG_CCR_N : 0) |
(z == 0 ? XEiJ.REG_CCR_Z : 0) |
(x ^ z) >>> 31 << 1 | //Vは最上位ビットが変化したときセット
x >> 15 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //XとCは最後に押し出されたビット
} //irpAslToMem
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//LSR.W <ea> |-|012346|-|UUUUU|*0*0*| M+-WXZ |1110_001_011_mmm_rrr
//
//LSR.W #<data>,Dr
//LSR.W Dq,Dr
//LSR.W <ea>
// 論理右シフトワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*00 Z=アイウエオカキクケコサシスセソタ==0
// 1 ................0アイウエオカキクケコサシスセソ タ0*0タ Z=アイウエオカキクケコサシスセソ==0
// :
// 15 ................000000000000000ア イ0*0イ Z=ア==0
// 16 ................0000000000000000 ア010ア
// 17 ................0000000000000000 00100
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は最後に押し出されたビット
public static void irpLsrToMem () throws M68kException {
XEiJ.mpuCycleCount += 8;
int ea = XEiJ.regOC & 63;
int a = efaMltWord (ea);
int x = XEiJ.busRwz (a);
int z = x >>> 1;
XEiJ.busWw (a, z);
XEiJ.regCCR = ((z == 0 ? XEiJ.REG_CCR_Z : 0) |
-(x & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //XとCは最後に押し出されたビット
} //irpLsrToMem
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//LSL.W <ea> |-|012346|-|UUUUU|***0*| M+-WXZ |1110_001_111_mmm_rrr
//
//LSL.W #<data>,Dr
//LSL.W Dq,Dr
//LSL.W <ea>
// 論理左シフトワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*00 Z=アイウエオカキクケコサシスセソタ==0
// 1 ................イウエオカキクケコサシスセソタ0 アイ*0ア Z=イウエオカキクケコサシスセソタ==0
// :
// 15 ................タ000000000000000 ソタ*0ソ Z=タ==0
// 16 ................0000000000000000 タ010タ
// 17 ................0000000000000000 00100
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は最後に押し出されたビット
public static void irpLslToMem () throws M68kException {
XEiJ.mpuCycleCount += 8;
int ea = XEiJ.regOC & 63;
int a = efaMltWord (ea);
int x = XEiJ.busRws (a);
int z = (short) (x << 1);
XEiJ.busWw (a, z);
XEiJ.regCCR = ((z < 0 ? XEiJ.REG_CCR_N : 0) |
(z == 0 ? XEiJ.REG_CCR_Z : 0) |
x >> 15 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //XとCは最後に押し出されたビット
} //irpLslToMem
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ROXR.W <ea> |-|012346|-|*UUUU|***0*| M+-WXZ |1110_010_011_mmm_rrr
//
//ROXR.W #<data>,Dr
//ROXR.W Dq,Dr
//ROXR.W <ea>
// 拡張右ローテートワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*0X Z=アイウエオカキクケコサシスセソタ==0
// 1 ................Xアイウエオカキクケコサシスセソ タX*0タ Z=アイウエオカキクケコサシスセソX==0
// 2 ................タXアイウエオカキクケコサシスセ ソタ*0ソ Z=アイウエオカキクケコサシスセタX==0
// :
// 15 ................ウエオカキクケコサシスセソタXア イウ*0イ Z=アウエオカキクケコサシスセソタX==0
// 16 ................イウエオカキクケコサシスセソタX アイ*0ア Z=イウエオカキクケコサシスセソタX==0
// 17 ................アイウエオカキクケコサシスセソタ Xア*0X Z=アイウエオカキクケコサシスセソタ==0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときXのコピー。他は最後に押し出されたビット
public static void irpRoxrToMem () throws M68kException {
XEiJ.mpuCycleCount += 8;
int ea = XEiJ.regOC & 63;
int a = efaMltWord (ea);
int x = XEiJ.busRwz (a);
int z = -(XEiJ.regCCR & XEiJ.REG_CCR_X) << 15 - 4 | x >>> 1;
XEiJ.busWw (a, z);
XEiJ.regCCR = ((z < 0 ? XEiJ.REG_CCR_N : 0) |
(z == 0 ? XEiJ.REG_CCR_Z : 0) |
-(x & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //XとCは最後に押し出されたビット
} //irpRoxrToMem
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ROXL.W <ea> |-|012346|-|*UUUU|***0*| M+-WXZ |1110_010_111_mmm_rrr
//
//ROXL.W #<data>,Dr
//ROXL.W Dq,Dr
//ROXL.W <ea>
// 拡張左ローテートワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*0X Z=アイウエオカキクケコサシスセソタ==0
// 1 ................イウエオカキクケコサシスセソタX アイ*0ア Z=イウエオカキクケコサシスセソタX==0
// 2 ................ウエオカキクケコサシスセソタXア イウ*0イ Z=アウエオカキクケコサシスセソタX==0
// :
// 15 ................タXアイウエオカキクケコサシスセ ソタ*0ソ Z=アイウエオカキクケコサシスセタX==0
// 16 ................Xアイウエオカキクケコサシスセソ タX*0タ Z=アイウエオカキクケコサシスセソX==0
// 17 ................アイウエオカキクケコサシスセソタ Xア*0X Z=アイウエオカキクケコサシスセソタ==0
// CCR
// X countが0のとき変化しない。他は最後に押し出されたビット
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときXのコピー。他は最後に押し出されたビット
public static void irpRoxlToMem () throws M68kException {
XEiJ.mpuCycleCount += 8;
int ea = XEiJ.regOC & 63;
int a = efaMltWord (ea);
int x = XEiJ.busRws (a);
int z = (short) (x << 1 | XEiJ.regCCR >> 4 & 1);
XEiJ.busWw (a, z);
XEiJ.regCCR = ((z < 0 ? XEiJ.REG_CCR_N : 0) |
(z == 0 ? XEiJ.REG_CCR_Z : 0) |
x >> 15 & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C)); //XとCは最後に押し出されたビット
} //irpRoxlToMem
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ROR.W <ea> |-|012346|-|-UUUU|-**0*| M+-WXZ |1110_011_011_mmm_rrr
//
//ROR.W #<data>,Dr
//ROR.W Dq,Dr
//ROR.W <ea>
// 右ローテートワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*00 Z=アイウエオカキクケコサシスセソタ==0
// 1 ................タアイウエオカキクケコサシスセソ Xタ*0タ Z=アイウエオカキクケコサシスセソタ==0
// :
// 15 ................イウエオカキクケコサシスセソタア Xイ*0イ Z=アイウエオカキクケコサシスセソタ==0
// 16 ................アイウエオカキクケコサシスセソタ Xア*0ア Z=アイウエオカキクケコサシスセソタ==0
// CCR
// X 常に変化しない
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は結果の最上位ビット
public static void irpRorToMem () throws M68kException {
XEiJ.mpuCycleCount += 8;
int ea = XEiJ.regOC & 63;
int a = efaMltWord (ea);
int x = XEiJ.busRwz (a);
int z = (short) (x << 15 | x >>> 1);
XEiJ.busWw (a, z);
XEiJ.regCCR = (XEiJ.regCCR & XEiJ.REG_CCR_X | //Xは変化しない
(z < 0 ? XEiJ.REG_CCR_N : 0) |
(z == 0 ? XEiJ.REG_CCR_Z : 0) |
z >>> 31); //Cは結果の最上位ビット
} //irpRorToMem
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//ROL.W <ea> |-|012346|-|-UUUU|-**0*| M+-WXZ |1110_011_111_mmm_rrr
//
//ROL.W #<data>,Dr
//ROL.W Dq,Dr
//ROL.W <ea>
// 左ローテートワード
// ................アイウエオカキクケコサシスセソタ XNZVC
// 0 ................アイウエオカキクケコサシスセソタ Xア*00 Z=アイウエオカキクケコサシスセソタ==0
// 1 ................イウエオカキクケコサシスセソタア Xイ*0ア Z=アイウエオカキクケコサシスセソタ==0
// :
// 15 ................タアイウエオカキクケコサシスセソ Xタ*0ソ Z=アイウエオカキクケコサシスセソタ==0
// 16 ................アイウエオカキクケコサシスセソタ Xア*0タ Z=アイウエオカキクケコサシスセソタ==0
// CCR
// X 常に変化しない
// N 結果の最上位ビット
// Z 結果が0のときセット。他はクリア
// V 常にクリア
// C countが0のときクリア。他は結果の最下位ビット
public static void irpRolToMem () throws M68kException {
XEiJ.mpuCycleCount += 8;
int ea = XEiJ.regOC & 63;
int a = efaMltWord (ea);
int x = XEiJ.busRwz (a);
int z = (short) (x << 1 | x >>> 15);
XEiJ.busWw (a, z);
XEiJ.regCCR = (XEiJ.regCCR & XEiJ.REG_CCR_X | //Xは変化しない
(z < 0 ? XEiJ.REG_CCR_N : 0) |
(z == 0 ? XEiJ.REG_CCR_Z : 0) |
z & 1); //Cは結果の最下位ビット
} //irpRolToMem
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BFTST <ea>{#o:#w} |-|--2346|-|-UUUU|-**00|D M WXZP |1110_100_011_mmm_rrr-00000ooooo0wwwww
//BFTST <ea>{#o:Dw} |-|--2346|-|-UUUU|-**00|D M WXZP |1110_100_011_mmm_rrr-00000ooooo100www
//BFTST <ea>{Do:#w} |-|--2346|-|-UUUU|-**00|D M WXZP |1110_100_011_mmm_rrr-0000100ooo0wwwww
//BFTST <ea>{Do:Dw} |-|--2346|-|-UUUU|-**00|D M WXZP |1110_100_011_mmm_rrr-0000100ooo100www
public static void irpBftst () throws M68kException {
int w;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
if ((w & ~0b0000_111_111_111_111) != 0 ||
(w & 0b0000_111_111_000_000) > 0b0000_100_111_000_000 ||
(w & 0b0000_000_000_111_111) > 0b0000_000_000_100_111) {
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
}
int o = w << 31 - 11 >= 0 ? w >> 6 & 31 : XEiJ.regRn[w >> 6 & 7]; //o=offset
w = -(w << 31 - 5 >= 0 ? w : XEiJ.regRn[w & 7]) & 31; //w=32-width。1<=width<=32なので0<=32-width<=31
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int z;
if (ea < XEiJ.EA_AR) { //BFTST Dr{~}
z = XEiJ.regRn[ea];
z = z << o | z >>> -o; //下位からはみ出したフィールドは上位に戻る
} else { //BFTST <mem>{~}
int a = efaCntLong (ea) + (o >> 3); //フィールドの最上位ビットを含むバイトのアドレス
o &= 7;
z = 31 - w + o >> 3; //フィールドが跨ぐバイト境界の数。0~4
z = (z == 0 ? XEiJ.busRbs (a) << 24 + o : //不要なバイトにアクセスしない
z == 1 ? XEiJ.busRws (a) << 16 + o : //020以上なのでアドレスエラーは出ない
z == 2 ? (XEiJ.busRws (a) << 8 | XEiJ.busRbz (a + 2)) << 8 + o :
z == 3 ? XEiJ.busRls (a) << o :
XEiJ.busRls (a) << o | XEiJ.busRbz (a + 4) >>> 8 - o);
}
z >>= w; //符号拡張。下位のゴミを消す
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
} //irpBftst
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BFEXTU <ea>{#o:#w},Dn |-|--2346|-|-UUUU|-**00|D M WXZP |1110_100_111_mmm_rrr-0nnn0ooooo0wwwww
//BFEXTU <ea>{#o:Dw},Dn |-|--2346|-|-UUUU|-**00|D M WXZP |1110_100_111_mmm_rrr-0nnn0ooooo100www
//BFEXTU <ea>{Do:#w},Dn |-|--2346|-|-UUUU|-**00|D M WXZP |1110_100_111_mmm_rrr-0nnn100ooo0wwwww
//BFEXTU <ea>{Do:Dw},Dn |-|--2346|-|-UUUU|-**00|D M WXZP |1110_100_111_mmm_rrr-0nnn100ooo100www
public static void irpBfextu () throws M68kException {
int w;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
if ((w & ~0b0111_111_111_111_111) != 0 ||
(w & 0b0000_111_111_000_000) > 0b0000_100_111_000_000 ||
(w & 0b0000_000_000_111_111) > 0b0000_000_000_100_111) {
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
}
int n = w >> 12;
int o = w << 31 - 11 >= 0 ? w >> 6 & 31 : XEiJ.regRn[w >> 6 & 7]; //o=offset
w = -(w << 31 - 5 >= 0 ? w : XEiJ.regRn[w & 7]) & 31; //w=32-width。1<=width<=32なので0<=32-width<=31
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int z;
if (ea < XEiJ.EA_AR) { //BFEXTU Dr{~}
z = XEiJ.regRn[ea];
z = z << o | z >>> -o; //下位からはみ出したフィールドは上位に戻る
} else { //BFEXTU <mem>{~}
int a = efaCntLong (ea) + (o >> 3);
o &= 7;
z = 31 - w + o >> 3;
z = (z == 0 ? XEiJ.busRbs (a) << 24 + o : //不要なバイトにアクセスしない
z == 1 ? XEiJ.busRws (a) << 16 + o : //020以上なのでアドレスエラーは出ない
z == 2 ? (XEiJ.busRws (a) << 8 | XEiJ.busRbz (a + 2)) << 8 + o :
z == 3 ? XEiJ.busRls (a) << o :
XEiJ.busRls (a) << o | XEiJ.busRbz (a + 4) >>> 8 - o);
}
XEiJ.regRn[n] = z >>> w; //ゼロ拡張
z >>= w; //符号拡張。下位のゴミを消す
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
} //irpBfextu
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BFCHG <ea>{#o:#w} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_101_011_mmm_rrr-00000ooooo0wwwww
//BFCHG <ea>{#o:Dw} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_101_011_mmm_rrr-00000ooooo100www
//BFCHG <ea>{Do:#w} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_101_011_mmm_rrr-0000100ooo0wwwww
//BFCHG <ea>{Do:Dw} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_101_011_mmm_rrr-0000100ooo100www
public static void irpBfchg () throws M68kException {
int w;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
if ((w & ~0b0000_111_111_111_111) != 0 ||
(w & 0b0000_111_111_000_000) > 0b0000_100_111_000_000 ||
(w & 0b0000_000_000_111_111) > 0b0000_000_000_100_111) {
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
}
int o = w << 31 - 11 >= 0 ? w >> 6 & 31 : XEiJ.regRn[w >> 6 & 7]; //o=offset
w = -(w << 31 - 5 >= 0 ? w : XEiJ.regRn[w & 7]) & 31; //w=32-width。1<=width<=32なので0<=32-width<=31
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int z;
if (ea < XEiJ.EA_AR) { //BFCHG Dr{~}
z = XEiJ.regRn[ea];
z = z << o | z >>> -o; //下位からはみ出したフィールドは上位に戻る
int t = z ^ -1 << w; //フィールドの幅だけ反転する
XEiJ.regRn[ea] = t << -o | t >>> o;
} else { //BFCHG <mem>{~}
int a = efaCltLong (ea) + (o >> 3); //フィールドの最上位ビットを含むバイトのアドレス
o &= 7;
z = 31 - w + o >> 3; //フィールドが跨ぐバイト境界の数。0~4
if (z == 0) {
// <ea>{2,5} o=2,w=32-5=27 <ea> --abcde-
int t = XEiJ.busRbs (a) << 24; // t --abcde- 00000000 00000000 00000000 不要なバイトにアクセスしない
z = t << o; // z abcde-00 00000000 00000000 00000000
// // -1<<w 11111000 00000000 00000000 00000000
// // -1<<w>>>o 00111110 00000000 00000000 00000000
// //t^-1<<w>>>o --ABCDE- 00000000 00000000 00000000
XEiJ.busWb (a, (t ^ -1 << w >>> o) >>> 24); // <ea> --ABCDE-
} else if (z == 1) {
// <ea>{7,5} o=7,w=32-5=27 <ea> -------a bcde----
int t = XEiJ.busRws (a) << 16; // t -------a bcde---- 00000000 00000000 020以上なのでアドレスエラーは出ない
z = t << o; // z abcde--- -0000000 00000000 00000000
// // -1<<w 11111000 00000000 00000000 00000000
// // -1<<w>>>o 00000001 11110000 00000000 00000000
// //t^-1<<w>>>o -------A BCDE---- 00000000 00000000
XEiJ.busWw (a, (t ^ -1 << w >>> o) >>> 16); // <ea> -------A BCDE----
} else if (z == 2) {
// <ea>{7,12} o=7,w=32-12=20 <ea> -------a bcdefghi jkl-----
int t = XEiJ.busRws (a) << 16 | XEiJ.busRbz (a + 2) << 8; // t -------a bcdefghi jkl----- 00000000
z = t << o; // z abcdefgh ijkl---- -0000000 00000000
// // -1<<w 11111111 11110000 00000000 00000000
// // -1<<w>>>o 00000001 11111111 11100000 00000000
t ^= -1 << w >>> o; // t -------A BCDEFGHI JKL----- 00000000
XEiJ.busWw (a, t >>> 16); // <ea> -------A BCDEFGHI jkl-----
XEiJ.busWb (a + 2, t >>> 8); // <ea> -------A BCDEFGHI JKL-----
} else if (z == 3) {
// <ea>{7,19} o=7,w=32-19=13 <ea> -------a bcdefghi jklmnopq rs------
int t = XEiJ.busRls (a); // t -------a bcdefghi jklmnopq rs------
z = t << o; // z abcdefgh ijklmnop qrs----- -0000000
// // -1<<w 11111111 11111111 11100000 00000000
// // -1<<w>>>o 00000001 11111111 11111111 11000000
XEiJ.busWl (a, t ^ -1 << w >>> o); // <ea> -------A BCDEFGHI JKLMNOPQ RS------
} else {
// <ea>{7,26} o=7,w=32-26=6 <ea> -------a bcdefghi jklmnopq rstuvwxy z-------
int t = XEiJ.busRls (a); // t -------a bcdefghi jklmnopq rstuvwxy
z = t << o; // z abcdefgh ijklmnop qrstuvwx y0000000
// -1>>>o 00000001 11111111 11111111 11111111
XEiJ.busWl (a, t ^ -1 >>> o); // <ea> -------A BCDEFGHI JKLMNOPQ RSTUVWXY
t = XEiJ.busRbz (a + 4); // t 00000000 00000000 00000000 z-------
// // t>>>8-o 00000000 00000000 00000000 0z------
z |= t >>> 8 - o; // z abcdefgh ijklmnop qrstuvwx yz------
// // -1<<8-o+w 11111111 11111111 11111111 10000000
XEiJ.busWb (a + 4, t ^ -1 << 8 - o + w); // <ea> -------A BCDEFGHI JKLMNOPQ RSTUVWXY Z-------
}
}
z >>= w; //符号拡張。下位のゴミを消す
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
} //irpBfchg
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BFEXTS <ea>{#o:#w},Dn |-|--2346|-|-UUUU|-**00|D M WXZP |1110_101_111_mmm_rrr-0nnn0ooooo0wwwww
//BFEXTS <ea>{#o:Dw},Dn |-|--2346|-|-UUUU|-**00|D M WXZP |1110_101_111_mmm_rrr-0nnn0ooooo100www
//BFEXTS <ea>{Do:#w},Dn |-|--2346|-|-UUUU|-**00|D M WXZP |1110_101_111_mmm_rrr-0nnn100ooo0wwwww
//BFEXTS <ea>{Do:Dw},Dn |-|--2346|-|-UUUU|-**00|D M WXZP |1110_101_111_mmm_rrr-0nnn100ooo100www
public static void irpBfexts () throws M68kException {
int w;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
if ((w & ~0b0111_111_111_111_111) != 0 ||
(w & 0b0000_111_111_000_000) > 0b0000_100_111_000_000 ||
(w & 0b0000_000_000_111_111) > 0b0000_000_000_100_111) {
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
}
int n = w >> 12;
int o = w << 31 - 11 >= 0 ? w >> 6 & 31 : XEiJ.regRn[w >> 6 & 7]; //o=offset
w = -(w << 31 - 5 >= 0 ? w : XEiJ.regRn[w & 7]) & 31; //w=32-width。1<=width<=32なので0<=32-width<=31
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int z;
if (ea < XEiJ.EA_AR) { //BFEXTS Dr{~}
z = XEiJ.regRn[ea];
z = z << o | z >>> -o; //下位からはみ出したフィールドは上位に戻る
} else { //BFEXTS <mem>{~}
int a = efaCntLong (ea) + (o >> 3); //フィールドの最上位ビットを含むバイトのアドレス
o &= 7;
z = 31 - w + o >> 3; //フィールドが跨ぐバイト境界の数。0~4
z = (z == 0 ? XEiJ.busRbs (a) << 24 + o : //不要なバイトにアクセスしない
z == 1 ? XEiJ.busRws (a) << 16 + o : //020以上なのでアドレスエラーは出ない
z == 2 ? (XEiJ.busRws (a) << 8 | XEiJ.busRbz (a + 2)) << 8 + o :
z == 3 ? XEiJ.busRls (a) << o :
XEiJ.busRls (a) << o | XEiJ.busRbz (a + 4) >>> 8 - o);
}
XEiJ.regRn[n] = z >>= w; //符号拡張。下位のゴミを消す
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
} //irpBfexts
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BFCLR <ea>{#o:#w} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_110_011_mmm_rrr-00000ooooo0wwwww
//BFCLR <ea>{#o:Dw} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_110_011_mmm_rrr-00000ooooo100www
//BFCLR <ea>{Do:#w} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_110_011_mmm_rrr-0000100ooo0wwwww
//BFCLR <ea>{Do:Dw} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_110_011_mmm_rrr-0000100ooo100www
public static void irpBfclr () throws M68kException {
int w;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
if ((w & ~0b0000_111_111_111_111) != 0 ||
(w & 0b0000_111_111_000_000) > 0b0000_100_111_000_000 ||
(w & 0b0000_000_000_111_111) > 0b0000_000_000_100_111) {
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
}
int o = w << 31 - 11 >= 0 ? w >> 6 & 31 : XEiJ.regRn[w >> 6 & 7]; //o=offset
w = -(w << 31 - 5 >= 0 ? w : XEiJ.regRn[w & 7]) & 31; //w=32-width。1<=width<=32なので0<=32-width<=31
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int z;
if (ea < XEiJ.EA_AR) { //BFCLR Dr{~}
z = XEiJ.regRn[ea];
z = z << o | z >>> -o; //下位からはみ出したフィールドは上位に戻る
int t = z & ~(-1 << w); //フィールドの幅だけ0を並べる
XEiJ.regRn[ea] = t << -o | t >>> o;
} else { //BFCLR <mem>{~}
int a = efaCltLong (ea) + (o >> 3); //フィールドの最上位ビットを含むバイトのアドレス
o &= 7;
z = 31 - w + o >> 3; //フィールドが跨ぐバイト境界の数。0~4
if (z == 0) {
// <ea>{2,5} o=2,w=32-5=27 <ea> --abcde-
int t = XEiJ.busRbs (a) << 24; // t --abcde- 00000000 00000000 00000000 不要なバイトにアクセスしない
z = t << o; // z abcde-00 00000000 00000000 00000000
// // -1<<w 11111000 00000000 00000000 00000000
// // -1<<w>>>o 00111110 00000000 00000000 00000000
// //~(-1<<w>>>o) 11000001 11111111 11111111 11111111
// //t&~(-1<<w>>>o) --00000- 00000000 00000000 00000000
XEiJ.busWb (a, (t & ~(-1 << w >>> o)) >>> 24); // <ea> --00000-
} else if (z == 1) {
// <ea>{7,5} o=7,w=32-5=27 <ea> -------a bcde----
int t = XEiJ.busRws (a) << 16; // t -------a bcde---- 00000000 00000000 020以上なのでアドレスエラーは出ない
z = t << o; // z abcde--- -0000000 00000000 00000000
// // -1<<w 11111000 00000000 00000000 00000000
// // -1<<w>>>o 00000001 11110000 00000000 00000000
// //~(-1<<w>>>o) 11111110 00001111 11111111 11111111
// //t&~(-1<<w>>>o) -------0 0000---- 00000000 00000000
XEiJ.busWw (a, (t & ~(-1 << w >>> o)) >>> 16); // <ea> -------0 0000----
} else if (z == 2) {
// <ea>{7,12} o=7,w=32-12=20 <ea> -------a bcdefghi jkl-----
int t = XEiJ.busRws (a) << 16 | XEiJ.busRbz (a + 2) << 8; // t -------a bcdefghi jkl----- 00000000
z = t << o; // z abcdefgh ijkl---- -0000000 00000000
// // -1<<w 11111111 11110000 00000000 00000000
// // -1<<w>>>o 00000001 11111111 11100000 00000000
// //~(-1<<w>>>o) 11111110 00000000 00011111 11111111
t &= ~(-1 << w >>> o); // t -------0 00000000 000----- 00000000
XEiJ.busWw (a, t >>> 16); // <ea> -------0 00000000 jkl-----
XEiJ.busWb (a + 2, t >>> 8); // <ea> -------0 00000000 000-----
} else if (z == 3) {
// <ea>{7,19} o=7,w=32-19=13 <ea> -------a bcdefghi jklmnopq rs------
int t = XEiJ.busRls (a); // t -------a bcdefghi jklmnopq rs------
z = t << o; // z abcdefgh ijklmnop qrs----- -0000000
// // -1<<w 11111111 11111111 11100000 00000000
// // -1<<w>>>o 00000001 11111111 11111111 11000000
// //~(-1<<w>>>o) 11111110 00000000 00000000 00111111
XEiJ.busWl (a, t & ~(-1 << w >>> o)); // <ea> -------0 00000000 00000000 00------
} else {
// <ea>{7,26} o=7,w=32-26=6 <ea> -------a bcdefghi jklmnopq rstuvwxy z-------
int t = XEiJ.busRls (a); // t -------a bcdefghi jklmnopq rstuvwxy
z = t << o; // z abcdefgh ijklmnop qrstuvwx y0000000
// -1>>>o 00000001 11111111 11111111 11111111
// ~(-1>>>o) 11111110 00000000 00000000 00000000
XEiJ.busWl (a, t & ~(-1 >>> o)); // <ea> -------0 00000000 00000000 00000000
t = XEiJ.busRbz (a + 4); // t 00000000 00000000 00000000 z-------
// // t>>>8-o 00000000 00000000 00000000 0z------
z |= t >>> 8 - o; // z abcdefgh ijklmnop qrstuvwx yz------
// // -1<<8-o+w 11111111 11111111 11111111 10000000
// //~(-1<<8-o+w) 00000000 00000000 00000000 01111111
XEiJ.busWb (a + 4, t & ~(-1 << 8 - o + w)); // <ea> -------0 00000000 00000000 00000000 0-------
}
}
z >>= w; //符号拡張。下位のゴミを消す
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
} //irpBfclr
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BFFFO <ea>{#o:#w},Dn |-|--2346|-|-UUUU|-**00|D M WXZP |1110_110_111_mmm_rrr-0nnn0ooooo0wwwww
//BFFFO <ea>{#o:Dw},Dn |-|--2346|-|-UUUU|-**00|D M WXZP |1110_110_111_mmm_rrr-0nnn0ooooo100www
//BFFFO <ea>{Do:#w},Dn |-|--2346|-|-UUUU|-**00|D M WXZP |1110_110_111_mmm_rrr-0nnn100ooo0wwwww
//BFFFO <ea>{Do:Dw},Dn |-|--2346|-|-UUUU|-**00|D M WXZP |1110_110_111_mmm_rrr-0nnn100ooo100www
public static void irpBfffo () throws M68kException {
int w;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
if ((w & ~0b0111_111_111_111_111) != 0 ||
(w & 0b0000_111_111_000_000) > 0b0000_100_111_000_000 ||
(w & 0b0000_000_000_111_111) > 0b0000_000_000_100_111) {
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
}
int n = w >> 12;
int o = w << 31 - 11 >= 0 ? w >> 6 & 31 : XEiJ.regRn[w >> 6 & 7]; //o=offset
w = -(w << 31 - 5 >= 0 ? w : XEiJ.regRn[w & 7]) & 31; //w=32-width。1<=width<=32なので0<=32-width<=31
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int z;
if (ea < XEiJ.EA_AR) { //BFFFO Dr{~}
z = XEiJ.regRn[ea];
z = z << o | z >>> -o; //下位からはみ出したフィールドは上位に戻る
} else { //BFFFO <mem>{~}
int a = efaCntLong (ea) + (o >> 3); //フィールドの最上位ビットを含むバイトのアドレス
int o7 = o & 7;
z = 31 - w + o7 >> 3; //フィールドが跨ぐバイト境界の数。0~4
z = (z == 0 ? XEiJ.busRbs (a) << 24 + o7 : //不要なバイトにアクセスしない
z == 1 ? XEiJ.busRws (a) << 16 + o7 : //020以上なのでアドレスエラーは出ない
z == 2 ? (XEiJ.busRws (a) << 8 | XEiJ.busRbz (a + 2)) << 8 + o7 :
z == 3 ? XEiJ.busRls (a) << o7 :
XEiJ.busRls (a) << o7 | XEiJ.busRbz (a + 4) >>> 8 - o7);
}
if (true) {
XEiJ.regRn[n] = Integer.numberOfLeadingZeros (z >>> w) - w + o; //ゼロ拡張してから1のビットを探す。見つからないときはoffset+widthになる
} else {
int t = z >>> w;
if (t == 0) {
XEiJ.regRn[n] = 32 - w + o;
} else {
int k = -(t >>> 16) >> 16 & 16;
k += -(t >>> k + 8) >> 8 & 8;
k += -(t >>> k + 4) >> 4 & 4;
// bit3 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
// bit2 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0
// bit1 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0
// bit0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
XEiJ.regRn[n] = ((0b11_11_11_11_11_11_11_11_10_10_10_10_01_01_00_00 >>> (t >>> k << 1)) & 3) + k - w + o; //intのシフトカウントは下位5bitだけが使用される
}
}
z >>= w; //符号拡張。下位のゴミを消す
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
} //irpBfffo
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BFSET <ea>{#o:#w} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_111_011_mmm_rrr-00000ooooo0wwwww
//BFSET <ea>{#o:Dw} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_111_011_mmm_rrr-00000ooooo100www
//BFSET <ea>{Do:#w} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_111_011_mmm_rrr-0000100ooo0wwwww
//BFSET <ea>{Do:Dw} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_111_011_mmm_rrr-0000100ooo100www
public static void irpBfset () throws M68kException {
int w;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
if ((w & ~0b0000_111_111_111_111) != 0 ||
(w & 0b0000_111_111_000_000) > 0b0000_100_111_000_000 ||
(w & 0b0000_000_000_111_111) > 0b0000_000_000_100_111) {
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
}
int o = w << 31 - 11 >= 0 ? w >> 6 & 31 : XEiJ.regRn[w >> 6 & 7]; //o=offset
w = -(w << 31 - 5 >= 0 ? w : XEiJ.regRn[w & 7]) & 31; //w=32-width。1<=width<=32なので0<=32-width<=31
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int z;
if (ea < XEiJ.EA_AR) { //BFSET Dr{~}
z = XEiJ.regRn[ea];
z = z << o | z >>> -o; //下位からはみ出したフィールドは上位に戻る
int t = z | -1 << w; //フィールドの幅だけ1を並べる
XEiJ.regRn[ea] = t << -o | t >>> o;
} else { //BFSET <mem>{~}
int a = efaCltLong (ea) + (o >> 3); //フィールドの最上位ビットを含むバイトのアドレス
o &= 7;
z = 31 - w + o >> 3; //フィールドが跨ぐバイト境界の数。0~4
if (z == 0) {
// <ea>{2,5} o=2,w=32-5=27 <ea> --abcde-
int t = XEiJ.busRbs (a) << 24; // t --abcde- 00000000 00000000 00000000 不要なバイトにアクセスしない
z = t << o; // z abcde-00 00000000 00000000 00000000
// // -1<<w 11111000 00000000 00000000 00000000
// // -1<<w>>>o 00111110 00000000 00000000 00000000
// //t|-1<<w>>>o --11111- 00000000 00000000 00000000
XEiJ.busWb (a, (t | -1 << w >>> o) >>> 24); // <ea> --11111-
} else if (z == 1) {
// <ea>{7,5} o=7,w=32-5=27 <ea> -------a bcde----
int t = XEiJ.busRws (a) << 16; // t -------a bcde---- 00000000 00000000 020以上なのでアドレスエラーは出ない
z = t << o; // z abcde--- -0000000 00000000 00000000
// // -1<<w 11111000 00000000 00000000 00000000
// // -1<<w>>>o 00000001 11110000 00000000 00000000
// //t|-1<<w>>>o -------1 1111---- 00000000 00000000
XEiJ.busWw (a, (t | -1 << w >>> o) >>> 16); // <ea> -------1 1111----
} else if (z == 2) {
// <ea>{7,12} o=7,w=32-12=20 <ea> -------a bcdefghi jkl-----
int t = XEiJ.busRws (a) << 16 | XEiJ.busRbz (a + 2) << 8; // t -------a bcdefghi jkl----- 00000000
z = t << o; // z abcdefgh ijkl---- -0000000 00000000
// // -1<<w 11111111 11110000 00000000 00000000
// // -1<<w>>>o 00000001 11111111 11100000 00000000
t |= -1 << w >>> o; // t -------1 11111111 111----- 00000000
XEiJ.busWw (a, t >>> 16); // <ea> -------1 11111111 jkl-----
XEiJ.busWb (a + 2, t >>> 8); // <ea> -------1 11111111 111-----
} else if (z == 3) {
// <ea>{7,19} o=7,w=32-19=13 <ea> -------a bcdefghi jklmnopq rs------
int t = XEiJ.busRls (a); // t -------a bcdefghi jklmnopq rs------
z = t << o; // z abcdefgh ijklmnop qrs----- -0000000
// // -1<<w 11111111 11111111 11100000 00000000
// // -1<<w>>>o 00000001 11111111 11111111 11000000
XEiJ.busWl (a, t | -1 << w >>> o); // <ea> -------1 11111111 11111111 11------
} else {
// <ea>{7,26} o=7,w=32-26=6 <ea> -------a bcdefghi jklmnopq rstuvwxy z-------
int t = XEiJ.busRls (a); // t -------a bcdefghi jklmnopq rstuvwxy
z = t << o; // z abcdefgh ijklmnop qrstuvwx y0000000
// -1>>>o 00000001 11111111 11111111 11111111
XEiJ.busWl (a, t | -1 >>> o); // <ea> -------1 11111111 11111111 11111111
t = XEiJ.busRbz (a + 4); // t 00000000 00000000 00000000 z-------
// // t>>>8-o 00000000 00000000 00000000 0z------
z |= t >>> 8 - o; // z abcdefgh ijklmnop qrstuvwx yz------
// // -1<<8-o+w 11111111 11111111 11111111 10000000
XEiJ.busWb (a + 4, t | -1 << 8 - o + w); // <ea> -------1 11111111 11111111 11111111 1-------
}
}
z >>= w; //符号拡張。下位のゴミを消す
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
} //irpBfset
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//BFINS Dn,<ea>{#o:#w} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_111_111_mmm_rrr-0nnn0ooooo0wwwww
//BFINS Dn,<ea>{#o:Dw} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_111_111_mmm_rrr-0nnn0ooooo100www
//BFINS Dn,<ea>{Do:#w} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_111_111_mmm_rrr-0nnn100ooo0wwwww
//BFINS Dn,<ea>{Do:Dw} |-|--2346|-|-UUUU|-**00|D M WXZ |1110_111_111_mmm_rrr-0nnn100ooo100www
public static void irpBfins () throws M68kException {
int w;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
if ((w & ~0b0111_111_111_111_111) != 0 ||
(w & 0b0000_111_111_000_000) > 0b0000_100_111_000_000 ||
(w & 0b0000_000_000_111_111) > 0b0000_000_000_100_111) {
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
}
int n = w >> 12;
int o = w << 31 - 11 >= 0 ? w >> 6 & 31 : XEiJ.regRn[w >> 6 & 7]; //o=offset
w = -(w << 31 - 5 >= 0 ? w : XEiJ.regRn[w & 7]) & 31; //w=32-width。1<=width<=32なので0<=32-width<=31
XEiJ.mpuCycleCount += 4;
int ea = XEiJ.regOC & 63;
int z = XEiJ.regRn[n] << w; //z=Dn<<-width
if (ea < XEiJ.EA_AR) { //BFINS Dn,Dr{~}
// Dr{30,5} o=30,w=32-5=27 t=Dr cde----- -------- -------- ------ab
// t<<o ab000000 00000000 00000000 00000000
// t>>>-o 00cde--- -------- -------- --------
// t<<o|t>>>-o abcde--- -------- -------- --------
// -1<<w 11111000 00000000 00000000 00000000
// ~(-1<<w) 00000111 11111111 11111111 11111111
// (t<<o|t>>>-o)&~(-1<<w) 00000--- -------- -------- --------
// r[n] -------- -------- -------- ---ABCDE
// z=r[n]<<w ABCDE000 00000000 00000000 00000000
// t=(t<<o|t>>>-o)&~(-1<<w)|z ABCDE--- -------- -------- --------
// t<<-o CDE----- -------- -------- ------00
// t>>>o 00000000 00000000 00000000 000000AB
// t<<-o|t>>>o CDE----- -------- -------- ------AB
int t = XEiJ.regRn[ea];
t = (t << o | t >>> -o) & ~(-1 << w) | z;
XEiJ.regRn[ea] = t << -o | t >>> o;
} else { //BFINS Dn,<mem>{~}
int a = efaCltLong (ea) + (o >> 3); //フィールドの最上位ビットを含むバイトのアドレス
o &= 7;
n = 31 - w + o >> 3; //フィールドが跨ぐバイト境界の数。0~4
if (n == 0) {
// <ea>{2,5} o=2,w=32-5=27 <ea> --abcde-
// XEiJ.busRbs(a)<<24 --abcde- 00000000 00000000 00000000
// -1<<w 11111000 00000000 00000000 00000000
// -1<<w>>>o 00111110 00000000 00000000 00000000
// ~(-1<<w>>>o) 11000001 11111111 11111111 11111111
// XEiJ.busRbs(a)<<24&~(-1<<w>>>o) --00000- 00000000 00000000 00000000
// r[n] -------- -------- -------- ---ABCDE
// z=r[n]<<w ABCDE000 00000000 00000000 00000000
// z>>>o 00ABCDE0 00000000 00000000 00000000
// XEiJ.busRbs(a)<<24&~(-1<<w>>>o)|z>>>o --ABCDE- 00000000 00000000 00000000
XEiJ.busWb (a, (XEiJ.busRbs (a) << 24 & ~(-1 << w >>> o) | z >>> o) >>> 24);
} else if (n == 1) {
// <ea>{3,11} o=3,w=32-11=21 <ea> ---abcde fghijk--
// rws(a)<<16 ---abcde fghijk-- 00000000 00000000
// -1<<w 11111111 11100000 00000000 00000000
// -1<<w>>>o 00011111 11111100 00000000 00000000
// ~(-1<<w>>>o) 11100000 00000011 11111111 11111111
// rws(a)<<16&~(-1<<w>>>o) ---00000 000000-- 00000000 00000000
// r[n] -------- -------- -----ABC DEFGHIJK
// z=r[n]<<w ABCDEFGH IJK00000 00000000 00000000
// z>>>o 000ABCDE FGHIJK00 00000000 00000000
// rws(a)<<16&~(-1<<w>>>o)|z>>>o ---ABCDE FGHIJK-- 00000000 00000000
XEiJ.busWw (a, (XEiJ.busRws (a) << 16 & ~(-1 << w >>> o) | z >>> o) >>> 16);
} else if (n == 2) {
// <ea>{4,17} o=4,w=32-17=15 <ea> ----abcd efghijkl mnopq---
// rws(a)<<16|rbz(a+2)<<8 ----abcd efghijkl mnopq--- 00000000
// -1<<w 11111111 11111111 10000000 00000000
// -1<<w>>>o 00001111 11111111 11111000 00000000
// ~(-1<<w>>>o) 11110000 00000000 00000111 11111111
// (rws(a)<<16|rbz(a+2)<<8)&~(-1<<w>>>o) ----0000 00000000 00000--- 00000000
// r[n] -------- -------A BCDEFGHI JKLMNOPQ
// z=r[n]<<w ABCDEFGH IJKLMNOP Q0000000 00000000
// z>>>o 0000ABCD EFGHIJKL MNOPQ000 00000000
// (rws(a)<<16|rbz(a+2)<<8)&~(-1<<w>>>o)|z>>>o ----ABCD EFGHIJKL MNOPQ--- 00000000
int t = (XEiJ.busRws (a) << 16 | XEiJ.busRbz (a + 2) << 8) & ~(-1 << w >>> o) | z >>> o;
XEiJ.busWw (a, t >>> 16);
XEiJ.busWb (a + 2, t >>> 8);
} else if (n == 3) {
// <ea>{5,23} o=5,w=32-23=9 <ea> -----abc defghijk lmnopqrs tuvw----
// rls(a) -----abc defghijk lmnopqrs tuvw----
// -1<<w 11111111 11111111 11111110 00000000
// -1<<w>>>o 00000111 11111111 11111111 11110000
// ~(-1<<w>>>o) 11111000 00000000 00000000 00001111
// rls(a)&~(-1<<w>>>o) -----000 00000000 00000000 0000----
// r[n] -------- -ABCDEFG HIJKLMNO PQRSTUVW
// z=r[n]<<w ABCDEFGH IJKLMNOP QRSTUVW0 00000000
// z>>>o 00000ABC DEFGHIJK LMNOPQRS TUVW0000
// rls(a)&~(-1<<w>>>o)|z>>>o -----ABC DEFGHIJK LMNOPQRS TUVW----
XEiJ.busWl (a, XEiJ.busRls (a) & ~(-1 << w >>> o) | z >>> o);
} else {
// <ea>{6,29} o=6,w=32-29=3 <ea> ------ab cdefghij klmnopqr stuvwxyz abc-----
// rls(a) ------ab cdefghij klmnopqr stuvwxyz
// -1>>>o 00000011 11111111 11111111 11111111
// ~(-1>>>o) 11111100 00000000 00000000 00000000
// rls(a)&~(-1>>>o) ------00 00000000 00000000 00000000
// r[n] ---ABCDE FGHIJKLM NOPQRSTU VWXYZABC
// z=r[n]<<w ABCDEFGH IJKLMNOP QRSTUVWX YZABC000
// z>>>o 000000AB CDEFGHIJ KLMNOPQR STUVWXYZ
// rls(a)&~(-1>>>o)|z>>>o ------AB CDEFGHIJ KLMNOPQR STUVWXYZ
XEiJ.busWl (a, XEiJ.busRls (a) & ~(-1 >>> o) | z >>> o);
// rbz(a+4) 00000000 00000000 00000000 abc-----
// -1<<8-o+w 11111111 11111111 11111111 11100000
// ~(-1<<8-o+w) 00000000 00000000 00000000 00011111
// rbz(a+4)&~(-1<<8-o+w) 00000000 00000000 00000000 000-----
// z<<8-o CDEFGHIJ KLMNOPQR STUVWXYZ ABC00000
// rbz(a+4)&~(-1<<8-o+w)|z<<8-o CDEFGHIJ KLMNOPQR STUVWXYZ ABC-----
XEiJ.busWb (a + 4, XEiJ.busRbz (a + 4) & ~(-1 << 8 - o + w) | z << 8 - o);
}
}
//zは上位に寄ったままだが下位の空きは0なのでそのままテストする
XEiJ.regCCR = z >> 28 & XEiJ.REG_CCR_N | (z == 0 ? XEiJ.regCCR & XEiJ.REG_CCR_X | XEiJ.REG_CCR_Z : XEiJ.regCCR & XEiJ.REG_CCR_X); //ccr_tst
} //irpBfins
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//PFLUSHA |-|---3--|P|-----|-----| |1111_000_000_000_000-0010010000000000
//PFLUSH SFC,#<mask> |-|---3--|P|-----|-----| |1111_000_000_000_000-00110000mmm00000
//PFLUSH DFC,#<mask> |-|---3--|P|-----|-----| |1111_000_000_000_000-00110000mmm00001
//PFLUSH Dn,#<mask> |-|---3--|P|-----|-----| |1111_000_000_000_000-00110000mmm01nnn
//PFLUSH #<data>,#<mask> |-|---3--|P|-----|-----| |1111_000_000_000_000-00110000mmm10ddd
//PMOVE.L <ea>,TTn |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-00001n0000000000
//PMOVEFD.L <ea>,TTn |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-00001n0100000000
//PMOVE.L TTn,<ea> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-00001n1000000000
//PLOADW SFC,<ea> |-|--M3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0010000000000000
//PLOADW DFC,<ea> |-|--M3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0010000000000001
//PLOADW Dn,<ea> |-|--M3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0010000000001nnn
//PLOADW #<data>,<ea> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0010000000010ddd
//PLOADR SFC,<ea> |-|--M3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0010001000000000
//PLOADR DFC,<ea> |-|--M3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0010001000000001
//PLOADR Dn,<ea> |-|--M3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0010001000001nnn
//PLOADR #<data>,<ea> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0010001000010ddd
//PFLUSH SFC,#<mask>,<ea> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-00111000mmm00000
//PFLUSH DFC,#<mask>,<ea> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-00111000mmm00001
//PFLUSH Dn,#<mask>,<ea> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-00111000mmm01nnn
//PFLUSH #<data>,#<mask>,<ea> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-00111000mmm10ddd
//PMOVE.L <ea>,TC |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0100000000000000
//PMOVEFD.L <ea>,TC |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0100000100000000
//PMOVE.L TC,<ea> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0100001000000000
//PMOVE.Q <ea>,SRP |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0100100000000000
//PMOVEFD.Q <ea>,SRP |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0100100100000000
//PMOVE.Q SRP,<ea> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0100101000000000
//PMOVE.Q <ea>,CRP |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0100110000000000
//PMOVEFD.Q <ea>,CRP |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0100110100000000
//PMOVE.Q CRP,<ea> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0100111000000000
//PMOVE.W <ea>,MMUSR |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0110000000000000
//PMOVE.W MMUSR,<ea> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-0110001000000000
//PTESTW SFC,<ea>,#<level> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll0000000000
//PTESTW DFC,<ea>,#<level> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll0000000001
//PTESTW Dn,<ea>,#<level> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll0000001nnn
//PTESTW #<data>,<ea>,#<level> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll0000010ddd
//PTESTW SFC,<ea>,#<level>,An |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll01nnn00000
//PTESTW DFC,<ea>,#<level>,An |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll01nnn00001
//PTESTW Dn,<ea>,#<level>,An |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll01nnn01nnn
//PTESTW #<data>,<ea>,#<level>,An |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll01nnn10ddd
//PTESTR SFC,<ea>,#<level> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll1000000000
//PTESTR DFC,<ea>,#<level> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll1000000001
//PTESTR Dn,<ea>,#<level> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll1000001nnn
//PTESTR #<data>,<ea>,#<level> |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll1000010ddd
//PTESTR SFC,<ea>,#<level>,An |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll11nnn00000
//PTESTR DFC,<ea>,#<level>,An |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll11nnn00001
//PTESTR Dn,<ea>,#<level>,An |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll11nnn01nnn
//PTESTR #<data>,<ea>,#<level>,An |-|---3--|P|-----|-----| M WXZ |1111_000_000_mmm_rrr-100lll11nnn10ddd
public static void irpPgen () throws M68kException {
int ea = XEiJ.regOC & 63;
int mmm = ea >> 3;
if (mmm == XEiJ.MMM_DR ||
mmm == XEiJ.MMM_MM ||
mmm == XEiJ.MMM_MW ||
mmm == XEiJ.MMM_MX ||
ea == XEiJ.EA_ZW ||
ea == XEiJ.EA_ZL) {
//! 未対応。030チェックを通すためのダミー。拡張ワードを読み飛ばして何もしない
XEiJ.regPC += 2; //第2オペコード
if (ea >= XEiJ.EA_MM) {
efaAnyByte (ea);
}
} else {
irpFline ();
}
} //irpPgen
//浮動小数点例外
// 48 BSUN FP分岐または比較不能状態でのセット
// 49 INEX FP不正確な結果
// 50 DZ FPゼロによる除算
// 51 UNFL FPアンダーフロー
// 52 OPERR FPオペランドエラー
// 53 OVFL FPオーバーフロー
// 54 SNAN FPシグナリングNAN
// 55 FP未実装データ型
//FPSRのビットオフセット→例外ベクタ番号
/*
public static final int[] FP_OFFSET_TO_NUMBER = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48, //16 15 BSUN 48 BSUN FP分岐または比較不能状態でのセット
54, //17 14 SNAN 54 SNAN FPシグナリングNAN
52, //18 13 OPERR 52 OPERR FPオペランドエラー
53, //19 12 OVFL 53 OVFL FPオーバーフロー
51, //20 11 UNFL 51 UNFL FPアンダーフロー
50, //21 10 DZ 50 DZ FPゼロによる除算
49, //22 9 INEX2 49 INEX FP不正確な結果
49, //23 8 INEX1 49 INEX FP不正確な結果
0, 0, 0, 0, 0, 0, 0, 0,
};
*/
public static final byte[] FP_OFFSET_TO_NUMBER = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00006453211\0\0\0\0\0\0\0\0".getBytes (XEiJ.ISO_8859_1);
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//FTST.X FPm |-|--CC46|-|-----|-----| |1111_001_000_000_000-000mmm0000111010
//FMOVE.X FPm,FPn |-|--CC46|-|-----|-----| |1111_001_000_000_000-000mmmnnn0000000
//FINT.X FPm,FPn |-|--CCS6|-|-----|-----| |1111_001_000_000_000-000mmmnnn0000001
//FSINH.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0000010
//FINTRZ.X FPm,FPn |-|--CCS6|-|-----|-----| |1111_001_000_000_000-000mmmnnn0000011
//FSQRT.X FPm,FPn |-|--CC46|-|-----|-----| |1111_001_000_000_000-000mmmnnn0000100
//FLOGNP1.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0000110
//FETOXM1.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0001000
//FTANH.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0001001
//FATAN.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0001010
//FASIN.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0001100
//FATANH.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0001101
//FSIN.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0001110
//FTAN.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0001111
//FETOX.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0010000
//FTWOTOX.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0010001
//FTENTOX.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0010010
//FLOGN.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0010100
//FLOG10.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0010101
//FLOG2.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0010110
//FABS.X FPm,FPn |-|--CC46|-|-----|-----| |1111_001_000_000_000-000mmmnnn0011000
//FCOSH.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0011001
//FNEG.X FPm,FPn |-|--CC46|-|-----|-----| |1111_001_000_000_000-000mmmnnn0011010
//FACOS.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0011100
//FCOS.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0011101
//FGETEXP.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0011110
//FGETMAN.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0011111
//FDIV.X FPm,FPn |-|--CC46|-|-----|-----| |1111_001_000_000_000-000mmmnnn0100000
//FMOD.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0100001
//FADD.X FPm,FPn |-|--CC46|-|-----|-----| |1111_001_000_000_000-000mmmnnn0100010
//FMUL.X FPm,FPn |-|--CC46|-|-----|-----| |1111_001_000_000_000-000mmmnnn0100011
//FSGLDIV.X FPm,FPn |-|--CCS6|-|-----|-----| |1111_001_000_000_000-000mmmnnn0100100
//FREM.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0100101
//FSCALE.X FPm,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmnnn0100110
//FSGLMUL.X FPm,FPn |-|--CCS6|-|-----|-----| |1111_001_000_000_000-000mmmnnn0100111
//FSUB.X FPm,FPn |-|--CC46|-|-----|-----| |1111_001_000_000_000-000mmmnnn0101000
//FCMP.X FPm,FPn |-|--CC46|-|-----|-----| |1111_001_000_000_000-000mmmnnn0111000
//FSINCOS.X FPm,FPc:FPs |-|--CCSS|-|-----|-----| |1111_001_000_000_000-000mmmsss0110ccc
//FMOVECR.X #ccc,FPn |-|--CCSS|-|-----|-----| |1111_001_000_000_000-010111nnn0cccccc
//FMOVE.L FPn,<ea> |-|--CC46|-|-----|-----|D M+-WXZ |1111_001_000_mmm_rrr-011000nnn0000000
//FMOVE.S FPn,<ea> |-|--CC46|-|-----|-----|D M+-WXZ |1111_001_000_mmm_rrr-011001nnn0000000
//FMOVE.W FPn,<ea> |-|--CC46|-|-----|-----|D M+-WXZ |1111_001_000_mmm_rrr-011100nnn0000000
//FMOVE.B FPn,<ea> |-|--CC46|-|-----|-----|D M+-WXZ |1111_001_000_mmm_rrr-011110nnn0000000
//FMOVE.L FPIAR,<ea> |-|--CC46|-|-----|-----|DAM+-WXZ |1111_001_000_mmm_rrr-1010010000000000
//FMOVEM.L FPIAR,<ea> |-|--CC46|-|-----|-----|DAM+-WXZ |1111_001_000_mmm_rrr-1010010000000000
//FMOVE.L FPSR,<ea> |-|--CC46|-|-----|-----|D M+-WXZ |1111_001_000_mmm_rrr-1010100000000000
//FMOVEM.L FPSR,<ea> |-|--CC46|-|-----|-----|D M+-WXZ |1111_001_000_mmm_rrr-1010100000000000
//FMOVE.L FPCR,<ea> |-|--CC46|-|-----|-----|D M+-WXZ |1111_001_000_mmm_rrr-1011000000000000
//FMOVEM.L FPCR,<ea> |-|--CC46|-|-----|-----|D M+-WXZ |1111_001_000_mmm_rrr-1011000000000000
//FTST.L <ea> |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-0100000000111010
//FMOVE.L <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0000000
//FINT.L <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0000001
//FSINH.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0000010
//FINTRZ.L <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0000011
//FSQRT.L <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0000100
//FLOGNP1.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0000110
//FETOXM1.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0001000
//FTANH.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0001001
//FATAN.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0001010
//FASIN.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0001100
//FATANH.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0001101
//FSIN.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0001110
//FTAN.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0001111
//FETOX.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0010000
//FTWOTOX.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0010001
//FTENTOX.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0010010
//FLOGN.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0010100
//FLOG10.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0010101
//FLOG2.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0010110
//FABS.L <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0011000
//FCOSH.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0011001
//FNEG.L <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0011010
//FACOS.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0011100
//FCOS.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0011101
//FGETEXP.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0011110
//FGETMAN.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0011111
//FDIV.L <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0100000
//FMOD.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0100001
//FADD.L <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0100010
//FMUL.L <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0100011
//FSGLDIV.L <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0100100
//FREM.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0100101
//FSCALE.L <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0100110
//FSGLMUL.L <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0100111
//FSUB.L <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0101000
//FCMP.L <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000nnn0111000
//FSINCOS.L <ea>,FPc:FPs |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010000sss0110ccc
//FTST.S <ea> |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-0100010000111010
//FMOVE.S <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0000000
//FINT.S <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0000001
//FSINH.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0000010
//FINTRZ.S <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0000011
//FSQRT.S <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0000100
//FLOGNP1.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0000110
//FETOXM1.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0001000
//FTANH.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0001001
//FATAN.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0001010
//FASIN.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0001100
//FATANH.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0001101
//FSIN.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0001110
//FTAN.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0001111
//FETOX.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0010000
//FTWOTOX.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0010001
//FTENTOX.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0010010
//FLOGN.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0010100
//FLOG10.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0010101
//FLOG2.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0010110
//FABS.S <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0011000
//FCOSH.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0011001
//FNEG.S <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0011010
//FACOS.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0011100
//FCOS.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0011101
//FGETEXP.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0011110
//FGETMAN.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0011111
//FDIV.S <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0100000
//FMOD.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0100001
//FADD.S <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0100010
//FMUL.S <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0100011
//FSGLDIV.S <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0100100
//FREM.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0100101
//FSCALE.S <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0100110
//FSGLMUL.S <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0100111
//FSUB.S <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0101000
//FCMP.S <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001nnn0111000
//FSINCOS.S <ea>,FPc:FPs |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010001sss0110ccc
//FTST.W <ea> |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-0101000000111010
//FMOVE.W <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0000000
//FINT.W <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0000001
//FSINH.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0000010
//FINTRZ.W <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0000011
//FSQRT.W <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0000100
//FLOGNP1.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0000110
//FETOXM1.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0001000
//FTANH.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0001001
//FATAN.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0001010
//FASIN.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0001100
//FATANH.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0001101
//FSIN.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0001110
//FTAN.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0001111
//FETOX.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0010000
//FTWOTOX.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0010001
//FTENTOX.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0010010
//FLOGN.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0010100
//FLOG10.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0010101
//FLOG2.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0010110
//FABS.W <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0011000
//FCOSH.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0011001
//FNEG.W <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0011010
//FACOS.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0011100
//FCOS.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0011101
//FGETEXP.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0011110
//FGETMAN.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0011111
//FDIV.W <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0100000
//FMOD.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0100001
//FADD.W <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0100010
//FMUL.W <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0100011
//FSGLDIV.W <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0100100
//FREM.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0100101
//FSCALE.W <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0100110
//FSGLMUL.W <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0100111
//FSUB.W <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0101000
//FCMP.W <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100nnn0111000
//FSINCOS.W <ea>,FPc:FPs |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010100sss0110ccc
//FTST.B <ea> |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-0101100000111010
//FMOVE.B <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0000000
//FINT.B <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0000001
//FSINH.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0000010
//FINTRZ.B <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0000011
//FSQRT.B <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0000100
//FLOGNP1.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0000110
//FETOXM1.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0001000
//FTANH.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0001001
//FATAN.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0001010
//FASIN.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0001100
//FATANH.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0001101
//FSIN.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0001110
//FTAN.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0001111
//FETOX.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0010000
//FTWOTOX.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0010001
//FTENTOX.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0010010
//FLOGN.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0010100
//FLOG10.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0010101
//FLOG2.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0010110
//FABS.B <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0011000
//FCOSH.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0011001
//FNEG.B <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0011010
//FACOS.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0011100
//FCOS.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0011101
//FGETEXP.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0011110
//FGETMAN.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0011111
//FDIV.B <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0100000
//FMOD.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0100001
//FADD.B <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0100010
//FMUL.B <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0100011
//FSGLDIV.B <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0100100
//FREM.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0100101
//FSCALE.B <ea>,FPn |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0100110
//FSGLMUL.B <ea>,FPn |-|--CCS6|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0100111
//FSUB.B <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0101000
//FCMP.B <ea>,FPn |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110nnn0111000
//FSINCOS.B <ea>,FPc:FPs |-|--CCSS|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-010110sss0110ccc
//FMOVE.L <ea>,FPIAR |-|--CC46|-|-----|-----|DAM+-WXZPI|1111_001_000_mmm_rrr-1000010000000000
//FMOVEM.L <ea>,FPIAR |-|--CC46|-|-----|-----|DAM+-WXZPI|1111_001_000_mmm_rrr-1000010000000000
//FMOVE.L <ea>,FPSR |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-1000100000000000
//FMOVEM.L <ea>,FPSR |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-1000100000000000
//FMOVE.L <ea>,FPCR |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-1001000000000000
//FMOVEM.L <ea>,FPCR |-|--CC46|-|-----|-----|D M+-WXZPI|1111_001_000_mmm_rrr-1001000000000000
//FMOVE.X FPn,<ea> |-|--CC46|-|-----|-----| M+-WXZ |1111_001_000_mmm_rrr-011010nnn0000000
//FMOVE.P FPn,<ea>{#k} |-|--CCSS|-|-----|-----| M+-WXZ |1111_001_000_mmm_rrr-011011nnnkkkkkkk
//FMOVE.D FPn,<ea> |-|--CC46|-|-----|-----| M+-WXZ |1111_001_000_mmm_rrr-011101nnn0000000
//FMOVE.P FPn,<ea>{Dk} |-|--CCSS|-|-----|-----| M+-WXZ |1111_001_000_mmm_rrr-011111nnnkkk0000
//FMOVEM.L FPSR/FPIAR,<ea> |-|--CC46|-|-----|-----| M+-WXZ |1111_001_000_mmm_rrr-1010110000000000
//FMOVEM.L FPCR/FPIAR,<ea> |-|--CC46|-|-----|-----| M+-WXZ |1111_001_000_mmm_rrr-1011010000000000
//FMOVEM.L FPCR/FPSR,<ea> |-|--CC46|-|-----|-----| M+-WXZ |1111_001_000_mmm_rrr-1011100000000000
//FMOVEM.L FPCR/FPSR/FPIAR,<ea> |-|--CC46|-|-----|-----| M+-WXZ |1111_001_000_mmm_rrr-1011110000000000
//FMOVEM.X #<data>,<ea> |-|--CC46|-|-----|-----| M WXZ |1111_001_000_mmm_rrr-11110000dddddddd
//FMOVEM.X <list>,<ea> |-|--CC46|-|-----|-----| M WXZ |1111_001_000_mmm_rrr-11110000llllllll
//FMOVEM.X Dl,<ea> |-|--CC4S|-|-----|-----| M WXZ |1111_001_000_mmm_rrr-111110000lll0000
//FMOVEM.L <ea>,FPSR/FPIAR |-|--CC46|-|-----|-----| M+-WXZP |1111_001_000_mmm_rrr-1000110000000000
//FMOVEM.L <ea>,FPCR/FPIAR |-|--CC46|-|-----|-----| M+-WXZP |1111_001_000_mmm_rrr-1001010000000000
//FMOVEM.L <ea>,FPCR/FPSR |-|--CC46|-|-----|-----| M+-WXZP |1111_001_000_mmm_rrr-1001100000000000
//FMOVEM.L <ea>,FPCR/FPSR/FPIAR |-|--CC46|-|-----|-----| M+-WXZP |1111_001_000_mmm_rrr-1001110000000000
//FMOVEM.X <ea>,#<data> |-|--CC46|-|-----|-----| M+ WXZP |1111_001_000_mmm_rrr-11010000dddddddd
//FMOVEM.X <ea>,<list> |-|--CC46|-|-----|-----| M+ WXZP |1111_001_000_mmm_rrr-11010000llllllll
//FMOVEM.X <ea>,Dl |-|--CC4S|-|-----|-----| M+ WXZP |1111_001_000_mmm_rrr-110110000lll0000
//FTST.X <ea> |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-0100100000111010
//FMOVE.X <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0000000
//FINT.X <ea>,FPn |-|--CCS6|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0000001
//FSINH.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0000010
//FINTRZ.X <ea>,FPn |-|--CCS6|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0000011
//FSQRT.X <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0000100
//FLOGNP1.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0000110
//FETOXM1.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0001000
//FTANH.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0001001
//FATAN.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0001010
//FASIN.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0001100
//FATANH.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0001101
//FSIN.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0001110
//FTAN.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0001111
//FETOX.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0010000
//FTWOTOX.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0010001
//FTENTOX.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0010010
//FLOGN.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0010100
//FLOG10.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0010101
//FLOG2.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0010110
//FABS.X <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0011000
//FCOSH.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0011001
//FNEG.X <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0011010
//FACOS.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0011100
//FCOS.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0011101
//FGETEXP.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0011110
//FGETMAN.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0011111
//FDIV.X <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0100000
//FMOD.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0100001
//FADD.X <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0100010
//FMUL.X <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0100011
//FSGLDIV.X <ea>,FPn |-|--CCS6|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0100100
//FREM.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0100101
//FSCALE.X <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0100110
//FSGLMUL.X <ea>,FPn |-|--CCS6|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0100111
//FSUB.X <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0101000
//FCMP.X <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010nnn0111000
//FSINCOS.X <ea>,FPc:FPs |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010010sss0110ccc
//FTST.P <ea> |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-0100110000111010
//FMOVE.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0000000
//FINT.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0000001
//FSINH.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0000010
//FINTRZ.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0000011
//FSQRT.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0000100
//FLOGNP1.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0000110
//FETOXM1.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0001000
//FTANH.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0001001
//FATAN.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0001010
//FASIN.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0001100
//FATANH.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0001101
//FSIN.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0001110
//FTAN.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0001111
//FETOX.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0010000
//FTWOTOX.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0010001
//FTENTOX.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0010010
//FLOGN.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0010100
//FLOG10.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0010101
//FLOG2.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0010110
//FABS.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0011000
//FCOSH.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0011001
//FNEG.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0011010
//FACOS.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0011100
//FCOS.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0011101
//FGETEXP.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0011110
//FGETMAN.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0011111
//FDIV.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0100000
//FMOD.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0100001
//FADD.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0100010
//FMUL.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0100011
//FSGLDIV.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0100100
//FREM.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0100101
//FSCALE.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0100110
//FSGLMUL.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0100111
//FSUB.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0101000
//FCMP.P <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011nnn0111000
//FSINCOS.P <ea>,FPc:FPs |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010011sss0110ccc
//FTST.D <ea> |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-0101010000111010
//FMOVE.D <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0000000
//FINT.D <ea>,FPn |-|--CCS6|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0000001
//FSINH.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0000010
//FINTRZ.D <ea>,FPn |-|--CCS6|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0000011
//FSQRT.D <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0000100
//FLOGNP1.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0000110
//FETOXM1.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0001000
//FTANH.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0001001
//FATAN.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0001010
//FASIN.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0001100
//FATANH.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0001101
//FSIN.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0001110
//FTAN.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0001111
//FETOX.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0010000
//FTWOTOX.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0010001
//FTENTOX.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0010010
//FLOGN.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0010100
//FLOG10.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0010101
//FLOG2.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0010110
//FABS.D <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0011000
//FCOSH.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0011001
//FNEG.D <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0011010
//FACOS.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0011100
//FCOS.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0011101
//FGETEXP.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0011110
//FGETMAN.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0011111
//FDIV.D <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0100000
//FMOD.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0100001
//FADD.D <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0100010
//FMUL.D <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0100011
//FSGLDIV.D <ea>,FPn |-|--CCS6|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0100100
//FREM.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0100101
//FSCALE.D <ea>,FPn |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0100110
//FSGLMUL.D <ea>,FPn |-|--CCS6|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0100111
//FSUB.D <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0101000
//FCMP.D <ea>,FPn |-|--CC46|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101nnn0111000
//FSINCOS.D <ea>,FPc:FPs |-|--CCSS|-|-----|-----| M+-WXZPI|1111_001_000_mmm_rrr-010101sss0110ccc
//FMOVEM.X #<data>,-(Ar) |-|--CC46|-|-----|-----| - |1111_001_000_100_rrr-11100000dddddddd
//FMOVEM.X <list>,-(Ar) |-|--CC46|-|-----|-----| - |1111_001_000_100_rrr-11100000llllllll
//FMOVEM.X Dl,-(Ar) |-|--CC4S|-|-----|-----| - |1111_001_000_100_rrr-111010000lll0000
//FMOVEM.L #<data>,#<data>,FPSR/FPIAR |-|--CC4S|-|-----|-----| I|1111_001_000_111_100-1000110000000000-{data}
//FMOVEM.L #<data>,#<data>,FPCR/FPIAR |-|--CC4S|-|-----|-----| I|1111_001_000_111_100-1001010000000000-{data}
//FMOVEM.L #<data>,#<data>,FPCR/FPSR |-|--CC4S|-|-----|-----| I|1111_001_000_111_100-1001100000000000-{data}
//FMOVEM.L #<data>,#<data>,#<data>,FPCR/FPSR/FPIAR|-|--CC4S|-|-----|-----| I|1111_001_000_111_100-1001110000000000-{data}
@SuppressWarnings ("fallthrough") public static void irpFgen () throws M68kException {
fgen: {
if ((7 & XEiJ.currentCopro0) == 0) {
irpFline ();
break fgen;
}
XEiJ.mpuCycleCount += 16;
int ea = XEiJ.regOC & 63;
int w;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
int m = w >> 10 & 7;
int n = w >> 7 & 7;
int c = w & 0x7f;
XEiJ.fpuBox.epbSetRoundingPrec (XEiJ.fpuBox.epbFpcr >> 6 & 3); //丸め桁数
XEiJ.fpuBox.epbSetRoundingMode (XEiJ.fpuBox.epbFpcr >> 4 & 3); //丸めモード
int a = 0; //実効アドレス
switch (w >> 13) {
case 0b010: //$4xxx-$5xxx: Fop.* <ea>,FPn
XEiJ.fpuBox.epbFpsr &= 0x00ff00ff;
XEiJ.fpuBox.epbFpiar = XEiJ.regPC0; //FPIARはFMOVEM/FMOVE FPcr/FSAVE/FRESTORE以外の命令で例外が発生しなくても更新される
switch (m) {
case 0b000: //$40xx-$43xx: Fop.L <ea>,FPn
XEiJ.fpuFPn[m = EFPBox.EPB_SRC_TMP].seti (ea < XEiJ.EA_AR ? XEiJ.regRn[ea] : XEiJ.busRls (a = efaAnyLong (ea)));
break;
case 0b001: //$44xx-$47xx: Fop.S <ea>,FPn
XEiJ.fpuFPn[m = EFPBox.EPB_SRC_TMP].setf0 (ea < XEiJ.EA_AR ? XEiJ.regRn[ea] : XEiJ.busRls (a = efaAnyLong (ea)));
break;
case 0b010: //$48xx-$4Bxx: Fop.X <ea>,FPn
{
a = efaAnyExtd (ea);
int i = XEiJ.busRls (a);
long l = (long) XEiJ.busRls (a + 4) << 32 | 0xffffffffL & XEiJ.busRls (a + 8);
if (XEiJ.fpuBox.epbIsTriple ()) { //三倍精度
XEiJ.fpuFPn[m = EFPBox.EPB_SRC_TMP].sety012 (i, l);
} else { //拡張精度
XEiJ.fpuFPn[m = EFPBox.EPB_SRC_TMP].setx012 (i, l);
}
}
break;
case 0b011: //$4Cxx-$4Fxx: Fop.P <ea>,FPn
{
a = efaAnyExtd (ea);
XEiJ.fpuFPn[m = EFPBox.EPB_SRC_TMP].setp012 (XEiJ.busRls (a), (long) XEiJ.busRls (a + 4) << 32 | 0xffffffffL & XEiJ.busRls (a + 8));
}
break;
case 0b100: //$50xx-$53xx: Fop.W <ea>,FPn
XEiJ.fpuFPn[m = EFPBox.EPB_SRC_TMP].seti (ea < XEiJ.EA_AR ? (short) XEiJ.regRn[ea] : XEiJ.busRws (a = efaAnyWord (ea)));
break;
case 0b101: //$54xx-$57xx: Fop.D <ea>,FPn
{
a = efaAnyQuad (ea);
XEiJ.fpuFPn[m = EFPBox.EPB_SRC_TMP].setd01 ((long) XEiJ.busRls (a) << 32 | 0xffffffffL & XEiJ.busRls (a + 4));
}
break;
case 0b110: //$58xx-$5Bxx: Fop.B <ea>,FPn
XEiJ.fpuFPn[m = EFPBox.EPB_SRC_TMP].seti (ea < XEiJ.EA_AR ? (byte) XEiJ.regRn[ea] : XEiJ.busRbs (a = efaAnyByte (ea)));
break;
case 0b111: //$5Cxx-$5Fxx: FMOVECR.X #ccc,FPn
default:
if (0x40 <= c) {
//マニュアルにはFMOVECRの命令フォーマットのROMオフセットが7bitあるように書かれているが実際は6bit
//MC68882で0x40以上を指定すると命令実行前例外のF-Line Emulator(レスポンス$1C0B)が返る
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
if (false) {
m = EFPBox.EPB_CONST_START + c; //定数
c = 0; //FMOVE
} else {
//FMOVECR
XEiJ.fpuBox.epbFmovecr (XEiJ.fpuFPn[n], c);
//FPSRのAEXCを設定する
XEiJ.fpuBox.epbFpsr |= XEiJ.FPU_FPSR_EXC_TO_AEXC[XEiJ.fpuBox.epbFpsr >> 8 & 255];
//浮動小数点命令実行後例外 floating-point post-instruction exception
if (irpFPPostInstruction (a)) {
break fgen;
}
break fgen;
}
}
//浮動小数点命令実行前例外 floating-point pre-instruction exception
if (irpFPPreInstruction ()) {
break fgen;
}
//Fop.X <ea>,FPn → Fop.X FP[EFPBox.EPB_SRC_TMP],FPn
//FMOVECR.X #ccc,FPn → FMOVE.X FPc,FPn
//fallthrough
case 0b000: //$0xxx-$1xxx: Fop.X FPm,FPn
if (w >> 13 == 0) {
XEiJ.fpuBox.epbFpsr &= 0x00ff00ff;
}
//Fop.* <ea>,FPnのときFPIARは設定済み
XEiJ.fpuBox.epbFpiar = XEiJ.regPC0; //FPIARはFMOVEM/FMOVE FPcr/FSAVE/FRESTORE以外の命令で例外が発生しなくても更新される
switch (c) {
case 0b000_0000: //$xx00: FMOVE.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL 常にクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].sete (XEiJ.fpuFPn[m]).finish ();
break;
case 0b000_0001: //$xx01: FINT.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL 常にクリア
// 正規化数の最大値は整数なので丸めても大きくなることはない
// UNFL 常にクリア
// 結果は整数なので非正規化数にはならない
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
// FINTはsingleとdoubleの丸め処理を行わない
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_EXD);
XEiJ.fpuFPn[n].round (XEiJ.fpuFPn[m], XEiJ.fpuBox.epbRoundingMode);
break;
case 0b000_0010: //$xx02: FSINH.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].sinh (XEiJ.fpuFPn[m]);
break;
case 0b000_0011: //$xx03: FINTRZ.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL 常にクリア
// UNFL 常にクリア
// 結果は整数なので非正規化数にはならない
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
// FINTRZはsingleとdoubleの丸め処理を行わない
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_EXD);
XEiJ.fpuFPn[n].trunc (XEiJ.fpuFPn[m]);
break;
case 0b000_0100: //$xx04: FSQRT.* *m,FPn
case 0b000_0101: //$xx05: FSQRT.* *m,FPn (MC68882)
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が-0を除く負数のときセット、それ以外はクリア
// OVFL 常にクリア
// 1よりも大きい数は小さくなるので溢れることはない
// UNFL 常にクリア
// 非正規化数の平方根は正規化数なので結果が非正規化数になることはない
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].sqrt (XEiJ.fpuFPn[m]);
break;
case 0b000_0110: //$xx06: FLOGNP1.* *m,FPn
case 0b000_0111: //$xx07: FLOGNP1.* *m,FPn (MC68882)
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が-1よりも小さいときセット、それ以外はクリア
// OVFL 常にクリア
// log(1+0)=0,log(1+x)<=xなので結果が引数よりも大きくなることはない
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 引数が-1のときセット、それ以外はクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].log1p (XEiJ.fpuFPn[m]);
break;
case 0b000_1000: //$xx08: FETOXM1.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].expm1 (XEiJ.fpuFPn[m]);
break;
case 0b000_1001: //$xx09: FTANH.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL 常にクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].tanh (XEiJ.fpuFPn[m]);
break;
case 0b000_1010: //$xx0A: FATAN.* *m,FPn
case 0b000_1011: //$xx0B: FATAN.* *m,FPn (MC68882)
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL 常にクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].atan (XEiJ.fpuFPn[m]);
break;
case 0b000_1100: //$xx0C: FASIN.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数の絶対値が1よりも大きいときセット、それ以外はクリア
// OVFL 常にクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].asin (XEiJ.fpuFPn[m]);
break;
case 0b000_1101: //$xx0D: FATANH.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数の絶対値が1よりも大きいときセット、それ以外はクリア
// OVFL 常にクリア
// 1のとき無限大なのだから1の近くでオーバーフローしそうに思えるがatanh(1-2^-80)≒28.07くらい
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 引数の絶対値が1のときセット、それ以外はクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].atanh (XEiJ.fpuFPn[m]);
break;
case 0b000_1110: //$xx0E: FSIN.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が無限大のときセット、それ以外はクリア
// OVFL 常にクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].sin (XEiJ.fpuFPn[m]);
break;
case 0b000_1111: //$xx0F: FTAN.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が無限大のときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// cos(x)=0を満たすxは正確に表現できないのだからsin(x)/cos(x)がゼロ除算になるのはおかしい
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].tan (XEiJ.fpuFPn[m]);
break;
case 0b001_0000: //$xx10: FETOX.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].exp (XEiJ.fpuFPn[m]);
break;
case 0b001_0001: //$xx11: FTWOTOX.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].exp2 (XEiJ.fpuFPn[m]);
break;
case 0b001_0010: //$xx12: FTENTOX.* *m,FPn
case 0b001_0011: //$xx13: FTENTOX.* *m,FPn (MC68882)
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].exp10 (XEiJ.fpuFPn[m]);
break;
case 0b001_0100: //$xx14: FLOGN.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が0よりも小さいときセット、それ以外はクリア
// OVFL 常にクリア
// log(1)=0,log(x)<=x-1なので結果が引数よりも大きくなることはない
// UNFL 常にクリア
// log(1+2^-80)≒2^-80
// DZ 引数がゼロのときセット、それ以外はクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].log (XEiJ.fpuFPn[m]);
break;
case 0b001_0101: //$xx15: FLOG10.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が0よりも小さいときセット、それ以外はクリア
// OVFL 常にクリア
// UNFL 常にクリア
// DZ 引数がゼロのときセット、それ以外はクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].log10 (XEiJ.fpuFPn[m]);
break;
case 0b001_0110: //$xx16: FLOG2.* *m,FPn
case 0b001_0111: //$xx17: FLOG2.* *m,FPn (MC68882)
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が0よりも小さいときセット、それ以外はクリア
// OVFL 常にクリア
// UNFL 常にクリア
// DZ 引数がゼロのときセット、それ以外はクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].log2 (XEiJ.fpuFPn[m]);
break;
case 0b001_1000: //$xx18: FABS.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL 常にクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 常にクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].abs (XEiJ.fpuFPn[m]);
break;
case 0b001_1001: //$xx19: FCOSH.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 常にクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].cosh (XEiJ.fpuFPn[m]);
break;
case 0b001_1010: //$xx1A: FNEG.* *m,FPn
case 0b001_1011: //$xx1B: FNEG.* *m,FPn (MC68882)
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL 常にクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 常にクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].neg (XEiJ.fpuFPn[m]);
break;
case 0b001_1100: //$xx1C: FACOS.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数の絶対値が1よりも大きいときセット、それ以外はクリア
// OVFL 常にクリア
// UNFL 常にクリア
// acos(1-ulp(1))はulp(1)よりも大きい
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// おそらくセットされないのはacos(1)=0だけ
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].acos (XEiJ.fpuFPn[m]);
break;
case 0b001_1101: //$xx1D: FCOS.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が無限大のときセット、それ以外はクリア
// OVFL 常にクリア
// UNFL 常にクリア
// cos(x)=0を満たすxは正確に表現できず、cos(pi/2)とcos(3*pi/2)が正規化数になってしまう
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].cos (XEiJ.fpuFPn[m]);
break;
case 0b001_1110: //$xx1E: FGETEXP.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が無限大のときセット、それ以外はクリア
// OVFL 常にクリア
// UNFL 常にクリア
// DZ 常にクリア
// INEX2 常にクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].getexp (XEiJ.fpuFPn[m]);
break;
case 0b001_1111: //$xx1F: FGETMAN.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が無限大のときセット、それ以外はクリア
// OVFL 常にクリア
// UNFL 常にクリア
// DZ 常にクリア
// INEX2 常にクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].getman (XEiJ.fpuFPn[m]);
break;
case 0b010_0000: //$xx20: FDIV.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が両方ゼロまたは両方無限大のときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 被除数がゼロ、無限大、NaN以外で除数がゼロのときセット、それ以外はクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].div (XEiJ.fpuFPn[m]);
break;
case 0b010_0001: //$xx21: FMOD.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 除数がゼロまたは被除数が無限大のときセット、それ以外はクリア
// OVFL 常にクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// 除数がゼロのとき結果は無限大ではなくNaNでありゼロ除算にはならない
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
// FPSRのquotient byteに符号付き商の下位7bitが入る
XEiJ.fpuFPn[n].rem (XEiJ.fpuFPn[m]);
break;
case 0b010_0010: //$xx22: FADD.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が両方無限大で符号が異なるときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].add (XEiJ.fpuFPn[m]);
break;
case 0b010_0011: //$xx23: FMUL.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数の一方がゼロで他方が無限大のときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].mul (XEiJ.fpuFPn[m]);
break;
case 0b010_0100: //$xx24: FSGLDIV.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が両方ゼロまたは両方無限大のときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 被除数がゼロ、無限大、NaN以外で除数がゼロのときセット、それ以外はクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_XSG);
XEiJ.fpuFPn[n].div (XEiJ.fpuFPn[m]);
break;
case 0b010_0101: //$xx25: FREM.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 除数がゼロまたは被除数が無限大のときセット、それ以外はクリア
// OVFL 常にクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// 除数がゼロのとき結果は無限大ではなくNaNでありゼロ除算にはならない
// INEX2 結果に誤差があるときセット、それ以外はクリア
// マニュアルにClearedと書いてあるのは間違い
// 除数が無限大で被除数をそのまま返す場合でもサイズが減ればアンダーフローや不正確な結果になることはマニュアルにも書かれている
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
// FPSRのquotient byteに符号付き商の下位7bitが入る
XEiJ.fpuFPn[n].ieeerem (XEiJ.fpuFPn[m]);
break;
case 0b010_0110: //$xx26: FSCALE.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が無限大のときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 常にクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
//! 本来はソースが整数のとき浮動小数点数を経由しないが、これは経由してしまっている。結果は同じだが効率が悪い
XEiJ.fpuFPn[n].scale (XEiJ.fpuFPn[m]);
break;
case 0b010_0111: //$xx27: FSGLMUL.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数の一方がゼロで他方が無限大のときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
{
//引数を24bitに切り捨てるときX2をセットしない
int sr = XEiJ.fpuBox.epbFpsr;
XEiJ.fpuFPn[EFPBox.EPB_SRC_TMP].roundmanf (XEiJ.fpuFPn[m], EFPBox.EPB_MODE_RZ);
XEiJ.fpuFPn[EFPBox.EPB_DST_TMP].roundmanf (XEiJ.fpuFPn[n], EFPBox.EPB_MODE_RZ);
XEiJ.fpuBox.epbFpsr = sr;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_XSG);
XEiJ.fpuFPn[n].mul (XEiJ.fpuFPn[EFPBox.EPB_DST_TMP], XEiJ.fpuFPn[EFPBox.EPB_SRC_TMP]);
break;
case 0b010_1000: //$xx28: FSUB.* *m,FPn
case 0b010_1001: //$xx29: FSUB.* *m,FPn (MC68882)
case 0b010_1010: //$xx2A: FSUB.* *m,FPn (MC68882)
case 0b010_1011: //$xx2B: FSUB.* *m,FPn (MC68882)
case 0b010_1100: //$xx2C: FSUB.* *m,FPn (MC68882)
case 0b010_1101: //$xx2D: FSUB.* *m,FPn (MC68882)
case 0b010_1110: //$xx2E: FSUB.* *m,FPn (MC68882)
case 0b010_1111: //$xx2F: FSUB.* *m,FPn (MC68882)
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が両方無限大で符号が同じときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuFPn[n].sub (XEiJ.fpuFPn[m]);
break;
case 0b011_0000: //$xx30: FSINCOS.* *m,FP0:FPn (c=0,s=n)
case 0b011_0001: //$xx31: FSINCOS.* *m,FP1:FPn (c=1,s=n)
case 0b011_0010: //$xx32: FSINCOS.* *m,FP2:FPn (c=2,s=n)
case 0b011_0011: //$xx33: FSINCOS.* *m,FP3:FPn (c=3,s=n)
case 0b011_0100: //$xx34: FSINCOS.* *m,FP4:FPn (c=4,s=n)
case 0b011_0101: //$xx35: FSINCOS.* *m,FP5:FPn (c=5,s=n)
case 0b011_0110: //$xx36: FSINCOS.* *m,FP6:FPn (c=6,s=n)
case 0b011_0111: //$xx37: FSINCOS.* *m,FP7:FPn (c=7,s=n)
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が無限大のときセット、それ以外はクリア
// OVFL 常にクリア
// UNFL sin(x)の結果が非正規化数のときセット、それ以外はクリア
// cos(x)の結果は非正規化数にならない
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
c &= 7;
//m==EFPBox.EPB_SRC_TMP||m==n||m==cの場合があることに注意する
XEiJ.fpuFPn[EFPBox.EPB_SRC_TMP].sete (XEiJ.fpuFPn[m]);
XEiJ.fpuFPn[c].cos (XEiJ.fpuFPn[EFPBox.EPB_SRC_TMP]);
XEiJ.fpuFPn[n].sin (XEiJ.fpuFPn[EFPBox.EPB_SRC_TMP]);
break;
case 0b011_1000: //$xx38: FCMP.* *m,FPn
case 0b011_1001: //$xx39: FCMP.* *m,FPn (MC68882)
case 0b011_1100: //$xx3C: FCMP.* *m,FPn (MC68882) コマンドワードの不連続箇所に注意
case 0b011_1101: //$xx3D: FCMP.* *m,FPn (MC68882)
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL 常にクリア
// UNFL 常にクリア
// DZ 常にクリア
// INEX2 常にクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
// FCMPはinfinityを常にクリアする
// efp.compareTo(x,y)を使う
// efp.compareTo(x,y)はefp.sub(x,y)よりも速い
// efp.sub(x,y)はINEX2をセットしてしまう
// efp.compareTo(x,y)は-0<+0だがFCMPは-0==+0なのでこれだけ調節する
{
int xf = XEiJ.fpuFPn[n].flg;
int yf = XEiJ.fpuFPn[m].flg;
if ((xf | yf) << 3 < 0) { //どちらかがNaN
//XEiJ.fpuFPn[EFPBox.EPB_DST_TMP].setnan ();
XEiJ.fpuFPn[EFPBox.EPB_DST_TMP].flg = EFPBox.N;
} else {
int i = ((xf & yf) << 1 < 0 ? 0 : //両方±0
XEiJ.fpuFPn[n].compareTo (XEiJ.fpuFPn[m])); //-Inf==-Inf<-x<-0<+0<+x<+Inf==+Inf<NaN==NaN
if (i == 0) {
if (xf < 0) {
//XEiJ.fpuFPn[EFPBox.EPB_DST_TMP].negset0 ();
XEiJ.fpuFPn[EFPBox.EPB_DST_TMP].flg = EFPBox.M | EFPBox.Z;
} else {
//XEiJ.fpuFPn[EFPBox.EPB_DST_TMP].set0 ();
XEiJ.fpuFPn[EFPBox.EPB_DST_TMP].flg = EFPBox.P | EFPBox.Z;
}
} else if (i < 0) {
XEiJ.fpuFPn[EFPBox.EPB_DST_TMP].negset1 ();
} else {
XEiJ.fpuFPn[EFPBox.EPB_DST_TMP].set1 ();
}
}
n = EFPBox.EPB_DST_TMP;
}
break;
case 0b011_1010: //$xx3A: FTST.* *m
case 0b011_1011: //$xx3B: FTST.* *m (MC68882)
case 0b011_1110: //$xx3E: FTST.* *m (MC68882) コマンドワードの不連続箇所に注意
case 0b011_1111: //$xx3F: FTST.* *m (MC68882)
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL 常にクリア
// UNFL 常にクリア
// DZ 常にクリア
// INEX2 常にクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
// ソースオペランドをダミーのデスティネーションオペランドにコピーしてテストする
// デスティネーションオペランドは変化しない
// デスティネーションオペランドにはFP0が指定される場合が多いがFP0である必要はない
XEiJ.fpuFPn[EFPBox.EPB_DST_TMP].sete (XEiJ.fpuFPn[m]);
n = EFPBox.EPB_DST_TMP;
break;
case 0b100_0000: //$xx40: FSMOVE.* *m,FPn
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL 常にクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_SGL);
XEiJ.fpuFPn[n].sete (XEiJ.fpuFPn[m]).finish ();
break;
case 0b100_0001: //$xx41: FSSQRT.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が-0を除く負数のときセット、それ以外はクリア
// OVFL 常にクリア
// UNFL 常にクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_SGL);
XEiJ.fpuFPn[n].sqrt (XEiJ.fpuFPn[m]);
break;
//case 0b100_0010: //$xx42:
//case 0b100_0011: //$xx43:
case 0b100_0100: //$xx44: FDMOVE.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL 常にクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_DBL);
XEiJ.fpuFPn[n].sete (XEiJ.fpuFPn[m]).finish ();
break;
case 0b100_0101: //$xx45: FDSQRT.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が-0を除く負数のときセット、それ以外はクリア
// OVFL 常にクリア
// UNFL 常にクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_DBL);
XEiJ.fpuFPn[n].sqrt (XEiJ.fpuFPn[m]);
break;
//case 0b100_0110: //$xx46:
//case 0b100_0111: //$xx47:
//case 0b100_1000: //$xx48:
//case 0b100_1001: //$xx49:
//case 0b100_1010: //$xx4A:
//case 0b100_1011: //$xx4B:
//case 0b100_1100: //$xx4C:
//case 0b100_1101: //$xx4D:
//case 0b100_1110: //$xx4E:
//case 0b100_1111: //$xx4F:
//case 0b101_0000: //$xx50:
//case 0b101_0001: //$xx51:
//case 0b101_0010: //$xx52:
//case 0b101_0011: //$xx53:
//case 0b101_0100: //$xx54:
//case 0b101_0101: //$xx55:
//case 0b101_0110: //$xx56:
//case 0b101_0111: //$xx57:
case 0b101_1000: //$xx58: FSABS.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL 常にクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 常にクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_SGL);
XEiJ.fpuFPn[n].abs (XEiJ.fpuFPn[m]);
break;
//case 0b101_1001: //$xx59:
case 0b101_1010: //$xx5A: FSNEG.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL 常にクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 常にクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_SGL);
XEiJ.fpuFPn[n].neg (XEiJ.fpuFPn[m]);
break;
//case 0b101_1011: //$xx5B:
case 0b101_1100: //$xx5C: FDABS.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL 常にクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 常にクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_DBL);
XEiJ.fpuFPn[n].abs (XEiJ.fpuFPn[m]);
break;
//case 0b101_1101: //$xx5D:
case 0b101_1110: //$xx5E: FDNEG.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 常にクリア
// OVFL 常にクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 常にクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_DBL);
XEiJ.fpuFPn[n].neg (XEiJ.fpuFPn[m]);
break;
//case 0b101_1111: //$xx5F:
case 0b110_0000: //$xx60: FSDIV.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が両方ゼロまたは両方無限大のときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 被除数がゼロ、無限大、NaN以外で除数がゼロのときセット、それ以外はクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_SGL);
XEiJ.fpuFPn[n].div (XEiJ.fpuFPn[m]);
break;
//case 0b110_0001: //$xx61:
case 0b110_0010: //$xx62: FSADD.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が両方無限大で符号が異なるときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_SGL);
XEiJ.fpuFPn[n].add (XEiJ.fpuFPn[m]);
break;
case 0b110_0011: //$xx63: FSMUL.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数の一方がゼロで他方が無限大のときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_SGL);
XEiJ.fpuFPn[n].mul (XEiJ.fpuFPn[m]);
break;
case 0b110_0100: //$xx64: FDDIV.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が両方ゼロまたは両方無限大のときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 被除数がゼロ、無限大、NaN以外で除数がゼロのときセット、それ以外はクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_DBL);
XEiJ.fpuFPn[n].div (XEiJ.fpuFPn[m]);
break;
//case 0b110_0101: //$xx65:
case 0b110_0110: //$xx66: FDADD.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が両方無限大で符号が異なるときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_DBL);
XEiJ.fpuFPn[n].add (XEiJ.fpuFPn[m]);
break;
case 0b110_0111: //$xx67: FDMUL.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数の一方がゼロで他方が無限大のときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_DBL);
XEiJ.fpuFPn[n].mul (XEiJ.fpuFPn[m]);
break;
case 0b110_1000: //$xx68: FSSUB.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が両方無限大で符号が同じときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_SGL);
XEiJ.fpuFPn[n].sub (XEiJ.fpuFPn[m]);
break;
//case 0b110_1001: //$xx69:
//case 0b110_1010: //$xx6A:
//case 0b110_1011: //$xx6B:
case 0b110_1100: //$xx6C: FDSUB.* *m,FPn
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR 引数が両方無限大で符号が同じときセット、それ以外はクリア
// OVFL オーバーフローしたときセット、それ以外はクリア
// UNFL 結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 引数がpackedで正確に変換できないときセット、それ以外はクリア
if (!XEiJ.fpuBox.epbIsFullSpec ()) {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
XEiJ.fpuBox.epbSetRoundingPrec (EFPBox.EPB_PREC_DBL);
XEiJ.fpuFPn[n].sub (XEiJ.fpuFPn[m]);
break;
//case 0b110_1101: //$xx6D:
//case 0b110_1110: //$xx6E:
//case 0b110_1111: //$xx6F:
case 0b111_0000: //$xx70: FLGAMMA *m,FPn
if (EFPBox.EPB_EXTRA_OPERATION) {
XEiJ.fpuFPn[n].lgamma (XEiJ.fpuFPn[m]);
break;
} else {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
case 0b111_0001: //$xx71: FTGAMMA *m,FPn
if (EFPBox.EPB_EXTRA_OPERATION) {
XEiJ.fpuFPn[n].tgamma (XEiJ.fpuFPn[m]);
break;
} else {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
//case 0b111_0010: //$xx72:
//case 0b111_0011: //$xx73:
//case 0b111_0100: //$xx74:
//case 0b111_0101: //$xx75:
//case 0b111_0110: //$xx76:
//case 0b111_0111: //$xx77:
//case 0b111_1000: //$xx78:
//case 0b111_1001: //$xx79:
//case 0b111_1010: //$xx7A:
//case 0b111_1011: //$xx7B:
//case 0b111_1100: //$xx7C:
//case 0b111_1101: //$xx7D:
//case 0b111_1110: //$xx7E:
//case 0b111_1111: //$xx7F:
default: //未定義
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
//FPSRのFPCCを設定する
XEiJ.fpuBox.epbFpsr |= XEiJ.fpuFPn[n].flg >>> 4;
//FPSRのAEXCを設定する
XEiJ.fpuBox.epbFpsr |= XEiJ.FPU_FPSR_EXC_TO_AEXC[XEiJ.fpuBox.epbFpsr >> 8 & 255];
//浮動小数点命令実行後例外 floating-point post-instruction exception
if (irpFPPostInstruction (a)) {
break fgen;
}
break fgen;
case 0b011: //$6xxx-$7xxx: FMOVE.* FPn,<ea>
// BSUN 常にクリア
// SNAN 引数がシグナリングNaNのときセット、それ以外はクリア
// OPERR byte,word,longで無限大または指定されたサイズに収まらないとき、packedでk-factorが17よりも大きいか指数部が3桁に収まらないときセット、それ以外はクリア
// OVFL packedではなくてオーバーフローしたときセット、それ以外はクリア
// UNFL packedではなくて結果が非正規化数のときセット、それ以外はクリア
// DZ 常にクリア
// INEX2 結果に誤差があるときセット、それ以外はクリア
// INEX1 常にクリア
XEiJ.fpuBox.epbFpsr &= 0xffff00ff; //FMOVE.* FPn,<ea>でFPSRのコンディションコードバイトは変化しない
XEiJ.fpuBox.epbFpiar = XEiJ.regPC0; //FPIARはFMOVEM/FMOVE FPcr/FSAVE/FRESTORE以外の命令で例外が発生しなくても更新される
switch (m) {
case 0b000: //$60xx-$63xx: FMOVE.L FPn,<ea>
if (ea < XEiJ.EA_AR) { //FMOVE.L FPn,Dr
XEiJ.regRn[ea] = XEiJ.fpuFPn[n].geti (XEiJ.fpuBox.epbRoundingMode);
} else { //FMOVE.L FPn,<mem>
XEiJ.busWl (a = efaMltLong (ea), XEiJ.fpuFPn[n].geti (XEiJ.fpuBox.epbRoundingMode));
}
break;
case 0b001: //$64xx-$67xx: FMOVE.S FPn,<ea>
if (ea < XEiJ.EA_AR) { //FMOVE.S FPn,Dr
XEiJ.regRn[ea] = XEiJ.fpuFPn[n].getf0 (XEiJ.fpuBox.epbRoundingMode);
} else { //FMOVE.S FPn,<mem>
XEiJ.busWl (a = efaMltLong (ea), XEiJ.fpuFPn[n].getf0 (XEiJ.fpuBox.epbRoundingMode));
}
break;
case 0b010: //$68xx-$6Bxx: FMOVE.X FPn,<ea>
{
byte[] b = new byte[12];
if (XEiJ.fpuBox.epbIsTriple ()) { //三倍精度
XEiJ.fpuFPn[n].gety012 (b, 0, XEiJ.fpuBox.epbRoundingMode);
} else { //拡張精度
XEiJ.fpuFPn[n].getx012 (b, 0, XEiJ.fpuBox.epbRoundingMode);
}
XEiJ.busWbb (a = efaMltExtd (ea), b, 0, 12);
}
break;
case 0b011: //$6Cxx-$6Fxx: FMOVE.P FPn,<ea>{#k}
{
byte[] b = new byte[12];
XEiJ.fpuFPn[n].getp012 (b, 0, w); //k-factor付き
XEiJ.busWbb (a = efaMltExtd (ea), b, 0, 12);
}
break;
case 0b100: //$70xx-$73xx: FMOVE.W FPn,<ea>
if (ea < XEiJ.EA_AR) { //FMOVE.W FPn,Dr
XEiJ.regRn[ea] = XEiJ.regRn[ea] & 0xffff0000 | (char) XEiJ.fpuFPn[n].gets (XEiJ.fpuBox.epbRoundingMode);
} else { //FMOVE.W FPn,<mem>
XEiJ.busWw (a = efaMltWord (ea), XEiJ.fpuFPn[n].gets (XEiJ.fpuBox.epbRoundingMode));
}
break;
case 0b101: //$74xx-$77xx: FMOVE.D FPn,<ea>
{
a = efaMltQuad (ea);
long d = XEiJ.fpuFPn[n].getd01 (XEiJ.fpuBox.epbRoundingMode);
XEiJ.busWl (a, (int) (d >>> 32));
XEiJ.busWl (a + 4, (int) d);
}
break;
case 0b110: //$78xx-$7Bxx: FMOVE.B FPn,<ea>
if (ea < XEiJ.EA_AR) { //FMOVE.B FPn,Dr
XEiJ.regRn[ea] = XEiJ.regRn[ea] & 0xffffff00 | XEiJ.fpuFPn[n].getb (XEiJ.fpuBox.epbRoundingMode) & 0xff;
} else { //FMOVE.B FPn,<mem>
XEiJ.busWb (a = efaMltByte (ea), XEiJ.fpuFPn[n].getb (XEiJ.fpuBox.epbRoundingMode));
}
break;
case 0b111: //$7Cxx-$7Fxx: FMOVE.P FPn,<ea>{Dl}
default:
{
byte[] b = new byte[12];
XEiJ.fpuFPn[n].getp012 (b, 0, XEiJ.regRn[w >> 4 & 7]); //k-factor付き
XEiJ.busWbb (a = efaMltExtd (ea), b, 0, 12);
}
}
//FPSRのAEXCを設定する
XEiJ.fpuBox.epbFpsr |= XEiJ.FPU_FPSR_EXC_TO_AEXC[XEiJ.fpuBox.epbFpsr >> 8 & 255];
//浮動小数点命令実行後例外 floating-point post-instruction exception
if (irpFPPostInstruction (a)) {
break fgen;
}
break fgen;
case 0b100: //$8xxx-$9xxx: FMOVEM.L <ea>,FPCR/FPSR/FPIAR
// FMOVEM命令は例外を発生させずFPCR/FPSR/FPIARも(デスティネーションに書かれたもの以外)変化しない
// 格納順序はFPCRが下位アドレス(連結したとき上位),FPIARが上位アドレス(連結したとき下位)
switch (m) {
case 0b000: //$8000: FMOVE.L <ea>,<>
// レジスタを1個も指定しないとFPIARが指定されたものとみなされる
case 0b001: //$8400: FMOVE.L <ea>,FPIAR
XEiJ.fpuBox.epbFpiar = ea < XEiJ.EA_MM ? XEiJ.regRn[ea] : XEiJ.busRls (a = efaAnyLong (ea)); //Ar可
break;
case 0b010: //$8800: FMOVE.L <ea>,FPSR
XEiJ.fpuBox.epbFpsr = (ea < XEiJ.EA_AR ? XEiJ.regRn[ea] : XEiJ.busRls (a = efaAnyLong (ea))) & EFPBox.EPB_FPSR_ALL; //Ar不可
//fmove.lでfpsrのEXCに書き込んだだけではAEXCは更新されない
//fmove.lでfpsrに0x0000ff00を書き込んですぐに読み出しても0x0000ff00のまま
break;
case 0b011: //$8C00: FMOVEM.L <ea>,FPSR/FPIAR
{
a = efaAnyQuad (ea);
XEiJ.fpuBox.epbFpsr = (XEiJ.busRls (a)) & EFPBox.EPB_FPSR_ALL;
XEiJ.fpuBox.epbFpiar = XEiJ.busRls (a + 4);
}
break;
case 0b100: //$9000: FMOVE.L <ea>,FPCR
XEiJ.fpuBox.epbFpcr = (ea < XEiJ.EA_AR ? XEiJ.regRn[ea] : XEiJ.busRls (a = efaAnyLong (ea))) & EFPBox.EPB_FPCR_ALL; //Ar不可
break;
case 0b101: //$9400: FMOVEM.L <ea>,FPCR/FPIAR
{
a = efaAnyQuad (ea);
XEiJ.fpuBox.epbFpcr = (XEiJ.busRls (a)) & EFPBox.EPB_FPCR_ALL;
XEiJ.fpuBox.epbFpiar = XEiJ.busRls (a + 4);
}
break;
case 0b110: //$9800: FMOVEM.L <ea>,FPCR/FPSR
{
a = efaAnyQuad (ea);
XEiJ.fpuBox.epbFpcr = (XEiJ.busRls (a)) & EFPBox.EPB_FPCR_ALL;
XEiJ.fpuBox.epbFpsr = (XEiJ.busRls (a + 4)) & EFPBox.EPB_FPSR_ALL;
}
break;
case 0b111: //$9C00: FMOVEM.L <ea>,FPCR/FPSR/FPIAR
default:
{
a = efaAnyExtd (ea);
XEiJ.fpuBox.epbFpcr = (XEiJ.busRls (a)) & EFPBox.EPB_FPCR_ALL;
XEiJ.fpuBox.epbFpsr = (XEiJ.busRls (a + 4)) & EFPBox.EPB_FPSR_ALL;
XEiJ.fpuBox.epbFpiar = XEiJ.busRls (a + 8);
}
break;
}
break fgen;
case 0b101: //$Axxx-$Bxxx: FMOVEM.L FPCR/FPSR/FPIAR,<ea>
// FMOVEM命令は例外を発生させずFPCR/FPSR/FPIARも(デスティネーションに書かれたもの以外)変化しない
switch (m) {
case 0b000: //$A000: FMOVE.L <>,<ea>
// レジスタを1個も指定しないとFPIARが指定されたものとみなされる
case 0b001: //$A400: FMOVE.L FPIAR,<ea>
if (ea < XEiJ.EA_MM) { //Ar可
XEiJ.regRn[ea] = XEiJ.fpuBox.epbFpiar;
} else {
XEiJ.busWl (a = efaMltLong (ea), XEiJ.fpuBox.epbFpiar);
}
break;
case 0b010: //$A800: FMOVE.L FPSR,<ea>
if (ea < XEiJ.EA_AR) { //Ar不可
XEiJ.regRn[ea] = XEiJ.fpuBox.epbFpsr;
} else {
XEiJ.busWl (a = efaMltLong (ea), XEiJ.fpuBox.epbFpsr);
}
break;
case 0b011: //$AC00: FMOVEM.L FPSR/FPIAR,<ea>
{
a = efaMltQuad (ea);
XEiJ.busWl (a, XEiJ.fpuBox.epbFpsr);
XEiJ.busWl (a + 4, XEiJ.fpuBox.epbFpiar);
}
break;
case 0b100: //$B000: FMOVE.L FPCR,<ea>
if (ea < XEiJ.EA_AR) { //Ar不可
XEiJ.regRn[ea] = XEiJ.fpuBox.epbFpcr;
} else {
XEiJ.busWl (a = efaMltLong (ea), XEiJ.fpuBox.epbFpcr);
}
break;
case 0b101: //$B400: FMOVEM.L FPCR/FPIAR,<ea>
{
a = efaMltQuad (ea);
XEiJ.busWl (a, XEiJ.fpuBox.epbFpcr);
XEiJ.busWl (a + 4, XEiJ.fpuBox.epbFpiar);
}
break;
case 0b110: //$B800: FMOVEM.L FPCR/FPSR,<ea>
{
a = efaMltQuad (ea);
XEiJ.busWl (a, XEiJ.fpuBox.epbFpcr);
XEiJ.busWl (a + 4, XEiJ.fpuBox.epbFpsr);
}
break;
case 0b111: //$BC00: FMOVEM.L FPCR/FPSR/FPIAR,<ea>
default:
{
a = efaMltExtd (ea);
XEiJ.busWl (a, XEiJ.fpuBox.epbFpcr);
XEiJ.busWl (a + 4, XEiJ.fpuBox.epbFpsr);
XEiJ.busWl (a + 8, XEiJ.fpuBox.epbFpiar);
}
break;
}
break fgen;
case 0b110: //$Cxxx-$Dxxx: FMOVEM.X <ea>,<list>
// FMOVEM命令は例外を発生させずFPCR/FPSR/FPIARも(デスティネーションに書かれたもの以外)変化しない
{
byte[] b = new byte[12];
int list = ((m & 2) == 0 ? w : XEiJ.regRn[w >> 4 & 7]) << 24;
if (ea >> 3 == XEiJ.MMM_MP) { //(Ar)+
int arr = XEiJ.regOC & 7 | 8;
a = XEiJ.regRn[arr];
for (n = 0; list != 0; n++, list <<= 1) {
if (list < 0) {
XEiJ.busRbb (a, b, 0, 12);
if (XEiJ.fpuBox.epbIsTriple ()) { //三倍精度
XEiJ.fpuFPn[n].sety012 (b, 0);
} else { //拡張精度
XEiJ.fpuFPn[n].setx012 (b, 0);
}
a += 12;
}
}
XEiJ.regRn[arr] = a;
} else { //(Ar)+以外
a = efaCntLong (ea);
for (n = 0; list != 0; n++, list <<= 1) {
if (list < 0) {
XEiJ.busRbb (a, b, 0, 12);
if (XEiJ.fpuBox.epbIsTriple ()) { //三倍精度
XEiJ.fpuFPn[n].sety012 (b, 0);
} else { //拡張精度
XEiJ.fpuFPn[n].setx012 (b, 0);
}
a += 12;
}
}
}
}
break fgen;
case 0b111: //$Exxx-$Fxxx: FMOVEM.X <list>,<ea>
// FMOVEM命令は例外を発生させずFPCR/FPSR/FPIARも(デスティネーションに書かれたもの以外)変化しない
{
byte[] b = new byte[12];
int list = ((m & 2) == 0 ? w : XEiJ.regRn[w >> 4 & 7]) << 24;
if (ea >> 3 == XEiJ.MMM_MN) { //-(Ar)
int arr = XEiJ.regOC & 7 | 8;
a = XEiJ.regRn[arr];
for (n = 7; list != 0; n--, list <<= 1) {
if (list < 0) {
a -= 12;
if (XEiJ.fpuBox.epbIsTriple ()) { //三倍精度
XEiJ.fpuFPn[n].gety012 (b, 0, XEiJ.fpuBox.epbRoundingMode);
} else { //拡張精度
XEiJ.fpuFPn[n].getx012 (b, 0, XEiJ.fpuBox.epbRoundingMode);
}
XEiJ.busWbb (a, b, 0, 12);
}
}
XEiJ.regRn[arr] = a;
} else { //-(Ar)以外
a = efaCltLong (ea);
for (n = 0; list != 0; n++, list <<= 1) {
if (list < 0) {
if (XEiJ.fpuBox.epbIsTriple ()) { //三倍精度
XEiJ.fpuFPn[n].gety012 (b, 0, XEiJ.fpuBox.epbRoundingMode);
} else { //拡張精度
XEiJ.fpuFPn[n].getx012 (b, 0, XEiJ.fpuBox.epbRoundingMode);
}
XEiJ.busWbb (a, b, 0, 12);
a += 12;
}
}
}
}
break fgen;
case 0b001: //$2xxx-$3xxx: 未定義
default: //未定義
XEiJ.fpuBox.epbFpiar = XEiJ.regPC0; //FPIARはFMOVEM/FMOVE FPcr/FSAVE/FRESTORE以外の命令で例外が発生しなくても更新される
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fgen;
}
} //fgen
} //irpFgen
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//FSF.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000000000
//FSEQ.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000000001
//FSOGT.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000000010
//FSOGE.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000000011
//FSOLT.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000000100
//FSOLE.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000000101
//FSOGL.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000000110
//FSOR.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000000111
//FSUN.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000001000
//FSUEQ.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000001001
//FSUGT.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000001010
//FSUGE.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000001011
//FSULT.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000001100
//FSULE.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000001101
//FSNE.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000001110
//FST.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000001111
//FSSF.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000010000
//FSSEQ.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000010001
//FSGT.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000010010
//FSGE.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000010011
//FSLT.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000010100
//FSLE.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000010101
//FSGL.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000010110
//FSGLE.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000010111
//FSNGLE.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000011000
//FSNGL.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000011001
//FSNLE.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000011010
//FSNLT.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000011011
//FSNGE.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000011100
//FSNGT.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000011101
//FSSNE.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000011110
//FSST.B <ea> |-|--CC4S|-|-----|-----|D M+-WXZ |1111_001_001_mmm_rrr-0000000000011111
//FDBF Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000000000-{offset}
//FDBRA Dr,<label> |A|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000000000-{offset} [FDBF Dr,<label>]
//FDBEQ Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000000001-{offset}
//FDBOGT Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000000010-{offset}
//FDBOGE Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000000011-{offset}
//FDBOLT Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000000100-{offset}
//FDBOLE Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000000101-{offset}
//FDBOGL Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000000110-{offset}
//FDBOR Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000000111-{offset}
//FDBUN Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000001000-{offset}
//FDBUEQ Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000001001-{offset}
//FDBUGT Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000001010-{offset}
//FDBUGE Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000001011-{offset}
//FDBULT Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000001100-{offset}
//FDBULE Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000001101-{offset}
//FDBNE Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000001110-{offset}
//FDBT Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000001111-{offset}
//FDBSF Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000010000-{offset}
//FDBSEQ Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000010001-{offset}
//FDBGT Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000010010-{offset}
//FDBGE Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000010011-{offset}
//FDBLT Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000010100-{offset}
//FDBLE Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000010101-{offset}
//FDBGL Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000010110-{offset}
//FDBGLE Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000010111-{offset}
//FDBNGLE Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000011000-{offset}
//FDBNGL Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000011001-{offset}
//FDBNLE Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000011010-{offset}
//FDBNLT Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000011011-{offset}
//FDBNGE Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000011100-{offset}
//FDBNGT Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000011101-{offset}
//FDBSNE Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000011110-{offset}
//FDBST Dr,<label> |-|--CC4S|-|-----|-----| |1111_001_001_001_rrr-0000000000011111-{offset}
//FTRAPF.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000000000-{data}
//FTRAPEQ.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000000001-{data}
//FTRAPOGT.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000000010-{data}
//FTRAPOGE.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000000011-{data}
//FTRAPOLT.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000000100-{data}
//FTRAPOLE.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000000101-{data}
//FTRAPOGL.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000000110-{data}
//FTRAPOR.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000000111-{data}
//FTRAPUN.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000001000-{data}
//FTRAPUEQ.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000001001-{data}
//FTRAPUGT.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000001010-{data}
//FTRAPUGE.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000001011-{data}
//FTRAPULT.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000001100-{data}
//FTRAPULE.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000001101-{data}
//FTRAPNE.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000001110-{data}
//FTRAPT.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000001111-{data}
//FTRAPSF.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000010000-{data}
//FTRAPSEQ.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000010001-{data}
//FTRAPGT.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000010010-{data}
//FTRAPGE.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000010011-{data}
//FTRAPLT.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000010100-{data}
//FTRAPLE.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000010101-{data}
//FTRAPGL.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000010110-{data}
//FTRAPGLE.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000010111-{data}
//FTRAPNGLE.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000011000-{data}
//FTRAPNGL.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000011001-{data}
//FTRAPNLE.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000011010-{data}
//FTRAPNLT.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000011011-{data}
//FTRAPNGE.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000011100-{data}
//FTRAPNGT.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000011101-{data}
//FTRAPSNE.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000011110-{data}
//FTRAPST.W #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_010-0000000000011111-{data}
//FTRAPF.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000000000-{data}
//FTRAPEQ.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000000001-{data}
//FTRAPOGT.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000000010-{data}
//FTRAPOGE.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000000011-{data}
//FTRAPOLT.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000000100-{data}
//FTRAPOLE.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000000101-{data}
//FTRAPOGL.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000000110-{data}
//FTRAPOR.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000000111-{data}
//FTRAPUN.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000001000-{data}
//FTRAPUEQ.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000001001-{data}
//FTRAPUGT.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000001010-{data}
//FTRAPUGE.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000001011-{data}
//FTRAPULT.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000001100-{data}
//FTRAPULE.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000001101-{data}
//FTRAPNE.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000001110-{data}
//FTRAPT.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000001111-{data}
//FTRAPSF.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000010000-{data}
//FTRAPSEQ.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000010001-{data}
//FTRAPGT.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000010010-{data}
//FTRAPGE.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000010011-{data}
//FTRAPLT.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000010100-{data}
//FTRAPLE.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000010101-{data}
//FTRAPGL.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000010110-{data}
//FTRAPGLE.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000010111-{data}
//FTRAPNGLE.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000011000-{data}
//FTRAPNGL.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000011001-{data}
//FTRAPNLE.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000011010-{data}
//FTRAPNLT.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000011011-{data}
//FTRAPNGE.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000011100-{data}
//FTRAPNGT.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000011101-{data}
//FTRAPSNE.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000011110-{data}
//FTRAPST.L #<data> |-|--CC4S|-|-----|-----| |1111_001_001_111_011-0000000000011111-{data}
//FTRAPF |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000000000
//FTRAPEQ |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000000001
//FTRAPOGT |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000000010
//FTRAPOGE |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000000011
//FTRAPOLT |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000000100
//FTRAPOLE |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000000101
//FTRAPOGL |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000000110
//FTRAPOR |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000000111
//FTRAPUN |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000001000
//FTRAPUEQ |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000001001
//FTRAPUGT |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000001010
//FTRAPUGE |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000001011
//FTRAPULT |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000001100
//FTRAPULE |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000001101
//FTRAPNE |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000001110
//FTRAPT |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000001111
//FTRAPSF |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000010000
//FTRAPSEQ |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000010001
//FTRAPGT |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000010010
//FTRAPGE |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000010011
//FTRAPLT |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000010100
//FTRAPLE |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000010101
//FTRAPGL |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000010110
//FTRAPGLE |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000010111
//FTRAPNGLE |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000011000
//FTRAPNGL |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000011001
//FTRAPNLE |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000011010
//FTRAPNLT |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000011011
//FTRAPNGE |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000011100
//FTRAPNGT |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000011101
//FTRAPSNE |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000011110
//FTRAPST |-|--CC4S|-|-----|-----| |1111_001_001_111_100-0000000000011111
public static void irpFscc () throws M68kException {
fscc: {
if ((7 & XEiJ.currentCopro0) == 0) {
irpFline ();
break fscc;
}
XEiJ.fpuBox.epbFpiar = XEiJ.regPC0; //FPIARはFMOVEM/FMOVE FPcr/FSAVE/FRESTORE以外の命令で例外が発生しなくても更新される
int w;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
if ((w & 0b010000) != 0 && (XEiJ.fpuBox.epbFpsr & XEiJ.FPU_FPSR_NAN) != 0) { //IEEEノンアウェアテストでNANがセットされているとき
XEiJ.fpuBox.epbFpsr |= XEiJ.FPU_FPSR_EXC_BSUN; //BSUNをセット
XEiJ.fpuBox.epbFpsr |= XEiJ.FPU_FPSR_EXC_TO_AEXC[XEiJ.fpuBox.epbFpsr >> 8 & 255];
if ((XEiJ.fpuBox.epbFpcr & XEiJ.FPU_FPCR_BSUN) != 0) { //BSUN例外許可
irpException (M68kException.M6E_FP_BRANCH_SET_UNORDERED, XEiJ.regPC0, XEiJ.regSRT1 | XEiJ.regSRT0 | XEiJ.regSRS | XEiJ.regSRM | XEiJ.regSRI | XEiJ.regCCR, 0x0000, 0); //pcは命令の先頭
break fscc;
}
}
int ea = XEiJ.regOC & 63;
if (ea < XEiJ.EA_AR) { //FScc.B Dr
if (XEiJ.FPU_CCMAP_882[(w & 63) << 4 | XEiJ.fpuBox.epbFpsr >> 24 & 15]) { //セット
XEiJ.mpuCycleCount += 10;
XEiJ.regRn[ea] |= 0xff;
} else { //クリア
XEiJ.mpuCycleCount += 8;
XEiJ.regRn[ea] &= ~0xff;
}
} else if (ea < XEiJ.EA_MM) { //FDBcc Dr,<label>
if (XEiJ.FPU_CCMAP_882[(w & 63) << 4 | XEiJ.fpuBox.epbFpsr >> 24 & 15]) { //条件が成立しているので通過
XEiJ.mpuCycleCount += 16;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else {
int rrr = XEiJ.regOC & 7;
int t = XEiJ.regRn[rrr];
if ((short) t == 0) { //Drの下位16bitが0なので通過
XEiJ.mpuCycleCount += 18;
XEiJ.regRn[rrr] = t + 65535;
XEiJ.regPC += 2; //オフセットを読み飛ばす
} else { //Drの下位16bitが0でないのでジャンプ
XEiJ.mpuCycleCount += 14;
XEiJ.regRn[rrr] = t - 1; //下位16bitが0でないので上位16bitは変化しない
irpSetPC (XEiJ.regPC + XEiJ.busRws (XEiJ.regPC)); //pc==pc0+2
}
}
} else if (ea < XEiJ.EA_PW) { //FScc.B <mem>
XEiJ.mpuCycleCount += 12;
XEiJ.busWb (efaMltByte (ea), XEiJ.FPU_CCMAP_882[(w & 63) << 4 | XEiJ.fpuBox.epbFpsr >> 24 & 15] ? 0xff : 0x00);
} else if (ea <= XEiJ.EA_IM) { //FTRAPcc.W/FTRAPcc.L/FTRAPcc
int t = (ea & 3) + (ea & 1); //111_010→2,111_011→4,111_100→0
XEiJ.regPC += t;
if (!XEiJ.FPU_CCMAP_882[(w & 63) << 4 | XEiJ.fpuBox.epbFpsr >> 24 & 15]) { //通過
XEiJ.mpuCycleCount += 8 + (t << 1);
} else {
XEiJ.mpuCycleCount += 4 + (t << 1);
M68kException.m6eAddress = XEiJ.regPC0; //アドレスは命令の先頭
M68kException.m6eNumber = M68kException.M6E_TRAPV_INSTRUCTION;
throw M68kException.m6eSignal;
}
} else {
XEiJ.regPC = XEiJ.regPC0 + 2; //拡張ワードを読まなかったことにする
irpFline ();
break fscc;
}
} //fscc
} //irpFscc
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//FNOP |A|--CC46|-|-----|-----| |1111_001_010_000_000-0000000000000000 [FBF.W (*)+2]
//FBF.W <label> |-|--CC46|-|-----|-----| |1111_001_010_000_000-{offset}
//FBEQ.W <label> |-|--CC46|-|-----|-----| |1111_001_010_000_001-{offset}
//FBOGT.W <label> |-|--CC46|-|-----|-----| |1111_001_010_000_010-{offset}
//FBOGE.W <label> |-|--CC46|-|-----|-----| |1111_001_010_000_011-{offset}
//FBOLT.W <label> |-|--CC46|-|-----|-----| |1111_001_010_000_100-{offset}
//FBOLE.W <label> |-|--CC46|-|-----|-----| |1111_001_010_000_101-{offset}
//FBOGL.W <label> |-|--CC46|-|-----|-----| |1111_001_010_000_110-{offset}
//FBOR.W <label> |-|--CC46|-|-----|-----| |1111_001_010_000_111-{offset}
//FBUN.W <label> |-|--CC46|-|-----|-----| |1111_001_010_001_000-{offset}
//FBUEQ.W <label> |-|--CC46|-|-----|-----| |1111_001_010_001_001-{offset}
//FBUGT.W <label> |-|--CC46|-|-----|-----| |1111_001_010_001_010-{offset}
//FBUGE.W <label> |-|--CC46|-|-----|-----| |1111_001_010_001_011-{offset}
//FBULT.W <label> |-|--CC46|-|-----|-----| |1111_001_010_001_100-{offset}
//FBULE.W <label> |-|--CC46|-|-----|-----| |1111_001_010_001_101-{offset}
//FBNE.W <label> |-|--CC46|-|-----|-----| |1111_001_010_001_110-{offset}
//FBT.W <label> |-|--CC46|-|-----|-----| |1111_001_010_001_111-{offset}
//FBRA.W <label> |A|--CC46|-|-----|-----| |1111_001_010_001_111-{offset} [FBT.W <label>]
//FBSF.W <label> |-|--CC46|-|-----|-----| |1111_001_010_010_000-{offset}
//FBSEQ.W <label> |-|--CC46|-|-----|-----| |1111_001_010_010_001-{offset}
//FBGT.W <label> |-|--CC46|-|-----|-----| |1111_001_010_010_010-{offset}
//FBGE.W <label> |-|--CC46|-|-----|-----| |1111_001_010_010_011-{offset}
//FBLT.W <label> |-|--CC46|-|-----|-----| |1111_001_010_010_100-{offset}
//FBLE.W <label> |-|--CC46|-|-----|-----| |1111_001_010_010_101-{offset}
//FBGL.W <label> |-|--CC46|-|-----|-----| |1111_001_010_010_110-{offset}
//FBGLE.W <label> |-|--CC46|-|-----|-----| |1111_001_010_010_111-{offset}
//FBNGLE.W <label> |-|--CC46|-|-----|-----| |1111_001_010_011_000-{offset}
//FBNGL.W <label> |-|--CC46|-|-----|-----| |1111_001_010_011_001-{offset}
//FBNLE.W <label> |-|--CC46|-|-----|-----| |1111_001_010_011_010-{offset}
//FBNLT.W <label> |-|--CC46|-|-----|-----| |1111_001_010_011_011-{offset}
//FBNGE.W <label> |-|--CC46|-|-----|-----| |1111_001_010_011_100-{offset}
//FBNGT.W <label> |-|--CC46|-|-----|-----| |1111_001_010_011_101-{offset}
//FBSNE.W <label> |-|--CC46|-|-----|-----| |1111_001_010_011_110-{offset}
//FBST.W <label> |-|--CC46|-|-----|-----| |1111_001_010_011_111-{offset}
public static void irpFbccWord () throws M68kException {
fbcc: {
if ((7 & XEiJ.currentCopro0) == 0) {
irpFline ();
break fbcc;
}
XEiJ.fpuBox.epbFpiar = XEiJ.regPC0; //FPIARはFMOVEM/FMOVE FPcr/FSAVE/FRESTORE以外の命令で例外が発生しなくても更新される
if ((XEiJ.regOC & 0b010000) != 0 && (XEiJ.fpuBox.epbFpsr & XEiJ.FPU_FPSR_NAN) != 0) { //IEEEノンアウェアテストでNANがセットされているとき
XEiJ.fpuBox.epbFpsr |= XEiJ.FPU_FPSR_EXC_BSUN; //BSUNをセット
XEiJ.fpuBox.epbFpsr |= XEiJ.FPU_FPSR_EXC_TO_AEXC[XEiJ.fpuBox.epbFpsr >> 8 & 255];
if ((XEiJ.fpuBox.epbFpcr & XEiJ.FPU_FPCR_BSUN) != 0) { //BSUN例外許可
irpException (M68kException.M6E_FP_BRANCH_SET_UNORDERED, XEiJ.regPC0, XEiJ.regSRT1 | XEiJ.regSRT0 | XEiJ.regSRS | XEiJ.regSRM | XEiJ.regSRI | XEiJ.regCCR, 0x0000, 0); //pcは命令の先頭
break fbcc;
}
}
if (XEiJ.FPU_CCMAP_882[(XEiJ.regOC & 63) << 4 | XEiJ.fpuBox.epbFpsr >> 24 & 15]) { //ジャンプ
XEiJ.mpuCycleCount += 10;
int s;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
s = XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
} else {
s = XEiJ.regPC;
XEiJ.regPC = s + 2;
s = XEiJ.busRwse (s); //pcws
}
irpSetPC (XEiJ.regPC0 + 2 + s);
} else { //通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 2; //オフセットを読み飛ばす。リードを省略
}
} //fbcc
} //irpFbccWord
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//FBF.L <label> |-|--CC46|-|-----|-----| |1111_001_011_000_000-{offset}
//FBEQ.L <label> |-|--CC46|-|-----|-----| |1111_001_011_000_001-{offset}
//FBOGT.L <label> |-|--CC46|-|-----|-----| |1111_001_011_000_010-{offset}
//FBOGE.L <label> |-|--CC46|-|-----|-----| |1111_001_011_000_011-{offset}
//FBOLT.L <label> |-|--CC46|-|-----|-----| |1111_001_011_000_100-{offset}
//FBOLE.L <label> |-|--CC46|-|-----|-----| |1111_001_011_000_101-{offset}
//FBOGL.L <label> |-|--CC46|-|-----|-----| |1111_001_011_000_110-{offset}
//FBOR.L <label> |-|--CC46|-|-----|-----| |1111_001_011_000_111-{offset}
//FBUN.L <label> |-|--CC46|-|-----|-----| |1111_001_011_001_000-{offset}
//FBUEQ.L <label> |-|--CC46|-|-----|-----| |1111_001_011_001_001-{offset}
//FBUGT.L <label> |-|--CC46|-|-----|-----| |1111_001_011_001_010-{offset}
//FBUGE.L <label> |-|--CC46|-|-----|-----| |1111_001_011_001_011-{offset}
//FBULT.L <label> |-|--CC46|-|-----|-----| |1111_001_011_001_100-{offset}
//FBULE.L <label> |-|--CC46|-|-----|-----| |1111_001_011_001_101-{offset}
//FBNE.L <label> |-|--CC46|-|-----|-----| |1111_001_011_001_110-{offset}
//FBT.L <label> |-|--CC46|-|-----|-----| |1111_001_011_001_111-{offset}
//FBRA.L <label> |A|--CC46|-|-----|-----| |1111_001_011_001_111-{offset} [FBT.L <label>]
//FBSF.L <label> |-|--CC46|-|-----|-----| |1111_001_011_010_000-{offset}
//FBSEQ.L <label> |-|--CC46|-|-----|-----| |1111_001_011_010_001-{offset}
//FBGT.L <label> |-|--CC46|-|-----|-----| |1111_001_011_010_010-{offset}
//FBGE.L <label> |-|--CC46|-|-----|-----| |1111_001_011_010_011-{offset}
//FBLT.L <label> |-|--CC46|-|-----|-----| |1111_001_011_010_100-{offset}
//FBLE.L <label> |-|--CC46|-|-----|-----| |1111_001_011_010_101-{offset}
//FBGL.L <label> |-|--CC46|-|-----|-----| |1111_001_011_010_110-{offset}
//FBGLE.L <label> |-|--CC46|-|-----|-----| |1111_001_011_010_111-{offset}
//FBNGLE.L <label> |-|--CC46|-|-----|-----| |1111_001_011_011_000-{offset}
//FBNGL.L <label> |-|--CC46|-|-----|-----| |1111_001_011_011_001-{offset}
//FBNLE.L <label> |-|--CC46|-|-----|-----| |1111_001_011_011_010-{offset}
//FBNLT.L <label> |-|--CC46|-|-----|-----| |1111_001_011_011_011-{offset}
//FBNGE.L <label> |-|--CC46|-|-----|-----| |1111_001_011_011_100-{offset}
//FBNGT.L <label> |-|--CC46|-|-----|-----| |1111_001_011_011_101-{offset}
//FBSNE.L <label> |-|--CC46|-|-----|-----| |1111_001_011_011_110-{offset}
//FBST.L <label> |-|--CC46|-|-----|-----| |1111_001_011_011_111-{offset}
public static void irpFbccLong () throws M68kException {
fbcc: {
if ((7 & XEiJ.currentCopro0) == 0) {
irpFline ();
break fbcc;
}
XEiJ.fpuBox.epbFpiar = XEiJ.regPC0; //FPIARはFMOVEM/FMOVE FPcr/FSAVE/FRESTORE以外の命令で例外が発生しなくても更新される
if ((XEiJ.regOC & 0b010000) != 0 && (XEiJ.fpuBox.epbFpsr & XEiJ.FPU_FPSR_NAN) != 0) { //IEEEノンアウェアテストでNANがセットされているとき
XEiJ.fpuBox.epbFpsr |= XEiJ.FPU_FPSR_EXC_BSUN; //BSUNをセット
XEiJ.fpuBox.epbFpsr |= XEiJ.FPU_FPSR_EXC_TO_AEXC[XEiJ.fpuBox.epbFpsr >> 8 & 255];
if ((XEiJ.fpuBox.epbFpcr & XEiJ.FPU_FPCR_BSUN) != 0) { //BSUN例外許可
irpException (M68kException.M6E_FP_BRANCH_SET_UNORDERED, XEiJ.regPC0, XEiJ.regSRT1 | XEiJ.regSRT0 | XEiJ.regSRS | XEiJ.regSRM | XEiJ.regSRI | XEiJ.regCCR, 0x0000, 0); //pcは命令の先頭
break fbcc;
}
}
if (XEiJ.FPU_CCMAP_882[(XEiJ.regOC & 63) << 4 | XEiJ.fpuBox.epbFpsr >> 24 & 15]) { //ジャンプ
XEiJ.mpuCycleCount += 14;
int s;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
s = XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
} else {
s = XEiJ.regPC;
XEiJ.regPC = s + 4;
s = XEiJ.busRlse (s); //pcls
}
irpSetPC (XEiJ.regPC0 + 2 + s);
} else { //通過
XEiJ.mpuCycleCount += 12;
XEiJ.regPC += 4; //オフセットを読み飛ばす。リードを省略
}
} //fbcc
} //irpFbccLong
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//FSAVE <ea> |-|--CC46|P|-----|-----| M -WXZ |1111_001_100_mmm_rrr
public static void irpFsave () throws M68kException {
if ((7 & XEiJ.currentCopro0) == 0) {
irpFline ();
return;
}
if (XEiJ.regSRS == 0) { //ユーザモードのとき
irpFline (); //特権違反またはFライン
return;
}
//以下はスーパーバイザモード
int ea = XEiJ.regOC & 63;
int a;
if (ea >> 3 == XEiJ.MMM_MN) { //-(Ar)
int arr = XEiJ.regOC & 7 | 8;
a = XEiJ.regRn[arr] -= 4;
XEiJ.mpuCycleCount += 8;
} else { //-(Ar)以外
a = efaCltLong (ea);
}
XEiJ.busWl (a, 0); //NULL
} //irpFsave
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//FRESTORE <ea> |-|--CC46|P|-----|-----| M+ WXZP |1111_001_101_mmm_rrr
public static void irpFrestore () throws M68kException {
if ((7 & XEiJ.currentCopro0) == 0) {
irpFline ();
return;
}
if (XEiJ.regSRS == 0) { //ユーザモードのとき
irpFline (); //特権違反またはFライン
return;
}
//以下はスーパーバイザモード
int ea = XEiJ.regOC & 63;
int a;
if (ea >> 3 == XEiJ.MMM_MP) { //(Ar)+
int arr = XEiJ.regOC & 7 | 8;
a = XEiJ.regRn[arr];
XEiJ.regRn[arr] = a + 4;
XEiJ.mpuCycleCount += 8;
} else { //(Ar)+以外
a = efaCntLong (ea);
}
XEiJ.busRls (a); //NULL
//FPSRのAEXCをクリアする
XEiJ.fpuBox.epbFpsr = 0;
//FPIARをクリアする
XEiJ.fpuBox.epbFpiar = 0;
} //irpFrestore
//irpFPPreInstruction ()
// 浮動小数点命令実行前例外 floating-point pre-instruction exception
// 優先順位はBSUN>SNAN>OPERR>OVFL>UNFL>DZ>INEX2/INEX1
// 複数の例外が同時に発生したときは最上位の例外ハンドラだけが呼び出される
// 浮動小数点例外ハンドラは自分よりも下位の浮動小数点例外が発生していないか確認しなければならない
public static boolean irpFPPreInstruction () throws M68kException {
int mask = XEiJ.fpuBox.epbFpcr & XEiJ.fpuBox.epbFpsr & 0x0000ff00;
if (mask == 0) {
return false;
}
irpException (FP_OFFSET_TO_NUMBER[Integer.numberOfLeadingZeros (mask)],
XEiJ.regPC0, //pcは命令の先頭
XEiJ.regSRT1 | XEiJ.regSRT0 | XEiJ.regSRS | XEiJ.regSRM | XEiJ.regSRI | XEiJ.regCCR,
0x0000,
0);
return true;
} //irpFPPreInstruction()
//irpFPPostInstruction (a)
// 浮動小数点命令実行後例外 floating-point post-instruction exception
// 優先順位はBSUN>SNAN>OPERR>OVFL>UNFL>DZ>INEX2/INEX1
// 複数の例外が同時に発生したときは最上位の例外ハンドラだけが呼び出される
// 浮動小数点例外ハンドラは自分よりも下位の浮動小数点例外が発生していないか確認しなければならない
public static boolean irpFPPostInstruction (int a) throws M68kException {
int mask = XEiJ.fpuBox.epbFpcr & XEiJ.fpuBox.epbFpsr & 0x0000ff00;
if (mask == 0) {
return false;
}
irpException (FP_OFFSET_TO_NUMBER[Integer.numberOfLeadingZeros (mask)],
XEiJ.regPC, //pcは次の命令
XEiJ.regSRT1 | XEiJ.regSRT0 | XEiJ.regSRS | XEiJ.regSRM | XEiJ.regSRI | XEiJ.regCCR,
0x3000,
a);
return true;
} //irpFPPostInstruction(int)
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//FPACK <data> |A|012346|-|UUUUU|*****| |1111_111_0dd_ddd_ddd [FLINE #<data>]
public static void irpFpack () throws M68kException {
if (!MainMemory.mmrFEfuncActivated) {
irpFline ();
return;
}
StringBuilder sb;
int a0;
if (FEFunction.FPK_DEBUG_TRACE) {
sb = new StringBuilder ();
String name = Disassembler.DIS_FPACK_NAME[XEiJ.regOC & 255];
if (name.length () == 0) {
XEiJ.fmtHex4 (sb.append ('$'), XEiJ.regOC);
} else {
sb.append (name);
}
sb.append ('\n');
XEiJ.fmtHex8 (XEiJ.fmtHex8 (XEiJ.fmtHex8 (XEiJ.fmtHex8 (sb.append (" D0="), XEiJ.regRn[0]).append (" D1="), XEiJ.regRn[1]).append (" D2="), XEiJ.regRn[2]).append (" D3="), XEiJ.regRn[3]);
a0 = XEiJ.regRn[8];
MainMemory.mmrRstr (sb.append (" (A0)=\""), a0, MainMemory.mmrStrlen (a0, 20)).append ("\"\n");
}
XEiJ.mpuCycleCount += FEFunction.FPK_CLOCK; //一律にFEFunction.FPK_CLOCKサイクルかかることにする
switch (XEiJ.regOC & 255) {
case 0x00: FEFunction.fpkLMUL (); break;
case 0x01: FEFunction.fpkLDIV (); break;
case 0x02: FEFunction.fpkLMOD (); break;
//case 0x03: break;
case 0x04: FEFunction.fpkUMUL (); break;
case 0x05: FEFunction.fpkUDIV (); break;
case 0x06: FEFunction.fpkUMOD (); break;
//case 0x07: break;
case 0x08: FEFunction.fpkIMUL (); break;
case 0x09: FEFunction.fpkIDIV (); break;
//case 0x0a: break;
//case 0x0b: break;
case 0x0c: FEFunction.fpkRANDOMIZE (); break;
case 0x0d: FEFunction.fpkSRAND (); break;
case 0x0e: FEFunction.fpkRAND (); break;
//case 0x0f: break;
case 0x10: FEFunction.fpkSTOL (); break;
case 0x11: FEFunction.fpkLTOS (); break;
case 0x12: FEFunction.fpkSTOH (); break;
case 0x13: FEFunction.fpkHTOS (); break;
case 0x14: FEFunction.fpkSTOO (); break;
case 0x15: FEFunction.fpkOTOS (); break;
case 0x16: FEFunction.fpkSTOB (); break;
case 0x17: FEFunction.fpkBTOS (); break;
case 0x18: FEFunction.fpkIUSING (); break;
//case 0x19: break;
case 0x1a: FEFunction.fpkLTOD (); break;
case 0x1b: FEFunction.fpkDTOL (); break;
case 0x1c: FEFunction.fpkLTOF (); break;
case 0x1d: FEFunction.fpkFTOL (); break;
case 0x1e: FEFunction.fpkFTOD (); break;
case 0x1f: FEFunction.fpkDTOF (); break;
case 0x20: FEFunction.fpkVAL (); break;
case 0x21: FEFunction.fpkUSING (); break;
case 0x22: FEFunction.fpkSTOD (); break;
case 0x23: FEFunction.fpkDTOS (); break;
case 0x24: FEFunction.fpkECVT (); break;
case 0x25: FEFunction.fpkFCVT (); break;
case 0x26: FEFunction.fpkGCVT (); break;
//case 0x27: break;
case 0x28: FEFunction.fpkDTST (); break;
case 0x29: FEFunction.fpkDCMP (); break;
case 0x2a: FEFunction.fpkDNEG (); break;
case 0x2b: FEFunction.fpkDADD (); break;
case 0x2c: FEFunction.fpkDSUB (); break;
case 0x2d: FEFunction.fpkDMUL (); break;
case 0x2e: FEFunction.fpkDDIV (); break;
case 0x2f: FEFunction.fpkDMOD (); break;
case 0x30: FEFunction.fpkDABS (); break;
case 0x31: FEFunction.fpkDCEIL (); break;
case 0x32: FEFunction.fpkDFIX (); break;
case 0x33: FEFunction.fpkDFLOOR (); break;
case 0x34: FEFunction.fpkDFRAC (); break;
case 0x35: FEFunction.fpkDSGN (); break;
case 0x36: FEFunction.fpkSIN (); break;
case 0x37: FEFunction.fpkCOS (); break;
case 0x38: FEFunction.fpkTAN (); break;
case 0x39: FEFunction.fpkATAN (); break;
case 0x3a: FEFunction.fpkLOG (); break;
case 0x3b: FEFunction.fpkEXP (); break;
case 0x3c: FEFunction.fpkSQR (); break;
case 0x3d: FEFunction.fpkPI (); break;
case 0x3e: FEFunction.fpkNPI (); break;
case 0x3f: FEFunction.fpkPOWER (); break;
case 0x40: FEFunction.fpkRND (); break;
case 0x41: FEFunction.fpkSINH (); break;
case 0x42: FEFunction.fpkCOSH (); break;
case 0x43: FEFunction.fpkTANH (); break;
case 0x44: FEFunction.fpkATANH (); break;
case 0x45: FEFunction.fpkASIN (); break;
case 0x46: FEFunction.fpkACOS (); break;
case 0x47: FEFunction.fpkLOG10 (); break;
case 0x48: FEFunction.fpkLOG2 (); break;
case 0x49: FEFunction.fpkDFREXP (); break;
case 0x4a: FEFunction.fpkDLDEXP (); break;
case 0x4b: FEFunction.fpkDADDONE (); break;
case 0x4c: FEFunction.fpkDSUBONE (); break;
case 0x4d: FEFunction.fpkDDIVTWO (); break;
case 0x4e: FEFunction.fpkDIEECNV (); break;
case 0x4f: FEFunction.fpkIEEDCNV (); break;
case 0x50: FEFunction.fpkFVAL (); break;
case 0x51: FEFunction.fpkFUSING (); break;
case 0x52: FEFunction.fpkSTOF (); break;
case 0x53: FEFunction.fpkFTOS (); break;
case 0x54: FEFunction.fpkFECVT (); break;
case 0x55: FEFunction.fpkFFCVT (); break;
case 0x56: FEFunction.fpkFGCVT (); break;
//case 0x57: break;
case 0x58: FEFunction.fpkFTST (); break;
case 0x59: FEFunction.fpkFCMP (); break;
case 0x5a: FEFunction.fpkFNEG (); break;
case 0x5b: FEFunction.fpkFADD (); break;
case 0x5c: FEFunction.fpkFSUB (); break;
case 0x5d: FEFunction.fpkFMUL (); break;
case 0x5e: FEFunction.fpkFDIV (); break;
case 0x5f: FEFunction.fpkFMOD (); break;
case 0x60: FEFunction.fpkFABS (); break;
case 0x61: FEFunction.fpkFCEIL (); break;
case 0x62: FEFunction.fpkFFIX (); break;
case 0x63: FEFunction.fpkFFLOOR (); break;
case 0x64: FEFunction.fpkFFRAC (); break;
case 0x65: FEFunction.fpkFSGN (); break;
case 0x66: FEFunction.fpkFSIN (); break;
case 0x67: FEFunction.fpkFCOS (); break;
case 0x68: FEFunction.fpkFTAN (); break;
case 0x69: FEFunction.fpkFATAN (); break;
case 0x6a: FEFunction.fpkFLOG (); break;
case 0x6b: FEFunction.fpkFEXP (); break;
case 0x6c: FEFunction.fpkFSQR (); break;
case 0x6d: FEFunction.fpkFPI (); break;
case 0x6e: FEFunction.fpkFNPI (); break;
case 0x6f: FEFunction.fpkFPOWER (); break;
case 0x70: FEFunction.fpkFRND (); break;
case 0x71: FEFunction.fpkFSINH (); break;
case 0x72: FEFunction.fpkFCOSH (); break;
case 0x73: FEFunction.fpkFTANH (); break;
case 0x74: FEFunction.fpkFATANH (); break;
case 0x75: FEFunction.fpkFASIN (); break;
case 0x76: FEFunction.fpkFACOS (); break;
case 0x77: FEFunction.fpkFLOG10 (); break;
case 0x78: FEFunction.fpkFLOG2 (); break;
case 0x79: FEFunction.fpkFFREXP (); break;
case 0x7a: FEFunction.fpkFLDEXP (); break;
case 0x7b: FEFunction.fpkFADDONE (); break;
case 0x7c: FEFunction.fpkFSUBONE (); break;
case 0x7d: FEFunction.fpkFDIVTWO (); break;
case 0x7e: FEFunction.fpkFIEECNV (); break;
case 0x7f: FEFunction.fpkIEEFCNV (); break;
//case 0x80: break;
//case 0x81: break;
//case 0x82: break;
//case 0x83: break;
//case 0x84: break;
//case 0x85: break;
//case 0x86: break;
//case 0x87: break;
//case 0x88: break;
//case 0x89: break;
//case 0x8a: break;
//case 0x8b: break;
//case 0x8c: break;
//case 0x8d: break;
//case 0x8e: break;
//case 0x8f: break;
//case 0x90: break;
//case 0x91: break;
//case 0x92: break;
//case 0x93: break;
//case 0x94: break;
//case 0x95: break;
//case 0x96: break;
//case 0x97: break;
//case 0x98: break;
//case 0x99: break;
//case 0x9a: break;
//case 0x9b: break;
//case 0x9c: break;
//case 0x9d: break;
//case 0x9e: break;
//case 0x9f: break;
//case 0xa0: break;
//case 0xa1: break;
//case 0xa2: break;
//case 0xa3: break;
//case 0xa4: break;
//case 0xa5: break;
//case 0xa6: break;
//case 0xa7: break;
//case 0xa8: break;
//case 0xa9: break;
//case 0xaa: break;
//case 0xab: break;
//case 0xac: break;
//case 0xad: break;
//case 0xae: break;
//case 0xaf: break;
//case 0xb0: break;
//case 0xb1: break;
//case 0xb2: break;
//case 0xb3: break;
//case 0xb4: break;
//case 0xb5: break;
//case 0xb6: break;
//case 0xb7: break;
//case 0xb8: break;
//case 0xb9: break;
//case 0xba: break;
//case 0xbb: break;
//case 0xbc: break;
//case 0xbd: break;
//case 0xbe: break;
//case 0xbf: break;
//case 0xc0: break;
//case 0xc1: break;
//case 0xc2: break;
//case 0xc3: break;
//case 0xc4: break;
//case 0xc5: break;
//case 0xc6: break;
//case 0xc7: break;
//case 0xc8: break;
//case 0xc9: break;
//case 0xca: break;
//case 0xcb: break;
//case 0xcc: break;
//case 0xcd: break;
//case 0xce: break;
//case 0xcf: break;
//case 0xd0: break;
//case 0xd1: break;
//case 0xd2: break;
//case 0xd3: break;
//case 0xd4: break;
//case 0xd5: break;
//case 0xd6: break;
//case 0xd7: break;
//case 0xd8: break;
//case 0xd9: break;
//case 0xda: break;
//case 0xdb: break;
//case 0xdc: break;
//case 0xdd: break;
//case 0xde: break;
//case 0xdf: break;
case 0xe0: FEFunction.fpkCLMUL (); break;
case 0xe1: FEFunction.fpkCLDIV (); break;
case 0xe2: FEFunction.fpkCLMOD (); break;
case 0xe3: FEFunction.fpkCUMUL (); break;
case 0xe4: FEFunction.fpkCUDIV (); break;
case 0xe5: FEFunction.fpkCUMOD (); break;
case 0xe6: FEFunction.fpkCLTOD (); break;
case 0xe7: FEFunction.fpkCDTOL (); break;
case 0xe8: FEFunction.fpkCLTOF (); break;
case 0xe9: FEFunction.fpkCFTOL (); break;
case 0xea: FEFunction.fpkCFTOD (); break;
case 0xeb: FEFunction.fpkCDTOF (); break;
case 0xec: FEFunction.fpkCDCMP (); break;
case 0xed: FEFunction.fpkCDADD (); break;
case 0xee: FEFunction.fpkCDSUB (); break;
case 0xef: FEFunction.fpkCDMUL (); break;
case 0xf0: FEFunction.fpkCDDIV (); break;
case 0xf1: FEFunction.fpkCDMOD (); break;
case 0xf2: FEFunction.fpkCFCMP (); break;
case 0xf3: FEFunction.fpkCFADD (); break;
case 0xf4: FEFunction.fpkCFSUB (); break;
case 0xf5: FEFunction.fpkCFMUL (); break;
case 0xf6: FEFunction.fpkCFDIV (); break;
case 0xf7: FEFunction.fpkCFMOD (); break;
case 0xf8: FEFunction.fpkCDTST (); break;
case 0xf9: FEFunction.fpkCFTST (); break;
case 0xfa: FEFunction.fpkCDINC (); break;
case 0xfb: FEFunction.fpkCFINC (); break;
case 0xfc: FEFunction.fpkCDDEC (); break;
case 0xfd: FEFunction.fpkCFDEC (); break;
case 0xfe: FEFunction.fpkFEVARG (); break;
//case 0xff: FEFunction.fpkFEVECS (); break; //FLOATn.Xに処理させる
default:
XEiJ.mpuCycleCount -= FEFunction.FPK_CLOCK; //戻す
irpFline ();
}
if (FEFunction.FPK_DEBUG_TRACE) {
int i = sb.length ();
XEiJ.fmtHex8 (XEiJ.fmtHex8 (XEiJ.fmtHex8 (XEiJ.fmtHex8 (sb.append (" D0="), XEiJ.regRn[0]).append (" D1="), XEiJ.regRn[1]).append (" D2="), XEiJ.regRn[2]).append (" D3="), XEiJ.regRn[3]);
int l = MainMemory.mmrStrlen (a0, 20);
sb.append (" (A0)=\"");
i = sb.length () - i;
MainMemory.mmrRstr (sb, a0, l).append ("\"\n");
if (a0 <= XEiJ.regRn[8] && XEiJ.regRn[8] <= a0 + l) {
for (i += sb.length () + XEiJ.regRn[8] - a0; sb.length () < i; ) {
sb.append (' ');
}
sb.append ('^');
}
System.out.println (sb.toString ());
}
} //irpFpack
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//DOS <data> |A|012346|-|UUUUU|UUUUU| |1111_111_1dd_ddd_ddd [FLINE #<data>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//FLINE #<data> |-|012346|-|UUUUU|UUUUU| |1111_ddd_ddd_ddd_ddd (line 1111 emulator)
public static void irpFline () throws M68kException {
int oc9 = XEiJ.regOC & 0b0000_000_111_111_111; //命令コードの下位9bit
if (XEiJ.regSRS == 0) { //ユーザモードのとき
if ((0b100_010_000 <= oc9 && oc9 <= 0b100_010_111) || //cpSAVE (Ar)
(0b100_100_000 <= oc9 && oc9 <= 0b100_111_001) || //cpSAVE -(Ar)|(d16,Ar)|(d8,Ar,Rn.wl)|(xxx).W|(xxx).L
(0b101_010_000 <= oc9 && oc9 <= 0b101_011_111) || //cpRESTORE (Ar)|(Ar)+
(0b101_101_000 <= oc9 && oc9 <= 0b101_111_011) //cpRESTORE (d16,Ar)|(d8,Ar,Rn.wl)|(xxx).W|(xxx).L|(d16,PC)|(d8,PC,Rn.wl)
) { //cpSAVEまたはcpRESTOREでアドレッシングモードが有効なとき
M68kException.m6eNumber = M68kException.M6E_PRIVILEGE_VIOLATION; //特権違反
throw M68kException.m6eSignal;
}
} else { //スーパーバイザモードのとき
if ((0b101_010_000 <= oc9 && oc9 <= 0b101_011_111) || //cpRESTORE (Ar)|(Ar)+
(0b101_101_000 <= oc9 && oc9 <= 0b101_111_011) //cpRESTORE (d16,Ar)|(d8,Ar,Rn.wl)|(xxx).W|(xxx).L|(d16,PC)|(d8,PC,Rn.wl)
) { //cpRESTOREでアドレッシングモードが有効なとき
int ea = oc9 & 63;
if (ea >> 3 == XEiJ.MMM_MP) { //(Ar)+を
ea += (XEiJ.MMM_MM - XEiJ.MMM_MP) << 3; //(Ar)とみなす
}
XEiJ.busRls (efaCntLong (ea)); //<ea>をリードする。ここでバスエラーが発生する可能性がある
}
}
XEiJ.mpuCycleCount += 34;
if (XEiJ.MPU_INLINE_EXCEPTION) {
int save_sr = XEiJ.regSRT1 | XEiJ.regSRT0 | XEiJ.regSRS | XEiJ.regSRM | XEiJ.regSRI | XEiJ.regCCR;
int sp = XEiJ.regRn[15];
XEiJ.regSRT1 = XEiJ.regSRT0 = XEiJ.mpuTraceFlag = 0; //srのTビットを消す
if (XEiJ.regSRS == 0) { //ユーザモードのとき
XEiJ.regSRS = XEiJ.REG_SR_S; //スーパーバイザモードへ移行する
XEiJ.mpuUSP = sp; //USPを保存
sp = XEiJ.regSRM != 0 ? XEiJ.mpuMSP : XEiJ.mpuISP; //SSPを復元
if (DataBreakPoint.DBP_ON) {
DataBreakPoint.dbpMemoryMap = DataBreakPoint.dbpSuperMap; //スーパーバイザメモリマップに切り替える
} else {
XEiJ.busMemoryMap = XEiJ.busSuperMap; //スーパーバイザメモリマップに切り替える
}
if (InstructionBreakPoint.IBP_ON) {
InstructionBreakPoint.ibpOp1MemoryMap = InstructionBreakPoint.ibpOp1SuperMap;
}
}
XEiJ.regRn[15] = sp -= 8;
XEiJ.busWw (sp + 6, 0x0000 | M68kException.M6E_LINE_1111_EMULATOR << 2); //pushw。フォーマットとベクタオフセットをプッシュする
XEiJ.busWl (sp + 2, XEiJ.regPC0); //pushl。pcをプッシュする
XEiJ.busWw (sp, save_sr); //pushw。srをプッシュする
irpSetPC (XEiJ.busRlsf (XEiJ.mpuVBR + (M68kException.M6E_LINE_1111_EMULATOR << 2))); //例外ベクタを取り出してジャンプする
} else {
irpException (M68kException.M6E_LINE_1111_EMULATOR, XEiJ.regPC0, XEiJ.regSRT1 | XEiJ.regSRT0 | XEiJ.regSRS | XEiJ.regSRM | XEiJ.regSRI | XEiJ.regCCR, 0x0000, 0); //pcは命令の先頭
}
} //irpFline
//irpIllegal ()
// オペコードの上位10bitで分類されなかった未実装命令
// 命令実行回数をカウントするために分けてある
// 0x4afcのILLEGAL命令はTASに分類されて未実装実効アドレスで処理されるのでここには来ない
public static void irpIllegal () throws M68kException {
if (true) {
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
}
} //irpIllegal
//z = irpAbcd (x, y)
// ABCD
public static int irpAbcd (int x, int y) {
int c = XEiJ.regCCR >> 4;
int t = (x & 0xff) + (y & 0xff) + c; //仮の結果
int z = t; //結果
if (0x0a <= (x & 0x0f) + (y & 0x0f) + c) { //ハーフキャリー
z += 0x10 - 0x0a;
}
//XとCはキャリーがあるときセット、さもなくばクリア
if (0xa0 <= z) { //キャリー
z += 0x100 - 0xa0;
XEiJ.regCCR |= XEiJ.REG_CCR_X | XEiJ.REG_CCR_C;
} else {
XEiJ.regCCR &= ~(XEiJ.REG_CCR_X | XEiJ.REG_CCR_C);
}
//Zは結果が0でないときクリア、さもなくば変化しない
z &= 0xff;
if (z != 0x00) {
XEiJ.regCCR &= ~XEiJ.REG_CCR_Z;
}
if (false) {
//000/030のときNは結果の最上位ビット
if ((z & 0x80) != 0) {
XEiJ.regCCR |= XEiJ.REG_CCR_N;
} else {
XEiJ.regCCR &= ~XEiJ.REG_CCR_N;
}
//000のときVは補正値の加算でオーバーフローしたときセット、さもなくばクリア
int a = z - t; //補正値
if ((((t ^ z) & (a ^ z)) & 0x80) != 0) {
XEiJ.regCCR |= XEiJ.REG_CCR_V;
} else {
XEiJ.regCCR &= ~XEiJ.REG_CCR_V;
}
} else if (true) {
//000/030のときNは結果の最上位ビット
if ((z & 0x80) != 0) {
XEiJ.regCCR |= XEiJ.REG_CCR_N;
} else {
XEiJ.regCCR &= ~XEiJ.REG_CCR_N;
}
//030のときVはクリア
XEiJ.regCCR &= ~XEiJ.REG_CCR_V;
} else {
//060のときNとVは変化しない
}
return z;
} //irpAbcd
//z = irpSbcd (x, y)
// SBCD
public static int irpSbcd (int x, int y) {
int b = XEiJ.regCCR >> 4;
int t = (x & 0xff) - (y & 0xff) - b; //仮の結果
int z = t; //結果
if ((x & 0x0f) - (y & 0x0f) - b < 0) { //ハーフボロー
z -= 0x10 - 0x0a;
}
//XとCはボローがあるときセット、さもなくばクリア
if (z < 0) { //ボロー
if (t < 0) {
z -= 0x100 - 0xa0;
}
XEiJ.regCCR |= XEiJ.REG_CCR_X | XEiJ.REG_CCR_C;
} else {
XEiJ.regCCR &= ~(XEiJ.REG_CCR_X | XEiJ.REG_CCR_C);
}
//Zは結果が0でないときクリア、さもなくば変化しない
z &= 0xff;
if (z != 0x00) {
XEiJ.regCCR &= ~XEiJ.REG_CCR_Z;
}
if (false) {
//000/030のときNは結果の最上位ビット
if ((z & 0x80) != 0) {
XEiJ.regCCR |= XEiJ.REG_CCR_N;
} else {
XEiJ.regCCR &= ~XEiJ.REG_CCR_N;
}
//000のときVは補正値の加算でオーバーフローしたときセット、さもなくばクリア
int a = z - t; //補正値
if ((((t ^ z) & (a ^ z)) & 0x80) != 0) {
XEiJ.regCCR |= XEiJ.REG_CCR_V;
} else {
XEiJ.regCCR &= ~XEiJ.REG_CCR_V;
}
} else if (true) {
//000/030のときNは結果の最上位ビット
if ((z & 0x80) != 0) {
XEiJ.regCCR |= XEiJ.REG_CCR_N;
} else {
XEiJ.regCCR &= ~XEiJ.REG_CCR_N;
}
//030のときVはクリア
XEiJ.regCCR &= ~XEiJ.REG_CCR_V;
} else {
//060のときNとVは変化しない
}
return z;
} //irpSbcd
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | MPU | |CCin |CCout|addressing| 1st opcode 2nd opcode
// A:alias P:privileged |A|012346|P|XNZVC|XNZVC|DAM+-WXZPI|bbbb_bbb_bbb_bbb_bbb-bbbbbbbbbbbbbbbb
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//HFSBOOT |-|012346|-|-----|-----| |0100_111_000_000_000
//HFSINST |-|012346|-|-----|-----| |0100_111_000_000_001
//HFSSTR |-|012346|-|-----|-----| |0100_111_000_000_010
//HFSINT |-|012346|-|-----|-----| |0100_111_000_000_011
//EMXNOP |-|012346|-|-----|-----| |0100_111_000_000_100
// エミュレータ拡張命令
public static void irpEmx () throws M68kException {
switch (XEiJ.regOC & 63) {
case XEiJ.EMX_OPCODE_HFSBOOT & 63:
XEiJ.mpuCycleCount += 40;
if (HFS.hfsIPLBoot ()) {
//JMP $6800.W
irpSetPC (0x00006800);
}
break;
case XEiJ.EMX_OPCODE_HFSINST & 63:
XEiJ.mpuCycleCount += 40;
HFS.hfsInstall ();
break;
case XEiJ.EMX_OPCODE_HFSSTR & 63:
XEiJ.mpuCycleCount += 40;
HFS.hfsStrategy ();
break;
case XEiJ.EMX_OPCODE_HFSINT & 63:
XEiJ.mpuCycleCount += 40;
//XEiJ.mpuClockTime += (int) (TMR_FREQ / 100000L); //0.01ms
if (HFS.hfsInterrupt ()) {
//WAIT
XEiJ.mpuTraceFlag = 0; //トレース例外を発生させない
XEiJ.regPC = XEiJ.regPC0; //ループ
XEiJ.mpuClockTime += XEiJ.TMR_FREQ * 4 / 1000000; //4μs。10MHzのとき40clk
XEiJ.mpuLastNano += 4000L;
}
break;
case XEiJ.EMX_OPCODE_EMXNOP & 63:
XEiJ.emxNop ();
break;
case XEiJ.EMX_OPCODE_EMXWAIT & 63:
WaitInstruction.execute (); //待機命令を実行する
break;
default:
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
}
} //irpEmx
//irpSetPC (a)
// pcへデータを書き込む
// 奇数のときはアドレスエラーが発生する
public static void irpSetPC (int a) throws M68kException {
if (XEiJ.TEST_BIT_0_SHIFT ? a << 31 - 0 < 0 : (a & 1) != 0) {
M68kException.m6eNumber = M68kException.M6E_ADDRESS_ERROR;
M68kException.m6eAddress = a & -2; //アドレスを偶数にする
M68kException.m6eDirection = XEiJ.MPU_WR_READ;
M68kException.m6eSize = XEiJ.MPU_SS_LONG;
throw M68kException.m6eSignal;
}
XEiJ.mpuTraceFlag |= XEiJ.regSRT0; //フロートレース
if (BranchLog.BLG_ON) {
BranchLog.blgJump (a); //分岐ログに分岐レコードを追加する
} else {
XEiJ.regPC = a;
}
} //irpSetPC
//irpSetSR (newSr)
// srへデータを書き込む
// ori to sr/andi to sr/eori to sr/move to sr/stop/rteで使用される
// スーパーバイザモードになっていることを確認してから呼び出すこと
// rteではr[15]が指すアドレスからsrとpcを取り出してr[15]を更新してから呼び出すこと
// スーパーバイザモード→ユーザモードのときは移行のための処理を行う
// 新しい割り込みマスクレベルよりも高い割り込み処理の終了をデバイスに通知する
public static void irpSetSR (int newSr) {
XEiJ.regSRT1 = XEiJ.REG_SR_T1 & newSr;
XEiJ.regSRT0 = XEiJ.REG_SR_T0 & newSr;
int old_srM = XEiJ.regSRM;
XEiJ.regSRM = XEiJ.REG_SR_M & newSr;
if ((XEiJ.regSRS = XEiJ.REG_SR_S & newSr) == 0) { //スーパーバイザモード→ユーザモード
if (old_srM != 0) { //スーパーバイザマスタモード→ユーザモード
XEiJ.mpuMSP = XEiJ.regRn[15]; //XEiJ.mpuMSPを保存
} else { //スーパーバイザ割り込みモード→ユーザモード
XEiJ.mpuISP = XEiJ.regRn[15]; //XEiJ.mpuISPを保存
}
XEiJ.regRn[15] = XEiJ.mpuUSP; //XEiJ.mpuUSPを復元
if (DataBreakPoint.DBP_ON) {
DataBreakPoint.dbpMemoryMap = DataBreakPoint.dbpUserMap; //ユーザメモリマップに切り替える
} else {
XEiJ.busMemoryMap = XEiJ.busUserMap; //ユーザメモリマップに切り替える
}
if (InstructionBreakPoint.IBP_ON) {
InstructionBreakPoint.ibpOp1MemoryMap = InstructionBreakPoint.ibpOp1UserMap;
}
} else if (old_srM != XEiJ.regSRM) {
if (old_srM != 0) { //マスタモード→割り込みモード
XEiJ.mpuMSP = XEiJ.regRn[15]; //XEiJ.mpuMSPを保存
XEiJ.regRn[15] = XEiJ.mpuISP; //XEiJ.mpuISPを復元
} else { //割り込みモード→マスタモード
XEiJ.mpuISP = XEiJ.regRn[15]; //XEiJ.mpuISPを保存
XEiJ.regRn[15] = XEiJ.mpuMSP; //XEiJ.mpuMSPを復元
}
}
int t = (XEiJ.mpuIMR = 0x7f >> ((XEiJ.regSRI = XEiJ.REG_SR_I & newSr) >> 8)) & XEiJ.mpuISR; //XEiJ.mpuISRで1→0とするビット
if (t != 0) { //終了する割り込みがあるとき
XEiJ.mpuISR ^= t;
//デバイスに割り込み処理の終了を通知する
if (t == XEiJ.MPU_MFP_INTERRUPT_MASK) { //MFPのみ
MC68901.mfpDone ();
} else if (t == XEiJ.MPU_DMA_INTERRUPT_MASK) { //DMAのみ
HD63450.dmaDone ();
} else if (t == XEiJ.MPU_SCC_INTERRUPT_MASK) { //SCCのみ
Z8530.sccDone ();
} else if (t == XEiJ.MPU_IOI_INTERRUPT_MASK) { //IOIのみ
IOInterrupt.ioiDone ();
} else if (t == XEiJ.MPU_EB2_INTERRUPT_MASK) { //EB2のみ
XEiJ.eb2Done ();
} else { //SYSのみまたは複数
if (XEiJ.TEST_BIT_1_SHIFT ? t << 24 + XEiJ.MPU_MFP_INTERRUPT_LEVEL < 0 : (t & XEiJ.MPU_MFP_INTERRUPT_MASK) != 0) {
MC68901.mfpDone ();
}
if (t << 24 + XEiJ.MPU_DMA_INTERRUPT_LEVEL < 0) { //(t & XEiJ.MPU_DMA_INTERRUPT_MASK) != 0
HD63450.dmaDone ();
}
if (XEiJ.TEST_BIT_2_SHIFT ? t << 24 + XEiJ.MPU_SCC_INTERRUPT_LEVEL < 0 : (t & XEiJ.MPU_SCC_INTERRUPT_MASK) != 0) {
Z8530.sccDone ();
}
if (t << 24 + XEiJ.MPU_IOI_INTERRUPT_LEVEL < 0) { //(t & XEiJ.MPU_IOI_INTERRUPT_MASK) != 0
IOInterrupt.ioiDone ();
}
if (t << 24 + XEiJ.MPU_EB2_INTERRUPT_LEVEL < 0) { //(t & XEiJ.MPU_EB2_INTERRUPT_MASK) != 0
XEiJ.eb2Done ();
}
if (XEiJ.TEST_BIT_0_SHIFT ? t << 24 + XEiJ.MPU_SYS_INTERRUPT_LEVEL < 0 : (t & XEiJ.MPU_SYS_INTERRUPT_MASK) != 0) {
XEiJ.sysDone ();
}
}
}
XEiJ.mpuIMR |= ~XEiJ.mpuISR & XEiJ.MPU_SYS_INTERRUPT_MASK; //割り込みマスクレベルが7のときレベル7割り込みの処理中でなければレベル7割り込みを許可する
XEiJ.regCCR = XEiJ.REG_CCR_MASK & newSr;
} //irpSetSR
//irpInterrupt (vectorNumber, level)
// 割り込み処理を開始する
public static void irpInterrupt (int vectorNumber, int level) throws M68kException {
if (XEiJ.regOC == 0b0100_111_001_110_010) { //最後に実行した命令はSTOP命令
XEiJ.regPC = XEiJ.regPC0 + 4; //次の命令に進む
}
XEiJ.mpuClockTime += XEiJ.mpuModifiedUnit * 44;
int save_sr = XEiJ.regSRT1 | XEiJ.regSRT0 | XEiJ.regSRS | XEiJ.regSRM | XEiJ.regSRI | XEiJ.regCCR;
XEiJ.regSRI = level << 8; //割り込みマスクを要求されたレベルに変更する
XEiJ.mpuIMR = 0x7f >> level;
XEiJ.mpuISR |= 0x80 >> level;
int sp = XEiJ.regRn[15];
XEiJ.regSRT1 = XEiJ.regSRT0 = 0; //srのTビットを消す
if (XEiJ.regSRS == 0) { //ユーザモードのとき
XEiJ.regSRS = XEiJ.REG_SR_S; //スーパーバイザモードへ移行する
XEiJ.mpuUSP = sp; //USPを保存
sp = XEiJ.regSRM != 0 ? XEiJ.mpuMSP : XEiJ.mpuISP; //SSPを復元
if (DataBreakPoint.DBP_ON) {
DataBreakPoint.dbpMemoryMap = DataBreakPoint.dbpSuperMap; //スーパーバイザメモリマップに切り替える
} else {
XEiJ.busMemoryMap = XEiJ.busSuperMap; //スーパーバイザメモリマップに切り替える
}
if (InstructionBreakPoint.IBP_ON) {
InstructionBreakPoint.ibpOp1MemoryMap = InstructionBreakPoint.ibpOp1SuperMap;
}
}
XEiJ.regRn[15] = sp -= 8;
XEiJ.busWw (sp + 6, 0x0000 | vectorNumber << 2); //pushw。フォーマットとベクタオフセットをプッシュする
XEiJ.busWl (sp + 2, XEiJ.regPC); //pushl。pcをプッシュする
XEiJ.busWw (sp, save_sr); //pushw。srをプッシュする
if (XEiJ.regSRM != 0) { //マスタモードのとき
save_sr = XEiJ.regSRT1 | XEiJ.regSRT0 | XEiJ.regSRS | XEiJ.regSRM | XEiJ.regSRI | XEiJ.regCCR;
XEiJ.regSRM = 0; //割り込みモードへ移行する
XEiJ.mpuMSP = sp; //XEiJ.mpuMSPを保存
sp = XEiJ.mpuISP; //SSPを復元
//割り込みスタックにスローアウェイフレームを作成する
XEiJ.regRn[15] = sp -= 8;
XEiJ.busWw (sp + 6, 0x1000 | vectorNumber << 2); //pushw。フォーマットとベクタオフセットをプッシュする
XEiJ.busWl (sp + 2, XEiJ.regPC); //pushl。pcをプッシュする
XEiJ.busWw (sp, save_sr); //pushw。srをプッシュする
}
if (BranchLog.BLG_ON) {
XEiJ.regPC0 = XEiJ.regPC; //rteによる割り込み終了と同時に次の割り込みを受け付けたとき間でpc0を更新しないと2番目の分岐レコードの終了アドレスが1番目と同じになっておかしな分岐レコードができてしまう
}
irpSetPC (XEiJ.busRlsf (XEiJ.mpuVBR + (vectorNumber << 2))); //例外ベクタを取り出してジャンプする
} //irpInterrupt
//irpException (vectorNumber, save_pc, save_sr, format, address)
// 例外処理を開始する
// スタックへのプッシュ、ベクタの取り出し、ジャンプのいずれかでバスエラーまたはアドレスエラーが発生する場合がある
public static void irpException (int vectorNumber, int save_pc, int save_sr, int format, int address) throws M68kException {
int sp = XEiJ.regRn[15];
XEiJ.regSRT1 = XEiJ.regSRT0 = XEiJ.mpuTraceFlag = 0; //srのTビットを消す
if (XEiJ.regSRS == 0) { //ユーザモードのとき
XEiJ.regSRS = XEiJ.REG_SR_S; //スーパーバイザモードへ移行する
XEiJ.mpuUSP = sp; //USPを保存
sp = XEiJ.regSRM != 0 ? XEiJ.mpuMSP : XEiJ.mpuISP; //SSPを復元
if (DataBreakPoint.DBP_ON) {
DataBreakPoint.dbpMemoryMap = DataBreakPoint.dbpSuperMap; //スーパーバイザメモリマップに切り替える
} else {
XEiJ.busMemoryMap = XEiJ.busSuperMap; //スーパーバイザメモリマップに切り替える
}
if (InstructionBreakPoint.IBP_ON) {
InstructionBreakPoint.ibpOp1MemoryMap = InstructionBreakPoint.ibpOp1SuperMap;
}
}
if (format <= 0x1000) {
XEiJ.regRn[15] = sp -= 8;
} else {
XEiJ.regRn[15] = sp -= 12;
XEiJ.busWl (sp + 8, address); //pushl。アドレスをプッシュする
}
XEiJ.busWw (sp + 6, format | vectorNumber << 2); //pushw。フォーマットとベクタオフセットをプッシュする
XEiJ.busWl (sp + 2, save_pc); //pushl。pcをプッシュする
XEiJ.busWw (sp, save_sr); //pushw。srをプッシュする
irpSetPC (XEiJ.busRlsf (XEiJ.mpuVBR + (vectorNumber << 2))); //例外ベクタを取り出してジャンプする
} //irpException
//a = efaAnyByte (ea) //| M+-WXZPI|
// 任意のモードのバイトオペランドの実効アドレスを求める
// (A7)+と-(A7)はA7を奇偶に関わらず2変化させ、跨いだワードの上位バイト(アドレスの小さい方)を参照する
// #<data>はオペコードに続くワードの下位バイトを参照する。上位バイトは不定なので参照してはならない
@SuppressWarnings ("fallthrough") public static int efaAnyByte (int ea) throws M68kException {
int t, w, x;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b011_000: //(A0)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 8]++;
}
//fallthrough
case 0b011_001: //(A1)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 9]++;
}
//fallthrough
case 0b011_010: //(A2)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[10]++;
}
//fallthrough
case 0b011_011: //(A3)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[11]++;
}
//fallthrough
case 0b011_100: //(A4)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[12]++;
}
//fallthrough
case 0b011_101: //(A5)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[13]++;
}
//fallthrough
case 0b011_110: //(A6)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[14]++;
} else {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ea - (0b011_000 - 8)]++;
}
case 0b011_111: //(A7)+
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[15] += 2) - 2;
case 0b100_000: //-(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[ 8];
}
//fallthrough
case 0b100_001: //-(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[ 9];
}
//fallthrough
case 0b100_010: //-(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[10];
}
//fallthrough
case 0b100_011: //-(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[11];
}
//fallthrough
case 0b100_100: //-(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[12];
}
//fallthrough
case 0b100_101: //-(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[13];
}
//fallthrough
case 0b100_110: //-(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[14];
} else {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[ea - (0b100_000 - 8)];
}
case 0b100_111: //-(A7)
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[15] -= 2;
case 0b101_000: //(d16,A0)
case 0b101_001: //(d16,A1)
case 0b101_010: //(d16,A2)
case 0b101_011: //(d16,A3)
case 0b101_100: //(d16,A4)
case 0b101_101: //(d16,A5)
case 0b101_110: //(d16,A6)
case 0b101_111: //(d16,A7)
XEiJ.mpuCycleCount += 8;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse ((XEiJ.regPC += 2) - 2)); //pcws。ワードディスプレースメント
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
}
case 0b110_000: //(d8,A0,Rn.wl)
case 0b110_001: //(d8,A1,Rn.wl)
case 0b110_010: //(d8,A2,Rn.wl)
case 0b110_011: //(d8,A3,Rn.wl)
case 0b110_100: //(d8,A4,Rn.wl)
case 0b110_101: //(d8,A5,Rn.wl)
case 0b110_110: //(d8,A6,Rn.wl)
case 0b110_111: //(d8,A7,Rn.wl)
XEiJ.mpuCycleCount += 10;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
XEiJ.mpuCycleCount += XEiJ.EFA_EXTENSION_CLK[w & 511];
t = (((~w & 0x0180) == 0 ? 0 : //ベースレジスタサプレス
XEiJ.regRn[ea - (0b110_000 - 8)]) //ベースレジスタ
+ (w << 31 - 8 >= 0 ? (byte) w : //バイトディスプレースメント
w << 31 - 5 >= 0 ? 0 : //ヌルベースディスプレースメント
w << 31 - 4 >= 0 ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードベースディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングベースディスプレースメント
x = ((~w & 0x0140) == 0 ? 0 : //インデックスサプレス
(w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12]) //ロングインデックス
<< (w >> 9 & 3)); //スケールファクタ。ワードインデックスのときは符号拡張してから掛ける
return ((w & 0x0103) <= 0x0100 ? t + x : //メモリ間接なし
((XEiJ.TEST_BIT_2_SHIFT ? w << 31 - 2 >= 0 : (w & 4) == 0) ? XEiJ.busRls (t + x) : //プリインデックス
XEiJ.busRls (t) + x) //ポストインデックス
+ ((XEiJ.TEST_BIT_1_SHIFT ? w << 31 - 1 >= 0 : (w & 2) == 0) ? 0 : //ヌルアウタディスプレースメント
(XEiJ.TEST_BIT_0_SHIFT ? w << 31 - 0 >= 0 : (w & 1) == 0) ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードアウタディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングアウタディスプレースメント
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 8;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 12;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
case 0b111_010: //(d16,PC)
XEiJ.mpuCycleCount += 8;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (t //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
case 0b111_011: //(d8,PC,Rn.wl)
XEiJ.mpuCycleCount += 10;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
w = XEiJ.busRwze (t); //pcwz。拡張ワード
XEiJ.mpuCycleCount += XEiJ.EFA_EXTENSION_CLK[w & 511];
t = (((~w & 0x0180) == 0 ? 0 : //ベースレジスタサプレス
t) //ベースレジスタ
+ (w << 31 - 8 >= 0 ? (byte) w : //バイトディスプレースメント
w << 31 - 5 >= 0 ? 0 : //ヌルベースディスプレースメント
w << 31 - 4 >= 0 ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードベースディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングベースディスプレースメント
x = ((~w & 0x0140) == 0 ? 0 : //インデックスサプレス
(w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12]) //ロングインデックス
<< (w >> 9 & 3)); //スケールファクタ。ワードインデックスのときは符号拡張してから掛ける
return ((w & 0x0103) <= 0x0100 ? t + x : //メモリ間接なし
((XEiJ.TEST_BIT_2_SHIFT ? w << 31 - 2 >= 0 : (w & 4) == 0) ? XEiJ.busRls (t + x) : //プリインデックス
XEiJ.busRls (t) + x) //ポストインデックス
+ ((XEiJ.TEST_BIT_1_SHIFT ? w << 31 - 1 >= 0 : (w & 2) == 0) ? 0 : //ヌルアウタディスプレースメント
(XEiJ.TEST_BIT_0_SHIFT ? w << 31 - 0 >= 0 : (w & 1) == 0) ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードアウタディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングアウタディスプレースメント
case 0b111_100: //#<data>
XEiJ.mpuCycleCount += 4;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
return (XEiJ.regPC += 2) - 1; //下位バイト
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return t + 1; //下位バイト
}
} //switch
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaAnyByte
//a = efaMemByte (ea) //| M+-WXZP |
// メモリモードのバイトオペランドの実効アドレスを求める
// efaAnyByteとの違いは#<data>がないこと
@SuppressWarnings ("fallthrough") public static int efaMemByte (int ea) throws M68kException {
int t, w, x;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b011_000: //(A0)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 8]++;
}
//fallthrough
case 0b011_001: //(A1)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 9]++;
}
//fallthrough
case 0b011_010: //(A2)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[10]++;
}
//fallthrough
case 0b011_011: //(A3)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[11]++;
}
//fallthrough
case 0b011_100: //(A4)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[12]++;
}
//fallthrough
case 0b011_101: //(A5)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[13]++;
}
//fallthrough
case 0b011_110: //(A6)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[14]++;
} else {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ea - (0b011_000 - 8)]++;
}
case 0b011_111: //(A7)+
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[15] += 2) - 2;
case 0b100_000: //-(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[ 8];
}
//fallthrough
case 0b100_001: //-(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[ 9];
}
//fallthrough
case 0b100_010: //-(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[10];
}
//fallthrough
case 0b100_011: //-(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[11];
}
//fallthrough
case 0b100_100: //-(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[12];
}
//fallthrough
case 0b100_101: //-(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[13];
}
//fallthrough
case 0b100_110: //-(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[14];
} else {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[ea - (0b100_000 - 8)];
}
case 0b100_111: //-(A7)
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[15] -= 2;
case 0b101_000: //(d16,A0)
case 0b101_001: //(d16,A1)
case 0b101_010: //(d16,A2)
case 0b101_011: //(d16,A3)
case 0b101_100: //(d16,A4)
case 0b101_101: //(d16,A5)
case 0b101_110: //(d16,A6)
case 0b101_111: //(d16,A7)
XEiJ.mpuCycleCount += 8;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse ((XEiJ.regPC += 2) - 2)); //pcws。ワードディスプレースメント
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
}
case 0b110_000: //(d8,A0,Rn.wl)
case 0b110_001: //(d8,A1,Rn.wl)
case 0b110_010: //(d8,A2,Rn.wl)
case 0b110_011: //(d8,A3,Rn.wl)
case 0b110_100: //(d8,A4,Rn.wl)
case 0b110_101: //(d8,A5,Rn.wl)
case 0b110_110: //(d8,A6,Rn.wl)
case 0b110_111: //(d8,A7,Rn.wl)
XEiJ.mpuCycleCount += 10;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
XEiJ.mpuCycleCount += XEiJ.EFA_EXTENSION_CLK[w & 511];
t = (((~w & 0x0180) == 0 ? 0 : //ベースレジスタサプレス
XEiJ.regRn[ea - (0b110_000 - 8)]) //ベースレジスタ
+ (w << 31 - 8 >= 0 ? (byte) w : //バイトディスプレースメント
w << 31 - 5 >= 0 ? 0 : //ヌルベースディスプレースメント
w << 31 - 4 >= 0 ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードベースディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングベースディスプレースメント
x = ((~w & 0x0140) == 0 ? 0 : //インデックスサプレス
(w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12]) //ロングインデックス
<< (w >> 9 & 3)); //スケールファクタ。ワードインデックスのときは符号拡張してから掛ける
return ((w & 0x0103) <= 0x0100 ? t + x : //メモリ間接なし
((XEiJ.TEST_BIT_2_SHIFT ? w << 31 - 2 >= 0 : (w & 4) == 0) ? XEiJ.busRls (t + x) : //プリインデックス
XEiJ.busRls (t) + x) //ポストインデックス
+ ((XEiJ.TEST_BIT_1_SHIFT ? w << 31 - 1 >= 0 : (w & 2) == 0) ? 0 : //ヌルアウタディスプレースメント
(XEiJ.TEST_BIT_0_SHIFT ? w << 31 - 0 >= 0 : (w & 1) == 0) ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードアウタディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングアウタディスプレースメント
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 8;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 12;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
case 0b111_010: //(d16,PC)
XEiJ.mpuCycleCount += 8;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (t //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
case 0b111_011: //(d8,PC,Rn.wl)
XEiJ.mpuCycleCount += 10;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
w = XEiJ.busRwze (t); //pcwz。拡張ワード
XEiJ.mpuCycleCount += XEiJ.EFA_EXTENSION_CLK[w & 511];
t = (((~w & 0x0180) == 0 ? 0 : //ベースレジスタサプレス
t) //ベースレジスタ
+ (w << 31 - 8 >= 0 ? (byte) w : //バイトディスプレースメント
w << 31 - 5 >= 0 ? 0 : //ヌルベースディスプレースメント
w << 31 - 4 >= 0 ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードベースディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングベースディスプレースメント
x = ((~w & 0x0140) == 0 ? 0 : //インデックスサプレス
(w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12]) //ロングインデックス
<< (w >> 9 & 3)); //スケールファクタ。ワードインデックスのときは符号拡張してから掛ける
return ((w & 0x0103) <= 0x0100 ? t + x : //メモリ間接なし
((XEiJ.TEST_BIT_2_SHIFT ? w << 31 - 2 >= 0 : (w & 4) == 0) ? XEiJ.busRls (t + x) : //プリインデックス
XEiJ.busRls (t) + x) //ポストインデックス
+ ((XEiJ.TEST_BIT_1_SHIFT ? w << 31 - 1 >= 0 : (w & 2) == 0) ? 0 : //ヌルアウタディスプレースメント
(XEiJ.TEST_BIT_0_SHIFT ? w << 31 - 0 >= 0 : (w & 1) == 0) ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードアウタディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングアウタディスプレースメント
} //switch
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaMemByte
//a = efaMltByte (ea) //| M+-WXZ |
// メモリ可変モードのバイトオペランドの実効アドレスを求める
// efaMemByteとの違いは(d16,PC)と(d8,PC,Rn.wl)がないこと
@SuppressWarnings ("fallthrough") public static int efaMltByte (int ea) throws M68kException {
int t, w, x;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b011_000: //(A0)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 8]++;
}
//fallthrough
case 0b011_001: //(A1)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 9]++;
}
//fallthrough
case 0b011_010: //(A2)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[10]++;
}
//fallthrough
case 0b011_011: //(A3)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[11]++;
}
//fallthrough
case 0b011_100: //(A4)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[12]++;
}
//fallthrough
case 0b011_101: //(A5)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[13]++;
}
//fallthrough
case 0b011_110: //(A6)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[14]++;
} else {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ea - (0b011_000 - 8)]++;
}
case 0b011_111: //(A7)+
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[15] += 2) - 2;
case 0b100_000: //-(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[ 8];
}
//fallthrough
case 0b100_001: //-(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[ 9];
}
//fallthrough
case 0b100_010: //-(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[10];
}
//fallthrough
case 0b100_011: //-(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[11];
}
//fallthrough
case 0b100_100: //-(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[12];
}
//fallthrough
case 0b100_101: //-(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[13];
}
//fallthrough
case 0b100_110: //-(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[14];
} else {
XEiJ.mpuCycleCount += 6;
return --XEiJ.regRn[ea - (0b100_000 - 8)];
}
case 0b100_111: //-(A7)
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[15] -= 2;
case 0b101_000: //(d16,A0)
case 0b101_001: //(d16,A1)
case 0b101_010: //(d16,A2)
case 0b101_011: //(d16,A3)
case 0b101_100: //(d16,A4)
case 0b101_101: //(d16,A5)
case 0b101_110: //(d16,A6)
case 0b101_111: //(d16,A7)
XEiJ.mpuCycleCount += 8;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse ((XEiJ.regPC += 2) - 2)); //pcws。ワードディスプレースメント
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
}
case 0b110_000: //(d8,A0,Rn.wl)
case 0b110_001: //(d8,A1,Rn.wl)
case 0b110_010: //(d8,A2,Rn.wl)
case 0b110_011: //(d8,A3,Rn.wl)
case 0b110_100: //(d8,A4,Rn.wl)
case 0b110_101: //(d8,A5,Rn.wl)
case 0b110_110: //(d8,A6,Rn.wl)
case 0b110_111: //(d8,A7,Rn.wl)
XEiJ.mpuCycleCount += 10;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
XEiJ.mpuCycleCount += XEiJ.EFA_EXTENSION_CLK[w & 511];
t = (((~w & 0x0180) == 0 ? 0 : //ベースレジスタサプレス
XEiJ.regRn[ea - (0b110_000 - 8)]) //ベースレジスタ
+ (w << 31 - 8 >= 0 ? (byte) w : //バイトディスプレースメント
w << 31 - 5 >= 0 ? 0 : //ヌルベースディスプレースメント
w << 31 - 4 >= 0 ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードベースディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングベースディスプレースメント
x = ((~w & 0x0140) == 0 ? 0 : //インデックスサプレス
(w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12]) //ロングインデックス
<< (w >> 9 & 3)); //スケールファクタ。ワードインデックスのときは符号拡張してから掛ける
return ((w & 0x0103) <= 0x0100 ? t + x : //メモリ間接なし
((XEiJ.TEST_BIT_2_SHIFT ? w << 31 - 2 >= 0 : (w & 4) == 0) ? XEiJ.busRls (t + x) : //プリインデックス
XEiJ.busRls (t) + x) //ポストインデックス
+ ((XEiJ.TEST_BIT_1_SHIFT ? w << 31 - 1 >= 0 : (w & 2) == 0) ? 0 : //ヌルアウタディスプレースメント
(XEiJ.TEST_BIT_0_SHIFT ? w << 31 - 0 >= 0 : (w & 1) == 0) ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードアウタディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングアウタディスプレースメント
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 8;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 12;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
} //switch
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaMltByte
//a = efaCntByte (ea) //| M WXZP |
// 制御モードのロングオペランドの実効アドレスを求める
// efaMemByteとの違いは(Ar)+と-(Ar)がないこと
@SuppressWarnings ("fallthrough") public static int efaCntByte (int ea) throws M68kException {
int t, w, x;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b101_000: //(d16,A0)
case 0b101_001: //(d16,A1)
case 0b101_010: //(d16,A2)
case 0b101_011: //(d16,A3)
case 0b101_100: //(d16,A4)
case 0b101_101: //(d16,A5)
case 0b101_110: //(d16,A6)
case 0b101_111: //(d16,A7)
XEiJ.mpuCycleCount += 8;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse ((XEiJ.regPC += 2) - 2)); //pcws。ワードディスプレースメント
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
}
case 0b110_000: //(d8,A0,Rn.wl)
case 0b110_001: //(d8,A1,Rn.wl)
case 0b110_010: //(d8,A2,Rn.wl)
case 0b110_011: //(d8,A3,Rn.wl)
case 0b110_100: //(d8,A4,Rn.wl)
case 0b110_101: //(d8,A5,Rn.wl)
case 0b110_110: //(d8,A6,Rn.wl)
case 0b110_111: //(d8,A7,Rn.wl)
XEiJ.mpuCycleCount += 10;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
XEiJ.mpuCycleCount += XEiJ.EFA_EXTENSION_CLK[w & 511];
t = (((~w & 0x0180) == 0 ? 0 : //ベースレジスタサプレス
XEiJ.regRn[ea - (0b110_000 - 8)]) //ベースレジスタ
+ (w << 31 - 8 >= 0 ? (byte) w : //バイトディスプレースメント
w << 31 - 5 >= 0 ? 0 : //ヌルベースディスプレースメント
w << 31 - 4 >= 0 ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードベースディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングベースディスプレースメント
x = ((~w & 0x0140) == 0 ? 0 : //インデックスサプレス
(w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12]) //ロングインデックス
<< (w >> 9 & 3)); //スケールファクタ。ワードインデックスのときは符号拡張してから掛ける
return ((w & 0x0103) <= 0x0100 ? t + x : //メモリ間接なし
((XEiJ.TEST_BIT_2_SHIFT ? w << 31 - 2 >= 0 : (w & 4) == 0) ? XEiJ.busRls (t + x) : //プリインデックス
XEiJ.busRls (t) + x) //ポストインデックス
+ ((XEiJ.TEST_BIT_1_SHIFT ? w << 31 - 1 >= 0 : (w & 2) == 0) ? 0 : //ヌルアウタディスプレースメント
(XEiJ.TEST_BIT_0_SHIFT ? w << 31 - 0 >= 0 : (w & 1) == 0) ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードアウタディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングアウタディスプレースメント
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 8;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 12;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
case 0b111_010: //(d16,PC)
XEiJ.mpuCycleCount += 8;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (t //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
case 0b111_011: //(d8,PC,Rn.wl)
XEiJ.mpuCycleCount += 10;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
w = XEiJ.busRwze (t); //pcwz。拡張ワード
XEiJ.mpuCycleCount += XEiJ.EFA_EXTENSION_CLK[w & 511];
t = (((~w & 0x0180) == 0 ? 0 : //ベースレジスタサプレス
t) //ベースレジスタ
+ (w << 31 - 8 >= 0 ? (byte) w : //バイトディスプレースメント
w << 31 - 5 >= 0 ? 0 : //ヌルベースディスプレースメント
w << 31 - 4 >= 0 ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードベースディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングベースディスプレースメント
x = ((~w & 0x0140) == 0 ? 0 : //インデックスサプレス
(w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12]) //ロングインデックス
<< (w >> 9 & 3)); //スケールファクタ。ワードインデックスのときは符号拡張してから掛ける
return ((w & 0x0103) <= 0x0100 ? t + x : //メモリ間接なし
((XEiJ.TEST_BIT_2_SHIFT ? w << 31 - 2 >= 0 : (w & 4) == 0) ? XEiJ.busRls (t + x) : //プリインデックス
XEiJ.busRls (t) + x) //ポストインデックス
+ ((XEiJ.TEST_BIT_1_SHIFT ? w << 31 - 1 >= 0 : (w & 2) == 0) ? 0 : //ヌルアウタディスプレースメント
(XEiJ.TEST_BIT_0_SHIFT ? w << 31 - 0 >= 0 : (w & 1) == 0) ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードアウタディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングアウタディスプレースメント
} //switch
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaCntByte
//a = efaAnyWord (ea) //| M+-WXZPI|
// 任意のモードのワードオペランドの実効アドレスを求める
// efaAnyByteとの違いは(Ar)+と-(Ar)がArを2変化させることと、(A7)+と-(A7)と#<data>の特別な動作がないこと
@SuppressWarnings ("fallthrough") public static int efaAnyWord (int ea) throws M68kException {
int t, w, x;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b011_000: //(A0)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[ 8] += 2) - 2;
}
//fallthrough
case 0b011_001: //(A1)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[ 9] += 2) - 2;
}
//fallthrough
case 0b011_010: //(A2)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[10] += 2) - 2;
}
//fallthrough
case 0b011_011: //(A3)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[11] += 2) - 2;
}
//fallthrough
case 0b011_100: //(A4)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[12] += 2) - 2;
}
//fallthrough
case 0b011_101: //(A5)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[13] += 2) - 2;
}
//fallthrough
case 0b011_110: //(A6)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[14] += 2) - 2;
}
//fallthrough
case 0b011_111: //(A7)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[15] += 2) - 2;
} else {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[ea - (0b011_000 - 8)] += 2) - 2;
}
case 0b100_000: //-(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[ 8] -= 2;
}
//fallthrough
case 0b100_001: //-(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[ 9] -= 2;
}
//fallthrough
case 0b100_010: //-(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[10] -= 2;
}
//fallthrough
case 0b100_011: //-(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[11] -= 2;
}
//fallthrough
case 0b100_100: //-(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[12] -= 2;
}
//fallthrough
case 0b100_101: //-(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[13] -= 2;
}
//fallthrough
case 0b100_110: //-(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[14] -= 2;
}
//fallthrough
case 0b100_111: //-(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[15] -= 2;
} else {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[ea - (0b100_000 - 8)] -= 2;
}
case 0b101_000: //(d16,A0)
case 0b101_001: //(d16,A1)
case 0b101_010: //(d16,A2)
case 0b101_011: //(d16,A3)
case 0b101_100: //(d16,A4)
case 0b101_101: //(d16,A5)
case 0b101_110: //(d16,A6)
case 0b101_111: //(d16,A7)
XEiJ.mpuCycleCount += 8;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse ((XEiJ.regPC += 2) - 2)); //pcws。ワードディスプレースメント
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
}
case 0b110_000: //(d8,A0,Rn.wl)
case 0b110_001: //(d8,A1,Rn.wl)
case 0b110_010: //(d8,A2,Rn.wl)
case 0b110_011: //(d8,A3,Rn.wl)
case 0b110_100: //(d8,A4,Rn.wl)
case 0b110_101: //(d8,A5,Rn.wl)
case 0b110_110: //(d8,A6,Rn.wl)
case 0b110_111: //(d8,A7,Rn.wl)
XEiJ.mpuCycleCount += 10;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
XEiJ.mpuCycleCount += XEiJ.EFA_EXTENSION_CLK[w & 511];
t = (((~w & 0x0180) == 0 ? 0 : //ベースレジスタサプレス
XEiJ.regRn[ea - (0b110_000 - 8)]) //ベースレジスタ
+ (w << 31 - 8 >= 0 ? (byte) w : //バイトディスプレースメント
w << 31 - 5 >= 0 ? 0 : //ヌルベースディスプレースメント
w << 31 - 4 >= 0 ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードベースディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングベースディスプレースメント
x = ((~w & 0x0140) == 0 ? 0 : //インデックスサプレス
(w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12]) //ロングインデックス
<< (w >> 9 & 3)); //スケールファクタ。ワードインデックスのときは符号拡張してから掛ける
return ((w & 0x0103) <= 0x0100 ? t + x : //メモリ間接なし
((XEiJ.TEST_BIT_2_SHIFT ? w << 31 - 2 >= 0 : (w & 4) == 0) ? XEiJ.busRls (t + x) : //プリインデックス
XEiJ.busRls (t) + x) //ポストインデックス
+ ((XEiJ.TEST_BIT_1_SHIFT ? w << 31 - 1 >= 0 : (w & 2) == 0) ? 0 : //ヌルアウタディスプレースメント
(XEiJ.TEST_BIT_0_SHIFT ? w << 31 - 0 >= 0 : (w & 1) == 0) ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードアウタディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングアウタディスプレースメント
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 8;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 12;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
case 0b111_010: //(d16,PC)
XEiJ.mpuCycleCount += 8;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (t //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
case 0b111_011: //(d8,PC,Rn.wl)
XEiJ.mpuCycleCount += 10;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
w = XEiJ.busRwze (t); //pcwz。拡張ワード
XEiJ.mpuCycleCount += XEiJ.EFA_EXTENSION_CLK[w & 511];
t = (((~w & 0x0180) == 0 ? 0 : //ベースレジスタサプレス
t) //ベースレジスタ
+ (w << 31 - 8 >= 0 ? (byte) w : //バイトディスプレースメント
w << 31 - 5 >= 0 ? 0 : //ヌルベースディスプレースメント
w << 31 - 4 >= 0 ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードベースディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングベースディスプレースメント
x = ((~w & 0x0140) == 0 ? 0 : //インデックスサプレス
(w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12]) //ロングインデックス
<< (w >> 9 & 3)); //スケールファクタ。ワードインデックスのときは符号拡張してから掛ける
return ((w & 0x0103) <= 0x0100 ? t + x : //メモリ間接なし
((XEiJ.TEST_BIT_2_SHIFT ? w << 31 - 2 >= 0 : (w & 4) == 0) ? XEiJ.busRls (t + x) : //プリインデックス
XEiJ.busRls (t) + x) //ポストインデックス
+ ((XEiJ.TEST_BIT_1_SHIFT ? w << 31 - 1 >= 0 : (w & 2) == 0) ? 0 : //ヌルアウタディスプレースメント
(XEiJ.TEST_BIT_0_SHIFT ? w << 31 - 0 >= 0 : (w & 1) == 0) ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードアウタディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングアウタディスプレースメント
case 0b111_100: //#<data>
XEiJ.mpuCycleCount += 4;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
return (XEiJ.regPC += 2) - 2;
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return t;
}
} //switch
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaAnyWord
//a = efaMemWord (ea) //| M+-WXZP |
// メモリモードのワードオペランドの実効アドレスを求める
// efaAnyWordとの違いは#<data>がないこと
@SuppressWarnings ("fallthrough") public static int efaMemWord (int ea) throws M68kException {
int t, w, x;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b011_000: //(A0)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[ 8] += 2) - 2;
}
//fallthrough
case 0b011_001: //(A1)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[ 9] += 2) - 2;
}
//fallthrough
case 0b011_010: //(A2)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[10] += 2) - 2;
}
//fallthrough
case 0b011_011: //(A3)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[11] += 2) - 2;
}
//fallthrough
case 0b011_100: //(A4)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[12] += 2) - 2;
}
//fallthrough
case 0b011_101: //(A5)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[13] += 2) - 2;
}
//fallthrough
case 0b011_110: //(A6)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[14] += 2) - 2;
}
//fallthrough
case 0b011_111: //(A7)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[15] += 2) - 2;
} else {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[ea - (0b011_000 - 8)] += 2) - 2;
}
case 0b100_000: //-(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[ 8] -= 2;
}
//fallthrough
case 0b100_001: //-(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[ 9] -= 2;
}
//fallthrough
case 0b100_010: //-(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[10] -= 2;
}
//fallthrough
case 0b100_011: //-(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[11] -= 2;
}
//fallthrough
case 0b100_100: //-(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[12] -= 2;
}
//fallthrough
case 0b100_101: //-(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[13] -= 2;
}
//fallthrough
case 0b100_110: //-(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[14] -= 2;
}
//fallthrough
case 0b100_111: //-(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[15] -= 2;
} else {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[ea - (0b100_000 - 8)] -= 2;
}
case 0b101_000: //(d16,A0)
case 0b101_001: //(d16,A1)
case 0b101_010: //(d16,A2)
case 0b101_011: //(d16,A3)
case 0b101_100: //(d16,A4)
case 0b101_101: //(d16,A5)
case 0b101_110: //(d16,A6)
case 0b101_111: //(d16,A7)
XEiJ.mpuCycleCount += 8;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse ((XEiJ.regPC += 2) - 2)); //pcws。ワードディスプレースメント
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
}
case 0b110_000: //(d8,A0,Rn.wl)
case 0b110_001: //(d8,A1,Rn.wl)
case 0b110_010: //(d8,A2,Rn.wl)
case 0b110_011: //(d8,A3,Rn.wl)
case 0b110_100: //(d8,A4,Rn.wl)
case 0b110_101: //(d8,A5,Rn.wl)
case 0b110_110: //(d8,A6,Rn.wl)
case 0b110_111: //(d8,A7,Rn.wl)
XEiJ.mpuCycleCount += 10;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
XEiJ.mpuCycleCount += XEiJ.EFA_EXTENSION_CLK[w & 511];
t = (((~w & 0x0180) == 0 ? 0 : //ベースレジスタサプレス
XEiJ.regRn[ea - (0b110_000 - 8)]) //ベースレジスタ
+ (w << 31 - 8 >= 0 ? (byte) w : //バイトディスプレースメント
w << 31 - 5 >= 0 ? 0 : //ヌルベースディスプレースメント
w << 31 - 4 >= 0 ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードベースディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングベースディスプレースメント
x = ((~w & 0x0140) == 0 ? 0 : //インデックスサプレス
(w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12]) //ロングインデックス
<< (w >> 9 & 3)); //スケールファクタ。ワードインデックスのときは符号拡張してから掛ける
return ((w & 0x0103) <= 0x0100 ? t + x : //メモリ間接なし
((XEiJ.TEST_BIT_2_SHIFT ? w << 31 - 2 >= 0 : (w & 4) == 0) ? XEiJ.busRls (t + x) : //プリインデックス
XEiJ.busRls (t) + x) //ポストインデックス
+ ((XEiJ.TEST_BIT_1_SHIFT ? w << 31 - 1 >= 0 : (w & 2) == 0) ? 0 : //ヌルアウタディスプレースメント
(XEiJ.TEST_BIT_0_SHIFT ? w << 31 - 0 >= 0 : (w & 1) == 0) ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードアウタディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングアウタディスプレースメント
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 8;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 12;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
case 0b111_010: //(d16,PC)
XEiJ.mpuCycleCount += 8;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (t //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
case 0b111_011: //(d8,PC,Rn.wl)
XEiJ.mpuCycleCount += 10;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
w = XEiJ.busRwze (t); //pcwz。拡張ワード
XEiJ.mpuCycleCount += XEiJ.EFA_EXTENSION_CLK[w & 511];
t = (((~w & 0x0180) == 0 ? 0 : //ベースレジスタサプレス
t) //ベースレジスタ
+ (w << 31 - 8 >= 0 ? (byte) w : //バイトディスプレースメント
w << 31 - 5 >= 0 ? 0 : //ヌルベースディスプレースメント
w << 31 - 4 >= 0 ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードベースディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングベースディスプレースメント
x = ((~w & 0x0140) == 0 ? 0 : //インデックスサプレス
(w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12]) //ロングインデックス
<< (w >> 9 & 3)); //スケールファクタ。ワードインデックスのときは符号拡張してから掛ける
return ((w & 0x0103) <= 0x0100 ? t + x : //メモリ間接なし
((XEiJ.TEST_BIT_2_SHIFT ? w << 31 - 2 >= 0 : (w & 4) == 0) ? XEiJ.busRls (t + x) : //プリインデックス
XEiJ.busRls (t) + x) //ポストインデックス
+ ((XEiJ.TEST_BIT_1_SHIFT ? w << 31 - 1 >= 0 : (w & 2) == 0) ? 0 : //ヌルアウタディスプレースメント
(XEiJ.TEST_BIT_0_SHIFT ? w << 31 - 0 >= 0 : (w & 1) == 0) ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードアウタディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングアウタディスプレースメント
} //switch
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaMemWord
//a = efaMltWord (ea) //| M+-WXZ |
// メモリ可変モードのワードオペランドの実効アドレスを求める
// efaMemWordとの違いは(d16,PC)と(d8,PC,Rn.wl)がないこと
@SuppressWarnings ("fallthrough") public static int efaMltWord (int ea) throws M68kException {
int t, w, x;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b011_000: //(A0)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[ 8] += 2) - 2;
}
//fallthrough
case 0b011_001: //(A1)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[ 9] += 2) - 2;
}
//fallthrough
case 0b011_010: //(A2)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[10] += 2) - 2;
}
//fallthrough
case 0b011_011: //(A3)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[11] += 2) - 2;
}
//fallthrough
case 0b011_100: //(A4)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[12] += 2) - 2;
}
//fallthrough
case 0b011_101: //(A5)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[13] += 2) - 2;
}
//fallthrough
case 0b011_110: //(A6)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[14] += 2) - 2;
}
//fallthrough
case 0b011_111: //(A7)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[15] += 2) - 2;
} else {
XEiJ.mpuCycleCount += 4;
return (XEiJ.regRn[ea - (0b011_000 - 8)] += 2) - 2;
}
case 0b100_000: //-(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[ 8] -= 2;
}
//fallthrough
case 0b100_001: //-(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[ 9] -= 2;
}
//fallthrough
case 0b100_010: //-(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[10] -= 2;
}
//fallthrough
case 0b100_011: //-(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[11] -= 2;
}
//fallthrough
case 0b100_100: //-(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[12] -= 2;
}
//fallthrough
case 0b100_101: //-(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[13] -= 2;
}
//fallthrough
case 0b100_110: //-(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[14] -= 2;
}
//fallthrough
case 0b100_111: //-(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[15] -= 2;
} else {
XEiJ.mpuCycleCount += 6;
return XEiJ.regRn[ea - (0b100_000 - 8)] -= 2;
}
case 0b101_000: //(d16,A0)
case 0b101_001: //(d16,A1)
case 0b101_010: //(d16,A2)
case 0b101_011: //(d16,A3)
case 0b101_100: //(d16,A4)
case 0b101_101: //(d16,A5)
case 0b101_110: //(d16,A6)
case 0b101_111: //(d16,A7)
XEiJ.mpuCycleCount += 8;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse ((XEiJ.regPC += 2) - 2)); //pcws。ワードディスプレースメント
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
}
case 0b110_000: //(d8,A0,Rn.wl)
case 0b110_001: //(d8,A1,Rn.wl)
case 0b110_010: //(d8,A2,Rn.wl)
case 0b110_011: //(d8,A3,Rn.wl)
case 0b110_100: //(d8,A4,Rn.wl)
case 0b110_101: //(d8,A5,Rn.wl)
case 0b110_110: //(d8,A6,Rn.wl)
case 0b110_111: //(d8,A7,Rn.wl)
XEiJ.mpuCycleCount += 10;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
XEiJ.mpuCycleCount += XEiJ.EFA_EXTENSION_CLK[w & 511];
t = (((~w & 0x0180) == 0 ? 0 : //ベースレジスタサプレス
XEiJ.regRn[ea - (0b110_000 - 8)]) //ベースレジスタ
+ (w << 31 - 8 >= 0 ? (byte) w : //バイトディスプレースメント
w << 31 - 5 >= 0 ? 0 : //ヌルベースディスプレースメント
w << 31 - 4 >= 0 ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードベースディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングベースディスプレースメント
x = ((~w & 0x0140) == 0 ? 0 : //インデックスサプレス
(w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12]) //ロングインデックス
<< (w >> 9 & 3)); //スケールファクタ。ワードインデックスのときは符号拡張してから掛ける
return ((w & 0x0103) <= 0x0100 ? t + x : //メモリ間接なし
((XEiJ.TEST_BIT_2_SHIFT ? w << 31 - 2 >= 0 : (w & 4) == 0) ? XEiJ.busRls (t + x) : //プリインデックス
XEiJ.busRls (t) + x) //ポストインデックス
+ ((XEiJ.TEST_BIT_1_SHIFT ? w << 31 - 1 >= 0 : (w & 2) == 0) ? 0 : //ヌルアウタディスプレースメント
(XEiJ.TEST_BIT_0_SHIFT ? w << 31 - 0 >= 0 : (w & 1) == 0) ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードアウタディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングアウタディスプレースメント
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 8;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 12;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
} //switch
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaMltWord
//a = efaCntWord (ea) //| M WXZP |
// 制御モードのワードオペランドの実効アドレスを求める
// efaMemWordとの違いは(Ar)+と-(Ar)がないこと
// efaCntLongとの違いはサイクル数のみ
@SuppressWarnings ("fallthrough") public static int efaCntWord (int ea) throws M68kException {
int t, w, x;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b101_000: //(d16,A0)
case 0b101_001: //(d16,A1)
case 0b101_010: //(d16,A2)
case 0b101_011: //(d16,A3)
case 0b101_100: //(d16,A4)
case 0b101_101: //(d16,A5)
case 0b101_110: //(d16,A6)
case 0b101_111: //(d16,A7)
XEiJ.mpuCycleCount += 8;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse ((XEiJ.regPC += 2) - 2)); //pcws。ワードディスプレースメント
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
}
case 0b110_000: //(d8,A0,Rn.wl)
case 0b110_001: //(d8,A1,Rn.wl)
case 0b110_010: //(d8,A2,Rn.wl)
case 0b110_011: //(d8,A3,Rn.wl)
case 0b110_100: //(d8,A4,Rn.wl)
case 0b110_101: //(d8,A5,Rn.wl)
case 0b110_110: //(d8,A6,Rn.wl)
case 0b110_111: //(d8,A7,Rn.wl)
XEiJ.mpuCycleCount += 10;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
XEiJ.mpuCycleCount += XEiJ.EFA_EXTENSION_CLK[w & 511];
t = (((~w & 0x0180) == 0 ? 0 : //ベースレジスタサプレス
XEiJ.regRn[ea - (0b110_000 - 8)]) //ベースレジスタ
+ (w << 31 - 8 >= 0 ? (byte) w : //バイトディスプレースメント
w << 31 - 5 >= 0 ? 0 : //ヌルベースディスプレースメント
w << 31 - 4 >= 0 ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードベースディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングベースディスプレースメント
x = ((~w & 0x0140) == 0 ? 0 : //インデックスサプレス
(w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12]) //ロングインデックス
<< (w >> 9 & 3)); //スケールファクタ。ワードインデックスのときは符号拡張してから掛ける
return ((w & 0x0103) <= 0x0100 ? t + x : //メモリ間接なし
((XEiJ.TEST_BIT_2_SHIFT ? w << 31 - 2 >= 0 : (w & 4) == 0) ? XEiJ.busRls (t + x) : //プリインデックス
XEiJ.busRls (t) + x) //ポストインデックス
+ ((XEiJ.TEST_BIT_1_SHIFT ? w << 31 - 1 >= 0 : (w & 2) == 0) ? 0 : //ヌルアウタディスプレースメント
(XEiJ.TEST_BIT_0_SHIFT ? w << 31 - 0 >= 0 : (w & 1) == 0) ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードアウタディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングアウタディスプレースメント
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 8;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 12;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
case 0b111_010: //(d16,PC)
XEiJ.mpuCycleCount += 8;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (t //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
case 0b111_011: //(d8,PC,Rn.wl)
XEiJ.mpuCycleCount += 10;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
w = XEiJ.busRwze (t); //pcwz。拡張ワード
XEiJ.mpuCycleCount += XEiJ.EFA_EXTENSION_CLK[w & 511];
t = (((~w & 0x0180) == 0 ? 0 : //ベースレジスタサプレス
t) //ベースレジスタ
+ (w << 31 - 8 >= 0 ? (byte) w : //バイトディスプレースメント
w << 31 - 5 >= 0 ? 0 : //ヌルベースディスプレースメント
w << 31 - 4 >= 0 ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードベースディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングベースディスプレースメント
x = ((~w & 0x0140) == 0 ? 0 : //インデックスサプレス
(w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12]) //ロングインデックス
<< (w >> 9 & 3)); //スケールファクタ。ワードインデックスのときは符号拡張してから掛ける
return ((w & 0x0103) <= 0x0100 ? t + x : //メモリ間接なし
((XEiJ.TEST_BIT_2_SHIFT ? w << 31 - 2 >= 0 : (w & 4) == 0) ? XEiJ.busRls (t + x) : //プリインデックス
XEiJ.busRls (t) + x) //ポストインデックス
+ ((XEiJ.TEST_BIT_1_SHIFT ? w << 31 - 1 >= 0 : (w & 2) == 0) ? 0 : //ヌルアウタディスプレースメント
(XEiJ.TEST_BIT_0_SHIFT ? w << 31 - 0 >= 0 : (w & 1) == 0) ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードアウタディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングアウタディスプレースメント
} //switch
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaCntWord
//a = efaCltWord (ea) //| M WXZ |
// 制御可変モードのワードオペランドの実効アドレスを求める
// efaCntWordとの違いは(d16,PC)と(d8,PC,Rn.wl)がないこと
// efaCltLongとの違いはサイクル数のみ
@SuppressWarnings ("fallthrough") public static int efaCltWord (int ea) throws M68kException {
int t, w, x;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 4;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b101_000: //(d16,A0)
case 0b101_001: //(d16,A1)
case 0b101_010: //(d16,A2)
case 0b101_011: //(d16,A3)
case 0b101_100: //(d16,A4)
case 0b101_101: //(d16,A5)
case 0b101_110: //(d16,A6)
case 0b101_111: //(d16,A7)
XEiJ.mpuCycleCount += 8;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse ((XEiJ.regPC += 2) - 2)); //pcws。ワードディスプレースメント
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (XEiJ.regRn[ea - (0b101_000 - 8)] //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
}
case 0b110_000: //(d8,A0,Rn.wl)
case 0b110_001: //(d8,A1,Rn.wl)
case 0b110_010: //(d8,A2,Rn.wl)
case 0b110_011: //(d8,A3,Rn.wl)
case 0b110_100: //(d8,A4,Rn.wl)
case 0b110_101: //(d8,A5,Rn.wl)
case 0b110_110: //(d8,A6,Rn.wl)
case 0b110_111: //(d8,A7,Rn.wl)
XEiJ.mpuCycleCount += 10;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
w = XEiJ.busRwze ((XEiJ.regPC += 2) - 2); //pcwz。拡張ワード
} else {
w = XEiJ.regPC;
XEiJ.regPC = w + 2;
w = XEiJ.busRwze (w); //pcwz。拡張ワード
}
XEiJ.mpuCycleCount += XEiJ.EFA_EXTENSION_CLK[w & 511];
t = (((~w & 0x0180) == 0 ? 0 : //ベースレジスタサプレス
XEiJ.regRn[ea - (0b110_000 - 8)]) //ベースレジスタ
+ (w << 31 - 8 >= 0 ? (byte) w : //バイトディスプレースメント
w << 31 - 5 >= 0 ? 0 : //ヌルベースディスプレースメント
w << 31 - 4 >= 0 ? XEiJ.busRwse ((XEiJ.regPC += 2) - 2) : //pcws。ワードベースディスプレースメント
XEiJ.busRlse ((XEiJ.regPC += 4) - 4))); //pcls。ロングベースディスプレースメント
x = ((~w & 0x0140) == 0 ? 0 : //インデックスサプレス