|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.