Search code examples
assemblyx86masm

My random number procedure prints garbage value in Graphic mode


I have to prints random values in graphic mode in assembly language 8086. My random procedure works fine in simple mode but in graphic mode it prints garbage values? draw1 macro is used to prints digits or any character on screen in Graphic mode it also works fine. The only issue is in random procedure. It print correct values in simple mode but prints garbage values in Graphic mode.

draw1 macro R1,C1,v1,Col;ROW,COL,value,Colour
    mov AH,2                               
    mov DH,C1   
    mov DL,R1
    INT 10H                 
    
    mov ah,09h
    mov al,v1
    add al,48
    mov bh,0
    mov bl,Col;colour1
    mov cx,1
    int 10h
endm
.model small
.stack 100
.data
ran db 0
.code   
main proc
mov ah,0
         mov al,3
         int 10h    

         ;Graphic mode
;;Command        Size           Colour
;;0Eh            640 x 200      16
;;12h            640 x 480      16
mov ah,0
mov al,0Eh  ;640x200 16 color graphics 
int 10h



call random ;Call random procedure
;draw1 12,8,3,2; To test---draw1 xaxis,yaxis,value,colour
draw1 7,4,ran,3; To draw value on screen

;;Exit Graphic mode
    mov ax,4c00h
    int 21h
  mov ah,4ch
 int 21h 
MAIN ENDP
;Random number procedure
random proc
  mov cx,1000
  L1:
    push cx
    mov cx,1000
  L2:
    Loop L2
    pop cx
    Loop L1
  MOV AH, 00h        
   INT 1AH         

   mov  ax, dx
   xor  dx, dx
   mov  cx, 5  
   div  cx       

   add  dl, '1'  
   mov ran,al
  
  ret
  random endp
END MAIN

Solution

  • mov DH,C1   
    mov DL,R1
    

    The BIOS.SetCursorPosition function 02h expects the column in DL and the row in DH. You've inversed this. Also you need to specify the displaypage for which you want to set the cursor position (mov bh, 0).

    The random procedure divides the low word of the timer tick by 5. This leaves a quotient in AX and a remainder in DX. The remainder wil be in the range [0,4], but the quotient could be much larger than what a byte can hold (up to more than 12000).

    add  dl, '1'        <<< This adds to much (most probably not what you want)
    mov ran,al          <<< This is AL containing garbage
    

    It's not clear what you need here. If you want a random number from 1 to 5, the correct code is:

    add dl, 1
    mov ran, dl
    

    It's the draw1 macro that will turn the value in ran into a character by adding 48.