|
|
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: // メモリから値を読み込む。 ! 47: void ! 48: acc_bf::LoadMem(uint32 addr) ! 49: { ! 50: // EA の計算 ! 51: ea = addr + offset / 8; ! 52: local_offset = offset % 8; ! 53: if (local_offset < 0) { ! 54: local_offset += 8; ! 55: ea--; ! 56: } ! 57: ! 58: // アクセスするバイト数 ! 59: bytes = (local_offset + width + 7) / 8; ! 60: ! 61: // 40ビットバッファに読み込む ! 62: if (bytes <= 4) { ! 63: buf = ((uint64)cpu->read_n(ea, bytes)) << ((5 - bytes) * 8); ! 64: } else { ! 65: // 実際どういうアクセスになるのか分からないが。 ! 66: if ((ea & 1) == 0) { ! 67: // 偶数アドレスから5バイト ! 68: buf = ((uint64)cpu->read_4(ea)) << 8; ! 69: buf |= ((uint64)cpu->read_1(ea + 4)); ! 70: } else { ! 71: // 奇数アドレスから5バイト ! 72: buf = ((uint64)cpu->read_1(ea)) << 32; ! 73: buf |= ((uint64)cpu->read_4(ea + 1)); ! 74: } ! 75: } ! 76: ! 77: // 32ビット左詰めにする ! 78: data = (buf >> (8 - local_offset)) & mask; ! 79: } ! 80: ! 81: // データレジスタに値を書き出す。 ! 82: void ! 83: acc_bf::StoreReg(uint n) ! 84: { ! 85: uint32 m = ROR32(mask, local_offset); ! 86: uint32 d = ROR32(data, local_offset); ! 87: ! 88: cpu->reg.D[n] = (cpu->reg.D[n] & ~m) | (d & m); ! 89: } ! 90: ! 91: // メモリに値を書き出す ! 92: void ! 93: acc_bf::StoreMem() ! 94: { ! 95: // 32ビット左詰めデータを 40ビットバッファにマージ ! 96: uint64 m = (uint64)mask << (8 - local_offset); ! 97: uint64 d = (uint64)data << (8 - local_offset); ! 98: buf = (buf & ~m) | (d & m); ! 99: ! 100: // 40ビットバッファを書き戻す ! 101: if (bytes <= 4) { ! 102: cpu->write_n(ea, bytes, buf >> ((5 - bytes) * 8)); ! 103: } else { ! 104: // 実際どういうアクセスになるのか分からないが。 ! 105: if ((ea & 1) == 0) { ! 106: // 偶数アドレスから5バイト ! 107: cpu->write_4(ea, buf >> 8); ! 108: cpu->write_1(ea + 4, buf & 0xff); ! 109: } else { ! 110: // 奇数アドレスから5バイト ! 111: cpu->write_1(ea, buf >> 32); ! 112: cpu->write_4(ea + 1, buf); ! 113: } ! 114: } ! 115: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.