Author Topic: MasmBasic  (Read 248498 times)

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9635
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #465 on: February 09, 2019, 08:04:52 AM »
Update 8 February 2019:
- 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:
Code: [Select]
 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

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9635
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #466 on: February 12, 2019, 09:53:51 PM »
Update 12 February 2019 fixes a minor glitch in the editor. As a side effect, a request by HSE to set the foreground colour 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.

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9635
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #467 on: April 02, 2019, 09:24:27 PM »
Update 2 April '19 adds a bunch of improvements under the hood, check this Gui programming post 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.

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9635
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #468 on: May 08, 2019, 11:20:59 PM »
MasmBasic was updated, 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:
Code: [Select]
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

TimoVJL

  • Member
  • ***
  • Posts: 408
Re: MasmBasic
« Reply #469 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 :(
May the source be with you

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9635
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #470 on: May 09, 2019, 01:42:30 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.

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

2B||!2B

  • Member
  • **
  • Posts: 61
Re: MasmBasic
« Reply #471 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


jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9635
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #472 on: May 22, 2019, 12:52:38 PM »
Hi,

The example in the manual has a FOR counter:
Code: [Select]
For_ ct=0 To Split$("Masm32 is great", " ", My$())-1
PrintLine "[", My$(ct), "]"
Next

Since Split$() returns the number of strings in eax, you could write this also as
Code: [Select]
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 is for strings only.

Thanks for the feedback - I will modify the manual to make that point clearer :Thmbsup:

2B||!2B

  • Member
  • **
  • Posts: 61
Re: MasmBasic
« Reply #473 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?

Code: [Select]
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.

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9635
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #474 on: May 22, 2019, 05:36:52 PM »
If you mean the number of elements: mov ecx, somearray(?)

2B||!2B

  • Member
  • **
  • Posts: 61
Re: MasmBasic
« Reply #475 on: May 23, 2019, 05:08:48 PM »
Thanks. It works perfect. Very useful library :D

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9635
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #476 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:
Code: [Select]
  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.

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9635
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #477 on: August 04, 2019, 09:02:28 PM »
Update 4 August 2019 (download):

- 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:
Code: [Select]
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
  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_(...)
       xchg eax, ecx
        PrintLine Str$("line %i\t", ecx), L$(ecx)
        inc ecx
  .Endw
  MsgBox 0, "ok?", "Hi", MB_OK
EndOfCode


Project attached.

AW

  • Member
  • *****
  • Posts: 2233
  • Let's Make ASM Great Again!
Re: MasmBasic
« Reply #478 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:


jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9635
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #479 on: August 05, 2019, 06:03:57 AM »
Yeah, completely different:
Code: [Select]
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: