Author Topic: ASM - Can someone make this work?  (Read 6062 times)

0 Members and 1 Guest are viewing this topic.

Offline Unseen Machine

  • Forum Regular
  • Posts: 158
  • Make the game not the engine!
    • View Profile
ASM - Can someone make this work?
« on: June 22, 2020, 06:08:23 am »
I thought it would be quite easy but i keep getting compilation fails no matter what i try so i guess i'm doing it wrong....

Code: QB64: [Select]
  1.  
  2. ASMString$ = "movl, %ebx, %eax" '// Move contents of ebx to eax
  3.  
  4. asm ASMString$
  5.  
  6.  
  7.  
  8.  SUB asm (Str$)

Unseen

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: ASM - Can someone make this work?
« Reply #1 on: June 22, 2020, 07:15:34 am »
I'm kind of thinking that it won't work due to the nature of QB64's translation into C. asm looks for a literal string immediately after the parentheses. In the translation, you get this:
Quote
In file included from qbx.cpp:2208:
..\\temp\\main.txt: In function 'void QBMAIN(void*)':
..\\temp\\main.txt:7:5: error: expected string-literal before '(' token
 asm((char*)(__STRING_ASMSTRING)->chr);
     ^
compilation terminated due to -Wfatal-errors.
It is looking for a literal string, terminated in quotes, not a variable (according to people on Stack Overflow). Even if we try with an actual string, terminated in quotes, we get this:
Quote
In file included from qbx.cpp:2208:
..\\temp\\main.txt: In function 'void QBMAIN(void*)':
..\\temp\\main.txt:7:5: error: expected string-literal before '(' token
 asm((char*)(qbs_add(qbs_add(func_chr( 34 ),qbs_new_txt_len("movl, %ebx, %eax",16)),func_chr( 34 )))->chr);
     ^
compilation terminated due to -Wfatal-errors.
I don't see how we'd be able to use this function/sub in QB64 unless Dav, or SMcNeil have an idea.
« Last Edit: June 22, 2020, 07:16:55 am by SpriggsySpriggs »
Shuwatch!

Offline Unseen Machine

  • Forum Regular
  • Posts: 158
  • Make the game not the engine!
    • View Profile
Re: ASM - Can someone make this work?
« Reply #2 on: June 22, 2020, 07:53:19 am »
Quote
I'm kind of thinking that it won't work due to the nature of QB64's translation into C.
Thats exactly what i was thinking after i looked in to the compile logs like you have.

I think it might be possible with a wrapper that converts the qb64 string into a cstring....but im going out to fish on the canal so for now at least i can just say thanks for having a look.

Unseen

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: ASM - Can someone make this work?
« Reply #3 on: June 22, 2020, 10:06:52 am »
I wonder if in future builds of QB64 if they can maybe implement a change that will allow to run pure C code in QB64 with a block like :
$C
'insert C code here
$ENDC
Maybe then we could use functions that would otherwise not work. Similar to how you are using Assembly in your C.
Shuwatch!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: ASM - Can someone make this work?
« Reply #4 on: June 22, 2020, 10:21:45 am »
But you can run C code in QB64 now. Just add an H file and call it as a CUSTOMTYPE library. However, this applies to simple programs, when another library is attached to the C code, there is a bug that sometimes stops compilation. An example of how C is called and how the output is returned is here, to get filenames and directories. I think, the Assembler cooperation could be done in a similar way.
https://www.qb64.org/forum/index.php?topic=1712.msg109492#msg109492

In the same way, Ashish and me calling quadrics in OpenGL, which are not directly supported in QB64.
« Last Edit: June 22, 2020, 10:26:17 am by Petr »

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: ASM - Can someone make this work?
« Reply #5 on: June 22, 2020, 10:37:23 am »
I think it might be possible with a wrapper that converts the qb64 string into a cstring
Now that I think about it, RhoSigma made a library that can be found here:https://www.qb64.org/forum/index.php?topic=809.0

In his QB64Library folder he has INCLUDEs for converting to a C String in the QB-StdLibs folder. I don't know if it is a true C string but it might be worth checking out.
Shuwatch!

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: ASM - Can someone make this work?
« Reply #6 on: June 22, 2020, 07:57:51 pm »
hi guys
but if do you like to play with ASM (MASM/TASM?) I think you must follow the QB style like showed by TheBob in his programs
Code: QB64: [Select]
  1. 'Create and load MouseDATA$ for CALL ABSOLUTE routines
  2. Cheddar:
  3. DATA 55,89,E5,8B,5E,0C,8B,07,50,8B,5E,0A,8B,07,50,8B,5E,08,8B
  4. DATA 0F,8B,5E,06,8B,17,5B,58,1E,07,CD,33,53,8B,5E,0C,89,07,58
  5. DATA 8B,5E,0A,89,07,8B,5E,08,89,0F,8B,5E,06,89,17,5D,CA,08,00
  6. MouseDATA$ = SPACE$(57)
  7. RESTORE Cheddar
  8. FOR i = 1 TO 57
  9.     READ h$
  10.     Hexxer$ = CHR$(VAL("&H" + h$))
  11.     MID$(MouseDATA$, i, 1) = Hexxer$
  12.  
  13. Moused = InitMOUSE
  14.  
  15. SUB MouseDRIVER (LB, RB, MX, MY)
  16.  
  17.     DEF SEG = VARSEG(MouseDATA$)
  18.     mouse = SADD(MouseDATA$)
  19.     CALL ABSOLUTE(LB, RB, MX, MY, mouse)
  20.  
  21.  
  22. SUB MouseSTATUS (LB, RB, MouseX, MouseY)
  23.  
  24.     LB = 3
  25.     MouseDRIVER LB, RB, MX, MY
  26.     LB = ((RB AND 1) <> 0)
  27.     RB = ((RB AND 2) <> 0)
  28.     MouseX = MX
  29.     MouseY = MY
  30.  
  31. SUB ClearMOUSE
  32.  
  33.     WHILE LB OR RB
  34.         MouseSTATUS LB, RB, MouseX, MouseY
  35.     WEND
  36.  

Code: QB64: [Select]
  1. SetPALETTE:
  2. DATA 20,0,24,0,0,42,0,0,45,10,0,50
  3. DATA 55,0,0,50,0,0,40,0,0,42,42,42
  4. DATA 30,0,0,20,10,55,25,5,29,40,30,63
  5. DATA 45,0,0,63,0,0,60,45,20,63,63,63
  6. RESTORE SetPALETTE
  7. OUT &H3C8, 0
  8. FOR n = 1 TO 48
  9.     READ Intensity
  10.     OUT &H3C9, Intensity
or in cabsmous.bas that you find in the example of QB64 package
Code: QB64: [Select]
  1. 'Mouse utilities for text mode. Written by TFM 9/11/94
  2. 'Uses INT 33 to use a Microsoft Compatable mouse driver
  3. 'Written in basic calling an assembly language routine.
  4. 'Works in normal basic
  5.  
  6. DECLARE FUNCTION inbox! (boxx1!, boxx2!, boxy1!, boxy2!)            'if pointer is in box return 1 else return 0
  7. DECLARE FUNCTION inboxpress1! (boxx1!, boxx2!, boxy1!, boxy2!)      'if last press was in box return 1 else return 0
  8. DECLARE FUNCTION inboxpress2! (boxx1!, boxx2!, boxy1!, boxy2!)      'if last press was in box return 1 else return 0
  9. DECLARE FUNCTION inboxrelease1! (boxx1!, boxx2!, boxy1!, boxy2!)    'if last release was in box return 1 else return 0
  10. DECLARE FUNCTION inboxrelease2! (boxx1!, boxx2!, boxy1!, boxy2!)    'if last release was in box return 1 else return 0
  11. DECLARE SUB releasemouse (button!)               'mouse x & y = last place botton 1 pressed
  12. DECLARE SUB pressmouse (button!)                 'mouse x & y = last place botton 1 released
  13. DECLARE SUB hidemouse ()                         'hide mose
  14. DECLARE SUB mouseinterupt (ax!, bx!, cx!, dx!)   'int 33 with register values
  15. DECLARE SUB initmouse ()                         'sets up mouse & if found mouse passed = 1
  16. DECLARE SUB showmouse ()                         'show the mouse
  17. DECLARE SUB getxymouse ()                        'get position of mouse in mouse x & y and mouse buttons in mousebutton 1 & 2
  18. DECLARE SUB verticalmouse (miny!, maxy!)         'Set vertical mouse limmits
  19. DECLARE SUB horizontalmouse (miny!, maxy!)       'Set horizontal mouse limmits
  20.  
  21. DIM SHARED mousebutton1 AS INTEGER
  22. DIM SHARED mousebutton2 AS INTEGER
  23. DIM SHARED mousevisible AS INTEGER
  24. DIM SHARED mousepassed AS INTEGER
  25.  
  26.  
  27. CALL initmouse
  28. CALL showmouse
  29. CALL horizontalmouse(10, 70) 'Set mouse position (min and max)
  30. CALL verticalmouse(10, 15) 'Set mouse position
  31.  
  32.     CALL pressmouse(1) 'Wait for button 1 to be pressed
  33.  
  34.     CALL getxymouse 'Store current positon in globals
  35.     'This isn't needed coz pressmouse(1)
  36.     'Already does it, but it is an example
  37.    
  38.     'Display position, stored in global variables
  39.     LOCATE 24, 1
  40.     PRINT "X - "; mousex, "  Y - "; mousey, "  Button1 - "; mousebutton1; "     Button2 - "; mousebutton2;
  41.    
  42.     IF inboxpress1(10, 70, 10, 12) THEN
  43.         LOCATE 24, 70
  44.         PRINT "*";
  45.     ELSE
  46.         LOCATE 24, 70
  47.         PRINT " ";
  48.     END IF
  49.     IF mousebutton1 = 1 THEN CALL hidemouse
  50.     IF mousebutton2 = 1 THEN CALL showmouse
  51.  
  52. SUB getxymouse
  53.  
  54.  
  55.     IF mousepassed = 1 THEN
  56.    
  57.         CALL mouseinterupt(&H3, 0, 0, 0)
  58.  
  59.         mousex = (cx / 8) + 1
  60.         mousey = (dx / 8) + 1
  61.         button = bx
  62.  
  63.  
  64.         IF button = 0 THEN
  65.             mousebutton1 = 0: mousebutton2 = 0
  66.         ELSEIF button = 1 THEN
  67.             mousebutton1 = 1: mousebutton2 = 0
  68.         ELSEIF button = 2 THEN
  69.             mousebutton1 = 0: mousebutton2 = 1
  70.         ELSEIF button = 3 THEN
  71.             mousebutton1 = 1: mousebutton2 = 1
  72.         END IF
  73.  
  74.         DEF SEG
  75.  
  76.  
  77.         LOCATE 24, 1
  78.         PRINT "X - "; mousex, "  Y - "; mousey, "  Button1 - "; mousebutton1; "     Button2 - "; mousebutton2;
  79.     ELSE
  80.         LOCATE 24, 1
  81.         PRINT "Sorry no mouse found"
  82.     END IF
  83.  
  84. SUB hidemouse
  85.  
  86.     IF mousepassed = 1 THEN
  87.         IF mousevisible = 1 THEN
  88.             CALL mouseinterupt(2, 0, 0, 0)
  89.             mousevisible = 0
  90.         END IF
  91.     ELSE
  92.         LOCATE 24, 1
  93.         PRINT "Sorry no mouse found"
  94.     END IF
  95.  
  96.  
  97. SUB horizontalmouse (minx, maxx)
  98.  
  99.     IF mousepassed = 1 THEN
  100.         IF minx < 0 THEN maxx = 0
  101.         IF maxx > 80 THEN maxx = 80
  102.         IF maxx < minx THEN maxx = minx
  103.         CALL mouseinterupt(7, 0, (minx - 1) * 8, (maxx - 1) * 8)
  104.     ELSE
  105.         LOCATE 24, 1
  106.         PRINT "Sorry no mouse found"
  107.     END IF
  108.  
  109.  
  110. FUNCTION inbox (boxx1, boxx2, boxy1, boxy2)
  111.  
  112.     IF mousepassed = 1 THEN
  113.         CALL getxymouse
  114.         IF mousex <= boxx2 AND mousex >= boxx1 AND mousey <= boxy2 AND mousey >= boxy1 THEN
  115.             inbox = 1
  116.         ELSE
  117.             inbox = 0
  118.         END IF
  119.     ELSE
  120.         LOCATE 24, 1
  121.         PRINT "Sorry no mouse found"
  122.     END IF
  123.  
  124.  
  125.  
  126. FUNCTION inboxpress1 (boxx1, boxx2, boxy1, boxy2)
  127.  
  128.     IF mousepassed = 1 THEN
  129.         CALL pressmouse(1)
  130.         IF mousex <= boxx2 AND mousex >= boxx1 AND mousey <= boxy2 AND mousey >= boxy1 THEN
  131.             inboxpress1 = 1
  132.         ELSE
  133.             inboxpress1 = 0
  134.         END IF
  135.     ELSE
  136.         LOCATE 24, 1
  137.         PRINT "Sorry no mouse found"
  138.     END IF
  139.  
  140.  
  141. FUNCTION inboxpress2 (boxx1, boxx2, boxy1, boxy2)
  142.  
  143.     IF mousepassed = 1 THEN
  144.         CALL pressmouse(2)
  145.         IF mousex <= boxx2 AND mousex >= boxx1 AND mousey <= boxy2 AND mousey >= boxy1 THEN
  146.             inboxpress2 = 1
  147.         ELSE
  148.             inboxpress2 = 0
  149.         END IF
  150.     ELSE
  151.         LOCATE 24, 1
  152.         PRINT "Sorry no mouse found"
  153.     END IF
  154.  
  155.  
  156. FUNCTION inboxrelease1 (boxx1, boxx2, boxy1, boxy2)
  157.  
  158.     IF mousepassed = 1 THEN
  159.         CALL releasemouse(1)
  160.         IF mousex <= boxx2 AND mousex >= boxx1 AND mousey <= boxy2 AND mousey >= boxy1 THEN
  161.             inboxrelease1 = 1
  162.         ELSE
  163.             inboxrelease1 = 0
  164.         END IF
  165.     ELSE
  166.         LOCATE 24, 1
  167.         PRINT "Sorry no mouse found"
  168.     END IF
  169.  
  170.  
  171.  
  172. FUNCTION inboxrelease2 (boxx1, boxx2, boxy1, boxy2)
  173.  
  174.     IF mousepassed = 1 THEN
  175.         CALL releasemouse(2)
  176.         IF mousex <= boxx2 AND mousex >= boxx1 AND mousey <= boxy2 AND mousey >= boxy1 THEN
  177.             inboxrelease2 = 1
  178.         ELSE
  179.             inboxrelease2 = 0
  180.         END IF
  181.     ELSE
  182.         LOCATE 24, 1
  183.         PRINT "Sorry no mouse found"
  184.     END IF
  185.  
  186.  
  187.  
  188. SUB initmouse
  189.  
  190.  
  191.     CALL mouseinterupt(0, 0, 0, 0)
  192.  
  193.     IF ax = 2 THEN
  194.         mousepassed = 1
  195.     ELSE
  196.         mousepassed = 0
  197.     END IF
  198.  
  199.  
  200.  
  201. SUB mouseinterupt (m1, m2, m3, m4)
  202.  
  203.     n1 = 0: n2 = 0: n3 = 0: n4 = 0
  204.  
  205.     DO WHILE m1 > 255
  206.         m1 = m1 - 255
  207.         n1 = n1 + 1
  208.     LOOP
  209.     DO WHILE m2 > 255
  210.         m2 = m2 - 255
  211.         n2 = n2 + 1
  212.     LOOP
  213.     DO WHILE m3 > 255
  214.         m3 = m3 - 255
  215.         n3 = n3 + 1
  216.     LOOP
  217.     DO WHILE m4 > 255
  218.         m4 = m4 - 255
  219.         n4 = n4 + 1
  220.     LOOP
  221.  
  222.     DIM b%(47)
  223.     DEF SEG = VARSEG(b%(0))
  224.  
  225.     POKE VARPTR(b%(0)) + 0, &H50 'push AX
  226.     POKE VARPTR(b%(0)) + 1, &H53 'push BX
  227.     POKE VARPTR(b%(0)) + 2, &H51 'push CX
  228.     POKE VARPTR(b%(0)) + 3, &H52 'push DX
  229.     POKE VARPTR(b%(0)) + 4, &H1E 'push DS
  230.  
  231.     POKE VARPTR(b%(0)) + 5, &HB8
  232.     POKE VARPTR(b%(0)) + 6, m1 'set AX
  233.     POKE VARPTR(b%(0)) + 7, n1
  234.    
  235.     POKE VARPTR(b%(0)) + 8, &HBB
  236.     POKE VARPTR(b%(0)) + 9, m2 'set BX
  237.     POKE VARPTR(b%(0)) + 10, n2
  238.  
  239.     POKE VARPTR(b%(0)) + 11, &HB9
  240.     POKE VARPTR(b%(0)) + 12, m3 'set CX
  241.     POKE VARPTR(b%(0)) + 13, n3
  242.  
  243.     POKE VARPTR(b%(0)) + 14, &HBA
  244.     POKE VARPTR(b%(0)) + 15, m4 'set DX
  245.     POKE VARPTR(b%(0)) + 16, n4
  246.    
  247.     POKE VARPTR(b%(0)) + 17, &HCD 'INT 33
  248.     POKE VARPTR(b%(0)) + 18, &H33
  249.    
  250.     POKE VARPTR(b%(0)) + 19, &H50 'push AX
  251.  
  252.     POKE VARPTR(b%(0)) + 20, &HB8 'AX = B800
  253.     POKE VARPTR(b%(0)) + 21, &H0
  254.     POKE VARPTR(b%(0)) + 22, &HB8
  255.  
  256.     POKE VARPTR(b%(0)) + 23, &H8E 'DS = AX
  257.     POKE VARPTR(b%(0)) + 24, &HD8
  258.          
  259.     POKE VARPTR(b%(0)) + 25, &H58 'pop AX
  260.    
  261.     POKE VARPTR(b%(0)) + 26, &H89
  262.     POKE VARPTR(b%(0)) + 27, &H1E '[0001] = AX
  263.     POKE VARPTR(b%(0)) + 28, &HA1
  264.     POKE VARPTR(b%(0)) + 29, &HF
  265.    
  266.     POKE VARPTR(b%(0)) + 30, &H89
  267.     POKE VARPTR(b%(0)) + 31, &H1E '[0003] = BX
  268.    
  269.     POKE VARPTR(b%(0)) + 32, &HA3
  270.     POKE VARPTR(b%(0)) + 33, &HF
  271.  
  272.     POKE VARPTR(b%(0)) + 34, &H89
  273.     POKE VARPTR(b%(0)) + 35, &HE '[0005] = CX
  274.     POKE VARPTR(b%(0)) + 36, &HA5
  275.     POKE VARPTR(b%(0)) + 37, &HF
  276.  
  277.     POKE VARPTR(b%(0)) + 38, &H89
  278.     POKE VARPTR(b%(0)) + 39, &H16 '[0007] = DX
  279.     POKE VARPTR(b%(0)) + 40, &HA7
  280.     POKE VARPTR(b%(0)) + 41, &HF
  281.  
  282.  
  283.     POKE VARPTR(b%(0)) + 42, &H1F 'pop DS
  284.     POKE VARPTR(b%(0)) + 43, &H5A 'pop DX
  285.     POKE VARPTR(b%(0)) + 44, &H59 'pop CX
  286.     POKE VARPTR(b%(0)) + 45, &H5B 'pop BX
  287.     POKE VARPTR(b%(0)) + 46, &H58 'pop AX
  288.  
  289.     POKE VARPTR(b%(0)) + 47, &HCB 'RETF
  290.  
  291.  
  292.     CALL ABSOLUTE(VARPTR(b%(0)))
  293.  
  294.     DEF SEG = &HB800
  295.     ax = PEEK(&HFA1) + 256 * PEEK(&HFA2)
  296.     bx = PEEK(&HFA3) + 256 * PEEK(&HFA4)
  297.     cx = PEEK(&HFA5) + 256 * PEEK(&HFA6)
  298.     dx = PEEK(&HFA7) + 256 * PEEK(&HFA8)
  299.    
  300.  
  301.  
  302. SUB movemouse (newx, newy)
  303.  
  304.     IF mousepassed = 1 THEN
  305.         IF newx < 26 AND newx > 0 AND newy < 81 AND newy > 0 THEN
  306.             CALL mouseinterupt(4, 0, (newx - 1) * 8, (newy - 1) * 8)
  307.             mousex = newx
  308.             mousey = newy
  309.         ELSE
  310.             PRINT
  311.             PRINT "Illegal mouse position!!!";
  312.         END IF
  313.     ELSE
  314.         LOCATE 24, 1
  315.         PRINT "Sorry no mouse found"
  316.     END IF
  317.  
  318.  
  319. SUB pressmouse (button)
  320.  
  321.     IF mousepassed = 1 THEN
  322.         CALL mouseinterupt(5, button - 1, 0, 0)
  323.         mousex = (cx / 8) + 1
  324.         mousey = (dx / 8) + 1
  325.    
  326.  
  327.     ELSE
  328.         LOCATE 24, 1
  329.         PRINT "Sorry no mouse found"
  330.     END IF
  331.  
  332. SUB releasemouse (button)
  333.  
  334.     IF mousepassed = 1 THEN
  335.         CALL mouseinterupt(5, button - 1, 0, 0)
  336.         mousex = (cx / 8) + 1
  337.         mousey = (dx / 8) + 1
  338.     ELSE
  339.         LOCATE 24, 1
  340.         PRINT "Sorry no mouse found"
  341.     END IF
  342.  
  343.  
  344. SUB showmouse
  345.  
  346.     IF mousepassed = 1 THEN
  347.         IF mousevisible = 0 THEN
  348.             CALL mouseinterupt(1, 0, 0, 0)
  349.             mousevisible = 1
  350.         END IF
  351.     ELSE
  352.         LOCATE 24, 1
  353.         PRINT "Sorry no mouse found"
  354.     END IF
  355.  
  356.  
  357. SUB verticalmouse (miny, maxy)
  358.  
  359.     IF mousepassed = 1 THEN
  360.         IF miny < 0 THEN maxy = 0
  361.         IF maxy > 25 THEN maxy = 25
  362.         IF maxy < miny THEN maxy = miny
  363.         CALL mouseinterupt(8, 0, (miny - 1) * 8, (maxy - 1) * 8)
  364.     ELSE
  365.         LOCATE 24, 1
  366.         PRINT "Sorry no mouse found"
  367.     END IF
  368.  
  369.  
.

I'm just kidding. It is too easy in this way!

Just a curiosity: but  do you like the syntax check too for C/C++/ASM?
Programming isn't difficult, only it's  consuming time and coffee

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: ASM - Can someone make this work?
« Reply #7 on: June 22, 2020, 10:22:33 pm »
Nice collection of snippets, Tempo.  Let me comment on them:

hi guys
but if do you like to play with ASM (MASM/TASM?) I think you must follow the QB style like showed by TheBob in his programs
Code: QB64: [Select]
  1. 'Create and load MouseDATA$ for CALL ABSOLUTE routines
  2. Cheddar:
  3. DATA 55,89,E5,8B,5E,0C,8B,07,50,8B,5E,0A,8B,07,50,8B,5E,08,8B
  4. DATA 0F,8B,5E,06,8B,17,5B,58,1E,07,CD,33,53,8B,5E,0C,89,07,58
  5. DATA 8B,5E,0A,89,07,8B,5E,08,89,0F,8B,5E,06,89,17,5D,CA,08,00
  6. MouseDATA$ = SPACE$(57)
  7. RESTORE Cheddar
  8. FOR i = 1 TO 57
  9.     READ h$
  10.     Hexxer$ = CHR$(VAL("&H" + h$))
  11.     MID$(MouseDATA$, i, 1) = Hexxer$
  12.  
  13. Moused = InitMOUSE
  14.  
  15. SUB MouseDRIVER (LB, RB, MX, MY)
  16.  
  17.     DEF SEG = VARSEG(MouseDATA$)
  18.     mouse = SADD(MouseDATA$)
  19.     CALL ABSOLUTE(LB, RB, MX, MY, mouse)
  20.  
  21.  
  22. SUB MouseSTATUS (LB, RB, MouseX, MouseY)
  23.  
  24.     LB = 3
  25.     MouseDRIVER LB, RB, MX, MY
  26.     LB = ((RB AND 1) <> 0)
  27.     RB = ((RB AND 2) <> 0)
  28.     MouseX = MX
  29.     MouseY = MY
  30.  
  31. SUB ClearMOUSE
  32.  
  33.     WHILE LB OR RB
  34.         MouseSTATUS LB, RB, MouseX, MouseY
  35.     WEND
  36.  

Why in the world do people use DATA statements? Totally unnecessary and bloated, you can pack everything into nice LONGs.  Here is a efficiently written minimal mouse demo, look how simple and compact it is:
Code: [Select]
DEFINT A-Z
DECLARE SUB mouse (ax, mb, mx, my)

DIM SHARED m(7) AS LONG
m(0) = &H8BE58955
m(1) = &H48B0C76
m(2) = &H768B33CD
m(3) = &H8B1C890A
m(4) = &HC890876
m(5) = &H8906768B
m(6) = &H8CA5D14

SCREEN 12

mouse 0, mb, mx, my 'reset mouse driver
mouse 1, mb, mx, my 'show mouse cursor

DO
   'get mouse state
   mouse 3, mb, mx, my

   'print mouse coordinates
   LOCATE 1, 1: PRINT mb, mx, my
LOOP UNTIL INP(&H60) = 1
SYSTEM

SUB mouse (ax, mb, mx, my)
   DEF SEG = VARSEG(m(0))
   CALL absolute(ax, mb, mx, my, VARPTR(m(0)))
END SUB



Code: QB64: [Select]
  1. SetPALETTE:
  2. DATA 20,0,24,0,0,42,0,0,45,10,0,50
  3. DATA 55,0,0,50,0,0,40,0,0,42,42,42
  4. DATA 30,0,0,20,10,55,25,5,29,40,30,63
  5. DATA 45,0,0,63,0,0,60,45,20,63,63,63
  6. RESTORE SetPALETTE
  7. OUT &H3C8, 0
  8. FOR n = 1 TO 48
  9.     READ Intensity
  10.     OUT &H3C9, Intensity
This has little to do with assembly, this is the old VGA ports method of setting the palette.  Here is equivalent QB64 code:
Code: QB64: [Select]
  1. DATA 20,0,24,0,0,42,0,0,45,10,0,50
  2. DATA 55,0,0,50,0,0,40,0,0,42,42,42
  3. DATA 30,0,0,20,10,55,25,5,29,40,30,63
  4. DATA 45,0,0,63,0,0,60,45,20,63,63,63
  5.  
  6. FOR n = 0 TO 15
  7.     READ red%
  8.     READ green%
  9.     READ blue%
  10.         palette n, red% + (green% * 256) + (blue% * 65536)
  11.  


or in cabsmous.bas that you find in the example of QB64 package
Code: QB64: [Select]
  1. 'Mouse utilities for text mode. Written by TFM 9/11/94
  2. 'Uses INT 33 to use a Microsoft Compatable mouse driver
  3. 'Written in basic calling an assembly language routine.
  4. 'Works in normal basic
  5.  
  6. DECLARE FUNCTION inbox! (boxx1!, boxx2!, boxy1!, boxy2!)            'if pointer is in box return 1 else return 0
  7. DECLARE FUNCTION inboxpress1! (boxx1!, boxx2!, boxy1!, boxy2!)      'if last press was in box return 1 else return 0
  8. DECLARE FUNCTION inboxpress2! (boxx1!, boxx2!, boxy1!, boxy2!)      'if last press was in box return 1 else return 0
  9. DECLARE FUNCTION inboxrelease1! (boxx1!, boxx2!, boxy1!, boxy2!)    'if last release was in box return 1 else return 0
  10. DECLARE FUNCTION inboxrelease2! (boxx1!, boxx2!, boxy1!, boxy2!)    'if last release was in box return 1 else return 0
  11. DECLARE SUB releasemouse (button!)               'mouse x & y = last place botton 1 pressed
  12. DECLARE SUB pressmouse (button!)                 'mouse x & y = last place botton 1 released
  13. DECLARE SUB hidemouse ()                         'hide mose
  14. DECLARE SUB mouseinterupt (ax!, bx!, cx!, dx!)   'int 33 with register values
  15. DECLARE SUB initmouse ()                         'sets up mouse & if found mouse passed = 1
  16. DECLARE SUB showmouse ()                         'show the mouse
  17. DECLARE SUB getxymouse ()                        'get position of mouse in mouse x & y and mouse buttons in mousebutton 1 & 2
  18. DECLARE SUB verticalmouse (miny!, maxy!)         'Set vertical mouse limmits
  19. DECLARE SUB horizontalmouse (miny!, maxy!)       'Set horizontal mouse limmits
  20.  
  21. DIM SHARED mousebutton1 AS INTEGER
  22. DIM SHARED mousebutton2 AS INTEGER
  23. DIM SHARED mousevisible AS INTEGER
  24. DIM SHARED mousepassed AS INTEGER
  25.  
  26.  
  27. CALL initmouse
  28. CALL showmouse
  29. CALL horizontalmouse(10, 70) 'Set mouse position (min and max)
  30. CALL verticalmouse(10, 15) 'Set mouse position
  31.  
  32.     CALL pressmouse(1) 'Wait for button 1 to be pressed
  33.  
  34.     CALL getxymouse 'Store current positon in globals
  35.     'This isn't needed coz pressmouse(1)
  36.     'Already does it, but it is an example
  37.    
  38.     'Display position, stored in global variables
  39.     LOCATE 24, 1
  40.     PRINT "X - "; mousex, "  Y - "; mousey, "  Button1 - "; mousebutton1; "     Button2 - "; mousebutton2;
  41.    
  42.     IF inboxpress1(10, 70, 10, 12) THEN
  43.         LOCATE 24, 70
  44.         PRINT "*";
  45.     ELSE
  46.         LOCATE 24, 70
  47.         PRINT " ";
  48.     END IF
  49.     IF mousebutton1 = 1 THEN CALL hidemouse
  50.     IF mousebutton2 = 1 THEN CALL showmouse
  51.  
  52. SUB getxymouse
  53.  
  54.  
  55.     IF mousepassed = 1 THEN
  56.    
  57.         CALL mouseinterupt(&H3, 0, 0, 0)
  58.  
  59.         mousex = (cx / 8) + 1
  60.         mousey = (dx / 8) + 1
  61.         button = bx
  62.  
  63.  
  64.         IF button = 0 THEN
  65.             mousebutton1 = 0: mousebutton2 = 0
  66.         ELSEIF button = 1 THEN
  67.             mousebutton1 = 1: mousebutton2 = 0
  68.         ELSEIF button = 2 THEN
  69.             mousebutton1 = 0: mousebutton2 = 1
  70.         ELSEIF button = 3 THEN
  71.             mousebutton1 = 1: mousebutton2 = 1
  72.         END IF
  73.  
  74.         DEF SEG
  75.  
  76.  
  77.         LOCATE 24, 1
  78.         PRINT "X - "; mousex, "  Y - "; mousey, "  Button1 - "; mousebutton1; "     Button2 - "; mousebutton2;
  79.     ELSE
  80.         LOCATE 24, 1
  81.         PRINT "Sorry no mouse found"
  82.     END IF
  83.  
  84. SUB hidemouse
  85.  
  86.     IF mousepassed = 1 THEN
  87.         IF mousevisible = 1 THEN
  88.             CALL mouseinterupt(2, 0, 0, 0)
  89.             mousevisible = 0
  90.         END IF
  91.     ELSE
  92.         LOCATE 24, 1
  93.         PRINT "Sorry no mouse found"
  94.     END IF
  95.  
  96.  
  97. SUB horizontalmouse (minx, maxx)
  98.  
  99.     IF mousepassed = 1 THEN
  100.         IF minx < 0 THEN maxx = 0
  101.         IF maxx > 80 THEN maxx = 80
  102.         IF maxx < minx THEN maxx = minx
  103.         CALL mouseinterupt(7, 0, (minx - 1) * 8, (maxx - 1) * 8)
  104.     ELSE
  105.         LOCATE 24, 1
  106.         PRINT "Sorry no mouse found"
  107.     END IF
  108.  
  109.  
  110. FUNCTION inbox (boxx1, boxx2, boxy1, boxy2)
  111.  
  112.     IF mousepassed = 1 THEN
  113.         CALL getxymouse
  114.         IF mousex <= boxx2 AND mousex >= boxx1 AND mousey <= boxy2 AND mousey >= boxy1 THEN
  115.             inbox = 1
  116.         ELSE
  117.             inbox = 0
  118.         END IF
  119.     ELSE
  120.         LOCATE 24, 1
  121.         PRINT "Sorry no mouse found"
  122.     END IF
  123.  
  124.  
  125.  
  126. FUNCTION inboxpress1 (boxx1, boxx2, boxy1, boxy2)
  127.  
  128.     IF mousepassed = 1 THEN
  129.         CALL pressmouse(1)
  130.         IF mousex <= boxx2 AND mousex >= boxx1 AND mousey <= boxy2 AND mousey >= boxy1 THEN
  131.             inboxpress1 = 1
  132.         ELSE
  133.             inboxpress1 = 0
  134.         END IF
  135.     ELSE
  136.         LOCATE 24, 1
  137.         PRINT "Sorry no mouse found"
  138.     END IF
  139.  
  140.  
  141. FUNCTION inboxpress2 (boxx1, boxx2, boxy1, boxy2)
  142.  
  143.     IF mousepassed = 1 THEN
  144.         CALL pressmouse(2)
  145.         IF mousex <= boxx2 AND mousex >= boxx1 AND mousey <= boxy2 AND mousey >= boxy1 THEN
  146.             inboxpress2 = 1
  147.         ELSE
  148.             inboxpress2 = 0
  149.         END IF
  150.     ELSE
  151.         LOCATE 24, 1
  152.         PRINT "Sorry no mouse found"
  153.     END IF
  154.  
  155.  
  156. FUNCTION inboxrelease1 (boxx1, boxx2, boxy1, boxy2)
  157.  
  158.     IF mousepassed = 1 THEN
  159.         CALL releasemouse(1)
  160.         IF mousex <= boxx2 AND mousex >= boxx1 AND mousey <= boxy2 AND mousey >= boxy1 THEN
  161.             inboxrelease1 = 1
  162.         ELSE
  163.             inboxrelease1 = 0
  164.         END IF
  165.     ELSE
  166.         LOCATE 24, 1
  167.         PRINT "Sorry no mouse found"
  168.     END IF
  169.  
  170.  
  171.  
  172. FUNCTION inboxrelease2 (boxx1, boxx2, boxy1, boxy2)
  173.  
  174.     IF mousepassed = 1 THEN
  175.         CALL releasemouse(2)
  176.         IF mousex <= boxx2 AND mousex >= boxx1 AND mousey <= boxy2 AND mousey >= boxy1 THEN
  177.             inboxrelease2 = 1
  178.         ELSE
  179.             inboxrelease2 = 0
  180.         END IF
  181.     ELSE
  182.         LOCATE 24, 1
  183.         PRINT "Sorry no mouse found"
  184.     END IF
  185.  
  186.  
  187.  
  188. SUB initmouse
  189.  
  190.  
  191.     CALL mouseinterupt(0, 0, 0, 0)
  192.  
  193.     IF ax = 2 THEN
  194.         mousepassed = 1
  195.     ELSE
  196.         mousepassed = 0
  197.     END IF
  198.  
  199.  
  200.  
  201. SUB mouseinterupt (m1, m2, m3, m4)
  202.  
  203.     n1 = 0: n2 = 0: n3 = 0: n4 = 0
  204.  
  205.     DO WHILE m1 > 255
  206.         m1 = m1 - 255
  207.         n1 = n1 + 1
  208.     LOOP
  209.     DO WHILE m2 > 255
  210.         m2 = m2 - 255
  211.         n2 = n2 + 1
  212.     LOOP
  213.     DO WHILE m3 > 255
  214.         m3 = m3 - 255
  215.         n3 = n3 + 1
  216.     LOOP
  217.     DO WHILE m4 > 255
  218.         m4 = m4 - 255
  219.         n4 = n4 + 1
  220.     LOOP
  221.  
  222.     DIM b%(47)
  223.     DEF SEG = VARSEG(b%(0))
  224.  
  225.     POKE VARPTR(b%(0)) + 0, &H50 'push AX
  226.     POKE VARPTR(b%(0)) + 1, &H53 'push BX
  227.     POKE VARPTR(b%(0)) + 2, &H51 'push CX
  228.     POKE VARPTR(b%(0)) + 3, &H52 'push DX
  229.     POKE VARPTR(b%(0)) + 4, &H1E 'push DS
  230.  
  231.     POKE VARPTR(b%(0)) + 5, &HB8
  232.     POKE VARPTR(b%(0)) + 6, m1 'set AX
  233.     POKE VARPTR(b%(0)) + 7, n1
  234.    
  235.     POKE VARPTR(b%(0)) + 8, &HBB
  236.     POKE VARPTR(b%(0)) + 9, m2 'set BX
  237.     POKE VARPTR(b%(0)) + 10, n2
  238.  
  239.     POKE VARPTR(b%(0)) + 11, &HB9
  240.     POKE VARPTR(b%(0)) + 12, m3 'set CX
  241.     POKE VARPTR(b%(0)) + 13, n3
  242.  
  243.     POKE VARPTR(b%(0)) + 14, &HBA
  244.     POKE VARPTR(b%(0)) + 15, m4 'set DX
  245.     POKE VARPTR(b%(0)) + 16, n4
  246.    
  247.     POKE VARPTR(b%(0)) + 17, &HCD 'INT 33
  248.     POKE VARPTR(b%(0)) + 18, &H33
  249.    
  250.     POKE VARPTR(b%(0)) + 19, &H50 'push AX
  251.  
  252.     POKE VARPTR(b%(0)) + 20, &HB8 'AX = B800
  253.     POKE VARPTR(b%(0)) + 21, &H0
  254.     POKE VARPTR(b%(0)) + 22, &HB8
  255.  
  256.     POKE VARPTR(b%(0)) + 23, &H8E 'DS = AX
  257.     POKE VARPTR(b%(0)) + 24, &HD8
  258.          
  259.     POKE VARPTR(b%(0)) + 25, &H58 'pop AX
  260.    
  261.     POKE VARPTR(b%(0)) + 26, &H89
  262.     POKE VARPTR(b%(0)) + 27, &H1E '[0001] = AX
  263.     POKE VARPTR(b%(0)) + 28, &HA1
  264.     POKE VARPTR(b%(0)) + 29, &HF
  265.    
  266.     POKE VARPTR(b%(0)) + 30, &H89
  267.     POKE VARPTR(b%(0)) + 31, &H1E '[0003] = BX
  268.    
  269.     POKE VARPTR(b%(0)) + 32, &HA3
  270.     POKE VARPTR(b%(0)) + 33, &HF
  271.  
  272.     POKE VARPTR(b%(0)) + 34, &H89
  273.     POKE VARPTR(b%(0)) + 35, &HE '[0005] = CX
  274.     POKE VARPTR(b%(0)) + 36, &HA5
  275.     POKE VARPTR(b%(0)) + 37, &HF
  276.  
  277.     POKE VARPTR(b%(0)) + 38, &H89
  278.     POKE VARPTR(b%(0)) + 39, &H16 '[0007] = DX
  279.     POKE VARPTR(b%(0)) + 40, &HA7
  280.     POKE VARPTR(b%(0)) + 41, &HF
  281.  
  282.  
  283.     POKE VARPTR(b%(0)) + 42, &H1F 'pop DS
  284.     POKE VARPTR(b%(0)) + 43, &H5A 'pop DX
  285.     POKE VARPTR(b%(0)) + 44, &H59 'pop CX
  286.     POKE VARPTR(b%(0)) + 45, &H5B 'pop BX
  287.     POKE VARPTR(b%(0)) + 46, &H58 'pop AX
  288.  
  289.     POKE VARPTR(b%(0)) + 47, &HCB 'RETF
  290.  
  291.  
  292.     CALL ABSOLUTE(VARPTR(b%(0)))
  293.  
  294.     DEF SEG = &HB800
  295.     ax = PEEK(&HFA1) + 256 * PEEK(&HFA2)
  296.     bx = PEEK(&HFA3) + 256 * PEEK(&HFA4)
  297.     cx = PEEK(&HFA5) + 256 * PEEK(&HFA6)
  298.     dx = PEEK(&HFA7) + 256 * PEEK(&HFA8)
  299.    
  300.  
  301.  
  302. SUB movemouse (newx, newy)
  303.  
  304.     IF mousepassed = 1 THEN
  305.         IF newx < 26 AND newx > 0 AND newy < 81 AND newy > 0 THEN
  306.             CALL mouseinterupt(4, 0, (newx - 1) * 8, (newy - 1) * 8)
  307.             mousex = newx
  308.             mousey = newy
  309.         ELSE
  310.             PRINT
  311.             PRINT "Illegal mouse position!!!";
  312.         END IF
  313.     ELSE
  314.         LOCATE 24, 1
  315.         PRINT "Sorry no mouse found"
  316.     END IF
  317.  
  318.  
  319. SUB pressmouse (button)
  320.  
  321.     IF mousepassed = 1 THEN
  322.         CALL mouseinterupt(5, button - 1, 0, 0)
  323.         mousex = (cx / 8) + 1
  324.         mousey = (dx / 8) + 1
  325.    
  326.  
  327.     ELSE
  328.         LOCATE 24, 1
  329.         PRINT "Sorry no mouse found"
  330.     END IF
  331.  
  332. SUB releasemouse (button)
  333.  
  334.     IF mousepassed = 1 THEN
  335.         CALL mouseinterupt(5, button - 1, 0, 0)
  336.         mousex = (cx / 8) + 1
  337.         mousey = (dx / 8) + 1
  338.     ELSE
  339.         LOCATE 24, 1
  340.         PRINT "Sorry no mouse found"
  341.     END IF
  342.  
  343.  
  344. SUB showmouse
  345.  
  346.     IF mousepassed = 1 THEN
  347.         IF mousevisible = 0 THEN
  348.             CALL mouseinterupt(1, 0, 0, 0)
  349.             mousevisible = 1
  350.         END IF
  351.     ELSE
  352.         LOCATE 24, 1
  353.         PRINT "Sorry no mouse found"
  354.     END IF
  355.  
  356.  
  357. SUB verticalmouse (miny, maxy)
  358.  
  359.     IF mousepassed = 1 THEN
  360.         IF miny < 0 THEN maxy = 0
  361.         IF maxy > 25 THEN maxy = 25
  362.         IF maxy < miny THEN maxy = miny
  363.         CALL mouseinterupt(8, 0, (miny - 1) * 8, (maxy - 1) * 8)
  364.     ELSE
  365.         LOCATE 24, 1
  366.         PRINT "Sorry no mouse found"
  367.     END IF
  368.  
  369.  
.
Here, instead of DATA statements they use POKE...VARPTR, so much text.  At least they used an integer array for storage

FellippeHeitor

  • Guest
Re: ASM - Can someone make this work?
« Reply #8 on: June 22, 2020, 10:25:06 pm »
I must add TheBOB's programs have all been recently adapted in the repository not to use CALL ABSOLUTE anymore - especially since that doesn't work in QB64.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: ASM - Can someone make this work?
« Reply #9 on: June 23, 2020, 04:18:31 am »
Hi

@FellippeHeitor
Yes it is known that the lowlevel calling (CALL ABSOLUTE/ CALL INTERRUPT/ CALL INTERRUPTX) used also in theBob's code aren't supported by QB64 but it is emulated only the INT33 for the 3 first services.
Moreover other low level work is emulated and deprecated to use in code (INP, OUT, PEEK, POKE, DEF SEG, VARPTR, VARPTR$, SADD). Analog discussion about IOCTL and IOCTL$.
That is a choice of Galleon and of the QB64 developers team!
The policy about the lowlevel work is forbidden in QB64 using the old ways.
Old ways that exhume 8-16 bit worlds are out!

But how can the QB64 coder access to the low level? 
The actual answer of QB64 developers team is
 1. QB64 is not a language to make low level work like build a driver, work on wire, access to port but if you need to do some work surely there is anywhere a library (often DLL or C/C++ library) that you can integrate into your work.
2. for efficient memory access it has been added _MEM
(... please all you that know more to add others ways available today.)


So is the request to open to ASM inline and C inline in the other thread  simply an attempt to have more control of machine towards low level coding ? Or also to implement some feature that is not developed into QB64 language and it is hard that QB64 developers team can support at time?

We can think that this kind of need is for expert programmers that must build something with QB64  but are valid C/C++ coders.  In this case is better to open to ASM and/or C/C++ inline or a more robust support of integration of external library made by the expert coder?
The third way is that defined by Galleon in that old post
Quote
My new philosophy is to let QB64 be what the community want it to be. Even if we end up with 1000s of commands that barely get used by the majority, it is better than QB64 not being used at all. And if someone implements something incredibly stupid/unnecessary (such as a _HELLOWORLD command) the beauty of a repository is that it can always be rolled back later. Because of this philosophy, you won't see me standing in the way of any changes.

but this third way brings to QB64 developers team a pletora of work more than that they already had.
Programming isn't difficult, only it's  consuming time and coffee

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: ASM - Can someone make this work?
« Reply #10 on: June 23, 2020, 04:55:34 am »
Hi
@_vince
Thanks to reply to my provocation to introduce an open discussion starting from a request

about your comment let me say that I love those!
I have tried to use your better code but QB64 refuses to run

  [ You are not allowed to view this attachment ]  
so nevertheless your good attempt we arrive at affirmation stated by Fellippe.
Quote
No more support for old ways to access to low level of machine, expecially if it exhumes 16 bit structures.

and so for expert coders that want to build something in QB64 and need something that is not yet implemented in QB64 what is the way to follow?
1. gain the ASM and/or C and/or C++ gateway
2. search/ build an external library (DLL o other .LIB) to integrate in its code
3. implement the feature needed into QB64 code to
      A) make a personal fork for his use
      B) post the news to QB64 developers team to integrate the news in the official version
Here my knowledge. Thanks to talk about this point of view.

Programming isn't difficult, only it's  consuming time and coffee

FellippeHeitor

  • Guest
Re: ASM - Can someone make this work?
« Reply #11 on: June 23, 2020, 08:58:42 am »
CALL INTERRUPT has some emulation. CALL ABSOLUTE doesn't.

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: ASM - Can someone make this work?
« Reply #12 on: June 23, 2020, 09:31:18 am »
Originally, QB64 had limited support for CALL ABSOLUTE because just so many programs used it and it was the only way to have a mouse in QBasic 1.1, the version that shipped with win95 and caused QBasic to explode in popularity.  CALL INTERRUPT was something that only worked with QB45+ and required starting QB with the /L switch, have the libraries, etc.  Support for ABSOLUTE seemed quite complicated because it had to emulate to some extent 16bit machine language and handle all the different ways people implement it and pass variables between it, etc.  I guess it is all lost with abandonment of the SDL version because no one will bother to port ABSOLUTE mice to GL.

FellippeHeitor

  • Guest
Re: ASM - Can someone make this work?
« Reply #13 on: June 23, 2020, 09:38:32 am »
Versions of QB64 prior to the conversion to OpenGL couldn't run code with ABSOLUTE either (at least not as far back as I went testing). @_vince do you happen to know with which version it compiled successfully? That can lead to it being brought back.

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Re: ASM - Can someone make this work?
« Reply #14 on: June 24, 2020, 10:05:10 pm »
gcc inline asm takes time to learn, I wrote 2 simple functions for 64-bit

cinclude.h
Code: [Select]
void myfun(double *x)
{
asm (
"fldpi \n"
"movq %[x], %%rax \n"
"fstpl (%%rax) \n"
:[x]"=m"(x)
:
:
);
}

double myfun2(void)
{
double x;
asm (
"fldpi \n"
"leaq %[x], %%rax \n"
"fstpl (%%rax) \n"
:[x]"=m"(x)
:
:
);
return x;
}

casm_test.bas
Code: [Select]
' cinclude.h needs to be in QB64 folder
DECLARE CUSTOMTYPE LIBRARY ".\cinclude"
    SUB myfun (x AS DOUBLE)
    FUNCTION myfun2# ()
END DECLARE

DIM x AS DOUBLE
DIM y AS DOUBLE
CALL myfun(y)
PRINT y
x = myfun2
PRINT x