Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
language:
- c
compiler:
- gcc
script:
- make
56 changes: 50 additions & 6 deletions assembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,10 @@ enum tokens {
tR0, tR1, tR2, tR3, tR4, tR5, tR6, tR7,
tSET, tADD, tSUB, tMUL, tDIV, tMOD, tSHL,
tSHR, tAND, tBOR, tXOR, tIFE, tIFN, tIFG, tIFB,
tJSR,
tPOP, tPEEK, tPUSH, tSP, tPC, tO,
tJSR,
tINT, tIAG, tIAS, tRFI, tIAQ,
tHWN, tHWQ, tHWI,
tPOP, tPEEK, tPUSH, tSP, tPC, tEX,
tJMP, tMOV, tNOP,
tDATA, tDAT, tDW, tWORD,
tCOMMA, tOBRACK, tCBRACK, tCOLON, tPLUS,
Expand All @@ -162,7 +164,9 @@ static const char *tnames[] = {
"SET", "ADD", "SUB", "MUL", "DIV", "MOD", "SHL",
"SHR", "AND", "BOR", "XOR", "IFE", "IFN", "IFG", "IFB",
"JSR",
"POP", "PEEK", "PUSH", "SP", "PC", "O",
"INT", "IAG", "IAS", "RFI", "IAQ",
"HWN", "HWQ", "HWI",
"POP", "PEEK", "PUSH", "SP", "PC", "EX",
"JMP", "MOV", "NOP",
"DATA", "DAT", "DW", "WORD",
",", "[", "]", ":", "+",
Expand Down Expand Up @@ -290,10 +294,10 @@ int assemble_operand(void) {
case tPUSH: return 0x1a;
case tSP: return 0x1b;
case tPC: return 0x1c;
case tO: return 0x1d;
case tEX: return 0x1d;
case tNUMBER:
if (tnumber < 0x20)
return tnumber + 0x20;
return tnumber + 0x21;
image[PC++] = tnumber;
return 0x1f;
case tSTRING:
Expand Down Expand Up @@ -427,7 +431,47 @@ void assemble(const char *fn) {
case tJSR:
pc = PC++;
n = assemble_operand();
image[pc] = (n << 10) | 0x0010;
image[pc] = (n << 10) | (0x01 << 5);
continue;
case tINT:
pc = PC++;
n = assemble_operand();
image[pc] = (n << 10) | (0x08 << 5);
continue;
case tIAG:
pc = PC++;
n = assemble_operand();
image[pc] = (n << 10) | (0x09 << 5);
continue;
case tIAS:
pc = PC++;
n = assemble_operand();
image[pc] = (n << 10) | (0x0a << 5);
continue;
case tRFI:
pc = PC++;
n = assemble_operand();
image[pc] = (n << 10) | (0x0b << 5);
continue;
case tIAQ:
pc = PC++;
n = assemble_operand();
image[pc] = (n << 10) | (0x0c << 5);
continue;
case tHWN:
pc = PC++;
n = assemble_operand();
image[pc] = (n << 10) | (0x10 << 5);
continue;
case tHWQ:
pc = PC++;
n = assemble_operand();
image[pc] = (n << 10) | (0x11 << 5);
continue;
case tHWI:
pc = PC++;
n = assemble_operand();
image[pc] = (n << 10) | (0x12 << 5);
continue;
default:
die("unexpected: %s", tnames[token]);
Expand Down
8 changes: 4 additions & 4 deletions dcpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ extern u16 *disassemble(u16 *pc, char *out);

void dumpheader(void) {
fprintf(stderr,
"PC SP OV A B C X Y Z I J Instruction\n"
"---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -----------\n");
"PC SP EX IA A B C X Y Z I J Instruction\n"
"---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -----------\n");
}

void dumpstate(struct dcpu *d) {
char out[128];
disassemble(d->m + d->pc, out);
fprintf(stderr,
"%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %s\n",
d->pc, d->sp, d->ov,
"%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %s\n",
d->pc, d->sp, d->ex, d->ia,
d->r[0], d->r[1], d->r[2], d->r[3],
d->r[4], d->r[5], d->r[6], d->r[7],
out);
Expand Down
56 changes: 50 additions & 6 deletions disassemble.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ static u16 *dis_operand(u16 *pc, u16 n, char *out) {
} else if (n < 0x18) {
sprintf(out,"[%c, 0x%04x]",regs[n & 7], *pc++);
} else if (n > 0x1f) {
sprintf(out,"%d", n - 0x20);
sprintf(out,"%d", n - 0x21);
} else switch (n) {
case 0x18: strcpy(out,"POP"); break;
case 0x19: strcpy(out,"PEEK"); break;
case 0x1A: strcpy(out,"PUSH"); break;
case 0x1B: strcpy(out,"SP"); break;
case 0x1C: strcpy(out,"PC"); break;
case 0x1D: strcpy(out,"O"); break;
case 0x1D: strcpy(out,"EX"); break;
case 0x1e: sprintf(out,"[0x%04x]",*pc++); break;
case 0x1f: sprintf(out,"0x%04x",*pc++); break;
}
Expand All @@ -82,11 +82,55 @@ u16 *disassemble(u16 *pc, char *out) {
pc = dis_operand(pc, b, out+strlen(out));
return pc;
}
if (a == 1) {
sprintf(out,"JSR ");
pc = dis_operand(pc, b, out+strlen(out));
return pc;
switch (a >> 1) {
case 0x01:
sprintf(out,"JSR ");
pc = dis_operand(pc, b, out+strlen(out));
return pc;
break;

case 0x08:
sprintf(out,"INT ");
pc = dis_operand(pc, b, out+strlen(out));
return pc;
break;
case 0x09:
sprintf(out,"IAG ");
pc = dis_operand(pc, b, out+strlen(out));
return pc;
break;
case 0x0a:
sprintf(out,"IAS ");
pc = dis_operand(pc, b, out+strlen(out));
return pc;
break;
case 0x0b:
sprintf(out,"RFI ");
pc = dis_operand(pc, b, out+strlen(out));
return pc;
break;
case 0x0c:
sprintf(out,"IAQ ");
pc = dis_operand(pc, b, out+strlen(out));
return pc;
break;
case 0x10:
sprintf(out,"HWN ");
pc = dis_operand(pc, b, out+strlen(out));
return pc;
break;
case 0x11:
sprintf(out,"HWQ ");
pc = dis_operand(pc, b, out+strlen(out));
return pc;
break;
case 0x12:
sprintf(out,"HWI ");
pc = dis_operand(pc, b, out+strlen(out));
return pc;
break;
}

sprintf(out,"UNK[%02x] ", a);
pc = dis_operand(pc, b, out+strlen(out));
return pc;
Expand Down
39 changes: 30 additions & 9 deletions emulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ u16 *dcpu_opr(struct dcpu *d, u16 code) {
case 0x1c:
return &d->pc;
case 0x1d:
return &d->ov;
return &d->ex;
case 0x1e:
return d->m + d->m[d->pc++];
case 0x1f:
return d->m + d->pc++;
default:
return lit + (code & 0x1F);
return lit + (code & 0x1F) - 1;
}
}

Expand Down Expand Up @@ -107,13 +107,13 @@ void dcpu_step(struct dcpu *d) {

switch (op & 0xF) {
case 0x1: res = b; break;
case 0x2: res = a + b; d->ov = res >> 16; break;
case 0x3: res = a - b; d->ov = res >> 16; break;
case 0x4: res = a * b; d->ov = res >> 16; break;
case 0x5: if (b) { res = a / b; } else { res = 0; } d->ov = res >> 16; break;
case 0x2: res = a + b; d->ex = res >> 16; break;
case 0x3: res = a - b; d->ex = res >> 16; break;
case 0x4: res = a * b; d->ex = res >> 16; break;
case 0x5: if (b) { res = a / b; } else { res = 0; } d->ex = res >> 16; break;
case 0x6: if (b) { res = a % b; } else { res = 0; } break;
case 0x7: res = a << b; d->ov = res >> 16; break;
case 0x8: res = a >> b; d->ov = res >> 16; break;
case 0x7: res = a << b; d->ex = res >> 16; break;
case 0x8: res = a >> b; d->ex = res >> 16; break;
case 0x9: res = a & b; break;
case 0xA: res = a | b; break;
case 0xB: res = a ^ b; break;
Expand All @@ -128,11 +128,32 @@ void dcpu_step(struct dcpu *d) {

extended:
a = *dcpu_opr(d, op >> 10);
switch ((op >> 4) & 0x3F) {
aa = dcpu_opr(d, op >> 10);
switch ((op >> 5) & 0x1F) {
case 0x01:
d->m[--(d->sp)] = d->pc;
d->pc = a;
return;
case 0x08: // TODO: Realize interrupt work
return;
case 0x0b:
return;
case 0x0c:
return;
case 0x09:
*aa = d->ia;
return;
case 0x0a:
d->ia = a;
return;
case 0x10: // TODO: There is no devices at current time
*aa = 0;
return;
case 0x11: // HWQ
memset(d->r,0x00,10); // A,B,C,X,Y are set to zero
return;
case 0x12: // HWI
return;
default:
fprintf(stderr, "< ILLEGAL OPCODE >\n");
exit(0);
Expand Down
3 changes: 2 additions & 1 deletion emulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ struct dcpu {
u16 r[8];
u16 pc;
u16 sp;
u16 ov;
u16 ex;
u16 ia;
u16 unused;
u16 m[65536];
};
Expand Down