|
|
nono 0.0.3
//
// nono
// Copyright (C) 2017 [email protected]
//
#include "vicon.h"
std::unique_ptr<ViconDevice> gVicon;
ViconDevice::ViconDevice()
{
logname = "vicon";
devname = "Vicon";
devaddr = baseaddr;
devlen = 0x2000;
}
ViconDevice::~ViconDevice()
{
}
// アドレスデコーダ
inline uint64
ViconDevice::Decoder(uint32 addr) const
{
// 折り返しは?
return addr - baseaddr;
}
uint64
ViconDevice::Read8(uint32 addr)
{
uint32 offset = Decoder(addr);
uint32 data;
if (offset < 0x400) {
// パレット
return palette.b[HB(offset)];
}
// レジスタ
switch (offset) {
case 0x401:
data = read_r0();
break;
case 0x500:
data = read_r1H();
break;
case 0x501:
data = read_r1L();
break;
case 0x600:
data = read_r2H();
break;
case 0x601:
data = read_r2L();
break;
default:
PANIC("Vicon $%06x.B 未実装読み込み", addr);
break;
}
return data;
}
uint64
ViconDevice::Read16(uint32 addr)
{
uint32 offset = Decoder(addr);
uint32 data;
if (offset < 0x400) {
return palette.w[offset / 2];
}
// レジスタ
switch (offset) {
case 0x400:
data = read_r0();
break;
case 0x500:
data = (read_r1H() << 8) | read_r1L();
break;
case 0x600:
data = (read_r2H() << 8) | read_r2L();
break;
default:
PANIC("Vicon $%06x.W 未実装読み込み", addr);
break;
}
return data;
}
uint64
ViconDevice::Write8(uint32 addr, uint32 data)
{
uint32 offset = Decoder(addr);
if (offset < 0x400) {
putlog(3, "パレット $%06x.B <- $%02x", addr, data);
palette.b[HB(offset)] = data;
return 0;
}
// レジスタ
switch (offset) {
case 0x400:
break;
case 0x401:
write_r0(data);
break;
case 0x500:
write_r1H(data);
break;
case 0x501:
write_r1L(data);
break;
case 0x600:
write_r2H(data);
break;
case 0x601:
write_r2L(data);
break;
default:
PANIC("Vicon $%06x.B <- $%02x 未実装書き込み", addr, data);
break;
}
return 0;
}
uint64
ViconDevice::Write16(uint32 addr, uint32 data)
{
uint32 offset = Decoder(addr);
if (offset < 0x400) {
if (offset < 0x200) {
putlog(3, "Gパレット $%06x [$%02x] <- $%04x",
addr, offset / 2, data);
} else {
putlog(3, "Tパレット $%06x [$%02x] <- $%04x",
addr, (offset - 0x200) / 2, data);
}
palette.w[offset / 2] = data;
return 0;
}
// レジスタ
switch (offset) {
case 0x400:
write_r0(data);
break;
case 0x500:
write_r1H(data >> 8);
write_r1L(data & 0xff);
break;
case 0x600:
write_r2H(data >> 8);
write_r2L(data & 0xff);
break;
default:
PANIC("Vicon $%06x.W <- $%04x 未実装書き込み", addr, data);
break;
}
return 0;
}
uint64
ViconDevice::Peek8(uint32 addr)
{
uint32 offset = Decoder(addr);
uint32 data;
if (offset < 0x400) {
return palette.b[HB(offset)];
}
switch (offset) {
case 0x401:
data = read_r0();
break;
case 0x500:
data = read_r1H();
break;
case 0x501:
data = read_r1L();
break;
case 0x600:
data = read_r2H();
break;
case 0x601:
data = read_r2L();
break;
default:
data = 0xff;
break;
}
return data;
}
uint32
ViconDevice::read_r0() const
{
return vicon.r0;
}
uint32
ViconDevice::read_r1H() const
{
return vicon.r1 >> 8;
}
uint32
ViconDevice::read_r1L() const
{
return vicon.r1 & 0xff;
}
uint32
ViconDevice::read_r2H() const
{
return vicon.r2 >> 8;
}
uint32
ViconDevice::read_r2L() const
{
return vicon.r2 & 0xff;
}
void
ViconDevice::write_r0(uint32 data)
{
putlog(0, "R0 <- $%02x 未実装書き込み", data);
vicon.r0 = data & 3;
}
void
ViconDevice::write_r1H(uint32 data)
{
putlog(0, "R1(H) <- $%02x 未実装書き込み", data);
vicon.r1 &= 0x00ff;
vicon.r1 |= (data & 0x3f00);
}
void
ViconDevice::write_r1L(uint32 data)
{
putlog(0, "R1(L) <- $%02x 未実装書き込み", data);
vicon.r1 &= 0xff00;
vicon.r1 |= (data & 0x00ff);
}
void
ViconDevice::write_r2H(uint32 data)
{
putlog(0, "R2(H) <- $%02x 未実装書き込み", data);
vicon.r2 &= 0x00ff;
vicon.r2 |= (data & 0xff00);
}
void
ViconDevice::write_r2L(uint32 data)
{
putlog(0, "R2(L) <- $%02x 未実装書き込み", data);
vicon.r2 &= 0xff00;
vicon.r2 |= (data & 0x007f);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.