【问题标题】:Achieving 160x100 Mode in x86 Assembly在 x86 汇编中实现 160x100 模式
【发布时间】:2017-01-13 05:54:57
【问题描述】:

我早就知道,通过使用 CRTC 将行高更改为两个像素,可以在 IBM CGA 上实现伪 160 x 100 图形模式。我这几天一直在尝试完成这个,走到了死胡同。

Intel® Open Source HD Graphics and Intel Iris™ Graphics Programmer's Reference Manual 声称我可以在第 45 页(或 PDF 中的第 59 页)通过写入最大扫描线寄存器来执行此操作,或者这就是我的解释。

我已经尝试直接写入内存地址 3B5,值为 00000001b,或者我相信 2 条扫描线的代码。当我在 DOSBox 中测试它时,这根本没有做任何事情。

如果您想查看我编写的将在 NASM 中组装的代码:

BITS 16
xor bx,bx
mov ax, 3b5h
mov es, ax
mov ah, 00000001b
mov BYTE [es:bx], ah    ; write 00000001b to 0x03b5:0000, right?
cli
hlt

我对这种低级的东西还不是很有信心,如果有任何帮助,我将不胜感激。

【问题讨论】:

  • 你在 DOSBOX 中配置了 CGA 图形适配器吗?
  • DOSBox 是一个模拟器/虚拟机。在其中运行的代码将看到整台机器,但其行为完全由 DOSBox 软件决定,而不是由运行 DOSBox 的主机的硬件决定。 Intel 手册可能是有关 VGA/CGA 的有用文档来源,但请记住,它记录的任何 Intel 特定功能或行为都不会在 DOSBox 中发生。如果您想对您的实际英特尔硬件进行编程,您可以在裸硬件上启动您的代码。另请参阅x86 tag wiki 以获取大量 x86 链接(无直接相关)。
  • 获得伪 160x100 图形模式的更简单方法可能是使用标准 80x50 VGA 文本模式和具有 2x2 块字符的自定义字体。另一种选择是使用 VGA 的 320x200 图形模式,并在绘制像素时将像素的宽度和高度加倍。
  • 我知道 DOSBox 是一个模拟器。我想让它在 DOSBox 中工作,因为 DOSBox 当前配置为在 CGA 中运行。由于我无法访问实际的硬件,所以我求助于模拟器。

标签: assembly x86 intel dosbox undocumented-behavior


【解决方案1】:

您不是写信给地址 3b5h,而是写信给地址 3b50h。如果你想写地址 3b5h,你会用 0 加载 ES,然后执行mov BYTE [es:3b5h], 01 之类的操作,但这也不是你想要做的。您链接的手册中给出的地址 3b5h 是“I/O 地址”,这意味着它位于完全不同的地址空间中,您需要使用专门的 IN 和 OUT 指令才能访问。

要将值 01 写入 I/O 地址 3b5h,您可以使用如下代码:

mov dx, 3b5h
mov al, 01
out dx, al

请注意,这是您可以在此处使用的唯一OUT instruction 形式。您必须使用 DX 寄存器来指定地址,并使用 AL 寄存器来提供要写入该 I/O 地址的数据。

除非那也不对。正如您链接的手册所解释的,I/O 地址 3b5h 是 MDA 数据端口,CGA 数据端口位于 I/O 地址 3d5h。最后,“最大扫描线寄存器”不是唯一通过 I/O 地址 3d5h 访问的寄存器。有几个不同的寄存器使用这个地址。要选择要写入的寄存器,首先需要通过将其索引值写入 I/O 地址 3d4h 处的 CGA CRT 控制器索引寄存器来选择它。这意味着您的代码需要如下所示:

mov dx, 3d4h   ; CGA CRTC Index Register
mov al, 09h    ; Maximum Scan Line Reigster
out dx, al
mov dx, 3d5h   ; CGA CRTC Data Port
mov al, 01     ; 2 scan lines
out dx, al

请注意,这仍然可能不正确,因为 VGA 将其他参数添加到最大扫描线寄存器。您可能需要保留这些值,但在实际的 CGA 硬件上这是不可能的,因为该寄存器是只读的。这可能取决于您在模拟真实 CGA 视频卡下运行代码的准确度。

【讨论】:

  • 您的代码似乎组装得很好并且做得对。谢谢!
  • @CollisionDetection:当答案解决您的问题时,您应该单击向上/向下投票箭头下方的复选框,而不是离开感谢 cmets。
  • 这是我的第一个 SO 问题,假设我仍然掌握了窍门。
猜你喜欢
  • 2013-12-18
  • 2014-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-08
  • 2022-12-11
  • 2011-02-18
  • 2017-01-11
相关资源
最近更新 更多