Annotation of nono/m680x0/m68030bitfield.cpp, revision 1.1

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2022 nono project
        !             4: // Licensed under nono-license.txt
        !             5: //
        !             6: 
        !             7: #include "m68030bitfield.h"
        !             8: 
        !             9: // コンストラクタ
        !            10: // 呼び出し側でここまでに ir2 へのフェッチはしておくこと。
        !            11: acc_bf::acc_bf(MPU680x0Device *cpu_)
        !            12: {
        !            13:        cpu = cpu_;
        !            14: 
        !            15:        //  F  E  D  C  B  A  9  8  7  6  5  4  3  2  1  0
        !            16:        //  0  0  0  0 DO <-- offset --> DW <-- width --->
        !            17: 
        !            18:        offset = (cpu->GetIR2() >> 6) & 0x1f;
        !            19:        if ((cpu->GetIR2() & 0x0800)) {
        !            20:                offset = (int32)cpu->reg.D[offset & 7];
        !            21:                local_offset = offset & 0x1f;
        !            22:        } else {
        !            23:                local_offset = offset;
        !            24:        }
        !            25: 
        !            26:        width = cpu->GetIR2();
        !            27:        if ((cpu->GetIR2() & 0x0020)) {
        !            28:                width = cpu->reg.D[width & 7];
        !            29:        }
        !            30:        // モジュロ 32 を取り、0 なら 32 を表す
        !            31:        width = ((width - 1) & 31) + 1;
        !            32:        // mask は32ビットの上位から width ビット 1 が並んだもの
        !            33:        mask = 0xffffffff << (32 - width);
        !            34: }
        !            35: 
        !            36: // データレジスタから値を読み込む。n はデータレジスタの番号。
        !            37: void
        !            38: acc_bf::LoadReg(uint n)
        !            39: {
        !            40:        data = cpu->reg.D[n];
        !            41:        data = ROL32(data, local_offset);
        !            42:        data &= mask;
        !            43: }
        !            44: 
        !            45: // メモリから値を読み込む。
        !            46: void
        !            47: acc_bf::LoadMem(uint32 addr)
        !            48: {
        !            49:        // EA の計算
        !            50:        ea = addr + offset / 8;
        !            51:        local_offset = offset % 8;
        !            52:        if (local_offset < 0) {
        !            53:                local_offset += 8;
        !            54:                ea--;
        !            55:        }
        !            56: 
        !            57:        // アクセスするバイト数
        !            58:        bytes = (local_offset + width + 7) / 8;
        !            59: 
        !            60:        // 40ビットバッファに読み込む
        !            61:        // read_NN() はミスアラインドでもアクセスできる
        !            62:        switch (bytes) {
        !            63:         case 1:
        !            64:                buf = ((uint64)cpu->read_8(ea)) << 32;
        !            65:                break;
        !            66:         case 2:
        !            67:                buf = ((uint64)cpu->read_16(ea)) << 24;
        !            68:                break;
        !            69:         case 3:
        !            70:                if ((ea & 1) == 0) {
        !            71:                        // 偶数アドレスから3バイト
        !            72:                        buf = ((uint64)cpu->read_16(ea)) << 24;
        !            73:                        buf |= ((uint64)cpu->read_8(ea + 2)) << 16;
        !            74:                } else {
        !            75:                        // 奇数アドレスから3バイト
        !            76:                        buf = ((uint64)cpu->read_8(ea)) << 32;
        !            77:                        buf |= (uint64)cpu->read_16(ea + 1) << 16;
        !            78:                }
        !            79:                break;
        !            80:         case 4:
        !            81:                buf = ((uint64)cpu->read_32(ea)) << 8;
        !            82:                break;
        !            83:         case 5:
        !            84:                if ((ea & 1) == 0) {
        !            85:                        // 偶数アドレスから5バイト
        !            86:                        buf = ((uint64)cpu->read_32(ea)) << 8;
        !            87:                        buf |= ((uint64)cpu->read_8(ea + 4));
        !            88:                } else {
        !            89:                        // 奇数アドレスから5バイト
        !            90:                        buf = ((uint64)cpu->read_8(ea)) << 32;
        !            91:                        buf |= ((uint64)cpu->read_32(ea + 1));
        !            92:                }
        !            93:                break;
        !            94:         default:
        !            95:                PANIC("corrupted bytes=%d", bytes);
        !            96:        }
        !            97: 
        !            98:        // 32ビット左詰めにする
        !            99:        data = (buf >> (8 - local_offset)) & mask;
        !           100: }
        !           101: 
        !           102: // データレジスタに値を書き出す。
        !           103: void
        !           104: acc_bf::StoreReg(uint n)
        !           105: {
        !           106:        uint32 m = ROR32(mask, local_offset);
        !           107:        uint32 d = ROR32(data, local_offset);
        !           108: 
        !           109:        cpu->reg.D[n] = (cpu->reg.D[n] & ~m) | (d & m);
        !           110: }
        !           111: 
        !           112: // メモリに値を書き出す
        !           113: void
        !           114: acc_bf::StoreMem()
        !           115: {
        !           116:        // 32ビット左詰めデータを 40ビットバッファにマージ
        !           117:        uint64 m = (uint64)mask << (8 - local_offset);
        !           118:        uint64 d = (uint64)data << (8 - local_offset);
        !           119:        buf = (buf & ~m) | (d & m);
        !           120: 
        !           121:        // 40ビットバッファを書き戻す
        !           122:        // write_NN() はミスアラインドでもアクセスできる
        !           123:        switch (bytes) {
        !           124:         case 1:
        !           125:                cpu->write_8(ea, buf >> 32);
        !           126:                break;
        !           127:         case 2:
        !           128:                cpu->write_16(ea, buf >> 24);
        !           129:                break;
        !           130:         case 3:
        !           131:                if ((ea & 1) == 0) {
        !           132:                        // 偶数アドレスから3バイト
        !           133:                        cpu->write_16(ea, buf >> 24);
        !           134:                        cpu->write_8(ea + 2, buf >> 16);
        !           135:                } else {
        !           136:                        // 奇数アドレスから3バイト
        !           137:                        cpu->write_8(ea, buf >> 32);
        !           138:                        cpu->write_16(ea + 1, buf >> 16);
        !           139:                }
        !           140:                break;
        !           141:         case 4:
        !           142:                cpu->write_32(ea, buf >> 8);
        !           143:                break;
        !           144:         case 5:
        !           145:                if ((ea & 1) == 0) {
        !           146:                        // 偶数アドレスから5バイト
        !           147:                        cpu->write_32(ea, buf >> 8);
        !           148:                        cpu->write_8(ea + 4, buf);
        !           149:                } else {
        !           150:                        // 奇数アドレスから5バイト
        !           151:                        cpu->write_8(ea, buf >> 32);
        !           152:                        cpu->write_32(ea + 1, buf);
        !           153:                }
        !           154:                break;
        !           155:         default:
        !           156:                PANIC("corrupted bytes=%d", bytes);
        !           157:        }
        !           158: }

unix.superglobalmegacorp.com

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