|
|
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: //
6:
1.1.1.8 root 7: //
8: // システムポート
9: //
10:
1.1 root 11: #include "sysport.h"
1.1.1.8 root 12: #include "keyboard.h"
1.1.1.10 root 13: #include "mainram.h"
1.1.1.8 root 14: #include "mpu.h"
15: #include "nmi.h"
1.1.1.9 root 16: #include "power.h"
1.1.1.4 root 17: #include "romimg_x68k.h"
1.1 root 18: #include "sram.h"
1.1.1.12! root 19: #include "videoctlr.h"
1.1.1.9 root 20: #include <array>
1.1 root 21:
1.1.1.8 root 22: // コンストラクタ
1.1 root 23: SysportDevice::SysportDevice()
1.1.1.10 root 24: : inherited(OBJ_SYSPORT)
1.1 root 25: {
1.1.1.12! root 26: monitor.func = ToMonitorCallback(&SysportDevice::MonitorUpdate);
! 27: monitor.SetSize(56, 8);
! 28: monitor.Regist(ID_MONITOR_SYSPORT);
1.1 root 29: }
30:
1.1.1.8 root 31: // デストラクタ
1.1 root 32: SysportDevice::~SysportDevice()
33: {
1.1.1.10 root 34: }
35:
36: // 初期化
37: bool
38: SysportDevice::Init()
39: {
40: if (inherited::Init() == false) {
41: return false;
42: }
43:
44: cgrom = GetCGROMDevice();
45: iplrom1 = GetIPLROM1Device();
46: iplrom2 = GetIPLROM2Device();
47: keyboard = GetKeyboard();
48: mainram = GetMainRAMDevice();
49: nmi = GetNMIDevice();
50: sram = GetSRAMDevice();
1.1.1.12! root 51: videoctlr = GetVideoCtlrDevice();
1.1.1.10 root 52:
53: return true;
1.1 root 54: }
55:
1.1.1.8 root 56: // リセット
1.1.1.4 root 57: void
1.1.1.8 root 58: SysportDevice::ResetHard(bool poweron)
1.1.1.4 root 59: {
60: sysport.ram_wait = 0;
61: sysport.rom_wait = 0;
1.1.1.6 root 62: sysport.key_ctrl = false;
1.1.1.9 root 63: sysport.pwoff_count = 0;
1.1.1.10 root 64: GetPowerDevice()->SetSystemPowerOn(true);
1.1.1.4 root 65: }
66:
1.1.1.12! root 67: busdata
1.1.1.5 root 68: SysportDevice::Read(uint32 offset)
1.1 root 69: {
70: uint32 data;
71:
1.1.1.5 root 72: switch (offset) {
1.1 root 73: case SYSPORT::CONTRAST:
1.1.1.12! root 74: data = 0xf0 | videoctlr->GetContrast();
1.1 root 75: break;
76: case SYSPORT::SCOPE3D:
77: data = 0xff;
78: break;
79: case SYSPORT::IMAGEUNIT:
80: data = 0xff;
81: break;
82: case SYSPORT::KEY:
1.1.1.8 root 83: // XXX bit3 以外は要実機確認
84: data = 0xf7;
1.1.1.10 root 85: if (keyboard->IsConnected()) {
1.1.1.8 root 86: data |= 0x08;
87: }
1.1 root 88: break;
89: case SYSPORT::WAIT:
90: data = 0xff;
91: break;
92: case SYSPORT::MPU:
93: data = 0xdc;
94: break;
95: case SYSPORT::SRAMWP:
96: data = 0xff;
97: break;
1.1.1.3 root 98: case SYSPORT::POWEROFF:
99: data = 0xff;
100: break;
101: default:
1.1.1.10 root 102: VMPANIC("corrupted offset=%d", offset);
103: return 0xff;
1.1 root 104: }
1.1.1.10 root 105: putlog(2, "$%06x -> $%02x", mpu->GetPaddr(), data);
1.1 root 106: return data;
107: }
108:
1.1.1.12! root 109: busdata
1.1.1.5 root 110: SysportDevice::Write(uint32 offset, uint32 data)
1.1 root 111: {
1.1.1.5 root 112: switch (offset) {
1.1 root 113: case SYSPORT::CONTRAST:
1.1.1.12! root 114: putlog(1, "$e8e001 <- $%02x", data);
! 115: videoctlr->SetContrast(data & 15);
1.1 root 116: break;
117:
118: case SYSPORT::SCOPE3D:
119: case SYSPORT::IMAGEUNIT:
120: break;
121:
122: case SYSPORT::KEY:
1.1.1.3 root 123: data &= 0x0e;
1.1.1.8 root 124: // bit1
125: if ((data & 0x02)) {
1.1.1.9 root 126: putlog(0, "$e8e007 <- $%02x (HRL NOT IMPLEMENTED)", data);
1.1.1.3 root 127: }
1.1.1.8 root 128: // bit2: NMI リセット
129: if ((data & 0x04)) {
1.1.1.10 root 130: nmi->NegateNMI();
1.1.1.8 root 131: }
1.1.1.6 root 132: sysport.key_ctrl = (data & 0x08);
1.1 root 133: break;
134:
135: case SYSPORT::WAIT:
1.1.1.4 root 136: {
1.1.1.12! root 137: uint32 rom_wait = data >> 4;
! 138: uint32 ram_wait = data & 0xf;
! 139:
! 140: // InsideOut p.124
! 141: rom_wait += 2;
! 142: if (ram_wait > 0) {
! 143: ram_wait += 2;
! 144: }
! 145:
! 146: // ROM/RAM に指示。
! 147: iplrom1->SetWait(rom_wait);
! 148: iplrom2->SetWait(rom_wait);
! 149: cgrom->SetWait(rom_wait);
! 150: mainram->SetWait(ram_wait);
! 151:
! 152: // ROM/RAM への指定値で保持する。
! 153: sysport.rom_wait = rom_wait;
! 154: sysport.ram_wait = ram_wait;
1.1 root 155: break;
1.1.1.4 root 156: }
1.1 root 157:
158: case SYSPORT::MPU:
159: break;
160:
161: case SYSPORT::SRAMWP:
162: if (data == 0x31) {
1.1.1.10 root 163: sram->WriteEnable(true);
1.1 root 164: } else {
1.1.1.10 root 165: sram->WriteEnable(false);
1.1 root 166: }
167: break;
168:
169: case SYSPORT::POWEROFF:
1.1.1.9 root 170: {
171: static const std::array<uint8, 3> sig { 0x00, 0x0f, 0x0f };
172:
1.1.1.10 root 173: if (sysport.pwoff_count >= sig.size()) {
174: // すでにカウントオーバーしている場合何もしない?
175: putlog(2, "$e8e00f (POWEROFF) <- %02x", data);
176: break;
177: }
178:
1.1.1.9 root 179: if (data == sig[sysport.pwoff_count]) {
180: sysport.pwoff_count++;
181: } else {
182: sysport.pwoff_count = 0;
183: }
184: putlog(2, "$e8e00f (POWEROFF) <- %02x (count=%d)",
185: data, sysport.pwoff_count);
186: if (sysport.pwoff_count == sig.size()) {
187: // pwoff_count はここではクリアせず、電源オン時に再初期化する。
188: putlog(1, "$e8e00f (POWEROFF) Power Off");
1.1.1.10 root 189: GetPowerDevice()->SetSystemPowerOn(false);
1.1.1.9 root 190: }
1.1 root 191: break;
1.1.1.9 root 192: }
1.1.1.3 root 193:
194: default:
1.1.1.10 root 195: VMPANIC("corrupted offset=%d", offset);
196: break;
1.1 root 197: }
198: return 0;
199: }
200:
1.1.1.12! root 201: busdata
1.1.1.5 root 202: SysportDevice::Peek(uint32 offset)
1.1 root 203: {
204: uint32 data;
205:
1.1.1.5 root 206: switch (offset) {
1.1 root 207: case SYSPORT::CONTRAST:
1.1.1.12! root 208: data = 0xf0 | videoctlr->GetContrast();
1.1 root 209: break;
210: case SYSPORT::SCOPE3D:
211: data = 0xff;
212: break;
213: case SYSPORT::IMAGEUNIT:
214: data = 0xff;
215: break;
216: case SYSPORT::KEY:
1.1.1.8 root 217: // XXX bit3 以外は要実機確認
218: data = 0xf7;
1.1.1.10 root 219: if (keyboard->IsConnected()) {
1.1.1.8 root 220: data |= 0x08;
221: }
1.1 root 222: break;
223: case SYSPORT::WAIT:
224: data = 0xff;
225: break;
226: case SYSPORT::MPU:
227: data = 0xdc;
228: break;
229: case SYSPORT::SRAMWP:
230: data = 0xff;
231: break;
1.1.1.3 root 232: case SYSPORT::POWEROFF:
1.1 root 233: data = 0xff;
234: break;
1.1.1.3 root 235: default:
1.1.1.10 root 236: data = 0xff;
237: break;
1.1 root 238: }
239: return data;
240: }
1.1.1.12! root 241:
! 242: void
! 243: SysportDevice::MonitorUpdate(Monitor *, TextScreen& screen)
! 244: {
! 245: screen.Clear();
! 246:
! 247: static const char * const name[] = {
! 248: "Contrast",
! 249: "3D Scope",
! 250: "Image Unit",
! 251: "Keyboard Control",
! 252: "ROM/RAM Wait",
! 253: "MPU/FPU Type",
! 254: "SRAM Protect",
! 255: "PowerOff Sequence",
! 256: };
! 257:
! 258: uint8 val[8];
! 259: const uint32 disphex = 0x39;
! 260: for (int i = 0; i < 8; i++) {
! 261: char hex[4];
! 262: if ((disphex & (1U << i)) != 0) {
! 263: val[i] = Peek(i);
! 264: snprintf(hex, sizeof(hex), "%02x", val[i]);
! 265: } else {
! 266: strlcpy(hex, "--", sizeof(hex));
! 267: }
! 268:
! 269: screen.Print(0, i, "$%06x %s: #%d %-17s:",
! 270: baseaddr + 1 + i * 2, hex, i, name[i]);
! 271: }
! 272:
! 273: int x = 34;
! 274: // #0 Contrast
! 275: screen.Print(x, 0, "%2d", videoctlr->GetContrast());
! 276: screen.Puts(x, 1, "(Not Supported)");
! 277: screen.Puts(x, 2, "(Not Supported)");
! 278: // #3 Keyboard
! 279: if ((val[SYSPORT::KEY] & 0x08) != 0) {
! 280: screen.Puts(x, 3, "Connected");
! 281: } else {
! 282: screen.Puts(x, 3, "Not connected");
! 283: }
! 284: // #4 ROM/RAM Wait
! 285: screen.Print(x, 4, "ROM %2u clk, RAM %2u clk",
! 286: sysport.rom_wait, sysport.ram_wait);
! 287: // #5 MPU/FPU Type
! 288: screen.Puts(x, 5, "MC68030 / 25MHz");
! 289: // #6 SRAM
! 290: if (sram->IsWriteable()) {
! 291: screen.Puts(x, 6, "Writeable");
! 292: } else {
! 293: screen.Puts(x, 6, "Protected");
! 294: }
! 295: // #7 PowerOff
! 296: screen.Print(x, 7, "%d/3", sysport.pwoff_count);
! 297: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.