首页 > 解决方案 > 如何在 c 或 asm 中切换到 Super VGA?

问题描述

我正在创建一个图形操作系统,我目前正在使用在保护模式之前启动的模式 19,但我希望提前获得更高的分辨率。我在 asm 中的图形激活

graphicmode:
  mov ax, 19; here select which mode you want
  int 16

感谢您的帮助 :) 我的程序运行但我在 0xA0000 中绘制,我认为我的缓冲区不足,因为我只看到了屏幕的一部分。你能帮助我吗?如何使用银行切换? 图片

标签: cassemblyx86-16osdevvga

解决方案


如何在 c 或 asm 中切换到 Super VGA?

适用于具有 BIOS 的旧 80x86 PC;几乎所有视频卡都支持 VBE(请参阅https://en.wikipedia.org/wiki/VESA_BIOS_Extensions)。在这种情况下,您的代码将要求它提供视频模式编号列表,然后使用这些编号获取有关每种视频模式的信息并过滤掉您的软件不支持的视频模式,然后选择“最佳”视频模式支持,并设置该视频模式。这是必要的,因为不同的计算机支持不同的视频模式(您不能只期望存在像 800*600 这样的特定视频模式,因为当该视频模式不存在时,您的代码将被破坏且无法使用)。有 3 种不同的方式使用 VBE 功能 - 使用实模式,使用随 VBE2.0 引入但在 VBE3.0 中已过时/可选的 32 位保护模式接口,以及使用 16 位保护模式接口,在VBE3.0中引入;但是有些功能不是

这意味着(启动后),对于 BIOS,支持所有显卡(带/不带 VBE,带/不带 32 位保护模式接口,以及带/不带 16 位保护模式接口)在引导后更改视频模式是严重的疼痛;特别是当操作系统是 64 位并且不能使用 virtual8086 模式时(并且必须实现一个仿真器/解释器来执行实模式代码而不破坏所有操作系统的其他设备驱动程序)。

对于带有 UEFI 的现代 80x86 PC(请参阅https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface),有一些类似于 VBE 的 UEFI 功能(获取视频模式列表、获取视频模式的详细信息、设置视频模式) . 最大的不同是 API 支持多显示器和多显卡(VBE 不支持);并且您在启动后(调用后)不能使用这些功能中的任何一个ExitBootServices()

另一种选择是编写本机显卡驱动程序,而不是使用固件/依赖于显卡的 ROM。这非常复杂,非常耗时(因为每个显卡需要不同的代码);而且你总是需要一个后备来处理“哎呀,显卡太新了,我还没有为它写一个本机视频驱动程序”,所以它不会避免需要支持使用固件(UEFI或BIOS / VBE) 查找/设置视频模式。

要使操作系统在所有情况下都可以工作(带有 BIOS 的旧计算机、带有 UEFI 的新计算机、带有/不带有本机视频驱动程序),唯一合理的方法是:

  • 引导加载程序使用 VBE(如果引导加载程序专为 BIOS 设计)或 UEFI(GOP 或 UGA,如果引导加载程序专为 UEFI 设计)为所有显示器/视频卡设置默认视频模式;然后告诉每个监视器的内核/操作系统详细信息(帧缓冲区的地址、像素格式、每行像素的字节数、水平和垂直分辨率),然后操作系统使用这些详细信息来绘制图形;这样操作系统就没有理由关心引导加载程序是使用 BIOS 还是 UEFI。

  • 稍后在启动期间;操作系统尝试为每个视频卡启动本机视频驱动程序。如果找到了,那么操作系统可以使用它来更改视频模式,并且可能会在引导期间尝试找到更好的视频模式(未作为引导加载程序的选项提供)。

  • 如果没有合适的视频驱动程序,则操作系统在启动后无法更改视频模式;因为只有当固件是 BIOS 并且(对于 BIOS)它太麻烦时才能支持这一点。请注意,操作系统仍然可以在磁盘上的某个位置(例如,在引导配置文件中)设置引导加载程序将查找的一些“视频模式首选项”信息,然后重新启动以使引导加载程序选择不同的模式。

请注意,现代显示器具有首选/原始分辨率(如果分辨率不同,则会进行“通常为低质量”缩放),因此对于每台显示器,实际上只有一种好的视频模式可供任何人使用;如果操作系统不是很糟糕,它将提供“分辨率独立性”(参见https://en.wikipedia.org/wiki/Resolution_independence)。只有 2 种情况用户实际上想要在启动后更改视频模式 - 他们已经更换了显示器,并且出于性能原因这样做。幸运的是,人们不会经常更换他们的显示器(因此在这种情况下,重新启动只是一个小小的不便);并且性能应该不是问题,除非用户尝试玩 3D 游戏(其中“每秒帧数”更重要,并且处理量明显更高)用户无论如何都会感到烦恼(除非有原生视频支持硬件加速 3D 的驱动程序)。换句话说,如果您没有本机视频驱动程序并且无法在启动后更改视频模式;几乎没有人会关心。

如果您确实希望引导加载程序设置视频模式/秒;那么这将取决于哪个引导加载程序。大多数通用引导加载程序(例如 GRUB)会为您设置一个视频模式并告诉您它设置的视频模式的信息,因此您根本不必这样做。

如果您正在编写自己的引导加载程序;那么 VBE 和 UEFI 的相关规范很容易在线获得(例如,参见上面链接的相应维基百科页面的“外部链接”部分);因此您可以阅读规范,然后尝试编写代码(如果遇到问题,请提出更具体的问题)。

我的程序运行但我在 0xA0000 中绘制,我认为我的缓冲区不足,因为我只看到了屏幕的一部分。你能帮助我吗?如何使用银行切换?

对于旧的 VGA“320*200 和 256 色”模式,一切都适合 64 KiB,因此您不需要任何存储库切换。

请注意,对于更高分辨率的视频模式,您将需要存储库切换(这对性能来说很糟糕,UEFI 不支持,而且对于 BIOS 来说太麻烦了),或者您将不得不使用保护模式或长模式来访问线性帧缓冲。当然,使用更高分辨率视频模式的图形操作系统将在 RAM 中拥有许多 MiB 的图形数据,用于图标、图片和缓冲区等内容;所以实模式(不能访问超过 640 KiB 的 RAM)无论如何都是完全不可用的。例如,出于性能原因;您最终将需要在 RAM 中进行所有绘图的缓冲区(然后,当所有绘图完成后,您会将生成的像素数据从 RAM 中的缓冲区复制到视频卡的帧缓冲区);对于像“800x600,每像素 32 位”这样的视频模式


推荐阅读