程序集在 x 模式下读取平面是否需要与写入不同的输出到 VGA 端口?
Assembly does reading a plane in mode x needs a different output to the VGA ports from writing?
1I am writing in TASM 3.0 on DosBox 0.74 and I am trying to write in Mode x (Tweaked 13h, unchained mode 13),我运行陷入了一个问题,你怎么能在图像中看到,每一行都打印出来,但是在每一行中,每组四个像素只有颜色第一个像素被打印,这是在 VRAM 中的不同 space 中打印图像以进行双缓冲之后,因此所有四个平面都具有第一个平面的数据。
图像应该这样打印(这是没有双缓冲的直接打印,是的,定时器有问题但没关系)
这是使用双缓冲打印图像的方式
我认为问题是当涉及模式x时,数据与VGA端口中的读写不同,这里是选择VGA平面的代码
proc VGAPlaneSelect
push ax
push dx
push cx
mov al, 02h
mov dx, 03C4h
out dx, al
VGAPlaneSelect_start:
mov ax, 1
mov cl, [VGAPlane]
shl ax, cl
cmp [VGAPlane], 4
jne VGAPlaneSelect_end
mov [VGAPlane], 0
jmp VGAPlaneSelect_start
VGAPlaneSelect_end:
mov dx, 03C5h
out dx, al
pop cx
pop dx
pop ax
ret
endp VGAPlaneSelect
如果输出不是问题,这里是内存代码 t运行sfer:
proc DoubleBuffer
mov ax, 0A000h
mov es, ax
mov [VGAPlane], 0
call VGAPlaneSelect
cli
mov cx, 4
DoubleBuffer_loop:
xor di, di
xor si, si
push cx
mov cx, 16000
DoubleBuffer_loop_plane:
push di
push si
shr di, 2
shr si, 2
add si, NON_VISABLE_PLANE_OFFSET
mov al, [es:si]
stosb
pop si
pop di
add di, 4
add si, 4
loop DoubleBuffer_loop_plane
inc [VGAPlane]
call VGAPlaneSelect
pop cx
loop DoubleBuffer_loop
sti
ret
endp pageFlipping
在 VGA 的图形控制器中,有一个单独的寄存器来指定要读取的平面。
你select它通过在地址端口03CEh写入一个4,然后在数据端口03CFh写入平面号(0-3)。
您使用的 03C4h:02h 寄存器称为 ColorPlaneWriteEnable。答案已经在它的名字里了!它允许同时写入一个或多个平面。阅读使用 03CEh:04h ReadPlaneSelect.
proc DoubleBuffer
...
endp pageFlipping
这是哪个?
PageFlipping 不需要像此过程那样复制大块内存。
DoubleBuffering的思想是利用'normal'RAM构建画面,将画面全部或部分复制到显存中。您的程序使用显存来保存双缓冲区,因此读取速度会很慢!
为什么 DoubleBuffer_loop 这么复杂?
你根本不需要移动和保存!
xor di, di
mov si, NON_VISABLE_PLANE_OFFSET
mov cx, 16000
DoubleBuffer_loop_plane:
mov al, [es:si]
stosb
inc si
dec cx
jnz DoubleBuffer_loop_plane
这可以进一步简化为:
xor di, di
mov si, NON_VISABLE_PLANE_OFFSET
mov cx, 16000
cld
rep movs byte [di], [es:si]
rep movs
的语法取决于您使用的汇编程序。
在 NASM 中,您必须在 REP MOVSB
指令之前通过段覆盖,因此 ES REP MOVSB
1I am writing in TASM 3.0 on DosBox 0.74 and I am trying to write in Mode x (Tweaked 13h, unchained mode 13),我运行陷入了一个问题,你怎么能在图像中看到,每一行都打印出来,但是在每一行中,每组四个像素只有颜色第一个像素被打印,这是在 VRAM 中的不同 space 中打印图像以进行双缓冲之后,因此所有四个平面都具有第一个平面的数据。
图像应该这样打印(这是没有双缓冲的直接打印,是的,定时器有问题但没关系)
这是使用双缓冲打印图像的方式
我认为问题是当涉及模式x时,数据与VGA端口中的读写不同,这里是选择VGA平面的代码
proc VGAPlaneSelect
push ax
push dx
push cx
mov al, 02h
mov dx, 03C4h
out dx, al
VGAPlaneSelect_start:
mov ax, 1
mov cl, [VGAPlane]
shl ax, cl
cmp [VGAPlane], 4
jne VGAPlaneSelect_end
mov [VGAPlane], 0
jmp VGAPlaneSelect_start
VGAPlaneSelect_end:
mov dx, 03C5h
out dx, al
pop cx
pop dx
pop ax
ret
endp VGAPlaneSelect
如果输出不是问题,这里是内存代码 t运行sfer:
proc DoubleBuffer
mov ax, 0A000h
mov es, ax
mov [VGAPlane], 0
call VGAPlaneSelect
cli
mov cx, 4
DoubleBuffer_loop:
xor di, di
xor si, si
push cx
mov cx, 16000
DoubleBuffer_loop_plane:
push di
push si
shr di, 2
shr si, 2
add si, NON_VISABLE_PLANE_OFFSET
mov al, [es:si]
stosb
pop si
pop di
add di, 4
add si, 4
loop DoubleBuffer_loop_plane
inc [VGAPlane]
call VGAPlaneSelect
pop cx
loop DoubleBuffer_loop
sti
ret
endp pageFlipping
在 VGA 的图形控制器中,有一个单独的寄存器来指定要读取的平面。
你select它通过在地址端口03CEh写入一个4,然后在数据端口03CFh写入平面号(0-3)。
您使用的 03C4h:02h 寄存器称为 ColorPlaneWriteEnable。答案已经在它的名字里了!它允许同时写入一个或多个平面。阅读使用 03CEh:04h ReadPlaneSelect.
proc DoubleBuffer ... endp pageFlipping
这是哪个?
PageFlipping 不需要像此过程那样复制大块内存。
DoubleBuffering的思想是利用'normal'RAM构建画面,将画面全部或部分复制到显存中。您的程序使用显存来保存双缓冲区,因此读取速度会很慢!
为什么 DoubleBuffer_loop 这么复杂?
你根本不需要移动和保存!
xor di, di
mov si, NON_VISABLE_PLANE_OFFSET
mov cx, 16000
DoubleBuffer_loop_plane:
mov al, [es:si]
stosb
inc si
dec cx
jnz DoubleBuffer_loop_plane
这可以进一步简化为:
xor di, di
mov si, NON_VISABLE_PLANE_OFFSET
mov cx, 16000
cld
rep movs byte [di], [es:si]
rep movs
的语法取决于您使用的汇编程序。
在 NASM 中,您必须在 REP MOVSB
指令之前通过段覆盖,因此 ES REP MOVSB