News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

MasmBasic

Started by jj2007, October 06, 2009, 08:24:57 PM

Previous topic - Next topic

dedndave

Jochen has put a lot of work into it
you can bet it generates some pretty fast code   :U

jj2007

#136
Quote from: frktons on April 27, 2010, 08:36:37 PM
Great job  :U
As soon as I move a little into ASM I'll give a try to your lib.
Hoping it will be a stable release when I'll get to that point.  :P

Thanks, Frank. The release is stable in the sense of "it works fine", but I am still adding features. For example, the Recall function that loads a string array is comfortable but I often work with spreadsheets; so tonight I added a few lines that allow to access the elements of a spreadsheet e.g. as
Print Matrix$(1000, 5), i.e. print row 1000, column 5.
include \masm32\MasmBasic\MasmBasic.inc
Init ; get a fat csv file here: http://mdgs.un.org/unsd/mdg/Handlers/ExportHandler.ashx?Type=Csv
Print "Load a 13 MB csv file, and get the address of each single element:", CrLf$
push Timer()
Recall "D:\ZIP_TEMP\MDG_Export_20100428_130002671.csv", L$(), csv
mov ebx, eax ; save the line count
void Timer()
sub eax, [esp]
push eax
timings=1 ; disactive to see some real strings
ife timings
Print CrLf$, "Full string:", CrLf$, "[", L$(0), "]", CrLf$
For_ n=0 To 0
else
For_ n=0 To ebx-1
endif
For_ ct=0 To 64
if timings
void L$(n, ct) ; for timings
else
Print L$(n, ct), CrLf$
endif
Next
Next
void Timer()
sub eax, [esp+4]
Print Str$("Your puter needed %i ms", eax)
pop eax
pop edx
Inkey Str$(", of which %i ms for Recall", eax)
Exit
end start

So all I need is Recall CL$(), L$(), csv to have a spreadsheet matrix at my fingertips...

@Dave: Yeah, most of them are pretty fast, but getting the addresses from all elements of that 13MB file takes over a second... sloooow :wink

I attach the version with the csv reader temporarily. The csv (or tab) flag is not yet documented.

jj2007

#137
Temporary rc2704 removed above, more stable rc3004 attached at top of thread. Inter alia, it can now read and write csv files - see attached demo.
It reads a 13 MB csv file in 32 milliseconds, roughly a factor 100 faster than ExcelTM :toothy

frktons

Have you ever used the library in a PB program?
I mean is it a simple task calling the masm functions in your
library within a PB program?

Thanks

Frank
Mind is like a parachute. You know what to do in order to use it :-)

jj2007

Frank,
Afaik direct linking of obj files is not possible with PB, but nothing stops you from putting the required calls into a dll. Check

\masm32\RichMasm\Res\MiniDll.asc
\masm32\RichMasm\Res\MiniDll_call.asc

Otherwise, explain a bit what you need, or PM me.

P.S.: Spreadsheet example updated, see SpreadsheetDemo2.zip above.

frktons

I was thinking about using your quick sort function inside a PB
program, instead of the PB Function that is a bit slow. This is
just a first idea, because if I learn how to use the lib you are building,
I could use many more functions as well.  :wink

Thanks
Mind is like a parachute. You know what to do in order to use it :-)

dedndave

if you were to use Jochen's library in PB, you might have a few naming conflicts   :P
get past that, though - i think the PB community would really appreciate it

frktons

Quote from: dedndave on May 02, 2010, 10:23:04 PM
if you were to use Jochen's library in PB, you might have a few naming conflicts   :P
get past that, though - i think the PB community would really appreciate it

Or maybe the PB community would really appreciate the possibility of using
faster code for some tasks  :lol

Well I'm thinking about a couple of ways of doing it:

- use the source of MASM quick sort and translate it into INLINE ASM
- use a DLL instead of a STATIC LIB

And there are probably other ways I'm not aware of.  ::)

Frank
Mind is like a parachute. You know what to do in order to use it :-)

jj2007

Bug fix: KSS discovered that wInstr (i.e. the Unicode version of Instr_) did not deliver correct values. New version attached on top of thread.

Most important new function:
QuoteSetWin$
   SetWin$ hWnd="A new title for my app"
Rem[/color]   for main windows and controls; you can use string concatenation as in Let

jj2007

The wide (Unicode) version of Instr returned a match if the pattern was longer than the source. Fixed in MasmBasicRC010710.zip at top of thread.

Quoteinclude \masm32\MasmBasic\MasmBasic.inc
   
Init
   wData wSource, "Another test for seeing if wInstr works fine", 0
   wData wPattern, "wInstr WORKS", 0
   .if wInstr(offset wSource, offset wPattern, 1)   ; startpos default, src, pattern, 1=case-insensitive
      invoke MessageBoxW, 0, eax, wChr$("The match:"), MB_OK
   .else
      invoke MessageBoxW, 0, offset wPattern, wChr$("NO MATCH:"), MB_OK
   .endif
   
Exit
end start

jj2007

Finally I could convince the editor to remember window position and size. New version attached on top of thread (5 July).

jj2007

#146
Version 22 July 2010 (attached at the bottom of post #1) features a major remake of the Recall macro. Inter alia, it will now ignore single LF characters in strings, and will not stumble over text files that end without a CRLF. Recall is actually pretty stable now: I have run it through a stress test with a randomised number of strings with variable (randomised) lengths, and the last version didn't choke any more for tens of Gigabytes. Which shows also that HeapAlloc is a safe way of organising Millions of small allocations.

Two new features are Cat$ and Clip$(), also in wide (Unicode) versions. SetWin$ and Win$() are now also available as Unicode versions.

QuoteRecall
   Recall "\masm32\include\winextra.inc", MyRec$()
   mov lc, Min(eax, 20)
   Print Str$("%i lines found", lc)
   For_ n=0 To lc-1
      Print Str$("\nRec %i\t", n)
      Print Left$(MyRec$(n), 50)
   Next

   Recall "MyFile.csv", MyRec$(), csv   ; loads a spreadsheet in comma separated values format
   Recall "MyFile.txt", MyRec$(), tab   ; loads a spreadsheet in tab-delimited format
Rem[/color]   - returns lines in eax (null if an error occurred), and the number of total bytes read in edx
   - see Store below for saving arrays
   - with the spreadsheet variants, single cells can be accessed via Let My$=MyRec$(row, column)[/b]

QuoteClip$, wClip$
   Print "[", Clip$(), "]"      ; displays the content of the clipboard
   MsgBox 0, Clip$(), "Text on the clipboard:", MB_OK   ; same as MessageBox
            MsgBox 0,\
            Cat$("The text on the clipboard:"+CrLf$+String$(33,"-")+CrLf$+Clip$(20)+CrLf$+String$(0,0)),\
            "MasmBasic:", MB_OK   ; displays a MessageBox with two horizontal delimiters
            
MsgBox 0, Clip$(40), "The text on the clipboard, truncated to 40 chars:", MB_OK
            invoke lstrcpy, offset my40charbuffer, Clip$(40-1)   ; yep, don't forget space for the zero delimiter
Rem[/color]   - returns ptr in eax
   - you can truncate the content for security reasons, e.g. for use in a MessageBox
   - if no argument is specified, up to 160k will be copied into the internal buffer[/b]

QuoteCat$, wCat$
   MsgBox 0, Cat$("The content of the editbox is"+CrLf$+Win$(hEdit)), "Info", MB_OK
Rem[/color]   returns ptr in eax and MbCat$
   - Cat$ is meant to replace Let My$=... in MessageBox or similar situations
   - every use of Cat$ overwrites content in the dedicated Cat$ buffer; mov myptr, Cat$() is
     therefore pretty useless. If you want permanent strings, use Let[/b]

jj2007

27 August 2010 news:

Dim is no longer limited to string arrays. You can now use it for arrays of DWORDs, WORDs, BYTEs and even structures such as RECT etc:
Dim MyFloats(5)  As FLOATSTRUC
Dim Mybyte(99) as BYTE
Dim Ws(eax) As WNDCLASSEX


QuoteFLOATSTRUC STRUCT
f4   REAL4 ?
f8   REAL8 ?
f10   REAL10 ?
fsrect   RECT <?>
filler   WORD ?
FLOATSTRUC ENDS

   Dim MyFloats(5) As FLOATSTRUC      ; Create an array of structures in heap memory, with 5 elements
   fldpi      ; push PI on the FPU (3.14159265358979324)
   fst MyFloats(3, f4)      ; load PI into the REAL4 and REAL8 members
   fst MyFloats(3, f8)
   fstp MyFloats(3, f10)      ; load PI into the REAL10 member, and pop ST
   
Let MyFloats(4)=MyFloats(3)      ; copy array element #3 into array element #4
   
Print Str$("\nTesting structures:\nResult 4, f10=%If\n", MyFloats(4, f10))   ; show the result (%If means full precision; use 0...9, A...I)
   MovVal MyFloats(4, f10), chr$("123.456e97")   ; convert an Ascii string, and move it directly into array member #4, f10 (the REAL10 member)
   
Print Str$("Result 4, f10=%f\n", MyFloats(4, f10))   ; show the result (%f means default precision)
   
Let MyFloats(0)=MyFloats(4)      ; copy array element #4 into array element #0
   
push esi      ; your responsibility to preserve esi
   MyFloats(
4:esi)      ; from now on, use esi for array element #3 - same as ASSUME
   fld MyFloats(f8)      ; push the REAL8 member onto the FPU
   fstp MyFloats(f10)      ; load the value into the REAL10 member, and pop ST
   
Print Str$("Result ?, f10=%f\n", MyFloats(f10))   ; OK
   Print Str$("Result 4, f10=%f\n", MyFloats(4, f10))   ; OK
   MyFloats(
4:none[/color])      ; release esi, back to normal mode (where edx is used for every call)
   pop esi      ; restore esi
   
Print Str$("Result 0, f10=%f\n", MyFloats(0, f10))   ; show the results for three array members and their REAL10 elements
   Print Str$("Result 3, f10=%f\n", MyFloats(3, f10))
   Print Str$("Result 4, f10=%f", MyFloats(4, f10))

etc... have fun :bg

P.S.: Typechecking rules apply, e.g.    movq xmm0, MyFloats(ecx, f8) works if f8 is a REAL8 member

jj2007

27 August 2010, minor bugfix: JWasm choked over wLet My$=wChr$("Test")+wCrLf$
Check version MasmBasic270810b.zip on top of this thread.

jj2007

Just discovered that the help file still has the old version for printing qwords and REAL4. Note that prefixes are no longer needed, except for Sqrt (I am working on that one) and if you want to use xmm regs in float mode:

Quoteinclude \masm32\MasmBasic\MasmBasic.inc
.data
MyReal4   REAL4   3.1416
MyPI   REAL10   3.14159265358979323846
MyQword   dq   0
MyR4   REAL4   0.0
V32QW   dq   36
V32R4   REAL4   36.0

   
Init
[/color]
   MovVal f:xmm0, Left$(Chr$("123.4567"), 6)      ; to use xmm regs in float mode, use the f:
   Print Str$("MyXmm=\t%f\n", f:xmm0)         ; prefix both for MovVal and Str$
   MovVal xmm0, Left$(Chr$("123.4567"), 6)      ; same xmm reg but in integer mode
   Print Str$("MyXmm=\t%f\n", xmm0)
   
   Print Str$("Square root QWord \t%If\n", Sqrt(q:V32QW))   ; q: qword prefix
   Print Str$("Square root Real4 \t%If\n", Sqrt(s:V32R4))   ; s: single prefix
   
   MovVal MyQword, Chr$("123.4567")         ; NO prefix required for
   Print Str$("MyQword=\t%f\n", MyQword)      ; qwords and
   MovVal MyR4, Chr$("123.4567")         ; REAL4 in MovVal, Str$
   Print Str$("MyR4=\t%f\n", MyR4)
   Fcmp MyReal4, MyPI
   .if !Carry?
      Inkey Str$("The rounded value %f", MyReal4), Str$(" is higher than the real PI, %Jf", MyPI)
   .else
      Inkey Str$("The rounded value %f", MyReal4), Str$(" is lower than the real PI, %Jf", MyPI)
   .endif
   Exit
end start

Since xmm regs can be used both as floats and as integers, the f: prefix is needed if you want to use it as a float reg (the assumption being that we use it more often for integers).