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