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