|
kevin
|
 |
« on: September 08, 2008, 12:13:35 PM » |
|
PlayBasicFX VM2 translation WIP/BLOG This thread is mainly for me so I can keep track of what is functional and what changes have needed to be made during to the translation from the VM1 to VM2 runtime. ON Goto ON GOTO is now in VM2, one change is the it only accepts Integer 'select' variables. However, you can still use a float, but it's recast for you. Sample. Setfps 30
Do Cls 0 a#=rnd(5) print a# on a# goto l0,l1,l2,l3 print "MISSED" goto Cont L0: print "label #0" goto Cont L1: print "label #1" goto Cont L2: print "label #2" goto Cont L3: print "label #3" goto Cont Cont: Sync waitkey loop
Loops - FOR/NEXT / REPEAT UNTIL / WHILE ENDWHILE & DO DECLOOP All variable loop structures are running on VM2 max=30000
Do cls 0 inc frames
t=timer() K=0 for lp=0 to max K=K+1 next t3#=t3#+(timer()-t) print k print "For loop:"+Str$(t3#/frames)
t=timer() K=0 while K<max K=K+1 endwhile t1#=t1#+(timer()-t) print k print "While Loop:"+Str$(t1#/frames) t=timer() K=0 repeat K=K+1 until K>=max t2#=t2#+(timer()-t) print k print "Repeat Loop:"+Str$(t2#/frames)
t=timer() lp=max k=0 do K=K+1 decloop lp t4#=t4#+(timer()-t) print k print "Dec Loop:"+Str$(t4#/frames)
sync loop
INC / DEC are inline Old INC/DEC opcodes are removed and recast as packed ADD/SUB opcodes. Do Cls 0
a=0 b#=0 c=0 d#=0 For lp=0 to 1000 inc a inc B# dec c dec d#
next print a print B# print c print D#
sync
loop
|
|
|
|
« Last Edit: September 08, 2008, 01:04:24 PM by kevin »
|
Logged
|
|
|
|
|
kevin
|
 |
« Reply #1 on: September 09, 2008, 08:08:53 AM » |
|
Strings Started moving/reworking the base string operations code to Vm2.
a$="yeah" b$="dude" print a$ For lp =0 to 10 print "Hello"+Str$(lp) print left$("Hello"+Str$(lp),2) next test("Local String") Sync Waitkey
Function test(LocalString$) print LocalString$ EndFunction
String Addition Updated the String Addition opcodes, it's following loop is now pure VM2. The string addition test (1 meg long string) runs about 5 milliseconds faster than 1.64. Running on average in 12.7 milliseconds...  . a$="hello World"
max=99000
Do cls 0 inc frames c$="" t=timer() For lp=0 to max c$=c$+a$ next tt#=tt#+(timer()-t) print len(c$) print left$(c$,1024) print tt#/frames Sync
loop
String Compares This$="Aaa" That$="Bbb" print "Strings Equal:"+Str$(This$=This$) print "Strings Equal:"+Str$(This$=That$) print "Strings Not Equal:"+Str$(This$<>That$) print "Strings Less Than:"+Str$(This$<That$) print "Strings Greater Than:"+Str$(This$>That$) print "Strings Less Than Equal:"+Str$(This$<=That$) print "Strings Greater Than Equal:"+Str$(This$>=That$) Sync waitkey
Changed the opcode structure a little (smaller) and when the test loop are running purely on Vm2 all the string compare methods are about 2->4ms faster over a 100,000 iterations. When comparing 41 chr strings. This$="BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB1" That$="BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB2"
max=100000
Do cls 0 inc frames t=timer() For lp=0 to max result=This$=That$ next t1#=t1#+(timer()-t) print "Equals:"+Str$(t1#/frames)
t=timer() For lp=0 to max result=This$<>That$ next t2#=t2#+(timer()-t) print "Not Equals:"+Str$(t2#/frames)
t=timer() For lp=0 to max result=This$<That$ next t3#=t3#+(timer()-t) print "Less Than:"+Str$(t3#/frames)
t=timer() For lp=0 to max result=This$>That$ next t4#=t4#+(timer()-t) print "Greater Than:"+Str$(t4#/frames)
t=timer() For lp=0 to max result=This$<=That$ next t5#=t5#+(timer()-t) print "Less Than Equals:"+Str$(t5#/frames)
t=timer() For lp=0 to max result=This$>=That$ next t6#=t6#+(timer()-t) print "Greater Than Equals:"+Str$(t4#/frames)
Sync
loop
|
|
|
|
« Last Edit: September 09, 2008, 11:54:00 AM by kevin »
|
Logged
|
|
|
|
|
kevin
|
 |
« Reply #2 on: September 11, 2008, 11:40:38 AM » |
|
Pointers The current beta has pointer operations hooked up. So while the following works, it's not purely running on VM2 in this edition. Bank=NewBank(1000) Dim Ptr as Byte Pointer print Bank
Ptr=GetBankPtr(Bank)
For lp=0 to 100 *ptr =lp print PeekBankByte(Bank,lp) print *ptr ptr=ptr+1 next Sync waitkey
and Type tviewport x1,y1,x2,y2 Endtype
Type Stuff state cool yeah x viewport as tviewport
Array(100) EndType
Dim me as Stuff pointer Me = new Stuff me.state=1 me.state=2
SetVP(Me.Viewport,100,100,200,200)
For lp=0 to 10 me.array(lp)=100+lp next
print int(me) print me.state Sync waitkey
Function SetVP(Vp as tviewport pointer,x1,y1,x2,y2) vp.x1=x1 vp.y1=y1 vp.x2=x2 vp.y2=y2
EndFunction
|
|
|
|
|
Logged
|
|
|
|
|
kevin
|
 |
« Reply #3 on: September 14, 2008, 01:00:59 AM » |
|
Vm2 Stack Moving/changing how the Stack works in the VM2. As such this means setting up various base controls again. Gosub/return Gosub is now running on Vm2, the new code doesn't support stack errors though. So under/overflow will crash the runtime. gosub SubRoutine print "done"
Sync waitkey end
SubRoutine: print "inside gosub" gosub SubRoutine2 gosub SubRoutine2 gosub SubRoutine2 gosub SubRoutine2 return
SubRoutine2: print "inside gosub #2" return
On Variable Gosub ON variable GOSUB is now in VM2. The select variable is now integer only (as per on variable goto), but floats are recast for you. Sample. Setfps 30
Do Cls 0 a#=rnd(10) print a# on a# gosub l0,l1,l2,l3 Sync waitkey loop
L0: print "label #0" gosub Hold return L1: print "label #1" gosub Hold return L2: print "label #2" gosub Hold return L3: print "label #3" gosub Hold return
Hold: Sync waitkey return
|
|
|
|
« Last Edit: September 14, 2008, 01:15:42 AM by kevin »
|
Logged
|
|
|
|
|
kevin
|
 |
« Reply #4 on: September 16, 2008, 11:46:32 AM » |
|
Scope / Stack Controls in VM2 The new stack behaviors in VM2 give it about a 40->50% speed increase in calling functions. It's also a little more logically firendly in regards to string thrashing also..
; gosub SubRoutine ; print "done"
RecFun(100,200,"Cool")
Test(50.78,123.456,200) Stuff() print "pointer" a= int(CalcTest(100,33.44)) print a Fun(45, 33.33, "hello") Fun(45, 33.33, "hello")
; push 1234567 ; print pop() Sync #break WaitKey end
Function Stuff() print "stuff"
EndFunction
Function Test(A,B#,C) print a print b# print c
EndFunction
Function CalcTest(A,B#) ; print a ; print b# result$="String Result"+str$(a+B#) Bank=NewBank(100) BankPtr= GetBankPtr(Bank) Ptr=GetBankPtr(Bank) ; print Bank ; print int(PTR)
endFUnction Ptr as pointer
Function Fun(a,b#,c$) print "FUNCTION BABY" #break print a ; print b# print c$
g#=45 Stuffs$="Yeah yeah" print Stuffs$ result=455 EndFunction
Function RecFun(a,b#,c$) print "Recusive FUNCTION" print a print b# print c$ Sync
g#=45 Stuffs$="Yeah yeah" print Stuffs$ result=455
#break
if a<200 RecFun(a*2,b#*2,c$+c$) endif
EndFunction
SubRoutine: print "inside gosub" gosub SubRoutine2 gosub SubRoutine2 gosub SubRoutine2 gosub SubRoutine2 return
SubRoutine2: print "inside gosub #2" return
This second example is just for benching the function/psub and sub routine calling mechanisms. I should point out that this code isn't running purely on VM2 just yet, so some bits are slower than they should due to the context switches (falling back to run old opcodes in VM1) But that's only temporary ! Tests=10000
Do cls 0 inc frames
// =================================== // USer Functions VS Projected Subroutines // ===================================
// ========== // Test #1 // ==========
T=timer() For LP=0 to Tests result=SomeFunctionCalc(10,lp) next tt1#=tt1#+(timer()-t) Print "Test #1 Average Time:"+Str$(tt1#/frames)
// ========== // Test #2 // ==========
T=timer() // Call the Psub function For LP=0 to Tests result=SomesubCalc(10,lp) next tt2#=tt2#+(timer()-t) Print "Test #2 Average Time:"+Str$(tt2#/frames)
T=timer() // Call the Psub function For LP=0 to Tests gosub MySub next tt3#=tt3#+(timer()-t) Print "Test #3 Sub Routine Calling:"+Str$(tt3#/frames)
Sync loop
Function SomeFunctionCalc(A,B)
A=A*B
l1=23 l2=23 l3=23 l4=23 l5=23 l6=23 l7=23 l8=23 l9=23
EndFunction A
Psub SomeSubCalc(A,B) A=A*B
l1=23 l2=23 l3=23 l4=23 l5=23 l6=23 l7=23 l8=23 l9=23
EndPsub A
MySub: return
|
|
|
|
« Last Edit: September 17, 2008, 03:22:20 PM by kevin »
|
Logged
|
|
|
|
|
kevin
|
 |
« Reply #5 on: September 17, 2008, 03:26:48 PM » |
|
Assignments / Basic Arrays in VM2 Today's revision now includes basic move operations on Vm2. These instructions currently only support simple variables & arrays. Speed wise they're about twice as fast (for integers & floats) as the quickest Vm1 edition (V1.64). Dim table(1000) Dim table#(1000)
address=GetArrayPtr(Table()) print address for lp=0 to 100 pokeint PBArrayStruct_size+address+(lp*4),lp next
for lp=0 to PBArrayStruct_size-1 step 4 print peekint(Address+lp) next
lp=10 print Table(lp) print hex$(Table(lp))
Table(lp)=45.23 print Table(lp) print hex$(Table(lp))
Sync Waitkey
max=50000 Do cls 0 inc frames Offset=(Offset+1) and 255
t=timer() For lp=0 to max Table(offset)=lp a=Table(offset) next T1#=t1#+(timer()-t) print t1#/frames
t=timer() For lp=0 to max Table#(offset)=lp a=Table#(offset) next T2#=t2#+(timer()-t) print t2#/frames
sync loop
|
|
|
|
« Last Edit: September 19, 2008, 01:27:36 PM by kevin »
|
Logged
|
|
|
|
|
kevin
|
 |
« Reply #6 on: September 19, 2008, 01:40:05 PM » |
|
User Defined Types/Structures Today's little task has been to expand upon the 'move' instruction set by adding support for UDT structures on Vm2. This allows for types to be nulled/freed on VM2 side. The following NULL type runs about 4->5 times faster than PB1.64. However, field accesses still fall back through vm1 ATM. Type Kev2 MyInteger MyFloat# MyString$ MyInteger2 MyFloat2# EndType
constant ArraySize=100 Type Kev MyInteger MyFloat# MyString$ IntegerArray(ArraySize) FloatArray(ArraySize) StringArray$(ArraySize) MyInteger2 MyFloat2# EndType
Dim me as kev
max=1000
Do cls 0 inc frames
me.MYinteger=45 me.MYFloat#=123.456 me.MYString$="Abccddeded" me.MYinteger2=10045 me.MYFloat2#=200123.456
For lp=0 to ArraySize me.Integerarray(lp)=30000+lp me.Floatarray(lp)=22222.45+lp me.stringarray$(lp)="yeah"+str$(lp) next
// Clear the fields to zero t=timer() For test=0 to max me.kev =null next t1#=t1#+(timer()-t) print t1#/frames Sync loop
|
|
|
|
« Last Edit: September 19, 2008, 02:08:52 PM by kevin »
|
Logged
|
|
|
|
|
kevin
|
 |
« Reply #7 on: September 20, 2008, 05:13:38 PM » |
|
Bound Function Calling Finally moved & updated the function calling opcodes to the Vm2 runtime. The new approach is a lot cleaner, which results is less man handling of data and thus faster call/return behaviors. Todays edition of the Vm2 can call the RGB() function 50000 times in 2.8/2.9 milliseconds. Compared to PB1.64 which takes 10.8/10.9 milliseconds, making Vm2 about 3 times faster. There will be difference depending upon the number of parameters etc. max=5000
Do cls 0 inc frames
// calling the rgb function t=timer() For test=0 to max ; unroll so were timing the function calling mainly result=rgb(r,g,b) result=rgb(r,g,b) result=rgb(r,g,b) result=rgb(r,g,b) result=rgb(r,g,b)
result=rgb(r,g,b) result=rgb(r,g,b) result=rgb(r,g,b) result=rgb(r,g,b) result=rgb(r,g,b) next t1#=t1#+(timer()-t) a#=t1#/frames print a#
// Calls per second print "Calls Per second:"+str$(int((1000.0/a#)*(max*10)))
Sync loop
|
|
|
|
« Last Edit: September 21, 2008, 10:12:28 AM by kevin »
|
Logged
|
|
|
|
|
kevin
|
 |
« Reply #8 on: September 21, 2008, 10:16:41 AM » |
|
Select /Case Somehow the select/case opcodes had been missed, so those have been tonights little focus. While the update it's not finished, Integer immediate selects are already some 3 times faster. SelectionValue=30
max=50000
Do cls 0 print "Select Value:"+str$(SelectionValue)
inc frames t=timer() For lp=0 to max Select SelectionValue case 10 R=10 case 20 R=20
case 30 R=30 EndSelect next t1#=t1#+(Timer()-t) print t1#/frames print "Result:"+Str$(r) print "done Select case"
Sync loop
Select /Case String$ All the operations are supported now. Bellow is a demo of string range case trapping. Vm2 can run this code a little over twice as fast as Vm1. max=50000
SelectionValue$="feef"
Do
Cls rgb(0,0,0) Print "Select Value:"+(SelectionValue$)
inc frames t=timer() For lp=0 to max Select SelectionValue$ case "aa" R=10 case "bb" R=20 case "cc" R=30 case "dd" to "zz" R=40 EndSelect next t1#=t1#+(Timer()-t) print t1#/frames print lp print "Result:"+Str$(r) print "Done Select case"
Sync loop
|
|
|
|
« Last Edit: September 21, 2008, 01:25:22 PM by kevin »
|
Logged
|
|
|
|
|
kevin
|
 |
« Reply #9 on: September 22, 2008, 01:59:22 PM » |
|
String Functions on Vm2 Tonight I've been working on the moving the built in string functions across. So far the only one that works is the "LEN" function. Only another 25 or so to go.. What fun  a$="abcdef" print len(a$) Sync waitkey
MID$() & Mid() a$="abcdef" print mid$(a$,2,3)
for lp=1 to len(a$) print mid(a$,lp) next Sync waitkey
LEFT$() & RIGHT$() a$="abcdef"
print Left$(a$,1) print Right$(a$,1) Sync waitkey
CutLeft$() & CutRight$() a$="abcdef"
print CutLeft$(a$,3) print CutRight$(a$,3) Sync waitkey
Trim$(), TrimLeft$(),TrimRight$() a$="<<<<<stuff>>>>>" print trim$(a$,"<>") print trimLEft$(a$,"<") print trimRight$(a$,">") Sync waitkey
Upper$(),lower$(),AutoCaps$() a$="aaaaaa" b$="BBBBBBBB" c$="hello world" print upper$(a$) print lower$(b$) print autocaps$(c$) Sync waitkey
CHR$() / bin$(), HEX$() For lp=32 to 40 print chr$(lp) print bin$(lp) print hex$(lp) next
Sync waitkey
ASC() a$="abcdefg" For lp=1 to len(a$) print asc(mid$(a$,lp,1)) print mid(a$,lp) next Sync waitkey
VAL() & VAL#() a$="123.456" print Val(a$) print Val#(a$)
Sync waitkey
STR$() a$="123.456" for lp=0 to 10 print "yeah"+str$(lp) print "yeah"+str$(float(lp)) next Sync waitkey
Replace$() a$="aaaaabbbbBBBBcdefg" print replace$(a$,"b","-",1,0,0) print replace$(a$,"b","-",1,0,true) print replace$(a$,"b","-",1,true,false) Sync waitkey
Instring() a$="aaaaabbbbBBBBcdefg"
print instring(a$,"B",1,false) print instring(a$,"B",1,true)
Sync waitkey
Make$(), insert$, Digits$(),Flip$(),pad$() a$="abc" print make$(a$,10) print pad$(a$,".",1) print flip$(a$) print Insert$(a$,"---",2) print digits$(12,6)
Sync waitkey
|
|
|
|
« Last Edit: September 26, 2008, 01:15:10 PM by kevin »
|
Logged
|
|
|
|
|
kevin
|
 |
« Reply #10 on: September 22, 2008, 04:13:00 PM » |
|
String Function Test I've now moved all the built in string functions across to VM2. The following is a fairly nasty stress test comparison between Vm2 (found in 1.73j) and Vm1 found in PB V1.64. The results are the same as other previous tests, with a good health (25->50%) performance boast when running through Vm2. The gain is mainly due to the faster loop processing though, as I haven't really changed the library. But anyway b$="aaaaaaaaaaaaaaabbbbbbbbbbbbbbcccccccccccccccddddddddddddddddddddddd" max=50000 Do Cls rgb(0,0,0) inc frames
t=timer() For lp=0 to max a$=mid$(b$,5,5) next t1#=t1#+(Timer()-t) print "MID:"+str$(t1#/frames) print a$
t=timer() For lp=0 to max a$=left$(b$,20) next t2#=t2#+(Timer()-t) print "Left:"+str$(t2#/frames) print a$
t=timer() For lp=0 to max a$=Right$(b$,20) next t3#=t3#+(Timer()-t) print "Right:"+str$(t3#/frames) print a$
t=timer() For lp=0 to max a$=Replace$(b$,"c","d",1,0,0,) next t4#=t4#+(Timer()-t) print "Replace:"+str$(t4#/frames) print a$
Sync loop
|
|
|
|
|
Logged
|
|
|
|
|
kevin
|
 |
« Reply #11 on: September 26, 2008, 01:14:36 PM » |
|
Array Command Set Haven't had much computer time the past couple of days, but the current WIP is the array command set. So far, the only command running on VM2 is DIM. There's not really much to speed up with dim, so I've mostly been breaking up the function set. With any luck and a little bit of effort, this will make upgrading the rest of the library much easier. Size=50 max=10000 Do Cls rgb(0,0,0) inc frames
Memory=0 t=timer() For lp=0 to max Dim Table(Size) next t1#=t1#+(Timer()-t) print "DIM1D:"+str$(t1#/frames) Memory=Memory+(Max*Size)
t=timer() For lp=0 to max Dim Table(Size,Size) next t2#=t2#+(Timer()-t) print "DIM2D:"+str$(t2#/frames)
Memory=Memory+(Max*(Size*Size))
print "Integers:"+Str$(Memory) Sync loop
|
|
|
|
« Last Edit: September 27, 2008, 01:50:49 PM by kevin »
|
Logged
|
|
|
|
|
kevin
|
 |
« Reply #12 on: September 28, 2008, 09:23:36 AM » |
|
Array Command Set Cont. Setting up the array query functions. One change is the GetArrayElements() will return a zero if you access an illegal dimension (a dimension that doesn't exist). Also, the new library doesn't throw errors ATM. Dim Table(20,30) Print GetArrayStatus(Table()) Print GetArrayDimensions(Table()) for lp=0 to GetArrayDimensions(Table())+1 print GetArrayElements(Table(),lp) next Sync waitkey Sort Array Size=20 do Cls 0 Dim Table(20) Print "Random Array" For lp=0 to size Table(lp)=rnd(100) print Table(lp) next SortArray Table(),0, size Print "Sorted Array" For lp=0 to size print Table(lp) next
Sync waitkey waitnokey loop
|
|
|
|
« Last Edit: September 28, 2008, 10:51:00 AM by kevin »
|
Logged
|
|
|
|
|
kevin
|
 |
« Reply #13 on: September 28, 2008, 10:52:18 AM » |
|
Array Command Set Cont. Swap Array Dim Table(20) Dim Table2(10)
Print "Random Array" FillArray(Table()) FillArray(Table2()) Do Cls 0 Print "Table1" ShowArray(Table())
Print "Table2" ShowArray(Table2())
print "Press any key" Sync waitkey waitnokey
swaparray Table(),Table2() loop
Function ShowArray(ThisArray()) For lp=0 to GetArrayElements(ThisArray(),1) print ThisArray(lp) next EndFunction
Function FillArray(ThisArray()) For lp=0 to GetArrayElements(ThisArray(),1) ThisArray(lp)=rnd(100) next EndFunction
Move Array Dim Table(20) Dim Table2(10)
Print "Random Array" FillArray(Table()) FillArray(Table2()) Do Cls 0 Print "Table1" ShowArray(Table())
Print "Table2" ShowArray(Table2())
print "Press any key" Sync waitkey waitnokey
Movearray Table(),Table2() loop
Function ShowArray(ThisArray()) For lp=0 to GetArrayElements(ThisArray(),1) print ThisArray(lp) next EndFunction
Function FillArray(ThisArray()) For lp=0 to GetArrayElements(ThisArray(),1) ThisArray(lp)=rnd(100) next EndFunction
|
|
|
|
|
Logged
|
|
|
|
|
kevin
|
 |
« Reply #14 on: September 29, 2008, 02:42:16 AM » |
|
Redim replacement. Working on REDIM reaplacement, it's sorta working, even though it's currently got some issues. SIZE=100 Dim Table$(size) For lp2=0 to size table$(lp2)="test:"+str$(1000+lp2) Next Test()
Sync WaitKey
Function Test() redim Table$(10) EndFunction
|
|
|
|
« Last Edit: September 29, 2008, 11:24:15 AM by kevin »
|
Logged
|
|
|
|
|