| Author |
| Thread |
 |
|
MattDiesel
Joined: 31 Oct 2010
Posts: 34
Location: England
|
DCPU-16
As with anything notch does, I am really excited about this:
http://0x10c.com/
People have already written assemblers for the specification, but I think it would be great to adapt fasm to be able to use it for this. Not least because it would then be very easy to add more complex instructions in the form of macros.
It should be possible with just macros, but I've had a few problems with even basic instructions, as I can't change the output for [0x1000] and similar statements.
I have tried something like:
[ fix MEM(
] fix )
To try and change it to be a macro that I can then do something with, but that didn't work. The alternative would be some way to detect if a parameter is enclosed in [] from a macro.
_________________ Cogito Cogito Ergo Essum
|
04 Apr 2012, 14:58 |
|
Tomasz Grysztar
Assembly Artist
Joined: 16 Jun 2003
Posts: 5287
Location: Kraków, Poland
|
It's relatively easy to do it with fasm's macros, but with one serious problem: fasm calculates label values with byte granularity, while this CPU uses addresses with word granularity. So I had to create a special macro LABEL to define labels, otherwise you'd always have to divide all label values by 2 when using them.
Here are my macros:
Code: |
|
A equ eax
B equ ebx
C equ ecx
X equ edx
Y equ ebp
Z equ esp
I equ esi
J equ edi
@A = 0
@B = 1
@C = 2
@X = 3
@Y = 4
@Z = 5
@I = 6
@J = 7
@SET = 0x1
@ADD = 0x2
@SUB = 0x3
@MUL = 0x4
@DIV = 0x5
@MOD = 0x6
@SHL = 0x7
@SHR = 0x8
@AND = 0x9
@BOR = 0xA
@XOR = 0xB
@IFE = 0xC
@IFN = 0xD
@IFG = 0xE
@IFB = 0xF
@JSR = 0x01
macro parse_operand value {
define v value
@nextword = -1
match =POP,v \{
define v
@value = 0x18
\}
match =PEEK,v \{
define v
@value = 0x19
\}
match =PUSH,v \{
define v
@value = 0x1A
\}
match =SP,v \{
define v
@value = 0x1B
\}
match =PC,v \{
define v
@value = 0x1C
\}
match =O,v \{
define v
@value = 0x1D
\}
match [addr],v \{
define v
if +addr relativeto 0
@value = 0x1E
@nextword = word addr
irps reg,A B C X Y Z I J \\{
else if +addr relativeto reg
if +addr-reg = 0
@value = 0x08 + @\\#reg
else
@value = 0x10 + @\\#reg
@nextword = +addr-reg
end if
\\}
end if
\}
match expr,v \{
define v
if +expr relativeto 0
if expr>=0 & expr<=0x1F
@value = 0x20 + expr
else
@value = 0x1F
@nextword = word expr
end if
irps reg,A B C X Y Z I J \\{
else if +expr relativeto reg
assert +expr-reg = 0
@value = 0x00 + @\\#reg
\\}
end if
\}
}
macro basic_instruction opcode,a,b {
@word1 = opcode and 1111b
parse_operand a
@word1 = @word1 or @value shl 4
@word2 = @nextword
parse_operand b
@word1 = @word1 or @value shl (4+6)
@word3 = @nextword
db @word1 shr 8,@word1 and 0FFh
if @word2>=0
db @word2 shr 8,@word2 and 0FFh
end if
if @word3>=0
db @word3 shr 8,@word3 and 0FFh
end if
}
macro nonbasic_instruction opcode,a {
@word1 = (opcode and 111111b) shl 4
parse_operand a
@word1 = @word1 or @value shl (4+6)
db @word1 shr 8,@word1 and 0FFh
if @nextword>=0
db @nextword shr 8,@nextword and 0FFh
end if
}
irps instr,SET ADD SUB MUL DIV MOD SHL SHR AND BOR XOR IFE IFN IFG IFB {
macro instr a,b \{ basic_instruction @\#instr,a,b \}
}
irps instr,JSR {
macro instr a \{ nonbasic_instruction @\#instr,a \}
}
macro LABEL name {
name = $ shr 1
}
|
|
and converted example code (note that everything is case-sensitive):
Code: |
|
; Try some basic stuff
SET A, 0x30
SET [0x1000], 0x20
SUB A, [0x1000]
IFN A, 0x10
SET PC, crash
; Do a loopy thing
SET I, 10
SET A, 0x2000
LABEL _loop
SET [0x2000+I], [A]
SUB I, 1
IFN I, 0
SET PC, _loop
; Call a subroutine
SET X, 0x4
JSR testsub
SET PC, crash
LABEL testsub
SHL X, 4
SET PC, POP
; Hang forever. X should now be 0x40 if everything went right.
LABEL crash
SET PC, crash
|
|
And, of course, fasm optimizes the instructions to short forms automatically.
Still, it would be perhaps better to make a custom fasm version for such architecture. First, it would allow to generate label values correctly divided by 2. Second, it would make instructions and register names not case-sensitive. And third - you would not have to worry about the huge amount of x86 reserved words that fasm doesn't allow to use as label (as with "loop" in the example above).
|
04 Apr 2012, 16:11 |
|
MattDiesel
Joined: 31 Oct 2010
Posts: 34
Location: England
|
I was going to post what I'd done so far...
But you seem to have it all sorted!
You sir, are a genius.
_________________ Cogito Cogito Ergo Essum
|
04 Apr 2012, 16:43 |
|
shutdownall
Joined: 02 Apr 2010
Posts: 372
Location: Munich
|
Maybe better put this to "non x86 architectures" forum. 
|
04 Apr 2012, 19:44 |
|
MattDiesel
Joined: 31 Oct 2010
Posts: 34
Location: England
|
I'm working on implementing some extended features, like procedures (using Z as the base pointer at the moment). Unfortunately I don't fully understand everything going on in PROC32.inc that I was hoping I could replicate. This is what I get for not bothering to learn macros. So far I have very badly implemented stdcall, enter, leave and ret functions.
I also hacked together a disassembler just to check the output of various things: http://dl.dropbox.com/u/49542897/Programming/undcpu.tar.gz
Next thing to write is the emulator, which I'm going to write tomorrow (just a console debugger).
The game has barely started development and I can already tell I'm going to waste a lot of time playing it.
_________________ Cogito Cogito Ergo Essum
|
04 Apr 2012, 21:20 |
|
Madis731
Joined: 25 Sep 2003
Posts: 2138
Location: Estonia
|
When I was young, I was dreaming about a game like this. I thought it would never work because of the nerdy stuff that only some people like. But I can see that they've managed to solve a lot of these problems with duct tape and alike
When I see people crafting ALU-s in Minecraft I think there's a lot of potential. That is going to be a game that I can't wait to play.
|
05 Apr 2012, 06:05 |
|
MattDiesel
Joined: 31 Oct 2010
Posts: 34
Location: England
|
Just rewrote my disassembler in C (a lot cleaner than C++) with support for more readable output, cycle counting, recognising SET PC, ... etc.
http://pastie.org/pastes/3732465
Using "-railc" (Readable output, no Assembly, Indent if*, show Lines and show Cycles):
Code: |
|
000000 [ 2 ] A = 0x30
000002 [ 3 ] [0x1000] = 0x20
000005 [ 3 ] A = A - [0x1000]
000007 [2+1] IF ( A != 0x10 )
000008 [ 1 ] GOTO 0x16
000009 [ 1 ] I = 0xa
00000a [ 2 ] A = 0x2000
00000c [ 2 ] [I + 0x2000] = [A]
00000e [ 2 ] I = I - 0x1
00000f [2+1] IF ( I != 0 )
000010 [ 1 ] goto 0xc
000011 [ 1 ] X = 0x4
000012 [ 2 ] CALL 0x14
000013 [ 1 ] GOTO 0x16
000014 [ 2 ] X = X << 0x4
000015 [ 1 ] RET
000016 [ 1 ] GOTO 0x16
|
|
Now writing an emulator 
_________________ Cogito Cogito Ergo Essum
|
05 Apr 2012, 11:38 |
|
Madis731
Joined: 25 Sep 2003
Posts: 2138
Location: Estonia
|
Intel Compiler gave some warnings about making boolean operations on enums. I changed the first few lines to:
Code: |
|
#define showHex 1
#define showLines 2
#define showCycles 4
#define showHR 8
#define noshowAsm 16
#define showInd 32
int cmdFlags;
|
|
Fixed some crashes here and there (mostly dealing with reserved/unexpected input):
Code: |
|
if (o->code.opcode == 0)
{
if(o->n.opcode == 1)
{
ret = printf("%s\t", opcodeNames_nbasic[o->n.opcode]);
ret += valPrint(o->n.a_type, o->n.a);
}
else
ret = printf("%s\t", opcodeNames_nbasic[0]);
}
|
|
Reserved will not print out instruction costs as [137677396] and similar:
Code: |
|
if (cmdFlags & showCycles)
{
if(o->b.opcode == 0 && o->n.opcode != 1)
printf("[???] ");
else if (o->b.opcode >= 0xC)
printf("[%i+1] ", instrGetCycles(o));
else
printf("[ %i ] ", instrGetCycles(o));
}
|
|
When I tested all possible input values then the program went into an infinite loop because of the word limitation. The spec says * 0x10000 words of ram which means that maximum address can be 2*65536-2=0x1FFFE in our world, but 0xFFFF in DCPU16 world.
Code: |
|
void instrDisasm(const word inp[], int len)
{
int cur = 0, delta;
|
|
I changed cur to int for the program to finish.
...and you're missing code behind -h switch.
|
06 Apr 2012, 10:25 |
|
MattDiesel
Joined: 31 Oct 2010
Posts: 34
Location: England
|
Thats what you get for getting excited and programming quickly. Loads of bugs.
Thanks for the info, I was only really concerned about getting valid input to work rather than spotting the invalid. I've moved on to trying to write a full C compiler, though I am doing that properly (i.e. more structured) and so it is taking longer.
I am also trying to implement half precision floating point arithmetic for the dcpu16 but that is turning out to be very tricky, and it takes a lot of cycles no matter what I do.
_________________ Cogito Cogito Ergo Essum
|
10 Apr 2012, 08:55 |
|
Madis731
Joined: 25 Sep 2003
Posts: 2138
Location: Estonia
|
Reading material:
http://fail0verflow.com/blog/2012/dcpu-16-review.html
https://twitter.com/#!/notch/status/189533061967380481
I've wondered if DCPU-16 emulator could use AVX effectively. This would theoretically mean that a 2GHz thread could emulate 8 CPUs in parallel and emulation speed at 100kHz means 20000*8=160000 CPUs realtime. Of course there's overhead and the CPI is not exactly 1.0, but roughly 100000 DCPU-16 CPUs emulated on a single thread is amazing
Thinking about the loose timings given in the spec, this might work.
|
10 Apr 2012, 11:25 |
|
r22
Joined: 27 Dec 2004
Posts: 747
|
This looks like the perfect job for JavaScript.
- Simple Regex Match for every instruction, with Match Groups for Register and/or Memory
- An associative array with OPCode objects that have cycle timings, binary encoding help etc.
- More than fast enough to emulate in real-time
- Simple way to add the API input and output elements that will undoubtedly be added.
- - Graphics = HTML Canvas
- - Sound = HTML Audio
- - Input = DOM Mouse/Key Events
- Host the whole thing on a web page
Unfortunately, I prefer mindless entertainment. Programming my space ship's computer sound too much like work. However, I will watch the youtube video of the first weapon-system aimbot that never misses.
|
10 Apr 2012, 19:33 |
|
Madis731
Joined: 25 Sep 2003
Posts: 2138
Location: Estonia
|
Yes, that is perfect, and it was already done (maybe not all the HTML5 stuff), but I was thinking more about the hardware in the server that will simulate the MMORPG. I think this needs to be pretty efficient. And I made a mistake. 256-bit wide AVX could handle 16x16-bit ops, but I don't know if every instruction has a WORD-capable variant (I know there are a lot of D & Q variants for floats). Maybe AVX2 will repair that
EDIT: Forgot the link http://www.0x10co.de/
Last edited by Madis731 on 15 Apr 2012, 09:36; edited 1 time in total
|
11 Apr 2012, 07:33 |
|
r22
Joined: 27 Dec 2004
Posts: 747
|
@Madis731 - I would of thought the CPU emulation would happen Client side and there would just be a client-server interface for API calls (I/O). Since, according to the little write-ups I've read the CPU only controls the player's ship (which I assume the player could control manually, it wouldn't make much sense for the server to take up that processing burden.
The only argument for server-side CPU emulation would be anti-cheat. But even in that case some sort of verification / signing could be done to mitigate it, without the need to emulate every client.
I don't see how SIMD would be helpful in emulating multiple CPUs at once. Since the instructions that would need to be emulated would be different, in essence losing the SI (single instruction) portion. But haven't thought about this topic to the extent you have...
|
11 Apr 2012, 11:51 |
|
Madis731
Joined: 25 Sep 2003
Posts: 2138
Location: Estonia
|
Yes, that would become a problem (the SI part), extensive use of GATHER family (future AVX2) and alike must be very high latency. Even if brought to the client side, the 3 or 4 CPUs on board would likely be emulated on different cores/threads rather than in a single thread
On the bright side, look what some people have made: http://t.co/JgYfil6t
|
11 Apr 2012, 12:41 |
|
|
|
Forum Rules:
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|
|
|
|
|
Powered by phpBB © 2001-2005 phpBB Group.
|