侧向滚动终端BIOS

问题描述

我正在编写一个bootsector游戏,尝试复制没有互联网时可以玩的铬恐龙游戏。

要做到这一点,我必须从左到右奔跑,直到玩家碰到仙人掌为止。

我该如何实现? (如何使终端机从右向左滚动,使其看起来好像在移动?) 因此,除了上下滚动外,我还需要从右向左滚动和从左向右滚动。 我处于16位实模式(BIOS),并且正在使用nasm / intel语法。

解决方法

在与CGA兼容的文本模式下,屏幕内容存储在从B800:000开始的4000字节缓冲区中(除非您更改活动的显示页面,但我假设您没有这样做)。每行包含80个字符,存储在160个字节中,总共25行,分辨率为80×25。

因此,要向左滚动屏幕,必须将屏幕的字符向左移动所需的列数,并在屏幕的右侧填充空白字符。使用一系列rep movsw指令移动字符,然后跟随rep stosw指令填充右侧,可以轻松实现这一点。假设ds = es = b800并假设ds:di指向行的开头,那么将c列向左移动一行的代码如下所示:

        lea     si,[di+2*c]   ; set up SI to the column that is scrolled
                               ; into the first column of the line
        mov     cx,80-c       ; copy all columns beginning at that column
                               ; to the end of the row
        rep     movsw          ; scroll row to the left
        mov     cx,c          ; need to blank that many columns
        rep     stosw          ; blank remaining columns

此代码序列之后,DI指向下一行的开头。因此,通过重复此序列25次,我们可以轻松滚动整个屏幕:

        mov     ax,0xb800     ; screen segment
        mov     ds,ax         ; set up segments
        mov     es,ax
        xor     di,di         ; point to the beginning of the screen
        mov     dx,25         ; process 25 lines
        mov     ax,0x0700     ; what to scroll in (grey on black blanks)

.loop:  lea     si,c          ; need to blank that many columns
        rep     stosw          ; blank remaining columns

        dec     dx             ; decrement loop counter
        jnz     .loop          ; loop until we're done

这就是全部。当然,如果c是变量而不是常量,则代码会稍微复杂一些。但是我相信你会弄清楚的。

还要注意,您似乎将屏幕称为“ BIOS终端”或类似的东西。那是不对的。屏幕是由图形卡绘制的,实际上可以完全在没有BIOS的情况下进行更改。 BIOS是计算机上ROM中提供的一组例程。其中包括一些用于配置图形模式和打印字符的例程。但是,这纯粹是为了方便。实际上,您不需要通过BIOS即可执行任何操作。