I'm a cs student and I need to build a project for my architecture class. I have tried to build a simple drag and drop program in asm. The whole idea would be to draw a sqaure somewhere on the screen and then drag it somewhere else using the mouse just like you would on a regular desktop.
I have tried using a buffer but it was to no avail. I'm too much of a beginner to make it work. so I tried some functions to redraw the square. Here is the best I've got using Copilot:
.model small
.stack 100h
.data
x dw 100 ; Initial x position of square
y dw 100 ; Initial y position of square
size_square dw 50 ; Size of the square
isDragging db 0 ; Flag to check if the square is being dragged
prev_x dw 100 ; Previous x position of square
prev_y dw 100 ; Previous y position of square
.code
start:
; Initialize graphics mode
mov ax, 13h
int 10h
; Initialize mouse
mov ax, 0
int 33h
mov ax, 1
int 33h
; Hide mouse cursor
mov ax, 2
int 33h
; Draw initial square
call draw_square
main_loop:
; Show mouse cursor
mov ax, 1
int 33h
; Get mouse status
mov ax, 3
int 33h
; Check if left button is pressed
test bx, 1
jz no_drag
; Start dragging
mov isDragging, 1
mov prev_x, cx
mov prev_y, dx
dragging:
; Hide mouse cursor while dragging
mov ax, 2
int 33h
; Get mouse status
mov ax, 3
int 33h
; Check if button is still pressed
test bx, 1
jz stop_drag
; Clear previous square position
call clear_square
; Update square position
mov x, cx
mov y, dx
; Draw square at new position
call draw_square
; Store current position as previous position
mov prev_x, x
mov prev_y, y
jmp dragging
no_drag:
; If not dragging, wait for next mouse event
jmp main_loop
stop_drag:
; Stop dragging
mov isDragging, 0
; Show mouse cursor
mov ax, 1
int 33h
jmp main_loop
draw_square:
; Draw the square
push si
push di
push cx
push bx
push dx
mov cx, 0
draw_loop1:
mov dx, 0
draw_loop2:
mov ax, y
add ax, cx
mov si, ax
mov ax, x
add ax, dx
mov di, ax
mov al, 15
mov ah, 0Ch
int 10h
inc dx
cmp dx, size_square
jl draw_loop2
inc cx
cmp cx, size_square
jl draw_loop1
pop dx
pop bx
pop cx
pop di
pop si
ret
clear_square:
; Clear the previous square position
push si
push di
push cx
push bx
push dx
mov cx, 0
clear_loop1:
mov dx, 0
clear_loop2:
mov ax, prev_y
add ax, cx
mov si, ax
mov ax, prev_x
add ax, dx
mov di, ax
mov al, 0
mov ah, 0Ch
int 10h
inc dx
cmp dx, size_square
jl clear_loop2
inc cx
cmp cx, size_square
jl clear_loop1
pop dx
pop bx
pop cx
pop di
pop si
ret
exit_program:
; Restore text mode
mov ax, 3
int 10h
ret
end start
Please help me understand what went wrong ;(
Please help me understand what went wrong ;(
So many things that are wrong in this program! The AI wasn't even able to draw a solid square at (x,y) using BIOS.WritePixel. (A solid white square could get displayed in the upper left corner of the screen). And why a different code was needed to wipe the square is beyond me. Same procedure, other set of arguments.
push bx pop bx
BX wasn't initialized to anything, so why waste bytes on preserving BX.
mov ax, y add ax, cx mov si, ax
BIOS.WritePixel expects its Y coordinate in the DX register, so very much not SI.
mov ax, x add ax, dx mov di, ax
BIOS.WritePixel expects its X coordinate in the CX register, so very much not DI.
My version:
mov cx, x
mov dx, y
mov al, 15 ; To 'clear' the square, you pass AL=0
call PaintSquare
...
; IN (al,cx,dx)
PaintSquare:
push bx ; AL is Color=[0,255]
push si ; CX is X=[0,319]
push di ; DX is Y=[0,199]
mov bh, 0 ; DisplayPage
mov di, size_square ; Height
.OuterLoop:
mov si, size_square ; Width
.InnerLoop:
mov ah, 0Ch ; BIOS.WritePixel
int 10h
inc cx ; X++
dec si
jnz .InnerLoop
sub cx, size_square
inc dx ; Y++
dec di
jnz .OuterLoop
sub dx, size_square
pop di
pop si
pop bx
ret
prev_x dw 100 ; Previous x position of square prev_y dw 100 ; Previous y position of square
The AI is loading prev_x and prev_y with the coordinates where the mouse click was registered. This is unrelated to where the square needs to be erased!
Moreover, before any dragging can begin, you still need to check whether the mouse is actually on top of the current square.
exit_program: ; Restore text mode mov ax, 3 int 10h ret
Although the AI included this nice 'exit_program' part, this code is unreachable and if jumped at, its ret
could only return to DOS is this were a .COM executable. Sadly, the .model small
says this is going to be an .EXE executable, for which additionally the DS segment register wasn't setup and therefore addressing the memory-based variables will fail completely.
The list goes on...
My suggestion then would be that you forget about using the mouse for now, and that, with the help of my PaintSquare procedure, you try your hand at a version of the program that moves the square based on the arrow keys on the keyboard. In the intrest of flicker-free graphics you could use a double buffer like you described in one of your comments. Good luck.