SHARE
TWEET

FVM

vikt144 Dec 18th, 2019 57 in 155 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. /* Part of the project take  from retro forth
  3. http://forthworks.com/retro/
  4. */
  5. package forth;  
  6.  
  7. public class FVM {
  8.  
  9.         public fas as;
  10.  
  11.         public int IMAGE_SIZE=1024;  //my   this is param for imgsize
  12.  
  13.         private int sp = 0, rsp = 0, ip = 0; // указатели стека, стека возвратов и адрес команды
  14.  
  15.         public STACK stack,adrStack;    //стеки  
  16.  
  17.         public short[] image=null;  // память
  18.  
  19.         public int [] ports;  // порты ввода вывода
  20.  
  21.  
  22.   public static final int
  23.     VM_NOP = 0 ,
  24.     VM_LIT = 1 ,  // положить 16 битное значение на стек
  25.     VM_DUP = 2 ,    VM_DROP = 3 ,  VM_SWAP = 4 ,
  26.     VM_PUSH = 5 ,    VM_POP = 6 ,
  27.     VM_CALL = 7 ,    VM_JUMP = 8 ,    VM_RETURN = 9 ,
  28.     VM_GT  = 10 ,VM_LT  = 11 , VM_EQ  = 12 ,  VM_EQ_JUMP  = 13 ,  //  >  <  =  =+jump
  29.     VM_FETCH = 14 ,  VM_STORE = 15 ,  // @  !
  30.     VM_ADD = 16 ,    VM_SUB = 17 ,    VM_MUL = 18 ,  VM_DIVMOD = 19 , // + - *  /
  31.     VM_AND = 20 , VM_OR = 21 , VM_XOR = 22 ,
  32.  
  33.     VM_SHL = 23 ,    VM_SHR = 24 ,    VM_ZERO_EXIT = 25 ,
  34.     VM_INC = 26 ,  VM_DEC = 27 ,
  35.     VM_IN = 28 ,  VM_OUT = 29 ,  VM_WAIT = 30, // записсь чтение портов , ожидание
  36.    
  37.     VM_LIT32 = 31, // положить 32 битное значение на стек
  38.  
  39.     VM_FETCH16 = 32 ,  VM_STORE16 = 33   // c@  c!  
  40.     ;
  41.  
  42.   private void handleDevices() {  // от ретро, // вызывается командой wait
  43.         //зависит от реализации
  44.   }
  45.  
  46.  private void callService(int port, int y) { // вызывается во время записи в порт (out)
  47.         // зависит от реализации
  48.    
  49.    if (port != 0) System.out.println("нетот порт "+ port);
  50.      else
  51.      {
  52.      switch (y) {
  53.        case 0 : _HALT=true; break;
  54.        case 1 : System.out.println("st= "+stack.pop() ); _HALT=true; break;
  55.       } //switch
  56.    }//else
  57.  }
  58.  
  59.   /**    * Process a single opcode*/
  60.  
  61.  
  62.   private void process() {
  63.  
  64.   int x, y, z,tmp,  op;
  65.   op = image[ip];
  66.         switch(op) {
  67.  
  68.     case VM_NOP:
  69.       break;
  70.     case VM_LIT:    ip++;stack.push(image[ip]); // положить 16 битное значение на стек
  71.       break;
  72.     case VM_DUP:    tmp=stack.pop(); stack.push(tmp);stack.push(tmp);
  73.       break;
  74.     case VM_DROP:  stack.drop(1);
  75.       break;
  76.     case VM_SWAP:  x = stack.pop(); y= stack.pop(); stack.push(x);stack.push(y);
  77.       break;
  78.     case VM_PUSH:  x = stack.pop();  adrStack.push(x); // со стека данных на адресный стек
  79.       break;
  80.     case VM_POP:    x = adrStack.pop(); stack.push(x); // обратно
  81.       break;
  82.  
  83.  
  84.     case VM_CALL:  ip++; adrStack.push(ip); ip=image[ip]-1;
  85.       break;
  86.     case VM_JUMP:  ip++;    ip = image[ip]-1;
  87.       break;
  88.     case VM_RETURN:
  89.       ip = adrStack.pop();
  90.       break;
  91.     case VM_GT :  
  92.      x = stack.pop();  if (x>0) x=-1; else x=0; stack.push(x);
  93.       break;
  94.     case VM_LT :  
  95.      x = stack.pop();  if (x<0) x=-1; else x=0; stack.push(x);
  96.       break;
  97.     case VM_EQ :  
  98.      x = stack.pop();  if (x==0) x=-1; else x=0; stack.push(x);
  99.       break;
  100.     case VM_EQ_JUMP:  ip++;  // ?branch
  101.      x = stack.pop(); if (x==0) ip = image[ip] - 1;    
  102.       break;
  103.    
  104.    
  105.     case VM_FETCH: /// @
  106.       tmp=stack.pop();                        // со стека снимается адрес
  107.       x=image[tmp]; tmp++; y=image[tmp];      // с этого адреса снимаются две соседние
  108.       stack.push(x << 16  | y & 0xffff  );  // 16битные ячейки и с помощью сдвига и AND
  109.       break;              // объединяются в 32 битное значение и кладутся на стек
  110.  
  111.  
  112.     case VM_STORE:  //    //  обратная операция 32 битное знач. разлагается
  113.     x = stack.pop(); y= stack.pop(); // на два 16 битных с помощью сдвигов
  114.     short a=(short)y ,  b = (short) (y >> 16);
  115.     image[x]=b; x++ ;  image[x]=a;
  116.       break;
  117.  
  118.     case VM_ADD:    x = stack.pop(); y= stack.pop();stack.push(y+x);
  119.       break;
  120.     case VM_SUB:    x = stack.pop(); y= stack.pop();stack.push(y-x);
  121.       break;
  122.     case VM_MUL:    x = stack.pop(); y= stack.pop();stack.push(y*x);
  123.       break;
  124.     case VM_DIVMOD:    //my relize div 0
  125.       x = stack.pop(); y= stack.pop();  
  126.       stack.push(y % x);  stack.push(y/x); // на стеке остаток и целое
  127.       break;    // иожно добавить проверку /0 если не отлавливаются исключения
  128.     case VM_AND:    x = stack.pop(); y= stack.pop();stack.push(x & y);
  129.       break;
  130.     case VM_OR:      x = stack.pop(); y= stack.pop();stack.push(x | y);
  131.       break;
  132.     case VM_XOR:  x = stack.pop(); y= stack.pop();stack.push(x ^ y);
  133.       break;
  134.     case VM_SHL:    x = stack.pop(); y= stack.pop();stack.push(  y << x );  // сдвиг битов влево
  135.       break;
  136.     case VM_SHR:  x = stack.pop(); y= stack.pop();stack.push( y >>= x );  //  вправо
  137.       break;
  138.     case VM_ZERO_EXIT:    // выход из подпрограммы, если на стеке 0
  139.       if (stack.peek() == 0)
  140.       {
  141.         stack.drop(1);
  142.         ip = adrStack.pop();
  143.       }
  144.       break;
  145.     case VM_INC:  x = stack.pop(); x++; stack.push(x);
  146.     break;
  147.     case VM_DEC:  x = stack.pop(); x--; stack.push(x);
  148.     break;
  149.  
  150.   case VM_IN:          // чтение порта
  151.       x = stack.pop();
  152.       y = ports[x];
  153.       stack.push(y);
  154.       ports[x] = 0;
  155.       break;
  156.     case VM_OUT:  // вершина номер порта
  157.       x=stack.pop();
  158.       y=stack.pop();
  159.       ports[x]=y;//
  160.       callService(x,y);  //вызов внешней функции
  161.       break;
  162.     case VM_WAIT:  handleDevices(); // наследство от  ретро
  163.       break;
  164.  
  165.     case VM_LIT32:  // положить 32 битное значение
  166.       ip++; x=image[ip]; ip++; y=image[ip];  stack.push( x << 16  | y & 0xffff );
  167.       break; //2 16 битные ячейки объединяются в 32 битную с помощью сдвигов
  168.  
  169.     case VM_FETCH16: /// c@
  170.       tmp=stack.pop();                        // со стека снимается адрес
  171.       x=image[tmp];  
  172.       stack.push(x );
  173.       break;          
  174.  
  175.  
  176.     case VM_STORE16:  // c!   //  обратная операция 32 битное знач. разлагается
  177.     x = stack.pop(); y= stack.pop(); // на два 16 битных с помощью сдвигов
  178.    // short
  179.      b = (short) (y);
  180.     image[x]=b;
  181.       break;
  182.  
  183.  }
  184. }
  185.  
  186.  
  187.   boolean _HALT =  false;  //Переменной Halt присваиваются значение во время выполнения
  188.                                 //callService, при исполнении инструкции out
  189.  
  190.  public void processImage( int startIP ) {
  191.   ip=startIP;
  192.   _HALT=false;
  193.   while  (ip<IMAGE_SIZE  && ! _HALT) {
  194.       process();
  195.       ip++;}
  196.   } //void
  197.  
  198.    public void processImageQ( int startIP ) {ip=startIP;  process();}
  199. }  //all
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top