模拟游戏机的内存映射,根据提供的地址访问不同的位置

Emulate memory-mapping of a game console, access different locations based on the address provided

我正在为旧游戏机实现模拟器,主要用于学习目的。

此控制台将 rom 和许多其他内容映射到其地址 space 内的区域。某些位置也被镜像,以便多个地址可以对应于相同的物理位置。我想效仿这个,但我不确定这样做的好方法是什么(也不知道这个过程叫什么,因此这个问题有点笼统)。

一个有用的东西是一个简单的、无序的地图。让它包含绝对地址和指向我的数据结构的相应指针。这样,我就可以轻松地将我需要的所有内容映射到系统的地址 space 中。这种方法的问题在于,它显然是一种内存消耗。由于上述镜像,即使是小 rom,我最终也有近千万个条目。当然,这不是正确的做法吗?

非常感谢任何帮助。

编辑:

提供一些关于我具体是怎么做的细节:

有问题的系统当然是 SNES。使用 this wiki 作为我的主要资源,我实现了上面提到的内容如下:

如果我现在想访问地址 space 内的任何内容,我可以简单地使用系统将在内部使用的地址。

与其使用简单的地图(即使有范围也可以变大),不如使用更智能的地图。

例如,如果控制台将 0x10XXXX0x1FXXXX 全部映射到相同的 0x20XXXX,您可以设计一个结构来保存该重复(开始 0x100000 结束 0x1FFFFF 重复 0x010000 尽管您可能想使用位掩码而不是重复)。

我假设对于连续地址,物理位置也是连续的,在某些内存块或 "chunks" 内。也就是说,如果地址 0x0000 映射到 0xFF00,则 0x0004 映射到 0xFF04。

如果它们是这样工作的,那么您可以制作一个包含这些块信息的列表。说:

struct Chunk
{
   int addressStart, memoryStart, size;
}

块可能按 addressStart 排序,因此您可以找到任何地址所需的正确块。这需要您迭代列表,但如果您只有几个块,这可能是可以接受的。

我目前和你在同一条船上,正在做一个 NES 模拟器用于学习目的。完整的内存映射被声明为字节指针数组。每个指针都可以指向另一个数组,这让我在镜像的情况下可以有指向相同数据的指针。

byte *memoryMap[cpuMemSize];

我遍历重复的地址并将它们映射到指向以下数组中的字节。 ram 数组是在 CPU 的内存映射中被映射 4 次的内存。

byte ram[ramSize];

以下代码遍历 RAM 数组并将其映射到 CPU 内存映射 4 次。

// map RAM 4 times to emulate mirroring
mem_address memAddr = 0;
for (int x = 0; x < 4; ++x)
{
    for (mem_address ramAddr = 0; ramAddr < ramSize; ++ramAddr.value)
    {
        memoryMap[memAddr.value++] = &ram[ramAddr.value];
    }
}

然后您可以使用类似这样的方法将 a 值写入第 256 个字节,这当然会传播到内存映射的其他部分,因为它们指向内存中的相同字节:

*memoryMap[0x00ff] = 10;

我还没有真正测试过这个,想做一些关于 CPU 缓存使用和性能的更多测试。当我偶然发现您的问题并认为我会投入(未经验证的)两美分时,我显然正在寻找其他方法来做到这一点。希望这是有道理的。