部件x86-16中的模式X,为什么不打印平面1,而所有其他平面的顺序都不正确? [英] Mode X in Assembly x86-16, Why is plane 1 not printing and all the other planes are not in the correct order?

查看:98
本文介绍了部件x86-16中的模式X,为什么不打印平面1,而所有其他平面的顺序都不正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在DosBox 0.74上用TASM 3.0编写,并且我试图用模式x (已调整13h,未链接模式13 ),但是您可以在图中看到,这不太正确. 看来平面1(第二平面)根本没有打印,而所有其他平面的顺序都不正确. 我知道这里的代码效率低下,但是我想使其正常工作然后清理.

proc showBMP
    push cx
    mov ax, 0A000h
    mov es, ax
    mov cx, [BMPHeight]
    mov ax, [BMPWidth]
    xor dx, dx
    mov si, 4
    div si
    mov bp, dx
    mov dx, [BMPX]
    showBMP_nextLine:
        call VGAPlaneStartBMP
        push cx
        push dx
        mov di, cx
        add di, [BMPY]
        mov cx, di
        shl cx, 6
        shl di, 8
        add di, cx
        add di, dx
        mov ah, 3fh
        mov cx, [BMPWidth]
        add cx, bp
        mov dx, offset BMPMaxLine
        int 21h
        cld
        mov cx, [BMPWidth]
        mov si, offset BMPMaxLine
        showBMP_nextLine_movsbLoop:
            push cx
            push di
            shr di, 2
            mov cl, [ds:si]
            mov [es:di], cl
            inc [VGAPlane]
            inc si
            pop di
            inc di
            pop cx
            call VGAPlaneSelect
        loop showBMP_nextLine_movsbLoop
        pop dx
        pop cx
    loop showBMP_nextLine
    pop cx
    ret
endp showBMP

在这里您可以看到打印位图文件的过程,该过程在链4模式13上运行良好.

  • BMPHeight-顾名思义,是图片的高度
  • BMPWidth-相同
  • BMPX-图片在屏幕上开始的位置(x坐标)
  • BMPY-相同,但Y坐标
  • BMPMaxLine-320数组用作缓冲区
  • VGAPlane-0/1/2/3其中一个平面

  proc VGAPlaneStartBMP
       push ax
       push bx
       mov ax, [BMPX]
       mov bx, offset PlaneByX
       add bx, ax
       mov al, [bx]
       mov [VGAPlane], al
       pop bx
       pop ax
       call VGAPlaneSelect
       ret
   endp VGAPlaneStartBMP

对于每行打印,此过程均以行的开头x选择平面:

  • PlaneByX-MAX_WIDTH/NUMBER_OF_PLANES个重复项(PLANES),已重置

  • MAX_WIDTH为320,NUMBER_OF_PLANES为4,PLANES为0、1、2、3,

proc VGAPlaneSelect
        push ax
        push dx
        mov al, 02h
        mov dx, 03C4h
        out dx, al
        VGAPlaneSelect_start:
        cmp [VGAPlane], 0
        jne VGAPlaneSelect_0
            mov al, 0h
            jmp VGAPlaneSelect_end
        VGAPlaneSelect_0:
        cmp [VGAPlane], 1
        jne VGAPlaneSelect_1
            mov al, 1h
            jmp VGAPlaneSelect_end
        VGAPlaneSelect_1:
        cmp [VGAPlane], 2
        jne VGAPlaneSelect_2
            mov al, 4h
            jmp VGAPlaneSelect_end
        VGAPlaneSelect_2:
        cmp [VGAPlane], 3
        jne VGAPlaneSelect_3
            mov al, 8h
            jmp VGAPlaneSelect_end
        VGAPlaneSelect_3:
            mov [VGAPlane], 0
            jmp VGAPlaneSelect_start
        VGAPlaneSelect_end:
        inc dx
        out dx, al
        pop dx
        pop ax
        ret
    endp VGAPlaneSelect

最后,这段代码是在选择飞机时使用的.

解决方案

感谢Fuz找到答案,并感谢Jonathon Reinhart澄清了我的问题. 在VGAPlaneSelect过程中,al值(0x3c5 VGA地址的输出)应为2 ^(您要选择的平面),对于平面0 2 ^ 0则应为1,我写了0

如此:

        cmp [VGAPlane], 0
        jne VGAPlaneSelect_0
            mov al, 1h
            jmp VGAPlaneSelect_end
        VGAPlaneSelect_0:

执行VGAPlaneSelect过程的更好方法是:

    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

I am writing in TASM 3.0 on DosBox 0.74 and I am trying to write in Mode x (Tweaked 13h, unchained mode 13), but here you can see in the image, it's not quite right. It seems that plane 1 (second plane) is not printing at all, and all the others are not in the right order. I know that the code here is inefficient, but I want to make it work and then clean it up.

proc showBMP
    push cx
    mov ax, 0A000h
    mov es, ax
    mov cx, [BMPHeight]
    mov ax, [BMPWidth]
    xor dx, dx
    mov si, 4
    div si
    mov bp, dx
    mov dx, [BMPX]
    showBMP_nextLine:
        call VGAPlaneStartBMP
        push cx
        push dx
        mov di, cx
        add di, [BMPY]
        mov cx, di
        shl cx, 6
        shl di, 8
        add di, cx
        add di, dx
        mov ah, 3fh
        mov cx, [BMPWidth]
        add cx, bp
        mov dx, offset BMPMaxLine
        int 21h
        cld
        mov cx, [BMPWidth]
        mov si, offset BMPMaxLine
        showBMP_nextLine_movsbLoop:
            push cx
            push di
            shr di, 2
            mov cl, [ds:si]
            mov [es:di], cl
            inc [VGAPlane]
            inc si
            pop di
            inc di
            pop cx
            call VGAPlaneSelect
        loop showBMP_nextLine_movsbLoop
        pop dx
        pop cx
    loop showBMP_nextLine
    pop cx
    ret
endp showBMP

Here you can see a procedure for printing a bitmap file, which worked perfectly on chain-4 mode 13.

  • BMPHeight - as name suggest is the height of the picture
  • BMPWidth - same
  • BMPX - where the picture starts on the screen (x coordinate)
  • BMPY - same but Y coordinate
  • BMPMaxLine - array of 320 works as a buffer
  • VGAPlane - 0/1/2/3 one of the planes

  proc VGAPlaneStartBMP
       push ax
       push bx
       mov ax, [BMPX]
       mov bx, offset PlaneByX
       add bx, ax
       mov al, [bx]
       mov [VGAPlane], al
       pop bx
       pop ax
       call VGAPlaneSelect
       ret
   endp VGAPlaneStartBMP

This procedure, for each line of printing, chooses the plane by the starting x of a line:

  • PlaneByX - MAX_WIDTH / NUMBER_OF_PLANES dup (PLANES), RESET

  • MAX_WIDTH is 320, NUMBER_OF_PLANES is 4, PLANES is 0, 1, 2, 3,

proc VGAPlaneSelect
        push ax
        push dx
        mov al, 02h
        mov dx, 03C4h
        out dx, al
        VGAPlaneSelect_start:
        cmp [VGAPlane], 0
        jne VGAPlaneSelect_0
            mov al, 0h
            jmp VGAPlaneSelect_end
        VGAPlaneSelect_0:
        cmp [VGAPlane], 1
        jne VGAPlaneSelect_1
            mov al, 1h
            jmp VGAPlaneSelect_end
        VGAPlaneSelect_1:
        cmp [VGAPlane], 2
        jne VGAPlaneSelect_2
            mov al, 4h
            jmp VGAPlaneSelect_end
        VGAPlaneSelect_2:
        cmp [VGAPlane], 3
        jne VGAPlaneSelect_3
            mov al, 8h
            jmp VGAPlaneSelect_end
        VGAPlaneSelect_3:
            mov [VGAPlane], 0
            jmp VGAPlaneSelect_start
        VGAPlaneSelect_end:
        inc dx
        out dx, al
        pop dx
        pop ax
        ret
    endp VGAPlaneSelect

And lastly this code is when selecting a plane.

解决方案

Thanks to Fuz for finding an answer and Jonathon Reinhart for making my question clearer. in the VGAPlaneSelect procedure, the al values, which are outputs for the 0x3c5 VGA address, should be 2^(the plane that you want to choose), and for plane 0 2^0 it should be 1, and I wrote 0

so:

        cmp [VGAPlane], 0
        jne VGAPlaneSelect_0
            mov al, 1h
            jmp VGAPlaneSelect_end
        VGAPlaneSelect_0:

a better way to do the VGAPlaneSelect procedure is:

    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

这篇关于部件x86-16中的模式X,为什么不打印平面1,而所有其他平面的顺序都不正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆