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

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).

TWell

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).
OpenFolder works nicely in Win7 64-bit.
Avast don't let me download that zip.

BYE

jj2007

#137
Major update of MasmBasic, 24 October 2013 (download):

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.

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.

jj2007

#138
Update 30 October 2013 (download):

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$() 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

Farabi

 :t Impressive, it become more and more usefull. I'll use MASM BASIC started from now and forever.
http://farabidatacenter.url.ph/MySoftware/
My 3D Game Engine Demo.

Contact me at Whatsapp: 6283818314165

Farabi

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?
http://farabidatacenter.url.ph/MySoftware/
My 3D Game Engine Demo.

Contact me at Whatsapp: 6283818314165

jj2007

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...

jj2007

There was a nasty little bug since the introduction of ArraySet():

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

Other changes concern only DosBasic, the little 16-bit brother of MasmBasic.

jj2007

A small addition for version 11.11.2013 (download): 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

jj2007

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 ;)

anta40

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$?"

jj2007

#146
Hi anta,

"La$?" is what Launch$("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

jj2007

There is a problem with Str$() 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.

jj2007

With MasmBasic of 22 December 2013, you can print unsigned qwords like 12345678901234567890:

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

jj2007

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)