|
|
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.9 root 19: #include <array>
1.1 root 20:
1.1.1.8 root 21: // コンストラクタ
1.1 root 22: SysportDevice::SysportDevice()
1.1.1.10 root 23: : inherited(OBJ_SYSPORT)
1.1 root 24: {
25: }
26:
1.1.1.8 root 27: // デストラクタ
1.1 root 28: SysportDevice::~SysportDevice()
29: {
1.1.1.10 root 30: }
31:
32: // 初期化
33: bool
34: SysportDevice::Init()
35: {
36: if (inherited::Init() == false) {
37: return false;
38: }
39:
40: cgrom = GetCGROMDevice();
41: iplrom1 = GetIPLROM1Device();
42: iplrom2 = GetIPLROM2Device();
43: keyboard = GetKeyboard();
44: mainram = GetMainRAMDevice();
45: nmi = GetNMIDevice();
46: sram = GetSRAMDevice();
47:
48: return true;
1.1 root 49: }
50:
1.1.1.8 root 51: // リセット
1.1.1.4 root 52: void
1.1.1.8 root 53: SysportDevice::ResetHard(bool poweron)
1.1.1.4 root 54: {
1.1.1.6 root 55: sysport.contrast = 0; // XXX 未調査
1.1.1.4 root 56: sysport.ram_wait = 0;
57: sysport.rom_wait = 0;
1.1.1.6 root 58: sysport.key_ctrl = false;
1.1.1.9 root 59: sysport.pwoff_count = 0;
1.1.1.10 root 60: GetPowerDevice()->SetSystemPowerOn(true);
1.1.1.4 root 61: }
62:
1.1 root 63: uint64
1.1.1.5 root 64: SysportDevice::Read(uint32 offset)
1.1 root 65: {
66: uint32 data;
67:
1.1.1.5 root 68: switch (offset) {
1.1 root 69: case SYSPORT::CONTRAST:
70: data = 0xf0 | sysport.contrast;
71: break;
72: case SYSPORT::SCOPE3D:
73: data = 0xff;
74: break;
75: case SYSPORT::IMAGEUNIT:
76: data = 0xff;
77: break;
78: case SYSPORT::KEY:
1.1.1.8 root 79: // XXX bit3 以外は要実機確認
80: data = 0xf7;
1.1.1.10 root 81: if (keyboard->IsConnected()) {
1.1.1.8 root 82: data |= 0x08;
83: }
1.1 root 84: break;
85: case SYSPORT::WAIT:
86: data = 0xff;
87: break;
88: case SYSPORT::MPU:
89: data = 0xdc;
90: break;
91: case SYSPORT::SRAMWP:
92: data = 0xff;
93: break;
1.1.1.3 root 94: case SYSPORT::POWEROFF:
95: data = 0xff;
96: break;
97: default:
1.1.1.10 root 98: VMPANIC("corrupted offset=%d", offset);
99: return 0xff;
1.1 root 100: }
1.1.1.10 root 101: putlog(2, "$%06x -> $%02x", mpu->GetPaddr(), data);
1.1 root 102: return data;
103: }
104:
105: uint64
1.1.1.5 root 106: SysportDevice::Write(uint32 offset, uint32 data)
1.1 root 107: {
1.1.1.5 root 108: switch (offset) {
1.1 root 109: case SYSPORT::CONTRAST:
110: sysport.contrast = data & 15;
111: break;
112:
113: case SYSPORT::SCOPE3D:
114: case SYSPORT::IMAGEUNIT:
115: break;
116:
117: case SYSPORT::KEY:
1.1.1.3 root 118: data &= 0x0e;
1.1.1.8 root 119: // bit1
120: if ((data & 0x02)) {
1.1.1.9 root 121: putlog(0, "$e8e007 <- $%02x (HRL NOT IMPLEMENTED)", data);
1.1.1.3 root 122: }
1.1.1.8 root 123: // bit2: NMI リセット
124: if ((data & 0x04)) {
1.1.1.10 root 125: nmi->NegateNMI();
1.1.1.8 root 126: }
1.1.1.6 root 127: sysport.key_ctrl = (data & 0x08);
1.1 root 128: break;
129:
130: case SYSPORT::WAIT:
1.1.1.4 root 131: {
1.1 root 132: // 設定値で保持
133: sysport.rom_wait = data >> 4;
134: sysport.ram_wait = data;
1.1.1.4 root 135:
136: // ROM に指示。常に設定値 + 2 でよい
1.1.1.10 root 137: iplrom1->SetWait(sysport.rom_wait + 2);
138: iplrom2->SetWait(sysport.rom_wait + 2);
139: cgrom->SetWait(sysport.rom_wait + 2);
1.1.1.4 root 140: // RAM に指示。InsideOut p.124
141: int wait = sysport.ram_wait;
142: if (wait > 0)
143: wait += 2;
1.1.1.10 root 144: mainram->SetWait(wait);
1.1 root 145: break;
1.1.1.4 root 146: }
1.1 root 147:
148: case SYSPORT::MPU:
149: break;
150:
151: case SYSPORT::SRAMWP:
152: if (data == 0x31) {
1.1.1.10 root 153: sram->WriteEnable(true);
1.1 root 154: } else {
1.1.1.10 root 155: sram->WriteEnable(false);
1.1 root 156: }
157: break;
158:
159: case SYSPORT::POWEROFF:
1.1.1.9 root 160: {
161: static const std::array<uint8, 3> sig { 0x00, 0x0f, 0x0f };
162:
1.1.1.10 root 163: if (sysport.pwoff_count >= sig.size()) {
164: // すでにカウントオーバーしている場合何もしない?
165: putlog(2, "$e8e00f (POWEROFF) <- %02x", data);
166: break;
167: }
168:
1.1.1.9 root 169: if (data == sig[sysport.pwoff_count]) {
170: sysport.pwoff_count++;
171: } else {
172: sysport.pwoff_count = 0;
173: }
174: putlog(2, "$e8e00f (POWEROFF) <- %02x (count=%d)",
175: data, sysport.pwoff_count);
176: if (sysport.pwoff_count == sig.size()) {
177: // pwoff_count はここではクリアせず、電源オン時に再初期化する。
178: putlog(1, "$e8e00f (POWEROFF) Power Off");
1.1.1.10 root 179: GetPowerDevice()->SetSystemPowerOn(false);
1.1.1.9 root 180: }
1.1 root 181: break;
1.1.1.9 root 182: }
1.1.1.3 root 183:
184: default:
1.1.1.10 root 185: VMPANIC("corrupted offset=%d", offset);
186: break;
1.1 root 187: }
188: return 0;
189: }
190:
191: uint64
1.1.1.5 root 192: SysportDevice::Peek(uint32 offset)
1.1 root 193: {
194: uint32 data;
195:
1.1.1.5 root 196: switch (offset) {
1.1 root 197: case SYSPORT::CONTRAST:
198: data = 0xf0 | sysport.contrast;
199: break;
200: case SYSPORT::SCOPE3D:
201: data = 0xff;
202: break;
203: case SYSPORT::IMAGEUNIT:
204: data = 0xff;
205: break;
206: case SYSPORT::KEY:
1.1.1.8 root 207: // XXX bit3 以外は要実機確認
208: data = 0xf7;
1.1.1.10 root 209: if (keyboard->IsConnected()) {
1.1.1.8 root 210: data |= 0x08;
211: }
1.1 root 212: break;
213: case SYSPORT::WAIT:
214: data = 0xff;
215: break;
216: case SYSPORT::MPU:
217: data = 0xdc;
218: break;
219: case SYSPORT::SRAMWP:
220: data = 0xff;
221: break;
1.1.1.3 root 222: case SYSPORT::POWEROFF:
1.1 root 223: data = 0xff;
224: break;
1.1.1.3 root 225: default:
1.1.1.10 root 226: data = 0xff;
227: break;
1.1 root 228: }
229: return data;
230: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.