在长模式下用 VGA 绘制一个像素

Posted

技术标签:

【中文标题】在长模式下用 VGA 绘制一个像素【英文标题】:Draw a pixel with VGA in long mode 【发布时间】:2018-03-29 15:11:44 【问题描述】:

如何在长模式下使用 AT&T 程序集绘制像素? 我已经在实模式状态下开启了VGA模式。

【问题讨论】:

不知道您使用的是哪种 VGA 模式,我假设您知道视频内存的基地址。不确定是通过 VESA 还是其他方式(使用 VESA 兼容模式,您可以查询线性帧缓冲区 LFB 地址)。但是您只需将一个值移动到您想要的像素的内存地址。如果像素的地址在 RDI 中,那么您可以使用mov %al,(%rdi) 之类的内容对其进行更新(使用任何大小的寄存器作为包含您想要的数据的源。 @MichaelPetch 我正在使用模式 0x13 所以模式 0x13 非常简单。 320x200,您可以通过 0xa0000 的低内存地址访问它。模式 0x13 的每个内存位置(字节)代表一个像素并包含 256 位颜色。如果你想把蓝色放在左上角像素你可以做 movb $0x20,0xa0000 。如果您实际上处于 64 位长模式 - 我假设在该示例中您的身份映射低内存低于 1MB。如果您已将视频内存放置在虚拟地址空间的其他位置,则将 0xA0000 替换为适当的内存地址。 @MichaelPetch 谢谢,它工作得很好。您是否知道如何获得更大的分辨率以及更好的透明色彩系统? 如果你使用VBE你可以获得更高的分辨率,OSDEV Wiki上有教程你可以看看:wiki.osdev.org/User:Omarrx024/VESA_Tutorial。如果您无法通过 VBE 获得所需的分辨率,那么您将不得不编写特定的设备驱动程序代码来访问您拥有的特殊图形硬件(这是一项不平凡的任务) 【参考方案1】:

我的代表只有 1 位,所以我无法发表评论,但如果您接受此作为部分答案,您应该调查位平面。模式 13 很容易,因为它在 0xA000(64000 字节)处都适合小于 64k,但是当图形模式需要比 64k 更多的内存时,VGA 适配器会采用过于复杂的位平面解决方案。

位平面是存储在 VGA 控制器内部存储器中的 64k 内存块,其中至少包含 4 个这些“组”。您需要使用相关端口的 in 和 out 指令与 VGA 控制器通信,以便告诉 VGA 适配器您希望将哪个组映射到 0xA000 段,然后您通过 mov、xor 和等在 0xA000 上工作您会使用模式 13....但是....这里变得复杂了。

这些银行不仅仅作为所有模式的连续块出现。在 16 位和 24 位颜色模式中,一个单字节组中的一个字节只能表示一个 RGB 分量,最终输出实际上是所有位平面相互重叠的组合,就像投影仪屏幕上的三张幻灯片一样,但您只能操作一张幻灯片一次必须通过 IN 和 OUT 指令与 VGA 控制器交谈,告诉它您要使用哪个银行。

如果我没记错的话,VGA 控制器是一个 16 位总线,需要一次处理一个字节,这使得它更加烦人。我不确定这些端口,但您可以在任何列表中找到它们。

抱歉,它不是一个完整的答案,而是一个调查路径。 “VGA 位平面”。

【讨论】:

以上是关于在长模式下用 VGA 绘制一个像素的主要内容,如果未能解决你的问题,请参考以下文章

ROM+VGA 图片显示

在win32中绘制像素的最快方法是啥

11.Emacs进阶之艺术家模式

C#在winform上画一张大于全屏的图片(至少3000*3000像素)。在窗口最大化下用鼠标拖动图片,必须画面流畅。

C#在winform上画一张大于全屏的图片(至少3000*3000像素)。在窗口最大化下用鼠标拖动图片,必须画面流畅。

C#在winform上画一张大于全屏的图片(至少3000*3000像素)。在窗口最大化下用鼠标拖动图片,必须画面流畅。