The MASM Forum

Projects => MasmBasic & the RichMasm IDE => Topic started by: jj2007 on May 23, 2012, 10:16:07 PM

Title: MasmBasic
Post by: jj2007 on May 23, 2012, 10:16:07 PM
BASIC is the Best Approach to Simple and Intelligent Coding. MasmBasic is a library that allows to use BASIC syntax in assembler, i.e. it is not a "separate" language but rather a library of macros and routines, fully compatible with the latest Masm32 SDK (version 11) (http://masm32.com/), MASM (http://www.microsoft.com/downloads/en/details.aspx?familyid=7a1c9da0-0510-44a2-b042-7ef370530c64&displaylang=en) (version 6.15 or higher) and UAsm (http://www.terraspace.co.uk/uasm.html), and thoroughly tested on Windows XP, 7, 8 and 10.

While MasmBasic is pretty stable (and pretty fast - typically twice as fast as C), it is still Assembler, therefore the usual disclaimers apply - do not use for military purposes, in hospitals and anywhere else where buggy applications could cause damage. You have been warned :cool:

To install the library, double-click SetupMasmBasic.exe in the attached archive (see step-by-step instructions (https://www.jj2007.eu/Masm32_Tips_Tricks_and_Traps.htm)).
Note that some AntiVirus programmes don't like it - see Latest batch of unsound AV scanners (http://masm32.com/board/index.php?topic=10591.0) for reasons.

For an overview of the over 500 powerful available functions, see \Masm32\MasmBasic\MbGuide.rtf (after extracting the archive, of course) or see the (incomplete) MasmBasic Quick Reference (http://www.jj2007.eu/MasmBasicQuickReference.htm) online. See also A guide to the RichMasm editor (http://masm32.com/board/index.php?topic=5314.0).

12 April 2024: Updated archive attached below, now with ultrafast HexVal(), OpenAdo, ZipFiles, Json$(), RichMasm support for the Masm64 SDK, SetWatch, StackWalk, StringBuild, FastMath, Say "Hello World", ArrayIndex(array, match), _Local x$="Hello World", better UTF-8 support (http://masm32.com/board/index.php?topic=6231.msg72181#msg72181), MemState for finding leaks, MapView control (http://masm32.com/board/index.php?topic=6631.msg71093#msg71093), Math symbols in RichMasm, PrintRtf, dual 32/64-bit examples in File/New Masm source menu, and a 64-bit version of the deb macro (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1019). Older changes: For_ each x$ in My$(), improved Switch_ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1285); GetFiles (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1056) returns UTF8 now; WebCam, GetProcessArray(), new GSL lib, Choose, fast MemSet, Instr_() and Sinus() added, GuiTextBox improved. Data and Read , float counters are valid in For_ ... Next, and xmm regs are preserved for all MasmBasic commands. Note that simple Windows API calls can trash them on 64-bit versions of Windows.
Latest additions: GuiXX functions, Split$, Join$, Filter$, commandline to Files$(), GfCallback, true Unicode, also in file I/O; UnzipFile, ArraySet, SetReg64 for 64-bit registry settings, ArrayMerge, Age(), GetRegArrays, unsigned LONGLONG in Str$(), ShEx, xls interface (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1085), ArraySet (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1128), ArrayPlot (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1182), AddWin$, WritePipe, Plugins, IsFolder(), wOpen, FileOpen$ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1031)/FileSave$, also as Unicode versions, Extract$, Dialogs (http://masm32.com/board/index.php?topic=697.0), COM support (CoInvoke, GuidsEqual(), IUnknown, VARIANT, ...), improved ANSI and Unicode commandline macros CL$()/wCL$(), improved xHelp (http://masm32.com/board/index.php?topic=463.msg4190#msg4190), Launch$(), Try/Catch/Finally, ...

Installation hints for Windows 8 ... 10 (on Win7 & XP it's simpler):
- click on SetupMasmBasicDayMonthYear.zip below
- depending on your browser and zip application, choose open in xyZip or Save as...
- if it doesn't open in 7-zip or WinZip or whatever, locate the zip file and open it
- once you see SetupMasmBasic.exe, open it (double-click or select and Enter)
- you should see an extraction dialog, and shortly after a box "Windows Protected Your PC - Windows SmartScreen prevented..."
- do NOT click OK; instead, click on the tiny green link "More info"
- you will see Program SetupMasmBasic.exe and "unknown publisher"; click "Run Anyway"
- the screen will darken, and you see a box "Do you want to allow .. changes to your computer?"
- click Yes
- you should see now a big box "MasmBasic - a fast library..." with a EULA; read it, then click "Accept & Install"

** if anything goes wrong, have a look at our AV Software sh*t list subforum (http://masm32.com/board/index.php?board=23.0), then disable your antivirus for the \Masm32 folder and try again; if that doesn't help, reply to this thread **
Title: Extras
Post by: jj2007 on May 23, 2012, 10:17:30 PM
Various extras, JBasic for dual 64-/32-bit assembly (https://masm32.com/board/index.php?topic=9266.0)

The attached JBasic (SetupJBasic*.zip) builds on your existing Masm32 and MasmBasic installation. Just run the JBasic*.exe installer.



-------- Maps in MasmBasic: --------
In the RichMasm editor, click on File/New Masm source to see a green box with code templates.
Two of them called Gdi+ and maps (in the middle to the right) require a map of Europe. Extract the two files in the attachment to \Masm32\MasmBasic\Res\europe.* to make these templates work.
Title: New MasmBasic version
Post by: jj2007 on July 29, 2012, 09:12:15 AM
(http://www.webalice.it/jj2006/pics/MbSnippets.png)

This snippet (a full-fledged Windows console application  :biggrin:) produces the following output:
Введите строку, которую вы хотите найти в папке \Masm32\Include: bitmap
#1      \Masm32\Examples\advanced\wrep\result.asm
#2      LOCAL tbab   :TBADDBITMAP
#3      \Masm32\Examples\advanced\wrep\richedit.asm
#4      LOCAL tbab   :TBADDBITMAP
#5      \Masm32\Examples\Bill_Cravener\calender\calendar.asm
...
#96     \Masm32\Examples\exampl02\appack\toolbar.asm
#97     LOCAL tbab  :TBADDBITMAP
#98     ; The toolbar bitmap
#99     ; You must supply a bitmap for the toolbar that ha
#100    \Masm32\Examples\exampl02\appack\rsrc.rc
ok


As the example shows,
    1. MasmBasic is not BASIC: No BASIC dialect understands mov ebx, 400
    2. MasmBasic is assembly, i.e. it will flawlessly assemble with Microsoft Macro Assembler (MASM, version 6.15 upwards) or, better, with Jwasm (http://www.japheth.de/JWasm.html)

Here is a more complex application. It opens Windows.inc, converts all hexadecimal equates into decimal ones, and writes it back to disk:

include \masm32\MasmBasic\MasmBasic.inc

Init
call Convert
Exit

Convert proc
LOCAL pos, posAfter, MyTimer, MyCounter
  and MyCounter, 0
  mov MyTimer, Timer
  Recall "\Masm32\include\Windows.inc", L$() ; load an array of strings from file
  mov ebx, eax
  For_ n=0 To ebx-1
mov pos, Instr_(1, L$(n), "equ", 5) ; start in pos 1, 1=case-insensitive + 4=full word
.if pos
mov esi, Val(Mid$(L$(n), pos+3, 99)) ; get the numeric value of the string behind equ
.if signed edx<0 ; edx returns the number of usable chars; a
neg edx ; negative number indicates a hex$ or bin$ was found
add edx, pos
add edx, 3
mov posAfter, edx
inc MyCounter
Let L$(n)=Left$(L$(n), pos-1)+"EQU "+Str$(esi)+Mid$(L$(n), posAfter)
.endif
.endif
  Next
  Store "MyWindows.inc", L$() ; write all strings back to file
  sub MyTimer, Timer
  Print Str$("\nConverting %i hex equates in Windows.inc to decimals", MyCounter), Str$(" took %i ms\n", 0-MyTimer)
  ret
Convert endp

end start


Output:
Converting 7676 hex equates in Windows.inc to decimals took 31 ms

MasmBasic comes with RichMasm (http://www.masmforum.com/board/index.php?topic=9044.0). The editor is configured to give context-sensitive help with the F1 key, and to expand many instructions. For example,
opo [space] will expand to Open "O", #1,
mb becomes MsgBox 0, "¨", "Hi", MB_OK
for_ becomes For_ n=0 To ebx-1 ... Next
ism becomes invoke SendMessage,
etc.; more in \masm32\MasmBasic\MbGuide.rtf (in RichMasm:  File/MasmBasic Guide)

Last but not least an ultra-short Win32 application  ;)

include \masm32\MasmBasic\MasmBasic.inc
Init
Credits
Exit
end start


Let me know who is missing  :biggrin:

I wrote this library for my own use and pleasure, but since many forum members contributed to it, through good advice and even better algos, I think it is just fair to release it here. Thanks to everybody :icon14:

For the xHelp project, I had to add a few functions - sorry if you tried to assemble xHelp.asc with the June version. Among others, these features have been included:

Launch$
   Init
   ; the line below launches Arc.exe with option v and returns what SdtOut produces:
   Let esi=Launch$(ExpandEnv$(Chr$(34, "%ProgramFiles%\FreeArc\bin\Arc.exe", 34, " v Lib32.arc")))   ; see FreeArc (http://freearc.org/download/testing/FreeArc-0.67-alpha-sources.tar.bz2)
   StringToArray esi, FreeArc$()   ; translate linear output to an array
   For_ ebx=0 To eax-1
      PrintLine Str$(ebx), Tb$, FreeArc$(ebx)
   Next
Rem   args as in Launch above; returns string in eax

Output:
0       FreeArc 0.666 listing archive: Lib32.arc
1       Listing archive: Lib32.arc
2       Date/time              Attr     Size          Packed      CRC Filename
3       ----------------------------------------------------------------------
4       2000-06-02 16:24:14 .......     1364           10002 c2249beb Masm32\m32lib\a2dw.asm
5       2004-05-21 07:38:48 .......     3399               0 50c16759 Masm32\m32lib\a2dw_ex.asm
...
41      2003-12-06 08:43:10 .......     4843            1097 b83a653e Masm32\m32lib\ascdump.asm
42      ----------------------------------------------------------------------
43      38 files, 77,396 bytes, 11,099 compressed


ExeFromWin$
   Let esi="Recent Unread Topics"
   Print esi, " was launched by ", ExeFromWin$(WinByTitle(esi))   ; by firefox.exe, of course ;-)
Rem   returns full path of executable that created a window

SetGlobals   
; declares global variables relative to ebx, syntax as in LOCAL
.data?
   whatever   dd ?
   SetGlobals hMain, hStatic, hEdit
   SetGlobals hMenu, hM1, hM2, rc:RECT
   SetGlobals msg:MSG, wc:WNDCLASSEX, exeBuffer[MAX_PATH]:BYTE, gBuffer[1024]:BYTE
   .code
   ; no args: set ebx to the right offset; must be used in Init part and all callbacks (WndProc, SubEdit, ...)
   SetGlobals

Rem   variables return [ebx+x]

Enum      
; create a list of IDs
   Enum   IdMenuNew, IdMenuSave, IdMenuCopy, IdTimer
   Enum   20:IdEdit, IdButton1, 30:IdButton2, IdStatic, IdFind, IdFindStatic
Rem   - variables return [ebx+x]
   - default start is 10, but different start values can be specified
Title: OLE support in MasmBasic
Post by: jj2007 on September 14, 2012, 08:18:53 AM
Version 14 September features two new macros for use with COM, GuidFromString and GuidsEqual.
I hope the sample below is self-explanatory for the COM fans ;-)

.code
CLSID_WebBrowser   GuidFromString(8856F961-340A-11D0-A96B-00C04FD705A2)      ; ExDisp.h (http://%programfiles%\microsoft%20sdks\windows\v7.0a\include\exdisp.h)
IID_IWebBrowser2     GuidFromString(D30C1661-CDAF-11D0-8A3E-00C04FC9E26E)   ; OleIdl.h (http://%programfiles%\microsoft%20sdks\windows\v7.0a\include\oleidl.h)
IID_IUnknown      GuidFromString(00000000-0000-0000-C000-000000000046)
IID_IOleObject      GuidFromString(00000112-0000-0000-C000-000000000046)     ; MSDN (http://msdn.microsoft.com/en-us/library/windows/desktop/ms683922%28v=vs.85%29.aspx)
IID_IOleClientSite      GuidFromString(00000118-0000-0000-C000-000000000046)
IID_IOleWindow      GuidFromString(00000114-0000-0000-C000-000000000046)
IID_IOleInPlaceSite   GuidFromString(00000119-0000-0000-C000-000000000046)

MyQuery proc pRefID, pRet
  xor edx, edx
  .if GuidsEqual(pRefID, IID_IUnknown)
           mov edx, pWB2   ; return this
  .else
  .if GuidsEqual(pRefID, IID_IOleClientSite)
           mov edx, MyClientSite   ; return ptr to a handler
  .else
  .if GuidsEqual(pRefID, IID_IOleWindow)
           mov edx, MySite
  .else
  .if GuidsEqual(pRefID, IID_IOleInPlaceSite)
           mov edx, MySite
  .endif
  .endif
  .endif
  .endif
  mov eax, pRet
  mov [eax], edx   ; return result
  xor eax, eax      ; S_OK
  .if !edx
           mov eax, E_NOINTERFACE   ; flag failure
  .endif
  ret
MyQuery endp
Title: MasmBasic bug fix
Post by: jj2007 on September 19, 2012, 08:40:38 AM
Versions earlier than 19 Sept had a problem with Declare, it's fixed now:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masmforum.com/~masm32/board/index.php?topic=94)
      Init            ; initialise the app
      Dll "shimgvw"      ; load the shell image view dll aka Windows Picture and Fax Viewer Library
      Declare ImageView_Fullscreen, 4      ; ImageView_Fullscreen expects 4 dwords
      void ImageView_Fullscreen(0, 0, wCL$(1), SW_SHOW)   ; we need the wide version of the commandline arg
      Err$(0)         ; there is no retval, so we have to test for errors
      Exit         ; do a clean exit, inter alia FreeLibrary
end start

I seized the occasion to tune up the dialog examples. Here is a nice one:

include \masm32\MasmBasic\MasmBasic.inc   ; download (http://masm32.com/board/index.php?topic=94.0) (version 19 Sept 2012)
  Init
  Let ecx=NoTag$(FileRead$("http://masm32.com/why.htm"))   ; get some wise words from the World Wide Web
  DlgDefine "... but nothing beats Basic, hehe:", 0, 0, 325, 90
  DlgControl dcStatic, "\Masm32\examples\exampl04\car\car.jpg", SS_BITMAP, 80, 5   ; any Masm32 installation has this JPG
  DlgControl dcStatic, "\masm32\RichMasm\icons\Smiley.ico", SS_ICON, 30, 1   ; x, y [, width, height]
  Let ecx="... "+Mid$(ecx, Instr_(ecx, "and contrary"), 109)
  DlgControl dcStatic, wChr$(ecx), SS_LEFT, 5, 18, 70, 70      ; x, y, width, height
  DlgShow
  Exit
end start

Full source and exe attached ;)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on September 25, 2012, 08:01:44 AM
Extract$   extracts a substring based on left and right matches
   ; simple example:
   Let esi='This is a link to <a href="http://www.google.com">Google</a> that can be extracted'
   Print "The URL for ", Extract$(esi, Chr$(34, 62), "</a>"), " is "   ; 34, 62 = ">
   Inkey Extract$(esi, "http://", Chr$(34), xsIncL)         ; you could use '"' (single/double/single quote) instead of Chr$(34)
   ; result: The URL for Google is http://www.google.com

   ; syntax: Extract$(pSrc, "left match" [, "right match"] [, xsFlags] [, maxlines*)] [, startIndex])
   ; right match: if omitted, end of line is assumed
   ; xsFlags: if omitted, search for left match is case-sensitive, left and right matches are excluded
   ; maxlines: default is 1, i.e. right match must be in same line; for extracting structures etc, put a reasonable value, e.g. 100
   ; startIndex: default is 1, i.e. beginning of string; if xsLoop is set, search for the left match restarts where the last right match
   was found; see also the options for Instr_ - Extract$ uses Instr_ for the left match
   xsCaseI   ; case-insensitive search for left match (right: always case-sensitive)
   xsIs       ; intellisense; search is case-insensitive for 1st char only, i.e. Hello = hello
   xsI1c   ; ignore 1st char in left match, e.g. ?:\Masm32\...
   xsFullW   ; full word (left match only)
   xsIncL   ; include left pattern (e.g. http://)
   xsIncR   ; include right pattern
   xsExcL   ; exclude left pattern, e.g. {url= ... }
   xsExcR   ; exclude right pattern
   xsTrimL   ; trim left side, i.e. strip everything <=ASCII 39 aka single quote
   xsTrimR   ; trim right side (after excluding right match if xsExcL is set)
   xsTrim=xsTrimL or xsTrimR   ; trim both sides
   xsLineL   ; include line of the left match
   xsLineR   ; include rest of line after the right match (must include right match...)
   xsLoop   ; let Instr_ start behind the last position, for using in loops
    *) if the right pattern contains a linefeed (LF, Ascii 10), the maxlines counter will never stop the pattern search
   ----------------------------------------------------------
   The last flag, xsLoop, is used in the following demo, a Windows console application that extracts
   all structures from the two main Masm32 include files. Do not use the result for work, as there are
   problems with nested structures (e.g. unions ending with ends) and some structures ending with
   lowercase ends.
   
include \masm32\MasmBasic\MasmBasic.inc   ; download (http://masm32.com/board/index.php?topic=94.0)
   Init
   ; First, let's get some useful source string:
   Let ecx=FileRead$("\Masm32\include\Windows.inc")+FileRead$("\Masm32\include\WinExtra.inc")
   Open "O", #1, "Structures.txt"   ; open a file for output
   xor ebx, ebx   ; reset counter
   .While 1
      inc ebx
      .Break .if !Extract$(ecx, "STRUCT", 'ENDS', xsFullW or xsLineL or xsIncR or xsLoop, 100)
      Print #1, eax, CrLf$
   .Endw
   Close #1   ; file #1 closed
   Inkey Str$("%i structures found\n", ebx)
   Exit
end start

Rem   - Extract$ returns pointer in eax, and len of result in edx
   - can be used with Print and Let even if no match found, i.e. eax=0; in this case, Extract$ will print as ?
RichMasm Key   ex$
Title: MasmBasic & Unicode: wOpen added
Post by: jj2007 on October 04, 2012, 09:54:11 AM
As a complement to MasmBasic's new file dialog understanding Unicode file names,
I added the capacity to use these file names for opening files:

      wOpen "O", #1, wRes$(ResID)   ; file name from a resource string, e.g. Добро пожаловать.txu
... wPrint to this file ...

   .if wFileOpen$("Unicode text=*.txu")
      wPrint wCrLf$, "You selected ", wFileOpen$(), wCrLf$
      wOpen "I", #1, wFileOpen$()   ; use the filename
      lea ecx, [Lof(#1)-2]   ; required: length of file minus 2 bytes BOM
      Let esi=New$(ecx)   ; create a string with the required length
      Input #1, esi, 2   ; discard the Unicode BOM
      Input #1, esi, ecx   ; read rest of file into buffer
      Close
      wPrint "The content of the selected file: [", esi, "]", wCrLf$
      ; the console may have problems with Chinese etc, a MessageBox shouldn't:
      wMsgBox 0, esi, "The content of the selected file:"
   .endif


Version 4 October is available on top of this thread. Full example in \masm32\RichMasm\Res\SkelFileIO_Unicode.asc - open in RichMasm and hit F6.
Title: Ascii to byte/word/dword/sdword/qword/Real4/8/10 and xmm regs
Post by: jj2007 on October 14, 2012, 10:43:56 AM
Version 14 October 2012 has some improvements under the hood, inter alia regarding JWasm compatibility and handling of more data types for ebx-relative global variables. Here is an example, a more complete one will be in \masm32\RichMasm\SetGlobalsQword.asc after extracting the MasmBasic archive.

include \masm32\MasmBasic\MasmBasic.inc   ; download (http://masm32.com/board/index.php?topic=94.0)
   SetGlobals MyR4:REAL4, MyR8:REAL8, MyR10:REAL10, MyPoint:POINT, MyQ:QWORD
   SetGlobals MySD:SDWORD, MyD, MyW:WORD, MyB:BYTE, MyRect:RECT

   Init
   SetGlobals   ; short code through ebx-relative addressing
   MovVal MyB, "123"
   MovVal MyW, "12345"
   MovVal MySD, "-123456789"   ; signed dword
   MovVal MyD, "123456789"   ; both versions work
   mov MyD, Val("123456789")   ; Val is for DWORD destinations only
   MovVal MyR4, "12345.6789"
   MovVal MyR8, "123456789012345678"
   MovVal MyR10, "12345678901234567890"
   MovVal MyQ, "123456789012345678"
   MovVal xmm0, "123456789012345678"
   MovVal f:xmm1, "123456789012345678"

   MovVal MyPoint.y, "987654321"   ; structure elements
   mov MyPoint.x, Val("123456789")   ; Val is for DWORD destinations only
   MovVal  MyRect.left, "111111111"
   mov MyRect.bottom, Val("999999999")

   deb 4, "SetGlobals", MyB, MyW, MyD, MySD, MyQ, MyR4, MyR8, MyR10, xmm0, f:xmm1
   deb 4, "POINT & RECT", MyPoint.x, MyPoint.y, MyRect.left, MyRect.bottom
   Inkey
   Exit
end start



Output:
SetGlobals
MyB             123
MyW             12345
MyD             123456789
MySD            -123456789
MyQ             123456789012345678
MyR4            12345.68
MyR8            1.234567890123457e+17
MyR10           1.23456789012345679e+19
xmm0            123456789012345678
f:xmm1          1.234567890123457e+17

POINT & RECT
MyPoint.x       123456789
MyPoint.y       987654321
MyRect.left     111111111
MyRect.bottom   999999999
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on October 30, 2012, 10:28:00 AM
Update 30 October 2012 (attached to 1st post above):

- RichMasm editor has learned to warn the user when doing stupid things (http://masm32.com/board/index.php?topic=844.msg7270#msg7270)

- Launch$("proggie.exe") has been enhanced with ExitCode():

   Let My$=Launch$("GetInfo.exe")      ; imagine a little proggie that writes something useful to console ...
   mov eax, ExitCode()      ; ... and  finishes with a Yes/No/Cancel MsgBox plus invoke ExitProcess, eax
   .if eax==IDYES
      ... do something with My$ ...
   .endif
Rem   - returns a global variable containing the para passed with ExitProcess, i.e. the DOS-style errorlevel
   - for Launch "whatever", this value is also returned in edx
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: anta40 on November 04, 2012, 03:24:43 AM
Hi jj,

Does MB supports nested for loop?

Example:

include \masm32\MasmBasic\MasmBasic.inc

Init

For_ ebx=1 To 3
    For_ ecx=1 To (4-ebx)
        Print Str$(edx," ")
    Next
    Print CrLf$
Next

Exit

end start


I tried to assemble using jwasm and ML. Both failed.

jwasm
Quote
JWasm v2.09pre, Oct 29 2012, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.

forloop.asm(6) : Error A2227: Missing right parenthesis in expression
MbFor(46)[MasmBasic.inc]: Macro called from
  forloop.asm(6): Main line code
forloop.asm(6) : Error A2227: Missing right parenthesis in expression
MbFor(60)[MasmBasic.inc]: Macro called from
  forloop.asm(6): Main line code
forloop.asm(6) : Error A2209: Syntax error: )
MbFor(74)[MasmBasic.inc]: Macro called from
  forloop.asm(6): Main line code
invalid Str$
forloop.asm: 14 lines, 1 passes, 109 ms, 0 warnings, 3 errors

ML
Quote
Microsoft (R) Macro Assembler Version 11.00.50522.1
Copyright (C) Microsoft Corporation.  All rights reserved.

Assembling: forloop.asm
forloop.asm(6) : error A2006:undefined symbol : atVt
MbFor(49): Macro Called From
  forloop.asm(6): Main Line Code
invalid Str$
forloop.asm(7) : error A2207:missing right parenthesis in expression
MbFor(3): Macro Called From
  forloop.asm(6): Main Line Code
forloop.asm(7) : error A2207:missing right parenthesis in expression
MbFor(10): Macro Called From
  forloop.asm(6): Main Line Code
forloop.asm(7) : error A2208:missing left parenthesis in expression
MbFor(11): Macro Called From
  forloop.asm(6): Main Line Code
forloop.asm(7) : error A2052:forced error
Str$(3): Macro Called From
  Print(0): Macro Called From
   forloop.asm(7): Main Line Code
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on November 04, 2012, 04:03:49 AM
Quote from: anta40 on November 04, 2012, 03:24:43 AM
Hi jj,

Does MB supports nested for loop?

Example:

include \masm32\MasmBasic\MasmBasic.inc

Init

For_ ebx=1 To 3
    For_ ecx=1 To (4-ebx)
        Print Str$(edx," ")
    Next
    Print CrLf$
Next

Exit

end start


Hi Anta,

No brackets for 4-ebx, and Str$() has a different syntax (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1167):

   For_ ebx=1 To 3
      For_ ecx=1 To 4-ebx   
         Print Str$(ecx), " "
      Next
      Print CrLf$
   Next
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: anta40 on November 05, 2012, 01:42:39 AM
Ah, a small typo :redface:

Thanks jj, now it works as expected  :t
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on November 05, 2012, 10:23:52 AM
Great ;-)

Version 5 Nov 2012 is out:
- FileOpen$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1030)() keeps user's folder changes
- IsFolder() macro
- Dll & Declare speedup: see example here (http://masm32.com/board/index.php?topic=815.msg7655#msg7655)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: frktons on November 25, 2012, 03:21:08 AM
Hi jj.

MasmBasic is really a nice project. If I had enough knowledge I'd started
a similar project myself. Unfortunately I'm not able to do much with it for the time
being.

It remains, however, one of my goal to learn and use some MasmBasic as soon
as I've enough capacity to do it.

Carry on this optimal work.

Frank
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on December 03, 2012, 10:43:42 AM
Thanks a lot, Frank.

Version 3 December features an improved xHelp, now included in the MasmBasic package.
Inter alia, xHelp has learned how to add F1 context-sensitive help to qEditor. After extraction of the package (the archive in post #1 of this thread (http://masm32.com/board/index.php?topic=94.msg264#msg264)) with "use folder names", launch \Masm32\InstallXhelp.exe. Afterwards, you can select some text, e.g. CreateWindowEx in qEditor, and press F1. Compliments to Hutch who made such a great plugin interface for the Masm32 editor :t

And apologies that I stole the idea to create a plugin interface for RichMasm, too - PM me for details ;-)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: frktons on December 05, 2012, 01:25:15 AM
One lesson a day keeps the teacher away [somehow]  :lol:

The only thing I really miss for an extension of MASM32 like
MasmBasic is a tutorial to learn step by step the use of the
MACROS library and routines.

Probably some help can be found in the editor and in the
examples, but a Tutorial is always welcome.  :t
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on December 26, 2012, 10:00:02 AM
Changes in the update of 26.12.2012 (attached to first post, details in \Masm32\MasmBasic\MbGuide.rtf):

AddWin$
        AddWin$ hEdit=CrLf$+"[one line more]"        ; append some text to an edit control
        ; this line appends the current date and time to an edit control:
        AddWin$ hEdit=CrLf$+"["+Trim$(Launch$("cmd.exe /C date /T"))+", "+Trim$(Launch$("cmd.exe /C time /T"))+"]"

WritePipe
        Launch "cmd.exe /C time", SW_RESTORE, cb:hEdit        ; launch an app that requires console input; show its output in the edit control
        WritePipe "20:40:50"                        ; set the time
        ; you may add a 0 as second argument if you don't want a CrLf sequence to be appended:
        WritePipe esi, 0        ; write zero-delimited string in esi, do not append CrLf
Rem        will show an error message if the pipe was closed for some reason
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Gunther on January 03, 2013, 12:00:20 AM
Jochen,

it seems you've done a great effort for the new update. Did you burn the midnight oil?

Gunther
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on January 03, 2013, 02:23:28 AM
Quote from: Gunther on January 03, 2013, 12:00:20 AM
it seems you've done a great effort for the new update. Did you burn the midnight oil?

Yes I did, Gunther - but I just fixed a "midnight bug". Launch$() returns output from a console proggie, but it is not designed for proggies that expect input, and it choked badly when I tried. Version 2 Jan b behaves better, it just returns La$? to indicate an error.
----
Changes in the update of 2 Jan 2013 concern the handling of pipes in Launch (more in \masm32\MasmBasic\MbGuide.rtf):

        dec ready2load                ; set the "we launched a process" flag
        Launch esi, SW_MINIMIZE, cb:hOutput  ; cb: = we want to see the output

...

        CASE WM_TIMER
                .if ready2load        ; flag "we launched a process"
                        .if ExitCode()!=STILL_ACTIVE        ; process finished?
                                and ready2load, 0        ; clear the flag and
                                call LvGetFiles        ; load the processed files
                        .endif
                .endif


Basically, you can thus:
- launch an external preprocessor
- watch its output in an edit window
- and proceed once the external process is no longer STILL_ACTIVE.

It is now also possible to have a permanent pipe, e.g. with cmd.exe, and to retrieve output from other processes with Launch$() in parallel.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: anta40 on January 08, 2013, 02:10:34 PM
Hi jj,

This code compiles fine and works as expected (with the latest MasmBasic)

include \masm32\MasmBasic\MasmBasic.inc

.data?
aNumber dd ?

Init
MovVal aNumber,Input$("Input: ")
add aNumber, 123
Print "Result: ",Str$(aNumber)
Exit
end start


But if you shorten the input message like this:

include \masm32\MasmBasic\MasmBasic.inc

.data?
aNumber dd ?

Init
MovVal aNumber,Input$("N: ")
add aNumber, 123
Print "Result: ",Str$(aNumber)
Exit
end start


Then the result is compilation error

Quote
JWasm v2.10pre, Dec 30 2012, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.

input.asm(7) : Error A2172: Initializer magnitude too large:
repargA(55)[MasmBasic.inc]: Macro called from
  cStyle$(99)[MasmBasic.inc]: Macro called from
   Input$(3)[MasmBasic.inc]: Macro called from
    input.asm(7): Main line code
input.asm: 11 lines, 1 passes, 78 ms, 0 warnings, 1 errors

Is this a bug?
Title: Always trouble with four-letter words...
Post by: jj2007 on January 08, 2013, 05:41:01 PM
Quote from: anta40 on January 08, 2013, 02:10:34 PM
Is this a bug?

YES, fat and ugly (but harmless). Will be fixed asap, thanks for the feedback :t

The reason is that "abcd" is an immediate for the macro engine, not a string. For example, you can write mov eax, "abcd" or mov al, "x". But the macro can check for the <"> and then decide to treat it as a string. The bug didn't show up until now because all my test examples had more then four chars - and then JWasm & Ml are clever enough to realise "no, can't fit into 32 bits, so it must be a string". Cute, ain't it?  ;)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: anta40 on January 08, 2013, 06:05:52 PM
Ah I see.
Indeed it's not harmful, just a little annoying.
I was confused for a while why my code wouldn't compile, until somehow I reverted back the input message, and finally the assembler accepted it.

:P
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on January 08, 2013, 08:18:19 PM
Until the new version is ready, you can use Chr$() as a workaround:

; MovVal aNumber,Input$("nu: ", "1000")
MovVal aNumber, Input$(Chr$("nu: "), "1000")
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jeivarmarr on January 09, 2013, 07:03:34 AM
I have this problem  :(
Then the result is compilation error
MasmBasic.inc (5871): error A2102: Symbol not defined: CP_UTF8
MasmBasic.inc (6288): error A2102: Symbol not defined: OFN_ENABLESIZING
MasmBasic.inc (6289): error A2102: Symbol not defined: OFN_ENABLESIZING

some solution?
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on January 09, 2013, 08:41:34 AM
both symbols are defined in windows.inc

you are simply not including the proper include files
it is possible that you are trying to assemble a file on a different drive than the one where masm32 is installed
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on January 09, 2013, 08:46:14 AM
Dave is correct, they are defined in Windows.inc

How does your source start? There should be no problem if your first line is
include \masm32\MasmBasic\MasmBasic.inc

On top of MasmBasic.inc you find this:
IFNDEF _wininc_
   include   \masm32\include\masm32rt.inc
   .686   ; JWasm needs this
   .xmm
ENDIF


In other words, all standard includes are in anyway.
Title: MasmBasic - major update
Post by: jj2007 on March 02, 2013, 10:34:04 AM
With 145 downloads, the Jan 2 version got a bit stale, so I guess it's time for an update.

Many improvements "under the hood", but also some visible goodies; inter alia, all arrays (strings, byte/word/dword, REAL4/8/10, structures) can now be dynamically defined, e.g.

        Dim My$()
        Dim NormalDist() As DWORD
        Dim Sinus() As REAL8

Note though, that values can be assigned only incrementally, e.g.

        Dim My$()
        Let My$(99)="Hello"        ; illegal, will throw an error
        xor ecx, ecx
        .Repeat
                Let My$(ecx)=Str$("#%i", ecx)
                inc ecx
        .Until ecx>9999

The deb macro has learned to display flags (without changing them, of course):

        deb 4, "End of loop:", ecx, flags, FLAGS

flags displays carry, zero, sign and overflow, FLAGS the whole set:

End of loop:
ecx             10000
flags:          czso
FLAGS:          cpAzstIdo


c means carry clear, C carry set, etc.

Last but not least, attached a minimally modified \Masm32\examples\exampl01\generic\generic.asm:
1. Includes were replaced by the usual one-liner: include \masm32\MasmBasic\MasmBasic.inc
2. These few lines were added below "end menu commands":

    ;====== end menu commands ======

    .elseif uMsg == WM_CREATE
        ToolTips start        ; we'd like to see the country names
        ToolTips end

        Dim NormalDist() As DWORD        ; read the data of a normal distribution from file
        ArrayRead NormalDist(), "NormalDist.dat"

        ArrayLoadMap 0, "Europe"        ; load a map

        Dim Sinus() As REAL8        ; define an array for a sinus curve
        xor ecx, ecx
        push 180
        fild stack        ; stack is an equate for dword ptr [esp]
        push ecx
        fldpi
        fdivr
        fstp REAL4 PTR stack[4]
        .Repeat
                mov stack, ecx
                fild stack
                fmul REAL4 PTR stack[4]
                fsin
                fstp Sinus(ecx)
                inc ecx
        .Until ecx>500
        pop ecx
        pop eax

    .elseif uMsg == WM_MOUSEMOVE
                ArrayMapRegion(lParam, 0, hWnd)

    .elseif uMsg == WM_PAINT
        ArrayPlot hWnd, RgbCol(200, 255, 240)                ; init with window (or control) handle and background colour
        ArrayPlot 0, RgbCol(200, 200, 200), lines:2        ; plot map 0 as loaded above, with grey border and 2px lines
        ArrayPlot Sinus()        ; plot the sinus curve defined above
        ArrayPlot NormalDist()
        ; ------ here you could add additional features, e.g. a legend ------
        ArrayPlot exit, "Europe"        ; finish with a title

    .elseif uMsg == WM_CLOSE


The output? Check yourself :biggrin:

P.S.: With more recent MasmBasic versions, replace the start: label with Init, otherwise it will crash.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on March 02, 2013, 10:41:08 AM
so - what are we looking at, Jochen ???
is it, in any way, related to the pr0n ban in Iceland ?   :redface:
it seems not to have affected pr0n in Western Europe   :P

btw - when i "install" MasmBasic, where are the read-me's that outline how to do that ?
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on March 02, 2013, 10:45:17 AM
Quote from: dedndave on March 02, 2013, 10:41:08 AM
btw - when i "install" MasmBasic, where are the read-me's that outline how to do that ?

After unzipping with "use folder names" with the root of your Masm32 as start directory, there is one in
\Masm32\RichMasm\ReadMeMasmBasic.txt

\Masm32\MasmBasic\MbGuide.rtf is more interesting, though ;-)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: qWord on March 02, 2013, 11:00:57 AM
Quote from: jj2007 on March 02, 2013, 10:45:17 AM\Masm32\MasmBasic\MbGuide.rtf is more interesting, though ;-)
yea, if one has no problem with developing eye cancer  ;-D

BTW: what about double buffering?
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on March 02, 2013, 11:14:45 AM
Quote from: qWord on March 02, 2013, 11:00:57 AM
BTW: what about double buffering?

What do you mean??
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: qWord on March 02, 2013, 11:20:21 AM
Quote from: jj2007 on March 02, 2013, 11:14:45 AM
Quote from: qWord on March 02, 2013, 11:00:57 AM
BTW: what about double buffering?

What do you mean??
Sry, I was talking about the example with ArrayPlot - it flickers on resizing.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on March 02, 2013, 11:25:12 AM
Yes, that's true. I wanted to keep the example simple. To reduce the flicker, do the following:

- line 135:
        mov wc.style, CS_BYTEALIGNWINDOW

- in line 238, add:

    .elseif uMsg == WM_SIZE
       invoke InvalidateRect, hWnd, 0, 0
    .elseif uMsg == WM_CREATE
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: qWord on March 02, 2013, 11:29:32 AM
It's much simpler: set the background brush to zero
mov wc.hbrBackground,  0

:biggrin:
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on March 02, 2013, 11:33:01 AM
Good trick, but you still need the InvalidateRect in the WM_SIZE handler. Even better but CPU-hungry: InvalidateRect in the WM_SIZING handler.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: qWord on March 02, 2013, 11:37:44 AM
Quote from: jj2007 on March 02, 2013, 11:33:01 AM
Good trick, but you still need the InvalidateRect in the WM_SIZE handler. Even better but CPU-hungry: InvalidateRect in the WM_SIZING handler.
your original example does not need that, because the window class has the CS_HREDRAW and CS_VREDRAW style.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on March 02, 2013, 11:41:19 AM
i didn't think CS_BYTEALIGNWINDOW meant much on modern displays
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on March 02, 2013, 11:48:14 AM
Quote from: qWord on March 02, 2013, 11:37:44 AM
your original example does not need InvalidateRect, because the window class has the CS_HREDRAW and CS_VREDRAW style.

That's right - CS_HREDRAW or CS_VREDRAW plus a zero background brush seems to give the best results. Thanks, the new version is uploaded above :t

The documentation is still incomplete; for example, you can add a margin and a legend:

    .elseif uMsg == WM_PAINT
        ArrayPlot hWnd, RgbCol(200, 255, 240)                ; init with window (or control) handle and background colour
        ArrayPlot 0, RgbCol(200, 200, 200), lines:2, 00001900h        ; plot map 0 as loaded above, with grey border and 2px lines, margin right=19h
        ArrayPlot Sinus()        ; plot the sinus curve defined above
        ArrayPlot NormalDist()
        ; ------ here you could add additional features, e.g. a legend ------
        invoke SetBkMode, APs.apMemDC, TRANSPARENT
        invoke SelectObject, APs.apMemDC, LegendFont
        invoke TextOut, APs.apMemDC, 380, 100, Chr$("Legend"), 6
        ArrayPlot exit, "Europe"        ; finish with a title
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Gunther on March 04, 2013, 10:16:42 AM
Hi Jochen,

Quote from: jj2007 on March 02, 2013, 11:48:14 AM
Thanks, the new version is uploaded above :t

in which post? I'd like to test it.

Gunther
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on March 04, 2013, 10:21:26 AM
Hi Gunther,

It's always attached to the first post in this thread. Feedback welcome ;)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Gunther on March 04, 2013, 06:45:06 PM
Thank you, Jochen.  :t

Gunther
Title: Bug warning
Post by: jj2007 on March 06, 2013, 10:32:46 AM
Version 6 March uploaded here (http://www.masm32.com/board/index.php?topic=94.0). It fixes a nasty little bug in the ArrayRead macro (the wrong file was closed). Usage:

        Dim rc4() As REAL4   ; can be REAL4, REAL8, DWORD, ... structures
        ArrayRead rc4(), "MyReal4.dat"

To compensate for this bug :redface:, I added ArrayMean:

                        ArrayMean MyR8()                            ; all array elements are added up, then the sum is divided by the count
                        Print Str$("Resall=\t%f\n", ST(0))      ; the resulting mean is left on the FPU
                        fstp st
                        ArrayMean MyR8(XY)                        ; same as before but we assume the array consists of x,y pairs
                        Print Str$("ResY=\t%f\n", ST(0))       ; the mean of the Y elements is returned in ST(0)
                        fstp st
                        Print Str$("ResX=\t%f\n", ST(0))       ; the mean of the X elements is returned in ST(1)
                        fstp st
Rem        returns mean(s) on the FPU and total number of elements in eax
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on March 24, 2013, 11:35:40 AM
Version 24 March uploaded (download: top of thread (http://www.masm32.com/board/index.php?topic=94.0))

New functions are ArraySet, SetPoly3 and GetPoly3, see example below and \Masm32\MasmBasic\MbGuide.rtf

As shown in the repeat loop below, AllPts(ecx+1) is now valid syntax (same for string arrays)

include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0)
        Init
        Dim My3Pts(5) As DWORD                ; create an array with 3 XY pairs, i.e. 6 elements (0 .. 5)
        ArraySet My3Pts() = 1, 100, 2, 300, 4, 150        ; assign XY values (ArraySet can be handy but any other array works, too)
        SetPoly3 My3Pts()                ; create coefficients for a 3-point polynomial, i.e. Y=a0+a1*X+a2*X2
        Dim AllPts(11) As REAL4                ; create a destination array with 12 elements
        Print "N", Tb$, "X", Tb$, "Y", Tb$, "Y(ecx)"        ; the last column uses the "direct" variant GetPoly3(X)
        GetPoly3(AllPts())                ; fill starting from X=0, create coefficients for Y=a0+a1*X+a2*X2
        add eax, eax
        push eax
        xor ecx, ecx
        .Repeat                ; print N, X, Y=f(x), Y=f(2*X)
                Print Str$("\n%i\t", ecx/2), Str$("%2f\t", AllPts(ecx)), Str$("%3f\t", AllPts(ecx+1)), Str$("%3f", GetPoly3(ecx))
                fstp st                ; pop the return value from the FPU
                add ecx, 2
        .Until ecx>=stack
        pop eax
        Inkey CrLf$, "ok"
        Exit
end start

Output:
N       X       Y       Y(ecx)
0       0.0     -283.0  -283.0
1       1.0     100.0   300.0
2       2.0     300.0   150.0
3       3.0     317.0   -733.0
4       4.0     150.0   -2.35e+03
5       5.0     -200.0  -4.70e+03

Title: DDE interface for Excel
Post by: jj2007 on April 01, 2013, 11:19:22 AM
Latest addition to MasmBasic is an interface to Excel - more in the Easter Egg (http://masm32.com/board/index.php?topic=1733.0) thread.

Note that when you use the File, New Masm source menu in RichMasm, the interface is offered here:
Client & server                example for InterProcessCommunication (IPC)
Masm2Excel                an easy-to-use DDE interface to MS Excel
MasmBasic console app        more examples using BASIC syntax

However, the MB archive is at the 512kB limit, therefore I couldn't squeeze it in. Extract Masm2Excel.asc from post #1 of the Easter Egg (http://masm32.com/board/index.php?topic=1733.0) thread to \Masm32\RichMasm\Res\Masm2Excel.asc to add this sample to the templates.
Title: Excel and DDE: No undo
Post by: jj2007 on April 04, 2013, 05:35:33 PM
With version 5 April, the xlsHotlink macro works now just fine :biggrin:
A little warning: All macros that write to Excel, whether VBA or XLA or MasmBasic, do not preserve the previous state, i.e. there is no undo. If you really need undo, use xlsRead$("yourselection") and handle it manually.

include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  xlsConnect                ; no args=Excel, System
  .if !Zero?                  ; non-zero means success
        xlsOpen "\Masm32\RichMasm\Res\LifeExOecd.xls"                ; we open a sample spreadsheet
        .if !Zero?                ; non-zero signals success
                ; xlsCommand "[app.activate()]"                  ; optional: activate Excel
                xlsConnect "LE Males at birth"                ; tell Excel to which sheet you want to talk
                .if !Zero?                ; non-zero signals success
                        .if rv(GetConsoleWindow)                ; you may print to the console...
                                ConsoleColor cBlack, cYellow        ; make the spaces visible that Excel exports
                                Print "Current selection=[", xlsRead$(), "]", CrLf$        ; no args means current selection
                        .else
                                ifdef hEdit                ; this section would be typical for a GUI application
                                    SetWin$ hEdit='R1C1:R9C5=['+xlsRead$("R1C1:R9C5")+']'+CrLf$                ; ... or set window content
                                    AddWin$ hEdit="Extract #2=["+xlsRead$('R9C1:R12C5')+"]"+CrLf$                ; and add bits & pieces
                                    xlsHotlink "R5C1:R38C2", hEdit        ; see how user modifies a selected area
                                endif
                        .endif
                        ; writing is possible but attention, there is no undo (as for all modifications done by Excel macros)
                        xlsWrite "R1C1", Cat$("This sheet was modified on "+Date$+", "+Time$)
                .endif
                xlsClose 0                ; close the file without saving (0=don't save, 1=save, no arg: ask)
        .endif
        xlsDisconnect                ; say bye to Excel
  .endif
  Inkey "ok"
  Exit
end start
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Gunther on April 04, 2013, 08:52:07 PM
Jochen,

looks like a rock solid work.  :t

Gunther
Title: Excel and DDE: help files
Post by: jj2007 on April 04, 2013, 09:44:42 PM
Danke, Gunther :icon14:

Although DDE is an old technology, there are some arguments for using it - it's fast, lightweight, and there is no "version hell" as (reportedly) with the alternative COM technology. What I really needed was pulling tables programmatically out of an Excel file - sounds simple but if you don't want the user to install add-ins (with all the nice warnings about untrusted software etc), then DDE is probably the only option.

One problem is the documentation; DDE uses the old Excel 4.0 macro language, the only official source is "MacroFun.hlp" from Microsoft Support (http://support.microsoft.com/kb/128185).
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: TouEnMasm on April 05, 2013, 12:11:21 AM
Quote
What I really needed was pulling tables programmatically out of an Excel file

If it is just for that,ODBC is better (same language since ....)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: japheth on April 05, 2013, 12:19:18 AM
Quote from: ToutEnMasm on April 05, 2013, 12:11:21 AM
If it is just for that,ODBC is better (same language since ....)

What is better with ODBC?

- DDE  = dinosaur technology
- COM/OLE = pleistocene
- ODBC = ??? (  perhaps eocene? )
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: TouEnMasm on April 05, 2013, 12:57:11 AM
Quote
What is better with ODBC?
The Use of sql with it , simplify the work.
Simple to use,you don't need to know all the langage.
Access can generate SQL for you.

http://msdn.microsoft.com/en-us/library/bb545450.aspx (http://msdn.microsoft.com/en-us/library/bb545450.aspx)
2012 isn't so old.



Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on April 05, 2013, 01:12:29 AM
i mentioned in the other thread that i had to have Excel for a business client
what i did at the time was - Save Special (without the cell formulas) - Save As CSV
then, i wrote a csv2bin program in 16-bit code   :P
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on April 05, 2013, 02:06:37 AM
Quote from: ToutEnMasm on April 05, 2013, 12:11:21 AM
Quote
What I really needed was pulling tables programmatically out of an Excel file

If it is just for that,ODBC is better (same language since ....)

Hi Yves,

Please show me. Write a little example  - just extracting a table by RnCn:RmCm coordinates.
The testfile is at \Masm32\RichMasm\Res\LifeExOECD.xls

:t
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: TouEnMasm on April 05, 2013, 03:13:47 AM

The file is not a database.
A database had columns titles on the first line.
Do it and no more problems.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on April 05, 2013, 04:32:41 AM
Quote from: ToutEnMasm on April 05, 2013, 12:11:21 AM
If it is just for that,ODBC is better (same language since ....)

There is an old German proverb: Wer gackert muss auch legen. Free translation "He who cackles must lay an egg".

Waiting for your sample code showing that "ODBC is better", Yves :biggrin:

(the requirement is very simple, "get data out of Excel without the user having to install an add-in or a macro; establish a hotlink so that Excel sends data to your proggie every time the Excel user has changed a cell". It would also nice to preserve the formatting as shown in the attached example - source in \Masm32\RichMasm\Res\XlsViewer.asc. If you change the ending to .edm, you can even view it in EditMasm, as it's RTF...)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: TouEnMasm on April 05, 2013, 05:45:48 AM

Quote
What I really needed was pulling tables programmatically out of an Excel file
For That,not for all thing you want to do.

Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on April 05, 2013, 05:53:12 AM
Quote from: ToutEnMasm on April 05, 2013, 12:11:21 AM
Waiting for your sample code showing that "ODBC is better", Yves
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: japheth on April 05, 2013, 06:48:44 AM
Quote from: jj2007 on April 05, 2013, 05:53:12 AM
Quote from: ToutEnMasm on April 05, 2013, 12:11:21 AM
Waiting for your sample code showing that "ODBC is better", Yves

I cannot see why he needs to provide "sample code" - that's an additional requirement imposed by you, troll!  :icon_mrgreen:

Actually, it is sufficient if a plausible reason is supplied that makes obvious - more or less -  that ODBC is at least in one aspect better than DDE.

One possible reason that comes into my mind is that DDE requires a window for communication, while ODBC does NOT requires this.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on April 05, 2013, 07:31:39 AM
Quote from: japheth on April 05, 2013, 06:48:44 AMOne possible reason that comes into my mind is that DDE requires a window for communication, while ODBC does NOT requires this.

Thanks for this clarification, Andreas. I wonder, though, why the attached executable works - must be an invisible window then  ::)

Source is in \Masm32\RichMasm\Res\Masm2Excel.asc, the Excel sheet at \Masm32\RichMasm\Res\LifeExOECD.xls ;-)

Still waiting for demo code (or at least: arguments) why ODBC is better than DDE for grabbing data from an Excel sheet ;-)

EDIT: To complete the DDE interface, I added four new macros, ddeConnect, ddeDisconnect, ddeCommand and ddeRequest$(). This snippet shows the Firefox URL currently loaded, and if the user presses y, it opens a new page (code for MSIE attached):

include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  ddeConnect "Firefox|WWW_GetWindowInfo"
  .if !Zero?
        PrintLine "Current URL= ", ddeRequest$("URL")
        ddeDisconnect
        Inkey "Open a new page (y)?"
        .if eax=="y"
                ddeConnect "Firefox|WWW_OpenURL"
                .if !Zero?
                        ddeCommand "http://masm32.com/board/index.php?action=unread"
                        ddeDisconnect
                .endif
        .endif
  .endif
  Inkey CrLf$, "bye"
  Exit
end start
Title: MasmBasic bug fix
Post by: jj2007 on April 05, 2013, 06:20:58 PM
Bugfix concerning \Masm32\RichMasm\Res\Masm2Excel.asc, line 51:

Wrong:
                mov ecx, Instr_(esi, "[Book")                ; this might fail for a non-English Excel version
                .if ecx
                        .if Instr_(ecx, esi, Tb$)
                                xlsConnect Mid$(esi, ecx, edx-1)          ; connect to the new sheet
                        Let TopBot$=String$(9, Cat$("xxxxxxxxx"+Tb$))+"x"
                        xlsWrite "R2C3:R2C14", TopBot$

Right:
                mov ecx, Instr_(esi, "[Book")                ; this might fail for a non-English Excel version
                .if ecx
                        .if Instr_(ecx, esi, Tb$)
                                xlsConnect Mid$(esi, ecx, edx-ecx)          ; connect to the new sheet
                        Let TopBot$=String$(9, Cat$("xxxxxxxxx"+Tb$))+"x"
                        xlsWrite "R2C3:R2C14", TopBot$

Excel 2003 did not complain about being connected to [Book1]Sheet1 whatever, but Excel 2010 didn't like it  :biggrin:

Updated library here (http://masm32.com/board/index.php?topic=94.0), as always.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: japheth on April 05, 2013, 06:26:20 PM
Quote from: jj2007 on April 05, 2013, 07:31:39 AM
Thanks for this clarification, Andreas. I wonder, though, why the attached executable works - must be an invisible window then  ::)

Yes, I guess that's true. Sorry, can't really run your sample because I threw away the MSO BS from this machine - and the one where it's still installed is now too noisy for my taste.
Title: DDE and Excel 2010 Starter Edition on Win7-64
Post by: jj2007 on April 06, 2013, 08:49:51 PM
The DDE demo in \Masm32\RichMasm\Res\Masm2Excel.asc works fine with DDE and Excel 2010 Starter Edition on Italian Win7-64. Note that the "starter" editions do not run any macros... but DDE works just fine. Probably some big corporations running legacy software had a chat with the M$ marketing department. Won't go into detail here because it would violate the forum rules  ;-)

                xlsCommand "[new(1)]"                          ; let Excel create a new workbook (works fine on non-English Excel versions!)
                Let esi=xlsSysRead$("Topics")        ; we must find the sheet
                mov ecx, Instr_(esi, "[Book")                ; this might fail for a non-English Excel version
                .if !ecx
                        mov ecx, Instr_(esi, "[Cartel")                ; let's try Italian - OK on Win7-64, Excel Starter 2010 (does not support macros!!)
                .endif
                .if ecx
                        .if Instr_(ecx, esi, Tb$)
                                xlsConnect Mid$(esi, ecx, edx-ecx)          ; connect to the new sheet
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on April 15, 2013, 08:41:19 AM
Update 15 April (download from post #1 (http://masm32.com/board/index.php?topic=94.msg264#msg264)):
- fixed a bug in Replace$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1079)
- Clip$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1099) had a 160k limit, now the limit is available memory
- Exp10, Exp2, ExpE and ExpXY (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1192) implemented (special thanks to qWord :t (http://masm32.com/board/index.php?topic=1783.msg18292#msg18292))
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on April 19, 2013, 06:01:01 AM
Update 18 April (download from post #1 (http://masm32.com/board/index.php?topic=94.msg264#msg264)):

- fixed a bug in StringToArray (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1130) (the string to numerical array variant pushed one dword too much; the string to string array variant was OK)

- Pelles C "Hello World" example added (see New Masm source in the RichMasm editor)

- SetPoly3 (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1124) MyArray(ecx) is now possible, i.e. take 3 xy pairs starting with element ecx (where ecx = 0, 2, 4...)

- Str$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1186)() accepts now single quotes (rarely needed, but I had a problem with DDE...):
                        mov row, 3
                        xlsCommand (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1085) Str$('[select("R%iC5")]', row)                ; select("R3C5")

Finally, the handling of resource strings was improved, so that you can use two of them in MsgBoxes, as shown below for Unicode (same for the Ansi version):

include \masm32\MasmBasic\MasmBasic.inc
        Init
        wMsgBox 0, wRes$(2), wRes$(3), MB_OK
        Exit
end start

Rsrc
STRINGTABLE                ; RichMasm creates the rc file "on the fly"; edit the strings, then press F6 to assemble, link & run
BEGIN
  2,        "Нажмите на эту кнопку"        ; "Click on this button" in Russian
  3,        "Добро пожаловать"        ; "Welcome" in Russian
END
Rsrc
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Gunther on April 19, 2013, 06:46:52 AM
You're a hard working man, Jochen.  :t Thank you for the update.

Gunther
Title: PickFont
Post by: jj2007 on May 06, 2013, 08:43:25 PM
Thanks, Gunther ;-)

In the meantime, I had to fix a little bug: CL$() and wCL$() choked after arg #126. Now the number of arguments from the commandline is apparently limited by Windows; for example, under Win7-32 you can pass up to 32767 bytes via CreateProcess aka Launch (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1045)(). Little test app attached.

I seized the occasion to add one more macro:

        PickFont addr hFont        ; use the font dialog to change the font whose handle is in hFont
        PickFont addr hFont, hEdit        ; apply to edit control (if user didn't cancel)
Title: BUG warning
Post by: jj2007 on May 08, 2013, 06:11:14 PM
Quote from: jj2007 on May 06, 2013, 08:43:25 PM
In the meantime, I had to fix a little bug: CL$()...

And I introduced a fresh one on that occasion: CL$() with no args (i.e. "return the complete commandline") crashed. Concerns only version 6 May and is now fixed with version 8 May attached on top of this thread. Apologies :redface:
Title: Inter-Process communication with shared segments
Post by: jj2007 on July 15, 2013, 06:18:43 PM
It is possible to share data between two applications using the same DLL. In Win-16, that was the default, in Win-32 you need to declare a shared data segment (more at MSDN (http://msdn.microsoft.com/en-us/library/h90dkhs0(v=vs.80).aspx)).

Strangely enough, it is even possible to have a joint memory area between two instances of an application:

include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0)
MyShared SEGMENT read write shared "BSS"
TheCount        dd ?
MyShared ends

        Init
        inc TheCount
        .if TheCount<=2
                Delay 500        ; if you see "1" on screen more than once, press Ctrl C
                Launch CL$(0)        ; launch another instance
        .endif
        Inkey Str$("n=%i\n", TheCount)
        Exit
end start

Output:
1
2
3

(hit any key three times to exit - there are three inkey statements)

Sharing segments as shown above works for JWasm and Masm 8.0 and higher. For Masm 6.15, there is a workaround as shown below, but it needs the linker option...
/SECTION:.bss,rws
... which fails miserably with POLINK (warning: /SECTION:.bss ignored; section is missing)

.data?
TheCount        dd ?


Credits go to Japheth (http://forum.pellesc.de/index.php?topic=5476.msg20945#msg20945) and  qWord (http://www.masmforum.com/board/index.php?topic=14096.msg111856#msg111856)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: hutch-- on July 15, 2013, 09:03:08 PM
JJ,

I have seen IPC done this way but its rather clunky along side a memory mapped file and conventional messaging. The memory mapped file provides the shared memory area of more or less any size you like while the messaging using the HWND_BROADCAST identifier can be used to signal when data is available to any other app that can access the shared memory.
Title: Re: Inter-Process communication with shared segments
Post by: jj2007 on July 16, 2013, 03:43:58 AM
Hutch,

I wouldn't call it clunky, it's really as simple as declaring myvar dd 123 in the .data section. Memory-mapped files are great for many purposes, sure.

But I have to admit that I don't see many uses for shared segments. As a proof of concept, I attach a little app that launches itself three times, declaring instance 0 as "server" and 1+2 as "clients". The common segment has an array where each instance stores its window handle, so no need for broadcasting:
MyShared SEGMENT read write shared "BSS"
MyCount   dd ?
hWinByInstance   dd 20 dup(?)
MyShared ends


The server can send a WM_COPYDATA message, the clients can handle them. Instead of that message, shared memory could be used to copy strings from server to client. IIRC, WM_COPYDATA eats around 4,000 cycles, which is quite a lot. Mem to mem should be faster...

On startup, MyCount is increased. Each instance knows its identity, and uses it e.g. to decide the x position on the screen, and whether to add pushbuttons or not.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Antariy on July 16, 2013, 07:07:19 PM
Hi Jochen :t

Yes, I can confirm that this way of IPC in suitable cases is the best possible, just unbeatable: it's simple, reliable and fastest.

As one more proof of the concept: RAM Clear working in Advanced Mode - when it is unlimited with the size of memory it may free - working in that way. It launch "subsystems" - "clients" in your terminology here - and all interaction between server-controller-interface-father and client-subsystem-child is going via shared section of the same EXE.

RAM Clear has multiprocess, multithreaded concept, and in the extents it was designed for, special shared section does its job for IPC best of any other method.

But one needs to remember that with such an IPC way the designed controlling system should be properly designed for preemptiveness and reenterantness - i.e., multithreading (here this is equal to multiprocessing) there is no serialization like in message pump of the target-window process, like if "messages-way" IPC is using. I.e., all working programs can change data in the shared section just simultaneously, and there should be a mechanism to protect "atomical values" from changing simultaneously.

On the alpha-stage RAM Clear there were a fullscale tests with 96 working subsystems (96 child processes launched by a father process). So, this concept is really good one - when it is suitable :t
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on July 26, 2013, 08:03:43 AM
After over 150 downloads, it seems time for an update...

Apart from fixing minor glitches, there are three significant changes in MasmBasic of 26.7.2013:

1. MasmBasic's debug macro has learned to display variables and registers also in hex and binary format:
        deb 1, "On loop entry:", al, ecx, $esi, xmm0, xmm1, ST, ST(5)        ; xmm in lowercase, FPU regs in uppercase
        deb 4, "#4 will show in the console:", xmm0, f:xmm0                ; display xmm0 as integer (default) and float with f: prefix
        deb 5, "#5 will be written to DebLog.txt:", ebx, $My$, $MyArray$(n)
        usedeb=0                        ; disable debugging completely (no code inserted - very handy...)
        deb 1, "This box will never pop up", eax
        usedeb=16                        ; force hex display
        deb 4, "Hexadecimal:", eax, xmm1, ST(3)                ; limited to 32 bits, i.e. low dword of xmm regs, FPU as int 32
        usedeb=2                        ; force binary display
        deb 4, "Binary:", eax, xmm1, ST(3)                ; limited to 32 bits
        usedeb=1                        ; decimal display (default)
        deb 4, "Multiple:", eax, x:eax, b:eax                ; override usedeb: show arguments in decimal, hexadecimal and binary format

        If you are still not desperate enough to launch Olly, give deb a try.
        Nothing is more powerful for bug-chasing.

2. ClearLocals replaces ClearLocalVariables and is now much simpler (and a lot faster, too (http://masm32.com/board/index.php?topic=2137.0)):
        MyTest proc uses edi esi ebx arg1:DWORD, arg2:RECT
        LOCAL v1, v2, rc:RECT, buffer[100]:BYTE
          ClearLocals        ; first line after the LOCALs
          MsgBox 0, Str$("The value of v1: %i", v1), "Test clv:", MB_OK
          ret
        MyTest endp

        ClearLocals is fast, compact (5 bytes per call), and leaves all registers intact.

3. StackBuffer has become simpler, and you can use more than one buffer:
        MyTest proc uses edi esi ebx arg1:DWORD, arg2:RECT
        LOCAL rc:RECT, sbuf1, sbuf2, whatever[100]:BYTE
         ; optional: ClearLocals        ; first line after the LOCALs
          mov sbuf1, StackBuffer(100000)        ; allocate two fat buffers, and make sure
          mov sbuf2, StackBuffer(4000h)        ; they are 16-byte aligned for use with SSE2
          PrintLine "Start buffer 1:", Tb$, Hex$(sbuf1)
          PrintLine "Start buffer 2:", Tb$, Hex$(sbuf2)
          StackBuffer()        ; release second buffer
          StackBuffer()        ; release first buffer (sb without args = free the buffer)
          ret
        MyTest endp

   - buffer size is limited by start address of stack;
   - the start address is aligned to 16 bytes for use with SIMD instructions
   - can be combined with ClearLocals, but no zero-init performed for the stack buffer
   - StackBuffer does the stack probing for you

Download the library from the top of this thread. (http://masm32.com/board/index.php?topic=94.0)
Title: crtbuf and StackBuffer()
Post by: jj2007 on July 29, 2013, 07:16:26 PM
A small addition for version 29 July concerns the crtbuf macro (see also StackBuffer() above):
        crtbuf ThisExe$, MAX_PATH                        ; create a buffer in the uninitialised data section
        invoke GetModuleFileName, 0, ThisExe$, MAX_PATH        ; use it...
        crtbuf pBuffer, 1000000, 16                        ; create a 1 Mio bytes buffer in .data?, align 16 for use with SSE2

So SIMD fans can now specify 16-byte alignment (default is DWORD). Note that StackBuffer() is always aligned to 16 bytes but not zeroed.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Gunther on July 30, 2013, 02:55:14 AM
Jochen,

Quote from: jj2007 on July 29, 2013, 07:16:26 PM
So SIMD fans can now specify 16-byte alignment (default is DWORD). Note that StackBuffer() is always aligned to 16 bytes but not zeroed.

good feature. It avoids a GPF in some cases. Thank you.  :t

Gunther
Title: Hex$ displays XMM and FPU registers
Post by: jj2007 on August 05, 2013, 10:29:52 AM
MasmBasic version 5 August 2013 (http://masm32.com/board/index.php?topic=94.0) is much improved on the deb and Hex$() macros. Example:

include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0)
        Init
        ; create a WORD array (byte, dword, qword, realX are also valid sizes):
        Dim MyW() As WORD
        mov MyW(0), 100        ; give it a start value
        xor ecx, ecx
        .Repeat
                mov ax, MyW(ecx)
                add ax, cx
                mov MyW(ecx+1), ax
                deb 6, "Fill a WORD array", ecx, MyW(ecx), MyW(ecx+1)        ; print the first 6 iterations to the console
                inc ecx
        .Until ecx>999

        Print Str$("\n%i loops OK\n", ecx)
        Print Str$("MyW(ecx-2)=%i\n", MyW(ecx-2))        ; show the last two values assigned
        Inkey Str$("MyW(ecx-1)=%i\n", MyW(ecx-1))
        Exit
end start


Output:
Fill a WORD array
ecx             0
MyW(ecx)        100
MyW(ecx+1)      100

Fill a WORD array
ecx             1
MyW(ecx)        100
MyW(ecx+1)      101

Fill a WORD array
ecx             2
MyW(ecx)        101
MyW(ecx+1)      103

Fill a WORD array
ecx             3
MyW(ecx)        103
MyW(ecx+1)      106

Fill a WORD array
ecx             4
MyW(ecx)        106
MyW(ecx+1)      110

Fill a WORD array
ecx             5
MyW(ecx)        110
MyW(ecx+1)      115

1000 loops OK
MyW(ecx-2)=38851
MyW(ecx-1)=39849


The Hex$() macro can now handle more sizes, including the 4 DWORDS of xmm registers, and has learned to display exotic formats, such as FPU and XMM registers:

include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0)
.data
MyByte        db 12h
MyWord        dw 1234h
MyDword        dd 12345678h
MyQword        dq 1234567812345678h
MyReal8        REAL8 1234567812345678r        ; r means the hex representation of a real number
MyPackedQwords dq 11aa22bb33cc44ddh, 55aa66bb77cc88ddh
        Init
        mov ecx, 12345678h
        PrintLine Hex$(cl)        ; reg8, 12 - same for dh, ah etc
        PrintLine Hex$(ch)        ; reg8, 12 - same for dh, ah etc
        PrintLine Hex$(cx)        ; reg16, 1234
        PrintLine Hex$(ecx)        ; reg32, 12345678
        PrintLine Hex$(123)        ; immediate
        PrintLine Hex$(MyByte)        ; global and local variables
        PrintLine Hex$(MyWord)
        PrintLine Hex$(MyDword)
        PrintLine Hex$(MyQword)        ; QWORD will be displayed with one space as 12345678 90123456
        movups xmm1, oword ptr MyPackedQwords
        PrintLine Hex$(xmm1)        ; if QWORD is not enough, get e.g. 11AA22BB 33CC44DD 55AA66BB 77CC88DD
        PrintLine Hex$(MyReal8)        ; same as QWORD
        fldpi
        PrintLine CrLf$, "PI=", Hex$(ST)        ; PI as 10-BYTE hex
        Let esi=CrLf$+"Result = "+Hex$(287454020)+"h"        ; in case you need the trailing h or a leading 0x, use Let or Cat$()
        Inkey esi
        Exit
end start


Output:
78
56
5678
12345678
0000007B
12
1234
12345678
12345678 12345678
11AA22BB 33CC44DD 55AA66BB 77CC88DD
12345678 12345678

PI=4000 C90FDAA2 2168C235

Result = 11223344h


If you find a problem, please let me know.
Title: Bugfix for displaying Hex$(xmmreg)
Post by: jj2007 on August 12, 2013, 01:09:38 PM
Version 5 August of MasmBasic displayed OWORDs in the incorrect order. The bug is fixed in version 12 August. (http://masm32.com/board/index.php?topic=94.0)
The reason, or rather: my bad excuse, is that I try to keep compatibility to good old MASM 6.15 - and the latter doesn't know about OWORDs. My workaround is usual to declare two QWORDs instead:

; MyO   OWORD 00112233445566778899aabbccddeeffh   ; no good for ML 6.15 and lower
; MyO   QWORD 0011223344556677, 8899aabbccddeeffh ; solution #0 - WRONG
MyO     QWORD 8899aabbccddeeffh, 0011223344556677 ; solution #1 - RIGHT


As you can easily guess, I had tested the new Hex$(xmm1) with solution #0 :redface:

Below a simple demo (the deb macro uses Hex$() internally):

include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0)
.data
O0        OWORD 0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFh
O1        OWORD 0FFFF99FFFFFFFFFFFFFF11FFFFFFFFFFh
O3        OWORD 0ffeeddccbbaa99887766554433221100h

        Init
        movups xmm0, O0
        movups xmm1, O1
        movups xmm3, O3
        movaps xmm2, xmm0        ; copy for pcmpeqb
        PCMPEQB xmm2, xmm1
        deb 4, "x0/1/2", x:xmm0, x:xmm1, x:xmm2, x:xmm3
        Print CrLf$, "16 bits", Tb$, Tb$, Tb$, "5432109876543210", CrLf$
        PMOVMSKB eax, xmm2        ; show in ax where xmm0 differs to xmm1
        xor ecx, ecx
        not ax        ; we are interested in bits set
        deb 4, "MSKB", b:ax
        bsr ecx, eax
        deb 4, "msb set", ecx
        bsf ecx, eax
        deb 4, "lsb set", ecx
        Inkey
        Exit
end start

Output:
x0/1/2
x:xmm0          FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
x:xmm1          FFFF99FF FFFFFFFF FFFF11FF FFFFFFFF
x:xmm2          FFFF00FF FFFFFFFF FFFF00FF FFFFFFFF
x:xmm3          FFEEDDCC BBAA9988 77665544 33221100

16 bits                 5432109876543210
MSKB    b:ax            0010000000100000
msb set ecx             13
lsb set ecx             5
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Magnum on August 12, 2013, 01:50:17 PM
Quote from: jj2007 on May 23, 2012, 10:16:07 PM
MasmBasic is a library that allows to use BASIC syntax in assembler, i.e. it is not a "separate" language but rather a library of macros and routines, fully compatible with the latest Masm32 SDK (version 11) (http://masm32.com/), MASM (http://www.microsoft.com/downloads/en/details.aspx?familyid=7a1c9da0-0510-44a2-b042-7ef370530c64&displaylang=en) (from version 6.15 upwards, see e.g. version 8.0 (http://www.masm32.com/board/index.php?topic=13529.msg105895#msg105895)) and JWasm (http://www.japheth.de/JWasm.html#jwdownload). The usual disclaimers apply - do not use for military purposes, in hospitals and anywhere else where buggy applications could cause damage. You have been warned 8)


I wish you had posted that earlier.

I used it to write a program that monitors C-eye-PAV.

I think you are safe though.

Andy
Title: Comparing OWORDs and QWORDs
Post by: jj2007 on August 15, 2013, 10:58:39 AM
Update 15 August (download (http://masm32.com/board/index.php?topic=94.0)):

Qcmp, Ocmp
.data        ; for testing
qSmall    qWORD 7700000000000001h
qBig      qWORD 7700000000000003h
oSmall    OWORD 77000000000000000000000000000001h
oBig      OWORD 77000000000000000000000000000003h        ; OWORD for JWasm and higher ML.exe versions
; oBig    qWORD 00000000000000003h, 7700000000000000h        ; 2 QWORDS for ML 6.15
.code
        Qcmp qBig, qSmall        ; compare two global variables
        mov ecx, offset oBig        ; use a pointer ...
        Ocmp ecx, oSmall        ; ... for one (or both) of them
        movups xmm0, OWORD PTR oSmall        ; even ML 6.15 understands that
        oqDeb=1        ; if this flag is set, Qcmp or Ocmp print e.g. "ecx greater xmm0" to console
        Ocmp ecx, xmm0        ; a pointer and an XMM reg (xmm0...xmm2 will be trashed)
        deb 4, "Result", flags        ; CzSo, i.e. Carry? and Sign? set
Rem
        - returns flags as in a cmp eax, edx comparison (control for overflow!)
        - trashes eax and edx, xmm0 and xmm1; do not use edx as input
        - you cannot use both ecx and ebx as input pointers (an error will be thrown)

## for comparing floats (REAL4, REAL8, REAL10): ##
Fcmp
        MyPI_hi        REAL4        3.14160
        ...
        Fcmp MyPI_hi, PI, medium        ; PI is what you think it is
        .if FcmpLesser
                Print Str$("MyPI_hi at %f is lower than the real PI\n", MyPI_hi)
        .elseif Zero?
                Print Str$("MyPI_hi at %f is exact\n", MyPI_hi)
        .else
                Print Str$("MyPI_hi at %f is higher than the real PI\n", MyPI_hi)
        .endif
Rem        - returns Zero? and Sign? flags (and only these are valid): Sign? means "first arg below second arg"
        - you may use FcmpGreater and FcmpLess (aka !Sign? and Sign?)
        - single arg, e.g. Fcmp xmm1, tests for zero
         - see also QCmp and Ocmp for comparing QWORDs and OWORDs
         - almost any number formats can be compared, including xmm registers etc
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Magnum on August 15, 2013, 11:43:38 AM
Quote from: jj2007 on May 23, 2012, 10:16:07 PM
MasmBasic is a library that allows to use BASIC syntax in assembler, i.e. it is not a "separate" language but rather a library of macros and routines, fully compatible with the latest Masm32 SDK (version 11) (http://masm32.com/), MASM (http://www.microsoft.com/downloads/en/details.aspx?familyid=7a1c9da0-0510-44a2-b042-7ef370530c64&displaylang=en) (from version 6.15 upwards, see e.g. version 8.0 (http://www.masm32.com/board/index.php?topic=13529.msg105895#msg105895)) and


When I clicked on version 8, it said off limits.

Andy
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on August 15, 2013, 04:54:56 PM
Thanks, Andy - I just corrected the link to Erol's post. Caution, though, when going to the M$ site:

QuoteThe Microsoft Macro Assembler 8.0 (MASM) is a tool that consumes x86 assembly language programs and generates corresponding binaries.

Make a backup of your sources ;)

Or, much better idea, use JWasm (http://www.japheth.de/JWasm.html) - fully compatible with Masm32 and MasmBasic, and at least twice as fast as the latest M$ snails. RichMasm has now autodetection for JWasm:
   ; if OPT_Assembler not explicitly set, check if ML is old and JWasm is available
   .if Exist("\Masm32\Bin\ml.exe")
           .if Instr_(GfDate$(-1), "1999")
                   mov ecx, Chr$("\Masm32\bin\JWasm.exe")
                   .if Exist(ecx)
                           invoke lstrcat, edi, offset txOptAss
                   .else
                           MsgBox 0, Cat$("You need"+CrLf$+ecx), "Hi", MB_OK
                   .endif
           .endif
   .endif
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on August 15, 2013, 05:01:13 PM
PacMasm ?   :biggrin:

(http://wallofgame.info/images/pacman3.png)
Title: PacMasm
Post by: jj2007 on August 15, 2013, 05:20:57 PM
Quote from: dedndave on August 15, 2013, 05:01:13 PM
PacMasm ?   :biggrin:
include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0)
        Init
        GetFiles \Masm32\*.asm
        push eax
        For_ ebx=0 To eax-1
                Kill Files$(ebx)
        Next
        Inkey Str$("Dave, wifey is waiting, and %i files are gone!!!!", stack)
        Exit
end start  :greensml:
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Antariy on August 15, 2013, 06:11:27 PM
:greensml:



C:\MASM32\>ML the_proper_code.asm
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000.  All rights reserved.

Assembling: the_proper_code.asm
Yum-yum!



C:\MASM32\>ML the_untidy_code.asm
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000.  All rights reserved.

Assembling: the_untidy_code.asm
the_untidy_code.asm(9) : warning A4011: multiple .MODEL directives found : .MODEL ignored
*sound of belch*

Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on August 15, 2013, 06:17:32 PM
Post the sources, Alex :biggrin:
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Gunther on August 16, 2013, 02:18:20 AM
Jochen,

Quote from: jj2007 on August 15, 2013, 06:17:32 PM
Post the sources, Alex :biggrin:

he will, he will. Please be patient.  :lol:

Gunther
Title: Olly
Post by: jj2007 on August 18, 2013, 11:11:05 AM
Update 18 August concerns only MasmBasic's default editor, RichMasm (located in \Masm32\RichMasm\RichMasm.exe after installation):

include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0)
        Init
;       if RichMasm finds at least one int 3 that is not commented out, the editor
;       will launch \Masm32\OllyDbg\ollydbg.exe for the current exe with arguments
        int 3        ; Hit F9 in Olly, it will stop here
        Print "The commandline args are [", CL$(1), "] and [", CL$(2), "]"
        Exit
end start

RichMasm options for seeing symbols in Olly:
OPT_Assembler   JWasm         ; download (http://www.japheth.de/JWasm.html) - must be present in \bin (ML 6.15 works, too)
OPT_DebugA      /Zi           ; activate symbols
OPT_Linker      link          ; Masm32 standard, i.e. version 6.14, must be present in \bin
OPT_DebugL      /debug        ; for debugging
OPT_Arg1        "Hello coder"
OPT_Arg2        "what's cooking in the Masm32 forum?"


Note that Olly must be present as \Masm32\OllyDbg\ollydbg.exe

When Olly starts a console app, the console window will be in the foreground. This is rarely what you want, therefore RichMasm has now learned to move Olly to the foreground, so that you can directly hit F9 without having to click the bl**dy console away.
Title: Fearless beta testers wanted!
Post by: jj2007 on August 23, 2013, 09:07:14 AM
Since the zipped package was very close to the Forum's 512k limit, I wrote an installer which pushed it down to 322k. Feedback sought regarding
- the EULA
- the extraction process
- whatever observation you may have 8)

Just open the attachment and double-click on MbSetup.exe
(It's not MSI, sorry, but it seems to do the job, too - source will be available soon)

P.S.: Second version posted, the first one didn't find the image for the title bar :(
P.S.: Third version attached, #2 tried to sell VB to Dave, and I hope that is fixed for the time being ;-)

P.S.: See reply #100 for version #4
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on August 23, 2013, 01:08:23 PM
oops - lol
it says MasmBasic is not for me, then googles VB for me   :lol:
nothing cryptic about that message

i have some of my masm32 subfolders named a little differently
perhaps you could tell us which subfolders must be in place before throwing us to the wolves   :biggrin:

great idea, though
i always wondered if i had it set up correctly, before
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on August 23, 2013, 03:40:05 PM
Quote from: dedndave on August 23, 2013, 01:08:23 PM
oops - lol
it says MasmBasic is not for me, then googles VB for me   :lol:

Soooorry... that means I have to revise the routine that checks if user X is a valid member of the Masm32 community :redface:

What I did is check the registry for the asm_auto_file editor. If there is \Masm32\ in one of the possible entries, you are a good user. Which means you are a bad user, Dave :eusa_naughty:

  call IsMasm32        ; check if user has Masm32 installed
  .if eax
        inc GoodUser
        wLet Button1$="Accept && Install"
        wLet Static$="MasmBasic will be installed to "+wChr$(M32$)+"MasmBasic"
  .else
        wLet Button1$="Continue"        ; will open Google ;-)
        wLet Static$="Bye..."
  .endif

IsMasm32:
        ; If an entry exists in both HKLM\SOFTWARE\Classes and HKEY_CURRENT_USER\SOFTWARE\Classes,
        ; then the value of the entry in HKEY_CURRENT_USER\SOFTWARE\Classes takes precedence (MSDN (http://technet.microsoft.com/en-us/library/cc739822%28v=ws.10%29.aspx)).
        ; Win7: HKCU & HKCR
        Let edi=GetRegVal("HKCU\SOFTWARE\Classes\asm_auto_file\shell\open\command", 0, "No luck in HKCU...")
        .if !Instr_(edi, "\Masm32\", 1)
                Let edi=GetRegVal("HKLM\SOFTWARE\Classes\asm_auto_file\shell\open\command", 0, "No luck in HKLM...")
        .endif
        .if !Instr_(edi, "\Masm32\", 1)
                Let edi=GetRegVal("HKCR\asm_auto_file\shell\open\command", 0, "No luck in HKCR...")
        .endif
        .if !Instr_(edi, "\Masm32\", 1)
                FileWrite "tmp.asm", "MasmBasic is great"
                lea edi, TmpPath$
                invoke FindExecutable, esi, Chr$("\"), edi
                Kill esi
        .endif
        Clr$ esi
        push Instr_(edi, "\Masm32\", 1)
        .if eax
                or ecx, -1
                .Repeat
                        inc ecx
                .Until byte ptr [edi+ecx]>="A"
                sub edx, ecx
                lea eax, [edi+ecx]
                Let M32$=Left$(eax, edx+7)
        .endif       
        pop eax
        retn
end start
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Antariy on August 23, 2013, 07:58:08 PM
Quote from: jj2007 on August 23, 2013, 09:07:14 AM
Since the zipped package was very close to the Forum's 512k limit, I wrote an installer which pushed it down to 322k. Feedback sought regarding
- the EULA
- the extraction process
- whatever observation you may have 8)

Just open the attachment and double-click on MbSetup.exe
(It's not MSI, sorry, but it seems to do the job, too - source will be available soon)

P.S.: Second version posted, the first one didn't find the image for the title bar :(

Just downloaded it, Jochen :t
As for MSI - no need in excuses - don't like MSI packages :biggrin:

As for search for "asm_auto_file", the robust way is to get in HKCR\.asm key the default value contents - if it's empty, then search for the "Shell\Open\command" subkey in the same key, otherwise it will be the name of the key with right "Shell\Open\command". HKCR\.asm default value usually contains redirection to "asm_auto_file", so right redirection path is HKCR\asm_auto_file, but the redirection may be other - depends on different things and how user setup the handling of files, like the opening program.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Antariy on August 24, 2013, 09:13:59 AM
Version 3 works for me, Jochen :t It founds MASM32 package path properly.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on August 24, 2013, 10:23:59 AM
it looks like it installed correctly   :t

the title bar in the browser flickers continuously - well - it's odd behaviour - the cursor is nutty - lol
it would be nice to have an "installation test" program that assembles using MB
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: sinsi on August 24, 2013, 12:49:31 PM
V3 works for me, but a success/fail message would be nice...
In RichMasm, the menu in the title bar overwrites the title bar text - normal behaviour?
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on August 24, 2013, 04:47:12 PM
Quote from: dedndave on August 24, 2013, 10:23:59 AM
the title bar in the browser flickers continuously - well - it's odd behaviour - the cursor is nutty - lol
There is one spot between System Apps and Help that flickers for me - will have to solve that one day. But no continuous flicker on my machines. What exactly do you see? Which OS, which resolution?

Quoteit would be nice to have an "installation test" program that assembles using MB
Will add my testbed in version 4, now that the 512k limitation is far away.

Quote from: sinsi on August 24, 2013, 12:49:31 PM
V3 works for me, but a success/fail message would be nice...
In RichMasm, the menu in the title bar overwrites the title bar text - normal behaviour?
Not really. Are your title bars centered, or right-aligned? Windows 8, I guess?

The problem here is/was Aero. The idea was to maximise the height of the editor's "real estate", since Assembler is a "vertical language" (note that FF and Thunderbird nowadays do something similar). So I placed the menus inside the caption, and made them also show without clicks (I hate clicking). But then Lingo complained about not seeing them with Vista/Aero (http://www.masmforum.com/board/index.php?topic=9044.msg81497#msg81497), and I found this solution, which is not perfect but works most of the time.

But it should not flicker, and not overwrite titles, of course. Grateful for more detailed descriptions of the problems, folks :icon14:

Bookmarks to the right and listbox are working properly?
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: sinsi on August 24, 2013, 05:34:55 PM
On the laptop (win8):
Download masm32 and install...ok
Download and install masmbasic...f**k this, I'm going to use VB
Step 2 needs to be "try to open a .asm file, fail, associate it with something"

Interestingly, SmartScreen blocked masmbasic install but not masm32.

Windows 8 has no aero and centred titles.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on August 24, 2013, 05:56:10 PM
Quote from: sinsi on August 24, 2013, 05:34:55 PM
On the laptop (win8):
Download masm32 and install...ok
Download and install masmbasic...f**k this, I'm going to use VB
Step 2 needs to be "try to open a .asm file, fail, associate it with something"

Interestingly, SmartScreen blocked masmbasic install but not masm32.

Windows 8 has no aero and centred titles.

Thanxalot, John. Could you please run the register tests attached here (http://here)? In my installations, qEditor.exe has a HKCR\Applications\qEditor.exe\shell\open\command key, so I wonder where that one is gone...

Re SmartScreen: I have added a manifest to the Setup.exe; does it convince SmartScreen?
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Antariy on August 24, 2013, 06:08:57 PM
Jochen, maybe it will be useful to make the installation path variable? Like "MasmBasic will be installed to ..." and near this a button "Change location..." - for those who have more than one MASM32 installation on different drives.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: sinsi on August 24, 2013, 06:11:18 PM
Could you please run the register tests attached here (http://here)?
Here? Nope  :P
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Antariy on August 24, 2013, 06:22:12 PM
John, it's there http://masm32.com/board/index.php?topic=2277.msg23601#msg23601
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: sinsi on August 25, 2013, 04:23:50 PM
Fresh install of everything on my win7 box

Before any install ------------------------------------------------------------------------------------------------
C:\Users\User\Desktop>IsMasm32.exe
*** Running Windows 7 Home Premium ***

### Testing asm files: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.asm\UserChoice
Progid=[* failed *]
HKCR\.asm
default=[* failed *]
HKCR\* failed *\shell\Open\Command
default=[* failed *]

### Testing inc files: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.inc\UserChoice
Progid=[* failed *]
HKCR\.inc
default=[* failed *]
HKCR\* failed *\shell\Open\Command
default=[* failed *]

### Testing rc files: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.rc\UserChoice
Progid=[* failed *]
HKCR\.rc
default=[* failed *]
HKCR\* failed *\shell\Open\Command
default=[* failed *]

### Finding the path for qEditor.exe: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\qEditor.exe    [* failed *]
HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\qEditor.exe    [* failed *]
HKCR\Applications\qEditor.exe\shell\open\command        [* failed *]

### Finding the path for winword.exe: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\winword.exe    [* failed *]
HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\winword.exe    [C:\PROGRA~1\MICROS~3\Office14\WINWORD.EXE]
HKCR\Applications\winword.exe\shell\open\command        [* failed *]

Messy, right? Now trying to find the editor elsewhere...

Registry HKCU   $edi            No luck in HKCU...
Registry HKLM   $edi            No luck in HKLM...
Registry HKCR   $edi            No luck in HKCR...
Registry HKCR   $edi            No luck in HKCR...

FileWrite
$esi            C:\Users\User\Desktop\~tmp25081517.asm
$edi            C:\Windows\system32\NOTEPAD.EXE

After installing masm32, same as above ---------------------------------------------------------------------------

After associating .asm with qeditor.exe --------------------------------------------------------------------------
C:\Users\User\Desktop>IsMasm32.exe
*** Running Windows 7 Home Premium ***

### Testing asm files: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.asm\UserChoice
Progid=[* failed *]
HKCR\.asm
default=[asm_auto_file]
HKCR\asm_auto_file\shell\Open\Command
default=["D:\masm32\qeditor.exe" "%1"]

### Testing inc files: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.inc\UserChoice
Progid=[* failed *]
HKCR\.inc
default=[* failed *]
HKCR\* failed *\shell\Open\Command
default=[* failed *]

### Testing rc files: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.rc\UserChoice
Progid=[* failed *]
HKCR\.rc
default=[* failed *]
HKCR\* failed *\shell\Open\Command
default=[* failed *]

### Finding the path for qEditor.exe: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\qEditor.exe    [* failed *]
HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\qEditor.exe    [* failed *]
HKCR\Applications\qEditor.exe\shell\open\command        ["D:\masm32\qeditor.exe" "%1"]

### Finding the path for winword.exe: ###
HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\winword.exe    [* failed *]
HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\winword.exe    [C:\PROGRA~1\MICROS~3\Office14\WINWORD.EXE]
HKCR\Applications\winword.exe\shell\open\command        [* failed *]

Messy, right? Now trying to find the editor elsewhere...

Registry HKCU   $edi            "D:\masm32\qeditor.exe" "%1"
Registry HKLM   $edi            No luck in HKLM...
Registry HKCR   $edi            "D:\masm32\qeditor.exe" "%1"
Registry HKCR   $edi            "D:\masm32\qeditor.exe" "%1"

FileWrite
$esi            C:\Users\User\Desktop\~tmp25081536.asm
$edi            D:\masm32\qeditor.exe

Your Masm32 root        $M32$           D:\masm32\
Your asm files editor   $edi            D:\masm32\qeditor.exe

One thing I found, once you pick a program not in the "open with" dialog it gets added to HKCR\Applications\the.exe\shell\open\command.
That makes it available in other "open with" dialogs without having to browse. Handy to know.

Alex, so it was there instead of here  :biggrin:
jj needs a refresher on using the url tag...
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Magnum on August 25, 2013, 05:41:50 PM
I see that some Volks ask for extra free stuff when your programs are already free.

Jeez.

Your patience is admirable.

Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on August 25, 2013, 06:53:52 PM
Thanxalot, John, that was very helpful :t

Version 5 attached, with testbeds included - just click the "Try one more" link in MbGuide.rtf.

Quote from: sinsi on August 25, 2013, 04:23:50 PM
...
FileWrite
$esi            C:\Users\User\Desktop\~tmp25081517.asm
$edi            C:\Windows\system32\NOTEPAD.EXE

After installing masm32, same as above ---------------------------------------------------------------------------

After associating .asm with qeditor.exe ..
HKCR\.asm
default=[asm_auto_file]
HKCR\asm_auto_file\shell\Open\Command
default=["D:\masm32\qeditor.exe" "%1"]

HKCR\Applications\qEditor.exe\shell\open\command        ["D:\masm32\qeditor.exe" "%1"]
...
Registry HKCU   $edi            "D:\masm32\qeditor.exe" "%1"
Registry HKLM   $edi            No luck in HKLM...
Registry HKCR   $edi            "D:\masm32\qeditor.exe" "%1"
Registry HKCR   $edi            "D:\masm32\qeditor.exe" "%1"

FileWrite
$esi            C:\Users\User\Desktop\~tmp25081536.asm
$edi            D:\masm32\qeditor.exe
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Antariy on August 25, 2013, 08:34:36 PM
Version 5 did found MASM32 installation path, but also allowed to change the drive to be installed to, and successfully installed on a different drive :t
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on August 25, 2013, 09:20:54 PM
successful install   :t

the title bar is looking a lot better
however, if i move the mouse to a specific spot between items, the dropdown menu flashes in and out

for example, between Help and AutoCode, there is a spot where the Help menu is repeatedly shown and hidden
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on August 25, 2013, 09:46:26 PM
Quote from: dedndave on August 25, 2013, 09:20:54 PM
between Help and AutoCode, there is a spot where the Help menu is repeatedly shown and hidden

That's a known bug to be fixed soon :(

@Alex: The first line of the listbox ("matches") can be used to drag it. While the listbox has the focus, cursor left exits to found text, cursor right exits to findbox. One * as in mov*edx means "find mov and edx in the same line". More stars mean "extend search to n lines".
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on August 25, 2013, 10:18:16 PM
not trying to hurry you - lol
just wanted to help you wring out the bugzzz
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Antariy on August 25, 2013, 11:09:43 PM
Quote from: jj2007 on August 25, 2013, 09:46:26 PM@Alex: The first line of the listbox ("matches") can be used to drag it. While the listbox has the focus, cursor left exits to found text, cursor right exits to findbox. One * as in mov*edx means "find mov and edx in the same line". More stars mean "extend search to n lines".

Not drag - resize. When bottom edge of listbox is below or sometimes near of bottom edge of the screen, it is not resizable using top edge of a listbox.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: qWord on August 26, 2013, 12:06:55 AM
oh no, I'm excluded from the best lib on net  :(

BTW: eliFoTdaolnwoDLRU?
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on August 26, 2013, 03:13:43 AM
Quote from: qWord on August 26, 2013, 12:06:55 AM
oh no, I'm excluded from the best lib on net  :(

BTW: eliFo...

Obviously, you are not excluded ;-)
Title: Re: Fearless beta testers
Post by: jj2007 on August 26, 2013, 08:22:28 PM
Quote from: dedndave on August 25, 2013, 10:18:16 PM
not trying to hurry you - lol
just wanted to help you wring out the bugzzz

Thanxalot, Dave & Alex & Sinsi :icon14:

I fixed the flickering between the System Apps and Help menus, and a couple of other issues in File/New Masm source, and it should be fine now.

The installer is now on top of this thread. (http://masm32.com/board/index.php?topic=94.0)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on August 27, 2013, 02:21:11 PM
nice   :t
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: anta40 on August 27, 2013, 10:33:19 PM
Hi jj,

I got the "Oops! It seems that MasmBasic is not good for you.."

:icon_eek:
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on August 28, 2013, 03:22:52 AM
Quote from: anta40 on August 27, 2013, 10:33:19 PM
I got the "Oops! It seems that MasmBasic is not good for you.."

That's mean :biggrin:

What does the attached exe show as output?
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: anta40 on August 28, 2013, 04:08:33 AM
This is the output:
Quote
Registry HKCR
$edi            No luck in HKCR/App...
$Err$()         The operation completed successfully.

Registry HKCU   $edi            No luck in HKCU...
Registry HKLM   $edi            No luck in HKLM...
Registry HKCR   $edi            No luck in HKCR...

FileWrite
$esi            C:\Users\CSL-NB-064\Desktop\~tmp28080107.asm
$edi            C:\Program Files\Microsoft Visual Studio 11.0\Common7\IDE\devenv
.exe
Bye...
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on August 28, 2013, 05:51:53 AM
Quote from: anta40 on August 28, 2013, 04:08:33 AM
$edi            C:\Program Files\Microsoft Visual Studio 11.0\Common7\IDE\devenv

Ouch... that's a tough case 8)

I am really tempted to send you googling for Visual Basic, that's what you deserve :P
However, after several glasses of a good red wine I decided to give you a last chance - try again (http://masm32.com/board/index.php?topic=94.0) ;-)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: anta40 on August 28, 2013, 09:59:32 AM
OK, finally it asked for macros.asm
Seems to work, now  :biggrin:
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on August 28, 2013, 03:01:45 PM
Yeah :t
The problem is to find out on which drive the valid Masm32 installation sits (and there should be one, otherwise go google for VB, script kiddie :lol:)
So the installer checks for a qeditor installation, if that fails, it asks how asm files are being opened. And you open them with a prog outside the Masm32 path, that's why it failed. So I added the "last chance" ;)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on August 28, 2013, 10:21:03 PM
@echo off
for %%X in (D E F G H I J K L M N O P Q R S T U V W X Y Z) do if exist %%X:\masm32\qeditor.exe set MyDrive=%%X:\
MbInstall %MyDrive%


:P

i know - you don't want a batch file
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: qWord on August 29, 2013, 01:45:46 AM
Great, now I've got a "last" chance! However, a bit strange because I didn't realized that I've had any chance before that one ;)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on August 29, 2013, 03:31:44 AM
Quote from: dedndave on August 28, 2013, 10:21:03 PM
i know - you don't want a batch file

That's brute force, Dave :eusa_naughty:

Quote from: qWord on August 29, 2013, 01:45:46 AM
Great, now I've got a "last" chance! However, a bit strange because I didn't realized that I've had any chance before that one ;)

You found the elifo, so you had more than one chance ;-)

Update 30 August:
- default buffer for GetRegVal is now 128k
- The Gf...() family returns for index=-1 or no argument the values for the file identified by the last Exist():

GfSize, GfDate$, GfTime$, GfAgeHours, GfAgeMinutes, GfAgeMs, GfLastWrite
        GetFiles *.asm        ; get all sources in the current folder and its subfolders
        xchg eax, ecx        ; save #files
        For_ ebx=0 To ecx-1
                .if GfAgeHours(ebx)<=24                ; pick your latest code
                        mov esi, Cat$(Files$(ebx)+Space$(20))        ; we simulate LSET
                        Print Str$("\n#%i ", ebx+1), GfDate$(ebx), ", ", GfTime$(ebx), Spc2$, Str$("%i bytes", edx::GfSize(ebx))        ; edx::eax for QUADWORD size
                .endif
        Next
Rem        - all GetFiles special arrays return a DWORD in eax, except for GfLastWrite, which returns
          in xmm0 the ftLastWriteTime FILETIME member of the WIN32_FIND_DATA structure
        - GfSize returns the high quad in edx
        - Gf....(-1I or Gf...(), i.e. index -1 or no arg: all functions return data for the last Exist()
        - GfAge...() is calculated from the moment when GetFiles was launched, except for index=-1, which returns age
          relative to the time of the last Exist() call
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on September 27, 2013, 11:08:21 PM
Update 27 September 2013:
- Fixed a rare bug in Hex$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1198)
- Clip$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1099): the optional parameter is now working properly
- QSort (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1175) works now also for dynamic string arrays
- ShEx for those who can't memorise the 5 ShellExecute args (=myself :biggrin:)

include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Dim My$()        ; create a dynamic string array
  xor ecx, ecx
  .Repeat
        Let My$(ecx)=Str$("String %i", Rand(20)+1000)
        inc ecx
  .Until ecx>=20
  QSort My$()                ; sort all elements allocated so far
  For_ ebx=0 To ecx-1
        PrintLine Str$("Line %i =\t", ebx), My$(ebx)
  Next

  if 0        ; New: ShellExecute for dummies
        FileWrite "~tmp.txt", Cat$("Hello, it's "+Time$)        ; create a text file
        ShEx "~tmp.txt"        ; you can add e.g. SW_MAXIMIZE if needed
  endif

  Exit
end start
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on October 02, 2013, 06:42:00 PM
i know this isn't where it started....

but, Bresenham circles are pretty simple
if you develop an ASM algo, you can plot 8 points with each calculation
for elipses, 4 points - and a little "flip" on the second group of octets

maybe some day, i will play with a full set of Bresenham lines and conics   :P
but, this will get you started...

http://people.cs.uchicago.edu/~kaharris/15200/Labs/lab3/circle.html (http://people.cs.uchicago.edu/~kaharris/15200/Labs/lab3/circle.html)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on October 02, 2013, 08:10:10 PM
Quote from: dedndave on October 02, 2013, 06:42:00 PM
but, Bresenham circles are pretty simple

You are the expert :t

But are they simpler than this? Or at least faster, in case it matters??

; This application draws a circle to the console
include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0) the library
  Init
  Enum 24:xScale, 16:yScale         ; define width and height of the circle
  push 0        ; start with zero degrees
  .Repeat
        fld FP4(0.0174533)        ; load 360/(2*PI)
        fimul stack        ; multiply with decimal degrees
        fsincos        ; get sinus and cosinus simultaneously
        push yScale        ; create a stack slot containing the vertical scale
        fimul stack        ; cosinus * yScale
        fistp stack        ; save to...
        pop eax        ; ... eax
        push xScale        ; create a stack slot with the horizontal scale
        fimul stack        ; sinus * xScale
        fistp stack        ; save to...
        pop ecx        ; ... ecx
        add eax, yScale+2
        add ecx, xScale+3
        Locate(ecx, eax)
        Print "#"
        inc stack
  .Until stack>=360        ; loop until the circle is complete
  pop eax        ; restore stack balance
  Locate(xScale/2+7, yScale/2+9)
  ConsoleColor cRed
  Inkey "Masm32 is great"
  Exit
end start
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on October 02, 2013, 08:17:58 PM
i would guess faster
well - in the old days, they were much faster
don't really know how they compare since ~P4 era
Title: Bresenham circle needs a SQRT?
Post by: jj2007 on October 03, 2013, 08:00:13 AM
Bresenham circle needs a SQRT, right?

Intel(R) Celeron(R) M CPU        420  @ 1.60GHz (SSE3)
loop overhead is approx. 188/100 cycles

6678    cycles for 100 * Sqrt
11083   cycles for 100 * fsincos

6670    cycles for 100 * Sqrt
11072   cycles for 100 * fsincos
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on October 03, 2013, 08:38:34 AM
the whole idea behind Bresenham is to use integers, as opposed to floating point math

here is some decent "pseudo-code"
of course, you wouldn't want to use SetPixel
better to calculate DIB section addresses

int x,y,d,r;
y=r;
putpixel(x,y,1);
d=(3-2*r);
while(x<=y)
{
    if(d<=0)
        d += (4*x+6);
    else
    {
        d = d+4*(x-y)+10;
        y--;
    }
    x++;
    putpixel(x,y,1);
    putpixel(-x,y,1);
    putpixel(x,-y,1);
    putpixel(-x,-y,1);
    putpixel(y,x,1);
    putpixel(-y,x,1);
    putpixel(y,-x,1);
    putpixel(-y,-x,1);
}


http://www.asksatyam.com/2011/01/bresenhams-circle-algorithm_22.html (http://www.asksatyam.com/2011/01/bresenhams-circle-algorithm_22.html)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on October 03, 2013, 05:05:56 PM
Quote from: dedndave on October 03, 2013, 08:38:34 AM
the whole idea behind Bresenham is to use integers, as opposed to floating point math

here is some decent "pseudo-code"

int x,y,d,r;
y=r;
  <<<<<<<<<<<< assigns garbage

Doesn't fly. But I found one that works great, see attachment (you may have to maximise the console).

For BASIC illiterates: The only MasmBasic instruction is Locate() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1039). If you have a decent Locate macro yourself, you can do it with Masm32 only.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on October 03, 2013, 05:46:45 PM
i would assume "y" and "r" are initialized with the radius

not sure how you got bresenham.asm to assemble
end start
start is not defined - i am guessing at the Init call
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on October 03, 2013, 06:04:32 PM
Quote from: dedndave on October 03, 2013, 05:46:45 PM
not sure how you got bresenham.asm to assemble
Don't be shy, it's just a library, like Masm32 ;-)

Quoteend start
start is not defined - i am guessing at the Init call
Good guess :t
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on October 03, 2013, 06:20:59 PM
the reason for it not assembling being "start" is undefinded   :P
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on October 08, 2013, 09:25:41 PM
Update 8 October 2013 (download (http://masm32.com/board/index.php?topic=94.0)):

1. Some improvements of the DDE interface to Excel. Inter alia, there is a new xlsRC$() macro:
  xlsRC$(1, 2) returns "R1C2"

  See detailed example (http://masm32.com/board/index.php?topic=2421.0).

2. Win$() can now take as second argument the ID of a child window:

include \masm32\MasmBasic\MasmBasic.inc
  Init                       
  Launch "Notepad.exe \Masm32\include\bignumsdk.inc", SW_MINIMIZE
  Delay 200                ; give Notepad 200 ms to get ready
  .if WinByTitle("bignumsdk.inc - Note")
        xchg eax, ecx                ; ecx is the parent, 15 is the ID of the Notepad edit control
        wPrint "Content=", wTb$, wWin$(ecx, 15)        ; delete the w if you prefer ANSI
        ConsoleColor cYellow
        wInkey wCrLf$, "Title=", wWin$(ecx)
        invoke SendMessage, ecx, WM_CLOSE, 0, 0        ; close Notepad window
  .else
        Inkey "Notepad not ready - increase the delay?"
  .endif
  Exit
end start


3. GSL (GNU Scientific Library) example updated (see \Masm32\MasmBasic\GNUSCLIB\DLL\GslExample.asc)

4. New If_ ... Then ... macro (for details see this thread (http://masm32.com/board/index.php?topic=2439.0)):
  If_ ebx==123 Then inc ebx : dec eax : call mytest
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on October 11, 2013, 09:22:25 AM
Update 10 October (download (http://masm32.com/board/index.php?topic=94.0)):
RichMasm can now handle a collection of snippets in one file, as in the attached file containing 40 examples of simple console mode code. In the editor, it is sufficient to select the Init of any examples and then hit F6 to assemble, link & run the example.

EDIT: See update in Reply #147
Title: FolderOpen$()
Post by: jj2007 on October 19, 2013, 01:23:04 AM
Update 18 October (download (http://masm32.com/board/index.php?topic=94.0)):

1. Analogous to FileOpen$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1031), MasmBasic has now a comfortable wrapper for SHBrowseForFolder called FolderOpen$():

include \masm32\MasmBasic\MasmBasic.inc        ; RichMasm: select Init and hit F6 to test the examples
  Init                          ; FolderOpen$(prompt [, title] [, path] [, BIF flags])
  Let esi=FolderOpen$()        ; no args = use Windows defaults, start with current folder
  Print "Selected: [", esi, "]", CrLf$        ; if the user cancelled, esi will be an empty string
  PrintLine "Selected: ", FolderOpen$("Pick a folder:", "Masm32 is great")        ; a prompt and a nice title, start with current folder
  PrintLine "Selected: ", FolderOpen$("Pick a folder:",, "\Masm32\Examples")        ; just a prompt, default title, specific folder
  PrintLine "Selected: ", FolderOpen$("9Pick a big folder:")                ; a big prompt (font 9), default title, current folder
  ; prompt, title, path with environment variables, flags
  Let esi=FolderOpen$("What is the edit box for?","Locate Office:", "%ProgramFiles%\Microsoft Office", BIF_USENEWUI)
  PrintLine esi
  PrintLine "Selected folder=[", FolderOpen$("Where are your tools?",, "D:\Masm32\bin"), "]"        ; fully qualified initial path
;   if you need to check whether the user cancelled, use void and check the zero flag:
  void FolderOpen$("5Pick the bin folder, please:","Getting help", "\Masm32\bin")        ; use current drive plus initial path
  .if !Zero?
        MsgBox 0, Launch$(Cat$(eax+"\link.exe /Lib")), "Library manager help:", MB_OK
  .else
        PrintLine "Nothing selected: [", eax, "]"        ; Zero? set = user cancelled, eax points to a Null$
  .endif
  Exit
end start


2. Minor bugfix: Str$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1186)() can now also handle LARGE_INTEGER values properly.

3. See also Monitoring WM_nnnn messages (http://masm32.com/board/index.php?topic=2479.0).

P.S.: There is a pretty fat and pretty stupid SHBrowseForFolder bug in Windows 7 (http://social.msdn.microsoft.com/Forums/vstudio/en-US/a22b664e-cb30-44f4-bf77-b7a385de49f3/shbrowseforfolder-bug-in-windows-7?forum=vcgeneral). Grateful for feedback if FolderOpen$() works properly on all Windows versions from XP upwards. XP and Win7-32 seem to work AFAIK.
Title: SHBrowseForFolder bug
Post by: jj2007 on October 19, 2013, 03:24:55 AM
Quote from: TWell on October 19, 2013, 02:49:45 AMIf you can give that MamBasic in zip package without installer, i may test it.
I made the installer precisely because many people have forgotten how to extract an archive properly. The installer creates one folder (\Masm32\MasmBasic) and does not modify the registry.

What do you typically do if Adobe or Microsoft or Sun ask you to run a *.msi file? Do you have any reason to trust me less than, ehm, Microsoft?

Quote
Quote from: jj2007 on October 19, 2013, 01:23:04 AM
P.S.: There is a pretty fat and pretty stupid SHBrowseForFolder bug in Windows 7 (http://social.msdn.microsoft.com/Forums/vstudio/en-US/a22b664e-cb30-44f4-bf77-b7a385de49f3/shbrowseforfolder-bug-in-windows-7?forum=vcgeneral). Grateful for feedback if FolderOpen$() works properly on all Windows versions from XP upwards. XP and Win7-32 seem to work AFAIK.
What problem ?
That example code works in my Win7 32/64-bit

Just google for SHBrowseForFolder bug in Windows 7 - many hits, and most mention that it does "not always" scroll down. Your code works fine on XP, can't test it on Win7 right now, but I have seen the no-scroll problem often enough in action on Win7. Need an official Microsoft site? BFFM_SETSELECTION does not work with SHBrowseForFolder on Windows 7 (http://connect.microsoft.com/VisualStudio/feedback/details/518103/bffm-setselection-does-not-work-with-shbrowseforfolder-on-windows-7)
Title: Re: SHBrowseForFolder bug
Post by: TWell on October 19, 2013, 04:09:05 AM
Quote from: jj2007 on October 19, 2013, 03:24:55 AM
Just google for SHBrowseForFolder bug in Windows 7 - many hits, and most mention that it does "not always" scroll down. Your code works fine on XP, can't test it on Win7 right now, but I have seen the no-scroll problem often enough in action on Win7. Need an official Microsoft site? BFFM_SETSELECTION does not work with SHBrowseForFolder on Windows 7 (http://connect.microsoft.com/VisualStudio/feedback/details/518103/bffm-setselection-does-not-work-with-shbrowseforfolder-on-windows-7)
Thanks for that link, now i see that problem, it starts showing from Destop and selected folder isn't visible as in WinXP, so no scrolling to that.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: dedndave on October 19, 2013, 04:17:44 AM
the MasmBasic installer is benign - and a good way to go
it can be a little confusing to install it manually
Title: Re: SHBrowseForFolder bug
Post by: jj2007 on October 19, 2013, 08:33:56 AM
Quote from: TWell on October 19, 2013, 05:54:44 AMHere is code example to fix that problem:

Thanks, I know that example, and I wouldn't have posted a new MasmBasic version if I had not already fixed the problem. Still, grateful for feedback if MB OpenFolder$() works, because I took a slightly different road (the code you posted failed occasionally on my Win7-32 system).

Attached an exe for testing. The source is lines 372ff of MbFuide.rtf (also included, you have it already at \Masm32\MasmBasic\MbGuide.rtf in case you downloaded MasmBasic (http://masm32.com/board/index.php?topic=94.0)).
Title: Re: SHBrowseForFolder bug
Post by: TWell on October 19, 2013, 07:22:57 PM
Quote from: jj2007 on October 19, 2013, 08:33:56 AM
Still, grateful for feedback if MB OpenFolder$() works, because I took a slightly different road (the code you posted failed occasionally on my Win7-32 system).

Attached an exe for testing. The source is lines 372ff of MbFuide.rtf (also included, you have it already at \Masm32\MasmBasic\MbGuide.rtf in case you downloaded MasmBasic (http://masm32.com/board/index.php?topic=94.0)).
OpenFolder works nicely in Win7 64-bit.
Avast don't let me download that zip.

BYE
Title: Setting multiple clipboard entries
Post by: jj2007 on October 24, 2013, 09:24:04 AM
Major update of MasmBasic, 24 October 2013 (download (http://masm32.com/board/index.php?topic=94.0)):

1. Put multiple formats on the clipboard (full example attached, MS Word should be running):

        SetClip #start        ; ---- set multiple clipboard formats ----
        SetHtmlClip$ "Text in <font color='blue'>HTML</font> format"        ; for Thunderbird and Excel
        SetClip 100, CF_BITMAP        ; 100 = ID of bitmap resource
        SetClip$ offset txTest, CF_RTF        ; Rich Text Format
        SetClip$ wRes$(123)        ; use resource string #123, "This is a sub-title" in Russian (Unicode)
        SetClip$ "This is ANSI text"
        SetClip #end        ; ---- end of multiple clipboard formats ----

2. Improved DDE to Excel macros, inter alia for writing Unicode (the real thing, e.g. Chinese etc from resources), pasting HTML format etc. - screenshot (example attached) below.(http://www.webalice.it/jj2006/pics/Masm2Excel.png)

P.S.: The attached MbSnippets.asc, when opened in \Masm32\MasmBasic\RichMasm.exe, allows to build & run over 40 "snippets", i.e. short examples showing what the MB macros can do. Just click one of the Init entries in the listbox (or select an Init by hand), then hit F6 to see the result. Test it, for example, with the ## Unicode with wRes$ ## snippet in line 468.
Title: StackBuffer()
Post by: jj2007 on October 30, 2013, 11:05:27 AM
Update 30 October 2013 (download (http://masm32.com/board/index.php?topic=94.0)):

StackBuffer
        MyTest proc uses edi esi ebx arg1:DWORD, arg2:RECT
        LOCAL rc:RECT, sbuf1, sbuf2, sbuf3, whatever[100]:BYTE
         ; optional: ClearLocals        ; first line after the LOCALs
          mov sbuf1, StackBuffer(100000)        ; allocate two fat buffers, and make sure
          mov sbuf2, StackBuffer(4000h)        ; they are 16-byte aligned for use with SSE2
          invoke GetFileSize, hFile, 0        ; you may use a register or any other variable to specify the buffer size
          mov sbuf3, StackBuffer(eax, nz)        ; option nz means "no zeroing" - much faster (the buffer end is zeroed anyway)
          PrintLine "Start buffer 1:", Tb$, Hex$(sbuf1)
          PrintLine "Start buffer 2:", Tb$, Hex$(sbuf2)
          StackBuffer()        ; release all buffers (sb without args = free the buffer)
          ret
        MyTest endp

Rem     - buffer size is limited by start address of stack; normally, you can use close to one MB
        - the start address is aligned to 64 bytes for use with SIMD instructions
        - you can use StackBuffer anywhere (not only at proc start & end), but make sure esp is unchanged
        - StackBuffer zero-inits the buffer, unless option nz is specified (much faster)
        - with option nz, only the end of the buffer (+/- 2 bytes, one DWORD) is zeroed
        - can be combined with ClearLocals
        - StackBuffer does the stack probing for you; up to about half a megabyte, it is significantly faster than HeapAlloc


EDIT: Version MbSetup30Oct2013d.zip fixes a problem with the Launch$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1047) timeout. In the new version, Launch$() throws an error when there is no read activity for more than n milliseconds, which is a better behaviour with apps that give slow feedback in bits and pieces, e.g. zippers or even ML.exe (the old Launch$() version stopped when the timeout was reached overall).

Example:
a) slowly printing app:
include \masm32\MasmBasic\MasmBasic.inc
  Init
  push 15
  .Repeat
        Print Str$("sp%i ", stack)
        mov ecx, 100
        .if stack==5 || stack==10
                mov ecx, 2000        ; the app "chokes" two seconds with element 5+10
        .endif
        invoke Sleep, ecx
        dec stack
  .Until Sign?
  Print "BYE", 13, 10        ; No inkey, please
  Exit
end start


b) Launcher:
include \masm32\MasmBasic\MasmBasic.inc
  Init

  PrintLine "## Launch Nr. 1 ##"
  Let esi=Launch$("SlowPrint", SW_RESTORE, 1000)        ; SlowPrint is an app that ... prints slowly
  PrintLine "First attempt, timeout=1000: ", Tb$, esi

  PrintLine "## Launch Nr. 2 ##"
  Let esi=Launch$("SlowPrint", SW_RESTORE, 1500)
  PrintLine "Second attempt, timeout=1500: ", Tb$, esi

  PrintLine "## Launch Nr. 3 ##"
  Let esi=Launch$("SlowPrint", SW_RESTORE, 2000)
  Inkey "Third attempt, timeout=2000: ", Tb$, esi

  Exit
end start


Output:
## Launch Nr. 1 ##
First attempt, timeout=1000:    La$?
## Launch Nr. 2 ##
Second attempt, timeout=1500:   La$?
## Launch Nr. 3 ##
Third attempt, timeout=2000:    sp15 sp14 sp13 sp12 sp11 sp10 sp9 sp8 sp7 sp6 sp5 sp4 sp3 sp2 sp1 sp0 BYE
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Farabi on November 08, 2013, 05:39:13 PM
 :t Impressive, it become more and more usefull. I'll use MASM BASIC started from now and forever.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: Farabi on November 08, 2013, 06:16:32 PM
What does it is mean ? "D:\Masm32\Include\MasmBasic.inc(168) : error A2052: forced error"
My other project did not yield this error, what causing it?
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on November 08, 2013, 11:39:16 PM
Quote from: Farabi on November 08, 2013, 06:16:32 PM
What does it is mean ? "D:\Masm32\Include\MasmBasic.inc(168) : error A2052: forced error"
My other project did not yield this error, what causing it?

Hi Farabi,

What else does the error message say? To which source code line does it refer? Can you post these lines (+/- 10 lines)?

There are several "forced" errors in the library, some because you can't use the old ML 6.14 assembler, others because of syntax problems...
Title: Bug warning
Post by: jj2007 on November 10, 2013, 12:35:55 PM
There was a nasty little bug since the introduction of ArraySet (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1129)():

include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Dim My3Pts(5) As REAL4        ; create an array with 3 XY pairs, i.e. 6 elements (0 .. 5)
  ArraySet My3Pts() = 1.0, 100.0, 2.0, 300.0, 4.0, 150.0        ; assign XY values
  Inkey "ok"
  Exit
end start


The macro started one step above its HeapAlloc'ed area, and thus on rare occasions could cause an exception. This bug showed up with REAL4 and REAL8 but not with DWORD arrays.

Apologies - it's fixed now, download here (http://masm32.com/board/index.php?topic=94.0)

Other changes concern only DosBasic (http://masm32.com/board/index.php?topic=1855.0), the little 16-bit brother of MasmBasic.
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on November 11, 2013, 10:16:52 AM
A small addition for version 11.11.2013 (download (http://masm32.com/board/index.php?topic=94.0)): CL$(?) returns the number of commandline arguments.
Note that CL$(0), i.e. the name of the executable, is not counted here, which is a minor inconsistency with regard to
  Dim My$(9)
  Print Str$("There are %i elements in the array\n", My$(?))
returning There are 10 elements in the array, i.e. 0...9
Title: Qtrim$, Extract$()
Post by: jj2007 on December 11, 2013, 10:16:31 AM
Update 11 December 2013:

- a completely redesigned installer (well, under the hood ;))

- Qtrim$():
        Let My$=Qtrim$(Chr$(9, '  "quoted"  ', 13, 10))        ; returns quoted
        Let My$=Qtrim$(CL$())                ; same for complete quoted commandline

- Extract$() has a new flag, xsEscape, meaning translate \n to CrLf and \t to a tab:
  ; exclude left pattern, case-insensitive, trim whitespace, right pattern is default aka CrLf; in short: grab the line after =
  xsDefault=xsExcL or xsCaseI or xsTrim or xsEscape
  Let Title$=Extract$(esi, "title=")

.. where esi is a buffer containing this text:

This is a simple text file, and we want to extract the part below after "=":
Title=Hello\nWorld\nhow are you?
Let title$=Extract$(esi, "Title") will yield only the hello world part (in three lines), provided the right flags are set. For details, see \Masm32\MasmBasic\MbGuide.rtf


Several new snippets were added, see attachment. When opened with RichMasm, each of them can be built and run by selecting Init and hitting F6. This works also when the Find string is Init, and the user selects one of the entries in the listbox. In a way, this is multiple projects in a single source file ;)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: anta40 on December 11, 2013, 12:59:12 PM
Hi jj,

I think there's a bug with the installer.
After I selected C:\masm32\macros\macros.asm, I could see this on the installer:

"The MasmBasic library will be installed to La$?"

"Can't create destination folder
La$?"
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on December 11, 2013, 05:12:01 PM
Hi anta,

"La$?" is what Launch$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1047)("whatever.exe") returns if whatever.exe hangs and/or a timeout occurs. Apparently the default timeout is too short - I will fix this asap.

Thanks a lot for the feedback,
jj

EDIT: It's fixed, see version 11 Dec 2013b
Title: Bug in Str$() - and workaround
Post by: jj2007 on December 15, 2013, 09:50:37 AM
There is a problem with Str$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1186) when used with .data section arrays - it will not digest e.g. Str$(MyArray[3*REAL8]):

include \masm32\MasmBasic\MasmBasic.inc

.data
MyArray        REAL8 1.23, 4.56, 7.89, 9.87

  Init

  Print Str$("Element 0 is %3f\n", MyArray)        ; Str$(REAL8_var) works, but only for element zero

  el1 equ MyArray[1*8]        ; workaround for other elements - no <brackets> please
  Print Str$("Element 1 is %3f\n", el1)

  mov ecx, offset MyArray+1*REAL8        ; use a register to access array elements
  Print Str$("Element 2 is %3f\n", real8 ptr [ecx+8])        ; OK if exactly one blank between ptr and [

  ; no problems with Basic-style arrays (byte/word/dword/qword/R4/r8/r10):
  Dim MyR8(3) As REAL10        ; create an array of long doubles (same for REAL4, REAL8)
  fldpi
  fstp MyR8(3)                ; put PI into element 3
  Print Str$("Element 3 is %Jf\n", MyR8(3))

  Inkey "ok"
  Exit
end start


I had found a fix, but unfortunately it chokes with JWasm, so for the time being, and if you really need it, use the equate.
Title: Printing unsigned LONGLONG variables
Post by: jj2007 on December 23, 2013, 02:54:37 AM
With MasmBasic of 22 December 2013, you can print unsigned qwords like 12345678901234567890:

include \masm32\MasmBasic\MasmBasic.inc  ; download (http://masm32.com/board/index.php?topic=94.0)
MyLongLong    LONGLONG    12345678901234567890
MyDword       LONG        1234567890
MyWord        WORD        12345
MyByte        BYTE        123
MySingle      REAL4       12345678901234567890.0
MyDouble      REAL8       12345678901234567890.0
MyR10         REAL10      1234567890123456789012.0

  Init                        ; ## deb and the Art of Type Checking ##
  mov eax, MyDword
  mov bx, MyWord
  mov cl, MyByte
  fldpi                         ; PI, 3.14159
  fldl2e                        ; Log2(e), 1.4427
  fldlg2                        ; Log10(2), 0.3013
  movlps xmm0, MyLongLong
  movlps xmm1, MyDouble
  DefNum 16                ; set precision (only f:xmm1 affected)
  deb 4, "Any type missing?", u:MyLongLong, u:xmm0, f:xmm1, ST(0), ST(1), ST(2), MyDword, MyWord, MyByte, cl, bx, eax, MySingle, MyDouble, MyR10
  Exit
end start


Output:

Any type missing?
u:MyLongLong    12345678901234567890
u:xmm0          12345678901234567890
f:xmm1          1.234567890123457e+19
ST(0)           0.301029995663981195
ST(1)           1.44269504088896341
ST(2)           3.14159265358979324
MyDword         1234567890
MyWord          12345
MyByte          123
cl              123
bx              12345
eax             1234567890
MySingle        1.234568e+19
MyDouble        1.234567890123457e+19
MyR10           1.23456789012345679e+21


This example is included in the attached MbSnippets.asc
Title: Arrays: Insert and Delete
Post by: jj2007 on December 28, 2013, 10:10:32 AM
MasmBasic 28 Dec 2013 supports Insert and Delete for numerical arrays:

  Init                        ; we create several numeric arrays,
  Dim MyByte() As BYTE        ; from byte to ...
  Dim MyWord() As WORD
  Dim MyDw() As DWORD
  Dim MyQw() As QWORD        ; ... qword
  Dim MyRc() As RECT        ; any other structure would work, too
  Dim My$()                ; plus one string array

  call FillTheArrays        ; fill the arrays with some nice values
  call PrintTheArrays        ; display the original values
  xor ecx, ecx                ; we test different index positions:
  Delete MyQw(ecx)        ; 0        reg32
  Delete MyDw(ecx+1)        ; 1        reg plus offset
  Delete MyWord(gct2)        ; 2        global var
  Delete MyByte(3)        ; 3        immediate
  Delete MyRc(ecx+4)        ; 4
  Delete My$(ecx+3)        ; 3
  PrintLine CrLf$, "Elements 0 1 2 3 4 3 deleted:"
  call PrintTheArrays        ; display the modified arrays


Output:
   Qword             Dword    Word Byte rcLeft   rcBottom (8 elements)
0  00000000 00000000 00000000 0000 00   00000000 1000   String #0
1  11111111 11111111 11111111 1111 11   11111111 1001   String #1
2  22222222 22222222 22222222 2222 22   22222222 1002   String #2
3  33333333 33333333 33333333 3333 33   33333333 1003   String #3
4  44444444 44444444 44444444 4444 44   44444444 1004   String #4
5  55555555 55555555 55555555 5555 55   55555555 1005   String #5
6  66666666 66666666 66666666 6666 66   66666666 1006   String #6
7  77777777 77777777 77777777 7777 77   77777777 1007   String #7

Elements 0 1 2 3 4 3 deleted:
   Qword             Dword    Word Byte rcLeft   rcBottom (8 elements)
0  11111111 11111111 00000000 0000 00   00000000 1000   String #0
1  22222222 22222222 22222222 1111 11   11111111 1001   String #1
2  33333333 33333333 33333333 3333 22   22222222 1002   String #2
3  44444444 44444444 44444444 4444 44   33333333 1003   String #4
4  55555555 55555555 55555555 5555 55   55555555 1005   String #5
5  66666666 66666666 66666666 6666 66   66666666 1006   String #6
6  77777777 77777777 77777777 7777 77   77777777 1007   String #7
7  00000000 00000000 00000000 0000 00   00000000 0

Elements 3 4 5 6 7 6 inserted:
   Qword             Dword    Word Byte rcLeft   rcBottom (8 elements)
0  11111111 11111111 00000000 0000 00   00000000 1000   String #0
1  22222222 22222222 22222222 1111 11   11111111 1001   String #1
2  33333333 33333333 33333333 3333 22   22222222 1002   String #2
3  00000000 00000000 44444444 4444 44   33333333 1003   String #4
4  44444444 44444444 00000000 5555 55   55555555 1005   String #5
5  55555555 55555555 55555555 0000 66   66666666 1006   String #6
6  66666666 66666666 66666666 6666 00   77777777 1007
7  77777777 77777777 77777777 7777 77   00000000 0      String #7


Testbed attached (*.asc opens with \Masm32\MasmBasic\RichMasm.exe)
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on January 08, 2014, 10:29:10 AM
Update 8 January 2014: (http://masm32.com/board/index.php?topic=94.0)

- fixed a problem with MyNumericArray(?) and non-autoexpanding arrays (when used with ArrayRead (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1179), ? erroneously returned the initial count only)
- fixed a problem with Str$() and signed QWORDs
- introduced the option to leave a MovVal (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1203) result on the FPU in ST(0):
  MovVal ST(0), "3.141592653589793238"
Title: Re: MasmBasic - a fast and easy-to-use library
Post by: jj2007 on January 11, 2014, 01:31:44 PM
Update 11 January (http://masm32.com/board/index.php?topic=94.0) fixed a minor problem with Trim$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1164) and introduced voidTrue and voidFalse macros (see Assert (http://masm32.com/board/index.php?topic=2831.0) and \Masm32\MasmBasic\MbGuide.rtf):

include \masm32\MasmBasic\MasmBasic.inc     ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Dim My$()                                 ; create a string array
  mov ecx, Chr$("          Hello ")         ; you can't use eax or edx ...
  Let My$(0)=Trim$(ecx)                     ; ...  when assigning to an array,
  Let My$(1)=Str$(123)+Trim$(ecx)+Str$(456) ; but ecx is persistent
  Inkey "My$(0)=[", My$(0), "]", CrLf$, "My$(1)=[", My$(1), "]"
  Exit
end start

Output:
My$(0)=[Hello]
My$(1)=[123Hello456]
Title: PeekNamedPipe better than WaitForSingleObject?
Post by: jj2007 on January 14, 2014, 12:38:23 PM
It seems so :P

I've been fighting with pipes for a while, and google says I'm in good company - it's messy. After a lot of testing, it seems PeekNamedPipe is the best way to decide when to leave the read loop, so the new Launch$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1047) uses this internally.

The sample below launches a console app that returns strings unsteadily, i.e. normally it takes around 50ms to see the next output, but occasionally it chokes for a whole second. This is a typical behaviour e.g. of archivers, and the coder must impose a timeout to decide if the delay is OK or if the child process hangs. In other words, the third arg of Launch$() is now the tolerated inactivity period:

include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0)
  Init

  PrintLine "## Launching SlowPrint.exe ##"        ; slowprint.exe must be in the same folder
  Let esi=Launch$("SlowPrint", SW_MINIMIZE, 1000)        ; max allowed inactive period of child process is 1000ms
  PrintLine Str$("\nFirst attempt, timeout=1000: exit code=%i\n", ExitCode($)), "Output:", Tb$, esi

  Let esi=Launch$("SlowPrint", SW_MINIMIZE, 1020)
  PrintLine Str$("\nSecond attempt, timeout=1020: exit code=%i\n", ExitCode($)), "Output:", Tb$, esi

  Let esi=Launch$("SlowPrint", SW_MINIMIZE, 1040)
  PrintLine Str$("\nThird attempt, timeout=1040: exit code=%i\n", ExitCode($)), "Output:", Tb$, esi, CrLf$

  Inkey "bye"
  Exit
end start

Output:
## Launching SlowPrint.exe ##

First attempt, timeout=1000: exit code=259
Output: La$?

Second attempt, timeout=1020: exit code=0
Output: sp15 sp14 sp13 sp12 sp11 sp10 sp9 sp8 sp7 sp6 sp5 sp4 sp3 sp2 sp1 sp0 2656 ms

Third attempt, timeout=1040: exit code=0
Output: sp15 sp14 sp13 sp12 sp11 sp10 sp9 sp8 sp7 sp6 sp5 sp4 sp3 sp2 sp1 sp0 2656 ms
Title: 50+ snippets
Post by: jj2007 on January 16, 2014, 09:07:56 PM
MasmBasic update of 17 January: (http://masm32.com/board/index.php?topic=94.0)

The snippets file is now integrated into the package, see the "try 50+ snippets" link in the Hello World example.

Latest feature is a much easier handling of strings (e.g. paths) in structures:

include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0)

MyStruct STRUCT
  xText20$       db 20 dup(?)       ; 20 bytes of text
  xDword         dd ?               ; a dword, just for fun
  xText4$        db 4 dup(?)        ; more text
  xText1$        db 1 dup(?)        ; and one byte of text
MyStruct ENDS

.data?
myS        MyStruct <>
  Init
  ; assign strings with Let:
  Let myS.xText20$="This string can take a maximum of 20 chars"
  Let myS.xText4$="That one can take only 4 chars"
  Let myS.xText1$="1 char only..."
  ; print the strings:
  PrintLine "{", myS.xText20$, "}"
  PrintLine "{", myS.xText4$, "}"
  Print "{", myS.xText1$, "}"
  Exit
end start

Output:
{This string can take}
{That}
{1}


EDIT: Now it works also for structures defined with SetGlobals (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1015).

include \masm32\MasmBasic\MasmBasic.inc

PATHS STRUCT
path1        db MAX_PATH dup(?)
path2        db MAX_PATH dup(?)
PATHS ENDS

  SetGlobals MyPaths:PATHS             ; define a global structure

  Init
  SetGlobals                           ; let ebx point to the global memory
  mov ecx, CurDir$(0)                  ; get the current folder (0=no backslash)
  Let MyPaths.path1=ecx
  Let MyPaths.path2=MbExeFolder$       ; assign the folder from which the exe was started
  PrintLine "Path1=", MyPaths.path1
  Inkey "Path2=", MyPaths.path2
  Exit
end start
Title: RegEdit won't tell you when a key was last modified
Post by: jj2007 on January 24, 2014, 03:12:02 AM
But MasmBasic will :biggrin:

include \masm32\MasmBasic\MasmBasic.inc  ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi="HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion"
  PrintLine "Checking ", esi
  GetRegKeyArray esi, Lev1$(), LastMod1()
  For_ ecx=0 To eax-1
  .if Age(LastMod1(ecx), d)<=31  ; changed in the last 31 days
      Print Str$("\nKey %i\t", ecx), fDate$(LastMod1(ecx)),\
       ", ", fTime$(LastMod1(ecx)), Tb$, "[", Lev1$(ecx), "]"
      GetRegKeyArray Cat$(esi+"\"+Lev1$(ecx)), Lev2$(), LastMod2()
      For_ ebx=0 To eax-1
        .if Age(LastMod2(ebx), h)<=24*3  ; changed in the last 3 days
            Print CrLf$, "- ", Tb$, fDate$(LastMod2(ebx)),\
            ", ", fTime$(LastMod2(ebx)), Tb$, Lev2$(ebx)
        .endif
      Next
    .endif
  Next
  Exit
end start


Sample output:

Checking HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion

Key 7   23.01.2014, 07:11:19    Explorer
Key 10  23.01.2014, 15:27:22    Group Policy
-       23.01.2014, 15:42:00    Regedit
-       23.01.2014, 11:35:39    SysTray
Key 11  23.01.2014, 07:11:30    HomeGroup
Key 13  08.01.2014, 07:11:42    Internet Settings
Key 18  23.01.2014, 14:08:57    Run
Key 19  23.01.2014, 07:11:20    RunOnce


Source & exe attached - the very latest version of MasmBasic is required.

EDIT: Typo Lev1$(ebx) corrected - it must be Lev1$(ecx), of course.
Title: Nested For ... Next loops
Post by: jj2007 on January 25, 2014, 02:17:03 PM
Update 25 January: For ... Next loops will now not enter the first iteration if begin>end, in line with (most if not all) other Basic dialects. Example (from \Masm32\MasmBasic\Res\MbSnippets.asc):

include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0)
  Init                        ; ## nested For ... Next loops ##
  mov eax, 3
  For_ ebx=0 To eax-1        ; 0...2 (using eax is allowed here)
        ; first iteration is 1 to 0 and will be rejected (2*ebx=0, 2, 4, ...)
        For_ ecx=1 To ebx+ebx
                call MyTest
        Next
        Print
  Next
  Inkey "ok"
  Exit

MyTest proc
LOCAL ct
  For_ ct=0 To 9
        Print "*"
  Next  ct
  Print Str$("\tebx=%i, ", ebx), Str$("ecx=%i\n", ecx)
  ret
MyTest endp
end start

Output:

++++++++++      ebx=1, ecx=1
++++++++++      ebx=1, ecx=2

++++++++++      ebx=2, ecx=1
++++++++++      ebx=2, ecx=2
++++++++++      ebx=2, ecx=3
++++++++++      ebx=2, ecx=4
Title: Re: MasmBasic
Post by: jj2007 on January 31, 2014, 10:24:23 AM
31 January 2014 - improved Dll & Declare:

include \masm32\MasmBasic\MasmBasic.inc                ; include this library
.data
MyLongLong        LONGLONG 12345678901234567890
        Init                                        ; initialise the app

        Dll "shimgvw"                ; load the Windows Picture and Fax Viewer Library
        Declare void ImageView_Fullscreen, 4                ; ImageView_Fullscreen expects 4 dwords but returns nothing useful, therefore void
        ImageView_Fullscreen(0, 0, wCL$(1), SW_SHOW)        ; we need the wide version of the commandline arg
        Err$(1)                                ; there is no retval, so we have to test for errors

        Dll "msvcr100"
        Declare void printf, C:?        ; don't return anything, C calling convention, vararg
        printf(cfm$("MyLongLong is %llX aka %llu\n"), MyLongLong, MyLongLong)        ; MyLL as hex and decimal figure
        Print "MyLongLong is ", Hex$(MyLongLong), Str$(" =  %u\n", MyLongLong)        ; standard MasmBasic syntax, for comparison

        Dll "NtDll"
        Declare RtlRandomEx, 1                ; one arg, _Inout_  PULONG Seed

        Dll "ntoskrnl.exe"
        Declare RtlRandomExNtos, 1 Alias "RtlRandomEx"        ; same but native API - will crash in user mode
        PrintLine "A random number: ", Hex$(RtlRandomEx(addr MyLongLong))

        Exit                        ; do a clean exit, inter alia FreeLibrary
end start

        - Dll performs LoadLibrary, Declare initialises the macro with GetProcAddress, Exit frees the libraries
        - use Declare void SomeFunction, ... if you don't need the return value
        - use Declare SomeFunction, C:3 for C calling convention with three args
        - use Declare SomeFunction, C:? for C calling convention with a variable number of arguments
        - the Alias keyword allows to declare a self-defined name; use in case of "already defined" errors
        - use Declare #123=SomeFunction, 2 to access a function by ordinal number; then mov ecx, SomeFunction(arg1, arg2)
        - if the function cannot be found, try the decorated name:
                Declare _SomeFunction@12, C:3        ; three args, C calling convention
                then use e.g. mov ecx, SomeFunction(arg1, arg2, arg3)
         - do not use Dll & Declare for the static libraries of the Masm32 package (user32, kernel32, ..., see Masm32rt.inc (http://\masm32\include\masm32rt.inc))
         - up to 9 libraries can be loaded
Title: Obscure a string
Post by: jj2007 on February 26, 2014, 10:25:59 AM
Update 26 February (download (http://masm32.com/board/index.php?topic=94.0)):
- Declare accepts now entire structures:
      Dll Cat$(MbExeFolder$+"ZipDll\Zip32")
      Declare ZpArchive, 1      ; the arg is a ZCL structure with three DWORDs


- the second new feature is in response to questions how to protect one's code. It concerns the RichMasm editor, which has a new entry in the Edit & Format menu:

include \masm32\include\masm32rt.inc

.code   ; You can bet that Olly cannot recognise the code sequence which creates this string!
start:
   exit

end start


Now select the "You can bet..." part and click on Edit & Format, Obscure string.
Result:
include \masm32\include\masm32rt.inc

.code      ; You can bet that Olly cannot recognise the code sequence which creates this string!
start:
; ---- start ----
      call @F
@obs$      dd 0DB771968h,0DB567E06h,0B2240A75h,09257631Dh,0E6771078h,09216750Ah,0F1361D69h,0985E6A49h,0FD3D042Ch,0884C615Fh,0A8290530h,
0CB096058h,0BF29052Bh,0D6476244h,0B5221064h,0C14D7E0Ah,0A02E5E73h,0CC421153h,0B8237927h,098571C45h,0B8397D26h,0984C127Fh
@@:      pop edx
      mov ecx, sizeof @obs$/4
      .Repeat
            mov eax, [edx]
            xor eax, [edx-4]
            add edx, 4
            push eax
            dec ecx
      .Until Zero?

      PrintLine esp        ; that one is for MasmBasic, but...
      print esp            ; ... Masm32 print works fine, too

      add esp, sizeof @obs$
; ---- end ----
      exit

end start


I guess the code is self-explanatory for those who need this feature :P
Title: Re: MasmBasic
Post by: hutch-- on February 26, 2014, 10:53:11 AM
You could try a tool in the masm32 bin directory called "mangle.exe". Once the string is assembled into the binary its a genuine joy to track it down.  :P
Title: Re: Obscure a string
Post by: jj2007 on February 26, 2014, 07:51:31 PM
Quote from: hutch-- on February 26, 2014, 10:53:11 AM
You could try a tool in the masm32 bin directory called "mangle.exe". Once the string is assembled into the binary its a genuine joy to track it down.  :P
It's in \Masm32, not in \bin, and it works fine :t
My code is shorter, though, and confuses Olly a lot more (and no need to mfree).

Attached a test piece. The exe has two int 3s for use with Olly or any other debugger.
The source requires MasmBasic (http://masm32.com/board/index.php?topic=94.0), of course.
Title: MasmBasic bugfix
Post by: jj2007 on March 01, 2014, 10:46:41 PM
Update 1 March with two minor bugfixes: (http://masm32.com/board/index.php?topic=94.0)
- Launch (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1045) could give a wrong ExitProcess return value
- buffers created with SetGlobals (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1015) choked when invoked as e.g. MsgBox 0, addr buffer, ...
Title: ArrayMerge Dest$(), Src$()
Post by: jj2007 on March 27, 2014, 03:13:28 PM
EDIT: Version SetupMasmBasic27March14.zip (http://masm32.com/board/index.php?topic=94.0) fixes a bug that prevented \Masm32\MasmBasic\Res\XlsViewer.asc to send text to Excel.

Update 27 March 2014:
- ArrayMerge does what the name says, it merges two string arrays:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init                  ; ## merge two string arrays ##
  Dim Dest$()
  Dim Src$()
  xor ecx, ecx
  .Repeat
      Let Dest$(ecx)=Str$("Destination #%i", ecx)
      Let Src$(ecx)=Str$("Source #%i", ecx)
      inc ecx
  .Until ecx>=5
  ArrayMerge Dest$(), Src$()
  push Dest$(?)      ; put the new element counter on the stack
  xor ecx, ecx
  .Repeat
      Print Str$("\n#%i\t", ecx), Dest$(ecx)      ; see dest 0...4, then source 0...4
      inc ecx
  .Until ecx>=stack
  pop eax
  Exit
end start


Output:
#0      Destination #0
#1      Destination #1
#2      Destination #2
#3      Destination #3
#4      Destination #4
#5      Source #0
#6      Source #1
#7      Source #2
#8      Source #3
#9      Source #4


- Str$() can now handle leading spaces or zeros:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init                  ; ## leading spaces for Str$() ##
  Print Str$("\nA number: %__i", 1)
  Print Str$("\nA number: %__i", 12)
  Print Str$("\nA number: %__i", 123)
  Print Str$("\nA number: %000i", 1)
  Print Str$("\nA number: %000i", 12)
  Print Str$("\nA number: %000i", 123)
  Exit
end start

Output:
A number:   1
A number:  12
A number: 123
A number: 0001
A number: 0012
A number: 0123
Title: Re: MasmBasic
Post by: sinsi on April 12, 2014, 10:27:40 PM
Installing the latest version
Title: Re: MasmBasic
Post by: sinsi on April 12, 2014, 10:38:32 PM
I see the menu problem is still there, in my case the text is yellow and unreadable.
Clicking one seems to stop it from working from then on too, unless you click another menu..
Title: Re: MasmBasic
Post by: jj2007 on April 12, 2014, 10:46:32 PM
The crash box is the equivalent to MS Word auto recovery. It happens when user exited an edit session in an, ehm, unusual way. Normally it shouldn't happen, RichMasm is pretty stable, but a forced reboot could cause that, for example. Or killing the editor with Task Manager. I usually click Yes.

Re menus, yes the yellow-brownish font was the compromise for Vista Aero, and I also don't like it. Do the menus work at least? And can you reproduce the hanging?
Title: SetLaunchTimeout
Post by: jj2007 on April 15, 2014, 08:27:27 AM
Update 15 April (download here (http://masm32.com/board/index.php?topic=94.0)):
QuoteLaunch
...
- the default timeout for a "normal" Launch is ten seconds; if you mostly need asynchronous launches,
  you can modify this value with e.g. SetLaunchTimeout 1 (in ms)

And this solved also the little problem with the ten seconds "hanging" of RichMasm (http://masm32.com/board/index.php?topic=3108.0) ;-)
Title: Windows Safer
Post by: jj2007 on April 18, 2014, 09:29:40 AM
Update 18 April (http://masm32.com/board/index.php?topic=94.0) features some improvements of the registry functions:
- SetReg64 allows to read the registry on a 64-bit system
- GetRegVal (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1214) returns now
  1. a pointer to the string or the data in eax
  2. the type (REG_DWORD ...) in edx
  3. REG_QWORD values in xmm0; same for the first 16 bytes of REG_BINARY
- finally, xmm0 is now a valid argument for the fDate$() and fTime$() macros.

Below an example which reads the "Safer" keys and displays first the "official" LastModified value, and second, the real modification date and time as reported by the registry's timestamp.

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi="HKLM\SOFTWARE\Policies\Microsoft\Windows\Safer\CodeIdentifiers\0\Hashes\"
  GetRegKeyArray esi, My$(), LastMod()
  .if eax
      push eax

      xor ecx, ecx
      PrintLine esi, CrLf$, "... modified according to LastModified value:"
      .Repeat
            ; GetRegVal returns the LastModified REG_QWORD in xmm0:
            void GetRegVal(Cat$(esi+My$(ecx)), "LastModified", 0)
            PrintLine fDate$(xmm0, "dd MMMM yyyy   "), Tb$, fTime$(xmm0), Spc2$, My$(ecx)
            inc ecx
      .Until ecx>=stack

      xor ecx, ecx
      PrintLine CrLf$, "Hashes modified according to registry timestamp:"
      .Repeat
            PrintLine fDate$(LastMod(ecx), "dd MMMM yyyy   "), Tb$, fTime$(LastMod(ecx)), Spc2$, My$(ecx)
            inc ecx
      .Until ecx>=stack

      pop eax
  .endif
  Inkey Str$("\n%i keys found\n", eax)
  Exit
end start


Source & exe attached. The second attachment (RADAR (http://windowsir.blogspot.it/2011/09/registry-stuff.html)) lists all software on your PC that suffered from a heap leak. Very interesting, but it works only on Windows 7 and higher, so right now I can't test it. Please post some example output :icon_mrgreen:
Title: Re: MasmBasic
Post by: sinsi on April 18, 2014, 10:00:47 AM
QuotePlease post some example output
0 keys found
0 keys found

:biggrin:
Title: RADAR
Post by: jj2007 on April 18, 2014, 03:44:17 PM
Hi sinsi,

Yesterday I tested it on Win7, and got the Who's Who of the software industry, Acrobat.exe on top... do you see HKLM\SOFTWARE\Microsoft\RADAR\HeapLeakDetection\DiagnosedApplications\ in regedit, or is it simply absent?

But wait - you are on Win8-64, right? This could do the trick:

  Init
  SetReg64
  Let esi="HKLM\SOFTWARE\Microsoft\RADAR\HeapLeakDetection\DiagnosedApplications\"
  GetRegKeyArray esi, Radar$(), Modified()


Modified package attached.

BTW first tests with SetReg64 failed miserably until I discovered that KEY_WOW64_32KEY was 100h, not 100 as set in Windows.inc (see also Don57,
windows.inc KEY_WOW64_32KEY def'n error (http://masm32.com/board/index.php?topic=1404.0))
Title: Re: MasmBasic
Post by: sinsi on April 18, 2014, 03:51:29 PM
 :t
HKLM\SOFTWARE\Microsoft\RADAR\HeapLeakDetection\DiagnosedApplications\
... modified according to Modifiedified value:
03 March 2014           00:00:00  BurnoutParadise.exe
14 May 2013     05:14:28  CNC4.game
21 January 2014         03:50:13  CoDWaW LanFixed.exe
04 August 2013          23:56:45  DllHost.exe
03 February 2014        01:05:19  eduke32.exe
01 April 2014           08:45:25  firefox.exe
09 February 2014        11:13:45  GasGuzzlers.exe
15 September 2013       08:33:07  IEXPLORE.EXE
27 June 2013    09:35:22  Need for Speed The Run.exe
07 January 2014         06:52:41  NFS11.exe
05 April 2014           06:26:25  NFS13.exe
20 November 2013        05:35:14  shift2u.exe
22 December 2013        00:19:09  simnow.exe
30 April 2013           08:29:50  Stronghold3.exe
10 April 2014           06:43:19  TiWorker.exe

15 keys found
Title: Re: RADAR
Post by: jj2007 on April 18, 2014, 03:55:06 PM
Thanks :biggrin:

Nice to see two competing browsers here. Would be even nicer to see how much they are leaking ;-)

01 April 2014           08:45:25  firefox.exe
15 September 2013       08:33:07  IEXPLORE.EXE
Title: Re: MasmBasic
Post by: Gunther on April 18, 2014, 10:38:03 PM
Jochen,


HKLM\SOFTWARE\Microsoft\RADAR\HeapLeakDetection\DiagnosedApplications\
... modified according to Modifiedified value:
06 Februar 2014         00:00:00  ChessProgram13.exe
16 Januar 2014          19:00:27  firefox.exe
07 Oktober 2013         00:06:34  FlashPlayerPlugin_11_8_800_168.exe
12 Januar 2014          16:20:51  FlashPlayerPlugin_11_9_900_170.exe
17 Februar 2014         23:10:44  FlashPlayerPlugin_12_0_0_44.exe
02 April 2014           11:19:31  FlashPlayerPlugin_12_0_0_77.exe

6 keys found


Gunther
Title: Re: RADAR
Post by: jj2007 on April 19, 2014, 08:25:29 PM
Thanks. Gunther. How dare you run such old versions of Flash?? I haven't rebooted my machine today, but I am sure Adobe has a better version for us, with better performance and less risks, grosses Indianerehrenwort ;-)

Here results from a rarely used notebook with no Internet connection:

HKLM\SOFTWARE\Microsoft\RADAR\HeapLeakDetection\DiagnosedApplications\
... modified according to ModifiedValue:
05 January 2014         00:00:00  firefox.exe
20 March 2014           17:31:46  InsertDeleteNumArrays.exe
10 November 2012        23:13:25  OllyDbg.exe
04 January 2014         20:15:58  svchost.exe_netsvcs
10 November 2012        20:37:00  TrustedInstaller.exe

Hint: One of these leaky apps is from a well-known hobby coder testing his library ;-)
Title: Re: MasmBasic
Post by: hutch-- on April 19, 2014, 08:35:50 PM
 :biggrin:

Flash is not the problem I have, its the McCafee crap that is bundled with it. I have to uninstall it every time Flash wants an upgrade.
Title: Re: MasmBasic
Post by: Gunther on April 19, 2014, 09:03:29 PM
Quote from: hutch-- on April 19, 2014, 08:35:50 PM
:biggrin:
Flash is not the problem I have, its the McCafee crap that is bundled with it. I have to uninstall it every time Flash wants an upgrade.

that is the point.

Gunther
Title: Bug warning
Post by: jj2007 on April 22, 2014, 08:24:45 PM
ArrayMerge had a problem with differently sized arrays. It is fixed in version 22 April 2014. (http://masm32.com/board/index.php?topic=94.0)

The code below will now work correctly.

include \masm32\MasmBasic\MasmBasic.inc
  Init                  ; ## merge two string arrays ##
  Dim Dest$()
  Dim Src$()
  xor ecx, ecx
  .Repeat
      .if ecx<3
            Let Dest$(ecx)=Str$("Destination #%i", ecx)
      .endif
      Let Src$(ecx)=Str$("Source #%i", ecx)
      inc ecx
  .Until ecx>=10
  ArrayMerge Dest$(), Src$()
  push Dest$(?)      ; put the new element counter on the stack
  xor ecx, ecx
  .Repeat
      Print Str$("\n#%i\t", ecx), Dest$(ecx)      ; see dest 0...2, then source 0...9
      inc ecx
  .Until ecx>=stack
  pop eax
  Exit
end start


Output:
#0      Destination #0
#1      Destination #1
#2      Destination #2
#3      Source #0
#4      Source #1
...
#12      Source #9
Title: ArraySet
Post by: jj2007 on April 25, 2014, 09:26:18 AM
Version 25 April supports ArraySet (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1129) for strings and numerical arrays.
Excerpt from MbSnippets.asc:

include \masm32\MasmBasic\MasmBasic.inc
  Init                 
  PrintLine "ArraySet strings:"
  ArraySet My$() = "These", "are", "four", "strings"
  Let My$(My$(?))="Only strings support"      ; My$(?) is the current number
  Let My$(My$(?))="dynamic expansion"         ; of elements in the array
  For_ ecx=0 To My$(?)-1
      PrintLine Str$(ecx), Tb$, My$(ecx)
  Next
  PrintLine CrLf$, "Same with numerical arrays:"  ; could be DWORD, REAL4, REAL8
  Dim MyNum(5) As DWORD      ; create an array with 6 elements (0 .. 5)
  ArraySet MyNum() = 11, 22, 33, 44, 55, 66      ; assign values
  xor ecx, ecx
  .Repeat
      Print Str$(MyNum(ecx)), Spc2$
      inc ecx
  .Until ecx>=MyNum(?)
  Exit
end start

Output:

ArraySet strings:
0       These
1       are
2       four
3       strings
4       Only strings support
5       dynamic expansion

Same with numerical arrays:
11  22  33  44  55  66
Title: Bugfix
Post by: jj2007 on May 31, 2014, 09:26:45 AM
Version 31 May 2014 (download (http://masm32.com/board/index.php?topic=94.0)) fixes an odd bug: I had built the tinf.lib used for the new UnzipFile function with /subsystem:CONSOLE, so all code using tinf had a console window, including the spreadsheet viewer (http://masm32.com/board/index.php?topic=3231.0).

The new UnzipFile decompresses zipped files to a buffer; more in \Masm32\MasmBasic\MbGuide.rtf

Check also the improved QSort function; it allows now to sort string matrices by column, as demonstrated in the spreadsheet viewer.
Title: Re: MasmBasic
Post by: jj2007 on June 05, 2014, 09:02:04 AM
Update 5 June (download) - the unzipper is now even simpler to use:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  UnzipInit "\Masm32\MasmBasic\Res\UnicodeTest.zip"
  ; now restore the first file, and don't forget the timestamp
  FileWrite Files$(0), UnzipFile(0), GfLastWrite(0)
  UnzipExit      ; cleanup
  Exit
end start


It handles Unicode file names, and you can retrieve the optional comment, too.
Full example here (http://masm32.com/board/index.php?topic=3215.msg34107#msg34107).
Title: Bugfix
Post by: jj2007 on June 19, 2014, 06:26:00 PM
Tonight's version of MasmBasic had a little bug in the deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019) macro:

include \masm32\MasmBasic\MasmBasic.inc     
  Init
  MovVal f:xmm1, "12345678901234567890"
  deb 1, "Result", f:xmm1
  Exit
end start


You have the latest version with the bugfix if the box displays
Result     f:xmm1          1.234567890123457e+19

If you see any other number, download the latest version here. (http://masm32.com/board/index.php?topic=94.0)

For latest additions, see True Unicode (http://masm32.com/board/index.php?topic=3310.0) in the Campus.
Title: Re: MasmBasic
Post by: sinsi on June 19, 2014, 06:48:45 PM
Downloaded and installed a version 12 hours ago, all OK.
Saw the new version, downloaded and installed OK until the very end showing RichMasm

Faulting application name: RichMasm.exe, version: 0.0.0.0, time stamp: 0x53a20f44
Faulting module name: RichMasm.exe, version: 0.0.0.0, time stamp: 0x53a20f44
Exception code: 0xc0000005
Fault offset: 0x0000ff0c
Faulting process ID: 0x1940
Faulting application start time: 0x01cf8b99d380e62d
Faulting application path: C:\Masm32\MasmBasic\RichMasm.exe
Faulting module path: C:\Masm32\MasmBasic\RichMasm.exe
Report ID: 130f4421-f78d-11e3-bfda-bc5ff496160b
Faulting package full name:
Faulting package-relative application ID:

Title: Re: MasmBasic
Post by: jj2007 on June 19, 2014, 10:28:57 PM
Thanks for the feedback, Sinsi. If the offset means "from entry", then it is pcmpeqb xmm0, xmmword ptr [edx] in MbStrLen. So a nullpointer was passed ::)

I always wonder what a len() routine should return if a nullpointer is passed. Zero maybe? Minus one??

Which Windows version was that? Anybody else having the same problem?
Title: SetGlobals
Post by: jj2007 on July 02, 2014, 08:27:42 AM
The SetGlobals (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1015) macro allows now to initialise DWORD, WORD, REAL4, REAL8 and string variables in the declaration:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  SetGlobals v1=123456789, MyFile$="SomeTest.txt", v2
  SetGlobals MyR4:REAL4=123456.789012345678, MyR8:double=123456.789012345678
  SetGlobals v3:WORD=12345, v4

  Init
  SetGlobals            ; no args = load ebx, initialise variables
  Print "MyFile$=", MyFile$, CrLf$
  Print Str$("V1=%i", v1), Str$(", v3=%i\n", v3)
  Print Str$("R4=%If\n", MyR4)
  Print Str$("R8=%If\n", MyR8)
  Exit
end start

String variables must have the '$' suffix. In the first call of the .code section (i.e. the line below Init), SetGlobals without arguments initialises these variables.

EDIT: Update 3 July fixed a very odd bug: Recall (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172), when reading an ANSI file that had Unicode embedded, had extremely long strings containing the Unicode parts; that may happen if you saved an inc file as Unicode, and afterwards you create e.g. with copy *.inc AllIncludes.txt a file that will have, oops, an embedded Unicode part. The BadLines variable can be used to test this:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
      Init
      Recall "\Masm32\include\AllIncludes.txt", L$()
      ExternDef BadLines:DWORD
      Print Str$("%i lines, of which ", eax), Str$("%i badly formatted", BadLines)
      Exit
end start


In the new version, the array will simply contain Unicode strings where Recall found them; no more obscure crashes, but still, garbage in, garbage out...
Note that Recall has no problems with regular Unicode files - it returns the string array in UTF-8 format (and you can use wRec$(My$(123)) if you need UTF-16, e.g. for menus).
Title: Re: MasmBasic
Post by: guga on August 02, 2014, 10:27:19 AM
Hi JJ

not sure if you are aware of this small bug on masmbasic, but with winXP SP3, the menus text are being detached when you resize the window.

To see the error, you need to open masmbasic and then press the mouse upon a windows and drag it vertically.
1st - Double click the window to you be able to drag it
2nd one the window is not maximixed, click on the title bar with the left button pressed and drag the window

(http://i62.tinypic.com/e8pjt4.jpg)
Title: Re: MasmBasic
Post by: jj2007 on August 02, 2014, 04:29:47 PM
Hi Gustavo,

It's a feature, not a bug ;-)

On my machines (Win XP, W7-32, 2*W7-64) it works, though. The menus get detached while dragging or resizing but follow some milliseconds later. Strange that for you it's different.

The background for this strange feature is

a) Aero (not allowing drawing directly on the caption) and

b) the fact that assembly is a "vertical" language, with one short instruction per line: I didn't want to sacrifice a line for a stupid standard menu.

Besides, the menu activates itself without clicking, like most browser menus nowadays.

Still, I am curious why the menu stays put in the middle of the desktop in your case... ::)
Title: Re: MasmBasic
Post by: guga on August 02, 2014, 06:57:41 PM
A feature ? Hmm..interesting...I never used aero before to see what exactly it is.

But...since this is the normal behavior, son´t worry...the menus on the middle of the desktop goes back to the original position after a few time (milliseconds, in fact)....I took the screenshot pressing "PrintScreen" thinking it was a bug to show you, because i didn´t found other way to explain.

But...do aero works on XP ? I would like to see what is this feature. It is unusual, but, interesting.
Title: Re: MasmBasic
Post by: jj2007 on August 02, 2014, 08:15:16 PM
No aero on XP. It was introduced with Vista, but it seems not very popular. Most people I know reverted to the classic non-aero themes. Don't even know if it still exists on Win8.

BTW the editor is not needed to assemble MasmBasic code, but it has some nice features. For example, load a big source (>10,000 lines), select a global variable like "buffer" and hit F3...
Title: Find duplicate files on disk
Post by: jj2007 on August 18, 2014, 07:27:55 AM
Just for fun, a 40 lines app to find duplicate files, starting from the current folder:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi=CurDir$()+"*.*"
  .While 1
      Let esi=Input$("\nEscape+Return to quit\nEnter path & wildcards:\t", esi)      ; e.g. C:\Masm32\*.*
      .Break .if !Len(esi)            ; user pressed Escape
      .if !Instr_(esi, "*")
            PrintLine "Unrestricted search not allowed"
      .else
            GetFiles esi
            .if eax
                  push eax
                  Print Str$("%i files found\n\n", eax)
                  xor ecx, ecx
                  .Repeat
                        mov edi, Files$(ecx)
                        mov ebx, Rinstr(edi, "\")            ; let's move the name part to the front for sorting
                        .if ebx
                            Let Files$(ecx)=Mid$(edi, ebx+1)+Tb$+GfDate$(ecx)+Spc2$+GfTime$(ecx)+Spc2$+Str$(GfSize(ecx))+Spc2$+Left$(edi, ebx)
                        .endif
                        inc ecx
                  .Until ecx>=stack
                  SortFiles name, asc            ; sort by name, ascending
                  xor ecx, ecx
                  Let ebx="#"            ; no such file
                  .Repeat
                        mov edi, Files$(ecx)
                        .if Instr_(ebx, Left$(edi, Instr_(edi, Tb$)), 1)==1
                            PrintLine CrLf$, edi, CrLf$, ebx
                        .endif
                        Let ebx=Files$(ecx)
                        inc ecx
                  .Until ecx>=stack
                  pop eax
            .endif
      .endif
  .Endw
  Print "bye"
  Exit
end start
Title: Re: MasmBasic
Post by: Gunther on August 19, 2014, 05:17:02 AM
Jochen,

nice little application. I've no redundancy on my machine.  :lol:

Gunther
Title: Re: MasmBasic
Post by: jj2007 on August 20, 2014, 08:01:33 AM
Quote from: Gunther on August 19, 2014, 05:17:02 AM
nice little application. I've no redundancy on my machine.  :lol:

Thanks, Gunther.

Update 20 August (here (//http://)):

- GfSetInfo allows to copy a file's timestamp and size to another element of the Files$() array generated by GetFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1056), or time & size of the last match of Exist(); example:

GfSetInfo 1, GfLastWrite(-1)      ; set Files$(1) to Exist() time and size
Destination is an element of Files$(), source is either Files$ (index 0 ... n) or the last match of Exist (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1049)() with index -1.

- wChr$() can now have embedded zeros:
mov esi, wChr$("All files", 0, "*.*", 0)

This allows to avoid a bug in LoadStringW when loading a resource string with trailing zeros. (http://masm32.com/board/index.php?topic=3509.msg36865#msg36865).

- the menus of RichMasm are now better aligned, see Pelles C (http://forum.pellesc.de/index.php?topic=6370.0)
Title: WM_DROPFILES handler
Post by: jj2007 on August 25, 2014, 09:23:14 AM
  CASE WM_DROPFILES
            GetFiles WM_DROPFILES      ; put dropped files into the Files$() array
            push eax
            Let esi=Str$("%i files and folders dropped:", eax)
            xor ecx, ecx
            .Repeat
                  void Rinstr(Files$(ecx), "\")      ; strip the path: Rinstr() returns absolute pos in eax (and relative pos in edx)
                  lea edi, [eax+1]
                  Let esi=esi+Str$("\n%i\t", GfSize(ecx))+GfDate$(ecx)+Spc2$+GfTime$(ecx)+Tb$+edi      ; size, date, time and filename
                  inc ecx
            .Until ecx>=stack
            pop eax
            SetWin$ hEdit=esi                 


Sample output:
7 files and folders dropped:
0       13.01.2012  19:59:15   procs
0       13.01.2012  19:59:14   tutorial
0       13.01.2012  19:59:14   tools
65536   17.08.2014  15:04:04   uniedit.exe
5598    17.08.2014  04:13:03   AllFiles.zip
22528   17.08.2014  00:40:24   topgun.exe
37376   17.08.2014  00:25:44   qeditor.exe


Full source attached, requires MasmBasic of 25 August 2014 (http://masm32.com/board/index.php?topic=94.0).
Title: Re: MasmBasic
Post by: Gunther on August 26, 2014, 02:08:24 AM
Good idea, Jochen. Thanks.  :t

Gunther
Title: MasmBasic bug fixes
Post by: jj2007 on September 22, 2014, 08:05:55 AM
Version 22 Sept 14 (download (http://masm32.com/board/index.php?topic=94.0)):

- BUGFIX: Val (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1202)("12.34.56") returns now correctly 12.34
- BUGFIX: StringsDiffer (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1157) used wrong location to test the case-insensitive flag

- New feature: Now dialogs (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1012) close apart from IDOK and IDCANCEL also for IDs 100...120, and return the ID

Title: FileRead$("http://...")
Post by: jj2007 on October 05, 2014, 12:50:06 PM
Bugfix 5 October (download (http://masm32.com/board/index.php?topic=94.0)):

For a while, the FileRead$() function had "forgotten" how to read a file from the Internet - sorry :redface:

Now the snippet below works again. It downloads an attachment from this forum, checks the zip directory for the first *.asm file, and displays the first 1.8 k on the screen:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  ; assign contents of a well-known file to esi:
  Let esi=FileRead$("http://masm32.com/board/index.php?action=dlattach;topic=49.0;attach=30")
  FileWrite "tmp.zip", esi, LastFileSize      ; write contents to a temporary file
  UnzipInit "tmp.zip"      ; expects a filename, returns a comment (if present)
  .if Sign?
      Print eax      ; print an error message
  .else
      For_ ecx=0 To edx-1      ; #files returned in edx
            mov esi, Files$(ecx)
            .if Instr_(esi, ".asm", 1)      ; assembler source, plain text?
                PrintLine "## First 1800 chars of ", esi, " ################# : ", CrLf$, Left$(UnzipFile(ecx), 1800), " ..."
            .endif
      Next
      UnzipExit
  .endif
  Inkey "## Cute, isn't it? #################"
  Exit
end start
Title: Menus with tooltips
Post by: jj2007 on October 15, 2014, 09:18:42 AM
MasmBasic update of 15 October (download) concerns mainly improvements of the editor:

- plugins don't need to be registered in the menus.ini file, it is sufficient to build them in the plugin folder
- all menus allow now tooltips, as shown below; for plugins, they can be defined in the source using txName db "name in menu§description of\nthe plugin", 0
Title: Bugfix for MasmBasic
Post by: jj2007 on October 27, 2014, 10:24:20 AM
I know it's hard to believe but YES, MasmBasic had a bug: wLeft$/wRight$/wMid$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1159) didn't work :redface:

The Ascii versions were ok but the wide (Unicode) versions returned drastically shortened strings. No idea when this regression crept in but now it's fixed (http://masm32.com/board/index.php?topic=94.0). Test it e.g. with the "talk to Excel" example in \Masm32\MasmBasic\Res\Masm2ExcelCircle.asc, line 39:

      xlsFormat CF_UNICODETEXT      ; back to Unicode
      wPrint "Cur selection", wTb$, wMid$(xlsRead$(), 16), wCrLf$      ; get current selection, strip the string "Real Unicode":


Note that in order to see the Unicode strings returned by Excel properly, you need to set the console font to Lucida Console (in the console window's system menu, properties, font).

Other good news is that UnzipFile() (see \Masm32\MasmBasic\MbGuide.rtf - based on JibZ' Tiny Inflate Library (http://www.ibsensoftware.com/download.html)) is now twice as fast (the bad news is I had to abandon Pelles C to achieve that :().
Title: MasmBasic thread-safe?
Post by: jj2007 on November 10, 2014, 12:52:49 PM
Update 10 November: Launch$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1047) is now thread-safe. This was never a problem in console apps, but GUI apps could occasionally choke. It's fixed.

Other changes:
- Dll (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1017) accepts now environment variables such as %ProgramFiles% - works with non-English Windows versions, ok for Win7-64:

  Dll "%ProgramFiles%\FreeArc\Addons\InnoSetup\unarc"

- Err$() allows an optional text, and instead of throwing a runtime error, you can programmatically check the availability of a DLL or certain functions inside a DLL:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  DllRTE=1             ; 1=throw runtime error if LoadLibrary fails (default), 0=no runtime error, check eax instead
  Dll "shimgvw"        ; load the shell image view dll aka Windows Picture and Fax Viewer Library
  DecRTE=0             ; 1=throw runtime error if GetProcAddress fails (default), 0=check eax instead
  Declare void ImageView_Fullscreen, 4            ; ImageView_Fullscreen expects 4 dwords but returns nothing useful
  .if eax
      ImageView_Fullscreen(0, 0, wCL$(1), SW_SHOW)      ; we need the wide version of the commandline arg
      Err$(0, "ImgView:")            ; there is no retval - you may test here for errors
      ; Err$(0, L)            ; same but titled "Error in line xx:"
  .else
      PrintLine "Problem with procedure: [", Trim$(Err$()),"]"            ; use Err$() without args for printing
  .endif
  Exit
end start
Title: Re: MasmBasic
Post by: Gunther on November 10, 2014, 11:35:52 PM
Jochen,

Quote from: jj2007 on November 10, 2014, 12:52:49 PM
Update 10 November: Launch$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1047) is now thread-safe. This was never a problem in console apps, but GUI apps could occasionally choke. It's fixed.

well done.  :t

Gunther
Title: Unicode file I/O
Post by: jj2007 on November 17, 2014, 12:04:39 PM
The MasmBasic update of 17 November (download (http://masm32.com/board/index.php?topic=94.0)) features a number of improvements under the hood, in particular an almost fool-proof handling of Unicode filenames. Example:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi=wCL$()
  .if wExist(esi)
      wOpen "I", #1, esi
      wLet edi=Input$(#1, Lof(#1))
      Close
      wMsgBox 0, edi, wCat$("Contents of "+LastFileName$+":"), MB_OK
  .else
      wMsgBox 0, esi, "No such file:", MB_OK
  .endif
  Exit
end start


Among other improvements, MasmBasic's preferred editor, \Masm32\MasmBasic\RichMasm.exe, can now build directly with non-Latin alphabets:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  uMsgBox 0, "Добро пожаловать", "Hi", MB_OK
  Exit
end start
Title: Re: MasmBasic
Post by: Gunther on November 19, 2014, 04:05:05 AM
Jochen,

your Russian is getting better and better.  :t And MasmBasic, too. That's clear.

Gunther
Title: Russian & Unicode
Post by: jj2007 on November 19, 2014, 05:19:46 AM
Quote from: Gunther on November 19, 2014, 04:05:05 AMyour Russian is getting better and better.  :t And MasmBasic, too. That's clear.

Gunther,
Thanks :P
I use Russian for Unicode demos because the font is installed on most machines (unlike Chinese, for example), but as a matter of fact, I did speak Russian when I was young. Now I've forgotten everything, since I never practised it seriously.
Title: Re: MasmBasic
Post by: habran on November 19, 2014, 07:03:39 AM
I know the filling, I used to speak German when I was young but when I come to Australia(1992) I was mixing German with English, so I had to push the German somewhere deep in my memory and now it is hard to dig it out :biggrin:
Title: Re: MasmBasic
Post by: Gunther on November 19, 2014, 07:57:23 AM
Jochen,

Quote from: jj2007 on November 19, 2014, 05:19:46 AM
I use Russian for Unicode demos because the font is installed on most machines (unlike Chinese, for example), but as a matter of fact, I did speak Russian when I was young. Now I've forgotten everything, since I never practised it seriously.

Интересно, так что вы не говорите по-русски.

Gunther
Title: Callback for GetFolders() and GetFiles()
Post by: jj2007 on December 06, 2014, 01:05:24 PM
Update of 6 December:

GfCallback defines a callback function to monitor progress in GetFiles or GetFolders:

      include \masm32\MasmBasic\MasmBasic.inc
      Init      ; <<< select init and hit F6 to test this snippet
      Let esi=ExpandEnv$("%WINDIR%")      ; usually C:\Windows
      PrintLine "Searching ", esi
      GfCallback cbGetFiles      ; define a callback function
      GetFolders esi
      Print Str$("\n%i folders found\n", eax)
      Exit

cbGetFiles:
      test edx, 1023      ; file or folder counter
      .if Zero?
            Print "*"      ; console mode progress bar ;-)
      .endif
      ret
      end start

Title: ToolTips, FileRead$(), GfCallback, Dim syntax
Post by: jj2007 on December 09, 2014, 11:13:46 AM
Minor fixes in MasmBasic version 9 December 2014 (download (http://masm32.com/board/index.php?topic=94.0))

- ToolTips (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1096) don't use edi ebx any more, i.e. you can use them in a loop; keep away from esi, though, and note that ecx will exceptionally be trashed here.

- the GetFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1056) GfCallback (examples (http://masm32.com/board/index.php?topic=3838.msg40571#msg40571)) gives access to WIN32_FIND_DATAW in ebx (edx=file counter, edi=last path of FindFirstFileEx)

- Dim (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1126) MyArray() As dword will choke now, and invite you to use uppercase DWORD (or BYTE, REAL8, whatever); note also that Dim without specifying the number of elements, i.e. Dim whatever() As WHATEVERSTRUCT is perfectly legal - same for strings and other types: MasmBasic arrays are dynamic. Just make sure you assign elements incrementally starting with zero, i.e. Let My$(0)="..." or mov MyRect(0, left)=123 etc

- FileRead$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1075) occasionally threw generic API errors when the file was not found; now it chokes correctly with "can't find thatfile.txt"
Title: Re: MasmBasic
Post by: jj2007 on December 16, 2014, 11:09:41 AM
Minor update of 16 December 2014 (download (http://masm32.com/board/index.php?topic=94.0))

One new feature: Extract$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1156) has a new flag called xsScan, which serves to extract substrings sequentially using the same delimiter to the left and right. Example:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi="My car,is,red,but, if it  ,was,  green,  I,  would,still,drive,it."
  .While 1
      .Break .if !Extract$(esi, ",", ",", xsScan or xsTrim)
      PrintLine "[", eax, "]"
  .Endw

  Inkey "ok?"
  Exit
end start


Output:
[My car]
[is]
[red]
[but]
[if it]
[was]
[green]
[I]
[would]
[still]
[drive]
[it.]
ok?
Title: Re: MasmBasic
Post by: Gunther on December 16, 2014, 08:37:36 PM
Interesting feature, Jochen.  :t Well done.

Gunther
Title: Files$() array from commandline
Post by: jj2007 on December 24, 2014, 11:14:07 AM
Update 24.12.2014 (download (http://masm32.com/board/index.php?topic=94.0)):

In addition to the standard file pattern, GetFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1056) can now take special arguments:

1. GetFiles <pattern>

  GetFiles *.asm           ; simple: puts all filenames from the current folder into the Files$() array
  GetFiles C:\Windows\System32\msvc*.dll|nt*.dll|nt*.exe
  SortFiles                ; sort the Files$() array by date, most recent files first
  For_ ebx=0 To eax-1      ; print the detailed results
      PrintLine Str$(GfSize(ebx)), Tb$, GfDate$(ebx), Spc2$, GfTime$(ebx), Tb$, Files$(ebx)
  Next



2. GetFiles CL (or GetFiles wCL for Unicode file names):

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  GetFiles CL              ; put filenames in the commandline into the Files$() array
  For_ ebx=0 To eax-1      ; print the results
      PrintLine Str$(GfSize(ebx)), Tb$, GfDate$(ebx), Spc2$, GfTime$(ebx), Tb$, "[", Left$(Files$(ebx), 90), "]"
  Next
  Inkey Str$("%i files found in commandline", ebx)
  Exit
end start



3. GetFiles WM_DROPFILES (in WndProc, main window must have WS_EX_ACCEPTFILES style):

  CASE WM_DROPFILES
      GetFiles WM_DROPFILES
      For_ ebx=0 To eax-1      ; show the files in the edit control
            AddWin$ hEdit=Str$(GfSize(ebx))+Tb$+GfDate$(ebx)+Spc2$+GfTime$(ebx)+Tb$+Files$(ebx)+CrLf$
      Next


#2 is handy when the user drags a group of files from Explorer over the name of the executable (i.e. the files are passed via the commandline).

#3 does the same but with files dropped over the window itself. During installation, you will see the MasmBasic guide; on top of the page, click on "File" to the left of the usual disclaimers apply, and choose "New Masm source". In the green window, click on Simple window in the upper left corner, hit F6 to build the application, then select files in Explorer and drag them over the application.
Title: Limitation of line length to 255 chars in MASM (but not JWasm)
Post by: jj2007 on December 26, 2014, 12:42:46 PM
The update fixed an issue with a limitation of the line length in ML (all versions), which caused cryptic error messages when the user tried to initialise many global variables. In addition, more types are now possible, also for Swap.

SetGlobals & Swap: C/C++ allows direct assigning of values to variables during their initialisation. Same applies to GfaBasic, code such as
LOCAL my$="Hello", mydouble=123.456 is quite common.

A similar command called SetGlobals (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1015) has been available for a while, but it choked for multiple assignments. This bug is fixed.

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  SetGlobals v1=111, v2=222, a$="String A", b$="String B"
  SetGlobals s1:REAL4=111.111, s2:REAL4=222.222
  SetGlobals x1:REAL10=111.111, x2:REAL10=222.222
  Init
  Dim da1() As REAL8       ; create two dynamic double arrays; note the
  Dim da2() As REAL8       ; type after Dim ... As it must be uppercase
  Print "Arrays:"
  For_ ecx=0 To 2
      mov esi, Str$("%If", ecx*1.1111111111111111+10)
      MovVal da1(ecx), esi      ; assign values to arrays - clumsy but OK for testing
      mov esi, Str$("%If", ecx*2.2222222222222222+20)
      MovVal da2(ecx), esi
      Print Str$(" da1(%i)=", ecx), Str$(da1(ecx)), Str$(" da2(%i)=", ecx), Str$(da2(ecx))
  Next
  deb 4, "original", v1, v2, $a$, $b$, s1, s2, x1, x2, da1(1), da2(2)
  Swap v1, v2
  Swap a$, b$
  Swap s1, s2
  Swap x1, x2
  Swap da1(), da2()
  Print "Arrays:"
  For_ ecx=0 To 2
      Print Str$(" da1(%i)=", ecx), Str$(da1(ecx)), Str$(" da2(%i)=", ecx), Str$(da2(ecx))
  Next
  deb 4, "swapped", v1, v2, $a$, $b$, s1, s2, x1, x2, da1(1), da2(2)
  Exit
end start


Output:[/tt]
Arrays: da1(0)=10.00000 da2(0)=20.00000 da1(1)=11.11111 da2(1)=22.22222 da1(2)=12.22222 da2(2)=24.44444
original
v1      111
v2      222
$a$             String A
$b$             String B
s1      111.1110
s2      222.2220
x1      111.111000000000000
x2      222.222000000000000
da1(1)  22.22222222222222
da2(2)  24.44444444444444
Arrays: da1(0)=20.00000 da2(0)=10.00000 da1(1)=22.22222 da2(1)=11.11111 da1(2)=24.44444 da2(2)=12.22222
swapped
v1      222
v2      111
$a$             String B
$b$             String A
s1      222.2220
s2      111.1110
x1      222.222000000000000
x2      111.111000000000000
da1(1)  11.11111111111111
da2(2)  12.22222222222222[/tt]

Attached a more detailed example, needs MasmBasic version 26 December (http://masm32.com/board/index.php?topic=94.0).
Title: BUG WARNING
Post by: jj2007 on December 27, 2014, 10:48:15 AM
Version 26.12. choked for Sqrt(2); it's fixed with version 27.12. (download (http://masm32.com/board/index.php?topic=94.0))

Examples for Sqrt():

include \masm32\MasmBasic\MasmBasic.inc
  SetGlobals sq:double
  Init
  movlps xmm0, FP8(2.0)      ; load an xmm reg using the Masm32 FP8 macro
  Print Str$("sq2=%Jf\n", Sqrt(f:xmm0))      ; it's a float, so put the f: prefix before the xmm reg
  mov eax, 3
  movd xmm0, eax      ; put a value into an xmm reg
  Print Str$("sq3=%Jf\n", Sqrt(xmm0))      ; it's integer
  fld Sqrt(4)
  fstp sq                  ; sq = sqrt(3), the manual way
  Print Str$("sq4=%Jf\n", sq)
  Print Str$("sq5=%Jf\n", Sqrt(5, sq))
  void Sqrt(6, ST(0))
  Print Str$("sq6=%Jf\n", ST(0))
  fstp st                  ; when leaving values on the FPU, do the cleanup!!
  Inkey Str$("sq7=%Jf\n", Sqrt(7, ST(0)))
  fstp st                  ; cleanup
  Exit
end start


Output:
sq2=1.414213562373095049
sq3=1.732050807568877293
sq4=2.000000000000000000
sq5=2.236067977499789805
sq6=2.449489742783178098
sq7=2.645751311064590590
Title: Re: MasmBasic
Post by: Gunther on December 27, 2014, 01:14:45 PM
Jochen,

the cleanup of the FPU stack is always necessary. That has to do with the stack roll over.

Gunther
Title: Re: MasmBasic
Post by: jj2007 on December 27, 2014, 06:34:40 PM
Quote from: Gunther on December 27, 2014, 01:14:45 PMthe cleanup of the FPU stack is always necessary.

That is rarely necessary. In fact, the cleanup instruction fstp st appears only 14 times in the MB source.

QuoteThat has to do with the stack roll over.
While I know what you mean when writing "stack roll over", it is not a term used when dealing with the FPU. You can check that in Raymond's excellent tutorial. (http://www.website.masmforum.com/tutorials/fptute/)

Btw if you want to make a little tutorial for the noobs, you should do it properly: Open a FPU thread in the Campus.
Title: Re: MasmBasic
Post by: Gunther on December 27, 2014, 11:02:25 PM
Quote from: jj2007 on December 27, 2014, 06:34:40 PM
That is rarely necessary. In fact, the cleanup instruction fstp st appears only 14 times in the MB source.

I think it's a good style to give back the entire processor in the same state how did you get it. That reduces furthermore error sources. But it's only my point of view, no offense.

Gunther
Title: Printing numbers with 19 digits precision
Post by: jj2007 on December 29, 2014, 11:59:08 AM
Update 29 December: (http://masm32.com/board/index.php?topic=94.0) Str$() can now print REAL10 numbers with up to 19 digits precision, if a) the format string contains %Jf and b) the number starts with less than 923... (which is the case for 92.3% of all numbers ;)).

deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019) uses this format for all REAL10 variables.

include \masm32\MasmBasic\MasmBasic.inc
.data
qwjj      QWORD 7fffffffffffffffh  ; aka +9223372036854775807
qwj2      qword -9223372036854775807
      SetGlobals numericvar1:REAL10=1.8888888888888888888888888888e9
      SetGlobals numericvar2:REAL10=9.2222222222234567895e9
      SetGlobals numericvar3:REAL10=9.2333333333333333335e9
      SetGlobals numericvar4:REAL10=1.2345678901234567890e9
      SetGlobals numericvar5:REAL10=9.2345678901234567890e9
      Init
      fldpi
      deb 4, "Values", numericvar1, numericvar2, numericvar3, PI, ST(0)
      fstp st
      mov f2sOlly, 123
      Print Str$("qword limit\t+%i\n", qwjj)      ; 4294967295 or 2147483647
      Print Str$("qword limit\t%i\n", qwj2)      ; 4294967295 or 2147483647
      fldpi
      Print Str$("PI=\t\t%Jf\n", ST(0))
      fstp st
      Print Str$("PI=\t\t%Jf\n", PI)
      Print Str$("numericvar1=\t%Jf\n", numericvar1)
      Print Str$("numericvar2=\t%Jf\n", numericvar2)
      Print Str$("numericvar3=\t%Jf\n\n", numericvar3)
      Print Str$("numericvar4=\t%Jf (number starts with 123, 19 digits)\n", numericvar4)
      Print Str$("numericvar5=\t%Jf  (number starts with 923, 18 digits)\n", numericvar5)
      Exit
end start


Output:
Values
numericvar1     1888888888.888888889
numericvar2     9222222222.223456788
numericvar3     9233333333.33333333
PI              3.141592653589793238
ST(0)           3.141592653589793238
qword limit     +9223372036854775807
qword limit     -9223372036854775807
PI=             3.141592653589793238
PI=             3.141592653589793238
numericvar1=    1888888888.888888889
numericvar2=    9222222222.223456788
numericvar3=    9233333333.33333333

numericvar4=    1234567890.123456789 (number starts with 123, 19 digits)
numericvar5=    9234567890.12345678  (number starts with 923, 18 digits)
Title: MasmBasic updated
Post by: jj2007 on January 02, 2015, 10:37:50 AM
Version 2 January (download (http://masm32.com/board/index.php?topic=94.0)): The restriction to not assign eax to an array element is removed. This is now legal code:

include \masm32\MasmBasic\MasmBasic.inc  ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Dim My$()
  invoke GetCommandLine                  ; CL$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1011) is easier to use, but for this demo we take the API
  Let My$(1)=eax                         ; you can now assign eax to an array element
  Inkey "Commandline=[", My$(1), "]"
  Exit
end start

OPT_Arg1      Hello Forum                ; RichMasm's way to supply arguments for testing


Output: Commandline=[C:\somepath\some.exe Hello Forum]
Title: 19 digits precision
Post by: jj2007 on January 08, 2015, 02:21:12 AM
see updated post below
Title: 19 digits precision and increased range
Post by: jj2007 on January 26, 2015, 11:01:50 AM
By default, REAL10 numbers are now printed with 19 digits precision. The last digit might be one too high or too low.
The range of printable numbers is now 1.0e+-309, i.e. roughly the range of ordinary doubles.
Speedwise Str$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1186) has improved, it is now about a factor 15 faster than the gcc ssprintf() function provided here by adeyblue (http://masm32.com/board/index.php?topic=3915.msg41398#msg41398) (thanks!!). Attached a testbed using Str$(), MovVal and the gcc counterparts ssprintf() and sscanf().

include \masm32\MasmBasic\MasmBasic.inc      ; download version 26 January 2015 (http://masm32.com/board/index.php?topic=94.0)
  SetGlobals MyR10:REAL10, Add01:REAL10=0.111111111111111111111
  Init
  xor ecx, ecx
  Print "digits", Tb$, "  1234567890123456789"
  .Repeat
      inc ecx
      push ecx
      fld Add01
      fimul stack      ; load ct*0.111
      pop eax
      fstp MyR10      ; store back to memory
      .if ecx<10 || ecx>=84 && ecx<99 || ecx>=994
            Print Str$("\n#%i\t", ecx), Str$(MyR10)
      .elseif ecx==10 || ecx==99
            Print      ; insert a blank line
      .endif
  .Until ecx>=1000
  Exit
end start


Output:
digits    1234567890123456789
#1      0.1111111111111111111
#2      0.2222222222222222222
#3      0.3333333333333333333
#4      0.4444444444444444444
#5      0.5555555555555555555
#6      0.6666666666666666666
#7      0.7777777777777777777
#8      0.8888888888888888888
#9      1.000000000000000000

#84     9.333333333333333333
#85     9.444444444444444444
#86     9.555555555555555555
#87     9.666666666666666666
#88     9.777777777777777777
#89     9.888888888888888888
#90     10.00000000000000000
#91     10.11111111111111111
#92     10.22222222222222222
#93     10.33333333333333333
#94     10.44444444444444444
#95     10.55555555555555555
#96     10.66666666666666667
#97     10.77777777777777778
#98     10.88888888888888889

#994    110.4444444444444444
#995    110.5555555555555555
#996    110.6666666666666667
#997    110.7777777777777778
#998    110.8888888888888889
#999    111.0000000000000000
#1000   111.1111111111111111
Title: New Split$(), Join$() and Filter$() macros, bugfix for Extract$()
Post by: jj2007 on February 01, 2015, 10:37:41 PM
Update 2 February 2015 - download here (http://masm32.com/board/index.php?topic=94.0):

1. Join$() converts a string array to one string:

  include \masm32\MasmBasic\MasmBasic.inc
  Init     
  Dim My$()
  Let My$(0)="Masm32"
  Let My$(1)="is"
  Let My$(2)="great"
  PrintLine "[", Join$(My$()), "]"   ; with no second arg, output is [Masm32\nis\ngreat], i.e. items separated by 13, 10
  Print "[", Join$(My$(), " "), "]"  ; shows [Masm32 is great] with " " as second arg
  Exit
  EndOfCode


For Split$() and Filter$(), see the guide during installation.

2. Bugfix for Extract$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1156):
   When using the flag xsLineR, one byte from the right match string was duplicated. It's fixed. Usage example (this extracts structures from a C header file; you need Visual Studio installed):

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  My$ equ esi         ; two equates saying we'll use a register for the string to be searched
  Struct$ equ edi     ; and for the strings returned, in this case C/C++ structures
  SetReg64            ; the registry wants to cheat 32-bit programs, we cheat back ;-)
  Let My$=GetRegVal("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\2E22551E7BF434E44AAD692811011B7C", "66FC8F6438BA7A83992B5AEB05E74E27", "NoSuchFile.bla")

  .if Exist(My$)      ; should be something like C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\srv.h
      Let My$=FileRead$(My$)
      Open "O", #1, "Structures.txt"      ; open a file for output
      xor ebx, ebx      ; reset counter
      .While 1
            ; flags: full word, include beginning of first line and end of last line, use in a loop; 100 lines max (enough for a big structure)
            mov Struct$, Extract$(My$, "struct", '}', xsFullW or xsLineL or xsLineR or xsIncR or xsLoop, 100)
            .Break .if !Struct$
            Print Struct$, CrLf$, CrLf$      ; print to console
            Print #1, Struct$, CrLf$, CrLf$      ; and to file
            inc ebx
      .Endw
      Close #1
      Print Str$("%i structures found\n", ebx)
  .endif
  Exit
end start


Output:
typedef struct srv_datetime
{       // Format for SRVDATETIME
    long dtdays;            // number of days since 1/1/1900
    unsigned long dttime;   // number 300th second since mid
} DBDATETIME;

typedef struct srv_money
{               // Format for SRVMONEY
    long mnyhigh;
    unsigned long mnylow;
} DBMONEY;

typedef struct dbdatetime4
{       // Format for SRVDATETIM4
    unsigned short numdays; // number of days since 1/1/1900
    unsigned short nummins; // number of minutes sicne midnight
} DBDATETIM4;

typedef struct dbnumeric
{       // Format for SRVNUMERIC,SRVNUMERICN,SRVDECIMAL,SRVDECIMALN
        BYTE precision;
        BYTE scale;
        BYTE sign;
        BYTE val[MAXNUMERICLEN];
} DBNUMERIC;

4 structures found
Title: Bugfix for 64-bit Windows
Post by: jj2007 on February 06, 2015, 11:12:50 AM
As noted on other occasions (http://masm32.com/board/index.php?topic=2630.0), the 64-bit versions of Windows have the bad habit to destroy registers xmm0 ... xmm5 in API calls, nota bene: in 32-bit code on a 64-bit OS. Since 32-bit code on 32-bit Windows does not trash them, and many people may have relied on this benign but undocumented behaviour, there is a nice potential for bugs that come out of the blue when running the same application the first time on a 64-bit OS.

For performance reasons, MasmBasic does not preserve the xmm regs for each and every API call used, but its own algos do preserve the xmm regs.

This worked fine in general, but I ran into a strange case that needed fixing:

include \masm32\MasmBasic\MasmBasic.inc      ; download the fixed version of 6 February 2015 (http://masm32.com/board/index.php?topic=94.0)
  Init
  Dim MyDouble() As REAL8      ; same for QWORD

  MovVal f:xmm0, "1234.5678"      ; fill low quad of xmm0 with float
  movlps MyDouble(0), xmm0
  deb 4, "Element 0", f:xmm0, MyDouble(0)

  MovVal f:xmm0, "1234.5678"
  movlps MyDouble(1), xmm0      ; <<<<<<< this instruction misbehaved
  deb 4, "Element 1", f:xmm0, MyDouble(1)

  MovVal f:xmm0, "1234.5678"
  movlps MyDouble(2), xmm0
  deb 4, "Element 2", f:xmm0, MyDouble(2)
  Exit
end start

Old buggy version:
Element 0
f:xmm0          1234.567800000000
MyDouble(0)     1234.567800000000

Element 1
f:xmm0          0
MyDouble(1)     0.0

Element 2
f:xmm0          1234.567800000000
MyDouble(2)     1234.567800000000


The reason for this unexpected behaviour was that the simple instruction movlps MyDouble(1), xmm0 has a nice feature under the hood: MyDouble() is a dynamic array. When an index hits the boundary, new memory is being requested via HeapReAlloc. And that request trashed the xmm regs - all six of them. I'd like to trash Windows, but Linux doesn't seem any better, so the solution was to preserve the six regs around the HeapReAlloc call. It works correctly from version 6 Feb 2015 onwards.
Title: 64-bit Windows trashes XMM regs
Post by: jj2007 on February 10, 2015, 11:20:07 AM
Update 10 Feb (download (http://masm32.com/board/index.php?topic=94.0)): Since I ran often into problems with Windows' bad habit to trash xmm0 ... xmm5 in its 64-bit versions, I decided to address this Microsoft 'feature' more systematically.

Inter alia, ordinary message boxes and setting the timestamp for a FileWrite (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1078) did not work in 32-bit code on Win64. This is now fixed, and the simple unzipper below will work as expected:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Let esi=CL$()
  .if !Instr_(esi, ".zip", 1)
      MsgBox 0, esi, "Not a zip archive?", MB_OK
      Exit
  .endif
  UnzipInit esi            ; expects a filename, returns a comment (if present); edx returns #records
  .if Sign?
      Print eax      ; print an error message
  .else
      For_ ecx=0 To edx-1      ; #files returned in edx
            Let esi=Files$(ecx)
            .if Rinstr(esi, "/")      ; zipfiles use forward slashes
                  xchg eax, esi      ; we don't display the full path, and we
                  inc esi      ; don't use folder names for extraction!!
            .endif
            PrintLine Str$(GfSize(ecx)), Tb$, GfDate$(ecx), Spc2$, GfTime$(ecx), Tb$, esi
            Inkey "Extract? (yes/no/quit) ", Cr$
            .Break .if eax=="q" || eax==VK_ESCAPE
            .if eax=="y"
                  FileWrite esi, UnzipFile(ecx), GfLastWrite(ecx)      ; setting the timestamp works now on Win7-64, too
            .endif
      Next
      UnzipExit
  .endif
  Exit
end start
Title: Print At(3, ecx) CColor(cRed, cWhite) "Hello colourful World"
Post by: jj2007 on February 16, 2015, 10:19:51 AM
Update 16 Feb 2015 (download (http://masm32.com/board/index.php?topic=94.0)):

- MovVal MyFloat(ct), My$(ct) is legal code now
- For_ ... Next has Step now (can be negative, too)
- In addition to At(col, row), Print can now take a CColor(foreground, background) arg

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Dim My$()
  Dim MyFloat() As REAL8
  For_ ct=0 To 1000
      Let My$(ct)=Str$(ct)
      MovVal MyFloat(ct), My$(ct)
  Next
  For_ ct=100 To 1000 Step 100
        mov ecx, ct
        and ecx, 15
      Print At(35, Locate(y)+2) CColor(ecx, cWhite) Str$(ct), Str$("\tMyFloat(ct) = %Jf", MyFloat(ct))
  Next
  Exit
end start
Title: Re: MasmBasic
Post by: jj2007 on February 24, 2015, 10:29:29 AM
Update 24 February (download (http://masm32.com/board/index.php?topic=94.0)):

This snippet creates a windows application with a menu and monitors all WM_xx messages to the console.

GuiParas equ "Hello jj2007", x650, y20, w200, h200, cblack, b00FFFFD0h
GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste
include \masm32\MasmBasic\Res\MbGui.asm
Event Message
  inc msgCount
  deb 4, "msg", chg:msgCount      ; , wParam, lParam      ; see deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019)
GuiEnd


More a proof of concept than a serious exercise, but it works. Attached a more detailed example, using create, key, menu and paint "events".
Title: For .. Next loop with REAL counter
Post by: jj2007 on March 03, 2015, 10:15:41 AM
Just for fun:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  SetGlobals fct:REAL10, fStart:REAL8=2.0, fEnd:REAL8=1.5
  Init
  For_ fct=1.0 To 2.0 Step 0.25
      Print Str$("\n%Jf\t", fct)
  Next
  Print CrLf$, "..."
  For_ fct=fStart To fEnd Step -0.1
      Print Str$("\n%Jf\t", fct)
  Next
  Exit
end start


Output:
1.000000000000000000
1.250000000000000000
1.500000000000000000
1.750000000000000000
2.000000000000000000
...
2.000000000000000000
1.900000000000000000
1.800000000000000000
1.700000000000000000
1.600000000000000000
1.500000000000000000
Title: Re: MasmBasic
Post by: rrr314159 on March 03, 2015, 11:49:01 AM
Do u realize the last 12 posts in this thread are yours? Figured I'd break your streak :)

But also it's interesting you're using float instead of integer in the for-next loop, because I've just done the similar thing with timing macros. I'll soon post a "faster" 32-bit algo in the laboratory - this time using MichaelW's timers, everything "by the book", but with "massively parallel" use of xmm registers. I'd gotten used to returning 64-bits from the rdtsc call and couldn't stand being confined to 32-bits again (1 second vs. 100 years) so wrote a 32-bit version of timers using REAL8 to hold the rdtsc result. Works fine, it's fast enough, this way you can add, average print out etc the timing figures easily.

Anyway, c u later!
Title: Re: MasmBasic
Post by: jj2007 on March 03, 2015, 12:19:40 PM
Thanks for the heads up ;-)

I posted a float example because that's new - integers always worked.

Re rdtsc, printing a qword is not a big deal:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  rdtsc
  Print Str$("TSC=%i\n", edx::eax)
  invoke Sleep, 1
  rdtsc
  Print Str$("TSC=%i\n", edx::eax)
  Exit
end start


The problems with rdtsc are elsewhere. M$ suggests QueryPerformanceCounter instead, which is under the hood of NanoTimer() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1171).
Title: Prompt$
Post by: jj2007 on March 04, 2015, 10:32:12 AM
Sometimes I need a prompt asking for input from a console app. Version 4 March has it:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi=NoTag$(FileRead$("http://masm32.com/board/index.php?action=unread;all;start=0"))
  Print "[", Prompt$("Type something, please:", esi), "]"
  Exit
end start

See Input$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1041) for comparison.

Other changes: For... Next loops with float counters act now, like their integer equivalents, rejecting if start>end.

P.S.: Version 9 March fixes a minor issue with UnzipFile (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1234).
Title: Re: MasmBasic
Post by: jj2007 on March 16, 2015, 11:49:08 AM
Version 16 March 2015 has improvements under the hood. Inter alia, Recall (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172) can now read files directly from the Internet, including csv and tab-delimited files. Unix format (i.e. LF only) will automatically be recognised, Unicode files are translated to UTF-8 text arrays.

Attached a gift for the U.S. members: A 100-lines application that
- reads an archive from the Internet
- extracts a database in csv format
- allows the user to enter:
  - either the name of a city, and get its LatLong coordinates
  - or LatLong coordinates, and get the nearest three cities

Let me know if it works.

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  SetGlobals firstUse, best, second, third, xc:REAL4, yc:REAL4, xNow, xyMin, OneMio:REAL4=1000000.0, zipfile$="ZipCodes.zip", tmp$="~FrLocal.tmp"
  Init
  .if !Exist(zipfile$)
      void FileRead$("http://www.boutell.com/zipcodes/zipcode.zip")
      .if Exist(tmp$)
            Rename tmp$, zipfile$
            inc firstUse      ; flag fresh download, show the MsgBox
      .endif
  .endif
  .if Exist(zipfile$)
      UnzipInit zipfile$
      ... -> see attachment
Title: Sex & Crime
Post by: jj2007 on March 17, 2015, 04:58:06 PM
Please install version 17 March of the MasmBasic library (http://masm32.com/board/index.php?topic=94.0).
Older versions have a problem with the translation of *.csv (comma-separated values) into a two-dimensional string array: If the very first column (see Bonaire, Saint below) contained quoted strings with embedded commas, they were interpreted as two columns. This is fixed now, and the snippet below (source and exe attached) will work just fine (as long as WHO provides the database, of course 8)) 

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Recall "https://extranet.who.int/tme/generateCSV.asp?ds=mdr_estimates", who$(), csv
  Print Str$("%i records downloaded", eax)
  For_ ct=0 To who$(?)-1
      Print CrLf$, who$(ct, 0)
      Print At(33, Locate(y)) Spc2$, who$(ct, 4), Space$(40)
      For_ ecx=8 To 14      ; columns 8...14 contain the data
            Print At(ecx*8-25, Locate(y)) Spc2$, who$(ct, ecx)
      Next
  Next
  Exit
end start


Output:

217 records downloaded
country                            year  e_new_  e_new_  e_new_  e_new_  e_new_  e_new_  source_mdr_ret
Afghanistan                        2013  3.7     2.5     4.9     820     560     1100    Model
Albania                            2013  0.58    0.02    3.2     2       0       10      Surveillance
...
Bonaire, Saint Eustatius and Saba  2013  2.2     1.3     3.1     0       0       0       Surveillance
Bosnia and Herzegovina             2013  0       0       0.57    0       0       6       Surveillance
Botswana                           2013  2.5     1.5     3.5     120     70      160     Survey
Brazil                             2013  1.4     1       1.8     840     600     1100    Survey


P.S.: Just stumbled over a public database on crime records. Interesting, but guess what? The database is neither Windows nor Linux, apparently it's MAC - carriage returns only! So I felt morally obliged to add the Mac format to Recall's autodetect feature. That cost a whopping 40 bytes or so extra but it works like a charm. Go to http://masm32.com/board/index.php?topic=94.0 and re-install MasmBasic, so that you can test the snippet below :biggrin:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Recall "http://samplecsvs.s3.amazonaws.com/SacramentocrimeJanuary2006.csv", Crime$(), csv
  For_ ct=0 To Crime$(?)-1
      .if Instr_(Crime$(ct), "card info", 1) || ct==0
            xor esi, esi
            For_ ecx=0 To 8
                  Print At(esi, Locate(y)) Spc2$, Crime$(ct, ecx), Space$(8)
                  add esi, 8
                  .if ecx==1 || ecx==5
                        add esi, 18
                        .if ecx==5
                            add esi, 10
                        .endif
                  .endif
            Next
            Print
      .endif
  Next
  Print Str$("\n%i records received from Sacramento", Crime$(?))
  Exit
end start
Title: Re: MasmBasic
Post by: jcfuller on March 19, 2015, 12:15:30 AM
Jochen,
  I figured it was about time I gave masmbasic a try but I am unable to install.
I double click on the exe and I get a window with a title:
"Last chance - show me where macro.asm sits and then a messagebox that says I should google Visual Basic??

James
Title: Re: MasmBasic
Post by: jj2007 on March 19, 2015, 02:10:52 AM
James,

Sorry for that. To deter the script kiddies, the installer tests if you have Masm32 installed, via the registry. If it doesn't find exactly what it expects, it gives you a "last chance" to select the macros.asm file in your Masm32 installation. It sits in the dedicated Masm32 folder. Please let me know if it works; I am also curious why it doesn't find the registry entries.

Thanks,
Jochen
Title: Re: MasmBasic
Post by: dedndave on March 19, 2015, 02:23:34 AM
i might be wrong, but i think the masm32 install only writes to the registry if the user elects to use QE as the default ASM editor
Title: Re: MasmBasic
Post by: jj2007 on March 19, 2015, 02:59:16 AM
You might be right, Dave :biggrin:
Title: Re: MasmBasic
Post by: jcfuller on March 19, 2015, 03:13:01 AM
It is now available.

James
Title: Re: MasmBasic
Post by: jj2007 on March 19, 2015, 03:36:27 AM
Great :t

GuiParas equ "Hello James", x650, y20, w200, h200, sWS_CAPTION OR WS_POPUPWINDOW, cblack, b00FFFFD0h
GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste
include \masm32\MasmBasic\Res\MbGui.asm
Event Message
  inc msgCount
  deb 4, "msg", chg:msgCount      ; , wParam, lParam      ; see deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019)
GuiEnd
Title: Re: MasmBasic
Post by: jj2007 on March 24, 2015, 11:22:08 AM
Update 24 March 2015:

- gsl (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1123) interface improved (see original gsl example program (http://www.gnu.org/software/gsl/manual/gsl-ref.html#An-Example-Program)):

include \masm32\MasmBasic\MasmBasic.inc
  gsl double gsl_sf_bessel_J0 (double x)      ; double x means a REAL8 is required as input
  Init                  ; ## GNU Scientific Library: Bessel function ##
  Print Str$("Bessel(5)=%Jf \n", gsl_sf_bessel_J0(FP8(5.0)))
  fstp st                  ; see a detailed gsl example here (http://masm32.com/n%5Cmasm32%5CMasmBasic%5CRes%5CSkelGsl.asc)
  Exit
EndOfCode


- SetGlobals (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1015) understands C-style declarations:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  SetGlobals OWORD xx0, xx1, xx2, xx3, xx4, xx5, xx6, xx7
  Init
  mov eax, 11111111
  movd xmm0, eax
  movaps xx0, xmm0

  add eax, 11111111
  movd xmm1, eax
  movaps xx1, xmm1
  Exit
end start
Title: Printing a sinus via the FPU, the CRT, the GSL, and Python
Post by: jj2007 on April 03, 2015, 10:59:13 AM
Update 3 April 15 (http://masm32.com/board/index.php?topic=94.0): How to steal goodies from other languages... before distributing or selling any of this, study the copyright situation 8)

include \masm32\MasmBasic\MasmBasic.inc
; libgsl.dll download (http://gnuwin32.sourceforge.net/packages/gsl.htm) : open Binaries zip, and extract the two files libgsl.dll and libgslcblas.dll to \masm32\MasmBasic\GnuScLib\DLL
  gsl double gsl_sf_sin (double x)      ; define your required gsl function using the syntax of the GNU Scientific Library Reference (http://www.gnu.org/software/gsl/manual/gsl-ref.html)
  SetGlobals threezero:double=3.0

  Init

  Dll "python34"      ; needs Python 3.4.3 (direct link to MSI (https://www.python.org/ftp/python/3.4.3/python-3.4.3.msi))
  Declare void Py_Initialize, C:0
  Declare void PyRun_SimpleString, C:1      ; can be used like the commandline version of Python
  Declare void Py_Finalize, C:0

  Py_Initialize()
  PyRun_SimpleString("print('Printing the sinus of 3.0 in various languages:')")      ; use Python in MasmBasic
  PyRun_SimpleString("import math")      ; the math library needs to be imported first
  PyRun_SimpleString('print("Sinus(3)=", math.sin(3), "   Python 3.4.3")')

  Print Str$("Sinus(3)= %Jf\tGSL, global var\n", gsl_sf_sin(threezero))
  fstp st                  ; since doubles are returned via the FPU, ST(0) must be popped
  Print Str$("Sinus(3)= %Jf\tGSL, immediate\n", gsl_sf_sin(3.0))
  fstp st

  Dll "msvcrt"            ; good ol' CRT
  Declare double sin, C:1
  Print Str$("Sinus(3)= %Jf\tCRT, global var\n", sin(threezero))
  fstp st
  Print Str$("Sinus(3)= %Jf\tCRT, immediate\n", sin(3.0))
  fstp st

  fld FP10(3.0)            ; finally, the traditional way, using the FPU
  fsin 
  Print Str$("Sinus(3)= %Jf\tAssembler/Fpu\n", ST(0))
  fstp st
  PrintLine "Exact:    0.14112000805986722210074480... Wolfram Alpha"      ; link (http://www.wolframalpha.com/input/?i=sin%283%29)
  Py_Finalize()
  Inkey "--- hit any key ---"
  Exit
EndOfCode


Output:
Printing the sinus of 3.0 in various languages:
Sinus(3)= 0.1411200080598672    Python 3.4.3
Sinus(3)= 0.1411200080598672135 GSL, global var
Sinus(3)= 0.1411200080598672135 GSL, immediate
Sinus(3)= 0.1411200080598672135 CRT, global var
Sinus(3)= 0.1411200080598672135 CRT, immediate
Sinus(3)= 0.1411200080598672221 Assembler/Fpu
Exact:    0.14112000805986722210074480... Wolfram Alpha
Title: Re: MasmBasic
Post by: hutch-- on April 03, 2015, 12:49:15 PM
The only interaction the installer has with the OS apart from disk IO is the VBS script file that gives you the option of putting the editor on the desktop. There is no direct registry writes at all. This is done to ensure the SDK is fully portable.
Title: Re: MasmBasic
Post by: jj2007 on April 09, 2015, 08:28:47 AM
Thanks, Hutch. So the registry entry that I found for qEditor was probably what I created myself when associating .asm with qEditor.

I have changed the installer accordingly. It checks now for the presence of x:\Masm32; if more than one installation exists, it checks the timestamps of x:\Masm32\Examples\*.exe, and picks the drive that has the more recent executables in the examples folder tree. Only GetDriveType = DRIVE_FIXED are checked.

So, hopefully the latest update of today, 9 April (http://masm32.com/board/index.php?topic=94.0) will work for everybody with a Masm32 installation. Please let me know if it works now.

There are also some improvements under the hood, notably I managed to speed up Len() a little bit:
Comparing Masm32 len() and MasmBasic Len()
Total=401700900  in   31 ms (Len)
Total=401700900  in  217 ms (len)

Total=401700900  in   32 ms (Len)
Total=401700900  in  217 ms (len)

Total=401700900  in   31 ms (Len)
Total=401700900  in  216 ms (len)

Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz


Testbed attached.
Title: StrLen timings
Post by: jj2007 on April 10, 2015, 08:25:48 AM
Version 2 - I've added CRT strlen and the "safe" version strnlen:
Comparing MasmBasic Len(), crt_strlen and Masm32 len()
Total bytes:
401700900 in  36 ms Len
401700900 in 229 ms crt strlen
401700900 in 428 ms crt strnlen
401700900 in 259 ms Masm32 len

401700900 in  37 ms Len
401700900 in 229 ms crt strlen
401700900 in 419 ms crt strnlen
401700900 in 261 ms Masm32 len

401700900 in  36 ms Len
401700900 in 227 ms crt strlen
401700900 in 419 ms crt strnlen
401700900 in 263 ms Masm32 len

Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz


P.S.: Version 10 April (http://masm32.com/board/index.php?topic=94.0) fixed a minor incompatibility with JWasm (the xlsPixels2Points macro used in the DDE demo \masm32\MasmBasic\Res\Masm2Excel.asc assembled fine with ML 6.15 .. 10 but choked with JWasm).
Title: Re: MasmBasic
Post by: dedndave on April 11, 2015, 01:46:49 AM
error line (??)
the specified procedure could not be found

xp sp3
Title: Re: MasmBasic
Post by: jj2007 on April 11, 2015, 03:39:28 AM
Yep, I just verified with my old machine: strnlen is not available on XP... :(
Title: Sound command
Post by: jj2007 on April 25, 2015, 05:10:19 PM
I know feature overkill is a big problem, but I couldn't resist :redface:

Sound
  Sound "880:200"           ; plays 880Hz for 200 ms; separator can be space, tab, / or :
  Sound 111                 ; plays a wav resource with ID 111 (rc file: 111 WAVE "hello.wav")
  Sound "hello.wav"         ; plays a file directly (wav only)
  Sound "hello.mp3"         ; plays a file in its associated player
  Sound "大桥在混乱的水.mp3"  ; Unicode names are allowed


Download version 25 April 2015 (http://masm32.com/board/index.php?topic=94.0)
Title: Re: MasmBasic
Post by: hutch-- on April 25, 2015, 10:57:37 PM
Use the unsafe version, from memory its faster and you just use it correctly.
Title: Re: MasmBasic
Post by: Farabi on April 26, 2015, 01:38:10 AM
That is impressive Mr. Jochen  :t
Title: Re: Sound
Post by: jj2007 on April 26, 2015, 03:05:36 AM
Thanks, Onan :icon14:
Title: Two-dimensional string arrays
Post by: jj2007 on May 02, 2015, 11:55:18 AM
The MasmBasic update of 23 May concerns basically string arrays with two dimensions, e.g. for use with spreadsheets. Example:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Dim My$(tab)      ; create a two-dimensional string array using tabs (csv: commas) as separators
  For_ row=0 To 7
      Let My$(row, 0)=Str$("Row %i", row)
      For_ col=1 To 7
            Let My$(row, col)=Str$("Col %i", col)
      Next
      Delete My$(row, 6)      ; cut out all even columns
      Delete My$(row, 4)
      Delete My$(row, 2)
  Next
  For_ row=0 To 7
      PrintLine My$(row)
  Next
  Exit
EndOfCode


Output:
Row 0   Col 1   Col 3   Col 5   Col 7
Row 1   Col 1   Col 3   Col 5   Col 7
Row 2   Col 1   Col 3   Col 5   Col 7
Row 3   Col 1   Col 3   Col 5   Col 7
Row 4   Col 1   Col 3   Col 5   Col 7
Row 5   Col 1   Col 3   Col 5   Col 7
Row 6   Col 1   Col 3   Col 5   Col 7
Row 7   Col 1   Col 3   Col 5   Col 7


EDIT: version 3 May adds the corresponding Insert command:

  Dim some$(tab)      : same for some$(csv)
  Let some$(0)=cfm$("rc00\trc01\trc02\trc03\trc04\trc05\trc06")
  Let some$(1)=cfm$("rc10\trc11\trc12\trc13\trc14\trc15\trc16")
  Insert some$(0, 3)
  Let some$(0, 3)="NEW r0c3"
Title: Bug warning
Post by: jj2007 on May 05, 2015, 10:32:12 AM
MasmBasic version 5 May 2015 (http://masm32.com/board/index.php?topic=94.0) fixes two bugs:
- Csv2Tab (converts an array loaded from a *.csv file to tab-delimited) had problems with malformed files;
- mov esi, some$(row, column) could produce garbage in loops with many thousand iterations (Let  (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1132)esi= was not affected; mov must be used only for read-only pointers).

Some new functions for the simplified GUI have been added:
output:
(http://www.webalice.it/jj2006/pics/GuiDemo.png)

source:
GuiParas equ "Hello jj2007", x100, y100, w300, h180, b0F0F0A0h
GuiMenu      equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste
include \masm32\MasmBasic\Res\MbGui.asm
MakeFont hFontSmall, Height:15, Weight:FW_SEMIBOLD, "Arial"
MakeFont hFontBig, Height:36, "Script MT Bold"
MakeBrush hRed, RgbCol(255, 64, 64)            ; light red
MakeBrush hGB, RgbCol(0, 160, 64)            ; dark green
Event Menu
  MsgBox 0, Str$("You clicked menu #%i", MenuID), "Hi", MB_OK
Event Paint
  m2m ecx, 3            ; just to demonstrate how to use scaling
  GuiTextStyle font:hFontSmall, bcol=RgbCol(255, 255, 160), fcol RgbCol(0, 0, 255)
  GuiLine 70, 15, ecx*90+10, ecx*5      ; start x+y, end x+y
  GuiLine 280, 120      ; end x+y
  GuiLine 70, 120
  GuiLine 70, 15
  GuiSetFill hRed      ; use the red brush
  GuiEllipse 236, ecx*7+4, 40, 20      ; x, y, radius x, radius y
  GuiSetFill hGB
  GuiCircle ecx*80-4, 25, ecx*5      ; x, y, radius
  For_ ct=0 To 7
      GuiText 4, ct*15+4, Str$("Line %i ", ct+1)
  Next
  GuiTextBox "Добро пожаловать", ecx*4+75, ecx*2+20, ecx*4+250, ecx*2+120, font:hFontBig, bcol:0f0f0a0h, fcol:RgbCol(0, 255, 0)
GuiEnd
Title: Simple GUI app with toolbar
Post by: jj2007 on May 19, 2015, 09:26:40 AM
This one needs MasmBasic version 19 May 2015 (http://masm32.com/board/index.php?topic=94.0) (works with Unicode tooltips, too):

GuiParas equ "Editor demo", x40, y40, w900, h666
GuiMenu equ @File, &New, &Open, &Save as
include \masm32\MasmBasic\Res\MbGui.asm
  GuiControl MyEdit, "richedit", y=0+37, h=1000-35, text "No valid commandline found"
  GuiControl MyTb, "Toolbar", resid 111
  SetGlobals MyEd$="Simple editor:", CurrentFile$
  SetGlobals
  Let CurrentFile$=CL$()      ; OPT_Arg1 SimpleEditor.asc      ; RichMasm: specify a commandline for testing
  .if Len(CurrentFile$)>1
      SetWin$(hMyEdit)=FileRead$(CurrentFile$))
  .endif
Event Menu
  Switch MenuID
  Case TB0, 0      ; first toolbar button or first menu entry
      MsgBox 0, "New doc?", MyEd$, MB_OKCANCEL
      .if eax==IDOK
            SetWin$ hMyEdit=Chr$(0)
      .endif
  Case 1, TB0+1      ; 2nd toolbar button or 2ndmenu entry
      .if FileOpen$("Standard Basic=*.bas|Oxygen=*.o2bas|SdlBasic=*.sdlbas|MasmBasic=*.asc", "Open source:")
            SetWin$ hMyEdit=FileRead$(FileOpen$())
      .endif
  Case 2, TB0+2
      .if Alert("WARNING: long files will\nbe truncated at 160kBytes", MyEd$, MB_OKCANCEL)==IDOK
            .if FileSave$("Standard Basic=*.bas|Oxygen=*.o2bas|SdlBasic=*.sdlbas")
                  FileWrite FileSave$(), Win$(hMyEdit)
            .endif
      .endif
  Case 3, TB0+3
      FileOpenSetFolder FolderOpen$("Pick a folder:", MyEd$, "\Masm32\Examples")
  Endsw
GuiEnd

Rsrc
32512 ICON "\\masm32\\MasmBasic\\icons\\Disc.ico"      ; Asm, House, Keys, Globe, Hammer, Setup, Disc, Eye, ...
1 24 "\\Masm32\\MasmBasic\\Res\\XpSimple.xml"
111 10 \Masm32\MasmBasic\Res\Tb4Res\SimpleToolbar.zip
Rsrc
Title: Re: MasmBasic
Post by: dedndave on May 19, 2015, 12:10:25 PM
glad to see you got it going   :t
Title: Re: MasmBasic
Post by: jj2007 on May 19, 2015, 12:41:45 PM
Well, kind of: with a stripped down manifest. It looks ok, it behaves ok - see attached exe (and source). But it doesn't use the latest version of the common controls...
Title: Unicode editor with multilingual user interface
Post by: jj2007 on May 21, 2015, 01:32:19 AM
Just for fun - needs MasmBasic version 20 May 2015 (http://masm32.com/board/index.php?topic=94.0):

(http://www.webalice.it/jj2006/pics/MultiLingualEditor.png)

Source (28 lines of code :icon_mrgreen:) included in the package: when the help file pops up, click on "Try a GUI app" in line 15.
Title: Multilingual GUI apps
Post by: jj2007 on May 23, 2015, 12:30:25 PM
What I always missed with M$ Office (and Windows in general) was an option to switch the language of the user interface. Here is one way to do it: Instead of writing ...
invoke AppendMenu, esi, MF_POPUP, edi, chr$("&File")
... you use ...
invoke AppendMenu, esi, MF_POPUP, edi, Mlg$(File)
... and depending on the language chosen by the user, the menu appears as File or Fichier or Datei.

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Mlg$(File:"\Masm32\MasmBasic\Res\Tb4Res\Sample.tab")      ; file:"path" loads the multilingual matrix
  For_ ct=0 To 5
      Mlg$(Language: Mid$("ENESBRITDEFR", ct*2+1, 2))      ; example: Mlg$(Lang:IT) sets Italian
      PrintLine Mlg$(LgTx), ":", CrLf$, Tb$, Mlg$(_ASM), CrLf$, Tb$, Mlg$("_BEL")
      PrintLine Tb$, Mlg$("_USA"), CrLf$, Tb$, Mlg$(_AUS), CrLf$, Tb$, Mlg$(_AUT)
  Next
  Exit
EndOfCode


Output (shortened):
English:
        American Samoa
        Belgium
        United States
        Australia
        Austria
Español:
        Samoa americana
        Bélgica
        Estados Unidos
        Australia
        Austria


Format of the tab file:
Line 0 = comment, Tb$, ID1, Tb$, Id2, ...
Line 1...n: 3 or 4 letter ID (here: understroke+ISO 3 letter code), Tb$, text, Tb$, text, Tb$, etc.

Do not change this line EN ES BR IT DE FR
LgTxt English Español Português (BR) Italiano Deutsch Français
_ASM American Samoa Samoa americana Samoa Americana Samoa Americane Amerikanisch-Samoa Samoa Américaines
_AUS Australia Australia Austrália Australien Australie
_AUT Austria Austria Áustria Österreich Autriche
_BEL Belgium Bélgica Bélgica Belgio Belgien Belgique
_FRA France Francia França Francia Frankreich
_USA United States Estados Unidos Estados Unidos Stati Uniti d'America Vereinigte Staaten von Amerika Etats-Unis


Example attached, requires MasmBasic of 23 May 2015 (http://masm32.com/board/index.php?topic=94.0)
Title: Toolbar with embedded controls
Post by: jj2007 on May 29, 2015, 10:26:05 AM
Source (ca. 70 lines) is in \Masm32\MasmBasic\Res\MiniGui.asc (MasmBasic of 29 May) (http://masm32.com/board/index.php?topic=94.0)
Title: Windows 8.1
Post by: jj2007 on June 11, 2015, 08:29:21 AM
Since I finally have a machine with Windows 8.1 installed, I managed to fix a bug in RichMasm. As of version 11 June 15 (download (http://masm32.com/board/index.php?topic=94.0)), MasmBasic's IDE is fit for Win 8 :t

Note that before installing MasmBasic, you need a valid Masm32 installation. One known issue with Win 8.1 is that you will see these messages several times:
- inc2l.exe: can't find ordinal 200 in windir\AppPatch\AcGenral.dll
- inc2l.exe: can't find ordinal 202 in windir\AppPatch\AcLayers.dll

Masm32 will work just fine, in spite of these error messages.

Note also that Win 8 will display a message "PC protected by Windows" saying that "SmartScreen" has stopped the launch of an unknown application. This is a nasty trick to force coders to buy signatures. Click on "more info" and "Run anyway".
Title: Re: MasmBasic
Post by: dedndave on June 11, 2015, 08:33:29 AM
you wanna tell us about the bug ?   :biggrin:
Title: Re: MasmBasic
Post by: jj2007 on June 11, 2015, 08:47:17 AM
Quote from: dedndave on June 11, 2015, 08:33:29 AM
you wanna tell us about the bug ?   :biggrin:

It's actually quite weird. There was an access violation in RichMasm, due to a fairly fat bug - sh*t happens. Windows 7-64 has the strange habit to "fix" such problems somehow, so I never noticed (and I should check why I didn't see it on the XP machine). Win 8 made it crash.

First, I thought it had to do with SEH, but the example in \Masm32\MasmBasic\Res\SkelTryCatch.asc works just fine both in Win 8.1 and in Win 7, so I really don't know why the exception made it crash in Win 8.1 ::)

Another problem was RichMasm's habit to be stingy, pardon: parsimonious with the screen real estate: It uses the caption for the menu titles. That works fine from XP to Win7, but Win 8.1 re-introduced a design feature that will certainly be loved by the fans of Windows 3.1: the captions are centered. So to avoid overlap of menus and title, I had to cheat the OS by padding the caption with spaces to the right. To avoid doing that in Win 7, too, I had to get the OS version. I really wonder when they will retire the person who is responsible for the GetVersion mess, it's incredible. Google for GetVersionEx deprecated manifest, and you'll even find postings that make fun of M$. Richmond, still sleeping...?
Title: Re: MasmBasic
Post by: dedndave on June 12, 2015, 01:23:15 AM
what i was looking for was code to avoid
i (we) write code, testing under XP
it would be nice if we could learn the pitfalls to avoid to allow the code to run under win8+
Title: Re: MasmBasic
Post by: jj2007 on June 12, 2015, 07:35:28 PM
Quote from: dedndave on June 12, 2015, 01:23:15 AM
what i was looking for was code to avoid

So far,  the only oddity when passing from Win7-64 to Win 8.1-64 was the access violation in RichMasm, which was swallowed by the OS in Win7. So it seems it's always a good idea to test release code with Olly, because the latter catches the access violations.

A bigger problem was the nasty discovery that the 64-bit OS versions trash xmm regs in 32-bit code, while the 32-bit OS versions leave them intact. In MasmBasic, I eventually solved that with
fxsave MbXs
...
fxrstor MbXs

pairs. The impact on performance is negligible because it concerns only Win API calls.
Title: New Switch macro creates jump table
Post by: jj2007 on August 29, 2015, 08:13:45 AM
MasmBasic update of 29 August 2015: (http://masm32.com/board/index.php?topic=94.0)

Switch_, Case_, Default_, Endsw_
The Masm32 Switch macro is more powerful than its C or GfaBasic equivalents, since it can handle even variables or registers in the "cases". Old versions of the MasmBasic Switch_ (note the understroke) could not handle variables, i.e. the cases can be integer constants only. However, under the hood it creates a jump table that is for long lists of cases much faster than the Masm32 macro. Below an example for MasmBasic Switch_:

      include \masm32\MasmBasic\MasmBasic.inc
      Init                  ; ## Switch with jump table ##
      m2m ecx, -5
      PrintLine "------- testing the new MasmBasic Switch_ macro -------"
      .Repeat
            Print Str$(ecx), Tb$
            Switch_ ecx
            Case_ -2
                  PrintLine "Case -2"
            Case_ 0
                  PrintLine "Case NULL"
            Case_ 10
                  PrintLine "Case 10"
            Case_ 18
                  PrintLine "Case 18"
            Case_ 14 .. 16
                  PrintLine "Case 14 .. 16"
            Default_
                  PrintLine "---"
            Endsw_
            inc ecx
      .Until signed ecx>20
      Exit
      EndOfCode
Rem      Switch_ trashes edx but not eax; do not forget the understroke
Title: Basic-style Data and Read
Post by: jj2007 on September 01, 2015, 03:39:24 AM
For the fans of "real" BASIC, I have added Data and Read statements to MasmBasic. Example:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Data 123, "Hello World, how are you?", 'single quotes are allowed', My$, sq$, 456
  SetGlobals My$, sq$, c1$, c2$, MyByte, MyDword, MyR4:REAL4, MyR8:REAL8, Last$, MyQ:QWORD
  Data 789, 111, 1234567890123456789, 1234567890.123456789, 12345.6789, 12345.6789
  Init
  Data 33333, "Last string item"         ; Data statements can go almost everywhere...
  Read ecx, My$, sq$, c1$, c2$, eax      ; once My$+sq$ are read, c1$ and c2$ can be copied
  Read edx
  Read esi     
  Data 1234567890123456789               ; ... but values must be defined before they are read
  Read xmm0, f:xmm1, MyR8, MyR4, edi, Last$, MyQ
  deb 4, "Read variables:", ecx, eax, $My$, $sq$, $c1$, $c2$, edx, esi, xmm0, f:xmm1, MyR8, MyR4, edi, MyQ, $Last$
  Exit
EndOfCode

Output:
Read variables:
ecx             123
eax             456
$My$            Hello World, how are you?
$sq$            single quotes are allowed
$c1$            Hello World, how are you?
$c2$            single quotes are allowed
edx             789
esi             111
xmm0            1234567890123456789
f:xmm1          1234567890.123457
MyR8            12345.67890000000
MyR4            12345.68
edi             33333
MyQ             1234567890123456789
$Last$          Last string item
Title: MasmBasic bug fix
Post by: jj2007 on September 02, 2015, 08:28:06 AM
QSort (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1175) misbehaved - fixed in version 2 September (http://masm32.com/board/index.php?topic=94.0):

qsmb proc
  push esi
  push esi edi
  push ebx 8)
Title: 9/11
Post by: jj2007 on September 12, 2015, 12:06:14 AM
I rewrote the Gui interface a little bit. Of course, it looks horribly BASIC, but traces of pure assembler indicate what is under the hood. And it also offers some eye candy ;D

Oh, and btw - this window is resizable 8)

Assembling requires version 9/11 of MasmBasic (http://masm32.com/board/index.php?topic=94.0).

GuiParas equ "MasmBasic is easy to use", x50, y50, w1200, h666
GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste
include \masm32\MasmBasic\Res\MbGui.asm

  Dim MySinus() As REAL8
  For_ ct=-400 To 400
      SetFloat MySinus(ct+400)=Sinus(ct)      ; ******* a GUI demo in 30 lines of code *******
  Next

Event Menu
  MsgBox 0, Str$("You clicked into menu entry #%i", MenuID), "Hello:", MB_OK

Event Paint
  ArrayPlot hWnd, RgbCol(255, 255, 128)            ; init & set background
  ArrayPlot MySinus(), 0, lines=5                  ; draw the array
  ArrayPlot exit, "Playing with Sinus() plots"     ; finish with a title
  For_ ct=20 To GuiWidth-20 Step 10
      GuiLine 50.0, 8.0, ct, 99.0, RgbCol(255, 160, 160)            ; the 'pink pyramid'
      void Cosinus(ct)
      fimul GuiHeight
      fiadd GuiHeight       ; center
      fmul FP4(0.4)
      push eax              ; create a slot
      fistp stack           ; convert to integer
      pop ecx               ; retrieve as ecx
      GuiText ct+30, ecx+50, Str$(ct), bcol RgbCol(255, 255, 128)
      GuiCircle ct, ecx+60, 1.5, b Rand(0ffffffh), p RgbCol(80, 80, 80)
  Next
  GuiEllipse 32.0+9, 20.0, 7.0, 8.0, b RgbCol(255, 128, 128)            ; RGB for n00bs
  GuiEllipse 60.0-9, 20.0, 7.0, 8.0, b 0FF2020h, p 808080h              ; BGR for experts
  GuiTextBox 50.0-60, 40.0, 120, 100, "This is just a simple text box, try to do the same in other programming languages", bcol RgbCol(255, 255, 255)
  GuiCircle 50.0, 40.0+50, 12.0, p 0, b none                  ; none = hollow brush

EndOfCode

(http://forum.basicprogramming.org/index.php?action=dlattach;topic=3709.0;attach=2707;image)
Title: Editor background colour
Post by: jj2007 on September 18, 2015, 09:49:27 AM
Somebody complained about RichMasm not being configurable, so in version 18 September (http://masm32.com/board/index.php?topic=94.0) I added the option to change the RichEdit control's background colour.

See ColBg in \Masm32\MasmBasic\Res\RichMasm.ini for a list of available background and foreground colours (you may change the ini file, but the next installation will overwrite your changes, so keep a backup please).

To change the background colour for a document, press Ctrl G and enter e.g. udc=2. Available colours:
ColBg=0FFFFE0h ; default, turquois
Bg1=0F0F0F0h ; almost white
Bg2=0C0FFB0h ; greenish
Bg3=0C0C0FFh ; light red
Bg4=0B0FFFFh ; light yellow
Bg5=0FFB0FFh ; pink
Bg6=202020h ; grey; 1=almost black, 0 picks default colour ColBg
BgH=0AAFFFFh ; reserved for hilite colour

ColFg=0 ; default text colour
Fg8=0B0B0B0h ; light gray
Fg16=0A0h ; dark red
Fg24=0A00000h ; dark blue
Fg32=0aaaah ; dark yellow
Fg40=0ffffffh ; white
Fg48=8000h ; green


udc=14 would pick dark grey background with light gray text colour. While the background changes as soon as you hit Enter, the text colour will change only if you select all text and then hit Ctrl E twice.

Among the templates, "Editor with toolbar" has been improved, and the first on top of the list when clicking menu File/New Masm source called "MessageBox only" looks now a bit different, thanks to a radical redesign of RichMasm:
Title: Re: MasmBasic
Post by: HSE on September 19, 2015, 10:12:14 AM
Hi jj!

A lot better.

I don't remember if was posible to open asm files in RichMasm from the explorer. Now it's no posible.

Regards. HSE
Title: Re: MasmBasic
Post by: jj2007 on September 19, 2015, 05:29:10 PM
Problem could be an obsolete file association, or that RichMasm.exe and your asm file are on different drives. Try finding ???:\Masm32\MasmBasic\RichMasm.exe, then drag an asm file over the exe.

Version 20 September: (http://masm32.com/board/index.php?topic=94.0) Problem fixed. RichMasm will work now even if the source is on a different drive.
Title: Re: MasmBasic
Post by: HSE on September 20, 2015, 11:52:16 AM
Perfect now  :t
Title: Re: MasmBasic
Post by: jj2007 on September 20, 2015, 06:09:25 PM
Quote from: HSE on September 20, 2015, 11:52:16 AM
Perfect now  :t

In this case, I have a special version of the help file for you :greensml:
Title: Re: MasmBasic
Post by: HSE on September 21, 2015, 08:59:36 AM
Better and better!  Thanks

But I use a lot of text coloring, for assembly programming mostly in RadAsm (a more dark version that the released one) . Of course some pure GreyAndBoring for small tests in QEditor.

Testing MasmBasic, RichMasm is always the first option  :biggrin:.
Title: Fast MemSet and Instr() algos
Post by: jj2007 on September 25, 2015, 09:11:53 AM
Version 25 September 2015 (http://masm32.com/board/index.php?topic=94.0) features:

- fast string search:
  .if Instr_ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1153)(FAST, pBuffer, pPattern, 0)
        Print "substring found"

- fast MemSet:
      MemSet offset somebuffer, 0, 1000                    ; destination, pattern, #bytes
      MemSet offset somebuffer, "x", 1000                  ; 1000 * x
      MemSet offset somebuffer, Mirror$("abcd"), 1000      ; 250 * abcd, slightly faster
      mov eax, Chr$("Masm32 is great ")                    ; string must have (at least) 16 bytes
      movups xmm0, oword ptr [eax]
      mov edx, offset somestring
      MemSet edx, xmm0, 99


The two new commands are on recent CPUs more than twice as fast as their C/C++ equivalents; Instr_() supports also mode 2, i.e. ignore case of the first character (as in "This is OK, this too") without significant speed loss.
Title: Re: MasmBasic
Post by: TWell on September 25, 2015, 04:53:38 PM
Avast don't like that Setup.exe :(
Title: Re: MasmBasic
Post by: jj2007 on September 25, 2015, 05:40:49 PM
Avast dislikes many things, just disable it temporarily. I have no time and no money to sue them for damaging the reputation of the library, but false positives are a fat problem. Did you know that we have even a dedicated sub-forum called AV Software sh*t list? (http://masm32.com/board/index.php?board=23.0)

Attached an updated "MasmBasic for C" example. Extract to a folder named \Masm32\MasmBasic\Mb4C and make sure it's on the same drive as Masm32 and Pelles C (this is clumsy, I know, and will change when I find time to fix it).
Title: Re: MasmBasic
Post by: dedndave on September 26, 2015, 03:15:45 AM
soooo
should i uninstall an older version first, or will the new one take care of it ?
Title: Re: MasmBasic
Post by: dedndave on September 26, 2015, 03:37:05 AM
better question here....

how do i do a clean uninstall of MasmBasic?
Title: Re: MasmBasic
Post by: jj2007 on September 26, 2015, 04:13:34 AM
Quote from: dedndave on September 26, 2015, 03:15:45 AMshould i uninstall an older version first, or will the new one take care of it ?
...
how do i do a clean uninstall of MasmBasic?

The installer will just overwrite any MB files, unless they have been altered after the new version. Normally, you can't do anything wrong with this logic; unless you fumble with MasmBasic.inc, and forget to make a backup. But that would be about as stupid as improving Windows.inc and re-installing Masm32 :biggrin:

Re uninstall: It doesn't write anything to the registry, so it's just the \Masm32\MasmBasic folder. The editor has the habit to save user-written code to \Masm32\MasmBasic\AscUser, so you might check if there is anything valuable in there.

Attached a list of all currently installed files.
Title: Re: MasmBasic
Post by: dedndave on September 26, 2015, 04:22:19 AM
thanks Jochen   :t

it's been a while since i updated it
so, i will delete the folder and install "anew"
Title: Re: MasmBasic
Post by: jj2007 on September 26, 2015, 04:46:35 AM
Good idea ;)

I've also just updated the web-based copy of MbGuide.rtf called MasmBasic Quick Reference (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm). Instr_(Fast...) as well as InstrOr(haystack, needle1 or needle2 or needle3) are now documented there. (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1153)
Title: Re: MasmBasic
Post by: jj2007 on October 01, 2015, 08:52:35 AM
Version 1 October 15 features the new ultrafast variant of Instr_():

Instr_, Rinstr, wInstr, InstrOr
      Print "The current drive is ", Left$(ThisExe$, Instr_(ThisExe$, "\")-1)
      mov pos, Instr_(1, L$(n), "equ", 1+4)      ; 1=start pos, 1=case-insensitive + 4=full word
Rem   - returns relative pos in edx, absolute in eax
      - if no match is found, zero is returned in edx, and eax points to the start of the 'haystack'; same if 'needle' is empty
      - six syntax variants allowed:
         A: has startpos:      Instr_(1, "Test", "Te", 2)     ; 4 args
         B: no startpos:      Instr_("Test", "Te", 2)         ; 3 args, last one immediate = mode
         C: has startpos:      Instr_(1, "Test", "Te")        ; 3 args, last one not immediate
         D: no startpos:      Instr_("Test", "Te")            ; 2 args
         E: test several patterns:      InstrOr("Test", "Te" or "st", 1)  ; 3 args (startpos is 1)
         F: extra fast mode:      Instr_(FAST, My$(ecx), "Hello", 0)      ; 4 args, no startpos, modes 0+2 only
       - case & mode (bitwise flag):
         0=case-sensitive, +1=insensitive, +2=intellisense (Name=name),
         +4=full word search, +8=include start of line in text block search
         Note: full word search returns failure for chars above ASCII 64 to the left or right
         Example: Nostructfoundhere, this123struct456isfound, this@struct, too

         The FAST option is about twice as fast as CRT strstr, and three times
         as fast when used with string arrays;

         using FAST, binary search in haystacks containing zeros is possible by
         assigning the buffer size to edx:
           mov edx, LastFileSize      ; any info on length of buffer can be used with edx
           Print Str$("Pos in executable: %i", Instr_(FAST, esi, "kernel32", 2 or 64)      ; 2=case-insensitive, 64=len in edx


       - wRinstr is available but only as wRinstr(src, pattern) with a one-byte pattern (e.g. "\")
Title: Enum$
Post by: jj2007 on October 03, 2015, 12:08:29 PM
MasmBasic version 3 October (http://masm32.com/board/index.php?topic=94.0) features Enum$(), the companion to Enum:

Enum            ; create a list of IDs
Enum      IdMenuNew, IdMenuSave, IdMenuCopy, IdTimer
Enum      20:IdEdit, IdButton1, 30:IdButton2, IdStatic, IdFind, IdFindStatic
Remdefault start is 10, but (as shown above) new start values can be specified with nn:

Enum$          ; return numeric constant as text
Case WM_CREATE
  Enum 20:IdEdit, IdButton1, 30:IdButton2, IdStatic, IdFind, IdFindStatic
  ; use with CreateWindowEx
Case WM_COMMAND
  ; ID is loword(wParam), print it as Enum$(ID, list of numeric constants)
  PrintLine "command for control ", Enum$(word ptr wParam, IdEdit, IdButton1, IdButton2, IdStatic, IdFind, IdFindStatic)
  mov ecx, Enum$(uMsg, WM_CREATE, WM_PAINT, WM_SIZE, WM_SIZING, WM_COMMAND)
  .if byte ptr [ecx]!="?"      ; if no matching entry is found, Enum$() returns a question mark
      PrintLine "Message: ", ecx      ; output e.g. Message: WM_PAINT
  .endif


Below and attached a full example showing a practical use of Enum$().

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
uselib ntdll            ; for RtlGetVersion
  Init                  ; OPT_Assembler JWasm ; ML chokes with version suite string
  sub esp, RTL_OSVERSIONINFOEXW-DWORD
  push RTL_OSVERSIONINFOEXW      ; set size member
  invoke RtlGetVersion, esp
  mov ecx, esp      ; ecx is pointer to RTL_OSVERSIONINFOEXW structure
  ovi equ [ecx.RTL_OSVERSIONINFOEXW]      ; MSDN (https://msdn.microsoft.com/en-us/library/windows/hardware/ff563620%28v=vs.85%29.aspx)
  .if eax
      PrintLine "RtlGetVersion failed with ", Err$()
  .else
      PrintLine Str$("RtlGetVersion\t%i.", ovi.dwMajorVersion), Str$(ovi.dwMinorVersion), Str$(" SP %i.", ovi.wServicePackMajor), Str$(ovi.wServicePackMinor), Str$(" build %i", ovi.dwBuildNumber)
      Print "Suite mask", Tb$, Hex$(ovi.wSuiteMask), ": "
      For_ esi=0 To 31      ; see Geoff Chappell: The Product Suite (http://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/exinit/productsuite.htm)
            xor eax, eax
            bts eax, esi
            and ax, ovi.wSuiteMask      ; extra long line requires JWasm or AsmC (http://masm32.com/board/index.php?topic=902.msg50161#msg50161)
            mov ebx, Enum$(eax, VER_SUITE_BACKOFFICE, VER_SUITE_BLADE, VER_SUITE_COMPUTE_SERVER, VER_SUITE_DATACENTER, VER_SUITE_ENTERPRISE, VER_SUITE_EMBEDDEDNT, VER_SUITE_PERSONAL, VER_SUITE_SINGLEUSERTS, VER_SUITE_SMALLBUSINESS, VER_SUITE_SMALLBUSINESS_RESTRICTED, VER_SUITE_STORAGE_SERVER, VER_SUITE_TERMINAL, VER_SUITE_WH_SERVER)
            .if byte ptr [ebx]!="?"
                  Print Mid$(ebx, 11), " "
            .endif
      Next
      PrintLine CrLf$, "ProductType", Tb$, Mid$(Enum$(ovi.wProductType, VER_NT_WORKSTATION, VER_NT_DOMAIN_CONTROLLER, VER_NT_SERVER), 8)
      lea eax, ovi.szCSDVersion
      wPrintLine "CSDVersion", wTb$, eax, wCrLf$      ; Unicode
  .endif
  add esp, RTL_OSVERSIONINFOEXW

  Inkey CrLf$, "---- hit any key ----"
  Exit
EndOfCode            ; see MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/aa370663%28v=vs.85%29.aspx)


Output for Win7-64:
RtlGetVersion   6.1 SP 1.0 build 7601
Suite mask      0300: SINGLEUSERTS PERSONAL
ProductType     WORKSTATION
CSDVersion      Service Pack 1
Title: Re: MasmBasic
Post by: dedndave on October 04, 2015, 11:37:25 AM
XP - not much help - lol

i guess that would formatted as "5.1.2600 SP 3.0"

RtlGetVersion   5.1 SP 3.0 build 2600
Suite mask      0100: SINGLEUSERTS
ProductType     WORKSTATION
CSDVersion      Service Pack 3
Title: Choose command
Post by: jj2007 on October 06, 2015, 09:32:57 AM
Update 6 October: Inspired by James Fuller (http://bc9.bcxbasic.com/choose2.htm), the Choose command was added to the library:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
.data
tx123      db "This is tx123", 0

  Init
  mov ecx, Chr$("ecx is a string")
  Dim My$()
  Let My$(0)="array element 0"
  Let My$(1)="array element 1"
  .While 1
      Inkey "Gimme a letter from a-z: "
      .Break .if eax==VK_ESCAPE
      xchg eax, ecx
      .if Choose(ecx-"a", 100, 101, 102, "abc", 124, 12345.67, 12345678.90123456789, offset tx123, ecx, My$(1), "the letter k")<=ChooseString
            .if eax==ChooseReal
                  Print Str$("You chose the real number %Jf\n", ST(0))
                  fstp st
            .elseif eax==ChooseError
                  PrintLine "You typed the letter ", Chr$(ecx), " - error..."
            .else
                  push eax
                  Print Str$("You chose the integer %i ", eax)
                  pop eax
                  PrintLine " (hex", Hex$(eax), ")"
            .endif
      .else
            PrintLine "You chose the string [", eax, "]"
      .endif
  .Endw
EndOfCode


P.S.: VB Choose Function (https://msdn.microsoft.com/en-us/library/824bz7dy%28v=vs.90%29.aspx) on MSDN uses a double as the index - funny idea 8)
Title: Plotting a map
Post by: jj2007 on October 11, 2015, 10:35:59 PM
MasmBasic update of 11 October (http://masm32.com/board/index.php?topic=94.0) improves on its GUI interface:

GuiParas equ "Plotting a sinus and a map", x30, y30, w1200, h700, bnone
include \masm32\MasmBasic\Res\MbGui.asm
  ToolTips                  ; initialise the tooltips, they will
  ToolTips end              ; show the country names
  ArrayLoadMap 0, "\masm32\MasmBasic\Res\europe.map"
Event Paint
  ArrayPlot hWnd, RgbCol(144, 240, 255)          ; init with window (or control) handle and background colour
  ArrayPlot 0, RgbCol(127, 127, 127), lines=2    ; display map #0 with grey borders 2px thick
  ArrayPlot exit, "Europe"                       ; finish with a title
  GuiTextBox 35.0, 92.0, 120, 32, "This application is sizeable - try it!!!!", fcol 0ffh, bcol RgbCol(204, 255, 204)
  GuiTextBox 29.0, 63.0, 85, 66, "Move the mouse over a country to see its name", fcol 0, bcol RgbCol(255, 255, 128)
Event Message
  .if uMsg==WM_MOUSEMOVE
      ArrayMapRegion(lParam, 0, hWnd)      ; activate tooltip if mouse enters a region
  .endif
GuiEnd


Screenshot below. It's heavily sized, to save bandwidth - the full version looks better ;-)
Title: Re: MasmBasic
Post by: dedndave on October 12, 2015, 09:48:59 AM
i like the idea - but have no idea how it works - lol

i'd like to write a program that generates "great circle" maps (azimuthal equidistant)
they have them - they even have online generators, but i'd like my own
at any rate - no time to play with it for now   :(
Title: Re: MasmBasic
Post by: dedndave on October 12, 2015, 09:52:08 AM
here's one, with the center on "some town" in France
they are different for every location in the world - lol

http://www4.plala.or.jp/nomrax/BM/Paris_l.gif (http://www4.plala.or.jp/nomrax/BM/Paris_l.gif)

we use them to "aim" our antennas
some guy in France wants to talk to a guy in Alaska, he aims his antenna about 350 degrees
Title: Extracting data tables from Wikipedia
Post by: jj2007 on October 14, 2015, 12:45:00 PM
Once upon a time, MSIE had a function that allowed to extract a table to Excel (the only reason I ever used Explorer instead of Firefox). That seems to have stopped working a long time ago, so I wrote a little proggie (70 lines) that does the job.

It is not for general use, though; some manual adjustment will be needed to download other tables. Here is the main loop that generates the string array (full code & exe attached, requires MB of 14 October 2015 (http://masm32.com/board/index.php?topic=94.0))

GetElements:
  .While ct<maxcountries      ; xs mode: use in loop, exclude left and right search strings
      Let t$(ct, Rank)=Extract$(esi, '<td>', '</td>', xsLoop or xsExcL or xsExcR)
      Let t$(ct, Country)=Extract$(esi, 'title="', Chr$(34, 62), xsLoop or xsExcL or xsExcR)
      Let t$(ct, Int$)=Extract$(esi, '<td>', '</td>', xsLoop or xsExcL or xsExcR)
      inc ct
  .Endw


So if you are feeling strong in HTML, press Ctrl U in FF or MSIE and try to guess which left and right matches are suitable for extracting the table :P

P.S.: Download of the library (http://masm32.com/board/index.php?topic=94.0) appears to be disturbed today. I managed once to download and install with MSIE, but very, very slowly. FF downloads at under 3kB/s, and doesn't complete. Is it just my line, or have the Aussies been cut off from the Internet once more? The forum is also really slow today.
Title: Re: MasmBasic
Post by: bsdsource on October 15, 2015, 01:52:02 AM
I was attempting to install your masmbasic library but the install screen is too large for my laptop screen. The max resolution for my laptop is 1366 x 768. I'm unable to see any buttons at the bottom of the screen to press to install masmbasic. Here is a screenshot:

(http://i62.tinypic.com/nn5zsg.jpg)

Just used my desktop to install your library and copied the files onto my laptop. Couple things I noticed.

- The ReadMeMasmBasic.txt shows the download location for JWasm at "http://www.japheth.de/JWasm.html#jwdownload" which seems to be an invalid location now.

- After replacing ml.exe with Jwasm.exe I received  an error when attempting to assemble my program. Example of code where I encountered and error below:


.if eax == 1
     do this
.elseif
     do this
.endif


Now my .elseif should have been an .else in the first place but just wanted to let you know since it appears you wanted Jwasm to be a backwards compatible with microsofts ml.exe. Jwasm was just letting me know about my poor programming which microsofts ml.exe didn't care about.

Also just FYI. I'm sure you already know but Avast is throwing some fits about your installer.
Title: Re: MasmBasic
Post by: jj2007 on October 16, 2015, 11:14:32 AM
Quote from: azdps on October 15, 2015, 01:52:02 AMI was attempting to install your masmbasic library but the install screen is too large for my laptop screen.

Thanks a lot for your feedback, azdps. The installer should be OK with version 16 October.

Quote- The ReadMeMasmBasic.txt shows the download location for JWasm at "http://www.japheth.de/JWasm.html#jwdownload" which seems to be an invalid location now.

- After replacing ml.exe with Jwasm.exe I received an error

That ReadMe is obsolete and will disappear soon. Re JWasm, just hit F6 when you see the manual, RichMasm will install JWasm. If Avast allows it, of course :bgrin:

And indeed, JWasm is occasionally a bit stricter than ML, but that's a feature IMHO. You may try also Nidud's AsmC, it's incredibly fast and seems to work fine now.

Version 16 October 2015 (http://masm32.com/board/index.php?topic=94.0): Fixed a few minor glitches in RichMasm, and re-installed the possibility to concatenate FileRead$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1075) as in the snippet below.

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  StringToArray FileRead$("\Masm32\include\Windows.inc")+FileRead$("http://masm32.com/board/index.php?action=help")+FileRead$("\Masm32\include\WinExtra.inc"), x$()
  push eax
  For_ ecx=0 To eax-1
      .if Instr_(x$(ecx), "<head>", 1)
            PrintLine "...", CrLf$, Str$(ecx), Tb$, "[", Left$(x$(ecx), 70), " ...]"      ; print one line of the embedded HTML code
      .endif
      mov edx, stack
      sub edx, 4
      .if ecx<5 || ecx>=edx      ; print first 5 and last 4 strings
            .if Zero?
                  PrintLine "..."
            .endif
            PrintLine Str$(ecx), Tb$, x$(ecx)
      .endif
  Next
  pop edx
  pop edx
  Store "ThreeFiles.txt", x$()      ; write all strings to disk
  ShEx "ThreeFiles.txt"      ; show the result in Notepad
EndOfCode
Title: Re: MasmBasic
Post by: bsdsource on October 17, 2015, 03:56:53 PM
jj2007 when testing the newest installer from the SetupMasmBasic17Oct15.zip the buttons now show at the bottom so it will install now. Just for testing purposes I pressed on the Masm32 Forum button and the program crashes and an error message box displays indicating the following: Setup.exe has stopped working. A problem caused the program to stop working correctly. Please close the program. I get the crash as well when clicking on close at the top right corner. The install button works without any issues.

I'm using Windows 8.1 32bit. Haven't tested it on my desktop which is running Windows 7 yet.
Title: Re: MasmBasic
Post by: jj2007 on October 18, 2015, 04:38:33 AM
Thanks, azdps, for this information. It is indeed a bug, and I am trying to fix it right now.

EDIT: Fixed in version 19 October, please download and reinstall. (http://masm32.com/board/index.php?topic=94.0)

Extract$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1156) has now a wildcard option:
Let t$(ct, subject)=Extract$(esi, Chr$('class="subject"*"', 62), '</a>', xsWildcard)

Useful if you want to extract e.g. The Campus from
<a class="subject" href="http://masm32.com/board/index.php?board=1.0" name="b1">The Campus</a>

With the attached example, this output can be obtained:
The Campus                  Today at 07:48:01 AM             Re: Calling an EXEs export functions
The Workshop                Today at 07:56:53 AM             Re: MasmBasic
The Laboratory              Today at 07:02:35 AM             Re: GetCpuFrequency Tests
The Soap Box                Today at 11:45:25 AM             Re: What base jumpers do when they grow up. :)
The Colosseum               Today at 11:50:13 AM             Re: Microsoft 'Accident' Forces Windows 10 Onto Windows 7, Windows
Title: Bug warning for MasmBasic before 20 Oct 2015
Post by: jj2007 on October 20, 2015, 01:59:37 PM
Please reinstall MasmBasic (safe, doesn't overwrite any user sources). This bug affects all versions before today:

include \masm32\MasmBasic\MasmBasic.inc      ; download the good version (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let edi="LMR"
  Let esi=Mid$(edi, 2, 1)+Str$(0)+Mid$(edi, 2, 1)      ; M0M, OK
  PrintLine "[", esi, "]"      ; Mid$+Str$+Mid$ ok
  Let esi=Mid$(edi, 2, 1)+"/"+Mid$(edi, 2, 1)      ; crappy result
  PrintLine "[", esi, "]"      ; 2xMid$ etc failed miserably before 20.10.2015
  Exit
end start


In short, using Left$, Mid$ or Right$ twice with the same string as in Let My$=Left$(some$, somect)+Left$(some$, somect) caused trouble.

Sorry for the inconvenience. To compensate, I've improved the "Tiny GUI demo" that appears in menu File/New Masm source (34 lines of code, sizable window):
Title: Simple graphics
Post by: jj2007 on October 23, 2015, 07:41:00 PM
MasmBasic update of 23 October 2015 (http://masm32.com/board/index.php?topic=94.0) features major changes under the hood:
include \masm32\MasmBasic\Res\MbGui.asm ; OPT_Icon Plot
  Dim MySinus() As REAL8
  For_ ct=-400 To 400
SetFloat MySinus(ct+400)=Sinus(ct) ; *** a GUI demo in 24 lines of code ***
  Next
Event Paint
  ArrayPlot hWnd, RgbCol(192, 222, 255) ; init & set background
  ArrayPlot MySinus(), 0, lines=5, 00100204h ; draw the array
  ArrayPlot exit, "Playing with Sinus() plots" ; finish with a title
  For_ ct=20 To GuiWidth-20 Step 10
GuiLine 50.0, 3.0+25, ct, 99.0, RgbCol(255, 160, 160) ; the 'pink pyramid'
void Cosinus(ct) ; load cos(ct) into ST(0)
fimul GuiHeight
fiadd GuiHeight ; center
fmul FP4(0.4)
SetInt ecx ; convert result to integer
GuiText ct+30, ecx+60, Str$(ct), bcol RgbCol(192, 222, 255)
GuiCircle ct, ecx+70, 1.5, b Rand(0ffffffh), p RgbCol(80, 80, 80)
  Next
  GuiEllipse 32.0+9, 10.0+35, 7.0, 8.0, b RgbCol(255, 128, 128) ; RGB for n00bs
  GuiEllipse 60.0-9, 10.0+35, 7.0, 8.0, b 0FF2020h, p 808080h ; BGR for experts
  GuiTextBox 50.0-70, 40.0, 140, 96, Str$("Painting took %i ms. This is just a simple text box, you can do the same in other programming languages", GuiMs), bcol RgbCol(255, 255, 192)
  GuiCircle 50.0, 40.0+50, 12.0, p 0, b none ; none = hollow brush
EndOfCode


The window is sizable and flicker-free. The template is available via RichMasm's File/New Masm source list of templates, it's the "more" link behind "Tiny GUI demo".

RichMasm has now a full word search option, for distinguishing e.g. between edi and immediate. In the upper right corner, the FW check box switches it on (in case the toolbar is not wide enough to see the FW, press Ctrl G, type tbw=150 and hit Enter).
Title: Re: MasmBasic
Post by: jj2007 on October 30, 2015, 12:54:53 PM
Update 30 October 2015 (http://masm32.com/board/index.php?topic=94.0) features minor improvements, inter alia the recognition of quoted strings like "123" and '123' as valid number formats, see StringToArray in \Masm32\MasmBasic\MbGuide.rtf:

      ; convert string to a numerical array:
      include \masm32\MasmBasic\MasmBasic.inc
      SetGlobals a1$="123 27.5 28.49 -56.78 '20h' 0x40 11111b/123456789"      ; string with a wild mix of number formats
      Init
      Dim MyDw() As DWORD
      For_ ecx=0 To Fn(StringToArray a1$, MyDw())-1      ; strings to dwords conversion
            PrintLine Str$("MyDw(%i)=", ecx), Str$(MyDw(ecx))
      Next
      EndOfCode


Output:
MyDw(0)=123
MyDw(1)=28
MyDw(2)=28
MyDw(3)=-57
MyDw(4)=32
MyDw(5)=64
MyDw(6)=31
MyDw(7)=123456789


Notes:
- StringToArray returns #elements in eax; in For_ ... Next loops, you may use Fn(...)-1 as shown above
- numeric arrays must be declared (BYTE ... QWORD, REAL4/8/10), but there is no need to Dim a string array before
Title: Re: MasmBasic
Post by: jj2007 on November 06, 2015, 12:23:31 PM
Update 6 November changes the display of file timestamps (more (http://masm32.com/board/index.php?topic=4785.msg51603#msg51603)). Files that were modified during Daylight Saving Time now show the correct time, identical to the one displayed by Windows Explorer (which is in contrast to time shown by DOS and some file managers).
Title: Major update
Post by: jj2007 on November 21, 2015, 01:25:28 PM
MasmBasic update 21 Nov 2015 (download (http://masm32.com/board/index.php?topic=94.0)) features several improvements under the hood. Check (in MbGuide.rtf) in particular the TimeSF and IsoWeek functions.

The RichMasm editor crashed on rare occasions when inserting a hyperlink with Ctrl K. This is fixed now.
Title: 90 projects
Post by: jj2007 on November 23, 2015, 11:34:05 AM
Sometimes people post Hello World "projects" distributed over a dozen files. Apparently it looks more professional to put the three PROTO lines into separate include files.

When installing MasmBasic (e.g. the latest version (http://masm32.com/board/index.php?topic=94.0)), the first thing you'll see after clicking Accept & Install is the file MbGuide.rtf loaded with the RichMasm editor, as shown below (shortened).

Click the link "try 90+ snippets" to open MbSnippets.asc, a collection of over 90 "projects" (second image below). MasmBasic's editor has a very special feature: If the command Init is selected and you hit F6, it checks if there is an include ... line before and an end start or EndOfCode line afterwards. If both are found, the editor exports only the code between the two lines.

While the listbox has the focus, you can use cursor up/down to scroll through the "projects", which demonstrate some of the over 200 MasmBasic commands. If you see an interesting command, just hit F6 to see it in action :biggrin:
Title: GetProcessArray()
Post by: jj2007 on November 26, 2015, 10:32:53 AM
As a complement to GetRegKeyArray and GetRegArray (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1280):

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Print "ct", Tb$, "ID", Tb$, "path"
  For_ n=0 To GetProcessArray(?)-1
      Print Str$("\n%i\t", n), Str$(MbProcID(n)), Tb$, MbProc$(n)
  Next
  Inkey CrLf$, "--- hit any key ---"
EndOfCode


Output:
ct      ID      path
1       324     \Device\HarddiskVolume3\Windows\System32\smss.exe
2       692     \Device\HarddiskVolume3\Windows\System32\wininit.exe
3       752     \Device\HarddiskVolume3\Windows\System32\services.exe
4       772     \Device\HarddiskVolume3\Windows\System32\lsass.exe
5       780     \Device\HarddiskVolume3\Windows\System32\lsm.exe
6       888     \Device\HarddiskVolume3\Windows\System32\winlogon.exe
7       924     \Device\HarddiskVolume3\Windows\System32\svchost.exe
8       992     \Device\HarddiskVolume3\Windows\System32\nvvsvc.exe
...


Source & exe attached, building requires latest MasmBasic version.
Title: Re: MasmBasic
Post by: Oliver Scantleberry on November 28, 2015, 03:08:25 PM
Quote from: jj2007 on May 23, 2012, 10:16:07 PM
MasmBasic is a library that allows to use BASIC syntax in assembler. . .

This is absolutely brilliant! I have been programming Intel processors in Assembly Language since 1975. In fact, hand-assembling the first few years. What I have always dreamed of, is using Microsoft 4k Basic syntax in assembly. Wow! This guy JJ is just awesome! He knows what everybody wants! I am thrilled!
Title: Re: MasmBasic
Post by: dedndave on November 28, 2015, 08:14:34 PM
i think Jochen has a new fan   :biggrin:
Title: Re: MasmBasic
Post by: jj2007 on November 28, 2015, 08:26:52 PM
At least one :P

Quote from: Oliver Scantleberry on November 28, 2015, 03:08:25 PMHe knows what everybody wants! I am thrilled!

Thanks, although I am not so convinced ::)
I would be stinkin' rich if that bold statement was true :bgrin:
Title: WebCam and Scintilla
Post by: jj2007 on December 02, 2015, 11:04:53 AM
MasmBasic version 2 December '15 features two new templates called Scintilla+RichEdit and WebCam. The latter is a bit long to post here, but here is a choice of three edit controls (plus a listbox) in less than 20 lines:

include \masm32\MasmBasic\Res\MbGui.asm      ; OPT_Icon Smiley
  GuiControl MySci, "scintilla", h 333, w 750, text "Привет, это контроль Scintilla"      ; h 333 = 1/3 of height
  GuiControl MyEdit, "edit", y 336, h 333, w 750, text "Это нормальная управления редактирования."
  GuiControl MyRich, "richedit", y 672, h 333, w 750, text "Это контрольный RichEdit."
  GuiControl MyListbox, "listbox", x 750, w 250
  GetFiles *.asm             ; fill Files$() array
  SortFiles                  ; most recent on top
  SetListbox "** select a file **"
  SetListbox Files$()
  SetGlobals cursel, f$
Event Command
  .if IsTrue(LbSel ne cursel) && signed LbSel>0
      m2m cursel, LbSel
      Let f$=FileRead$(LbSel$)
      SetWin$ hMySci=f$, sci
      SetWin$ hMyEdit=f$
      SetWin$ hMyRich=f$
  .endif
GuiEnd


As you can see above, Unicode is fine for these controls, and with MasmBasic's RichMasm editor you can type Chinese or Russian or whatever directly into the source code.

The snippet assumes \Masm32\wscite\SciLexer.dll; add YOUR path before the GuiControl if needed, for example:
ScintillaPath equ "\Masm32\bin\SciLexer.dll"

The Scintilla DLL is available here (http://www.scintilla.org/SciTEDownload.html), see "A full download (1200K) includes the SciTE executable, any required DLLs". Extract to \Masm32\ to get the wscite folder and SciLexer.dll (the only file you need from the package to run the three edit controls example)
Title: GetFiles is now UTF-8
Post by: jj2007 on December 12, 2015, 11:28:29 AM
MasmBasic update 12 Dec 2015 features a major change under the hood: GetFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1056) returns now UTF-8 file names. This has no effect on file names using only Ansi characters, but it is a major improvement for those who use Russian, Chinese or Arabic file names (and that is quite a lot of people...). The snippet below shows its usage:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  SetCpUtf8
  GfCallback MyCb      ; set callback function for GetFiles
  GetFiles \Masm32\*.bas|*.inc|*.as?|*.rc      ; fill the Files$() array
  PrintLine Str$("\n%i files found. Newest files:\n", eax)
  SortFiles                  ; new files on top
  For_ ecx=0 To eax-1
      lea edx, [Files$(?)-10]      ; somearray(?) means #elements
      .if ecx<10 || ecx>=edx
            If_ Zero? Then PrintLine CrLf$, "Oldest files:"
            PrintLine Str$(GfSize(ecx)), Tb$, GfDate$(ecx), Spc2$, GfTime$(ecx), Tb$, Files$(ecx)
      .endif
  Next
  Inkey "---- hit any key ----"
  Exit

MyCb:            ; simple callback: ecx is file counter, esi current file in Unicode format
  If_ wInstr(esi, wChr$("msv"), 1) Then wPrintLine esi      ; demo for filtering output
  ret
end start


Output (shortened):
comsvcs.inc
msv1_0.inc
msvcrt.inc
msvcrt.inc
msvcrt

8868 files found. Newest files:
327013  12.12.2015  01:14:55    \Masm32\MasmBasic\MasmBasic.inc
1985    12.12.2015  01:13:22    \Masm32\MasmBasic\AscUser\NewSources.asc
1032520 11.12.2015  11:25:24    \Masm32\RichMasm\RichMasm.asc
620     11.12.2015  08:18:32    \Masm32\MasmBasic\TestMasmBasic.rc

Oldest files:
288     07.09.1998  14:17:58    \Masm32\examples\exampl01\filtinpt\rsrc.rc
288     07.09.1998  14:17:58    \Masm32\examples\exampl01\comctls\rsrc.rc
288     07.09.1998  14:17:58    \Masm32\examples\exampl01\dll\loaddll\rsrc.rc
288     07.09.1998  14:17:58    \Masm32\examples\exampl01\3dframes\rsrc.rc
288     07.09.1998  14:17:58    \Masm32\examples\exampl01\dll\calldll\rsrc.rc


The snippet shows also how to use a callback function for GetFiles. If you return -111 in ecx, the current file will not be added to the Files$() array. Source & exe attached. Feedback, in particular from non-English members, appreciated :t
Title: Re: GetFiles is now UTF-8
Post by: Oliver Scantleberry on December 14, 2015, 01:33:13 PM
Quote from: jj2007 on December 12, 2015, 11:28:29 AM
MasmBasic update 12 Dec 2015 features a major change under the hood: GetFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1056) returns now UTF-8 file names. This has no effect on file names using only Ansi characters, but it is a major improvement for those who use Russian, Chinese or Arabic file names (and that is quite a lot of people...). . .

If I ever decide to program in assembly using Russian, Chinese, or Arabic, I will definitely give MbasicBasic a try. I'm right on top of Russian and Chinese but I need a little more work with Arabic. I keep reading it left to right.
Title: Unicode
Post by: jj2007 on December 23, 2015, 04:49:47 PM
MasmBasic update of 23 December 2015 (http://masm32.com/board/index.php?topic=94.0) improves and simplifies the use of Unicode & UTF-8 encoded charsets. This example shows recent sources in a listbox, and you can open them by double-clicking on an entry (source & exe attached):

include \masm32\MasmBasic\Res\MbGui.asm
  GuiControl MyLb, "listbox", y60, h940
  GuiControl MyEd, "static", text "Double-click to open a file - Дважды щелкните, чтобы открыть файл", h50
  GetFiles *.as?|*.rc      ; asc, asm, rc
  SortFiles                 ; latest files on top
  SetListbox Files$()      ; Fill the listbox with UTF-8 encoded file names
Event Command
  If_ NotifyCode==LBN_DBLCLK Then uShEx LbSel$   ; open selected file with ShellExecuteW (u=assume UTF-8 for LbSel$)
GuiEnd


Second example (screenshot below, source attached) shows three edit controls: Scintilla, ordinary "edit" and RichEdit. The program is resizable, and the controls adjust their sizes proportionally based on this simple syntax:

  GuiControl MySci, "scintilla", h500, x250, w300, text "... initial text ..."
  GuiControl MyEdit, "edit", y500, h500, x250, w300, text "..."
  GuiControl MyRich, "richedit", x550, w450, text "..."
  GuiControl MyListbox, "listbox", w250


MyEdit, for example, is positioned at x=25% of client area, y=50%, 30% wide and 50% high.
MyListbox is positioned at default x+y positions, i.e. top left, full height and 25% width.
Title: Re: MasmBasic
Post by: guga on December 24, 2015, 06:41:11 AM
All i can say is WOW !!!!!

How you managed to hide the code from the rtf on right click ?

And the sinus example ! Loved it !
Title: Re: MasmBasic
Post by: Grincheux on December 24, 2015, 07:06:49 AM
I launched NewSources and it told me

Quote

0 files found. Newest files:

---- hit any key ----

Does not like Frenchies this program!!!

The two others programs run OK.
Title: Re: MasmBasic
Post by: jj2007 on December 24, 2015, 07:08:57 AM
Thank you, Guga, that was a nice feedback :P

But what do you mean with "hide the code from the rtf on right click" ?
Title: Re: MasmBasic
Post by: guga on December 24, 2015, 11:02:08 AM
Hmm...I found this feature while reading MasmBasic guide. The feature is the same behaviour as in Radasm.

In Radasm, when you click on a token or a macro ("If" macro or the ones marked with a "+" sign), the text is hidden. Ex:

If eax = 5
   mov eax 1558
End_If


When you click in the "If" string, the text is hidden and it displays only this:


If eax = 5
End_If


Yours interface is different then in Radasm, but the behaviour is similar. What i liked on yours is the way we can actually read things on the richedit control. The ability to read the hyperlinks is great, and the way the help is displayed on certain mouse clicks, such this "hidden" of part of the text, or when you click on a string that may be a defined token and shows up a sort of help of what it is

On yours, I did this...before clicking on the word "Init"

include \masm32\MasmBasic\MasmBasic.inc
;   hit F6 to assemble, link & run the Hello World example
  Init
  ; to test examples, replace the white line with your test code and press F6
  MsgBox 0, "Wow, it works!!!!", "Hi", MB_OK ; It worked? Use a template, or try 90+ snippets
  Print CrLf$, "OK - press any key" ; It choked? Read below about JWasm.
  Exit
end start


After waiting 2 seconds, the mouse pointer changed to a question mark and  it displayed this on a different color. (Also, the new text that shows can be scrolled. I simply loved that !:


include \masm32\MasmBasic\MasmBasic.inc
;   hit F6 to assemble, link & run the Hello World example
  Init
------------------------------------------------------------------------------------------------- <-------- This showed and it can be scrolled
Init This is perhaps the smallest possible complete Masm application:
include \masm32\MasmBasic\MasmBasic.inc
Init
Inkey "Hello World"
Exit
end start
Rem - the Init macro inserts the following two lines:
-------------------------------------------------------------------------------------------------<-------- This showed and it can be scrolled

  ; to test examples, replace the white line with your test code and press F6
  MsgBox 0, "Wow, it works!!!!", "Hi", MB_OK ; It worked? Use a template, or try 90+ snippets
  Print CrLf$, "OK - press any key" ; It choked? Read below about JWasm.
  Exit
end start



How you managed to do that on a richedit control ?????
Title: Re: MasmBasic
Post by: jj2007 on December 24, 2015, 08:14:38 PM
Quote from: guga on December 24, 2015, 11:02:08 AMAfter waiting 2 seconds, the mouse pointer changed to a question mark and  it displayed this on a different color. (Also, the new text that shows can be scrolled. I simply loved that !:
..
How you managed to do that on a richedit control ?????

Well, two richedit controls ;-)

When you hover over a keyword, e.g. GetFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1056) *.asm, and you right-click when the cursor changes to ?, RichMasm displays, overlapping the main control, a second borderless richedit control containing the MbGuide.rtf content. If you are fast enough, you can even left-click into that content and actually copy the example code. I use that several times a day, it's much easier than typing the stuff... try it with SortFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1060) ;-)

Btw inserting a hyperlink is very easy: copy the URL, select a word in the comment area, hit Ctrl K, OK.
Title: Advanced string sorting
Post by: jj2007 on December 31, 2015, 12:36:08 PM
This year's last MasmBasic version (http://masm32.com/board/index.php?topic=94.0) does not only care for an exotic bug in the JWasm and AsmC assemblers (http://masm32.com/board/index.php?topic=4964.0) (or is ML wrong? who knows  ::)), it also adds an interesting feature to the QSort string sort: You may use an index array to keep track of a string's original line number. Note this is not my idea, GfaBasic had it already in the mid-eighties; but MasmBasic is a bit faster: in case-insensitive mode, skipping leading spaces and using an index array, the routine sorts a Million strings in roughly one second on my Core i5 8)

include \masm32\MasmBasic\MasmBasic.inc
  SetGlobals c1, c2, c3
  Init                  ; ## create a dynamic string array and sort it ##
  Dim My$()
  xor ecx, ecx
  PrintLine "line", Tb$, "random string"
  .Repeat
      Let My$(ecx)=Str$("String %i", Rand(20)+1000)
      PrintLine Str$(ecx), Tb$, My$(ecx)
      inc ecx
  .Until ecx>=10
  QSortMode cis, sls, MyKeys()      ; case-insensitive, skip leading spaces, use an index array
  PrintLine CrLf$, "line", Tb$, "sorted string", Tb$, "was line"
  QSort My$()            ; sort all elements allocated so far
  For_ esi=0 To ecx-1
      PrintLine Str$("%i\t", esi), My$(esi), Str$("\t%i", MyKeys(esi))
  Next
  For_ esi=0 To ecx-1
      Rand("A", "Z", c1)      ; create three
      Rand("a", "z", c2)      ; random
      Rand("a", "z", c3)      ; chars
      Let My$(esi)=Chr$(c1, c2, c3, "_")+Mid$(My$(esi), 6)      ; rewrite string
  Next
  QSort My$()            ; sort all elements allocated so far
  PrintLine CrLf$, "line", Tb$, "resorted string", Tb$, "was line"
  For_ esi=0 To ecx-1
      PrintLine Str$("%i\t", esi), My$(esi), Str$("\t%i", MyKeys(esi))
  Next
  Inkey "OK?"
EndOfCode


Output:
line    random string
0       String 1009
1       String 1001
2       String 1002
3       String 1017
4       String 1013
5       String 1016
6       String 1004
7       String 1015
8       String 1000
9       String 1010

line    sorted string   was line
0       String 1000     8
1       String 1001     1
2       String 1002     2
3       String 1004     6
4       String 1009     0
5       String 1010     9
6       String 1013     4
7       String 1015     7
8       String 1016     5
9       String 1017     3

line    resorted string was line
0       Ebw_g 1017      3
1       Kia_g 1015      7
2       Ojo_g 1000      8
3       Olr_g 1002      2
4       Qgd_g 1001      1
5       Tvx_g 1010      9
6       Vdf_g 1009      0
7       Vny_g 1016      5
8       Xjo_g 1013      4
9       Ype_g 1004      6


Source + exe attached, plus an extended example showing how to use GuiImage:

include \masm32\MasmBasic\Res\MbGui.asm
Event Paint
  GuiImage "\Masm32\examples\exampl04\car\car.jpg", fit      ; fit to window mode
GuiEnd
Title: ZipMyProject
Post by: jj2007 on January 12, 2016, 01:07:20 PM
Inspired by Pelles C, I have written a plugin for RichMasm that zips the current source (including .rc, .inc etc if in the same folder) and copies the name of the zip file to the clipboard. It requires some zipper, e.g. 7-Zip (http://www.7-zip.org/download.html), and a recent MasmBasic installation (http://masm32.com/board/index.php?topic=94.0).

The attachment contains:
- a new version of RichMasm.exe, to be extracted as \Masm32\MasmBasic\RichMasm.exe
- ZipTheProject.dll and the source, to be extracted to \Masm32\MasmBasic\Plugins\ZipTheProject.dll

The plugin appears as last item in the System & plugins menu. For now, I have tested it with my 7z installation, and it works fine. Unicode file names work, too, but the name of the zip file will be e.g. ~tmpFile_12Jan.zip because 7z doesn't like UTF8 in the name of the archive.

Note that with 7-zip you can also use the extension .7z, with much better compression.

Work in progress, use at your own risk etc, feedback welcome 8)
Title: GDI+
Post by: jj2007 on February 25, 2016, 02:21:07 PM
First MasmBasic update this year (http://masm32.com/board/index.php?topic=94.0) features some improvements under the hood, plus new GdiPlus functions, see screenshot below and attached executable. The source is in \Masm32\MasmBasic\Res\GuiPieExcel.asc; inter alia, there is a conditional flag allowing to extract the data for the pie straight from M$ Excel.

P.S.: More recent versions of MasmBasic require that line 3, MyPie=100 gets deleted or commented out.
Title: Re: MasmBasic
Post by: HSE on February 26, 2016, 02:45:02 AM
Why Read R1C1:R6C2 notprocessed?
Title: Re: MasmBasic
Post by: Grincheux on February 26, 2016, 03:27:43 AM
It is not MasmBasic but RichBasic :badgrin:
Title: Re: MasmBasic
Post by: jj2007 on February 26, 2016, 03:36:57 AM
Quote from: HSE on February 26, 2016, 02:45:02 AM
Why Read R1C1:R6C2 notprocessed?

No idea. The request is StringToArray xlsRead$("R2C1:R9C2"), x$(), tab, and it works fine with my versions of Excel, i.e. Office 2003 and Office Starter 2010.

If you see this error string, it means you arrived at the connected state; which implies that the communication to Excel is working in principle.

If you comment out the xlsClose command, what do you see in Excel? Does Excel open the file?

If the Excel part is not interesting for you, here is an alternative:

  if 1                        ; 1 for testing, 0=use Excel to read from file
      ; Data "Asset      percent"            ; no header row
      Data "Gold      20"
      Data "Stocks      15"
      Data "Bonds      35"
      Data "ETFs      15"
      Data "Options      7.5"
      Data "Cash      7.5"
      Read x$(tab)      ; create and read a dynamic array of tab-delimited strings
  else
      xlsConnect            ; no args=System
      .if !Zero?              ; errors are returned via the Zero? flag
            xlsOpen esi            ; example from C++ (http://www.softwareandfinance.com/Visual_CPP/Pie_Chart.html)
            .if !Zero?
                  xlsConnect "PieData"            ; tell Excel to which sheet you want to talk
                  .if !Zero?
                        StringToArray xlsRead$("R2C1:R9C2"), x$(), tab
                  .endif
                  ; xlsClose
                  xlsDisconnect
            .endif
      .endif
  endif
Title: Re: MasmBasic
Post by: HSE on February 26, 2016, 04:59:04 AM
The file is open in the correct sheet when the message appear (just to test I saved it open in a different sheet), and later close normally. Perhaps some request format problem (realated with languaje?).

I don't say before but, of course, using the table the screen is magnificent.
Title: Re: MasmBasic
Post by: jj2007 on February 26, 2016, 05:24:34 AM
If your language is espanol, try using "F2C1:F9C2"
With Portuguese, it should be L2C1:L9C2 (more (http://cherbe.free.fr/traduc_fonctions_xl97.html) - look for row and column)

I attach the exe for Spanish.
Title: Re: MasmBasic
Post by: HSE on February 26, 2016, 06:17:13 AM
Impressive !  :t
Title: HeapValidate doesn't find any problems
Post by: jj2007 on March 02, 2016, 03:20:09 AM
include \masm32\include\masm32rt.inc
.code
start:
  mov ebx, rv(GetProcessHeap)
  invoke HeapAlloc, ebx, 0, 33
  xchg eax, esi
  mov byte ptr [esi+33], "x"   ; oops!
  invoke HeapValidate, ebx, 0, 0
  print LastError$()
  invoke HeapFree, ebx, 0, esi
  print LastError$()
  exit
end start


So far, so clear: 33 bytes allocated, 33 bytes used (or was it 34 with esi+33? anybody good at math?  ;))
And, as we all expect, LastError$ is 2 x "The operation completed successfully."

However, if you build this snippet with RichMasm, you'll get a different message:
## HEAP[DebugHeapTestMasm32.exe]:
## Heap block at 00583F08 modified at 00583F31 past requested size of 21
The operation completed successfully.

## HEAP[DebugHeapTestMasm32.exe]:
## Heap block at 00583F08 modified at 00583F31 past requested size of 21

## HEAP[DebugHeapTestMasm32.exe]:
## Invalid address specified to RtlFreeHeap( 00580000, 00583F10 )
The operation completed successfully.

** DebugHeap found errors **


From version 1 March 2016 (http://masm32.com/board/index.php?topic=94.0) onwards, RichMasm will debug console mode applications (and this includes Gui apps built with subsys console, so that's how you can test windows applications).

This feature can be suppressed by inserting OPT_NoDebug somewhere in the code (same for OPT_Wait 0, i.e. don't wait for a keypress). It will also not be used if RichMasm finds an int 3 somewhere in the source, as this will invoke Olly instead.

My tests with timing code from The Laboratory showed no performance differences to non-debugged code.
Title: MasmBasic update
Post by: jj2007 on March 03, 2016, 11:40:45 AM
Version 3 March 2016:
- DebugHeap now handles the infamous SHBrowseForFolder (http://masm32.com/board/index.php?topic=1169.msg11300#msg11300) exception
- If Structured Exception Handling is being used, DebugHeap is off; this was a problem for the SEH example in MbSnippets.asc (the file you see in the middle of the MbGuide welcome screen as "try 90+ snippets")
- Also, when scrolling through the code examples in MbSnippets.asc, the "Init" listbox does no longer lose the focus when you hit F6
Title: Bug warning
Post by: jj2007 on March 09, 2016, 03:58:34 PM
Recent versions of MasmBasic returned wrong results for the case-insensitive version of StringsDiffer() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1157), with consequences for QSort() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1175).
Please reinstall (http://masm32.com/board/index.php?topic=94.0).

The good news is that the new version works correctly, is 40% shorter and 30% faster :biggrin:
Title: Spreadsheet sorting
Post by: jj2007 on March 12, 2016, 02:46:46 PM
Version 12 March has a new feature - sorting by a column's value: (http://masm32.com/board/index.php?topic=94.0)

Quote; spreadsheet mode - you can sort tab-delimited files by column:
      Recall "MyDataBase.tab", db$(), tab            ; tab = tell Recall it's a tab-delimited file, Excel style
      xchg eax, ecx            ; keep #rows read in ecx
      QSort db$(), 0, 3  [, 0]            ; sort db$(), all rows, by column 3; [optional 0: do not skip the header row]
      QSort db$(), 0, 2003h            ; same but 2000h added: sort using Val() of column 3

This snippet sorts Windows.inc by the value of its equates, regardless if they are expressed as hex or decimal (see e.g. VT_ILLEGAL in the output below):

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Recall "\Masm32\include\Windows.inc", L$(), tab      ; load file to two-dimensional string array
  QSortMode cis, sls      ; case-insensitive, skip leading spaces
  QSort L$()            ; pre-sort alphabetically
  For_ ecx=0 To eax-1
      .if Instr_(L$(ecx), "equ", 5)      ; 5: 4=full word, 1=case-insensitive
            .Repeat
                  inc eax
                  mov dl, [eax]
            .Until !dl || dl>="0" && dl<="9"      ; e.g. SOMECONSTANT equ <123h>
            .if dl
                  mov byte ptr [eax-1], 9      ; insert a tab to separate string from numerical column
            .endif
      .endif
  Next
  QSort L$(), 0, 2001h, 0      ; sort all rows, 2000h to force MovVal() sort, column 1, 0=don't skip header row
  Store "MyFile.txt", L$()      ; save to file
  Print Str$("%i lines stored, now launching text viewer", L$(?))
  ShEx "MyFile.txt"      ; have a look - search for IMAGE_ORDINAL_FLAG64
EndOfCode


Output:
MAXLONGLONG                      equ 7fffffffffffffffh
CLR_NONE         equ 0FFFFFFFFh
ColorsWhite                 EQU 0FFFFFFFFh
FLS_OUT_OF_INDEXES               equ 0FFFFFFFFh
HOVER_DEFAULT   equ 0FFFFFFFFh
INADDR_BROADCAST          equ      0FFFFFFFFh
INADDR_NONE          equ            0FFFFFFFFh
...
VT_ILLEGAL          equ 0ffffh
Yellow                               equ 00FFFFh
UNICODE_STRING_MAX_BYTES         equ 065534
MCI_SEQ_NONE                         equ 65533
WCH_EMBEDDING                    equ 0FFFCh
Green                                equ 00FF00h
...
WS_EX_RIGHTSCROLLBAR                 equ 00000000h
WS_OVERLAPPED                        equ 0h
WSA_WAIT_EVENT_0                 equ ((DWORD 0)
WT_EXECUTEDEFAULT equ 00000000h                           
X3_BTYPE_QP_INST_VAL_POS_X       equ 0
X3_D_WH_SIGN_VAL_POS_X           equ 0
X3_EMPTY_INST_VAL_POS_X          equ 0
X3_IMM20_SIGN_VAL_POS_X          equ 0
...
IMAGE_ORDINAL_FLAG64             equ 8000000000000000h


Since MasmBasic's string sort is stable, the "pre-sort" after Recall() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172) provides alphabetical order for identical values, e.g. for CLR_NONE ... INADDR_NONE in the example above. The numerical sort is not overwhelmingly fast, due to the complexity of Val() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1202), but sorting one Million lines in three seconds looks acceptable IMHO.

Full code attached. Note that in 21 lines you cannot handle the more complex equates 8)
Title: New Switch_ macro
Post by: jj2007 on April 28, 2016, 09:04:26 AM
include \masm32\MasmBasic\MasmBasic.inc
  SetGlobals someinteger=5      ; for testing a case with a variable
  Init                          ; ## fast switch with jump table ##
  PrintLine "---------------- testing MasmBasic Switch_ ----------------"
  For_ ct=-3 To 20
      m2m ecx, 3
      Print Str$(ct), Tb$

      Switch_ ct
      Case_ -2
            PrintLine "Case -2"
      Case_ 0
            PrintLine "Case NULL"
      Case_ 8, 10, 12, ecx
            PrintLine "Case 8, 10, 12 or ecx"             ; ecx is set to 3
      Case_ someinteger
            PrintLine Str$("Case int var=%i", someinteger) ; case is a variable (or register)
      Case_ 19 : PrintLine "Case 19 (one line)" ; one-liner if only one instruction is needed
      Case_ 15 .. 17
            PrintLine "Case 15 .. 17"
      Default_
            PrintLine "..."
      Endsw_
  Next
EndOfCode


Output:
---------------- testing MasmBasic Switch_ ----------------
-3      ...
-2      Case -2
-1      ...
0       Case NULL
1       ...
2       ...
3       Case 8, 10, 12 or ecx
4       ...
5       Case int var=5
6       ...
7       ...
8       Case 8, 10, 12 or ecx
9       ...
10      Case 8, 10, 12 or ecx
11      ...
12      Case 8, 10, 12 or ecx
13      ...
14      ...
15      Case 15 .. 17
16      Case 15 .. 17
17      Case 15 .. 17
18      ...
19      Case 19 (one line)
20      ...


Requires MasmBasic of 28 April 2016, available here (http://masm32.com/board/index.php?topic=94.0). During installation, click on try 90+ snippets to see more examples.

The new Switch_ macro works with Microsoft MASM versions 6.15 ... 10.0 (11 not tested, grateful if somebody can do that...), JWasm, HJWasm and AsmC.

With the exception of the colon-separated one liner, Switch_ is perfectly compatible with the standard Masm32 switch macro. Under the hood, however, it creates a jump table, which makes it faster and shorter.
Title: Re: MasmBasic
Post by: HSE on April 28, 2016, 10:46:31 AM
Very nice JJ!

Give me a couple of years to study the macros :biggrin:

At first read it's unexpected that I obtain:

### line 343: case 19 : PrintLine "Case 19 (one line)",13,10 already defined ###


when I was expecting nothing or:
     < not possible, use separate line ##>


This is my PrintLine:PrintLine MACRO args:VARARG
  ifb <args>
print
  else
print args, 13,10
  endif
ENDM
Title: Re: MasmBasic
Post by: jj2007 on April 28, 2016, 05:24:30 PM
Interesting... you should get "already defined" when a Case_ is already defined, e.g. you have 2x Case 123 (which wouldn't make sense, therefore the forced error).

Would you mind post a complete little example? Thanks.
Title: Re: MasmBasic
Post by: HSE on April 28, 2016, 11:33:15 PM
Apparently the problem is that the comma of the arguments are interpreted like a multiple case (case_ 10 already exist). 

Case_ 19 : PrintLine "Case 19 (one line)",13,10

With Case_ 19 : PrintLine "Case 19 (one line)",13 ; A Case_ 13 is constructed (see the .exe)

Work perfect with only one argument (and no comma) Case_ 19 : PrintLine "Case 19 (one line)"
Title: Re: MasmBasic
Post by: jj2007 on April 29, 2016, 12:17:02 AM
It also works if you move it to the next line as shown below, but anyway, this is a very odd problem. Thanks for flagging this, HSE :icon14:

      Case_ 19
            PrintLine "Case 19 (one line)", 13, 10 ; one-liner if only one instruction is needed
Title: Re: MasmBasic
Post by: nidud on April 29, 2016, 12:41:06 AM
Post deleted per PM request
Title: Bug is fixed
Post by: jj2007 on April 29, 2016, 09:21:13 AM
*** archive 28 April was temporarily removed - under certain conditions, the Switch_ macro would unbalance the stack ***

But it's fixed now - please reinstall (http://masm32.com/board/index.php?topic=94.0). Sorry for the inconvenience, and thanks again to HSE for informing me about the problem.

Title: Improved Switch_ macro
Post by: jj2007 on May 06, 2016, 09:25:23 AM
Please install MB version 6 May 2016: (http://masm32.com/board/index.php?topic=94.0)
Inspired by point #2 of a blog post on the merits of Visual Basic, the Switch_ macro can now handle lt and gt:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  PrintLine cfm$("years\tclassification")       ; see #2, VB Case a<b (https://www.simple-talk.com/dotnet/.net-framework/10-reasons-why-visual-basic-is-better-than-c/)
  For_ ecx=6 To 34 Step 2
      Print Str$(ecx), Tb$

      Switch_ ecx
      Case_ lt 10 :      PrintLine "child"
      Case_ lt 19
            Print "teenie, "

            Switch_ ecx
            Case_ 10..13:      PrintLine "10..13"
            Case_ 14:          PrintLine "14"
            Case_ gt 14:       PrintLine "over 14"
            Endsw_

      Case_ gt 32 :            PrintLine "very old"
      Case_ gt 29, 29 :        PrintLine "old"
      Case_ 24, 26 :           PrintLine "the ideal age"
      Default_
            PrintLine "twen"
      Endsw_
  Next
EndOfCode


Output:
years   classification
6       child
8       child
10      teenie, 10..13
12      teenie, 10..13
14      teenie, 14
16      teenie, over 14
18      teenie, over 14
20      twen
22      twen
24      the ideal age
26      the ideal age
28      twen
30      old
32      old
34      very old


Source attached, tested with ML 6.15 and 10.0, JWasm, HJWasm and AsmC.
Title: For each x$ in My$() and Val("12, 45, 67", 3)
Post by: jj2007 on May 14, 2016, 02:17:03 PM
MasmBasic version 14 May 2016 has two new features:

1. For each x$ in My$():
See demo here (http://masm32.com/board/index.php?topic=5361.msg57453#msg57453). Works with arrays of strings, integers, real numbers and structures (created e.g. with Dim myrc() As RECT)

2. Val("12, 45, 67", pos):
Imagine you have a line of settings in some ini file, and you want to know the value of the sixth entry... cumbersome, right?

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  SetGlobals settings$="0, 0, 1366, 768, 3, 123, 456, 789"
  Init
  Inkey Str$("The value of the 6th number is %i", Val(settings$, 6))
EndOfCode

Output:
The value of the 6th number is 123
Title: MasmBasic & Windows 10
Post by: jj2007 on May 26, 2016, 12:46:49 PM
Following this thread (http://masm32.com/board/index.php?topic=5383.0) about the Rich Edit control, and unexpected error messages in Windows 10, RichMasm got a minor revision of the way it loads RichEd20.dll

Please reinstall. (http://masm32.com/board/index.php?topic=94.0) The new function is available to MasmBasic users as invoke MbLoadRich. A simple window (<50 lines) with a Rich Edit control is attached; check the WM_CREATE handler, as shown below. In a nutshell: If you have MS Office or the free Word Viewer (https://www.microsoft.com/en-us/download/details.aspx?id=4) installed, loading a fat RTF file will be a factor 30-50 faster.

WndProc proc uses esi edi ebx hWnd, uMsg, wParam:WPARAM, lParam:LPARAM
  SWITCH uMsg
  CASE WM_CREATE
      ; picks the best RichEd20.dll available, or, if available, the one in the current folder:
      invoke MbLoadRich
      invoke CreateWindowEx, WS_EX_CLIENTEDGE, chr$("RichEdit20A"), NULL,
        WS_CHILD or WS_VISIBLE or WS_BORDER or WS_VSCROLL or ES_MULTILINE,
        9, 9, 570, 352, hWnd, 103, wcx.hInstance, NULL
ExternDef RichEditUsed:DWORD ; optional: check which version was installed
xchg eax, ecx
SetWin$ ecx=Cat$("This control was created using "+CrLf$+RichEditUsed)
Title: Re: MasmBasic
Post by: jj2007 on June 22, 2016, 09:06:47 AM
Version 22 June 2016 (http://masm32.com/board/index.php?topic=94.0) features some improvements of the RichMasm editor (see here (http://masm32.com/board/index.php?topic=5314.msg58185#msg58185)), plus one new LineCount() macro and an improvement of PopCount() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1029).

LineCount - pretty fast, see timings (http://masm32.com/board/index.php?topic=3505.msg58276#msg58276)
      mov ecx, LineCount(pBuffer)                ; count carriage returns (Ascii 13, 0Dh)
      mov ecx, LineCount(pBuffer, 1000)          ; count CRs in the first 1000 bytes of the buffer
      mov ecx, LineCount(pBuffer, 1000, lf)      ; count linefeeds (Ascii 10, 0Ah)
      mov ecx, LineCount(pBuffer, 1000, "a")     ; count the char a
Rem   - returns DWORD in eax
      - use instead of EM_EXLINEFROMCHAR (which returns wrapped lines, not very useful for coding)


The new PopCount() allows limiting the count to 16 or 8 bits (this is not documented in MbGuide.rtf; note that PopCount() runs on all CPUs and is almost as fast as the native popcnt instruction that you may find on recent CPUs):

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init

  mov ebx, 88888888h
  PrintLine Str$("In ebx, %i bits are set: ", PopCount(ebx)), Bin$(ebx)
  mov ebx, 8888h
  Print Str$("In bx, %i bits are set\n", PopCount(16:ebx))
  mov ebx, 88h
  Print Str$("In bl, %i bits are set\n\n", PopCount(8:ebx))

  mov esi, cfm$("\nThis\nstring\nhas\nplenty\nof\nlines,\nbut\ncounting\nthem\nis\neasy")
  Inkey "The string", esi, Str$("\nhas %i lines", LineCount(esi))

EndOfCode


Output:
In ebx, 8 bits are set: 10001000100010001000100010001000
In bx, 4 bits are set
In bl, 2 bits are set

The string
This
string
has
plenty
of
lines,
but
counting
them
is
easy
has 11 lines
Title: MasmBasic interpreter
Post by: jj2007 on June 30, 2016, 10:58:18 AM
MasmBasic version 30 June (http://masm32.com/board/index.php?topic=94.0) has some improvements under the hood. Attached is a proof of concept for an "interpreter" - launch it, and edit the prefilled text.

Other changes regard the editor. A new option:
OPT_Cls 0 ; 0=do not clear the console when building a new version

Default remains "clear the console when building".
Title: Re: MasmBasic
Post by: jj2007 on July 03, 2016, 11:04:32 AM
Inspired by the A close to authodox API Window (http://masm32.com/board/index.php?topic=5468.msg58624#msg58624) thread, MasmBasic and RichMasm can now build 64-bit sources - example attached.

Inter alia, Vasily Sotnikov's includes and libs are required in \Masm64\Include and \Masm64\Lib
Plus, you need \Masm64\bin\ml64.exe etc

Note that the attached *.asc file, which opens in RichMasm, is the complete project. The resource file is built "on the fly", see the two red Rsrc at the end, while the x64 xml file is now included in the MasmBasic package. The icon files in \Masm32\MasmBasic\icons work fine with x64 8)

One of RichMasm's nice features is that an int 3 triggers the debugger when building a project. This works now with the x64 debugger, too. See the WM_CLOSE message for an example.
Title: Dual 64/32-bit assembly
Post by: jj2007 on July 16, 2016, 11:40:01 AM
MasmBasic update of 17 July 2016 (http://masm32.com/board/index.php?topic=94.0) has two new templates for "dual 32/64 building". The OPT_64 switch determines which version to use. A standard Masm32 installation is enough, no additional libraries required.

Here is the simpler console version:

include \Masm32\MasmBasic\Res\JBasic.inc
; ### simple console demo, assembles in 32- or 64-bit mode with ML64, AsmC, JWasm, HJWasm ###
  j@start     
  Print "This code was assembled with "      ; OPT_64 1      ; put 0 for 32 bit, 1 for 64 bit assembly
  Print Chr$(@AsmUsed$(1))
  ifidn @Environ(o64), <1>
      Print Chr$(" in 64-bit format", 13, 10)
  else
      Print Chr$(" in 32-bit format", 13, 10)
  endif
  Print "Print Str$(123), CrLf: "
  if 0
      Print Str$(123), 13, 10      ; not possible
  else
      PrintLine Str$(123)      ; much better ;-)
  endif
  Print "Type a number: "
  mov rsi, Input$()
  Print Str$("The value of your number is %i\n", Val(rsi))
  Print "64-bit assembly is easy, it seems..."
  j@end


; activate your favourite debugger by eliminating the x, then insert int 3 somewhere in your code and hit F6
OxPT_DebPath   \Masm64\arkdasm\arkDasm.exe
OxPT_DebPath   \Masm64\x64Dbg\release\x64\x64dbg.exe

Current macros available for 64-bit code (the absolute minimum for the usual homework request...):
jinvoke apiarg, args:VARARG
rv FuncName:REQ,args:VARARG
repargA rarg
Chr$ any_text:VARARG
Hex$ arg
Str$ sform$, sNum0:VARARG
Input$
Val arg$
Print args
PrintLine args
@AsmUsed$()
Err$()
Title: Dual 64/32-bit assembly
Post by: jj2007 on July 30, 2016, 03:16:40 AM
Side-by-side assembly ;)

(in CreateWindowEx, the @64 variable sets the x coordinate to a different position)
Title: Re: MasmBasic
Post by: jj2007 on August 06, 2016, 08:34:49 AM
Update 6 August (http://masm32.com/board/index.php?topic=94.0) features Inkey (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1109) and deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019) macros for 64-bit code - see menu File/New Masm code:
Dual 32/64 bit console/GUI   templates that compile both as 64 and 32-bit applications
Title: Re: MasmBasic
Post by: jj2007 on August 07, 2016, 07:14:39 PM
Minor update 8 August: SetListBox got more options; default options are fast but produce more code. Standard example:

include \masm32\MasmBasic\Res\MbGui.asm
  GuiControl MyLb, "listbox", y 60, h 940
  GuiControl MyEd, "static", text "Double-click to open a file - Дважды щелкните, чтобы открыть файл", h 50
  GetFiles *.as?|*.rc      ; asc, asm, rc
  SortFiles                ; show latest files on top
  SetListbox Files$()      ; Fill the listbox with UTF-8 encoded file names
  Event Command
  .if NotifyCode==LBN_DBLCLK
      uShEx LbSel$         ; open selected file with ShellExecuteW (u=assume UTF-8 for LbSel$)
  .endif
GuiEnd


For a speed test, see http://masm32.com/board/index.php?topic=5573.0
Title: Re: MasmBasic
Post by: jj2007 on August 15, 2016, 10:24:24 AM
Update 15 August: (http://masm32.com/board/index.php?topic=94.0)
- SetListbox may now take a callback function to decide if a string in a given array should be added
- Under menu File/New Masm source, a new template "controls" was added, inter alia with a SetListBox example
Title: Re: MasmBasic
Post by: jj2007 on August 30, 2016, 11:08:02 AM
Update 30 August: (http://masm32.com/board/index.php?topic=94.0)

- more complete dual 64/32 bit include files (no external libraries required)

- GetHash function:

include \masm32\MasmBasic\MasmBasic.inc
      Init
      Let esi=FileRead$("\Masm32\qEditor.exe")
      .if GetHash(esi, LastFileSize, sha)     ; FileRead$ sets LastFileSize, also for binary files
            PrintLine "The SHA of qEditor.exe is   ", Tb$, Hex$(xmm0), " ", Hex$(ecx)
      .else
            PrintLine "Hashing failed: ", Err$()
      .endif
      void GetHash(esi, LastFileSize)
      mov ecx, edx                              ; fifth word returned in edx
      Print "Fast MD5 of qEditor.exe is ", Tb$, Hex$(xmm0), CrLf$
      GetHashRev=1                              ; use official MD5 byte order
      .if GetHash(FileRead$("\Masm32\qEditor.exe"))   ; MD5, len of string will be calculated
            PrintLine "qEditor, byte order MD5 specs: ", Tb$, Hex$(xmm0)
      .endif
EndOfCode


- returns success (1) or failure (0) in eax
- four dwords are returned in xmm0
- in case of SHA, the fifth dword will be in edx
- results can be displayed as a Hex$(xmm0), plus Hex$(edx) for SHA. The byte order will be reversed, compared to
  online hash calculators. You may use GetHashRev=1 to follow the MD5 specs, but more code will be generated
- with only one para, GetHash calculates the length; this is meaningful only for text files
Title: Bug warning for MasmBasic
Post by: jj2007 on August 31, 2016, 11:02:44 AM
Attention, the 64-bit examples in version 30 August choked in Win10. Fixed for version 31 August (http://masm32.com/board/index.php?topic=94.0) - my apologies :redface:
Title: Re: MasmBasic
Post by: jj2007 on September 10, 2016, 10:53:32 AM
Version 10 September 2016 (http://masm32.com/board/index.php?topic=94.0) sees one major change: Instead of JWasm, the RichMasm IDE will now install HJWasm32 if it can't find it in \Masm32\bin

You can test this feature by
- renaming \Masm32\bin\HJWasm32.exe to HJWasm32_old.exe
- during MasmBasic installation, hitting F6 while the help file is shown

Feedback welcome - and thanks a lot to Habran and Johnsa for their hard work :t
Title: Alloc16 for SSE
Post by: jj2007 on September 20, 2016, 10:13:02 AM
Version 20 September 2016 (http://masm32.com/board/index.php?topic=94.0) introduces two new macros, Alloc16 and Free16:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
      Init
      Dim PtrSSE() As DWORD
      For_ ct=0 To A16Max-1      ; 100 aligned pointers
            Alloc16 Rand(10000)
            mov PtrSSE(ct), eax
            Print Hex$(al), " "
      Next
      For_ ct=0 To A16Max-1
            Free16 PtrSSE(ct)
      Next
      EndOfCode
Rem      for use with SSE instructions that require 16-bit alignment


Typical output:F0 D0 B0 B0 80 30 50 00 D0 D0 10 20 70 10 90 70 40 50 70 60 B0 B0 30 20 00 30 90 00 50 20 A0 30 E0 10 F0 20 B0 80 F0 50 E0 70 00 90 C0 F0 10 F0 50 E0 90 60 A0 20 A0 20 F0
C0 40 C0 50 A0 B0 20 E0 30 80 70 B0 A0 30 C0 50 B0 00 20 D0 F0 10 80 A0 A0 B0 10 A0 C0 70 10 20 F0 50 D0 B0 40 80 90 D0 B0 D0 60
Title: Re: MasmBasic
Post by: jj2007 on October 10, 2016, 11:59:56 AM
Update 10 October 2016: (http://masm32.com/board/index.php?topic=94.0) The MasmBasic Switch_ macro (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1285) is now also available for dual 64-/32-bit builds (see menu File/New Masm source/Dual 32/64 bit console/GUI templates, and the RichMasm (http://masm32.com/board/index.php?topic=5314.0) screenshot below). The source builds as 32- or 64-bit code with ML.exe, HJWasm (default) or AsmC. No other libraries required, just a valid Masm32 installation plus MasmBasic (http://masm32.com/board/index.php?topic=94.0).

Other minor additions:

mcs      multiple commands - see example in the message loop below
      mcs mov eax, 100 : add eax, 30 : sub eax, 7: deb 4, "sum:", eax : Inkey "-- press any key --"
      mcs mov eax, 100 : add eax, 30 : sub eax, 7: <Print Str$("result: eax=%i\n", eax)>
Rem      - mcs allows to put several commands on one line, separated by a colon as in Basic
      - if macros depend on previous commands, like e.g. Str$(...), <put them in brackets>


xmov      extended mov
      xmov MyR8, 123456.7890123456      ; assign a double directly
      xmov MyR4, MyR8      ; mem to mem, different operand size
      xmov someSQ, someSD
      xmov someSD, someSQ
      xmov ct, -5
      xmov MyR4, 32767
Rem      - use if in doubt about the best way to shove a value into a memory location (check the disassembly)
      - works with MasmBasic and 64-/32-bit JBasic


jinvoke
      jinvoke MyTest, &v0, *v1, addr v2, offset v3, &v4, v5
Rem      - jinvoke is a macro that works like invoke but assembles with 32- and 64-bit code alike
Title: Re: MasmBasic
Post by: jj2007 on November 04, 2016, 11:15:12 AM
Version 4 November 2016 is available (http://masm32.com/board/index.php?topic=94.0) :icon_cool:

New features:

a) GuiImage (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1342) learned to care for resources, Unicode and the Internet (see attached Avatars.zip for an example using resources; no temp files 8)):

include \masm32\MasmBasic\Res\MbGui.asm
Event Paint
  ; args are imgsrc$ or resource ID, optional: no args=upper left corner, original size, x=fit: use full canvas, or x, y [, w, h]
  GuiImage "\Masm32\examples\exampl04\car\car.jpg", fit                  ; use full canvas
  GuiImage "\Masm32\examples\exampl04\car\car.jpg", 50, 400, 160, 900   ; use specific x, y, w, h
  GuiImage "\Masm32\examples\exampl04\car\car.jpg", 50, 200            ; use x, y, original w, h
  GuiImage "\Masm32\MasmBasic\Res\FileOpen.png", 100, 7, 40, 40      ; use specific x, y, w, h
  GuiImage "\Masm32\MasmBasic\Res\MasmLogo.png"                  ; upper left corner, original size
  GuiImage "http://masm32.com/board/index.php?action=dlattach;attach=6;type=avatar", 7, 7
  GuiImage "Это тест.jpg", fit     ; Unicode is allowed
  GuiImage wCL$(), 315, 7          ; also via the commandline
  GuiImage 125, 84, 7, 70, 70      ; 125 is a RC_DATA resource ID (IDs must be 48...127)
  GuiImage Files$(ecx), 238, 7, 70, 70                  ; you can dynamically load images
GuiEnd


b) MemState for identifying leaks, e.g. in the Paint event:

GuiParas equ "Hello Masm32 Forum", x400, y100, w250, h300
include \masm32\MasmBasic\Res\MbGui.asm
SetGlobals imgCt
void Split$("Hutch\nDednDave\nErol\nqWord\nrrr314159\nSteve\nMarinus\nBaltoro\nYves\njj2007", "\n", name$())
Event Key
  .if wParam==VK_LEFT && imgCt>48
      dec imgCt
  .elseif wParam==VK_RIGHT && imgCt<57
      inc imgCt
  .endif
  GuiRefresh

Event Paint
  If_ imgCt==0 Then add imgCt, 48
  MemState("WorkingSetSize, abs delta: %__i ", abs delta)
  GuiImage imgCt, fit
  GuiTextBox 7, 99.9-25, 80, 18, name$(imgCt-48)

GuiEnd


In Avatar.exe, when you hit the right key to advance in the list of images, changes in memory use will be printed to the console (see \Masm32\MasmBasic\MbGuide.rtf for all MemState() options):
WorkingSetSize, abs delta: 3392 2840
WorkingSetSize, abs delta: 3524 132
WorkingSetSize, abs delta: 3636 112
WorkingSetSize, abs delta: 3572 -64
WorkingSetSize, abs delta: 3620 48
WorkingSetSize, abs delta: 4008 388
WorkingSetSize, abs delta: 4020 12


c) SysLink control implemented:

GuiParas equ "SysLink demo", w600, h400, ICC_LINK_CLASS      ; title, height, classes needed
include \masm32\MasmBasic\Res\MbGui.asm            ; this include file ships with MasmBasic (http://masm32.com/board/index.php?topic=94.0)
GuiControl MySysLink, "SysLink", FileRead$("http://www.webalice.it/jj2006/MbLinks.htm")
Event Command
  If_ NotifyCode==NM_CLICK Then wShEx Link$()            ; open link in browser
GuiEnd
Title: Re: MasmBasic
Post by: jj2007 on November 07, 2016, 12:02:51 PM
Update 7 November (download (http://masm32.com/board/index.php?topic=94.0)):

The GuiImage function got two companions: GuiImageCallback and SaveImageToFile:
include \masm32\MasmBasic\Res\MbGui.asm ; simple foto viewer, allows rotation without changing the time stamp
  GuiImageCallback RotateOrSave
  SetGlobals rotatemode, savemode, imgCt, maxCt ; *** use at your own risk, test with less valuable photos! ***
  GetFiles wCL ; translate commandline to Files$() array
  dec eax
  mov maxCt, eax
Event Key
  mov ecx, maxCt
  .if wParam==VK_LEFT && imgCt>0
dec imgCt
  .elseif wParam==VK_RIGHT && imgCt<ecx
inc imgCt
  .elseif wParam==VK_R && rotatemode<=7
.if Zero?
and rotatemode, 0 ; 7->0
.else
inc rotatemode
.endif
  .elseif wParam==VK_L
dec rotatemode
.if Sign?
m2m rotatemode, 3 ; 0->3
.endif
  .elseif wParam==VK_S
dec savemode ; save image
  .endif
  GuiCls ; trigger the Paint event
Event Paint
  mov ecx, Files$(imgCt)
  SetWin$ hWnd=Mid$(ecx, Rinstr(ecx, "\")+1))+" - ImageViewer"
  GuiImage ecx, fit
EndOfEvents ; v v v user-defined callback function v v v
RotateOrSave:
  gdi+ GdipImageRotateFlip, gicbObj, rotatemode ; gicb stands for GuiImageCallBackObject
  .if savemode
Clr savemode, rotatemode
SaveImageToFile wFiles$(imgCt)
  .endif
retn
GuiEnd


Full project attached. Tested on Win10, Win7-64 and XP, but use at your own risk. Make a backup of your marriage photos first 8)

Btw, in contrast to the behaviour of the Windows image viewer, this proggie will keep the timestamp after rotation. Use the left and right arrow keys to scroll through the photos, use the l and r keys to rotate and flip images. If you build it yourself, you may use the s key to save the rotated image.

If you see GetLastError, incorrect parameter, it just means that you didn't drag any images over the exe. You can also open a DOS prompt in the exe's folder and paste ImageViewAndRotate.exe http://masm32.com/board/index.php?action=dlattach;attach=6;type=avatar :eusa_dance:
Title: Bug warning for MasmBasic
Post by: jj2007 on November 08, 2016, 12:19:19 PM
To all who installed version 7 November: There was a little glitch with SaveImageToFile and Unicode file names. It's fixed, please install version 8 November (http://masm32.com/board/index.php?topic=94.0) (thanks to Mike for the inspiration :P).

The update allows also Unicode launches now, e.g. passing Chinese text to a MessageBox.exe in Russian:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Launch "Окносообщения.exe 您可以将中文文本传递到应用程序。"
EndOfCode
Title: Re: MasmBasic
Post by: jj2007 on November 09, 2016, 12:13:44 PM
Attached two new examples - extract to a new folder, launch
a) LaunchUnicodeExes.exe (should produce what's shown in the screenshot)
b) ImageViewAndRotate.exe
to test them. Grateful for feedback 8)

Sources are included as *.asc files, building requires Masm32 and the latest November 9 MasmBasic. (http://masm32.com/board/index.php?topic=94.0)

Title: Re: MasmBasic
Post by: jj2007 on November 26, 2016, 11:28:12 AM
Download update 26 Nov 16: (http://masm32.com/board/index.php?topic=94.0)

Inter alia, GuiImage handles now animated GIFs automatically; search \Masm32\MasmBasic\MbGuide.rtf for .MbGui

Example (attached):

GuiParas equ "GuiImage demo", x100, y100, w540, h180, bnone, m0, deb0  ; no background, margin zero, debug 0
include \masm32\MasmBasic\Res\MbGui.asm                  ; part of MasmBasic (http://masm32.com/board/index.php?topic=94.0)
Event Paint
  GuiImageSpeed 200                  ; animation speed 200%
  GuiImage "\Masm32\examples\exampl04\car\car.jpg", fit            ; background
  GuiImage "http://masm32.com/board/index.php?action=dlattach;attach=6;type=avatar", 300, 64, 40, 40
  GuiImage "\masm32\MasmBasic\icons\Smiley.ico", 118, 40, 32, 32
  GuiImage 48, 170, 56, 64, 64                  ; resID, x y w h
GuiEnd
Rsrc            ; **** during assembly, RichMasm exports this section as filename.rc ****
32512 ICON "\\masm32\\MasmBasic\\icons\\Globe.ico"
48 RCDATA "Shooter.gif"
Rsrc


The demo displays
- a static background car.jpg
- an avatar (members only, sorry :biggrin:)
- a smiley (the car needed a little decoration)
- and an animated GIF from the resources
Title: Re: MasmBasic
Post by: jj2007 on December 01, 2016, 01:11:52 AM
Version 30.11.16 (http://masm32.com/board/index.php?topic=94.0) adds a new functionality to the StringToArray  (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1130)command:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi="Open"      ; just an example: Open "O", #1, "somefile.txt"
  StringToArray 123, mbi$()    ; 123 is the resource ID
  .While 1
      Let esi=Input$("Search for macro: ", esi)
      .Break .if Len(Trim$(esi))==0
      push mbi$(?)      ; #elements on stack
      xor ecx, ecx
      Cls
      .Repeat
            .if Instr_(mbi$(ecx), esi, 1)==1      ; case-insensitive search
                  .Break .if Instr_(mbi$(ecx), "macro", 5)      ; case-insensitive, full word
            .endif     
            inc ecx
      .Until ecx>=stack
      dec ecx
      .Repeat
            inc ecx
            PrintLine mbi$(ecx)
      .Until Instr_(mbi$(ecx), "endm", 5)==1 || ecx>=stack
      pop edx
  .Endw
  Print "bye"
  Delay 500
EndOfCode

Rsrc      ; when hitting F6, RichMasm exports this section to [filename].rc
123 RCDATA "\\Masm32\\MasmBasic\\MasmBasic.inc"
Rsrc


In this snippet, StringToArray converts an embedded text file (MasmBasic.inc) to a string array.

Project is attached, including the rc file, which is not needed if you build the source with RichMasm.
Title: Re: MasmBasic
Post by: jj2007 on December 12, 2016, 01:59:09 PM
Update 12 December (http://masm32.com/board/index.php?topic=94.0) features an improved handling of toolbars, see an example in the small editor thread (http://masm32.com/board/index.php?topic=5858.0).

One new feature, you can extract a file from resources:

  FileWrite "MyFile.txt", "MyString"            ; opens a file and writes a string to file
  FileWrite "MyFile.txt", "MyString", 2         ; same but writes only first 2 bytes
  FileWrite "MyFile.rtf", stream:hRichEdit      ; save contents of the RichEdit control
  FileWrite "MyFile.uctxt", stream:hRichEdit, SF_TEXT or SF_UNICODE  ; same but specify a format
  If_ Not Exist("build.bat") Then FileWrite "build.bat", res:99      ; extract a file from RCDATA resource #99
  FileWrite "MyFile.txt", "MyString", xmm0      ; sets the timestamp in xmm0
Rem      returns Close retval in eax and bytes written in edx
Title: Re: MasmBasic
Post by: jj2007 on December 16, 2016, 11:52:20 AM
Update 16 December is inspired by Caballero's Ancient DOS sounds (http://masm32.com/board/index.php?topic=5866.0) thread and uses the new 'get a string array from resources' feature:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0) (needs version 16 December 2016 or later)
  Init
  StringToArray 123, music$()      ; get an array from resources
  For_ ct=0 To eax-1
      Sound music$(ct)
  Next
EndOfCode


Resources:
32512 ICON      "\\Masm32\\MasmBasic\\icons\\Smiley.ico"
123 RCDATA      "Song4MasmBasic.txt"


The attachment contains a Pelles C source (BeepWC01.asc) based on Caballero's version for Tiny C. The switch #define Export2MasmBasic 0 in line 2 allows to export his sound as a text file with entries meaning pitch:duration:pause:
1045:250:100
650:250:100
650:250:100
1045:250:100
1045:1000:100
650:250:100
Title: Re: MasmBasic
Post by: jj2007 on December 20, 2016, 10:59:43 AM
Please install update 20 December 2016 (http://masm32.com/board/index.php?topic=94.0); inter alia, new events Data and DropFiles were added:

      Event Data      ; WM_COPYDATA
            MsgBox 0, CopyData$, "Received:", MB_OK
      Event DropFiles      ; loads the Files$() array; use wRec$() to convert Utf8 file names to true Unicode
            wMsgBox 0, wCat$(wStr$("%i files dropped, first one is\n[", Files$(?))+wRec$(Files$(0))+"], last one is "+CrLf$+"["+wRec$(Files$(Files$(?)-1))+"]"), "Event Dropfiles:", MB_OK or MB_TOPMOST
            Store "~tmpDropped.txt", Files$()      ; write dropped filenames to a text file in Utf8 format


As with GetFiles (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1056), file names obtained in the DropFiles Event are in Utf8 format.
Title: Re: MasmBasic
Post by: jj2007 on December 29, 2016, 11:00:31 AM
MasmBasic update 29 December 2016 is out, please reinstall.

In honour of the "Editor for testing (http://masm32.com/board/index.php?topic=5858.0)" thread, I've added a new handy macro:

Print "This application uses ComCtl32.dll version ", ComCtl32$()

Output: This application uses ComCtl32.dll version 6.16 (provided your resources and manifests are 100% ok :icon_mrgreen:)
Title: Re: MasmBasic
Post by: anta40 on December 29, 2016, 12:41:15 PM
Found a weird bug on the latest (29 December 2016) version:
While RichMasm is opened, if you click the "X" button, RichMasm won't quit, but only minimze itself instead.
Gotta terminate it manually using Task Manager.

Happens on 32-bit Windows 10.
Title: Re: MasmBasic
Post by: jj2007 on December 29, 2016, 01:03:01 PM
It's not a bug, it's a feature :P

Seriously: MbGuide.rtf is a special document, it will only minimise if you try close it. But if you close it while it is minimised, it will indeed close (besides, it will also close if no other docs are open in RichMasm).

The reason for this special behaviour is that it also serves as "F1 help". Select a keyword, then hit F1:
- if it's a MasmBasic keyword like Print, the paragraph on Print will be displayed in MbGuide.rtf
- if it's not found in MbGuide.rtf, e.g. CreateWindowEx, RichMasm will pass on the request to the program that follows in \Masm32\MasmBasic\Res\menus.ini, i.e. Win32.hlp:

[&Help]
&Basic,\masm32\MasmBasic\MbGuide.rtf#Mb
&WinHLP32,\Masm32\RichMasm\Help\WIN32.HLP


Thus, you get most of the time the help you expect, simply by selecting the keyword and hitting F1.

Note that for the MasmBasic keywords, about 200, RichMasm has another mechanism: Hover over the keyword, e.g. GetFiles, until the mouse cursor turns into a question mark. Then right-click (I'm afraid this is case-sensitive, so getfiles will work only with F1).
Title: Printing the content of an edit control on paper
Post by: jj2007 on January 05, 2017, 01:12:48 PM
Just found a lengthy article on Printing text in Win32 can be a little complicated (http://www.masmforum.com/board/index.php?topic=9364.msg68003#msg68003) posted by Paul Brennick over 8 years ago - I wish I had seen it earlier, it would have saved me a lot of work :(

Anyway, here is a simple method to print the content of a RichEdit control. This snippet reads a file from the commandline, and if you hit Ctrl P, its contents get printed - not in the sense of console print, but in the sense of: on real paper. Here is the source:

include \masm32\MasmBasic\Res\MbGui.asm      ; download (version 5 January 2017 or later) (http://masm32.com/board/index.php?topic=94.0)
  GuiControl MyEdit, "RichEdit"             ; create a RichEdit control
  If_ wExist(wCL$()) Then <SetWin$(hMyEdit)=wFileRead$(wExist$)>
Event Key
  If_ KeyCtrl && (VKey==VK_P || VKey==-VK_P) Then <MsgBox 0, Str$("%i pages printed", PrintRtf(hMyEdit, 2)), "PrintRtf:", MB_OK>
GuiEnd


Full project attached. The PrintRtf() macro needs a handle to a RichEdit control, and takes optional parameters as follows (excerpt from \Masm32\MasmBasic\MbGuide.rtf):

- if text is selected, then only the selection will be printed
- optional second arg: 0=use default printer, 1=use once the printer dialog, 2=use it always
- optional: margins in mm, e.g. void PrintRtf(hMyEdit, 0, 20, 20, 15, 20)       ; left, top, right, bottom
- printer settings like orientation etc are kept for the program's duration
Title: Download & Unzip
Post by: jj2007 on January 11, 2017, 12:42:48 PM
include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0) (version 11 January 2017 required)
  Init
  UnzipInit "http://www.terraspace.co.uk/hjwasm217_x86.zip"
  .if Sign?
      Print eax            ; print an error message
  .else
      For_ ecx=0 To edx-1      ; #files returned in edx
            mov esi, Files$(ecx)
            .if Rinstr(esi, "/")     ; zipfiles use forward slashes
                  xchg eax, esi      ; we don't display the full path
                  inc esi
            .endif
            PrintLine Str$(GfSize(ecx)), Tb$, GfDate$(ecx), Spc2$, GfTime$(ecx), Tb$, esi
            .if Instr_(esi, ".pdf", 1)
                  UnzipFile(ecx, Cat$(Left$(MbExeFolder$)+":\Masm32\bin\"))
                  ShEx Cat$("\Masm32\bin\"+esi)
            .endif
      Next
      UnzipExit
  .endif
EndOfCode
Title: Bugfix for Recall
Post by: jj2007 on January 27, 2017, 10:30:53 AM
With certain types of Unicode text files, Recall (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172) added garbage to the last string read. This is fixed with MasmBasic version 27 Jan 2017 - please reinstall (http://masm32.com/board/index.php?topic=94.0). The following will work properly now:

include \masm32\MasmBasic\Res\MbGui.asm      ; download (http://masm32.com/board/index.php?topic=94.0)
  Recall "http://www.webalice.it/jj2006/DemoChinese.dat", L$()
Event Paint
  For_ ct=0 To L$(?)-1
      GuiText 7, ct*16+7, Str$("# %i ", ct+1)
      GuiText 90, ct*16+7, L$(ct)
  Next
GuiEnd


The snippet above downloads the text from my personal website. Here is a variant where Chinese text is used in $Data statements:

GuiParas equ "A Chinese Poem", x300, y70, w300, h125, bRgbCol(255, 255, 222)
include \masm32\MasmBasic\Res\MbGui.asm
$Data 月夜
$Data 霜风呼呼地吹着,
$Data 月光明明地照着。
$Data 我和一株顶高的树并排立着
$Data 却没有靠着  。
Read poem$()            ; translate $Data elements to a string array
Event Paint
  For_ ct=0 To poem$(?)-1
      GuiText 7, ct*16+7, Str$("# %i ", ct+1)      ; display the array elements
      GuiText 60, ct*16+7, poem$(ct)
  Next
GuiEnd


The screenshot shows how it looks like in RichMasm and in the little window created by the above code.
Projects attached, feedback welcome of course.
Title: Re: MasmBasic
Post by: jj2007 on February 01, 2017, 10:40:11 AM
Update 1 February (http://masm32.com/board/index.php?topic=94.0) fixes two bugs:
1. One minor bug with Chr$("The letter is ", reg32): if reg32 was edi, the displayed letter was wrong. This works now (attached):

GuiParas equ "Key events only", x50, y50, w100, h60, s0
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl MyStatic, "static"
Event Key
  SetWin$ hMyStatic=Chr$("You pressed ", VKey)            ; requires MasmBasic of 1 February 2017 (http://masm32.com/board/index.php?topic=94.0)
GuiEnd


2. Val (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1202)() and MovVal (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1203)() returned -127 (error) in edx for the string 0 if there was text after the zero delimiter, e.g. sometext db "0", 0, "more text"
Title: FindProcess
Post by: jj2007 on February 08, 2017, 02:48:59 AM
New FindProcess() function:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  .if FindProcess("Explоrer.exe")
      Inkey Str$("FindProcess returned ID %i\n", [eax.PROCESSENTRY32.th32ProcessID])
  .else
      Inkey "Process not found, error: ", Err$()
  .endif
EndOfCode


Attached a demo: Extract all files to a folder and launch first Explorer.exe (don't close the MsgBox), then the FindProcessDemo.exe

The macro is still based on Tim's example (http://masm32.com/board/index.php?topic=5985.msg63494#msg63494), although I managed to bring it down to exactly 80 bytes, using three (!) times the extremely old xchg instruction :biggrin:

Don't worry, the explorer.exe won't do any harm to your machine. Really :P
You can see it in Olly if you don't trust me; or look at Jotti's scan results (https://virusscan.jotti.org/en-US/filescanjob/1efkn8p4xf)
Sorry, no manifest, no vcb, "0/18 scanners reported malware" ... although, an intelligent AV should indeed shout foul 8)

EDIT: Explorer source added
Title: Re: MasmBasic
Post by: anta40 on February 16, 2017, 01:01:21 PM
Pardon my ignorance. How to quit the RichMasm gracefullly? 
I assume you need not to use the Task Manager :redface:
Title: Re: MasmBasic
Post by: jj2007 on February 16, 2017, 07:07:29 PM
Hit Alt F4
Title: Missing feature
Post by: jj2007 on February 22, 2017, 01:41:18 AM
For a while, RichMasm had forgotten how to display tooltips :(
Fixed with version 21 Feb 2017 - please reinstall. (http://masm32.com/board/index.php?topic=94.0)

Quote from: jj2007 on February 08, 2017, 02:48:59 AMan intelligent AV should indeed shout foul 8)
Interesting that nobody asked why... check the filename Explorer.exe very, very carefully. You may find out that the o is not the usual one. The whole AV battery at Jotti's found nothing to complain, which confirms my theory that they cooperate closely with the malware scene. It's called a "business model" :P
Title: Re: MasmBasic
Post by: jj2007 on February 25, 2017, 02:26:51 PM
Since full Unicode support was introduced some days ago, RichMasm had a problem with commandline arguments: If there was e.g. an OPT_Arg1 test.gif in the text, it created files named myname.exe test.exe instead of myname.exe

Fixed with MasmBasic update of 25 February, please reinstall (http://masm32.com/board/index.php?topic=94.0)
Title: Re: MasmBasic
Post by: jj2007 on March 01, 2017, 12:31:49 PM
Update 1 March 17 (http://masm32.com/board/index.php?topic=94.0) fixes a minor issue with the handling of 64-bit code (http://masm32.com/board/index.php?topic=5314.msg59884#msg59884), and adds the PushText macro (http://masm32.com/board/index.php?topic=5799.msg63987#msg63987).
Title: Re: MasmBasic
Post by: LordAdef on March 02, 2017, 06:10:59 PM
Hi JJ,

I wrote this little prog for my Ascii game. It compresses the txt file even more than I got the last time (original= 89.999, new size= 4.323).

I´s all good but I have a question.

I´m using (for the first time) the Switch case MACRO from MasmBasic (masm32 didn´t like how I did it):

Quote
Quote    ;========== FILTER UNWANTED CHARS ====================
          xor edi, edi      
     filter:
           mov   bl, BYTE Ptr  [esi + edi]
      Switch_ bl
      Case_ '='
         mov bl, " "
      Case_ 60, 62
         mov bl, '@'                        ; chars < , > (bombers)
      Endsw_
      
   add    edi, 1               ;add counter
   cmp   edi, tLen                 ;end of file?
   jnz     filter   

All good except from one thing: My file got 23kb fatter with MasmBasic. 26kb as opposed to 3kb with masm32rt.
Am I missing something?

By the way, check this colour set up, it´s really nice to work with.
Cheers,
Alex
Title: Re: MasmBasic
Post by: jj2007 on March 02, 2017, 08:52:11 PM
Quote from: LordAdef on March 02, 2017, 06:10:59 PMAll good except from one thing: My file got 23kb fatter with MasmBasic. 26kb as opposed to 3kb with masm32rt.

It's the 20k overhead of common functions like e.g. array handling. In exchange, you get interesting stuff like the Recall (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172) and Store (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1174) pair, or, most important, the deb macro (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019) ;)


QuoteBy the way, check this colour set up, it´s really nice to work with.

Looks nice indeed.

Btw, compliments, you are making big progress. Coding RLE in assembler is not a beginner's job :t
Title: Re: MasmBasic
Post by: jj2007 on March 03, 2017, 06:58:34 PM
Update 3 March:
- RichMasm works again as it should under Windows XP (F6 used to build code, but it wouldn't run it...); there were no problems under Win7 and Win10
- ComCtl32$() takes now an optional format string:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Inkey ComCtl32$("This program uses ComCtr32.dll version %3f\ncheck your manifest if you expected a higher version")
EndOfCode


Without a manifest, you will see the old pre-XP version of the common controls dll:This program uses ComCtr32.dll version 5.82

In RichMasm,
- go to the end of the file
- click on menu AutoCode, Resources: manifest (this inserts a Rsrc section, including a manifest)
- hit F6 again to seeThis program uses ComCtr32.dll version 6.16

As mentioned in the Manifests in 64-bit land (http://masm32.com/board/index.php?topic=6047.0) thread, the same manifest works also for 64-bit assembly. Even the 32-bit example that uses 64-bit code works fine with this manifest. (http://masm32.com/board/index.php?topic=6037.msg63972#msg63972)
Title: FileProp$() array
Post by: jj2007 on March 06, 2017, 01:01:38 PM
Update 6 March brings a new feature: the FileProp$() array.

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Print "Searching ", ExpandEnv$("%ProgramFiles%"), " ..."
  GetFiles ExpandEnv$("%ProgramFiles%\ms*.exe|ms*.dll")      ; limit to all executables starting with ms
  deb 4, "** files found", eax
  For_ ct=0 To Min(999, eax-1)            ; max 1000 files
            mov ecx, Files$(ct)
            GetFileProps ecx
            .if FileProp$(?)>1            ; more than one file property found
                  .if Rinstr(ecx, "\")
                        inc eax            ; put eax after the \
                        xchg eax, ecx            ; we don't show the full path
                  .endif
                  Print ecx            ; the filename
                  PrintLine At(40) FileProp$(FileDescription)
            .endif
  Next
  PrintLine CrLf$, "Finally, all properties of the current file:"
  GetFileProps            ; no args = current file
  For_ ecx=0 To FileProp$(?)-1
      Print Str$("%_i  ", ecx), FilePropName$(ecx)
      PrintLine At(30) FileProp$(ecx)
  Next
  Inkey "ok?"
EndOfCode


Typical output:Searching C:\Program Files (x86) ...
** files found      eax             630
msvcp60.dll                             Microsoft (R) Visual C++
msvcp71.dll                             Microsoft® Visual Studio .NET
msvcr71.dll                             Microsoft® Visual Studio .NET
msvcp80.dll                             Microsoft® Visual Studio® 2005
msvcr80.dll                             Microsoft® Visual Studio® 2005
msvcp71.dll                             Microsoft® Visual Studio .NET
msvcp80.dll                             Microsoft® Visual Studio® 2005
msvcr71.dll                             Microsoft® Visual Studio .NET
msvcr80.dll                             Microsoft® Visual Studio® 2005
msvcp71.dll                             Microsoft® Visual Studio .NET
msvcr71.dll                             Microsoft® Visual Studio .NET
MSVCP60.DLL                             Microsoft (R) Visual C++
msvcrt.dll                              Microsoft (R) Visual C++
MSDEUI.DLL                              Microsoft Data Environment 1.0
MSADDNDR.DLL                            AddInDesigner Object Library
MSDE.DLL                                Microsoft Data Environment 1.0
MSDERUN.DLL                             Microsoft Data Environment Runtime 1.0
MSHTMPGD.DLL                            DHTMLPageDesigner Object Library
MSHTMPGR.DLL                            DHTMLPageDesigner Object Library
MSWCRUN.DLL                             WebClass Runtime Object Library
MSOEURO.DLL                             Microsoft Office 2003
mshwgst.dll                             Microsoft® Windows® Operating System
mshwLatin.dll                           Sistema operativo Microsoft® Windows®
MSPFLTRS.DLL                            Microsoft Office Document Imaging
...
MSSP7SW.DLL                             Natural Language Components
mssp7tr.dll                             Natural Language Components
msoe.dll                                Microsoft® Windows® Operating System
MSOERES.dll                             Sistema operativo Microsoft® Windows®

Finally, all properties of the current file:
0  Lang                      080904B0
1  Comments                  This is a comment
2  InternalName              Internal name
3  ProductName               Jochen's Assembly Tools Collection
4  CompanyName               MasmBasic
5  LegalCopyright            © 2017 Jochen@Masm32
6  ProductVersion            Release version 6 March 2017
7  FileDescription           Testing FilePropDemo
8  LegalTrademarks           ?
9  PrivateBuild              ?
10  FileVersion               1.0
11  OriginalFilename          FilePropDemo
12  SpecialBuild              ?


Demo attached. Open in RichMasm, hit F6 to build it. Remove the "ms" in GetFiles to get all executables 8)
Title: Re: MasmBasic
Post by: Spamm3r on April 15, 2017, 12:04:41 AM
So hi! I am starting to learn asm and i have just found MasmBasic and to be honest after problems with VS (still cant set up subsystem) I am happy with it. But is there an possibility to change resolution of this (http://i.imgur.com/dJTXHEH.png)?

And is there an way to customize colors of background of text? I want to make it darker. Thanks!
Title: Re: MasmBasic
Post by: jj2007 on April 15, 2017, 01:54:09 AM
Quote from: Spamm3r on April 15, 2017, 12:04:41 AMBut is there an possibility to change resolution of this

What exactly do you mean with "resolution"? Does it look better if you hold Shift when opening a file, and use "screenshot mode"?

QuoteAnd is there an way to customize colors of background of text? I want to make it darker. Thanks!

Ctr G, udc=14, <Return>
Title: Re: MasmBasic
Post by: LordAdef on April 16, 2017, 08:33:38 PM
This fellow programmer reminds me of my suggestion of some colour tabs... remember?

Any chance of you giving us this powerful colour enhancement?

http://masm32.com/board/index.php?topic=6055.msg64384#msg64384 (http://masm32.com/board/index.php?topic=6055.msg64384#msg64384)
Title: Re: MasmBasic
Post by: jj2007 on April 17, 2017, 04:29:09 AM
Quote from: LordAdef on April 16, 2017, 08:33:38 PMAny chance of you giving us this powerful colour enhancement?

Real MenTM select the text, hit Ctrl G and type col=ff8000h :P
Title: Re: MasmBasic
Post by: Spamm3r on April 17, 2017, 05:46:16 AM
Any chance to get more sharp titles (I mean, file, edit etc) Beacuse on 1920x1080 they are not sharp...
Title: Re: MasmBasic
Post by: jj2007 on April 17, 2017, 06:21:14 AM
Sharp titles: If you hold Shift when opening a file e.g. from the recent files list, and confirm "screenshot mode", do they look better? There is a problem with the Gdi+ font that I use to work around Aero...
Title: Re: MasmBasic
Post by: LordAdef on April 17, 2017, 04:40:21 PM
Quote from: jj2007 on April 17, 2017, 04:29:09 AM
Quote from: LordAdef on April 16, 2017, 08:33:38 PMAny chance of you giving us this powerful colour enhancement?

Real MenTM select the text, hit Ctrl G and type col=ff8000h :P

and how do the Real Men set the bk colour?
Title: Re: MasmBasic
Post by: jj2007 on April 17, 2017, 07:03:14 PM
Quote from: LordAdef on April 17, 2017, 04:40:21 PM
and how do the Real Men set the bk colour?

Ha :t

You are getting ambitious here :icon_mrgreen:

1. Make a copy of
\Masm32\MasmBasic\Res\RichMasm.ini and place it in
\Masm32\MasmBasic\Res\UserDef\RichMasm.ini

2. Edit the lines under udc=nn, i.e. lines 18 to 25
3. Restart the editor.

That's for the document background. In case you want different backgrounds for individual sentences:
1. Try that in Micros**t Word (and tell me if that is possible :bgrin:)
2. Paste the result in RichMasm.

As mentioned in the 124 bugs thread (http://masm32.com/board/index.php?topic=5382.msg65319#msg65319), I need to add a warning that mat=0 destroys the work. If I find the time, I may add a Ctrl G bgc=bbggrrH function, too.

Attached a beta for you, Alex 8)
Title: Re: MasmBasic
Post by: LordAdef on April 18, 2017, 03:24:31 AM
Thanks JJ, I will try that.



QuoteYou are getting ambitious here :icon_mrgreen:

Nice one!  ::)


I use the Office trick often, it works.

Do you have plans to implement that infamous colour tab as we talked about in the other thread? That would be a great for a future upgrade version.
Title: Re: MasmBasic
Post by: jj2007 on April 18, 2017, 03:39:48 AM
Quote from: LordAdef on April 18, 2017, 03:24:31 AMDo you have plans to implement that infamous colour tab

No, but I have a little project for you (http://masm32.com/board/index.php?topic=5314.msg63462#msg63462) ;)
Title: Re: MasmBasic
Post by: LordAdef on April 22, 2017, 06:40:50 PM
Hi JJ,

I just checked the beta you sent it. The UserDef worked! Thanks
But the Beta didn`t build my project.

When you say a "Beta for you", is it something related to the colour things we were talking about it? I didn´t see the difference.

ps (And I´m still using an old version of RM... I´ve got to update it but it was running so nicely I didn´t stop to do it)
Title: Re: MasmBasic
Post by: jj2007 on April 22, 2017, 10:43:59 PM
Quote from: LordAdef on April 22, 2017, 06:40:50 PMBut the Beta didn`t build my project.

What happened? Details please 8)

QuoteWhen you say a "Beta for you", is it something related to the colour things we were talking about it? I didn´t see the difference.

Hey, that was ages ago :P I can't remember what was "beta" at that moment. Anyway, current version is online (http://masm32.com/board/index.php?topic=94.0) and works like a charm.
Title: Re: MasmBasic
Post by: LordAdef on April 23, 2017, 06:30:43 PM
QuoteWhat happened? Details please

Never mind, I´ve downloaded the latest version and everything is sweet!!

I got it=> you got the code for "bgc=" in there, right? That´s niice.

I know we are doing BGR, but would it be possible in the future to invert it to RGB? A lot more convenient when using color pickers that returns you the Hex values, and they usually do it in RGB. It´s only a Copy/Paste.

I like this online one, check it out, quite convenient: https://www.webpagefx.com/web-design/color-picker/a1d490 (https://www.webpagefx.com/web-design/color-picker/a1d490)

Title: Re: MasmBasic
Post by: jj2007 on April 23, 2017, 08:41:27 PM
Hmmmm... what about bgc=? and col=? instead of an online colour picker?

Of course, this requires major changes in the RichMasm source ::)

  void Val(esi)
  ...
  .if edx==-127           ; user typed col=? or bgc=?
      void RgbCol(?)      ; let the colour picker do it
  .endif
Title: Re: MasmBasic
Post by: LordAdef on April 23, 2017, 10:09:14 PM
that would be fantastic!
Title: Re: MasmBasic
Post by: jj2007 on April 24, 2017, 08:28:07 AM
Update 24 April (http://masm32.com/board/index.php?topic=94.0) features a new option for the RgbCol macro:
QuoteRgbCol, CgaCol, SysCol
      mov eax, RgbCol(ebx, 0, 0)            ; any mix of reg32, vars and immediates is allowed
      mov bl, 127            ; only bl will be used
      invoke SetTextColor, hDC, RgbCol(ebx, 0, 0)      ; Red Green Blue for Gdi32 functions
      invoke SetTextColor, hDC, SysCol(ebx)            ; use the system palette
      invoke SetTextColor, hDC, RgbCol(?)            ; use the colour picker
      mov hPG, rv(GdipCreatePen1, RgbCol(alpha, red, green, blue), FP4(3.0), UnitWorld, addr pPen)
Rem      - Gdi functions want RGB values, i.e. three parameters
      - in contrast, GdiPlus expects ARGB, i.e. four parameters; the first one, alpha, defines
        transparency ranging from 0=fully transparent to 255=opaque
      - CgaCol(index) may be used with console colours; see ConsoleColor for identifiers
      - SysCol(index) returns a GetSystemPaletteEntries colour for use in Gui applications

See Reply #393 above for an application in RichMasm - greetings to Alex :biggrin:

(the void avoids a mov eax, eax)
Title: Re: MasmBasic
Post by: LordAdef on April 24, 2017, 10:05:12 PM
===== THIS IS SO NICE JJ!!!! Thanks a lot ======


ps: edit to add: I mean this is reeeeally nice! Now I see RichMasm "flying clolours"  :greenclp: :eusa_clap: :eusa_dance:
Title: Re: MasmBasic
Post by: jj2007 on April 24, 2017, 10:18:43 PM
Don't overdo it, Alex. Rich text is certainly better than poor text, but with a lot of experience, I limit the use of colour nowadays to MB keywords, push/pop pairs (easier to see if the stack is balanced), and a few very specific tricky code consequences. Btw you can see this "default use" when selecting a block of text and hitting F4 aka "comment" twice.

Another example - red for @Backwards, blue for @Forward jumps (I prefer .Repeat ... .Exit .if ... .Until, though):

            xchg eax, ebx
  @@:  dec edx
            jl @F
            stosb                  ; insert new empty elements
            jmp @B
  @@:  xchg eax, edi
            pop ebx

This helps to grasp how the loop works. It is much more important to have this visual aid when the loop spans over 20 or 50 lines, of course.

Christmas tree looks nice at first sight, but it doesn't help to focus attention on the really important parts. Which applies, btw, also to the VS or Scintilla style automatic highlighting.
Title: Re: MasmBasic
Post by: LordAdef on April 24, 2017, 10:28:42 PM
QuoteDon't overdo it, Alex. Rich text is certainly better than poor text, but with a lot of experience, I limit the use of colour nowadays to MB keywords, push/pop pairs (easier to see if the stack is balanced), and a few very specific tricky code consequences.

Oh, don´t worry. In fact I never did it. But it´s invaluable for temporary modifications. I usually colour when trying things out. Later, when things look right, I bring them back to default.

I´m posting my game there at my thread, you will see it´s being used carefully.
Title: Re: MasmBasic
Post by: jj2007 on April 24, 2017, 11:09:20 PM
Quote from: LordAdef on April 24, 2017, 10:28:42 PMit´s invaluable for temporary modifications

Exactly :t

What I frequently use:

if 1
  ... 50 lines of active code ...
else
  ... 50 lines of alternative code ...
endif
Title: Re: MasmBasic
Post by: LordAdef on April 25, 2017, 09:03:16 PM
JJ,

only FYI, a behaviour I don't recall from the previous 2 versions but now in place:

If you select some code and build (while the code is still selected) it generates an error. I found this by chance when selecting some code, F4 and build. The commented bit must be unselected now in order for the build to be successful.

Nothing out of this world,  but I thought I should let you know.


Title: Re: MasmBasic
Post by: jj2007 on April 25, 2017, 09:22:05 PM
Quote from: LordAdef on April 25, 2017, 09:03:16 PMIf you select some code and build (while the code is still selected) it generates an error. I found this by chance when selecting some code, F4 and build. The commented bit must be unselected now in order for the build to be successful.

It's not a bug, it's a feature :lol:

Insert this somewhere in one of your sources:if 0
include \masm32\MasmBasic\MasmBasic.inc
  Init
  Inkey "Current time is ", Launch$("cmd /c time /t")
EndOfCode
endif


The if 0 ... endif comments it out, so it won't disturb building your source. But if you select the lines inside and hit F6, then only the lines include ... EndOfCode will be used for the assembly. Useful for testing little snippets, but I will add a warning to the output window explaining why there was an error...
Title: Re: MasmBasic
Post by: LordAdef on April 27, 2017, 04:47:57 AM
Updated as instructed! :dazzled:
Title: Unicode is easy
Post by: jj2007 on May 11, 2017, 04:37:47 PM
MasmBasic update 11 May features several improvements of Unicode handling (http://masm32.com/board/index.php?topic=94.0). Inter alia,
- you can write strings in any language directly in the editor;
- file names can be in any language, too;
- find & replace is now Unicode aware.

The snippet below is a full-fledged Windows application. Please test in particular the FileOpen() feature.

GuiParas equ "严重的软件应该使用Unicode!!!!", h400      ; in RichMasm, hit F6 to build this application
GuiMenu equ <@File, Open, Save, Save &as, E&xit>     ; requires MasmBasic (http://masm32.com/board/index.php?topic=94.0)
include \masm32\MasmBasic\Res\MbGui.asm
  MakeFont hFont, Height:24
  GuiControl MyEdit, "RichEdit", font hFont, wCat$("The commandline passed was"+CrLf$+wCL$())

Event Menu
  Switch_ MenuID
  Case_ 0            ; first menu item has index 0
      .if wFileOpen$("богатый источник=*.asc|Poor sauce=*.asm|资源=*.rc", "богатый источник")
            SetWin$ hMyEdit=wFileRead$(wFileOpen$())
      .endif
  Case_ 1, 2:      MsgBox 0, "Saving not implemented, sorry", "Hi", MB_OK
  Case_ 3:         invoke SendMessage, hWnd, WM_CLOSE, 0, 0            ; yes, you can use pure assembler ;-)
  Endsw_
GuiEnd


Demo attached. To test it, extract to \Masm32\MasmBasic, then drag the file with the exotic name over \Masm32\MasmBasic\UnicodeIsEasy.exe
Title: Re: MasmBasic
Post by: LordAdef on May 11, 2017, 09:03:47 PM
Quote- find & replace is now Unicode aware.

Since you mentioned find & replace, let me report this one for FYI sake:

"find" now finds key words in INCLUDE files (with Capital letters) and shows them in the find window. But "Replace" can't replace them in the include files. So the replace doesn't run if everything is selected to be replaced.

I can understand why, I'm just letting you know for development sake.
Cheers Alex
Title: Re: MasmBasic
Post by: jj2007 on May 12, 2017, 09:34:58 PM
Quote from: LordAdef on May 11, 2017, 09:03:47 PM"find" now finds key words in INCLUDE files (with Capital letters) and shows them in the find window. But "Replace" can't replace them in the include files.

Thanks, Alex. Version 12 May has a warning now, please let me know if that is the right choice. It would be technically possible to replace strings in the include files, but updating include files is not something I would support - too risky.

Among the other changes:

- By holding Ctrl and moving the mousewheel, the RichEdit control can zoom the display. At my age and my eyesight, I need 110%, but there may be people who have brilliant eyes and want to see more code. Pressing Alt Z saves the current zoom level; this is a global setting, i.e. RichMasm remembers this when opening any document (it also affects the font in the Find listbox, but only after restarting RichMasm).

- introduced a new Event variable VKey2:

Event Key
  Switch_ VKey2
  Case_ VK_LEFT:      wAddWin$ hMyEdit=" текст", 44       ; insert Unicode text at position 44
  Case_ VK_RIGHT:      AddWin$ hMyEdit=" missed", 50, 57  ; insert Ansi text at position 50, overwrite 7 bytes
  Case_ VK_UP     
            Let My$=FileRead$("UnicodeIsEasy.asc")
            wAddWin$ hMyEdit=My$
  Case_ VK_DOWN:      <wAddWin$ hMyEdit=wRec$(cfm$("\nВведите\nтекст\nздесь\n"))>  ; append & use cfm$ for \n escapes
  Endsw_


Until now, VKey was available to test for e.g. VK_SPACE or whatever; and the rule was that a positive VKey comes from the main application, a negative one (.if VKey==-VK_SPACE) from the riched control. Now you can catch a keypress independently of whether the control has the focus or not. Full example attached.

The snippet above also demonstrates new optional arguments for AddWin$:
AddWin$ hRichEdit="Text" [, startpos][, endpos]

The online doc for AddWin$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1093) says it's normal edit controls only, but that is wrong. I should update that page...
Title: Re: MasmBasic
Post by: LordAdef on May 13, 2017, 02:39:46 AM
QuoteThanks, Alex. Version 12 May has a warning now, please let me know if that is the right choice. It would be technically possible to replace strings in the include files, but updating include files is not something I would support - too risky.

ok JJ.
One other issue for you, still on the Find:
  .Once I make a change in the include file and save it,
  . come back to Main source code and
  . search for something...
  . the result in the Find is not updated for the include files, and still shows the old expression
Title: Re: MasmBasic
Post by: jj2007 on May 29, 2017, 11:35:41 AM
Version 29 May is online (http://masm32.com/board/index.php?topic=94.0). As usual, you can just reinstall the package, no need to delete old files or backup your own sources.

Pens and brushes can now be created to arrays. This creates 100 random circles in random colours (attached):

include \masm32\MasmBasic\Res\MbGui.asm
  Dim Pens() As DWORD
  Dim Brushes() As DWORD
  For_ ct=0 To 99
      MakePen Pens(ct), Rand(-1), width 10      ; use random colours
      MakeBrush Brushes(ct), Rand(-1)      ; also for the fill
  Next
  MakePath      123, Circle(200)      ; ID, type circle: radius 20%, i.e. n/1000 of window rect
Event Paint
  For_ ct=0 To 99  ; ID       pen/brush          x        y     scaleX      scaleY
      GuiDraw 123, <Pens(ct)/Brushes(ct)>, <Rand(850).>, <Rand(850).>, eax, <Rand(900)>      ; ScaleX is eax, same as scaleY
  Next
GuiEnd



Quote from: LordAdef on May 13, 2017, 02:39:46 AMthe result in the Find is not updated for the include files, and still shows the old expression

Sorry, Alex, no time to fix that right now. You can reload, though: Shift F5

Good news: RichMasm works on Windows XP. Again. It had stopped working due to a hilarious Windows bug, see
Code pages and batch files - fun with XP (http://masm32.com/board/index.php?topic=6284.0).

As a side effect, I had to write a new macro:

include \masm32\MasmBasic\MasmBasic.inc
      Init
      Print Str$("This is Windows version %i", MbWinVersion()), Str$(".%i", ecx)
      void MbWinVersion()
      Print Str$(", build %i", dx)
EndOfCode
Rem      returns major version in eax, minor version in ecx, and build in dx


Output: This is Windows version 6.1, build 7601

Note this is the real Windows version, not what you declare via "compatibility settings".

Btw when building a project in RichMasm, the environment variable is accessible via  ifidn @Environ(oWin), <5>
MsgBox 0, "Built on XP", "Hi", MB_OK
  endif
Title: Re: MasmBasic
Post by: jj2007 on May 30, 2017, 02:24:47 AM
Drag an avi file over the exe, for example Mikl's demo file (https://yadi.sk/i/J4bVuX4H3JdByJ) - see Uncle Remus tales:#37a Animation (http://masm32.com/board/index.php?topic=6275.msg67228;topicseen#msg67228).

GuiParas equ "SysAnimate32 demo", w452, h374, bRgbCol(255, 255, 160)
include \masm32\MasmBasic\Res\MbGui.asm            ; part of MasmBasic (http://masm32.com/board/index.php?topic=94.0)
GuiControl Avi, "SysAnimate32"
invoke SendMessage, hAvi, ACM_OPEN, 0, CL$()
invoke SendMessage, hAvi, ACM_PLAY, -1, 0FFFF0000h
GuiEnd


I was surprised how easy it is, but its usage is rather limited: no sound :(
Title: Re: MasmBasic
Post by: jj2007 on May 31, 2017, 09:21:38 AM
Quote from: LordAdef on May 13, 2017, 02:39:46 AM. the result in the Find is not updated for the include files, and still shows the old expression

Implemented in version 31 May - please reinstall the whole package (http://masm32.com/board/index.php?topic=94.0), there was also a bug in the Ansi version of FileOpen$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1031).

Let me know if it's OK like that, Alex. In contrast to the current version, the "external" matches now respect also the "case" and "fw" checkboxes, i.e. case-sensitive and full word mode are working correctly for the include files now.
Title: Re: MasmBasic
Post by: LordAdef on May 31, 2017, 12:46:19 PM
Quote from: jj2007 on May 31, 2017, 09:21:38 AM
Quote from: LordAdef on May 13, 2017, 02:39:46 AM. the result in the Find is not updated for the include files, and still shows the old expression

Implemented in version 31 May - please reinstall the whole package (http://masm32.com/board/index.php?topic=94.0), there was also a bug in the Ansi version of FileOpen$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1031).

Let me know if it's OK like that, Alex. In contrast to the current version, the "external" matches now respect also the "case" and "fw" checkboxes, i.e. case-sensitive and full word mode are working correctly for the include files now.

Great update Johen. I'm downloading it tonight when I get back home.
Title: MasmBasic update
Post by: jj2007 on June 13, 2017, 08:33:56 AM
Version 13 June (http://masm32.com/board/index.php?topic=94.0) fixes an exotic bug in RichMasm - it choked if many uppercase INCLUDE files were found.

New feature: Console input with character limit as discussed here (http://masm32.com/board/index.php?topic=6315.0):

  .Repeat
      Print At(5, Locate(y)) " "
      Let esi=Input$("Go ahead, edit that string: ", "123456789012345678", max20)
      PrintLine "                       you typed [", esi, "]"
  .Until Len(esi)<5


Attached is a beta, exe only, that plays media files. Drag an audio or video file over the exe, if the codec is installed it will play. Cursor left, space, cursor right are relevant keys. Hold Ctrl for fast forward, Shift for slow back+forth.
Title: Re: MasmBasic
Post by: jj2007 on July 11, 2017, 06:28:10 PM
Minor update 11 July (download (http://masm32.com/board/index.php?topic=94.0)):

jd@150 equ KernelBase                               ; a little hack for a missing WinAPI,
j@VirtualProtectFromApp equ jbNextApi/150:s1111     ; may be refined in the near future
...
  mov r12, rv(MessageBoxA, @address)    ; address of MessageBoxA in the DLL


This is a rather exotic function needed for 64-bit code when you need the true address of a function in its DLL. Full example here (http://masm32.com/board/index.php?topic=6378.msg68416#msg68416).

Plus, RichMasm produces now better formatted output for this forum. (http://masm32.com/board/index.php?topic=5820.msg68375#msg68375)
Title: Re: MasmBasic
Post by: jiucenglou on July 15, 2017, 11:27:36 PM
Wow ! Such a wonderful project !
Would you recommend which debugger to use if MasmBasic dialect is used together with ML.exe ? (I mean, VS seems to provide a really decent and productive debugger for C/C++ or even MASM.)
Title: Re: MasmBasic
Post by: jj2007 on July 15, 2017, 11:37:44 PM
Quote from: jiucenglou on July 15, 2017, 11:27:36 PM
Wow ! Such a wonderful project !
Would you recommend which debugger to use if MasmBasic dialect is used together with ML.exe ? (I mean, VS seems to provide a really decent and productive debugger for C/C++ or even MASM.)

Thanks ;-)
Re debugger, many of us here use Olly (http://www.ollydbg.de/version2.html).
Title: Re: MasmBasic
Post by: jiucenglou on July 16, 2017, 12:37:04 AM
Thank you for your recommendation very much ! I will try OllyDbg 2 :t
Title: Re: MasmBasic
Post by: Rob260z on August 01, 2017, 01:05:14 PM
Yes... What a wonderful project. Extremely grateful for all the hard work and effort that has gone into developing this. Starting using the Rand function last week, but then I discovered Deb!, and it's been love at first site :)

Working with a lot of loops that involve the creation and use of indexed addressing. Can't recommend this function enough, especially the ability to output to a text file.

Keep up the good work :)
Title: Re: MasmBasic
Post by: jj2007 on August 01, 2017, 05:14:46 PM
Thanks, Rob - that is the kind of feedback I've been looking for the last 20 years :greensml:

Re deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019): I rarely use deb 5 (to file) nowadays, but it can be useful. For monitoring a loop, try deb 7 or deb 30 - any number above 5 shows n times the result, then the loop continues. Also, deb 4, "The error:", eax, $Err$() is a very useful one in WinAPI programming ;-)
Title: Re: MasmBasic
Post by: Rob260z on August 01, 2017, 07:06:52 PM
Cheers for the advice jj :)

deb 7 or 30 , I'll have to have a look. Excuse my ignorance , but these will require a Win32 console/window ? . Just had a quick read through the help file , but didn't see any info about these.

I'm using SDL2 , simply as a means of spitting out a custom texture , so I'm simply going into an Opengl/DirectX full screen mode. That's why I'm currently using the text file approach. Using the same approach to spit out any performance/benchmark info.


Cheers,
Rob
Title: Re: MasmBasic
Post by: jj2007 on August 01, 2017, 07:12:46 PM
Quote from: Rob260z on August 01, 2017, 07:06:52 PMso I'm simply going into a full screen Opengl mode.

So that doesn't allow a separate console window, right? Then deb 5 is the only solution indeed. Or deb 0...3, you can cancel the messageboxes separately.

; OPT_Susy Console ; forces console mode
Title: Re: MasmBasic
Post by: Rob260z on August 01, 2017, 09:29:12 PM
Well...I can actually make it run in a windowed mode. I'm going to explore this a little further. Has real potential.

Real-time debugging is going to be really beneficial, once I move past this initial setup phase.

Cheers for the info.
Title: Re: MasmBasic
Post by: jj2007 on August 01, 2017, 11:17:54 PM
Quote from: Rob260z on August 01, 2017, 09:29:12 PMWell...I can actually make it run in a windowed mode. I'm going to explore this a little further. Has real potential.

Another trick:
  winX=150
  winW=900
  ifidni @Environ(oSusy), <console> ; OxPT_Susy Console ; RichMasm autodetect will pick Windows, delete the x to force console
winX=450  ; leave more space for console output
winW=600
deb 4, "Hey, we are using a console in parallel to a window", $wc.lpszClassName
  endif
  invoke CreateWindowEx, WS_EX_ACCEPTFILES, wc.lpszClassName, chr$("Hello World"), ; set window title here
     WS_OVERLAPPEDWINDOW or WS_VISIBLE,
     winX, 150, winW, 400, ; window position: x, y, width, height
     NULL, NULL, wc.hInstance, NULL
Title: Re: MasmBasic
Post by: jj2007 on August 26, 2017, 10:38:00 AM
Please download and run the 26 August 2017 version of the package (http://masm32.com/board/index.php?topic=94.0). As always, you can just follow the instructions, the new installation does not change any of your sources or settings, does not write anything to the registry, and does not interfere with your Masm32 installation (I do reinstallations frequently myself when testing...).

Note that you can use an xmm reg as destination in QuadMath mode, but it has to be prefixed as MovVal (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1203) q:xmm0, "123", otherwise, an ordinary 64-bit integer will be loaded:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
include \masm32\MasmBasic\Res\QuadMath.inc
  Init quad                                     ; requires C:\TDM-GCC-32\bin\libquadmath-0.dll
  mov esi, Chr$("1234567890123456789.0123456789012345678901234567890")
  MovVal xmm0, esi
  PrintLine "64-bit int: ", Tb$, Str$(xmm0)
  MovVal f:xmm0, esi
  PrintLine "double/Real8: ", Tb$, Str$(f:xmm0)
  MovVal q:xmm0, esi
  PrintLine "Quad float e:", Tb$, Quad$(xmm0)
  MovVal q:xmm0, esi
  PrintLine "Quad float g:", Tb$, Quad$(xmm0, "%*.33Qg")        ; formats (https://gcc.gnu.org/onlinedocs/gcc-6.3.0/libquadmath/quadmath_005fsnprintf.htmlquadmath_005fsnprintf)
EndOfCode


Output:
64-bit int:     1234567890123456789
double/Real8:   1.23456789012346e+18
Quad float e:   1.23456789012345678901234567890123e+18
Quad float g:   1234567890123456789.01234567890123


The other aspect concerns UAsm (http://masm32.com/board/index.php?topic=6422.0): By default, RichMasm will from now on use the faster UAsm64 for building 32-bit as well as "dual" 64/32-bit (http://masm32.com/board/index.php?topic=5314.msg59884#msg59884) sources. If UAsm64 is not present in \Masm32\bin, RichMasm will ask you if you want to install it, and download and extract a recent version.
Title: For_ each ecx in Files$(): PrintLine ecx
Post by: jj2007 on September 06, 2017, 12:44:29 PM
include \masm32\MasmBasic\MasmBasic.inc         ; download version 6 September (http://masm32.com/board/index.php?topic=94.0)
  Init
  GetFiles \Masm32\examples\unicode_generic\*.asm|*.inc|*.rc  ; use the "or" character to separate masks
  For_ each ecx in Files$() : <PrintLine Str$("file %_i\t", ForNextCounter), ecx>   ; one line is enough ;-)
EndOfCode


Output:file # 0        \Masm32\examples\unicode_generic\console\hello\hello.asm
file # 1        \Masm32\examples\unicode_generic\console\textio\textio.asm
file # 2        \Masm32\examples\unicode_generic\diskfile\diskfile.asm
file # 3        \Masm32\examples\unicode_generic\diskfile\WININC.INC
file # 4        \Masm32\examples\unicode_generic\multi_lingual\multi_lingual.asm
file # 5        \Masm32\examples\unicode_generic\multi_lingual\multi_lingual.inc
file # 6        \Masm32\examples\unicode_generic\multi_lingual\ansi.rc
file # 7        \Masm32\examples\unicode_generic\multi_lingual\rsrc - Copia.rc
file # 8        \Masm32\examples\unicode_generic\multi_lingual\rsrc.rc
file # 9        \Masm32\examples\unicode_generic\string_examples\append$\append$.asm
file #10        \Masm32\examples\unicode_generic\string_examples\cat$\cat$.asm
file #11        \Masm32\examples\unicode_generic\string_examples\find$\find$.asm
file #12        \Masm32\examples\unicode_generic\string_examples\switch$\switch$.asm
file #13        \Masm32\examples\unicode_generic\template\misc.asm
file #14        \Masm32\examples\unicode_generic\template\template.asm
file #15        \Masm32\examples\unicode_generic\template\template.inc
file #16        \Masm32\examples\unicode_generic\template\rsrc.rc
Title: Re: MasmBasic
Post by: jj2007 on September 12, 2017, 08:23:37 AM
MasmBasic update 12 September: (http://masm32.com/board/index.php?topic=94.0)
- ifdeb allows single lines that create code only in debug mode:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  usedeb=1
  For_ ecx=1 To 20
        ifdeb push ecx : Print "[": .if 0
       Print Str$("%_i ", ecx)
        ifdeb .endif : PrintLine "]" : pop ecx
  Next
EndOfCode

- RichMasm has got a more advanced "Obscure string" feature (more (http://masm32.com/board/index.php?topic=94.msg30979#msg30979))
- an error will be thrown if the handle for ToolTips is passed in esi

- finally, dynamic string arrays got a bit speedier, they are now practically as fast as fixed Dim some$(100) arrays:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  PrintCpu 0
  Dim MyArray$()                ; create a dynamic array
  NanoTimer()                   ; start high resolution timer
  xor ecx, ecx
  .Repeat
        Let MyArray$(ecx) = Str$("This is string %i", ecx)
        inc ecx
  .Until ecx>=1000000
  Print Str$("%i ms", NanoTimer(ms)), Str$(", %i Million strings allocated\n", MyArray$(?)/1000000)

  Dim FixedArray$(1000000)      ; create a fixed size array
  NanoTimer()
  For_ each ecx in FixedArray$(): <Let FixedArray$(ForNextCounter) = Str$("This is string %i", ForNextCounter)>
  Inkey Str$("%i ms", NanoTimer(ms)), Str$(", %i Million strings allocated\n", FixedArray$(?)/1000000)
EndOfCode


Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
353 ms, 1 Million strings allocated
349 ms, 1 Million strings allocated
Title: HexDump$
Post by: jj2007 on September 18, 2017, 11:18:07 PM
Install the MasmBasic update 18 September 2017 (http://masm32.com/board/index.php?topic=94.0) to get this new feature inspired by the How to read Windows MFT thread (http://masm32.com/board/index.php?topic=6546.msg70196#msg70196):

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Inkey "Dump of GetModuleHandle(0):", CrLf$, HexDump$(rv(GetModuleHandle, 0), 90h)
EndOfCode


Options are documented in MbGuide.rtf, as usual.

The other major change is that RichMasm got new menus (more (http://masm32.com/board/index.php?topic=6055.msg70165#msg70165)), thanks to LiaoMi :icon14:

Tested on WinXP, Win7-64 (also with Aero, see screenshot below) and Win10, looks OK so far, but let me know if it can be improved :icon_mrgreen:
Title: Re: MasmBasic
Post by: jj2007 on October 27, 2017, 01:13:11 AM
Changes in version 26 October (http://masm32.com/board/index.php?topic=94.0):
- online help is updated, e.g. for deb & friends (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019) (remember that in RichMasm, hovering over a keyword allows to access help with a right-click)
- see Graphics demo (http://masm32.com/board/index.php?topic=6631.msg71135#msg71135); handling of maps is strongly improved
- HexDump$() got a "dd" option:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi=FileRead$("\Masm32\examples\exampl04\car\car.jpg")    ; Masm32 SDK
  PrintLine HexDump$(esi, 80)   ; show 80 bytes of jpg header
  Inkey HexDump$(esi, 80, dd)   ; same but for use with code
EndOfCode


Output:006337D0  FF D8 FF E0 00 10 4A 46 49 46 00 01 00 01 00 64 ÿØÿà..JFIF.....d
006337E0  00 64 00 00 FF FE 00 1F 4C 45 41 44 20 54 65 63 .d..ÿþ..LEAD Tec
006337F0  68 6E 6F 6C 6F 67 69 65 73 20 49 6E 63 2E 20 56 hnologies Inc. V
00633800  31 2E 30 31 00 FF DB 00 84 00 08 05 06 07 06 05 1.01.ÿÛ.,,.......
00633810  08 07 06 07 09 08 08 09 0C 14 0D 0C 0B 0B 0C 19 ................

db  0FFh, 0D8h, 0FFh, 0E0h, 000h, 010h, 04Ah, 046h, 049h, 046h, 000h, 001h, 000h, 001h, 000h, 064h
db  000h, 064h, 000h, 000h, 0FFh, 0FEh, 000h, 01Fh, 04Ch, 045h, 041h, 044h, 020h, 054h, 065h, 063h
db  068h, 06Eh, 06Fh, 06Ch, 06Fh, 067h, 069h, 065h, 073h, 020h, 049h, 06Eh, 063h, 02Eh, 020h, 056h
db  031h, 02Eh, 030h, 031h, 000h, 0FFh, 0DBh, 000h, 084h, 000h, 008h, 005h, 006h, 007h, 006h, 005h
db  008h, 007h, 006h, 007h, 009h, 008h, 008h, 009h, 00Ch, 014h, 00Dh, 00Ch, 00Bh, 00Bh, 00Ch, 019h


- the new MasmBasic version is again compatible with UAsm
- a bug in RichMasm was fixed (if a very big document was loaded, and user opened a small one in the same instance, it crashed)
Title: Bugfix
Post by: jj2007 on October 30, 2017, 01:15:56 AM
a) Version 29 October (http://masm32.com/board/index.php?topic=94.0) has now the "unique" feature for generation random numbers (->Unique random numbers (http://masm32.com/board/index.php?topic=6645.0)):
Rand(-99, 100, SomeIntegerArray(ecx), unique) ; min, max, destination, unique flag

Full example:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  tests=100
  Dim SomeInteger() As DWORD
  PrintLine Str$("Possible range: %i ... ", -tests/2), Str$(tests/2)
  Let edi="unique numbers: "
  Rand()                                        ; set a seed value
  For_ ecx=0 To tests-1
       Rand(-tests/2, tests/2+1, SomeInteger(ecx), unique)     ; min, max, destination, flag
       Let esi=Str$(" %i ", SomeInteger(ecx))
        .if Instr_(edi, esi)
                inc  ebx                ; oops, we got that one already
        .else
                Let edi=edi+esi         ; remember the last number
        .endif
  Next
  if tests le 100
        PrintLine edi                   ; show the unique numbers
  endif
  Inkey Str$("-- %i errors, hit any key --", ebx)
EndOfCode


Output:Possible range: -50 ... 50
unique numbers:  -13  31  43  11  16  1  -14  -36  -6  21  34  -45  17  -2  -35  39  23  40  7  -1  -5  32  -25  -30  -28  -19  15  -26  0
-29  41  -10  27  -15  22  -33  44  35  -9  29  -12  -16  -24  13  -3  -38  26  -20  -21  20  4  18  -46  36  -23  47  37  49  -34  19  14
10  -37  9  -40  -49  -4  -32  -48  -27  -11  33  2  28  -17  -31  -39  -8  8  -41  -22  24  -50  38  25  -42  6  12  42  -47  48  -44  46
45  3  -7  -18  -43  50  30
-- 0 errors, hit any key --


If you find a duplicate, I owe you a beer, but you must come here to get it :bgrin:

Note that for high numbers of unique random numbers, e.g. tests=30000, it may take a few seconds.


b) another little feature: SetWin$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1092) can now set the text of child controls. Example:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Launch "Notepad.exe SetChildWin.rc", SW_RESTORE, 100  ; give Notepad a few milliseconds to set the caption properly
  .if WinByTitle("SetChildWin.rc - ")
        xchg eax, ecx                   ; set the handle to ecx (MasmBasic won't touch ecx)
        SetWin$ ecx, 15=Replace$(Cat$(Win$(ecx, 15)), "Win$", "Win$#####", 0)   ; replace with an easy-to-spot string
  .endif
EndOfCode


Full project attached, tested with Win7-64 and WinXP. When you hit F6 in RichMasm, the fake rc file for Notepad gets generated from the text between the red Rsrc tags.
Title: MasmBasic hits the 400 commands mark
Post by: jj2007 on November 08, 2017, 03:00:29 PM
Version 8 November 2017 is ready to be installed. (http://masm32.com/board/index.php?topic=94.0) Changes:

- updated help file, with now 400+ macros documented (also online - use Ctrl F to find commands (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm); but remember the best help option is to use RichMasm, hover over a keyword like Open, then right-click on the word and copy the line that fits your case)

- fDate$() and fTime$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1267) can now take a third parameter to force any language:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Print "Right now, ", fDate$(0, "dddd dd MMMM yyyy "), fTime$(0, "HH:mm:ss"), Str$(", we are in ISO week %i\n", IsoWeek())
  Print fDate$(0, "dddd dd MMMM yyyy ", russian), fTime$(0, "HH:mm"), Str$(", мы находимся в ИСО неделе %i", IsoWeek())
  wMsgBox 0, wCat$(wfDate$(0, "dddd dd MMMM yyyy ", hindi)+wfTime$(0)), "This is Unicode:", MB_OK
EndOfCode

Output:
Right now, Wednesday 08 November 2017 04:55:26, we are in ISO week 45
среда 08 ноября 2017 04:55, мы находимся в ИСО неделе 45


- SetInt can now move the content of ST(0) to xmm0:
  fldpi
  Print Str$("PI=\t%Jf\n", ST(0))
  fmul FP4(100.0)
  SetInt ecx
  Print Str$("100*PI=\t %i\n", ecx)
  fldpi
  fmul FP8(10.0e16)
  SetInt xmm0
  Print Str$("100*PI=\t %i\n", xmm0)


Output:
PI=     3.141592653589793238
100*PI=  314
10e16*PI=314159265358979324


- finally, the ternary operator If? can now also take the Zero? and Carry? flags as input (testbed attached):

  xor ecx, ecx
  Print Str$("zero flag set: %i\txor ecx, ecx\n", If?(zero?, 111, 222))         ; prints first number, 111
  or ecx, -1
  Print Str$("zero flag set: %i\tor ecx, -1\n", If?(zero?, 111, 222))   ; prints second number, 222
  stc
  Print Str$("carry set: %i\tstc\n", If?(Carry?, 111, 222))     ; carry is set, prints 111
  clc
  Print Str$("carry set: %i\tclc\n", If?(Carry?, 111, 222))     ; carry clear, prints 222
Title: Exe to .DATA
Post by: jj2007 on November 25, 2017, 01:46:45 AM
HexDump$() got new options:

Let My$=HexDump$("SomeFile.exe", file, dq)  ; translate the file to a string ready for pasting

Attached source & exe of an application that translates any file into an include file. Limit is around 640kB for the *.inc file. The format is as follows (as an example, I translated \Masm32\MasmBasic\RichMasm.exe):.DATA
hdBytes=68608
RichMasmStart LABEL BYTE
.radix 16
dq 06172627261665A4D, 00000455068637375, 05A1809200001014C, 00000000000000000, 03202010B010F00E0, 000197A0000018400, 00000FE6800000000, 00000000C00001000
...
dq 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000
.radix 10
.code
; FileWrite "RichMasm.tmp", offset RichMasmStart, hdBytes


include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  .if Exist(CL$())
        Let edi=HexDump$(Exist$, file, dq)
        Let esi=Extract$(CL$(), "\", ".", xsRinstrL)+".inc"
        Let ecx=Str$("%i bytes translated to ", LastFileSize)+esi+CrLf$+CrLf$+Left$(edi, 200)+\
          CrLf$+"..."+CrLf$+Right$(edi, 200)+CrLf$+CrLf$+"Create inc (NO=copy to clipboard)?"
        If_ Exist(esi) Then Let ecx="Attention, "+esi+" exists!!!!"+CrLf$+ecx
        MsgBox 0, ecx, "File to *.inc:", MB_YESNOCANCEL or MB_ICONQUESTION
        .if eax==IDYES
                FileWrite esi, edi
        .elseif eax==IDNO
                SetClip$ edi
        .endif
  .else
        If_ Rinstr(CL$(0), "\") Then inc eax
        MsgBox 0, Cat$("Drag a file over "+eax), "File to *.inc:", MB_OK
  .endif
EndOfCode

OPT_Arg1        \Masm32\MasmBasic\RichMasm.exe  ; just for fun, translate the editor to .DATA ;-)
Title: Re: MasmBasic
Post by: jj2007 on December 19, 2017, 10:56:51 AM
MasmBasic updated, please reinstall version 19 December 2017. (http://masm32.com/board/index.php?topic=94.0) Minor changes, inter alia:

- Cpu$():
include \masm32\MasmBasic\MasmBasic.inc
  Init
  MsgBox 0, Cat$("My CPU: "+Cpu$()), "Hi:", MB_OK
EndOfCode


NanoTimer() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1171) has been improved, see the new timings thread (http://masm32.com/board/index.php?topic=6718.msg71908#msg71908).

- Delay until (-> full example (http://masm32.com/board/index.php?topic=6483.msg72347#msg72347)):

        Delay 1000                      ; standard version: wait a second
       PrintLine fTime$(0, "HH:mm:ss.fff"), Tb$, "started"
        Delay until fTime$(s:1, "HH:mm:ss.123")         ; use time$(current plus one second)
       PrintLine fTime$(0, "HH:mm:ss.fff "), Tb$, NanoTimer$(), " restarted"
Rem    - uses Sleep but preserves ecx
        - the until variant uses a time string to wait until a precise moment; use e.g. fTime$(1, "HH:mm") to
          suspend running until the current minute is finished; fTime$(s:10, ...) would mean 10 seconds


- the "controls" snippet in the templates has been improved (-> File/New Masm source/console/window/controls)

Let me know if there are any problems (there might be some with Windows XP - I test thoroughly for Win7 and Win10 but for XP I only have a VM).
Title: ClearFileCache and new GuiControls
Post by: jj2007 on December 26, 2017, 03:36:15 AM
MasmBasic 25 December 2017 (http://masm32.com/board/index.php?topic=94.0) features ClearFileCache for timings and benchmarks involving disk I/O (http://masm32.com/board/index.php?topic=6483.msg72680#msg72680), uMirror$() (http://masm32.com/board/index.php?topic=6483.msg72658#msg72658), plus a number of new controls. Here are 75 lines of code showing 18 controls in action (screenshot below, source & exe attached; drag a text file over the exe):

GuiParas equ "Controls", x660, y50, w500, h320, m4, b RgbCol(160, 255, 255)    ; position, margins, background
GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste    ; define a menu (functions not implemented)
include \masm32\MasmBasic\Res\MbGui.asm
  SetGlobals ticks=rv(GetTickCount), f$="some text to find", r$="Доброе утро!!!!"     ; set global variables; note that they use ebx under the hood
  SetGlobals                                                    ; initialise them
  GuiControl ListBox, "listbox", x700, w300, h1000-80, WS_EX_CLIENTEDGE, +WS_BORDER or LBS_NOINTEGRALHEIGHT     ; start at 70% width, use 30% width, full height; + means defstyle or ...
  GuiControl MyDt, "syslink", "Date+Time (MSDN):", x700, w300, y1000-72, h0+18
  GuiControl MyTime, "time", x700, w300, y1000-53, h0+25
  GuiControl MyDate, "date", x700, w300, y1000-26, h0+25
  GuiGroup "Controls can be grouped:", w0+246, h0+75, bgcol RgbCol(255, 255, 200)
    GuiControl StatFind, "static", "Find:",        h0+22, w0+55              ; general syntax:
    GuiControl StatRepl, "static", "Replace:", h0+22, w0+55, y 0+24            ; guicontrol ID, "class", args "text", x, y, w, h, style
    GuiControl EditFind, "edit", f$, x 0+62, w0+100, h0+22, WS_EX_CLIENTEDGE   ; args have a variable part plus an optional fixed one, example:
    GuiControl EditRepl, "edit", r$, x 0+62, w0+100, h0+22, WS_EX_CLIENTEDGE, y 0+28   ; x1000-90 means "at right border, i.e. 100.0%, minus 90 pixels"
    GuiControl Cis, "button", BS_AUTOCHECKBOX, h0+22, x0+170, w0+60, "Case"    ; args may appear in no particular order, e.g. "Case" at the end
    GuiControl Fw, "button", text "Full word", h0+22, x0+170, w0+64, y0+28, BS_AUTOCHECKBOX
  GuiGroup end
  GuiControl BigEdit, "richedit", y0+120, h1000-120, w700      ; y at fixed 120px, h at full height minus 100px; width 70.0%
  If_ Exist(CL$()) Then <SetWin$ hBigEdit=FileRead$(Exist$)>    ; OPT_Arg1      \Masm32\MasmBasic\Res\MbSnippets.asc
  GuiControl Ok, "button", "Reset", x0+257, w0+80, h0+24, BS_DEFPUSHBUTTON
  GuiControl Progress, "progressbar", y0+88, h0+29, w700        ; , style PBS_SMOOTH    ; no effect if manifest is active
  GuiControl Status, "statusbar", "MasmBasic is pure assembly!!!!"
  GuiControl TimeMs, "static", x0+260, y0+32, h0+17, w0+75
  GuiControl InstallMB, "syslink", x0+260, y0+50, h0+17, w0+80, "MasmBasic"     ; RichMasm: copy a URL, select a word, press Ctrl K
  GuiControl Track, "trackbar", x0+257, y0+68, h0+17, w0+75, style TBS_AUTOTICKS or TBS_ENABLESELRANGE
  StringToArray cfm$("These\nare\nsome\nentries\nin\na\nlittle\nlistbox"), lbox$()      ; create an array (use Recall to load a textfile)
  SetListbox lbox$()                   ; fill the listbox
Event Timer
  sub rv(GetTickCount), ticks
  invoke SendMessage, hProgress, PBM_SETPOS, eax, 0
  SetWin$ hTimeMs=fTime$(0, "HH:mm:ss.fff")     ; shows milliseconds (check CPU usage in Task Manager!)
Event Message
  .if uMsg_==WM_HSCROLL                 ; horizontal trackbar sends this message
        mov eax, lParam_
        .if eax==hTrack
                mov ticks, rv(GetTickCount)             ; try to sync with progressbar ;-)
                shl rv(SendMessage, lParam_, TBM_GETPOS, 0, 0), 9
                sub ticks, eax
        .endif
  .elseif uMsg==WM_CLOSE
        if 0                                    ; put 0 for testing (Escape quits), 1 for the release version
               MsgBox 0, "Save settings?", "Hi", MB_YESNOCANCEL
                sub eax, IDCANCEL
                je @RetEax                      ; return 0, i.e. do NOT close
                .if eax==IDYES-IDCANCEL
                                MsgBox 0, "Add your 'save settings' etc here", "Hi", MB_OK
                .endif
        endif
  .endif
Event Key
  .if VKey==VK_A
        MsgBox 0, "You pressed 'A'", "Hi", MB_OK                ; negative VK_ codes indicate the key was hit in an edit control
  .endif
Event Command
  Switch_ MenuID                                        ; menu entries start with 0, controls return their IDs here
  Case_ 0, Ok
        SetWin$ hStatus="You clicked the Open menu or the Reset button"
        mov ticks, rv(GetTickCount)
  Case_ 1: call MySave                          ; your own functions may appear after EndOfEvents
  Case_ 2: invoke SendMessage, hWnd, WM_CLOSE, 0, 0     ; the Exit menu entry
  Case_ 3 .. 9 : <MsgBox 0, Str$("You clicked MenuID #%i", MenuID), "Menu clicked:", MB_OK>
  Case_ EditFind, EditRepl, Cis, Fw
        wSetWin$ hStatus=wStr$("You clicked inside the group on item %i with text '", MenuID)+wWin$(rv(GetDlgItem, hWnd, MenuID))+"'"      ; Unicode is possible
  Endsw_
  .if NotifyCode==DTN_DATETIMECHANGE && (wParam==MyDate || wParam==MyTime)
        SetWin$ hStatus=Cat$(Win$(hMyDate)+", "+Win$(hMyTime))  ; 11.12.2013, 12:34:56
  .endif
  If_ NotifyCode==NM_CLICK && (word ptr wParam==InstallMB || word ptr wParam==MyDt) Then <wShEx Link$()>  ; open a web page
  If_ NotifyCode==LBN_SELCHANGE && word ptr wParam==ListBox Then SetWin$ hStatus=LbSel$         ; LbSel$ returns the text of the current listbox entry
EndOfEvents
MySave proc    ; your procs go below EndOfEvents
  SetWin$ hStatus="You clicked the Save menu"
  ret
MySave endp
GuiEnd


P.S.: You may try other types of controls, see Current UI Automation Control Types (https://msdn.microsoft.com/en-us/ee671197%28v=vs.85%29#currentcontroltypes) for an overview. Let me know what you tried and if it worked; if not, I may be able to implement the missing bits. Btw there is no "control" that allows to pick colours. Instead, use the MasmBasic RgbCol (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1331) macro with ?, for example: invoke someapi, RgbCol(?). Just for fun, here an "add-on" for the source above: SetWin$ hStatus="You clicked the Open menu or the Reset button"
mov ticks, rv(GetTickCount)
invoke DeleteObject, hcGroupBx   ; internal handles for the groupbox (not documented)
mov hcGroupBx[4], RgbCol(?)
mov hcGroupBx, rv(CreateSolidBrush, eax)
invoke InvalidateRect, hcGroupBx[8], 0, 1
Title: Re: MasmBasic
Post by: jack on January 01, 2018, 12:06:04 AM
hi jj2007
I installed the masm32 sdk without problems but trying to install MasmBasic trows Wndows Defender into panic, I forgot the trojans name that it purportedly found, any advise?
Title: Re: MasmBasic
Post by: jj2007 on January 01, 2018, 03:06:00 AM
Just tested the current package on Jotti, details here (https://virusscan.jotti.org/en-US/filescanjob/wimbb8ufl1), but "0/18 scanners reported malware". Quite unusual, actually :icon_mrgreen:

Similar for VirusTotal (results (https://www.virustotal.com/#/file/efd1fbb01c14902ba1c974a8c74849f82572402dd8949aba9295e7a233acf63f/detection)) - the Baidu AV reported "WisdomEyes", whatever that is, but 60 others say it's clean.

The Forum is on a safe server, and the MasmBasic package gets built with an automated procedure. There is no chance of a trojan creeping in. But many AV produce false positives - we even have a dedicated sub-forum AV Software sh*t list (http://masm32.com/board/index.php?board=23.0)  :bgrin:

Assembler produces by its nature suspicious code: The virus scanners expect C/C++ initialisation routines, CRT, SEH, etc; if they don't find them, they shout foul. Sometimes they shout foul because they see a pushad ... popad sequence, which is very unusual in C code, so it's "suspicious". Everything that is non-standard looks dangerous to them. Well, we are all proud here to produce non-standard software, so evidently there is a certain tension between assembler programmers and the AV brigade. And to be honest, there is also a community of assembler programmers who do produce malware, but we usually smell them from a distance if they appear here and ask for advice. The forum rules are very strict, and for valid reasons.

If you cannot ignore or override the message, try if there is an option to exclude certain folders, e.g. \Masm32\, from the scan. In the last five ten years or so, we had one case of a virus introduced here in this forum by a young member (who apparently had an infected machine without knowing it), and it was spotted by experienced members, not by their antivirus software...
Title: Re: MasmBasic
Post by: jack on January 01, 2018, 03:17:48 AM
ok thanks, I suspected it was a false positive.
Title: Re: MasmBasic
Post by: jj2007 on January 01, 2018, 03:28:02 AM
Just remembered the Test your AV software (http://masm32.com/board/index.php?topic=4814.0) thread, which I launched two years ago because I couldn't explain why Windows Defender never tried to defend me from really suspicious software ;)
Title: MatchLine
Post by: jj2007 on March 01, 2018, 12:53:05 PM
Sometimes you may want to know in which line of a string array a certain text is found. The standard way of doing this is a loop: or ecx, -1
.Repeat
inc ecx
.Until Instr_(L$(ecx), Match$, 2) || ecx>ebx


Attached is a new MatchLine(L$(), "text", mode) macro that does the same but a factor 9*) faster:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
include MatchLine.mac   ; the new macro
  Init
  PrintCpu 0
  Match$ equ <"duplicate include">      ; see Windows.inc, line 26900: echo WARNING Duplicate include file windows.inc
  Recall "\Masm32\include\Windows.inc", L$()
  xchg eax, ebx
  PrintLine "new fast MatchLine:"
  push 9                                ; ten iterations
  .Repeat
        NanoTimer()
        PrintLine Str$("Match in line %i found in ", MatchLine(L$(), Match$, 2)), NanoTimer$()
        dec stack
  .Until Sign?

  PrintLine cfm$("\nold loop method:")
  push 9                                ; ten iterations
  .Repeat
        NanoTimer()
        or ecx, -1
        .Repeat
                inc ecx
        .Until Instr_(L$(ecx), Match$, 2) || ecx>ebx
        PrintLine Str$("Match in line %i found in ", ecx), NanoTimer$()
        dec stack
  .Until Sign?
EndOfCode


Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
new fast MatchLine:
Match in line 26899 found in 215 µs
Match in line 26899 found in 205 µs
Match in line 26899 found in 204 µs
Match in line 26899 found in 202 µs
Match in line 26899 found in 202 µs
Match in line 26899 found in 202 µs
Match in line 26899 found in 203 µs
Match in line 26899 found in 202 µs
Match in line 26899 found in 202 µs
Match in line 26899 found in 202 µs

old loop method:
Match in line 26899 found in 1742 µs
Match in line 26899 found in 1753 µs
Match in line 26899 found in 1831 µs
Match in line 26899 found in 1774 µs
Match in line 26899 found in 1728 µs
Match in line 26899 found in 1721 µs
Match in line 26899 found in 1722 µs
Match in line 26899 found in 1722 µs
Match in line 26899 found in 2017 µs
Match in line 26899 found in 1740 µs


Usage of MatchLine() is restricted to:
- unmodified text arrays obtained with Recall (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172)
- Instr_ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1153) modes 0 (=case-sensitive) and 2 (=intellisense, case of first char ignored)

*)
MatchLine() is about 9x as fast as the loop method for a small file like Windows.inc - and it is probably irrelevant if the search takes 0.2 or 1.8 milliseconds. My tests with a much bigger file, 12MB and 164,000 lines (i.e. too big to be cached) still show a factor 4 improvement.

Macro and exe are attached - grateful for some timings on other CPUs.
Title: Re: MasmBasic
Post by: 2B||!2B on April 17, 2018, 09:47:41 PM
There is a bug in the Dim directive. It uses a call to HeapAlloc with NULL as the heap which leads to crash.
Title: Dim causes a crash?
Post by: jj2007 on April 17, 2018, 10:17:22 PM
Quote from: 2B||!2B on April 17, 2018, 09:47:41 PM
There is a bug in the Dim directive. It uses a call to HeapAlloc with NULL as the heap which leads to crash.

Can you post your code please? Since I use Dim very often, and without such problems, I suspect that you forgot to use Init at the beginning. I am afraid the documentation is a bit misleading there - Init is not optional, some commands will simply not work. Sorry for that, it will be corrected once I find time to post a new version.
Title: Re: Dim causes a crash?
Post by: 2B||!2B on April 18, 2018, 01:16:44 PM
Quote from: jj2007 on April 17, 2018, 10:17:22 PM
Quote from: 2B||!2B on April 17, 2018, 09:47:41 PM
There is a bug in the Dim directive. It uses a call to HeapAlloc with NULL as the heap which leads to crash.

Can you post your code please? Since I use Dim very often, and without such problems, I suspect that you forgot to use Init at the beginning. I am afraid the documentation is a bit misleading there - Init is not optional, some commands will simply not work. Sorry for that, it will be corrected once I find time to post a new version.

Hi man,

Yes you are right. Have forgot the Init actually sorry about that.

Added it before Dim and now it works fine.

Awesome work man.
Title: Re: MasmBasic
Post by: 2B||!2B on April 19, 2018, 04:51:57 PM
I have a question. Why do you use FPU/MMX/SSE instructions set so often? are there any advantages by using them rather than using the standard x86 instructions set? like faster execution, smaller code size maybe?
Title: Re: MasmBasic
Post by: jj2007 on April 19, 2018, 05:32:39 PM
There are no MMX instructions in MasmBasic (MMX code is inefficient, and there are conflicts with the FPU).

For calculations, the FPU is generally being used; it's not faster (and not slower) than the corresponding SSE* instructions, but internally it gives REAL10 precision, while SSE* offers only double precision, i.e. REAL8.

SSE* code is generally not shorter than ordinary x86 (but there are exceptions). However, it's often a lot faster. Take a simple example, getting the length of a zero-delimited string. There is a little thread here (http://www.masmforum.com/board/index.php?topic=14626.0) showing how the Masm32 team developed the current MasmBasic Len() macro. The thread has 149 replies, meaning it took a while to find the fastest option. Check yourself how fast it is, compared to the strlen function of the C runtime library (remember C is the fastest language on Earth :P):

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Recall "\Masm32\include\Windows.inc", L$() ; get a string array
  push eax ; #elements
  xor ebx, ebx
  xor edi, edi
  NanoTimer()
  .Repeat
invoke crt_strlen, L$(ebx)
add edi, eax ; calculate total len
inc ebx
  .Until ebx>=stack
  Print "The CRT needs ", NanoTimer$(), Str$(" for calculating the length of %i strings", ebx), Str$(", a total of %i bytes\n", edi)
  xor ebx, ebx
  xor edi, edi
  NanoTimer()
  .Repeat
add edi, Len(L$(ebx)) ; calculate total len
inc ebx
  .Until ebx>=stack
  pop edx
  Inkey " MB Len needs ", NanoTimer$(), Str$(" for calculating the length of %i strings", ebx), Str$(", a total of %i bytes\n", edi)
EndOfCode


Note that Windows.inc has relatively short strings. The difference between the speed of Len vs crt_strlen is much bigger for long strings. For example, if you apply the code above to a bible.txt file, with longer strings, the difference is twice as much. I won't tell you how much because there a C/C++ coders here in the forum, and they might fall into a deep depression if they see the results :icon_cool: 

Attached a full example, comparing also the Instr() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1153) performances of MasmBasic and the CRT (if that sounds interesting, see Benchmark 2: Alice in Wonderland (http://old.blog.phusion.nl/2010/12/06/efficient-substring-searching/) for a CRT strstr vs Boyer-Moore comparison)
Title: Re: MasmBasic
Post by: 2B||!2B on April 20, 2018, 03:35:12 PM
Ah ok i got it now thanks for clarifying that. Actually i used some FPU instructions for floating point result (like progress bar 0.# for example) but have never used SSE instructions.  :biggrin:

Quote from: jj2007 on April 19, 2018, 05:32:39 PM
I won't tell you how much because there a C/C++ coders here in the forum, and they might fall into a deep depression if they see the results :icon_cool: 

Lol, they can still use inline ASM though  :biggrin:
Title: Floor & Ceil
Post by: jj2007 on April 25, 2018, 05:24:34 PM
include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  SetGlobals MyR4:REAL4, MyW:WORD=-123, MyDw:DWORD=-123
  Init
  PrintLine cfm$("number\tFloor(number)\tCeil(number)")
  PrintLine Str$("%4f", MyW), Str$("\t%5f", Floor(MyW)v), Str$("  \t%5f", Ceil(MyW)v), " (WORD size integer)"
  PrintLine Str$("%4f", MyDw), Str$("\t%5f", Floor(MyDw)v), Str$("  \t%5f", Ceil(MyDw)v), " (DWORD size integer)"
  For_ ecx=0 To 29
        Rand(-99.9, +99.9, MyR4)
        PrintLine Str$("%4f ", MyR4), Str$("\t%5f", Floor(MyR4)v), Str$("  \t%5f", Ceil(MyR4)v)
  Next
EndOfCode


Output:number  Floor(number)   Ceil(number)
-123.0  -123.00         -123.00 (WORD size integer)
-123.0  -123.00         -123.00 (DWORD size integer)
-9.629  -10.0000        -9.0000
-85.50  -86.000         -85.000
-72.59  -73.000         -72.000
72.67   72.000          73.000
31.14   31.000          32.000
64.07   64.000          65.000
-55.86  -56.000         -55.000
57.42   57.000          58.000
-95.26  -96.000         -95.000
3.386   3.0000          4.0000
12.49   12.000          13.000
-27.00  -28.000         -27.000
15.36   15.000          16.000
35.19   35.000          36.000
-49.67  -50.000         -49.000
-70.70  -71.000         -70.000
17.82   17.000          18.000
-7.807  -8.0000         -7.0000
37.56   37.000          38.000
95.73   95.000          96.000
27.80   27.000          28.000
-67.03  -68.000         -67.000
68.09   68.000          69.000
-75.14  -76.000         -75.000
-53.27  -54.000         -53.000
55.16   55.000          56.000
75.63   75.000          76.000
90.65   90.000          91.000
88.01   88.000          89.000
-21.09  -22.000         -21.000


Not included in the current (December '17) release, therefore attached as FloorCeil.inc; you may add it to your MasmBasic.inc.

Note the red v after the Str$("format", Numberv): Floor() and Ceil() always return ST(0) for further processing; if you just print the value, it needs to be popped via fstp st from the FPU. That's what the v does. Of course, you can also pop it directly into another variable, specified as second argument:

  Floor(123.456, MyDw)
  Print Str$("dw(123.456)=%i", MyDw)


The first argument can be an immediate (interpreted as double) or a DWORD, WORD, REAL4 ... REAL10 variable.
Title: Missing .inc file
Post by: tenkey on October 25, 2018, 08:52:22 AM
The second example in the MasmBasic guide fails to assemble due to missing DualWin.inc file. I see LibUsed$() example is also using JBasic.inc instead of MasmBasic.inc. MasmBasic Version 25 Dec 2017.
Title: Re: MasmBasic
Post by: jj2007 on October 25, 2018, 11:07:41 AM
Thanks for the feedback. Did you get any error messages?

Please tell me if the following files are present (this helps me to understand what went wrong):
  \Masm32\MasmBasic\Res\GetPT.exe
  \Masm32\MasmBasic\Res\StructInfo.txt

- Extract the attached files to \Masm32\MasmBasic\Res
- Try again to build the example; if that doesn't work, try to run \Masm32\MasmBasic\Res\GetPT.bat

Note that the 64-bit examples build also with MASM; to do so, add an OPTion as follows:
include \masm32\MasmBasic\Res\JBasic.inc ; OPT_Assembler ML

However, RichMasm prefers UAsm and will try to install it if it's not present at \Masm32\bin\Uasm64.exe
You can do that manually, too: install UAsm64 (http://www.terraspace.co.uk/uasm.html#p2), i.e. extract \Masm32\bin\Uasm64.exe

Let me know if it works, please.
Title: Re: MasmBasic
Post by: 2B||!2B on November 08, 2018, 02:09:01 PM
Hi jj,

Is there a Unicode Split$() version?
Title: Re: MasmBasic
Post by: jj2007 on November 08, 2018, 07:34:28 PM
No, but it could be implemented. Something like this works already - not Unicode but Utf8:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi="Введите\nтекст\nздесь"
  For_ ct=0 To Split$(esi, "\n", My$())-1
        PrintLine "[", My$(ct), "]"
  Next
EndOfCode


Output:
[Введите]
[текст]
[здесь]


What exactly do you want to do?
Title: Re: MasmBasic
Post by: 2B||!2B on November 08, 2018, 09:16:31 PM
Cool, but i don't want to assign my string to a new variable. My string is like "####STRING####STRING" etc
So i use #### as string delimiter.
But i used wInstr and it worked fine for me. Although i have to add a null terminator after each substring, this way i can use the string in it's source.
Title: Re: MasmBasic
Post by: tenkey on November 09, 2018, 06:38:43 PM
Quote from: jj2007 on October 25, 2018, 11:07:41 AM
Thanks for the feedback. Did you get any error messages?
*** Assemble using \masm32\bin\UAsm64 /c /coff /Zd /Zi /Zf tmp_file.asm ***
UASM v2.46, Dec  8 2017, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.

*** using Res\JBasic32.lib ***
\masm32\MasmBasic\Res\JBasic.inc(558) : Error A2106: Cannot open file: "\Masm32\MasmBasic\Res\DualWin.inc" [ENOENT]
\masm32\MasmBasic\Res\JBasic.inc(558): Included by
  Tmp_File.asm(1): Main line
Quote
Please tell me if the following files are present (this helps me to understand what went wrong):
  \Masm32\MasmBasic\Res\GetPT.exe
  \Masm32\MasmBasic\Res\StructInfo.txt
GetPT.asm exists, but not GetPT.exe.
StructInfo.txt exists.
Quote
- Extract the attached files to \Masm32\MasmBasic\Res
Extracted the files and ran GetPT.exe in a command prompt. Had to  turn off security.
The example (32-bit) assembled and ran.
I re-enabled security and now the file names \masm32\masmbasic\mbguide.exe and \masm32\masmbasic\tmp_file.exe are flagged as suspicious. polink can't create them - access denied.
I can probably create the exe files in another directory, but that means i'll have to use a custom BAT file for each example.

*** Assemble using \masm32\bin\UAsm64 /c /coff /Zd /Zi /Zf tmp_file.asm ***
UASM v2.46, Dec  8 2017, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.

*** MasmBasic version 25.12.2017 ***
Tmp_File.asm: 6 lines, 2 passes, 99 ms, 0 warnings, 0 errors

*** Link  MbGuide.obj rsrc.res  using polink, sub Console /debug /mapinfo:lines***
Writing debug information
Compacting CodeView information
POLINK: fatal error: Access is denied.
*** Link error ***
Title: Re: MasmBasic
Post by: jj2007 on November 09, 2018, 07:01:33 PM
So it's all a security thing. If I used an AV, I would simply exclude the whole \Masm32 folder. Assembly code is considered unsafe because it's unusual by the dumb AV brigade, see our dedicated sub-forum AV Software sh*t list (http://masm32.com/board/index.php?board=23.0) 8)
Title: MasmBasic update
Post by: jj2007 on November 25, 2018, 12:48:54 PM
It has been a while since MasmBasic was updated - grab the new version here (http://masm32.com/board/index.php?topic=94.0). Below an alphabetical list of the new macros added. In RichMasm, check File/MasmBasic help for the new keywords. Let me know if one is missing.

AddMru MACRO pTxt
ArrayStripDuplicates MACRO numID
Ceil MACRO arg, dest
ClosePipe MACRO arg:=<2>
ExeFromExt$ MACRO argExt, opt:=<2>
Floor MACRO arg, dest
Geo$ MACRO arg1:=<GEO_FRIENDLYNAME>, arg2:=<G
HeapStrings MACRO
LineInput MACRO dest$
Lset MACRO args:VARARG
MruText$ MACRO arg
MulQQ MACRO argQ1, argQ2, pDest
rCosinus MACRO arg
ResFile$ MACRO id
rSinus MACRO arg
SetAxisX MACRO args:VARARG
SetAxisY MACRO args:VARARG
SetMru MACRO fname ; SetMru "filename.ini"
SetRgbCol MACRO dest, noarg
ShowPlaces MACRO arg:=<1>
StoreHeader MACRO pSHeader
TitleCase$ MACRO arg
uClip$ MACRO MbLimit
uFileOpen$ MACRO args:VARARG
uFileSave$ MACRO args:VARARG
uSetWin$ MACRO arg1:REQ
uWin$ MACRO h1, cHandle
wExeFromExt$ MACRO argExt, opt:=<2>
wGeo$ MACRO arg1:=<GEO_FRIENDLYNAME>, arg2:=<
Win64 MACRO
Title: Re: MasmBasic
Post by: 2B||!2B on November 29, 2018, 07:15:57 AM
Hi jj,

I could not get the Try/Catch to work.

Init tc

Is causing unresolved external symbol.


error LNK2001: unresolved external symbol _MbTryCatch@0
fatal error LNK1120: 1 unresolved externals



How do i solve it?
Title: Re: MasmBasic
Post by: jj2007 on November 29, 2018, 09:38:05 AM
Without seeing your full code, I can't help you much. This works:

include \masm32\MasmBasic\MasmBasic.inc         ; simple Try/Catch demo - use as a template
  Init tc                               ; initialise MasmBasic with Try/Catch (aka SEH)
  PrintLine "This code was built with ", @AsmUsed$()
  mov eax, 123                  ; use 123 as the dividend
  cdq                           ; and sign-extend it to edx
  xor ecx, ecx
  Try
        div ecx
        PrintLine "Congrats, it worked!!!!"     ; you won't see this line
  Catch
        PrintLine "Sorry, div ecx failed"
  Finally
        PrintLine Str$("Ouch, we had an exception in source line %i at\nAddress\t", LastEx(line)), Hex$(LastEx(addr)), CrLf$, "Code", Tb$, Hex$(LastEx(code)), CrLf$
        Inkey "The OS reports:", CrLf$, LastEx(info)
EndOfCode

OPT_TryCatch on       ; tells MasmBasic's preferred editor RichMasm to select the source line that triggered the first exception


This code was built with UAsm64
Sorry, div ecx failed
Ouch, we had an exception in source line -6 at
Address 004010D4
Code    C0000094

The OS reports:
{ERRORE DI EXCEPTION}
Divisione intera per zero.
EIP     004010D4
Code    C0000094
Title: Re: MasmBasic
Post by: 2B||!2B on November 29, 2018, 12:52:49 PM
The code you posted does not compile if used inside a procedure

Error A2093: Cannot nest procedures
Error A2142: Unmatched block nesting: MbTryCatch



Try/Catch does not work inside a procedure. I tried using it outside a procedure and it compiled.
Is there a way to fix this so it can be used inside a procedure?
Title: Re: MasmBasic
Post by: jj2007 on November 29, 2018, 01:07:32 PM
I cannot diagnose what went wrong if you don't post the complete code. This works fine:
include \masm32\MasmBasic\MasmBasic.inc ; simple Try/Catch demo - use as a template
  Init tc, console ; initialise MasmBasic with Try/Catch (aka SEH), and output errors to console
  PrintLine "This code was built with ", @AsmUsed$()
  call MyTest
  Exit

MyTest proc
  mov eax, 123 ; now we'll do something illegal in line 13...
  cdq
  xor ecx, ecx
  Try
; ****** the line below will be selected a second after the program finishes: ******
div ecx ; dividing by zero is a criminal act, right?
Print Str$("div succeeded, eax is %i\n", eax) ; you will not see this message
  Catch
Print Str$("div failed, eax is still %i\n\n", eax)
  PrintLine Str$("Ouch, we had an exception in source line %i at\nAddress\t", LastEx(line)), Hex$(LastEx(addr)), CrLf$, "Code", Tb$, Hex$(LastEx(code)), CrLf$
  PrintLine "The OS reports:", CrLf$, LastEx(info)
  Finally
  ret
MyTest endp

EndOfCode ; OPT_TryCatch on ; activate jump to the error line in the source code


Output:
This code was built with UAsm64
div failed, eax is still 123

Ouch, we had an exception in source line 13 at
Address 0040110A
Code    C0000094

The OS reports:
{ERRORE DI EXCEPTION}
Divisione intera per zero.
EIP     0040110A
Code    C0000094
Title: Re: MasmBasic
Post by: 2B||!2B on November 29, 2018, 01:11:24 PM
Which code you want me to post?
I have only tried to compile your code that you posted earlier.
So does the Init TC needed to be called outside a procedure?
and also, do we need to call it once in every thread?
Title: Re: MasmBasic
Post by: jj2007 on November 29, 2018, 07:24:16 PM
Quote from: 2B||!2B on November 29, 2018, 01:11:24 PM
Which code you want me to post?

Your complete code. My crystal ball is not working today, I must see what you are trying to assemble...
Title: Re: MasmBasic
Post by: HSE on November 30, 2018, 03:16:20 AM
Quote from: jj2007 on November 25, 2018, 12:48:54 PM
It has been a while..

- could not open MenusRM.ini
- problem with @AsmUsed$()
Title: Re: MasmBasic
Post by: jj2007 on November 30, 2018, 02:09:40 PM
Quote from: HSE on November 30, 2018, 03:16:20 AM- could not open MenusRM.ini
- problem with @AsmUsed$()

Both problems fixed, please reinstall MasmBasic (http://masm32.com/board/index.php?topic=94.0). Grateful if you could test this snippet with the new version:

GuiParas equ "Hello World", w160, h100
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl MyEdit, "RichEdit", Cat$("This program was assembled with "+@AsmUsed$()+" and uses common controls version "+ComCtl32$())
GuiEnd xp
Title: Re: MasmBasic
Post by: Phrediac on January 17, 2019, 09:46:13 AM
Hi

I get this popping up when I try to run the program. It's not from the AV software (Avast).
I'm running Windows 7.

Sorry, can't figure out how to upload images.

Many thanks
-Ian
Title: Avast false positive
Post by: jj2007 on January 17, 2019, 02:15:51 PM
Hi Ian,

RichMasm.exe is the editor, and I use it all the time on several machines. It is clean, no virus there, I know it because I build it from the source, over 20,000 lines. However, several AV scanners report malware, see the VirusTotal results (https://www.virustotal.com/#/file/0b674d9888d10af2eb32d0f9843a1f680d15230a92a2813c0a3cdf9ba06f6ded/detection): 18 out of 70! Here is the report for the same file but uncompressed (https://www.virustotal.com/#/file/09e4a8f78506e6eeb109d62ef26817db79d2032a60e9d2f9a9f58b5db101c152/detection), and the detection rate drops to 6 of 69. So simple compression is sufficient for 12 of these brilliant AV engines to shout foul. The reason is that no AV can test for all viruses and trojans in the wild, the databases would be huge, and testing would slow down your Windows to a crawl. So they use "heuristics" for detecting "suspicious behaviour", such as: Does the instruction "pushad" appear in the exe? Normal for assembler, almost never used by C compilers.

Check what the better AV engines report, like Kaspersky, Symantec etc., and then decide whether you really want to learn assembly. Once your executables grow a bit in size, they will never look like mainstream C/C++ executables - bad luck :P

I see you are using Avast. Virustotal says Avast reports Win32:Evo-gen, and googling for that virus leads quickly to
Is Win32.Evo-gen(Susp) a False Positive? (https://forum.avast.com/index.php?topic=173072.0) and What's with all the new Win32:Evo-gen [Susp] false positives?  (Read 23100 times) (https://forum.avast.com/index.php?topic=151077.0), so RichMasm.exe is not the only victim of Avast.

If you are interested, the forum has a dedicated section "AV Software sh*t list" (http://masm32.com/board/index.php?board=23.0).

Cheers, Jochen

P.S.: VirusTotal has "Details" and "Behaviour" tabs. Here are details for the attached uncompressed RichMasm.exe (https://www.virustotal.com/#/file/09e4a8f78506e6eeb109d62ef26817db79d2032a60e9d2f9a9f58b5db101c152/details):
Win32 Executable MS Visual C++ 4.x (59.6%)
Win32 Executable MS Visual C++ (generic) (13.8%)
Win64 Executable (generic) (12.2%)
Windows screen saver (5.8%)
Win32 Dynamic Link Library (generic) (2.9%)


So they believe with 59.6+13.8%=73.4% probability that it was built with MS Visual Crap :icon_mrgreen:

Here is another example (https://www.virustotal.com/#/file/8da5e5241fa1d1f50c5a6bb63d6da9f02cb1c56cf115e11e87098369f0b0852c/details), it is the Download URL with UTF8 (http://masm32.com/board/index.php?topic=6483.msg83157#msg83157) executable:
Win64 Executable (generic) (47.7%)
Windows screen saver (22.6%)
Win32 Dynamic Link Library (generic) (11.3%)
Win32 Executable (generic) (7.7%)
OS/2 Executable (generic) (3.5%)


So they believe it's a Win64 exe. Or a DLL, or maybe a screensaver. Oh well, this is hitech, folks :t

I attach the uncompressed version of RichMasm.exe - welcome to the Forum :icon14:
Title: Re: MasmBasic
Post by: felipe on January 18, 2019, 04:00:31 AM
nice info  :icon14:
Title: Re: MasmBasic
Post by: jj2007 on January 25, 2019, 11:36:04 AM
Please reinstall MasmBasic, updated on 25 January 2019. (http://masm32.com/board/index.php?topic=94.0)

Minor improvements under the hood, plus:

1. A new macro, _Local; my old favourite programming language, GfaBasic, had local variables (of course), but in contrast to MASM one could initialise them. This is now possible in Assembler:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
.code

MyTest proc uses esi edi ebx arg1, arg2
LOCAL var1, var2, rc:RECT, buffer[100]:BYTE                   ; "normal" locals, will be initialised to zero
_Local MyR4:REAL4=12345.6789, MyR8:REAL8=1234567890.1234567890         ; REAL variables
_Local var3=arg2, var4=200, x$=arg1, y$="Hello World"                  ; DWORDs and strings
  ClearLocals                          ; clear or set locals
  Print Str$("v1=%i", var1), Str$(", v2=%i", var2), Str$(", v3=%i", var3), Str$(", v4=%i", var4), Str$(", a2=%i", arg2)
  Print Str$(", R4=%7f", MyR4), Str$(", R8=%Df", MyR8)
  PrintLine ", x$=", x$, ", y$=", y$
  ret
MyTest endp

  Init
  For_ ecx=0 To 150
        invoke MyTest, Str$(ecx), ecx
  Next
EndOfCode


The syntax is _Local var=whatever (i.e. understroke plus camel case Local). The declarations must be followed by ClearLocals. Full project is attached.

2. NoTag$() recognises many more special characters now. Test it:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi=FileRead$("http://masm32.com/board/index.php?topic=94.0")     ; assign page to a string
  FileWrite "temp.txt", NoTag$(esi)     ; strip the tags and write plain text to disk
  ShEx "temp.txt"               ; have a look with ShellExecute
EndOfCode


3. A bugfix for the SysLink GuiControl; the tooltips didn't appear. Now it's working fine, see attached project and screenshot below.
Title: Re: MasmBasic
Post by: anunitu on January 26, 2019, 05:11:27 AM
as always JJ love your hard work on masmbasic
Title: Re: MasmBasic
Post by: jj2007 on January 26, 2019, 05:30:40 AM
Thanks, anunitu :icon14:
Title: Re: MasmBasic
Post by: anunitu on January 26, 2019, 05:32:10 AM
you sly asm devil
Title: Re: MasmBasic
Post by: jj2007 on January 31, 2019, 01:54:36 PM
Update 31 January 2019 (http://masm32.com/board/index.php?topic=94.0):
- Rand(): randomness of REAL8 variables improved
- add2m and sub2m macros (use like m2m)
- MakePath: graphs can now be modified 'on the fly', e.g. in the Timer event, thus allowing moving shapes (demo attached):

  MakePen hPenBez, RgbCol(255, 255, 0, 0), width 4
  ArraySet pts() As DWORD = 10, 10, 80, 40, 40, 190, 190, 50, 100, 170, 180, 170, 100, 0
  MakePath 123, Bezier(pts())

Event Timer
  add2m pts(2), dirX
  add2m pts(7), dirY

Event Paint
  GuiDraw 123, hPenBez, 10.0, 10.0, 2500, 5000  ; x, y, scaleX, scaleY
Title: ArrayIndex(SomeNumericArray(), SomeNumber)
Post by: jj2007 on February 05, 2019, 10:54:52 PM
The MasmBasic update of 5 February 2019 (http://masm32.com/board/index.php?topic=94.0) features a new ArrayIndex() macro inspired by Guga's Fast Compare Real8 with SSE (http://masm32.com/board/index.php?topic=7659.0) thread. The macro returns in eax the position of a number in a sorted array; if dl is zero, an exact match was found, otherwise the nearest position will be returned in eax. Syntax example:

Print Str$("The position of the number 8377 in the array table() is %i", ArrayIndex(table(), 83777))

The sorted array, table() in this example, can be composed of DWORD, QWORD or REAL8 values. Below and attached a complete example:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  StringToArray FileRead$(99), table() As DWORD  ; read an array from resource #99
  ArraySort table()    ; sort ascending
  Let esi="83777"      ; just a suggestion
  Print "Hit Escape & Return to exit"
  .While 1
        Print At(0, 1)
        Let esi=Input$("Gimme a prime: ", esi)
        .Break .if !Len(esi)
       void ArrayIndex(table(), Val(esi))      ; works with DWORD, QWORD and REAL8 arrays
        .if dl
                PrintLine esi, Str$(" is not a prime, sorry!!!! - the nearest prime is %i   ", table(eax))
        .else
                PrintLine Str$("congrats, prime found at pos #%i !!", eax), Space$(32)
        .endif
  .Endw
EndOfCode
Title: Re: MasmBasic
Post by: guga on February 06, 2019, 02:14:01 AM
Tks, JJ :)

Found only a small issue. Whenever the searching number is bigger or equal to the last one on the table it should return the last one and not 2 before.

For example, i gave a try with only 10 numbers to search:
Table =  101, 103, 107, 109, 113, 127, 131, 137, 139, 149
(So, the Index/Pos = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

Number is smaller or equal to the 1st one is ok :t Ex:
Number to Search = 100. Return nearest number is 101. (So, index = 0)  OK !! :t
Number to Search = 101. Return nearest number is 101. (So, index = 0)  OK !! :t

Numbers in between are Ok :t
Number to Search = 104. Return nearest number is 103. (So, index = 1)  OK !! :t


Number is equal,is ok only when it is not the last one. Ex:
Number to Search = 103. Return index = 1  OK !! :t
Number to Search = 139. Return index = 8  OK !! :t
But....
Number to Search = 149. Not found. Return index should be 9.


but...when Number is bigger or equal to the last, it is returning 2 positions backwards and not the last one

Number to Search = 149. Not finding the proper number. Is giving a message of nearest The correct should be 149. So, index (Pos from 0 to XX) = 9
Number to Search = 150. Return nearest number is 139. The correct should be 149. So, index (Pos from 0 to XX) = 9
Number to Search = 151. Return nearest number is 139. The correct should be 149 So, index = 9
Number to Search = 2751. Return nearest number is 139. The correct should be 149 So, index = 9
Title: Re: MasmBasic
Post by: guga on February 06, 2019, 04:08:34 AM
Btw. the same issue i described happens when the size of the table is odd. For example , table size = 11
Table =  101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 177
(So, the Index/Pos = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

Number to search = 149; Found at pos 8 (139) rather then 9

It cannot find the number and, this time (For odd sized table), is returning 3 positions backwards, rather then 2 when the same error happens for even sized table.
Title: Re: MasmBasic
Post by: jj2007 on February 06, 2019, 05:06:36 AM
Thanks a lot, Guga. I'm working on it...
Title: Re: MasmBasic
Post by: guga on February 06, 2019, 06:01:41 AM
You´re welcome, JJ  :t :t :t

Thank you for the effort. This function will be very helpful for the CieLCH functions i´m making. I´m still working on the pdf i told. I finished part of it, but still trying to find the limits of all those equations. For what i saw so far, those equations are utterly incorrect, since they allows the user to input any RGB value despite the fact that some of those combination simply don´t matches to the results of their own formulas. The major problem is find a way to make them work ok, without using incorrect RGB values whose combinations, simply were impossible on the CieLab/CieLCH color spaces. This is the main reason why the backwards convertion allows clipping and generate incorrect results.

For example, when the user inputs a RGB value originate form a HSL convertion it is not guaranteed that it will result the proper Lab or LCH values from the perceptual colorspaces, since the input can be a combination of colors that don´t actually "exists".
Title: Re: MasmBasic
Post by: jj2007 on February 09, 2019, 08:04:52 AM
Update 8 February 2019 (http://masm32.com/board/index.php?topic=94.0):
- ArrayIndex(someArray(), findnumber) is now working properly
- three new macros Log2, LogE, Log10:

include \masm32\MasmBasic\MasmBasic.inc
  SetGlobals REAL10 ct, tmp10
  Init
  For_ ct=1.5 To 10.0 Step 0.5
        Print Str$(" Log2(%2f)", ct), Str$("\t%Jf ", Log2(ct)v), Str$("\t%Jf ", LogE(ct)v), Str$("\t%Jf\n", Log10(ct)v)
  Next
  void Log10(123.4567890)
  fadd FP4(3.0)
  ExpXY(10.0, ST(0), tmp10)     ; calculates 10^ST(0) and saves it to tmp10
  Inkey Str$("The value of tmp10 is now %f", tmp10)
EndOfCode


Output:
 Log2(1.5)      0.5849625007211561815   0.4054651081081643820   0.1760912590556812421
Log2(2.0)      1.000000000000000000    0.6931471805599453094   0.3010299956639811952
...
Log2(9.5)      3.247927513443585494    2.251291798606495151    0.9777236052888477664
Log2(10.0)     3.321928094887362348    2.302585092994045684    1.000000000000000000
The value of tmp10 is now 123456.8
Title: Re: MasmBasic
Post by: jj2007 on February 12, 2019, 09:53:51 PM
Update 12 February 2019 fixes a minor glitch in the editor (http://masm32.com/board/index.php?topic=94.0). As a side effect, a request by HSE to set the foreground colour (http://masm32.com/board/index.php?topic=5314.msg78962#msg78962) has been answered: YES it works now.

The snippets collection (\Masm32\MasmBasic\Res\MbSnippets.asc) has one problem with the ArraySet examples:

  Dim MyNum(5) As DWORD         ; create an array with 6 elements (0 .. 5)
  ArraySet MyNum() = 11, 22, 33, 44, 55, 66    ; assign values


This syntax is obsolete and crashes, unfortunately. The proper way to handle this is like this:

  ArraySet MyNum() As DWORD = 11, 22, 33, 44, 55, 66    ; create an array and assign values
  xor ecx, ecx
  .Repeat
        mov MyNum(ecx), Rand(12345)
        PrintLine Str$(ecx), Tb$, Str$(MyNum(ecx))
        inc ecx
  .Until ecx>=MyNum(?)


First, a DWORD array gets created, and 6 values are being assigned.
The loop replaces these values with random ones (range 0... 12344) and prints them.

Note a tricky little detail: .Until ecx>=MyNum(?) exits the loop when the current number of elements is reached. Take the = away, and you'll get an endless loop because when assigning a value to the last element+1, the array gets automatically expanded. This is not a bug, it's a feature of dynamic arrays.
Title: Re: MasmBasic
Post by: jj2007 on April 02, 2019, 09:24:27 PM
Update 2 April '19 (http://masm32.com/board/index.php?topic=94.0) adds a bunch of improvements under the hood, check this Gui programming post (http://masm32.com/board/index.php?topic=7722.msg85206#msg85206) for an example. Inter alia, the new CanvasZoom macro allows to "zoom" a control:

GuiControl MyList, "listbox", x800, w200       ; put the box at x=80% width, full height
GuiControl MyImg, "canvas", w800, h500         ; images have width 80%, height 50%
GuiControl MyMap, "canvas", y500, h500, w800   ; same but at y=50% of height

...
Event Key
  Switch_ VKey                                 ; press M or I to zoom a canvas control (press twice to toggle)
  Case_ VK_I:  CanvasZoom MyImg, MyList        ; zoom the image, hide the listbox
  Case_ VK_M:  CanvasZoom MyMap, MyList        ; zoom the map, hide the listbox
  Endsw_


Attached an image viewer; extract the exe to a folder that contains images (jpg, png, animated gif), then run the exe.
Title: Re: MasmBasic
Post by: jj2007 on May 08, 2019, 11:20:59 PM
MasmBasic was updated (http://masm32.com/board/index.php?topic=94.0), version 8 May features some improvements under the hood, inter alia building a library has become a lot faster because it will no longer do a full rebuild (unless you use Shift F6).

As a side effect, RichMasm now supports the conversion of a library folder into a single source (the MasmBasic library is indeed one fat 2.2 MB file containing 33 modules). To test this feature, extract the attached files to a folder of your choice, then either drag a folder over the exe, or open a DOS prompt and type e.g. BuildTheLibSource.exe \Masm32\m32lib

Soon after, RichMasm will show you more or less this:
include TestFile.asm
OxPT_LibName \fullpath\MyLib
OPT_DelTmp 0
OPT_DelObj 0
OPT_Tgt rml ; RichMasmLibrary
OPT_Linker link ; polink does not recognise certain options
OPT_Arg1 "Hello coder, how are you?" ; for testing

LibMod AA: a2dw
; #########################################################################

    ; --------------------------------------
    ; This procedure was written by Iczelion
    ; --------------------------------------

      .386
      .model flat, stdcall  ; 32 bit memory model
... etc ...


Hit F6 and watch the library being built. By default, it will be named BuildLib.lib - move it wherever you need it, the little TestFile.asm includes it "as is", i.e. as BuildLib.lib

What is the advantage of one big source file, instead of 237 tiny modules? It surely is a matter of taste, but, for example, you can search the source for mov e*, 0 to do a bit of maintenance (Intel says xor reg32, reg32 is the right thing to do). Plus comfortable navigation, highlighting of critical parts, etc - it's not meant for bare metal purists :P
Title: Re: MasmBasic
Post by: TimoVJL on May 09, 2019, 12:35:23 AM
splitting / combine source is a good idea.
easy too see what parts are changes, time stamp.

a common keyword for it might be usable ?

Find in files helps finding things, but often too many files to open in an editor.

MasmBasic.lib:
almost 250 symbols in 33 modules, still some work to do ?

PS: ml and pocc have a same problem, no COMDAT support :(
Title: Re: MasmBasic
Post by: jj2007 on May 09, 2019, 01:42:30 AM
Quote from: TimoVJL on May 09, 2019, 12:35:23 AM
splitting / combine source is a good idea.
easy too see what parts are changes, time stamp.
I use a checksum for the part between LibMods. When working inside the source, RichMasm remembers the last 8 edit positions (and saves them with the file!). By pressing Alt Left / Alt Right, you can jump between them. Hitting Alt Right several times brings you always back to the last edit. Thus, even if you stopped working on a source months ago, the editor will remember what you were last working on. Extremely handy in my experience. I hate editors that open a file, and you always stare at the top of the file.

QuoteMasmBasic.lib:
almost 250 symbols in 33 modules, still some work to do ?

Not all modules can be neatly separated, unfortunately. This is mainly because of the fast circular buffer and the array engines; many modules use them.
Title: Re: MasmBasic
Post by: 2B||!2B on May 22, 2019, 11:15:32 AM
Hi jj,

How can i get the returned value of Split$ (number of found substrings)?

MOV EBX,Split$("Masm32 is great", " ", My$())-1 ;Does not work
Let EBX = Split$("Masm32 is great", " ", My$())-1 ;Does not work

Title: Re: MasmBasic
Post by: jj2007 on May 22, 2019, 12:52:38 PM
Hi,

The example in the manual has a FOR counter:
For_ ct=0 To Split$("Masm32 is great", " ", My$())-1
PrintLine "[", My$(ct), "]"
Next


Since Split$() (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1320) returns the number of strings in eax, you could write this also as
void Split$("Masm32 is great", " ", My$())
For_ ct=0 To eax-1
PrintLine "[", My$(ct), "]"
Next


The example returns 3 strings, so this is for x=0 ... 3-1, given that arrays are zero-based. The problem in your example is the -1. You are writing MOV EBX, eax-1, and indeed, that does not work. Take away the -1, and all is fine.

Re your second example: Let (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1132) is for strings only.

Thanks for the feedback - I will modify the manual to make that point clearer :Thmbsup:
Title: Re: MasmBasic
Post by: 2B||!2B on May 22, 2019, 02:55:24 PM
Thank you, that works now compiled without error.

I have one more question

Is it possible to get the Array size?

Dim MyBuffer(10) As BYTE

How can i get the size of this buffer?
I have looked the manual and couldn't find what i am looking for.
Title: Re: MasmBasic
Post by: jj2007 on May 22, 2019, 05:36:52 PM
If you mean the number of elements: mov ecx, somearray(?)
Title: Re: MasmBasic
Post by: 2B||!2B on May 23, 2019, 05:08:48 PM
Thanks. It works perfect. Very useful library :D
Title: Re: MasmBasic
Post by: jj2007 on May 23, 2019, 05:22:10 PM
Thanks. Note that you can, but you don't have to, specify the array size. This is legal code:
  xor ecx, ecx
  Dim MyBuffer() As BYTE  ; no size!
  .Repeat
mov MyBuffer(ecx), cl
inc ecx
  .Until ecx>100
  Inkey "hit any key"


Arrays are dynamic, they auto-expand when the index (ecx in this case) hits the allocated number. You can't do a mov MyBuffer(1000), 123 though - the loop must increment the counter from the bottom.
Title: Re: MasmBasic
Post by: jj2007 on August 04, 2019, 09:02:28 PM
Update 4 August 2019 (download (http://masm32.com/board/index.php?topic=94.0)):

- added a warning to RichMasm for a hilarious MASM bug where a constant passed as e.g. SS_LEFT or WS_BORDER was not recognised as a constant by ML.exe:
DlgControl dcStatic,  "some text", SS_LEFT or WS_BORDER, 1, -7, 60.0

RichMasm will now add a "(1): Brackets around paras?" at the end of the output window. This may seem ridiculous but understanding the non-logic and misleading error messages of ML took me several hours, so I decided to warn myself next time.

- new macro ArrayFind(strings$(), "match", [mode], [startindex]):

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Recall "\Masm32\include\Windows.inc", L$()
  Print Str$("%i lines found in Windows.inc\n", eax)
  .if ArrayFind(L$(), "Hutch")
        PrintLine Trim$(L$(eax))        ; Original file 1998        hutch
  .endif
  xor ecx, ecx
  .While 1
        .Break .if ArrayFind(L$(), "MACRO", 1, ecx)<0   ; mode 1: case insensitive; see Instr_(...) (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1153)
       xchg eax, ecx
        PrintLine Str$("line %i\t", ecx), L$(ecx)
        inc ecx
  .Endw
  MsgBox 0, "ok?", "Hi", MB_OK
EndOfCode


Project attached.
Title: Re: MasmBasic
Post by: aw27 on August 05, 2019, 01:58:54 AM
We know the trolling pleasure you have in ranting Microsoft (and not only Microsoft).  :badgrin:
However, the MASM BASIC macro (DlgControl MACRO ctrlType, szText, dstyle, etc) you provided as an example is buggy.

Look here:
if (dstyle and SS_ICON) eq SS_ICON

It is completely different to pass SS_LEFT or WS_BORDER and to pass (SS_LEFT or WS_BORDER). Macros are not functions, just in case you don't know.

BTW, I am not studying MASM BASIC at this time, I was looking at the latest posts and noticed this perl.  :skrewy:

Title: Re: MasmBasic
Post by: jj2007 on August 05, 2019, 06:03:57 AM
Yeah, completely different:
include \masm32\include\masm32rt.inc  ; plain Masm32, no MasmBasic required

rant MACRO par1, par2, par3
Local tmp$
  tmp$ CATSTR <Paras passed: p1=>, <par1>, <, p2=>, <par2>, <, p3=>, <par3>
  % echo tmp$
  print "Test "
  print hex$(par1), 9
  print hex$(par2), 9
  print hex$(par3), 9
  if (par2 and WS_BORDER) eq WS_BORDER
print "WS_BORDER passed "
  endif
  print chr$(13, 10)
ENDM
.code
start:
   rant 1, SS_LEFT, 3
   rant 2, WS_BORDER, 3
   rant 3, SS_LEFT or WS_BORDER, 3
   rant 4, WS_BORDER or SS_LEFT, 3
   rant 5, (SS_LEFT or WS_BORDER), 3
   rant 6, (WS_BORDER or SS_LEFT), 3
   inkey
  exit

end start


And you shouldn't feel ashamed for studying MasmBasic macros. There is a lot to learn for you :cool:
Title: Re: MasmBasic
Post by: nidud on August 05, 2019, 07:18:08 AM
deleted
Title: Re: MasmBasic
Post by: jj2007 on August 05, 2019, 08:15:29 AM
Quote from: nidud on August 05, 2019, 07:18:08 AM
    if ((dstyle) and SS_ICON) eq SS_ICON

Thanks, Nidud, I see. Irrelevant for this specific macro (it works indeed), but there may be cases where it matters. Here is one, building on the previously posted example:
include \masm32\include\masm32rt.inc

rant MACRO par1, par2, par3
Local tmp$
  tmp$ CATSTR <Paras passed: p1=>, <par1>, <, p2=>, <par2>, <, p3=>, <par3>
  % echo tmp$
  print "Test "
  print hex$(par1), 9
  print hex$(par2), 9
  print hex$(par3), 9
  if ((par2) and WS_BORDER) eq WS_BORDER ; Nidud's solution: (SS_RIGHT or WS_BORDER) and WS_BORDER
print "WS_BORDER passed "
  endif
  if (par2 and WS_BORDER) eq WS_BORDER ; fails: SS_RIGHT or WS_BORDER and WS_BORDER
print " +"
  endif
  print chr$(13, 10)
ENDM
.code
start:
   rant 1, SS_RIGHT, 3
   rant 2, WS_BORDER, 3
   rant 3, SS_RIGHT or WS_BORDER, 3
   rant 4, WS_BORDER or SS_RIGHT, 3
   rant 5, (SS_RIGHT or WS_BORDER), 3
   rant 6, (WS_BORDER or SS_RIGHT), 3
   inkey
  exit

end start


Test 3 fails:
Test 00000001   00000002        00000003
Test 00000002   00800000        00000003        WS_BORDER passed  +
Test 00000003   00800002        00000003        WS_BORDER passed
Test 00000004   00800002        00000003        WS_BORDER passed  +
Test 00000005   00800002        00000003        WS_BORDER passed  +
Test 00000006   00800002        00000003        WS_BORDER passed  +
Title: Re: MasmBasic
Post by: jj2007 on August 05, 2019, 09:04:53 PM
This is code from an old plugin posted here two years ago (http://masm32.com/board/index.php?topic=5314.msg63462#msg63462):

  DlgControl dcEdit, wRec$(ini$(4)), WS_BORDER, 89.0, -6, 11.0, , ID_MODE2 ; x, y only, the macro will assign width, height and ID; OPT_Assembler mlv615
  if 0
DlgControl dcStatic,  "Files containing both strings:", SS_LEFT or WS_BORDER, 1, -7, 60.0  ; THIS ONE CHOKES
DlgControl dcStatic,  "maxMB=", SS_LEFT, 73.0%, -7, 31%
  elseif 0
DlgControl dcStatic,  "Files containing both strings:", (SS_LEFT or WS_BORDER), 1, -7, 60.0  ; this one is OK - Nidud's trick with the brackets works!!
DlgControl dcStatic,  "maxMB=", SS_LEFT, 73.0%, -7, 31%
  else
DlgControl dcStatic,  "Files containing both strings:", SS_LEFT or WS_BORDER, 1, -7, 60.0  ; guess what?
DlgControl dcStatic,  "maxMB=", SS_LEFT, 73.0%, -7, 31% ; this one is also OK!!
  endif


The interesting part is that, under the hood, Nidud's suggestion has been implemented:
if ((dstyle) and SS_ICON) eq SS_ICON
and ch, 10111111b ; clear bit 14
endif


So it should not matter whether we use (SS_LEFT or WS_BORDER) or SS_LEFT or WS_BORDER

But it does, as case 2 shows! Now the hilarious part is that it works in case 3.

Needless to say that UAsm and AsmC have no problem at all - this is a MASM only bug! Project attached.
Title: Re: MasmBasic
Post by: sinsi on August 05, 2019, 11:41:31 PM
Table 1.3 Operator Precedence
Precedence Operators
1 ( ), [ ]
2 LENGTH , SIZE , WIDTH , MASK, LENGTHOF, SIZEOF
3 . (structure-field-name operator)
4 : (segment-override operator), PTR
5 LROFFSET , OFFSET , SEG , THIS , TYPE
6 HIGH , HIGHWORD , LOW , LOWWORD
7 + ,– (unary)
8 *, /, MOD , SHL , SHR
9 +, – (binary)
10 EQ , NE , LT , LE , GT , GE
11 NOT
12 AND
13 OR , XOR
14 OPATTR , SHORT , .TYPE
Title: Re: MasmBasic
Post by: jj2007 on August 05, 2019, 11:58:30 PM
Thanks, Sinsi - this is already fixed with Nidud's suggestion to use brackets: if ((dstyle) and SS_ICON) eq SS_ICON

To my big surprise, I discovered that, after applying that fix, the line that choked was no longer the SS_LEFT or WS_BORDER line but rather the line that followed - see snippet above. After some trial and error, I discovered that cases 1 and 3, although almost identical, act differently:

case 1: DlgControl dcStatic,  "maxMB=", SS_LEFT, 73.0%, -7, 31%
case 3: DlgControl dcStatic,  "maxMB=", SS_LEFT, 73.0%, -7, 31%   ; this one is also OK!!

The first one chokes, the second one is OK. And of course, both are OK for UAsm and AsmC.
Title: Re: MasmBasic
Post by: TimoVJL on August 06, 2019, 12:42:26 AM
8.14.5 Macro Parameter Expansion and Macro Operators
QuoteOne possible solution, that works well for macros like the above, is to put parentheses
around macro parameters that occur within expressions inside the macro
.
http://www.phatcode.net/res/223/files/html/Chapter_8/CH08-7.html

EDIT: to avoid further misunderstanding, only documentation for that ?
QuoteThe problem above occurs because MASM simply replaces a formal parameter by the actual parameter's text, not the actual parameter's value. This pass by name parameter passing mechanism should be familiar to long-time C and C++ programmers who use the #define statement. If you think that macro (pass by name) parameters work just like Pascal and C's pass by value parameters, you are setting yourself up for eventual disaster.

One possible solution, that works well for macros like the above, is to put parentheses around macro parameters that occur within expressions inside the macro. Consider the following code:
Title: Re: MasmBasic
Post by: jj2007 on August 06, 2019, 02:25:21 AM
Yes, Timo, but it's not relevant here. Or, rather: it does work if you put parentheses around (x or z) but if you don't put these parentheses, all paras are passed correctly to this macro but the macro in the next line chokes.

And to make things perfect, you can make it assemble if ... tara! ... you add a comment to the next line:
case 1: DlgControl dcStatic,  "maxMB=", SS_LEFT, 73.0%, -7, 31%
case 3: DlgControl dcStatic,  "maxMB=", SS_LEFT, 73.0%, -7, 31%   ; this comment makes the line assemble!!


If there is no comment, you get error A2026: constant expected - and that is complete BS. It's a MASM bug, that's all. Of the same kind as the inability to deal with the "#" character if it's not at a certain position inside the include file. I can't find the reference right now, but that was another ML bug that drove me crazy. My suspicion is that during macro processing, some buffers don't get delimited properly, but that is impossible to chase.

MASM has some serious problems, and I would ditch it completely in favour of UAsm or AsmC if there wasn't a bit of nostalgia around to stick with the original M$ product.
Title: Re: MasmBasic
Post by: jj2007 on August 09, 2019, 11:00:57 PM
Timo,

I use all these macros on a daily basis, they work just fine. The problem is really some kind of buffer overflow in MASM that makes it choke with the % and # characters. I opened a separate MASM bug post with the complete example. (http://masm32.com/board/index.php?topic=8022.0)

The new MasmBasic version (http://masm32.com/board/index.php?topic=94.0) has fixes for the brackets bug, allows using e.g. 12.3% in the first DlgControl (that was the DlgDefY issue), and adds a specific warning to the output window if RichMasm sees "error A2026:constant expected".

Thanks a lot, Timo, Nidud and Sinsi, for your help.
Title: Re: MasmBasic
Post by: jj2007 on October 26, 2019, 12:09:19 PM
MasmBasic version 26 October 2019 is online. (http://masm32.com/board/index.php?topic=94.0)

Changes:
- the RichMasm editor lists now macros and procs correctly, as in the image below
- \Masm32\MasmBasic\MbGuide.rtf got a Table of Contents
- For_ ... Next (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1185) with floats follows a different logic now:
  * previously, the step was added to the float counter (fct in the example below). For small steps and REAL4 counters, significant deviations could accumulate
  * the new version calculates fct as endvalue - step*(total - current iterations), which is much more exact.

include \masm32\MasmBasic\MasmBasic.inc
  SetGlobals fct:REAL4
  Init
  For_ fct=1.5 To 2.0 Step 0.01 ; counter is a float, and therefore needs to be
Print Str$("%Jf\n", fct) ; previously defined in .data? or with SetGlobals
  Next
  Inkey "ok?"
EndOfCode
Title: Re: MasmBasic
Post by: jj2007 on December 08, 2019, 01:17:13 AM
Version 7 December 2019 is online (http://masm32.com/board/index.php?topic=94.0). Minor improvements, e.g. it's now possible to add a legend to an ArrayPlot (project attached):

(http://www.jj2007.eu/pics/LifeExpScreenshot.jpg)

The code required to add the legend:

        ArrayPlot RgbCol(192, 255, 255)         ; init & set background
        If_ useLegend Then Legend ld$(), mr, hLegendFont                ; corners: ul, ur, ll, lr, mr
...
        ArrayPlot exit, 0005000032#T title$, fcol Black         ; finish with a title, xxxxyyyyfsize


ld$() can be any Utf8 string array; mr indicates the position middle/right

To build the project,
- install the latest MasmBasic version (http://masm32.com/board/index.php?topic=94.0)
- extract the archive below to a folder on your Masm32 drive
- open LifeExpOECD.asc in RichMasm (\Masm32\MasmBasic\RichMasm.exe)
- hit F6
Title: Re: MasmBasic
Post by: JK on February 05, 2020, 04:05:19 AM
Hi jj2007,


just downloaded your MasmBasic - interesting! I think there will be questions ...


JK
Title: Re: MasmBasic
Post by: jj2007 on February 05, 2020, 04:52:03 AM
Go ahead :biggrin:
Title: Re: MasmBasic
Post by: JK on February 05, 2020, 09:23:23 AM
The idea is very cool, the implementation (RichMasm) is ... not easy to get used to. I would like to discuss a few things (MasmBasic and FreeBASIC related) in private - would you please drop me a mail at "jklwn44 at mail dot de".
Title: Re: MasmBasic
Post by: jj2007 on February 05, 2020, 10:13:00 AM
Email sent, although I prefer discussing here in this thread, or, if necessary, via PMs.

Re RichMasm, there are some posts here (http://masm32.com/board/index.php?topic=5314.0). I know it looks different, but I couldn't do any serious work with one of the standard editors. For example, the RichMasm source has currently 21,000 lines, try working with such a source without the listbox, the bookmarks and the history (Alt cursor left/right) :cool:

Note you can build FreeBasic sources with RichMasm, but a little add-on is needed. Let me know if you want to test it.

My biggest nuisance with RichMasm is that the MRU is limited to 25 files. The library itself is easy to handle, just one big file with 30 or so modules, but I have over 5,000 sources hanging around, and I am always playing with a dozen new ideas.
Title: Trigonometric functions: sine, cosine, tangent
Post by: jj2007 on February 22, 2020, 03:58:11 PM
Update 22 Feb 2020: (http://masm32.com/board/index.php?topic=94.0)
- minor improvements of the RichMasm editor
- changes to the deb macro (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1019):

  - displaying a string by address is now possible via e.g. deb 4, "test", $addr MyAnsi$, $$addr MyWide$
  - the handling of strings in structures was improved
  - debugging the FPU was improved - now the state of the registers is displayed:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  FpuFill ; fill FPU with 1001.0 ... 1008.0
  ffree st(7) ; create some problems
  fldz
  fldpi
  ffree st(5)
  ffree st(7)
  fldl2e
  deb 4, "FPU filled, NaN in ST1, zero in ST2, ST6 empty", ST(0), ST(1), ST(2), ST(3), ST(4), ST(5), ST(6), ST(7)
  fstp st
  ffree st(7)
  ffree st(6)
  ffree st(5)
  ffree st(4)
  ffree st(3)
  deb 1, "As previous, one fstp st plus 5*ffree", ST(0), ST(1), ST(2), ST(3), ST(4), ST(5), ST(6), ST(7)
EndOfCode


You may wonder why there are five ffree instructions: it is a special service for the Windows 10 users (http://masm32.com/board/index.php?topic=8363.msg91594#msg91594) :bgrin:

Console output (deb 1 produces a MsgBox):
FPU filled, NaN in ST1, zero in ST2, ST6 empty
ST(0)           1.442695040888963407
ST(1)           - NaN -
ST(2)           zero
ST(3)           1001.000000000000000
ST(4)           1002.000000000000000
ST(5)           1003.000000000000000
ST(6)           empty 1004.000000000
ST(7)           1005.000000000000000


- various trigonometric functions added (source attached):

include \masm32\MasmBasic\MasmBasic.inc
  SetGlobals fct:REAL8
  Init
  Cls
  Print cfm$("degrees\tSinus\tCosinus\t  Tangens    Cotangens")
  For_ fct=0.1 To 360.0 Step 15.0
Print Str$("\n%__i", fct), Str$("\t%3f", Sinus(fct)v), Str$("\t%3f", Cosinus(fct)v), Str$("\t  %3f", Tangens(fct)v)
Print At(37) Str$("%3f", Cotangens(fct)v)
  Next
  Print
  Print Str$("\nrTangens(PI/3)=30°    \t%3f", rTangens(0.5236)v)
  Print Str$("\nrCotangens(PI/6)=15° \t%3f", rCotangens(0.2618)v)
  Print Str$("\nArctangens(0.268) \t%3f", Arctangens(0.268)v)
  Print Str$("\nArctangens(0.577) \t%3f", Arctangens(0.577)v)
  Print Str$("\nArctangens(1)    \t%3f", Arctangens(1)v)
  Print Str$("\nArctangens(1.732) \t%3f", Arctangens(1.732)v)
  Print Str$("\nArctangens(60/30) \t%3f", Arctangens(60, 30)v) ; ideally opposite/adjacent sides of a rectangular triangle
  Print Str$("\nArctangens(4/3) \t%3f", Arctangens(4, 3)v) ; Pythagoras: 25=16+9
EndOfCode


Output:
degrees Sinus   Cosinus   Tangens    Cotangens
  0     0.00175 1.000     0.00175    573.
15     0.259   0.966     0.268      3.73
30     0.500   0.866     0.577      1.73
45     0.707   0.707     1.00       1.00
60     0.866   0.500     1.73       0.577
75     0.966   0.259     3.73       0.268
90     1.00    0.0       -3.69e+19  -2.71e-20
105     0.966   -0.259    -3.73      -0.268
120     0.866   -0.500    -1.73      -0.577
135     0.707   -0.707    -1.000     -1.00
150     0.500   -0.866    -0.577     -1.73
165     0.259   -0.966    -0.268     -3.73
180     0.0     -1.00     5.42e-20   1.84e+19
195     -0.259  -0.966    0.268      3.73
210     -0.500  -0.866    0.577      1.73
225     -0.707  -0.707    1.00       1.00
240     -0.866  -0.500    1.73       0.577
255     -0.966  -0.259    3.73       0.268
270     -1.00   0.0       -5.27e+18  -1.90e-19
285     -0.966  0.259     -3.73      -0.268
300     -0.866  0.500     -1.73      -0.577
315     -0.707  0.707     -1.00      -1.000
330     -0.500  0.866     -0.577     -1.73
345     -0.259  0.966     -0.268     -3.73
360     0.0     1.00      1.08e-19   9.22e+18

rTangens(PI/3)=30°      0.577
rCotangens(PI/6)=15°    3.73
Arctangens(0.268)       15.0
Arctangens(0.577)       30.0
Arctangens(1)           45.0
Arctangens(1.732)       60.0
Arctangens(60/30)       63.4
Arctangens(4/3)         53.1
Title: Say "Hello World": simple TTS with SAPI
Post by: jj2007 on May 02, 2020, 07:43:12 PM
MasmBasic of 2 May 2020 (http://masm32.com/board/index.php?topic=94.0) features the Say macro (source included). Simple example:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Say "Hello World"
EndOfCode


Attached is a project (tested with Win10, Win7 and WinXP) that might amuse Hutch - here is the complete source, it's a fascinating lecture :bgrin:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Say wRec$(NoTag$(FileRead$("http://masm32.com/why.htm")))
EndOfCode


Using Say from a GUI application is also quite easy:

- in RichMasm's File menu, click "New Masm source" to open the greenish window with the templates
- pick "controls" (the third item in the list with white background)
- hit F6 to test it, then check the syntax in the source.

Excerpt from \Masm32\MasmBasic\MbGuide.rtf:

Sound
       Sound "880:200"         ; plays frequency 880Hz for 200 ms; allowed separators are space, tab, / and :
       Sound "880/200/150"     ; plays frequency 880Hz for 200 ms, followed by 150 ms of silence
       Sound 111               ; plays a wav resource with ID 111 (in rc file: 111 WAVE "hello.wav")
       Sound "hello.wav"       ; plays a file directly (wav only)
       Sound "hello.mp3"       ; plays a file in its associated player
       Sound "大桥在混乱的水.mp3"  ; Unicode names are allowed
       Sound wCL$()            ; even if passed via the commandline
Rem    - The simple "frequency:duration" syntax works on Windows 7 and higher but not on Windows Vista;
          a minimum duration of about 90...100 ms is required
        - PlaySound/Beep/ShellExecute results can be checked with Err$()
Say
       include \masm32\MasmBasic\MasmBasic.inc
       Init                            ; select Init and hit F6
        Say "Hello World"
        Say "Low and slow", SetVolume(50), SetRate(-7)  ; you can use some methods of the ISpVoice interface
       ; Say wWin$(hEdit)              ; any Unicode string is ok
       ; Say FileRead$("TTS_Unicode.txt")
       ; Say wRec$(FileRead$("TTS_Ansi.txt"))  ; conversion necessary
       EndOfCode
Rem    uses ISpVoice


P.S.: Does anybody know how to use SpCreateBestObject (https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms717500(v=vs.85))? In theory, SetVoice(...) should work with the Say macro, but I can find only one female voice under Win7 and Win10.
Title: Re: MasmBasic
Post by: Siekmanski on May 02, 2020, 08:10:35 PM
Speaking of source code, literally.  :cool:
Title: Re: MasmBasic
Post by: jj2007 on May 02, 2020, 09:29:58 PM
Exactly :tongue:

Here is another one for you: it reads the Say macro source for you :bgrin:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Say wRec$(Extract$(FileRead$("\masm32\MasmBasic\MasmBasic.inc"), "Say MACRO", "ENDM", xsIncL or xsIncR, 99))
EndOfCode


Obviously, you need the last MB installation (http://masm32.com/board/index.php?topic=94.0) to extract the macro from the inc file, otherwise Extract$(..) (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1156) will only return a question mark.

Another variant, reading a very old short source:
include \masm32\MasmBasic\MasmBasic.inc
  Init
  Recall "\Masm32\examples\Tut17\2\USEDLL.ASM", L$()
  For_ each ecx in L$()
PrintLine ecx
Say wRec$(ecx), SetRate(5)
  Next
EndOfCode
Title: Re: MasmBasic
Post by: Siekmanski on May 02, 2020, 11:01:00 PM
Couldn't read MasmBasic.inc ( I haven't installed MasmBasic )
Title: Re: MasmBasic
Post by: Siekmanski on May 02, 2020, 11:11:54 PM
I had a plan ( never came so far to try it ) to write something with SAPI to copy speech to memory as a wav file.
I'm not sure anymore, think it should be possible with SAPI...
Title: Re: MasmBasic
Post by: TimoVJL on May 03, 2020, 05:24:05 PM
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms719484(v%3Dvs.85)
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms722562(v%3Dvs.85)
https://stackoverflow.com/questions/20498004/how-to-save-sapi-text-to-speech-to-an-audio-file-in-vbscript
Title: Re: MasmBasic
Post by: Siekmanski on May 03, 2020, 06:16:11 PM
Quote from: TimoVJL on May 03, 2020, 05:24:05 PM
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms719484(v%3Dvs.85)
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms722562(v%3Dvs.85)
https://stackoverflow.com/questions/20498004/how-to-save-sapi-text-to-speech-to-an-audio-file-in-vbscript

Thanks!  :thumbsup:
Title: Re: MasmBasic
Post by: jj2007 on May 03, 2020, 08:32:08 PM
Quote from: jj2007 on May 02, 2020, 09:29:58 PMObviously, you need the last MB installation (http://masm32.com/board/index.php?topic=94.0) to extract the macro from the inc file, otherwise Extract$(..) (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1156) will only return a question mark.
Quote from: Siekmanski on May 02, 2020, 11:01:00 PM
Couldn't read MasmBasic.inc ( I haven't installed MasmBasic )

No problem, Marinus - you just wanted to demonstrate that you would never, ever install MasmBasic. That's fine for me :tongue:

Has anybody at least tried to use SpCreateBestObject?
Title: Re: MasmBasic
Post by: Siekmanski on May 04, 2020, 12:56:14 AM
 :tongue:
What SAPI 5 version do you have?
I have 5.1.
I could find SpCreateBestObject in the Help file but not in the includes. ( could be I'm missing some files )
Is it a helper function from a lib?
I can't remember if there was also a lib included in the SAPI5.1 SDK.
Why not enumerate all the voices yourself and pick the one you want to use, or is there more to the SpCreateBestObject?
Title: Re: MasmBasic
Post by: jj2007 on May 04, 2020, 01:16:47 AM
I have 5.3, which should have it: https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms717500(v%3Dvs.85)

invoke LoadLibrary, Chr$("C:\Windows\System32\Speech\Common\sapi.dll")
fdeb 4, "LL", eax
.if eax
push eax
invoke GetProcAddress, eax, Chr$("SpCreateBestObject")
fdeb 4, "GPA", eax
call FreeLibrary
Inkey
Exit
.endif


NOT FOUND.
Title: Re: MasmBasic
Post by: Siekmanski on May 04, 2020, 01:31:11 AM
Just had a look in the Windows v7.1 SDK,
There I found the sapi.lib and the sapi51 and sapi53 includes, no SpCreateBestObject ( also not in the sapi.lib )  :sad:
Title: Re: MasmBasic
Post by: jj2007 on May 04, 2020, 01:38:25 AM
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\sphelper.h
template<class T>
HRESULT SpCreateBestObject(
    const WCHAR * pszCategoryId,
    const WCHAR * pszReqAttribs,
    const WCHAR * pszOptAttribs,
    T ** ppObject,
    IUnknown * pUnkOuter = NULL,
    DWORD dwClsCtxt = CLSCTX_ALL)
{
    HRESULT hr;
Title: Re: MasmBasic
Post by: Siekmanski on May 04, 2020, 01:50:49 AM
Looks like a function.
Do you have the Sapi5.3 SDK installed? Maybe there is a lib....
Title: Re: MasmBasic
Post by: jj2007 on May 04, 2020, 01:55:03 AM
I have over 3GB of Visual Studio 14.0 hanging around in C:\Program Files (x86)\Microsoft Visual Studio 14.0 - no SpHelper found in 7789 folders, but 224 lib files. None of them has SpCreate*

I wonder if it's Windows CE only: https://docs.microsoft.com/en-us/previous-versions/ms937518(v%3Dmsdn.10)

https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms717321(v%3Dvs.85)
QuoteMicrosoft Speech API 5.3

Helper Functions
Helper functions are available as a convenience to programming. Since many of the procedures use the same few methods or calls in the same sequence each time, these functions are available to consolidate those standard sequences. In all cases, the functions represent nothing more than the individual steps combined into one call; no additional features have been added or removed. Programmers are free to either use these functions or include the original lines of code. The function name attempts to clearly identify the purpose of the function itself.

The following helper functions are used with SAPI 5.

Token Helpers
SpCreateBestObject
SpCreateDefaultObjectFromCategoryId
SpCreateNewToken (by category ID)
SpCreateNewToken (by token ID)
SpCreateNewTokenEx (by category ID)
SpCreateNewTokenEx (by token ID)
SpCreateObjectFromSubToken
SpCreateObjectFromToken
SpCreateObjectFromTokenId
SpCreatePhoneConverter
SpEnumTokens
SpFindBestToken
SpGetCategoryFromId
SpGetDefaultTokenFromCategoryId
SpGetDefaultTokenIdFromCategoryId
SpGetDescription
SpGetSubTokenFromToken
SpGetTokenFromId
SpGetUserDefaultUILanguage
SpSetCommonTokenData
SpSetDefaultTokenForCategoryId
SpSetDefaultTokenIdForCategoryId
SpSetDescription
Title: Re: MasmBasic
Post by: Siekmanski on May 04, 2020, 02:03:04 AM
I have searched on my computer, found nothing.
Title: Re: MasmBasic
Post by: Siekmanski on May 04, 2020, 02:12:22 AM
Maybe you have succes with: IID_ISpObjectTokenCategory EnumTokens ?
Title: Re: MasmBasic
Post by: jj2007 on May 04, 2020, 07:45:03 AM
Not yet. I guess it's useless anyways because I have only one voice installed. Extra voices cost real money.

There is a demo here (https://www.cereproc.com/en/node/645). Try with the text below - amazing!

There are many reasons why experienced programmers choose to write assembler code, performance issues where speed matters, the architectural freedom to lay out code in any way you like, the capacity to do things that cannot be done in many compilers but the main reason is simply because you can. Many conjure up the image of cobbling together a few DOS interrupts in unintelligible notation to prop up the shortcomings of compilers yet a modern assembler like MASM has the range of a high level language and can be written that way for high level code while retaining all of its power at the lowest level.

With the introduction of the 32 bit Windows API functions, MASM had access at the same functions that compilers had from the operating system but without the clutter and assumption of many of the compilers available. When you write Windows API code in MASM you get perfectly clear minimal precision code that leverages the full power of the Windows operating system and you get it at the code size you write, not with a pile of unwanted extras dumped into your executable by a compiler.

MASM has never been for the faint of heart, it is an uncompromised tool that has never been softened into a user friendly toy and it required the development of expertise to use correctly but for the programmer who already has experience in low level C and similar code, MASM offers power and flexibility that the best of compilers cannot deliver and contrary to popular opinion it can be developed and written at about the same development time as C code.
Title: Re: MasmBasic
Post by: Siekmanski on May 04, 2020, 08:40:03 AM
I heard the text from your example.  :cool:
Copied it in the link you posted, there are some High Quality ones.

I have 2 amazingly High Quality SAPI5 Dutch female voices. (paid 200 euros for the 2 voices, today you can get 1 for 40 euros. )
Unfortunately they will only install on Windows 32bit.  :sad:
Title: Re: MasmBasic
Post by: jj2007 on May 04, 2020, 09:15:37 AM
I have downloaded the SDK from http://download.microsoft.com/download/B/4/3/B4314928-7B71-4336-9DE7-6FA4CF00B7B3/SpeechSDK51.exe

Mary & Mike don't work, and "Sample TTS voice" works but says most of the time "bla" (really :tongue:)
Title: Re: MasmBasic
Post by: Siekmanski on May 04, 2020, 09:19:50 AM
 :biggrin:
https://harposoftware.com/en/search?controller=search&orderby=position&orderway=desc&search_query=italian&submit_search=
Title: Re: MasmBasic
Post by: TimoVJL on May 05, 2020, 01:07:50 AM
A test program for SAPI 5.x
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <sapi.h>

#pragma comment(lib, "ole32.lib")

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
ISpVoice * pVoice = NULL;
CoInitialize(NULL);
HRESULT hr = CoCreateInstance(&CLSID_SpVoice, NULL, CLSCTX_ALL, &IID_ISpVoice, (void **)&pVoice);
if (SUCCEEDED(hr))
{
hr = pVoice->lpVtbl->Speak(pVoice, L"<voice optional='Gender=Male;'>Hello world", 0, NULL);
//hr = pVoice->lpVtbl->Speak(pVoice, L"<voice required='Gender = Male;'>Hello world", 0, NULL);
//if (hr) hr = pVoice->lpVtbl->Speak(pVoice, L"<voice required='Gender = Female;'>Hello world", 0, NULL);
pVoice->lpVtbl->Release(pVoice);
pVoice = NULL;
}
CoUninitialize();
return 0;
}
Title: Re: MasmBasic
Post by: jj2007 on May 05, 2020, 07:52:09 AM
Very interesting, Timo - I didn't know that you can specify options with XML tags:
hr = pVoice->lpVtbl->Speak(pVoice, L"<voice optional='Gender=Male;'>Hello world, I am a man", 0, NULL);
if (1)
hr = pVoice->lpVtbl->Speak(pVoice, L"<voice required='Gender=Female;'>Hello world, I am a woman", 0, NULL);

With this modification, I hear both strings spoken by the same female voice when built as X64, but only "I am a woman" when built as x86  :sad:

With MasmBasic:

Say wChr$("<voice optional='Gender=lgbt;'>Good morning")


For Gender=, everything works fine except Gender=male, which is mute :rolleyes:
Title: Re: MasmBasic
Post by: jj2007 on July 29, 2020, 07:40:14 PM
Update 28 July 2020 (http://masm32.com/board/index.php?topic=94.0) (in response to fast median thread (http://masm32.com/board/index.php?topic=8671.msg95039#msg95039) and timings (http://masm32.com/board/index.php?topic=8688.msg95011#msg95011))

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Dim MyArray() As REAL4        ; can be DWORD, REAL4 or REAL8
  For_ ecx=0 To 99
        Rand(-888.8, 999.9, MyArray(ecx))       ; put random numbers into the array
  Next
  PrintLine Str$("The elements:\t%i", MyArray(?))
  PrintLine Str$("The columns:\t%i", MyArray(?cols))    ; will return 0: this array is one-dimensional
  PrintLine Str$("The minimum:\t%f", MyArray(?min)v)    ; the functions marked with v return the
  PrintLine Str$("The maximum:\t%9f", MyArray(?max)v)   ; value in ST(0); the v tells Str$() to discard
  PrintLine Str$("The median:\t%f", MyArray(?median)v)  ; ST(0) with fstp st after printing
  PrintLine Str$("The mean:\t%9f", MyArray(?mean)v)     ; ?average does the same as ?mean
  PrintLine Str$("The sum: \t%9f", MyArray(?sum)v)      ; sum of all elements
EndOfCode


The elements:   100
The columns:    0
The minimum:    -884.9537
The maximum:    994.308716
The median:     -8.574001
The mean:       35.9553806
The sum:        3595.53806
Title: Re: MasmBasic
Post by: Siekmanski on July 29, 2020, 09:12:59 PM
Cool, all in one.  :cool:
Title: Re: MasmBasic
Post by: guga on July 30, 2020, 06:17:44 AM
Great work, JJ

One question about the median function.

Here
  fld st
  faddp st(2), st
  fsub arrInf.yMin ; make positive
  fmul arrInf.yRange ; normalise 0...99999
  ; fadd FP4(0.45)
  fistp arrInf.yIndex ; we need a
  mov eax, arrInf.yIndex ; reg32
  inc dword ptr [edi+4*eax] ; Populate the Median buffer with the values as index numbers and keep track for duplicates in one go
  dec ecx
  jns aiPop ; 0 is still ok


the size of the Table (MedBuffer) used in edi must be the double when we are dealing with negative values, right ?

I mean, say i have limits from -255 to 255, then the total size of the table should be (256*4*2) ?

Also, since it will be subtracting the negative values to set onto the proper address of the table, should it calculate the median and preserve the sign in case the resultant median is also negative ?

I previously normalized the inputed data to -1 to 1, so i divided each value with 255. On your version, at that routine, i made the following port:


; [Med_MinVal_Normalized: R$ -1.0] = < --- The minimum value as set in arrInf.yMin already normalized

    Do
        fld F$esi | fsub R$Med_MinVal_Normalized | fmul R$Float255 | fistp D@Index | mov eax D@Index ; Multiplied the input with 255 to it points to the proper address on the table.
        inc D$edi+eax*4   ; Populate the Median buffer with the values as index numbers
        add esi ebx       ; and keep track for duplicates in one go. And skip positions if needed
    Repeat_Until_Zero ecx


Is this correct ? Will it result a negative median (thus, preserving the sign) if the median is, in fact, negative ?
Title: Re: MasmBasic
Post by: jj2007 on July 30, 2020, 10:39:15 AM
Hi Guga,
In the example above the range of values is determined by the Rand (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1030)(-888.8, 999.9, destination). The normalisation takes care of negative numbers. In fact, the median for this dataset is slightly negative.
The minimum:    -884.9537
The maximum:    994.308716
The median:     -8.574001
The mean:       35.9553806
Title: Re: MasmBasic
Post by: guga on July 30, 2020, 12:11:06 PM
Hi JJ, ok, but how the normalization works ? The math operation, i mean.

I saw it takes the subtraction of the Maxvalue to the MinValue, but it will divide by what ?

Fraction = (Max-Min)/ WhatData ?

What Data is suppose to be divided with ? If we have negative numbers, it means we have double the amount of values, right ? ex, if the limits to be settled are -255 to 255, it means we have, in fact a limit of 255*2 data to load. So, if our Minimum value found is, let´s say -200 and Max is 185, then to apply the normalization, is correct to do this ?

Fraction = (185-(-200))(2*255) = (185+200)/510 = 385/510 = 0.754901961

So, our Fraction (arrInf.yRange) would be 0.754901961, right ?

And to recover the proper median at the end of the function, we do this ?

New Value = ValueFound/Fraction - Minimum Value ? = ValueFound/0.75490191 - (-200) ?


Title: Re: MasmBasic
Post by: jj2007 on July 30, 2020, 06:35:55 PM
Quote from: guga on July 30, 2020, 12:11:06 PM
Hi JJ, ok, but how the normalization works ? The math operation, i mean.

Search for arrInf.yRange - it should be self-explanatory :cool:
Title: Re: MasmBasic
Post by: jj2007 on October 03, 2020, 09:29:44 AM
New version online (http://masm32.com/board/index.php?topic=94.0)

There are numerous little improvements under the hood. One new feature: RichMasm knows a new option called "Close" (see the Capitals of Europe thread (http://masm32.com/board/index.php?topic=8808.0) for an example).

OPT_Close Capitals of Europe ; close the window before building

When testing a Windows program, I often forget to close it before hitting F6 (the build all key). Inevitably, the linker chokes because the exe is still running. Now with OPT_Close <the window title> RichMasm sends a WM_CLOSE message to the running exe, and it closes (unless there are data to be saved, of course). Problem solved :tongue:

Another new feature: the canvas control (for plots, images and maps, see e.g. GuiImage (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1375)) has now a right-click context menu for saving its content to the clipboard or to a file. It can also be zoomed to fill the entire client area.

The one-line If_ accepts now also Exist(), FileOpen$() etc args:
include \masm32\MasmBasic\MasmBasic.inc
  Init
  If_ Exist("*.bmp") Then PrintLine "yeah, ", Exist$, " exists"
  If_ not Exist("no.bmp") Then Print "Nope, it does not exist"
EndOfCode


Btw did you know the difference between these two?
a) ; int 3
b) int 3

With a), hitting F6 builds and launches the executable
With b), hitting F6 builds and launches \Masm32\OllyDbg\ollydbg.exe <executable path>

Greetings from a lazy programmer :tongue:
Title: Re: MasmBasic
Post by: jj2007 on October 06, 2020, 09:22:30 PM
New version online (http://masm32.com/board/index.php?topic=94.0)

Here is an attempt to use an I/O library to communicate with ports, inspired by this FreeBasic thread (https://www.freebasic.net/forum/viewtopic.php?f=18&t=28863):

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Cls
  if 0
        Dll "InpOut32"          ; WikiDll (https://wikidll.com/other/inpout32-dll); first three functions
  else
        Dll "DlPortIO"          ; Scientific Software Tools at WikiDll (https://wikidll.com/scientific-software-tools-inc/dlportio-dll) ; next four
  endif
  Declare void Out32, 2         ; ushort port, data
  Declare void Inp32, 2         ; ushort port, data
  Declare IsInpOutDriverOpen    ; no args
  Declare DlPortReadPortUshort, 1       ; ushort port
  Declare DlPortReadPortUlong, 1       ; int port
  Declare DlPortWritePortUshort, 2     ; int port, data
  Declare DlPortWritePortUlong, 2      ; int port, data
  PrintLine Str$("Out32: %i", Out32(?))        ; prints the address or zero if the function was not found
  If_ IsInpOutDriverOpen(?) Then <Print Str$("driver open: %i\n", IsInpOutDriverOpen())>        ; crashes
  If_ Out32(?) Then <Out32(111h, 222h)>        ; crashes
  If_ DlPortReadPortUshort(?) Then <Print Str$("read port: %i\n", DlPortReadPortUshort(99))> ; error message
  PrintLine "done"
EndOfCode


The DLLs are available at various places, see links above, but it is unclear how they actually work. Inp32 and Out32 are actually straightforward, under the hood you see in al, dx and out dx, al, but the rest is badly documented.

What's new in MasmBasic then?
- SomeFunction(?) checks if the function has been loaded - see IsInpOutDriverOpen(?) above
- in console mode, you get feedback on Declare (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1018):
not found (line 9):     Out32
not found (line 10):    Inp32
not found (line 11):    IsInpOutDriverOpen


Unrelated: $Data (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1290) accepts now empty strings. This was inspired by Guga's Resource String Table (http://masm32.com/board/index.php?topic=8828.0) thread. If, for example, you copy \Masm32\include\masm32rt.inc into a source (to display the strings, whatever), there are some empty strings, and they used to choke with $Data. This little problem has been solved*)

In case you want a huge string table copied from a text file:
- File/New/Masm source: pick the Console example
- between the include line and Init, paste the lines from the text file
- select the whole block
- press Alt R
- insert $Data ]#[ into the replace edit control, hit Return and confirm
- insert these three lines under Init (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1009):
  Read my$()
  For_ ecx=0 To eax-1
PrintLine my$(ecx)
  Next


*) at least for UAsm and AsmC - M$ MASM misbehaves on this one, and for ML there is no workaround other than deleting the offending empty line; otherwise, the whole MasmBasic library is fully compatible with ML versions 6.15 ... 14 or so, but attention, some recent ML versions have ugly bugs (http://masm32.com/board/index.php?topic=6447.0). I strongly recommend to use UAsm (http://www.terraspace.co.uk/uasm.html).
Title: Re: MasmBasic
Post by: jj2007 on October 12, 2020, 10:34:27 AM
Version 12 October is online (http://masm32.com/board/index.php?topic=94.0)

- version 3 of Capitals of Europe (http://masm32.com/board/index.php?topic=8808.0) will build with the latest MasmBasic package (maps with flicker-free Unicode tooltips)
- new macro LineNumber(buffer, search$):

include \masm32\MasmBasic\MasmBasic.inc
Init
Print Str$("The string 'Duplicate' is in line %i of Windows.inc", LineNumber(FileRead$("\Masm32\include\Windows.inc"), "Duplicate")+1)
EndOfCode


Output:
The string 'Duplicate' is in line 26900 of Windows.inc

Optional 3rd argument: mode as for Instr_() (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1153), i.e. 1=case-insensitive, 2=first char of match case-insensitive, 4=full word...
Optional 4th argument: line delimiter char, e.g. 13 (default is 10=linefeed)

LineNumber() is not particularly fast, but it returns the #lines of Duplicate in Windows.inc in under 3ms on my trusty old Core i5 - reading the file included :cool:
Title: StringBuild macro for fast concatenation of strings in the MegaByte range
Post by: jj2007 on October 16, 2020, 01:03:57 PM
Update 16 October 2020 is online (http://masm32.com/board/index.php?topic=94.0) and features a new StringBuild macro (http://masm32.com/board/index.php?topic=8853.msg96604#msg96604):

StringBuild edi ; ---------- start building the string
For_ ecx=1 To 70000
Let edi=CrLf$+"string "+Str$("#%i", ecx)
Next
StringBuild ; ---------- stop string building


For a 1MB string, the speed gain compared to Let my$=my$+"xx" is roughly a factor 1,000 :cool:

With e.g. StringBuild some$, 2000000 the default 1MB allocation can be adjusted if needed. For usedeb=1 (default), overflow will trigger a MsgBox; this costs a few bytes more but has practically no influence on performance.
Title: Linear regression
Post by: jj2007 on October 25, 2020, 12:18:42 PM
GuiParas equ "Plotting a linear regression", w600, h300, col Pink, icon Plot, b RgbCol(0, 0, 0)
include \masm32\MasmBasic\Res\MbGui.asm
  ArrayRead x() As REAL8, 90    ; get x+y arrays
  ArrayRead y() As REAL8, 91    ; from resources
  Dim y2() As REAL8             ; this array will hold the regression line
  GetLinReg x(), y()            ; set the A and B coefficients
  For_ ecx=0 To eax-1           ; #elements in eax
        SetFloat <y2(ecx)>=LinRegY(x(ecx))      ; <destination> brackets needed here
  Next
Event Paint
  ArraySet MyRange() As REAL4=-0.5, 0.0, 3.2, 50.0
  ArrayPlot MyRange(XY), setrange
  ArrayPlot x():y(), RgbCol(255, 255, 255, 0), 5
  ArrayPlot x():y2(), RgbCol(160, 255, 0, 0), lines=3
  ArrayPlot exit, "Linear regression"
EndOfCode
Rsrc
90 RCDATA       "RegressionX.dat"
91 RCDATA       "RegressionY.dat"
Rsrc


Source, exe and data files attached - building requires MasmBasic version 25 October 2020 (http://masm32.com/board/index.php?topic=94.0)
Title: Re: MasmBasic
Post by: jj2007 on October 27, 2020, 11:57:15 AM
Version 27.10.2020: (http://masm32.com/board/index.php?topic=94.0)
- bugfix: ArrayStripDuplicates could set a faulty last value
- new: ArrayMinMax myarray(), minVar, maxVar (i.e. you can now specify two destination variables)
- new: AddFloat, e.g. SetFloat myRealX=123.456, AddFloat myRealX=[any immediate number or numeric variable]
- ArraySet accepts now variables, e.g. ArraySet xyarray() As REAL4=maxDate, 0.0, minDate, ecx

Finally, RichMasm's layout improved slightly: the pinboard has moved to the upper right corner, as shown below (this is the proc called by GuiImage (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1375) - a bit over 350 lines).

(http://www.jj2007.eu/pics/ImgPaintP.png)
Title: Re: MasmBasic
Post by: xandaz on November 02, 2020, 02:32:02 AM
  MasmBasic gives net error when downloading. can someone give me a valid linlk?
Title: Re: MasmBasic
Post by: jj2007 on November 02, 2020, 02:32:58 AM
http://masm32.com/board/index.php?topic=94.0 doesn't work for you? I just tested it, everything works as it should...
Title: The Russian Guitars
Post by: jj2007 on November 04, 2020, 03:58:48 AM
I found lovely music that doesn't distract me from coding: The Russian Guitars 1800-1850 (https://www.youtube.com/watch?v=dTdPizz7Dic)
Title: Re: MasmBasic
Post by: hutch-- on November 14, 2020, 07:13:01 PM
Nice track, like it.
Title: Re: MasmBasic
Post by: 2B||!2B on December 07, 2020, 05:45:16 PM
jj,

The new update seems to give errors about unresolved externals. Why?
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _CreateFontIndirectA@4 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _GetOpenFileNameA@4 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _GetOpenFileNameW@4 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _GetSaveFileNameA@4 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _GetSaveFileNameW@4 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _SHBrowseForFolderA@4 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _SHGetPathFromIDListA@8 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _CoTaskMemFree@4 referenced in function _MbCloseN@0
MasmBasic.lib(LibTmpAB.obj) : error LNK2019: unresolved external symbol _StdOut@4 referenced in function _TestRetVal@0


Also, how can i redim an array that has been allocated by Dim?

Example:
Dim My$(999) As DWORD
Dim My$(new:1234)


Errors
Error A2102: Symbol not defined : new
The documentation is so confusing.
Title: Re: MasmBasic
Post by: jj2007 on December 07, 2020, 09:13:11 PM
Quote from: 2B||!2B on December 07, 2020, 05:45:16 PM
The new update seems to give errors about unresolved externals. Why?

I've just downloaded the installer, and used it on a "virgin" Masm32 installation. Everything works fine... did you modify any Masm32 files? Does it work now, if yes: what did you change? I am curious what could be the cause, as I cannot reproduce this problem.

QuoteAlso, how can i redim an array that has been allocated by Dim?

Example:
Dim My$(999) As DWORD
Dim My$(new:1234)


Errors
Error A2102: Symbol not defined : new

When you add As DWORD, MasmBasic assumes you want a numeric array. I will add an error message to catch this :cool:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Dim MyDouble() As REAL8 ; a numeric array
  Dim My$() ; a string array
  For_ ecx=0 To 9
Let My$(ecx)=Str$("This is string #%i", ecx) ; assign strings
  Next
  For_ ecx=0 To 9
PrintLine "[", My$(ecx), "]" ; display them
  Next
  Dim My$(new:99)
  Print Str$("The new array has %i elements\n", My$(?))
  For_ ecx=0 To 9
PrintLine "[", My$(ecx), "]" ; empty strings
  Next
EndOfCode


QuoteThe documentation is so confusing.

Sorry for that... I'm not very good at writing help files, I know. Just ask if you run into a problem.
Title: Re: MasmBasic
Post by: jj2007 on December 10, 2020, 12:26:39 PM
Quote from: 2B||!2B on December 07, 2020, 05:45:16 PM
The new update seems to give errors about unresolved externals. Why?
MasmBasic.lib(LibTmpAC.obj) : error LNK2019: unresolved external symbol _CreateFontIndirectA@4 referenced in function _MbCloseN@0 ...

Does anybody else have such problems? I can't reproduce it here...

Today's update (http://masm32.com/board/index.php?topic=94.0) simplifies the re-dimensioning of string arrays:
include \masm32\MasmBasic\MasmBasic.inc ; download
  Init
  Dim My$() ; create a string array
  For_ ecx=0 To 99
Let My$(ecx)=Str$("String #%i", ecx)
  Next
  Print Str$("This array has %i elements\n", My$(?))
  Dim My$() ; re-dim it
  For_ ecx=0 To 9
Let My$(ecx)=Str$("New string #%i", ecx)
  Next
  Inkey Str$("The new one has %i elements\n", My$(?))
EndOfCode


Output:
This array has 100 elements
The new one has 10 elements


Attached the demo, but with code for a two-dimensional string array
Title: Re: MasmBasic
Post by: 2B||!2B on December 15, 2020, 03:45:43 PM
Hi JJ,

Sorry for the late reply. Yes, i modded some masm32 inc files to remove the duplicate of include of files.
I think that is the cause of this issue. But previous version(not sure which one i currently use as i have no idea how to get the version) is working.
Title: Re: MasmBasic
Post by: jj2007 on December 15, 2020, 08:33:46 PM
Quote from: 2B||!2B on December 15, 2020, 03:45:43 PM
Hi JJ,

Sorry for the late reply. Yes, i modded some masm32 inc files to remove the duplicate of include of files.
I think that is the cause of this issue. But previous version(not sure which one i currently use as i have no idea how to get the version) is working.

That is generally not a good idea, as you are no longer compatible with anybody else in the forum. And to my knowledge, duplicates of include files were never an issue, neither for MasmBasic nor for plain Masm32 SDK code (it shows in the output window if there are any duplicates).

As to the version: all files have a date+time stamp.
Title: Re: MasmBasic
Post by: Richard on March 27, 2021, 04:48:14 AM
Just installed SetUpMasmBasic18Feb2021

My computer has a 3200 x 1800 native display (15 inch) and because many applications require the High DPI resolution - I have to set Windows 10 scaling to 100% (default is 200%).

However, now all the text is "half height" (compared to a standard display)!

The usual windows [Ctrl] +  does not work here to increase text size, and using [Windows Key] + is a "pain" to keep on doing. Because I have applications running in the background needing scaling 100, I do not constantly want to switch scaling 100 to 200 and vice versa.

Any way to increase text size for the IDE etc?
Title: Re: MasmBasic
Post by: jj2007 on March 27, 2021, 05:50:05 AM
Quote from: Richard on March 27, 2021, 04:48:14 AMAny way to increase text size for the IDE etc?

Hi Richard,

Hold Control and move the mouse wheel forward. When you are ok with the font, press Alt Z.

Note this is not possible with the system font; if you encounter a template with that font, press Ctrl A to select everything, then go to the menu "Edit & Format" and select "Proportional". Let me know if it works, please :cool:
Title: Re: MasmBasic
Post by: Richard on March 27, 2021, 06:33:24 AM
@jj2007

Thanks for [Ctrl] mouse wheel  Tip - very helpful for me (eventually will try out template situation).

Now as long as I remember to use [Ctrl] mouse wheel I should be OK (in general)



Problems I have are that

the top row menu options File Edit&Format etc is not permanently visible (sometimes the case)

once I have opened an .asc file (etc) (yellow background) - I cannot seem to be able to get back to the "opening screen" (green background) UNLESS I just reinstall the SetUpMasmBasic

there is an alinement issue in that to get the pull down context menu (eg from File) - the cursor has to be in the right adjacent "Tab Setting"  (refer attachment - the green "crosshairs" show where the cursor has to be to access File options)

Title: Re: MasmBasic
Post by: jj2007 on March 27, 2021, 06:50:39 AM
Quote from: Richard on March 27, 2021, 06:33:24 AM
Thanks for [Ctrl] mouse wheel  Tip - very helpful for me (eventually will try out template situation).

Now as long as I remember to use [Ctrl] mouse wheel I should be OK (in general)

When you press Alt Z, you can make your level of zooming permanent.

Quotethe top row menu options File Edit&Format etc is not permanently visible (sometimes the case)

They should be visible when the window is activated. Can you check that, please?

Quoteonce I have opened an .asc file (etc) (yellow background) - I cannot seem to be able to get back to the "opening screen" (green background) UNLESS I just reinstall the SetUpMasmBasic

- The green background is reserved for the help file ("opening screen"). You can open it from menu File/MasmBasic help.
- Use menu File/New Masm source to create a new project; use the links with white background for the time being.
- When you hover with the mouse over a keyword such as Print, Open, For_ etc, the cursor turns into an arrow with a question mark; right-click to get a greenish box from which you can copy entire snippets.
- there are many keyboard shortcuts (see \Masm32\MasmBasic\Res\Keywords.ini); try typing .rep<space> or opi<space>. You will often need deb4<space> to understand what your code does.

Quotethere is an alinement issue in that to get the pull down context menu (eg from File) - the cursor has to be in the right adjacent "Tab Setting"  (refer attachment - the green "crosshairs" show where the cursor has to be to access File options)

Sorry for that. My noteback has a modest 1366*780 resolution, so I cannot compete with your 3200 x 1800 native display. Aligning the menus was tricky, so I can't promise anything in the near future. The same applies for other elements that are not DPI aware, such as the bookmarks to the right.
Title: Re: MasmBasic
Post by: Richard on March 27, 2021, 02:04:43 PM
@jj2007

Quote
Quote
the top row menu options File Edit&Format etc is not permanently visible (sometimes the case)
[
They should be visible when the window is activated. Can you check that, please?

IF I (left or right) Click in the

" File Edit ... AutoCode"  region    lets call this region = "..." here and call this clicking = "stray mouse click"

then "..." disappears BUT returns again IF I immediately "valid mouse click", with or without moving mouse!


So as long as I do not "stray mouse click", but "hover" instead, then that stops the disappearing (of course, as mentioned by you, if I go to another application meaning RichMasm is not active = "..." disappear but returns immediately when click in RichMasm background to make RichMasm active)

So NOT really a problem of disappearing "..." , just only needs a bit of getting used to (as all other applications I use NEVER disappear their "..." region for "stray mouse clicks" in the "..." region, also other applications never disappear "..." when temporarily leaving but application still visible in multi window)

Thanks for your explanation.
Title: Re: MasmBasic
Post by: Richard on April 04, 2021, 04:46:07 PM

Just getting some practice before I start writing my own code. I tried the following example (first time for examples) and F6 gave the following error.

I may have some residual MASM5.1 (and more recently MASM 6) stuff floating around - so before I start changing/deleting things I better ask! Note that ALL my MASM5.1 (+ MASM 6) stuff existed before I ever heard about RichMasm and MASM32 SDK.


*** Start C:\Masm32\MasmBasic\Res\bldallRM.bat ***
*** 32-bit assembly ***


*** Assemble, link and run SkelTimer ***

*** Assemble using ml  ***
Assembling: tmp_file.asm
##########################

You CANNOT use the MasmBasic library with
the old ml.exe version 6.14 - use UAsm instead

##########################
*** MasmBasic version 18.02.2021 ***
*** Warning: SQWORD is unsigned with ml **
\masm32\MasmBasic\MasmBasic.inc(728) : error A2052: forced error
TestMasmVersion(8): Macro Called From
  \masm32\MasmBasic\MasmBasic.inc(728): Include File
*** Assembly error ***

Title: Re: MasmBasic
Post by: jj2007 on April 04, 2021, 07:11:48 PM
Hi Richard,

how did you force RichMasm to use ML? With OPT_Assembler ml? The error message is clear, MasmBasic won't accept the old assembler, for good reasons. So if \Masm32\bin\ml.exe is an old version, you get that message.

By default, RichMasm wants ?:\Masm32\bin\UAsm64.exe, but with e.g. ; OPT_Assembler AsmC you can work with another one.

Do you have the latest UAsm, see http://www.terraspace.co.uk/uasm.html#p2, to be extracted as \Masm32\bin\UAsm64.exe?

I have no experience with any pre-MASM 6.14 code, can you post a short example? Perhaps I can make it run...
Title: Re: MasmBasic
Post by: Richard on April 05, 2021, 12:54:50 AM
@jj2007

Thanks for reply - would have answered sooner (for some reason your email ended up in junk mail and so did not know).

Refer attachment

All I wanted to do was to try programs from the forum (refer last two images) to gain a bit of practice (with code that works) before trying out my original code.

(Keeping in mind that I am still getting used to my 3200x1800 display in high DPI mode (scaling 100) and as you mentioned only some parts I can scale up (to be readable) with Ctrl Mouse  wheel but system fonts can not be.  So the "mixed sizes" is OK (needs getting used to) but until I practice a lot more, it is easy for me to accidently click in error. Also, I am getting used to selection from top menu bar is not aligned to context columns (as you acknowledged earlier - it is very tricky to code especially when one (you) does not have a high DPI display.

First, just for fun, I wanted to try out the unicode ascii file program - loaded the .asc file from the forum and pressed F6 (not adjusting any settings or anything). A black DOS-like command screen appeared and a little pop-up window saying something to the effect that if some unicode characters do not appear correctly ... then to try Lucinda Console (or something similar sounding). So I immediately went to Settings>Personalize>Fonts> and selected Lucinda Console. I returned to the unicode program console window - but it looked like something "locked up" with it - so I tried to completely close down the program (and RichMasm) but no response. Not even Windows Task Manager OR Task Bar could close it! I could not even move that window around (out of the way of other applications running). "a.asc" was just a temporary "save" just to allow from earlier on, to close RichMASM application - I was not actually wanting to do anything with a.asc - just to close off RichMASM (I got confused with something earlier - so best to start with a "clean slate").  RichMASM locked up with the first image window (keep in mind I was trying to click my way out - so who knows what I may have triggered off.

So I SHUTDOWN my computer, checked that the Lucina Console font was active (according to windows), launched RichMASM and opened up Unicode_File_Names.asc and so the Unicode_File_Names.asc appeared to work OK (just pressing F6 in RichMASM IDE).

I went to the second example program SkelTimer.asc and pressed F6 and the error message as above appeared.

So the "lock up" confused me, I probably did some wrong key presses trying to exit. (I think maybe changing the font and not restarting first also added to the confusion).

I was not attempting to load any old MASM (5 and 6) stuff - however they are still lingering around (maybe I should permanently remove - since I am no longer using DOSBOX and MASM5.1 (RichMASM has "spoilt me")). However it is quite possible that some directories (eg MASM) is loaded up with MASM5.1 stuff and MASM32 SDK stuff etc (I have not checked out for this double useage of directory).

I hope you have enough info from me to see what went wrong - I do not think there is anything wrong with RichMASM.
Title: Re: MasmBasic
Post by: jj2007 on April 05, 2021, 02:05:17 AM
Hi Richard,

I can't solve the font problems for anything outside the main editor window (listbox, Find+Replace, bookmarks etc) for the time being. Regarding the main editor window, you already know the mouse wheel trick, and I suppose you hit Alt Z to save the zoom level. One more hint: There are templates that use the System font, which is not zoomable; press Ctrl A to select the whole text, then Ctrl L twice. This changes the whole text to a zoomable flavour. Ctrl Shift L selects an extra large text btw - I use that for macro and proc names.

Re freezing: I've experienced that in recent months, and the culprit is Firefox in my case. It happens after a long (5-10 hours) session, and it freezes indeed everything. Normally it goes away after a few minutes. I doubt that RichMasm has any role in it, as its memory usage is tiny compared to a browser.

Thanks a lot for your feedback :thup:
Title: Re: MasmBasic
Post by: Richard on April 05, 2021, 02:52:37 AM
Thanks for reply.

I understand and appreciate re sizes - that is a major reason why I want to "practice" with code that works, so to get "used to" and be "comfortable with" with everything.

I use windows 10 x64 build 2H20 and all sorts of "weird things" quite often happen - the latest is that for a few months now, when I run my computer for a long time (1-3 days continuously) number crunching - I will most likely get a "black screen" , no mater what I try and screen won't come back (and my programs are still running). In these cases I have to press and hold the power key for 10 seconds (the most drastic shutdown procedure).

On this occasion, my computer has been running about 2 days (and the black screen not yet occurred) - so maybe changing the font really really messed up windows).

I will "sleep over it" and start from scratch re example programs before I will download any UASM stuff (I am not planning on going "backwards" (from RichMASM) so after a lot more practice with examples from this forum and RichMASM then will try my own code writing solely using your IDE and F6.

Just a side note, if you don't mind me asking, are you "in the know" about - GNU gcc, Intel syntax versus AT&T syntax, Geany. The reason why I ask is that once I get relatively small and simple sounding MASM projects up and going (in RichMASM) - that I will port the code into a (other) High level language via include files but the preferred way is via gcc and at that using intel syntax (my ultimate aim, the "other" high level language occupies 99% of code but that code only does 1% of the work, the assembly code (technically not really "in-line assembly") occupies 1% of the code but does 99% of the work (and probably much faster)) 
Title: Re: MasmBasic
Post by: jj2007 on April 05, 2021, 03:14:26 AM
Quote from: Richard on April 05, 2021, 02:52:37 AMJust a side note, if you don't mind me asking, are you "in the know" about - GNU gcc, Intel syntax versus AT&T syntax, Geany. The reason why I ask is that once I get relatively small and simple sounding MASM projects up and going (in RichMASM) - that I will port the code into a (other) High level language via include files but the preferred way is via gcc and at that using intel syntax (my ultimate aim, the "other" high level language occupies 99% of code but that code only does 1% of the work, the assembly code (technically not really "in-line assembly") occupies 1% of the code but does 99% of the work (and probably much faster))

That's a matter of taste. I don't like C/C++, and I can produce what I need much faster with Basic syntax. I've tried FreeBasic, but it's an awful mess of "toolchains" and "backends", and on the FB Forum 90% of the discussion is about problems compiling some code with the Gas, Gcc, whatever backend. No thanks. In Assembly, the number of instructions is limited, and the machine does exactly what I tell it to do :cool:

Try doing this in C or C++ (you can drag a .txt, .asm, .rtf or .asc file over the exe):
GuiParas equ "Controls", xr20, w500, h200, icon Info, bBlue, m7
GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste
include \masm32\MasmBasic\Res\MbGui.asm
  GuiControl MyEdit, "RichEdit", wCL$()
  GuiControl MyStatus, "statusbar", "Hello"
Event Command
  If_ NotifyCode==BN_CLICKED Then SetWin$ hMyStatus=Str$("Button or menu #%i clicked at ", MenuID)+fTime$(0)
GuiEnd
Title: MasmBasic updated
Post by: jj2007 on February 18, 2022, 12:40:48 PM
After exactly one year, MasmBasic was updated today (http://masm32.com/board/index.php?topic=94.0). Inter alia, the StackWalk and profiling macro (http://masm32.com/board/index.php?topic=9854.msg108113#msg108113) might be interesting for members with somewhat bigger projects.
Title: Re: MasmBasic
Post by: jj2007 on February 20, 2022, 01:05:23 PM
Version 20 February (http://masm32.com/board/index.php?topic=94.0) has one small change against version 18 February:

- with e.g. Declare SomeFunction, 2 passing a string and an immediate as in SomeFunction("Test", 123.456)
  will pass a REAL4 as second argument; to force a double, use SomeFunction("Test", REAL8:123.456)


In the new versions, the editor RichMasm has built-in profiling:
- press F9
- hold Ctrl
- click "No"
Title: Re: MasmBasic
Post by: jj2007 on March 12, 2022, 01:55:48 PM
Version 12 March is online, now with almost 500 commands.

GuiParas equ "Rtf viewer", w700, h600, m0, b none, icon Butterfly      ; position, margins, background colour
include \masm32\MasmBasic\Res\MbGui.asm
  GetFiles *.as?|*.rtf|*.inc    ; load whatever fits your needs
  SortFiles name                ; could be also date (recent on top) or size (big ones on top)
  GuiControl MyList, "listbox", Files$(), x=1000-120, w=0+120   ; leave some space to the right
  GuiControl MyEdit, "RichEdit", FileRead$(Files$(0)), bcol RgbCol(120, 120, 120), fcol White, w1000-120, font -14:FW_SEMIBOLD
  GuiControl MyStatus, "statusbar", wRec$("Started "+fTime$())

Event Command
  .if NotifyCode==LBN_SELCHANGE
     SetWin$ hMyEdit=FileRead$(LbSel$)       ; load selected file into the RichEdit control
     SetStatus$ Cat$("Current file: "+LbSel$+Str$(", %i bytes", LastFileSize)+", created "+GfDate$(-1))
  .endif
GuiEnd


Among the improvements is the option to give a foreground colour also to a RichEdit control (see attached source and exe):

GuiControl MyEdit, "RichEdit", FileRead$(Files$(0)), bcol RgbCol(120, 120, 120), fcol White,

This is a tricky business, because it works fine with a plain text file loaded into the RichEdit control, but what about RTF files? They have their own text colours stored in the file, but they don't have a background colour unless you explicitly apply it in your RTF editor, such as RichMasm (http://masm32.com/board/index.php?topic=5314.0) or WordPad.

So what happens is that you tell the control "I want white text on dark background", and that works fine for plain text, but if you load a RTF file, you are stuck with the text colours chosen by the file's author. Which might be, ehm, black... :cool:

Btw the RichEdit control checks automagically if an MS Office versions of RichEd20.dll is installed on your machine. If so, it loads RTF files a factor 20-30 faster than the standard RichEd20 in Windows\System32. That doesn't matter if your files are tiny, but when they approach the megabyte range, it surely makes a big difference. The RichMasm source, for example, with 1.4 MB, loads in less than a second on my trusty old Core i5.

You don't need MS Office to get the fast DLLs: the old Microsoft Office Compatibility Pack for Word, Excel, and PowerPoint (https://filehippo.com/download_microsoft_office_compatibility_pack_for_word_excel_and_powerpoint_file_formats/) installs them for free. Same for the Word viewer (https://filehippo.com/download_word-viewer/), I suppose.

Test it yourself: Extract the exe to a folder that has both *.rtf (or *.asc) files and plain text, such as *.asm and *.inc.
Title: Re: MasmBasic
Post by: HSE on March 12, 2022, 02:53:19 PM
Hi JJ!

Too much talk. What you maked?
Title: Re: MasmBasic
Post by: jj2007 on March 12, 2022, 07:59:55 PM
Quote from: HSE on March 12, 2022, 02:53:19 PM
Hi JJ!

Too much talk. What you maked?

What did I do to make the fcol White work?
- SetWin$ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1092) checks if the control is a RichEdit control (GuiControl (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1304) can be almost every Windows control)
- if so, it checks for the \rtf string at the start of the file to be read in
- if it's plain text, it sends an EM_SETCHARFORMAT message

Then there is a MbLoadRich proc that checks for the presence (in this order) of...
- RichEd20.dll in the executable's folder
- %CommonProgramFiles%\Microsoft shared\Office11\RichEd20.dll
- %CommonProgramFiles%\Microsoft shared\Office12\RichEd20.dll
- %WinDir%\System32\RichEd20.dll

You can force another version using mov RichEditUsed, <path>, and you can check which version was used with a...

  MsgBox 0, RichEditUsed, "Your Dll:", MB_OK

... before the Event Command (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1395). Simple, right? It can be even simpler; this is a full-fledged rtf viewer in three lines (see CL$() (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1011)):

include \masm32\MasmBasic\Res\MbGui.asm
  GuiControl MyEdit, "RichEdit", FileRead$(CL$()), bcol Black, fcol White
GuiEnd
Title: Re: MasmBasic
Post by: HSE on March 13, 2022, 12:29:58 AM
 :thumbsup:  Thanks.

I'm developing a different approach for small files.
Title: Re: MasmBasic
Post by: jj2007 on May 12, 2022, 01:58:10 AM
MasmBasic version 11 May 2022 is online (http://masm32.com/board/index.php?topic=94.0). Mostly minor cosmetics, but there are also some significant changes under the hood:

1. Str$(someDword) (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1186) has become blazingly fast, see The joy of beating the CRT by a factor 10 (http://masm32.com/board/index.php?topic=10037.0) in the Laboratory.

2. Same for Instr_(haystack, needle) (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1153) - it beats the Boyer-Moore algos now most of the time (http://masm32.com/board/index.php?topic=10040.msg109942#msg109942) (and CRT strstr by a factor 10) :cool:

3. MasmBasic's editor RichMasm (part of the package) now supports Hutch' brand new Masm64 SDK (http://masm32.com/board/index.php?topic=10052.0). Just open a source, e.g. \Masm64\Examples\Advanced\JpgTool\JpgTool.asm and hit F6 :thumbsup:

Feedback please, I need to know when things don't work  :biggrin:

P.S.: I made some minor changes today. You have the correct version if the zip file is named SetupMasmBasic11May.zip, and there is a link to the Masm64 SDK in the MasmBasic help file at the top of the second "Hello World" example:

include \masm32\MasmBasic\Res\JBasic.inc        ; instead of JBasic, you might try the Masm64 SDK
Title: Re: MasmBasic
Post by: jj2007 on May 20, 2022, 10:12:02 AM
MasmBasic version 20 May 2022 is online (http://masm32.com/board/index.php?topic=94.0). Significant changes:

- RichMasm handles better the case that you "forgot" an active program, e.g. by not answering to an Inkey ("hit any key"); it will present a MessageBox asking if you want to kill the current instance before building the new version.

- improved cycle count macros:

  include \masm32\MasmBasic\MasmBasic.inc
  Init
  CyCtInit
  CyCtStart
        fldpi
        fmul FP8(100.0)
        fdiv FP4(10.0)
        fstp st
  CyCtEnd PI*100/10             ; describe what the code does
  EndOfCode


- output is e.g. 17 Cycles for PI*100/10
- without description after CyCtEnd, 1,000 individual cycle counts are accessible through the CyCt() DWORD array
- using CyInit store, the counts are saved to the CyCt$() array (see Store (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1174) for saving the array to disk)
Title: Re: MasmBasic
Post by: jj2007 on May 31, 2022, 06:23:13 PM
Version 30 May 2022 is online, with several minor improvements, inter alia of NoTag$ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1077)():

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  FileWrite "test.tab", NoTag$(Clip$())         ; get html from the clipboard, convert to plain text
  ShEx "test.tab"                               ; launch the application associated with *.tab (often Excel)
EndOfCode


Source & exe attached. To test it,
- go to a site that has tables, e.g. https://www.tiobe.com/tiobe-index/ or http://masm32.com/board/index.php?action=stats
- press Ctrl U to see the html source
- press Ctrl A, Ctrl C to copy the source
- launch the attached executable

The output file test.tab will open e.g. in Excel. On my machine, it will look like this:

(https://www.jj2007.eu/pics/HtmlTableFromClipboard.png)

As you can see, row #5 is slightly off - sometimes the tab files may require some editing. Another example, exported from https://www.stackscale.com/blog/popular-programming-languages-2021/ and imported into M$ Excel:

(https://www.jj2007.eu/pics/HtmlTableFromClipboard2.png)

I attach a sample tab file extracted from WorldoMeters (https://www.worldometers.info/co2-emissions/co2-emissions-per-capita/). Most Wikipedia tables should work, too - please inform me if you find one that doesn't. Note it will not work on sites that use scripts to generate tables, such as this World Bank page (https://data.worldbank.org/indicator/EN.ATM.CO2E.PC).

The ancient Internet Explorer used to have the option to export a table; no idea why they abolished it :cool:
Title: MasmBasic updated, with some new features
Post by: jj2007 on October 02, 2022, 10:25:53 AM
Version 2 October is online (http://masm32.com/board/index.php?topic=94.0) :biggrin:

It's over 500 macros now. Here are the additions since November 2020:
SetLaunchEnvironment
Ini$
Cls
_Passed$
Arctangens
rTangens
Tangens
rCotangens
Cotangens
ArcSinus
rArcSinus
Cosinus
rCosinus
Tangent
FontExist
WinByClass
WinFromID
WinFromID$
MbProfile
WarmUp
CyCtInit
CyCtStart
CyCtEnd
SetWatch
swShow
swEnd
StackWalk
SWalkP
SWalkE
@FP4
@FP8
@FP10
GuiImageSet


With a handful of exceptions, they are documented in \Masm32\MasmBasic\MbGuide.rtf; search e.g. for .MbWinByClass

The most recent addition are coloured pushbuttons:
GuiParas equ "Colourful buttons", w320, h110 ; 32% of window width, 11% of height
; GuiButtonPen equ <MakePen MbBtnPen, RgbCol(128, 255, 255, 255), width 3> ; white, half transparent
include \masm32\MasmBasic\Res\MbGui.asm ; select GuiParas and hit F6
  GuiControl Button1, "button", "That's a normal pushbutton", w250, h0+40 ; width 25% of client area, height 0%+40px
  GuiControl Button2, "button", "Lite Turquoise"/"Blue", bcol LiteBlueGreen/Blue, x250, w250, h0+40, font -14
  GuiControl Button3, "button", "Lite Yellow"/"Full Yellow", bcol LiteYellow/Yellow, fcol Red/Black, x500, w250, h0+40, font -14:FW_BOLD
  GuiControl Button4, "button", "Rounded button", bcol LiteGrey/Red, fcol Black/White, rr40, x750, w250, h0+40, font -12:FW_SEMIBOLD
GuiEnd

Rem To define a button, use:
- x, y, w, h for its position, followed by n 1000th of the window width or height
- bcol RgbCol(...) to define the background colour; bcol Blue/Red means "blue, but red if pressed"
- fcol Black/White to define the foreground (text) colour; white if pressed
- "normal text"/"pressed text"
- rr0=no rounded corners, rr100=a circle; use guiRoundRect=n to set the default rounding
- you may define a pen: put GuiButtonPen before the include line


With 7 lines of code, you can create this:

(http://www.jj2007.eu/pics/ColouredButtons.png)

These buttons require an XP manifest, as shown in the attachment. When you size the window, the buttons size horizontally but not vertically, due to the w250, h0+40.

If you zoom in the image below, you may notice that the buttons' borders use antialiasing: under the hood, Gdi+ is at work.
Title: MasmBasic updated
Post by: jj2007 on November 15, 2022, 11:01:21 PM
MasmBasic version 15 Nov 22 is online (http://masm32.com/board/index.php?topic=94.0). The included RichMasm editor will now colourise plain text asm sources to a certain extent, like in this example from \Masm32\examples\threads\multhread\multhrd.asm:

WndProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD

    LOCAL tID    :DWORD

    Switch uMsg
      Case WM_COMMAND
        Switch wParam
          Case 50
          ; ------------------------------------
          ; loop through starting 10 new threads
          ; ------------------------------------
            push esi
            push edi
            xor esi, esi
            xor edi, edi
          @@:
            add esi, 25
            add edi, 1
            fn CreateThread,0,0,ADDR CreateNewThread,esi,0,ADDR tID
            cmp edi, 10
            jl @B
            pop edi
            pop esi

          Case 51
          ; ----------------
          ; close all thread
          ; ----------------


All push arg and pop arg instructions are highlighted in red. Jumps to @@: labels are red for @B and blue for @F. Such a few red spots can help to recognise, for example, problems with stack balance. I am not a fan of Christmas trees aka automatic highlighting of each and every little feature, but I do use manual colouring in my sources, especially when doing little tricks, see below.

When saving the source code in RTF format (as *.asc), these changes are permanent.
Title: Santa Claus edition is online
Post by: jj2007 on December 06, 2022, 11:18:30 AM
Install the latest MasmBasic version (http://masm32.com/board/index.php?topic=94.0) to get access to over 500 powerful macros, and in case you want to build the Simple Editor (http://masm32.com/board/index.php?topic=10401.msg116252#msg116252). Latest items:

Guid$():
Let edi=Guid$()
MsgBox 0, Cat$("A Guid: ["+edi+"]"), "Hi", MB_OK


Output: A Guid: [d6e3dc8a-f76a-4ec2-9163-65f8bdd0138f] (plus a pointer to the GUID itself in edx)

xCall for passing arguments to a label, invoke style:
include \masm32\MasmBasic\MasmBasic.inc
.code
somelabel:
mov ecx, [esp+4]
MsgBox 0, ecx, "Hi", MB_OK
retn 4
Init
xCall somelabel, Chr$("Hello World")
EndOfCode


MsgBox: see http://masm32.com/board/index.php?topic=10530.msg116251#msg116251, the new MsgBox will not make your controls lose the focus.
Title: Re: MasmBasic
Post by: jj2007 on December 07, 2022, 03:38:35 AM
I forgot this one: CenterWindow hWnd_, 400, 200  ; 400px wide, 200px high, right in the middle
Title: Re: Santa Claus edition is online
Post by: LiaoMi on December 08, 2022, 05:12:12 AM
Quote from: jj2007 on December 06, 2022, 11:18:30 AM
Install the latest MasmBasic version (http://masm32.com/board/index.php?topic=94.0) to get access to over 500 powerful macros, and in case you want to build the Simple Editor (http://masm32.com/board/index.php?topic=10401.msg116252#msg116252). Latest items:

Guid$():
Let edi=Guid$()
MsgBox 0, Cat$("A Guid: ["+edi+"]"), "Hi", MB_OK


Output: A Guid: [d6e3dc8a-f76a-4ec2-9163-65f8bdd0138f] (plus a pointer to the GUID itself in edx)

xCall for passing arguments to a label, invoke style:
include \masm32\MasmBasic\MasmBasic.inc
.code
somelabel:
mov ecx, [esp+4]
MsgBox 0, ecx, "Hi", MB_OK
retn 4
Init
xCall somelabel, Chr$("Hello World")
EndOfCode


MsgBox: see http://masm32.com/board/index.php?topic=10530.msg116251#msg116251, the new MsgBox will not make your controls lose the focus.

Hi jj2007,

Bad DLL for R? - msftEdit.dll
Title: Re: MasmBasic
Post by: jj2007 on December 08, 2022, 08:41:34 AM
Hi LiaoMi,

On my Win7-64, C:\Windows\System32\msftedit.dll accepts only RichEdit50W RichEdit60W as well as RichEdit20W. Which Windows version are you running?

Can you do me favour and test the attached version, which does an extra check? If you get it running, please hit F9 and give me the RichEdit??W version. Thanks :thup:
Title: Re: MasmBasic
Post by: TimoVJL on December 08, 2022, 10:07:29 AM
My windows 7 x64 msftedit use RichEdit50W
File version: 5.41.21.2510
Inside dll is UNICODE string RichEdit50W
Title: Re: MasmBasic
Post by: jj2007 on December 08, 2022, 11:39:46 AM
Quote from: TimoVJL on December 08, 2022, 10:07:29 AM
My windows 7 x64 msftedit use RichEdit50W
File version: 5.41.21.2510
Inside dll is UNICODE string RichEdit50W

RichEdit is driving me mad!

00000000        RichEdit20W
Impossibile trovare la classe della finestra.

001603E0        RichEdit50W
Operazione completata.

00000000        RichEdit60W
Impossibile trovare la classe della finestra.

00000000        RichEdit20A
Impossibile trovare la classe della finestra.

00000000        RichEdit50A
Impossibile trovare la classe della finestra.


Fun fact: RichMasm.exe runs just fine with RichEdit60W... and I just found out why - it loads the Office12 variant present on my machine :rolleyes:

Testbed attached, pure Masm32 SDK :cool:
Title: Re: MasmBasic
Post by: LiaoMi on December 09, 2022, 10:11:32 AM
Quote from: jj2007 on December 08, 2022, 08:41:34 AM
Hi LiaoMi,

On my Win7-64, C:\Windows\System32\msftedit.dll accepts only RichEdit50W RichEdit60W as well as RichEdit20W. Which Windows version are you running?

Can you do me favour and test the attached version, which does an extra check? If you get it running, please hit F9 and give me the RichEdit??W version. Thanks :thup:

Hi jj2007,

I have windows 10 Ent 21h1  :rolleyes:

---------------------------
RichMasm editor version 07.12.2022, built with UAsm64:
---------------------------

RichEdit20W of msftEdit.dll, ComCtl32 version 6.16
---------------------------
Yes   No   Cancel   
---------------------------
Title: Re: MasmBasic
Post by: jj2007 on December 09, 2022, 11:25:07 AM
Thanks a lot, LiaoMi :thup:
Title: Re: MasmBasic
Post by: zedd151 on June 21, 2023, 03:35:20 AM
Well MasmBasic (3March23) installed okay. But upon running RichMasm:
'Compatibilty Options' (Exporer Right Click)  did nothing to help resolve this. AVX code there I suppopse?
No AV software btw.
Have a recommendation for previous version that *might* work for me here?


Attached image removed as it has served its purpose.
Title: Re: MasmBasic
Post by: jj2007 on June 21, 2023, 04:18:47 AM
Quote from: zedd151 on June 21, 2023, 03:35:20 AM
Well MasmBasic (3March23) installed okay. But upon running RichMasm:
'Compatibilty Options' (Exporer Right Click)  did nothing to help resolve this. AVX code there I suppopse?
No AV software btw.

Have a recommendation for previous version that *might* work for me here?

This is the SSE 4.2 problem, sorry. Can you please run the attached test?
Title: Re: MasmBasic
Post by: zedd151 on June 21, 2023, 04:23:29 AM
Thanks for the reply. Not really urgent for me, was only going to play around with it for a bit - but for compatibility for other users might be a good idea at least to have a separate (dumbed down lol) version for users with same CPU issues ( old as dirt computer/CPU that is) and still keep the presumably high powered version for users with more modern hardware.
Title: Re: MasmBasic
Post by: zedd151 on June 21, 2023, 05:50:26 AM
Quote from: jj2007 on June 21, 2023, 04:18:47 AM
Can you please run the attached test?
Old cpu
MessageBox:
eax       7139135


:cool:
Title: Re: MasmBasic
Post by: jj2007 on June 21, 2023, 06:09:32 AM
Ok, bug found. It is more complicated than I thought, though. Please extract the attached exe as \Masm32\MasmBasic\RichMasm.exe and launch it. That should work fine, but it's a debug edition.
Title: Re: MasmBasic
Post by: zedd151 on June 21, 2023, 06:28:20 AM
Quote from: jj2007 on June 21, 2023, 06:09:32 AM
That should work fine, but it's a debug edition.
Yerp, it appears to be working alright.


Building an example there prompts to install Uasm64? hrumph ... okay I see the examples in Masm64 folder. lol I don't have Masm64 on this OS, its 32 ...  :biggrin:
Title: Re: MasmBasic
Post by: zedd151 on June 21, 2023, 06:30:52 AM
Quote from: jj2007 on June 21, 2023, 06:29:39 AM
It expects to find \Masm32\bin\uasm64.exe
Well crap. Lemme through 64 bits into another partition.... will only take a few minutes ...
Title: Re: MasmBasic
Post by: zedd151 on June 21, 2023, 06:36:15 AM
Okee dokee Windows 10- 64 is being installed as I speak... takes a while longer than plonking a fresh copy of Windows 7 into the box.
Title: Re: MasmBasic
Post by: jj2007 on June 21, 2023, 06:38:18 AM
You install Win10? That's an overkill, my friend...

No need for a Masm64 folder, it works fine with what you have already. However, it expects \Masm32\bin\UAsm64.exe, and I just see that you have a 32-bit OS :rolleyes:

Solution: make a copy of your UAsm32.exe and call it UAsm64.exe :cool:

https://www.terraspace.co.uk/uasm.html#p2 is the download link, in case you don't have UAsm at all. You need the 32-bit version, and it must be renamed to UAsm64.exe to work. That's a bug or a missing feature with RichMasm, because I haven't seen a 32-bit Windows version for quite some time ;-)
Title: Re: MasmBasic
Post by: zedd151 on June 21, 2023, 06:41:24 AM
Yup, I install w10  (from disk image backup) only when needed. I cannot find atm the image for 7/64...  :biggrin:
Title: Re: MasmBasic
Post by: zedd151 on June 21, 2023, 07:02:03 AM
Had to go and walk the dog while reinstalling Win 10. But I got er done.  :biggrin:
Aw, c'mon now... polink???  :tongue:  Lemme fetch a copy  :rolleyes:
Title: Re: MasmBasic
Post by: zedd151 on June 21, 2023, 07:18:50 AM
Alright everything is working okay here now.  :biggrin:  If I can only remember now, what file I wanted to look at that was a MB (asc) source.  :tongue:
RichMasm seems a bit 'busy' for my taste - btw.

I am going to make a backup copy (of the partition) with the MasmBasic Dev environment set up in it. Just in case the need for it ever arises. I know that at times, you post some interesting sources... now I'll head back over to Windows 7   :cool:


Okay, now I am back on Windows 7  :biggrin: . How would I configure RichMasm to better suit my needs, as far as appearance, fonts, etc?
Title: Re: MasmBasic
Post by: jj2007 on June 21, 2023, 09:58:50 AM
- For fonts, check FaceSrc=... etc in \Masm32\MasmBasic\Res\RichMasm.ini (may be overwritten at next install, so save a copy)
- You can zoom the font with Ctrl + mousewheel. Save your setting with Alt Z
- Press Ctrl G, then type behind the Goto: prompt udc=n, where n=0...9

Quote from: zedd151 on June 21, 2023, 07:18:50 AMRichMasm seems a bit 'busy' for my taste

I don't understand - what do you mean?
Title: Re: MasmBasic
Post by: zedd151 on June 21, 2023, 10:02:54 AM
Quote from: jj2007 on June 21, 2023, 09:58:50 AM
- For fonts, check FaceSrc=... etc in \Masm32\MasmBasic\Res\RichMasm.ini (may be overwritten at next install, so save a copy)
Oh, there's an ini file. I missed that. I'll take a look at this later...
Title: CreateAndSelect
Post by: jj2007 on June 24, 2023, 11:25:51 PM
Hi Z,

New version (http://masm32.com/board/index.php?topic=94.0) should fix all your issues:
- accepts \Masm32\bin\UAsm32.exe
- uses the old Instr() algo if the Cpu is below SSE 4.2

Plus, it has a new macro (heavily inspired by NoCForMe - thanks :thup:):

DrawMyRect proc hDC
Local hBrush, whatever
  CreateAndSelect(hDC) ; one arg: set the DC (right after the locals)
  mov hBrush, CreateAndSelect(brush, Blue) ; the hBrush is not really needed
  invoke Rectangle, hDC, 3, 3, 202, 78
  void CreateAndSelect(brush, LiteYellow)
  invoke Rectangle, hDC, 9, 9, 196, 72
  invoke SetBkMode, hDC, TRANSPARENT
  casThrowErrors=1 ; now try bitmap instead of font v v v
  void CreateAndSelect(font, addr MyFont)
  invoke TextOut, hDC, 20, 18, fTime$(), 9
  ReleaseObjects ; no leaks please ;-)
  ret
DrawMyRect endp


First argument of CreateAndSelect can be bitmap, brush, font or pen (case-insensitive).

Project attached.
Title: Re: CreateAndSelect
Post by: zedd151 on June 24, 2023, 11:46:07 PM
Quote from: jj2007 on June 24, 2023, 11:25:51 PM
Hi Z,

New version (http://masm32.com/board/index.php?topic=94.0) should fix all your issues:
Project attached.
You really didn't have to, but thanks. As said before I will look at MasmBasic later on, when I have enough time to delve in to the macros there and other 'masm basic' specifics. It's like learning a new language (probably like Mandarin  :greensml: ) either way it's mostly Greek to me at this point. Will take some time...  :cool:
Title: Re: CreateAndSelect
Post by: zedd151 on June 24, 2023, 11:50:11 PM
Quote from: jj2007 on June 24, 2023, 11:25:51 PM
Project attached.
57 kb example exe?  :dazzled:  How big is the runtime library contained within?  :tongue:
It works as advertised of course, and no leaks. Surely I have adequate memory for this behemoth example.  :biggrin:
Title: Re: CreateAndSelect
Post by: jj2007 on June 25, 2023, 12:29:57 AM
Quote from: zedd151 on June 24, 2023, 11:46:07 PMIt's like learning a new language

It adds macros and routines to Masm32. Practically all the sources in \Masm32\Examples build fine by simply hitting F6 in RichMasm. It's a bit like moving from "old" assembly to SIMD assembly - you add new features.

Quote from: zedd151 on June 24, 2023, 11:50:11 PM
Quote from: jj2007 on June 24, 2023, 11:25:51 PM
Project attached.
57 kb example exe?  :dazzled:  How big is the runtime library contained within?  :tongue:
It works as advertised of course, and no leaks. Surely I have adequate memory for this behemoth example.  :biggrin:

\masm32\MasmBasic\Res\MiniWin.asc builds a 34kB exe, which is about the minimum. That's a lot compared to the 1,024 bytes examples, but it also means features such as Recall (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1172).

For comparison, a standalone QT "hello World" is 8MB :cool:
Title: Re: CreateAndSelect
Post by: zedd151 on June 25, 2023, 12:35:18 AM
Quote from: jj2007 on June 25, 2023, 12:29:57 AM
For comparison, a standalone QT "hello World" is 8MB :cool:
:rofl:  okay, good point.  :biggrin:
Still, it will take me some time to digest all of the 'new' things there. In due time...
I've installed the latest version of MasmBasic (I thought I'd never say that again  :tongue: )  , Uasm and put polib back into the bin folder.
Succesfully assembled an example from Masm32 SDK examples. :thumbsup:

'Select proc or macro' does not select proc or macro.   :tongue:  I wanted to see that work, since you had mentioned that recently.

Quote from: jj2007 on June 22, 2023, 03:50:50 AM
Quote from: zedd151 on June 22, 2023, 12:48:48 AMto right click a selected procedure name anywhere in the source and click 'go to procedure' or 'select procedure'. 


I can confirm that this is a very useful feature
Title: Re: CreateAndSelect
Post by: jj2007 on June 25, 2023, 12:59:04 AM
Quote from: zedd151 on June 25, 2023, 12:35:18 AM'Select proc or macro' does not select proc or macro

You must select the word proc or the word macro, then you right-click.

Another minor "bugfix" (it's not a bug, actually) concerning Instr_(haystack, needle) (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1153):
.if Instr_(esi, "test")
  ...


That always worked fine. However, the old "below SSE 4.2" algo returned, if nothing was found, a pointer in eax. So, if you were clever and used, for some odd reason...
void Instr_(esi, "test")
.if eax
  ...

... that gave the wrong answer, because the found/not found is being returned in edx, while eax points at the result if one is found. In the previous version, eax pointed at haystack-1 if nothing was found, so .if eax failed. I fixed it, now eax is zero for no match.
Title: Re: CreateAndSelect
Post by: zedd151 on June 25, 2023, 01:10:12 AM
Quote from: jj2007 on June 25, 2023, 12:59:04 AM
Quote from: zedd151 on June 25, 2023, 12:35:18 AM'Select proc or macro' does not select proc or macro

You must select the word proc or the word macro, then you right-click.
Okay, only works some of time...
in attached example displays error "not found:      endp"
selecting 'proc' for WndProc for example.
edit=removed attachment as it has served its purpose.
Title: Re: MasmBasic
Post by: jj2007 on June 25, 2023, 01:14:13 AM
I see; it's a coding style issue: you leave four spaces before WinMain proc and WinMain endp. The algo expects
WinMain proc
...
WinMain endp


Sorry, it won't work for you. For consistency, I never leave spaces before the xxx proc or the xxx macro. Inside macros, when there is more than one ENDM, only the last one has no spaces.

Do your 4 spaces serve a specific purpose?
Title: Re: MasmBasic
Post by: zedd151 on June 25, 2023, 01:17:53 AM
Of course, formatting. I detest hard tabs.  :tongue: 
okay then, I'll keep this in mind if selecting a procedure or macro comes up in a real situation.
Title: Re: MasmBasic
Post by: jj2007 on June 25, 2023, 01:20:50 AM
Quote from: zedd151 on June 25, 2023, 01:17:53 AM
Of course, formatting. I detest hard tabs.  :tongue:

Tabs or spaces, what for at the beginning of a proc? That's the central unit in your source, it should be left-aligned imho :cool:

All my procs follow this formatting:
DrawMyRect proc hDC
Local hBrush, whatever
  CreateAndSelect(hDC) ; one arg: set the DC (right after the locals)
  mov hBrush, CreateAndSelect(brush, Blue) ; the hBrush is not really needed
  .if !eax
MsgBox 0, "error", "Hi", MB_OK
  .endif
  ReleaseObjects ; no leaks please ;-)
  ret
DrawMyRect endp


First line, locals, last line: no blanks
Level 1: two spaces
Level n: n tabs

For good readability...
Title: Re: MasmBasic
Post by: zedd151 on June 25, 2023, 01:24:26 AM
Quote from: jj2007 on June 25, 2023, 01:20:50 AM
Tabs or spaces, what for at the beginning of a proc? That's the central unit in your source, it should be left-aligned imho :cool:
Actuall I haven't the slightes idea why I do it. I had started that practice years ago and the reasoning behind it is lost to history.   :rolleyes:  Very odd.
Title: Re: MasmBasic
Post by: jj2007 on June 25, 2023, 01:32:44 AM
Quote from: zedd151 on June 25, 2023, 01:24:26 AM
Quote from: jj2007 on June 25, 2023, 01:20:50 AM
Tabs or spaces, what for at the beginning of a proc? That's the central unit in your source, it should be left-aligned imho :cool:
Actuall I haven't the slightes idea why I do it. I had started that practice years ago and the reasoning behind it is lost to history.   :rolleyes:  Very odd.

I checked some sources in \Masm32\examples. Hutch did procs like I do, but left spaces before mytest macro :rolleyes:
Title: Re: MasmBasic
Post by: StrykerX on July 06, 2023, 10:03:35 AM
Would this be a good starting point for learning Assembly? Keen to give it a crack!
Title: Re: MasmBasic
Post by: Caché GB on July 06, 2023, 10:28:37 AM
jj2007's MasmBasic confused the h*ll out of when I first got started with MASM. Sorry jj.

It's a very complicated macro system for doing assembly. "Basic" is becuase it has a Basic
language like syntax.
Title: Re: MasmBasic
Post by: jj2007 on July 06, 2023, 12:24:40 PM
Quote from: Caché GB on July 06, 2023, 10:28:37 AM
jj2007's MasmBasic confused the h*ll out of when I first got started with MASM. Sorry jj.
:biggrin:

QuoteIt's a very complicated macro system for doing assembly. "Basic" is becuase it has a Basic
language like syntax.

include \masm32\include\masm32rt.inc

.code
start:
  print "Masm32 is great"
  MsgBox 0, "Hello World", "Basic style", MB_OK
  exit

end start


Guess what? This is not MasmBasic, it's "HutchBasic" aka "Masm32 SDK". I grew up with GfaBasic (https://en.wikipedia.org/wiki/GFA_BASIC), Hutch grew up with PowerBasic (https://en.wikipedia.org/wiki/PowerBASIC). That's one reason why we understood each other very well :tongue:

Re "very complicated macro system": under the hood, yes. For the user, it's actually very simple to do things like
Let esi="Now esi is a pointer to a string", or
include \masm32\MasmBasic\MasmBasic.inc
  Init
  .if Instr_(FileRead$("\Masm32\menus.ini"), "[&Project")
PrintLine "QEditor has a project section: ", Left$(eax, 200)
  .else
PrintLine "Nope, no project section in your QEditor menus"
  .endif
EndOfCode


Quote from: StrykerX on July 06, 2023, 10:03:35 AM
Would this be a good starting point for learning Assembly? Keen to give it a crack!

Opinions differ wildly. My extremely biased take on this is that using MasmBasic, you can do everything that you can do with the standard Masm32 libraries plus deb (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1019) and Recall (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1172) and a few (500+) others. Example:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  mov eax, 12345
  cdq
  mov ecx, 123
  deb 4, "Before the div:", eax, edx, ecx
  div ecx
  deb 4, "What happened to the registers?", eax, edx, ecx
EndOfCode


Output:
Before the div:
eax             12345
edx               0
ecx             123

What happened to the registers?
eax             100
edx              45
ecx             123


Check the File/MasmBasic help menu in RichMasm:
(http://www.jj2007.eu/pics/MbHelp.png)
Title: Re: MasmBasic
Post by: jj2007 on July 26, 2023, 06:47:07 PM
MasmBasic (http://masm32.com/board/index.php?topic=94.0) of 26.7.23 features:

- the MbMod macro (https://masm32.com/board/index.php?msg=121943)
- when you select a number in RichMasm and press Ctrl N, the dec, hex & binary representations can be copied to the clipboard.
Title: Re: MasmBasic
Post by: jj2007 on July 29, 2023, 12:33:05 AM
MasmBasic (http://masm32.com/board/index.php?topic=94.0) of 28.7.23 fixes a minor bug with wStr$(number) (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1274): if no format string was present, it spit out Ansi instead of Unicode. Works fine now :thumbsup:
Title: Re: MasmBasic
Post by: NoCforMe on July 29, 2023, 01:11:10 PM
Quote from: StrykerX on July 06, 2023, 10:03:35 AMWould this be a good starting point for learning Assembly? Keen to give it a crack!

Wellll, since you got one biased answer, from the author of MasmBasic, JJ, here's another answer biased in the other direction.

Mind you, I have nothing bad to say about his creation. It's magnificent, a megalithic work, a wonderful system that seems to do everything: macros galore, and it slices and dices.

However, my suggestion would be to learn standard assembly language (MASM) first. Why? Because if you start with MasmBasic, for one thing you'll get spoiled, and if you make a transition to standard MASM you'll probably be disappointed. Plus I think the less insulated approach of standard asm, having to do everything "by hand", may make you understand the underlying principles better.

But you should definitely try it (MasmBasic) at some point.

(My bias here is that I don't even like to use macros with MASM. I'm pretty much a loner here in that regard.)
Title: Re: MasmBasic
Post by: jj2007 on July 29, 2023, 06:56:59 PM
Quote from: NoCforMe on July 29, 2023, 01:11:10 PMif you start with MasmBasic, for one thing you'll get spoiled

Good point :thumbsup:

For example, by changing five lines in \Masm32\examples\exampl04\jacts\jacts.asm:

if 1
   include \masm32\MasmBasic\MasmBasic.inc
   uselib winmm   ; see deb below
else
.386
.model flat,stdcall
option casemap:none
...
includelib \masm32\lib\winmm.lib
endif   ; ----- ^ ^ ^ excluded in favour of MasmBasic -----

... you don't change anything. Oh wait: the executable is 4 times bigger... and you can use the deb macro (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1019) from now on ;-)
Title: Re: MasmBasic
Post by: jj2007 on August 03, 2023, 08:42:49 AM
What's new in MasmBasic version 2 August 2023 (http://masm32.com/board/index.php?topic=94.0)?

a) Coloured rounded ownerdraw buttons, with text that moves some pixels to the right and down when the button is pressed (https://masm32.com/board/index.php?topic=11082.0):

(http://www.jj2007.eu/pics/ColouredButtons.png)

b) the fastest Hex$() (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1198) ever:
  Let o$=New$(40000000h)+"END"
  REPEAT 5
  NanoTimer()
  mov edi, o$
  xor ebx, ebx
  .Repeat
    Hex$(ebx, edi)
    add edi, QWORD
    inc ebx
  .Until ebx>=8000000h
  Print NanoTimer$(), Str$(" for writing %i MB\n", ebx/1048576)

Output:
315 ms for writing 128 MB
366 ms for writing 128 MB
361 ms for writing 128 MB
310 ms for writing 128 MB
312 ms for writing 128 MB

Same with standard Masm32 SDK hex$() - invoke dw2hex, ebx, edi:
1961 ms for writing 128 MB
1967 ms for writing 128 MB
1940 ms for writing 128 MB
1991 ms for writing 128 MB
1968 ms for writing 128 MB

Not to mention that you can use invoke crt_sprintf, edi, chr$("%00x"), ebx, too - but it takes 26 seconds :biggrin:
Title: Re: MasmBasic
Post by: 2B||!2B on September 10, 2023, 11:32:07 AM
Nice looking rounded buttons. Do you use GDI+ or D2D?
Title: Re: MasmBasic
Post by: jj2007 on September 10, 2023, 06:02:24 PM
Quote from: 2B||!2B on September 10, 2023, 11:32:07 AMNice looking rounded buttons. Do you use GDI+ or D2D?

Thanks. It's Gdi+
Title: Re: MasmBasic
Post by: jj2007 on September 24, 2023, 08:13:15 AM
MasmBasic & RichMasm were updated (http://masm32.com/board/index.php?topic=94.0): Now most if not all sources in...

\Masm32\Examples
\Masm64\Examples

... will assemble & link out of the box just by hitting F6 in RichMasm. No individual batch file is needed, since the IDE will autodetect if a) resources are needed and b) if it's a console or GUI application.

Please let me know if you find an example does not build flawlessly. Actually, I found one: \Masm64\Examples\Advanced\tEdit\tEdit.asm needs an OPT_Assembler ml64 to build properly, in a comment or at the end of the source (Hutch put the masm64rt.ìnc in an include file instead of the main source...).

Plus minor improvements, such as the icon option for static controls (project attached, it's just two tiny files):

GuiParas equ "Hello Ida", w104, h222, b BlueGreen, style 0, icon Butterfly    ; width+height, background colour, icon for caption
include \masm32\MasmBasic\Res\MbGui.asm
  GuiControl MyStatic, "static",  icon IDI_APPLICATION
GuiEnd
Rsrc
#include "resource.h"
01 RT_MANIFEST    "\\Masm32\\MasmBasic\\Res\\XpManifest.xml"
IDI_APPLICATION ICON        "Ida.ico"
Rsrc

You may note that in RichMasm, the resources can be integrated into the main source. This is often handy, as you can edit quickly e.g. a resource ID in both the asm and the rc file without opening two files. When hitting the build button F6, the section between the two Rsrc lines gets exported to [filename].rc before the assembly starts.
Title: Re: MasmBasic
Post by: mstram on September 26, 2023, 11:36:03 PM
I just installed this on the sdk from http://masm32.masmcode.com/masm32/masm32v11r.zip (had to use Edge and bypass the "can't be downloaded securely).

When I click on File / Build and run get :

\masm32\bin\UAsm32' is not recognized as an internal or external command,
operable program or batch file.
*** Assembly error ***
Title: Re: MasmBasic
Post by: jj2007 on September 26, 2023, 11:43:11 PM
Hi mstram,

Check https://www.terraspace.co.uk/uasm.html#p2 (https://www.terraspace.co.uk/uasm.html#p2)

There are UAsm64.exe and UAsm32.exe. Are you using a 32-bit version of Windows?
Title: Re: MasmBasic
Post by: mstram on September 27, 2023, 10:57:19 PM
Thanks, working now
Title: Re: MasmBasic
Post by: jj2007 on October 11, 2023, 10:00:41 AM
Update 11 October 2023 (download (https://masm32.com/board/index.php?topic=94.0)):

1. Clean$(pString, leftMatch, rightMatch, mode):
  include \masm32\MasmBasic\MasmBasic.inc
  Init        ; select and hit F6
  Let esi="index.php?PHPSESSID=74e64f1f&amp;topic="
  PrintLine "before: [", esi, "]"
  PrintLine "after:  [", Clean$(esi, "PHPSESSID=", "&amp;", 0), "]"    ; string, left, right match, mode
EndOfCode

Output:
before: [index.php?PHPSESSID=74e64f1f&amp;topic=]
after:  [index.php?topic=]

It's the counterpart to Extract$() (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1156):
- "cleans" a given string depending on left and right matches
- mode as in Instr_()
- if no right match is given, Cr$ is assumed, i.e. until end of line

2. GuiControl allows now to set the background colour with e.g. Ini$() - see CheckNewPosts (https://masm32.com/board/index.php?msg=124449):
  .if !Ini$()  ; if [filename].ini not found, create it and set defaults:
    SetIni$ "upperBgColour", Str$(LiteBlueGreen)
    SetIni$ "lowerBgColour", Str$(LiteGrey)
  .endif
  GuiControl TheDesc, "RichEdit", y=0+26, h=0+230, font -16, bcol <Val(Ini$("upperBgColour"))>, text hover$
  GuiControl TheLinks, "RichEdit", y0+228, h1000-228, font -14, bcol <Val(Ini$("lowerBgColour"))>
Title: Re: MasmBasic
Post by: jj2007 on October 29, 2023, 01:53:13 AM
Update 28 October 23 (http://masm32.com/board/index.php?topic=94.0):

a) ZipFiles adjusted, see here (https://masm32.com/board/index.php?topic=11385.msg124786#new)

b) CoInvoke:
Sometimes you see things like this on the web:
hResult = pISD->namespace(vFile, &pToFolder)
To make the translation to Assembly easier, you can now use
Local vDest:VARIANT
  mov vDest.vt, VT_BSTR ; the type
  mov vDest.bstrVal, rv(SysAllocStringLen, ecx, eax) ; put a filename
  CoInvoke pISD, IShellDispatch.NameSpace, vFile, &pFolder

Looks unnecessary? Yes, but the "v" in vFile stands for VARIANT, and to do that properly by hand, you would need this:
CoInvoke pISD, IShellDispatch.NameSpace, VT_BSTR, 0, vFile.bstrVal, 0, addr pFolder
It's easy to get a little bit confused here, especially if the COM call expects several VARIANTs, as e.g. in Folder.CopyHere :cool:
Title: Re: MasmBasic
Post by: jj2007 on December 02, 2023, 12:06:29 PM
Update 2 December 23 (https://masm32.com/board/index.php?topic=94.0):

As shown in the Assembly uses Python (https://masm32.com/board/index.php?topic=11506.0) thread, it may happen that a DLL doesn't work as expected because, well, it can't find its components. Python3.dll loads six more DLLs, and since it's a bit dumb, it looks for them
a) in the current folder (i.e. the executable's folder)
b) in C:\Windows\System32

No luck, folks, if the executable sits elsewhere. So I had to invent the SetDllFolder macro:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  SetDllFolder "\Python"            ; adjust to your setup; downloaded from here (https://www.python.org/ftp/python/3.8.9/python-3.8.9-embed-win32.zip)
  Dll "python38"                          ; depends on six more DLLs
  Declare void Py_Initialize
  Declare void PyRun_SimpleString, C:1    ; requires python38.dll
  SetDllFolder                     ; no args=go back to previous folder after declaring the functions
  Py_Initialize()
  PyRun_SimpleString("MyLong=123456789")    ; use the interpreter
  Inkey "ok"
EndOfCode

The good news is that with SetDllFolder you don't need the full path for Dll "Python3" :cool:

Overall, Python is a horrible mess:
- Python 3 is absolutely incompatible with Python 2
- dll hell, see SetDllFolder above
- there is Python3.dll in the downloaded folder (https://www.python.org/ftp/python/3.8.9/python-3.8.9-embed-win32.zip), but it does not pass on all the functions of the main DLL, which is (in this case) Python38.dll
- so you often must hardcode the version in your code, and force the user to install a specific version (3.8 is the last one that works on Win7 btw)
- there are three distinct methods to access Python from Assembly:
  1. C API (https://docs.python.org/3/c-api/) (probably the fastest)
  2. PyRun_SimpleString
  3. PyObject_CallMethod
- my guess is that three quarters of the over 1,600 functions exported by Python38.dll are either for typecasting or simply redundant
Title: Re: MasmBasic
Post by: TimoVJL on December 03, 2023, 08:18:40 AM
Idea for hunting down correct Python3x.dll, but not reliable, as that string is missing many import Python3.dlls, like in version 3.10.0
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "user32.lib")
// https://docs.python.org/3/c-api/
typedef void (PY_INITIALIZE)(void);
typedef PY_INITIALIZE *LPPY_INITIALIZE;
// PyRun_SimpleString
typedef int PYRUN_SIMPLESTRING(char *);
typedef PYRUN_SIMPLESTRING *LPPYRUN_SIMPLESTRING;

int __cdecl main(void)
{
    static LPPY_INITIALIZE Py_Initialize;
    static LPPYRUN_SIMPLESTRING PyRun_SimpleString;
    char szVersion[50];
    char szPythonDll[260] = "bin64/Python3.dll";
    HMODULE hMod = LoadLibrary(szPythonDll);    //
    if (hMod) {
        int nLen = GetModuleFileName(hMod, szPythonDll, 260);
        LoadString(hMod, 1000, szVersion, 50);
        printf("%s\n", szVersion);
        FreeLibrary(hMod);
        szPythonDll[nLen-5] = szVersion[0];
        szPythonDll[nLen-4] = szVersion[2];
        szPythonDll[nLen-3] = 0;
        printf("%s\n", szPythonDll);
        hMod = LoadLibrary(szPythonDll);
    }
    if (hMod) {
        printf("%s loaded\n", szPythonDll);
        Py_Initialize = (LPPY_INITIALIZE)GetProcAddress(hMod, "Py_Initialize");
        if (Py_Initialize) {
            Py_Initialize();
            PyRun_SimpleString = (LPPYRUN_SIMPLESTRING)GetProcAddress(hMod, "PyRun_SimpleString");
            if (PyRun_SimpleString) {
                PyRun_SimpleString("print('Python Print test')");
            } else printf("PyRun_SimpleString not found\n");
        } else printf("Py_Initialize not found\n");
        FreeLibrary(hMod);
    } else printf("Python3x.dll not loaded\n");
    return 0;
}
This works with 3.10
    char szVersion[50];
    char szPythonDll[260] = "bin64_310/Python3.dll";
    HMODULE hMod = LoadLibrary(szPythonDll);
    if (hMod) {
        int nLen = GetModuleFileName(hMod, szPythonDll, 260);
        printf("%s\n",GetVersionInfo(hMod, "FileVersion", szVersion, sizeof(szVersion)));
        FreeLibrary(hMod);
        szPythonDll[nLen-5] = szVersion[0];
        szPythonDll[nLen-4] = szVersion[2];
        if (szVersion[3] != '.') szPythonDll[nLen-3] = szVersion[3]; else szPythonDll[nLen-3] = 0;
        szPythonDll[nLen-2] = 0;
        printf("%s\n", szPythonDll);
        hMod = LoadLibrary(szPythonDll);
    }
GetVersionInfo.c
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winver.h>
#include <stdio.h>

#pragma comment(lib, "version.lib")
#pragma comment(lib, "user32.lib")

LPSTR GetVersionInfo(HMODULE hMod, TCHAR *szValue, TCHAR *szBuffer, ULONG nLength)
{
    LPSTR csRet;

    csRet = NULL;
    HRSRC hVersion = FindResource(hMod, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
    DWORD dwSize = SizeofResource(hMod, hVersion);
    if (hVersion != NULL)
    {
        HGLOBAL hGlobal = LoadResource(hMod, hVersion);

        if (hGlobal != NULL)
        {
            //LPVOID ver = LockResource(hGlobal);
            LPVOID ver = LocalAlloc(LPTR, dwSize*2);

            if (ver != NULL)
            {
                memcpy(ver, hGlobal, dwSize);
                DWORD *codepage;
                UINT len;
                char fmt[0x40];
                PVOID ptr = 0;
                if (VerQueryValue(ver, "\\VarFileInfo\\Translation", (LPVOID) & codepage, &len))
                {
                    //wsprintf(fmt, "\\StringFileInfo\\%04x%04x\\%s", (*codepage) & 0xFFFF, (*codepage) >> 16, csEntry);
                    wsprintf(fmt, "\\StringFileInfo\\%08x\\%s", (*codepage) << 16 | (*codepage) >> 16, szValue);
                    if (VerQueryValue(ver, fmt, &ptr, &len))
                    {
                        lstrcpyn(szBuffer, (TCHAR*)ptr, min(nLength, len));
                        csRet = szBuffer;
                    }
                }
                LocalFree(ver);
            }
            FreeResource(hGlobal);
        }
    }
    return csRet;
}
EDIT 2023-12-03:
api-ms-win-core-path-l1-1-0.dll for Windows 7 (https://github.com/nalexandru/api-ms-win-core-path-HACK)

Windows API function AddDllDirectory() is useful with
LoadLibraryEx(szPythonDll, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_USER_DIRS);
char szVersion[50];
char szPythonDll[260] = "bin64_310/Python3.dll";
wchar_t wszPath[260];
HMODULE hMod = LoadLibrary(szPythonDll);
if (hMod) {
int nLen = GetModuleFileNameW(hMod, wszPath, 260);
while (wszPath[--nLen] != '\\');
if (nLen) wszPath[nLen+1] = 0;
AddDllDirectory(wszPath);
nLen = GetModuleFileName(hMod, szPythonDll, 260);
printf("%s\n",GetVersionInfo(hMod, "FileVersion", szVersion, sizeof(szVersion)));
FreeLibrary(hMod);
szPythonDll[nLen-5] = szVersion[0];
szPythonDll[nLen-4] = szVersion[2];
if (szVersion[3] != '.') szPythonDll[nLen-3] = szVersion[3]; else szPythonDll[nLen-3] = 0;
szPythonDll[nLen-2] = 0;
printf("%s\n", szPythonDll);
//hMod = LoadLibrary(szPythonDll);
//if (!hMod)
hMod = LoadLibraryEx(szPythonDll, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_USER_DIRS);
}
Title: Re: MasmBasic
Post by: jj2007 on December 03, 2023, 10:55:55 AM
Thanks, Timo.

This works, it checks for the first Python3?.dll whose name is more than 11 chars long:

include \masm32\MasmBasic\MasmBasic.inc
  SetGlobals ffd:WIN32_FIND_DATA
  Init
  SetDllFolder "\Python" ; adjust to your setup; downloaded from here
  GetFiles python3*.dll
  or ecx, -1
  .Repeat
inc ecx
  .Until Len(Files$(ecx))>11 || ecx>=9
  .if Zero?
MsgBox 0, "Dll not found", "Hi", MB_OK
Exit
  .endif
  Dll Files$(ecx) ; python3?.dll offers twice as many functions
  Declare void Py_Initialize
  Declare Py_GetBuildInfo
  push ecx
  SetDllFolder ; no args=go back to previous folder after declaring the functions
  pop ecx
  Py_Initialize()
  Let edi=Py_GetBuildInfo()
  Inkey "Version ", edi, " loaded from ", Files$(ecx)
EndOfCode

Output: Version tags/v3.13.0a1:ad056f0, Oct 13 2023, 09:34:45 loaded from python313.dll
Title: Re: MasmBasic
Post by: jj2007 on December 04, 2023, 12:42:21 PM
Quote from: TimoVJL on December 03, 2023, 08:18:40 AMWindows API function AddDllDirectory() is useful with
LoadLibraryEx(szPythonDll, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_USER_DIRS);

  LOAD_LIBRARY_SEARCH_USER_DIRS=400h
  LOAD_LIBRARY_SEARCH_DEFAULT_DIRS=1000h
  Dll "kernelbase"
  Declare void AddDllDirectory, 1
  AddDllDirectory(wRec$("\Python"))
  Dll "python313", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS or LOAD_LIBRARY_SEARCH_USER_DIRS

Thanks, Timo, it works, but it's quite an effort. The SetDllFolder macro is straightforward, too.
Title: Re: MasmBasic
Post by: TimoVJL on December 04, 2023, 09:07:08 PM
With different API function:
int nLen = GetModuleFileNameW(hMod, wszPath, 260);
while (wszPath[--nLen] != '\\');
if (nLen) wszPath[nLen+1] = 0;
SetEnvironmentVariableW(L"PATH", wszPath);
Title: Re: MasmBasic
Post by: jj2007 on March 21, 2024, 01:00:08 AM
MasmBasic version 20 March 2024 comes with an improved SetAccels macro:
  SetAccels F1: 0
  SetAccels Ctrl F2: Hlp        ; no args
  SetAccels Alt F2: Hlp1(22)
  SetAccels Ctrl Shift F2: Hlp2(33:var444)    ; see console
  SetAccels Ctrl Shift F3: Hlp3(44:Hello$)        ; a MsgBox
  SetAccels Ctrl F1, Ctrl Shift T
  SetAccels Alt F1
  SetAccels Shift F1
  SetAccels a, Shift B, c, D    ; lowercase a, c, d work, B needs a shift
  SetAccels Ctrl O: CtrlOpen
  SetAccels Ctrl VK_SPACE: MyConSpace
  SetAccels Ctrl Z: NoUndo
  SetAccels x: LowercaseX, Shift X: UppercaseX

F1:123 means "let F1 trigger an Event Accel"
F1:someproc means "jump to someproc" - with no, one, or two arguments.

Full code attached. Please report if anything is unexpected :cool: