user27789527
user27789527

Reputation: 13

Filling color in enclosed area in MASM using recursion

I have a function vmem, which is for drawing at (CX,DX). The function vmemr is for reading (CX,DX) to see if the pixel is painted. And vmemr will return AL=1 if there is color on (CX,DX).
Now I want to fill an enclosed area using recursion. The starting (CX,DX) is from the middle point of the enclosed area:

fill PROC
    mov al, 0
    push cx
    push dx
    call vmem
    inc cx
    call vmemr
    cmp al, 0
    jne notr
    call fill
notr:    
    dec cx
    dec cx
    call vmemr
    cmp al, 0
    jne notl
    call fill
notl:
    inc cx
    inc dx
    call vmemr
    cmp al, 0
    jne notu
    call fill
notu:
    dec dx
    dec dx
    call vmemr
    cmp al , 0
    jne notd
    call fill
notd:
    pop dx
    pop cx
    
    ret    
fill ENDP

I've tried this code. But it only drew a line and doesn't quit normally.

Upvotes: 1

Views: 86

Answers (1)

Nassau
Nassau

Reputation: 924

This procedure looks ok. Problem could be inside vmem or vmemr.

  • wrong pixel offset calculations.
  • push/pop, ret instruction pops bad address from the stack.

I added rest of the code and it works normally. Press any key to see how pixels are drawn.

Code:

.model small
.stack 0d00h

.data
    color db 48
.code
start:
    mov ax,@data                    ; load ds
    mov ds,ax

    mov ax,0a000h                   ; es = video mem, offset a000h
    mov es,ax
    
    mov ax,13h                      ; video mode 13h, 320x200x256
    int 10h
    
    call draw_shape                 ; draw rectangle
    
    mov cx, 115                     ; center of the shape
    mov dx, 35
    call fill
    
    mov ax, 4c00h                   ; end app
    int 21h

;-----------------------------------

vmem proc                           
    push dx                         
 
    mov bl,color
    sub bl,6
        
    mov ax,320                       
    mul dx
    add ax,cx
    mov di,ax
    
    mov es:[di],bl
    
    pop dx
    ret
vmem endp

vmemr proc
    push dx
    
    mov ax,320
    mul dx
    add ax,cx
    mov di,ax
    
    mov al,es:[di]
    
    pop dx
    ret
vmemr endp

fill proc
    mov al, 0
    push cx
    push dx
    call vmem
    
    mov ah,08h
    int 21h
    
    inc cx
    call vmemr
    cmp al, 0
    jne notr
    call fill
notr:    
    dec cx
    dec cx
    call vmemr
    cmp al, 0
    jne notl
    call fill
notl:
    inc cx
    inc dx
    call vmemr
    cmp al, 0
    jne notu
    call fill
notu:
    dec dx
    dec dx
    call vmemr
    cmp al , 0
    jne notd
    call fill
notd:
    pop dx
    pop cx
    
    ret    
fill endp

draw_shape proc

    mov di, 320*20 + 100            ; top horizontal line starting position
    mov bx, 320*50 + 100            ; bottom horizontal line starting position
    mov al, color                   ; border color
    
    mov cx,30                       ; draw 30 pixels
    
    hz_lines:
    
        mov es:[di],al              ; upper line pixel
        mov es:[bx],al              ; bottom line pixel
    
        inc di                      ; next pixel
        inc bx                      ;
        
        dec cx                      ; 
        jnz hz_lines                ;

    mov di, 320*21 + 100            ; left vertical line starting position
    mov bx, 320*21 + 129            ; right vertical line starting position
    mov al, 48                      ; border color
    
    mov cx, 29                      ; draw 29 pixels
    
    vt_lines:
    
        mov es:[di],al              ; left line pixel
        mov es:[bx],al              ; roght line pixel
    
        add di,320                  ; next row
        add bx,320                  ;
        
        dec cx                      ;
        jnz vt_lines                ;

    ret
draw_shape endp

end start
end

Upvotes: 1

Related Questions