|
|
nono 1.3.0
//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//
// EA は大別して6種類。
//
// |d m rxwp | 制御 CalcCtrl サイズ不問
// |dam+-rxw | 可変 CalcData B/W/L
// | m rxwp | MMU CalcMMU サイズ不問
// |dam+-rxwpi| FPU CalcFPU B/W/L/S/D/X/P
// |d m+-rxwpi| データ FetchData B/W/L
// |dam+-rxwpi| All FetchAll B/W/L
//
// CalcCtrl はユーザーズマニュアルで「制御(Control)」と呼ばれている
// グループで、デスティネーション側のため EA の計算のみ。
// また (An)+/-(An) を含まないため、サイズに関係なく1種類だけでよい。
//
// CalcData はユーザーズマニュアルで「可変」と呼ばれているグループで、
// デスティネーション側のため EA の計算のみ。サイズは B/W/L。
// (An)+/-(An) ならレジスタを保存する。
//
// CalcMMU は対 68030 MMU 命令用に勝手に用意したもの。
//
// CalcFPU は対 FPU 用。ソースであっても CalcFPU を使用する。
// サイズは B/W/L/S/D/X/P。
// (An)+/-(An) ならレジスタを保存する。
// フェッチサイクルは別途存在するはずだが不詳。
//
// FetchData はユーザーズマニュアルで「データ(Data)」と呼ばれている
// グループで、ソース側のため EA 計算および値の取得。サイズは B/W/L。
// (An)+/-(An) ならレジスタを保存する。
//
// FetchAll はユーザーズマニュアルのここには記載がないグループで、
// ソース側のため EA 計算および値の取得。サイズは B/W/L。
// (An)+/-(An) ならレジスタを保存する。
//
// CalcCtrl、CalcData でアドレッシングモードに D や A が含まれている場合は
// その命令のデスティネーションに Dn、An が指定できるという意味であり、
// EA 処理であるここには関係ない。
// EA 計算より前に呼出側で条件分けして処理すること。
//
// CalcCtrl、CalcData と FetchData には (*) 印の例外があるので留意。
//
// (CalcCtrl)
// | m rxwp | CMP2/CHK2
// | m rxwp | JMP/JSR
// | m rxwp | LEA/PEA
// |d m rxwp | BFEXT*/BFFFO/BFTST
// |d m rxw | (*) BFCHG/BFCLR/BFINS/BFSET <ea>{#o:#w}
//
// (CalcData)
// | m+-rxw | ADD/SUB/CMP Dx,<ea>
// | m+-rxw | CAS/TAS <ea>
// | m+-rxw | MOVES <ea>,Rn
// | m+-rxw | shift/rotate.W <ea>
// | m+-rxw | BCHG/BCLR/BSET src,<ea>
// |d m+-rxw | ADDI/SUBI Dx,<ea>
// |d m+-rxw | NBCD <ea>
// |d m+-rxw | AND/OR/EOR Dx,<ea>
// |d m+-rxw | CLR/NEG/NEGX/NOT/TST/Scc <ea>
// |d m+-rxw | MOVE CCR/SR,<ea>
// |dam+-rxw | ADDQ/SUBQ #qqq,<ea>
// |dam+-rxw | (*) MOVE の dst 側。EA の分類的には CalcData だが、
// 下位6ビットの IR ではないので、cea_data_NN() ではなく
// 各々 cea_XXXX() のほうを個別に呼ぶこと。
//
// (CalcMMU)
// | m rxw | MMU
//
// (CalcFPU)
// |d m+-rxw | FScc.B <ea>
// |dam+-rxw | FMOVE.f FPn,<ea>
// |dam+-rxw | FMOVE.L ctl,<ea>
// |dam+-rxw | FMOVEM.L ctl,<ea>
// |d m+-rxwpi| Fgen <ea>,FPn
// |d m+-rxwpi| FMOVE.f <ea>,FPn
// |dam+-rxwpi| FMOVE.L <ea>,ctl
// |dam+-rxwpi| FMOVEM.L <ea>,ctl
// 実際にどのアドレッシングモードが有効かどうかは極力個別の命令内で判断する?
// ここは実行サイクル数的な分類。
//
// (FetchData)
// |d m+-rxwpi| AND/OR/CHK <ea>,Dn
// |d m+-rxwpi| MOVE.B <ea>,dst
// |d m+-rxwpi| MOVE <ea>,CCR/SR
// |d m+-rxwpi| MUL*/DIV* <ea>,Dn
// |d m+-rxwp | (*) TST.B <ea>
// |d m+-rxwp | (*) CMPI #<data>,<ea>
// | m+-rxwp | (*) BTST.B #<data>,<ea>
// | m+-rxwpi| (*) BTST.B Dx,<ea>
//
// (FetchAll)
// |dam+-rxwpi| ADD/SUB/CMP <ea>,Dn
// |dam+-rxwpi| MOVEA/ADDA/SUBA/CMPA <ea>,An
// |dam+-rxwpi| TST.WL <ea>
// |dam+-rxwpi| MOVE.WL <ea>,dst
//
// (たぶん別対応)
// | m -rxw | MOVEM list,<ea>
// | m -rxw | FMOVEM.X reg,<ea>
// | m -rxw | FSAVE <ea>
// | m+ rxwp | MOVEM <ea>,list
// | m+ rxwp | FMOVEM.X <ea>,reg
// | m+ rxwp | FRESTORE <ea>
#include "mpu680x0.h"
#include "m680x0cycle.h"
//
// Calc EA
//
// 個別 EA は (An)+/-(An) でもレジスタを保存しない。
// 自動的に保存する cea_data() 等を介さずこれらを呼ぶ時は
// レジスタ保存のタイミングや回数に注意すること。
uint32
MPU680x0Device::cea_anin(uint n)
{
CYCLE3(cea_anin);
return internal_ea_anin(n);
}
uint32
MPU680x0Device::cea_anpi_1(uint n)
{
CYCLE3(cea_anpi);
return internal_ea_anpi_1(n);
}
uint32
MPU680x0Device::cea_anpi_2(uint n)
{
CYCLE3(cea_anpi);
return internal_ea_anpi_2(n);
}
uint32
MPU680x0Device::cea_anpi_4(uint n)
{
CYCLE3(cea_anpi);
return internal_ea_anpi_4(n);
}
uint32
MPU680x0Device::cea_anpd_1(uint n)
{
CYCLE3(cea_anpd);
return internal_ea_anpd_1(n);
}
uint32
MPU680x0Device::cea_anpd_2(uint n)
{
CYCLE3(cea_anpd);
return internal_ea_anpd_2(n);
}
uint32
MPU680x0Device::cea_anpd_4(uint n)
{
CYCLE3(cea_anpd);
return internal_ea_anpd_4(n);
}
uint32
MPU680x0Device::cea_andi(uint n)
{
CYCLE3(cea_andi);
return internal_ea_andi(n);
}
uint32
MPU680x0Device::cea_anix(uint n)
{
// CYCLE は呼び出し先で加算。
return internal_ea_anix(n);
}
uint32
MPU680x0Device::cea_absw()
{
CYCLE3(cea_absw);
return internal_ea_absw();
}
uint32
MPU680x0Device::cea_absl()
{
CYCLE3(cea_absl);
return internal_ea_absl();
}
uint32
MPU680x0Device::cea_pcdi()
{
CYCLE3(cea_andi);
return internal_ea_pcdi();
}
uint32
MPU680x0Device::cea_pcix()
{
// CYCLE は呼び出し先で加算。
return internal_ea_pcix();
}
//
// Fetch EA
//
inline uint32
MPU680x0Device::fea_anin()
{
CYCLE3(fea_anin);
return internal_ea_anin(eanum(ir));
}
inline uint32
MPU680x0Device::fea_anpi_1()
{
CYCLE3(fea_anpi);
return internal_ea_anpi_1(eanum(ir));
}
inline uint32
MPU680x0Device::fea_anpi_2()
{
CYCLE3(fea_anpi);
return internal_ea_anpi_2(eanum(ir));
}
inline uint32
MPU680x0Device::fea_anpi_4()
{
CYCLE3(fea_anpi);
return internal_ea_anpi_4(eanum(ir));
}
inline uint32
MPU680x0Device::fea_anpd_1()
{
CYCLE3(fea_anpd);
return internal_ea_anpd_1(eanum(ir));
}
inline uint32
MPU680x0Device::fea_anpd_2()
{
CYCLE3(fea_anpd);
return internal_ea_anpd_2(eanum(ir));
}
inline uint32
MPU680x0Device::fea_anpd_4()
{
CYCLE3(fea_anpd);
return internal_ea_anpd_4(eanum(ir));
}
inline uint32
MPU680x0Device::fea_andi()
{
CYCLE3(fea_andi);
return internal_ea_andi(eanum(ir));
}
inline uint32
MPU680x0Device::fea_anix()
{
// CYCLE は呼び出し先で加算。
return internal_ea_anix(eanum(ir));
}
inline uint32
MPU680x0Device::fea_absw()
{
CYCLE3(fea_absw);
return internal_ea_absw();
}
inline uint32
MPU680x0Device::fea_absl()
{
CYCLE3(fea_absl);
return internal_ea_absl();
}
inline uint32
MPU680x0Device::fea_pcdi()
{
CYCLE3(fea_andi);
return internal_ea_pcdi();
}
inline uint32
MPU680x0Device::fea_pcix()
{
// CYCLE は呼び出し先で加算。
return internal_ea_pcix();
}
inline void
MPU680x0Device::fea_imm_2()
{
CYCLE3(fea_immw);
}
inline void
MPU680x0Device::fea_imm_4()
{
CYCLE3(fea_imml);
}
//
// EA の拡張ワード
//
// 所要サイクルについて。
// 本来 internal_ea_*() はサイクルを加算しないが、ea_ix は展開してみないと
// 分からないのでここで加算する。CEA と FEA の両方から呼ばれて本来なら
// サイクル数が異なるのだが、実際にサイクル数が異なるのは No Cache Case 側
// だけなので、簡略化のため FEA (の NCC) のことは忘れる。
//
// サイクルは、メモリ間接かどうか、ベースディスプレースメント(bd) のサイズ、
// アウターディスプレースメント(od) のサイズ、の3つのパラメータで決まる。
//
// 間接 bd od CEA bd加算分 od加算分
// ---- ---- ---- ----
// n - - (6,6)
// n 16 - (8,9) = (6,6) + (2,3)
// n 32 - (12,12) = (6,6) + (6,6)
// y - - (10,10)
// y - 16/32 (12,13) = (10,10) + (2,3)
// y 16 - (12,13) = (10,10) + (2,3)
// y 16 16/32 (14,16) = (10,10) + (2,3) + (2,3)
// y 32 - (16,17) = (10,10) + (6,7)※1
// y 32 16/32 (18,20) = (10,10) + (6,7)※1+ (2,3)
//
// ※1: 簡略化のためここの (6,7) は (6,6) として扱う。
//
// FEA はだいたいこんな感じになるが、実装はしない。
//
// 間接 bd od FEA bd加算分 od加算分
// ---- ---- ---- ----
// n - - (6,7)
// n 16 - (8,10) = (6,7) + (2,3)
// n 32 - (12,13) = (6,7) + (6,6)
// y - - (10,10)
// y - 16 (12,13) = (10,10) + (2,3)
// y - 32 (12,14) = (10,10) + (2,4)
// y 16 - (12,13)
// y 16 16 (14,16) = (10,10) + (2,3) + (2,3)
// y 16 32 (14,17) = (10,10) + (2,3) + (2,4)
// y 32 - (16,17) = (10,10) + (6,7)
// y 32 16 (18,20) = (10,10) + (6,7) + (2,3)
// y 32 32 (18,21) = (10,10) + (6,7) + (2,4)
uint32
MPU680x0Device::internal_ea_ix(uint32 anpc)
{
uint16 ext = fetch_2();
uint rn = (ext >> 12) & 15;
bool idx_long = (ext & 0x0800);
uint scale = (ext >> 9) & 3;
if ((ext & 0x0100) == 0) {
// Brief extension
//
// F E D C B A 9 8 7 6 5 4 3 2 1 0
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// | DA| n | WL| SCALE | 0 | disp |
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//
// WL: インデックスレジスタ(Rn)のサイズ 1=.L 0=.W
// SCALE: スケールファクタ %00=*1 %01=*2 %10=*4 %11=*8
CYCLE3(cea_anix_brief);
int32 disp = (int32)(int8)(ext & 0xff);
uint32 idx;
if (idx_long) {
idx = reg.R[rn];
} else {
idx = (int32)(int16)(reg.R[rn] & 0xffff);
}
idx <<= scale;
return anpc + (int32)idx + disp;
} else {
// Full extension
//
// F E D C B A 9 8 7 6 5 4 3 2 1 0
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// | DA| n | WL| SCALE | 1 | BS| IS| BDSZ | 0 | I/IS |
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//
// BS=1: ベースレジスタ・サプレス
// IS=1: インデックスオペランド・サプレス
// BDSZ: ベースディスプレースメントのサイズ %01=null %10=.W %11=.L
// I/IS: モード
bool bs = (ext & 0x0080);
bool is = (ext & 0x0040);
uint bdsize = (ext >> 4) & 3;
uint iis = (ext & 7);
// ベースレジスタ
if (bs) {
anpc = 0;
}
// ベース・ディスプレースメント
uint32 base = 0;
switch (bdsize) {
case 0: // 予約
throw M68K::EXCEP_ILLEGAL;
case 1: // ベースはヌル
break;
case 2: // ベース.W
base = (int32)(int16)fetch_2();
CYCLE3(cea_anix_bd2);
break;
case 3: // ベース.L
base = fetch_4();
CYCLE3(cea_anix_bd4);
break;
default:
__unreachable();
}
uint32 outer;
if (is == 0) {
// インデックス
uint32 idx = 0;
if (idx_long) {
idx = reg.R[rn];
} else {
idx = (int32)(int16)(reg.R[rn] & 0xffff);
}
idx <<= scale;
switch (iis) {
case 0: // no memory indirection
CYCLE3(cea_anix_direct);
return anpc + base + idx;
case 1: // indirect pre-index with null outer
CYCLE3(cea_anix_indir);
return read_4(anpc + base + idx);
case 2: // indirect pre-index with word outer
CYCLE3(cea_anix_indir_od);
outer = (int32)(int16)fetch_2();
return read_4(anpc + base + idx) + outer;
case 3: // indirect pre-index with long outer
CYCLE3(cea_anix_indir_od);
outer = fetch_4();
return read_4(anpc + base + idx) + outer;
case 4:
throw M68K::EXCEP_ILLEGAL;
case 5: // indirect post-index with null outer
CYCLE3(cea_anix_indir);
return read_4(anpc + base) + idx;
case 6: // indirect post-index with word outer
CYCLE3(cea_anix_indir_od);
outer = (int32)(int16)fetch_2();
return read_4(anpc + base) + idx + outer;
case 7: // indirect post-index with long outer
CYCLE3(cea_anix_indir_od);
outer = fetch_4();
return read_4(anpc + base) + idx + outer;
default:
__unreachable();
}
} else {
switch (iis) {
case 0: // no memory indirection
CYCLE3(cea_anix_direct);
return anpc + base;
case 1: // memory indirect with null outer
CYCLE3(cea_anix_indir);
return read_4(anpc + base);
case 2: // memory indirect with word outer
CYCLE3(cea_anix_indir_od);
outer = (int32)(int16)fetch_2();
return read_4(anpc + base) + outer;
case 3: // memory indirect with long outer
CYCLE3(cea_anix_indir_od);
outer = fetch_4();
return read_4(anpc + base) + outer;
default:
throw M68K::EXCEP_ILLEGAL;
}
}
}
}
//
// Calc EA
//
uint32
MPU680x0Device::cea_ctrl()
{
switch (eamode(ir)) {
case 2: // (An)
return cea_anin(eanum(ir));
case 5: // d16(An)
return cea_andi(eanum(ir));
case 6: // (An,IX)
return cea_anix(eanum(ir));
case 7:
switch (eanum(ir)) {
case 0: // Abs.W
return cea_absw();
case 1: // Abs.L
return cea_absl();
case 2: // d16(PC)
return cea_pcdi();
case 3: // (PC,IX)
return cea_pcix();
default:
break;
}
break;
}
// 不当命令
throw M68K::EXCEP_ILLEGAL;
}
uint32
MPU680x0Device::cea_data_1()
{
switch (eamode(ir)) {
case 2: // (An)
return cea_anin(eanum(ir));
case 3: // (An)+
save_reg_pi(eanum(ir));
return cea_anpi_1(eanum(ir));
case 4: // -(An)
save_reg_pd(eanum(ir));
return cea_anpd_1(eanum(ir));
case 5: // d16(An)
return cea_andi(eanum(ir));
case 6: // (An,IX)
return cea_anix(eanum(ir));
case 7:
switch (eanum(ir)) {
case 0: // Abs.W
return cea_absw();
case 1: // Abs.L
return cea_absl();
default:
break;
}
break;
}
// 不当命令
throw M68K::EXCEP_ILLEGAL;
}
uint32
MPU680x0Device::cea_data_2()
{
switch (eamode(ir)) {
case 2: // (An)
return cea_anin(eanum(ir));
case 3: // (An)+
save_reg_pi(eanum(ir));
return cea_anpi_2(eanum(ir));
case 4: // -(An)
save_reg_pd(eanum(ir));
return cea_anpd_2(eanum(ir));
case 5: // d16(An)
return cea_andi(eanum(ir));
case 6: // (An,IX)
return cea_anix(eanum(ir));
case 7:
switch (eanum(ir)) {
case 0: // Abs.W
return cea_absw();
case 1: // Abs.L
return cea_absl();
default:
break;
}
break;
}
// 不当命令
throw M68K::EXCEP_ILLEGAL;
}
uint32
MPU680x0Device::cea_data_4()
{
switch (eamode(ir)) {
case 2: // (An)
return cea_anin(eanum(ir));
case 3: // (An)+
save_reg_pi(eanum(ir));
return cea_anpi_4(eanum(ir));
case 4: // -(An)
save_reg_pd(eanum(ir));
return cea_anpd_4(eanum(ir));
case 5: // d16(An)
return cea_andi(eanum(ir));
case 6: // (An,IX)
return cea_anix(eanum(ir));
case 7:
switch (eanum(ir)) {
case 0: // Abs.W
return cea_absw();
case 1: // Abs.L
return cea_absl();
default:
break;
}
break;
}
// 不当命令
throw M68K::EXCEP_ILLEGAL;
}
// MMU からの呼び出し用。
uint32
MPU680x0Device::cea_copro()
{
switch (eamode(ir)) {
case 2: // (An)
CYCLE(4);
return internal_ea_anin(eanum(ir));
case 5: // d16(An)
CYCLE(4);
return internal_ea_andi(eanum(ir));
case 6: // (An,IX)
CYCLE(4);
return internal_ea_anix(eanum(ir));
case 7:
switch (eanum(ir)) {
case 0: // Abs.W
CYCLE(4);
return internal_ea_absw();
case 1: // Abs.L
CYCLE(6);
return internal_ea_absl();
default:
break;
}
break;
}
// 不当命令
throw M68K::EXCEP_ILLEGAL;
}
//
// Fetch EA
//
uint32
MPU680x0Device::fea_data_1()
{
uint32 ea;
switch (eamode(ir)) {
case 0: // Dn
return reg.D[eanum(ir)] & 0xff;
case 2: // (An)
ea = fea_anin();
return read_1(ea);
case 3: // (An)+
save_reg_pi(eanum(ir));
ea = fea_anpi_1();
return read_1(ea);
case 4: // -(An)
save_reg_pd(eanum(ir));
ea = fea_anpd_1();
return read_1(ea);
case 5: // d16(An)
ea = fea_andi();
return read_1(ea);
case 6: // (An,IX)
ea = fea_anix();
return read_1(ea);
case 7:
switch (eanum(ir)) {
case 0: // Abs.W
ea = fea_absw();
return read_1(ea);
case 1: // Abs.L
ea = fea_absl();
return read_1(ea);
case 2: // d16(PC)
ea = fea_pcdi();
return read_1(ea);
case 3: // (PC,IX)
ea = fea_pcix();
return read_1(ea);
case 4: // #imm
fea_imm_2();
return fetch_2() & 0xff;
default:
break;
}
break;
default:
break;
}
// 不当命令
throw M68K::EXCEP_ILLEGAL;
}
uint32
MPU680x0Device::fea_data_2()
{
uint32 ea;
switch (eamode(ir)) {
case 0: // Dn
return reg.D[eanum(ir)] & 0xffff;
case 2: // (An)
ea = fea_anin();
return read_2(ea);
case 3: // (An)+
save_reg_pi(eanum(ir));
ea = fea_anpi_2();
return read_2(ea);
case 4: // -(An)
save_reg_pd(eanum(ir));
ea = fea_anpd_2();
return read_2(ea);
case 5: // d16(An)
ea = fea_andi();
return read_2(ea);
case 6: // (An,IX)
ea = fea_anix();
return read_2(ea);
case 7:
switch (eanum(ir)) {
case 0: // Abs.W
ea = fea_absw();
return read_2(ea);
case 1: // Abs.L
ea = fea_absl();
return read_2(ea);
case 2: // d16(PC)
ea = fea_pcdi();
return read_2(ea);
case 3: // (PC,IX)
ea = fea_pcix();
return read_2(ea);
case 4: // #imm
fea_imm_2();
return fetch_2();
default:
break;
}
break;
default:
break;
}
// 不当命令
throw M68K::EXCEP_ILLEGAL;
}
uint32
MPU680x0Device::fea_data_4()
{
uint32 ea;
switch (eamode(ir)) {
case 0: // Dn
return reg.D[eanum(ir)];
case 2: // (An)
ea = fea_anin();
return read_4(ea);
case 3: // (An)+
save_reg_pi(eanum(ir));
ea = fea_anpi_4();
return read_4(ea);
case 4: // -(An)
save_reg_pd(eanum(ir));
ea = fea_anpd_4();
return read_4(ea);
case 5: // d16(An)
ea = fea_andi();
return read_4(ea);
case 6: // (An,IX)
ea = fea_anix();
return read_4(ea);
case 7:
switch (eanum(ir)) {
case 0: // Abs.W
ea = fea_absw();
return read_4(ea);
case 1: // Abs.L
ea = fea_absl();
return read_4(ea);
case 2: // d16(PC)
ea = fea_pcdi();
return read_4(ea);
case 3: // (PC,IX)
ea = fea_pcix();
return read_4(ea);
case 4: // #imm
fea_imm_4();
return fetch_4();
default:
break;
}
break;
default:
break;
}
// 不当命令
throw M68K::EXCEP_ILLEGAL;
}
uint32
MPU680x0Device::fea_all_1()
{
uint32 ea;
switch (eamode(ir)) {
case 0: // Dn
return reg.D[eanum(ir)] & 0xff;
case 1: // An
// An.B は不当命令
break;
case 2: // (An)
ea = fea_anin();
return read_1(ea);
case 3: // (An)+
save_reg_pi(eanum(ir));
ea = fea_anpi_1();
return read_1(ea);
case 4: // -(An)
save_reg_pd(eanum(ir));
ea = fea_anpd_1();
return read_1(ea);
case 5: // d16(An)
ea = fea_andi();
return read_1(ea);
case 6: // (An,IX)
ea = fea_anix();
return read_1(ea);
case 7:
switch (eanum(ir)) {
case 0: // Abs.W
ea = fea_absw();
return read_1(ea);
case 1: // Abs.L
ea = fea_absl();
return read_1(ea);
case 2: // d16(PC)
ea = fea_pcdi();
return read_1(ea);
case 3: // (PC,IX)
ea = fea_pcix();
return read_1(ea);
case 4: // #imm
fea_imm_2();
return fetch_2() & 0xff;
default:
break;
}
break;
default:
break;
}
// 不当命令
throw M68K::EXCEP_ILLEGAL;
}
uint32
MPU680x0Device::fea_all_2()
{
uint32 ea;
switch (eamode(ir)) {
case 0: // Dn
case 1: // An
return reg.R[ir & 15] & 0xffff;
case 2: // (An)
ea = fea_anin();
return read_2(ea);
case 3: // (An)+
save_reg_pi(eanum(ir));
ea = fea_anpi_2();
return read_2(ea);
case 4: // -(An)
save_reg_pd(eanum(ir));
ea = fea_anpd_2();
return read_2(ea);
case 5: // d16(An)
ea = fea_andi();
return read_2(ea);
case 6: // (An,IX)
ea = fea_anix();
return read_2(ea);
case 7:
switch (eanum(ir)) {
case 0: // Abs.W
ea = fea_absw();
return read_2(ea);
case 1: // Abs.L
ea = fea_absl();
return read_2(ea);
case 2: // d16(PC)
ea = fea_pcdi();
return read_2(ea);
case 3: // (PC,IX)
ea = fea_pcix();
return read_2(ea);
case 4: // #imm
fea_imm_2();
return fetch_2();
default:
break;
}
break;
default:
break;
}
// 不当命令
throw M68K::EXCEP_ILLEGAL;
}
uint32
MPU680x0Device::fea_all_4()
{
uint32 ea;
switch (eamode(ir)) {
case 0: // Dn
case 1: // An
return reg.R[ir & 15];
case 2: // (An)
ea = fea_anin();
return read_4(ea);
case 3: // (An)+
save_reg_pi(eanum(ir));
ea = fea_anpi_4();
return read_4(ea);
case 4: // -(An)
save_reg_pd(eanum(ir));
ea = fea_anpd_4();
return read_4(ea);
case 5: // d16(An)
ea = fea_andi();
return read_4(ea);
case 6: // (An,IX)
ea = fea_anix();
return read_4(ea);
case 7:
switch (eanum(ir)) {
case 0: // Abs.W
ea = fea_absw();
return read_4(ea);
case 1: // Abs.L
ea = fea_absl();
return read_4(ea);
case 2: // d16(PC)
ea = fea_pcdi();
return read_4(ea);
case 3: // (PC,IX)
ea = fea_pcix();
return read_4(ea);
case 4: // #imm
fea_imm_4();
return fetch_4();
default:
break;
}
break;
default:
break;
}
// 不当命令
throw M68K::EXCEP_ILLEGAL;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.