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

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

unix.superglobalmegacorp.com

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