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

How to switch to Super VGA in c or asm?

我正在创建一个图形操作系统,我目前使用的是在保护模式之前启动的模式 19,但我想要更高的分辨率,谢谢。 我在 asm

中的图形激活
graphicmode:
  mov ax, 19; here select which mode you want
  int 16

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

How to switch to Super VGA in c or asm?

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

这意味着(开机后),对于BIOS,支持所有显卡(with/without VBE,with/without 32位保护模式接口,以及with/without 16 位保护模式接口)在启动后更改视频模式是一个主要的痛苦;特别是当 OS 是 64 位并且不能使用 virtual8086 模式时(并且必须实现 emulator/interpreter 来执行实模式代码而不破坏所有 OS 的其他设备驱动程序) .

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

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

要让 OS 处理所有情况(带有 BI 的旧计算机 OS、带有 UEFI 的新计算机、with/without 本地视频驱动程序),唯一明智的方法是:

  • boot loader 使用 VBE(如果 boot loader 是为 BIOS 设计的)或 UEFI(GOP或 UGA,如果引导加载程序是为 UEFI 设计的);然后告诉 kernel/OS 每个监视器的详细信息(帧缓冲区地址、像素格式、每行像素字节数、水平和垂直分辨率),然后 OS 使用这些详细信息绘制图形;因此 OS 没有理由关心引导加载程序使用的是 BIOS 还是 UEFI。

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

  • 如果没有合适的显卡驱动,则OS开机后无法切换显卡模式;因为只有当固件是 BIOS 和(对于 BIOS)时才可能支持它,这太麻烦了。请注意,OS 仍然可以在引导加载程序将查找的磁盘某处(例如,在引导配置文件中)设置一些“视频模式首选项”信息,然后重新启动以使引导加载程序选择不同的模式。

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

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

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

My program run but I draw in 0xA0000 and I think my buffer is insufficient because I saw just a part of my screen. Can you help me? How can I use a bank switching?

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

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