double buffer video in assembler -
i'm trying double buffer video in assembler, in case have problem, don't know how solve , can't close after key pressed. apparently problem in inc di:
(i'm trying paint 320*200 pixel white color buffer)
.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
a few things:
- check return value when allocate memory (carry set on error,
ax
contains error code, 8 meaning out of memory) [note if you're using com file of available memory allocated program , allocation fail] - you need clear/set direction flag before using string instructions (
cld
in case, see e.g. here) - after trashing
ds
in copying need restore before accessingmodovideo
(it usesds
implicitly).
with changes (and make work in com file) should work. used nasm (compile nasm -f bin -o gfx.com gfx.asm
) , dosbox test it. note method employ allocate memory buggy it's been while since programmed dos.
org 0x100 start: ; allocate buffer %if 0 ; use 21h call 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 (most/all) available memory, grab of mov bx, word [0x0002] ; last paragraph psp sub bx, 64000/16 ; make room buffer mov [vscr_seg], bx mov ax, ds add ax, 0x1000 ; program start paragraph + 64k (max of com file) cmp ax, bx ; did fit? jae error %endif ; clear buffer mov es, [vscr_seg] xor di, di xor ax, ax mov cx, 32000 cld rep stosw ; 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 buffer color 15 mov es, [vscr_seg] xor di, di mov ax, 0x0f0f mov cx, 16000 cld rep stosw ; , fill in pixel colors @ bottom row mov di, 199 * 320 mov cx, 255 xor al, al .fill: ; below 2 instructions equal stosb when direction flag cleared mov [es:di], al inc di inc al loop .fill ; copy buffer screen push ds ; remember 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 ; ... , restore again ; wait 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 , ax 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 , 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 , 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, '$'
Comments
Post a Comment