组装是否以模式x读取平面需要与写入VGA端口不同的输出?

问题描述 投票:5回答:1

[1我正在DosBox 0.74上用TASM 3.0编写,而我试图用Mode x编写(已调整13h,unchained mode 13),我遇到了一个问题,如何在图像中看到每一行会被打印,但是在每一行中,每四个像素组仅打印第一个像素的颜色,这是在将图像打印在VRAM中不同空间中以进行双缓冲之后,因此所有四个平面都具有第一架飞机。

这是应该打印图像的方式(这是不带双缓冲区的直接打印,是的,计时器有问题,但是没关系)

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9YV0pYVC5wbmcifQ==” alt =“在此处输入图像描述”>

这是使用双缓冲打印图像的方式

enter image description here

我确实相信问题在于,在模式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

如果输出不是问题,这里是内存传输的代码:

    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
assembly x86 dos x86-16 vga
1个回答
0
投票
您通过在地址端口03CEh中写入4,然后在数据端口03CFh中写入平面编号(0-3)来选择它。

您使用的03C4h:02h寄存器称为ColorPlane

Write Enable。答案已经是它的名字了!它允许同时写入一个或多个平面。对于阅读,请使用03CEh:04h ReadPlaneSelect。


proc DoubleBuffer ... endp pageFlipping
哪个?
PageFlipping不需要复制此过程中的大块内存。DoubleBuffering的想法是使用“普通” 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

© www.soinside.com 2019 - 2024. All rights reserved.