--- nono/m680x0/m68030core.cpp 2026/04/29 17:04:43 1.1.1.3 +++ nono/m680x0/m68030core.cpp 2026/04/29 17:04:49 1.1.1.5 @@ -8,6 +8,7 @@ #include "debugger.h" #include "cvprompt.h" #include "mpu.h" +#include "scheduler.h" #define OP_PROTO(name) static inline void __CONCAT(op_,name)(m68kcpu *cpu) #define OP_DEF(name) static inline void __CONCAT(op_,name)(m68kcpu *cpu) @@ -26,10 +27,7 @@ static void m68030_flush_interrupt(m68kcpu *cpu); // 仮想時間 delta [nsec] だけ CPU を実行する。実際には大抵行き過ぎる。 -// 戻り値はフラグ。 -// -// 戻る時に仮想時刻を確定させなくても構わない。スケジューラはこれを呼び出した -// 後に必然的に仮想時刻を取得することになるため、そこで確定させられる。 +// 戻り値は CPU 状態 (Scheduler::SCHED_CPU_*)。 uint32 m68030_run(m68kcpu *cpu, uint32 delta) { @@ -71,7 +69,7 @@ m68030_run(m68kcpu *cpu, uint32 delta) if ((cpu->atomic_reqflag & CPU_REQ_RELEASE)) { // ここで実行を中断してスケジューラに戻る cpu->atomic_reqflag &= ~CPU_REQ_RELEASE; - return cpu->atomic_reqflag; + goto exit; } if ((cpu->atomic_reqflag & CPU_REQ_RESET)) { @@ -88,16 +86,20 @@ m68030_run(m68kcpu *cpu, uint32 delta) if ((cpu->atomic_reqflag & CPU_REQ_STOP)) { // STOP 状態は、残りサイクルを消費したことにして戻る - cpu->reg.state = CPU_REQ_STOP; - cpu->used_cycle = cpu->goal_cycle; - return cpu->atomic_reqflag; + cpu->reg.state = Scheduler::SCHED_CPU_STOP; + if (cpu->used_cycle < cpu->goal_cycle) { + cpu->used_cycle = cpu->goal_cycle; + } + goto exit; } if ((cpu->atomic_reqflag & CPU_REQ_HALT)) { // HALT 状態も、残りサイクルを消費したことにして戻る - cpu->reg.state = CPU_REQ_HALT; - cpu->used_cycle = cpu->goal_cycle; - return cpu->atomic_reqflag; + cpu->reg.state = Scheduler::SCHED_CPU_HALT; + if (cpu->used_cycle < cpu->goal_cycle) { + cpu->used_cycle = cpu->goal_cycle; + } + goto exit; } if ((cpu->atomic_reqflag & CPU_REQ_TRACE)) { @@ -141,7 +143,7 @@ m68030_run(m68kcpu *cpu, uint32 delta) cpu->used_cycle += cpu->cycle_nocache; \ cpu->cycle_nocache = 0; \ if (cpu->used_cycle >= cpu->goal_cycle) \ - return cpu->atomic_reqflag; \ + goto exit; \ if (cpu->atomic_reqflag != 0) goto exit_inner_loop; \ JUMP @@ -171,7 +173,7 @@ m68030_run(m68kcpu *cpu, uint32 delta) cpu->used_cycle += cpu->cycle_nocache; cpu->cycle_nocache = 0; if (cpu->used_cycle >= cpu->goal_cycle) - return cpu->atomic_reqflag; + goto exit; } while (cpu->atomic_reqflag == 0); #endif @@ -185,6 +187,12 @@ m68030_run(m68kcpu *cpu, uint32 delta) } } __unreachable(); + + exit: + cpu->total_vtime += cpu->Cycle2Vtime(cpu->used_cycle); + cpu->used_cycle = 0; + + return cpu->reg.state; } // ペンディングの割り込みを確認 @@ -196,7 +204,7 @@ m68030_flush_interrupt(m68kcpu *cpu) // ストップ状態を解除 cpu->atomic_reqflag &= ~CPU_REQ_STOP; - cpu->reg.state = 0; + cpu->reg.state = Scheduler::SCHED_CPU_NORMAL; // 例外処理を起動 m68030_exception_interrupt(cpu, cpu->intr_pending);