|
|
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"
13: #include "mpu.h"
14: #include "nmi.h"
1.1.1.9 ! root 15: #include "power.h"
1.1.1.4 root 16: #include "ram.h"
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: // グローバル参照用
22: SysportDevice *gSysport;
1.1.1.5 root 23:
1.1.1.8 root 24: // コンストラクタ
1.1 root 25: SysportDevice::SysportDevice()
1.1.1.7 root 26: : inherited("SystemPort")
1.1 root 27: {
1.1.1.7 root 28: AddAlias("SysPort");
29:
1.1 root 30: devaddr = baseaddr;
31: devlen = 0x2000;
32: }
33:
1.1.1.8 root 34: // デストラクタ
1.1 root 35: SysportDevice::~SysportDevice()
36: {
1.1.1.8 root 37: gSysport = NULL;
1.1 root 38: }
39:
1.1.1.8 root 40: // リセット
1.1.1.4 root 41: void
1.1.1.8 root 42: SysportDevice::ResetHard(bool poweron)
1.1.1.4 root 43: {
1.1.1.6 root 44: sysport.contrast = 0; // XXX 未調査
1.1.1.4 root 45: sysport.ram_wait = 0;
46: sysport.rom_wait = 0;
1.1.1.6 root 47: sysport.key_ctrl = false;
1.1.1.9 ! root 48: sysport.pwoff_count = 0;
! 49: gPower->SetSystemPowerOn(true);
1.1.1.4 root 50: }
51:
1.1 root 52: uint64
1.1.1.5 root 53: SysportDevice::Read(uint32 offset)
1.1 root 54: {
55: uint32 data;
56:
1.1.1.5 root 57: switch (offset) {
1.1 root 58: case SYSPORT::CONTRAST:
59: data = 0xf0 | sysport.contrast;
60: break;
61: case SYSPORT::SCOPE3D:
62: data = 0xff;
63: break;
64: case SYSPORT::IMAGEUNIT:
65: data = 0xff;
66: break;
67: case SYSPORT::KEY:
1.1.1.8 root 68: // XXX bit3 以外は要実機確認
69: data = 0xf7;
70: if (gKeyboard->IsConnected()) {
71: data |= 0x08;
72: }
1.1 root 73: break;
74: case SYSPORT::WAIT:
75: data = 0xff;
76: break;
77: case SYSPORT::MPU:
78: data = 0xdc;
79: break;
80: case SYSPORT::SRAMWP:
81: data = 0xff;
82: break;
1.1.1.3 root 83: case SYSPORT::POWEROFF:
84: data = 0xff;
85: break;
86: default:
87: __unreachable();
1.1 root 88: }
1.1.1.9 ! root 89: putlog(2, "$%06x -> $%02x", gMPU->GetPaddr(), data);
1.1 root 90: return data;
91: }
92:
93: uint64
1.1.1.5 root 94: SysportDevice::Write(uint32 offset, uint32 data)
1.1 root 95: {
1.1.1.5 root 96: switch (offset) {
1.1 root 97: case SYSPORT::CONTRAST:
98: sysport.contrast = data & 15;
99: break;
100:
101: case SYSPORT::SCOPE3D:
102: case SYSPORT::IMAGEUNIT:
103: break;
104:
105: case SYSPORT::KEY:
1.1.1.3 root 106: data &= 0x0e;
1.1.1.8 root 107: // bit1
108: if ((data & 0x02)) {
1.1.1.9 ! root 109: putlog(0, "$e8e007 <- $%02x (HRL NOT IMPLEMENTED)", data);
1.1.1.3 root 110: }
1.1.1.8 root 111: // bit2: NMI リセット
112: if ((data & 0x04)) {
113: gNMI->NegateNMI();
114: }
1.1.1.6 root 115: sysport.key_ctrl = (data & 0x08);
1.1 root 116: break;
117:
118: case SYSPORT::WAIT:
1.1.1.4 root 119: {
1.1 root 120: // 設定値で保持
121: sysport.rom_wait = data >> 4;
122: sysport.ram_wait = data;
1.1.1.4 root 123:
124: // ROM に指示。常に設定値 + 2 でよい
125: gIPLROM1->SetWait(sysport.rom_wait + 2);
126: gIPLROM2->SetWait(sysport.rom_wait + 2);
127: gCGROM->SetWait(sysport.rom_wait + 2);
128: // RAM に指示。InsideOut p.124
129: int wait = sysport.ram_wait;
130: if (wait > 0)
131: wait += 2;
132: gRAM->SetWait(wait);
1.1 root 133: break;
1.1.1.4 root 134: }
1.1 root 135:
136: case SYSPORT::MPU:
137: break;
138:
139: case SYSPORT::SRAMWP:
140: if (data == 0x31) {
141: gSRAM->write_enable(true);
142: } else {
143: gSRAM->write_enable(false);
144: }
145: break;
146:
147: case SYSPORT::POWEROFF:
1.1.1.9 ! root 148: {
! 149: static const std::array<uint8, 3> sig { 0x00, 0x0f, 0x0f };
! 150:
! 151: assertmsg(sysport.pwoff_count < sig.size(),
! 152: "sysport.pwoff_count=%d", sysport.pwoff_count);
! 153: if (data == sig[sysport.pwoff_count]) {
! 154: sysport.pwoff_count++;
! 155: } else {
! 156: sysport.pwoff_count = 0;
! 157: }
! 158: putlog(2, "$e8e00f (POWEROFF) <- %02x (count=%d)",
! 159: data, sysport.pwoff_count);
! 160: if (sysport.pwoff_count == sig.size()) {
! 161: // pwoff_count はここではクリアせず、電源オン時に再初期化する。
! 162: putlog(1, "$e8e00f (POWEROFF) Power Off");
! 163: gPower->SetSystemPowerOn(false);
! 164: }
1.1 root 165: break;
1.1.1.9 ! root 166: }
1.1.1.3 root 167:
168: default:
169: __unreachable();
1.1 root 170: }
171: return 0;
172: }
173:
174: uint64
1.1.1.5 root 175: SysportDevice::Peek(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:
181: data = 0xf0 | sysport.contrast;
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;
192: if (gKeyboard->IsConnected()) {
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:
209: __unreachable();
1.1 root 210: }
211: return data;
212: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.