xeij/MC68010.java (2/2)
1 2 // 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6800) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
if (XEiJ.MPU_OMIT_OFFSET_READ) {
//リードを省略する
} else {
XEiJ.busRws (XEiJ.regPC);
}
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>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | 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> |-|01----|-|---*-|-----| |0110_100_011_sss_sss
//BNVS.S <label> |A|01----|-|---*-|-----| |0110_100_011_sss_sss [BVC.S <label>]
//JBNVS.S <label> |A|01----|-|---*-|-----| |0110_100_011_sss_sss [BVC.S <label>]
//JBVC.S <label> |A|01----|-|---*-|-----| |0110_100_011_sss_sss [BVC.S <label>]
public static void irpBvcs () 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; //オフセット
//MC68000のBRA.S/BSR.S/Bcc.Sは分岐するとき分岐しない方の直後のワードをリードする
// 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //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
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//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
} else { //Bcc.Sでジャンプ
//MC68000のBRA.S/BSR.S/Bcc.Sは分岐するとき分岐しない方の直後のワードをリードする
// 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6900) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
if (XEiJ.MPU_OMIT_OFFSET_READ) {
//リードを省略する
} else {
XEiJ.busRws (XEiJ.regPC);
}
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>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | 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> |-|01----|-|---*-|-----| |0110_100_111_sss_sss
//BNVC.S <label> |A|01----|-|---*-|-----| |0110_100_111_sss_sss [BVS.S <label>]
//JBNVC.S <label> |A|01----|-|---*-|-----| |0110_100_111_sss_sss [BVS.S <label>]
//JBVS.S <label> |A|01----|-|---*-|-----| |0110_100_111_sss_sss [BVS.S <label>]
public static void irpBvss () 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; //オフセット
//MC68000のBRA.S/BSR.S/Bcc.Sは分岐するとき分岐しない方の直後のワードをリードする
// 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //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
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//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
} else { //Bcc.Sでジャンプ
//MC68000のBRA.S/BSR.S/Bcc.Sは分岐するとき分岐しない方の直後のワードをリードする
// 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6a00) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
if (XEiJ.MPU_OMIT_OFFSET_READ) {
//リードを省略する
} else {
XEiJ.busRws (XEiJ.regPC);
}
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>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | 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> |-|01----|-|-*---|-----| |0110_101_011_sss_sss
//BNMI.S <label> |A|01----|-|-*---|-----| |0110_101_011_sss_sss [BPL.S <label>]
//JBNMI.S <label> |A|01----|-|-*---|-----| |0110_101_011_sss_sss [BPL.S <label>]
//JBPL.S <label> |A|01----|-|-*---|-----| |0110_101_011_sss_sss [BPL.S <label>]
public static void irpBpls () 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; //オフセット
//MC68000のBRA.S/BSR.S/Bcc.Sは分岐するとき分岐しない方の直後のワードをリードする
// 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //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
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//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
} else { //Bcc.Sでジャンプ
//MC68000のBRA.S/BSR.S/Bcc.Sは分岐するとき分岐しない方の直後のワードをリードする
// 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6b00) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
if (XEiJ.MPU_OMIT_OFFSET_READ) {
//リードを省略する
} else {
XEiJ.busRws (XEiJ.regPC);
}
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>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | 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> |-|01----|-|-*---|-----| |0110_101_111_sss_sss
//BNPL.S <label> |A|01----|-|-*---|-----| |0110_101_111_sss_sss [BMI.S <label>]
//JBMI.S <label> |A|01----|-|-*---|-----| |0110_101_111_sss_sss [BMI.S <label>]
//JBNPL.S <label> |A|01----|-|-*---|-----| |0110_101_111_sss_sss [BMI.S <label>]
public static void irpBmis () 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; //オフセット
//MC68000のBRA.S/BSR.S/Bcc.Sは分岐するとき分岐しない方の直後のワードをリードする
// 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //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
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//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
} else { //Bcc.Sでジャンプ
//MC68000のBRA.S/BSR.S/Bcc.Sは分岐するとき分岐しない方の直後のワードをリードする
// 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6c00) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
if (XEiJ.MPU_OMIT_OFFSET_READ) {
//リードを省略する
} else {
XEiJ.busRws (XEiJ.regPC);
}
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>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | 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> |-|01----|-|-*-*-|-----| |0110_110_011_sss_sss
//BNLT.S <label> |A|01----|-|-*-*-|-----| |0110_110_011_sss_sss [BGE.S <label>]
//JBGE.S <label> |A|01----|-|-*-*-|-----| |0110_110_011_sss_sss [BGE.S <label>]
//JBNLT.S <label> |A|01----|-|-*-*-|-----| |0110_110_011_sss_sss [BGE.S <label>]
public static void irpBges () 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; //オフセット
//MC68000のBRA.S/BSR.S/Bcc.Sは分岐するとき分岐しない方の直後のワードをリードする
// 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //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
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//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
} else { //Bcc.Sでジャンプ
//MC68000のBRA.S/BSR.S/Bcc.Sは分岐するとき分岐しない方の直後のワードをリードする
// 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6d00) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
if (XEiJ.MPU_OMIT_OFFSET_READ) {
//リードを省略する
} else {
XEiJ.busRws (XEiJ.regPC);
}
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>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | 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> |-|01----|-|-*-*-|-----| |0110_110_111_sss_sss
//BNGE.S <label> |A|01----|-|-*-*-|-----| |0110_110_111_sss_sss [BLT.S <label>]
//JBLT.S <label> |A|01----|-|-*-*-|-----| |0110_110_111_sss_sss [BLT.S <label>]
//JBNGE.S <label> |A|01----|-|-*-*-|-----| |0110_110_111_sss_sss [BLT.S <label>]
public static void irpBlts () 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; //オフセット
//MC68000のBRA.S/BSR.S/Bcc.Sは分岐するとき分岐しない方の直後のワードをリードする
// 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //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
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//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
} else { //Bcc.Sでジャンプ
//MC68000のBRA.S/BSR.S/Bcc.Sは分岐するとき分岐しない方の直後のワードをリードする
// 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6e00) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
if (XEiJ.MPU_OMIT_OFFSET_READ) {
//リードを省略する
} else {
XEiJ.busRws (XEiJ.regPC);
}
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>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | 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> |-|01----|-|-***-|-----| |0110_111_011_sss_sss
//BNLE.S <label> |A|01----|-|-***-|-----| |0110_111_011_sss_sss [BGT.S <label>]
//JBGT.S <label> |A|01----|-|-***-|-----| |0110_111_011_sss_sss [BGT.S <label>]
//JBNLE.S <label> |A|01----|-|-***-|-----| |0110_111_011_sss_sss [BGT.S <label>]
public static void irpBgts () 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; //オフセット
//MC68000のBRA.S/BSR.S/Bcc.Sは分岐するとき分岐しない方の直後のワードをリードする
// 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //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
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//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
} else { //Bcc.Sでジャンプ
//MC68000のBRA.S/BSR.S/Bcc.Sは分岐するとき分岐しない方の直後のワードをリードする
// 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
}
irpSetPC (t + s); //pc0+2+オフセット
} else if (XEiJ.regOC == 0x6f00) { //Bcc.Wで通過
XEiJ.mpuCycleCount += 12;
if (XEiJ.MPU_OMIT_OFFSET_READ) {
//リードを省略する
} else {
XEiJ.busRws (XEiJ.regPC);
}
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>]
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | 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> |-|01----|-|-***-|-----| |0110_111_111_sss_sss
//BNGT.S <label> |A|01----|-|-***-|-----| |0110_111_111_sss_sss [BLE.S <label>]
//JBLE.S <label> |A|01----|-|-***-|-----| |0110_111_111_sss_sss [BLE.S <label>]
//JBNGT.S <label> |A|01----|-|-***-|-----| |0110_111_111_sss_sss [BLE.S <label>]
public static void irpBles () 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; //オフセット
//MC68000のBRA.S/BSR.S/Bcc.Sは分岐するとき分岐しない方の直後のワードをリードする
// 2MB搭載機で$1FFFFEに無限ループ$60FE(BRA.S (*))を書いて飛び込むと$200000でバスエラーが出る
if (XEiJ.MPU_OMIT_EXTRA_READ) {
//! 軽量化。リードを省略する
} else {
XEiJ.busRwse (t); //pcws
}
irpSetPC (t + s); //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
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//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 常にクリア
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]; //被除数
XEiJ.mpuCycleCount += irpDivuCyclesModified (x, y);
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のときセット、さもなくばクリア
XEiJ.REG_CCR_V //Vは常にセット
); //Cは常にクリア
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 オーバーフローあり/オーバーフローなし
} //irpDivuWord
//DIVUの実行時間
// 以下に実効アドレスの時間を加える
// ゼロ除算のとき38
// オーバーフローのとき10
// 正常終了のとき76+
// 商のビット15~1について
// 被除数のビット16が1で商が1のとき0
// 被除数のビット16が0で商が1のとき2
// 被除数のビット16が0で商が0のとき4
// 補足
// 商のビット0を計算に含めると最大140になりマニュアルと一致する
// 参考
// https://www.atari-forum.com/viewtopic.php?t=6484
public static int irpDivuCyclesModified (int x, int y) {
y &= 0xffff; //ゼロ拡張
if (y == 0) { //ゼロ除算
return 38;
}
int r = x >>> 16; //余り。符号なし右シフト
if (y <= r) { //オーバーフロー
return 10;
}
int c = 76;
for (int i = 15; 0 < i; i--) { //ビット0を含まない
r = r << 1 | ((x >> i) & 1);
if (0x10000 <= r) { //被除数のビット16が1で商が1
r -= y;
} else if (y <= r) { //被除数のビット16が0で商が1
r -= y;
c += 2;
} else { //被除数のビット16が0で商が0
c += 4;
}
}
return c;
}
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
// | | 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
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//OR.W Dq,<ea> |-|012346|-|-UUUU|-**00| M+-WXZ |1000_qqq_101_mmm_rrr
public static void irpOrToMemWord () throws M68kException {
XEiJ.mpuCycleCount += 8;
int ea = XEiJ.regOC & 63;
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
} //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
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//OR.L Dq,<ea> |-|012346|-|-UUUU|-**00| M+-WXZ |1000_qqq_110_mmm_rrr
public static void irpOrToMemLong () throws M68kException {
XEiJ.mpuCycleCount += 12;
int ea = XEiJ.regOC & 63;
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
} //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
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]; //被除数
XEiJ.mpuCycleCount += irpDivsCycles (x, y);
if (y == 0) { //ゼロ除算
//Dqは変化しない
//!!! MC68030はゼロ除算のときオペランド以外の要因でZとVが変化する。その要因がわからないとZとVを正確に再現することができない
XEiJ.regCCR = (XEiJ.regCCR & XEiJ.REG_CCR_X | //Xは変化しない
//Nは常にクリア
XEiJ.REG_CCR_Z | //Zは常にセット
(x == 0x00008000 ? ~XEiJ.regCCR & XEiJ.REG_CCR_V : (0 <= x && x != 0x7fffffff) || x == 0x80000000 ? XEiJ.REG_CCR_V : XEiJ.regCCR & XEiJ.REG_CCR_V) //Vは被除数が$00008000のとき反転、被除数が$7fffffffを除く正または$80000000のときセット、さもなくば変化しない
); //Cは常にクリア
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 オーバーフローあり/オーバーフローなし
} //irpDivsWord
//DIVSの実行時間
// 以下に実効アドレスの時間を加える
// ゼロ除算のとき38
// 符号なしオーバーフローのとき
// 被除数が正のとき16
// 被除数が負のとき18
// 正常終了または符号ありオーバーフローのとき
// 被除数が正で除数が正のとき120+
// 被除数が正で除数が負のとき122+
// 被除数が負で除数が正のとき126+
// 被除数が負で除数が負のとき124+
// 符号なし商のビット15~1について
// 符号なし商が1のとき0
// 符号なし商が0のとき2
// 補足
// 符号なし商のビット0を計算に含めると最大158になりマニュアルと一致する
// 参考
// https://www.atari-forum.com/viewtopic.php?t=6484
public static int irpDivsCycles (int x, int y) {
y = (short) y; //符号拡張
if (y == 0) { //ゼロ除算
return 38;
}
//符号あり除算だと0x80000000/0xffffffffが0x00000000になる環境があるので
//符号なし除算を用いる。JavaはInteger.divideUnsigned
//符号なし商に0x80000000が含まれることに注意
int q = Integer.divideUnsigned ((x < 0 ? -x : x), (y < 0 ? -y : y));
if ((q & 0xffff0000) != 0) { //符号なしオーバーフロー。0xffff<qは不可
return x < 0 ? 18 : 16;
}
int t = ~q;
t = (t & 0x5554) + ((t >> 1) & 0x5555); //0x5554に注意。ビット0を含まない
t = (t & 0x3333) + ((t >> 2) & 0x3333);
t = (t & 0x0F0F) + ((t >> 4) & 0x0F0F);
t = (t & 0x00FF) + ((t >> 8) & 0x00FF);
return (x < 0 ? y < 0 ? 124 : 126 : y < 0 ? 122 : 120) + (t << 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
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//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.regSRS | XEiJ.regSRI | XEiJ.regCCR;
int sp = XEiJ.regRn[15];
XEiJ.regSRT1 = XEiJ.mpuTraceFlag = 0; //srのTビットを消す
if (XEiJ.regSRS == 0) { //ユーザモードのとき
XEiJ.regSRS = XEiJ.REG_SR_S; //スーパーバイザモードへ移行する
XEiJ.mpuUSP = sp; //USPを保存
sp = XEiJ.mpuISP; //SSPを復元
if (DataBreakPoint.DBP_ON) {
DataBreakPoint.dbpMemoryMap = DataBreakPoint.dbpSuperMap; //スーパーバイザメモリマップに切り替える
} else {
XEiJ.busMemoryMap = XEiJ.busSuperMap; //スーパーバイザメモリマップに切り替える
}
if (InstructionBreakPoint.IBP_ON) {
InstructionBreakPoint.ibpOp1MemoryMap = InstructionBreakPoint.ibpOp1SuperMap;
}
}
int vectorOffset = M68kException.M6E_LINE_1010_EMULATOR << 2; //vector offset
XEiJ.regRn[15] = sp -= 8; //short format
XEiJ.busWw (sp + 6, 0x0000 | vectorOffset); //format and vector offset
XEiJ.busWl (sp + 2, XEiJ.regPC0); //program counter
XEiJ.busWw (sp, save_sr); //status register
irpSetPC (XEiJ.busRlsf (XEiJ.mpuVBR + vectorOffset)); //例外ベクタを取り出してジャンプする
} else {
irpException (M68kException.M6E_LINE_1010_EMULATOR, XEiJ.regPC0, XEiJ.regSRT1 | XEiJ.regSRS | XEiJ.regSRI | XEiJ.regCCR); //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
} //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
} //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 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (byte) (x << 7 - y | (0xff & 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 >>> 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 += 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 & 1) & (XEiJ.REG_CCR_X | XEiJ.REG_CCR_C); //XとCは最後に押し出されたビット
break;
case 0b001_000 >> 3: //LSR.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 == 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 += 8 + 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 += 8 + 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 += 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 = 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 += 8 + (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 += 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 = (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 += 8 + (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 + 2 + ((y = (XEiJ.regOC >> 9) - 1 & 7) << 1); //y=data-1=1-1~8-1
XEiJ.regRn[rrr] = ~0xff & x | 0xff & (z = (byte) (x << y + 1 | (0xff & x) >>> 7 - 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
//------------------------------------------------+-+------+-+-----+-----+----------+-------------------------------------
//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 {
XEiJ.mpuCycleCount += 34;
if (XEiJ.MPU_INLINE_EXCEPTION) {
int save_sr = XEiJ.regSRT1 | XEiJ.regSRS | XEiJ.regSRI | XEiJ.regCCR;
int sp = XEiJ.regRn[15];
XEiJ.regSRT1 = XEiJ.mpuTraceFlag = 0; //srのTビットを消す
if (XEiJ.regSRS == 0) { //ユーザモードのとき
XEiJ.regSRS = XEiJ.REG_SR_S; //スーパーバイザモードへ移行する
XEiJ.mpuUSP = sp; //USPを保存
sp = XEiJ.mpuISP; //SSPを復元
if (DataBreakPoint.DBP_ON) {
DataBreakPoint.dbpMemoryMap = DataBreakPoint.dbpSuperMap; //スーパーバイザメモリマップに切り替える
} else {
XEiJ.busMemoryMap = XEiJ.busSuperMap; //スーパーバイザメモリマップに切り替える
}
if (InstructionBreakPoint.IBP_ON) {
InstructionBreakPoint.ibpOp1MemoryMap = InstructionBreakPoint.ibpOp1SuperMap;
}
}
int vectorOffset = M68kException.M6E_LINE_1111_EMULATOR << 2; //vector offset
XEiJ.regRn[15] = sp -= 8; //short format
XEiJ.busWw (sp + 6, 0x0000 | vectorOffset); //format and vector offset
XEiJ.busWl (sp + 2, XEiJ.regPC0); //program counter
XEiJ.busWw (sp, save_sr); //status register
irpSetPC (XEiJ.busRlsf (XEiJ.mpuVBR + vectorOffset)); //例外ベクタを取り出してジャンプする
} else {
irpException (M68kException.M6E_LINE_1111_EMULATOR, XEiJ.regPC0, XEiJ.regSRT1 | XEiJ.regSRS | XEiJ.regSRI | XEiJ.regCCR); //pcは命令の先頭
}
} //irpFline
//irpIllegal ()
// オペコードの上位10bitで分類されなかった未実装命令
// 0x4afcのILLEGAL命令はここには来ない
public static void irpIllegal () throws M68kException {
if (true) {
XEiJ.mpuCycleCount += 34;
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 (true) {
//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 (false) {
//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 (true) {
//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 (false) {
//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:
XEiJ.mpuCycleCount += 34;
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;
M68kException.m6eDirection = XEiJ.MPU_WR_READ;
M68kException.m6eSize = XEiJ.MPU_SS_LONG;
throw M68kException.m6eSignal;
}
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;
if ((XEiJ.regSRS = XEiJ.REG_SR_S & newSr) == 0) { //スーパーバイザモード→ユーザモード
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;
}
}
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.regSRS | XEiJ.regSRI | XEiJ.regCCR;
XEiJ.regSRI = level << 8; //割り込みマスクを要求されたレベルに変更する
XEiJ.mpuIMR = 0x7f >> level;
XEiJ.mpuISR |= 0x80 >> level;
int sp = XEiJ.regRn[15];
XEiJ.regSRT1 = 0; //srのTビットを消す
if (XEiJ.regSRS == 0) { //ユーザモードのとき
XEiJ.regSRS = XEiJ.REG_SR_S; //スーパーバイザモードへ移行する
XEiJ.mpuUSP = sp; //USPを保存
sp = XEiJ.mpuISP; //SSPを復元
if (DataBreakPoint.DBP_ON) {
DataBreakPoint.dbpMemoryMap = DataBreakPoint.dbpSuperMap; //スーパーバイザメモリマップに切り替える
} else {
XEiJ.busMemoryMap = XEiJ.busSuperMap; //スーパーバイザメモリマップに切り替える
}
if (InstructionBreakPoint.IBP_ON) {
InstructionBreakPoint.ibpOp1MemoryMap = InstructionBreakPoint.ibpOp1SuperMap;
}
}
int vectorOffset = vectorNumber << 2; //vector offset
XEiJ.regRn[15] = sp -= 8; //short format
XEiJ.busWw (sp + 6, 0x0000 | vectorOffset); //format and vector offset
XEiJ.busWl (sp + 2, XEiJ.regPC); //program counter
XEiJ.busWw (sp, save_sr); //status register
if (BranchLog.BLG_ON) {
XEiJ.regPC0 = XEiJ.regPC; //rteによる割り込み終了と同時に次の割り込みを受け付けたとき間でpc0を更新しないと2番目の分岐レコードの終了アドレスが1番目と同じになっておかしな分岐レコードができてしまう
}
irpSetPC (XEiJ.busRlsf (XEiJ.mpuVBR + vectorOffset)); //例外ベクタを取り出してジャンプする
} //irpInterrupt
//irpException (vectorNumber, save_pc, save_sr)
// 例外処理を開始する
// スタックへのプッシュ、ベクタの取り出し、ジャンプのいずれかでバスエラーまたはアドレスエラーが発生する場合がある
public static void irpException (int vectorNumber, int save_pc, int save_sr) throws M68kException {
int sp = XEiJ.regRn[15];
XEiJ.regSRT1 = XEiJ.mpuTraceFlag = 0; //srのTビットを消す
if (XEiJ.regSRS == 0) { //ユーザモードのとき
XEiJ.regSRS = XEiJ.REG_SR_S; //スーパーバイザモードへ移行する
XEiJ.mpuUSP = sp; //USPを保存
sp = XEiJ.mpuISP; //SSPを復元
if (DataBreakPoint.DBP_ON) {
DataBreakPoint.dbpMemoryMap = DataBreakPoint.dbpSuperMap; //スーパーバイザメモリマップに切り替える
} else {
XEiJ.busMemoryMap = XEiJ.busSuperMap; //スーパーバイザメモリマップに切り替える
}
if (InstructionBreakPoint.IBP_ON) {
InstructionBreakPoint.ibpOp1MemoryMap = InstructionBreakPoint.ibpOp1SuperMap;
}
}
int vectorOffset = vectorNumber << 2; //vector offset
XEiJ.regRn[15] = sp -= 8; //short format
XEiJ.busWw (sp + 6, 0x0000 | vectorOffset); //format and vector offset
XEiJ.busWl (sp + 2, save_pc); //program counter
XEiJ.busWw (sp, save_sr); //status register
irpSetPC (XEiJ.busRlsf (XEiJ.mpuVBR + vectorOffset)); //例外ベクタを取り出してジャンプする
} //irpException
//a = efaAnyByte (ea) //| M+-WXZPI|
// 任意のモードのバイトオペランドの実効アドレスを求める
// (A7)+と-(A7)はA7を奇偶に関わらず2変化させ、跨いだワードの上位バイト(アドレスの小さい方)を参照する
// #<data>はオペコードに続くワードの下位バイトを参照する。上位バイトは不定なので参照してはならない
@SuppressWarnings ("fallthrough") public static int efaAnyByte (int ea) throws M68kException {
int t, w;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
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。拡張ワード
return (t //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
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
XEiJ.mpuCycleCount += 34;
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;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
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。拡張ワード
return (t //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
} //switch
XEiJ.mpuCycleCount += 34;
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;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
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
XEiJ.mpuCycleCount += 34;
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;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
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。拡張ワード
return (t //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
} //switch
XEiJ.mpuCycleCount += 34;
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;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
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。拡張ワード
return (t //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
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
XEiJ.mpuCycleCount += 34;
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;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
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。拡張ワード
return (t //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
} //switch
XEiJ.mpuCycleCount += 34;
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;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
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
XEiJ.mpuCycleCount += 34;
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaMltWord
//a = efaCntWord (ea) //| M WXZP |
// 制御モードのワードオペランドの実効アドレスを求める
// efaMemWordとの違いは(Ar)+と-(Ar)がないこと
@SuppressWarnings ("fallthrough") public static int efaCntWord (int ea) throws M68kException {
int t, w;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
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。拡張ワード
return (t //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
} //switch
XEiJ.mpuCycleCount += 34;
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaCntWord
//a = efaCltWord (ea) //| M WXZ |
// 制御可変モードのワードオペランドの実効アドレスを求める
// efaCntWordとの違いは(d16,PC)と(d8,PC,Rn.wl)がないこと
@SuppressWarnings ("fallthrough") public static int efaCltWord (int ea) throws M68kException {
int t, w;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
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
XEiJ.mpuCycleCount += 34;
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaCltWord
//a = efaAnyLong (ea) //| M+-WXZPI|
// 任意のモードのロングオペランドの実効アドレスを求める
// efaAnyWordとの違いは(Ar)+と-(Ar)がArを4変化させることと、#<data>がPCを4変化させることと、
// オペランドのアクセスが1ワード増える分の4サイクルが追加されていること
@SuppressWarnings ("fallthrough") public static int efaAnyLong (int ea) throws M68kException {
int t, w;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b011_000: //(A0)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[ 8] += 4) - 4;
}
//fallthrough
case 0b011_001: //(A1)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[ 9] += 4) - 4;
}
//fallthrough
case 0b011_010: //(A2)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[10] += 4) - 4;
}
//fallthrough
case 0b011_011: //(A3)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[11] += 4) - 4;
}
//fallthrough
case 0b011_100: //(A4)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[12] += 4) - 4;
}
//fallthrough
case 0b011_101: //(A5)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[13] += 4) - 4;
}
//fallthrough
case 0b011_110: //(A6)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[14] += 4) - 4;
}
//fallthrough
case 0b011_111: //(A7)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[15] += 4) - 4;
} else {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[ea - (0b011_000 - 8)] += 4) - 4;
}
case 0b100_000: //-(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[ 8] -= 4;
}
//fallthrough
case 0b100_001: //-(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[ 9] -= 4;
}
//fallthrough
case 0b100_010: //-(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[10] -= 4;
}
//fallthrough
case 0b100_011: //-(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[11] -= 4;
}
//fallthrough
case 0b100_100: //-(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[12] -= 4;
}
//fallthrough
case 0b100_101: //-(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[13] -= 4;
}
//fallthrough
case 0b100_110: //-(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[14] -= 4;
}
//fallthrough
case 0b100_111: //-(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[15] -= 4;
} else {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[ea - (0b100_000 - 8)] -= 4;
}
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 += 12;
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 += 14;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 12;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 16;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
case 0b111_010: //(d16,PC)
XEiJ.mpuCycleCount += 12;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (t //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
case 0b111_011: //(d8,PC,Rn.wl)
XEiJ.mpuCycleCount += 14;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
w = XEiJ.busRwze (t); //pcwz。拡張ワード
return (t //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
case 0b111_100: //#<data>
XEiJ.mpuCycleCount += 8;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
return (XEiJ.regPC += 4) - 4;
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 4;
return t;
}
} //switch
XEiJ.mpuCycleCount += 34;
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaAnyLong
//a = efaMemLong (ea) //| M+-WXZP |
// メモリモードのロングオペランドの実効アドレスを求める
// efaAnyLongとの違いは#<data>がないこと
@SuppressWarnings ("fallthrough") public static int efaMemLong (int ea) throws M68kException {
int t, w;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b011_000: //(A0)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[ 8] += 4) - 4;
}
//fallthrough
case 0b011_001: //(A1)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[ 9] += 4) - 4;
}
//fallthrough
case 0b011_010: //(A2)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[10] += 4) - 4;
}
//fallthrough
case 0b011_011: //(A3)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[11] += 4) - 4;
}
//fallthrough
case 0b011_100: //(A4)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[12] += 4) - 4;
}
//fallthrough
case 0b011_101: //(A5)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[13] += 4) - 4;
}
//fallthrough
case 0b011_110: //(A6)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[14] += 4) - 4;
}
//fallthrough
case 0b011_111: //(A7)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[15] += 4) - 4;
} else {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[ea - (0b011_000 - 8)] += 4) - 4;
}
case 0b100_000: //-(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[ 8] -= 4;
}
//fallthrough
case 0b100_001: //-(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[ 9] -= 4;
}
//fallthrough
case 0b100_010: //-(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[10] -= 4;
}
//fallthrough
case 0b100_011: //-(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[11] -= 4;
}
//fallthrough
case 0b100_100: //-(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[12] -= 4;
}
//fallthrough
case 0b100_101: //-(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[13] -= 4;
}
//fallthrough
case 0b100_110: //-(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[14] -= 4;
}
//fallthrough
case 0b100_111: //-(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[15] -= 4;
} else {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[ea - (0b100_000 - 8)] -= 4;
}
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 += 12;
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 += 14;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 12;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 16;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
case 0b111_010: //(d16,PC)
XEiJ.mpuCycleCount += 12;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (t //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
case 0b111_011: //(d8,PC,Rn.wl)
XEiJ.mpuCycleCount += 14;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
w = XEiJ.busRwze (t); //pcwz。拡張ワード
return (t //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
} //switch
XEiJ.mpuCycleCount += 34;
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaMemLong
//a = efaMltLong (ea) //| M+-WXZ |
// メモリ可変モードのロングオペランドの実効アドレスを求める
// efaMemLongとの違いは(d16,PC)と(d8,PC,Rn.wl)がないこと
@SuppressWarnings ("fallthrough") public static int efaMltLong (int ea) throws M68kException {
int t, w;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b011_000: //(A0)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[ 8] += 4) - 4;
}
//fallthrough
case 0b011_001: //(A1)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[ 9] += 4) - 4;
}
//fallthrough
case 0b011_010: //(A2)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[10] += 4) - 4;
}
//fallthrough
case 0b011_011: //(A3)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[11] += 4) - 4;
}
//fallthrough
case 0b011_100: //(A4)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[12] += 4) - 4;
}
//fallthrough
case 0b011_101: //(A5)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[13] += 4) - 4;
}
//fallthrough
case 0b011_110: //(A6)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[14] += 4) - 4;
}
//fallthrough
case 0b011_111: //(A7)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[15] += 4) - 4;
} else {
XEiJ.mpuCycleCount += 8;
return (XEiJ.regRn[ea - (0b011_000 - 8)] += 4) - 4;
}
case 0b100_000: //-(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[ 8] -= 4;
}
//fallthrough
case 0b100_001: //-(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[ 9] -= 4;
}
//fallthrough
case 0b100_010: //-(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[10] -= 4;
}
//fallthrough
case 0b100_011: //-(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[11] -= 4;
}
//fallthrough
case 0b100_100: //-(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[12] -= 4;
}
//fallthrough
case 0b100_101: //-(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[13] -= 4;
}
//fallthrough
case 0b100_110: //-(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[14] -= 4;
}
//fallthrough
case 0b100_111: //-(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[15] -= 4;
} else {
XEiJ.mpuCycleCount += 10;
return XEiJ.regRn[ea - (0b100_000 - 8)] -= 4;
}
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 += 12;
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 += 14;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 12;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 16;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
} //switch
XEiJ.mpuCycleCount += 34;
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaMltLong
//a = efaCntLong (ea) //| M WXZP |
// 制御モードのロングオペランドの実効アドレスを求める
// efaMemLongとの違いは(Ar)+と-(Ar)がないこと
@SuppressWarnings ("fallthrough") public static int efaCntLong (int ea) throws M68kException {
int t, w;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 8;
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 += 12;
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 += 14;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 12;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 16;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
case 0b111_010: //(d16,PC)
XEiJ.mpuCycleCount += 12;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (t //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
case 0b111_011: //(d8,PC,Rn.wl)
XEiJ.mpuCycleCount += 14;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
w = XEiJ.busRwze (t); //pcwz。拡張ワード
return (t //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
} //switch
XEiJ.mpuCycleCount += 34;
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaCntLong
//a = efaCltLong (ea) //| M WXZ |
// 制御可変モードのワードオペランドの実効アドレスを求める
// efaCntLongとの違いは(d16,PC)と(d8,PC,Rn.wl)がないこと
@SuppressWarnings ("fallthrough") public static int efaCltLong (int ea) throws M68kException {
int t, w;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 8;
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 += 12;
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 += 14;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 12;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 16;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
} //switch
XEiJ.mpuCycleCount += 34;
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaCltLong
//a = efaAnyQuad (ea) //| M+-WXZPI|
// 任意のモードのクワッドオペランドの実効アドレスを求める
// efaAnyLongとの違いは(Ar)+と-(Ar)がArを8変化させることと、#<data>がPCを8変化させることと、
// オペランドのアクセスが2ワード増える分の8サイクルが追加されていること
@SuppressWarnings ("fallthrough") public static int efaAnyQuad (int ea) throws M68kException {
int t, w;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b011_000: //(A0)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[ 8] += 8) - 8;
}
//fallthrough
case 0b011_001: //(A1)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[ 9] += 8) - 8;
}
//fallthrough
case 0b011_010: //(A2)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[10] += 8) - 8;
}
//fallthrough
case 0b011_011: //(A3)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[11] += 8) - 8;
}
//fallthrough
case 0b011_100: //(A4)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[12] += 8) - 8;
}
//fallthrough
case 0b011_101: //(A5)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[13] += 8) - 8;
}
//fallthrough
case 0b011_110: //(A6)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[14] += 8) - 8;
}
//fallthrough
case 0b011_111: //(A7)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[15] += 8) - 8;
} else {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[ea - (0b011_000 - 8)] += 8) - 8;
}
case 0b100_000: //-(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[ 8] -= 8;
}
//fallthrough
case 0b100_001: //-(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[ 9] -= 8;
}
//fallthrough
case 0b100_010: //-(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[10] -= 8;
}
//fallthrough
case 0b100_011: //-(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[11] -= 8;
}
//fallthrough
case 0b100_100: //-(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[12] -= 8;
}
//fallthrough
case 0b100_101: //-(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[13] -= 8;
}
//fallthrough
case 0b100_110: //-(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[14] -= 8;
}
//fallthrough
case 0b100_111: //-(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[15] -= 8;
} else {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[ea - (0b100_000 - 8)] -= 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 += 20;
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 += 22;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 20;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 24;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
case 0b111_010: //(d16,PC)
XEiJ.mpuCycleCount += 20;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (t //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
case 0b111_011: //(d8,PC,Rn.wl)
XEiJ.mpuCycleCount += 22;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
w = XEiJ.busRwze (t); //pcwz。拡張ワード
return (t //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
case 0b111_100: //#<data>
XEiJ.mpuCycleCount += 16;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
return (XEiJ.regPC += 8) - 8;
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 8;
return t;
}
} //switch
XEiJ.mpuCycleCount += 34;
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaAnyQuad
//a = efaMltQuad (ea) //| M+-WXZ |
// メモリ可変モードのクワッドオペランドの実効アドレスを求める
// efaMltLongとの違いは(Ar)+と-(Ar)がArを8変化させることと、#<data>がPCを8変化させることと、
// オペランドのアクセスが2ワード増える分の8サイクルが追加されていること
@SuppressWarnings ("fallthrough") public static int efaMltQuad (int ea) throws M68kException {
int t, w;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 16;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b011_000: //(A0)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[ 8] += 8) - 8;
}
//fallthrough
case 0b011_001: //(A1)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[ 9] += 8) - 8;
}
//fallthrough
case 0b011_010: //(A2)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[10] += 8) - 8;
}
//fallthrough
case 0b011_011: //(A3)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[11] += 8) - 8;
}
//fallthrough
case 0b011_100: //(A4)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[12] += 8) - 8;
}
//fallthrough
case 0b011_101: //(A5)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[13] += 8) - 8;
}
//fallthrough
case 0b011_110: //(A6)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[14] += 8) - 8;
}
//fallthrough
case 0b011_111: //(A7)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[15] += 8) - 8;
} else {
XEiJ.mpuCycleCount += 16;
return (XEiJ.regRn[ea - (0b011_000 - 8)] += 8) - 8;
}
case 0b100_000: //-(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[ 8] -= 8;
}
//fallthrough
case 0b100_001: //-(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[ 9] -= 8;
}
//fallthrough
case 0b100_010: //-(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[10] -= 8;
}
//fallthrough
case 0b100_011: //-(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[11] -= 8;
}
//fallthrough
case 0b100_100: //-(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[12] -= 8;
}
//fallthrough
case 0b100_101: //-(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[13] -= 8;
}
//fallthrough
case 0b100_110: //-(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[14] -= 8;
}
//fallthrough
case 0b100_111: //-(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[15] -= 8;
} else {
XEiJ.mpuCycleCount += 18;
return XEiJ.regRn[ea - (0b100_000 - 8)] -= 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 += 20;
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 += 22;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 20;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 24;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
} //switch
XEiJ.mpuCycleCount += 34;
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaMltQuad
//a = efaAnyExtd (ea) //| M+-WXZPI|
// 任意のモードのエクステンデッドオペランドの実効アドレスを求める
// efaAnyQuadとの違いは(Ar)+と-(Ar)がArを12変化させることと、#<data>がPCを12変化させることと、
// オペランドのアクセスが2ワード増える分の8サイクルが追加されていること
@SuppressWarnings ("fallthrough") public static int efaAnyExtd (int ea) throws M68kException {
int t, w;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b011_000: //(A0)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[ 8] += 12) - 12;
}
//fallthrough
case 0b011_001: //(A1)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[ 9] += 12) - 12;
}
//fallthrough
case 0b011_010: //(A2)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[10] += 12) - 12;
}
//fallthrough
case 0b011_011: //(A3)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[11] += 12) - 12;
}
//fallthrough
case 0b011_100: //(A4)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[12] += 12) - 12;
}
//fallthrough
case 0b011_101: //(A5)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[13] += 12) - 12;
}
//fallthrough
case 0b011_110: //(A6)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[14] += 12) - 12;
}
//fallthrough
case 0b011_111: //(A7)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[15] += 12) - 12;
} else {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[ea - (0b011_000 - 8)] += 12) - 12;
}
case 0b100_000: //-(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 26;
return XEiJ.regRn[ 8] -= 12;
}
//fallthrough
case 0b100_001: //-(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 26;
return XEiJ.regRn[ 9] -= 12;
}
//fallthrough
case 0b100_010: //-(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 26;
return XEiJ.regRn[10] -= 12;
}
//fallthrough
case 0b100_011: //-(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 26;
return XEiJ.regRn[11] -= 12;
}
//fallthrough
case 0b100_100: //-(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 26;
return XEiJ.regRn[12] -= 12;
}
//fallthrough
case 0b100_101: //-(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 26;
return XEiJ.regRn[13] -= 12;
}
//fallthrough
case 0b100_110: //-(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 26;
return XEiJ.regRn[14] -= 12;
}
//fallthrough
case 0b100_111: //-(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 26;
return XEiJ.regRn[15] -= 12;
} else {
XEiJ.mpuCycleCount += 26;
return XEiJ.regRn[ea - (0b100_000 - 8)] -= 12;
}
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 += 28;
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 += 30;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 28;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 32;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
case 0b111_010: //(d16,PC)
XEiJ.mpuCycleCount += 28;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (t //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
case 0b111_011: //(d8,PC,Rn.wl)
XEiJ.mpuCycleCount += 30;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
w = XEiJ.busRwze (t); //pcwz。拡張ワード
return (t //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
case 0b111_100: //#<data>
XEiJ.mpuCycleCount += 24;
if (XEiJ.MPU_COMPOUND_POSTINCREMENT) {
return (XEiJ.regPC += 12) - 12;
} else {
t = XEiJ.regPC;
XEiJ.regPC = t + 12;
return t;
}
} //switch
XEiJ.mpuCycleCount += 34;
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaAnyExtd
//a = efaMltExtd (ea) //| M+-WXZ |
// メモリ可変モードのエクステンデッドオペランドの実効アドレスを求める
// efaMltQuadとの違いは(Ar)+と-(Ar)がArを12変化させることと、#<data>がPCを12変化させることと、
// オペランドのアクセスが2ワード増える分の8サイクルが追加されていること
@SuppressWarnings ("fallthrough") public static int efaMltExtd (int ea) throws M68kException {
int t, w;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 24;
return XEiJ.regRn[ea - (0b010_000 - 8)];
}
case 0b011_000: //(A0)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[ 8] += 12) - 12;
}
//fallthrough
case 0b011_001: //(A1)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[ 9] += 12) - 12;
}
//fallthrough
case 0b011_010: //(A2)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[10] += 12) - 12;
}
//fallthrough
case 0b011_011: //(A3)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[11] += 12) - 12;
}
//fallthrough
case 0b011_100: //(A4)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[12] += 12) - 12;
}
//fallthrough
case 0b011_101: //(A5)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[13] += 12) - 12;
}
//fallthrough
case 0b011_110: //(A6)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[14] += 12) - 12;
}
//fallthrough
case 0b011_111: //(A7)+
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[15] += 12) - 12;
} else {
XEiJ.mpuCycleCount += 24;
return (XEiJ.regRn[ea - (0b011_000 - 8)] += 12) - 12;
}
case 0b100_000: //-(A0)
case 0b100_001: //-(A1)
case 0b100_010: //-(A2)
case 0b100_011: //-(A3)
case 0b100_100: //-(A4)
case 0b100_101: //-(A5)
case 0b100_110: //-(A6)
case 0b100_111: //-(A7)
XEiJ.mpuCycleCount += 26;
return XEiJ.regRn[ea - (0b100_000 - 8)] -= 12;
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 += 28;
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 += 30;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 28;
return XEiJ.busRwse ((XEiJ.regPC += 2) - 2); //pcws
case 0b111_001: //(xxx).L
XEiJ.mpuCycleCount += 32;
return XEiJ.busRlse ((XEiJ.regPC += 4) - 4); //pcls
} //switch
XEiJ.mpuCycleCount += 34;
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaMltExtd
//a = efaLeaPea (ea) //| M WXZP |
// LEA命令とPEA命令のオペランドの実効アドレスを求める
// efaCntWordとの違いはサイクル数のみ
// LEA命令のベースサイクル数4を含んでいるのでLEA命令ではベースサイクル数を加えなくてよい
// PEA命令のベースサイクル数は12-4=8
@SuppressWarnings ("fallthrough") public static int efaLeaPea (int ea) throws M68kException {
int t, w;
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 += 12;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
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 += 12;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
w = XEiJ.busRwze (t); //pcwz。拡張ワード
return (t //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
} //switch
XEiJ.mpuCycleCount += 34;
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaLeaPea
//a = efaJmpJsr (ea) //| M WXZP |
// JMP命令とJSR命令のオペランドの実効アドレスを求める
// efaCntWordとの違いはサイクル数のみ
// JMP命令のベースサイクル数8を含んでいるのでJMP命令ではベースサイクル数を加えなくてよい
// JSR命令のベースサイクル数は16-8=8
@SuppressWarnings ("fallthrough") public static int efaJmpJsr (int ea) throws M68kException {
int t, w;
switch (ea) {
case 0b010_000: //(A0)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[ 8];
}
//fallthrough
case 0b010_001: //(A1)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[ 9];
}
//fallthrough
case 0b010_010: //(A2)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[10];
}
//fallthrough
case 0b010_011: //(A3)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[11];
}
//fallthrough
case 0b010_100: //(A4)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[12];
}
//fallthrough
case 0b010_101: //(A5)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[13];
}
//fallthrough
case 0b010_110: //(A6)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[14];
}
//fallthrough
case 0b010_111: //(A7)
if (XEiJ.EFA_SEPARATE_AR) {
XEiJ.mpuCycleCount += 8;
return XEiJ.regRn[15];
} else {
XEiJ.mpuCycleCount += 8;
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 += 10;
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 += 14;
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。拡張ワード
}
return (XEiJ.regRn[ea - (0b110_000 - 8)] //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
case 0b111_000: //(xxx).W
XEiJ.mpuCycleCount += 10;
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 += 10;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
return (t //ベースレジスタ
+ XEiJ.busRwse (t)); //pcws。ワードディスプレースメント
case 0b111_011: //(d8,PC,Rn.wl)
XEiJ.mpuCycleCount += 14;
t = XEiJ.regPC;
XEiJ.regPC = t + 2;
w = XEiJ.busRwze (t); //pcwz。拡張ワード
return (t //ベースレジスタ
+ (byte) w //バイトディスプレースメント
+ (w << 31 - 11 >= 0 ? (short) XEiJ.regRn[w >> 12] : //ワードインデックス
XEiJ.regRn[w >> 12])); //ロングインデックス
} //switch
XEiJ.mpuCycleCount += 34;
M68kException.m6eNumber = M68kException.M6E_ILLEGAL_INSTRUCTION;
throw M68kException.m6eSignal;
} //efaJmpJsr
} //class MC68010