UnderwareDESIGN

PlayBASIC => Show Case => Topic started by: kevin on November 14, 2013, 10:41:59 PM

Title: PlayBASIC To DLL (Development Blog)
Post by: kevin on November 14, 2013, 10:41:59 PM


(http://www.playbasic.com/screens/Tools/PB2DLL-Tool-Page-Logo-Smaller.png)


(http://underwaredesign.com/PlayBasicSig.png)

PlayBASIC To DLL Development Blog (Nov 15th, 2013 - May 25th 2019)


    This thread will document the final stages of development for the PlayBASIC to DLL conversion tool.  This is a tool to translate PlayBASIC byte code to machine code DLL's.  These DLL's can then be included in your program (bound internally and executed directly from memory) to give you execution speed as fast your system can manage.

    The tool uses the PlayBASIC V1.64P retail compiler (http://www.underwaredesign.com/?l=PlayBASIC-V164P-WIP-GALLERY) (at least) to convert your source code the byte code, the byte code is then translated to assembly and assembled to dll.   This models enables multiple levels of optimizations in the output code.   The PlayBASIC compiler includes many code optimization features from instruction redundancies through to structure caching at byte code level.  The assembly generation stage builds upon this further including things like inlining support with the ability to short cut and further simplify the original byte codes logic, giving a more stream lined and efficient result.

 

Download




 
Download  [plink] PlayBASIC2DLL - FREE EDITION (https://underwaredesign.com/requestfile.php?file=PB2DLLFE73sxhjak5sasf43xasfd254) [/plink]





FAQ about PlayBASIC To DLL






Q. Will PlayBASIC To DLL work with the FREE learning editions or demo's

       A.  No, it's built as a companion tool for the retail editions.



Q. Is this going to be free ?

       A.  No.  The product will retail for $49.99 US,  with a cheaper edition available to the PlayBASIC community first (Note: Community Edition released 3rd,June,2014 - Community Special (http://www.underwaredesign.com/forums/index.php?topic=4199.0)).    You'll of course need a retail version of PlayBASIC for it to be of any use !



Q. Are updates to this product FREE ?

       A.  Yes, they'll be free for the life of the product.



Q. Can I Beta Test or get a Freebie ?

       A.  Possibly, but you'd need to really show a high level of PlayBASIC expertise to be considered.



Q. Where can find the older PlayBASIC To DLL Blog ?

       A.  Like the majority of projects here, this tool started it's life as private project.  Forum members can be read about the early stages of the project   [plink]Here (http://www.underwaredesign.com/forums/index.php?topic=4077.0)[/plink]



Q. Can I use the DLL's produced with other BASIC's or C ?

       A. No ,  the exported code is completely dependent upon PlayBASIC. So without PlayBASIC they won't function.



Q. How long does it take to convert PlayBASIC source code to Machine Code DLL?

       A. Depends on the size of the program.  But generally it's only few seconds from source code to end machine code dll.   The PlayBASIC compiler does all the really heavy lifting and is capable of compile speed beyond 10,000 lines per second on a single core system.   The end translation to assembly and final assembly passes are routinely inside a second.    



Q. What version of PlayBASIC does PB2DLL work with ?

       A. It requires a minimum of PlayBASIC V1.64P (or it's betas)



Q. Can I use PB2DLL dll's with the Free Learning Editions of PlayBASIC ?

       A. No, the learning edition is 3 years behind the current retail edition. If the learning edition is updated to to the V1.64P specification, then you could use DLL's with it..



Q. Does PB2DLL optimized my programs code or does it just convert it to machine code ?

       A. Yes, PB2DLL does indeed make further optimizations to your program during translation.  The program is optimized twice.  The source code it first translated to byte code using PlayBASIC (retail) compiler, the compiler has many optimizations built in that will reduce the output byte code to the minimum set of operations possible.   When PB2DLL translates your program, it's translating the Byte code representation of your source.  Here it can make further optimizations that the PB compiler can't such as removing the ambiguous nature of some byte code operations or in-lining the operation for you.  Depending upon the operation these short cuts and trim out a massive amount of 'function' calling overhead that would be experienced running the byte code through the the PB runtimes.






Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on November 17, 2013, 10:51:04 PM
  PlayBASIC To Dll  - Support for Globals - Program Re-Composition

         Up until this today the translator focused purely on user functions in the byte code.  So functions named with "DLL_"  would be exported and publicly addressed.   The only problem is that those functions couldn't really set up global data on the dll side.  So the function pretty much had to be standalone.  Which is fine for a lot of stuff, but there are situations where it's easier if the data was handled on the dll side.   So you can just export the code over to  DLL and forget.  

         For example, let's say you want to build a command set like a menu system.  What we could do is pass in/out typed pointers to the menu items as we need.  But this means the user is managing most of the data.   It'd be easier if the DLL side managed the data and just gave us an idiot proof interface to our command set.  So the data is hidden inside the DLL conceptually.  

         Generally for something like this we'd just dimension/create some array that's global to our helper functions, which are then built upon startup with a bunch of  Creation and Get/Set functions to manage the properties of the objects.  

         Eg,

[pbcode]

   Type MenuThing
          Name$
          TExt$
          X,Y
 etc etc
   EndTYpe

   Dim Menu(0) as MenuThing


Function DLL_NewMenu(GadgetName$,DisplayText$)
     index=getfreecell(_Menu())

     Menu(index) = new MenuThing
     Menu(index).Name$=upper$(GadgetName$)
     Menu(index).Text$  =DisplayText$

EndFunction Index


Function DLL_GetMenuStatus(Index)
    Status=ValidMenu(Index)
endFunction Status


Function DLL_DeleteMenu(Index)
    if ValidMenu(Index)
               Menu(Index) = Null
    endif
endFunction


Psub ValidMenu(Index)
   Status=0
    if Index>0
     if Index<=GetArrayElements(Menu())
               Status=Menu(Index)<>0
     endif
    endif
EndPsub Status

 etc etc

[/pbcode]


      So what today's build does, is it takes the 'global code'  and builds it into a sub routine that's called when the DLL is initialized by windows.  Basically the same as how C/C++ programs start up.  The only difference is you don't have a forced entry point.   Without this, the 'menu' array in this example would never exist and you'd have to manage it (create it) from inside the sibling functions.  Which isn't that difficult, but this way is really no different that normal PlayBASIC code.   You can of course have your own initialize function as part of your dll.   But the global code in the file will be executed before that.  

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on November 19, 2013, 10:24:29 PM
  PlayBASIC To Dll  - Select Statement Support

        Unlike most of the control statements Select/Case statement blocks are only now being implemented in the translator.  PlayBASIC's support for  Select Cases is rather unique. Generally select/switch statement blocks are explicitly literal, so cases must be constant.   Which helps the compiler back end when producing the appropriate logic.   The assumption most programmers make, is  their low level compiler is building a jump table, but this actually isn't true.  Visual C/C++ produces a range of different solutions for switch statements, as the input data has to fit the jump table model, even then, it often doesn't .

        In the most BASIC languages (PB included)  select/case block are generally nothing more elaborate IF/EndIF structures. The benefit being the 'select variable' can be cached on register unlike a block of user IF/Then statements.  The caching removes most of memory access when falling through the structure.    Converting this logic directly to assembly is a cake walk and will certainly perform very well.    Hey, if it's good enough for visual C it's good enough for us :)  

        However, the PlayBASIC compiler & runtime times support Variables, expressions, floats  and even strings in case statements.  So you can really mix up the anything you like into them (within reason).   This means the translator has to look ahead at any following case statements when producing code to try and suss out if a register can be cached or not.   The current version doesn't bother with that for a minute, just wanted to get the structure up and running first.

        Here's the current working test code, in this example we're building an Integer select on the A Variable with literal case matching.
       
[pbcode]

Function DLL_SelectCase(A,b#,s$)

      
      Select A
         case 0
            print "a=0"
         case 1
            print "a=1"
         case 5 to 2   
            print "a=2 to 5"

         case 10,6,7,8,9
            print "a=6,7,8,9,10"
            
         default
            print "no Match"
            
      EndSelect
   
EndFunction

[/pbcode]

      The translator already includes generation logic to pre-flips literal case terms and sorts + recast case rows into order.   So in the case 10,6,7,8,9 line, the literals are pre-sorted.  If the set has more than 3 values it inserts a bounds check for you.    So if the select variable is outside the range, it moves on without falling through this block of compares.    


     Edit #1:

        Working on dynamic versions of the select statement block.   The dynamic versions gives the exporter support for variables in case statements.  The  current focus is getting a good range detection without branching.   Have worked out way, but it's behavior is different from the VM.  The VM treats the range as inclusive ->inclusive, but the assembly version is currently inclusive->exclusive.   Which might not sound like a big deal but the behavior then is different between the two.

[pbcode]

Function DLL_IntegerSelectCaseTest(A )

         b#=123.456
         Variable=15
         Variable2=20


         r1=50
         r2=60
      
         Select A
            case 0
               result=0
            case 1
               result=1
            case 5 to 2   
               result=2
   
            case 10,6,7,8,9
               result=3
            
            case 66.5
               result=4

            case Variable
               result=5

            case B#
               result=6


            case Variable to 20
               result=7

            case r1 to r2
               result=8

            default
               result=-1
         EndSelect
   
   
EndFunction result

[/pbcode]

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on November 24, 2013, 11:24:37 PM

  PlayBASIC To Dll  - Floating Point Select Statement Support

        Today's little chore was to add support for floating point select statements.  Unlike the integer support, floats are pretty chunky in x86 making it difficult to implement boolean styled logic without branches.  Which is pretty annoying given the cost of a miss predicted branch in x86 is _very_ high.    But after an afternoon of testing, it does seem like the only way to get a reasonable result.  Eliminating the branches is possible, but the state handling seems to really impede any benefit, at least that what I get from testing on my test machines.     


        Meaning this is possible in the translator now.

[pbcode]

Function DLL_test_Float_select(a#)


   Print "Floating Select VALUE:"+Str$(a#)
   Select a#

       Case 5.7,5.8,5.9
           Print "yeah i'm in th list of options"

       Case 1.5
             Print "yeah i'm the first option"
     
       Case 1.5
             Print " i'm the first option AGAIN ?"

       Case 2.5
           Print "yeah i'm second option"
      
       Case 3.5
           Print "yeah i'm third option"

      Case 7.6 To 66.7
         Print  "with the Range 7.6 To 66.7"

      Case Test1+test2
         Print "Matched the Test Cases"

      Default
         Print "didn't match anything"

EndSelect

Print ""
EndFunction

[/pbcode]       


        After some consideration I'd probably recommend users convert their floating point select case statements to integer.   

         Something like this would probably be faster at runtme. 

[pbcode]

Function DLL_test_Float_select(a#)


        Key = Floor(a#*10)

   Print "Floating Select VALUE:"+Str$(a#)
   Select Key

       Case 57,58,59
           Print "yeah i'm in th list of options"

       Case 15
             Print "yeah i'm the first option"
     
       Case 15
             Print " i'm the first option AGAIN ?"

       Case 25
           Print "yeah i'm second option"
      
       Case 35
           Print "yeah i'm third option"

      Case 76 To 667
         Print  "with the Range 7.6 To 66.7"

      Case (Test1+test2)*10
         Print "Matched the Test Cases"

      Default
         Print "didn't match anything"

EndSelect

Print ""
EndFunction

[/pbcode]       
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on November 26, 2013, 11:19:49 PM
  PlayBASIC To Dll  - String Select Case Statements Supported

        String selects were the only version of the structure missing from the translator, which has now been addressed.  The string exporter isn't too smart and literally equates to a series of string compares, even so, it'll still be faster than the generic VM versions.    What the exporter is really missing is some logic to seek ahead and cache the strings better.   Which would help when a series of the cases can be skipped when a likely match is found, but that'll have to remain on the TODO: list for now.


[pbcode]

Function DLL_test_String_Select(a$)

   Print "String Select String: "+a$

   Select lower$(a$)

      Case "hello"
         Print "im option one"

      Case "world"
         Print "im option two"

      Case "a" To "g"
         Print "im from A-G"

      Case "mon","tue","wed","thurs","fri"
         Print "Days of the week I don't like"

      Case "sun","sat"
         Print "The two best days of the week, Sat/Sun"

      Default
      Print "didn't match any options"
   EndSelect
Print ""

EndFunction


[/pbcode]



  PlayBASIC To Dll  - Operators Support Mixes of Data Types


         The AND, OR & XOR operators have been in for a while, but it only supported Integers, where the VM actually supports mixtures of integer and floats.   If one term is a float it's recast to integer for you, but still it supports them.  Thus the translator should behave the same way.


[pbcode]

Function DLL_AND(A,B)

   a#=A
   b#=B
   
   print A and 255
   print A# and 255
   print 255 and B
   print 255 and B#
   print A and B
   print A and B#
   print A# and B#
   
EndFunction

[/pbcode]







Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on December 03, 2013, 09:14:09 AM
 PlayBASIC To Dll  - Flex Rotater

       This is something of a tech demo, much like the fractal render from a while back.   The idea here being to take a bigger chunk of code (in this case an old Amiga demo effect) and and build that into a DLL library.    The routine is an old z rotater styled effect where the spans are rotated and the result is drawn pixel by pixel to the screen.   The render loop is interpolating 800*600 pixels and drawing them via the awfuly generic FastDot.   Moveover the texture fetch is just reading a 2D integer array.   So the code was slapped together out to work, rather than be fast.        

      Running the original routine on the PB VM returns about a 500 plus millisecond refresh on my Athlon system.  The first conversion to DLL cuts that to about 61-62 milliseconds.  I suspect that once the array reading and fastdot are removed, it'll be possible to at least double possible triple that.     The only trouble at the moment is the machine code version isn't acting the same the VM version.  So there's some math operation not behaving the same way.


      Bellow is an example of what the original effect running on the Amiga looks like.

     




Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on December 03, 2013, 11:27:35 PM
  PlayBASIC To Dll  - Flex Rotater Test

           The issues mentioned above turned out to be pretty easy to track down, there was problem with the external trig library using radians rather than degrees and the other main issue was some array accessing of data that didn't exist making it crash.    It's still possible to crash at some arbitrary angles when some operation hits infinity in the  FPU, but that also occurs in the VM.   Beyond that, there's still a couple slight differences in the machine code version, but nothing all that taxing to work around for the time being.

           The rotater is based on linear interpolation, where it drawn strips between pairs of rotated 3D points each each scan line of the display. The spans are longer than the texture width in 3D space, so the UV coords are masked to keep them within the texture space (512 *512), which is what makes it repeat.  Simple to do today, but anything but back in the Amiga days.  

            The main work horse routine is the pixel interpolation, the demo includes 3 versions, there's a version that fetchs the texture from a 2D array and plots the dots via FastDot, as well as version that reads the texture from a bank and plots the dots via fastdot and the 3rd version writes directly to the screen in 32bit pixels.   The last one is quickest in the DLL, but slowest on the VM since it's emulating pixel reading and writing.   So those costs are magnified.    

            The attached code requires PlayBASIC V1.64P beta 18 to work correctly, it'll run in beta 16, but the rotation will stutter.  You might be able to fix that by first converting the angles to radians..


 Attached
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: monkeybot on December 05, 2013, 12:41:09 PM
hmm that's pretty impressive.
when is PB>Dll coming out then?
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on December 05, 2013, 11:43:59 PM
  There's still a bit to do, the arrays command sets aren't yet supported for example.  Getting all the side to function the same is pretty time consuming.   Then there's Gui->Doc's->website etc etc.     There's bound to be some version prior to that though.

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: monkeybot on December 06, 2013, 06:37:13 AM
I would be more than happy to help Beta testing!   ::)
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on December 06, 2013, 08:50:42 PM
Quote from: monkeybot on December 06, 2013, 06:37:13 AM
I would be more than happy to help Beta testing!   ::)


  It's possible, even probably I might say..  Although,  Why I do have a feeling that my idea of beta testing is little bit different than others. :)

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on December 06, 2013, 09:37:40 PM

  PlayBASIC To Dll  - Array Library

       The foundation of Arrays and Types have been in for a while now, but the Array command sets are still missing.   There's a few reasons for this, but the main one is that the existing library isn't particular friendly due to how VM dependent it is.    So the only way forward is to build a set of the commands that are free of the VM constraints.    Thankfully I've already got a couple of editions of most of this code in different forms, having tried various constructions over the years.

       One of the major differences between the two sides, is the VM editions decode the VM opcodes as well as performing the actions.  Therefore most instructions have logic in them to solve the passed data based on it's data type.  The machine code editions don't really need such logic, since the generator can solve this during translation.    Cutting a tiny a bit of fat from each process at runtime.    Another way to do that is pre-solve the arrays 'bank' when it's handle is written.

       Arrays in PlayBASIC are considered safe houses.   That's because the runtime always checks the existence of the array data/memory  before it lets you read or write to it.  Even so, it's still possible to crash in certain circumstances, but it's generally much safer for users.   One idea lifted from the VM3 model is to use a structure in the array table that contains not only the data bank of the array, but other information such as it's raw pointer and anything else that may be needed.    This eliminates the need to query the VM's manager about the validity of an array every time.  Much like now, there's probably still some situations where that'd break though.    The upside would be that there's one less function call in every read/write of array/type data.   Which obviously means better performance, without a huge culture shock for programmers.

       So far there's not much to show for an afternoons work with only a couple of query functions working, ran into a crash on exit problem yesterday that put the breaks on my progress.  Turned out to be that the variable table (which has to be rebuilt during export) could sometimes be a bit too small.  So the array functions were writing outside of allocated memory.  Easy to fix, but took a while to diagnose..

[pbcode]

Function DLL_Array_Functions(Size)

      Dim Stuff(Size)
      
      if Size>10
         Dim Stuff2(Size)
      endif

      print GetArrayStatus(Stuff())
      print GetArrayStatus(Stuff2())

      print GetArrayElements(Stuff(),1)
      print GetArrayDimensions(Stuff())
      
EndFunction

[/pbcode]
 
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: monkeybot on December 07, 2013, 10:40:43 AM
QuoteIt's possible, even probably I might say..  Although,  Why I do have a feeling that my idea of beta testing is little bit different than others.

you will have to create some caveats.
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on December 10, 2013, 09:26:30 PM

PlayBASIC To Dll  - Array Library Cont.

      Slow going at the moment due to a lot of external pressures that have cropped up besides the normal Xmas mumbo jumbo.  The result is that I can only work on this when free time appears, often very late at night.   So perhaps a couple of hours a day, which isn't much.    None the less, still pressing ahead with the Array library, which basically goes like this.   Write/import an operation and make it friendly for the new array structures, then write translation code for PlayBASIC To DLL,  run some tests and try and correct any wacky results.    It's not really a lot of coding persay,  it's just all the time consuming  junk  around that.   

      The Array library is really built on top of two foundation functions, the DIM and UNDIM commands as you know them.   The DIM does all the heavy lifting to create a nice new fresh array, where as UNDIM does all the heavy lifting to destroy this structure.   Of the two, the UnDim process is the more complicated for the DLL side.   Since when we release an array, it not only releases the main buffer, but any associated buffers with it.   Such as strings in string array for example.     Strings are easy enough but the Types are somewhat problematic as the DLL side needs it's own local cope of the local types.. So another slab of data that needs to be dragged across.  It's only necessary really so the DLL side an build a compatible decoder structure for the central type interface.     


      Here's about where these command are current at.  Pretty basic, but hopefully once the type interface stuff is sorted, progress with this library should be easier.

[pbcode]

   Type Dude2
         x,y,z
         s$
   endtype

;   END
Function DLL_Array_Functions(Size)

      Dim Stuff(Size)
      if Size>10
         Dim Stuff2(Size)
      endif
      print GetArrayStatus(Stuff())
      print GetArrayStatus(Stuff2())
      print GetArrayElements(Stuff(),1)
      print GetArrayDimensions(Stuff())


      UNdim Stuff()
      print "Stuff status"
      print GetArrayStatus(Stuff())

      Dim Cool(1000) as Dude2
            
      Dim S$(1000)
      
      For lp =0 to 1000
               S$(lp)="This String "+Str$(lp)
               Cool(lp)= new dude
               Cool(lp).s$="This String "+Str$(lp)
      next

   ;   undim Cool()
      undim s$()


EndFunction

[/pbcode]
   

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on December 12, 2013, 09:23:21 PM
 PlayBASIC To Dll  -  User Define Types.

    Support for UDT's has been in the translator for a few weeks, perhaps even a month now, but the translation is still pretty naive.   Namely the DLL side didn't have any understanding the actual type structures.  So you could create a type and stick them an array on the dll side, but if you tried to delete them or copy them then the dll just didn't have that information available to it.    What it needed is it's own local version of the type descriptions inside the DLL,  which is really a table of how a type structure lays out in memory.   So when that type is clear/deleted, any known buffers such as strings can be released from structure.    Without this, they'd leek strings.

    The last few session have been focused on getting the translator to build the tables required and then filling in the back end code to help initialize everything on startup.    The structures aren't anything all that exciting (as you can see bellow). But they give us all the information necessary to deal with typed structures of memory.
     


       ; ---------------------------------------------------------------------
       UDT_dude2:
       ; ---------------------------------------------------------------------
               dd  String_1
               dd 5
               dd 16
               dd UDT_dude2_Fields


               UDT_dude2_Fields:
                       dd  String_2      ,0      ,0
                       dd  String_3      ,0      ,4
                       dd  String_4      ,4      ,4
                       dd  String_5      ,8      ,4
                       dd  String_6      ,12     ,4




    One of the complexities with this project is that data passing needs to work seamlessly between the VM and any DLL libraries.   So a typed array created on the VM side can be passed to the a DLL function and modified by that function and vice versa.   To do that, you'll need a copy of the structure on both sides of the communication.   So your external dll is built against the structure, and you regular VM code also includes a copy of the same structure.  They have to be identical, if they're not, it'll fail ! -

    For some libraries you won't need to share structures at all, since the library will act like a black box and just give the user a set of high level functions, where all the data is housed internally.    

    I've got the all the components in but it's not running, as currently there's a strange crashing when writing to a newly allocated type, should just a matter of back tracking to find out what's broken.  

      Edit #1

      Finally found the what i think was the cause of type allocation and deletion problems on the DLL,  it just turned out to be a slight difference in the definition structure.   Fine by me as it's working again..  yay.. sleep time


Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on December 15, 2013, 08:59:28 AM
  PlayBASIC To Dll  -  User Define Types - Addressing the same ground.

         I've been testing the translation tonight hunting down those little gotchas in some bare bones type demos.    Found one such issue where PB would crash on exit when a typed array created inside the dll was returned to the VM.   Initially was thinking it was caused due to some difference between the Undim process in the VM, which is called when the VM exists.   This was a close guess, but it turned out to be just the order in which some of the vm libraries release themselves.   VM would release any bound resources such as DLL's before it release the array memory.  This is no problem when all the array data is created locally in the VM, but it's a big issue when the arrays point to structure definitions inside the DLL.   Which would cause access violations and hence the crash.

         Today's build gets us to a  point where the DLL side and VM side can create a type and other side can release it.  This allows the flow of data from VM to DLL and DLL to VM more freely.   Even so, i'd still recommend at least trying to keep the data life cycle management to one side or the other, but it's workable if you can't wrap your head around that.    If this all sounds familiar it's because a few months back I had to rewrite how the VM deals with it's local types.   In the older editions the VM maintains one central list.   Which is fine in a world where 3rd party code isn't expected to plug into the VM, but bound DLL's need to be able to control data much the same way the vm does.   There's other solutions of course, but altering it to support host structures seems the most workable.  


        All this messing around means you can finally do this, bellow we have a function that we'd export to Dll and bellow that is some code that accepts the returned structure..
 
[pbcode]

 // Declare structure on DLL side.. The VM will need a copy of this also if you indent to look at the fields in the types..
Type Dude2
         xxxx,yyyy,zzzz
         string$
   endtype


Function DLL_FillArray(Size)

      Dim Cool(size) as Dude2
            
      For lp =0 to size
               Cool(lp)= new dude2
               Cool(lp).xxxx=100+lp
               Cool(lp).yyyy=200+lp
               Cool(lp).zzzz=300+lp
               Cool(lp).string$="This String "+Str$(lp)
      next


EndFunction Cool() as Dude2


[/pbcode]


     The dll code just creates a junk array and fills it with some data, before returning the array handle upon completion back to the caller, the VM side.

[pbcode]

linkDLL  "testdll.dll"
      DLL_FillArray(Size) alias "fillarray" as integer
EndLinkDLL

 // Declare structure on VM side
      Type Dude2
            x,y,z
            Name$
      endtype


    // Dim our reciever array as type DUDe2
      Dim K(0) as dude2

    // Call our DLL function and assign the array handle to our K() array
      k()= DLL_FillArray(10)

    // query the contents of it
      if GetArrayStatus(k())
            for lp=0 to GetArrayElements(k())
               print k(lp)
               print k(lp).x
               print k(lp).y
               print k(lp).z
               print k(lp).name$
            next
      endif
      
      print "done"
      Sync
      waitnokey
      waitkey

[/pbcode]

      The VM side is just running through the contents of the array and dumping them to the screen.   Now much of an example, but it's fairly seamless.  There's a couple of oddity that appear in the debugger if you looked at the contents of the k() array in the VM after it was created externally, but those seem from the DLL's dimension instruction not classifying the arrays structure.  So it doesn't know the original 'name' of the type.


       Edit #1 - Debugger Name Resolving

        One problem i'd been having with structures passed back from a DLL was that if you clicked on them in the debugger the structure names would be wrong, but that seems to be now fixed..   As if you got to variables and click on k() array, it drops the info into the panel as normal.   






Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on December 18, 2013, 10:26:00 PM
  PlayBASIC To Dll  -  Redim - Life cycle of arrays & LIsts

        Pretty much all PB's data structures uses the same interface, that being the array interface.   Most of the legacy code i'm ok with, some of it i'm updating to bring in some of the newer ideas explored in it's descendants.     Haven't had much time to really chomp through it, but what I have been slowly working up the core routine with their support code.  One such replacement routine was the ReDIM function,  which is a lot more complicated than the DIM operation.

        Dim is fairly dumb, it just creates some empty (formatted) space for the array.  There's a little more to it than that, but conceptually that's about it.  ReDIM on the other had has to rebuild the structure when the sizes are different.   If you make an array larger, then it allocates some new memory and copies the old data across,  the same goes for shrinking an array.  It copies the existing data,not forgetting to deletes any excess.    Which can be an easy way to leak resources if you're not careful.   See-> Tips On Safe Resource Management: (http://www.underwaredesign.com/forums/index.php?topic=4029.0)

        The other thing i've been working on is the back end support for the linked lists.   A link list is an optional extension to the array structure, so when a list is present the address resolver uses the structures internal current position.    So far it's in a very bare bones state, due to how interdependent some of the back end actually is when dealing with lists.   For example the list iterators are set up, but insertions don't work because that requires insertion management of the arrays size,  hence the need for ReDIM.      

        But here's a general idea of where it was at last night..  

[pbcode]

   
Function DLL_ResizeArray(Size)

   Dim Cool(Size)
   
   For lp =0 to Size
         Cool(lp)=1+Rnd(10000)
   next
   
   redim Cool(Size+10)

EndFUnction   COol()


   Type Dude2
         xxxx,yyyy,zzzz
         string$
   endtype


Function Dll_TestLIst(Size)

         Dim Z as dude2
         Dim L as dude2 list

         For lp=1 to size
               l=new dude2
               l.xxxx=lp
               print l.xxxx
         next

EndFunction L.Dude2

[/pbcode]

       I think it should be smoother sailing once all the little inter-dependencies have been ironed out.      


 PlayBASIC To Dll  -  Macros make the world turn faster

       The back end assembly is built with flat assembler which has some very impressive macro support, most of which is way beyond the scope of the project and my understanding of it :).   However,  macro's can be a very powerful approach to programming, in particular in assembly, as they allows the user to dramatically reduce the lines of code, where a common behavior is wrapped as a macro and used throughout the project.  It's a bit like a function, except the macros are parsed out by the assembler at compile time. So all the code is inlined.  

       So what i've been doing is moving more of the code in the base template into macros.  You could pretty much make macro's for all the core operations,  which would simplify PlayBASIC to Dll's job by hiding how something works away in the template.   The current build of the generator is pretty reactionary, so when it sees some known byte code pattern it spits out the same' template assembly chunk in reply.  Such things could well be macro'd,  allowing improvement to be make to the template and not only via the translator.

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on December 19, 2013, 11:00:39 PM
 PlayBASIC To Dll  -  Linked Lists

         The temperature has been unseasonable hot here lately, pushing 40 degrees outside yesterday  and it wasn't much better in the office.   Which has a pretty negative impact upon code productivity, but none the less we crawl forward in the little time I have left.    Since it's easier working at nights now, last nights session moved the translations to a point where Linked Lists controls started working.   There's still a few missing tidbits, but you can dim a list, fill it full of stuff and iterate back through it.     I think deletion is currently missing and the query style functions aren't added, but the guts of it seems to be functioning now.

 
[pbcode]

   Type Dude2
         xxxx,yyyy,zzzz
         string$
   endtype


Function Dll_TestLIst(Size)

         Dim Z as dude2
         Dim L as dude2 list

         For lp=1 to size
               l=new dude2
               l.xxxx=lp
               l.string$="Stuff"+str$(lp)
         next

         Count=0
         for each l()
               print l.xxxx
               print l.string$
         next

EndFunction L.Dude2

[/pbcode]


       Edit #1

       Most of the list commands are now in the translated version.

[pbcode]

Function Dll_TestLIst(Size)

         Dim Z as dude2
         Dim L as dude2 list

         For lp=1 to size
               l=new dude2
               l.xxxx=lp
               l.string$="Stuff"+str$(lp)
         next


         print "List Size:"+Str$(GetListSize(l()))

         print "List First:"+Str$(GetListFirst(l()))

         Count=1
         for each l()
               Count++
               if COunt=5
                     print "Deleting five from list"
                     l = null               
               endif

               print str$(l.xxxx) +"  "+ l.string$
               print "List Pos:"+Str$(GetListPos(l()))  + "  Previous:"+Str$(GetListPrevious(l())) + "  Next:"+Str$(GetListNext(l()))+ "  Ptr:"+Str$(int(GetListPtr(l())))            


         next

         print "List Size:"+Str$(GetListSize(l()))

EndFunction L.Dude2




[/pbcode]

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on December 22, 2013, 08:22:27 AM
PlayBASIC To Dll  -  Array Functions

        The MoveArray & SwapArray functions were next on the list, so they're now in and running.


[pbcode]
   
Function DLL_SWAPANDMOVEARRAY(SIze)

   DIm Test(Size)
   Dim Dude(Size*2)

   For lp=0 to size
         test(lp)=lp
   next

   For lp=0 to size*2
         dude(lp)=lp+2000
   next

   print "Sizes before swap"
   print GetArrayElements(Test())   
   print GetArrayElements(Dude())   

   swaparray Test(),Dude()
   
   print "Sizes after swap"
   print GetArrayElements(Test())   
   print GetArrayElements(Dude())   

   print "Data in test array"     
   For lp =0 to GetArrayElements(Test())
          print Test(lp)
   next


   print GetArrayStatus(Test())   
   print GetArrayStatus(Dude())   

   movearray Test(),Dude()

   print GetArrayStatus(Test())   
   print GetArrayStatus(Dude())   

   print "Data in test array"     
   For lp =0 to GetArrayElements(Dude())
          print Dude(lp)
   next

EndFUnction Test()   

[/pbcode]



        EDIT

          Added SortArray,  supports integer, float and string arrays.    The string version is still pretty slow (it's the same as VM version), will likely change that at some point in the future.

[pbcode]
   
Function DLL_SWAPANDMOVEARRAY(SIze)

   DIm Test(Size)
   Dim Dude(Size*2)

   For lp=0 to size
         test(lp)=lp
   next

   For lp=0 to size*2
         dude(lp)=2000-lp
   next

   print "Sizes before swap"
   print GetArrayElements(Test())   
   print GetArrayElements(Dude())   

   swaparray Test(),Dude()
   
   print "Sizes after swap"
   print GetArrayElements(Test())   
   print GetArrayElements(Dude())   

   print "Data in test array"     
   For lp =0 to GetArrayElements(Test())
          print Test(lp)
   next


   print GetArrayStatus(Test())   
   print GetArrayStatus(Dude())   

   movearray Test(),Dude()

   print GetArrayStatus(Test())   
   print GetArrayStatus(Dude())   

   print "Data in test array"     
   For lp =0 to GetArrayElements(Dude())
          print Dude(lp)
   next

   SortArray Dude(),0,100

   print "Sorted data in test array"     
   For lp =0 to GetArrayElements(Dude())
          print Dude(lp)
   next

EndFunction Test()   

[/pbcode]
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: cybermind on January 10, 2014, 09:31:13 AM
I am trying to sort a string array with 830 elements. The program stops when it hits the sortarray command. If I change the last parameter of sortarray to 10 it works.

This is part of my inventory code, the program halts when it touches sortarray :-( Am I doing something wrong? Do you need more data?

if current_in_game_menu_selected$ = "Inventory"
u = 0
dim inventory_list$(830,2)
dim sortable_inventory_list$(830)
for t = 1 to 830
if item_holding(t) > 0
inc u
`transfer item name
inventory_list$(u,1) = item_text$(t,1)
`set pointer to item position in original inventory array
inventory_list$(u,2) = str$(t)
no_items_in_inventory = 0
current_selected_inventory_item = 1
first_item_to_show_in_inventory = 1
`make string for adding correct number of zero's to sortable inventory list number
if t < 10 then zero_string$ = "00"
if t > 9 and t < 100 then zero_string$ = "0"
if t > 99 then zero_string$ = ""
sortable_inventory_list$(t) = item_text$(t,1)+zero_string$
endif
next t
sortarray sortable_inventory_list$(),0,830
for t = 1 to 830
if sortable_inventory_list$(t) <> ""
length = len(sortable_inventory_list$(t)) - 3
inventory_list$(val(right$(sortable_inventory_list$(t),3)),1) = left$(sortable_inventory_list$(t),length)
inventory_list$(val(right$(sortable_inventory_list$(t),3)),2) = str$(val(right$(sortable_inventory_list$(t),3)))
endif
next t
if u = 0
current_selected_inventory_item = 0
no_items_in_inventory = 1
endif
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on January 10, 2014, 09:43:09 AM
 why would you post that here ?  when here (http://www.underwaredesign.com/forums/index.php?board=13.0) seems like a much more appropriate place
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on January 11, 2014, 07:28:43 AM
PlayBASIC To Dll  -  Array Searching Functions

        Added a replacements for the  FindArrayCell & SearchLowest/Highest functions.    I'm not too keen on the behavior of the lowest / highest functions really, since they seem to skims the entire data set only returning when complete, was expecting it to only return when the data was bellow the users  threshold.    

       
[pbcode]

Function DLL_SearchArrayTest(Size)

   Dim Table(100)
   
   for lp =0 to Size
         Table(lp)=1000+lp
   next   

   Print FindArrayCell(Table(),0,1,size+1,1010)
   Print FindArrayCell(Table(),Size,-1,size+1,1010)

   Print SearchLowestArrayCell(Table(),0      ,1   ,size+1   ,1010)
   Print SearchLowestArrayCell(Table(),Size   ,-1,size+1   ,1010)

   Print SearchHighestArrayCell(Table(),0      ,1   ,size+1   ,1010)
   Print SearchHighestArrayCell(Table(),Size   ,-1,size+1   ,1010)

EndFunction   

[/pbcode]


      EDIT #1: 

         Added the replacement split to array function, this one is lifted from VM3 couldn't be bothered with writing it again :)

[pbcode]

Function DLL_SplitToArray(S$)

   Dim Table(1)
   Dim Table#(1)
   Dim Table$(1)
   
   Count=SplitToArray(S$,",",Table(),0)
   Count=SplitToArray(S$,",",Table#(),0)
   Count=SplitToArray(S$,",",Table$(),0)
   
   print Count
   For lp =0 to Count-1
         print " "+str$(Table(lp))
         print "#"+str$(Table#(lp))
         print "String="+Table$(lp)
   next
   

EndFunction

[/pbcode]



Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on January 15, 2014, 07:55:33 AM

  PlayBASIC To Dll  -  CopyArray and CopyArrayCells

       It's summer time here and we're in the middle of a heat wave for our region (most of the country really), so long stints in the tiny office are virtually out of the question,  only short sessions for most of this week.  None the less, rewrote a couple more functions from the array library, those being the CopyArray and CopyArrayCells functions.  CopyArray does exactly that, it copies the entire source array (integer/float/string or typed) and places the newly created structure in the destination array.     CopyArrayCells  lets the programmer copy a run of cells between arrays of the same type from one to another.  It also supports integer / float / string and typed arrays, but doesn't support combinations.     It's tempting to drop in some combo modes for the Cells variant, while i doubt it'd get used,   if you have an array full of numeric strings then could Copy all of them or section directly to the Integer and or float array, and it's convert them for you,  much like what SplitToArray does.

      Here's our regular junk test code. 

[pbcode]

   Type GoodStuff
         a
         b#
         c$
   endtype

   makearray b().goodstuff

   for lp =0 to 10
      s$+=str$(rnd(100))+","
      s$+=str$(rndrange#(1000,2000))+","
      s$+="cool"+str$(rndrange#(10000,20000))+","
   next

   b()=DLL_CopyArrayCells(s$)
   
   Sync
   waitkey
   
[/pbcode]


      This is the function that's been exported to our test DLL.   The routine just splits the input string with SplitToArray, then copies those fragments into a local typed array,  where it copies some cells from that into another array.  The code doesn't  do anything at all useful, but it works and that's all that matters right now.

[pbcode]

Function DLL_CopyArrayCells(S$)

   Dim Table$(256)
   Count=SplitToArray(S$,",",Table$(),0)

   print COunt
   
   Dim d(Count/3) as goodstuff

   for lp =0 to (count/3)-1   
      d(lp)= new goodstuff
   
      d(lp).a    =val(Table$(Index)) : Index++
      d(lp).b# =val#(Table$(Index)) : Index++
      d(lp).c$ =Table$(Index) : Index++
   next

   Dim output(100) as goodstuff

   CopyArrayCells D(),0,1,Output(),50,1,Index

Endfunction Output().GoodStuff

[/pbcode]

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on January 22, 2014, 11:35:10 AM

  PlayBASIC To Dll  -  Data Statements


      There's only a few tidbits left in the entire conversion felt to do and DATA statement support is one of them.    Initially I wasn't going to bother with them, in favor of resource binding, but local data is probably easier for most people to wrap their heads around.  There's a few gotcha's with exporting data to our DLL's though and that's visibility.    In the VM data is global regardless of where it's defined, so the data heap exists outside of the program code.    Now if you compile a PlayBASIC source to DLL that has Data in it,  now the question is who should have access to that data.

      It's viable that the VM could retrieve any local data from the a bound dll and pull it into the global pool on the VM side, but then the dll's have to use the VM access.   Which is about as painful as it sounds !  - I think i'd much rather that any data be local to it's dll, which makes a lot more sense in terms of encapsulation anyway.   If the dll's shared data with the main program this could affect the users code in the VM or even in other bound dll's.   Making it a slippery slope.   

      The DATA command set was re-written for the VM3  prototypes, but after looking over the replacement code,  there's a few areas where it could be further improved.  I think some of those changes would have to be made at compiler level to really see the benefits, but one thing that comes to mind would be replacing how the string heap is set up.  If you have a lot of string data in a program and those strings share fragments/words, then there's some lost opportunities in terms of compression.   

       Ie.

        Data "Hello World", "Hello World2"

       The above data fragment would store two strings, since they're not a perfect match. But what it could do at build time is compare smaller fragments with the raw pool.  So any matching runs would compress away, both still exist, it's just one is a part of the other.   

       Stuff like this doesn't make any significant difference to small programs, but as programs get bigger the amount of partial collisions increases.   


Title: Re: PlayBASIC To DLL (Development Blog)
Post by: ATLUS on January 24, 2014, 10:05:23 AM
When it will be released? And how much is it?
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on January 24, 2014, 11:09:43 AM
 As mentioned in the [plink]2014 Blog (http://www.underwaredesign.com/forums/index.php?topic=4129.0)[/plink],  no decision has been made about cost or any release date.    It won't be before the next upgrade is released though.

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on January 26, 2014, 10:17:08 AM
 PlayBASIC To Dll  -  Data Statements Cont.

       It was Australia Day yesterday, but here I am slaving away at this app.  Tonight's focus continues to be data commands, ran into something of a hiccup last session where For/Next loops would break if a restore command (or any data command) was used inside them, turned out to be how translator identifies the loop start  could break after a label was used.   For/Next loops don't actually exist in the byte code version of your programs so it's not as simple as i'd like detecting them.  Will have to add some tokens into the exported byte code as a  fail safe.  

       So far the Data heap is built locally into the dll with an interface to access it.  The scope of data is local to the DLL, so the VM can't see the data inside any DLL.   Nor can one dll look inside another.    Bellow we have a function that compiles and exports. The code just creates a simple data heap with a function to run through the data heap dynamically.    The DLL has no runtime errors.  So if types don't match, it's not going to hold your hand.   This is a none issue really since, you'll only ever be exporting code when it's fully tested.   Yeah right :)

   
[pbcode]

Label1:
   Data 10
Label2:
   data 20,30,40,50

Label3:
   Data 111.111,222.222,333.333 ,444.444, 555.555

Label4:
   data "hello world1","hello world2","hello world3","hello world4","hello world5"

;      restore Label1
;      restore Label2
;      restore Label3
;      restore Label4


Function DLL_DATATEST()

;      restore 0
;      restore 1
;      restore 2

      print GetDataPointer()


      Label4=10
      restore Label4

;      print GetDataPointer()


      print "Reading data types on heap"
      Count=GetDataQuantity()
      print "Count:"+str$(count)
   
      for lp=0 to count
            restore lp
            DataType=getDataType()
            s$= Str$(lp)+"  ="+str$(getDataPointer())+" type="+str$(DataType)
            Select DataType
            
                  case 0
                        s$+="  Data="+str$( ReadData())
                  
                  case 1
                        s$+="  Data="+str$( ReadData#())
                  
                  case 2
                        s$+="  Data="+ReadData$()
            endselect
            print s$
      next
            

EndFunction

[/pbcode]


   Edit #1

       Restore in Pb supports three types of usages.   There's the absolute form, where the parameter is a label, a computed form where the parameter is a integer/float and a search form when it's passes a string.   All those are now in the dll back end.   Only thing left is the FindDATA function which is hooked up but not working at the moment.  


[pbcode]


   Data "StartBaby"

Label1:
   Data 10
Label2:
   data 20,30,40,50

Label3:
   Data 111.111,222.222,333.333 ,444.444, 555.555

Label4:
   data "hello world1","hello world2","hello world3","hello world4","hello world5"

;      restore Label1
;      restore Label2
;      restore Label3
;      restore Label4


;DLL_DATATEST()

;   sync
;   waitkey
   


Function DLL_DATATEST()

;      restore 0
;      restore 1
;      restore 2

      print GetDataPointer()


      Label4=100
      restore Label4

;      print GetDataPointer()


      print "Reading data types on heap"
      Count=GetDataQuantity()
      print "Count:"+str$(count)
   
      for lp=0 to count
            restore lp
            DataType=getDataType()
            s$= Str$(lp)+"  ="+str$(getDataPointer())+" type="+str$(DataType)
            Select DataType
            
                  case 0
                        s$+="  Data="+str$( ReadData())
                  
                  case 1
                        s$+="  Data="+str$( ReadData#())
                  
                  case 2
                        s$+="  Data="+ReadData$()
            endselect
            print s$
      next
            
            
            
      print "restore tests"            
      restore "hello world2"
      print GetDataPointer()
      restore "StartBaby"
      print GetDataPointer()
      

      print "find Data tests"
      print FindData("hello world3",0)
      print FindData(50,0)
      print FindData(222.222,0)
      
EndFunction

[/pbcode]



     Edit #2

     FindData is in and working now.   Added a option to make it search from the current Data Pointer position to the end (or top) of the data.   To do this set the 'position' field -1.   Of course this is currently only available in the exported DLL's,  i'll have to add this functionality to PlayBASIC V1.64P later.     



Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on February 01, 2014, 10:53:21 AM
 PlayBASIC To Dll  -  Function Calling

      So far this has been in fairly steady development now for probably 5 months now and would you believe that up until only a few minutes ago, you couldn't call any user defined functions in the your DLL.    You can call PSUBS, they're all up and running, but only now can you call an exported user defined functions (those prefixed with DLL_ are public functions) inside your dll.  However you still can't call private functions due to some VM dependencies that need ironing out.    It's possible to hook up as it stands, but the VM is doing things that the DLL version doesn't need to, which might get in the way.


      One of the major changes in the newer prototypes of the VM (such as VM3) was a altering how it handled calling and returning from functions.   The legacy solution works fine, but the newer approach is cleaner and more inline with how it needs to work when exported.   So there's that annoying little voice in the back of my head wanting to 'update' it to bring everything inline.  Dunno we'll see how painful getting it work as is first I think.


      Bellow is the normal junk test to see if it's even working.


[pbcode]


   Data "StartBaby"

Label1:
   Data 10
Label2:
   data 20,30,40,50

Label3:
   Data 111.111,222.222,333.333 ,444.444, 555.555

Label4:
   data "hello world1","hello world2","hello world3","hello world4","hello world5"




Function DLL_TEST_FUNCTION_CALLING()

      result=DLL_Passing_Parameters(100,123.456)
      print "result after calling passing parameters function"
      print result

      result#=DLL_Passing_ParametersFloat(100,123.456)
      print "result after calling passing parameters function"
      print result#

      result$=DLL_Passing_ParametersString(100,123.456,"This is a test string")
      print "result after calling passing with string parameters function"
      print result$
      ink $ffff0000
      print "DONE"
      ink -1
      result=DLL_DATATEST()
      print "called wrapp function"
EndFUnction  result


Function DLL_Passing_Parameters(A,B#)

      print "Passed"
      print a
      print b#
      result =a+b#

EndFunction result

Function DLL_Passing_ParametersFloat(A,B#)

      print "Passed"
      print a
      print b#
      result# =a+b#

EndFunction result#


Function DLL_Passing_ParametersString(A,B#,Cool$)

      print "Passed these params in"
      print a
      print b#
      print Cool$
      result$ =str$(a+b#)+cool$
      print result$

EndFunction result$

Function DLL_DATATEST()


      print GetDataPointer()

      Label4=100
      restore Label4

;      print GetDataPointer()

      print "Reading data types on heap"
      Count=GetDataQuantity()
      print "Count:"+str$(count)
   
      for lp=-10 to count
            restore lp
            DataType=getDataType()
            s$= Str$(lp)+"  ="+str$(getDataPointer())+" type="+str$(DataType)
            Select DataType
                  case 0
                        s$+="  Data="+str$( ReadData())
                  
                  case 1
                        s$+="  Data="+str$( ReadData#())
                  
                  case 2
                        s$+="  Data="+ReadData$()
            endselect
            print s$
      next
                        
      print "restore tests"            
      restore "hello world2"
      print GetDataPointer()
      restore "StartBaby"
      print GetDataPointer()
      
      print "find Data tests"
      print FindData("hello world3",0)
      print FindData(50,0)
      print FindData(222.222,0)

      print FindData(50)
      
EndFunction result

[/pbcode]    


  There's one limitation that comes to mind with exporting strings from the DLL either back to the VM or another.   Which is that strings are returned by pointer, rather than handle.  Returning the pointer means that receiver has to copy from the pointer to the target string.   Since it doesn't know the size, it'll treat the string as null terminated.    This could  be an issue as PB supports binary safe strings, so a zero character is legal with a string.  One way around this potential problem would be to return a typed pointer with a string field in it.


[pbcode]


 Type MyString
     Result$
 EndType


 DIm S as MyString Pointer

 S= DOStuff()

 print S.Result$

 Sync
waitkey

Function DOStuff()
    me = new MyString
   
    Me.Result$="bla bla bla"
EndFunction Me as MyString POinter

[/pbcode]

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on February 03, 2014, 10:50:47 AM
  PlayBASIC To Dll  -  Function Calling Cont.  

     Yesterday was get function calling done day, but things didn't turn out how I'd hoped.  In fact spent almost 12 hours on it, only to run into brick wall after brick wall.   Was initially going to wrap up some functionality in the library to handle an emulated VM stack, which I know would work and would be a perfectly fine solution, but it just doesn't sit well with me.  My preferred solution is to use the system stack, but that's where we hit a few dramas...   PB's internal calling convention has type casting wedged into it.  This makes sense in the VM, since it reduces the number of VM ocodes needed to execute a new scope.   But it means that any interface has to be data type aware when pushing or popping.   Macros to the rescue !

     The solution was to write a set of tiny macros that emulate the behavior of the VM in assembly. Since they're macros, the code is inlined into our exported dll code.  So there's no calling a VM function to do the task for us.   The up side is it's about as fast as you can get it, the down side is it adds a little extra bloat to the amount of code that's produced around a function and a function call, but personally it's not enough to worry about.

     So far, the caller only supports passing primitives such as Integer/Floats & Strings in and out.  Multiple returns (inside PB) are supported, but I haven't actually tested to see if they work correctly as yet.   Pointer and Array passing isn't currently hooked up..  

     Some test code:

[pbcode]


Function DLL_ExportMe(A,b#,s$)

   Dim Dude(100)

   Print "Calling Local PB function"
   
   result=TestFunction(A,b#,s$,Dude())
   
   print "result="+str$(result)

EndFunction result


Function TestFunction(A,b#,s$,Dude())

   print a
   print b#
   print s$
   
   result=A+b#
   
   print "array Status"
   if getarraystatus(Dude())
   
         print GetArrayElements(dude())
   endif

EndFunction result

[/pbcode]


    In this program we see two different types of functions. The first one DLL_ExportMe is our public / exported function.   This function is visible to other programs that load this compiled DLL.  Since it's a DLL function,  it uses the STDCALL calling convention rules.   The second function TestFunction (which is called from the first in this example) is a local function to the dll.  This function is not visible externally and uses the PlayBASIC's  calling convention internally, so even if you have a pointer to this code, it's not callable externally.



    EDIT #1 - testing multiple returns from functions

         This seemed like it initially would work, but there was problem with the translator using a previously defined instruction in an unexpected way.     Once that that was picked up it seems to work OK. 

         Recursion isn't currently supported though.

[pbcode]

      a=666
      b#=123.456
      s$="hello"


      DLL_ExportMe(A,b#,s$)
      Sync
      waitkey
   


Function DLL_ExportMe(A,b#,s$)

   Dim Dude(100)

   Print "Calling Local PB function"
   
   result=TestFunction(A,b#,s$,Dude())
   print "result="+str$(result)

   result,result2=TestFunction(A,b#,s$,Dude())

   print "Multi returns"
   print "result="+str$(result)
   print "result2="+str$(result2)
   
   print "------------------------"

EndFunction result


Function TestFunction(A,b#,s$,Dude())

   print a
   print b#
   print s$
   
   result=A+b#
   result2=result+1000
   
   print "array Status"
   if getarraystatus(Dude())
   
         print GetArrayElements(dude())
   endif

EndFunction result,result2

[/pbcode]


Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on February 05, 2014, 04:19:41 PM

  PlayBASIC To Dll  -  Function Calling - Recursion

     Parameter passing (for PB functions) was hooked up a few days ago now, but recursion wasn't supported until yesterday.   The only problem is that even through the stack alignment was correct,  the test code just wouldn't match the VM.    On the surface the procedures appeared to have same functionality, but it turned out one of the macros I'd written to save time :) , had some faulty logic in it.   Fixing it was easy, but it didn't solve the problem with recursion as I'd made a few opt's to try and reduce some string thrashing, so had to add some pre-screening to the translator to detect the problematic situation, which seems to have resorted it to working order. 


     Here's the function, in the screen shot it's being called from the exported DLL function (in a previous code snippet) so that's spitting out some other data..

 
   [pbcode]

Function Recursion(ThisValue,Cool#,abba$)

      dim Wally as integer pointer
      
      print "STart  Int="+digits$(ThisValue,2)+ " Float="+str$(Cool#)+" string="+Abba$

      ThisValue+=1
      Cool#+=11.2233
      abba$+="abba"

      if ThisValue<10
;            Recursion(ThisValue+1,Cool#+11.2233,abba$+"abba")
            Recursion(ThisValue+1,Cool#+11.2233,abba$+"abba")
      endif
      print "  End  Int="+digits$(ThisValue,2)+ " Float="+str$(Cool#)+" string="+Abba$
EndFunction


   [/pbcode]




Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on February 08, 2014, 03:26:52 PM
   PlayBASIC To Dll  -  Function Calling - Recursion Done

         Why it is always the last item on any 'to do' list, where problems always seem to occur.   No sooner had I ticked the recursive box off the list,  do we discover that the returns don't work with recursion in most cases.    Initially it didn't seem like much of a drama, but then you find yourself sitting in front of the PC two days later, with no solution in sight.  Then you know it's not going to be easy.   The Issue(s) just come from how instruction set in the original VM's work.  What I had been doing is trying to unify the data into one clean system within the DLL, but the order in which things need doing in the classic VM (pushing and popped)  are at odds with that.   Forcing me to the emulate it's VM behavior.     

          Another sort of related issue, was returning strings from functions had a nasty habit of crashing the DLL.     This is was just plain odd, since strings are passed into a function the same way they're returned.    If it's exactly the same code, then  what's was the problem ? -  Well.. the issue was due to not protecting the EAX register when cleaning the string up for return.   Which could make it crash and burn..  


          But anyway, here's the latest function calling tidbit..  

[pbcode]


      a   =666
      b#   =123.456
      s$   ="hello there kevie"

      oldptr=DLLDebug_STACKPC()
         result=Compiled_ExportMe(a,b#,s$)
         ptr= DLLDebug_STACKPC()
;      cls
      print oldptr
      print ptr
      
;      print PeekInt(ptr+0)
;      print PeekInt(ptr+4)
;      print PeekInt(ptr+8)
;      print PeekInt(ptr+12)
      
;      Address=PeekInt(ptr+4)
      
;      for lp =0 to 50
;            a=b
;            #print PeekInt(address+lp*4)
;      next

         Recursion(0,123.456,"First")


sync
waitkey
end      

   
      print result
      print ""
      DLL_ExportMe(A,b#,s$)
      Sync
      waitkey
   
;      */
      


Function DLL_ExportMe(A,b#,s$)

      Dim Dude(100)

      Print "Calling Local PB function"
   
   result=TestFunction(A,b#,s$,Dude())
   print "result="+str$(result)

   result,result2=TestFunction(A,b#,s$,Dude())

;   print "Multi returns"
;   print "result="+str$(result)
;   print "result2="+str$(result2)
;   
;   print "Recursion Test]------------------------"

   ThisisMyString$=TestReturnString()
   print ThisIsMyString$

   
   Recursion(0,123.456,"First")
   
   print ""

EndFunction result


Function TestReturnString()
      result$="--->> Retured this string from a function"
EndFunction Result$

Function TestFunction(A,b#,s$,Dude())

   print a
   print b#
   print s$
   
   result=A+b#
   result2=result+1000
   
   print "array Status"
   if getarraystatus(Dude())
         print GetArrayElements(dude())
   endif

EndFunction result,result2


   Type WallyStructure
         x,y,z
   endType


Function Recursion(ThisValue,Cool#,abba$)

      dim Wally as WallyStructure pointer

      Wally = new WallyStructure

      print "STart  Int="+digits$(ThisValue,2)+ " Float="+str$(Cool#)+" string="+Abba$ +" Ptr="+str$(int(Wally))

;      ThisValue+=1
;      Cool#+=11.2233
;      abba$+="abba"

      if ThisValue<10
         ;   Recursion(ThisValue+1,Cool#+11.2233,abba$+"abba")
            abba$+="A"
            ReturnedString$=Recursion(ThisValue+1,Cool#+11.2233,abba$+"C")+">>>>"
            print "              returned string="+ReturnedString$

      endif


      print "  End  Int="+digits$(ThisValue,2)+ " Float="+str$(Cool#)+" string="+Abba$+" Ptr="+str$(int(Wally))
      free Wally

EndFunction Abba$


[/pbcode]

 

         



Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on February 09, 2014, 10:35:53 PM

  PlayBASIC To Dll  -  Cleaning Up The Code

          It's finally cooled down around here, so today has become clean up day for this project.   The current source code weighs in at around 21,000+ lines of PlayBASIC code.  So it's a pretty big project on it's own (without GUI ), and like all big projects bloat creeps into the code over time.  You know things like alternative functions / methods that are no longer in use, that sort of thing.   Handy when you're testing something, but beyond that they're pretty useless.    Should be able to strip a 1000 plus lines, maybe more..  Need to start getting it ready for putting a front end on it, not that it'll be all that exciting to look at..     

          Command set wise,  been looking over the missing instruction list last night and there's really only the real dribs and drabs left now.  Probably the main ones would be the CallFunction  set.   While they're not used too much by the community, I tend to use them  when abstracting some code like GUI behaviors.   To support them, means building a function table on the DLL's side.    You wont be able to call functions outside of the DLL though.  For much the same reasoning as the DATA commands can't see outside of the DLL they live in.     It'd be nice to call a function back in the VM from the DLL, but that seems impossible at this point. 

         
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on February 11, 2014, 09:08:19 PM

  PlayBASIC To Dll  -  Bound Function Calling (linkDLL/EndLinkDLL)

      If your code calls external DLL's, then in PB you'd either write a LinkDLL/EndLInkDLL block or use the CallDLL functions from the DLL command set.  Linking the DLL is generally the better solution, since everything can be solve prior to runtime.    Moveover the VM supports loading/  and executing DLL functions directly from memory.    Exported DLL can't do that for the moment, but they can now prepare calls to other linked external dll's.   So if you linked some windows functions or use some external physics library etc etc, then those calls resolve just like any other now.

      In more recent years,  many of the new commands added to PlayBASIC have been internally bound, that means they're not part of the VM instruction set at all.   Rather they're just linked via LinkDLL/EndLinkDLL blocks declared in the startup code.     The startup code is what your code is appended after.   

      There's about 80 internally bound functions in V1.64P,  some examples of them would be Interval functions, resources, platette mapping etc
     
[pbcode]
Function DLL_BOUND_FUNCTION_TEST()

      STARTINTERVAL(1)
         for lp =0 to 1000000
            a=a+b*3
         next
      print EndInterval(1)
      print "Cpus In System:"+Str$(CPUCOUNT())
      
EndFUnction      

[/pbcode]


Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on February 13, 2014, 11:49:52 AM
  PlayBASIC To Dll  -  Odds and Ends

      Still working on the LinkDLL->>Call Function stuff, but have hit something of an stale mate for the moment, but rather than dwell on it for too long i've been looking for more commands that have been missed.  Found a few, the first was the GetArrayPtr()  function.  This function pulls the address of the arrays buffer in memory, it includes two modes the first gets the first byte of the arrays header and second is the first byte in the arrays data.    It's very handy if you want to roll your own array functions to man handle array data.     The others were pointer casting functions.  Which are obscure enough that i've be amazed if they've ever been used.    

      The sample chunk bellow calls some linked dll functions and messes around with the missing functions.  Most GetArrayPtr  and the pointer cast functions end up inlined into the output assembly, so we avoid some more function calling overhead.  Meaning faster execution of those operations.


[pbcode]

Function DLL_BOUND_FUNCTION_TEST()
 
    ;   hideMouse(0)
      STARTINTERVAL(1)
         for lp =0 to 1000000
            a=a+b*3
         next
      print EndInterval(1)
      print "Cpus In System:"+Str$(CPUCOUNT())
      
      
      Dim Table(100)
      
      print GetArrayPtr(Table(),0)
      print GetArrayPtr(Table(),1)
      
      print GetArrayPtr(Table(),Value)
      Value++

      Dim Ptr as integer pointer
   
      Ptr=GetArrayPtr(Table(),Value)

      v1=BytePtr(Ptr)
      v2=WordPtr(Ptr)
      v3=IntPtr(Ptr)
      v4=FloatPtr(Ptr)

      
      print Int(ptr)      ;
         
      print "recast pointers"
      print v1
      print v2
      print v3
      print v4

      undim Table()
      value=0      
      print GetArrayPtr(Table(),Value)
      Value++
      print GetArrayPtr(Table(),Value)
      
      
EndFUnction      

[/pbcode]


PlayBASIC To Dll  -  RCE (Retro Computer Environment) Test conversions to machine code

    The RCE is just an emulation of a mock up 8bit system (Read More (http://www.underwaredesign.com/forums/index.php?topic=4147.0)),  written as a kind of learning tool for those unfamiliar with binary operations.     The emulation is pretty heavy in terms of computations, making it a good candidate for conversion to a DLL.     On my old  athlon system the runtime can draw the test screen in about 60fps,  which is actually fast enough for that particular program, but when we convert it to machine code, it's running an 230Fps on the same system.  

     To really put in perspective, the VM version takes about 16.7 milliseconds to render each frame, while the dll version takes about 4.3 milliseconds, that's a very healthy return given all I had to do is point PlayBASIC to DLL at it.   You could probably get this particular demo even faster, by replacing the some of the external function calls with your own binary operations..    

   Demo project (DLL) is attached is bellow the piccy.. It's not very pretty but food for thought :)

[pbcode]
linkdll "ByteCode.dll"
      
      RCE_CLS()      alias "rce_cls"
      RCE_MouseX()   alias "rce_mousex" as integer
      RCE_MouseY()   alias "rce_mousey" as integer

      RCE_ScreenWidth()      alias "rce_screenwidth" as integer
;'      RCE_ScreenHeight()   alias "rce_screenheight" as integer      ; forget to export this function :)
      RCE_ScreenPtr()      alias "rce_screenpointer" as integer

      RCE_Dot(x,y,color)            alias "rce_dot"
      RCE_Box(x1,y1,x2,y2,color)      alias "rce_box"
      RCE_Sync()                     alias "rce_sync"
      
endlinkdll


      Do   
            cls 0
      

         ; calc mouse position over the simulated video memory
            MX=RCE_MouseX()
            MY=RCE_MouseY()
         
         ; get mouse state
            State=MouseButton()
   
         ; if left mouse is pressed, draw a dot in colour 1
            if State=1            
                  RCE_Dot(mx,my,1)
            endif
   
         ; if right mouse is pressed we draw a box
            if State=2            
                  RCE_Box(mx,my,mx+50,my+50,1)
            endif


         ; if space key is pressed
            if Spacekey()=true
               RCE_CLS()
            endif
            
         ;  draw the RCE screen and flip PB screen            
            RCE_SYNC()

            print RCE_ScreenWidth()
      ;      print RCE_ScreenHeight()
            print RCE_ScreenPtr()
            

            Sync
      loop esckey()
      
[/pbcode]
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on February 19, 2014, 11:59:57 PM
  PlayBASIC To Dll  -  Swap, SwapIfLower & SwapIfHigher

      The swap commands are really low level VM instructions, In other words they're not actually functions/command at all.   Support for  Swap was added previously, but it only supported situations when the two fields are of the same type.  Ie  Swap  A,B    SWap  A#,B#,  But the VM actually allows any combination to be swapped, dunno why you would.. but it allows it.  This means the translator has to be support this also.

      After looking at the Swap translator, ended up doing down the macro approach again.  It just means the  translator code inserts a standard macro for each possible situation, allowing the same generator code to be used for the Swap, SwapIfLower and SwapIfHigher opcodes.    The SwapIF variants are less known, but they're the same as code like this   If A<B  then swap A,B  .  Just that operation is packed into  a single operation in the VM.  They exist since it's generally quicker to have the VM do higher level combinations of logic than lots of small lower level micro logic..

      To export the SWapIF opcodes to assembly, means the translator has to create an the IF/THEN styled block above.  So output code compares the parameters and branches accordingly.   Only swapping the when the condition  (less than or greater than) are meet.  Thankfully I can just hide that away in the macros and exported code looks almost like BASIC..  


[pbcode]


   v1=100
   v2=200

   v1#=v1+0.5566
   v2#=v2+0.1235


   print "SwapIfLower Operator II"

   a=v1
   b=v2
   print a
   print b
   swapiflower a,b
   print a
   print b
   
   
   print "SwapIfLower Operator IF"
   a=v1
   b#=v2#
   print a
   print b#

   swapiflower a,b#
   print a
   print b#
   

   print "SwapIfLower Operator FI"
   a#=v1#
   b=v2
   print a#
   print b
   swapiflower a#,b
   print a#
   print b


   print "SwapIfLower Operator FF"
   a#=v1#
   b#=v2#
   print a#
   print b#
   swapiflower a#,b#
   print a#
   print b#

[/pbcode]
     

    PlayBASIC To Dll  -  MinVal/MaxVal functions

        These are another 'function' that doesn't actually exist in the bytecode, but they use one of the lower level decision instructions that didn't support mixed data types.   So code like  MaxVal(100,123.456)  would fail.


[pbcode]

   v1=100
   v2=200

   v1#=v1+0.5566
   v2#=v2+0.1235

   print "MInValue Functions"

   print MinVal(v1,v2)
   print MinVal#(v1#,v2#)
   
   print "MaxValue Functions"
   print MaxVal(v1,v2)
   print MaxVal#(v1#,v2#)
   print MaxVal#(100.5,200.5)

[/pbcode]





Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on February 21, 2014, 07:22:48 PM
  PlayBASIC To Dll  -  Range / ClipRange functions

      Added support for the integer Range instruction yesterday, you can't mix types at this point.  For expressions that pass Range a mix of floats, it's probably going to be best solved by calling a function (the call size is smaller than my inlined code).    Which is something I've been trying to avoid for maths functions where practical.  

      The ClipRange functions are borderline also, I suspect there's situations where the output code could be simplified more than calling a one size fits all function , like where the range terms are literal.   If that occurs, it could output a compare block in it's place.  Which would be faster at runtime !

      ie.
 
      Result=ClipRange(SomeValue, 100,200)

      could become something like this (in BASIC styled logic)

       Register=SomeValue
       if Register<100 then Register =100
       if Register>200 then Register =200
       Result =Register
       


      I could just take the easy way and cookie cut everything, but there's plenty of BASIC compilers that already do that..  :)




PlayBASIC To Dll  -  For/Next Problems
       
        It's not all rosey though as one of the problems i've been running into recently, stems from the very nature of the byte code itself.  The VM uses self modification in places, which is very handy for removing decisions from certain opcode pairs.   But can make translating the logic back something of a pain.

        For/Next loops are one of those areas, where the compiler produces all number of combinations at the start the loop sequence, but these opcodes are generic, there's nothing special about them and they appear in other constructs as well, so detecting exacting what's going on isn't turning out to be that easy..    The result of which, is sometimes the translator misses the FOR loop set up code, when that occurs the for/next doesn't work in the exported DLL.  I'm hoping there will be some rainbow moment where I can figure out a bullet proof solution, but nothing coming to mind at this point.

        There's a few solutions, worse case would be adding bread crumb opcodes to the byte code in order to help any translator(s) process down the line.   Another approach would be change how the VM works and use add loop start opcode which would make it easier to translate and possibly at runtime for VM also.    I kind of favoring the latter, but we'll see..

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on March 05, 2014, 11:02:30 PM
   PlayBASIC To Dll  -  Continued Misc functions & operators clean up

        Last week was spent shuffling opcodes in the PB runtime & compiler, so anything that could be blocked into a standard command set, was..  This allows the translator to simply export the command/function calls via table.    This doesn't work for other core operations though and there's a bunch of them that haven't been fleshed out completely.  Meaning some input combinations would break the exported code, in particular when passing 'floats' into a function/operator that's expecting integers.  

        So this morning->afternoon i've been picking through and have added support for Powers,  WrapAngle, CurveAngle,CurveValue and few others.    Really starting to struggle for operations that aren't implemented fully actually.   Which means we can start looking at some real live testing.  


  Benchmarking - ABS function
     
         Many of the core functions resolve inline in PLayBASIC-To-DLL, which can really make a lot of difference to the end performance.     The following code contains a for/next loop computes two ABS() results and adds them together.    Over 1000000 loops the code runs consistently around the 45->50 millisecond mark,  which is over twice as fast as one competitor (105->110 milliseconds) and  executes in around 48 times faster than another competitor.  (2400+ milliseconds)


[pbcode]

Function DLL_ABS_TEST()

   i = -396
   print Wrapangle(i)
   print Wrapangle(i,45)
   
   
   
   r#=curveangle(I,i2,45)
   print r#   

   r#=curvevalue(I,i2,45)
   print r#   

   r#=cliprange#(I,i2,45)
   print r#   

   r#=cliprange#(I,99.45,45)
   print r#   


   r#=cliprange(I,99.45,45)
   print r#   

   r#=cliprange(I,99.45,45)
   print r#   


   i=2
   abba=2233445   


   print i^8
   print i^4.5

   print "ABS TEST"

  count = 10000000

   Value1=1
   Value2=-1
   t = timer()
   for i = 1 to count
       x = abs(Value1) + abs(Value2)
   next
   print timer()-t :    sync
   print x
   print i   


   u=1
   print RoundUP(u)
   print RoundDown(u)

   print RoundUP(1)
   print RoundDown(1)

   
EndFUnction

[/pbcode]

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on March 20, 2014, 08:01:52 AM
  PlayBASIC To Dll  -  GUI time

      The translation engine is pretty solid really and has been for a while, but the conversion is one thing, testing the the final products output is another.   So we need to set this up in a way that's as simple as possible really.   In the current builds, there's no GUI at all and to build anything, I've got to specifically layout the file names and  paths.   Once set though, the engine takes care of the entire process.  It's not pretty as we're first calling PlayBASIC with your source code, which will then compile it,  then grabbing the byte code module, translating that and sending to the assembler.    So there's a few pop up's in the build process.  Can probably clean that up a little, but it'd be purely cosmetic..

      The front end i'm just dragging from the Amos-To-PlayBASIC project.  I can think of few settings it needs, but beyond that, there's not really much input needed from the user, other than picking a source file.   Generally when I make these types of tools, I write the 'guts' of the project first, then cut'n'paste the GUI together around it.  So the projects merge into one big project.   The thing is, it's sometimes handy to be able to work on the engine code without the GUI, so do this we build two projects.    There's the 'engine' project an the 'Gui' project.   These sit it two separate folders and the GUI project would reference the source files from the engine project.   The thing is if you sprinkle any GUI code in the engine project, then it'll no longer build on it's own.  To get around this, any GUI code in the engine project need to query the GUIs existence.  If it doesn't exist, then have the compiler remove the code completely

      Something like this,

[pbcode]

   #ifdef GUI_PRESENT
   
         GUI-CODE-GOES IN HERE
      
   #Endif

   Sync
   waitkey

[/pbcode]

       So code that's talking with GUI side can be effective removed depending upon what project you compile.

       Another method would be via say by using the FunctionIndex to detect if a function is present at compile time and  set up a the constant in this project,  it'll do the same thing.

[pbcode]

   constant GUI_EXIST = functionIndex("NAME OF GUI ONLY FUNCTION GOES HERE")>1

   #if GUI_EXIST
         GUI-CODE-GOES IN HERE
   #Endif

   Sync
   waitkey

[/pbcode]


       One of the down sides of using lots and lots of includes files in the legacy IDE,  is they tend to slow down the IDE'S pre-processor dramatically.   The compile time might only be a couple of seconds when it's actually built, but IDE might take 10, 20 seconds to parse everything out initially.    So sometimes as projects get bigger, it can just be easier / faster to just bundle all files you want from one(or more) projects into one/two big includes.   Then attach the bundled code to the project.    The down side means you can't 'change' the that source code, as it's physically a different copy of the original external source, but a small price to pay once you get your head around it.  

       So far in terms of the GUI i've got the frame work running, and are in the process of setting the translator engine code so there's no naming collisions.   Will probably use a combination of the above methods,  the translator needs a legacy PB project file parser/loader, which could in turn be used to bundle itself for the gui in the need takes me.    The loader works pretty well, loading the entire PlayBASIC to DLL project (main sources) in 25 milliseconds.   Which is peanuts..    Will have to add pre-processor to it though and that'd slow it down a bit..  

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on March 26, 2014, 07:32:04 AM

  PlayBASIC To Dll  -  GUI continued

       Been having a hardware issues lately, namely my main dev box has been BSOD randomly, been trying to isolate the drama for a while now, and seems like they've subsided for the time being, even so I'm not willing to put a lot of faith in it as yet and are setup a another dev box to move across to.   Which as i'm sure we're all well aware can be quite painful.  In the mean time I've been working on mainly stream lining the PB2DLL sources and build  process.

       Up until now, the PB2DLL build  process would use a hack in the PB compiler to dump the compiled byte code prior to the handing execution over to the VM.   The hack is really legacy addition from the disassembler project, which was useful at the time, but PB2LL needs an official way of calling the compiler to get the required response.  So this means adding a command line directive to the PB compiler.   The directive just make the compiler build the project with the required output settings so it can save the byte code module and exit.   The PB2DLL tool really has to check the status of the build process here.   As it's possible the code you pass it might fail to compile, which kill the process.   

      The other chore has been in cleaning up the translator code so that the GUI and translator engine can exist either separately or merged.  Since the project was based on the disassembler code, this wasn't too difficult to achieve, just needed some renaming to make sure there's no clashing of function/constants between the  projects.   Been able to strip out a fair amount code from the translator that's become obselete.  Even so, it still weighs in at around the 850K mark.     

      Today's little task is to make a customized version of the project merger that will build the complete translator source code and then drop the output in the GUI folder.   


  Edit:

       It's now about 10 hours later and i'm in the process rescuing my latest source codes for basically everything from this dying vessel after another frustrating afternoon.
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on March 28, 2014, 11:31:12 PM
  PlayBASIC To Dll  -  GUI - Up And Running !


     After a frustrating week of playing hard drive roulette, yesterday i've continued putting all the parts together.  The build process is broken into two halves, there's the GUI side and translation engine side.  Unlike other helper apps, these are two separate projects, which are combined using a slightly more customized version of the project loader/source merger.   This version of the tool lets me wedge the Engine into the GUI easily and rips unwanted blocks of the code from the engine.  The pre-processing tool works via looking for tokens inside comments.  So the tokens mean nothing to PB, but the pre-processor tool just skims through looking token pairs and rips anything between them.  


    Example,

[pbcode]

; [REMOVECODE]
function Some_Function_Not_USed_By_GUI()

EndFunction
; [/REMOVEDCODE]


[/pbcode]

      So the code (in this case a function) is included when engine when testing separately, but would be ripped when the engine is merged for inclusion into the GUI.  I often use such approach to substitute methods in the final source codes for example.     Once the engine source is built, I just include it into the GUI project and off we go.  The GUI side holds the high level properties and just calls the conversion functions from the engine.  To make the engine project output to the GUI rather than the odd print statement we just wrap up our own print function.  So depending upon the context, the wrapped function either uses the GUI console or a print to screen.


      When running the final program the user has to initially locate their PlayBASIC.exe compiler file.   This will generally be in your My Programs or  Program Files folder it's different between OS's.  I can sniff this out only when install in the most common location, but can't if you install to a custom location.  To find the file go to 'SETTINGS->CONVERSION'  and click the locate button.   The dialog is set up to only accept one file.  It's just matter of you finding it.  Once the location has been set, it remembers this path.  

      To convert a PB source (PBA file) we go to FILE->CONVERT FILE, this pops a file locate dialog where all you do is select the file.   PB2DLL will take over from there, there's is one little issue though and that's what your DLL name is going to be.  Unfortunately, you can't create the DLL then rename it later, that won't work as there's naming dependency.  So the name has to be given to the DLL up front.  There's a few ways around the issue i guess, the DLL name could become the source files name.  This is fine for those people that give their files meaningful names,  but unfortunately a lot of people don't.     One way around the problem would to be search through the compiled byte codes constant table for a constant called "PB2DLL_NAME$" or something similar, another would be to use a DLLNAME_ prefix in a function/psub declarations .   Either way the programmer can then simply add the name string to their source code and then not have to enter a name during translation.  Which would get old really fast if your constantly editing -> building -> repeat..      

      So anyway, it's up and running.. just matter of tweaking everything now.


Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on April 01, 2014, 12:25:12 PM

  PlayBASIC To Dll  -  Pricing & Back End

         PB2LL is something of a first around here, up until now all the helper tools have been freebies, PB2DLL is a commercial tool.   The initial price will be for the early adopter version !   Which will be similar to what PlayBASIC retail current costs, so somewhere between $20->$30 US.   The final will most likely cost around $50.   

         One of the most frustrating things when releasing new software is all the secondary stuff that's required.  It's not just the software you have to write,  it's the ordering infrastructure it requires as well.   Will probably go with shareit again, but contemplating just using PayPAL.  Much like the DTAB ordering process, the KEY creation side of the ordering process won't be automated.  You'll most likely order, then your registration will be sent to you once the order has processed locally.   Which is required, since the key builder process is written in PB.  Shouldn't be a drama really, as we're unlikely to see more than a few sales.   
           
         So today's little chore has been working on the activation system library which is just matter of dragging some of the code around from older libs,  was a little painfully setting it up, but the process seems to be working.  With other tools i've build pre-processing tools to do the entire process, which is tempting, but again can't really see any great demand.. 


Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on April 05, 2014, 01:22:24 PM

  PlayBASIC To Dll  -  Final Approach

     Much of the week I've working on the activation libraries and user interface.  After a few trails ended up going for a system that's cross between PB's and what's in DTAB.  When ordering you're given a unique key as well as a user name and email address,  the later come from your order details obviously and much match.   The system requires you enter the information provided to unlock the retail edition of the software.  Had a few drama's initially with some determinism issues but those seem solved now, as the tester gets zero fails over 10000 random checks.  That's not say it's impossible to fail, but it'd seem unlikely now.

     GUI wise there's few dialogs with some chumpy buttons in, there's not really that much to select.  Although It's difficult to know how many controls add really, but I think the higher level (ie. vague)  they are the better really.   Like you could add controls to control the instruction set usage, where you could target particular types of cpu's, but I've a feeling that might asking for trouble really.   Ironically that's one area where JIT is much better idea.. But ya get that.

     There's still a some things missing that come to mind, like getting it convert a folder of sources and history dialog of some sort.   Could add some command line support, so you can set up a short cut or batch file to do a bunch of conversions as once.

     Anyway, here's a piccy of what it looks like.  Surprise Surprise it looks like all the other tools... :)


Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on April 08, 2014, 01:28:02 AM
 PlayBASIC To Dll - Joining The Dots

       The GUI side of the app is looking fairly complete now (apart from some tweaks), wrote (largely cut'n'pasted) a history dialog the other day  from one of the other apps.     Turned it up a bit, one of my pet peeves is programs that only remember the last couple of files you worked on.    The current solution has no max size,  but really it's unlikely you'll ever have more than a page or so loaded.     There's a clean up button to remove files that no longer exist on disk.  So when stuff get moved or delete or whatever.    

      The other remaining GUI tidbit that was left over, was the batch / folder scanning stuff,  which was just transplanted across from the Amos2BASIC converter.   The batch processing stuff just scans the folder you provide looking for PBA files.   A PBA file for those who don't know, is the PlayBASIC source code file.    Each source it finds it'll attempt to build into a DLL.    The translator  expects the sources to be stand alone at this point, so they currently can't have #INCLUDE statements in them.   Which is limitation, but It should be able to be overcome.

      In order to get the best out of the tool,  it's highly advisable programmers adopt a parent->child structure to their machine code accelerated projects.    So your main project folder contains the game / tool source + media as normal,  in here you'd also have any secondary library sources stored inside that main folder.     Your libraries folder would include your PlayBASIC DLL projects sources.   So if you have a couple of lib's you can use the build folder option in PB2DLL to run through and build everything for you in one go.  The build process will write the created DLL's to those folders and ideally generate linkDLL wrapper code for them.  So in your main source you just #Include those wrappers and your away.  .  

      So if we had an imagery a game called "PONG" , we'd make a project folder called PONG and hopefully give it a meaningful project name such as PONG.PBP (PlayBASIC Project file), rather than the default 'Project.pbp' which the IDE will assign those lazy people.       Inside that folder we'd create a MEDIA folder for all the games graphics and sound assets.     This simple structure immediately helps keep everything more organized from just file management through our actual source code.      If for some reason we wanted to add build a DLL library to help our pong game,  we're create another folder inside the PONG folder.  It could be called anything, but giving it a name such a DLL's or  Libs, or Libraries or something, something that should be  obvious to what the folder contains

      Now let's say in your pong game you're loading media files that for of a different format, you can load them in your main source code, but there's some VM overhead in doing that.   This would be an ideal situation for converting the loader/conversion code to a DLL.    To do so, you start a new project in PB,  then we save this project (with a meaningful name) into our games / dlls folder.   So if our library was to be a packing library we might call it "Packer",  where it's path might be  PONG/DLL/PACKER/.    Once we have a project, we'd cut'n'paste all the required code for the DLL functions to operate separately.    So any structures  arrays etc your packer functions need, need to be inside that project.  The project should compile without any external requirements.   Once you have that, directly PB2DLL to that folder/and source and translate it.


     Once the functions we want are externally built into machine code, we need to convert our parent project to use the DLL version of the functions, rather than the original versions that might be in our code.  In this case, we'd pull all the Packer functions of our game.  We don't need them in the main source anymore since all that code is now hidden away in our machine code dll.    However,  if you're passing types between the sides you would still need those Types to be declared within your main source.   PB can't get this information back from the DLL.    Moreover the DLL is like a black box,  so the only functions you can see inside the dll are those that you exposed in your code.    To expose a function we rename it with the "DLL_"  prefix.  Only these will be exported.   Any function not containing the prefix, will be included inside the final code but not visible from the outside, so we can't access it.    


Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on April 09, 2014, 12:34:04 PM
 PlayBASIC To Dll - The last 10% is really more like 90%

      One of the many frustrating things about programming is the almost there sensation, where the last 10 or so  percent of the project, feels like it takes more like 90% of the development time.    Testing is notoriously difficult and not to mention time consuming, one of the challenges with a project like this, is the near infinite amount of input situations the program has to deal with.     One little issue I've been having is getting PB2DLL to control and understand the responses from both the PB compiler and FASM.     It's fairly easy trapping a compiler errors (Shown bellow ) from the PB and returning this information back to the user, but from assembler is still a bit iffy trying to sense of what it returns, which soon goes beyond the scope of the product.   Obviously it makes more sense to trap errors during generation, rather than after assembly.   Since it's entirely possible a broken translation source could assemble.  

      Another problem that's been appearing is with batched conversions, where on some sets of sources, it's happy to compile and convert them, but there's the odd program that doesn't like being compiled in a batch, they'll compile fine alone, but not in a group.    So there's something wrong with the loader state not being refreshed, but just can't find the actual smoking gun.


Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on April 11, 2014, 02:49:17 AM
 PlayBASIC To Dll - Eureka, It's Finally Working

        There's a funny thing that happens when your chasing down bugs, where you'll follow a hunch down a rabbit hole almost infinitely,  regardless of if there's real basis in it or not.   You know it seems like this, so it must be this!   Now the past week or so, I've tracking strange faults in the translator where compiling the same program twice in a row would work, then it'd fail when changing sources in a batch.    Initially it seem GUI related, since the test code worked fine in the stand alone translator, but generally failed when you batched a folder out (translated a group of sources).    There's a few obvious things come to mind, like the translators not initializing it's internal structures properly, or there's some unforeseen collision somewhere.

        Initially focused on tuning up the initialization code, but the problem  persisted.. So off I go looking for any collisions or potential issues between the two slabs of code, such as clash of variable scopes.  Even found a couple of such issues, which looked potentially lethal, but turned out to be a bust..   Next logically conclusion, oh there's must some bug in PB that's at fault..   But right before diving into the runtimes, it seemed it might be nice to get a clearer picture of what the translator is looking at to begin with.  If that code isn't valid, or has some bogus data in it, then there's possible smoking gun  and wouldn't ya know it :)  when comparing the byte code state being compiles, there's an odd similarity in where the errors occur in them, in particular in the map that flags byte code as data and to be skipped.

        So off I go looking at the byte code loader function and hey presto,  the function REDIM's the ignore table.   This creates a problem as  Redim preserves the contents of that array,  the array is used in parallel to the main byte code to screen stuff out, so compiling the same program would work but if you compile program A then program B..  Program B has Programs A's ignore list applied to it, the more programs to built in sequences the of lists get merged creating all sorts of strange artifacts.      But right on 5PM that's bee been fixed now and it's working nicely !

       Haven't just been searching for bugs in the translator,  I've also added more error trapping abilities.    Earlier this week, added support to trap error codes form PlayBASIC compile process.  This returned a line number / error number and error message, but it couldn't get the source line, until now.  So when a compile error occurs, it'll dump that to the console also.   Which should give you some idea as that's wrong with the source.    Beyond that, there was no error trapping in the translator side of the tool as all. In fact if an error occurred,  it'd still call the assembler and try build your DLL.    PB2DLL has limit on the amount of errors it'll accept, unlike PB.    This is because it's possible the error message you're getting is just a warning, so the code may assemble, but it may not also..    If there's too many errors though, it just considers this fatal case and aborts the process completely.

        Anyway, prior to this week I was hoping to have the first commercial releases up and running by the this weekend,  the delays this week make that very doubtful now, but it is just around the corner !

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on April 12, 2014, 02:02:43 AM
  PlayBASIC To Dll - Testing - 1,000,000 Point Rotation Example (real time)

    Here's something for those die hard skeptics out there, is rotating / clipping and drawing a 1,000,000 points to the screen possible in PlayBASIC ?  - Well, not running through the VM's, but it is if you translate your code to machine code via PB2DLL then it's easily within your grasp.  

    I remember back in the mid 90's counting clock cycles to try and get a few hundred points, let alone a 1000 points rotated in a couple of frames from hand optimized assembly.   You can do that easily in PB today (even running on the slowest VM ten years ago),  but it's mind boggling how far this has all scaled up.    Where we are at a point where you don't need to a low level understanding of machine language, just some a background in how images buffers work and you can unlock even more performance.   

    See ->  Common Point Rotation / Dot Cube (PB2DLL Example) (http://www.underwaredesign.com/forums/index.php?topic=4182.0)  - This example includes 3 version of original routine.  The first version is the naive solution, it's a direct port of the original PB code, where the second and third solutions use some lower level direct memory access to unlock further performance. The 2 and 3 routines run slower in the VM, but much faster in machine code.
 

    The best news about this, is the current PB2DLL's translator  has only a few redundancy tweaks in it, as yet I haven't added any arithmetic optimizations.  :)

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on April 24, 2014, 12:04:55 PM
 PlayBASIC To Dll -   Tweaking Looping Constructs

      The past day or so I've been wrestling with FOR/NEXT/STEP implementation in the translator of all things.   Those reading the PB1.64P upgrade blog lately would no doubt be aware that the compiler/VM side has recently changed,  the changes were explicitly made to facilitate an easier more accurate translation to machine code from the byte code origin.   When porting the changes across to PB2DLL I noticed that it only supported Integer FOR/NEXT looping structures, where as the VM supports integer and floating point look structures

      Floating point loops present a bit of a problem due to the FPU's rather awful implementation,  but really that's everything floating point in these things.   Writing the translator code isn't difficult, it's just that it needs extra steps when dealing with floats which feels rather awkward.    Knowing this,  invested some time into the PB compiler to make sure the compiler side cleans out any unnecessary steps when setting up the loop and gives enough information to easily work out how to set the loop and what kind of set up is needed.    The decoder is able to pick up short cut situations where you used literals in your For Next Statement and cut down amount of screen code needed, in some cases on screening is need.  Since the loops duration can be validated at compile time.   It's those little things that help fine tune the performance of the final machine code. 

       The big question is when do we release ?   - Well since both sides need to be in alignment for the resulting DLL's work, the original plan was to release them both together, but I think we might release PB2DLL first..  This will help further test the translation in real world situations.  Of course that'll most likely mean that  there will be a few updates made prior to the release,  but there's not that can be  done about it.   It now just needs people other than me testing it. 

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on April 28, 2014, 01:12:55 AM
PlayBASIC To Dll -   Exporting LinkDLL binding code

       Had a few short programming (testing mainly) sessions over the weekend. Up until now, I've been testing the translator from the PB IDE.    So in order to run it, i've got to compile and run as normal (F5),  but as release time nears, we need to be able to build it into a final  EXE, but it's here we ran into a new problem,  where the exported internal structures could stop the exe from running.    I though this might happen, given how much of the PB VM internals have changed over the last 6 months.  Tracking down the issue took a while, but was fairly easy to solve which is a good thing.    So now I can build & run PB2DLL in exe form and it works as normal. 

       Once the build problem was sorted, i've been getting back to the GUI and internal exporter functions.   For the first version(s) I'm not going to bother with adding switching over the assembly code generation/optimization, it'll just do it silently.    There are times when that wouldn't be wanted, but  can't foresee anybody running into such problems.   Which means for the time being some of the GUI toggles have been ripped.   The only option that is useful is the Export LINKDLL code option.     This option gets the translator to build a chunk of the PlayBASIC source code that handles the function binding to the newly created DLL.   

      Linking to DLL's is something of a mystery for most people, basically all that happens is the PB compiler/VM create interfaces to external machine code that look and act like normal PB functions in your program.    There's some limitations in current versions of PB as to what data type/structures you can pass into and out of them, but those will be tweaked out in time.    In order to use our newly converted DLL's in our PlayBASIC programs, it stands to reason that we'd need to know how to write the LinkDLL binding code for the functions we wish to use.  Which was true yesterday, but now the translator can build a template of the exported functions for you in PlayBASIC code.   Obviously there's some limits in terms of data types that it currently supports, which stem from the PB compiler side not supporting passing PB internal structures through to external code.  Why? - because nothing other than PB understands PB internal structures, making supporting that originally point less.   

   To test the LinkDLL exporting, added a function bogus functions to  the common point rotation demo and here's what we get.   

[pbcode]
; ---------------------------------------------------------------------
; ---------------------------------------------------------------------
; ---- [cube.dll ]---------------------------------------
; ---- [ Created:28 Apr 2014 ]---------------------------------------
; ---------------------------------------------------------------------
; ---------------------------------------------------------------------


linkDll "cube.dll"

   dll_addintegers(a,b) alias "dll_addintegers" as Integer
   dll_addfloats(a#,b#) alias "dll_addfloats" as Float
   dll_addstrings(a$,b$) alias "dll_addstrings" as String
   dll_rotate_vertex_cube_9mult_common_point(sections,spacing,scale#) alias "dll_rotate_vertex_cube_9mult_common_point"
   dll_rotate_vertex_cube_9mult_common_point_opt1(sections,spacing,scale#) alias "dll_rotate_vertex_cube_9mult_common_point_opt1"
   dll_rotate_vertex_cube_9mult_common_point_opt2(sections,spacing,scale#) alias "dll_rotate_vertex_cube_9mult_common_point_opt2"


EndlinkDll

 
[/pbcode]

   This code can either get cut'n'pasted in your project or #included.  Either way once it's in and assuming PB can find your DLL (it's in the project folder) then your away in the machine code era!   


   What might be a good is to get PB2DLL to mangle the export names in the DLL.  So if you have a function called "AddIntegers", the external name can be mangled into some random hash, such as  'ABHDGSNFSSF'  - This would mean that exported linkDLL codes must match the build of dll exactly, as if the alias names don't match, windows can't local the machine code function and it won't run !   It'd only be helpful to prevent snoops from look at your function  names and potentially working out the parameters. 

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on May 08, 2014, 07:15:08 PM
  PlayBASIC To Dll -   Doc's

      Haven't had a lot of time for this all week really, so I'm only just getting around to setting up the PB2HTML syntax highlighter library.  The lib is based on the PB documentation builder version, but with updated logic.   The updated version can handle block comments and is much more accurate when laying the code out in the output.  So tabbed code fragments line up where they need.   Ran into a couple of odd issues in the updated version where HTML special characters could leak through and break the output in the browser, which seem to be ironed out now.  

      Tonight I've been putting the PB2HTML library into the documentation builder.  The builder parses the source documents looking for PBCODE blocks in the html pages.  When it finds a pair, it grabs the text between them and passes it to syntax highlighter code.  It's a bit messier than say a forum post, since I'm using HTML editing rather than pure TEXT with all custom tags.   Using html just means I can use any old html editor to make pages as long as I place my info between the custom tags on the page.   The parser just grabs info sections form the html page, then wedges them into the output template.     The idea being to speed up editing of actual text, since it doesn't have to be rendered to see it.

      Bellow is another mock up of the doc's with the syntax highlighting stuff and menu stuff wedged into it.

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on May 13, 2014, 12:55:13 AM
PlayBASIC To Dll -   Doc's Continued:

   After a busy weekend which included  Mothers day, an 80th birthday,  a 50th birthday and an 18th birthday, the weekend wasn't really a code mine.    I think the sugar rush is only now  starting to ware off now.   But on the up side, we do  have some documentation now.    

   Late last week started pulling the components together for the doc's.  I had 90% of the code laying around and various pre existing templates previously set up, so it wasn't that hard to get it working.   The problem as always is coming up with useful content.   How you define useful is anybodies guess.  

   Thankfully the tool is simple enough though, it doesn't really need a lot of usage explanation, provided the user is familiar with PlayBASIC to begin with. If you're not, then really there's little point in paraphrasing what's already in the manual..   Anyway, a lot of the special case stuff will be presented in the form of FAQ's.  The major of that stuff is covered in this very blog or the initial blog,  but Been trying to distill the important bits up front.  I'd say it'll take a few rounds to get everything included..

     Bellow a live (AS IS) version of the docs.   Some of the pages are just left overs from the previous template, so they really don't need to be there..  

      (old doc's link removed)

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on June 03, 2014, 06:10:41 AM
  
PlayBASIC2DLL V0.99 Commercial Edition released


      Yes it's here... Finally...after more than few marathon nights the first fully fledged version of PlayBASIC2DLL is available to the community.  PlayBASIC2DLL brings the power of native code to the PlayBASIC developer,  all we can say is welcome back to the machine code age.  

      This initial release has been discounted for the community down to $27.50 (US) from it's regular $49.99 US


 
Order


      You can order the product through shareit who provide all major payment processing methods from bank card, paypal, cheque, money order and more.    

      [plink]Purchase PlayBASIC2DLL (http://www.underwaredesign.com/forums/index.php?topic=4199.0)[/plink]

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: ATLUS on June 03, 2014, 11:13:48 AM
All future updates free?
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: monkeybot on June 03, 2014, 01:59:01 PM
bought it.
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: ATLUS on June 03, 2014, 02:52:26 PM
me too, but how about future updates...
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: monkeybot on June 03, 2014, 04:00:03 PM
yeah..for sure
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on June 04, 2014, 12:36:30 AM
Quote from: ATLUS on June 03, 2014, 11:13:48 AM
All future updates free?

   Updates are indeed free for the life of the product.   
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: ATLUS on June 04, 2014, 12:46:17 AM
Nice! Thank You Kevin!
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: ATLUS on June 04, 2014, 06:25:13 AM
Did anyone receive a serial key. I still waiting a key.
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on June 04, 2014, 07:20:02 AM

Haven't received any confirmations from shareit as yet.  How many hours ago did you order ?
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: ATLUS on June 04, 2014, 08:23:02 AM
about 18 hours ago
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on June 04, 2014, 08:50:30 AM
 Unfortunately, there's no order emails here for PB2DLL.  Although when i look in the shareit account there are new PB2DLL orders listed, but it hasn't sent out those to me.. No idea why.. Although it's happened before.  

 I'll try and manually process them in a minute, which is likely to take about 30 minutes..  



  Update: All orders have been dispatched.
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: ATLUS on June 04, 2014, 09:33:03 AM
Good.
Now i try to convert file water, first time it convert ok, i deleted dll and try to convert again and tool write: "This program source code does not contain any DLL exportable function, aborting "
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on June 04, 2014, 10:42:15 AM
Quote from: ATLUS on June 04, 2014, 09:33:03 AM
Good.
Now i try to convert file water, first time it convert ok, i deleted dll and try to convert again and tool write: "This program source code does not contain any DLL exportable function, aborting "

  which file did you pick ?  If you select Example/water/Main.PBA you'll get that error, it's not an appropriate source (has no exportable functions) to convert.   Inside the Examples/Water project there's another folder called DLL, inside that is the Example/Water/DLL/Water.pba source file.     That's the actual DLL code.  

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: ATLUS on June 04, 2014, 11:17:21 AM
Now i understand, thank you!
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on June 05, 2014, 02:47:20 AM
  PlayBASIC To Dll -  In-lining More Math Functions

      The generation engine has been up and running for a while now, but it's still relatively young solution, it'll be a while till it matures.   One of the things on my to do list is inline pretty much every common place math function where it makes sense to do so.   It actually handles a bunch of then already, but the more the better.  

      This afternoon I've been looking at the getDistance2D function (still don't like that function name) as a possible candidate.  It's one of the situations where a lot of code is generated just to call the function (before it even does anything), in particular if the input parameters are of the wrong type.    Most math functions expect floats, so if you pass integers, the caller will cast them into temps for you.  Which is nice and all, but not ideal if you want lean and mean code produced.  

      Now since the the floating point unit in your CPU has a square root built in, the actual operation can be performed directly on the FPU.    Which not only turns out to be less code than calling the function, it performs a much much better also.   To bench mark the performance, all i'm doing is scanning through the screen of coordinates and calculating the distance to the fixed point.    I'm not plotting anything, just doing brute force square roots.    

     The code bellow originally ran on average at 149.5 milliseconds when built with previous editions of PB2DLL, but with today's build, it executes in 10 milliseconds on average.    For a 800*600 screen mode that's 480,000 square roots   (Test system 9 year old Althon FX64 3000)

     The result is an almost 15times performance boost.


[pbcode]

Function DLL_ComputeSquareRoots()

      Width=GetSurfaceWidth()
      Height=GetSurfaceHeight()

      midx=width/2
      midy=height/2

      for ylp=0 to height-1
         for xlp=0 to width-1
            Dist=GetDistance2D(xlp,ylp,midx,midy)         
         next
      next

EndFunction

[/pbcode]




   See ->  Sinus Rendering Example (Compares PB2DLL V099 to V099a) (http://www.underwaredesign.com/forums/index.php?topic=4202.0)



Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on June 06, 2014, 02:49:16 AM

  PlayBASIC To Dll V0.99a  Released and Available For Download


     Here's the first revision for the PB2DLL package.   The main changes are in the code generation routines for more common math functions being assembled in line so they can be executed without have to call functions.  This can give us some dramatic performance improvements over calling the internal function library inside PB.     


     These couple of translations improvements


  Download:

      To download use the link that was assigned to you from your registration email.   That link will always return the latest edition of PB2DLL to you. 



  History

 

V0.99a   May,2014  -6th,June, 2014 

Code Generation:

- RgbAlphaAnd(), RgbAlphaOr() & RgbAlphaXor() functions are now trapped and inlined
  on demand. 

- GetDistance2D(X1,y1,x2,y2) is trapped and placed in line for the FPU.
  The call is about 50% less code when passing floats to the function and probably
  75% less code when passing integers in.  Speed wise it bench marks up to 15 times  faster. 

- Cos/Sin functions are resolved now directly in line on the FPU for you.


Fixes:

- Sqrt() & ABS() decoders didn't move the PC correctly causing the parser to get
out of alignment... Throwing a bunch of bogus errors after those statements

                  - Tweaked the rego field screening to only accept characters between ASCII 32 to 128
                 

 


Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on June 10, 2014, 08:15:20 AM

PlayBASIC To Dll -  New Product Hiccups

       The interest in the PB2DLL is slowly by surely building, it was never going to be 'explosive'  opening that's for the sure.   None the less, hopefully we'll see some locals trying to push the bounds of what was thought to be possible in PB as time ticks on, perhaps hammering out some libraries.  Perhaps tacking some of those crazier demo effects.   
             
        Things haven't entirely gone to plan though, there's been a few hiccups occurring in the ordering process (It took them 3 days to send  the initial orders to me.. yeah WTF)..  There's been a few activation issues and even some dialog problems.   Haven't resolve them all as yet, but are working on it ! 



Optimization - Sinus Render
     
        Improved the conversion quality some more with it being able to inline all the common sin/cos functions.  Stuff like SinRadius SinNewValue, which are uses to plot polar coordinates. 

        The functions bellow solve as one chunck of hand optimikzed assembly. 

[pbcode]      
         for angle=0 to 360      
            x=cosradius(angle,100)
            y=sinradius(angle,100)
            fastdot 400+X,300+y,$00ff00
         next
      
         for angle=0 to 360      
            c#=a#+b#
            x=cosnewvalue(400,angle,20)
            y=sinnewvalue(300,angle,20)
            fastdot X,y,$FFff00
         next
[/pbcode]      



         Just by writing directly to the destination buffer you can double the performance of the sinus render. 


[pbcode]

      lockbuffer
      ThisRGB=point(0,0)

   /*
      for ylp=0 to height-1
         for xlp=0 to width-1
            Dist#=BaseAngle#+GetDistance2D(xlp,ylp,midx,midy)         
            Dist=sin(Dist#)*100.0
            fastdot xlp,ylp,Rgb(Dist,Dist,dist)
         next
      next
   */
      Ptr   =GetIMagePtr(0)
      Pitch=GetIMagePitch(0)

      for ylp=0 to height-1
         RowPtr=Ptr+(ylp*Pitch)
         for xlp=0 to width-1
            Dist#=BaseAngle#+GetDistance2D(xlp,ylp,midx,midy)         
            Dist=sin(Dist#)*100.0
;            fastdot xlp,ylp,Rgb(Dist,Dist,dist)

            POkeint RowPtr,Rgb(Dist,Dist,dist)
            RowPtr+=4

         next
      next
         
      
      unlockbuffer


[/pbcode]




PlayBASIC To Dll - Next Update ?

        I'll be uploading a new build (with some crazy debug logs in it) later on tonight (my time)..  I'm just testing an alternative LoadDialog function now,  if it behaves ok then i'll try and exchange with the PBdialogs version.






Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on June 11, 2014, 03:32:11 AM
  PlayBASIC To Dll V0.99d  Released and Available For Download

    Here's the second revision for the PB2DLL package.   The main changes are two fold, firstly it's  is built using the latest edition PlayBASIC V1.64P (Beta 41),  and it in includes more math function solvers to in line common PlayBASIC math functions.  



 Download:

     To download use the link that was assigned to you from your registration email.   That link will always return the latest edition of PB2DLL to you.  



 History

 



V0.99c   May,2014  -7th,June, 2014  

Code Generation:
- COSRADIUS & SINRADIUS resolved directly on FPU
- COSNewValue & SinNEwValue resolved directly on FPU

Fixes:

                 - Re-Tweaked the rego field screening :(
                 


V0.99a   May,2014  -6th,June, 2014  

Code Generation:

- RgbAlphaAnd(), RgbAlphaOr() & RgbAlphaXor() functions are now trapped and inlined
 on demand.  

- GetDistance2D(X1,y1,x2,y2) is trapped and placed in line for the FPU.
 The call is about 50% less code when passing floats to the function and probably
 75% less code when passing integers in.  Speed wise it bench marks up to 15 times  faster.  

- Cos/Sin functions are resolved now directly in line on the FPU for you.


Fixes:

- Sqrt() & ABS() decoders didn't move the PC correctly causing the parser to get
out of alignment... Throwing a bunch of bogus errors after those statements

                 - Tweaked the rego field screening to only accept characters between ASCII 32 to 128
                 

 



Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on June 14, 2014, 02:51:51 AM
  PlayBASIC To Dll -  Register Optimization (Serialization)

       Work on PB2DLL has been two fold, a cross between those GUI & file system niggles and the conversion engine itself.   Yesterday work focused upon the conversion engine,  where  previously the core math operations had been solved to emulate the behavior of the runtimes.     The compiler does a fairly good job of removing redundant moves from the byte code version of your source code, but there are times where you end up with a serialized run of operations. An example of such an expression that would create this pattern would be  A=B+C+D+E.  So the resulting compiled code is effectively tallying the result in a register waiting to put the final answer in some other variable.   In previous versions of the translator the tallying would still hit memory.   But not in today's build.  

       Now today people seem to think that memory access is super fast and abundant due to the x86 clever designs,  when the reality is quite at odds with that belief.   Your CPU has a limited number of on chip registers (think of them as variables).  Register values are stored in the fasted memory in your entire computer.    When a chunk of code read  / writes from system memory the cpu manages this process through levels of cache.   Cache is smaller chunks of on CPU memory that's faster again than your system memory.   Moreover modern chips are also smart enough to cache successive memory / register accesses in what they 'virtual registers', which are registers that don't exist to the user, but are substituted at the micro code level before code is executed.   CPU have all this to avoid reading or writing from memory.  

      Ok.. so what we can take from all that, is that anytime we hit memory we're losing some performance.  Therefore it makes a lot of sense to hold temp values in chip registers where ever possible.  Since we're in x86 land here,  this is not always possible since we don't exactly have a wealth of on chip registers or the implementation of the instruction (like in the FPU) can at times require reading / writing to memory.      

      What today's addition does, is it implements a look ahead mechanic into the translator.  The routine scans for obvious situations where a result of some operator can be held on chip and solved in series.    So far, the solver only handles integer sequential expressions that use the +, -, / , *, AND, OR , XOR, <<, >>. (Yes.. I'm going to add more)

      It's worth mentioning that the order of operations has to be respected for the following code to translate on chip.   So an expression like    A=B+C+D+E  can be solved in order on chip (since they're all the same operation level), removing at least 4 temporary read / writes from memory.   So it'll execute much faster.  But if you're expression was something like this, with a mult in the middle of some adds  A=B+C*D+E, then this can't be fully solved on chip (as yet), mainly due to how the PB compiler deals with the order of operations in such expressions.  Meaning the translator would need to learn more about how the expression is unfolding (top to bottom), but for now it's an marked improvement.

     You can get  A=B+C*D+E to solve completely on chip though, just be rearranging the expression and moving the higher precedence operators to left of the expression. This gives the same result A=C*D+B+E and avoids any temporal memory usage.  

      When we get a serialized run, the code generator can reduce your code to one instruction per operation for the aforementioned supported core operators.  Mult & Divides need more instructions unfortunately which is just how x86 does things.  

   
     All of this was added yesterday, Tonight's little challenge is going to be build something that can handle serialized floating point math operations.  These a bit harder than integer registers given how the FPU instruction set work, but we should be able to remove fair amount of memory thrashing also.  


      Bellow is just some same code integer only i've been bench marking performance with.

[pbcode]

Function DLL_TestTally(Max)

      a=100
      b=200
      c=300
      d=400

      For lp=0 to max

         result=a+b+c+d+20+a+b+c+d   
         result=a+b+c+d+20+a+b+c+d   
         result=a+b+c+d+20+a+b+c+d   
         result=a+b+c+d+20+a+b+c+d   
         result=a+b+c+d+20+a+b+c+d   

         result=a+b+c+d+20+a+b+c+d   
         result=a+b+c+d+20+a+b+c+d   
         result=a+b+c+d+20+a+b+c+d   
         result=a+b+c+d+20+a+b+c+d   
         result=a+b+c+d+20+a+b+c+d   

      next


EndFUnction result


[/pbcode]


 
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on June 16, 2014, 11:55:06 PM

  PlayBASIC To Dll -  Dialogs Replacement

      The first releases of  PB2DLL use the PBDialogs library for an easy interface to windows common dialogs library, the main stuff it requires are the Load/Save file dialogs / Find Folder dialog and the text input dialog.   Now i've been looking at replacing that library with a simple library.  The load/save dialogs turns out to be easy, then we hit FolderDialog problem.    This particular dialog is one of the easier ones visually but it's implementation (in windows) seems rather under done.   All because you can't set the initial path of the dialog without sending it a message from a it's own callback.    Without this it always starts at the computer level.    Which is ok for the initial search I guess, but just creates extra clicks in a repetitious process. 

      To solve the Folderdialog problem has meant including some functionality in the VM just to manage the callback side of it, so todays build of the WindowsDialogs library will only work in V1.64P or above.    Moreover, another annoying thing about them is you can't easily control the position of the dialog.  The folder dialog window seems to ignore all positioning for some reason.    No idea why..

      Originally I'd assumed the InputDialog in PBDialogs was a common dialog,  like message box for example, but it's apparently a custom one.   So we can't just call the API directly to get a replacement.   After thinking about it, I've decided to go a different way with it.     That functionality is only used in the registration window.   Which requires the user to cut'n'paste their fields individually.  However a method i've been using more recently is clipboard monitoring.   This way the user opens the rego dialog and clicks the 'cut'n'paste' fields button (will prolly rename that).   This dialog waits for a minute, while the use opens their rego email and grabs all the fields together.  PB2DLL examines and reacts to any the text in the clip board.    If it find some suitable fields in the clipboard text, it parses the Name,Email + Key fields into the dialog for you.  Making it a two click process.     

      So that's where at this afternoon,  with any luck we'll get all the components hooked together tonight and uploaded soon after.    Can't say i'm 100% sure this will solve some of the dialog drama, but even it if doesn't, the dialogs are slightly newer in terms of controls and therefore that little bit more flexible. 

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on June 17, 2014, 12:54:01 PM

  PlayBASIC To Dll V0.99f  Released and Available For Download (18th,June,2014)

     Here's revision F of PB2DLL V0.99 package.    This revision sees changes made to the both the GUI and code generation engine.   For the GUI side of the application we're change out the dialog libraries in favor of smaller replacement.   This gives us some generally better behaved dialogs with better features, but it has meant needing to the change the Registration Dialog

   
  Registration Dialog Changes:

       This dialog changed on 18th,June,2014.   The Original version of the dialog had three separate buttons.  The user would cut'n'paste each field separately, then hit the activate button.     This has been replaced to in favor of a single button called Set User Details

      When you click this button the software goes into a clipboard listening  state, where it's waiting for some text to be copied from another application.    So PB2DLL now expects the user will open their registration email and collectively select and copy the three important lines of the text from it.   The lines it wants, are the UserName, UserEmail & Serial lines all together as one chunk of text.    When PB2DLL notices new text on the clipboard, it parses it for looking for those important fields.   If it understand the lines of you copied, you'll get a successful message, other wise it'll continue waiting.   

       Once you've clipped your text and it's parsed it, hit the activate button as normal.



  Code Generation:

      This build include the most recent version of the code generator,  one of the newest features would be the ability to identify serialized runs of the math operators, be them Integer or floating point.  What this does it means the sequence of instructions can be solved without read/writing temp values back to memory.   So they're solved using on chip register.   Given that edition used the very  first edition of the generator, it's not a magic bullet, but can give a very healthy boost to long expressions of operators.

      The integer solver can handle ADD,SUB,MULT,DIV, AND,OR,XOR and the shift left <<  and shift >>  right operators.    So an some expression like  result=A+B+C+D+E+F only ever writes to memory when dropping the result into the result variable. 

     The floating point solver only handles ADD,SUB,MULT,DIV operators at this time. 




  Download:

      To download use the link that was assigned to you from your registration email.   That link will always return the latest edition of PB2DLL to you. 



  History

 

V0.99e   16th,June, 2014 - 18th,June, 2014

GUI:
- Replaced PBDialogs library with a custom solution.
- Changed the Rego dialog to use clipboard monitoring


V0.99e   13th,June, 2014  -14th,June, 2014

Code Generation:

- Added serialized solver for runs of INTEGER opcodes. 
  The solver currently supports  ADD, SUB, MULT, DIV
  / AND/OR/XOR/ shifts << and shift >> operators

                    eg.
                          result = 10*A +B - C <<2 >> 8   
                         
- Added serialized solver for runs of FLOAT opcodes. 
  The solver currently supports  ADD, SUB, MULT, DIV

                    eg.
                          result = 10*A# +B# - C#



V0.99c/d   May,2014  -7th,June, 2014 

Code Generation:
- COSRADIUS & SINRADIUS resolved directly on FPU
- COSNewValue & SinNEwValue resolved directly on FPU

Fixes:

                  - Re-Tweaked the rego field screening :(




V0.99a   May,2014  -6th,June, 2014 

Code Generation:

- RgbAlphaAnd(), RgbAlphaOr() & RgbAlphaXor() functions are now trapped and inlined
  on demand. 

- GetDistance2D(X1,y1,x2,y2) is trapped and placed in line for the FPU.
  The call is about 50% less code when passing floats to the function and probably
  75% less code when passing integers in.  Speed wise it bench marks up to 15 times  faster. 

- Cos/Sin functions are resolved now directly in line on the FPU for you.


Fixes:

- Sqrt() & ABS() decoders didn't move the PC correctly causing the parser to get
out of alignment... Throwing a bunch of bogus errors after those statements

                  - Tweaked the rego field screening to only accept characters between ASCII 32 to 128
                 

 



Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on June 28, 2014, 01:52:55 AM

  PlayBASIC To Dll -  Bug tweaking &  Even Better Code Generation

      While working on the G2D library I've discovered a few well hidden faults in PB2DLL, ranging from the some entry point trapping through to a few instruction combinations that it didn't support, but didn't pop errors from.    It's trickier than you might to  catch every permutation of VM opcode as many of those opcodes aren't single purpose !    So given the size of the instruction set, it's obvious such issues will happen.   Generally it's those lessor known or lesser used features that tend to break a translation now, but there will still more of them hidden away ! 

      One of the strange things that I've seen happen in various DLL's now is they cause strange crashes on exit from PB, when bound and executed from memory.  This turned out to be due to strange behavior of windows ( yet another one ) where it called the entry point (the dll's start up function) when the DLL was being closed. Why ?  I've no idea.. but it must have seemed like a good idea to them at the time.  Sorted it was easy enough, just meant tweaking the templates.

      Beyond just bug fixes,  I've been using the odd dev session to continue improving the translators Code generation, in particular when it sees serialized statements.  When such things occur, the solver can avoid hitting memory with temps.    The previous version of the solver was generally left handed.  Meaning that depending on the operation,  calculations that solved naturally left to right, would serialize easier than expressions that solved in a mixed order.   Which is a little more cumbersome to solve efficiently.     

      So to improve the code generation, i've dropped in some temp mapping to the expression solver.   The mapping tracks where the cumulative result is stored, which allows it to create better code from those unnatural expressions.    The integer solver has been further expanded to handle more common operations, namely the comparison operators and branching operations.   Which allows the translator to create better assembly from an expression like   (a=true) and (B=True) 

     Examples Misc,

    [pbcode]

      if (a+a)=b
            print "Yeah do this"
      endif

      if b=(a+a)
            print "Yeah do this"
      endif

      if a
            print "Yeah do this"
      endif


      if a=b
            print "Yeah do this"
      endif
      
      if a=b and c=d
            print "Yeah do this"
      endif

 
    [/pbcode]


    Simple expressions like  if a=b are really  two operations in the legacy runtime.    There's an equality  test  between A and B,  where the result is stored in a temp VM register.    Next there's compare with branch opcode on the value in that temp register.    So in the VM that's really two VM opcodes being created.   

    In the first versions of the PB2DLL, those opcodes would be translated separately.  This gives us cookie cutter code, that's obviously neglecting the data's path way (Ie. the comparison is being used in a decision).   But  now the solver can now look ahead, it'll see the CMP /BRANCH statement after the equality test and dump more  stream lined assembly code, avoiding temp data being written and read back from memory.   The solver could actually shorten this further, but  I'm trying to avoid over complicating it for a time being.   

    Most of the other expressions above will solve without hitting memory, except the last one if a=b and c=d, where the initial compare result isn't used immediately in the next opcode, thus breaking it's chain.   The other statements within that expression will though, so there's still a gain.


   To give you a clear idea of just how effective this technique really is.   If we have some cumulative expression like this   Result=A+B+D+E for example again.   PlayBASIC2DLL code generator gives us a virtually one to one mapping with assembly output, it doesn't get any quicker than that !



Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on June 30, 2014, 01:36:18 AM
  PlayBASIC To Dll -  Breaking the one second mark for fractal render

       After tweaking the floating point code generator just a little, we get an even more staggering result from the previous fractal test, which now is rendering inside a second for a 640*480 screen on my test machine AMD FX64 (3000+).    The result gives us about 150 millisecond improvement over the initial test, so even the first versions of PB2DLL are surprisingly optimal, in particular when you compare those results to the primary competitors.   PB2DLL is consistently 3.5 times  faster than one and 5.2 times faster than another..    

       In this particular example the routine has a lot of dependency, by that i mean, calculations need to be done in a set order.  I suspect if the generator could interleave some of the FPU instructions around integer instructions, we could go even further though.   This is possible as the integer and float (FPU) sides of your CPU can actually run in unison.    Instruction operations on either side can generally overlap other instructions also, providing the following instructions don't rely upon the result of a previous instruction.      So we could interleave instructions that take a long time to execute around other instructions as long as they don't rely upon the result.


      Note: The original code/demo is attached to an earlier post in the PB2DLL WIP thread, it's exactly the same code.

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on June 30, 2014, 02:39:58 AM
  PlayBASIC To Dll V0.99g  Released and Available For Download (30th,June,2014)

     Here's revision G of PB2DLL V0.99 package.    This revision is focuses on bugs and the more improvements to code generation engine.  The main bug that this update fixes is the possible freeze when attempting to load a PBA that's has no exportable functions in it.   It was a strange issue, caused by the Replace$() function in PB, but that's been solved now.    So if you select a source that has no exports, you should get an error message, rather than it hanging. 


   
  Code Generation:

      Just like the previous build i've been working on improving it's detection and abilities to solve sequences of byte code operations in order and with in CPU registers.  The solver can support integer and float data types mainly. SO it's looking for sequences of integer or float operations that stack up in sequence.  When it finds one, it short cuts this series of instructions.   

      The Integer solver has three main additions, it support equality tests (= and <>) ,  Compare/Branches as well as better support for Left/Right hand operators.   The latter allows it to better track where which side of the temp data came from, then remap the operator accordingly. 

       On the float side, the changes are a little different,  the float solver can handle recasting results and some limited single parameter functions like Sqrt(), ABS() as well as the normal addition/subtraction/Divide/Multiplies. 


  Download:

      To download use the link that was assigned to you from your registration email.   That link will always return the latest edition of PB2DLL to you. 


  History

 


V0.99g  23rd,June, 2014  - 30th,June,2014

Fixes:
- The import library list would break when there's more than one
  library that needed to be imported/exported

- Reading from typed fields was exporting UTD pointer.

- DLL entry code now screens for caller actions.  Which seems to fix
  the crash on exit stuff that's been happening. 
 
- Seemed to be passing the wrong 'temp variable' in the integer serialer     

Code Generation:

- Parser better detects when an  AND/ON/XOR opcode is at the start
  possible run of serialized opcodes

- Integer serializer can handle equal and not equal compare
  operations. 
 
- Integer serializer can handle comparewith branch opcodes.

- Testing some single param float functions (Sqrt/ABS) to the float
  solver.  Seems to work well !
 
 
V0.99e/f  13th,June, 2014  -14th,June, 2014

Code Generation:

- Added serialized solver for runs of INTEGER opcodes. 
  The solver currently supports  ADD, SUB, MULT, DIV
  / AND / OR / XOR / shift << and shift >> operators

                    eg.
                          result = 10*A +B - C <<2 >> 8   
                         
- Added serialized solver for runs of FLOAT opcodes. 
  The solver currently supports  ADD, SUB, MULT, DIV

                    eg.
                          result = 10*A# +B# - C#
                         


V0.99e   13th,June, 2014  -14th,June, 2014

Code Generation:

- Added serialized solver for runs of INTEGER opcodes. 
  The solver currently supports  ADD, SUB, MULT, DIV
  / AND/OR/XOR/ shifts << and shift >> operators

                    eg.
                          result = 10*A +B - C <<2 >> 8   
                         
- Added serialized solver for runs of FLOAT opcodes. 
  The solver currently supports  ADD, SUB, MULT, DIV

                    eg.
                          result = 10*A# +B# - C#



V0.99c/d   May,2014  -7th,June, 2014 

Code Generation:
- COSRADIUS & SINRADIUS resolved directly on FPU
- COSNewValue & SinNEwValue resolved directly on FPU

Fixes:

                  - Re-Tweaked the rego field screening :(




V0.99a   May,2014  -6th,June, 2014 

Code Generation:

- RgbAlphaAnd(), RgbAlphaOr() & RgbAlphaXor() functions are now trapped and inlined
  on demand. 

- GetDistance2D(X1,y1,x2,y2) is trapped and placed in line for the FPU.
  The call is about 50% less code when passing floats to the function and probably
  75% less code when passing integers in.  Speed wise it bench marks up to 15 times  faster. 

- Cos/Sin functions are resolved now directly in line on the FPU for you.


Fixes:

- Sqrt() & ABS() decoders didn't move the PC correctly causing the parser to get
out of alignment... Throwing a bunch of bogus errors after those statements

                  - Tweaked the rego field screening to only accept characters between ASCII 32 to 128
                 

 

Title: Re: PlayBASIC To DLL V0.99h (Development Blog)
Post by: kevin on July 04, 2014, 07:57:01 PM

  PlayBASIC To Dll V099h  -  Breaking 800 Milliseconds for fractal render

        The last round of tweaks got the fractal demo running inside the one second mark, which as about a 250 millisecond improvement over the original base translation version.  Breaking the second barrier was enormous and I was very very happy with those results, but knew there was a little more room to move.     So yesterday I set my sights on increasing PB2DLL's serialization support to help avoid some unnecessary memory access.   With these fairly simple changes  we've smashed another 200 milliseconds from the V0.99g  results..   Bringing rendering down to around the 780-790 millisecond range.   

    When compared to our competitors the results demostrate PB2DLL accelerated version is 4.1 times faster than one and 6.6 times faster an another.    So in terms of high iteration  pure math operations they're no competition at all.. 

   8 year old Test machine AMD FX64 (3000+).  Screen resolution: 640*480 screen



Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on July 07, 2014, 03:56:45 AM

PlayBASIC To Dll -  1,000,000 Point Rotation Example (Remix)

       You've probably noticed that dot cube examples is a particular favourite of mine when testing 'tweaks' to the Pb2DLL codes generation ability.   It's not that it's a particular beautiful demo, it just boils down to some serious number crunching with a good dose of memory thrashing to boot.   So it stands to reason if the generator can stream line any expressions better or avoid hitting memory unnecessarily, then those tweaks will show up as better performance.

       For the last few sessions of PB2DLL, I've been  focusing upon improving the serialization detection as well as embedded this behavior around more of the common functionality.   For example, if you call function that returned an Integer/float, then it scans ahead looking for any sequences it can clean up for us.     So if we had a bit of code like   AlignedToGridMouseX  = MouseX() /  GridWidth,  then previous versions would have hit memory when pulling the mouseX() function,  now the result lives in a register and would be divided on chip, before finally being written out to memory.   

        Performance wise today's build of PB2DLL gives us around a 4FPS boost, going from running at 11FPS on the test system to 15FPS.   In millisecond terms, that's about a 24 millisecond improvement.  The demo runs in about 66 milliseconds now, where as it was running in approximately 90 milliseconds before.       

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on July 11, 2014, 02:32:36 AM
  PlayBASIC To Dll V0.99h  Released and Available For Download (11th,July,2014)

    Here's revision H of PB2DLL V0.99 package.    This revision continues to focus on finding those left over core instructions that weren't supported in the translation,  as well as improving the quality of the code produced.   One of the operations that was missing was reading from a handle from a type structure.  This is important as we can use this to detect what cells within an array are populated are what ones aren't.  

    eg.

[pbcode]

    For lp=0 to 100

          if Alien(lp)    ;  here we're reading the handle of type at this position within the array.   If the value there is zero, then it's empty, otherwise it exists.

                  Alien(lp).x+=Alien(lp).SpeedX
                  Alien(lp).y+=Alien(lp).Speedy

          endif

    next
[/pbcode]


 
 Code Generation:

     This version supports better stream lining of expressions of core instructions onto the CPU from both the integer and floating point sides.  The goal of such changes it avoid hitting memory were possible as well as replacing common operations where it makes sense.  One of the recent additions can now trap temp registers that appear following internal command set function calls.  So if you called some internal command function that returned a floating point value, the generator will try and sequentially solve any following instructions.   

       Eg.

       x#  =GetSpriteX(SomeSPRITE) /  GridWidth

      So some code like this now leaves the result of the function call on the fpu and performs the division on the fpu also.    Which gets rid of some temporary memory thrashing that the runtimes have to do, but our machine code dll's don't.    This means that generally if your expression stacks well, you'll get very solid performance from it.


 Download:

     To download use the link that was assigned to you from your registration email.   That link will always return the latest edition of PB2DLL to you.  


 History

 

V0.99h  30th,June,2014  - 10th,July,2014

Added:

- ReadTypeCell byte code was being decoded, but didn't export
 any assembly. Making those programs fail

Code Generation Changes:

- Added COS/SIN single float functions  to the float solver.
- added Let to integer solver.  
- Integer solver now supports the less than, less than equal operators
- Float solver has better support to follow temps or left/right
 side of math operators.
- Integer solver supports RGBA(),RGBR(),RGBG(),RGBB()
- Tweaked internal command set caller to watch for the serialized returns
 from operations that return Integers and Floats
- RANGE() can start a serialized sequence.  Allowing code like
 IF RANGE(a,b,c) to solve on chip.
- Shift & roll functions now support integer sequences after them.
- Integer bit operations can now solve integer sequences after them
- String compares functions now support integer sequences after them

Fixes:

- Both Int & Flt serial solvers could look past the end of sequence when
  the first opcode didn't return a temp register.
- return parameters for 'bound' functions didn't seem export working code
- RANGE() wasn't allowing fields to be anything other than integer
- Integer serial solver didn't check if the return type when it ran into a
assignment statement.  Which would break is the expression was an integer
being written to a float.



V0.99g  23rd,June, 2014  - 30th,June,2014

Fixes:
- The import library list would break when there's more than one
 library that needed to be imported/exported

- Reading from typed fields was exporting UTD pointer.

- DLL entry code now screens for caller actions.  Which seems to fix
 the crash on exit stuff that's been happening.  
 
- Seemed to be passing the wrong 'temp variable' in the integer serialer    

Code Generation:

- Parser better detects when an  AND/ON/XOR opcode is at the start
 possible run of serialized opcodes

- Integer serializer can handle equal and not equal compare
 operations.  
 
- Integer serializer can handle comparewith branch opcodes.

- Testing some single param float functions (Sqrt/ABS) to the float
 solver.  Seems to work well !
 
 
V0.99e/f  13th,June, 2014  -14th,June, 2014

Code Generation:

- Added serialized solver for runs of INTEGER opcodes.  
 The solver currently supports  ADD, SUB, MULT, DIV
 / AND / OR / XOR / shift << and shift >> operators

                   eg.
                         result = 10*A +B - C <<2 >> 8    
                         
- Added serialized solver for runs of FLOAT opcodes.  
 The solver currently supports  ADD, SUB, MULT, DIV

                   eg.
                         result = 10*A# +B# - C#
                         


V0.99e   13th,June, 2014  -14th,June, 2014

Code Generation:

- Added serialized solver for runs of INTEGER opcodes.  
 The solver currently supports  ADD, SUB, MULT, DIV
 / AND/OR/XOR/ shifts << and shift >> operators

                   eg.
                         result = 10*A +B - C <<2 >> 8    
                         
- Added serialized solver for runs of FLOAT opcodes.  
 The solver currently supports  ADD, SUB, MULT, DIV

                   eg.
                         result = 10*A# +B# - C#



V0.99c/d   May,2014  -7th,June, 2014  

Code Generation:
- COSRADIUS & SINRADIUS resolved directly on FPU
- COSNewValue & SinNEwValue resolved directly on FPU

Fixes:

                 - Re-Tweaked the rego field screening :(




V0.99a   May,2014  -6th,June, 2014  

Code Generation:

- RgbAlphaAnd(), RgbAlphaOr() & RgbAlphaXor() functions are now trapped and inlined
 on demand.  

- GetDistance2D(X1,y1,x2,y2) is trapped and placed in line for the FPU.
 The call is about 50% less code when passing floats to the function and probably
 75% less code when passing integers in.  Speed wise it bench marks up to 15 times  faster.  

- Cos/Sin functions are resolved now directly in line on the FPU for you.


Fixes:

- Sqrt() & ABS() decoders didn't move the PC correctly causing the parser to get
out of alignment... Throwing a bunch of bogus errors after those statements

                 - Tweaked the rego field screening to only accept characters between ASCII 32 to 128
                 

 

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: ATLUS on September 14, 2014, 10:05:31 AM
Kevin, where can i read how to use DLL, any tutorial?
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on September 14, 2014, 10:07:34 AM
 have you read the documentation ?
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: ATLUS on September 14, 2014, 10:13:46 AM
Oh i am sorry completely forgot it.
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on November 24, 2014, 11:20:25 PM
PlayBASIC To Dll V099i  -  More Serialization Support

   While working on the G2D (Open GL for PLayBASIC) library  last week ran into a couple of operations that weren't being decoded by PB2DLL, so any programs that used them those would fail.   One situation was when passing UDT pointers between the various internal function types, of which there are a few.  While doing that I noticed some other easy to add serialization opportunities to the code generation.  In other words a few more easy ways to make it even faster in certain situations.

   Serialization in PB2DLL refers to how the code generator solves runs of operations, where the focus is to avoid writing temp data to the memory where possible.  One such situation that i'd noticed was with Peek/Poking fields user defined typed pointers.  Previously if you accessed a Integer/Byte/Word field from a type and depending upon the operation, the compiler would store these in VM registers, which means hitting memory in the VM.   Of course in our machine code DLL's we don't need that, but the translator has to detect when such situations occur.

    Let's have a look at an example.    

[pbcode]


   Type TestType
         Status
         Count
         ThisByte as byte
         ThisWord as word
         x#,y#,z#
         IntArray(10)
         FltArray#(10)
         StrArray$(10)
   EndTYpe



Function DLL_TEST()


   Dim me as testtype pointer
   
   Me          = new TestType
   me.count=100
   a=45

   result=me.count
   print result   
   result=me.count+A
   print result   
   result=me.count+A+me.count
   print result   
   

   
   me.count = me.count +a

   me.ThisByte = me.ThisByte +a+b
   me.ThisWord = me.ThisWord +a+b
   
 Sync
 WaitKey


EndFUnction

[/pbcode]


     Such test code doesn't really do anything interesting, but the various occurrences of the me.ThisByte ,  me.ThisWord & me.Count can now be further solved out, where they'd previously hit a VM register (written to memory).    

     
     This will even help direct writes between UDT pointers, so  a line of PlayBASIC code like this me.count = me.count say, now becomes 4 machine code instructions.  Which could be further simplified to 3 instructions when the two pointers are the same, but it doesn't currently do that.

   




   
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on December 01, 2014, 01:44:13 AM
 PlayBASIC To Dll V099i  -  Beta5 download

  This beta includes all the latest code generation features.   Custom need only  download it and copy the EXE into your existing PB2DLL folder.  

   Old beta removed

Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on December 04, 2014, 09:59:18 AM
  PlayBASIC To Dll V099i  -  More Pointer/Float Serialization

        Floating point support in x86 always feels like a  bit of mess to me really, which seems to stem from the external FPU legacy.   Back in the day, x86 cpu's didn't have floating point built in,  it was an optional extra.   Now even though it's been integrated into your cpu, it still feels like a completely separate device as far as the instruction set is concerned.  In some ways that's handy (2 separate pipelines), but occasionally you just wish you could move between the integer and float registers without hitting memory..  

        With this round of updates I've been focusing on making further improvements to the code generation, mostly focusing on Pointers and peek/poking the various data types.    Solving most integer stuff is fairly easy and side of the optimizer is the most mature, the float side can be a bit award as it only likes to pull floats from memory, rather than a register..  None the less, a number of extra little additions have been added that help sequences of float operations resolver easier and easier.  

        Bogus Example Code:

[pbcode]


      type TestType
            x#,y#,z#
      EndTYpe


      Dim Src as testtype pointer
      Dim Dest as testtype pointer

      Src    = new testtype   
      Dest    = new testtype   


      ; write some integer values into these float fields..
      ; this type of type mismatch  is now auto recast at compile time
      Src.x   = 1111
      Src.y   = 2222
      Src.z   = 3333


      ; copy a field to another within the same type
      ; The op
      Src.x=Src.Y

      ; copy fieldds between different types
      Dest.x=Src.x

      ; copy a field and add 100 to it
      Dest.y=Src.y+100

      ; copy a field and mult it by 2
      Dest.z=Src.z*2

      print Dest.x
      print Dest.y
      print Dest.z


      Sync
      waitkey
      
[/pbcode]


         Since all fields from these typed pointers are floats, PB2DLL can take some liberties with the output code.  Take the a line like Src.x=Src.Y,  where we're copying a float from one structure to a different location in the same structure.   Previous editions of PB2DLL would hit memory pulling the value out of the structure, only to write it in the next opcode.  The parser now has a short cut for this,  turning the output code into 3 instructions and since they're the same type we don't have to hit the FPU.  So it's just copying a pair of integers.  

     The expression Dest.y=Src.y+100 are now supported by the float sequencer.  Previously the result of Src.Y+100 would sit in a VM register (get written to memory) and them be written out into the target structure..  Now it only writes to  memory when the result is computed on the FPU.   

          Which all sounds like mumbo jumbo, but here the latest changes give the G2D particles demo about even more through put on my legacy test machine.   Will have to go test some other demos.
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on January 12, 2015, 11:59:37 AM
 PlayBASIC To Dll V0.99i  Released and Available For Download (13th,Jan,2015)

     Here's revision I of PlayBASIC2DLL V0.99 package.    This revision furthers more improvement to the machine code generation as well continuing to iron any hidden instructions that weren't supported by the translation engine.   

     In terms of code generation this version seem focuses mainly on pointer operations, in particular  when reading / writing from a user defined typed pointer is used within an expression, as well as arithmetic and assignment operations on between pointers or between a pointer and integer.   

     Example:
[pbcode]

      type TestType
            x#,y#,z#
      EndTYpe


      Dim Src as testtype pointer
      Dim Dest as testtype pointer

      Src    = new testtype   
      Dest    = new testtype   


      ; write some integer values into these float fields..
      ; this type of type mismatch  is now auto recast at compile time
      Src.x   = 1111
      Src.y   = 2222
      Src.z   = 3333


      ; copy a field to another within the same type
      ; The op
      Src.x=Src.Y

      ; copy fieldds between different types
      Dest.x=Src.x

      ; copy a field and add 100 to it
      Dest.y=Src.y+100

      ; copy a field and mult it by 2
      Dest.z=Src.z*2

      print Dest.x
      print Dest.y
      print Dest.z


      Sync
      waitkey
     
[/pbcode]



    This tool is intended to be used with PlayBASIC V1.64P2 retail update. !


    Reminder: Always read the development BLOG's carefully for information on the in's and outs of any upgrade !


  Download:

      To download, use your unique link that was assigned to you in your registration email.   That link will always return the latest edition of PlayBASIC2DLL to you. 



  History

 
V0.99i  19th,Nov,2014  - 13th,Jan,2015

Fixes:
- Call function was missing support for pointer as parameter fields
- On GOTO would output code with clashing labels in it.

Code Generation Changes:
- Integer solver now supports integer/byte/word typed pointer read
  accesses.    Eg  result = Me.X + SomeInteger
 
- Integer solver supports pointer additions
 
- Integer solver supports INT() function on pointers

- Integer solver supports MoveToPrr in INT() function on pointers

- Integer solver supports Pointer Additions Int/Word & Byte

- Float Solver support runs that write to integer/float pointers.
eg  UserDefinedTypePointer.SomeFloat#  = A#+B#+C
eg  UserDefinedTypePointer.SomeInteger = A#+B#+C   (auto cast when written)

- Solver can trap move pointers/ pointer casts and serialize them

- Float solver support runs from Peeked floats
- Float solver can short cut moves between float fields without loading to FPU
  eg    You.X# = Me.X#   - If ME & YOU are UDT pointer, then this just moves
  the memory, rather than loading to FPU and writing back


V0.99h  30th,June,2014  - 10th,July,2014

Added:

- ReadTypeCell byte code was being decoded, but didn't export
  any assembly. Making those programs fail

Code Generation Changes:

- Added COS/SIN single float functions  to the float solver.
- added Let to integer solver. 
- Integer solver now supports the less than, less than equal operators
- Float solver has better support to follow temps or left/right
  side of math operators.
- Integer solver supports RGBA(),RGBR(),RGBG(),RGBB()
- Tweaked internal command set caller to watch for the serialized returns
  from operations that return Integers and Floats
- RANGE() can start a serialized sequence.  Allowing code like
  IF RANGE(a,b,c) to solve on chip.
- Shift & roll functions now support integer sequences after them.
- Integer bit operations can now solve integer sequences after them
- String compares functions now support integer sequences after them

Fixes:

- Both Int & Flt serial solvers could look past the end of sequence when
   the first opcode didn't return a temp register.
- return parameters for 'bound' functions didn't seem export working code
- RANGE() wasn't allowing fields to be anything other than integer
- Integer serial solver didn't check if the return type when it ran into a
assignment statement.  Which would break if the expression was an integer
being written to a float.
 

V0.99g  23rd,June, 2014  - 30th,June,2014

Fixes:
- The import library list would break when there's more than one
  library that needed to be imported/exported

- Reading from typed fields wasn't exporting UTD pointer.

- DLL entry code now screens for caller actions.  Which seems to fix
  the crash on exit stuff that's been happening. 
 
- Seemed to be passing the wrong 'temp variable' in the integer serialer     

Code Generation:

- Parser better detects when an  AND/ON/XOR opcode is at the start
  possible run of serialized opcodes

- Integer serializer can handle equal and not equal compare
  operations. 
 
- Integer serializer can handle comparewith branch opcodes.

- Testing some single param float functions (Sqrt/ABS) to the float
  solver.  Seems to work well !
 
 
V0.99e/f  13th,June, 2014  -14th,June, 2014

Code Generation:

- Added serialized solver for runs of INTEGER opcodes. 
  The solver currently supports  ADD, SUB, MULT, DIV
  / AND / OR / XOR / shift << and shift >> operators

                    eg.
                          result = 10*A +B - C <<2 >> 8   
                         
- Added serialized solver for runs of FLOAT opcodes. 
  The solver currently supports  ADD, SUB, MULT, DIV

                    eg.
                          result = 10*A# +B# - C#
                         


V0.99c/d   May,2014  -7th,June, 2014 

Code Generation:
- COSRADIUS & SINRADIUS resolved directly on FPU
- COSNewValue & SinNEwValue resolved directly on FPU

Fixes:

                  - Re-Tweaked the rego field screening :(
                 


V0.99a   May,2014  -6th,June, 2014 

Code Generation:

- RgbAlphaAnd(), RgbAlphaOr() & RgbAlphaXor() functions are now trapped and inlined
  on demand. 

- GetDistance2D(X1,y1,x2,y2) is trapped and inlined onto the FPU for.
  The call is about 50% less code when passing floats to the function and probably
  75% less code when passing integers in.  Speed wise it bench marks at 15 times
  faster. 

- COS & SIN resolved directly onto FPU

Fixes:

- Sqrt() & ABS() decoders didn't move the PC correctly causing the parser to get
out of alignment and throw a bunch of bogus errors after those statements

                - Tweaked the rego field screening to only accept characters between ASCII 32 to 128
                 

 
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on November 23, 2015, 10:35:04 PM

PlayBASIC To Dll V0.99k  Released and Available For Download (24th,Nov,2015)

     Here's revision K of PlayBASIC2DLL V0.99 package.    This update address a few minor issues with the machine code generation and includes a few new command sets that were overlooked in previous builds.

    This tool is intended to be used with PlayBASIC V1.64P3 retail update. !


    Reminder: Always read the development BLOG's carefully for information on the in's and outs of any upgrade !


  Download:

      To download, use your unique link that was assigned to you in your registration email.   That link will always return the latest edition of PlayBASIC2DLL to you. 



  History

 
V0.99k  29th,Sep,2015   - 8th,Nov,2015

Code Generation Changes:
- Added support for the Date & Time function command set to PB2DLL

- Added some alignment to loop structures.

Fixes:
- Updated the Square Root parser. 



V0.99j  14th,Jan,2015  - 24th,May,2015

Fixes:
- external function calling was missing support for pointer parameters
- integer function calling was missing support for pointer parameters
making command calls like GetSpriteRect() fail in the DLL




V0.99i  19th,Nov,2014  - 13th,Jan,2015

Fixes:
- Call function was missing support for pointer as parameter fields
- On GOTO would output code with clashing labels in it.

Code Generation Changes:
- Integer solver now supports integer/byte/word typed pointer read
  accesses.    Eg  result = Me.X + SomeInteger
 
- Integer solver supports pointer additions
 
- Integer solver supports INT() function on pointers

- Integer solver supports MoveToPrr in INT() function on pointers

- Integer solver supports Pointer Additions Int/Word & Byte

- Float Solver support runs that write to integer/float pointers.
eg  UserDefinedTypePointer.SomeFloat#  = A#+B#+C
eg  UserDefinedTypePointer.SomeInteger = A#+B#+C   (auto cast when written)

- Solver can trap move pointers/ pointer casts and serialize them

- Float solver support runs from Peeked floats
- Float solver can short cut moves between float fields without loading to FPU
  eg    You.X# = Me.X#   - If ME & YOU are UDT pointer, then this just moves
  the memory, rather than loading to FPU and writing back


V0.99h  30th,June,2014  - 10th,July,2014

Added:

- ReadTypeCell byte code was being decoded, but didn't export
  any assembly. Making those programs fail

Code Generation Changes:

- Added COS/SIN single float functions  to the float solver.
- added Let to integer solver. 
- Integer solver now supports the less than, less than equal operators
- Float solver has better support to follow temps or left/right
  side of math operators.
- Integer solver supports RGBA(),RGBR(),RGBG(),RGBB()
- Tweaked internal command set caller to watch for the serialized returns
  from operations that return Integers and Floats
- RANGE() can start a serialized sequence.  Allowing code like
  IF RANGE(a,b,c) to solve on chip.
- Shift & roll functions now support integer sequences after them.
- Integer bit operations can now solve integer sequences after them
- String compares functions now support integer sequences after them

Fixes:

- Both Int & Flt serial solvers could look past the end of sequence when
   the first opcode didn't return a temp register.
- return parameters for 'bound' functions didn't seem export working code
- RANGE() wasn't allowing fields to be anything other than integer
- Integer serial solver didn't check if the return type when it ran into a
assignment statement.  Which would break if the expression was an integer
being written to a float.
 

V0.99g  23rd,June, 2014  - 30th,June,2014

Fixes:
- The import library list would break when there's more than one
  library that needed to be imported/exported

- Reading from typed fields wasn't exporting UTD pointer.

- DLL entry code now screens for caller actions.  Which seems to fix
  the crash on exit stuff that's been happening. 
 
- Seemed to be passing the wrong 'temp variable' in the integer serialer     

Code Generation:

- Parser better detects when an  AND/ON/XOR opcode is at the start
  possible run of serialized opcodes

- Integer serializer can handle equal and not equal compare
  operations. 
 
- Integer serializer can handle comparewith branch opcodes.

- Testing some single param float functions (Sqrt/ABS) to the float
  solver.  Seems to work well !
 
 
V0.99e/f  13th,June, 2014  -14th,June, 2014

Code Generation:

- Added serialized solver for runs of INTEGER opcodes. 
  The solver currently supports  ADD, SUB, MULT, DIV
  / AND / OR / XOR / shift << and shift >> operators

                    eg.
                          result = 10*A +B - C <<2 >> 8   
                         
- Added serialized solver for runs of FLOAT opcodes. 
  The solver currently supports  ADD, SUB, MULT, DIV

                    eg.
                          result = 10*A# +B# - C#
                         


V0.99c/d   May,2014  -7th,June, 2014 

Code Generation:
- COSRADIUS & SINRADIUS resolved directly on FPU
- COSNewValue & SinNEwValue resolved directly on FPU

Fixes:

                  - Re-Tweaked the rego field screening :(
                 


V0.99a   May,2014  -6th,June, 2014 

Code Generation:

- RgbAlphaAnd(), RgbAlphaOr() & RgbAlphaXor() functions are now trapped and inlined
  on demand. 

- GetDistance2D(X1,y1,x2,y2) is trapped and inlined onto the FPU for.
  The call is about 50% less code when passing floats to the function and probably
  75% less code when passing integers in.  Speed wise it bench marks at 15 times
  faster. 

- COS & SIN resolved directly onto FPU

Fixes:

- Sqrt() & ABS() decoders didn't move the PC correctly causing the parser to get
out of alignment and throw a bunch of bogus errors after those statements

                - Tweaked the rego field screening to only accept characters between ASCII 32 to 128
                 

 
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: baggey on March 05, 2016, 10:43:58 AM
Hi,

It's been a while since i used playbasic but im interested in the pb 2 dll program.
i can't order it as the site isn't working for me in france?

How can i get it so i can experiment!?

Keep up the good work Baggey!
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on March 09, 2016, 07:55:47 AM
Quotei can't order it as the site isn't working for me in france?

  It's not currently available and I'm not too sure when it will be, as there are a few more pressing things on the to do list.      
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on May 15, 2019, 12:18:31 AM

  PlayBASIC To Dll -  GOES FREE in MAY 2019

       Yes, you read that correctly, PB2DLL will be released FREE in the coming days.   




Title: Re: PlayBASIC To DLL (Development Blog)
Post by: stevmjon on May 19, 2019, 08:07:11 PM
free should get more people to use this.

out of interest kev, what made you decide to release this free?
Title: Re: PlayBASIC To DLL (Development Blog)
Post by: kevin on May 19, 2019, 09:42:39 PM
Quote from: stevmjon on May 19, 2019, 08:07:11 PM
free should get more people to use this.

   Perhaps, but it's a  little to difficult for most people.   


Quote
out of interest kev, what made you decide to release this free?

   Lack of  Time and it's 4 or 5 years old and now almost a complete generation behind..