横向滚动终端 (BIOS)
Scrolling the terminal sideways (BIOS)
我正在编写一个 bootsector 游戏,它试图复制 chrome 没有互联网时可以玩的恐龙游戏。
为此,我必须 运行 从左到右,直到玩家击中仙人掌。
我该如何实现?
(如何使终端从右向左滚动,使其看起来像我在移动?)
因此,我需要从右向左和从左向右滚动,而不是上下滚动。
我处于 16 位实模式 (BIOS),并且我正在使用 nasm / intel 语法。
在 CGA-compatible 文本模式下,屏幕内容存储在从 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, [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
dec dx ; decrement loop counter
jnz .loop ; loop until we're done
这就是全部内容。当然,如果 c
是变量而不是常量,代码会稍微复杂一些。但我相信你会弄明白的。
另请注意,您似乎将屏幕称为“BIOS 终端”或类似的东西。那是不正确的。屏幕由显卡绘制,实际上无需 BIOS 即可完全更改。 BIOS 是计算机 ROM 中提供的一组例程。其中包括一些配置图形模式和打印字符等的例程。然而,这纯粹是为了方便。您实际上不需要通过 BIOS 来执行任何操作。
我正在编写一个 bootsector 游戏,它试图复制 chrome 没有互联网时可以玩的恐龙游戏。
为此,我必须 运行 从左到右,直到玩家击中仙人掌。
我该如何实现? (如何使终端从右向左滚动,使其看起来像我在移动?) 因此,我需要从右向左和从左向右滚动,而不是上下滚动。 我处于 16 位实模式 (BIOS),并且我正在使用 nasm / intel 语法。
在 CGA-compatible 文本模式下,屏幕内容存储在从 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, [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
dec dx ; decrement loop counter
jnz .loop ; loop until we're done
这就是全部内容。当然,如果 c
是变量而不是常量,代码会稍微复杂一些。但我相信你会弄明白的。
另请注意,您似乎将屏幕称为“BIOS 终端”或类似的东西。那是不正确的。屏幕由显卡绘制,实际上无需 BIOS 即可完全更改。 BIOS 是计算机 ROM 中提供的一组例程。其中包括一些配置图形模式和打印字符等的例程。然而,这纯粹是为了方便。您实际上不需要通过 BIOS 来执行任何操作。