Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdint.h>
- #define HIGH_WORD(value) (value>>16)&0xffff;
- enum DCPU_reg {
- DCPU_a,
- DCPU_b,
- DCPU_c,
- DCPU_x,
- DCPU_y,
- DCPU_z,
- DCPU_i,
- DCPU_j
- };
- struct DCPU_state {
- int skip; // currently skipping?
- uint16_t r[8]; // normal registers
- uint16_t pc; // program counter
- uint16_t sp; // stack pointer, inits to 0xffff
- uint16_t ex; // extra
- uint16_t ia; // interrupt address
- uint16_t ram[0x10000];
- };
- uint16_t DPCU_next(struct DPCU_state *s) {
- return s->ram[s->pc++];
- }
- uint16_t *DPCU_pointer(struct DPCU_state *s, unsigned int p) {
- static uint16_t dummy;
- dummy = 0;
- switch(p) {
- case 0x00 ... 0x07:
- return &s->r[p];
- case 0x08 ... 0x0f:
- return &s->ram[s->r[p&7]];
- case 0x10 ... 0x17:
- return &s->ram[(s->r[p&7] + DPCU_next(s))&0xffff];
- case 0x18:
- return &s->ram[--s->sp];
- case 0x19:
- return &s->ram[s->sp];
- case 0x1a:
- return &s->ram[(s->sp + DPCU_next(s))&0xffff];
- case 0x1b:
- return &s->sp;
- case 0x1c:
- return &s->pc;
- case 0x1d:
- return &s->ex;
- case 0x1e:
- return &s->ram[DPCU_next(s)];
- case 0x1f:
- dummy = DPCU_next(s);
- return &dummy;
- case 0x20 ... 0x3f:
- dummy = p-0x21;
- return &dummy;
- }
- }
- uint16_t DPCU_value(struct DPCU_state *s, unsigned int p) {
- switch(p) {
- case 0x00 ... 0x07:
- return s->r[p];
- case 0x08 ... 0x0f:
- return s->ram[s->r[p&7]];
- case 0x10 ... 0x17:
- return s->ram[(s->r[p&7] + DPCU_next(s))&0xffff];
- case 0x18:
- return s->ram[--s->sp];
- case 0x19:
- return s->ram[s->sp];
- case 0x1a:
- return s->ram[(s->sp + DPCU_next(s))&0xffff];
- case 0x1b:
- return s->sp;
- case 0x1c:
- return s->pc;
- case 0x1d:
- return s->ex;
- case 0x1e:
- return s->ram[DPCU_next(s)];
- case 0x1f:
- return DPCU_next(s);
- case 0x20 ... 0x3f:
- return p-0x21;
- }
- return 0;
- }
- int DPCU_instruction(struct DPCU_state *s) {
- // extract instruction fields
- uint16_t op = DPCU_next(s);
- unsigned int opcode = op & 0x1f;
- unsigned int op_a = (op >> 10) & 63;
- unsigned int op_b = (op >> 5) & 31;
- int temp;
- uint16_t temp16_u;
- int16_t temp16_s;
- uint16_t val, *ptr;
- if(opcode) { // regular
- val = DPCU_value(s, op_a);
- ptr = DPCU_pointer(s, op_b);
- if(skip) {
- if((opcode < 0x10) || (opcode > 0x17))
- skip = 0;
- } else {
- switch(opcode) {
- case 0x01: // set
- *ptr = val;
- break;
- case 0x02: // add
- temp = *ptr + val;
- *ptr = temp;
- s->ex = HIGH_WORD(temp);
- break;
- case 0x03: // sub
- temp = *ptr - val;
- *ptr = temp;
- s->ex = HIGH_WORD(temp);
- break;
- case 0x04: // mul
- temp = *ptr * val;
- *ptr = temp;
- s->ex = HIGH_WORD(temp);
- break;
- case 0x05: // mli
- temp = (int16_t)*ptr * (int16_t)val;
- *ptr = temp;
- s->ex = HIGH_WORD(temp);
- break;
- case 0x06: // div
- temp = *ptr / val;
- *ptr = temp;
- s->ex = HIGH_WORD(temp);
- break;
- case 0x07: // dvi
- temp = (int16_t)*ptr / (int16_t)val;
- *ptr = temp;
- s->ex = HIGH_WORD(temp);
- break;
- case 0x08: // mod
- temp = *ptr % val;
- *ptr = temp;
- s->ex = HIGH_WORD(temp);
- break;
- case 0x09: // mdi
- temp = (int16_t)*ptr % (int16_t)val;
- *ptr = temp;
- s->ex = HIGH_WORD(temp);
- break;
- case 0x0a: // and
- *ptr &= val;
- break;
- case 0x0b: // bor
- *ptr |= val;
- break;
- case 0x0c: // xor
- *ptr ^= val;
- break;
- case 0x0d: // shr
- s->ex = ((*ptr<<16)>>>val)&0xffff;
- *ptr = *ptr >> val;
- break;
- case 0x0e: // asr
- s->ex = (((int16_t)*ptr<<16)>>>val)&0xffff;
- *ptr = ((int16_t)*ptr) >> val;
- break;
- case 0x0d: // shl
- s->ex = ((*ptr<<val)>>16)&0xffff;
- *ptr = *ptr << val;
- break;
- case 0x10: // ifb
- skip = !((*ptr & val)!=0);
- break;
- case 0x11: // ifc
- skip = !((*ptr & val)==0);
- break;
- case 0x12: // ife
- skip = !(*ptr == val);
- break;
- case 0x13: // ifn
- skip = !(*ptr != val);
- break;
- case 0x14: // ifg
- skip = !(*ptr > val);
- break;
- case 0x15: // ifa
- skip = !((int16_t)*ptr > (int16_t)val);
- break;
- case 0x16: // ifl
- skip = !(*ptr < val);
- break;
- case 0x17: // ifu
- skip = !((int16_t)*ptr < (int16_t)val);
- break;
- case 0x1a: // adx
- temp = *ptr + val + s->ex;
- *ptr = temp;
- s->ex = HIGH_WORD(temp);
- break;
- case 0x1b: // sbx
- temp = *ptr - val + s->ex;
- *ptr = temp;
- s->ex = HIGH_WORD(temp);
- break;
- case 0x1e: // sti
- *ptr = temp;
- s->r[DPCU_i]++;
- s->r[DPCU_j]++;
- break;
- case 0x1f: // std
- *ptr = temp;
- s->r[DPCU_i]--;
- s->r[DPCU_j]--;
- break;
- }
- }
- } else { // extended
- val = 0;
- ptr = DPCU_pointer(s, op_a);
- if(!skip) {
- switch(op_b) {
- case 0x01: // jsr
- s->ram[--s->sp] = s->pc;
- s->pc = *ptr
- break;
- case 0x08: // int
- break;
- case 0x09: // iag
- *ptr = s->ia;
- break;
- case 0x0a: // ias
- s->ia = *ptr;
- break;
- case 0x0b: // rfi
- *ptr = s->ram[s->sp++];
- s->pc = s->ram[s->sp++];
- break;
- case 0x0c: // iaq
- break;
- case 0x10: // hwn
- break;
- case 0x11: // hwq
- break;
- case 0x12: // hwi
- break;
- }
- }
- }
- return 0;
- }
- int main(int argc, char *argv[]) {
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement