|
|
nono 0.3.0
//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//
//
// 物理バスアクセス?
//
// addr はそれぞれアラインされていること
#include "bus.h"
#include "ram.h"
IODevice *devtable[256];
// RAM へのアクセスは、アクセスアドレスが direct_ram_size 未満なら ram[] を
// 直接アクセスし、そうでなければデバイスクラス経由でアクセスする。
// 高速モードでは RAM デバイスを経由すること自体とその中でアクセスウェイトを
// 計算する分を回避したい。
int direct_ram_size;
uint64
vm_phys_read_8(uint32 addr)
{
uint64 data;
if (addr < direct_ram_size) {
data = mainram[HLB(addr)];
} else {
IODevice *dev = ::devtable[addr >> 24];
data = dev->Read8(addr);
}
return data;
}
uint64
vm_phys_read_16(uint32 addr)
{
uint64 data;
if (__predict_false((addr & 1) != 0))
VMPANIC("unaligned access $%08x", addr);
if (addr < direct_ram_size) {
data = *(uint16 *)&mainram[HLW(addr)];
} else {
IODevice *dev = ::devtable[addr >> 24];
data = dev->Read16(addr);
}
return data;
}
uint64
vm_phys_read_32(uint32 addr)
{
uint64 data;
if (__predict_false((addr & 3) != 0))
VMPANIC("unaligned access $%08x", addr);
if (addr < direct_ram_size) {
data = *(uint32 *)&mainram[addr];
} else {
IODevice *dev = ::devtable[addr >> 24];
data = dev->Read32(addr);
}
return data;
}
uint64
vm_phys_write_8(uint32 addr, uint32 data)
{
if (addr < direct_ram_size) {
mainram[HLB(addr)] = data;
return 0;
} else {
IODevice *dev = ::devtable[addr >> 24];
return dev->Write8(addr, data);
}
}
uint64
vm_phys_write_16(uint32 addr, uint32 data)
{
if (__predict_false((addr & 1) != 0))
VMPANIC("unaligned access $%08x", addr);
if (addr < direct_ram_size) {
*(uint16 *)&mainram[HLW(addr)] = data;
return 0;
} else {
IODevice *dev = ::devtable[addr >> 24];
return dev->Write16(addr, data);
}
}
uint64
vm_phys_write_32(uint32 addr, uint32 data)
{
if (__predict_false((addr & 3) != 0))
VMPANIC("unaligned access $%08x", addr);
if (addr < direct_ram_size) {
*(uint32 *)&mainram[addr] = data;
return 0;
} else {
IODevice *dev = ::devtable[addr >> 24];
return dev->Write32(addr, data);
}
}
uint64
vm_phys_peek_8(uint32 addr)
{
uint64 data;
if (addr < direct_ram_size) {
data = mainram[HLB(addr)];
} else {
IODevice *dev = ::devtable[addr >> 24];
data = dev->Peek8(addr);
}
return data;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.