二、显卡驱动--CGA设置

2023-10-20 08:40
文章标签 设置 驱动 显卡 cga

本文主要是介绍二、显卡驱动--CGA设置,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在之前的博客上说过地址空间并不是全部映射到内存上,还有一些外部设备,IA手册上的1MB以下地址空间分布如下图所示。

我们都知道CPU访问外设有两种方式:IO与内存统一编址 和IO与内存独立编址,一般来说,外设中控制读写的端口都是独立编址,即用in/out指令控制,而外设中的存储器一般和内存进行统一编址,即CPU访问这些地址时和访问内存是一样的,也可以理解成这部分存储器映射到了内存中,比如上图中的各种地址段均被映射到了一些外设上。

回归正题,要在PC上要显示文字,通常需要显示器和显卡这两个硬件设备。一般来说显卡负责提供显示内容,并控制具体的显示模块和状态。显示器的职责是负责将显卡呈递的内容可视化的显示出来。既然显卡需要控制显示的数据,自然就需要存储这些待显示的内容,所以显卡就有自己的存储区域。这个存储区域叫做显示存储器(Video RAM,VRAM),简称显存。当然,访问显存就需要地址。CGA/EGA+ Chroma text video buffer 这个区域映射的就是工作在文本模式的显存。同时显卡还有另外一个工作模式叫做图形模式,这个模式是目前最常用的模式。

通常显卡内置一套关于基本英文字符的显示,很容易做到英文字符的显示。本文只使用显卡的文本模式,对于OS开发只需关注以下几点:

1、所有在PC上工作的显卡,在加电初始化之后都会自动初始化到80*25的文本模式。在这个模式下,屏幕被划分为25行,每行可以显示80个字符,所以一屏可以显示2000个字符。上图中的0xB8000~0xBFFFF这个地址段便是映射到文本模式的显存的。当访问这些地址的时候,实际上读写的是显存区域,而显卡会周期性的读取这里的数据,并且把它们按顺序显示在屏幕上。当然一些低版本显卡不支持彩色字符,只支持单色字符,其显存映射范围为0xb0000-0xb7fff。

2、那么,按照什么规则显示呢?这就要谈到内码了。内码定义了字符在内存中存储的形式,而英文编码就是大家所熟知的ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)码了。对应的关系很简单,从0xB8000这个地址开始,每2个字节表示屏幕上显示的一个字符。从屏幕的第一行开始对应,一行接着一行的对应下去。而这两个字节的前一个是显示字符的ASCII码,后一个是控制这个字符颜色和属性的控制信息,这个字节的8个bit位表示不同的含义。每一位的含义如图所示:

3、理解了显卡文本模式的原理之后接下来就是对屏幕显示控制编码了。不过显卡除了显示内容的存储单元之外,还有部分的显示控制单元需要了解。这些显示控制单元被编制在了独立的I/O空间里,需要用特殊的in/out指令去读写。这里相关的控制寄存器多达300多个,显然无法一一映射到I/O端口的地址空间。对此工程师们解决方案是,将一个端口作为内部寄存器的索引:0x3D4,再通过0x3D5端口来设置相应寄存器的值。

4、之前介绍了访问VGA显存的方法,现在我们要在屏幕上设置光标了。光标和显存不一样。它必须通过显卡的I/O端口开控制。VGA显卡内部有一系列寄存器可以用来控制显卡的状态。在标准的PC机上。 0x3d4和0x3d5两个端口可以用来读写显卡的内部寄存器。方法是先向0x3d4端口写入要访问的寄存器编号,再通过0x3d5端口来读写寄存器数据。存放光标位置的寄存器编号为14和15。两个寄存器合起来组成一个16位整数,这个整数就是光标的位置。比如0表示光标在第0行第0列,81表示第1行第1列(屏幕总共80列)。在实际使用中要注意光标位置的计算,比如需要在第x行、第y列设置光标,那么首先需要计算其相对于第0行、第0列的相对值,pos=x*80+y,然后将相对值pos的高8位输入到14号寄存器中,将低8位输入到15号寄存器中,即可将光标显示在第x行、第y列。如下图所示

 

光标的设置大概就这些,接下来继续看字符的显示,按照前面的说明,就是将字符和其属性输入到对应位置的显存中,但这里要注意一点,字符在第一个字节,其属性在第二个字节,但由于X86是小端方式,低地址高字节,所以字符需要放在地址低8位,其属性放在地址高8位。

上面QEMU模拟器输入显存的字符看上去有点难受,所以我们需要先把整个显示屏的字符全部清空后,再显示字符,清空操作相对而言比较简单,只需要用黑底白字的空格充满整个显存即可(25*80=2000个字符),如下所示。

在清空屏幕以及打印字符完成后,字符串的显示也就迎刃而解,只需要显示字符串中的每个字符,如下所示:

 

 

OK.在上述步骤完成后,我们可以显示常见的英文字符,但是数字的显示用这一套就没用了,因为数字大小和ASCII值并不匹配,因此需要进行转换。

 

 

结合之前的打印内存,可得下面的结果

 

 

 

 

 

 

 

 

 

 

遇到的坑:

编译器出错

没问题

没问题

上面三种情况的理解:只能除2的整数倍?相当于右移。经过一番搜索,应该是编译器在除2的整数倍时,可以用右移的指令取代,而我们的程序是32位的,由于32位机器没有64位的除法指令,所以编译器会出现”__udivdi3”或者”__umoddi3”错误,那解决办法就是人工输入除法指令,之前用了很多unsigned long long 指令,主要为了打印内存用,所以需要能解决64位除法的指令,通过嵌入汇编实现。

参考资料:

  1. http://wiki.0xffffff.org/posts/hurlex-4.html
  2. https://blog.csdn.net/gemini_star/article/details/4438280

这篇关于二、显卡驱动--CGA设置的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/245999

相关文章

idea设置快捷键风格方式

《idea设置快捷键风格方式》在IntelliJIDEA中设置快捷键风格,打开IDEA,进入设置页面,选择Keymap,从Keymaps下拉列表中选择或复制想要的快捷键风格,点击Apply和OK即可使... 目录idea设www.chinasem.cn置快捷键风格按照以下步骤进行总结idea设置快捷键pyth

MyBatis配置文件中最常用的设置

《MyBatis配置文件中最常用的设置》文章主要介绍了MyBatis配置的优化方法,包括引用外部的properties配置文件、配置外置以实现环境解耦、配置文件中最常用的6个核心设置以及三种常用的Ma... 目录MyBATis配置优化mybatis的配置中引用外部的propertis配置文件⚠️ 注意事项X

Java JAR 启动内存参数配置指南(从基础设置到性能优化)

《JavaJAR启动内存参数配置指南(从基础设置到性能优化)》在启动Java可执行JAR文件时,合理配置JVM内存参数是保障应用稳定性和性能的关键,本文将系统讲解如何通过命令行参数、环境变量等方式... 目录一、核心内存参数详解1.1 堆内存配置1.2 元空间配置(MetASPace)1.3 线程栈配置1.

C#借助Spire.XLS for .NET实现Excel工作表自动化样式设置

《C#借助Spire.XLSfor.NET实现Excel工作表自动化样式设置》作为C#开发者,我们经常需要处理Excel文件,本文将深入探讨如何利用C#代码,借助强大的Spire.XLSfor.N... 目录为什么需要自动化工作表样式使用 Spire.XLS for .NET 实现工作表整体样式设置样式配置

Java实现为PDF设置背景色和背景图片

《Java实现为PDF设置背景色和背景图片》在日常的文档处理中,PDF格式因其稳定性和跨平台兼容性而广受欢迎,本文将深入探讨如何利用Spire.PDFforJava库,以简洁高效的方式为你的PDF文档... 目录库介绍与安装步骤Java 给 PDF 设置背景颜色Java 给 PDF 设置背景图片总结在日常的

C#中通过Response.Headers设置自定义参数的代码示例

《C#中通过Response.Headers设置自定义参数的代码示例》:本文主要介绍C#中通过Response.Headers设置自定义响应头的方法,涵盖基础添加、安全校验、生产实践及调试技巧,强... 目录一、基础设置方法1. 直接添加自定义头2. 批量设置模式二、高级配置技巧1. 安全校验机制2. 类型

python库pydantic数据验证和设置管理库的用途

《python库pydantic数据验证和设置管理库的用途》pydantic是一个用于数据验证和设置管理的Python库,它主要利用Python类型注解来定义数据模型的结构和验证规则,本文给大家介绍p... 目录主要特点和用途:Field数值验证参数总结pydantic 是一个让你能够 confidentl

Java利用Spire.XLS for Java设置Excel表格边框

《Java利用Spire.XLSforJava设置Excel表格边框》在日常的业务报表和数据处理中,Excel表格的美观性和可读性至关重要,本文将深入探讨如何利用Spire.XLSforJava库... 目录Spire.XLS for Java 简介与安装Maven 依赖配置手动安装 JAR 包核心API介

Java+AI驱动实现PDF文件数据提取与解析

《Java+AI驱动实现PDF文件数据提取与解析》本文将和大家分享一套基于AI的体检报告智能评估方案,详细介绍从PDF上传、内容提取到AI分析、数据存储的全流程自动化实现方法,感兴趣的可以了解下... 目录一、核心流程:从上传到评估的完整链路二、第一步:解析 PDF,提取体检报告内容1. 引入依赖2. 封装

MySQL设置密码复杂度策略的完整步骤(附代码示例)

《MySQL设置密码复杂度策略的完整步骤(附代码示例)》MySQL密码策略还可能包括密码复杂度的检查,如是否要求密码包含大写字母、小写字母、数字和特殊字符等,:本文主要介绍MySQL设置密码复杂度... 目录前言1. 使用 validate_password 插件1.1 启用 validate_passwo