C-based Virtual Machine for Notch's DCPU-16
github.com
github.com
And a disassembler in JavaScript by evilpie: https://gist.github.com/2300590
Edit:
CoffeeScript, too (via steverb): https://github.com/Janiczek/cfs-dcpu16
@sp332: I feexed it
I checked your code, fixed a few things. It now works for: 7c01 0030 7de1 1000 0020 7803 1000 https://github.com/fbulens/dcpu16-js
I'll continue tomorrow (Europe here).
Seems to work, but I have no idea if it's correct, as I don't have much to test it on.
On the other hand, I feel that building all kinds of stuff around notchs MMO-CPU is just an outlet for all of the excitement that has built up. I guess its upon Mojang to deliver and stop people from diverting off course.
Here enum is not a good idea if you have a switch case like:
switch (val) { /* val is uint8_t / case OP_XXX: break; case OP_YYY: break; case OP_ZZZ: break; }
Looks nice, but in debugging, you have no idea where we are going when you set a breakpoint at the switch. because the val is not an enum type, so debugger can't make the job easier for you.
Now it is much better:
switch (val) { / val is uint8_t / case 0: / XXX / break; case 1: / YYY / break; case 2: / ZZZ */ break; }
So .. move forward a step?
The val may be a corrupted value which are not covered by any of the listed case. However, you will be able to identify what's going wrong right away by comparing the value with listed cases.
Yes, it is rare. but sometimes I do wish I haven't used enum.
putting three spaces in front of a line formats it as code and allows use of *
not putting those spaces means that text in asterisks become italicsSoftware changes, and is often changed by someone other than the original author.
A nice addition, until Notch's actual design is known, would be to specify a simple community-created "hardware" spec: say memory areas for 40x25 text, 80x25 text, 320x200 monochrome, etc. and a low page (say the first 0xff bytes) for switching between those modes. That way, code could be easily shared and tested.
I'm guessing it's 80x25, 2000 words starting at 0x8000, high byte is the attribute and low byte is the character. Just like a CGA/EGA/VGA display (except that started at 0xA0000). But it's sort of silly to speculate at such an early stage; for instance, is this emulated on the server? client? both, kept in sync somehow? If on the server, do you have to constantly send framebuffer updates?
I can only imagine how fast putting text on the screen can be if you did it with some of the vector instructions in a modern processor....
But from Notch's spec document:
"Instructions are 1-3 words long and are fully defined by the first word. In a basic instruction, the lower four bits of the first word of the instruction are the opcode, and the remaining twelve bits are split into two six bit values, called a and b. a is always handled by the processor before b, and is the lower six bits. In bits (with the least significant being last), a basic instruction has the format: bbbbbbaaaaaaoooo"
In other words, the current DCPU spec is Big Endian. So I wonder if Notch will be rewriting the spec, even though from all accounts it seems that he's already implemented the emulator.
For example, to do a 32 bit add of 0x12345678 and 0xaabbccdd, do this:
SET [0x1000], 0x5678 ; low word
SET [0x1001], 0x1234 ; high word
suggests he's thinking in little-endian.I don't think it's relevant to this spec though: there's no way for a DCPU program to detect the CPU's endianness. Imagine it's C with 16-bit "char"s and no larger int sizes.
I guess it matters if another CPU can read your memory and depends on the cycle count to synchronize...
Picture if memory location 7 is mapped to how much energy to pump into the laser cannon.
It'd be "more fair/realistic" if it took 3 clock cycles, and THEN the memory was overwritten.
Note: this is debating the timing of a 100 kHz simulated processor, within a game... so, the discussion is kind of inherently pedantic. =)
Given that Notch seems to want to continuously operate one or more virtual CPUs for every user, if it were me, I'd favor making the execution model as simple and cheap as possible.
SET A, 0x1 SHL A, 0x100
char A = 1; A = ((char) ((A << 32) & 0xFFFF)); System.out.println(Integer.toHexString(A));
actually outputs 1.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html...
This is a c implementation of that machine architecture.
I don't think we have any info on sensors or actuators for the ships though, yet...
I hope someone finds it useful!
It would definitely be a fitting nod to the history of the 6502 (which inspired this processor) to have a variety of incompatible undocumented instructions. Maybe not a good thing, but... fitting.