CALL ABSOLUTE - QB64 Wiki

CALL ABSOLUTE

From QB64 Wiki

Jump to: navigation, search

CALL ABSOLUTE is used to access Interrupts on the computer or execute assembly type procedures.


Syntax:

CALL ABSOLUTE([argument_list,] integer_offset)


Description:

  • CALL and parameter brackets are required in the statement.
  • argument_list contains the list of arguments passed to the procedure.
  • integer_offset contains the offset from the current code segment, set by DEF SEG and SADD, to the starting location of the called procedure.
  • Qbasic and QB64 have the Absolute statement built in and require no library.
  • QuickBASIC requires the QB.QLB Quick Library, loaded with the /L switch.
  • NOTE: QB64 does not currently support INT 33h mouse functions above 3 or BYVAL in an ABSOLUTE statement!


Example 1: Typical ABSOLUTE mouse program demonstrates the AX% mouse functions in QuickBASIC 4.x and QBasic 1.x:

DECLARE SUB MouseDriver (AX%, BX%, CX%, DX%, LB%, RB%, EX%) DIM SHARED mouse$ ' Hardware communications resource string (created in SUB MouseDriver) DIM SHARED CX%, DX%, LB%, RB% ' CX = column, DX = row, LB and RB are left and right buttons SCREEN 12 MouseDriver 1, BX%, CX%, DX%, LB%, RB%, 1 ' EX% = 1 initiates the mouse. Otherwise use EX% = 0 ' ----------------------- DEMO CODE ---------------------- COLOR 10: LOCATE 1, 36: PRINT "H = Hide, S = Show, M = Move, L = Limit area" COLOR 6: LOCATE 2, 10: PRINT "Hold mouse button down for total: P = Presses, R = Releases" COLOR 13: LOCATE 29, 30: PRINT "Click or [Esc] EXIT!"; CIRCLE (220, 150), 90, 10 ' use radius and center coordinates to find circle later LOCATE 9, 22: PRINT "Click in circle" COLOR 12: LOCATE 27, 10: PRINT "Show the mouse the same number of times it was Hidden!" COLOR 14 DO: Funct$ = UCASE$(INKEY$) ' any keypress....keeps loop running for mouse MouseDriver 3, BX%, CX%, DX%, LB%, RB%, 0 ' AX% = 3 reads mouse every loop LOCATE 1, 2: PRINT "LB "; LB% ' left button value 0 or 1 pressed LOCATE 1, 29: PRINT "RB "; RB% ' right button value 0 or 1 pressed LOCATE 1, 10: PRINT "COL"; CX% ' column coordinate LOCATE 1, 20: PRINT "ROW"; DX% ' row coordinate IF CX% >= 230 AND CX% <= 390 AND DX% >= 445 AND DX% <= 460 AND LB% THEN EXIT DO SELECT CASE Funct$ CASE "S": MouseDriver 1, BX%, CX%, DX%, LB%, RB%, 0 ' AX% = 1 show mouse CASE "H": MouseDriver 2, BX%, CX%, DX%, LB%, RB%, 0 ' AX% = 2 hide mouse(accumulates) CASE "M": CX% = 220: DX% = 150 ' set CX% and DX% to circle center MouseDriver 4, BX%, CX%, DX%, LB%, RB%, 0 ' AX% = 4 moves mouse pointer to a coordinate CASE "P": BX% = -1 IF LB% THEN BX% = 0: IF RB% THEN BX% = 1 MouseDriver 5, BX%, CX%, DX%, LB%, RB%, 0 ' AX% = 5 read button presses since last read COLOR 6: LOCATE 29, 10: PRINT "Presses ="; BX%; SPACE$(2); CASE "R": BX% = -1 IF LB% THEN BX% = 0: IF RB% THEN BX% = 1 MouseDriver 6, BX%, CX%, DX%, LB%, RB%, 0 ' AX% = 6 read button releases since last read COLOR 6: LOCATE 29, 10: PRINT "Releases ="; BX%; SPACE$(2); CASE "L": limit = NOT limit ' alternates between partial to fullscreen cursor move area. IF limit THEN CX% = 100: DX% = 500 ELSE CX% = 0: DX% = 639 ' min and max column coordinates MouseDriver 7, BX%, CX%, DX%, LB%, RB%, 0 ' AX% = 7 limit horizontal column area IF limit THEN CX% = 100: DX% = 400 ELSE CX% = 0: DX% = 479 ' min and max row coordinates MouseDriver 8, BX%, CX%, DX%, LB%, RB%, 0 ' AX% = 8 limit vertical row area END SELECT ' CALCULATING WHEN THE POINTER IS INSIDE OF THE CIRCLE ' Pythagorean calculation: X ^ 2 + Y ^ 2 <= Radius ^ 2 for a position inside circle XX& = ((CX% - 220) ^ 2) + ((DX% - 150) ^ 2) ' 220 and 150 are circle center coordinates COLOR 11: LOCATE 22, 8 PRINT "Columns"; CHR$(253); " + Rows"; CHR$(253); " <= Radius"; CHR$(253); " : IF"; XX&; "<= 8100 THEN "; IF XX& <= 8100 THEN ' 90 ^ 2 = 8100 is the circle radius squared PRINT "Over Circle"; SPACE$(7) IF LB% = 1 THEN COLOR 12 ' left mouse button pressed in circle IF RB% = 1 THEN COLOR 13 ' right mouse button pressed in circle ELSE: PRINT "Out of Circle"; SPACE$(5): COLOR 14 ' when mouse is not over circle END IF LOOP UNTIL Funct$ = CHR$(27) ' escape SYSTEM ' -------------------- END DEMO CODE ----------------- MouseData: DATA 55,89,E5,8B,5E,0C,8B,07,50,8B,5E,0A,8B,07,50,8B DATA 5E,08,8B,0F,8B,5E,06,8B,17,5B,58,1E,07,CD,33,53 DATA 8B,5E,0C,89,07,58,8B,5E,0A,89,07,8B,5E,08,89,0F DATA 8B,5E,06,89,17,5D,CA,08,00 SUB MouseDriver (AX%, BX%, CX%, DX%, LB%, RB%, EX%) IF EX% = 1 THEN ' initiate mouse once. EX normally = 0 ' mouse$ = Hardware communications resource string RESTORE MouseData ' restore MouseDATA mouse$ = SPACE$(57) ' defines fixed length as 57 bytes FOR i% = 1 TO 57 READ a$ ' read data for communication string H$ = CHR$(VAL("&H" + a$)) ' get DATA hex ASCII character MID$(mouse$, i%, 1) = H$ NEXT i% END IF DEF SEG = VARSEG(mouse$) CALL Absolute(AX%, BX%, CX%, DX%, SADD(mouse$)) 'get coordinates and buttons DEF SEG IF EX% = 1 THEN LOCATE 29, 60 IF AX% THEN PRINT "Mouse Found"; ' AX = -1 IF FOUND ELSE : BEEP: PRINT "Mouse not found"; : SYSTEM END IF END IF LB% = BX% AND 1 ' positive 1 return values RB% = (BX% AND 2) \ 2 MB% = (BX% AND 4) \ 4 END SUB

Code by: Ted Weissgerber
NOTE: QB64 does not currently support functions above AX% = 3 in above ABSOLUTE demo!

LB 0 COL 84 ROW 140 RB 0 H = Hide, S = Show, M = Move, L = Limit area Hold mouse button down for total: P = Presses, R = Releases Click in circle Columns^2 + Rows^2 <= Radius^2 : IF 18596 <= 8100 THEN Out of Circle Show the mouse the same number of times it was Hidden! Click or [Esc] EXIT! Mouse Found

Explanation: The circle isn't shown in this output screen, but when you run the example you can move the mouse into a circle in the middle of the screen and the text will change color to reflect that you are inside the circle, you can also use the mousebuttons and the color will change.


Example 2: An Absolute substitution for INTERRUPT that can be used by all QB versions including PDS(7.1):

TYPE regs AX AS INTEGER ' mouse function call CX AS INTEGER ' mouse column position DX AS INTEGER ' mouse row position BX AS INTEGER ' mouse button press SP AS INTEGER ' Ignored BP AS INTEGER SI AS INTEGER DI AS INTEGER Flags AS INTEGER DS AS INTEGER ES AS INTEGER END TYPE DIM R AS regs ' set dot variable to the TYPE ' Program code ' R.AX = 3 ' mouse read function = 3 ' CALL INTX(R) SUB INTX(R AS regs) STATIC Code AS STRING, M() AS INTEGER IF LEN(Code) = 0 THEN ' setup only DIM M(0 TO 26) AS INTEGER Code = "5589E58B76069C061EB90B00FCAD50E2FC071F9D61CD" '* Change this to the desired interrupt hex address number * Code = Code + "33" ' IN HEXadecimal form only! ' mouse = "33"; DOS Services = "21" Code = Code + "609C1E0689E58E46168B7E2283C714B90B00FD58ABE2FC1F079D5DCA02" DEF SEG = VARSEG(M(0)) FOR I = 0 TO 51 POKE VARPTR(M(0)) + I, VAL("&H" + MID$(Code, I * 2 + 1, 2)) NEXT END IF ' end setup DEF SEG = VARSEG(M(0)) CALL ABSOLUTE(R, VARPTR(M(0))) DEF SEG END SUB

Code by: Artelius

Explanation: To read or send values use dot variable names. Such as R.AX, R.BX(buttons), R.CX (horizontal coordinate) and R.DX (vertical coordinate). It can use all of the mouse functions used in previous code demo.

Note: The second example cannot currently be run in QB64 as "User defined types are invalid with Absolute"!


See also:



Navigation:
Go to Keyword Reference - Alphabetical
Go to Keyword Reference - By usage
Go to Main WIKI Page
Views
  • Page
  • Discussion
  • View source
  • History
Personal tools
  • Log in
Toolbox
  • What links here
  • Related changes
  • Special pages
  • Printable version