' QBasic Mouse Sub Procedure
' Source: https://web.archive.org/web/20171227233136/http://staticchaos.awardspace.com/basic/qbmouse.php
'
' If you just want a quick mouse routine for QBasic, then copy & paste the (below) code into a .BAS file
' and call the mouse SUB routine, passing it the number of the interrupt sub-function:
'
' 0 = initialize mouse
' 1 = show mouse cursor
' 2 = hide mouse cursor
' 3 = get mouse co-ordinates and button status
'
' Notes:
' 1. This works for graphics & text modes.
' 2. Typically, the mouse is initialized (sub-function 0) early in the program.
' 3. The mouse cursor should *always* be hidden (sub-function 2) when drawing any graphics to the screen
' to avoid distortion or erasure of the mouse cursor. The mouse cursor should be restored (sub-function 1)
' right after the graphic drawing statement(s).
' The mouse status (sub-function 3) procedure will return the cursor's column in cx and its row in dx.
' 4. The button states are returned in bx:
' 1 = left mouse button is pressed down
' 2 = right mouse button is pressed down
' 3 = left+right mouse buttons are pressed down
' 4 = middle mouse button is pressed down
'
'
' Your program code goes here...
'===============================
' Test Driver
'===============================
ml$ = "" ' -=<( Mouse Code )>=-
ml$
= ml$
+ CHR$(&H55) ' push bp ; preserve BP register ml$
= ml$
+ CHR$(&H89) + CHR$(&HE5) ' mov bp, sp ; copy SP to BP ml$
= ml$
+ CHR$(&HB8) + CHR$(ax
) + CHR$(&H0) ' mov ax, # ; copy SUBFUNCTION to AX ml$
= ml$
+ CHR$(&HCD) + CHR$(&H33) ' int 33 ; call mouse interrupt ml$
= ml$
+ CHR$(&H53) ' push bx ; preserve BX (again) ml$
= ml$
+ CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6) ' mov bx, [bp+6] ; copy location of dx (last variable) to BX ml$
= ml$
+ CHR$(&H89) + CHR$(&H17) ' mov [bx], dx ; copy DX to dx location in BX ml$
= ml$
+ CHR$(&H8B) + CHR$(&H5E) + CHR$(&H8) ' mov bx, [bp+8] ; copy location of cx to BX ml$
= ml$
+ CHR$(&H89) + CHR$(&HF) ' mov [bx], cx ; copy CX to cx location in BX ml$
= ml$
+ CHR$(&H8B) + CHR$(&H5E) + CHR$(&HC) ' mov bx, [bp+C] ; copy location of ax to BX ml$
= ml$
+ CHR$(&H89) + CHR$(&HF7) ' mov [bx], ax ; copy AX to ax location in BX ml$
= ml$
+ CHR$(&H8B) + CHR$(&H5E) + CHR$(&HA) ' mov bx, [bp+A] ; copy location of bx to BX ml$
= ml$
+ CHR$(&H58) ' pop ax ; restore int 33's BX value to AX ml$
= ml$
+ CHR$(&H89) + CHR$(&H7) ' mov [bx], ax ; copy AX to bx location in BX ml$
= ml$
+ CHR$(&H5D) ' pop bp ; restore BP ml$
= ml$
+ CHR$(&HCA) + CHR$(&H8) + CHR$(&H0) ' retf 8 ; Return Far and skip 8 bytes of variables DEF SEG = VARSEG(ml$
) ' Set current segment this machine code segment offset%
= SADD(ml$
) ' Set offset to this machine code location CALL ABSOLUTE(ax
, bx
, cx
, dx
, offset%
) ' The actual call to this machine code DEF SEG ' Restore the default segment