Annotation of nono/m680x0/m680x0bitfield.cpp, revision 1.1.1.2

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2022 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: #include "m680x0bitfield.h"
                      8: #include "bitops.h"
                      9: 
                     10: // コンストラクタ
                     11: // 呼び出し側でここまでに ir2 へのフェッチはしておくこと。
                     12: acc_bf::acc_bf(MPU680x0Device *cpu_)
                     13: {
                     14:        cpu = cpu_;
                     15: 
                     16:        //  F  E  D  C  B  A  9  8  7  6  5  4  3  2  1  0
                     17:        //  0  0  0  0 DO <-- offset --> DW <-- width --->
                     18: 
                     19:        offset = (cpu->GetIR2() >> 6) & 0x1f;
                     20:        if ((cpu->GetIR2() & 0x0800)) {
                     21:                offset = (int32)cpu->reg.D[offset & 7];
                     22:                local_offset = offset & 0x1f;
                     23:        } else {
                     24:                local_offset = offset;
                     25:        }
                     26: 
                     27:        width = cpu->GetIR2();
                     28:        if ((cpu->GetIR2() & 0x0020)) {
                     29:                width = cpu->reg.D[width & 7];
                     30:        }
                     31:        // モジュロ 32 を取り、0 なら 32 を表す
                     32:        width = ((width - 1) & 31) + 1;
                     33:        // mask は32ビットの上位から width ビット 1 が並んだもの
                     34:        mask = 0xffffffff << (32 - width);
                     35: }
                     36: 
                     37: // データレジスタから値を読み込む。n はデータレジスタの番号。
                     38: void
                     39: acc_bf::LoadReg(uint n)
                     40: {
                     41:        data = cpu->reg.D[n];
                     42:        data = ROL32(data, local_offset);
                     43:        data &= mask;
                     44: }
                     45: 
                     46: // メモリから値を読み込む。
1.1.1.2 ! root       47: // 命令サイクル数のため、4バイト以内なら true を返す。
        !            48: bool
1.1       root       49: acc_bf::LoadMem(uint32 addr)
                     50: {
                     51:        // EA の計算
                     52:        ea = addr + offset / 8;
                     53:        local_offset = offset % 8;
                     54:        if (local_offset < 0) {
                     55:                local_offset += 8;
                     56:                ea--;
                     57:        }
                     58: 
                     59:        // アクセスするバイト数
                     60:        bytes = (local_offset + width + 7) / 8;
                     61: 
                     62:        // 40ビットバッファに読み込む
                     63:        if (bytes <= 4) {
                     64:                buf = ((uint64)cpu->read_n(ea, bytes)) << ((5 - bytes) * 8);
                     65:        } else {
                     66:                // 実際どういうアクセスになるのか分からないが。
                     67:                if ((ea & 1) == 0) {
                     68:                        // 偶数アドレスから5バイト
                     69:                        buf = ((uint64)cpu->read_4(ea)) << 8;
                     70:                        buf |= ((uint64)cpu->read_1(ea + 4));
                     71:                } else {
                     72:                        // 奇数アドレスから5バイト
                     73:                        buf = ((uint64)cpu->read_1(ea)) << 32;
                     74:                        buf |= ((uint64)cpu->read_4(ea + 1));
                     75:                }
                     76:        }
                     77: 
                     78:        // 32ビット左詰めにする
                     79:        data = (buf >> (8 - local_offset)) & mask;
1.1.1.2 ! root       80: 
        !            81:        return (bytes <= 4);
1.1       root       82: }
                     83: 
                     84: // データレジスタに値を書き出す。
                     85: void
                     86: acc_bf::StoreReg(uint n)
                     87: {
                     88:        uint32 m = ROR32(mask, local_offset);
                     89:        uint32 d = ROR32(data, local_offset);
                     90: 
                     91:        cpu->reg.D[n] = (cpu->reg.D[n] & ~m) | (d & m);
                     92: }
                     93: 
                     94: // メモリに値を書き出す
                     95: void
                     96: acc_bf::StoreMem()
                     97: {
                     98:        // 32ビット左詰めデータを 40ビットバッファにマージ
                     99:        uint64 m = (uint64)mask << (8 - local_offset);
                    100:        uint64 d = (uint64)data << (8 - local_offset);
                    101:        buf = (buf & ~m) | (d & m);
                    102: 
                    103:        // 40ビットバッファを書き戻す
                    104:        if (bytes <= 4) {
                    105:                cpu->write_n(ea, bytes, buf >> ((5 - bytes) * 8));
                    106:        } else {
                    107:                // 実際どういうアクセスになるのか分からないが。
                    108:                if ((ea & 1) == 0) {
                    109:                        // 偶数アドレスから5バイト
                    110:                        cpu->write_4(ea, buf >> 8);
                    111:                        cpu->write_1(ea + 4, buf & 0xff);
                    112:                } else {
                    113:                        // 奇数アドレスから5バイト
                    114:                        cpu->write_1(ea, buf >> 32);
                    115:                        cpu->write_4(ea + 1, buf);
                    116:                }
                    117:        }
                    118: }

unix.superglobalmegacorp.com

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