|
|
nono 1.7.0
//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//
//
// システムポート
//
#include "sysport.h"
#include "keyboard.h"
#include "mainbus.h"
#include "mainram.h"
#include "monitor.h"
#include "nmi.h"
#include "power.h"
#include "romimg_x68k.h"
#include "sram.h"
#include "videoctlr.h"
#include <array>
// コンストラクタ
SysportDevice::SysportDevice()
: inherited(OBJ_SYSPORT)
{
monitor = gMonitorManager->Regist(ID_MONITOR_SYSPORT, this);
monitor->SetCallback(&SysportDevice::MonitorScreen);
monitor->SetSize(56, 8);
}
// デストラクタ
SysportDevice::~SysportDevice()
{
}
// 初期化
bool
SysportDevice::Init()
{
cgrom = GetCGROMDevice();
iplrom1 = GetIPLROM1Device();
iplrom2 = GetIPLROM2Device();
keyboard = GetKeyboard();
mainram = GetMainRAMDevice();
nmi = GetNMIDevice();
sram = GetSRAMDevice();
videoctlr = GetVideoCtlrDevice();
return true;
}
// リセット
void
SysportDevice::ResetHard(bool poweron)
{
sysport.ram_wait = 0;
sysport.rom_wait = 0;
sysport.key_ctrl = false;
sysport.pwoff_count = 0;
GetPowerDevice()->SetSystemPowerOn(true);
}
busdata
SysportDevice::ReadPort(uint32 offset)
{
busdata data;
data = PeekPort(offset);
putlog(2, "$%06x -> $%02x", GetMainbusDevice()->GetPaddr(), data.Data());
data |= BusData::Size1;
return data;
}
busdata
SysportDevice::WritePort(uint32 offset, uint32 data)
{
switch (offset) {
case SYSPORT::CONTRAST:
putlog(1, "$e8e001 <- $%02x", data);
videoctlr->SetContrast(data & 15);
break;
case SYSPORT::SCOPE3D:
case SYSPORT::IMAGEUNIT:
break;
case SYSPORT::KEY:
data &= 0x0e;
// bit1
if ((data & 0x02)) {
putlog(0, "$e8e007 <- $%02x (HRL NOT IMPLEMENTED)", data);
}
// bit2: NMI リセット
if ((data & 0x04)) {
nmi->NegateNMI();
}
sysport.key_ctrl = (data & 0x08);
break;
case SYSPORT::WAIT:
{
uint32 rom_wait = data >> 4;
uint32 ram_wait = data & 0xf;
// InsideOut p.124
rom_wait += 2;
if (ram_wait > 0) {
ram_wait += 2;
}
// ROM/RAM に指示。
iplrom1->SetWait(rom_wait);
iplrom2->SetWait(rom_wait);
cgrom->SetWait(rom_wait);
mainram->SetWait(ram_wait);
// ROM/RAM への指定値で保持する。
sysport.rom_wait = rom_wait;
sysport.ram_wait = ram_wait;
break;
}
case SYSPORT::MPU:
break;
case SYSPORT::SRAMWP:
if (data == 0x31) {
sram->WriteEnable(true);
} else {
sram->WriteEnable(false);
}
break;
case SYSPORT::POWEROFF:
{
static const std::array<uint8, 3> sig { 0x00, 0x0f, 0x0f };
if (sysport.pwoff_count >= sig.size()) {
// すでにカウントオーバーしている場合何もしない?
putlog(2, "$e8e00f (POWEROFF) <- %02x", data);
break;
}
if (data == sig[sysport.pwoff_count]) {
sysport.pwoff_count++;
} else {
sysport.pwoff_count = 0;
}
putlog(2, "$e8e00f (POWEROFF) <- %02x (count=%u)",
data, sysport.pwoff_count);
if (sysport.pwoff_count == sig.size()) {
// pwoff_count はここではクリアせず、電源オン時に再初期化する。
putlog(1, "$e8e00f (POWEROFF) Power Off");
GetPowerDevice()->SetSystemPowerOn(false);
}
break;
}
default:
VMPANIC("corrupted offset=%u", offset);
break;
}
busdata r = BusData::Size1;
return r;
}
busdata
SysportDevice::PeekPort(uint32 offset)
{
uint32 data;
switch (offset) {
case SYSPORT::CONTRAST:
data = 0xf0 | videoctlr->GetContrast();
break;
case SYSPORT::SCOPE3D:
data = 0xff;
break;
case SYSPORT::IMAGEUNIT:
data = 0xff;
break;
case SYSPORT::KEY:
// XXX bit3 以外は要実機確認
data = 0xf7;
if (keyboard->IsConnected()) {
data |= 0x08;
}
break;
case SYSPORT::WAIT:
data = 0xff;
break;
case SYSPORT::MPU:
data = 0xdc;
break;
case SYSPORT::SRAMWP:
data = 0xff;
break;
case SYSPORT::POWEROFF:
data = 0xff;
break;
default:
data = 0xff;
break;
}
return data;
}
bool
SysportDevice::PokePort(uint32 offset, uint32 data)
{
return false;
}
void
SysportDevice::MonitorScreen(Monitor *, TextScreen& screen)
{
screen.Clear();
static const char * const name[] = {
"Contrast",
"3D Scope",
"Image Unit",
"Keyboard Control",
"ROM/RAM Wait",
"MPU/FPU Type",
"SRAM Protect",
"PowerOff Sequence",
};
uint8 val[8];
const uint32 disphex = 0x39;
for (int i = 0; i < 8; i++) {
char hex[4];
if ((disphex & (1U << i)) != 0) {
val[i] = PeekPort(i);
snprintf(hex, sizeof(hex), "%02x", val[i]);
} else {
strlcpy(hex, "--", sizeof(hex));
}
screen.Print(0, i, "$%06x %s: #%u %-17s:",
baseaddr + 1 + i * 2, hex, i, name[i]);
}
int x = 34;
// #0 Contrast
screen.Print(x, 0, "%2u", videoctlr->GetContrast());
screen.Puts(x, 1, "(Not Supported)");
screen.Puts(x, 2, "(Not Supported)");
// #3 Keyboard
if ((val[SYSPORT::KEY] & 0x08) != 0) {
screen.Puts(x, 3, "Connected");
} else {
screen.Puts(x, 3, "Not connected");
}
// #4 ROM/RAM Wait
screen.Print(x, 4, "ROM %2u clk, RAM %2u clk",
sysport.rom_wait, sysport.ram_wait);
// #5 MPU/FPU Type
screen.Puts(x, 5, "MC68030 / 25MHz");
// #6 SRAM
if (sram->IsWriteable()) {
screen.Puts(x, 6, "Writeable");
} else {
screen.Puts(x, 6, "Protected");
}
// #7 PowerOff
screen.Print(x, 7, "%u/3", sysport.pwoff_count);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.