Пример #1
0
 private IPiValue LoadProgramMemory(ref int ptr, VarType t) {
   PiConst rez=new PiConst();
   switch(t) {
   case VarType.S1:
     rez.Set<long>((sbyte)_prg[ptr++]);
     break;
   case VarType.U1:
     rez.Set<long>(_prg[ptr++]);
     break;
   case VarType.S2:
     rez.Set<long>((short)((_prg[ptr++]<<8) | _prg[ptr++]));
     break;
   case VarType.U2:
     rez.Set<long>((_prg[ptr++]<<8) | _prg[ptr++]);
     break;
   case VarType.S4:
     rez.Set<long>((_prg[ptr++]<<24) | (_prg[ptr++]<<16) | (_prg[ptr++]<<8) | _prg[ptr++]);
     break;
   default:
     rez.Set<long>(0);
     break;
   }
   return rez;
 }
Пример #2
0
    public bool Step() {
      if(_prg==null || _pc>=_prg.Count) {
        return false;
      }
      OP cmd=(OP)_prg[_pc++];
      IPiValue tmp, tmp2;
      switch(cmd) {
        /*
      #region PUSH/POP
      case OP.DUP:
        PushS(_s[_sp]);
        break;
      case OP.DROP:
        PopS();
        break;
      case OP.NIP:    // (a b - b )
        tmp=PopS();
        _s[_sp]=tmp;
        break;
      case OP.SWAP:  // (b a - a b)
        tmp=_s[_sp];
        _s[_sp]=_s[_sp-1];
        _s[_sp-1]=tmp;
        break;
      case OP.PUSH_S1:
      case OP.PUSH_S2:
      case OP.PUSH_S4:
        PushS(LoadProgramMemory(ref _pc, (VarType)(((byte)cmd)&0x07)));
        break;
      case OP.PUSH_U1:
      case OP.PUSH_U2:
        PushS(LoadProgramMemory(ref _pc, (VarType)((-1+(byte)cmd)&0x07)));
        break;
      case OP.PUSH_ZERO:
        PushS(0);
        break;
      case OP.PUSH_TRUE:
        PushS(1);
        break;
      case OP.PUSH_P0:
      case OP.PUSH_P1:
      case OP.PUSH_P2:
      case OP.PUSH_P3:
      case OP.PUSH_P4:
      case OP.PUSH_P5:
      case OP.PUSH_P6:
      case OP.PUSH_P7:
      case OP.PUSH_P8:
      case OP.PUSH_P9:
      case OP.PUSH_PA:
      case OP.PUSH_PB:
      case OP.PUSH_PC:
      case OP.PUSH_PD:
      case OP.PUSH_PE:
      case OP.PUSH_PF:
        PushS(_s[_sfp-2-(((byte)cmd) & 0x0f)]);
        break;
      case OP.PUSH_L0:
      case OP.PUSH_L1:
      case OP.PUSH_L2:
      case OP.PUSH_L3:
      case OP.PUSH_L4:
      case OP.PUSH_L5:
      case OP.PUSH_L6:
      case OP.PUSH_L7:
      case OP.PUSH_L8:
      case OP.PUSH_L9:
      case OP.PUSH_LA:
      case OP.PUSH_LB:
      case OP.PUSH_LC:
      case OP.PUSH_LD:
      case OP.PUSH_LE:
      case OP.PUSH_LF:
        PushS(_s[_sfp+1+(((byte)cmd) & 0x0f)]);
        break;
      case OP.POP_P0:
      case OP.POP_P1:
      case OP.POP_P2:
      case OP.POP_P3:
      case OP.POP_P4:
      case OP.POP_P5:
      case OP.POP_P6:
      case OP.POP_P7:
      case OP.POP_P8:
      case OP.POP_P9:
      case OP.POP_PA:
      case OP.POP_PB:
      case OP.POP_PC:
      case OP.POP_PD:
      case OP.POP_PE:
      case OP.POP_PF:
        _s[_sfp-2-(((byte)cmd) & 0x0f)]=PopS();
        break;
      case OP.POP_L0:
      case OP.POP_L1:
      case OP.POP_L2:
      case OP.POP_L3:
      case OP.POP_L4:
      case OP.POP_L5:
      case OP.POP_L6:
      case OP.POP_L7:
      case OP.POP_L8:
      case OP.POP_L9:
      case OP.POP_LA:
      case OP.POP_LB:
      case OP.POP_LC:
      case OP.POP_LD:
      case OP.POP_LE:
      case OP.POP_LF:
        _s[_sfp+1+(((byte)cmd) & 0x0f)]=PopS();
        break;
      case OP.PUSHM_B1_S16: // memory -> stack
      case OP.PUSHM_B1_CS8:
      case OP.PUSHM_B1_CS16:
      case OP.PUSHM_B1_C16:
      case OP.PUSHM_S1_S16:
      case OP.PUSHM_S1_CS8:
      case OP.PUSHM_S1_CS16:
      case OP.PUSHM_S1_C16:
      case OP.PUSHM_S2_S16:
      case OP.PUSHM_S2_CS8:
      case OP.PUSHM_S2_CS16:
      case OP.PUSHM_S2_C16:
      case OP.PUSHM_S4_S16:
      case OP.PUSHM_S4_CS8:
      case OP.PUSHM_S4_CS16:
      case OP.PUSHM_S4_C16:
      case OP.PUSHM_U1_S16:
      case OP.PUSHM_U1_CS8:
      case OP.PUSHM_U1_CS16:
      case OP.PUSHM_U1_C16:
      case OP.PUSHM_U2_S16:
      case OP.PUSHM_U2_CS8:
      case OP.PUSHM_U2_CS16:
      case OP.PUSHM_U2_C16: {
          int addr;
          switch(((byte)cmd)&0x03) {
          case 0:
            addr=PopS();
            break;
          case 1:
            addr=PopS()+LoadProgramMemory(ref _pc, VarType.S1);
            break;
          case 2:
            addr=PopS()+LoadProgramMemory(ref _pc, VarType.S2);
            break;
          case 3:
            addr=LoadProgramMemory(ref _pc, VarType.U2);
            break;
          default:
            addr=-1;
            break;
          }
          PushS(LoadData(addr, (VarType)((((byte)cmd)>>2)&0x07)));
        }
        break;
      case OP.POPM_B1_S16: // stack -> memory
      case OP.POPM_B1_CS8:
      case OP.POPM_B1_CS16:
      case OP.POPM_B1_C16:
      case OP.POPM_S1_S16:
      case OP.POPM_S1_CS8:
      case OP.POPM_S1_CS16:
      case OP.POPM_S1_C16:
      case OP.POPM_S2_S16:
      case OP.POPM_S2_CS8:
      case OP.POPM_S2_CS16:
      case OP.POPM_S2_C16:
      case OP.POPM_S4_S16:
      case OP.POPM_S4_CS8:
      case OP.POPM_S4_CS16:
      case OP.POPM_S4_C16:
      case OP.POPM_U1_S16:
      case OP.POPM_U1_CS8:
      case OP.POPM_U1_CS16:
      case OP.POPM_U1_C16:
      case OP.POPM_U2_S16:
      case OP.POPM_U2_CS8:
      case OP.POPM_U2_CS16:
      case OP.POPM_U2_C16: {
          int addr;
          switch(((byte)cmd)&0x03) {
          case 0:
            addr=PopS();
            break;
          case 1:
            addr=PopS()+LoadProgramMemory(ref _pc, VarType.S1);
            break;
          case 2:
            addr=PopS()+LoadProgramMemory(ref _pc, VarType.S2);
            break;
          case 3:
            addr=LoadProgramMemory(ref _pc, VarType.U2);
            break;
          default:
            addr=-1;
            break;
          }
          StoreData(addr, (VarType)((((byte)cmd)>>2)&0x07), PopS());
        }
        break;
      #endregion PUSH/POP
        */
      #region ALU
      case OP.ADD:
        tmp=PopS();
        tmp2=PopS(); 
        {
          PiConst r=new PiConst();
          r.Set<double>(tmp.As<double>()+tmp2.As<double>());
          PushS(r);
        }
        //_s[_sp]+=tmp;
        break;
        /*
      case OP.SUB:
        tmp=PopS();
        _s[_sp]-=tmp;
        break;
      case OP.MUL:
        tmp=PopS();
        _s[_sp]*=tmp;
        break;
      case OP.DIV:
        tmp=PopS();
        _s[_sp]/=tmp;
        break;
      case OP.MOD:
        tmp=PopS();
        _s[_sp]%=tmp;
        break;
      case OP.SHL:
        tmp=PopS();
        _s[_sp]<<=tmp;
        break;
      case OP.SHR:
        tmp=PopS();
        _s[_sp]>>=tmp;
        break;
      case OP.AND:
        tmp=PopS();
        _s[_sp]&=tmp;
        break;
      case OP.OR:
        tmp=PopS();
        _s[_sp]|=tmp;
        break;
      case OP.XOR:
        tmp=PopS();
        _s[_sp]^=tmp;
        break;
      case OP.NOT:
        _s[_sp]=~_s[_sp];
        break;
      case OP.NEG:
        _s[_sp]=-_s[_sp];
        break;
      case OP.INC:
        _s[_sp]++;
        break;
      case OP.DEC:
        _s[_sp]--;
        break;
      case OP.CEQ:
        tmp=PopS();
        _s[_sp]=_s[_sp]==tmp?1:0;
        break;
      case OP.CNE:
        tmp=PopS();
        _s[_sp]=_s[_sp]!=tmp?1:0;
        break;
      case OP.CGT:
        tmp=PopS();
        _s[_sp]=_s[_sp]>tmp?1:0;
        break;
      case OP.CGE:
        tmp=PopS();
        _s[_sp]=_s[_sp]>=tmp?1:0;
        break;
      case OP.CLT:
        tmp=PopS();
        _s[_sp]=_s[_sp]<tmp?1:0;
        break;
      case OP.CLE:
        tmp=PopS();
        _s[_sp]=_s[_sp]<=tmp?1:0;
        break;
      case OP.NOT_L:
        _s[_sp]=_s[_sp]==0?1:0;
        break;
      case OP.AND_L:
        tmp=PopS();
        _s[_sp]=_s[_sp]!=0 && tmp!=0?1:0;
        break;
      case OP.OR_L:
        tmp=PopS();
        _s[_sp]=_s[_sp]!=0 || tmp!=0?1:0;
        break;
      case OP.XOR_L:
        tmp=PopS();
        _s[_sp]=_s[_sp]!=0 ^ tmp!=0?1:0;
        break;
        */
      #endregion ALU
        /*
      case OP.JMP:
        tmp=LoadProgramMemory(ref _pc, VarType.U2);
        _pc=(int)tmp.As<long>();
        break;
      case OP.CALL:
        tmp=LoadProgramMemory(ref _pc, VarType.U2);
        PushS(_pc);
        PushS(_sfp);
        _sfp=_sp;
        _pc=tmp;
        break;
      case OP.JZ:
        tmp2=PopS();
        if(tmp2==0) {
          tmp=LoadProgramMemory(ref _pc, VarType.U2);
          _pc=tmp;
        } else {
          _pc+=2;
        }
        break;
      case OP.JNZ:
        tmp2=PopS();
        if(tmp2!=0) {
          tmp=LoadProgramMemory(ref _pc, VarType.U2);
          _pc=tmp;
        } else {
          _pc+=2;
        }
        break;

      case OP.TEST_EQ:
        _testNr++;
        tmp=PopS();
        tmp2=LoadProgramMemory(ref _pc, VarType.S4);
        if(tmp!=tmp2) {
          Log.Warning("Test #{0} FAIL, cur={1}, exp={2}", _testNr, tmp, tmp2);
        } else {
          Log.Info("Test #{0} pass", _testNr);
        }
        break;
         */
      case OP.RET:
        if(_sfp<0) {
          return false;
        } else {
          _sp=_sfp;
          _sfp=(int)PopS().As<long>();
          _pc=(int)PopS().As<long>();
        }
        break;

      default:
        Log.Error("unknown OP [{0:X4}]:{1}", _pc-1, cmd);
        return false;
      }
      return true;
    }