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