如何在汇编(TASM)中使用页面?
How to use pages in assembly (TASM)?
我想在汇编 (TASM) 中创建一个像吉他英雄这样的游戏,我想我需要使用页面来向上滚动屏幕。如何在上面的页面上打印矩形并向上滚动页面?
确实,不同的视频模式有不同数量的 "pages" 可用,具体取决于视频硬件可用的内存量。可以看到一个基本完整的列表here. Not all video modes support multiple pages, though. For example, mode 13h,VGA上的一种常用图形模式(流行是因为它允许简化直接操作显存的方式,从而使编程更容易)只支持一页,这意味着翻页正常的方式是不可能的。* 你需要选择一个支持多页的模式。我自己不是一个图形模式的人,我不知道哪些是流行的,哪些值得推荐。也许是 0Dh,分辨率为 320×200,16 色,8 页?
翻页的标准方法是使用BIOS service 10h (video functions), function 05h。此 select 是活动显示页面。在线文档中可以看到here,你把AH
寄存器设置为函数标识符(05h
),AL
设置为你要[=61]的显示页面=],然后调用中断 10h:
mov al, 01h ; select display page 1
mov ah, 05h ; function 05h: select active display page
int 10h
或者,为了获得最佳性能,真正的汇编程序员会同时设置 AX 寄存器的这两半,如下所示:
mov ax, 0501h ; AL == display page, AH == function 05h
int 10h
如果请求的页面不存在,则中断调用将无效。您可以通过随后使用 function 0Fh 检查当前显示页码来验证这一点,其中 returns BH
寄存器中的活动显示页:
mov ax, 0F00h ; AH == function 0Fh
int 10h
这就是您使用页面的方式,但这实际上与滚动无关。您不能同时在屏幕上显示多个页面。出于滚动目的,您真正想要的是function 06h—scroll window up. The DX register contains the coordinates of the upper-left corner of the rectangle to be scrolled (DL == column, DH == row), and the CX register contains the coordinates of the lower-right corner (CL == column, CH == row). The AL register contains the number of lines to scroll, and the BH register contains the screen attributes(颜色)用于新清除的区域。
例如,如果你想将由 (0, 0)×(80, 20) 定义的屏幕矩形区域向上滚动 10 行,你可以执行以下操作:
xor dx, dx ; DL == 0, DH == 0
mov cx, 1450h ; CL == 80, CH == 20
mov ax, 060Ah ; AL == 10, AH == 06h
mov bh, 0Eh ; yellow foreground, black background
int 10h
此功能的一个非常常见的用途是清除整个屏幕。正如您可能想象的那样,这是通过设置 DX 和 CX 来定义整个屏幕的坐标,然后将 AL 设置为 0 来空白整个矩形来完成的。然后屏幕将被清除并填充 BH 中指定的颜色属性。请记住,屏幕的原点(左上角)位于 (0, 0)。范围(右下角)取决于您所处的模式。
有一个补充函数 07h,它可以 window 向下滚动 ,而不是向上滚动。它在其他方面的工作方式与功能 06h 完全相同。
请注意,正如我之前所说,并且如链接文档中所述,这些滚动屏幕功能仅适用于当前活动的显示页面。因此,一旦您向上或向下滚动屏幕,几乎暴露的区域将被您指定的 color/video 属性填充,然后您需要在其中绘制新图形。
这里唯一的缺点是当您在屏幕上绘制新内容时可能会遇到一些闪烁。翻页有助于防止这种情况发生,但实施起来需要做更多的工作。您不会让 BIOS 通过自动滚动屏幕的一部分来帮助您。您必须维护两个页面 — 一个页面包含当前屏幕上显示的内容,另一个页面已被绘制,就好像它已经滚动了一样。然后,您将直接从当前页面翻到新页面。
* 您实际上可以在模式 13h 中模拟翻页,但是,通过使用多个段,利用此模式对显存的快速写入允许。基本上,您有一个寻址 actual 显存的段寄存器,然后您有一个或多个寻址 "scratch" 内存区域的附加段寄存器,就好像它们是显存。然后,当您想要翻页时,您只需将所有数据从一个暂存区域 blit 到实际的视频内存中。如果您熟悉 现代 图形编程技术,这就是双缓冲 — 您绘制到屏幕外缓冲区,然后当您准备好时,从中复制数据屏幕外缓冲区到屏幕上。一切旧的都是新的。
我想在汇编 (TASM) 中创建一个像吉他英雄这样的游戏,我想我需要使用页面来向上滚动屏幕。如何在上面的页面上打印矩形并向上滚动页面?
确实,不同的视频模式有不同数量的 "pages" 可用,具体取决于视频硬件可用的内存量。可以看到一个基本完整的列表here. Not all video modes support multiple pages, though. For example, mode 13h,VGA上的一种常用图形模式(流行是因为它允许简化直接操作显存的方式,从而使编程更容易)只支持一页,这意味着翻页正常的方式是不可能的。* 你需要选择一个支持多页的模式。我自己不是一个图形模式的人,我不知道哪些是流行的,哪些值得推荐。也许是 0Dh,分辨率为 320×200,16 色,8 页?
翻页的标准方法是使用BIOS service 10h (video functions), function 05h。此 select 是活动显示页面。在线文档中可以看到here,你把AH
寄存器设置为函数标识符(05h
),AL
设置为你要[=61]的显示页面=],然后调用中断 10h:
mov al, 01h ; select display page 1
mov ah, 05h ; function 05h: select active display page
int 10h
或者,为了获得最佳性能,真正的汇编程序员会同时设置 AX 寄存器的这两半,如下所示:
mov ax, 0501h ; AL == display page, AH == function 05h
int 10h
如果请求的页面不存在,则中断调用将无效。您可以通过随后使用 function 0Fh 检查当前显示页码来验证这一点,其中 returns BH
寄存器中的活动显示页:
mov ax, 0F00h ; AH == function 0Fh
int 10h
这就是您使用页面的方式,但这实际上与滚动无关。您不能同时在屏幕上显示多个页面。出于滚动目的,您真正想要的是function 06h—scroll window up. The DX register contains the coordinates of the upper-left corner of the rectangle to be scrolled (DL == column, DH == row), and the CX register contains the coordinates of the lower-right corner (CL == column, CH == row). The AL register contains the number of lines to scroll, and the BH register contains the screen attributes(颜色)用于新清除的区域。
例如,如果你想将由 (0, 0)×(80, 20) 定义的屏幕矩形区域向上滚动 10 行,你可以执行以下操作:
xor dx, dx ; DL == 0, DH == 0
mov cx, 1450h ; CL == 80, CH == 20
mov ax, 060Ah ; AL == 10, AH == 06h
mov bh, 0Eh ; yellow foreground, black background
int 10h
此功能的一个非常常见的用途是清除整个屏幕。正如您可能想象的那样,这是通过设置 DX 和 CX 来定义整个屏幕的坐标,然后将 AL 设置为 0 来空白整个矩形来完成的。然后屏幕将被清除并填充 BH 中指定的颜色属性。请记住,屏幕的原点(左上角)位于 (0, 0)。范围(右下角)取决于您所处的模式。
有一个补充函数 07h,它可以 window 向下滚动 ,而不是向上滚动。它在其他方面的工作方式与功能 06h 完全相同。
请注意,正如我之前所说,并且如链接文档中所述,这些滚动屏幕功能仅适用于当前活动的显示页面。因此,一旦您向上或向下滚动屏幕,几乎暴露的区域将被您指定的 color/video 属性填充,然后您需要在其中绘制新图形。
这里唯一的缺点是当您在屏幕上绘制新内容时可能会遇到一些闪烁。翻页有助于防止这种情况发生,但实施起来需要做更多的工作。您不会让 BIOS 通过自动滚动屏幕的一部分来帮助您。您必须维护两个页面 — 一个页面包含当前屏幕上显示的内容,另一个页面已被绘制,就好像它已经滚动了一样。然后,您将直接从当前页面翻到新页面。
* 您实际上可以在模式 13h 中模拟翻页,但是,通过使用多个段,利用此模式对显存的快速写入允许。基本上,您有一个寻址 actual 显存的段寄存器,然后您有一个或多个寻址 "scratch" 内存区域的附加段寄存器,就好像它们是显存。然后,当您想要翻页时,您只需将所有数据从一个暂存区域 blit 到实际的视频内存中。如果您熟悉 现代 图形编程技术,这就是双缓冲 — 您绘制到屏幕外缓冲区,然后当您准备好时,从中复制数据屏幕外缓冲区到屏幕上。一切旧的都是新的。