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