--- nono/m680x0/m68030core.h 2026/04/29 17:04:28 1.1.1.1 +++ nono/m680x0/m68030core.h 2026/04/29 17:04:40 1.1.1.4 @@ -1,6 +1,7 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // #pragma once @@ -19,9 +20,9 @@ extern void m68030_restore_reg_pd(m68kcp extern void m68030_set_sr(m68kcpu *, uint16); extern void m68030_exception(m68kcpu *, int); extern void m68030_exception_reset(m68kcpu *); +extern void m68030_exception_buserr(m68kcpu *, int); extern void m68030_exception_interrupt(m68kcpu *, int, int); extern void m68030_rte(m68kcpu *); -extern const char *m68030_get_exception_name(int); static inline void cpulog(int lv, const char *fmt, ...) __printflike(2, 3); static inline void @@ -58,37 +59,28 @@ m68k_add_cycle_nc(m68kcpu *cpu, int cc, // cc はキャッシュケース、ncc はノーキャッシュケースのサイクル。 // ncc は cc からの差分ではなく、ノーキャッシュケースの時のサイクル数 // そのものを指定する。(内部で差分をとっている) -#define CYCLE2(cc, ncc) m68k_add_cycle_nc(cpu, (cc), (ncc)); +#define CYCLE2(cc, ncc) m68k_add_cycle_nc(cpu, (cc), (ncc)) + +// アドレスエラーチェック +// (jump() と jump_vector() の2か所で必要なため) +#define CHECK_ADDRESS_ERROR(addr) do { \ + if (__predict_false(((addr) & 1) != 0)) { \ + m68030_exception(cpu, M68K_EXCEP_ADDRERR); \ + return; \ + } \ +} while (0) // PC を addr に変更する。 // addr がメモリからの入力の場合アドレスエラーのチェックが必要なため。 +// ベクタへのジャンプはここではなく subr.cpp::m68030_jump_vector()。 static inline void m68030_jump(m68kcpu *cpu, uint32 addr) { - // アドレスエラーチェック - if (__predict_false((addr & 1) != 0)) { - m68030_exception(cpu, M68K_EXCEP_ADDRERR); - return; - } - + CHECK_ADDRESS_ERROR(addr); RegPC = addr; // ブランチ履歴 - m68kbrhist *h = &cpu->brhist[cpu->brhist_top]; -//printf("jump PPC=%x addr=%x h.from=%x to=%x", RegPPC, addr, h->from, h->to); - if (h->from == RegPPC && h->to == addr) { - // 前回と同じなら通過回数++ - h->count++; -//printf(" ++\n"); - } else { - // そうでなければ、新規エントリ - cpu->brhist_top++; -//printf(" [%d]\n", cpu->brhist_top); - h = &cpu->brhist[cpu->brhist_top]; - h->from = RegPPC; - h->to = addr; - h->count = 1; - } + cpu->brhist.AddEntry(RegPPC, addr, cpu->ir << 16); } // -(An) 実行前にレジスタを保存する。 @@ -159,9 +151,10 @@ cond_func(m68kcpu *cpu, int cond) // 副作用のあるマクロ // 特権違反例外のスタックに積む PC は違反を起こした命令先頭。 -#define SUPERVISOR_OP \ +#define SUPERVISOR_OP do { \ if (!RegIsS) { \ CYCLE2(18, 20); \ m68030_exception(cpu, M68K_EXCEP_PRIV); \ return; \ - } + } \ +} while (0)