This is a virtual machine. Built in SmileBasic
It can run assembly byte code that is custom-created.
It needs to be extended to do more, but the opcodes all work.
The program uses variable width opcodes.
A single byte in ram is represented one at a time.
It any opcode that does not have 8 or 16 in it's name is using 32-bit addressing.
Todo: The Opcodes list needs better documentation.
It is a good example of a virtual machine with it's own return stack, and opcode interpretation.
The program is stored in byte codes and is represented by the program array.
The registers are represented by the registers array. Please don't use registers higher than 12. It may cause a crash.
For now, in order to make programs for it you're going to need to understand assembly a bit.
The opcodes table is here for you to look at:
https://pastebin.com/j4GQa35B
If any of the tests at the start fail please tell me immediately, and tell me what version of SmileBasic you are using as well thank you.
This program will have an assembler in the future.
Instructions:
Make sure to do this. Once you set it to the working project folder.
LOAD"PARSER"
Look at the opcode table posted.
Modify Program[] array structure byte by byte.
Use Smile Basic first to calculate the 4 bytes of a 32 bit integer.
You can hijack functions as well, in the system.
I don't recommend it.
At this stage the VM is for highly experienced users but anyone can play with it.
You can directly modify the program's ram before it starts.
You can try to use the opcode table to create your own arbitrary programs.
You can put an if statement in the @Loop structure such as
IF PC==10 then goto @RESULTS
Then create a results routine like so
@RESULTS
FOR T=0 TO 12
PRINT "THE VALUE OF REGISTER#" +STR$(T) + " IS: "+STR$( REGISTERS[T] )
NEXT T
Mind you setting PC == 12 to a jump condition will be fairly short.
Here is why.
For every byte the VM has to read from PROGRAM[] it is progressing PC by +1 value.
You can play with the VM and put your own values into the registers and stuff like that.
I don't recommend trying to directly write values into ram but instead you can learn how to bit shift.
And then know how to convert say.. a normal number into 4 bytes to represent a 32-bit integer.
Then you can manually write those bytes into the register as the 4 parameters for one of the opcodes.
We aren't at high-level assembling yet. I need to make an assembler next.
Alternatively in the future let someone else (like me) write the assembler and then you can load in assembled programs at the start like this.
LOAD"DAT:PROGRAM1.DAT", PROGRAM
That would then load the program, before everything starts and allow you to run any program written for the vm.
If you want to learn assembly you can play with printing the registers out, and also having code run.
You can also set a condition for it to run any opcode as well so for instance if you wanted to play with it you could change the opcode calls
so they only get called if certain conditions are met, but that will also interfere with it being able to run normal programs.
But basically just have fun with it, see what you can do. See if you can make something out of it. :)
Here's one other thing you can do with this VM.
Create a ram map. where you know certain things in ram could represent the location of a sprite.
Load the sprite with SmileBasic, and then set up a routine that directly reads from ram the sprites' location and does a spofs command or something.
See if you can then write an assembly program that moves the sprite up or down.
You could also directly add a routine that treats one entry in RAM as button press results.
Then write the assembly program you want, to respond to those button presses.
Think of the ram as what you should read from directly for your program's behavior.
Build on the ram, a function that will do something based on a value in ram.
IE You could have 3 ram addresses set up.
One of them is for sprite commands for the sprite on screen. IE SPHIDE So if the ram address[0x100] ==1 then SPHIDE
If the ram address[0x100]==2 then SPSHOW
if the ram address[0x100]==3 then just do nothing. (so you have a nothing state where the sprite will still show but not accept a command.
Then write a routine called @UPDATESPRITE
and in that routine do things like SPSHOW, SPHIDE based on the value of RAM[100].
Then all you need to do is write a virtual machine assembly program that manipulates those ram addresses to see your result.
One one of them is the sprite's X and one is the sprite's Y