示例#1
0
文件: retro.c 项目: crcx/retroforth
void vm_process(VM *vm) {
  int a, b, opcode;
  opcode = vm->image[vm->ip];

  switch(opcode) {
    case VM_NOP:
         break;
    case VM_LIT:
         vm->sp++;
         vm->ip++;
         TOS = vm->image[vm->ip];
         break;
    case VM_DUP:
         vm->sp++;
         vm->data[vm->sp] = NOS;
         break;
    case VM_DROP:
         DROP
         break;
    case VM_SWAP:
         a = TOS;
         TOS = NOS;
         NOS = a;
         break;
    case VM_PUSH:
         vm->rsp++;
         TORS = TOS;
         DROP
         break;
    case VM_POP:
         vm->sp++;
         TOS = TORS;
         vm->rsp--;
         break;
    case VM_CALL:
         vm->ip++;
         vm->rsp++;
         TORS = vm->ip;
         vm->ip = vm->image[vm->ip] - 1;
         if (vm->ip < 0)
           vm->ip = IMAGE_SIZE;
         else {
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
         }
         break;
    case VM_JUMP:
         vm->ip++;
         vm->ip = vm->image[vm->ip] - 1;
         if (vm->ip < 0)
           vm->ip = IMAGE_SIZE;
         else {
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
         }
         break;
    case VM_RETURN:
         vm->ip = TORS;
         vm->rsp--;
         break;
    case VM_GT_JUMP:
         vm->ip++;
         if(NOS > TOS)
           vm->ip = vm->image[vm->ip] - 1;
         DROP DROP
         break;
    case VM_LT_JUMP:
         vm->ip++;
         if(NOS < TOS)
           vm->ip = vm->image[vm->ip] - 1;
         DROP DROP
         break;
    case VM_NE_JUMP:
         vm->ip++;
         if(TOS != NOS)
           vm->ip = vm->image[vm->ip] - 1;
         DROP DROP
         break;
    case VM_EQ_JUMP:
         vm->ip++;
         if(TOS == NOS)
           vm->ip = vm->image[vm->ip] - 1;
         DROP DROP
         break;
    case VM_FETCH:
         TOS = vm->image[TOS];
         break;
    case VM_STORE:
         vm->image[TOS] = NOS;
         DROP DROP
         break;
    case VM_ADD:
         NOS += TOS;
         DROP
         break;
    case VM_SUB:
         NOS -= TOS;
         DROP
         break;
    case VM_MUL:
         NOS *= TOS;
         DROP
         break;
    case VM_DIVMOD:
         a = TOS;
         b = NOS;
         TOS = b / a;
         NOS = b % a;
         break;
    case VM_AND:
         a = TOS;
         b = NOS;
         DROP
         TOS = a & b;
         break;
    case VM_OR:
         a = TOS;
         b = NOS;
         DROP
         TOS = a | b;
         break;
    case VM_XOR:
         a = TOS;
         b = NOS;
         DROP
         TOS = a ^ b;
         break;
    case VM_SHL:
         a = TOS;
         b = NOS;
         DROP
         TOS = b << a;
         break;
    case VM_SHR:
         a = TOS;
         b = NOS;
         DROP
         TOS = b >>= a;
         break;
    case VM_ZERO_EXIT:
         if (TOS == 0) {
           DROP
           vm->ip = TORS;
           vm->rsp--;
         }
         break;
    case VM_INC:
         TOS += 1;
         break;
    case VM_DEC:
         TOS -= 1;
         break;
    case VM_IN:
         a = TOS;
         TOS = vm->ports[a];
         vm->ports[a] = 0;
         break;
    case VM_OUT:
         vm->ports[0] = 0;
         vm->ports[TOS] = NOS;
         DROP DROP
         break;
    case VM_WAIT:
         if (vm->ports[0] == 1)
           break;

         /* Input */
         if (vm->ports[0] == 0 && vm->ports[1] == 1) {
           vm->ports[1] = dev_getch();
           vm->ports[0] = 1;
         }

         /* Output (character generator) */
         if (vm->ports[2] == 1) {
           dev_putch(TOS); DROP
           vm->ports[2] = 0;
           vm->ports[0] = 1;
         }

         if (vm->ports[4] != 0) {
           vm->ports[0] = 1;
           switch (vm->ports[4]) {
             case  1: vm_save_image(vm, vm->filename);
                      vm->ports[4] = 0;
                      break;
             case  2: file_add(vm);
                      vm->ports[4] = 0;
                      break;
             case -1: vm->ports[4] = file_handle(vm);
                      break;
             case -2: vm->ports[4] = file_readc(vm);
                      break;
             case -3: vm->ports[4] = file_writec(vm);
                      break;
             case -4: vm->ports[4] = file_closehandle(vm);
                      break;
             case -5: vm->ports[4] = file_getpos(vm);
                      break;
             case -6: vm->ports[4] = file_seek(vm);
                      break;
             case -7: vm->ports[4] = file_size(vm);
                      break;
             default: vm->ports[4] = 0;
           }
         }

         /* Capabilities */
         if (vm->ports[5] != 0) {
           vm->ports[0] = 1;
           switch(vm->ports[5]) {
             case -1:  vm->ports[5] = IMAGE_SIZE;
                       break;
             case -2:  vm->ports[5] = 0;
                       break;
             case -3:  vm->ports[5] = 0;
                       break;
             case -4:  vm->ports[5] = 0;
                       break;
             case -5:  vm->ports[5] = vm->sp;
                       break;
             case -6:  vm->ports[5] = vm->rsp;
                       break;
             case -7:  vm->ports[5] = 0;
                       break;
             case -8:  vm->ports[5] = time(NULL);
                       break;
             case -9:  vm->ports[5] = 0;
                       vm->ip = IMAGE_SIZE;
                       break;
             default:  vm->ports[5] = 0;
           }
         }

         if (vm->ports[8] != 0) {
           vm->ports[0] = 1;
           switch (vm->ports[8]) {
             case -1: rsocket(vm);
                      vm->ports[8] = 0;
                      break;
             case -2: rbind(vm);
                      vm->ports[8] = 0;
                      break;
             case -3: rlisten(vm);
                      vm->ports[8] = 0;
                      break;
             case -4: raccept(vm);
                      vm->ports[8] = 0;
                      break;
             case -5: rclose(vm);
                      vm->ports[8] = 0;
                      break;
             case -6: rsend(vm);
                      vm->ports[8] = 0;
                      break;
             case -7: rrecv(vm);
                      vm->ports[8] = 0;
                      break;
             case -8: rconnect(vm);
                      vm->ports[8] = 0;
                      break;
             default: vm->ports[8] = 0;
           }
           vm->ports[8] = 0;
         }
         break;
    default:
         vm->rsp++;
         TORS = vm->ip;
         vm->ip = vm->image[vm->ip] - 1;

         if (vm->ip < 0)
           vm->ip = IMAGE_SIZE;
         else {
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
         }
         break;
  }
  vm->ports[3] = 1;
}
示例#2
0
文件: devices.c 项目: js4/ngaro
/******************************************************
 *|F| int handle_devices(void *unused)
 ******************************************************/
int handle_devices(void *unused)
{
  SDL_Event event;
  int c;

  while (vm.ports[0] == 0)
  {
    if (SDL_PollEvent(&event) != 0)
    {
      switch(event.type)
      {
        case SDL_KEYDOWN:
             vm.ports[1] = (int)event.key.keysym.unicode;
             if (event.key.keysym.sym == SDLK_BACKSPACE)
               vm.ports[1] = 8;
             vm.ports[0] = 1;
             break;
        case SDL_KEYUP:
             break;
        case SDL_MOUSEMOTION:
             mousex = event.motion.x;
             mousey = event.motion.y;
             break;
        case SDL_MOUSEBUTTONDOWN:
             mouseb = 1;
             break;
        case SDL_MOUSEBUTTONUP:
             mouseb = 0;
             break;
        case SDL_QUIT:
             vm.ip = IMAGE_SIZE;
             vm.ports[0] = 1;
             break;
      }
    }
    if (vm.ports[2] == 1)
    {
      c = TOS; DROP
      if (c >= 0)
      {
        drawcharacter(tx, ty, c);
        tx += 9;
        if (c == 8)
        {
          tx -= 16;
          drawcharacter(tx, ty, '_');
        }
        if (c == 10)
        {
          tx  = 0;
          ty += 12;
        }
        if (tx > VIDEO_WIDTH - 9)
        {
          tx  = 0;
          ty += 12;
        }
        if (ty > VIDEO_HEIGHT - 12)
        {
          /* Scroll Up */
          gw = 0;
          for (gx = VIDEO_WIDTH * 12; gx < (VIDEO_WIDTH * VIDEO_HEIGHT) - 12; gx++)
          {
            vm.image[VIDEO_BASE + gw] = vm.image[VIDEO_BASE + gx];
            gw++;
          }

          ty = VIDEO_HEIGHT - 12;

          /* Clear bottom line */
          scratch = color;
          color = black;
          gw = VIDEO_WIDTH;     gh = 12;
          gy = ty;              gx = 0;
          for (; gw > 0; gw--)
          {
            line(gx, gy, gx + gw, gy);
            line(gx + gw, gy, gx + gw, gy + gh);
            line(gx + gw, gy + gh, gx, gy + gh);
            line(gx, gy + gh, gx, gy);
          }
          color = scratch;
          vm.ports[3] = 0;
        }
      }
      else
        clear_display();
      vm.ports[2] = 0;
      vm.ports[0] = 1;
    }
    if (vm.ports[4] == 1)
    {
      vm_save_image(vm.filename);
      vm.ports[4] = 0;
      vm.ports[0] = 1;
    }

    /* Capabilities */
    if (vm.ports[5] == -1)
    {
      vm.ports[5] = IMAGE_SIZE;
      vm.ports[0] = 1;
    }
    if (vm.ports[5] == -2)
    {
      vm.ports[5] = -1;
      vm.ports[0] = 1;
    }
    if (vm.ports[5] == -3)
    {
      vm.ports[5] = VIDEO_WIDTH;
      vm.ports[0] = 1;
    }
    if (vm.ports[5] == -4)
    {
      vm.ports[5] = VIDEO_HEIGHT;
      vm.ports[0] = 1;
    }
    if (vm.ports[5] == -5)
    {
      vm.ports[5] = vm.sp;
      vm.ports[0] = 1;
    }
    if (vm.ports[5] == -6)
    {
      vm.ports[5] = vm.rsp;
      vm.ports[0] = 1;
    }
    if (vm.ports[5] == -7)
    {
      vm.ports[5] = -1;
      vm.ports[0] = 1;
    }

    if (vm.ports[6] == 1)
    {
      video_color(TOS); DROP;
      vm.ports[6] = 0;
      vm.ports[0] = 1;
    }
    if (vm.ports[6] == 2)
    {
      gy = TOS; DROP;
      gx = TOS; DROP;
      video_pixel(gx, gy);
      vm.ports[6] = 0;
      vm.ports[0] = 1;
      vm.ports[3] = 0;
    }
    if (vm.ports[6] == 3)
    {
      gw = TOS; DROP;
      gh = TOS; DROP;
      gy = TOS; DROP;
      gx = TOS; DROP;
      line(gx, gy, gx + gw, gy);
      line(gx + gw, gy, gx + gw, gy + gh);
      line(gx + gw, gy + gh, gx, gy + gh);
      line(gx, gy + gh, gx, gy);
      vm.ports[6] = 0;
      vm.ports[0] = 1;
      vm.ports[3] = 0;
    }
    if (vm.ports[6] == 4)
    {
      gw = TOS; DROP;
      gh = TOS; DROP;
      gy = TOS; DROP;
      gx = TOS; DROP;
      for (; gw > 0; gw--)
      {
        line(gx, gy, gx + gw, gy);
        line(gx + gw, gy, gx + gw, gy + gh);
        line(gx + gw, gy + gh, gx, gy + gh);
        line(gx, gy + gh, gx, gy);
      }
      vm.ports[6] = 0;
      vm.ports[0] = 1;
      vm.ports[3] = 0;
    }
    if (vm.ports[6] == 5)
    {
      gh = TOS; DROP;
      gy = TOS; DROP;
      gx = TOS; DROP;
      line(gx, gy, gx, gy + gh);
      vm.ports[6] = 0;
      vm.ports[0] = 1;
      vm.ports[3] = 0;
    }
    if (vm.ports[6] == 6)
    {
      gw = TOS; DROP;
      gy = TOS; DROP;
      gx = TOS; DROP;
      line(gx, gy, gx + gw, gy);
      vm.ports[6] = 0;
      vm.ports[0] = 1;
      vm.ports[3] = 0;
    }
    if (vm.ports[6] == 7)
    {
      gw = TOS; DROP;
      gy = TOS; DROP;
      gx = TOS; DROP;
      video_circle(gx, gy, gw);
      vm.ports[6] = 0;
      vm.ports[0] = 1;
      vm.ports[3] = 0;
    }
    if (vm.ports[6] == 8)
    {
      gw = TOS; DROP;
      gy = TOS; DROP;
      gx = TOS; DROP;
      for (; gw > 0; gw--)
        video_circle(gx, gy, gw);
      vm.ports[6] = 0;
      vm.ports[0] = 1;
      vm.ports[3] = 0;
    }


    if (vm.ports[7] == 1)
    {
      vm.sp++; vm.data[vm.sp] = mousex;
      vm.sp++; vm.data[vm.sp] = mousey;
      vm.ports[7] = 0;
      vm.ports[0] = 1;
    }
    if (vm.ports[7] == 2)
    {
      vm.sp++; vm.data[vm.sp] = mouseb;
      vm.ports[7] = 0;
      vm.ports[0] = 1;
    }
  }