LoginLogin
Nintendo shutting down 3DS + Wii U online services, see our post

Virtual Machine (A fantasy Emulator) Development In Progress

Root / Talk About Programs / [.]

CoinzReturnsCreated:
PLEASE NOTE this is not a COPYRIGHT post, of any kind. All references to "ROM" mean, the program in question that users will create FOR this fantasy emulator. We are not talking about piracy of any kind here. This is going to probably be a train wreck (but maybe not) I'm working on a virtual machine and here are the specs. Up to 12 32 bit registers 0.75 MB of ROM (actually it's ram but the ROM is loaded into it) roughly 0.8 MB of RAM to play with. (trust me it's alot it's like 812300 bytes or something) Next we have 250 unique sprite graphics (also stored in RAM) as well as 250 unique Tile Images. a 512 by 512 pixel Tile Map for 16*16 pixels also stored in RAM 64 pallets or up to 1024 total colors stored at a time. (these are also in ram lol) all of this takes up only 0.8 mb of RAM, and the 0.75 MB of ram for the ROM. Progress: Welp, So far I have the memory map figured out, I've proven it fits inside SmileBasic. I have approximately 1 third of the opcodes created in concept. I've figured out how memory access (read/write) is going to work. It will be possible to issue a jump to an arbitrary RAM address and run it as code. I just realized today hilariously enough that due to the way i've designed the ram you aren't technically forced to use the 0.8 MB of ram for sprite memory.. just you can. Some notes: If you write a 32 bit value to a memory address the remaining 3 bytes will be automatically written to that address + 3 more bytes. This makes it easy to write a 32 bit value to memory just be aware that while the registers are 32 bytes, most sprite ram etc is treated as two-byte values. This is therefore primarily an 8 bit system with 32 bit registers, and addressing. Opcodes so far: The longest opcode is 6 bytes long. For an incomplete table /documentation of system opcodes look no further than.. here. Speed: I have no idea how fast this VM will perform. I plan to use an optimization of some kind for sprites and tiles though (the bg layers) and hopefully you guys won't be attempting to write directly to video pixel memory if you use this (I'm assuming it would be slow due to gpset or whatever being slow) this is more in line with what I had hoped to achieve in SmileBasic, and if I can optimize it to be fast then that will be another step forward for me. The next step after this would be some kind of a custom converter which can convert one type of program Ie translate, into the asm for the VM. If I can get that to work and fit everything I like in less than 1 MB then ideally I can port some things that normally would not run in SB to SB. Natively. This likely won't be anything cool with sound... though. The graphics pipeline I designed so far is pretty primitive. PLEASE NOTICE The VM isn't actually created in CODE yet. It just exists as a concept right now. (But I'll post updates here and you guys can comment)

Update As of right now, I've implemented some subtraction, addition, as well as a few register assignment opcodes. (including immediate value assign, and memory value assign) IE LD REGISTER1, $REGISTER2 will load a 32 bit integer stored in the RAM from the memory location which REGISTER2 points to. I've created a few support functions as well, and finally had a chance since implementing the opcodes for the first time to test out the performance. I began last night. So far it seems to perform as you'd expect SB to perform on an o3Ds. I haven't done anything graphically intense. I haven't created any loop structures yet as I still haven't implemented the branching calls yet. I'm a bit distracted writing this now. What I've figured out is that unless you're doing large memory reads/writes (i mean very large) you can probably get away easily with some operations. The VM isn't ready yet so I won't be releasing it. But I'm about 1/4 through the first batch of opcodes (They're implemented). It won't be easy to use YET. I still haven't decided on a final format for the ROM. So, once I finish (a large portion) of the opcodes. Basically all 39 of the currently proposed opcodes. (yay) 12Me21 said he'd probably be able to help adding more opcodes to it (like the various other forms of branching and such) Nothing graphical has been permanently worked out yet , but I think I want to release a few versions of the Virtual Machine. The first being a reduced simple Virtual Machine (how you get the bytes for your program into it is up to you). It won't have any graphics capabilities built into it or anything. But if you map out your ram, you can set up an update routine which will go through various memory addresses and treat them as data for sprites, and such allowing you to play with a virtual machine without fully understanding how to implement one yourself. Another thing to note is that, this virtual machine could serve as a simple code base for creating a more customized or even more advanced virtual machine. With minimal effort you can even change the opcode mapping. (but probably not the bytes each one requires, or the byte order) Changing the opcode mapping isn't recommended, and you'd have to do so by altering what happens when an opcode byte is found. It is actually quite simple you change the call code to match what you want the opcode to link to. (this also makes it great for experimentation or maybe toying with the idea of creating your own opcodes that extend the virtual machine). The virtual machine will fetch bytes, and increment the PC address pointer even if it finds bytes that don't match an expected opcode. Be weary of this. lastly, porting and interoperability I know now that it shouldn't be too hard to create ports of other assembly programs to SmileBasic. Also, I want to create some kind of a C compiler for this virtual machine so it's very important that the project is as complete as it can be before pursuing that, and as fully featured as possible. Most likely with C code you'd be able to create C-like structures to some extent, functions and function names, and probably various variable types. I wouldn't say it would be more efficient but it would certainly be interesting to see how far C for SmileBasic could go with a custom hand-created Virtual Machine focused on efficiency and ease of readability / expansion. That's all I really have to share, the virtual machine doesn't do anything exciting yet, it just moves memory around. Accurately.

yasssssss

Update Currently the opcodes that work are beyond the ones listed previously. I've been making headway and I'm nearly half way through every planned opcode. 12Me21 is going to be given a copy of the VM to work on once I finish implementing my planned list. So I figured I'd take some time to explain what the project still needs and also to just meander a bit about it. This Virtual Machine operates in primarily 8 bit mode, meaning that it takes in 8 bit opcodes only, but the opcodes can have a variable length. I want to document this virtual machine as early on as possible so that all of you can get started preparing to use it if you are interested. It will have 16 bit and 32 bit modes. the modes aren't a mode of operating but rather it will have extended functions IE
ST8 VALUE, REGISTER ' 8 bit
ST16 VALUE, REGISTER ' 16 bit
ST VALUE, $REGISTER 'pointer address mode from register value 
All the bittage for the values is SIGNED. That means you can't have an 8 bit value exceed roughly 127. About the system so far: It is an open VM the RAM is totally open. There are helper functions (that do some pretty cool stuff) Once released if you want to poke through those you can feel free. How to make a program: So basically to make a program in the virtual machine right now you would need two things. 1) An opcodes list. You basically need it no matter what 2) An understanding of byte-order and an idea for your program. If you know all the opcodes, and what they do. And how they are stored in a binary file you could easily write a program that converts a higher level language of your choice into the language this vm would use. I have NOT yet considered how it's going to handle strings. I'm not planning to deal with it directly. Most likely I'll make a puts assembly routine as part of the compiler that I create so that it already exists, and the compiler will know how to write text to the screen. (might be slow, I don't know). I'll work something out. So if you want to know what your assembly program actually did you will have to do these steps. 1) Write the program and get it into program memory somehow (basically just an array of values from 0-255 in sequence) that mean different opcodes and their parameters. 2) Run the program in the VM 3) Go into direct mode or append new information at the end of the program or create an interupt that halts the program then run a second program in another slot to print out the results of your program. The best thing you could do, is do
SAVE"DAT:Ramdump", RAM
in direct mode. What that would do is create an int file with all the values stored in the ram of the vm. NOTE that even if you do this, the ST16 and ST8 functions store values to ram in 8 bit or 16 bit mode. Here's a sample of what that means.
'Create some arbitrary ram
Dim Ram[1000]
'Create the value
Value = -699
'A value stored in ram in 16 bit mode is stored like this
'Assume the ram address starting point is zero
RamADDR=0

ByteHigh = (Value >>8) AND 255
ByteLow = (Value) AND 255
RAM[RamADDR] = ByteHigh
RAM[RamADDR+1] = ByteLow
Note this isn't exactly how the virtual machine handles a ST16. However. You can expect the format in RAM for an ST16 opcode to appear in the same data format listed here. Basically, we've converted a 16 bit integer into two 8 bit bytes. Now the re-construction of those bytes would look as so
'Add the two bytes back together properly
Value = (ByteHigh<<8) + ByteLow
I'll be documenting more notes here on how things work in the assembly VM soon enough. I just wanted to get some of this written down and explained. What about release There are some delays with release.
  • Release delayed because of life stuff
  • Release delayed because of slightly higher learning curve than expected
  • Release delayed because it isn't useful yet and I don't really know how to document something that isn't tested
At this point what will the VM be able to do for us
  • It will be able to run bytecode
  • It will be able to act as a proof of concept for other emulators that are optimized for SB specifically.
  • It will create a code-base for anyone who wants to use SB to make emulators or toy virtual consoles
  • It will serve as a starting point to create a software bridge of interoperability between PC and SmileBasic
  • It will be possible to fork it to create another emulator type (possibly). So you don't have to start from scratch.
  • With a compiler tool it will be possible to port other languages into SB without having to create a custom VM for each (language ? )
  • A compiler tool can probably be created that runs within SB to create/convert one code type into a dat binary file which the VM understands. From that point on it's simply a matter of running it within the VM.
  • It may be possible to convert already-existing SB games into single chip-roms for easier distribution as dat files that run in the VM (depending on the project).

Progress Update I didn't think this would take this long, sheesh.. I still have nearly 25 more opcodes left but the harder ones are almost all done. Here's basically what I got done tonight.
12) ST8 VALUE, REGISTER         | 0x0C             |1st Value Byte  | 0x00 ->0x0c    | //Stores the value padded to only 1 byte in Register
13) ST8 VALUE, $REGISTER       | 0x0D            |1st Value Byte  | 0x00 ->0x0c     | //Stores the value padded to only 1 byte in the address the Register Points to
14) ST16 VALUE, REGISTER       | 0x0E             | 1st Value Byte | 2nd Value Byte | 0x00 ->0x0c | //Stores the 2 byte value in the register
15) ST16 Value, $REGISTER       | 0x0F             |1st Value Byte  | 2nd Value Byte | 0x00 ->0x0c | //Stores the 2 byte value in the address the $REGISTER points to as a 16 bit value
16) LD8 REGISTER, $ADDRESS | 0x10             | 0x00 ->0x0c    | 1st Addr Byte   | 2nd AddrByte|3rd AddrByte|4th Addr Byte| //Load the 8 bit value from the address into REGISTER
17) LD8 REGISTER, REGISTER   | 0x11             | 0x00 ->0x0c    | 0x00->0x0c      //Load the 8 bit value in REGISTER to REGISTER
Hope that lines up right.. Uhh it probably will be a mess.. Anyway.. The point is I got like a major set of support functions installed into the codebase, and all of those opcodes are in the codebase now. I still have to work towards opcode #39 which is opcode 0x27 buut. they're all alot easier and more direct opcodes. Like branch if not equal (to address) and such. Yeah, I just basically have two more LD16 register opcodes to perform. Then after that, I'm out of 16 bit mode except for compares, Then I have a bunch of 8bit and 16 bit mode compares (and I have to implement the result flag which will just be the last bit of the F register (or was it the first? We better clear this up NOW) lol. There will be glitches with the F register or the register number 6... if signing is involved.. after a compare. A compare instruction should almost always branch as soon as possible .. in case you are not using the particular register F. JUST AS A HEADS UP in the future DO NOT USE the F Register or Register 6 in this case, in order to do math or memory read/write with before a compare instruction. Yes this is going to get specific... but you know what? It's really good. Once I finish the last .. uhh *twitches* 25 opcodes ish.. Then I will roll out a release and work on documentation of the byte code format. It may be a while before I can write an assembler for it though... But yeah.. huge chunk of progress tonight. Super proud. may not finish all of it yet.. mm... hoping I do though. Hoping tonight *crosses fingers* If not tonight then by the next 3 days (not for sure ok? ) *EDIT* Nearly done nearly done *type type type, pant pant pant* hope my eyes don't bleed yet U_U still have to... finish.. only 16 more opcodes. *EDIT EDIT 25 out of 40 opcodes are totally programmed into the VM now. The final 15 opcodes are ALL in 32 bit addressing only. (thank god) So tommorow I can finish those pretty easily (one would hope). The final 15 opcodes also all represent program flow control. Or adding/subtracting values or jumps or logical and / Xor or immediate (literal) jumps.. or branch not equal or branch equal type stuff. After I get some sleep and the opcodes are done, I will write yet another test program to test them all. If all the tests pass then I'll upload it and send it off to 12Me21 to finish the LSB and such opcodes for us (bit shifty things) I'm tired. This was worth it. The opcodes DID take a long time to make but this is after all pretty fast for a fully featured vm. This VM is cool because it is easy for anyone to add their own opcodes into (so if you wanted to add SmileBasic specific opcodes you could knock yourself out IE you could say one opcode symbolizes a SmileBasic specific feature and the call to it just calls the function for it (using given parameters ) But yeah writing bytecode from a table by hand is not for all of you so even if the VM works after this, we still need to create an easier way to create code for it that works inside it. If any of you are experienced in creating an assembler maybe one of our members would be willing to contribute to building an assembler.

Update Release coming tonight. Hopefully. It's all done now. Cross your fingers. Just trying to update firmware, and cfw.

Update The VM is basically complete. http://smilebasicsource.com/page?pid=884 Here's the program page. It needs to be extended now. Note: There are no sprite functions in it, no graphics functions in it,etc. It is just a VM nothing else. It's easy to extend though. The program page tries to explain.

Final Update for now The assembler is live. Please read this post for more information. http://smilebasicsource.com/forum?fpid=17521#post_17521