Draw on screen using mouse in assembly (emu8086)

5.4k views Asked by At

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 
3

There are 3 answers

2
Jose Manuel Abarca Rodríguez On BEST ANSWER

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

1
Ross Ridge On

It looks you've encountered a bug in your emulator (or its mouse driver). When I run your program on DOSBox and under MS-DOS 6.22 running both under VirtualBox and directly on a PC, your program only draws pixels on the left hand side of the display.

DOSBox screenshot MS-DOS 6.22 under VirtualBox screenshot

You might want to file a bug report with the people who wrote your emulator.

0
Leonardo On

An alternative way to fix the emu8086-bug mentioned in Jose Manuel Abarca Rodríguez's answer, is to use this graphics mode:

mov ah, 00
mov al, 13h       ; set screen to 256 colors, 320x200 pixels. 
int 10h

Normally, CX is only doubled in 320 x 200 pixels graphics mode. This is also documented in the emu8086 documentation as you can see in the following image:

get mouse position and status of its buttons