File:  [Isaki's NoNo m68k/m88k emulator] / nono / m680x0 / m68030core.h
Revision 1.1.1.7 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:08 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v016, v015, HEAD
nono 0.3.0

//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//

#pragma once

#include "m68030.h"
#include "m68030excep.h"
#include "mpu.h"

// XXX ?
#define CCR				(cpu->reg.ccr)

#define RegIsS			(cpu->reg.s)

extern void m68030_restore_reg_pi(m68kcpu *);
extern void m68030_restore_reg_pd(m68kcpu *);
extern void m68030_set_sr(m68kcpu *, uint16);
extern void m68030_exception(m68kcpu *, int);
extern void m68030_exception_buserr(m68kcpu *, int);
extern void m68030_rte(m68kcpu *);
extern void m68030_stop(m68kcpu *);

// 文字列を作る前にレベルを評価するためマクロ
#define cpulog(lv, fmt...)	do {	\
	if (__predict_false(gMPU->loglevel >= (lv))) {	\
		gMPU->putlogn(fmt);	\
	}	\
} while (0)
#define cpulogf(lv, msgf)	do {	\
	gMPU->putlogf(lv, msgf);	\
} while (0)

// ops 用のマクロとか

static inline void
m68k_add_cycle(m68kcpu *cpu, int cc)
{
	cpu->used_cycle += cc;
}

static inline void
m68k_add_cycle_nc(m68kcpu *cpu, int cc, int ncc)
{
	cpu->used_cycle += cc;
	cpu->cycle_nocache += ncc - cc;
}

// サイクルを加算する。
// キャッシュケース、ノーキャッシュケースで同じ場合用。
#define CYCLE(cc)		m68k_add_cycle(cpu, (cc))

// サイクルを加算する。
// cc はキャッシュケース、ncc はノーキャッシュケースのサイクル。
// ncc は cc からの差分ではなく、ノーキャッシュケースの時のサイクル数
// そのものを指定する。(内部で差分をとっている)
#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)
{
	CHECK_ADDRESS_ERROR(addr);
	RegPC = addr;

	// ブランチ履歴
	cpu->brhist.AddEntry(RegPPC | (cpu->reg.s ? 1 : 0), addr, cpu->ir << 16);
}

// -(An) 実行前にレジスタを保存する。
// バスエラーからの復帰用。
static inline void
m68030_save_reg_pd(m68kcpu *cpu, int n)
{
	// 該当ビットのフラグを立てる
	cpu->flag_pd |= (1 << n);

	// 保存
	cpu->save_pd[n] = RegA(n);
}

// (An)+ 実行前にレジスタを保存する。
// バスエラーからの復帰用。
static inline void
m68030_save_reg_pi(m68kcpu *cpu, int n)
{
	// 該当ビットのフラグを立てる
	cpu->flag_pi |= (1 << n);

	// 保存
	cpu->save_pi[n] = RegA(n);
}

// cond で示される条件が成立すれば true を返す。
static inline bool
cond_func(m68kcpu *cpu, int cond)
{
	switch (cond) {
	 case 0:	// T
		return RegCondT;
	 case 1:	// F
		return RegCondF;
	 case 2:
		return RegCondHI;
	 case 3:
		return RegCondLS;
	 case 4:
		return RegCondCC;
	 case 5:
		return RegCondCS;
	 case 6:
		return RegCondNE;
	 case 7:
		return RegCondEQ;
	 case 8:
		return RegCondVC;
	 case 9:
		return RegCondVS;
	 case 10:
		return RegCondPL;
	 case 11:
		return RegCondMI;
	 case 12:
		return RegCondGE;
	 case 13:
		return RegCondLT;
	 case 14:
		return RegCondGT;
	 case 15:
		return RegCondLE;
	}
	__unreachable();
}


// 副作用のあるマクロ
// 特権違反例外のスタックに積む PC は違反を起こした命令先頭。
#define SUPERVISOR_OP	do { \
	if (!RegIsS) {	\
		CYCLE2(18, 20);	\
		m68030_exception(cpu, M68K_EXCEP_PRIV);	\
		return;	\
	}	\
} while (0)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.