--- nono/hd64180/hd64180core.cpp 2026/04/29 17:05:18 1.1.1.1 +++ nono/hd64180/hd64180core.cpp 2026/04/29 17:05:47 1.1.1.5 @@ -34,7 +34,7 @@ MPU64180Device::ExecNormal(Event& ev) reg_r++; // 1バイト目処理 - op = Fetch8(); + op = Fetch1(); if (__predict_false(opmode == OpMode::Halt)) { // ホールトモードなら PC を戻し続けるだけ reg.pc--; @@ -91,7 +91,14 @@ MPU64180Device::op_illegal(int pos) // PC は未定義命令の先頭番地ではなく、未定義 opcode だった位置? // nono の実装ではフェッチと同時にインクリメントしているので、 // 1つ前でいい? HD64180.pdf p38-39 - Push16(reg.pc - 1); + if (pos == 2) { + Push2(reg.pc - 1); + } else { + // DD CB d OP xx + // ^ PC + // d の位置をスタックに積む + Push2(reg.pc - 2); + } ExceptionDirect(HD647180::IntmapTRAP, 0x0000); } @@ -103,15 +110,15 @@ MPU64180Device::Jump(uint16 addr) // 命令本体(オペランドを含まない)を16ビット左詰めにする。 // 分岐命令は1バイト命令か ED XX か DD/FD XX の2バイト命令しかないはず。 - //上位ワードは $0000。 - uint32 inst; + // 上位ワードは $0000。 + uint32 info; if (ops[0] == 0xed || ops[0] == 0xdd || ops[0] == 0xfd) { - inst = (ops[0] << 8) | ops[1]; + info = (ops[0] << 8) | ops[1]; } else { - inst = (ops[0] << 8); + info = (ops[0] << 8); } - brhist.AddEntry(GetPPC(), addr, inst); + brhist.AddEntry(GetPPC(), addr, info); } // @@ -185,6 +192,20 @@ MPU64180Device::NegateINT0() NegateIntmap(HD647180::IntmapINT0); } +// ASCIn 割り込みをアサート/ネゲートする。 +// IEF1 はこちらで加味する。 +void +MPU64180Device::ChangeASCIInt(uint n, bool asci_req) +{ + uint32 map = HD647180::IntmapASCI(n); + + if ((asci_req && GetIEF1())) { + AssertIntmap(map); + } else { + NegateIntmap(map); + } +} + // マスカブル割り込みを処理する。(命令境界で呼ばれる) void MPU64180Device::DoInterrupt() @@ -195,7 +216,7 @@ MPU64180Device::DoInterrupt() // 優先順位の最も高い割り込みを一つ選択。 assert(intmap != 0); - int source = __builtin_clz(intmap); + uint source = __builtin_clz(intmap); // TRAP はここに来ない。NMI は LUNA では未接続のため未実装。 assert(source != HD647180::IntmapTRAP); @@ -206,16 +227,16 @@ MPU64180Device::DoInterrupt() // ただし mode0 と mode2 は使われてないので未対応。 if (int0mode != 1) { - PANIC("INT0 on mode%d (NOT IMPLEMENTED)", int0mode); + PANIC("INT0 on mode%u (NOT IMPLEMENTED)", int0mode); } // mode1 は固定番地へ - Push16(reg.pc); + Push2(reg.pc); ExceptionDirect(source, 0x0038); } else { // 残りはすべてベクタ方式。 - Push16(reg.pc); + Push2(reg.pc); ExceptionVector(source); } @@ -279,7 +300,7 @@ MPU64180Device::ExceptionVector(int sour exhist.AddEntry(GetPPC(), -1, 0x80000000 | source); // ジャンプ先を読み込む - uint32 new_addr = Read16(vec_addr); + uint32 new_addr = Read2(vec_addr); // ベクタジャンプを記録。 brhist.AddEntry(vec_addr, new_addr, -1);