Advertisement
NovaYoshi

dcpu-16

Nov 30th, 2017
203
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.45 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #define HIGH_WORD(value) (value>>16)&0xffff;
  4.  
  5. enum DCPU_reg {
  6.     DCPU_a,
  7.     DCPU_b,
  8.     DCPU_c,
  9.     DCPU_x,
  10.     DCPU_y,
  11.     DCPU_z,
  12.     DCPU_i,
  13.     DCPU_j
  14. };
  15.  
  16. struct DCPU_state {
  17.     int skip;           // currently skipping?
  18.     uint16_t r[8]; // normal registers
  19.     uint16_t pc;     // program counter
  20.     uint16_t sp;     // stack pointer, inits to 0xffff
  21.     uint16_t ex;     // extra
  22.     uint16_t ia;     // interrupt address
  23.     uint16_t ram[0x10000];
  24. };
  25.  
  26. uint16_t DPCU_next(struct DPCU_state *s) {
  27.     return s->ram[s->pc++];
  28. }
  29.  
  30. uint16_t *DPCU_pointer(struct DPCU_state *s, unsigned int p) {
  31.     static uint16_t dummy;
  32.     dummy = 0;
  33.     switch(p) {
  34.         case 0x00 ... 0x07:
  35.             return &s->r[p];
  36.         case 0x08 ... 0x0f:
  37.             return &s->ram[s->r[p&7]];
  38.         case 0x10 ... 0x17:
  39.             return &s->ram[(s->r[p&7] + DPCU_next(s))&0xffff];
  40.         case 0x18:
  41.             return &s->ram[--s->sp];
  42.         case 0x19:
  43.             return &s->ram[s->sp];
  44.         case 0x1a:
  45.             return &s->ram[(s->sp + DPCU_next(s))&0xffff];
  46.         case 0x1b:
  47.             return &s->sp;
  48.         case 0x1c:
  49.             return &s->pc;
  50.         case 0x1d:
  51.             return &s->ex;
  52.         case 0x1e:
  53.             return &s->ram[DPCU_next(s)];
  54.         case 0x1f:
  55.             dummy = DPCU_next(s);
  56.             return &dummy;
  57.         case 0x20 ... 0x3f:
  58.             dummy = p-0x21;
  59.             return &dummy;
  60.     }
  61. }
  62.  
  63. uint16_t DPCU_value(struct DPCU_state *s, unsigned int p) {
  64.     switch(p) {
  65.         case 0x00 ... 0x07:
  66.             return s->r[p];
  67.         case 0x08 ... 0x0f:
  68.             return s->ram[s->r[p&7]];
  69.         case 0x10 ... 0x17:
  70.             return s->ram[(s->r[p&7] + DPCU_next(s))&0xffff];
  71.         case 0x18:
  72.             return s->ram[--s->sp];
  73.         case 0x19:
  74.             return s->ram[s->sp];
  75.         case 0x1a:
  76.             return s->ram[(s->sp + DPCU_next(s))&0xffff];
  77.         case 0x1b:
  78.             return s->sp;
  79.         case 0x1c:
  80.             return s->pc;
  81.         case 0x1d:
  82.             return s->ex;
  83.         case 0x1e:
  84.             return s->ram[DPCU_next(s)];
  85.         case 0x1f:
  86.             return DPCU_next(s);
  87.         case 0x20 ... 0x3f:
  88.             return p-0x21;
  89.     }
  90.     return 0;
  91. }
  92.  
  93. int DPCU_instruction(struct DPCU_state *s) {
  94.     // extract instruction fields
  95.     uint16_t op = DPCU_next(s);
  96.     unsigned int opcode = op & 0x1f;
  97.     unsigned int op_a   = (op >> 10) & 63;
  98.     unsigned int op_b   = (op >> 5)  & 31;
  99.     int temp;
  100.     uint16_t temp16_u;
  101.     int16_t temp16_s;
  102.  
  103.     uint16_t val, *ptr;
  104.     if(opcode) { // regular
  105.         val = DPCU_value(s, op_a);
  106.         ptr = DPCU_pointer(s, op_b);
  107.  
  108.         if(skip) {
  109.           if((opcode < 0x10) || (opcode > 0x17))
  110.             skip = 0;
  111.         } else {
  112.             switch(opcode) {
  113.                 case 0x01: // set
  114.                     *ptr = val;
  115.                     break;
  116.                 case 0x02: // add
  117.                     temp = *ptr + val;
  118.                     *ptr = temp;
  119.                     s->ex = HIGH_WORD(temp);
  120.                     break;
  121.                 case 0x03: // sub
  122.                     temp = *ptr - val;
  123.                     *ptr = temp;
  124.                     s->ex = HIGH_WORD(temp);
  125.                     break;
  126.                 case 0x04: // mul
  127.                     temp = *ptr * val;
  128.                     *ptr = temp;
  129.                     s->ex = HIGH_WORD(temp);
  130.                     break;
  131.                 case 0x05: // mli
  132.                     temp = (int16_t)*ptr * (int16_t)val;
  133.                     *ptr = temp;
  134.                     s->ex = HIGH_WORD(temp);
  135.                     break;
  136.                 case 0x06: // div
  137.                     temp = *ptr / val;
  138.                     *ptr = temp;
  139.                     s->ex = HIGH_WORD(temp);
  140.                     break;
  141.                 case 0x07: // dvi
  142.                     temp = (int16_t)*ptr / (int16_t)val;
  143.                     *ptr = temp;
  144.                     s->ex = HIGH_WORD(temp);
  145.                     break;
  146.                 case 0x08: // mod
  147.                     temp = *ptr % val;
  148.                     *ptr = temp;
  149.                     s->ex = HIGH_WORD(temp);
  150.                     break;
  151.                 case 0x09: // mdi
  152.                     temp = (int16_t)*ptr % (int16_t)val;
  153.                     *ptr = temp;
  154.                     s->ex = HIGH_WORD(temp);
  155.                     break;
  156.                 case 0x0a: // and
  157.                     *ptr &= val;
  158.                     break;
  159.                 case 0x0b: // bor
  160.                     *ptr |= val;
  161.                     break;
  162.                 case 0x0c: // xor
  163.                     *ptr ^= val;
  164.                     break;
  165.                 case 0x0d: // shr
  166.                     s->ex = ((*ptr<<16)>>>val)&0xffff;
  167.                     *ptr = *ptr >> val;
  168.                     break;
  169.                 case 0x0e: // asr
  170.                     s->ex = (((int16_t)*ptr<<16)>>>val)&0xffff;
  171.                     *ptr = ((int16_t)*ptr) >> val;
  172.                     break;
  173.                 case 0x0d: // shl
  174.                     s->ex = ((*ptr<<val)>>16)&0xffff;
  175.                     *ptr = *ptr << val;
  176.                     break;
  177.                 case 0x10: // ifb
  178.                     skip = !((*ptr & val)!=0);
  179.                     break;
  180.                 case 0x11: // ifc
  181.                     skip = !((*ptr & val)==0);
  182.                     break;
  183.                 case 0x12: // ife
  184.                     skip = !(*ptr == val);
  185.                     break;
  186.                 case 0x13: // ifn
  187.                     skip = !(*ptr != val);
  188.                     break;
  189.                 case 0x14: // ifg
  190.                     skip = !(*ptr > val);
  191.                     break;
  192.                 case 0x15: // ifa
  193.                     skip = !((int16_t)*ptr > (int16_t)val);
  194.                     break;
  195.                 case 0x16: // ifl
  196.                     skip = !(*ptr < val);
  197.                     break;
  198.                 case 0x17: // ifu
  199.                     skip = !((int16_t)*ptr < (int16_t)val);
  200.                     break;
  201.  
  202.                 case 0x1a: // adx
  203.                     temp = *ptr + val + s->ex;
  204.                     *ptr = temp;
  205.                     s->ex = HIGH_WORD(temp);
  206.                     break;
  207.                 case 0x1b: // sbx
  208.                     temp = *ptr - val + s->ex;
  209.                     *ptr = temp;
  210.                     s->ex = HIGH_WORD(temp);
  211.                     break;
  212.                 case 0x1e: // sti
  213.                     *ptr = temp;
  214.                     s->r[DPCU_i]++;
  215.                     s->r[DPCU_j]++;
  216.                     break;
  217.                 case 0x1f: // std
  218.                     *ptr = temp;
  219.                     s->r[DPCU_i]--;
  220.                     s->r[DPCU_j]--;
  221.                     break;
  222.             }
  223.         }
  224.     } else { // extended
  225.         val = 0;
  226.         ptr = DPCU_pointer(s, op_a);
  227.  
  228.         if(!skip) {
  229.             switch(op_b) {
  230.                 case 0x01: // jsr
  231.                     s->ram[--s->sp] = s->pc;
  232.                     s->pc = *ptr
  233.                     break;
  234.                 case 0x08: // int
  235.                     break;
  236.                 case 0x09: // iag
  237.                     *ptr = s->ia;
  238.                     break;
  239.                 case 0x0a: // ias
  240.                     s->ia = *ptr;
  241.                     break;
  242.                 case 0x0b: // rfi
  243.                     *ptr  = s->ram[s->sp++];
  244.                     s->pc = s->ram[s->sp++];
  245.                     break;
  246.                 case 0x0c: // iaq
  247.                     break;
  248.                 case 0x10: // hwn
  249.                     break;
  250.                 case 0x11: // hwq
  251.                     break;
  252.                 case 0x12: // hwi
  253.                     break;
  254.             }
  255.         }
  256.     }
  257.  
  258.     return 0;
  259. }
  260.  
  261. int main(int argc, char *argv[]) {
  262.     return 0;
  263. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement