diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c0677d6 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +language: + - c +compiler: + - gcc +script: + - make diff --git a/assembler.c b/assembler.c index 4ef8760..7092d02 100644 --- a/assembler.c +++ b/assembler.c @@ -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, @@ -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", ",", "[", "]", ":", "+", @@ -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: @@ -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]); diff --git a/dcpu.c b/dcpu.c index 859f6df..2f01f4c 100644 --- a/dcpu.c +++ b/dcpu.c @@ -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); diff --git a/disassemble.c b/disassemble.c index f5c836a..cbf393b 100644 --- a/disassemble.c +++ b/disassemble.c @@ -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; } @@ -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; diff --git a/emulator.c b/emulator.c index bd944e0..2e9f031 100644 --- a/emulator.c +++ b/emulator.c @@ -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; } } @@ -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; @@ -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); diff --git a/emulator.h b/emulator.h index 5c93641..af399f2 100644 --- a/emulator.h +++ b/emulator.h @@ -37,7 +37,8 @@ struct dcpu { u16 r[8]; u16 pc; u16 sp; - u16 ov; + u16 ex; + u16 ia; u16 unused; u16 m[65536]; };