|
|
nono 0.0.3
//
// nono
// Copyright (C) 2017 [email protected]
//
#include "iocon.h"
#include "mpu.h"
std::unique_ptr<IOConDevice> gIOCon;
IOConDevice::IOConDevice()
{
logname = "iocon";
devname = "IOCtrler";
devaddr = baseaddr;
devlen = 0x2000;
}
IOConDevice::~IOConDevice()
{
}
inline uint64
IOConDevice::Decoder(uint32 addr) const
{
// 折り返しは?
addr -= baseaddr;
// 偶数アドレスはバスエラー
if ((addr & 1) == 0)
return (uint64)-1;
return addr >> 1;
}
uint64
IOConDevice::Read8(uint32 addr)
{
switch (Decoder(addr)) {
case 0: // $E9C001 割り込みステータス
return (fdc_int ? 0x80 : 0)
| (fdd_int ? 0x40 : 0)
| (prt_int ? 0x20 : 0)
| (hdd_int ? 0x10 : 0)
| (hdd_en ? 0x08 : 0)
| (fdc_en ? 0x04 : 0)
| (fdd_en ? 0x02 : 0)
| (prt_en ? 0x01 : 0);
case 1: // $E9C003 割り込みベクタ
return vector;
break;
}
return (uint64)-1;
}
uint64
IOConDevice::Read16(uint32 addr)
{
return 0xff00 | Read8(addr + 1);
}
uint64
IOConDevice::Write8(uint32 addr, uint32 data)
{
switch (Decoder(addr)) {
case 0: // $E9C001 割り込みマスク
hdd_en = (data & 0x08);
fdc_en = (data & 0x04);
fdd_en = (data & 0x02);
prt_en = (data & 0x01);
putlog(1, "割り込みマスク設定 HDD=%d FDC=%d FDD=%d PRT=%d",
hdd_en, fdc_en, fdd_en, prt_en);
return 0;
case 1: // $E9C003 割り込みベクタ
vector = data & 0xfc;
putlog(1, "割り込みベクタ設定 $%02x", vector);
return 0;
default:
break;
}
return (uint64)-1;
}
uint64
IOConDevice::Write16(uint32 addr, uint32 data)
{
return Write8(addr + 1, data);
}
uint64
IOConDevice::Peek8(uint32 addr)
{
switch (Decoder(addr)) {
case 0:
return (fdc_int ? 0x80 : 0)
| (fdd_int ? 0x40 : 0)
| (prt_int ? 0x20 : 0)
| (hdd_int ? 0x10 : 0)
| (hdd_en ? 0x08 : 0)
| (fdc_en ? 0x04 : 0)
| (fdd_en ? 0x02 : 0)
| (prt_en ? 0x01 : 0);
case 1:
return vector;
default:
return 0xff;
}
}
// FDC からの割り込み要求
void
IOConDevice::IntFDC()
{
fdc_int = true;
if (fdc_en) {
putlog(1, "FDC からの割り込み要求");
gMPU680x0->Interrupt(1, vector + 0);
} else {
putlog(2, "FDC からの割り込み要求(マスク)");
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.