Annotation of nono/m680x0/m68030bitfield.cpp, revision 1.1.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.