PlayBASIC V1.64P (Work In Progress) Gallery

Started by kevin, August 31, 2013, 02:38:09 PM

Previous topic - Next topic

kevin

#30
PlayBASIC V1.64P Beta 38 - Loopy Loops

       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.      

monkeybot

glad to see you're not watching the new tv box too much.Roll on PBDLL. :-)

kevin

Quoteglad to see you're not watching the new tv box too much.Roll on PBDLL. :-)

   Well it is (well was) holiday time here.. so yeah i've been watching and playing a bit more than normal..  


PlayBASIC V1.64P Beta 38 - For / Next Loop updates

   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: [Select]
      For lp =0 to 100
print lp
next



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

PlayBASIC Code: [Select]
     if 0<=100
For lp =0 to 100
print lp
next
endif

 

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


kevin

#33
 PlayBASIC V1.64P BETA #39 (Retail Compiler Only 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


     Old beta removed


kevin

#34
 PlayBASIC V1.64P BETA #41 (Retail Compiler Only Beta) (11th,June,2014)

     Beta #41 includes some string function replacements including GetFileName$(), GetFolderName$(), GetDeviceName$() and GetFileExt$().   The existing where legacy functions and internally needed to be converted from VM2 ->VM1 format then back to VM2 strings.  Which obviously very slow and a potentially buggy process.      

     The show just how slow that process can be we have the standards performance over time test.    The code first demo's that the functions work, then brute force calls them 10000 odd times.    Running this code on BETA 39 and gives runtime performance of about 1FPS..  Where as running on Beta 41 and it runs and 60fps (Althon 3000 FX64 system)

     Those performance benefits are not just from the VM though,  DLL built with PB2DLL call the internal PB command sets.  So any performance gain from the function will be gained from compiling the code to DLL also..  


PlayBASIC Code: [Select]
   s$="C:\Stuff\MoreStuff\yeah.exe"
; s$="C:notehead.txt"

print GetDeviceName$(S$)
print GetFolderName$(s$)
print GetFileName$(s$)
print GetFileExt$(s$)


print FileExist(S$)
print FolderExist(GetFolderNAme$(S$))


print asc("\")
sync
waitkey



Max=10000


Do

cls
frames++


t=timer()
for lp =0 to max
result$= GetDeviceName$(S$)
next
tt1#+=timer()-t
print result$


t=timer()
for lp =0 to max
result$= GetFolderName$(S$)
next
tt2#+=timer()-t
print result$


t=timer()
for lp =0 to max
result$= GetfileName$(S$)
next
tt3#+=timer()-t
print result$


t=timer()
for lp =0 to max
result$= GetFileext$(S$)
next
tt4#+=timer()-t

print result$


print tt1#/frames
print tt2#/frames
print tt3#/frames
print tt4#/frames


print Fps()

sync
loop








Download


    removed.


kevin

#35
 PlayBASIC V1.64P BETA #41b (Retail Compiler Only Beta) (12th,June,2014)

     Beta #41b restores GetFileName$() to the same behavior as old editions.  In Beta 40 it'd not return anything if there wasn't a \ or colon in the path.



Download



     Obsolete, newer release bellow



kevin

#36
 PlayBASIC V1.64P BETA #42 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY)  (24th,Jun,2014)


     Beta #42 this build both corrects a few nasty little issues and of course adds some limited support for OPENGL


     NOTE: OpenGL rendering requires the G2D library..  



Download:


     Obsolete Beta Removed

kevin


PlayBASIC V1.64P - Building Release

      Well... after something of a delay I've started building the all the release versions for the V1.64P update.   There's not enough time tonight for a release, so suspect that'll come later today possibly  Sunday night (my time).    Was planning on importing a few more VM changes, but they can wait until the next round of updates.   This version will sync up with current PB2DLL releases, so there's no need to update that at this time.     



kevin

#38
 PlayBASIC V1.64P2 BETA #01 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY)  (7h,Oct,2014)


     Beta #01 addresses a few bugs in the sprite commands as well as addressing pass #1 parsing issue that wouldn't allow comments after Function/Psub prototypes.  While single comments are supported now, comment blocks aren't at this time.

      Eg..
PlayBASIC Code: [Select]
Function DoStuff(A,B,C)   ; My Comment


EndFunction







Download:


   Old beta Removed.



kevin


  PlayBASIC V1.64P2 BETA #02  - Pointer Corrections
 
     Somewhere during V1.64P (or perhaps later) a number of odd parsing issues have appeared with pointers.  Pointers are internally one of the foundational elements of the runtime, the issue has been with the higher level exposure of  these.  In terms of the parser they've always been (and still are) something of after thought which apparently makes them even more susceptible to parsing changes.    Fixed a couple of odd problems that seemed to occur during math operations between them as well as de-referencing (peeking) them..   

     So code like this is working again..

PlayBASIC Code: [Select]
; declare this as a generic (type less) pointer
Dim GenericPointer As Pointer

; Allocate a new bank and get the address of the bank for our pointer
GenericPointer= GetBankPtr(NewBank(1000))

; Write some integer data into this memory (assumes type from the right hand data type)
*GenericPointer = $11223344


; Recast our generic pointer as byte pointer and return this byte from memory as a hex string
print hex$(*byteptr(GenericPointer))

; do the same as above, but from the next byte and so on
print hex$(*byteptr(GenericPointer+1))
print hex$(*byteptr(GenericPointer+2))
print hex$(*byteptr(GenericPointer+3))

Sync
WaitKey







kevin

#40
 PlayBASIC V1.64P2 BETA #02  - Pointer Corrections Continued

     Last week was full of fun,  if not wasn't out on the mower or  wrestling with our tax return then i was hunting parsing issues concerning pointers.   Fixed a number oddities earlier in the week, only to discover those fixes broke other seemingly unrelated code later in the week. Initially it seem unrelated, but upon close inspection there was generation common function that could leave the expression in the state that following generators would make incorrect assumptions upon.

     One such case occurred, when the parser was resolving user defined type array fields, which would call this function and occasionally get back some strange data.   Making them do everything from function correctly to completely fail.  I've actually noticed something like this oddity before in the byte code diss-assemblies, but was unsure if that an issue in the compiler, runtime  or dissassembly.  The program ran so one would assume the latter, but apparently not.  Which is fairly rare really.  

    The following is the current test code that's running in the latest Beta #2 which i'll uploader later

PlayBASIC Code: [Select]
      Test01_GenericPointerCasting()

TEst02_TypedPointers()

TEst03_TypedArrays()

end


; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------

Function Test01_GenericPointerCasting()

cls
print "Test #01 - Generic Pointer Read Writing"


; Allocate a new bank and get it's address in memory
Dim GenericPointer As Pointer

GenericPointer= GetBankPtr(NewBank(1000))

; Write sopme data into this memory
*GenericPointer = $11223344

print Int(GenericPointer)
print hex$(*byteptr(GenericPointer))
print hex$(*byteptr(GenericPointer+1))
print hex$(*byteptr(GenericPointer+2))
print hex$(*byteptr(GenericPointer+3))


GenericPointer=GenericPointer+4
*GenericPointer = $11112222

print Int(GenericPointer)
print hex$(*wordptr(GenericPointer))
print hex$(*wordptr(GenericPointer+2))


GenericPointer=GenericPointer+4
*GenericPointer = $AABBCCDD
print Int(GenericPointer)
print hex$(*intptr(GenericPointer))

GenericPointer+=4
*GenericPointer = $AABBCCDD
print Int(GenericPointer)
print hex$(*intptr(GenericPointer))


print "Press Any Key"
flushkeys
Sync
WaitKey


EndFunction




; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------

Type PersonInfo
Name$
Age
Address$
EndType

Type TestType
Status
Counter
x#,y#,z#
IntArray(10)
FltArray#(10)
StrArray$(10)
Person as PersonInfo
EndTYpe


Function TEst02_TypedPointers()

cls
print "Test #02 - Typed Pointer Testing"


Dim Me as TestType Pointer

Me = new TestType

print "Me Address:"+Str$(Int(Me))

Me.Status = true
Me.Counter = 1
Me.Counter = 1.0
Me.Counter ++

Me.X =ME.X +100
Me.X =100+ME.X
Me.X += 100
Me.Y += me.x*10
Me.Z += me.y*22
Me.Z += me.y/22

Me.Z += 22/me.z*me.z
Me.Z += 22*me.z


; array fields
For lp =0 to 5
me.IntArray(lp)++
me.IntArray(lp)+=1+me.IntArray(lp)

me.FltArray(lp)++
me.FltArray(lp)+=1.23+me.FltArray(lp)

me.StrArray(lp)= "Hello World"
me.StrArray(lp)++
me.StrArray(lp)+= "More Text"+me.StrArray(lp)


me.Person.Name ="Name of person"
me.Person.Age =101

next

print ".Status:"+Str$(Me.Status)
print ".Counter:"+Str$(Me.Counter)
print " .X#:"+Str$(Me.x#)
print " .Y#:"+Str$(Me.y#)
print " .Z#:"+Str$(Me.z#)


For lp =0 to 5
print lp
print " >"+str$(int(me.IntArray))
print " >"+str$(me.IntArray(lp))
print " >"+str$(me.FltArray(lp))
Login required to view complete source code





Download:


      Download PlayBASIC V1.64P2 Beta #2  (3rd,Nov,2014)  - ( Obsolete Beta Removed )





kevin


   PlayBASIC V1.64P2 BETA #04  - Debugger - Controlling Auto Allocation Behavior

           Even though automatic type allocation is one of those things that's been hidden away deep inside PlayBASIC now for the best part of a decade, i'd be surprised if many people actually knew it occurs.   Basically any time you declare a typed variable , or typed array, the runtime includes some hand holding code with will prevent you code from failing when you attempt to access a type that's not been allocated. 

          Here's an example,

PlayBASIC Code: [Select]
   Type pos
x#,y#,z#
EndType

dim a as pos

a.x = 45

print a.x

sync
waitkey




         Notice after the declaration we're writing to a type before we've written a NEW object in it ?  That's automatic type allocation right there.   The VM traps this situation and automatically NEWS the type structure so we've something to write into.   Something similar occurs when reading a none existent type, where is the opcode returns a NULL. 

         What today's addition does is allows the user to toggle the runtime type allocation when running in debug mode. When you turn it off, it'll error on such lines.  Which might not seem all that useful, until you start writing DLL libraries with PlayBASIC2DLL, since the auto allocation isn't supported in the DLL's at this time.   

 

kevin

#42
 PlayBASIC V1.64P2 BETA #04b  (Released)  (26th Nov,2014)

     Beta #04 makes a few subtle changes.  This is the first version to include a manifest resource which will help PB when running on newer operating systems and with some of new libraries such as PB Dialogs2, which is another replacement for the PB dialogs library.    The Dialogs 2 library is same in principal to the first, but smaller and more up to date.  

     Some other changes found in this build are some more compiler optimizations, which can resolve array pointers with literal array indexes, plus even a new debugger mode that allows you to toggle if the runtime allows 'auto type allocations' or not.  This mode is enabled by default (so your programs run as normal!), there's no compiler switch at this time, only a debugger switch.     Whenauto allocation is turned off the runtime will halt execution if your program tries to access a type variable / type array  that hasn't been manually allocated with the NEW operator.  

PlayBASIC Code: [Select]
   #break
Type Stuff
x,y,z
EndType

Dim me as stuff

me.x = 100
me.y = 100
me.z = 100

Sync
waitkey





  Code like this will only run when automatic type allocation is enabled, if you run this in debug mode and turn it off,  you'll get a runtime error.   This is because the DIM statement allocates the variable/array container and not actually the TYPE instance.    So the structure is created, but no types have been allocated and stored in it.    Which is what allows you to store different types in the same variable/list/array (inheritance)

PlayBASIC Code: [Select]
   #break
Type Stuff
x,y,z
EndType

; builds the container this variable uses at runtime
Dim me as stuff

; allocate a type handle and store it in ME() container.
Me = new STUFF

; proceed as normal
me.x = 100
me.y = 100
me.z = 100

Sync
waitkey








Download



   Obsolete beta removed


kevin

#43
PlayBASIC V1.64P2 BETA #06  -  Better Literal Casting When Writing to UDT Pointer fields.

     While working on the PB2DLL machine code translator ran into a could of issues, the first was that the compiler didn't tag and export pointers flags correctly.  Without those, it made it impossible to detect if pointer was user defined or a VM temp register.  This is necessary when you wish to resolve UDT pointers and their fields when they appear in sequences.  The other issue was that there was some bogus casting when using operators on UDT fields and literals.  The casting would throw and extra instruction that wasn't necessary.  

       The following example benchmarks 30% quicker in tonight's build than any previous edition,   which will of course have a flow of effect into PB2DLL code generation.   What was happening, is if you assigned an Integer to a float field say, the process would insert a cast.   Which is fine, when it's  an integer variable, but if it's an integer literal, then the compiler should recast it compile time, avoiding the casting at runtime..

PlayBASIC Code: [Select]
   type Stuff
x#,y#,z#
a,b,c
Endtype

dim me as stuff pointer
me = new stuff


max=10000


Do
Cls

Frames#++
t=timer()
For lp=0 to max
me.x#=100
me.y#=100
me.z#=100

me.x#+=5
me.y#+=5
me.z#+=5
next
TT1+=(timer()-t)
print tt1/frames#


t=timer()
For lp=0 to max
me.a=100.0
me.b=100.0
me.c=100.0

me.a+=1.0
me.b+=1.0
me.c+=1.0

next
tt2+=(timer()-t)
print tt2/frames#


Sync

loop






       



kevin

#44
   PlayBASIC V1.64P2 BETA #07  -  Constant Colour Alpha Blend Speed Ups

       An hour of ago hit upon an idea for a possible speed up when doing variable alpha blending with a constant colour (inkmode 16), so when I had a look at the graphic engine noticed there wasn't any MMX support for this operation, so decided to add some and try the idea out.   The concept is simple you can pre-blend the input colour and do the post blend on with packed multiply.  Which gives us an inner loop of about 8->9 assembly instructions per 32bit pixel, but only 1 multiply per pixel.    After a bit of messing around, with the routine not working or blending in reserve to the old routine, it's up and running.     Performance wise the replacement routine is about twice as fast as the previous routine.  

       The demo bellow is potentially blending 14647680 32bit pixels.  On my legacy test system it only renders at about 10->11fps, the new version runs at 19fps. Might be able to claw back a few extra cycles when I look at the routine(s) later.  Would be nice to break 20 on this old box.    


PlayBASIC Code: [Select]
   Screen=NewImage(getScreenWidth(),GetSCreenHeight(),2)


; build a table of colours
Dim Colours(1024)
for lp=0 to 1024
Colours(lp)=rndrgb()
next


; --------------------------------------------------------------------
Do
; --------------------------------------------------------------------

rendertoimage screen
cls $334466

Size=100
xpos=0
ypos=0
pixelcount=0
; set ink mode to variable alpha blend with target

inkmode 1+16
for Alpha =0 to 255

;
inkalpha alpha/255.0 ;512.0

; draw box using the current inkmode
boxc xpos,xpos,xpos+size,ypos+size,true,Colours(Alpha)

; tally the number of pixels
PixelCount+=(Size*size)

; move boxes position, so we're not drawing completely over each previous render
xpos++
ypos++

; increase the size of the box
Size++
next

inkmode 1

rendertoscreen
drawimage screen,0,0,false

text 0,0,"Pixels Blended:"+Str$(pixelcount)
text 0,20,"MmX:"+Str$(GetGFXMMX())
text 0,40,"Fps:"+Str$(fps())

if spacekey()
GFXMMX 1-GetGFXMMX()
flushkeys
endif

Sync

; --------------------------------------------------------------------
loop
; --------------------------------------------------------------------






    EDIT #1:  The initial alpha blender was only handling a single pixel per loop, converting it to parallel gives us another couple of FPS back on this system, so it's now in the 21/22 range for the same number of pixels (another  5->6 milliseconds faster).