video - 停止屏幕刷新 - INT 0x10(视频服务)- assembly 中

标签 video assembly x86 refresh dos

我的编程环境是 MS-DOS 仿真器,我正在使用 16 位汇编编程。

我正在使用常规文本模式,我可以在其中打印字符和使用属性。

在屏幕的一部分上,我每秒钟绘制很多字符,数千个,这创建了一个漂亮的动画。

问题是,为了创建动画,首先我必须删除旧的,我基本上打印了大约 1000 次空格字符。 (!) 现在,因为我正在这样做,所以每次我重新绘制动画时都会出现轻微的闪烁问题,该问题很明显并且非常令人讨厌。

我正在使用视频服务来完成所有的输出和动画工作。所以我的第一个想法是以某种方式阻止屏幕刷新,重绘它,让屏幕继续自己刷新。

因为这个过程每秒发生很多次,而且它必须发生很多次,所以我发现任何其他清洁方法都不是很有帮助。

最佳答案

基本问题是,即使只是一瞬间,您也会向用户展示他们不想看到的东西,一个充满空格的空白屏幕。这就是造成闪烁的原因。您可以通过使用单个 BIOS 调用(例如 INT 10h AX=0600h)更快地删除屏幕来改进这一点,但更好的解决方案是只向用户显示他们想要看到的内容。

从上到下覆盖所有内容

执行此操作的一种方法是更改​​您的代码,以便在绘制新框架时完全覆盖旧框架。这样就不需要删除屏幕。因此,例如,不要在屏幕上的不同位置跳来跳去地绘制文本,而是从左上角开始,从左到右、从上到下绘制文本。打印空格以将光标从一个位置移动到另一个位置。假设您只有两个函数可以使用,一个将光标移动到屏幕的左上角,另一个打印一个字符并使光标前进。

在用户看不到的地方画

如果这太难了,您可以使用屏幕外缓冲区来完成您现在正在做的事情。删除屏幕外缓冲区,在上面绘制文本,然后显示它。这样用户就永远不会看到他们本不想看到的已删除屏幕。您可以在内存中创建一个屏幕外缓冲区,然后将其复制到屏幕,或者您可以在视频内存中的页面之间翻转。

绘制到内存中的离屏缓冲区

在内存中使用缓冲区意味着您不能使用 BIOS 函数对其进行绘制,但根据情况,这会方便很多。您将使用正常的内存写入来删除缓冲区并绘制文本,然后将整个缓冲区复制到屏幕上。本质上,这是一种从上到下完全覆盖所有内容的方法,如上所述。

绘制到非事件视频页面

在视频页面之间翻动可能会让您使用与现在相同的 BIOS 功能来绘制文本。也就是说,假设他们在 BH 中使用一个参数来指定要使用的页面。并不是所有的 BIOS 函数都有这个,特别是我前面提到的 BIOS 函数 INT 10h, AH=06h 没有。您将使用两个视频页面,0 和 1,并且您需要跟踪哪个页面当前处于事件状态并显示给用户。然后,您将在非事件页面上删除并绘制文本,完成后翻页,使非事件页面成为事件页面。为此,您可以使用 INT 10h AX=05XX,其中 XX 是要激活的页码。

直接写入显存

一种更高级的技术是直接写入显存。当 MS-DOS 流行时,PC 的速度非常慢,以至于使用 BIOS 绘制文本对于任何类型的实用动画来说通常都太慢了。相反,大多数执行此类操作的应用程序都直接写入视频内存,绕过缓慢的 BIOS 例程。您可以将上述任何技术与此结合使用。例如,您可以绘制到普通内存中的屏幕外缓冲区,然后使用 REP MOVS 指令将其复制(“blit”)到视频内存。

绕过 BIOS 的缺点是它会降低您的代码的可移植性。例如,最初的 IBM PC 单色显示适配器 (MDA) 和彩色图形适配器 (CGA) 的视频内存位于不同的位置(分别为 B000:0000 和 B800:0000)。其他第三方不是 100% PC 兼容的计算机甚至更奇怪。有些不支持文本模式,BIOS 将使用位图图形模式绘制文本。

关于video - 停止屏幕刷新 - INT 0x10(视频服务)- assembly 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37351078/

相关文章:

assembly - 为什么将 32 位寄存器移动到堆栈然后从堆栈移动到 xmm 寄存器?

assembly - X86 汇编中的 SAR 命令具有一个参数

iOS 崩溃 : missing images before playing video

audio - 如何使用 ffmpeg 录制音频流?

ios - "Invalid operand for instruction"arm64 架构错误

assembly - 标志、进位和溢出标志( assembly )

iOS swift : How to post a video to twitter with TwitterKit?

python - 当相机断开连接而不是返回 "False"时,opencv videocapture 挂起/卡住

linux - 如何使用中断在 x86 程序集中触发被零除错误异常?

c++ - 为什么单独循环中的元素加法比组合循环中的元素加法快得多?