|
|
1.1 root 1: //
2: // nono
1.1.1.3 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
1.1.1.3 root 6:
1.1 root 7: // 論理アクセス
8:
1.1.1.4 ! root 9: #include "mpu680x0.h"
1.1 root 10:
11: // バスエラー時に SSW をセットする。
1.1.1.4 ! root 12: // {fetch,read,write}_NN_mmu() 関数の下請け。
! 13: void
! 14: m68kbus::SET_SSW(bool use_mmu, uint size)
1.1 root 15: {
16: // サイズを設定
1.1.1.4 ! root 17: ssw &= ~M68K::SSW_SIZE_MASK;
! 18: ssw |= size;
1.1 root 19:
20: if (use_mmu) {
21: // データアクセスなら再試行のため DataFault ビットをセット。
22: // 命令アクセスなら RB をセット。
1.1.1.4 ! root 23: if ((ssw & M68K::FC_DATA)) {
! 24: ssw |= M68K::SSW_DF;
1.1 root 25: } else {
1.1.1.4 ! root 26: ssw |= M68K::SSW_RB;
1.1 root 27: }
28: }
29: }
30:
1.1.1.4 ! root 31: // {fetch,read,write}_NN() と {read,write}_NN_fc() の共通部分。
1.1 root 32: // fetch には FC 指定版はないので分ける必要は本来ないけど対称性のため。
1.1.1.4 ! root 33: // bus に必要な情報はセットされている。
1.1 root 34: // _bus 接尾辞はバスアクセスというより bus 構造体を使ったアクセスという感じ。
35:
1.1.1.4 ! root 36: inline uint32
! 37: MPU680x0Device::fetch_16_bus()
1.1 root 38: {
1.1.1.4 ! root 39: if (mmu_enable) {
! 40: return fetch_16_mmu<true>();
1.1 root 41: } else {
1.1.1.4 ! root 42: return fetch_16_mmu<false>();
1.1 root 43: }
44: }
45:
1.1.1.4 ! root 46: inline uint32
! 47: MPU680x0Device::fetch_32_bus()
1.1 root 48: {
1.1.1.4 ! root 49: if (mmu_enable) {
! 50: return fetch_32_mmu<true>();
1.1 root 51: } else {
1.1.1.4 ! root 52: return fetch_32_mmu<false>();
1.1 root 53: }
54: }
55:
1.1.1.4 ! root 56: inline uint32
! 57: MPU680x0Device::read_8_bus()
1.1 root 58: {
1.1.1.4 ! root 59: if(1)putlog(2, "%s $%08x", __func__, bus.laddr);
! 60: if (mmu_enable) {
! 61: return read_8_mmu<true>();
1.1 root 62: } else {
1.1.1.4 ! root 63: return read_8_mmu<false>();
1.1 root 64: }
65: }
66:
1.1.1.4 ! root 67: inline uint32
! 68: MPU680x0Device::read_16_bus()
1.1 root 69: {
1.1.1.4 ! root 70: if(1)putlog(2, "%s $%08x", __func__, bus.laddr);
! 71: if (mmu_enable) {
! 72: return read_16_mmu<true>();
1.1 root 73: } else {
1.1.1.4 ! root 74: return read_16_mmu<false>();
1.1 root 75: }
76: }
77:
1.1.1.4 ! root 78: inline uint32
! 79: MPU680x0Device::read_32_bus()
1.1 root 80: {
1.1.1.4 ! root 81: if(1)putlog(2, "%s $%08x", __func__, bus.laddr);
! 82: if (mmu_enable) {
! 83: return read_32_mmu<true>();
1.1 root 84: } else {
1.1.1.4 ! root 85: return read_32_mmu<false>();
1.1 root 86: }
87: }
88:
1.1.1.4 ! root 89: inline void
! 90: MPU680x0Device::write_8_bus()
1.1 root 91: {
1.1.1.4 ! root 92: if(1)putlog(2, "%s $%08x", __func__, bus.laddr);
! 93: if (mmu_enable) {
! 94: write_8_mmu<true>();
1.1 root 95: } else {
1.1.1.4 ! root 96: write_8_mmu<false>();
1.1 root 97: }
98: }
99:
1.1.1.4 ! root 100: inline void
! 101: MPU680x0Device::write_16_bus()
1.1 root 102: {
1.1.1.4 ! root 103: if(1)putlog(2, "%s $%08x", __func__, bus.laddr);
! 104: if (mmu_enable) {
! 105: write_16_mmu<true>();
1.1 root 106: } else {
1.1.1.4 ! root 107: write_16_mmu<false>();
1.1 root 108: }
109: }
110:
1.1.1.4 ! root 111: inline void
! 112: MPU680x0Device::write_32_bus()
1.1 root 113: {
1.1.1.4 ! root 114: if(1)putlog(2, "%s $%08x", __func__, bus.laddr);
! 115: if (mmu_enable) {
! 116: write_32_mmu<true>();
1.1 root 117: } else {
1.1.1.4 ! root 118: write_32_mmu<false>();
1.1 root 119: }
120: }
121:
122: //
123: // CPU 内部からのメモリアクセスは常にこの8つ (またはこれを呼び出すヘルパー
124: // 関数) を呼ぶこと。
1.1.1.4 ! root 125: // uint32 fetch_{16,32}()
! 126: // uint32 read_{8,16,32}(laddr)
! 127: // void write_{8,16,32}(laddr, data)
1.1 root 128: //
129:
130: uint32
1.1.1.4 ! root 131: MPU680x0Device::fetch_16()
1.1 root 132: {
1.1.1.4 ! root 133: bus.ssw = M68K::SSW_BUS_R | bus.fc2 | M68K::FC_PROG;
! 134: bus.laddr = reg.pc;
! 135: return fetch_16_bus();
1.1 root 136: }
137:
138: uint32
1.1.1.4 ! root 139: MPU680x0Device::fetch_32()
1.1 root 140: {
1.1.1.4 ! root 141: bus.ssw = M68K::SSW_BUS_R | bus.fc2 | M68K::FC_PROG;
! 142: bus.laddr = reg.pc;
! 143: return fetch_32_bus();
1.1 root 144: }
145:
146: uint32
1.1.1.4 ! root 147: MPU680x0Device::read_8(uint32 addr)
1.1 root 148: {
1.1.1.4 ! root 149: bus.ssw = M68K::SSW_BUS_R | bus.fc2 | M68K::FC_DATA;
! 150: bus.laddr = addr;
! 151: return read_8_bus();
1.1 root 152: }
153:
154: uint32
1.1.1.4 ! root 155: MPU680x0Device::read_16(uint32 addr)
1.1 root 156: {
1.1.1.4 ! root 157: bus.ssw = M68K::SSW_BUS_R | bus.fc2 | M68K::FC_DATA;
! 158: bus.laddr = addr;
! 159: return read_16_bus();
1.1 root 160: }
161:
162: uint32
1.1.1.4 ! root 163: MPU680x0Device::read_32(uint32 addr)
1.1 root 164: {
1.1.1.4 ! root 165: bus.ssw = M68K::SSW_BUS_R | bus.fc2 | M68K::FC_DATA;
! 166: bus.laddr = addr;
! 167: return read_32_bus();
1.1 root 168: }
169:
170: void
1.1.1.4 ! root 171: MPU680x0Device::write_8(uint32 addr, uint32 data)
1.1 root 172: {
1.1.1.4 ! root 173: bus.ssw = M68K::SSW_BUS_W | bus.fc2 | M68K::FC_DATA;
! 174: bus.laddr = addr;
! 175: bus.data = data;
! 176: write_8_bus();
1.1 root 177: }
178:
179: void
1.1.1.4 ! root 180: MPU680x0Device::write_16(uint32 addr, uint32 data)
1.1 root 181: {
1.1.1.4 ! root 182: bus.ssw = M68K::SSW_BUS_W | bus.fc2 | M68K::FC_DATA;
! 183: bus.laddr = addr;
! 184: bus.data = data;
! 185: write_16_bus();
1.1 root 186: }
187:
188: void
1.1.1.4 ! root 189: MPU680x0Device::write_32(uint32 addr, uint32 data)
1.1 root 190: {
1.1.1.4 ! root 191: bus.ssw = M68K::SSW_BUS_W | bus.fc2 | M68K::FC_DATA;
! 192: bus.laddr = addr;
! 193: bus.data = data;
! 194: write_32_bus();
1.1 root 195: }
196:
197: //
198: // MOVES 用の FC 指定版。
199: // 通常アクセスが現在の FC 空間に対してだが、
200: // こちらは SFC/DFC で指定された FC 空間に対してアクセスする。
201: //
202:
203: uint32
1.1.1.4 ! root 204: MPU680x0Device::read_8_fc(uint32 addr)
1.1 root 205: {
1.1.1.4 ! root 206: bus.ssw = M68K::SSW_BUS_R | reg.sfc;
! 207: bus.laddr = addr;
! 208: return read_8_bus();
1.1 root 209: }
210:
211: uint32
1.1.1.4 ! root 212: MPU680x0Device::read_16_fc(uint32 addr)
1.1 root 213: {
1.1.1.4 ! root 214: bus.ssw = M68K::SSW_BUS_R | reg.sfc;
! 215: bus.laddr = addr;
! 216: return read_16_bus();
1.1 root 217: }
218:
219: uint32
1.1.1.4 ! root 220: MPU680x0Device::read_32_fc(uint32 addr)
1.1 root 221: {
1.1.1.4 ! root 222: bus.ssw = M68K::SSW_BUS_R | reg.sfc;
! 223: bus.laddr = addr;
! 224: return read_32_bus();
1.1 root 225: }
226:
227: void
1.1.1.4 ! root 228: MPU680x0Device::write_8_fc(uint32 addr, uint32 data)
1.1 root 229: {
1.1.1.4 ! root 230: bus.ssw = M68K::SSW_BUS_W | reg.dfc;
! 231: bus.laddr = addr;
! 232: bus.data = data;
! 233: write_8_bus();
1.1 root 234: }
235:
236: void
1.1.1.4 ! root 237: MPU680x0Device::write_16_fc(uint32 addr, uint32 data)
1.1 root 238: {
1.1.1.4 ! root 239: bus.ssw = M68K::SSW_BUS_W | reg.dfc;
! 240: bus.laddr = addr;
! 241: bus.data = data;
! 242: write_16_bus();
1.1 root 243: }
244:
245: void
1.1.1.4 ! root 246: MPU680x0Device::write_32_fc(uint32 addr, uint32 data)
1.1 root 247: {
1.1.1.4 ! root 248: bus.ssw = M68K::SSW_BUS_W | reg.dfc;
! 249: bus.laddr = addr;
! 250: bus.data = data;
! 251: write_32_bus();
1.1 root 252: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.