News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

MasmBasic

Started by jj2007, May 23, 2012, 10:16:07 PM

Previous topic - Next topic

jj2007

I know it's hard to believe but YES, MasmBasic had a bug: wLeft$/wRight$/wMid$ 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. 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) is now twice as fast (the bad news is I had to abandon Pelles C to achieve that :().

jj2007

#196
Update 10 November: Launch$() is now thread-safe. This was never a problem in console apps, but GUI apps could occasionally choke. It's fixed.

Other changes:
- Dll 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
  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

Gunther

Jochen,

Quote from: jj2007 on November 10, 2014, 12:52:49 PM
Update 10 November: Launch$() 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
You have to know the facts before you can distort them.

jj2007

The MasmBasic update of 17 November (download) 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
  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

Gunther

Jochen,

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

Gunther
You have to know the facts before you can distort them.

jj2007

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.

habran

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:
Cod-Father

Gunther

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
You have to know the facts before you can distort them.

jj2007

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


jj2007

Minor fixes in MasmBasic version 9 December 2014 (download)

- ToolTips 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 GfCallback (examples) gives access to WIN32_FIND_DATAW in ebx (edx=file counter, edi=last path of FindFirstFileEx)

- Dim 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$() occasionally threw generic API errors when the file was not found; now it chokes correctly with "can't find thatfile.txt"

jj2007

Minor update of 16 December 2014 (download)

One new feature: Extract$() 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
  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?

Gunther

Interesting feature, Jochen.  :t Well done.

Gunther
You have to know the facts before you can distort them.

jj2007

Update 24.12.2014 (download):

In addition to the standard file pattern, GetFiles 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
  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.

jj2007

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 has been available for a while, but it choked for multiple assignments. This bug is fixed.

include \masm32\MasmBasic\MasmBasic.inc      ; download
  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.

jj2007

Version 26.12. choked for Sqrt(2); it's fixed with version 27.12. (download)

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