模拟一张简单的图形卡



好的。我可以找到简单架构的模拟设计。(编辑:绝对喜欢不是x86(

例如,使用int作为程序计数器,使用byte array作为内存等等。

但是我如何模拟图形卡(可以想象的最简单的图形卡(的功能

比如使用array来表示每个像素,并逐个"绘制"每个像素
但是什么时候绘画——与CPU同步还是异步?谁将graphic data存储在该阵列中?是否有存储像素和绘制像素的说明

请考虑所有的问号("?"(并不意味着"你问了很多问题",而是解释了问题本身——如何模拟图形卡?

编辑:链接到CPU+内存模拟的基本实现设计

图形卡通常具有许多KB或MB的内存,用于存储随后显示在屏幕上的各个像素的颜色。该卡每秒扫描该存储器多次,将像素颜色的数字表示转换为显示器能够理解和可视化的视频信号(模拟或数字(。

CPU可以访问这个存储器,每当它更改它时,卡最终会将新的颜色数据转换为适当的视频信号,显示器会显示更新的图片。该卡异步完成所有处理,不需要CPU的太多帮助。从CPU的角度来看,这很像是将新的像素颜色写入图形卡内存中与像素坐标对应的位置,然后忘记它。它在现实中可能会稍微复杂一点(由于tearingsnow等较差的同步伪影(,但这就是它的要旨。

当您模拟图形卡时,您需要以某种方式将模拟卡的内存镜像到物理图形卡的内存中。如果在操作系统中,您可以直接访问物理图形卡的内存,那么这是一项简单的任务。简单地实现对模拟计算机内存的写入,如下所示:

void MemoryWrite(unsigned long Address, unsigned char Value)
{
  if ((Address >= SimulatedCardVideoMemoryStart) &&
      (Address - SimulatedCardVideoMemoryStart < SimulatedCardVideoMemorySize))
  {
    PhysicalCard[Address - SimulatedCardVideoMemoryStart] = Value;
  }
  EmulatedComputerMemory[Address] = Value;
}

当然,以上假设模拟卡具有与物理卡完全相同的分辨率(例如,1024x768(和像素表示(例如,每个像素3个字节,第一个字节表示红色,第二个字节表示绿色,第三个字节表示蓝色(。在现实生活中,事情可能会稍微复杂一些,但这也是一般的想法。

如果您使代码可由PC BIOS引导,并将其限制为仅使用BIOS服务功能(中断(和所有其他PC设备的直接硬件访问,则可以直接在MSDOS中或在没有任何操作系统的裸机x86 PC上访问物理卡的内存。

顺便说一句,将模拟器实现为DOS程序并直接在Windows XP中运行可能会非常容易(Vista和7在32位版本中对DOS应用程序的支持非常有限,在64位版本中没有;但是,您可以安装XP模式,即在7中的VM中安装XP(,或者在DOSBox这样的软件中运行它,它似乎可用于多个操作系统。

如果你把它实现为一个Windows程序,你必须使用GDIDirectX才能在屏幕上画出一些东西。除非我弄错了,否则这两个选项都不允许您直接访问物理卡的内存,以便自动显示其中的更改。

如果需要大量渲染,使用GDI或DirectX在屏幕上绘制单个像素可能会很昂贵。每次其中一个像素发生变化时,重新绘制所有模拟卡的像素都会导致相同的性能问题。最好的解决方案可能是每秒更新屏幕25-50次,并且只更新自上次重画以来发生更改的部分。将模拟卡的缓冲区细分为较小的缓冲区,表示64x64像素的矩形区域,每当模拟器写入时,将这些缓冲区标记为"脏",当它们在屏幕上绘制时,将其标记为"干净"。您可以设置一个周期性计时器来驱动屏幕重绘,并在单独的线程中进行。你应该能够在Linux中做类似的事情,但我对那里的图形编程不太了解。

最新更新