mouse in qbasic with asm...

If you have questions about any aspect of QBasic programming, or would like to help fellow programmers solve their problems, check out this board!

Moderators: Pete, Mods

Post Reply
User avatar
bongomeno
Veteran
Posts: 266
Joined: Wed Dec 10, 2008 9:08 am
Location: Arizona
Contact:

mouse in qbasic with asm...

Post by bongomeno »

I am trying to learn assembly language.
I tried to make a mouse program that does the following:

- check for mouse; if no mouse, wait for one
- display mouse cursor
- wait until until mouse is moved to 1,1 on the screen
- end program

My code doent work!
Please help me fix it. lol

here is my code:

Code: Select all

;mouse routine
mov ax,0
int 33 ;check for mouse
cmp ax,-1
jne 0100 ;if no mouse then keep reading
mov ax,1
int 33 ;display mouse
mov ax,3
int 33 ; get mouse x and y coordinates intoo cx and dx
cmp cx,1
jne 010f ;wait until mouse x=1
cmp dx,1
jne 010f ;wait until mouse y=1
retf ;end program
Hristic
Newbie
Posts: 3
Joined: Thu Jan 29, 2009 1:57 pm
Location: Germany

Asm Code

Post by Hristic »

1. Have you forgotten to set the h after the 33? (33h)
- otherwise your program would exit because INT 21h and ax=0 starts an interrupt which ends your program.

2. Is your program called correctly? Have you either SHELL or CALL ABSOLUTE?

3. don't forget to set the lines PUSH BP - MOV BP, SP at the begin of your program. At the end you have to do POP BP.

4. Are the JMP-Adresses correct? On my computer the asm looks like this:

HEX ASM

PUSH BP
MOV BP, SP
MOV AX, 0000h
INT 33h ; Check for mouse
CMP AX, FFFFh ; FFFFh = -1
JNE 00000003h ; keep reading if no mosue
MOV AX, 0001h
INT 33h ; Display mouse
MOV AX, 03h
INT 33h ; Get x in cx and y in dx
CMP CX, 0001h ; (Do you really want to have this?
JNE 00000012h ; Please note that the x- and y-
CMP DX, 0001h ; coordinates begin with 0 on
JNE 00000012h ; every screen!)
POP BP
RETF

Then your program should work.
User avatar
bongomeno
Veteran
Posts: 266
Joined: Wed Dec 10, 2008 9:08 am
Location: Arizona
Contact:

ahhhh

Post by bongomeno »

ahhh thank you very much good sir!
this should answer my question for now.
ill test it as soon as i wake up.

btw im not using shell or call absolute.

using debug, i did this:

Code: Select all

DIM asm AS STRING

LET asm = asm + CHR$(&HB8) + CHR$(&H0) + CHR$(&H0)
LET asm = asm + CHR$(&HCD) + CHR$(&H33)
LET asm = asm + CHR$(&H3D) + CHR$(&HFF) + CHR$(&HFF)
LET asm = asm + CHR$(&H75) + CHR$(&HF6)
LET asm = asm + CHR$(&HB8) + CHR$(&H1) + CHR$(&H0)
LET asm = asm + CHR$(&HCD) + CHR$(&H33)
LET asm = asm + CHR$(&HB8) + CHR$(&H3) + CHR$(&H0)
LET asm = asm + CHR$(&HCD) + CHR$(&H33)
LET asm = asm + CHR$(&H83) + CHR$(&HF9) + CHR$(&H1)
LET asm = asm + CHR$(&H75) + CHR$(&HF6)
LET asm = asm + CHR$(&HB8) + CHR$(&H3) + CHR$(&H0)
LET asm = asm + CHR$(&HCD) + CHR$(&H33)
LET asm = asm + CHR$(&H83) + CHR$(&HFA) + CHR$(&H1)

OPEN "C:/MTST.COM" FOR OUTPUT AS #1
PRINT #1, asm
CLOSE #1

END
Yazar
Coder
Posts: 11
Joined: Sat May 24, 2008 10:51 pm

Post by Yazar »

First, I started learning assembly like you. Then I wrote a qb code that you can use debug, use labels and save the hex code and string code that qb can use.

Make a mini text editor, save the code lines, use the SHELL "DEBUG.EXE***************"

After all that, I started to use TASM for making my own qb libraries. I suggest you to keep on debug.exe till you feel enough. That really makes you a good asm coder. Any way;

xor ax, ax ;this is the same with mov ax, 0 (1 byte less operation ;) )
int 33
cmp al, FF ;Notice that not ax (shortes operations)
jne xxxx
mov ax, 1
int 33
@:
mov ax, 3
int 33
cmp cx, 1 ;Not cl, cx. cuz 257 = 101h also makes cl 1.So check two bytes
jnz @
cmp dx, 1
jnz @
xxxx:
retf

The labels and adresses will be clear with debug.

And here you are the unassembler/(mydebug.bas)

Code: Select all

DECLARE SUB clr ()
DECLARE SUB waitkey ()
DECLARE SUB sync ()
DECLARE SUB load.asm ()
DECLARE SUB memcopy (seg1%, off1%, seg2%, off2%, bytes%)
DECLARE SUB text (e$, x%, y%, f%, b%)
DECLARE FUNCTION StringNumber$ (num%, digit%)
DECLARE FUNCTION InputText$ ()

SCREEN 0: WIDTH 80
CLS

TYPE asmcommandtype
        caption AS STRING * 65
        bytes   AS STRING * 1
        index   AS INTEGER
        length  AS INTEGER
END TYPE

DIM asmline(511) AS asmcommandtype
DIM SHARED vs(24) AS STRING * 160
DIM SHARED asmcopy$

cs% = 0
Ip% = 0
cursor.y% = 0
cursor.x% = 0
page.y% = 0
load.asm

source$ = "c:\some.asm"
temp$ = "c:\some.txt"
asmline(0).index = 256



DO
a$ = INKEY$
IF a$ <THEN>= 32 AND ASC(a$) <128> 0 THEN
w1$ = MID$(asmline(cursor.y% + page.y%).caption, 1, cursor.x% - 1)
w2$ = MID$(asmline(cursor.y% + page.y%).caption, cursor.x% + 1)
asmline(cursor.y% + page.y%).caption = w1$ + w2$
cursor.x% = cursor.x% - 1
asmline(cursor.y% + page.y%).length = asmline(cursor.y% + page.y%).length - 1
END IF
END IF
IF a$ = CHR$(0) + CHR$(83) THEN
IF cursor.x% < asmline(cursor.y% + page.y%).length THEN
w1$ = MID$(asmline(cursor.y% + page.y%).caption, 1, cursor.x%)
w2$ = MID$(asmline(cursor.y% + page.y%).caption, cursor.x% + 2)
asmline(cursor.y% + page.y%).caption = w1$ + w2$
asmline(cursor.y% + page.y%).length = asmline(cursor.y% + page.y%).length - 1
END IF
END IF

IF a$ = CHR$(0) + CHR$(71) THEN cursor.x% = 0
IF a$ = CHR$(0) + CHR$(79) THEN cursor.x% = asmline(cursor.y% + page.y%).length


IF a$ = CHR$(0) + CHR$(72) THEN
cursor.y% = cursor.y% - 1
IF cursor.y% < 0 THEN
cursor.y% = 0
page.y% = page.y% - 1
IF page.y% <0> asmline(page.y% + cursor.y%).length THEN cursor.x% = asmline(page.y% + cursor.y%).length
END IF


IF a$ = CHR$(0) + CHR$(80) OR a$ = CHR$(13) THEN
IF asmline(cursor.y% + page.y%).length > 0 THEN
cursor.y% = cursor.y% + 1
lc% = 1
IF cursor.y% > 24 THEN
cursor.y% = 24
page.y% = page.y% + 1
IF page.y% > 482 THEN page.y% = 482: lc% = 0
END IF
IF cursor.x% > asmline(page.y% + cursor.y%).length THEN cursor.x% = asmline(page.y% + cursor.y%).length
IF lc% THEN GOSUB Proceed: total% = total% + 1
END IF
END IF



END IF
IF cursor.x% <0> 63 THEN cursor.x% = 63

IF a$ = CHR$(27) THEN GOSUB save
GOSUB InitScreen


sync
LOOP
END


Proceed:
cy% = cursor.y% + page.y% - 1
l% = asmline(cy%).length
w$ = RTRIM$(LTRIM$(MID$(asmline(cy%).caption, 1, l%)))
k% = INSTR(w$, ";")
IF k% THEN w$ = MID$(w$, 1, k% - 1)
IF w$ <> "" THEN
OPEN source$ FOR OUTPUT AS #1
PRINT #1, "A " + HEX$(asmline(cy%).index)
PRINT #1, w$
PRINT #1, ""
PRINT #1, "U " + HEX$(asmline(cy%).index)
PRINT #1, ""
PRINT #1, "Q"
CLOSE #1

SHELL "debug.exe <" + source$ + "> " + temp$

OPEN temp$ FOR INPUT AS #1
LINE INPUT #1, a$
LINE INPUT #1, a$
LINE INPUT #1, a$
LINE INPUT #1, a$
LINE INPUT #1, a$

k% = INSTR(a$, "^")
IF k% THEN
MID$(asmline(cy%).caption, asmline(cy%).length + 1, 6) = "  !!!!"
asmline(cy%).length = asmline(cy%).length + 6
cursor.y% = cursor.y% - 1
ELSE
b$ = "&h" + MID$(a$, 6, 4)
asmline(cy% + 1).index = VAL(b$)
END IF
CLOSE #1
KILL source$
KILL temp$
ELSE
asmline(cy% + 1).index = asmline(cy%).index
END IF
RETURN



InitScreen:
'clr
FOR t% = 0 TO 24
Ip% = asmline(page.y% + t%).index
f$ = StringNumber(Ip%, 4)
cc% = 9
dd% = 7
IF t% = cursor.y% THEN cc% = 1: dd% = 15
text f$, 0, t%, cc%, 7
text CHR$(179), 4, t%, 9, 7
f$ = " " + asmline(page.y% + t%).caption
text f$, 5, t%, dd%, 0
NEXT
LOCATE cursor.y% + 1, cursor.x% + 7, 1
RETURN



save:
clr
text "1 - Save Asm Source", 23, 8, 1, 0
text "2 - Extract Qb4.5 String", 23, 9, 14, 0
text "3 - Insert Qb4.5 String", 23, 10, 2, 0
text "4 - Load asm file", 23, 11, 9, 0
text "5 - Cancel", 23, 12, 6, 0
text "6 - Quit", 23, 13, 4, 0
DO
a$ = INKEY$
sync
LOOP UNTIL a$ <> ""
SELECT CASE a$
CASE "6"
END
RETURN
CASE CHR$(27)
a$ = ""
RETURN
CASE "5"
a$ = ""
RETURN
CASE "1"
LOCATE 15, 1: INPUT "Please enter asm source file name"; f$
OPEN f$ FOR OUTPUT AS #1
FOR t% = 0 TO total%
w$ = RTRIM$(LTRIM$(MID$(asmline(t%).caption, 1, asmline(t%).length)))
IF w$ <THEN> 24 THEN
cursor.y% = 24
page.y% = page.y% + 1
END IF
END IF
LOOP UNTIL EOF(2)
cursor.y% = 0
page.y% = 0
cursor.x% = 0
CLOSE #2
clr
text "File " + CHR$(34) + f$ + CHR$(34) + " loaded...", 23, 14, 3, 0
sync
waitkey

CASE "2"
FOR umt = 0 TO 511
IF asmline(umt).length = 0 THEN EXIT FOR
NEXT
total% = umt - 1
LOCATE 15, 1: INPUT "Please enter basic file name"; f$
LOCATE 16, 1: INPUT "Please enter basic string tag"; tag$
IF MID$(tag$, LEN(tag$), 1) <> "$" THEN tag$ = tag$ + "$"
OPEN f$ FOR OUTPUT AS #1
PRINT #1, tag$; " = "; CHR$(34); CHR$(34)
OPEN source$ FOR OUTPUT AS #2
PRINT #2, "A 100"

FOR t% = 0 TO total%
l% = asmline(t%).length
tw$ = RTRIM$(LTRIM$(MID$(asmline(t%).caption, 1, l%)))
IF tw$ <> "" THEN
PRINT #2, tw$
END IF
NEXT
PRINT #2, ""
PRINT #2, "U 100"
PRINT #2, ""
PRINT #2, "Q"
CLOSE #2
SHELL "debug.exe <" + source$ + "> " + temp$
OPEN temp$ FOR INPUT AS #2
FOR t = 1 TO total% * 2 + 4
LINE INPUT #2, a$
NEXT
FOR t = 0 TO total%
l% = asmline(t).length
tw$ = RTRIM$(LTRIM$(MID$(asmline(t).caption, 1, l%)))
LINE INPUT #2, a$
w$ = ""
e$ = ""
FOR u = 11 TO LEN(a$)
w$ = MID$(a$, u, 1)
IF w$ <> " " THEN e$ = e$ + w$ ELSE EXIT FOR
NEXT
rt% = LEN(e$) / 2
SELECT CASE rt%
CASE 1
pk% = 60 - LEN(tag$) * 2 - 16
CASE 2
pk% = 60 - LEN(tag$) * 2 - 29
CASE 3
pk% = 60 - LEN(tag$) * 2 - 42
END SELECT

IF pk% < 0 THEN pk% = 1
msp$ = SPACE$(pk%)
PRINT #1, tag$; " = "; tag$; " + chr$(&H";
FOR u = 1 TO rt%
ee$ = MID$(e$, (u - 1) * 2 + 1, 1)
ef$ = MID$(e$, (u - 1) * 2 + 2, 1)
IF u < rt% THEN
g$ = ee$ + ef$ + ")" + " + chr$(&H"
PRINT #1, g$;
ELSE
g$ = ee$ + ef$ + ")" + msp$ + "'" + tw$
PRINT #1, g$

END IF
NEXT

NEXT
CLOSE #1
CLOSE #2


clr
text "Your File " + CHR$(34) + f$ + CHR$(34) + " saved...", 23, 14, 3, 0
sync
waitkey









clr
text "Your File " + CHR$(34) + f$ + CHR$(34) + " saved...", 23, 14, 3, 0
sync
waitkey





END SELECT
RETURN


load:
RETURN

SUB clr
DIM empty AS STRING * 160
FOR y% = 0 TO 24
vs(y%) = empty
NEXT
END SUB

SUB load.asm
asmcopy$ = ""
asmcopy$ = asmcopy$ + CHR$(&H55)
asmcopy$ = asmcopy$ + CHR$(&H89) + CHR$(&HE5)
asmcopy$ = asmcopy$ + CHR$(&H1E)
asmcopy$ = asmcopy$ + CHR$(&H8B) + CHR$(&H46) + CHR$(&HA)
asmcopy$ = asmcopy$ + CHR$(&H8E) + CHR$(&HC0)
asmcopy$ = asmcopy$ + CHR$(&H8B) + CHR$(&H46) + CHR$(&HE)
asmcopy$ = asmcopy$ + CHR$(&H8E) + CHR$(&HD8)
asmcopy$ = asmcopy$ + CHR$(&H8B) + CHR$(&H76) + CHR$(&H8)
asmcopy$ = asmcopy$ + CHR$(&H8B) + CHR$(&H7E) + CHR$(&HC)
asmcopy$ = asmcopy$ + CHR$(&H8B) + CHR$(&H4E) + CHR$(&H6)
asmcopy$ = asmcopy$ + CHR$(&HF3)
asmcopy$ = asmcopy$ + CHR$(&HA4)
asmcopy$ = asmcopy$ + CHR$(&H1F)
asmcopy$ = asmcopy$ + CHR$(&H5D)
asmcopy$ = asmcopy$ + CHR$(&HCB)




END SUB

SUB memcopy (seg1%, off1%, seg2%, off2%, bytes%)
DEF SEG = VARSEG(asmcopy$)
CALL absolute(BYVAL seg1%, BYVAL off1%, BYVAL seg2%, BYVAL off2%, BYVAL bytes%, SADD(asmcopy$))
DEF SEG
END SUB

FUNCTION StringNumber$ (num%, digit%)
w$ = ""
f$ = HEX$(num%)

FOR t = 1 TO digit% - LEN(f$)
w$ = w$ + "0"
NEXT
w$ = w$ + f$
StringNumber$ = w$
END FUNCTION

SUB sync
memcopy VARSEG(vs(0)), VARPTR(vs(0)), &HB800, 0, 4000
END SUB

SUB text (e$, x%, y%, f%, b%)
DEF SEG = VARSEG(vs(y%))
add& = VARPTR(vs(y%)) + x% * 2
FOR t = 1 TO LEN(e$)
w$ = MID$(e$, t, 1)
POKE add&, ASC(w$)
POKE add& + 1, (f% + b% * 16) AND &HFF
add& = add& + 2&
NEXT
END SUB

SUB waitkey
DO
a$ = INKEY$
LOOP UNTIL a$ <> ""
END SUB

Notice that I don't remember if this was working properly. What I remember is, you can use home/end keys, cursor keys, delete and bck space key.

You type the asm code and press enter to proceed. The debug runs and finds the next Instruction Pointer. And when you press esc the options are listed...

Anyway, I am sure you will recode my code and use it for your needs. Also there was another guy's code. But it was the bug, which gives control to the Debug.exe with fault commands and never return back to qb. Cuz be careful with the 'SHELL' command. The rest is just Qb...
Post Reply