2011-07-03 7 views
2

私はアセンブラでダブルバッファのビデオを作成しようとしていますが、この場合は問題があります。私はそれを解決する方法がわかりません。 。ダブルバッファのビデオをアセンブラで

(私は、バッファと白の色を持つすべての320 * 200ピクセルを描画しようとしている)

.model small 
.386 
.stack 400h 
.data 

modovideo db ? 
vram dw 0 

xVal dw ? 
yVal dw ? 

.code 
main proc 
    mov ax,@data 
    mov ds,ax 

    mov ah,0fh 
    int 10h 
    mov modovideo,al 

    mov ah,0 
    mov al,13h 
    int 10h 

    ; Segmento de memoria ===================================== 

    mov ah,48h 
    mov bx,4000 ; 64000/16 
    int 21h 
    mov vram,ax 

    ; Escribir en el segmento de memoria ======================================= 

mov es,vram 

;offset = 320*y + x 
    ;mov xVal,160 
    ;mov yVal,100 
    ;mov ax,320 
    ;mul yVal 
    ;add ax,xVal 


mov di,0 
mov al,7 

mov cx,640 
paso1: 
    mov es:[di],al 
    inc di ; <----------- 
    loop paso1 

; Volcar sobre pantalla ====================================================== 

mov ds,vram 
xor si,si 
mov dx,0A000h 
mov es,dx 
xor di,di 
mov cx,64000 
rep movsb 

mov ah,1 
int 21h 

salir: 
mov al,modovideo 
mov ah,0 
int 10h 

mov ah,4ch 
int 21h 

    main endp 
+0

「inc di」の問題は何ですか?あなたがそれをコメントアウトすると動作しますか?ところで、おそらくあなたの悩みを引き起こすものではありませんが、 'movsb'を使う前に' cld'で方向フラグをクリアしてください。 – user786653

答えて

2

いくつかのこと:

    どうやら問題は 株式会社ディであります
  • メモリを割り当てるときに戻り値を確認します(エラー時にキャリーが設定され、axにはエラーコードが格納されます)。[COMファイルを使用している場合は、ほとんどのメモリにあなたのプログラムと割り当てのフェイル]
  • 文字列命令を使用する前に方向フラグをクリア/設定する必要があります(この場合はcldです。 here
  • dsをコピーした後、modovideo(暗黙的にdsを使用)にアクセスする前に復元する必要があります。

これらの変更(およびCOMファイルで機能させるためにいくつかの追加)を使用すると効果があります。私はそれをテストするためにnasm(でコンパイル)とDOSBoxを使用しました。私がDOS用にプログラミングしてからしばらく経っているので、私がメモリを割り当てる方法はおそらくバグであることに注意してください。

 
    org 0x100 

start: 
    ; Allocate back buffer 
%if 0 
    ; Use 21h call to allocate memory (for EXE files) 
    mov ah, 0x48 
    mov bx, 64000/16 
    int 0x21 
    jc error ; carry set on error 
    mov [vscr_seg], ax 
%else 
    ; COM files get (most/all) available memory, grab some of it 
    mov bx, word [0x0002] ; Get last paragraph from PSP 
    sub bx, 64000/16 ; Make room for back buffer 
    mov [vscr_seg], bx 

    mov ax, ds 
    add ax, 0x1000 ; Program start paragraph + 64K (max of COM file) 
    cmp ax, bx ; Did it fit? 
    jae error 
%endif 
    ; Clear back buffer 
    mov es, [vscr_seg] 
    xor di, di 
    xor ax, ax 
    mov cx, 32000 
    cld 
    rep stosw 


    ; Get previous video mode 
    mov ah, 0x0f 
    int 0x10 
    mov [previous_video_mode], al 

    ; Set mode 13h (320x200 256 colors) 
    mov ax, 0x0013 
    int 0x10 

    ; Fill half the back buffer with color 15 
    mov es, [vscr_seg] 
    xor di, di 
    mov ax, 0x0f0f 
    mov cx, 16000 
    cld 
    rep stosw 

    ; And fill in all pixel colors at bottom row 
    mov di, 199 * 320 
    mov cx, 255 
    xor al, al 
.fill: 
    ; the below two instructions are equal to stosb when the direction flag is cleared 
    mov [es:di], al 
    inc di 

    inc al 
    loop .fill 

    ; Copy from back buffer to the screen 
    push ds ; Remember to save DS! 
    mov ds, [vscr_seg] 
    mov ax, 0xa000 
    mov es, ax 
    xor di, di 
    xor si, si 
    mov cx, 32000 
    cld 
    rep movsw 
    pop ds ; ... And restore it again 

    ; Wait for keypress 
    mov ah, 0x01 
    int 0x21 

    ; Restore video mode 
    mov ah, 0x00 
    mov al, [previous_video_mode] 
    int 0x10 

    ; Skip error block 
    jmp exit 

error: 
    ; Print bx and ax to facilitate debugging 
    push ax 
    call print_hex_word 
    pop ax 
    mov bx, ax 
    call print_hex_word 

    mov ah, 0x09 
    mov dx, error_string 
    int 0x21 

exit: 
    ; Exit 
    mov ax, 0x4c00 
    int 0x21 

; Print 16-bit word in BX, trashes AX and DX (at least) 
print_hex_word: 
    mov dx, bx 
    shr dx, 12 
    call print_hex_digit 
    mov dl, bh 
    call print_hex_digit 
    mov dl, bl 
    shr dl, 4 
    call print_hex_digit 
    mov dl, bl 
    call print_hex_digit 
    ; New line 
    mov ah, 0x02 
    mov dl, 13 
    int 0x21 
    mov dl, 10 
    int 0x21 
    ret 

print_hex_digit: 
    push bx 
    and dl, 0x0f 
    add dl, '0' 
    cmp dl, '9' 
    jle .print 
    add dl, 'A' - '0' - 10 
.print: 
    mov ah, 0x02 
    int 0x21 
    pop bx 
    ret 


previous_video_mode db 0 
vscr_seg dw 0 
error_string db 'Error occurred!', 13, 10, 7, '$' 
関連する問題