Режим X в сборке x86-16. Почему плоскость 1 не печатается, а все остальные плоскости не в правильном порядке? - PullRequest
6 голосов
/ 22 января 2020

Я пишу в TASM 3.0 на DosBox 0.74 и пытаюсь писать в Mode x (твик 13h, unchained режим 13 ), но здесь вы можете видеть на картинке не совсем верно. Кажется, что плоскость 1 (вторая плоскость) вообще не печатает, а все остальные не в правильном порядке. Я знаю, что код здесь неэффективен, но я хочу заставить его работать, а затем очистить его.

Output

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 dup (PLANES), RESET

  • 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

И, наконец, этот код при выборе плоскости.

1 Ответ

2 голосов
/ 22 января 2020

Спасибо Fuz за поиск ответа и Jonathon Reinhart за разъяснение моего вопроса. в процедуре VGAPlaneSelect все значения al, которые являются выходами для адреса VGA 0x3c5, должны быть 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
...