NEWS ARTICLES


    What's News in the PlayBasic world ? - Find out here.




 PlayBasic2DLL V0.99 Released

By: Kevin Picone Added: June 3rd, 2014

Category: All,Update,Tools,Machine Code


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



What's PlayBasic2DLL ?


     It's a companion tool to the PlayBasic programming language. The tool converts PlayBasic Source code into machine code DLL's. Allowing the programmer to fully harness the process of their computers cpu.

     The tool has been in development for the best part 8 months now so rather than me crudely attempt to paraphrase the blogs, I recommend you read the PlayBasic2DLL blogs and check out some of the examples. ( 1,000,000 Vertex cube - Water Demo )




Order


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

     See->See Community Annoucement To Purchase PlayBasic2DLL








 PlayBasic V1.64P and PlayBasic To DLL Latest News

By: Kevin Picone Added: May 1st, 2014

Category: All,Update,Tools,Machine Code


The following is a selection of blog posts from the development of PlayBasic to DLL (Machine code translator) and the parallel upgrade PlayBasic V1.64P


PlayBasic V1.64P Beta 38 - Loopy Loops (April 17, 2014)

     After much head scratching it was decided that the VM's instruction set needed a few alterations with it's looping instructions. These changes are two fold, the parser now does a better job at producing cleaner input parameter data and the instructions produced are now more stream lined. Producing better code, is better for everything down the line from running the code through the VM and thus any translations. The translation stuff is really why these changes need to be made now, since the original parser would use generic instructions where some data was pre-computed. From the translators perspective, this made it very difficult to accurately detect those loops in a single pass.

     Today's changes introduce some new high level instructions to the VM. These changes make it trivial to accurately pin point the set up code in a FOR/NEXT looping blocks. I've already added a decoder to PB2DLL which locates the new opcodes and builds a export string in the dissassembly. The detection and output are working fine, but it's here that I noticed there's a few extra moves creating into the output code than need be. Which mostly happens when a loop is using literals. In previous editions the parser would drop an extra move prior to the loop entry point. The same can happen in the destination value expressions also. These things are easily tweaked out, just hadn't noticed them before.



PlayBasic V1.64P Beta 38 - For / Next Loop updates (April 22, 2014)

If you didn't already know, it's been Easter holidays here which has just come to a close, so only started firing up the compilers today. Last time I was working on the tuning the compiler and VM to use the new looping setup codes for FOR/NEXT loops. These changes have were translated across to PB2DLL when I was happy with the new structures. The changes are much easier for PB2LL parser to accurately detect what's going on in the program in regards to loops. But not only that, the new format allows us to make more optimizations to the assembly.

Tonight I've been back working on the parser in the PlayBasic compiler, as when converting the code to assembly, there's often these extra move operations that would end up in the byte code first and thus translated assembly. Surprisingly it generally happened what a for loop's (start / end) were both literal. For some reason it'd drop them into temps and then pull them into the loop structures internal registers. Which appears to be some left over instruction set behaviors that are no longer necessary. Older versions of the VM worked differently than today, in particular when dealing with literals. Now they can be treated just like variables, so don't they need to be treated special ways.

Something you might not be aware of is that when a for/loop is started, there's a comparison between the Start and End of loop. If Start is bigger than the end, the execution jumps to the beyond the matching next.

For example,

PlayBasic Code:
      For lp =0 to 100
          print lp
       next

COMMANDS USED: PRINT |


So there's an indivisible screening wrapped around loop entry, which might look at like this in PB style code.

PlayBasic Code:
     if 0<=100
      For lp =0 to 100
          print lp
       next
    endif

COMMANDS USED: PRINT |


     One of the new benefits of the FOR/NEXT replacement opcodes, is the export parser can detect constant behaviors and produce code accordingly. So the comparison behind the Start /End loop counters can actually be made at compile time when they're both literal. Removing those lead in comparisons from the output code. The same goes for the storing them in internal VM registers, saving more set up code.

     Being able to trap literals helps with STEP loops also. When a variable is used in for/next/step loop, the looping structure has constantly query what sign the STEP, then clip the loop counter based upon it. If the sign of step is known at compile time, then the loop can be created with this knowledge ahead of time. Removing more redundancy from the final translated assembly (in PB2DLL)

     PB is pretty flexible with FOR/NEXTS allowing integer and floating point counters with variable step directions in both. People rarely use floating point loops, but since the VM supports it, the exported assembly through PB2DLL should also. Dropped in the standard by one loop structure earlier today and have just started adding the variable STEP stuff with floats. It's painful purely because of the horrible fpu instruction set in x86 chips...





PlayBasic To Dll - Tweaking Looping Constructs ( April 24, 2014)

     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.




PlayBasic To Dll - Exporting LinkDLL binding code ( April 28, 2014)

     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 few bogus functions to the common point rotation demo and here's what we get.

PlayBasic Code:
; ---------------------------------------------------------------------
; ---------------------------------------------------------------------
; ---- [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
	DrawCube(sections,spacing,scale#) alias "dll_rotate_vertex_cube_9mult_common_point"
	DrawCube_opt1(sections,spacing,scale#) alias "dll_rotate_vertex_cube_9mult_common_point_opt1"
DrawCube_opt2(sections,spacing,scale#) alias "dll_rotate_vertex_cube_9mult_common_point_opt2"


EndlinkDll 

  

COMMANDS USED: LINKDLL | ALIAS | INTEGER | FLOAT | STRING | ENDLINKDLL |


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.




PlayBasic V1.64P BETA #39 (Retail Beta) (30th,Apr,2014)

     Beta #39 introduces a bunch of subtle but equally important changes, starting with the newly replaced FOR/NEXT/STEP parser and VM instruction set, there's also a few changes to the VM close down behavior. The close down changes are due to a strange issue i've been having with PB2DLL where the PB2DLL EXE would crash on exit when the program wasn't registered (worked fine once you entered your serial).

     So I've been chasing the close down issue most of the day, it appears that some typed arrays can somehow contained data that wasn't a typed array container. How that's the possible is a mystery at the moment, but I've included some more screening in the clean up code to make sure it's releasing the array an not some of random bank of that data that something else was/is using. Getting this right is more important now than ever, thus is because of the way type deletion works in the runtime, so we have to make sure it's releasing data that makes sense, as if it doesn't it'll die.

     The real question is how is the bad array data was/is getting into the arrays in the first place, which i'm not 100% on at this point. So i've added some debug messages to the debugger console (F7 to run, then click on the console tab) to help the community track where else these quirks put up.. Does it happen at runtime ? or only closing down the VM..

     So get testing !!!!!!



Download



     Download PlayBasic V1.64P Beta 39




More Information

For the full picture/ screen shots etc see the PlayBasic 2 DLL development blog






 PlayBasic To Dll - Tweaking Looping Constructs

By: Kevin Picone Added: April 25th, 2014

Category: All,Update,Tools,Machine Code

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.





 PlayBasic To DLL In Final Testing

By: Kevin Picone Added: April 12th, 2014

Category: All,Update,Tools,Machine Code


The following is from a selection of blog posts from the development of PlayBasic to DLL (Machine code translator) over the past months.


PlayBasic To Dll - Joining The Dots ( April 08, 2014)

     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.




PlayBasic To Dll - The last 10% is really more like 90% (April 09, 2014)

     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.




PlayBasic To Dll - Eureka, It's Finally Working (April 11, 2014)

     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 !



PlayBasic To Dll - Testing - 1,000,000 Point Rotation Example (real time) (April 11, 2014)

     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, it's 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, 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), but it's mind boggling how far this has all scaled up.

     Common Point Rotation / Dot Cube (PB2DLL Example)

     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.




More Information

For the full picture / screen shots etc see the PlayBasic 2 DLL development blog






 PlayBasic V1.64P - WIP Round Up #1

By: Kevin Picone Added: January 29th, 2014

Category: All,Update

The following clips are taken from the development blog of PlayBasic V1.64P and read oldest to newest - You can find the complete blog (for this and every other update) on our forums



PlayBasic V1.64P Beta 17 - Operators and Precedence (November 28, 2013)

     It shouldn't come as any great surprise that changes in this revision are to help with the PlayBasic To DLL translator and it's ability to produce cleaner and better code generally. Building the translator means taking a fine tooth comb to the generated byte code and making sure the compiler outputs the leanest set of instructions possible to perform each operation. While looking over the bit wise/logical operators recently noticed they'd not been set to force an integer result. So if you had an expression fragment that contained a float, it'd return a float in the legacy VM. Fortunately this is simple to rectify as the parser has a switch to force an integer return. This is a bit of a none issue in most programs since the operators are generally only ever see integers on either side of them, but it can and does actually occur in some code.

     Having operators return a float isn't an earth shattering problem, it just makes a simple operation messy and slower than need be when such things occur. The existing translator already supports operations upon integers, but it didn't handle mixtures between integers and floats. Forcing the compiler to produce an integer only result, helps the VM keep everything integer and translator produce cleaner machine code from the byte code without making multiple path ways.

     While looking at the operators again in the compiler and translator, noticed that NOT seems have a precedence issue. For some reason it's evaluated before the math/compare operators in an expression. It should be the same as the other operators and occur after them.

     So code like print not a=b is being evaluated Not A then result_of_Not_A=b , where it should do A=b then do Not Result_Of_Compare_A_With_B.

     Moreover Not is implemented as a mask and Xor of the bit zero value on the right hand side. After a rethink, it'd be better implemented as a equality test with zero then xor. So code like Not 45, would actually be evaluated as Not (44<>0), Not 1 = 0. Where it'd currently return 1 since bit zero is OFF, it'll flip that off bit to on.

     The bad thing about the NOT operator is that your introducing complexity into your expression for no real benefit, as result = (Not A = B) and Result = (A <>B) are functionality the same, expect the former is two operations and the latter is single operation. No big deal in a loop of 1 to 100, but a very big deal when iteration count blows out in both VM and Machine Code.

     Live Edit #1:

     Found the problem, the operator trap in the parser was missing the operation level screen. Once added, the order solves as expected.

PlayBasic Code:
		print not a=b
		print not a<>b

		print not a#=b#
		print not a#<>b#

                ; thee lines would fail in older versions of PB, since it'd evaluate Not A$ first
		print not a$=b$ 
		print not a$<>b$


COMMANDS USED: PRINT | NOT |


     Live Edit #2: Optimizer

     The expression solver now contains logic to optimize & rewrite code fragments like the following. The optimizer also supports literal Not statements as well so that be evaluated in constant expressions.

PlayBasic Code:
             Print Not 1
             Print Not 0

             Print Not 1.0
             Print Not 0.0

             Print Not A=B
             Print Not A<>B

             Print Not A#=B#
             Print Not A#<>B#

             Print Not A$=B$
             Print Not A$<>B$


COMMANDS USED: PRINT | NOT |


     Becomes,

PlayBasic Code:
             Print 0
             Print 1

             Print 0
             Print 1

             Print A<>B
             Print A=B

             Print A#<>B#
             Print A#=B#

             Print A$<>B$
             Print A$=B$


COMMANDS USED: PRINT |


     So since we're saving an opcode every time, the object code is smaller and of course faster in both the VM and machine code. No brainier really.



PlayBasic V1.64P Beta 18 - Shift Operators (December 02, 2013)

     Just dropping in some more C styled operators with the << and >> which are equivalent of the existing LSR32 and LSL32 functions (which is what they are in assembly btw). Just makes dragging code between dialects that little bit simpler. There's no functionality difference between them.

PlayBasic Code:
 		print 1 << 2
 		print 256 >> 2
 		
 		a=16
		b=4
		b#=b

		print "variables & literals:"
		print  a << 4
		print  a >> 4
		print  4 << a
		print  4 >> a
		
		
		print "integer only"
		print  a << b
		print  a >> b

		print  b << a
		print  b >> a


		print "mixtures (floats recast as ints)"
		print  a << b#
		print  a >> b#

		print  b# << a
		print  b# >> a

		Sync
		waitkey


COMMANDS USED: PRINT | SYNC | WAITKEY |


PlayBasic V1.64P Beta 18 - Updated Operator Codes For IDE ( December 02, 2013)

     The compiler and IDE talk to each other when you first start PlayBasic up. The discussion is pretty one sided, but the IDE basically asks PB for it's current internal command, constant and operator list.

     The forum board syntax highlighter currently doesn't support them all as you can currently see in this snippet. (This statement will be obsolette when i next update the board, so they'll appear as per the IDE..)

PlayBasic Code:
		; Testing operators in standard PlayBasic IDE

		a++
		a--
		
		a+=b
		a-=b
		a*=b
		a/=b

		print a< B
		print a> B
		print a<>B
		print a><B
		print a>=B
		print a<=B
		print a=>B
		print a=<B
	
 		print 1 << 2
 		print 256 >> 2
 		
 		a=16
		b=4
		b#=b

		print "variables & literals:"
		print  a << 4
		print  a >> 4
		print  4 << a
		print  4 >> a
		
		
		print "integer only"
		print  a << b
		print  a >> b

		print  b << a
		print  b >> a


		print "mixtures (floats recast as ints)"
		print  a << b#
		print  a >> b#

		print  b# << a
		print  b# >> a

		print hex$(255 and 15 << 8)

		Sync
		waitkey


COMMANDS USED: PRINT | HEX$ | AND | SYNC | WAITKEY |


     Edit #1 - Not Equal Operator

     It appears PB parser would only ID one version of the Not Equal operator, that being <> , where as the inverse also represents an inequality, but the parser didn't pick it up. With a quick tinker and it now supports >< also.

     Live Edit #2 - C styled not Not Equal Operator

     Dropped in the != this in for those who can't live without their c fix.. Same as <>and ><



PlayBasic V1.64P Beta 19/20 (January 16, 2014)      The V1.64P revision has only had a few changes late last year, none of them were really user related (just the odd tweak for how PB and PlayBasic 2 DLL communicate) , although tonight i've been looking over the GetArray and SetArray commands. These are a way a user can access arrays through a stub array. So if you create a stub (and array with no data of it's own) via MakeArray, you can copy the 'pointer/buffer' from any other array into the stub via getting that arrays index via GetArray and then setting it via SetArray. The array indexes are linear, so you can actually write code that runs through a block of similar arrays without having to pass them. The process is basically the same as how and array is passed into a function or psub anyway..

PlayBasic Code:
 	Dim Table(100)
	Dim Table2(1000)

	
	; make a stub array called Me()
	MakeArray Me()


	; Me() now contains  a copy of buffer that Table() officially owns
	SetArray Me(),  GetArray(Table())
	

	; see me is now 100 elements in size
	Print GetArrayElements(Me())


	; put some data in table are indexes 0,1,2
	Table(0) = 111
	Table(1) = 222
	Table(2) = 333
	
	; show what  me()'s looking at
	print Me(0)
	print Me(1)
	print Me(2)

	Sync
	waitkey
  
  
COMMANDS USED: DIM | MAKEARRAY | SETARRAY | GETARRAY | PRINT | GETARRAYELEMENTS | SYNC | WAITKEY |


     While working on PlayBasic to DLL noticed the GetARRAY function can be pre computed at compile time, currently there's actually a library function that preforms the rather trivial calculation at runtime. SetArray is little more difficult as it's scope aware, which is fine for the VM environment, but a little difficult in the translated version, without piping all the compile time data into the DLL, which i'm not too keen on. Originally the SetArray would let you set and get between any array regardless of scope. I forget why it was changed, but have a feeling that could well get reverted at some point in the near future



PlayBasic V1.64P Beta 21 - Data updates (January 27, 2014)

     While building the data support into PlayBasic to DLL, found a few issues with the VM data commands. The main one was the Restore command would allow a negative data pointer position. Which would pull data from off the table, since it's not clamped. Another change is the FindDATA function had some dead weight in it and was missing the ability to search from the current DataPointer position. This has been added as a switch in the position field, if you set the field to a -1 the command will use the existing data pointer to search from. The position field is optional now and defaults to -1

PlayBasic Code:
	Data 10, 20,30,40,50,10,10,50

	; find the first instant of the Integer value 50
	; and set the data pointer to the cell after that value
	Restore FindData(50)+1

	; show us what where it is within the set	
	Print GetDataPointer()


	; find the next instance of 50
	Restore FindData(50)

	; show us where it is	
	Print GetDataPointer()
	
	sync
	waitkey


COMMANDS USED: DATA | RESTORE | FINDDATA | PRINT | GETDATAPOINTER | SYNC | WAITKEY |


     Test Code.

PlayBasic Code:
	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"


	DLL_DATATEST()

	sync
	waitkey
	


Function DLL_DATATEST()

		print GetDataPointer()


		Label4=100
		restore Label4


		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)



		; find the first instance of 50 from the current data pointer position
		print FindData(50)
		


EndFunction







 PlayBasic To DLL Work In Progress Update

By: Kevin Picone Added: October 7th, 2013

Category: All,Update,Tools,Machine Code

PlayBasic To DLL (Convert PlayBasic to Machine Code DLL's)

     I've been quietly working on two sides of the tool in parallel, the translator tool, as well as making updates to PB so they can integrate side by side. It's pretty slow going as some things are added quicker than others, in particular commands that aren't actually commands in the legacy VM, which need to be wrapped in order to create an external interface. Most of the core operations work like this.

     The current edition of the translator supports around 160->170 core commands as well as Integer, Float, String, Pointer , Arrays (int, float, string, used defined typed) and core logic. The great thing about using the PlayBasic compiler to build the byte code, is the resulting code has lots of redundancies removed for us. Enabling us to export cleaner & faster executing assembly.

     The assembly generation routines are a cross between cookie cutter and smart at this point. It all depends upon the operation, the current generator can only optimize output code for extension speed, when it notices friendly sequences. The excitingly thing about that, is the machine code is already routinely faster than our competitors.

     Here's a few tidbits from the Work In Progress blogs.



PlayBasic To Dll - One Stop Shop - (August 20, 2013)

     It's 5:09am and the tool finally has it's first taste of automation. Previously, I had to compile the PlayBasic code to byte code, then copy the output object code to the test folder, run the convertor, cut'n'paste the resulting source code fragments into the dll template, assemble and repeat.. over and over... Which gets old real fast ! So the goal tonight has been to get the program to a point where I can point it at a PlayBasic source file (PBA file) and it'll call the compiler, build the byte code and do all the conversions itself. There's a couple of hacks for the time being, since the compiler will need a specific mode for this stuff, But all in all, it's pretty painless.

     The build speed is pretty good, even though the test sources are very simple, the actual conversion and assembly stage is consistently executing in about 50 milliseconds (or less). The conversion engine only supports a single PlayBasic source file at this time, it doesn't support includes (couldn't be bothered at this stage).. The resulting DLL will have all the code in the source in it, even if it's not in use. So ideally you'd use it to compile stand alone include files that perform some brute force task. The tool expects the functions you want to be made visible (exported) to have "DLL_" at the start of the function name. The tool rips this off, it's just a way to ID what functions you wish to export, without having to change the PlayBasic compiler dramatically.

     Once the DLL is built, you can not only link this to your application but bind it to be executed from memory (doesn't need to be exported to disc). Size wise the resulting DLL's are pretty small, weighing in about 5K for the output of the following.



PlayBasic Code:
Function DLL_JumpTableTest(ptr)

	; integer for next step loop
	For lp =0 to 100 step 10
		pokeint ptr,lp
		ptr+=4	
	next

	print lp
EndFunction



Function DLL_ForLoopTest(ptr)


	StepY=10
	StepX=10

	Counter=0
	; integer for next step loop
	For ylp =0 to 100 step StepY
		For xlp =0 to 100 step StepX
				Counter++
		next
	next


	For ylp =100 to 0 step -StepY
		For xlp =100 to 0 step -StepX
				Counter++
		next
	next



	a=100
	b=200
	swap a,b

	
	print Counter
EndFUnction


Function DLL_JumpTableTest_BIG(a)

	; integer for 'next with literal 
	for lp=0 to 100
		a=b
	next

	; Integer for next with variable/register end value
	for lp=0 to B
		a=b
	next

	; Nested integer for / next loop
	For xlp=A*B to 100
		For ylp =0 to xlp*100	
				Stuff=xlp	
		next
	next




	on a goto label0,label1,label2,label3

   a=999	
	goto done

Label0:
		a=0
		goto done
Label1:
		a=111
		goto done
Label2:
		a=222
		goto done

Label3:
		a=333
		goto done
Label4:
		a=444
	
Done:

	a=addtest(a,40000)	
EndFunction

Psub AddTest(A,B)
		result=a+B
EndPsub result



COMMANDS USED: POKEINT | PRINT |




PlayBasic To Dll - Fractals anyone ? - ( August 24, 2013)

     Attached you'll find a nice shiny example of what the DLL convertor is able to do today in the form of fractal render. I've modified the code slightly to work around a few functions that aren't supported as yet (the original code is in the source code board), but the result is a pleasant 18->19 times the performance improvement. The demo is drawing 640*480 pixels with potentially 200 square roots per pixel, So yeah.... that's a lot of work for the runtime to try and brute force.

     The convertor currently has a hand full of opt's it can make when translating / exporting code, but it has no real awareness of the register management, so it's hitting the variable heap a lot more than what it should (extra memory accesses). Even without bust a gut though, it's working pretty well for now on my 8 year old athlon system..

     Made a few register tweaks before tea tonight, then ported the bench mark code to a couple of competitors. No surprises the PlayBasic version runs 2.8 times faster than one, 4.5 times faster than the other... Oh dear, how embarrassing that must be for them...



PlayBasic To Dll - Strings -(August 28, 2013)

     Been working on getting strings working most of the afternoon only to run into a strange crash when two string are added together. On inspection one string was legal (Hello World) and the other was null for some reason.. It's funny how your mind focuses in on a segment of code of you think is the problem, only to find the issue a few lines above it. Turned out the function initialization was killing the string buffer. Once corrected, it worked as expected.

     So far I've only got a handful of core operators hooked up, it's just a matter of joining the dots. Something that is interesting is the when we start talking string management, we actually get less benefit from translating to machine code than what you might think. Unfortunately there's this idea out there that machine language is the golden bullet, but really it isn't and never was. In regards to strings.. well, there's no 'instruction set' in your CPU for doing string operations, everything is just reading and writing arrays of bytes. So if we add two big strings together, then regardless of how this operation was called, be it from machine code or the VM, the string joining operation is taking 99.9999% of execution time here.

     Strings are a notorious bottle neck of programming languages, knowing that, the PlayBasic string engine is a very optimal solution, every effort has gone into making it as quick as possible. That's why I write string processing apps in it..

     Here's a little something to bend your reality.. The function joins Hello World together 101 times. There's two version of the test, exported DLL version and the VM function. Bellow is clip from the current test code. So basically PB2DLL is pointed at this source and we get a nice shiny dll version couple of seconds later..

PlayBasic Code:
LinkDLL  "StringTest.dll"

		; String tests
		DLL_StringTest() alias "stringtest" as string
		
EndLinkDLL

	startinterval(0)
		for test=0 to 100
				Result$=DLL_StringTest()
		next
	print EndInterval(0)
	print Len(Result$)
	
	
	StartInterval(0)
		for test=0 to 100
				result$=DLL_StringTest2()
		next
	print EndInterval(0)
	print Len(Result$)

	Sync
	waitkey
	



Function DLL_StringTest2()
		s$="Hello World"

		for lp =0 to 100
			b$+=s$
		next	
				
		result$=b$		
Endfunction result$


COMMANDS USED: LINKDLL | ALIAS | STRING | ENDLINKDLL | PRINT | LEN | SYNC | WAITKEY |


     Yep, obviously the machine code version is going to be faster, but the interesting thing is by how much ? It'd be easy to assume it's going to be 5->10 times faster, where it's actually only around 35% faster.. Why, because it's spending most of it's time copying characters, not executing VM opcodes.

     To put that in some real world perspective, DLL version is 12 times faster than one competitor and 18 times faster than another.



PlayBasic To Dll - Typed Pointers Array Fields - (September 01, 2013)

     Getting this working has been a detoured chain of events. The first problem was the disassembler didn't support most of the pointer opcodes I needed, so the first port of call was adding that functionality, just so I could translate it back into assembly. After adding the decoder, it's here we notice there extra additions in the array field writes with type pointers. Could have ignored this, as an extra opcode in output might not like sound like much waste here and there, but if that code is sitting in some brute force loop, then it's throwing away 1/3 of the operations performance for nothing. This wastefulness would then be translated to the machine code DLL too, so it'd just be extra unwanted wasted cycles having a negative impact when the code is within a loop.

     The only way to solve such problems is fire up PlayBasic and take a look at what it generates in particular situations. For some reason it was adding the structure displacement offset to the temp pointer register, adding the array offset, then doing the write. When all it should need is the adding the array offset, then do the write since the writes opcodes support displacement. So the offset is virtually free. Moreover, it didn't support literal array indexes, which can be pre-computed at compile time and represented as one displacement. So that was yesterdays little chore. The results are as expected as it's 30% quicker. I suspect there might be a few more situations like that hidden away also.

     Tonight's mini session has been all about hooking up the assembly generation side, which gone relatively well really. Meaning it can produce working code from the following.

PlayBasic Code:
	Type CoolType
			x,y,z
			a#,b#,c#
			ThisString$
			IntArray(10)
			FltArray#(10)
			StrArray$(10)
			cool
	EndType

	
	
Function DLL_Pointer_FillCoolType(Address)
		if Address

			DIm Me as CoolType pointer
			Me=Address
			
			me.x=111
			me.y=222
			me.z=333
			
			me.a#=111.111
			me.b#=222.222
			me.c#=333.333
			
;			me.ThisSTring="String"
			
			for a=0 to 9
				me.intarray(a) = 2000+a
				me.fltarray(a) = 2222.34+a
				me.Strarray(a) = "storm"+str$(a)
			next

			me.intarray(1) = 1001 
			me.intarray(2) = 1002
			me.intarray(3) = 1003
			
			me.fltarray(0) = 1000.111
			me.fltarray(1) = 1001.111 
			me.fltarray(2) = 1002.111
			me.fltarray(3) = 1003.111

			me.Strarray(0) = "cool1"
			me.Strarray(1) = "cool2"
			me.Strarray(2) = "cool3"
			me.Strarray(3) = "cool4"
			
			me.cool=123456
			
		endif
EndFunction result$


COMMANDS USED: DIM | POINTER | STR$ |


     So it's getting to pretty familiar level of functionality, there's of course plenty of no no's just waiting to trap you. The main one that comes to mind, would be the lack of auto casting in some translated operations. Like if you have a FOR/NEXT loop, then it currently only supports Integer loop counters, where in PB you can have Integer or floating point loop counters. Same with things like function parameters. If a function expects an integer and you pass it a float, you can get away with this in PB, since the runtime is recasting the parameter on demand, but the translator tool doesn't currently support this. It will.. just not today.



     (To get the most up-to-date info, you'll have to read the complete blog on our forums)






Viewing Page [3] of [3]



 

 
     
 
       

(c) Copyright 2002 / 2024 Kevin Picone , UnderwareDesign.com  - Privacy Policy   Site: V0.99a [Alpha]