Annotation of nono/m680x0/m68030core.h, revision 1.1.1.7

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: #pragma once
                      8: 
                      9: #include "m68030.h"
                     10: #include "m68030excep.h"
                     11: #include "mpu.h"
                     12: 
                     13: // XXX ?
                     14: #define CCR                            (cpu->reg.ccr)
                     15: 
                     16: #define RegIsS                 (cpu->reg.s)
                     17: 
                     18: extern void m68030_restore_reg_pi(m68kcpu *);
                     19: extern void m68030_restore_reg_pd(m68kcpu *);
                     20: extern void m68030_set_sr(m68kcpu *, uint16);
                     21: extern void m68030_exception(m68kcpu *, int);
1.1.1.2   root       22: extern void m68030_exception_buserr(m68kcpu *, int);
1.1       root       23: extern void m68030_rte(m68kcpu *);
1.1.1.7 ! root       24: extern void m68030_stop(m68kcpu *);
1.1       root       25: 
1.1.1.6   root       26: // 文字列を作る前にレベルを評価するためマクロ
                     27: #define cpulog(lv, fmt...)     do {    \
                     28:        if (__predict_false(gMPU->loglevel >= (lv))) {  \
                     29:                gMPU->putlogn(fmt);     \
                     30:        }       \
                     31: } while (0)
1.1.1.7 ! root       32: #define cpulogf(lv, msgf)      do {    \
        !            33:        gMPU->putlogf(lv, msgf);        \
        !            34: } while (0)
1.1       root       35: 
                     36: // ops 用のマクロとか
                     37: 
                     38: static inline void
                     39: m68k_add_cycle(m68kcpu *cpu, int cc)
                     40: {
1.1.1.5   root       41:        cpu->used_cycle += cc;
1.1       root       42: }
                     43: 
                     44: static inline void
                     45: m68k_add_cycle_nc(m68kcpu *cpu, int cc, int ncc)
                     46: {
1.1.1.5   root       47:        cpu->used_cycle += cc;
1.1       root       48:        cpu->cycle_nocache += ncc - cc;
                     49: }
                     50: 
                     51: // サイクルを加算する。
                     52: // キャッシュケース、ノーキャッシュケースで同じ場合用。
                     53: #define CYCLE(cc)              m68k_add_cycle(cpu, (cc))
                     54: 
                     55: // サイクルを加算する。
                     56: // cc はキャッシュケース、ncc はノーキャッシュケースのサイクル。
                     57: // ncc は cc からの差分ではなく、ノーキャッシュケースの時のサイクル数
                     58: // そのものを指定する。(内部で差分をとっている)
1.1.1.2   root       59: #define CYCLE2(cc, ncc)        m68k_add_cycle_nc(cpu, (cc), (ncc))
1.1       root       60: 
1.1.1.3   root       61: // アドレスエラーチェック
                     62: // (jump() と jump_vector() の2か所で必要なため)
                     63: #define CHECK_ADDRESS_ERROR(addr)      do { \
                     64:        if (__predict_false(((addr) & 1) != 0)) { \
                     65:                m68030_exception(cpu, M68K_EXCEP_ADDRERR); \
                     66:                return; \
                     67:        } \
                     68: } while (0)
                     69: 
1.1       root       70: // PC を addr に変更する。
                     71: // addr がメモリからの入力の場合アドレスエラーのチェックが必要なため。
1.1.1.3   root       72: // ベクタへのジャンプはここではなく subr.cpp::m68030_jump_vector()。
1.1       root       73: static inline void
                     74: m68030_jump(m68kcpu *cpu, uint32 addr)
                     75: {
1.1.1.3   root       76:        CHECK_ADDRESS_ERROR(addr);
                     77:        RegPC = addr;
1.1       root       78: 
                     79:        // ブランチ履歴
1.1.1.5   root       80:        cpu->brhist.AddEntry(RegPPC | (cpu->reg.s ? 1 : 0), addr, cpu->ir << 16);
1.1       root       81: }
                     82: 
                     83: // -(An) 実行前にレジスタを保存する。
                     84: // バスエラーからの復帰用。
                     85: static inline void
                     86: m68030_save_reg_pd(m68kcpu *cpu, int n)
                     87: {
                     88:        // 該当ビットのフラグを立てる
                     89:        cpu->flag_pd |= (1 << n);
                     90: 
                     91:        // 保存
                     92:        cpu->save_pd[n] = RegA(n);
                     93: }
                     94: 
                     95: // (An)+ 実行前にレジスタを保存する。
                     96: // バスエラーからの復帰用。
                     97: static inline void
                     98: m68030_save_reg_pi(m68kcpu *cpu, int n)
                     99: {
                    100:        // 該当ビットのフラグを立てる
                    101:        cpu->flag_pi |= (1 << n);
                    102: 
                    103:        // 保存
                    104:        cpu->save_pi[n] = RegA(n);
                    105: }
                    106: 
                    107: // cond で示される条件が成立すれば true を返す。
                    108: static inline bool
                    109: cond_func(m68kcpu *cpu, int cond)
                    110: {
                    111:        switch (cond) {
                    112:         case 0:        // T
                    113:                return RegCondT;
                    114:         case 1:        // F
                    115:                return RegCondF;
                    116:         case 2:
                    117:                return RegCondHI;
                    118:         case 3:
                    119:                return RegCondLS;
                    120:         case 4:
                    121:                return RegCondCC;
                    122:         case 5:
                    123:                return RegCondCS;
                    124:         case 6:
                    125:                return RegCondNE;
                    126:         case 7:
                    127:                return RegCondEQ;
                    128:         case 8:
                    129:                return RegCondVC;
                    130:         case 9:
                    131:                return RegCondVS;
                    132:         case 10:
                    133:                return RegCondPL;
                    134:         case 11:
                    135:                return RegCondMI;
                    136:         case 12:
                    137:                return RegCondGE;
                    138:         case 13:
                    139:                return RegCondLT;
                    140:         case 14:
                    141:                return RegCondGT;
                    142:         case 15:
                    143:                return RegCondLE;
                    144:        }
                    145:        __unreachable();
                    146: }
                    147: 
                    148: 
                    149: // 副作用のあるマクロ
                    150: // 特権違反例外のスタックに積む PC は違反を起こした命令先頭。
1.1.1.2   root      151: #define SUPERVISOR_OP  do { \
1.1       root      152:        if (!RegIsS) {  \
                    153:                CYCLE2(18, 20); \
                    154:                m68030_exception(cpu, M68K_EXCEP_PRIV); \
                    155:                return; \
1.1.1.2   root      156:        }       \
                    157: } while (0)

unix.superglobalmegacorp.com

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