|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2022 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: #include "m68030bitfield.h"
1.1.1.2 ! root 8: #include "bitops.h"
1.1 root 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ビットバッファに読み込む
1.1.1.2 ! root 62: if (bytes <= 4) {
! 63: buf = ((uint64)cpu->read_n(ea, bytes)) << ((5 - bytes) * 8);
! 64: } else {
! 65: // 実際どういうアクセスになるのか分からないが。
1.1 root 66: if ((ea & 1) == 0) {
67: // 偶数アドレスから5バイト
1.1.1.2 ! root 68: buf = ((uint64)cpu->read_4(ea)) << 8;
! 69: buf |= ((uint64)cpu->read_1(ea + 4));
1.1 root 70: } else {
71: // 奇数アドレスから5バイト
1.1.1.2 ! root 72: buf = ((uint64)cpu->read_1(ea)) << 32;
! 73: buf |= ((uint64)cpu->read_4(ea + 1));
1.1 root 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ビットバッファを書き戻す
1.1.1.2 ! root 101: if (bytes <= 4) {
! 102: cpu->write_n(ea, bytes, buf >> ((5 - bytes) * 8));
! 103: } else {
! 104: // 実際どういうアクセスになるのか分からないが。
1.1 root 105: if ((ea & 1) == 0) {
106: // 偶数アドレスから5バイト
1.1.1.2 ! root 107: cpu->write_4(ea, buf >> 8);
! 108: cpu->write_1(ea + 4, buf & 0xff);
1.1 root 109: } else {
110: // 奇数アドレスから5バイト
1.1.1.2 ! root 111: cpu->write_1(ea, buf >> 32);
! 112: cpu->write_4(ea + 1, buf);
1.1 root 113: }
114: }
115: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.