Search code examples
assemblymousepixelemu8086

Draw on screen using mouse in assembly (emu8086)


The code below lets you draw on screen with mouse, and works perfect. My problem is why does CX need to be divided by 2? Why is it doubled in the first place?

code segment
main proc far

mov al, 12h
mov ah, 0   ; set graphics video mode.
int 10h   

mov ax, 1   ;shows mouse cursor
int 33h

Next:
mov ax, 3   ;get cursor positon in cx,dx
int 33h

call putpix ;call procedure 
jmp Next

mov ah,4ch
int 21h
main endp

;procedure to print
putpix proc   
mov al, 7   ;color of pixel  
mov ah, 0ch    
shr cx,1    ; cx will get double so we divide it by two
int 10h     ; set pixel.
ret
putpix endp
code ends 

Solution

  • Next screenshot of emu8086 and your code will help us to understand what is going on:

    • The purple arrow shows video mode 12h, which is 640x480.
    • The blue arrow shows where the cursor is when the code gets the cursor position in (CX, DX). It's the lower right corner, I chose it on purpose to get the maximum values.
    • I added a "readkey" code snippet to stop the execution in this point and see the values for CX and DX (the yellow bar).
    • The red arrow shows the values for CX and DX. DX is 01DB = 475, which is in the range of 0..479. But CX is 04FA = 1274 (green arrow), which is impossible because the video mode allows columns in the range 0..639.
    • The conclusion is simple: the mouse interrupt 33h returns a doubled value for the cursor column. In order to work around this emu8086-bug, the way to solve this is to divide the column by 2 (shr cx, 1).

    enter image description here