(http://underwaredesign.com/PlayBasicSig.png)
PlayBASIC V1.65 (Work In Progress) Gallery (3rd April, 2016 - 3rd Oct, 2023)
This thread will document the changes being made for the PlayBASIC 1.65.
Retail Builds
See PlayBASIC V1.65C2b (https://www.underwaredesign.com/forums/index.php?topic=4333.msg30367#msg30367) (fourth revision #2) (12th,Sep,2021)
See PlayBASIC V1.65C2 (https://www.underwaredesign.com/forums/index.php?topic=4333.msg30293#msg30293) (fourth revision) (10th,July,2021)
See PlayBASIC V1.65C (https://www.underwaredesign.com/forums/index.php?topic=4333.msg29665#msg29665) (third revision) (21st,Oct,2018)
See PlayBASIC V1.65B (http://www.underwaredesign.com/forums/index.php?topic=4333.msg29419#msg29419) (second revision) (23rd,June,2017)
See PlayBASIC V1.65 (http://www.underwaredesign.com/forums/index.php?topic=4333.msg29234#msg29234) (initial release)
Work In Progress Beta History
V1.65C3
See Beta 9 (https://www.underwaredesign.com/forums/index.php?topic=4333.msg31283#msg31283)
See Beta 8 (https://www.underwaredesign.com/forums/index.php?topic=4333.msg31278#msg31278)
See Beta 7 (https://www.underwaredesign.com/forums/index.php?topic=4333.msg31274#msg31274)
See Beta 5 (https://www.underwaredesign.com/forums/index.php?topic=4333.msg31182#msg31182)
See Beta 4 (https://www.underwaredesign.com/forums/index.php?topic=4333.msg30771#msg30771)
V1.65C2
See Beta 20 (https://www.underwaredesign.com/forums/index.php?topic=4333.msg30214#msg30214)
See Beta 15 (https://www.underwaredesign.com/forums/index.php?topic=4333.msg29985#msg29985)
See Beta 14 (https://www.underwaredesign.com/forums/index.php?topic=4333.msg29957#msg29957)
See Beta 12 (https://www.underwaredesign.com/forums/index.php?topic=4333.msg29767#msg29767)
V1.65C
See Beta 41 (https://www.underwaredesign.com/forums/index.php?topic=4333.msg29640#msg29640)
See Beta 24 (http://www.underwaredesign.com/forums/index.php?topic=4333.msg29557#msg29557)
See Beta 22 (http://www.underwaredesign.com/forums/index.php?topic=4333.msg29544#msg29544)
See Beta 20 (http://www.underwaredesign.com/forums/index.php?topic=4333.msg29529#msg29529)
See Beta 4 (http://www.underwaredesign.com/forums/index.php?topic=4333.msg29469#msg29469)
See Beta 3 (http://www.underwaredesign.com/forums/index.php?topic=4333.msg29457#msg29457)
V1.65
See Beta 57 (http://www.underwaredesign.com/forums/index.php?topic=4333.msg29215#msg29215)
See Beta 55 (http://www.underwaredesign.com/forums/index.php?topic=4333.msg29197#msg29197)
See Beta 54 (http://www.underwaredesign.com/forums/index.php?topic=4333.msg29186#msg29186)
See Beta 52 (http://www.underwaredesign.com/forums/index.php?topic=4333.msg29179#msg29179)
See Beta 51 (http://www.underwaredesign.com/forums/index.php?topic=4333.msg29176#msg29176)
See Beta 50 (http://www.underwaredesign.com/forums/index.php?topic=4333.msg29174#msg29174)
See Beta 49 (http://www.underwaredesign.com/forums/index.php?topic=4333.msg29171#msg29171)
Retail Upgrade History
For older upgrade work in progress see,
See PlayBASIC V1.64P (http://www.underwaredesign.com/forums/index.php?topic=4089.0)
See PlayBASIC V1.64O (http://www.underwaredesign.com/forums/index.php?topic=3988.0)
See PlayBASIC V1.64N2 & V1.64N3 (http://www.underwaredesign.com/forums/index.php?topic=3833.0)
See PlayBASIC V1.64N (http://www.underwaredesign.com/forums/index.php?topic=3651.0)
See PlayBASIC V1.64M (http://www.underwaredesign.com/forums/index.php?topic=3440.0)
See PlayBASIC V1.64L Learning Edition History (http://www.underwaredesign.com/forums/index.php?topic=3405.0) (Building learning Edition Thread)
Update Mission Statement:
Runtime Update Objectives: Faster, Smaller and Static.
Faster: Further bridge gap between native (machine code) and byte code execution through runtime.
Smaller: Separate command sets from runtime instruction sets. So runtime is independent of command set implementations.
Static: Instruction set, to make translations easy.. finally !
Upgrade Work In Progress Blog Followes
PlayBASIC V1.65 - Beta1/2 - Trig Instruction Set Tweaks
Like most updates work on the next revision started a day or two after the last one was uploaded and this is no different. Right off the bat there's a lot to do to get the runtimes where I need them. Superficially, all I'm doing is making the internal command sets more standardized (static) and hopefully some what cleaner.
In the last couple of V1.64P builds we're been testing some updated strands of the instruction set, with pretty positive results. The nice benefit of those is they don't break translations through PlayBASIC2DLL, meaning it's still compatible with those DLL's. So in keeping with such changes I've been converting the TRIG function block to same method. The benefit ranges from small to large, where a simple Cos() / Sin() function call is marginally quicker, but stacked polar functions are up to double. Which is SinRadius, SinNewValue styled functions.
The snaps bellow are of trig threshold death test, where is running each test millions of times.. The gains over V1.64P4 can be up to around twice as fast.. But like most benchmarks the shots aren't very interesting. (Tested on 11 year old athlon 64 system)
PlayBASIC V1.65 Beta 2 - Instruction Set Tweaks - Comparisons
Today's little update session was focused around the comparison instruction set, which is one of the old sections of the code in what in now the legacy runtime. Didn't take too long to get an alternative version set up and it seems to running as expected. The updated lay out isn't entirely what I've in mind as that will take a number of compiler & instruction set tweaks, but there's already a nice gain.
Here's the test code and some pictures of the test running on the 11 year old athlon...
[pbcode]
; ----------------------------------------------------------
; ----------------------------------------------------------
; COMPARE BENCH MARK TESTER
; ----------------------------------------------------------
; ----------------------------------------------------------
MaxTests =100
Size =10000
b=100
B#=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 A<=B
print A#<=B
print A<=B#
print A#<=B#
print "String compares:"
a$="aaaa"
b$="bbbb"
print a$=b$
print a$<>b$
print a$<b$
print a$<=b$
print a$>b$
print a$>=b$
print "Done"
; sync
;waitkey
;end
Do
cls
frames++
print "Number Of Tests:"+Str$(Size)
print ""
print ""
print ""
print "Integer and Float Compare Functions ----------------------------"
t=timer()
for lp=0 to Size
result=a=b
result=a=b
result=a=b
result=a=b
result=a=b
result=a#=b
result=a#=b
result=a#=b
result=a#=b
result=a#=b
result=a=b#
result=a=b#
result=a=b#
result=a=b#
result=a=b#
result=a#=b#
result=a#=b#
result=a#=b#
result=a#=b#
result=a#=b#
next
tt1#+=(Timer()-t)
print " Equals:"+str$(tt1#/frames)
t=timer()
for lp=0 to Size
result=a<>b
result=a<>b
result=a<>b
result=a<>b
result=a<>b
result=a#<>b
result=a#<>b
result=a#<>b
result=a#<>b
result=a#<>b
result=a<>b#
result=a<>b#
result=a<>b#
result=a<>b#
result=a<>b#
result=a#<>b#
result=a#<>b#
result=a#<>b#
result=a#<>b#
result=a#<>b#
next
tt2#+=(Timer()-t)
print " Not Equals:"+str$(tt2#/frames)
t=timer()
for lp=0 to Size
result=a<b
result=a<b
result=a<b
result=a<b
result=a<b
result=a#<b
result=a#<b
result=a#<b
result=a#<b
result=a#<b
result=a<b#
result=a<b#
result=a<b#
result=a<b#
result=a<b#
result=a#<b#
result=a#<b#
result=a#<b#
result=a#<b#
result=a#<b#
next
tt3#+=(Timer()-t)
print " Less Than:"+str$(tt3#/frames)
t=timer()
for lp=0 to Size
result=a<=b
result=a<=b
result=a<=b
result=a<=b
result=a<=b
result=a#<=b
result=a#<=b
result=a#<=b
result=a#<=b
result=a#<=b
result=a<=b#
result=a<=b#
result=a<=b#
result=a<=b#
result=a<=b#
result=a#<=b#
result=a#<=b#
result=a#<=b#
result=a#<=b#
result=a#<=b#
next
tt4#+=(Timer()-t)
print " Less Than Equals:"+str$(tt4#/frames)
print ""
print ""
print ""
print ""
print "STRING Compare Functions ----------------------------"
t=timer()
for lp=0 to Size
result=a$=b$
result=a$=b$
result=a$=b$
result=a$=b$
result=a$=b$
next
tt5#+=(Timer()-t)
print " String =:"+str$(tt5#/frames)
print result
t=timer()
for lp=0 to Size
result=a$<>b$
result=a$<>b$
result=a$<>b$
result=a$<>b$
result=a$<>b$
next
tt6#+=(Timer()-t)
print " String <>:"+str$(tt6#/frames)
print result
t=timer()
for lp=0 to Size
result=a$<b$
result=a$<b$
result=a$<b$
result=a$<b$
result=a$<b$
next
tt7#+=(Timer()-t)
print " String <:"+str$(tt7#/frames)
print result
t=timer()
for lp=0 to Size
result=a$<=b$
result=a$<=b$
result=a$<=b$
result=a$<=b$
result=a$<=b$
next
tt8#+=(Timer()-t)
print " String <=:"+str$(tt8#/frames)
print result
t=timer()
for lp=0 to Size
result=a$>b$
result=a$>b$
result=a$>b$
result=a$>b$
result=a$>b$
next
tt9#+=(Timer()-t)
print " String >:"+str$(tt9#/frames)
print result
t=timer()
for lp=0 to Size
result=a$>=b$
result=a$>=b$
result=a$>=b$
result=a$>=b$
result=a$>=b$
next
tt10#+=(Timer()-t)
print " String >=:"+str$(tt10#/frames)
print result
print "-----------------------------------------"
print "FPS:"+STR$(FPS())
Sync
loop
[/pbcode]
PlayBASIC V1.65 Beta 3/4 - DATA Instruction Set
After picking through some of the easier to convert blocks of the runtime instruction set I've come to that wall where the remaining changes can't be as easily accomplished. Meaning to process further down the rabbit hole, means changing the compiler/runtime and instruction sets. Making everything slower.. and tedious.. It's not all bad news though, there's a lot of code that can be harvested, tweaked into shape.
Before getting into the current WIP, I was able to make some more tweaks to the comparison instruction set and compiler to remove a bogus state temp that was in the previous bench mark and I guess all legacy builds. The state was only created when using the compare in a write expression (ie Result = A$ <> b$ ), which doesn't happen often in real life. But it was getting in the way of the bench.. Anyway, after that applied the same loops peel back about 2 milliseconds from the loop. So the demo runs in about 18-19 FPS. On the old test box..
Looking through the instruction set here's only about 5 or 6 blocks that need to be converted now. Annoyingly a lot of instructions are interdependent making them a house of cards, so if you only change one part, it'll break other parts badly. Which was the main problem back in the initial PB-> PBFX translation. This time though all the main command set is detached from the runtimes already (thanks PB2DLL), while still part of the instruction set, they're not same led balloon hanging around the neck of the translation.
So the stuff left to do is just thinks like looping, operators, core maths, array + variable structure accessing opcodes. There's some legacy pollution though with commands being blocked into the core set that should be. One of those was the DATA commands.
How the compiler/runtime handle data has always been a bit of annoyance, it made sense a decade ago, but not today. Sop that's what I've been doing I've been writing a replacement set of functions to handle the DATA heap. The new format uses less memory and should be quicker generally. The main thing I didn't like about the old way was it polluted the variable data tables, as DATA would like in those tables, but that's been changed now...
The library seems to be working so I'll plug it into the compiler and await the expected crashes tonight sometime.. what joy !
PlayBASIC V1.65 Beta 5 - DATA Bench
The data command set has been replacement with some surprising runtime results, with the bench doubling in performance. I was expecting it to be quicker, but not by that much, so that was a nice surprise.
The bench code is as follows. You'll need the attached version as i suspect the entire code would be too long for a post..
[pbcode]
cls 0
print "DATA SPEED TEST - Waiting"
sync
For lp=1 to 5
wait 1000
Sync
next
Dim Results#(100)
TestStart=Timer()
Dataloop =readdata()
MaxTests =500
; -------------------------------------------------------------------------
; -------------------------------------------------------------------------
Repeat
; -------------------------------------------------------------------------
; -------------------------------------------------------------------------
Cls 0
frames=frames+1
Test=0
Print "Displaying Average Times for "
Print "Current Frame:"+Str$(frames)
print "Data Loops:"+str$(DataLoop)
;--------------------------------------------------------------
;----INTEGER READING-------------------------------------------
;--------------------------------------------------------------
temp=0
ts=Timer()
For i = 0 To MaxTests
restore IntegerValues
for dlp=1 to Dataloop/10
Result=readDATA()
Result=readDATA()
Result=readDATA()
Result=readDATA()
Result=readDATA()
Result=readDATA()
Result=readDATA()
Result=readDATA()
Result=readDATA()
Result=readDATA()
next
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "READ DATA():"+Str$(results#(test)/frames)
print result
print GetDataPointer()
test=test+1
;--------------------------------------------------------------
;----FLOAT READING---------------------------------------------
;--------------------------------------------------------------
ts=Timer()
For i = 0 To MaxTests
restore FloatValues
for dlp=1 to Dataloop/10
Result#=readDATA#()
Result#=readDATA#()
Result#=readDATA#()
Result#=readDATA#()
Result#=readDATA#()
Result#=readDATA#()
Result#=readDATA#()
Result#=readDATA#()
Result#=readDATA#()
Result#=readDATA#()
next
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "READ DATA#():"+Str$(results#(test)/frames)
print result#
print GetDataPointer()
test=test+1
;--------------------------------------------------------------
;---STRING READING---------------------------------------------
;--------------------------------------------------------------
ts=Timer()
For i = 0 To Maxtests
restore StringValues
for dlp=1 to Dataloop/10
Result$=readDATA$()
Result$=readDATA$()
Result$=readDATA$()
Result$=readDATA$()
Result$=readDATA$()
Result$=readDATA$()
Result$=readDATA$()
Result$=readDATA$()
Result$=readDATA$()
Result$=readDATA$()
next
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "READ DATA$():"+Str$(results#(test)/frames)
print result$
print GetDataPointer()
test=test+1
Sync
Until Frames>200
Print "Test Complete"
testEnd=Timer()-TestSTart
Print "Seconds:"+Str$((Timer()-TestStart)/1000.0)
Sync
WaitKey
Waitnokey
end
[/pbcode]
PlayBASIC V1.65 Beta 6 - Trig Command Block Bench
After the DATA command sets the focus has shifting to cleaning house in the core math operations. There's some stuff in those that just shouldn't still there which fits better in other existing libraries. Like these bunch of trig commands that lived in the core blocks that have been moved to the new trig block. Now I wasn't expecting that to alter the performance much, but it does..
Bellow in the current trig block bench.. the test is running on the same system using revision 4 of PB1.64P and today's build of PB1.65.. It's a bit of surprise that 1.65 is this much faster.. But I'll take it..
[pbcode]
cls 0
print "TRIG Function Bench Mark Waiting"
sync
For lp=1 to 1;;
Sync
wait 1000
next
Dim Results#(100)
TestStart=Timer()
MaxTests=25000
Repeat
Cls 0
frames=frames+1
Test=0
Print "Displaying Average Times for "+str$(Maxtests)+" Tests"
Print "Current Frame:"+Str$(frames)
print ""
temp=0
print "": print ""
print "-- [ COS FUNCTIONS ]-------------------------------"
ts=Timer()
For i = 0 To MaxTests
result#=cos(Angle)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " COS(ANGLE):"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=cos(Angle)*RAdius
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " COS(ANGLE)*RAdius:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=cos(Angle#)*RAdius#
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " COS(ANGLE#)*RAdius#:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=cosRadius(Angle,RAdius)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " COSRADIUS(ANGLe,RADIUS):"+Str$(results#(test)/frames)
test=test+1
print "": print ""
print "-- [ SIN FUNCTIONS ]-------------------------------"
ts=Timer()
For i = 0 To MaxTests
result#=sin(Angle)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " SIN(ANGLE):"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=sin(Angle)*RAdius
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " SIN(ANGLE)*RAdius:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=sin(Angle)*RAdius#
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " SIN(ANGLE#)*RAdius#:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=sinradius(Angle,radius#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " SINRADIUS(ANGLE#,Radius#):"+Str$(results#(test)/frames)
test=test+1
print "": print ""
print "-- [ CONVERSION FUNCTIONS ]-------------------------------"
ts=Timer()
For i = 0 To MaxTests
result#=DegreeToRAD(i)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " DegreeToRad:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=RadToDegree(i0)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " RadToDegree:"+Str$(results#(test)/frames)
test=test+1
print "": print ""
print "-- [ ANGLE FUNCTIONS ]-------------------------------"
ts=Timer()
For i = 0 To MaxTests
result#=WrapAngle(i,90)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " WrapAngle:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=CurveAngle(i,90,10)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " CurveAngle:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=GetAngle2D(100,100,i,90)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " GetAngle2D:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=AngleDifference(i,90)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "Angle Difference:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=RotateToPoint(i,i,90,200,200,1)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " RotateToPoint:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=TurnDirection(i,90,1)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " TurnDirection:"+Str$(results#(test)/frames)
test=test+1
Sync
Until Frames>200
print ""
print "---------------------------------------------------------"
Print "Test Complete"
testEnd=Timer()-TestSTart
Print "Seconds:"+Str$((Timer()-TestStart)/1000.0)
Sync
WaitKey
Waitnokey
[/pbcode]
PlayBASIC V1.65 Beta 7 - Raw Memory (Peek/Poke) Command Block Bench
Here's the results of another block transformation of the Raw memory commands. In other builds these were combined into a single block but not in the legacy 164 runtimes, but after a bit of messing around they're converted to the new format. Found a few issues with some of the more odd commands to do with signed bytes, and of course a made few tweaks to the inners loops. The compare memory function is about twice a quick now for example.
The performance of the raw memory bench mark is much better in V1.65 than V1.64, running about 30 seconds faster. Tests like copymemory are moving 30 megabyte of memory in the combined test. So there's a lot of memory access overhead in such demos. On systems with large CPU data caches that's not really an issue.
[pbcode]
cls 0
print "RAW MEMORY ACCESS Bench Mark Waiting"
sync
For lp=1 to 2;
Sync
wait 1000
next
Dim Results#(100)
TestStart=Timer()
MaxTests =25000
SrcBank =NewBank(MaxTests*4)
SrcPtr =GetBankPtr(SrcBank)
DestBank =NewBank(MaxTests*4)
DestPtr =GetBankPtr(DestBank)
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
Repeat
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
Cls 0
frames=frames+1
Test=0
Print "Displaying Average Times for "+str$(Maxtests)+" Tests"
Print "Current Frame:"+Str$(frames)
print ""
temp=0
print "": print ""
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
print "-- [ PEEK FUNCTIONS ]-------------------------------"
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
ts=Timer()
For i = 0 To MaxTests
a=SrcPtr+i
result=PeekByte(a)
result=PeekByte(a)
result=PeekByte(a)
result=PeekByte(a)
result=PeekByte(a)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " PeekByte():"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
a=SrcPtr+i
result=PeekWord(a)
result=PeekWord(a)
result=PeekWord(a)
result=PeekWord(a)
result=PeekWord(a)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " PeekWord():"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
a=SrcPtr+i
result=PeekInt(a)
result=PeekInt(a)
result=PeekInt(a)
result=PeekInt(a)
result=PeekInt(a)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " PeekInt():"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
a=SrcPtr+i
result#=PeekFloat(a)
result#=PeekFloat(a)
result#=PeekFloat(a)
result#=PeekFloat(a)
result#=PeekFloat(a)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " PeekFlt#():"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
a=SrcPtr+i
result$=PeekString( a,8)
result$=PeekString( a,8)
result$=PeekString( a,8)
result$=PeekString( a,8)
result$=PeekString( a,8)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " PeekString$():"+Str$(results#(test)/frames)
test=test+1
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
print "": print ""
print "-- [ POKE FUNCTIONS ]-------------------------------"
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
ts=Timer()
For i = 0 To MaxTests
a=SrcPtr+i
PokeByte a,i
PokeByte a,i
PokeByte a,i
PokeByte a,i
PokeByte a,i
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " PokeByte():"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
a=SrcPtr+i
PokeWord a,i
PokeWord a,i
PokeWord a,i
PokeWord a,i
PokeWord a,i
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " PokeWord():"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
a=SrcPtr+i
PokeInt a,i
PokeInt a,i
PokeInt a,i
PokeInt a,i
PokeInt a,i
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " PokeInt():"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
a=SrcPtr+i
Result#=i
PokeFloat a,Result#
PokeFloat a,Result#
PokeFloat a,Result#
PokeFloat a,Result#
PokeFloat a,Result#
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " PokeFlt#():"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
a=SrcPtr+i
PokeString a,"COOLDUDE",8
PokeString a,"COOLDUDE",8
PokeString a,"COOLDUDE",8
PokeString a,"COOLDUDE",8
PokeString a,"COOLDUDE",8
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " PokeString#():"+Str$(results#(test)/frames)
test=test+1
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
print "": print ""
print "-- [ MEMORY FUNCTIONS ]-------------------------------"
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
BytesToCopy=256
ts=Timer()
For i = 0 To MaxTests
CopyMemory SrcPtr,DestPtr,BytesToCopy
CopyMemory SrcPtr,DestPtr,BytesToCopy
CopyMemory SrcPtr,DestPtr,BytesToCopy
CopyMemory SrcPtr,DestPtr,BytesToCopy
CopyMemory SrcPtr,DestPtr,BytesToCopy
Next i
t=Timer()-ts
CopiedBytes=i*(BytesToCopy*5)
Results#(test)=results#(test)+t
Print " CopyMemory:"+Str$(results#(test)/frames)+" Copied:"+Str$(CopiedBytes/(1024*1024))+" Meg"
test=test+1
BytesToCopy=256
ts=Timer()
For i = 0 To MaxTests
FillMemory SrcPtr,BytesToCopy,255,1
FillMemory SrcPtr,BytesToCopy,255,1
FillMemory SrcPtr,BytesToCopy,255,1
FillMemory SrcPtr,BytesToCopy,255,1
FillMemory SrcPtr,BytesToCopy,255,1
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " FillMemory:"+Str$(results#(test)/frames)
test=test+1
BytesToCopy=256
ts=Timer()
For i = 0 To MaxTests
Result=CompareMemory(SrcPtr,SrcPtr,BytesToCopy)
Result=CompareMemory(SrcPtr,SrcPtr,BytesToCopy)
Result=CompareMemory(SrcPtr,SrcPtr,BytesToCopy)
Result=CompareMemory(SrcPtr,SrcPtr,BytesToCopy)
Result=CompareMemory(SrcPtr,SrcPtr,BytesToCopy)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " CompareMemory:"+Str$(results#(test)/frames) + " Result="+str$( result)
test=test+1
; Fill the memory with a run of bytes
FillMemory SrcPtr,BytesToCopy,99,1
ThisByte=Peekbyte(SrcPtr)
ts=Timer()
For i = 0 To MaxTests
Result=FindMemoryRunLength( SrcPtr,1,BytesToCopy,1,ThisBYTE)
Result=FindMemoryRunLength( SrcPtr,1,BytesToCopy,1,ThisBYTE)
Result=FindMemoryRunLength( SrcPtr,1,BytesToCopy,1,ThisBYTE)
Result=FindMemoryRunLength( SrcPtr,1,BytesToCopy,1,ThisBYTE)
Result=FindMemoryRunLength( SrcPtr,1,BytesToCopy,1,ThisBYTE)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " FindRunLength:"+Str$(results#(test)/frames) + " Result="+str$( result)
test=test+1
Sync
Until Frames>200
print ""
print "---------------------------------------------------------"
Print "Test Complete"
testEnd=Timer()-TestSTart
Print "Seconds:"+Str$((Timer()-TestStart)/1000.0)
Sync
WaitKey
Waitnokey
[/pbcode]
PlayBASIC V1.65 Beta 8 - Remapping Core Maths Function Bench
Another day and there's another slab of code cross off the translation to do list. This section focuses on core math functions. Pretty tedious stuff, from casting, to randoms, range and clipping etc etc. Had a few gremlins yesterday where all kinds of strange things would occur, but all in all it's coming together pretty well. It's nice being able to lift similar routines from legacy code.
How fast is it.. well, of course the functions bench quicker than PB1.64P4.. You knew that already.. :) - One doesn't in this test here, which was the INT() command, but i think that's just from instruction alignment. Although it's only 2milliseconds slower across 125000 calls, which isn't much.
Here's the standard test and some snaps of it running on the legacy test system. Today's V1.65 build runs thos this 35 seconds faster than PB1.64P4... So yeah.. worth it :)
[pbcode]
cls 0
print "CORE MATH Function Bench Mark Waiting"
sync
For lp=1 to 1;;
Sync
wait 1000
next
Dim Results#(100)
TestStart=Timer()
MaxTests=25000
Repeat
Cls 0
frames=frames+1
Test=0
Print "Displaying Average Times for "+str$(Maxtests)+" Tests"
Print "Current Frame:"+Str$(frames)
print ""
temp=0
Angle#=45
print "": print ""
print "-- [ CONVERSION FUNCTIONS ]-------------------------------"
ts=Timer()
For i = 0 To MaxTests
result=int(Angle#)
result=int(Angle#)
result=int(Angle#)
result=int(Angle#)
result=int(Angle#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " INT(Float#):"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=float(i)
result#=float(i)
result#=float(i)
result#=float(i)
result#=float(i)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=Float(i):"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=ceil(Angle#)
result#=ceil(Angle#)
result#=ceil(Angle#)
result#=ceil(Angle#)
result#=ceil(Angle#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=Ceil(Angle#):"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=floor(Angle#)
result#=floor(Angle#)
result#=floor(Angle#)
result#=floor(Angle#)
result#=floor(Angle#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=Floor(Angle#):"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=abs(Angle#)
result#=abs(Angle#)
result#=abs(Angle#)
result#=abs(Angle#)
result#=abs(Angle#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=Abs(Angle#):"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=Neg(Angle#)
result#=Neg(Angle#)
result#=Neg(Angle#)
result#=Neg(Angle#)
result#=Neg(Angle#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=Neg(Angle#):"+Str$(results#(test)/frames)
test=test+1
Value1#=-100
Value2#=0
Value3#=100
ts=Timer()
For i = 0 To MaxTests
result#=sgn(Value1#)
result#=sgn(Value2#)
result#=sgn(Value3#)
result#=sgn(Value1#)
result#=sgn(Value3#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=SIGN(Angle#):"+Str$(results#(test)/frames)
test=test+1
print "": print ""
print "-- [ RANDOM FUNCTIONS ]-------------------------------"
Randomize 1000
ts=Timer()
For i = 0 To MaxTests
result#=rnd(100)
result#=rnd(100)
result#=rnd(100)
result#=rnd(100)
result#=rnd(100)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=RND(100):"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=rnd#(100)
result#=rnd#(100)
result#=rnd#(100)
result#=rnd#(100)
result#=rnd#(100)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=RND#(100):"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=rndRange(100,200)
result#=rndRange(100,200)
result#=rndRange(100,200)
result#=rndRange(100,200)
result#=rndRange(100,200)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=RndRange(100,200):"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=rndRange#(100,200)
result#=rndRange#(100,200)
result#=rndRange#(100,200)
result#=rndRange#(100,200)
result#=rndRange#(100,200)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=RndRange#(100,200):"+Str$(results#(test)/frames)
test=test+1
print "": print ""
print "-- [ MATH FUNCTIONS ]-------------------------------"
ts=Timer()
For i = 0 To MaxTests
result#=Sqrt(Angle#)
result#=Sqrt(Angle#)
result#=Sqrt(Angle#)
result#=Sqrt(Angle#)
result#=Sqrt(Angle#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=Sqrt(Angle):"+Str$(results#(test)/frames)
test=test+1
a#=100
Log_OF_A#=log(a#)
ts=Timer()
For i = 0 To MaxTests
result#=exp(Log_OF_A#)
result#=exp(Log_OF_A#)
result#=exp(Log_OF_A#)
result#=exp(Log_OF_A#)
result#=exp(Log_OF_A#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=Exp(A#):"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=log(A#)
result#=log(A#)
result#=log(A#)
result#=log(A#)
result#=log(A#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=log(A#):"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=log10(A#)
result#=log10(A#)
result#=log10(A#)
result#=log10(A#)
result#=log10(A#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=log10(A#):"+Str$(results#(test)/frames)
test=test+1
print "": print ""
print "-- [ RANGE FUNCTIONS ]-------------------------------"
ts=Timer()
For i = 0 To MaxTests
result=Range(A#,50,250)
result=Range(A#,50,250)
result=Range(A#,50,250)
result=Range(A#,50,250)
result=Range(A#,50,250)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=Range(A#):"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result=ClipRange(i,50,250)
result=ClipRange(i,50,250)
result=ClipRange(i,50,250)
result=ClipRange(i,50,250)
result=ClipRange(i,50,250)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=ClipRange(A#):"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result#=ClipRange#(a#,50,250)
result#=ClipRange#(a#,50,250)
result#=ClipRange#(a#,50,250)
result#=ClipRange#(a#,50,250)
result#=ClipRange#(a#,50,250)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " Result#=ClipRange#(A#):"+Str$(results#(test)/frames)
test=test+1
Sync
Until Frames>200
print ""
print "---------------------------------------------------------"
Print "Test Complete"
testEnd=Timer()-TestSTart
Print "Seconds:"+Str$((Timer()-TestStart)/1000.0)
Sync
WaitKey
Waitnokey
[/pbcode]
PlayBASIC V1.65 Beta 9 - Loop Processing
Really cleaning house with the runtime, which means souring over the instruction set and execution code sources (since there's 3 builds to choose from), for the best general solution. During this session i've dropped in a few more compile time optimizations for the trig functions, just wanted to see how viable my next ideas will be within the existing frame work. Need not have worried as it went off without a hitch.
Last nights build runs the 'classic' bench almost dead on 2 seconds now. Which is about 250 milliseconds faster than PBV1.64P4 for example. I seem to recall that VM1 (the first execution engine) from PlayBASIC V1.00 editions took a bout 5 or 6 seconds to execute the same test on the same hardware. So we've come a long way, but I know it's been ____slow____ going. Don't worry... I also find it frustrating also...
Tonights focus is on the looping opcodes mainly. Lean and mean is the order of the evening. They have to be fast at runtime and nice and easy to decode from the byte code for translation. It's looking like there's little doubt now we've going to be replacing majority of the core opcodes though (with some cut'paste :) ). Which will either this occur during upgrade pass or the next.
Pressing forward we've going to need community members to step up and test the work in progress versions as they're released.
PlayBASIC V1.65 Beta 10 - Decisions / Comparison bench marking
Been picking through the core instruction set with fine tooth comb, a little restructure here and little restore there and found a few that no longer used opcodes. Which of course have any place in PB and have such been erased them from existence. Sp far I've only need to make minor compiler changes to make runtime changes possible. Which is good and bad, good that we can trap some legacy issues but bad that we're undoubtable creating some new issues in the process. But the up side is faster and portable.
Ok so lets's get to the shots bellow, which are taken of the IF/THEN - IF/ENDIF – IF/ElSE/ENDIF – IF ELSE ELSEIF ENDIF styled bench mark. These types of statements resolve down to a set of branch not equal styles opcodes in the runtime. I've been able to use one of the newer optimizations in them which as almost doubling the performance of test, which executes in 14 seconds in 1.64P4 and about 8 seconds in yesterdays 1.65 build.
I'm confident we can slice some more time off the results, as the test is currently running in hybrid runtime. So the new opcode execution is sliced into the legacy runtime. The cost of changing from one to another is rather high and I haven't moved everything across. Just doing block by block for the time being.
PlayBASIC V1.65 Beta 11 - Core Maths Operators – Standard Bench Mark
The progress this week has been pretty consistent; we're getting through a lot of seemingly small but important tasks (compiler and runtime). This week we're running the replacement runtime alone side the existing runtime, which is a lot like the early PBFX builds. But there's couple of key differences, such as the shiny new instruction set and externalized command sets. Meaning we don't have to convert everything all at once to get something working. Rather we migrate in blocks, which is much easier.
Today we've got enough of the core runtime working to execute the classic standard test. For those that don't know, this is just a chunk or pretty bogus code that we've been testing runtime performance with for years now. They go back as far as 2004.. So a long time. Which is nice and all, but how does V1.65 perform ?? Well, this test runs almost twice as quick as V1.64P4 on the same hardware.
Results:
1.64 - 2.297 (revision P4)
1.65 - 1.286 (beta 11)
So we've pulled a full second out of the execution speed for this example. I'm not too sure we can get that much faster, would be nice to break the 1 second barrier though.
In others tests, we're getting more and more gains. They seem to be around 2 and bit times quicker. Like the Data statement bench runs in 14 seconds now compare to the original test of 49 seconds . It's important to understand that not everything will be that much faster though.
Anyway, here's the standard test code again with some boring runtime test pictures.
[pbcode]
; PROJECT : Project1
; AUTHOR : uwdesign
; CREATED : 4/26/2004
; EDITED : 4/29/2016
cls 0
print "Waiting"
sync
For lp=0 to 5
wait 1000
next
Dim TestArrayInt(1000)
Dim TestArrayFloat#(1000)
Dim Results#(100)
TestStart=Timer()
MaxTests=10000
Repeat
Cls 0
frames=frames+1
Test=0
Print "Displaying Average Times for "
;+str$(Maxtests)+" Tests"
Print "Current Frame:"+Str$(frames)
temp=0
ts=Timer()
For i = 0 To MaxTests
temp=temp+1
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: Addition:"+Str$(results#(test)/frames)
test=test+1
; print temp
ts=Timer()
For i = 0 To MaxTests
temp=(temp+1)*lp/(lp+1)-lp
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: Add + Sub + Mult + Div:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To Maxtests
If ThisVariable=0
temp=temp+1
EndIf
If ThisVariable=1
Nothing=0
EndIf
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: If/Then TRUE and False:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
Basex#=100
Basey#=100
Radius#=100
For i = 0 To MaxTests
angle=angle+1
X#=BaseX#+(Cos(angle#)*Radius#)
Y#=BaseY#+(Sin(angle#)*Radius#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "Basic Trig Functions:"+Str$(results#(test)/frames)
test=test+1
Sync
Until Frames>200
Print "Test Complete"
testEnd=Timer()-TestSTart
Print "Seconds:"+Str$((Timer()-TestStart)/1000.0)
Sync
WaitKey
Waitnokey
[/pbcode]
PlayBASIC V1.65 Beta 13 - Compiler + Runtime + Instruction Set
It's only been a month and we're got to point with the update that the easy superficial things are now in short supply, which means turning some attention to how some of the complex parts of the compiler/runtimes work.
To the end user we could sum it up like this, basically all the core simple operations have been updated and running in the new VM, which covers everything to do with variables say, But if you read from an array/call a function then it drops back to the legacy side. So code that that's interlaces variable and array operations performs very poorly for the time being. To counter this we need to move those operations to the new VM side.
Now what I could do it clean up the instructions a bit and get some cheap gains, but a better solution would be to implement the best solution that fits and performs the best. Luckly I've already worked this out over the previous rebuilds, which still use high level operations but are more split up. For example in the legacy VM's when we computes the element from an array, this is generalized. Which is nice and convient, but add weight to every array access.
Looking beyond that, I think some of the new feature like array caching can be further enhanced with some changes to the instruction set/compiler. Those features had to fit in the legacy design so they're implemented as such, but with the next instruction set should be able to stream line it better.. While will get rid of some of the ambiguous nature of those every common opcodes.
Anyway, back to it..
PlayBASIC V1.65 Beta 15/16 - Array Functions
Been working silently away on mostly compiler & runtime things, mixed in with some idea testing. Rappidly developing a nice list of very handy compiler optimizations that can applied to pretty much any high level and not just BASIC, but I suspect (or would hope) they already exist.. but ya never know.
This past few sessions have been spent on the Array command set. In the old editions of PB there was separation of key data tables. While that was nice and convenient in the legacy editions, it was wasn't so during the building of PB2DLL. Which meant adding an entirely new set of functions that worked on the DLL side 's unified data table. Which means there's number of duplications in the old runtime, with legacy versions that newer versions, so that has to go.
So long story short it means converting the compiler & runtimes to use a unified data heap first, then building a single version of the library that can be used from both sides. Which is where I'm at today.. I've been taking it slow though as there's some good ideas in both version of the libraries that I want to keep. The newer version does a better job with memory management in some places, but is lazy in others :) , which tends help in programs where the programmer doesn't really appreciate what DIM does, or CopyArray does or something.
Anyway.. back to it.
PlayBASIC V1.65 Beta 19 - Select /Case Blocks
Well... it's been one of those days. Where you end up starring at the screen for the best part of a day looking what turns out to be a rather obvious issue with the select case runtime evaluation opcodes in the replacement runtime. Functionally it's the same as before (constants / expressed can be mixed), with the exception the new opcodes only support single data types. Which means the parser expects the same type of case values/strings as the select variable.
In older editions of PlayBASIC numeric data types could be either Integer/Float and would be cast accordingly at runtime. Which fit nicely in how the older compiler/runtimes worked, but was something I wasn't too keen on, so that's gone.
Onto the benchmark... Bellow we have todays WIP bench marks showing integer and Float Select / Case blocks running against IF/ElseIF/EndIF blocks. The test spreads the calls evenly to get a better idea of the real world performance. Ideally the closer to the top of tree a match is found the better the loop would perform. So placing your most frequently used matches first can and will bias performance. But hopefully that should be common knowledge by now..
The results speaks for themselves, todays build is about 4 times quicker than V1.64P4 on the same legacy hardware.
PlayBASIC V1.65 Beta 24 - Bound DLL calls
Still picking my way through the VM transition, mostly been working on the dll calling. The process has been changed somewhat to avoid some extra memory fetching for every call. Which on the surface seemed easy enough, but it meant rolling a bunch of new support code to make it possible. Which is par for the course really in optimization terms. :(
Anyway, the results are what matter and we've doubled the test code performance. Which is calling 10K *5 *6 function calls per frame. On todays build we're getting about 300K function calls at 60fps and about half that V1.64P4 build. Which is rather pleasing..
[pbcode]
maxTests=10000
TestBank=VM_Alloc(MaxTests+256)
; --------------------------------------------------------------------------
do
; --------------------------------------------------------------------------
cls
frames++
// ----------------------------------------------------------------
// -[INTEGER FUNCTION CALLING]------------------------------------------
// ----------------------------------------------------------------
tt=timer()
For lp =0 to MaxTests
Status = VM_BankSize(TestBank)
Status = VM_BankSize(TestBank)
Status = VM_BankSize(TestBank)
Status = VM_BankSize(TestBank)
Status = VM_BankSize(TestBank)
next
tt1#+=(timer()-tt)
print " BANK SIZE: "+str$(tt1#/frames)
print "result:"+Str$(Status)
// ----------------------------------------------------------------
// -[SELECT CASE INTEGER]------------------------------------------
// ----------------------------------------------------------------
tt=timer()
For lp =0 to MaxTests
Colour=ThisRGB(lp,lp,lp)
Colour=ThisRGB(lp,lp,lp)
Colour=ThisRGB(lp,lp,lp)
Colour=ThisRGB(lp,lp,lp)
Colour=ThisRGB(lp,lp,lp)
next
tt2#+=(timer()-tt)
print " ThisRGB: "+str$(tt2#/frames)
/*
// ----------------------------------------------------------------
// -[SELECT CASE INTEGER]------------------------------------------
// ----------------------------------------------------------------
tt=timer()
For lp =0 to MaxTests
Colour=RGB(lp,lp,lp)
Colour=RGB(lp,lp,lp)
Colour=RGB(lp,lp,lp)
Colour=RGB(lp,lp,lp)
Colour=RGB(lp,lp,lp)
next
tt2b#+=(timer()-tt)
print " RGB: "+str$(tt2b#/frames)
*/
// ----------------------------------------------------------------
// -[Poke INT]------------------------------------------
// ----------------------------------------------------------------
tt=timer()
For lp =0 to MaxTests
VM_PokeInt(TestBank,lp,ThisValue)
VM_PokeInt(TestBank,lp,ThisValue)
VM_PokeInt(TestBank,lp,ThisValue)
VM_PokeInt(TestBank,lp,ThisValue)
VM_PokeInt(TestBank,lp,ThisValue)
next
tt3#+=(timer()-tt)
print " Poke Int: "+str$(tt3#/frames)
// ----------------------------------------------------------------
// -[Peek INT]------------------------------------------
// ----------------------------------------------------------------
tt=timer()
For lp =0 to MaxTests
ThisValue=VM_PeekInt(TestBank,lp)
ThisValue=VM_PeekInt(TestBank,lp)
ThisValue=VM_PeekInt(TestBank,lp)
ThisValue=VM_PeekInt(TestBank,lp)
ThisValue=VM_PeekInt(TestBank,lp)
next
tt4#+=(timer()-tt)
print " Peek Int: "+str$(tt4#/frames)
// ----------------------------------------------------------------
// -[Poke FLOAT]------------------------------------------
// ----------------------------------------------------------------
tt=timer()
For lp =0 to MaxTests
VM_PokeFLt(TestBank,lp,ThisValue#)
VM_PokeFLt(TestBank,lp,ThisValue#)
VM_PokeFLt(TestBank,lp,ThisValue#)
VM_PokeFLt(TestBank,lp,ThisValue#)
VM_PokeFLt(TestBank,lp,ThisValue#)
next
tt5#+=(timer()-tt)
print " Poke Flt: "+str$(tt5#/frames)
// ----------------------------------------------------------------
// -[Peek INT]------------------------------------------
// ----------------------------------------------------------------
tt=timer()
For lp =0 to MaxTests
ThisValue#=VM_PeekFlt(TestBank,lp)
ThisValue#=VM_PeekFlt(TestBank,lp)
ThisValue#=VM_PeekFlt(TestBank,lp)
ThisValue#=VM_PeekFlt(TestBank,lp)
ThisValue#=VM_PeekFlt(TestBank,lp)
next
tt6#+=(timer()-tt)
print " Peek Flt: "+str$(tt6#/frames)
print ""
print "FPS:"+STR$(FPS())
Sync
TestEnd++
loop TestEnd>200
print "Done"
sync
waitkey
waitnokey
end
[/pbcode]
PlayBASIC V1.65 Beta 26 - Long Lost Math Function & Operators
While picking through found a few legacy math functions that hadn't been translated, that are outside of the 'core math' group since they're not actually functions. Which is stuff like MOD/MidPoint come to mind, but there's others such as the SWAP, MidVal with the lowest or higher variants.
The MidPoint function is one of those legacy functions that i'm not too keen on. Basically it's the average of two values, where it really should be able to compute a pair, but a collections of them. ie Average(A,B,C,D) would be the same as (A+B+C+D) / 4 That sorta thing
The results of the updates have been good, generally twice as quick. In some cases a manual (inline) of the operation on the new VM is faster than the V1.64P4. Some extra speed still waiting to be unlocked as the optimizer doesn't understand all of the new instruction set as yet. Which will win back some extra speed.. Not a lot, but some..
PlayBASIC V1.65 VM clocks a 15 MIPS (Million Instructions Per Second )
While testing the SWAP commands, I did a bit of performance calculation of the current runtime, but not in milliseconds though, rather the number of byte code instructions the runtime can chew through per second, which comes in around the 15.6 million instructions per second, on this 11 year old system. Which for the test code is about 2.2 times quicker than V1.64P
Now this got me thinking, did you know the 68000 processor found in classic Amiga system, like the A500, have about a 1Mip through put in hardware. So the current PlayBASIC runtime is about 14->15 times quicker than that machine code the actual hardware.
::) ::) ::) :P
PlayBASIC V1.65 - The Stack
So what's been going on ? - Well... a fair bit, but again it's mostly all the boring stuff that's hidden deep down inside the VM. For example the current focus is on how the stack instruction sets are set out and by extension how functions themselves work.
One of the older ideas for functions was that there was way to help the parameter passing out when calling it. So when passing lots of parameters into a function it's not doing as much work to make that happen. Although it's always a pretty ugly operation anyway, since we're hitting memory regardless.
Every time you drive the cost of any core operation down, we win back runtime performance, moreover it should be a bit easier during translation too. It's just a pain having to revisit old stuff..
PlayBASIC V1.65 - User Function Call Bench marks
So here's today's little bench, this time we're calling User defined Functions and PSUBS with collection simple passing combo's.. Results are pretty good, as compared to the PB1.64P4 it's about 5.5 times faster. There's some bais though as we're not strickly comparing apples with apples here (meaning they work in different ways now), but it's the end result that matters.
Test Code:
[pbcode]
MaxTests=10000
Dim Tests#(100)
STARTTIME=Timer()
; ---------------------------------------------------------------------
do
; ---------------------------------------------------------------------
cls
frames++
a=45
b#=123.456
c$="Hello World"
a$=c$
b$=c$
Test=0
CallsPerTest=Maxtests*5
; ----------------------------------------------------------------------------
; ----------------------------------------------------------------------------
; ----------------------------------------------------------------------------
; ----------------------------------------------------------------------------
; ----------------------------------------------------------------------------
print make$("-",64)
print "--[ FunctionCalls ]----------------------------------"
print make$("-",64)
t=timer()
for lp=0 to maxtests
fInput0Params()
fInput0Params()
fInput0Params()
fInput0Params()
fInput0Params()
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " fInput0Params():"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
fInput1Params1(A)
fInput1Params1(A)
fInput1Params1(A)
fInput1Params1(A)
fInput1Params1(A)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " fInput1Params1(A ):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
fInput1Params2(B#)
fInput1Params2(B#)
fInput1Params2(B#)
fInput1Params2(B#)
fInput1Params2(B#)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " fInput1Params2(B#):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
fInput1Params3(C$)
fInput1Params3(C$)
fInput1Params3(C$)
fInput1Params3(C$)
fInput1Params3(C$)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " fInput1Params3(C$):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
fInput2Params1(A,B)
fInput2Params1(A,B)
fInput2Params1(A,B)
fInput2Params1(A,B)
fInput2Params1(A,B)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " fInput2Params1(A ,B ):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
fInput2Params2(A#,B#)
fInput2Params2(A#,B#)
fInput2Params2(A#,B#)
fInput2Params2(A#,B#)
fInput2Params2(A#,B#)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " fInput2Params2(A#,B#):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
fInput2Params3(A$,B$)
fInput2Params3(A$,B$)
fInput2Params3(A$,B$)
fInput2Params3(A$,B$)
fInput2Params3(A$,B$)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " fInput2Params3(A$,B$):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
fInput3Params1(A,B,C)
fInput3Params1(A,B,C)
fInput3Params1(A,B,C)
fInput3Params1(A,B,C)
fInput3Params1(A,B,C)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " fInput3Params1(A ,B ,C ):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
fInput3Params2(A#,B#,C#)
fInput3Params2(A#,B#,C#)
fInput3Params2(A#,B#,C#)
fInput3Params2(A#,B#,C#)
fInput3Params2(A#,B#,C#)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " fInput3Params2(A#,B#,C#):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
fInput3Params3(A$,B$,C$)
fInput3Params3(A$,B$,C$)
fInput3Params3(A$,B$,C$)
fInput3Params3(A$,B$,C$)
fInput3Params3(A$,B$,C$)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " fInput3Params3(A$,B$,C$):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
fInput3MixedParams(A,B#,c$)
fInput3MixedParams(A,B#,c$)
fInput3MixedParams(A,B#,c$)
fInput3MixedParams(A,B#,c$)
fInput3MixedParams(A,B#,c$)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " fInput3MixedParams(A,B#,c$):"+str$(Tests#(Test)/frames)
Test++
print ""
print ""
; ----------------------------------------------------------------------------
; ----------------------------------------------------------------------------
; ----------------------------------------------------------------------------
; ----------------------------------------------------------------------------
; ----------------------------------------------------------------------------
print make$("-",64)
print "--[ PSubCalls ]-------------------------"
print make$("-",64)
t=timer()
for lp=0 to maxtests
sInput0Params()
sInput0Params()
sInput0Params()
sInput0Params()
sInput0Params()
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " sInput0Params():"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
sInput1Params1(A)
sInput1Params1(A)
sInput1Params1(A)
sInput1Params1(A)
sInput1Params1(A)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " sInput1Params1(A ):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
sInput1Params2(B#)
sInput1Params2(B#)
sInput1Params2(B#)
sInput1Params2(B#)
sInput1Params2(B#)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " sInput1Params2(B#):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
sInput1Params3(C$)
sInput1Params3(C$)
sInput1Params3(C$)
sInput1Params3(C$)
sInput1Params3(C$)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " sInput1Params3(C$):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
sInput2Params1(A,B)
sInput2Params1(A,B)
sInput2Params1(A,B)
sInput2Params1(A,B)
sInput2Params1(A,B)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " sInput2Params1(A ,B ):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
sInput2Params2(A#,B#)
sInput2Params2(A#,B#)
sInput2Params2(A#,B#)
sInput2Params2(A#,B#)
sInput2Params2(A#,B#)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " sInput2Params2(A#,B#):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
sInput2Params3(A$,B$)
sInput2Params3(A$,B$)
sInput2Params3(A$,B$)
sInput2Params3(A$,B$)
sInput2Params3(A$,B$)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " sInput2Params3(A$,B$):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
sInput3Params1(A,B,C)
sInput3Params1(A,B,C)
sInput3Params1(A,B,C)
sInput3Params1(A,B,C)
sInput3Params1(A,B,C)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " sInput3Params1(A ,B ,C ):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
sInput3Params2(A#,B#,C#)
sInput3Params2(A#,B#,C#)
sInput3Params2(A#,B#,C#)
sInput3Params2(A#,B#,C#)
sInput3Params2(A#,B#,C#)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " sInput3Params2(A#,B#,C#):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
sInput3Params3(A$,B$,C$)
sInput3Params3(A$,B$,C$)
sInput3Params3(A$,B$,C$)
sInput3Params3(A$,B$,C$)
sInput3Params3(A$,B$,C$)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " sInput3Params3(A$,B$,C$):"+str$(Tests#(Test)/frames)
Test++
t=timer()
for lp=0 to maxtests
sInput3MixedParams(A,B#,c$)
sInput3MixedParams(A,B#,c$)
sInput3MixedParams(A,B#,c$)
sInput3MixedParams(A,B#,c$)
sInput3MixedParams(A,B#,c$)
next
Tests#(Test)=Tests#(Test)+(timer()-t )
print " sInput3MixedParams(A,B#,c$):"+str$(Tests#(Test)/frames)
Test++
print ""
print ""
print make$("-",32)
ThisFPS=fps()
print " Fps:"+STR$(ThisFPS)
CallsPerSecond=CallsPerTest * Test *ThisFPS
print "CallsPerSecond:"+STR$(CallsPerSecond/1000000.0 )+" Million"
print make$("-",32)
sync
; ---------------------------------------------------------------------
loop Frames>200
; ---------------------------------------------------------------------
print "Test Time:"+STR$(Timer()-STARTTIME)+" MIlliseconds"
sync
waitkey
waitNOkey
end
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; ---[0 PARAMETERS]------------------------------------------------------------
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
Function fInput0Params()
result=A
EndFUnction
Psub sInput0Params()
result=A
EndPsub
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; ---[1 PARAMETERS]------------------------------------------------------------
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
Function fInput1Params1(A)
result=A
EndFUnction
Psub sInput1Params1(A)
result=A
EndPsub
Function fInput1Params2(B#)
result=A#
EndFUnction
Psub sInput1Params2(B#)
result=A#
EndPsub
Function fInput1Params3(c$)
result=A#
EndFUnction
Psub sInput1Params3(c$)
result=A#
EndPsub
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; ---[2 PARAMETERS]------------------------------------------------------------
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
Function fInput2Params1(A,B)
result=A
EndFUnction
Psub sInput2Params1(A,B)
result=A
EndPsub
Function fInput2Params2(A#,B#)
result=A
EndFUnction
Psub sInput2Params2(A#,B#)
result=A
EndPsub
Function fInput2Params3(A$,B$)
result=A
EndFUnction
Psub sInput2Params3(A$,B$)
result=A
EndPsub
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; ---[3 PARAMETERS]------------------------------------------------------------
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
Function fInput3Params1(A,B,C)
result=A
EndFUnction
Psub sInput3Params1(A,B,C)
result=A
EndPsub
Function fInput3Params2(A#,B#,C#)
result=A
EndFUnction
Psub sInput3Params2(A#,B#,C#)
result=A
EndPsub
Function fInput3Params3(A$,B$,C$)
result=A
EndFUnction
Psub sInput3Params3(A$,B$,C$)
result=A
EndPsub
; -----------------------------------------------------------------------------
; ---[3 PARAMETERS]------------------------------------------------------------
; -----------------------------------------------------------------------------
Function fInput3MixedParams(A,B#,c$)
result=A
EndFUnction
Psub sInput3MixedParams(A,B#,c$)
result=A
EndPsub
[/pbcode]
PlayBASIC V1.65 - User Function Return Methods
Still working about at function calling opcodes, it seem the caller method works pretty well so we update the return from function opcodes. Which seem to work about the same really as V1.64P4, there's some gains in some tests and not in others. Which is all part of the wonderful would of optimization. I'm not too concerned about it though, as on balance it'll be quicker since the parameter passing is generally much quicker. It's be nice to keep shaving cycles out of the Vm loop, but not always practical.
One thing I've been thinking about bringing forward is some caching logic to returned temp strings from functions. This would potentially save at least one copy of the string being made. Moreover it should avoid the allocation and deallocation of that temp string. Unfortunately Allocating memory from the OS is NOT a fixed time operation. If anything it's road defragmentation, which makes allocations slower and slower and slower. So worth avoiding if possible, just painful :)
PlayBASIC V1.65 - User Function / Psub calling & returning
The FUNCTION calling /returning mech's seem to be working, so I've been working on the PSUB's today. It just means picking through the old byte code generation and parsing code and replacing stuff. The updated runtime method is both cleaner at compile and runtime so we can trim out of legacy code here and there which is nice.
Today's been slow going really, not a lot of code it's mostly tweaking/testing. Have picked up a few errors in the new byte code generation. One really odd one where it would opt'd a return value out by writing in into some other variable.. Giving some rather strange results.. It's one of those things that was hidden well enough away as to only occur in perfect combination of code, as of a lot of test code still worked. Bound to be a few more of those hidden away.
There's still a few tidbits left to do with functions / psubs like setting up a new version of the CallFunction and there's no support for ExitFunction or recursion either either. Even so, the bound dll calling method doesn't use the same approach as calling internal functions, so that needs to be tweaked with the latest method. Which will get rid of some work that needs to be performed at runtime.
PlayBASIC V1.65 - Runtime closing in on native C performance
Revisited the external function call operations again, wanted to try alternative opcode layout where the runtime can take as few steps as possible when calling a external bound functions. Even though the steps are small, small things still cost you performance, so every time we can shave cycles off of the runtimes overhead, means more VM instructions being executed per second for you.
When starting each update, that age old fantasy of closing the gap between native machine code execution and runtime execution continues to be firmly at the forefront of ones mind. We've been shaving the difference down month by month year after year, and are now inside a factor of 10 (on average). The general thinking for runtimes is there's if you can get down to 10 to 1 ratio, then that's pretty optimal. This is largely because of the amount of memory accesses runtimes require.
Having said all that... I'm rather excited to announce today that we're further broken down the execution wall and have achieved a ratio of 6 to 1 in raw function calling performance. Which is the test that calls executes external functions linked with the runtime. For some perspective that's over double the V1.64P4 performance for the same operation.
So it's been a good day.. :)
More Speed
Tweaked the caller again today in order to remove one memoy access and an addition, and we get even closer with a 4 to 1 ratio for the benchmark.. It is a rather narrow test though, calling more complex functions can't be done so easily, but a lot of general stuff we use all the time will get a nice boost...
PlayBASIC V1.65 – Call Function (Calling Functions By Name)
Have moved onto another legacy part of the runtime that needs to be updated into not only the new instruction set but the new application format. This time the opcode doesn't really need much tweaking, rather any changes are in how the data structure is set up. What I want to do is localize everything. This means that reading code/data from the current running application is going to cache better. Previous builds this is all in separate heaps, which may, or may not be being read/flushed from the cpu cache. When chunks are flushed it's effectively invisible overhead, if we build it all into one place, we can get rid of some of that. Ultimately it's up to your CPU how and when it fetch's data from he memory.
So far I've got the new structure all set up and are in the process of writing the application builder code, which is just some code that stores all the apps requirements in one chunk. Once that's done and running, we can set up CallFunction command blocks, which will got a ways to getting a bunch of legacy code working again. After that, the same type of thing will need to be done with the Types.
PlayBASIC V1.65 – FunctionIndex() FunctionExist() benching
So here we have the base function of the dynamic function calling command set are up and running again. All the code was written yesterday, but ran into a matching issue so have spent all morning debugging that, what joy ! Which means we've only got the FunctinIndex / FunctionExist functions working at this point. For those who don't read the manual, they're for querying functions in your program at compile and runtime. This is done generally with a view to calling said function by name or by index.
Stuff like functionExist can be used at compile time to determine if some code is included within the current code and then act accordingly, such optimally including/ excluding sections of code. Which is method I often use when writing bigger applications.
Anyway, the replacement benchmark shows the new data structures and opcode perform about *2 times faster than legacy V1.64P4 build. I'm just happy it works at this point. Now, I have to build a dynamic version of CallFunction.
[pbcode]
Maxtests=10000
; ------------------------------------------------------
do
; ------------------------------------------------------
cls
frames++
print "----[Function INDEX]--------------------------------------"
Name$="Test"
tt=timer()
for lp=0 to Maxtests
result=FUnctionIndex(Name$)
result=FUnctionIndex(Name$)
result=FUnctionIndex(Name$)
result=FUnctionIndex(Name$)
result=FUnctionIndex(Name$)
next
tt1#+=timer()-tt
print tt1#/frames
print result
Name$="LastFunctionInTableWithALongName"
tt=timer()
for lp=0 to Maxtests
result=FUnctionIndex(Name$)
result=FUnctionIndex(Name$)
result=FUnctionIndex(Name$)
result=FUnctionIndex(Name$)
result=FUnctionIndex(Name$)
next
tt2#+=timer()-tt
print tt2#/frames
print result
Name$="aaaaaasssssdsdsd"
tt=timer()
for lp=0 to Maxtests
result=FUnctionIndex(Name$)
result=FUnctionIndex(Name$)
result=FUnctionIndex(Name$)
result=FUnctionIndex(Name$)
result=FUnctionIndex(Name$)
next
tt3#+=timer()-tt
print tt3#/frames
print result
print ""
print ""
print "----[Function Exist]--------------------------------------"
Name$="Test"
tt=timer()
for lp=0 to Maxtests
result=FUnctionExist(Name$)
result=FUnctionExist(Name$)
result=FUnctionExist(Name$)
result=FUnctionExist(Name$)
result=FUnctionExist(Name$)
next
tt10#+=timer()-tt
print tt10#/frames
print result
Name$="LastFunctionInTableWithALongName"
tt=timer()
for lp=0 to Maxtests
result=FUnctionExist(Name$)
result=FUnctionExist(Name$)
result=FUnctionExist(Name$)
result=FUnctionExist(Name$)
result=FUnctionExist(Name$)
next
tt11#+=timer()-tt
print tt11#/frames
print result
Name$="aaaaaasssssdsdsd"
tt=timer()
for lp=0 to Maxtests
result=FUnctionExist(Name$)
result=FUnctionExist(Name$)
result=FUnctionExist(Name$)
result=FUnctionExist(Name$)
result=FUnctionExist(Name$)
next
tt12#+=timer()-tt
print tt12#/frames
print result
print ""
print ""
print "---[Stats]---------------------------------------------"
f=FPS()
TestCount=6
print F
print str$( (MaxTests*5*TestCount*f)/1000.0/1000)+" Million Searchs Per Second"
print "-------------------------------------------------------"
sync
loop
Function Test()
EndFUnction
Function LastFunctionInTableWithALongName()
EndFUnction
[/pbcode]
PlayBASIC V1.65 - Beta 37 – Dynamic CallFunction
Have replaced the CallFunction opcodes on the Vm side. The replacement allows us to getrid of some runtime calc's and uses the newer simpler function caller structure, so it's quicker than the legacy version. The param matching now works via the internal param's datatype class, where as it used to try and match the token at runtime. Which just means we can do things like pass a type handle into a function and it'll compute the pointer. This wasn't possible before as it the incoming data was just tagged as being integer, it didn't know it was Handle.
So this kind of thing is now possible
[pbcode]
Type tVector
x#,y#,Z#
EndType
Dim Table(10) as tVector
Table(5) = New tVector
Table(5).X = 1000
Table(5).Y = 2000
Table(5).z = 3000
for lp =0 to 10
CallFunction "ShowVector", Table(lp)
next
Sync
WaitKEY
Function ShowVector(me as tVector)
if int(me)
print Me.X
print Me.Y
print Me.Z
else
print "Not allocated"
endif
EndFunction
[/pbcode]
Alll that's left is set up a version of the caller that will wrapped/bound DLL calls, which about 1/2 way through currently.. So we should be able to sign off on all that later on today/tonight...
Edit: Got this set up and testing while watching the Footy. So we can tick that off the todo list for now.
PlayBASIC V1.65 - Beta 39 - Types & Runtime Structures
In keeping with the new app structure we need to move the types structures into the new container. Have tweaked the structure some what, mainly it uses a local heap for text fields. Which just means those strings aren't floating around in the main runtime.
So far have got all everything embedded in the new runtime APP structure, just have to work through the legacy opcodes and hook everything together. From memory there's only 3 or 4 opcodes anyway. There might be some runtime speed benefit but I can't imagine much, since ultimately your allocating memory, which is not a uniform speed operation.
Anyway, after those replacements the only legacy opcodes remaining are array access and some legacy stack opcodes. Some of which I'm not too sure we need anymore....
PlayBASIC V1.65 - Beta 41 - Array an List Functions
Have worked my way through the array / list functions replacing some bits and updating others. Haven't brute force tested them though, but stuff like searching should be quicker. There's few functions left over which might end up on the cutting room floor, since they require the old internal array data structures. GetArray() / SetArray() used the linear array table, which no longer exists. Could possibly emulate it, but just retrurning the handle of the structure and storing them in array does the same thing.
PlayBASIC V1.65 - Beta 43 - Type Fields
It's been a cold and miserable week at home, snowing most days which doesn't make sitting in the cold office much fun. None the less, I've been getting bits of final part of the update done replacing the type structure accesses opcodes. These are a collection of about 10 (from memory) opcodes that type accesses resolve down to in the VM. I've been sitting back look at that section of code for a few days before deciding to update it, the original code isn't much difference, it's just that types have a lot of secondary support opcodes which the compiler uses to optimize the output stream. So by changing them you break a lot of other stuff in the process. Which is not something I'm all the interested in..
But... now you should know, there's exception coming.. Which is .. If changing it makes it faster, then of course I'm going to try it... and it has, as the current (incomplete) build makes reading from a field in a typed array (1D) about 45% faster than what it was. That's when compared to a none cached type access, and without the write optimization that pre V1.65 versions have.
The compile time optimizer doesn't currently understand the new byte code instructions completely and as such can't make all those little short cuts when pulling data from a typed array/list. It's those little short cuts and can really win back a lot of runtime execution time.
I'm hoping that when everything is tweaked and running we should be able get beyond 50%->60% improvement (so it'd be doing the same work in ½ or less time it takes in V1.64P4) . I've a few tweaks for caching also in mind and I think a simple cached field should be somewhere %15 of the full field access.
PlayBASIC V1.65 - Beta 44 - Read Type Fields BenchMarks 3-> 5 times faster
Updated the compile time optimizer last night so it can understand the type access instructions. The results are as I'd hoped, showing between a *3 to *5 performance gain over V1.64P4 (without caching enabled). In raw read terms that's about 24 million reads per second on my test system, compared to about 6 million in the older version.
Bellow is the test code and some pics of the results running on the 2 different versions and the same system.
[pbcode]
Type tCool
a,b,c
EndType
TYPE tVector3
x#,y#,Z#
a,b,c
b1 as byte
b2 as byte
b3 as byte
b4 as byte
w1 as word
w2 as word
w3 as word
w4 as word
iArray(100)
sArray#(100)
fArray$(100)
EndType
Size = 100
Dim v(Size) as tVector3
For lp =0 to Size
v(lp)= new tVector3
v(lp).x = 1
v(lp).y = 1
v(lp).z = 1
next
Maxtests=500
Dim Tests#(1000)
Do
cls
frames++
Test=0
// ----------------------------------------------------------------------
// ---[ FLOAT ]----------------------------------------------------------
// ----------------------------------------------------------------------
t=timer()
For Testlp =0 to Maxtests
For lp =0 to Size
Result# =v(lp).x
Result# =v(lp).y
Result# =v(lp).z
Result# =v(lp).x
Result# =v(lp).y
Result# =v(lp).z
next
next
Test++
Tests#(Test)=Tests#(Test)+(Timer()-t)
print " Reading Float2Flt:"+str$(Tests#(Test)/frames)
t=timer()
For Testlp =0 to Maxtests
For lp =0 to Size
Result =v(lp).x
Result =v(lp).y
Result =v(lp).z
Result =v(lp).x
Result =v(lp).y
Result =v(lp).z
next
next
Test++
Tests#(Test)=Tests#(Test)+(Timer()-t)
print " Reading Float2Int:"+str$(Tests#(Test)/frames)
// ----------------------------------------------------------------------
// ---[ INTEGER ]--------------------------------------------------------
// ----------------------------------------------------------------------
t=timer()
For Testlp =0 to Maxtests
For lp =0 to Size
Result# =v(lp).a
Result# =v(lp).b
Result# =v(lp).c
Result# =v(lp).a
Result# =v(lp).b
Result# =v(lp).c
next
next
Test++
Tests#(Test)=Tests#(Test)+(Timer()-t)
print " Reading Int2Flt:"+str$(Tests#(Test)/frames)
t=timer()
For Testlp =0 to Maxtests
For lp =0 to Size
Result =v(lp).a
Result =v(lp).b
Result =v(lp).c
Result =v(lp).a
Result =v(lp).b
Result =v(lp).c
next
next
Test++
Tests#(Test)=Tests#(Test)+(Timer()-t)
print " Reading Int2Int:"+str$(Tests#(Test)/frames)
// ----------------------------------------------------------------------
// ---[ BYTE ]-----------------------------------------------------------
// ----------------------------------------------------------------------
t=timer()
For Testlp =0 to Maxtests
For lp =0 to Size
Result# =v(lp).b1
Result# =v(lp).b2
Result# =v(lp).b3
Result# =v(lp).b1
Result# =v(lp).b2
Result# =v(lp).b3
next
next
Test++
Tests#(Test)=Tests#(Test)+(Timer()-t)
print " Reading Byte2Flt:"+str$(Tests#(Test)/frames)
t=timer()
For Testlp =0 to Maxtests
For lp =0 to Size
Result =v(lp).b1
Result =v(lp).b2
Result =v(lp).b3
Result =v(lp).b1
Result =v(lp).b2
Result =v(lp).b3
next
next
Test++
Tests#(Test)=Tests#(Test)+(Timer()-t)
print " Reading Byte2Int:"+str$(Tests#(Test)/frames)
// ----------------------------------------------------------------------
// ---[ WORD ]-----------------------------------------------------------
// ----------------------------------------------------------------------
t=timer()
For Testlp =0 to Maxtests
For lp =0 to Size
Result# =v(lp).w1
Result# =v(lp).w2
Result# =v(lp).w3
Result# =v(lp).w1
Result# =v(lp).w2
Result# =v(lp).w3
next
next
Test++
Tests#(Test)=Tests#(Test)+(Timer()-t)
print " Reading Word2Flt:"+str$(Tests#(Test)/frames)
t=timer()
For Testlp =0 to Maxtests
For lp =0 to Size
Result =v(lp).w1
Result =v(lp).w2
Result =v(lp).w3
Result =v(lp).w1
Result =v(lp).w2
Result =v(lp).w3
next
next
Test++
Tests#(Test)=Tests#(Test)+(Timer()-t)
print " Reading Word2Int:"+str$(Tests#(Test)/frames)
// ----------------------------------------------------------------------
// ---[ Read Array Pointers ]-----------------------------------------------------------
// ----------------------------------------------------------------------
t=timer()
For Testlp =0 to Maxtests
For lp =0 to Size
Result =v(lp).iArray
Result =v(lp).fArray
Result =v(lp).sArray
Result =v(lp).iArray
Result =v(lp).fArray
Result =v(lp).sArray
next
next
Test++
Tests#(Test)=Tests#(Test)+(Timer()-t)
print " Reading ArrayPtr2Int:"+str$(Tests#(Test)/frames)
print ""
print "--------------------------------------------------------------"
f=fps()
Total=(TestLp*LP*6)
TotalReads = Total*(Test+1)
print " Tests Count:"+Str$(Total )
print " Total Reads:"+Str$(TotalReads )
print "Reads Per Second:"+Str$((TotalReads*f)/1000000.0 )+" million reads per second "
print " Fps:"+Str$(f)
print "--------------------------------------------------------------"
Sync
loop
[/pbcode]
PlayBASIC V1.65 – On It's way to beta testing..
Yes... the day has finally arrived when I've crossed the final big opcodes block off the runtime replacement to do list. Without the list in front of me, I'd say it's about 99% complete as of this morning. The only things missing now are little bits of stuff that need hooking up/replacing between how it used to work and how it works today. So there's still places where the compiler hasn't been updated to output the new instruction set, and as such would output some old instruction set, resulting some operation that won't work at runtime. They're generally easy fixes, but require some detective to track them down.
The performance of the runtime is pretty good, it's generally much quicker than V1.64P4 and there's still some fat on the bone that can be trimmed off. The coolest thing about that though, is that I'm yet to get really jump into the compile time optimizations to be added. Which are series of replacements that the code generation will make during output for you.
The compile time optimization list contains way too many opt's to list from memory (plus it's private part our compiler technologies), but here's one I see in peoples programs when reading characters from a string. This expression ThisChr=Asc(Mid$(String$,Pos,1)) which should be written as ThisChr= Mid (String$,Pos) in PlayBASIC. The latter is quicker as we're not returning a string, which no matter how fast you make them, will always be slower than reading a character directly from the string. This kind of thing can be done at compile time, so the output stream of opcodes can be made as clean as possible.
Anyway we should be able to start dropping a stream V1.65 Betas very soon ! - The more people that are active in testing them the quicker this process becomes.
PlayBASIC V1.65 – Write Array Strings Bench Marking
Updated the write string array opcodes last night and today and we can repeort yet another gain in performance. The change helps the VM avoid some bogus string coping when moving computed strings from expressions. It seems to work well so far gaining over 10fps in the deom on a per frame basis, but the test executes almost 10 seconds faster... in V1.65 and the V1.64.... very happy with that !
Benchmark code: running 10 year old athon 3000 (single core).. :)
[pbcode]
Max= 10000
Dim v1$(Max)
Dim v2$(Max)
Dim TempStrings$(Max)
For lp =0 to Max
TempStrings$(lp) = Make$(str$(lp),10+(lp and 64))
next
StartTime=Timer()
For Tests =0 to 400
cls
Frames++
a$=make$(Str$(Frames)+",",10)
s$=make$("-",len(PlayBASIC$))
s$+="---------------------------------------------------------"
print s$
print "---[ String Write Bench Marking "+PlayBASIC$+" ]-----------------------"
print s$
print ""
t=timer()
For lp =0 to max
Temp$=A$+ " Some Test String"
v1$(lp) = Temp$
next
tt1#=tt1#+(Timer()-T)
print " Test1 :"+Str$(tt1#/frames)
print "Test String :"+v1$(0)
print ""
t=timer()
For lp =0 to max
v2$(lp) = a$+" Some Test String"
next
tt2#=tt2#+(Timer()-T)
print " Test2 :"+Str$(tt2#/frames)
print "Test String :"+v2$(0)
print ""
// -----------------------------------------------------
// Direct Assignment From Array
// -----------------------------------------------------
t=timer()
For lp =0 to max
v1$(lp) = TempStrings$(lp)
next
tt3#=tt3#+(Timer()-T)
print " Test3 :"+Str$(tt3#/frames)
print "Test String :"+v1$(0)
print ""
// -----------------------------------------------------
// Stream Line String Function Returns
// -----------------------------------------------------
t=timer()
For lp =0 to max
Temp$=Left$(A$,10)
v1$(lp) = Temp$
next
tt4#=tt4#+(Timer()-T)
print " Test4 :"+Str$(tt4#/frames)
print "Test String :"+v1$(0)
print ""
t=timer()
For lp =0 to max
v1$(lp) = Left$(A$,10)
next
tt5#=tt5#+(Timer()-T)
print " Test5 :"+Str$(tt5#/frames)
print "Test String :"+v1$(0)
print ""
#break
print S$
print S$
print "String Count :"+Str$(Max)
print " FPS :"+STR$(Fps())
print S$
print S$
Sync
next Tests
print "DONE"
TotalTime=Timer()-StartTime
print "Time :"+str$(float(TotalTime)/Tests)+" Seconds"
Sync
waitkey
waitnokey
[/pbcode]
PlayBASIC V1.65 BETA #49 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (2nd Aug,2016)
V1.65 Beta #49 is the first public build of the V.65. This build replaces the run time execution engine, which means big updates to the compiler and optimizer.. So when lots of stuff change, more faults appear :) That's where you come in..
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Post Thread (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink]
Download
Removed, newer builds are bellow.
PlayBASIC V1.65 BETA #50 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (4th,Aug,2016)
V1.65 Beta #50 is the second public build of the V1.65. This one includes bugs for bound function calls, Restore DATA, ExitFunction and a minor console debug messages.. So more stuff runs out of the box, but not everything...
Newer build posted bellow..
PlayBASIC V1.65 BETA #51 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (6th,Aug,2016)
V1.65 Beta #51 is the 3rd public build of V1.65. Found some more missing stuff and broken tweaks, such as the directives failing which would make libraries like MAPS not compile. Another oddity caused the runtime to crash before the VM even started, which was nice of it, and another problem was with compares where the optimizer could break them, rather than stream line them..
End result is more stuff runs... A lot of things don't though :)
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
Download PlayBASIC V1.65 Beta51 (6th,Aug,2016) (OLD version removed, newer version bellow)
PlayBASIC V1.65 BETA #52 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (9th,Aug,2016)
V1.65 Beta #52 is the 4th public build of V1.65. This revision includes fixes to the new DIM which was missing some resizing and string handling code , SplitToArray wasn't adding the offset when outputing to a string array. FOR /NEXT didn't like STEP values of a different type. So an Integer loop with a float step would break at runtime and vice versa. There's also a fix in the linked list code that could break the range checking on the link as well as includes the missing On GOSUB command. The debugger has also has been updated and should now be able to view typed arrays and typed lists as before.
There's a few commands that aren't available such as SetArray/GetArrray which are used in a number of legayc demos, so I guess we'll have to look at some way to recreate such functionality in the new VM. All in all we're a step closer to a stable build, but there's still a lot of runtime error trapping mssing from the new VM... Which can make the runtime hang..
Download
DownloadPlayBASIC V1.65 Beta52 (9th,Aug,2016) (OLD version removed, newer version bellow)
PlayBASIC V1.65 – Beta 54: Stacking Around
Been testing a lot of code the last week or so and have found a dozen or so faults/missing functionality, one of the most recent was the scope handling code. Basically there operations to control the scopes data on the VM stack. Hadn't noticed it wasn't implemented as it only really gets used during recursion. After looking through the old solution we find a bunch of temp allocations in it. Which as you know I'm not terribly fond of. Dynamic allocating can be the bottle neck in some routines, so it's best if you can remove it.
Last night was spent sifting through the existing code trying to come up with a lighter alternative method. If you imagine strings for example, then when we enter a function the string needs to be prepared for you. If the function calls itself then we need to backup it's existing state. There's a number of ways of doing this and all they all have ugly by products. The old way just pushes the old handle and then allocates a new string, then pops and releases it later on.
What this means, is we're allocating a new string and continuing on with the function call, the string is then freed upon exit. This works, but... the new string might need to be expanded since we've no way of knowing how big a string is going to be up front, so new ones are allocated small (FASTER). So if pass a big string through a function and it might need multiple allocations and copies to preserve and restore..
The other main idea is the push by value idea, where the string gets copied to the heap and the string handle is reset to zero length. This requires no allocation, other than heap management. Which sounds good, until you hit the but.. which is now the size of the string could have significant impact on runtime performance. Most strings tend to be small, but imagine a function where the strings are large, say 10K or more characters long. Now that would create significant runtime penalty, even so I'm still tending towards trying out such an implementation. If it doesn't work so, we can always go back to a tweaked version of how it used to work..
PlayBASIC V1.65 BETA #54 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (16th,Aug,2016)
V1.65 Beta #54 is the 5th public build of V1.65. The main addition in this revision is the addition of the recursive function support, which had been left out of the previous builds. The method this now uses has been streamlined also to avoid runtime allocations, which should help functions with a local of local data perform better. It's worth noting though that stack space is limited, so diving into deep recursion isn't recommended, or even a good idea generally if you ask me... :)
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
Download PlayBASIC V1.65 Beta54 (16th,Aug,2016) (OLD version removed, newer version bellow)
PlayBASIC V1.65 Beta 55 - SetArray / GetArray
The SetArray / GetArray commands are some of the last known missing functions. They allow the user to grab the index of an array from the heap and then use that to move that array's handle to a target array. This worked fine in the legacy VM's but with VM3 we changed how all data is accessed, so these were broken. Replacing them has meant building a way of emulating the original behaviour, which was implemented this morning and as result more programs spring to life.
What's left now should be those subtle well hidden differences between the old and new runtimes.
PlayBASIC V1.65 BETA #55 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (20th,Aug,2016)
V1.65 Beta #55 is the 6th public build of V1.65. In this build we've uncovered that a shift in the logic behind the Dim/ReDim functions that could break some legacy programs from working. The problem boils down to the how arrays are passed by handle into functions. This is generally a cheap way of passing structures since all you need do it copy a single integer, but some array functions need to know the data type (user defined) of the structure they're building, such as dim and redim. Now since we're passing a handle, the compiler doesn't really know what User Defined type of array it's passing it the other. Some old programs uses this as a feature to save a few lines of code, even when it's not.. Long story short, is that is was possible to pass a Typed Array in a function and redim it as something else completely.. It works in old builds as they get the data type from the inside the array before it redim's it, where newer builds get the data type from the array's reference.. So the newer runtime mimics the old way for now. Will have to revisit this sooner or later.
Another change is with ExitFunction which would allow statements without the same number of params, which would create logic issues with stack management.
Download
Download PlayBASIC V1.65 BETA #55 (20th,Aug,2016) (Newer builds bellow)
PlayBASIC V1.65 BETA #57 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (7th,Sep,2016)
V1.65 Beta #57 is the 7th public build of V1.65. This build just contains a few small fixes..
PlayBASIC - Building a Release:
Unfortunately, real life has got in the way of PlayBASIC development over the past month. While life is starting to get back on track, V1.65 development has taken a real back seat for the time being. While is frustrating for everyone, I would rather get a version of this out sooner, than later. So starting tonight I'll be kicking into building a release version. Now this will mean it'll have a few missing VM changes, but I feel they'll take some time to perfect. So it's probably best to get a version out there and find all the existing hiccups, before introducing another big change...
Anyway, thanks for your patience and kick back get coding... Just one bit at a time !
PlayBASIC V1.65 - Retail Build Running
While I spent the afternoon watching the bulldogs (my football team) reserves winning their grand final.. (Can't help but start to put the cart before the horse now! :) #bemorebulldog ) I also was able to get the first retail build of PlayBASIC V1.65 to compile and run. So it's looking like we can get a retail build out sooner, rather than later.
So that's the good news, but the bad news is that's it's going be to be a little fresh in terms on the ground testing. So I wouldn't expect a seamless transition between V1.64 editions to V1.65 and beyond. But I'm sure the new speed will more than compensate you for that. Of course if you find something odd, post it the V1.65 bug report thread.
I'm not too sure when I'll be able to get a build on the server, but later in the week is looking most likely.
(http://www.underwaredesign.com/PlayBasicSig.png)
PlayBASIC V1.65 _Retail Upgrade_ Now Available (9th, Oct, 2016)
NOTE: THIS IS AN AS IS BUILD OF V1.65 - it's not 100%, we know that, but need your help to complete it ! The V1.65 introduces the next generation of the PlayBASIC virtual machine, so everything on the execution side of the product is new. This new VM gives us better speed (with even more speed to come) but of couse all these changes introduce new gremblins also. So you should expect to find programs that don't compile and simply wont work. Somoe of these changes occur from compiler / parser side of things, but things like crashes will be either some missing functionality in the new VM or something it used to do, isn't being handled anything, or has changed.
For V1.65 related errors, post them in the [plink]V1.65 bug reporting thread (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Don't have a retail version of PlayBASIC ? and want to find out more information about PlayBASIC programming > please visit the www.PlayBasic.com (http://www.playbasic.com) and download the free learning edition.
Downloads
[plink]Download PlayBASIC V1.65 Retail Upgrade (http://www.underwaredesign.com/forums/index.php?topic=1182.msg29233#msg29233)[/plink] (9th,Oct,2016)
PlayBASIC V1.65B - Work begins
Even though it's Christmas time and we've had a very difficult few months, I wanted to say that work has resumed / started on the second revision of the V1.65. It'll most likely be bugs and tweaks only, unless something really need to be replaced, so since it's true revision of V1.65.
I found a few programs that don't work in V1.65, but there should be a lot of others. Therefore I need you guys to help locate and isolate as many crashes as possible and put them all in the V1.65 bugs thread.. So there all in one big list.
Go here for [plink]V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink]
Anyway, in the mean time I hope you all have a great christmas and happy and safe new year.. .
PlayBASIC V1.65B - Beta 1
Found another operation that was missing that would cause programs to hang that inlined array copy functions. Which is where you can assign one array to another. Eg DestArray() = SrcArray() The parser would output these as move operations as such the array handle would have junk in it causing it to die.
PlayBASIC V1.65B BETA #2 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (6th,Jan,2017)
V1.65B Beta #2 is the 8th public build of V1.65. This build contains a few small fixes..
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
Download [plink] PlayBASIC V1.65B Beta2 (http://www.underwaredesign.com/forums/index.php?topic=1150.msg29274#msg29274)[/plink] (6th,Jan,2017)
PlayBASIC V1.65B - Beta 2
It's strange how life and art seem to emulate each other from time to time, but the last few coding sessions have been mainly house keeping, which is what I've been doing mainly in my real life too. The V1.65 runtime is in strange place at the moment, a huge amount of work has been done, but there's still some bridges to cross, or at least from what I can tell in comments/doc's I'd been jotting down.
Some of the remaining changes are the kind of stuff I'm not ready to take on today, as they tend to create nasty cascading side affects (as they're project wide) , so might have to limit myself to small but achievable things within the time frame available.
One task I've set myself of far is simply wandering through the shared/combo VM and culling anything that outgrown it's usefulness, of which there's a lot of legacy VM stuff hanging around, a bit like a boat anchor.. Ripped a bunch of array function double up (and more to come) which can itself be a painful, as routines you wouldn't expect are used in some other command set, often as some short cut here and there. Which might have been useful back in the day, but it's none the less annoying now...
In terms of bug hunting, form what I can tell so far (from the few things listed), the reported issues occur from either opcodes having different behaviours (to 1.64 and older) or in some cases simply don't have any support in the new runtime or compiler of some legacy ability. In other words there's opcodes that haven't been added yet... but ya get that :)
PlayBASIC V1.65B BETA #4 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (27th,Jan,2017)
V1.65B Beta #4 is the 9th public build of V1.65. This build contains a fix that could break the compipler during big sources (maybe some more of those in tghere) and the DeleteArray wasn't hooked up in the newer runtime.
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
[plink]Get PlayBASIC V1.65B Beta4 (http://www.underwaredesign.com/forums/index.php?topic=1150.msg29294#msg29294)[/plink] (27th,Jan,2017)
PlayBASIC V1.65B - Beta 5
Been tweaking the type variable/array/list reading code (it's all the same thing), which used to allow programs to access types that doesn't exist (ie not allocated) within the container. It's important to remember that Dim creates the container at runtime, and not the actual structure(s).
ie
[pbcode]
Type Stuff
a,b,c
EndType
; The DIM defines the variable THIS of type STUFF at compile time, and at runtime DIM allocates THIS's container.
; But the structure (of type stuff) hasn't been used created.
Dim This as Stuff
; To create/alloc it we'd..
This = New Stuff
; So NEW allocates the memory and returns a type handle for us to store in the container.
[/pbcode]
Now, what users often do with typed arrays is they read fields from types that don't yet exist.. Take a look at this, which is legal in old version of PB.. but isn't in the current build of V1.65
[pbcode]
Max = 100
Type tObject
Status
Xpos#,Ypos#
Sprite
EndType
Dim Character(Max) as tObject
For lp =0 to Max
if Character(lp).Status=true
; do character stuff etc
endif
next
[/pbcode]
What's wrong with it ? - Well, the type structures inside the array haven't been allocated. So the code Character(lp).Status is reading memory from a Type that doesn't exist. Old PB runtimes trap this and let you get away with it. It's not something i'm fond of..
So the current builds would pop a runtime error with the above code.
What you should do, is read the array for each types handle first, before accessing any fields within it. So If there's handle (any none zero value), it that type exists. If the value returned is ZERO, that cell is empty and there's nothing in this container as yet, be it Typed Variable or Typed Array..
[pbcode]
Max = 100
Type tObject
Status
Xpos#,Ypos#
Sprite
EndType
Dim Character(Max) as tObject
For lp =0 to Max
; check if this type is allocated ??
; if it's not null then it must exist.
if Character(lp) <> NULL
; do character stuff etc
endif
next
[/pbcode]
PlayBASIC V1.65B BETA #5 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (4th,Feb,2017)
V1.65B Beta #5 is the 10th public build of V1.65. This build contains two changes, the first one just one tweaks ATAN to return an ANGLE rather than RADIANS, so you might well find one code that will break in this build.. The other is more likely to hit you in the face, as the runtime now traps a read accesses from types that don't exist and will pop a runtime error..
Here's a post about type changes in PlayBASIC V1.65B - Beta 5 (http://www.underwaredesign.com/forums/index.php?topic=4333.msg29299#msg29299)
Update: newer build bellow
PlayBASIC V1.65B BETA #7 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (8th,Feb,2017)
V1.65B Beta #7 is the 11th public build of V1.65. This revision fixes a problem found in the CallDLL instructions. The older 1.65 versions would decode types passed through using the legacy Type structures which of course at some point have been removed and now replaced. So the new opcodes just needed to be tweaked to pull the structure info from the new APP structure. So slowly but surely the legacy runtime components are vanishing into far distant memory.
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
Newer build bellow.
PlayBASIC V1.65B BETA #8 - Linking Commands Sets Into New VM & APP format
Unfortunately the hiatus has sucked the life out of the project generally, but there are some up sides though, which is extra time between sessions tends to give you more strange ideas on how things can be linked together more easily.. So without a lot of effort, which I like the idea of mainly..
In V1.65 the new app format & it's instruction set only covers the 'core' instructions behind your program. This is the real nuts and blots stuff, but the the majority of command sets aren't handled through it at all. Well that's not entirely true, some things that are considered part of core are already in, while most specific command sets stuff is zoned as external command set. So stuff like string functions for example would be in core (as they're universal) but commands like the Sprite commands are not..
While developing PB2DLL a lot of work had was made to PB in an effort to externalize the command sets in a way that can be plugged into a program based upon a usage. Old PB runtime don't generally work like that, they tended to have a opcode decoded as part of the Vm (although there's a few variations of that basic theme).. Which was handy in some ways, but totally breaks when you have something like PB2DLL . This is because you need to call a command directly.
In todays build I'm working on a way of encoding instructions that will hopefully means they can be moved more easily into the new runtime without really having to to do a lot of hands on coding.. Not into that.. Ideally it should be possible to call any command from the set without breaking the existing stuff.. The basic optimizations prolly won't work (come to think of it) but it should mean that I can move 100's of commands over rather than a block at a time...
The benefit of this is basically speed for the short term. Currently any unknown opcodes on the new VM side, abort execution and fall back to the legacy runtime to be picked up there.. Which is very expensive.. I'm hoping we'll see a 25 to 50% calling gain.. Perhaps more on some commands, but we'll see...
Update:
After a bit of messing around I've managed to get one block of commands working using this method. The comands set is the just colour commands (The RGB stuff) but the bench mark now runs about twice as quick..
What's missing though is error trapping, which is handled in different ways.. I 'm assuming that If i drop in a status check into the general decoder, we'll loose some of that speed for the time being.. At least until I can make a cleaner.
But it works !
PlayBASIC V1.65B BETA #11 - Command Set Decoupling
Well we're getting some of the new VM problems sorted as time goes by, have sort far moved about a third of the internal command set to the new decoupled system and the results as very good, it makes the VM simpler and they perform better. But... there's a BUT... Annoyingly I've had to reshuffle the core 2d primitives command sets to get them to work. It's annoying for two reasons, first is I'd forgotten they still had some inline code in the legacy VM in them and second is that the really granular commands like Dot & FASTdot turn out to be about 20->25% slower, which is not a nice finding after all the work that's gone into it.
I used the same tests between versions, you know year in , year out. The FastDot one boils to a full screen fill which is something like this (all the test code is on dev box)
[pbcode]
For ylp=0 to Heigt-1
For xlp=0 to Width-1
fastDot Xlp,Ylp,Colour
next
Colour+=SomeValue
next
[/pbcode]
Now the clued in coder would notice that's a pretty awful code, but as it's just drawing strips of colour, but it's really a test of the how fast the loop + fastdot functions can be called.
While on the subject, here's a few ways to write pixels.. Some need a bit more work, but with that comes higher performance.
[pbcode]
Constant BumpValue=$111
Method=0
Do
Cls 0
if SpaceKey()=1 and Toggle=0
Method=Method+1
if FunctionExist("Test"+str$(MEthod))=false
Method=0
endif
endif
Toggle=ScanCode()<>0
CallFunction "Test"+str$(MEthod)
print fps()
print "Space to Cycle Test"
Sync
loop
// -----------------------------------------------------------------------------
// ----------------------------[TEST0 - DOT]--------------------------------
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
Function Test0()
Height =GetScreenHeight()
Width =GetScreenWidth()
lockbuffer
ThisRGB=Point(0,0)
Colour =0
For ylp=0 to Height-1
For xlp=0 to Width-1
DotC Xlp,Ylp,Colour
next
Colour+=BumpValue
next
unlockbuffer
Print "Test0: DOTC"
EndFunction
// -----------------------------------------------------------------------------
// ----------------------------[TEST1 - FAST DOT]--------------------------------
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
Function Test1()
Height =GetScreenHeight()
Width =GetScreenWidth()
lockbuffer
ThisRGB=Point(0,0)
Colour =0
For ylp=0 to Height-1
For xlp=0 to Width-1
fastDot Xlp,Ylp,Colour
next
Colour+=BumpValue
next
unlockbuffer
Print "Test1: FastDOT"
EndFunction
// -----------------------------------------------------------------------------
// ----------------------------[TEST2 - POkeINT]--------------------------------
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
Function Test2()
Height =GetScreenHeight()
Width =GetScreenWidth()
lockbuffer
ThisRGB=Point(0,0)
Ptr =GetImagePtr(0)
MOdulo = GetImagePitch(0)
Depth =GetScreenDepth()
Colour =0
For ylp=0 to Height-1
if Depth=32
RowPtr=Ptr+(yLP*MOdulo)
For xlp=0 to Width-1
PokeInt RowPTR+(xlp*4),Colour
next
endif
Colour+=BumpValue
next
unlockbuffer
Print "Test2: Direct Memory Access: PokeInt"
EndFunction
// -----------------------------------------------------------------------------
// ----------------------------[TEST3- Pointer Array ] ----------------
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
Type tRawRow
Row(8192)
EndTYpe
Function Test3()
Height =GetScreenHeight()
Width =GetScreenWidth()
lockbuffer
ThisRGB=Point(0,0)
Ptr =GetImagePtr(0)
MOdulo = GetImagePitch(0)
Depth =GetScreenDepth()
Colour =0
For ylp=0 to Height-1
if Depth=32
DIm RowPtr as tRawRow pointer
RowPtr=Ptr+(yLP*MOdulo)
For xlp=0 to Width-1
RowPTR.Row(xlp) =Colour
next
endif
Colour+=BumpValue
next
unlockbuffer
Print "Test3: Direct Memory Access Typed Pointer Sub Array"
EndFunction
// -----------------------------------------------------------------------------
// ----------------------------[TEST4- Pointer UNrolled Fields]--------------------------
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
Type tUnrolledPixels
Pixel0
Pixel1
Pixel2
Pixel3
Pixel4
Pixel5
Pixel6
Pixel7
EndTYpe
Function Test4()
Height =GetScreenHeight()
Width =GetScreenWidth()
lockbuffer
ThisRGB=Point(0,0)
Ptr =GetImagePtr(0)
MOdulo = GetImagePitch(0)
Depth =GetScreenDepth()
Colour =0
For ylp=0 to Height-1
if Depth=32
DIm RowPtr as tUnrolledPixels pointer
RowPtr=Ptr+(yLP*MOdulo)
For xlp=0 to (Width/8)-1
RowPTR.PIxel0 =Colour
RowPTR.PIxel1 =Colour
RowPTR.PIxel2 =Colour
RowPTR.PIxel3 =Colour
RowPTR.PIxel4 =Colour
RowPTR.PIxel5 =Colour
RowPTR.PIxel6 =Colour
RowPTR.PIxel7 =Colour
RowPTR= RowPtr+(8*4)
next
endif
Colour+=BumpValue
next
unlockbuffer
Print "Test4: Direct Memory Access Typed Pointer Sub Array"
EndFunction
[/pbcode]
Anyway, so getting back to the problem, I think we can get past some of the bottle necking with it, but we might have just have to live with it, at least for the time being..
PlayBASIC V1.65B BETA #14 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (26th,Mar,2017)
V1.65B Beta #14 is the 12th public build of V1.65. This revision moves some of the core command sets so they execute on the new VM side 100%. Older revisions would flip flop between the new and old run times to do this, so this build executes such loops faster than previous V1.65 editions.
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
New builds bellow
PlayBASIC V1.65B BETA #17 - Command Set Decoupling - Getting Simpler By The Day (18th,May,2017)-
Fired up the compiler/VM project the last few nights ripping into the left over command sets that are still suck on the old VM side on the runtime. Initially i was a little worried about this stuff as it's big (lots of commands) but after a few teething problems (ie not remember how some stuff works :) ) the sprites command blocks are now moved and working correctly. A few more sessions and they should just about all be detached, the error trapping isn't as pretty atm, but you'll have to live with that in the mean time. While looking over the caller code, it's very very generic, so there's some free speed sitting on the table once they're all everything moved over (10% or more on the call cost). So the losses from brute force functions like DOT drawing should be recovered.
PlayBASIC V1.65B BETA #21 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (26th,May,2017)
V1.65B Beta #21 is the 13th public build of V1.65. This revision moves all the core command sets across to the new VM side. Progress wise it's now about 98% running on the new VM, there's couple of legacy (and common) commands that still execute on old VM side and some missing legacy features in the new VM, which will be moved, but i wanted to get some info about how this runs in the wild first.. If it's OK then we can build a retail and get stuck into the final part of the process.
See->> [plink]Read V1.65 Update Work In Progress gallery (http://www.underwaredesign.com/forums/index.php?topic=4333.0)[/plink] for some info on what's changed.. Lots of STUFF.
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
old file removed, release build bellow
PlayBASIC V1.65B BETA #26 - Legacy Debugger To New Vm bindings
So as I was saying in the blog the other day the only set of command still running on the legacy VM side, is the debugger calls which aren't as easy to export, at least how they've been implemented into the old VM.. When you stop and pause a program for example, the VM included some special fall through logic, which works, but needed a bit of tweaking to get stuff functioning again ( as it's mostly broken in Beta21 above), which is what i've been doing over the last week.
It seems we might also be able to add a new deadlock feature or at least something to the current runtime that will post messages to the console when it thinks your code is chewing up too much VM time, without refreshing the scene (sync)... If you don't sync, you're not calling the message pump and windows doesn't like that and will start to think your app is dead..
Anyway, so it's starting to work again.. If I get it tweak tonight i'\ll throw up a another live beta later on today and fingers crossed we can build a retail edition.. yay !
PlayBASIC V1.65B BETA #26 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (09th,June,2017)
V1.65B Beta #26 is the 14th public build of V1.65. This revision tweaks up the debugger so that it'll work with 165 VM, it's not 100% but that why we beta these things..
See->> [plink]Read V1.65 Update Work In Progress gallery (http://www.underwaredesign.com/forums/index.php?topic=4333.0)[/plink] for some info on what's changed.. Lots of STUFF.
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
old files remove, release build bellow
(http://www.underwaredesign.com/PlayBasicSig.png)
PlayBASIC V1.65B _Retail Upgrade_ Now Available (23rd, June, 2017)
The
PlayBASIC V1.65B package includes updates of PlayBASIC Compiler, Release / Debug Runtimes, SLIBS, DOCS & IDE V1.17b.
The V1.65B includes second release of the next generation of the PlayBASIC virtual machine. In this build 99.99% of the commands now execute on the new VM side, giving much higher execution performance. There are still some 'commands' tied to the legacy VM which mainly the debugger command set and few text commands such as Print and TEXT and the Sync command which is actually a VM TRIGGER..
Performance wise this is easily the fastest edition of PlayBASIC to date, even though the runtime is missing some of the byte code optimization modes found in the V1.64 builds, which will be tackled in the next revision of 1.65, but for now get stuck into it
Reminder: The new runtime doesn't support reading from types that don't exist, which can cause old programs to fail from time to time.. For a full V1.65B development story read the
PlayBASIC V1.65 blogs and for V1.65 related errors, post them in the [plink] V1.65 bug reporting thread (http://www.underwaredesign.com/forums/index.php?topic=4350.0) [/plink].
Don't have a retail version of PlayBASIC ? and want to find out more information about PlayBASIC programming > please visit the www.PlayBasic.com (http://www.playbasic.com) and download the free learning edition.
Blogs
[plink]PlayBASIC Video Blog Ep 0003 (2017 -06-24) (http://www.underwaredesign.com/forums/index.php?topic=4372.msg29420#msg29420)[/plink]
Downloads
[plink] Download PlayBASIC V1.65B Retail Upgrade (http://www.underwaredesign.com/forums/index.php?topic=1182.msg29418#msg29418)[/plink] (23rd,June,2017) (No download managers!)
PlayBASIC V1.65C BETA #2 - Debugger Fixes
Kicked off work on revision C too iron out the left over problems in V1.65B starting with tweaking up the debugger again, which still has legacy hooks into the old variable tables when looking at pointers and typed pointers in particular, which would either work or crash or both :) Skimming through it and there looks to be a few gremlins in the bowels of that code as well.. Mainly due to the new VM's application structure.. Some stuff is looking at old mirrored data from when code it would execute across the two runtimes, which are still present, but hopefully we can get rid of those legacy opcodes in this build and be done with it. Which will mean any mirrored data fetches will disappear also, which is better for the CPU caching and execution performance.
PlayBASIC V1.65C BETA #3 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (21st Aug,2017)
V1.65C Beta #3 continues to clean up the V1.65 runtime and debugger. This version fixes a problem with the NOT operation which wasn't computing the target variable offsets correctly within the APP structure, so it was working but reading the wrong data. Making some stuff appear to work, but it didn't really..
The changes to the debugger, first we've go some fixes to viewing pointers and typed pointers can now resolve the structure and decode the memory. We might need a safe mdve here too, as it's possible a pointer is looking at memory that has been deallocated.. Another change is the addition of some extra information when viewing variables in the debugger. If you click on a Integer now, you'll see it's value as Integer ? Hex & Binary as before, but i've also added a colour and ASCII field also.. I've also tacked in a hex view into the String variable viewer. So it shows the length of the string, the raw character data then a hex view..
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
[plink] Download PlayBASIC V1.65C Beta3 (http://www.underwaredesign.com/forums/index.php?topic=1150.msg29455#msg29455)[/plink] (21st,Aug,2017)
PlayBASIC V1.65 Beta 4 - RndRange() being skewed by caller
Found an interesting difference between PlayBASIC V1.65 and PlayBASIC V1.64 last night with the RndRANGE() (integer version) being rounded slightly in the 1.65 runtimes..
This one was only detected while looking through the JetPAK sources from Ian Price. Some of the controller code in that demo used an expression like this Y=Y+RndRange(-1,1)*2 so those characters wouldn't move randomly UP / DOWN in PB1.65, only up, as a result of 1 wasn't seem possible.. Seems to be fixed now in PB1.65 Beta4 so í'll throw that up on the server over the weekend.
Another change has been made to legacy expression solver, NOT operations are now solved after AND/OR/XOR again..
PlayBASIC V1.65C BETA #4 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (6th Sep,2017)
V1.65C Beta #4 continues with the V1.65 clean up. While working through some old examples I noticed that JetPAK (after fixing it) ran different in V1.65 than older PB versions. The main issues were the optimizer was breaking some expressions that contain NOT and there was some rounding sneaking into the integer version of RNDRANGE() function call
. In JetPAK the game uses an expression such as Y = Y + RndRange(-1,1) * Speed to move some characters up / down randomly, when running the game in V1.65 they only would move up, where as in V1.64 they behave normally. Took a bit of detective work, but we ended up having to wrap a separate version of RndRange in order for it behave like the older versions of PB.. Another issue that work differently in older versions of PB then 1.65 was the player collisions and gravity in the game. There was an issue with the NOT opcode read/writing the incorrect variable/register as well the PB byte code optimizer could break those expressions by modifying the output expression incorrectly.
The only functionality change in this build is the precedence of NOT has been restored to being lower than the AND/OR/XOR operations. So the NOT will occur at the end of the expression. Which is how it used to work, but it seems to have changed at some point...
Anyway, the byte code optimizer should now tweak these kind of expressions into the simpler forms that function the same..
[pbcode]
result= not A=B
if not A=B
endif
if not A<>B
endif
if A=B
endif
if A<>b
endif
[/pbcode]
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
[plink] Download PlayBASIC V1.65C Beta4 (http://www.underwaredesign.com/forums/index.php?topic=1150.msg29468#msg29468)[/plink] 6th,Sep,2017)
PlayBASIC V1.65 Beta 6 - Command Caller
So last night I've finally managed to weed out the last dark corners of the legacy command callers from the new VM. This means that all of the command set can now be considered external. The problem I was having is that internal commands have some wacky parameter matching in them, which allowed for a bit less table data back in the day and pushed some of the work onto the VM, so those commands have logic inside them to handle the different input types. Some still do, in particular commands that are considered part of the VM. Arrays would be able of that.
For example, the classic PRINT statement, was defined as accepting Integer/Floats and String as parameter, then the VM caller would work out what to do when calling the print oncode in the VM. This is cool can all but in the new vm, were calling a function with a single pattern, so any differences need to be either be converted prior and our during the call, ideally without adding any overhead to the call. What I ended up doing is the latter, is coming with a way of defining stuff that is simple to how it works already (coz i'm lazy) that can handle conversion of terms if need be. So it should make the end functionality of the same how it already works, but the caller operation is much leaner and meaner, giving us faster execution.
I know this all sounds like none -sense but splitting the VM some the command sets and having a generic caller means the VM doesn't need to be updated to add new commands and more importantly, we can change command sets.... Still have to sure up the caller and opcode generation stuff (it's just hacked in to get it working) then we can convert the command set tables. Which I think I can write a parser to convert most if not all of them.. But for now I'll keep the test to a hand full of left over commands
PlayBASIC V1.65 Beta 7 - FastDot benchmark hits 60fps Yep, last nights build of PB1.65C pushed the FastDot bench from a new high of 22/23fps up to 60fps on Athlon test system.... (800*600 PIXELS IN 32BIT)
:) :) :) :)
EDIT:
PlayBASIC V1.65 Beta 14 - Kissing Vm2 Goodbye
Early this morning PB sprang back to life after being dead for the best of last week, as outlined in the last video blog, I moved directly pass the function caller updates onto separating VM3/4 from legacy VM2. Cutting the umbilical chord and making it sink or swim on it's own, of course initially it sunk :) - However after some pretty boring detective work, I've been able to track down why an where the crashes appear. Some obvious and some not so... So it's been sort of sorta of running for days, but wouldn't run anything big, now after this morning repairs it's actually starting to run bigger stuff again.. Still unstable, but working !!
PlayBASIC V1.65 Beta 15 - Hooking the debugger
So some good news today as work ticks along with the transition to the VM3 focusing on the debugger hooks, which has meant rewriting and patching the old debugger and new runtime together, as of today we're down to two instructions left to fix, which relate to step and trace. Once those are in place it should be all working, of course with whatever quirks...
PlayBASIC V1.65C BETA #20 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (29th Dec,2017)
V1.65C Beta #20 virtually concludes the V1.65 clean up. In this build we are running on the new VM only. Which means all new instruction set and all new inner workings of PlayBASIC... In this last build we're reconnected the Vm with the legayc debugger, which was previously rigidly hooked to the legacy VM making it break in later builds. In this version is almost back to normal, I say almost as the old interfaces are still there and there many be some routines still using them, but I'll tackle that in the clean up when building a release version in the new year.
The new runtime brings us more number crunching performance, standard instruction set and is now separate from most of the command sets (some are built into the VM.. like strings or array commands) the generally command sets could be swapped without needing to constantly update the runtime. There's some features of V1.64P that are NOT in the new VM, which are mainly some of the compiler optimizations that it would make to user byte code, one that comes to mind is the serialization of the Type / Structure accesses.. Which can give a massive performance benefit in code that focuses it's accessed on one structure of data.. I'm going to include this in V1.65, but wanted to get it working first.. then we can add some of my list of tricks :)
Anyway, have fun.. there's bound to be some DEBUG messages etc in this.. but it's the future !
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
Take me to [plink] Download PlayBASIC V1.65C Beta20 (http://www.underwaredesign.com/forums/index.php?topic=1150.msg29528#msg29528)[/plink] 29th,Dec,2017)
PlayBASIC V1.65C BETA #21
So a few issues have been found and release 20 so putting together a beta 21 (well build 21) , this one fixes SetFPS, strips from double reading from text drawing , fixes CopyRect and it's brothers (the command table was short :) ) and has some tweaks in it for the the release build.. All of which isn't on this system anymore, whcih means dragging it over from the devlopment box to put it online, which is always pretty tedious.
I did notice there's one command that's become homeless and that's one of the Mesh commands using in the old 2D in 3D demos as well as various terrain demos in the example packs... I think I might put together a mesh library, or at least make provision for one in the command sets.
Anyway, we'll try and get it together tonight..
PlayBASIC V1.65C BETA #22 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (17th Jan,2018)
V1.65C Beta #22 addresses various missing or broken issues with beta 20, things like the SetFPS command was broken, because SYNC is now actually a command and not a VM process, Text drawing had some extra String processing it in and some commands we're defined in the table and would crash at runtime, such as CopyRECT for example.
Anyway, have fun.. there's bound to be some DEBUG messages etc in this.. but it's the future !
Download
Take me to [plink] Download PlayBASIC V1.65C Beta22 (http://www.underwaredesign.com/forums/index.php?topic=1150.msg29543#msg29543)[/plink] (17th,Jan,2018)
PlayBASIC V1.65C BETA #24 - Mesh Command Set The last couple of very short coding sessions have been to find homes for a couple of commands that had become orphaned through out the 1.65C process. Thankfully these tent to be the legacy 'test' commands used in the some of the more obscure demos and even some that are in the demo packs even like the, like the 2D in 3D platformer and Terrain demos.
Here's a link to the 2D platformer in 3D (http://www.underwaredesign.com/forums/index.php?topic=1080.0) blog/ thread from back in 2006..
PlayBASIC V1.65C BETA #24 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (7th Feb,2018)
V1.65C Beta #24 includes some obscure commands that were missing from the previous builds, fixed an issues with constant declared within functions/psubs and includes a few clean ups in the low level mesh command commands.
That constant declaration bug was stopping a few old demos from working as they constant strings declared inside functions, at first this wasn't even on my radar thinking the problem was with the TranslateMeshToScene command, which was a test command from about 10 years ago.. But once they're in you can't really just remove them, well you prolly could but some of the funkier old demos use them.. Like the Terrain demo in the example pack. None the less, i spent more than few nights thinking that was faulty command, but of course what i should have been doing was putting in some break points and checking if the data passed into the command was good to begin with, it wasn't !
The problem turned out to be in a function that created a cube. The function used a string which I was then parsing out for the faces, a bit like bellow..
[pbcode]
Function NewCube(Size)
constant FaceList$="|1,2,3,4|1,2,3,4... blah"
For lp =0 to 5
Vertex1= mid(FaceList$,POs)-asc("0")
Vertex2= mid(FaceList$,POs+2)-asc("0")
Vertex3= mid(FaceList$,POs+4)-asc("0")
Vertex3= mid(FaceList$,POs+6)-asc("0")
SetFace(Vertex1,Vertex2,Vertex3,Vertex4)
Pos+=8
next
EndFunction ObjectIndex
[/pbcode]
The code was generated correctly, but the scope initial which is executed for each new scope when it's called was killing the FaceLIst$ constant thinking it was a string variable...
I should point, While declaring constants inside function works, they are defined GLOBALLY BTW... yeah.. yeah It's already on the TO DO list :)
Anyway, have fun..
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
[plink] Download PlayBASIC V1.65C Beta24 (http://www.underwaredesign.com/forums/index.php?topic=1150.msg29556#msg29556)[/plink] 7th,Feb,2018)
PlayBASIC V1.65C BETA #28 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (4th Mar,2018)
V1.65C Beta #28 includes support for FASTCALC expression stacks as well as a including a few compiler/parser level optimizations. The parser can detect and upgrade Sin/Cos(Angle)*Radius and upgrade it to Sin/CosRadius(Angle,Radius) as well as detecting a void usage of INT when occurring in an IF block.
Anyway, have fun..
See->> [plink]Read V1.65 Update Work In Progress gallery (http://www.underwaredesign.com/forums/index.php?topic=4333.0)[/plink] for some info on what's changed.. Lots of STUFF.
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
[plink] Download PlayBASIC V1.65C Beta28 (http://www.underwaredesign.com/forums/index.php?topic=1150.msg29568#msg29568)[/plink] 4th,Mar,2018)
PlayBASIC V1.65C BETA #34 - Rescue Me from the land of legacy code
After a bit of coding hiatus i've been sticking nose under the hood of the latest 165 builds with the thought of issues it as another 'as is ' retail build. So set up the runtime builder, but quickly ran into a bunch of issues with the generated code, namely like it doesn't work/build.. So that's annoying as I distinctly remember doing that ... obviously didn't :)
Since we're running the new VM with it's own program format, then it stands to reason it needs it's own support code for not only generation but startup the runtime, which I had wanted to hold off until a D revision of V1.65.. So I can get the boring stuff done and let you have something new to play with, but I don't think that's going to happen, might be forced into doing all this crap now.. Even then, we'll still another revision that deals with the command sets as it turns out there's about a 1000 commands parameter patterns that need to redefined, but that i should be able to most of that via code.
The internal command defines isn't at all important for users, this actually all about passing generated code through to 3rd part conversion tools. Since the tool need to be able to work out what command / function the code is calling. It works in old programs like pb2DLL because that tool contains a version of the instruction set that V1.64 uses and assumes it knows that commands from the fixed offsets. I could do that again, but then it doesn't detached the exported code from the compiler, in other words the conversion tool needs to know what compiler / version it was created with, which is exactly what I don't want... The solution will be ugly, but should work fine. A command set is defined by name and then functions/command names are offsets into that name set buy search out the parent, which is kind of how DLL's actually work..
Anyway, better go get something done.
PlayBASIC V1.65C BETA #36 - Reloc and DLL binding is a go
Just wanted to say that I've finally overcome the crashing at startup problem found in the most recent beta ( mentioned in the [plink]latest blog (http://www.underwaredesign.com/forums/index.php?topic=4428.msg29617#msg29617)[/plink]), which turned out to be just sloppy pointer handling, where the base structure pointer wasn't looking at the Reloc / DLL Binding chunks in the APP at all, but it was offset.. Which is annoying as I must have checked that code about 50 times for such an issue without noticing it. Turned out the brackets around the compute expression where wrong.. LOVELY...
PlayBASIC V1.65C Beta 39 - It LIVES
Just wanted to say that this morning the new build process finally sprang to life, after a number of trouble shooting sessions. This means that the current build includes the ironed out new APP format (localized) and it's new startup sequence. Long story short, this mean the runtime can be built into the release and debug editions and thus exe's can be built, but they work.
There's still some missing things from the APP format such as a replacement of the initial properties, which were a binary hunk in the original byte code, but could be replaced with either a text version or default startup function appended to the user code. Something like the latter will need to done at some point, but I'm in no rush with that.
Now what ? Well, it means we head into a clean up phase in order to build a release build from the V1.65C code bases, stuff like cleaning out legacy code & debug code from the runtimes. It'll need some testing in the wild that's for sure and there's some compiler features that are not present in v1.65 at all, but it's working and that's all I care about today...Tomorrow is another day!
Have fun !
PlayBASIC V1.65C Beta 40 - VROOM VROOM - Start Up Process is working
Some awesome news today as the initial properties have made there was into the APP format and seems to be working well albe it from the limited testing here this morning. I've had to keep the way the start up sequence much the same as the original for the time being, but it will be necessary to move the startup procedure into the platform bindings. The bindings are just some pre compiled Playbasic code which user code is compiled after, which is pretty standard fair in programming languages. The problem with the current design is that the startup sequence is initializing the screen state and libraries, which makes the startup dependent upon the command sets, so they can't be switched out easily. Ideally what we need is all the library and screen set up code moved into the bindings, so it's not attached to the VM. But that can be done during the next phase I think.
PlayBASIC V1.65C BETA #41 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (29th July,2018) V1.65C
Beta #41 includes support for building EXE's - thus it includes the release and debug runtimes in the BIN folder. So in order to test, you copy the files into your PLayBASIC folder, so that they replace your existing files. You might not want to break your 'official retail install, so what I generally go is just make a clone of my PlayBASIC folder somewhere and then drop the beta files into it. This allows me to play without ever worrying about damaging my retail install.
Anyway, have fun..
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
Download [plink] PlayBASIC V1.65C Beta 41 (With runtimes) (https://www.underwaredesign.com/forums/index.php?topic=1150.msg29639#msg29639)[/plink] 29th,July,2018)
Blog
PlayBASIC Blog - PlayBASIC V165C Beta 43 and Debugger Chat (2018-08-20 )
PlayBASIC V165C Beta 44 and Debugger (2018-08-27 )
Dropped a couple of new features into the old debugger such as some auto generated file names & some limited Font & colour controls and few optimizations and clean ups, that's about it for now
PlayBASIC V1.65C BETA #44 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (9th Sep,2018)
V1.65C Beta #44 includes support for building EXE's and a bunch of bug fixes and debugger tweaks. The tweaks include some abilities to change the Fonts & Colours in some of the debugger dialogs. apart from that I think the core is basically the same as beta #41.
Anyway, have fun..
See->> [plink]Read V1.65 Update Work In Progress gallery (https://www.underwaredesign.com/forums/index.php?topic=4333.0)[/plink] for some info on what's changed.. Lots of STUFF.
Download
Obsolete, newer builds bellow
Just a quick note that while testing PBV165 Beta 46 i've found some missing features, namely support for loading dll's form memory, which just leads to a crash in the current builds. Hopefully I'll be able to get this sorted ASAP and get the release out soon..
What fun ! :(
Update: Fixed 8th Oct 2018 .. the resource loader wasn't pulling a pointer to the resource and the order was out of sequence, so the function initialize wasn't returning function pointers
PlayBASIC V1.65C BETA #47 - Updating the Doc's
The current build is up and running with the old bigger code bases such as app's like the Amos2playBASIC conversion tool. Which works, but there's the odd assumption still left in the code where it's reading types that don't exist, which creates the odd runtime error. Most on the one's look like this where it's querying an array and then reading from the index beyond the current one without a safety check.
[pbcode]
if Token(Index)
; Here is where it'd trip runtime if the type beyond the current one which is known to exists, is then attempting read from the structure.. which
; would throw a runtime in V1.65
if token(Index+1).field
endif
endif
[/pbcode]
So in your code you should expect 1.65 to bark at you if you have code like this..
Beyond that I've been starting to update the doc's in order to build it all up into a release build for you.
(http://www.underwaredesign.com/PlayBasicSig.png)
PlayBASIC V1.65C _Retail Upgrade_ Now Available (21st, Oct, 2018)
The
PlayBASIC V1.65C package includes updates of PlayBASIC Compiler, Release / Debug Runtimes, SLIBS, DOCS & IDE V1.17b.
The V1.65C includes third major release of the next generation of the PlayBASIC virtual machine. In this build 100% of the commands now executed on the new VM side, giving much higher execution performance than V1.64 and previous legacy builds. The main objective of V1.65C revision was to catch the last remaining problems or missing functionality from the previous V1.65 releases, which I thing we've about covered now. There's still some features missing from the V1.64 era of the runtime that are not in v1.65c such as sequential type access optimizations, but that will reappear in the later build.
Reminder: The new runtime doesn't support reading from types that don't exist, which can cause old programs to fail from time to time.. For a full V1.65C development story read the PlayBASIC V1.65 blogs here (http://www.underwaredesign.com/forums/index.php?topic=4333.0) and for V1.65 related errors, post them in the [plink]V1.65 bug reporting thread (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Blogs
none
Downloads
Download [plink] Download PlayBASIC V1.65C Retail Upgrade (https://www.underwaredesign.com/forums/index.php?topic=1182.msg29664#msg29664)[/plink] (21st,Oct,2018)
PlayBASIC V1.65C2 BETA (2019-03-16) - CallDLL crashes
Been chasing my tail this past week looking for the reason behind some strange crashes in one of the compo games. Like most these issues you assume it'd be easy to find the smoking gun, which in this case is some CallDLL's in the code to some external library. These should work as the back end code is the same as previous builds of PB, so the new fault must be in the new VM wrapper or possibly the expression is being optimized when it shouldn't be. Dunno at this point.. it's annoying to run into a fault when I wanted to get it on the server. If the issue does appear soon that's what i'll probably do as it includes a number of other fixes.
The only other known problem that was found, appears in the VB6 to Flexi demo which has a mysterious deletion of one of the structures at runtime. Finding that one might take some real debugging, as those types of problems tend to be found in tiny changes that are generally hidden in smaller problems, as that's one of the longer PB programs.
PlayBASIC V1.65C2 BETA (2019-03-21) - CallDLL crashes follow up
Been looking at the JetPAK source for most of the week ( when time permits) as it uses a 3rd party Joystick dll that is crashing. The project seems to work in old versions of PB, so therefore it must be a problem with modern PB runtimes right ?? nope.. trawling through the code and there's no obvious issues at all , apart from those commands not returning runtime errors. So hmmm... strange
Last night i changed tact and started to look into the DLL itself, unfortunately it's really old and doesn't seem to be available anymore. so the only code I've got on the dev box is JetPAK, so you'd think that code would be correct right ... hmmm .. more testing on it's own and erm.. maybe not.. Fired up the disassembler to take a look at some of the function headers in the joystick DLL, as I was starting to wonder what parameters these functions take and that's one way you can work what the code is expecting to be passed upon call. This is where it gets strange as it appears the DLL functions are exported as cdecl but the jetpak code us using stdcall to call the functions. That seems like a crash waiting to happen, as they have different responsibility to clean up the stack.
So what happens if you set the joystick DLL to use cdecl calling covention ??? well it works as normal. So we're been chasing our tails looking for something that used to broken in old versions of PB as it would seem they befault to using cdecl rather than stdcall.. Which is why it works in old versions.
Moving on and while looking at that library at least I can hook up the errors to the runtime. Ideally i'll be able to get that done tonight and get a build out the next day or day after..
PlayBASIC V1.65C2 BETA #12 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (23rd March,2019)
V1.65C2 Beta #12 is the current build of the compiler and runtimes. Includes CallDLL fixes and some DATA fixes.
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
[plink] Download PlayBASIC V1.65C2 Beta12 (https://www.underwaredesign.com/forums/index.php?topic=1150.msg29766#msg29766)[/plink] 17th,Dec,2018)
PlayBASIC V1.65C2 BETA #14 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (5th March,2020)
V1.65C2 Beta #14 is the current build of the compiler and runtimes. Mostly small bug and tweak fixes as far as i can tell
Anyway, have fun..
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
[plink] Download PlayBASIC V1.65C2 Beta14 (https://www.underwaredesign.com/forums/index.php?topic=1150.msg29956#msg29956)[/plink] 5th,March,2020)
PlayBASIC Live - Finding RunTime Bug in 165C2 (16th June 2020) While developing a simple video animation tool to do privacy masking / blurring I ran into a weird runtime bug in PlayBASIC V1.65C2 and decided to make a video about it...
Did we find the bug ?? (Spoiler yes, but it wasn't what i expected.. never is )
Video:
Credits:
Video By:
Kevin Picone
http://PlayBASIC.com
https://Underwaredesign.com
Video Cast:
Sox and Sophie
Ava and Kevin Picone
Music:
Spirit of Fire by Jesse Gallagher
PlayBASIC LIVE PLAYLIST
https://www.youtube.com/playlist?list=PL_dvm0gvzzIVGlAhx34N6z2ce0ffMMOZ8
PlayBASIC BLOG PLAYLIST
https://www.youtube.com/playlist?list=PL_dvm0gvzzIU0Hnr6veV5UvwkSapHCo1J
PlayBASIC on FACEBOOK
http://www.facebook.com/pages/PlayBasic/127905400584274 (Facebook Page)
PlayBASIC on TWITTER
https://twitter.com/PlayBasic
#playbasic #debugging #sourcecode
PlayBASIC V1.65C2 - Beta 15 - expanding IF expression support to include strings / arrays
I've ran into a few runtime stopping issues this last week, starting some missing error trapping or execution support in CMPBNE instructions of the runtime. The CMP Branch not equal opcodes and the byte code behind such user statements as IF statements. Somewhere around the 1.65 rebuild the compiler parsing and byte code generation trimmed out some of screening logic that would trap the acceptable input parameters for the opcode. Hence there's nothing to trap expressions like IF A$ Then , even though that might be a valid thing to do...
So i've build in support for strings in IF expressions. This acts as way to detect if the string is empty. Internally what happens is the parser inserts a LEN() operation then compares if the length is none zero.
[pbcode]
gosub State
a$=""
gosub State
a$+="A"
gosub State
sync
waitkey
end
State:
if a$
print "a$ is Defined"
else
print "a$ is UNDefined (EMPTY/NULL STRING)"
endif
return
[/pbcode]
Might extend this to ARRAY HANDLES, so you could do something like IF Array() then Do stuff. This would wrap the handle with GetArrayStatus() call, but it's a little cleaner the programmer.
PlayBASIC V1.65C2 - Beta 15 - IF Array() supported and the NEW operator can create types from Indexs again
Just like the recent String support added to the IF expression which boils down to a compare not equal instruction in the runtime, this has been expanded to support Array handles (ie. If Array() then Do something) So you can check if an array has been allocated (Dimmed) just but going IF Array(), rather than typing IF GetarrayStatus(Array())
Now be aware that what actually happens is the compiler inserts the GetArrayStatus() function call around an Array() handles it sees. So it's a shortcut in typing only, performance wise it's the same speed as the long hand expression.
NEW
There was a bug uncovered in the code generation of the NEW operator. NEW allocates structure of TYPE, where you tell it the NAME of the TYPE. ie. NEW Alien. What of course happens is that Name is really an index into the type definition structure in the runtime. But what I suspect nobody knew is that you can use an Integer with NEW also, and it'll just assume that value of that integer is a valid Index into the internal definition table. But if you did that in V165 it'd break as the code generation was missed support for it. So that would parse but wpuld break at runtime.
[pbcode]
Type tPrivacyKeyFrames
frame
X#
y#
Size#
Image
EndType
Dim Mask(1000) as tPrivacyKeyFrames
// allocate a type of tPrivacyKeyFrames and write it's handle into index 1 of within the MASK array
Mask(1) = new tPrivacyKeyFrames
// Now let's do the same thing, from a variable
// Get the INDEX of a TYPE name
Index = tPrivacyKeyFrames + 0 ; (NOTE THE ADDITION)
Mask(2) = new INDEX
sync
waitkey
waitnokey
[/pbcode]
The original concept of allowing users to select the type from an index was only via an addition with the TYPE NAME. So you could select the child types of a parent type as they'd be sequentially stored in the type definition table, without worrying about makes mistakes with the indexes (Think about it ). A by product of allow this means you that providing you can complete the index of the TYPE NAME you want, you can use a variable for the type. You have to careful not to rearrange yur definitions though, but I you could compute them up front and store them in an array. and just pull the actually value from the array.
Thinking back on it now, it probably should have been wrapped into the INT() function. That is to say that INT() could compute the integer value of the type name and thus be used anywhere within reason. I'm sure we'd find a way to exploit it and create unwanted situations tho.. but isn't that fun ?
PlayBASIC V1.65C2 BETA #15 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (8th July,2020)
V1.65C2 Beta #15 is the current build of the compiler and runtimes. This includes parser updates to handle IF a$ expressions, IF ARRAY() and corrects the NEW operator.
Anyway, have fun..
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
[plink] Download PlayBASIC V1.65C2 Beta15 (https://www.underwaredesign.com/forums/index.php?topic=1150.msg29984#msg29984)[/plink] (8th,July,2020)
PlayBASIC V165C2 - Warning - Possible Memory Leak in debug mode
Not sure what's the cause here is, but would seem either UNDIM or DIM are leaking some handles here, as if you run in debug mode (F7) and watch the handle allocations it keeps raising each time the loop runs. I think it's caused from the updates make to DIM / UNDIM which try and cache buffers.. we'll see
[pbcode]
type tParams
Name$
Value$
EndType
makearray p().tParams
for lp =0 to 100
count=100
dim p(count) as tParams
for testlp=0 to count
p(testlp) = new tParams
p(testlp).Name$ ="Name"+str$(z)
p(testlp).value$ ="Value"+str$(z)
z++
next
handle = GetHandle(p())
print handle
deletearray p()
p() = handle
#break
undim p()
next
print z
sync
waitkey
function GetHandle(p() as tParams)
EndFunction p() as tParams
[/pbcode]
Another way of doing this is to use a 'text' heap and store the types in a chunk of memory with links between the cells or just in a global string array. Which I think should be OK in V165.. but haven't done the analysis to back that up as yet...
UNDIM doesn't support types or lists
Ok, well there's nothing like opening up the runtime and discovering this... Apparently UNDIM only supports INTEGERS / FLOATS AND STRINGS, TYPES and LISTS aren't supported at all .. Hence the memory leaks.. Funny that :)
UNDIM restored in build 16
This turned out to be just some missing support in UNDIM, Also added support to clean up any associated linked lists within type variables. There does seem to be a leak if you DIM in a loop though. But I suspect it's just not calling clean up the old buffer if it exists. Ideally it should try and manage / buffer those allocations to avoid some memory thrashing, which is what was partly implemented into the DIM revisions way back in 2016, but the fate stepped in..
[pbcode]
type tParams
Name$
Value$
EndType
// Test lists
for tests=0 to 100
cls
Dim L as tParams List
for lp=0 to 10
L = new tParams
l.Name ="Hello"+Str$(lp)
l.Value ="World"+Str$(lp)
next
for each l()
print l.Name+" "+l.value
next
sync
// remove to the see the leak in the debug mode
undim l()
#break
next
waitkey
[/pbcode]
PlayBASIC V1.65C2 BETA #20 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (17th March,2021)
V1.65C2 Beta #20 is the current build of the compiler and runtimes. This build includes some compiler WARNINGS for programs that use Optexpressions in particular mode 2 which is type caching. Type caching isn't supported in V1.65 for the time being, and if it's enabled can break programs hence the warning. Disabling it makes big programs I'd been testing ran again.
Other fixes relate to the fonts library when using classic bitmap fonts.
Anyway, have fun..
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
[plink] Download PlayBASIC V1.65C2 Beta20 (https://www.underwaredesign.com/forums/index.php?topic=1150.msg30213#msg30213)[/plink] 17th,MArch,2021)
(http://www.underwaredesign.com/PlayBasicSig.png)
PlayBASIC V1.65C2 _Retail Upgrade_ Now Available (10th, July, 2021)
This release updates any version from PlayBASIC
V1.63w2 (http://www.underwaredesign.com/forums/index.php?topic=1182.msg16703#msg16703) to PlayBASIC V1.65C (retail) to the current retail version of
PlayBASIC V1.65C2. If your current version is
older than PB1.63W (pre June/July 1997), then you may need to install patch
PB1.63w2 prior to this one ! if you haven't already, otherwise there's no need.
The
PlayBASIC V1.65C package includes updates of PlayBASIC Compiler, Release / Debug Runtimes, SLIBS, DOCS & IDE V1.17b.
Reminder: The new runtime doesn't support reading from types that don't exist, which can cause old programs to fail from time to time.. For a full V1.65C development story read the PlayBASIC V1.65 blogs here (http://www.underwaredesign.com/forums/index.php?topic=4333.0) and for V1.65 related errors, post them in the [plink]V1.65 bug reporting thread (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Don't have a retail version of PlayBASIC ? and want to find out more information about PlayBASIC programming > please visit the www.PlayBasic.com (http://www.playbasic.com) and download the free learning edition.
Downloads
[plink] Download PlayBASIC V1.65C2 Retail Upgrade (https://www.underwaredesign.com/forums/index.php?topic=1182.msg30292#msg30292)[/plink] (10th,July,2021) (No download managers!)
(http://www.underwaredesign.com/PlayBasicSig.png)
PlayBASIC V1.65C2b _Retail Upgrade_ Now Available (12th, Sep, 2021)
This release updates any version from PlayBASIC
V1.63w2 (http://www.underwaredesign.com/forums/index.php?topic=1182.msg16703#msg16703) to PlayBASIC V1.65C (retail) to the current retail version of
PlayBASIC V1.65C2b. If your current version is
older than PB1.63W (pre June/July 1997), then you may need to install patch
PB1.63w2 prior to this one ! if you haven't already, otherwise there's no need.
The
PlayBASIC V1.65C2b package includes updates of PlayBASIC Compiler, Release / Debug Runtimes, SLIBS, DOCS & IDE V1.17b.
Reminder: The new runtime doesn't support reading from types that don't exist, which can cause old programs to fail from time to time.. For a full V1.65C development story read the PlayBASIC V1.65 blogs here (http://www.underwaredesign.com/forums/index.php?topic=4333.0) and for V1.65 related errors, post them in the [plink]V1.65 bug reporting thread (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Don't have a retail version of PlayBASIC ? and want to find out more information about PlayBASIC programming > please visit the www.PlayBasic.com (http://www.playbasic.com) and download the free learning edition.
Downloads
[plink] Download PlayBASIC V1.65C2b Retail Upgrade (https://www.underwaredesign.com/forums/index.php?topic=1182.msg30366#msg30366)[/plink] (12th,Sep,2021) (No download managers!)
PlayBASIC V1.65D - Bug fixes and some more simple Vector operations built in.
Fired up the dev box for the first time in month or so to be reminded of the last WIP update that was started months ago wasn't running. Apparently I couldn't recall how to add command to PB's internal command set.. Which is way too complicated due to excessive hackie-ness of the various changes that have been to that stuff over the past 15 years... Yeah it's really time for a rewrite all that...
None the less there's an internal Lenght2D / Length3D and Dot Product 3D in place at the moment.
While on the subject of Vectors, I think if 2D/3D vector types were built in, the parameter matching could would with legacy commands.. So rather than PositionSprite Index,X#,y# you could PositionSprite Index, PositionVector2D where the position vector 2d variable is a typed structure that you've been working with in other calcs.. The caller would unwrap the parameters, but would save some boiler plate.
so PositionSprite Index, PositionVector2D
PositionSprite Index, PositionVector2D.X, , PositionVector2D.Y
PositionSprite Index, PositionVector2D
PlayBASIC V1.65C3 - Beta 2 - Faster Math operations (some)
The math operations are a mixture of libraries and code boiled into the legacy runtime.. Trying to tweak this today is a little more mind bending than I'd expected.. but we're making some progress..
Changes thus far are to the GetDistance2D / GetDistance3D / Point In Box functions.. Which have been replaced with a more stream lined versions. Which just means it calls the pattern directly. Performance wise there's from 20% up to 50% faster. It was possible before (1.65 editions) to roll your own distance function that could out perform the built in function. Which pre 1.65 was unthinkable, but all those real basic operations are now are about as lean and mean as can be (until I have another brain wave :) ) meaning rolling your own could be better.. But not anymore.
PlayBASIC V1.65C3 - Beta 3 - A few more Faster Math operations (some)
Replaced the point in circle and circles intersect which should be overlap, since it doesn't output the intersection points.. but moving along :)
See: CirclesIntersect (https://playbasic.com/help.php?page=MATH.CIRCLESINTERSECT)
See: PointIntersectCircle (https://playbasic.com/help.php?page=MATH.POINTINTERSECTCIRCLE)
PlayBASIC V1.65C3 BETA #4 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (31st July,2022) V1.65C3
Beta #4 is the current build of the
compiler and
runtimes. This build fixes the screen mode start up bug and includes the getLenght2D GetLenght3D DotProduct3D and some replacements of classic math intersection functions..
Anyway, have fun..
Download
[plink] Download PlayBASIC V1.65C3 Beta 4 (https://www.underwaredesign.com/forums/index.php?topic=1150.msg30770#msg30770)[/plink] 31st,July,2021)
PlayBASIC Live
Learn To Code @ PlayBASIC Home Page
https://playbasic.com/ (https://playbasic.com/)
PlayBASIC manual - PlayBASIC Documentation - PlayBASIC Help
https://playbasic.com/help.php (https://playbasic.com/help.php)
Vector Test Benchmark
[pbcode]
; PROJECT : 2D vector functions Benchmarks
; AUTHOR : PlayBASIC Tutor
; CREATED : 1/01/2003
; EDITED : 31/07/2022
; ---------------------------------------------------------------------
constant TestNewVectors = false
cls 0
print "Waiting Vector Functions"
sync
For lp=0 to 5
sync
wait 500
next
Dim TestArrayInt(1000)
Dim TestArrayFloat#(1000)
Dim Results#(100)
TestStart=Timer()
MaxTests=20000
Repeat
Cls 0
frames=frames+1
Test=0
Print "Displaying Average Times for "
;+str$(Maxtests)+" Tests"
Print "Current Frame:"+Str$(frames)
x#=50
y#=100
z#=200
temp=0
ts=Timer()
For i = 0 To MaxTests
result# = sqrt(x#*x# + y#*y#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "Compute Lenght2D:"+Str$(results#(test)/frames)+" Result="+str$( result#)
test=test+1
#if TestNewVectors = true
ts=Timer()
For i = 0 To MaxTests
result# = getlenght2d(x#,y#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " GetLenght2D:"+Str$(results#(test)/frames)+" Result="+str$( result#)
test=test+1
#endif
; -------------- [3D ] ---------------------------------------------------
ts=Timer()
For i = 0 To MaxTests
result# = sqrt(x#*x# + y#*y# + z#*z#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "Compute Lenght3D:"+Str$(results#(test)/frames)+" Result="+str$( result#)
test=test+1
#if TestNewVectors = true
ts=Timer()
For i = 0 To MaxTests
result# = getlenght3d(x#,y#,z#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " GetLenght3D:"+Str$(results#(test)/frames)+" Result="+str$( result#)
test=test+1
#endif
x1#=100
y1#=100
z1#=100
x2#= x1#*2
y2#= y1#*2
z2#= z1#*2
ts=Timer()
For i = 0 To MaxTests
dx#=x2#-x1#
dy#=y2#-y1#
dz#=z2#-z1#
result# = sqrt(dx#*dx# + dy#*dy# + dz#*dz#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "Compute GetDistance3D:"+Str$(results#(test)/frames)+" Result="+str$( result#)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result# = getDistance3d(x1#,y1#,z1#,x2#,y2#,z2#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " GetDistance3D:"+Str$(results#(test)/frames)+" Result="+str$( result#)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result = PointInBox(200,200,1000,1000,50,50)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " POintInBox:"+Str$(results#(test)/frames)
test=test+1
x1#=100
y1#=100
z1#=10
x2#=150
y2#=150
z2#=100
ts=Timer()
For i = 0 To MaxTests
dx#=(x1#-x2#)
dy#=(y1#-y2#)
Radius#=z1#+z2#
result= Abs((dx#*dx#)+(dy#*dy#))<(radius#*radius#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "Comnpute CirclesIntersect:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result = CirclesIntersect(x1#,y1#,z1#,x2#,y2#,z2#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " CirclesIntersect:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
dx#=(x1#-x2#)
dy#=(y1#-y2#)
result= Abs((dx#*dx#)+(dy#*dy#))<(z2#*z2#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "Comnpute POintInCirc;e:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
result = POintIntersectCircle(x1#,y1#,x2#,y2#,z2#)
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print " PointInCircle:"+Str$(results#(test)/frames)
test=test+1
Sync
Until Frames>200
Print "Test Complete"
testEnd=Timer()-TestSTart
Print "Seconds:"+Str$((Timer()-TestStart)/1000.0)
Sync
WaitKey
Waitnokey
[/pbcode]
PlayBASIC V1.65C3 BETA 5 - Concatenating Strings
Updated the PlayBASIC string engine tonight to better balance the load when strings get really large. This test originally took 20 odd seconds to build a 100 million character string, character by character.. while this update does it in about 2 seconds..
You're welcome ! :)
[pbcode]
max= 1000*1000*100
t=timer()
for lp =1 to max
result$=result$+"*"
next
print timer()-t
print len(result$)
// Time MAKE$() :)
t=timer()
REsult2$=Make$("*",max)
print timer()-t
print len(result2$)
print "CompareState:"+Str$(Result$=REsult2$)
sync
waitkey
[/pbcode]
PlayBASIC V1.65C3 BETA #5b (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (3rd May,2023)
V1.65C3 Beta #5 is the current build of the compiler . - This will report that it's Beta 4 also.. Just ignore that!
This build corrects OpenScreen / GetScreenTitle/ ScreenTitle (http://playbasic.com/help.php?page=SCREEN.INDEX) so they preserve the title regardless of the window mode. Previously the Screen Title functions would only work in windowed mode. Now they just store the title string and only set the window title if there's a window to set.
[pbcode]
TitleScreen "This is my screen title"
openscreen 800,200,32,1
sync
wait 1000
openscreen 500,500,32,1
sync
waitkey
[/pbcode]
This build also includes some optimization to the string engine when concatenating large strings. Smaller strings shouldn't be impacted by the change, it just expands the target string more aggressively when a larger amount is needed.
[pbcode]
Size=1000*1000
t=timer()
for lp=1 to Size
Result$=Result$+"*"
next
print "Ticks:"+str$(Timer()-t)
print Len(Result$)
print ""
// COmpare it to Make$()
t=timer()
Result2$=Make$("*",Size)
print "Ticks:"+Str$(Timer()-t)
print Len(Result2$)
print ""
// Compare them
t=timer()
State=result$=Result2$
print "Ticks:"+Str$(Timer()-t)
print State
print ""
Sync
waitkey
[/pbcode]
Anyway, have fun..
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
[plink] Take me to Download PlayBASIC V1.65C3 Beta 5b (https://www.underwaredesign.com/forums/index.php?topic=1150.msg31181#msg31181)[/plink] (3rd,May,2023) This build will report as Beta 4..
PlayBASIC Blog - Array Functions Find Array Cell Palette Mapping Test In this blog i'm using some palette mapping code to looking the performance of the general Array Functions in PlayBASIC V1.65; namely the performance of the FindArrayCell function when doing brute force searches.. Which is ok; but I feel could be a lot better.
Help Files: - Array Functions In PlayBASIC (https://playbasic.com/help.php?page=ARRAYS.INDEX)
PlayBASIC V1.65C3 - Beta 6 - Faster Numeric Comparisons After setting up a real standing desk for the PB dev box I was sifting through the layout of the current instruction sets; looking for ways to help the runtime win back some performance without having to jump in and re-write heaps of stuff. I generally don't like to do that as one you open the can of worms it can be hard to put the genie back in bottle.. Something keep bothering me though, numeric comparisons, surely they can blocked with the other low level simple integer and floating point operations; so that's what I set out to do..
Here's the rough results
Pb165C3 - Beta #6 = 8.9 seconds
Pb165C3 - Beta #5 = 20 seconds
Pb164P4 - Retail = 32 seconds
Pb164L - Learning Edition = 67 seconds
Set screenshots bellow..
PlayBASIC DevBlog - Faster Numeric Comparisons PlayBASIC Source Code [pbcode]
; PROJECT : Comparison_Bench_Mark
; AUTHOR : uwdesign
; CREATED : 26/04/2004
; EDITED : 27/07/2023
cls 0
print "Compares Waiting"
sync
For lp=0 to 5;
wait 1000
next
Dim Results#(100)
TestStart=Timer()
MaxTests=100000
Repeat
Cls 0
frames=frames+1
Test=0
Print "Displaying Average Times for "
;+str$(Maxtests)+" Tests"
Print "Current Frame:"+Str$(frames)
temp=0
ts=Timer()
For i = 0 To MaxTests
temp=A=B
temp=A=B
temp=A=B
temp=A=B
temp=A=B
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: = : INT=INT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A=B#
temp=A=B#
temp=A=B#
temp=A=B#
temp=A=B#
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: = : INT=FLT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A#=B
temp=A#=B
temp=A#=B
temp=A#=B
temp=A#=B
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: = : FLT=INT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A#=B#
temp=A#=B#
temp=A#=B#
temp=A#=B#
temp=A#=B#
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: = : FLT=FLT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A<>B
temp=A<>B
temp=A<>B
temp=A<>B
temp=A<>B
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: <> : INT=INT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A<>B#
temp=A<>B#
temp=A<>B#
temp=A<>B#
temp=A<>B#
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: <> : INT=FLT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A#<>B
temp=A#<>B
temp=A#<>B
temp=A#<>B
temp=A#<>B
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: <> : FLT=INT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A#<>B#
temp=A#<>B#
temp=A#<>B#
temp=A#<>B#
temp=A#<>B#
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: <> : FLT=FLT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A>B
temp=A>B
temp=A>B
temp=A>B
temp=A>B
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: > : INT=INT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A>B#
temp=A>B#
temp=A>B#
temp=A>B#
temp=A>B#
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: > : INT=FLT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A#>B
temp=A#>B
temp=A#>B
temp=A#>B
temp=A#>B
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: > : FLT=INT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A#>B#
temp=A#>B#
temp=A#>B#
temp=A#>B#
temp=A#>B#
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: > : FLT=FLT:"+Str$(results#(test)/frames)
test=test+1
// ---------- >=
ts=Timer()
For i = 0 To MaxTests
temp=A>=B
temp=A>=B
temp=A>=B
temp=A>=B
temp=A>=B
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: >= : INT=INT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A>=B#
temp=A>=B#
temp=A>=B#
temp=A>=B#
temp=A>=B#
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: >= : INT=FLT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A#>=B
temp=A#>=B
temp=A#>=B
temp=A#>=B
temp=A#>=B
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: >= : FLT=INT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A#>=B#
temp=A#>=B#
temp=A#>=B#
temp=A#>=B#
temp=A#>=B#
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: >= : FLT=FLT:"+Str$(results#(test)/frames)
test=test+1
// ----------------------------- < less than
ts=Timer()
For i = 0 To MaxTests
temp=A<B
temp=A<B
temp=A<B
temp=A<B
temp=A<B
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: < : INT=INT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A<B#
temp=A<B#
temp=A<B#
temp=A<B#
temp=A<B#
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: < : INT=FLT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A#<B
temp=A#<B
temp=A#<B
temp=A#<B
temp=A#<B
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: < : FLT=INT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A#<B#
temp=A#<B#
temp=A#<B#
temp=A#<B#
temp=A#<B#
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: < : FLT=FLT:"+Str$(results#(test)/frames)
test=test+1
// ----------------------------- <= less than EQUALZ
ts=Timer()
For i = 0 To MaxTests
temp=A<=B
temp=A<=B
temp=A<=B
temp=A<=B
temp=A<=B
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: <= : INT=INT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A<=B#
temp=A<=B#
temp=A<=B#
temp=A<=B#
temp=A<=B#
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: <= : INT=FLT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A#<=B
temp=A#<=B
temp=A#<=B
temp=A#<=B
temp=A#<=B
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: <= : FLT=INT:"+Str$(results#(test)/frames)
test=test+1
ts=Timer()
For i = 0 To MaxTests
temp=A#<=B#
temp=A#<=B#
temp=A#<=B#
temp=A#<=B#
temp=A#<=B#
Next i
t=Timer()-ts
Results#(test)=results#(test)+t
Print "For Next: <= : FLT=FLT:"+Str$(results#(test)/frames)
test=test+1
Sync
Until Frames>200
Print "Test Complete"
testEnd=Timer()-TestSTart
Print "Seconds:"+Str$((Timer()-TestStart)/1000.0)
Sync
WaitKey
Waitnokey
[/pbcode]
It's important to note that this is a specialized test; for this to have real impacts on your code you'll need to be doing a lot of comparisons.
One example where this shines through are things like PlayBASIC Vector Blast Processing (2023-06-23) (https://www.underwaredesign.com/forums/index.php?topic=4738.0) which runs about 4->5 fps faster in beta 6 on my test machine.
Download PlayBASIC V1.65C3 - Beta 6 [plink] Download PlayBASIC V1.65C3 Beta 6 (https://www.underwaredesign.com/forums/index.php?topic=1150.msg31234#msg31234) [/plink]
PlayBASIC V1.65C3 BETA #7 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (27th Sep , 2023)
V1.65C3 Beta #7 is the current build of the compiler . This also includes a build of the Runtimes
Build 7 fixes the SIGN bug for floats where it would do conversion of the float to integer which would round it.. Normally this isn't a problem, but it is for values near zero. That logic has been replaced now. So if you pass an Integer it performs the comparison on Integers and if you pass a float it occurs on the Floats.. (bug found by Stevmjon)
[pbcode]
; Older versions of V1.65 will give odd results in this code
a# = -1.9
b# = 0
c# = 1.9
print "value -1.9 = sign: " + str$( sgn(a#) )
print "value 0 = sign: " + str$( sgn(b#) )
print "value 1.9 = sign: " + str$( sgn(c#) )
print ""
a# = -0.9
b# = 0
c# = 0.9
r=sgn2(a#)
print "value -0.9 = sign: " + str$( r )
r=sgn2(b#)
print "value 0 = sign: " + str$( r )
r=sgn2(c#)
print "value 0.9 = sign: " + str$( r )
print ""
a# = -0.9
b# = 0
c# = 0.9
print "value -0.9 = sign: " + str$( sgn(a#) )
print "value 0 = sign: " + str$( sgn(b#) )
print "value 0.9 = sign: " + str$( sgn(c#) )
sync : flushkeys : waitkey
function sgn2(v#)
Result=(V#>0) - (V#<0)
endfunction result
[/pbcode]
Anyway, have fun..
See->> [plink]Read V1.65 Update Work In Progress gallery (https://www.underwaredesign.com/forums/index.php?topic=4333.0)[/plink] for some info on what's changed.. Lots and lots of STUFF.
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
[plink] Download PlayBASIC V1.65C3 Beta 7 (https://www.underwaredesign.com/forums/index.php?topic=1150.msg31273#msg31273)[/plink] (27th,Sep,2023)
PlayBASIC V1.65C3 BETA #8b (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (29th Sep , 2023)
V1.65C3 Beta #8b is the current build of the compiler .
Build 8 replace the implementation of the RoundUp and RoundDown functions. I honestly don't know how these were originally intended to work as there's little to no definition of them.. So these changes will no doubt break old programs that use the original behavior; so careful what you wish ! :)
[pbcode]
openscreen 1000,1000,32,1
loadfont "courier new" ,1 ,24
spacing = 150
text xpos ,ypos,"Value:"
text xpos+spacing*1 ,ypos,"RoundDown()"
text xpos+spacing*2 ,ypos,"RoundDown2()"
text xpos+spacing*3 ,ypos,"RoundUp()"
text xpos+spacing*4 ,ypos,"RoundUp2()"
text xpos+spacing*5 ,ypos,"Floor()"
text xpos+spacing*6 ,ypos,"Ciel()"
ypos+=30
for lp =-20 to 20
Value#=lp/10.0
text xpos ,ypos,Value#
text xpos+spacing*1 ,ypos,RoundDown(Value# )
text xpos+spacing*2 ,ypos,RoundDown2(Value# )
text xpos+spacing*3 ,ypos,Roundup(Value# )
text xpos+spacing*4 ,ypos,Roundup2(Value# )
text xpos+spacing*5 ,ypos,Floor(Value# )
text xpos+spacing*6 ,ypos,Ceil(Value# )
ypos+=20
next
sync
waitkey
function RoundDOWN2(ThisVALUE#)
if (ThisVALUE#>=0)
Result= ThisVALUE# - 0.5
else
Result= ThisVALUE# + 0.5
endif
EndFunction Result
function RoundUp2(ThisVALUE#)
if (ThisVALUE#>=0)
Result= ThisVALUE# + 0.5
else
Result= ThisVALUE# - 0.5
endif
EndFunction Result
[/pbcode]
Build 8 is also using the latest update the memory manager at runtime. These changes were moved across from recent compiler work so that that front and back end can use the same mechanics.. They've only been in place for a day but seem to be running as expected. Some other tweaks can be found in the debugger with the Stack info as well as stack overflow detection is a bit better also. Previously if your code overflowed the runtime stack; the runtime would hang.. now if your lucky you might get an error. It'll try and give you a line number; but generally those errors will only get caught as at sync or runtime refresh. The later occurs when a program executes more than 6 million instructions and needs to check system messages.
Anyway, have fun..
Download
[plink] Download PlayBASIC V1.65C3 Beta 8b (https://www.underwaredesign.com/forums/index.php?topic=1150.msg31277#msg31277)[/plink] (29th,Sep,2023)
PlayBASIC V1.65C3 BETA #9 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY) (3rd Oct, 2023)
Build 9 restores RoundUp and RoundDown functions to make that of V1.64 revisions. The newer versions are still available just renamed as RoundUp2 and RoundDown2
A few other functions are available also; such as Poke2Bytes / Poke3Bytes / Poke4Bytes and a few that appear to be undocumented commands. One handy one seems to the RgbFLT(R#,G#,B#) which is a floating point version of the RGB() function. In this version the R#/G#/B# fields should range between 0.0 and 1.0
The runtime has a few more tweaks with the internally bound command sets... I want to remove that block of instructions form the runtime; But i've more work to do with that; some of those instructions also had a few legacy hooks into the how the older VM stored programs.. which was a bit of worry; but I think they weren't in use; so this step shouldn't really break anything.
[pbcode]
openscreen 1200,1100,32,1
loadfont "courier new" ,1 ,24,0,8
Test_Rounding()
Test_PokeBytes()
function Test_Rounding()
spacing = 180
th=gettextheight("|")+1
ScrollY#=0
do
cls
Ypos=ScrollY#
lockbuffer
if ypos+th>0
text xpos ,Ypos,"Value:"
text xpos+spacing*1 ,Ypos,"RoundDown()"
text xpos+spacing*2 ,Ypos,"RoundDown164()"
text xpos+spacing*3 ,Ypos,"RoundUp()"
text xpos+spacing*4 ,Ypos,"RoundUp164()"
text xpos+spacing*5 ,Ypos,"Floor()"
text xpos+spacing*6 ,Ypos,"Ciel()"
endif
ypos+=(th*1.5)
for lp =-20 to 20
if (Ypos+th<0) or Ypos>GetScreenHeight()
Ypos+=th
continue
endif
if (lp/10)*10=lp
Boxc 0,ypos,GetSurfaceWidth(),Ypos+th,true,$334455
endif
Value#=lp/10.0
ink -1
text xpos ,ypos,Value#
Same = RoundDown(Value# )=RoundDown164(Value# )
ink -1
if Same=true then ink $00ffff00
text xpos+spacing*1 ,ypos,RoundDown(Value# )
text xpos+spacing*2 ,ypos,RoundDown164(Value# )
ink -1
Same = RoundUp(Value#) = RoundUp164(Value# )
ink -1
if Same=true
ink $00ff00ff
endif
text xpos+spacing*3 ,ypos,Roundup(Value# )
text xpos+spacing*4 ,ypos,Roundup164(Value# )
ink -1
text xpos+spacing*5 ,ypos,Floor(Value# )
text xpos+spacing*6 ,ypos,Ceil(Value# )
ypos+=th
next
unlockbuffer
Final_YPOS = YPOS - ScrollY#
mz#=mousemovez()
ScrollSpeed#+= (mz#*th)
ScrollY#+=ScrollSpeed#
ScrollY#=ClipRange#(ScrollY#,-Final_YPOS,0)
ScrollSpeed#=curvevalue(0,ScrollSpeed#,5)
sync
loop Spacekey()
flushkeys
EndFunction
// Functions that emulate behavior of 1.64
function RoundDown164(ThisVALUE#)
intResult=(ThisVALUE# - 0.5)
Result#=IntResult
EndFunction Result#
function RoundUp164(ThisVALUE#)
intResult=(ThisVALUE# + 0.5)
Result#=IntResult
EndFunction Result#
// Functions that emulate behavior of 1.65 beta 9
function _RoundDOWN2(ThisVALUE#)
if (ThisVALUE#>=0)
Result= ThisVALUE# - 0.5
else
Result= ThisVALUE# + 0.5
endif
EndFunction Result
function _RoundUp2(ThisVALUE#)
if (ThisVALUE#>=0)
Result= ThisVALUE# + 0.5
else
Result= ThisVALUE# - 0.5
endif
EndFunction Result
Function Test_PokeBytes()
Do
Cls
mx#=mousex()
my#=mousey()
ThisRGB =RgbFLT(mx#/GetScreenWidth(),0,my#/getscreenHeight())
lockbuffer
boxc 100,100,400,400,true,ThisRGB
_POkeBytes()
text 100,100,mz#
unlockbuffer
Sync
loop spacekey()
flushkeys
EndFunction
Function _POkeBytes()
Static Bank
Max = 10000
if Bank=0
Bank = NewBank(max)
endif
Ptr = GetBankPtr(Bank)
POkeByte Ptr ,100
POkeByte Ptr+1 ,101
POkeByte Ptr+2 ,102
POkeByte Ptr+3 ,103
print Get4Bytes$(Ptr)
POke2Bytes Ptr ,200,201
POke2Bytes Ptr+2 ,202,203
print Get4Bytes$(Ptr)
POke3Bytes Ptr ,30,31,32
POkeByte Ptr+3 ,33
print Get4Bytes$(Ptr)
POke4Bytes Ptr ,40,41,42,43
print Get4Bytes$(Ptr)
EndFunction
Function Get4Bytes$(Ptr)
s$ =Str$(PeekByte(Ptr) )+","
s$+=Str$(PeekByte(Ptr+1) )+","
s$+=Str$(PeekByte(Ptr+2) )+","
s$+=Str$(PeekByte(Ptr+3) )
ENdFunction s$
[/pbcode]
Anyway, have fun..
Bug Reporting
See->> [plink]PlayBASIC V1.65 Bug Reports (http://www.underwaredesign.com/forums/index.php?topic=4350.0)[/plink].
Download
[plink] Download PlayBASIC V1.65C3 Beta 9 (https://www.underwaredesign.com/forums/index.php?topic=1150.msg31282#msg31282)[/plink] (3rd,Oct,2023)