News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Seeking friendly collaborator

Started by mikorians, October 19, 2012, 03:29:02 AM

Previous topic - Next topic

jj2007

Quote from: MichaelW on October 26, 2012, 05:37:11 AM
I was just trying to show the more compact syntax that FreeBASIC allows, compared to VB.

Yeah, FreeBASIC looks nice. What a pity that Masm and JWasm don't understand the syntax :biggrin:

Here is a port to Assembler (full version attached, including one algo using SSE2, and somewhat surprising results for Michael's DLL):

Quoteinclude \masm32\MasmBasic\MasmBasic.inc   ; download
include \masm32\macros\timers.asm   ; download from the Masm32 Laboratory

D3DCOLORVALUETOLONG PROTO pCv:DWORD

D3DCOLORVALUE STRUCT
    r REAL4 ?
    g REAL4 ?
    b REAL4 ?
    a REAL4 ?
D3DCOLORVALUE ENDS

.data
cv   D3DCOLORVALUE <0.123, 0.234, 0.345, 0.456>

  Init
  Dll "testdll"
  Declare D3DCOLORVALUETOLONGASM, 1   ; one arg = ptr D3DCOLORVALUE

  PrintLine Hex$(D3DCOLORVALUETOLONGASM(offset cv))

  invoke D3DCOLORVALUETOLONG, offset cv
  PrintLine Hex$(eax)

  REPEAT 2
       invoke Sleep, 200
       counter_begin 500000, HIGH_PRIORITY_CLASS
              void D3DCOLORVALUETOLONGASM(offset cv)   ; very slow because it uses GetProcAddress; the attached version is a lot faster
       counter_end
       Print Str$("\n%i cycles for the DLL", eax)
   
       invoke Sleep, 200
       counter_begin 500000, HIGH_PRIORITY_CLASS
              invoke D3DCOLORVALUETOLONG, offset cv
       counter_end
       Print Str$("\n%i cycles for Assembler\n", eax)
  ENDM

  Inkey "ok"
  Exit

D3DCOLORVALUETOLONG proc pCv
LOCAL xr, xg, xb, xc
xa equ eax
   mov edx, pCv
   ffree st(7)
   ffree st(6)

   push 255
   fild stack   ; 255 in ST(0)
   fld st
   fmul [edx.D3DCOLORVALUE.r]
   fistp xr
   fld st
   fmul [edx.D3DCOLORVALUE.g]
   fistp xg
   fld st
   fmul [edx.D3DCOLORVALUE.b]
   fistp xb
   fmul [edx.D3DCOLORVALUE.a]
   fistp stack
   pop xa
   .if xa>127
          sub xa, 128
          shl xa, 24
          or xa, 80000000h
   .else
          shl xa, 24
   .endif
   mov edx, xr
   shl edx, 16
   or xa, edx
   mov edx, xg
   shl edx, 8
   or xa, edx
   or xa, xb
   ret
D3DCOLORVALUETOLONG endp

end start

mikorians

Dunno how helpful I can be, but I ran the .exe JJ, and here are the results.  Michael wins.

40 cycles for Michael's DLL
43 cycles for Assembler1
69 cycles for Assembler2
67 cycles for SSE2

jj2007

Quote from: mikorians on October 27, 2012, 04:42:33 AM
Michael wins.

Indeed, by a great margin. Which is very surprising because the SSE instruction processes the 4 dwords in parallel ::)

mikorians

Not too bad for an old computer,  an old OS, (and an old guy like me  :lol:) eh?   Yeah, I know....    :greensml:
It's strange that I can use some SSE instructions, but can't run MasmBasic's editor.
It's true that there are oddities with multi-threading, esp when you only have 1 cpu...  ha!
Erm.  I tried to recompile that program JJ, and it almost worked except for something missing--  The GDI plus .lib from NASM
May I please rant about something?  Mostly joking---  We all have to be careful about 'missing file litter'  If you're running 6 different compilers, etc..  please...   :badgrin:

jj2007

Quote from: mikorians on October 27, 2012, 06:07:56 AMI tried to recompile that program JJ, and it almost worked except for something missing--  The GDI plus .lib from NASM

What's wrong with the attached Masm32 version? It should already be part of your installation, if not: are you using an older Masm32 package? The current one if version 11.

mikorians

The one that runs on the embedded CPU: v9r Legacy.  Aaaalmost compiled...

MasmBasic.lib(libtmpAB.obj) : warning LNK4078: multiple ".drectve" sections found with different attributes (00000A00)
MasmBasic.lib(libtmpAB.obj) : error LNK2001: unresolved external symbol _GetConsoleWindow@0
masmbasictest.exe : fatal error LNK1120: 1 unresolved externals
Link error
Ah well...  No insult meant to anybody...  But this is why I'm still kind of clinging to FreeBasic...
I can transition to Asm gradually.  It seems to run as fast as C.  They say it can process C, too.  (Not that I can process C  :biggrin:)
And other than this one little library issue for DX8, I had fun compiling the Win32 GUI examples (not DX9 - really DX10),
and even wrote some code in it in QBasic very easily.  Yea.  :eusa_dance:
I did this little moving square graphic, and it ran at like 200,000FPS,  The original QBasic (which I can still run) was like... I dunno 50-100FPS

"This will be my C, and the inline Asm will be my future!"

jj2007

Quote from: mikorians on October 27, 2012, 09:31:32 AM
MasmBasic.lib(libtmpAB.obj) : error LNK2001: unresolved external symbol _GetConsoleWindow@0
masmbasictest.exe : fatal error LNK1120: 1 unresolved externals
...
"This will be my C, and the inline Asm will be my future!"

Attached a special lib that has the call to GetConsoleWindow disabled (it's needed only for displaying Chinese and Arabic in the console window, so you can live without it ;)).

MichaelW

QuoteIt seems to run as fast as C.

For some code it is, thanks to the efforts of the FreeBASIC developers on the compiler's asm emitter. But for other code, where the C compiler optimizations are effective, the compiled C is code faster than the FreeBASIC-compiled code, and generally competitive with asm code. To demonstrate, I compiled this C version of the original VB function:

typedef struct _D3DCOLORVALUE_
{
    float r;
    float g;
    float b;
    float a;
} D3DCOLORVALUE_ ;

int D3DCOLORVALUETOLONG_C( D3DCOLORVALUE_ *cv )
{
    int r,g,b,a,c;

    r = cv->r * 255;
    g = cv->g * 255;
    b = cv->b * 255;
    a = cv->a * 255;

    if( a > 127 )
    {
        a -= 128;
        c = a << 24 | 0x80000000;
        c |= r << 16;
        c |= g << 8 ;
        c |= b;
    }
    else
    {
        c = a << 24;
        c |= r << 16;
        c |= g << 8;
        c |= b;
    }
    return c;
}


With the Microsoft Visual C++ Toolkit 2003 compiler using /O2 /G6 optimizations, and linked the object module into my FreeBASIC test app, and running on my P3 I got these results (the cycle count order is empty loop, FB normal function, FB naked function, MASM, C):

VB code               :741F3C58
VB code -> FB syntax  :741F3C58
FB naked function     :741F3C58
MASM function (in DLL):741F3C58
Compiler optimized C  :741F3C58

0 cycles
78 cycles
31 cycles
30 cycles
33 cycles

0 cycles
78 cycles
31 cycles
30 cycles
33 cycles

0 cycles
78 cycles
31 cycles
30 cycles
33 cycles

0 cycles
78 cycles
31 cycles
30 cycles
33 cycles



Well Microsoft, here's another nice mess you've gotten us into.

mikorians

Ok JJ, it compiled.  Ran it, MsgBox: Fatal Error: GetLastError (line ??): One of the library files needed to run this application cannot be found.

MichaelW: Thank you for the statistics. They have been interesting and informative for my descision.  And the likelihood of me using C for any reason is 0

Now that I've chosen either FB or Masm, how shall we go about writing a targeted library file for DX8 for it?  Of course MichaelW, see our conversation on FB Forum.  (If it's you)

jj2007

Quote from: mikorians on October 28, 2012, 02:50:10 AM
Ok JJ, it compiled.  Ran it, MsgBox: Fatal Error: GetLastError (line ??): One of the library files needed to run this application cannot be found.

That could be gdiplus.dll or any other new dll that came along with XP. Sometimes
include \masm32\MasmBasic\MasmBasic.inc
MbUseErrLine = 1

helps to identify the culprit (it inserts extra code in each macro). Often, the XP dlls can be downloaded somewhere, but there is no guarantee that they work under Win98.

mikorians

#55
Thanks, JJ.  Added MbUseErrLine = 1:  Got your compiled sample exe to run finally -stupid me- it wanted the .dll file test.dll and i hadn't put it in the same directory.
Your source listing above (Oct 26) apparently compiled differently from the .exe you included in your .zip file.  Ran it.
621 cycles for the DLL
42 cycles for Assembler

I've written some applications in FreeBasic now, and find the environment enjoyable, so all I need now are examples of DirectX3D8 invocation in either FB or Asm.
Some kind of .bi wrapper would be appreciated.

I have found a wrapper set for PowerBasic if it could be adapted perhaps for FreeBasic, or---
http://www.rvalois.com.br/downloads/free/dx8vbtl/DX8IncTut.zip

Here was my attempt to convert/modify the relevant .bi files to point at the relevant libd3d8.dll.a library file
http://sites.google.com/site/mikorians/DX8 Demo (NG).zip

HAPPY HALLOWEEN

mikorians

OK, JJ --
MasmBasic's your baby.  I've been having a lot of trouble getting any 3D up with FreeBasic.
I can't run your editor, but the library loads, and we seem to compile things.

Can you give me a windows98 comatible example of a dll call like 'shimgvw' -- which 98 doesn't have ?  --  We did call MichaelW's test dll successfully, so that's encouraging.
We'll be trying in the future to access DX7 (for raw polygon power without the overhead)
You said you were game for this.

jj2007

Quote from: mikorians on November 03, 2012, 09:46:35 AM
Can you give me a windows98 comatible example of a dll call like 'shimgvw' -- which 98 doesn't have ?

Here is one. Don't give up on FreeBasic too early - MasmBasic is powerful, but many algos including the dynamic string engine use SSE2 and will crash with your CPU. But Dll & Declare should work. Try what happens if you activate the Print Str$ below  ::)

include \masm32\MasmBasic\MasmBasic.inc   ; download
.data
MyLowR8   REAL8 -123.4
MyHighR8   REAL8 456.7

   Init
   Dll "msvcrt"
   Declare floor, C:1   ; floor expects C calling convention and one argument

   push eax      ; create a slot for returning an integer from the FPU
   .if floor(MyLowR8)
      fistp stack   ; floor returns the value in ST0, so we need to drop it into the slot
   .else
      MsgBox 0, Str$("Error %i", eax), "Hi", MB_OK   ; never seen, it seems floor swallows everything...
   .endif
   pop ecx
   print str$(ecx), 9, "returned", 13, 10
   ; Print Str$("Result=%i",ecx), Str$(" for %f\n", MyLowR8)

   push eax      ; create a slot for returning an integer from the FPU
   void floor(MyHighR8)   ; instead of .if ..., we discard the return value
   fistp stack      ; (it's in eax, nonetheless, but we need the value returned in ecx)
   pop ecx
   print str$(ecx), 9, "returned", 13, 10
   ; Print Str$("Result=%i",ecx), Str$(" for %f\n", MyHighR8)

   Inkey
   Exit
end start

mikorians

-124    returned
456     returned
Result=4218990 for 456.7000

I'll check in at freebasic.
Been having a lot of luck with BlitzBasic3D --- Ever used it?

jj2007

#59
Quote from: mikorians on November 04, 2012, 04:51:58 AM
-124    returned
456     returned
Result=4218990 for 456.7000
So Dll/Declare works. I am surprised that Print works, it uses SSE2. But things like
print Str$("This is a float with nine digits precision: %9f\n", 3*PI)
print Str$("This is a float with nineteen digits precision: %Jf\n", PI)
should work, actually, i.e. combining Masm32 print (lowercase p) with MasmBasic Str$().

Quote
I'll check in at freebasic.
Been having a lot of luck with BlitzBasic3D --- Ever used it?

No. My experience with Basic is a bit of VB for Apps plus a lot of GfaBasic, and now MasmBasic.

EDIT: I attach an example with new Dll & Declare macros. Behaviour is identical except for the speed. Declare was not designed for innermost loops, so it called GetProcAddress all the time. The new version does it only once, so that should be a lot faster now.