2013-04-07 10:58:58 +01:00
using System ;
using System.Collections.Generic ;
namespace SharpCompress.Compressor.Rar.VM
{
internal class RarVM : BitInput
{
//private void InitBlock()
//{
// Mem.set_Renamed(offset + 0, Byte.valueOf((sbyte) (value_Renamed & 0xff)));
// Mem.set_Renamed(offset + 1, Byte.valueOf((sbyte) ((Utility.URShift(value_Renamed, 8)) & 0xff)));
// Mem.set_Renamed(offset + 2, Byte.valueOf((sbyte) ((Utility.URShift(value_Renamed, 16)) & 0xff)));
// Mem.set_Renamed(offset + 3, Byte.valueOf((sbyte) ((Utility.URShift(value_Renamed, 24)) & 0xff)));
//}
2013-04-28 12:32:55 +01:00
internal byte [ ] Mem { get ; private set ; }
2013-04-07 10:58:58 +01:00
public const int VM_MEMSIZE = 0x40000 ;
//UPGRADE_NOTE: Final was removed from the declaration of 'VM_MEMMASK '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
public static readonly int VM_MEMMASK = ( VM_MEMSIZE - 1 ) ;
public const int VM_GLOBALMEMADDR = 0x3C000 ;
public const int VM_GLOBALMEMSIZE = 0x2000 ;
public const int VM_FIXEDGLOBALSIZE = 64 ;
private const int regCount = 8 ;
private const long UINT_MASK = 0xffffFFFF ; //((long)2*(long)Integer.MAX_VALUE);
private int [ ] R = new int [ regCount ] ;
private VMFlags flags ;
private int maxOpCount = 25000000 ;
private int codeSize ;
private int IP ;
internal RarVM ( )
{
//InitBlock();
Mem = null ;
}
internal void init ( )
{
if ( Mem = = null )
{
Mem = new byte [ VM_MEMSIZE + 4 ] ;
}
}
private bool IsVMMem ( byte [ ] mem )
{
return this . Mem = = mem ;
}
private int GetValue ( bool byteMode , byte [ ] mem , int offset )
{
if ( byteMode )
{
if ( IsVMMem ( mem ) )
{
return ( mem [ offset ] ) ;
}
else
{
return ( mem [ offset ] & 0xff ) ;
}
}
else
{
if ( IsVMMem ( mem ) )
{
return Utility . readIntLittleEndian ( mem , offset ) ;
}
else
{
return Utility . readIntBigEndian ( mem , offset ) ;
}
}
}
private void SetValue ( bool byteMode , byte [ ] mem , int offset , int value )
{
if ( byteMode )
{
if ( IsVMMem ( mem ) )
{
2013-04-28 12:32:55 +01:00
mem [ offset ] = ( byte ) value ;
2013-04-07 10:58:58 +01:00
}
else
{
2013-04-28 12:32:55 +01:00
mem [ offset ] = ( byte ) ( ( mem [ offset ] & 0x00 ) | ( byte ) ( value & 0xff ) ) ;
2013-04-07 10:58:58 +01:00
}
}
else
{
if ( IsVMMem ( mem ) )
{
Utility . WriteLittleEndian ( mem , offset , value ) ;
// Mem[offset + 0] = (byte) value;
// Mem[offset + 1] = (byte) (value >>> 8);
// Mem[offset + 2] = (byte) (value >>> 16);
// Mem[offset + 3] = (byte) (value >>> 24);
}
else
{
Utility . writeIntBigEndian ( mem , offset , value ) ;
// Mem[offset + 3] = (byte) value;
// Mem[offset + 2] = (byte) (value >>> 8);
// Mem[offset + 1] = (byte) (value >>> 16);
// Mem[offset + 0] = (byte) (value >>> 24);
}
}
// #define SET_VALUE(ByteMode,Addr,Value) SetValue(ByteMode,(uint
// *)Addr,Value)
}
internal void SetLowEndianValue ( List < byte > mem , int offset , int value )
{
2013-04-28 12:32:55 +01:00
mem [ offset + 0 ] = ( byte ) ( value & 0xff ) ;
mem [ offset + 1 ] = ( byte ) ( Utility . URShift ( value , 8 ) & 0xff ) ;
mem [ offset + 2 ] = ( byte ) ( Utility . URShift ( value , 16 ) & 0xff ) ;
mem [ offset + 3 ] = ( byte ) ( Utility . URShift ( value , 24 ) & 0xff ) ;
2013-04-07 10:58:58 +01:00
}
private int GetOperand ( VMPreparedOperand cmdOp )
{
int ret = 0 ;
if ( cmdOp . Type = = VMOpType . VM_OPREGMEM )
{
int pos = ( cmdOp . Offset + cmdOp . Base ) & VM_MEMMASK ;
ret = Utility . readIntLittleEndian ( Mem , pos ) ;
}
else
{
int pos = cmdOp . Offset ;
ret = Utility . readIntLittleEndian ( Mem , pos ) ;
}
return ret ;
}
public void execute ( VMPreparedProgram prg )
{
for ( int i = 0 ; i < prg . InitR . Length ; i + + )
2013-04-28 12:32:55 +01:00
// memcpy(R,Prg->InitR,sizeof(Prg->InitR));
2013-04-07 10:58:58 +01:00
{
R [ i ] = prg . InitR [ i ] ;
}
2013-04-28 12:32:55 +01:00
long globalSize = ( long ) ( Math . Min ( prg . GlobalData . Count , VM_GLOBALMEMSIZE ) ) & 0xffFFffFF ;
2013-04-07 10:58:58 +01:00
if ( globalSize ! = 0 )
{
for ( int i = 0 ; i < globalSize ; i + + )
2013-04-28 12:32:55 +01:00
// memcpy(Mem+VM_GLOBALMEMADDR,&Prg->GlobalData[0],GlobalSize);
2013-04-07 10:58:58 +01:00
{
Mem [ VM_GLOBALMEMADDR + i ] = prg . GlobalData [ i ] ;
}
}
2013-04-28 12:32:55 +01:00
long staticSize = ( long ) ( Math . Min ( prg . StaticData . Count , VM_GLOBALMEMSIZE - globalSize ) ) & 0xffFFffFF ;
2013-04-07 10:58:58 +01:00
if ( staticSize ! = 0 )
{
for ( int i = 0 ; i < staticSize ; i + + )
2013-04-28 12:32:55 +01:00
// memcpy(Mem+VM_GLOBALMEMADDR+GlobalSize,&Prg->StaticData[0],StaticSize);
2013-04-07 10:58:58 +01:00
{
2013-04-28 12:32:55 +01:00
Mem [ VM_GLOBALMEMADDR + ( int ) globalSize + i ] = prg . StaticData [ i ] ;
2013-04-07 10:58:58 +01:00
}
}
R [ 7 ] = VM_MEMSIZE ;
flags = 0 ;
//UPGRADE_NOTE: There is an untranslated Statement. Please refer to original code. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1153'"
2013-04-28 12:32:55 +01:00
List < VMPreparedCommand > preparedCode = prg . AltCommands . Count ! = 0
? prg
. AltCommands
: prg . Commands ;
2013-04-07 10:58:58 +01:00
if ( ! ExecuteCode ( preparedCode , prg . CommandCount ) )
{
preparedCode [ 0 ] . OpCode = VMCommands . VM_RET ;
}
int newBlockPos = GetValue ( false , Mem , VM_GLOBALMEMADDR + 0x20 ) & VM_MEMMASK ;
int newBlockSize = GetValue ( false , Mem , VM_GLOBALMEMADDR + 0x1c ) & VM_MEMMASK ;
if ( ( newBlockPos + newBlockSize ) > = VM_MEMSIZE )
{
newBlockPos = 0 ;
newBlockSize = 0 ;
}
prg . FilteredDataOffset = newBlockPos ;
prg . FilteredDataSize = newBlockSize ;
prg . GlobalData . Clear ( ) ;
int dataSize = Math . Min ( GetValue ( false , Mem , VM_GLOBALMEMADDR + 0x30 ) , VM_GLOBALMEMSIZE - VM_FIXEDGLOBALSIZE ) ;
if ( dataSize ! = 0 )
{
//prg.GlobalData.Clear();
// ->GlobalData.Add(dataSize+VM_FIXEDGLOBALSIZE);
prg . GlobalData . SetSize ( dataSize + VM_FIXEDGLOBALSIZE ) ;
for ( int i = 0 ; i < dataSize + VM_FIXEDGLOBALSIZE ; i + + )
2013-04-28 12:32:55 +01:00
// memcpy(&Prg->GlobalData[0],&Mem[VM_GLOBALMEMADDR],DataSize+VM_FIXEDGLOBALSIZE);
2013-04-07 10:58:58 +01:00
{
prg . GlobalData [ i ] = Mem [ VM_GLOBALMEMADDR + i ] ;
}
}
}
private bool setIP ( int ip )
{
if ( ( ip ) > = codeSize )
{
return ( true ) ;
}
if ( - - maxOpCount < = 0 )
{
return ( false ) ;
}
IP = ip ;
return true ;
}
private bool ExecuteCode ( List < VMPreparedCommand > preparedCode ,
2013-04-28 12:32:55 +01:00
int cmdCount )
2013-04-07 10:58:58 +01:00
{
maxOpCount = 25000000 ;
this . codeSize = cmdCount ;
this . IP = 0 ;
while ( true )
{
VMPreparedCommand cmd = preparedCode [ IP ] ;
int op1 = GetOperand ( cmd . Op1 ) ;
int op2 = GetOperand ( cmd . Op2 ) ;
switch ( cmd . OpCode )
{
case VMCommands . VM_MOV :
2013-04-28 12:32:55 +01:00
SetValue ( cmd . IsByteMode , Mem , op1 , GetValue ( cmd . IsByteMode , Mem , op2 ) ) ;
// SET_VALUE(Cmd->ByteMode,Op1,GET_VALUE(Cmd->ByteMode,Op2));
2013-04-07 10:58:58 +01:00
break ;
case VMCommands . VM_MOVB :
SetValue ( true , Mem , op1 , GetValue ( true , Mem , op2 ) ) ;
break ;
case VMCommands . VM_MOVD :
SetValue ( false , Mem , op1 , GetValue ( false , Mem , op2 ) ) ;
break ;
case VMCommands . VM_CMP :
{
2013-04-28 12:32:55 +01:00
VMFlags value1 = ( VMFlags ) GetValue ( cmd . IsByteMode , Mem , op1 ) ;
2013-04-07 10:58:58 +01:00
VMFlags result = value1 - GetValue ( cmd . IsByteMode , Mem , op2 ) ;
if ( result = = 0 )
{
flags = VMFlags . VM_FZ ;
}
else
{
2013-04-28 12:32:55 +01:00
flags = ( VMFlags ) ( ( result > value1 ) ? 1 : 0 | ( int ) ( result & VMFlags . VM_FS ) ) ;
2013-04-07 10:58:58 +01:00
}
}
break ;
case VMCommands . VM_CMPB :
{
2013-04-28 12:32:55 +01:00
VMFlags value1 = ( VMFlags ) GetValue ( true , Mem , op1 ) ;
2013-04-07 10:58:58 +01:00
VMFlags result = value1 - GetValue ( true , Mem , op2 ) ;
if ( result = = 0 )
{
flags = VMFlags . VM_FZ ;
}
else
{
2013-04-28 12:32:55 +01:00
flags = ( VMFlags ) ( ( result > value1 ) ? 1 : 0 | ( int ) ( result & VMFlags . VM_FS ) ) ;
2013-04-07 10:58:58 +01:00
}
}
break ;
case VMCommands . VM_CMPD :
{
2013-04-28 12:32:55 +01:00
VMFlags value1 = ( VMFlags ) GetValue ( false , Mem , op1 ) ;
2013-04-07 10:58:58 +01:00
VMFlags result = value1 - GetValue ( false , Mem , op2 ) ;
if ( result = = 0 )
{
flags = VMFlags . VM_FZ ;
}
else
{
2013-04-28 12:32:55 +01:00
flags = ( VMFlags ) ( ( result > value1 ) ? 1 : 0 | ( int ) ( result & VMFlags . VM_FS ) ) ;
2013-04-07 10:58:58 +01:00
}
}
break ;
case VMCommands . VM_ADD :
{
int value1 = GetValue ( cmd . IsByteMode , Mem , op1 ) ;
2013-04-28 12:32:55 +01:00
int result =
( int )
( ( ( ( long ) value1 + ( long ) GetValue ( cmd . IsByteMode , Mem , op2 ) ) ) &
unchecked ( ( int ) 0xffffffff ) ) ;
2013-04-07 10:58:58 +01:00
if ( cmd . IsByteMode )
{
result & = 0xff ;
2013-04-28 12:32:55 +01:00
flags =
( VMFlags )
( ( result < value1 )
? 1
: 0 |
( result = = 0
? ( int ) VMFlags . VM_FZ
: ( ( ( result & 0x80 ) ! = 0 ) ? ( int ) VMFlags . VM_FS : 0 ) ) ) ;
2013-04-07 10:58:58 +01:00
// Flags=(Result<Value1)|(Result==0 ? VM_FZ:((Result&0x80) ?
// VM_FS:0));
}
else
2013-04-28 12:32:55 +01:00
flags =
( VMFlags )
( ( result < value1 )
? 1
: 0 | ( result = = 0 ? ( int ) VMFlags . VM_FZ : ( result & ( int ) VMFlags . VM_FS ) ) ) ;
2013-04-07 10:58:58 +01:00
SetValue ( cmd . IsByteMode , Mem , op1 , result ) ;
}
break ;
case VMCommands . VM_ADDB :
2013-04-28 12:32:55 +01:00
SetValue ( true , Mem , op1 ,
( int )
( ( long ) GetValue ( true , Mem , op1 ) & 0xFFffFFff + ( long ) GetValue ( true , Mem , op2 ) &
unchecked ( ( int ) 0xFFffFFff ) ) ) ;
2013-04-07 10:58:58 +01:00
break ;
case VMCommands . VM_ADDD :
2013-04-28 12:32:55 +01:00
SetValue ( false , Mem , op1 ,
( int )
( ( long ) GetValue ( false , Mem , op1 ) & 0xFFffFFff + ( long ) GetValue ( false , Mem , op2 ) &
unchecked ( ( int ) 0xFFffFFff ) ) ) ;
2013-04-07 10:58:58 +01:00
break ;
case VMCommands . VM_SUB :
{
int value1 = GetValue ( cmd . IsByteMode , Mem , op1 ) ;
2013-04-28 12:32:55 +01:00
int result =
( int )
( ( long ) value1 & 0xffFFffFF - ( long ) GetValue ( cmd . IsByteMode , Mem , op2 ) &
unchecked ( ( int ) 0xFFffFFff ) ) ;
flags =
( VMFlags )
( ( result = = 0 )
? ( int ) VMFlags . VM_FZ
: ( ( result > value1 ) ? 1 : 0 | ( result & ( int ) VMFlags . VM_FS ) ) ) ;
2013-04-07 10:58:58 +01:00
SetValue ( cmd . IsByteMode , Mem , op1 , result ) ; // (Cmd->ByteMode,Op1,Result);
}
break ;
case VMCommands . VM_SUBB :
2013-04-28 12:32:55 +01:00
SetValue ( true , Mem , op1 ,
( int )
( ( long ) GetValue ( true , Mem , op1 ) & 0xFFffFFff - ( long ) GetValue ( true , Mem , op2 ) &
unchecked ( ( int ) 0xFFffFFff ) ) ) ;
2013-04-07 10:58:58 +01:00
break ;
case VMCommands . VM_SUBD :
2013-04-28 12:32:55 +01:00
SetValue ( false , Mem , op1 ,
( int )
( ( long ) GetValue ( false , Mem , op1 ) & 0xFFffFFff - ( long ) GetValue ( false , Mem , op2 ) &
unchecked ( ( int ) 0xFFffFFff ) ) ) ;
2013-04-07 10:58:58 +01:00
break ;
case VMCommands . VM_JZ :
if ( ( flags & VMFlags . VM_FZ ) ! = 0 )
{
setIP ( GetValue ( false , Mem , op1 ) ) ;
continue ;
}
break ;
case VMCommands . VM_JNZ :
if ( ( flags & VMFlags . VM_FZ ) = = 0 )
{
setIP ( GetValue ( false , Mem , op1 ) ) ;
continue ;
}
break ;
case VMCommands . VM_INC :
{
2013-04-28 12:32:55 +01:00
int result = ( int ) ( ( long ) GetValue ( cmd . IsByteMode , Mem , op1 ) & 0xFFffFFffL + 1L ) ;
2013-04-07 10:58:58 +01:00
if ( cmd . IsByteMode )
{
result & = 0xff ;
}
SetValue ( cmd . IsByteMode , Mem , op1 , result ) ;
2013-04-28 12:32:55 +01:00
flags = ( VMFlags ) ( result = = 0 ? ( int ) VMFlags . VM_FZ : result & ( int ) VMFlags . VM_FS ) ;
2013-04-07 10:58:58 +01:00
}
break ;
case VMCommands . VM_INCB :
2013-04-28 12:32:55 +01:00
SetValue ( true , Mem , op1 , ( int ) ( ( long ) GetValue ( true , Mem , op1 ) & 0xFFffFFffL + 1L ) ) ;
2013-04-07 10:58:58 +01:00
break ;
case VMCommands . VM_INCD :
2013-04-28 12:32:55 +01:00
SetValue ( false , Mem , op1 , ( int ) ( ( long ) GetValue ( false , Mem , op1 ) & 0xFFffFFffL + 1L ) ) ;
2013-04-07 10:58:58 +01:00
break ;
case VMCommands . VM_DEC :
{
2013-04-28 12:32:55 +01:00
int result = ( int ) ( ( long ) GetValue ( cmd . IsByteMode , Mem , op1 ) & 0xFFffFFff - 1 ) ;
2013-04-07 10:58:58 +01:00
SetValue ( cmd . IsByteMode , Mem , op1 , result ) ;
2013-04-28 12:32:55 +01:00
flags = ( VMFlags ) ( result = = 0 ? ( int ) VMFlags . VM_FZ : result & ( int ) VMFlags . VM_FS ) ;
2013-04-07 10:58:58 +01:00
}
break ;
case VMCommands . VM_DECB :
2013-04-28 12:32:55 +01:00
SetValue ( true , Mem , op1 , ( int ) ( ( long ) GetValue ( true , Mem , op1 ) & 0xFFffFFff - 1 ) ) ;
2013-04-07 10:58:58 +01:00
break ;
case VMCommands . VM_DECD :
2013-04-28 12:32:55 +01:00
SetValue ( false , Mem , op1 , ( int ) ( ( long ) GetValue ( false , Mem , op1 ) & 0xFFffFFff - 1 ) ) ;
2013-04-07 10:58:58 +01:00
break ;
case VMCommands . VM_JMP :
setIP ( GetValue ( false , Mem , op1 ) ) ;
continue ;
case VMCommands . VM_XOR :
{
int result = GetValue ( cmd . IsByteMode , Mem , op1 ) ^ GetValue ( cmd . IsByteMode , Mem , op2 ) ;
2013-04-28 12:32:55 +01:00
flags = ( VMFlags ) ( result = = 0 ? ( int ) VMFlags . VM_FZ : result & ( int ) VMFlags . VM_FS ) ;
2013-04-07 10:58:58 +01:00
SetValue ( cmd . IsByteMode , Mem , op1 , result ) ;
}
break ;
case VMCommands . VM_AND :
{
int result = GetValue ( cmd . IsByteMode , Mem , op1 ) & GetValue ( cmd . IsByteMode , Mem , op2 ) ;
2013-04-28 12:32:55 +01:00
flags = ( VMFlags ) ( result = = 0 ? ( int ) VMFlags . VM_FZ : result & ( int ) VMFlags . VM_FS ) ;
2013-04-07 10:58:58 +01:00
SetValue ( cmd . IsByteMode , Mem , op1 , result ) ;
}
break ;
case VMCommands . VM_OR :
{
int result = GetValue ( cmd . IsByteMode , Mem , op1 ) | GetValue ( cmd . IsByteMode , Mem , op2 ) ;
2013-04-28 12:32:55 +01:00
flags = ( VMFlags ) ( result = = 0 ? ( int ) VMFlags . VM_FZ : result & ( int ) VMFlags . VM_FS ) ;
2013-04-07 10:58:58 +01:00
SetValue ( cmd . IsByteMode , Mem , op1 , result ) ;
}
break ;
case VMCommands . VM_TEST :
{
int result = GetValue ( cmd . IsByteMode , Mem , op1 ) & GetValue ( cmd . IsByteMode , Mem , op2 ) ;
2013-04-28 12:32:55 +01:00
flags = ( VMFlags ) ( result = = 0 ? ( int ) VMFlags . VM_FZ : result & ( int ) VMFlags . VM_FS ) ;
2013-04-07 10:58:58 +01:00
}
break ;
case VMCommands . VM_JS :
if ( ( flags & VMFlags . VM_FS ) ! = 0 )
{
setIP ( GetValue ( false , Mem , op1 ) ) ;
continue ;
}
break ;
case VMCommands . VM_JNS :
if ( ( flags & VMFlags . VM_FS ) = = 0 )
{
setIP ( GetValue ( false , Mem , op1 ) ) ;
continue ;
}
break ;
case VMCommands . VM_JB :
if ( ( flags & VMFlags . VM_FC ) ! = 0 )
{
setIP ( GetValue ( false , Mem , op1 ) ) ;
continue ;
}
break ;
case VMCommands . VM_JBE :
if ( ( flags & ( VMFlags . VM_FC | VMFlags . VM_FZ ) ) ! = 0 )
{
setIP ( GetValue ( false , Mem , op1 ) ) ;
continue ;
}
break ;
case VMCommands . VM_JA :
if ( ( flags & ( VMFlags . VM_FC | VMFlags . VM_FZ ) ) = = 0 )
{
setIP ( GetValue ( false , Mem , op1 ) ) ;
continue ;
}
break ;
case VMCommands . VM_JAE :
if ( ( flags & VMFlags . VM_FC ) = = 0 )
{
setIP ( GetValue ( false , Mem , op1 ) ) ;
continue ;
}
break ;
case VMCommands . VM_PUSH :
R [ 7 ] - = 4 ;
SetValue ( false , Mem , R [ 7 ] & VM_MEMMASK , GetValue ( false , Mem , op1 ) ) ;
break ;
case VMCommands . VM_POP :
SetValue ( false , Mem , op1 , GetValue ( false , Mem , R [ 7 ] & VM_MEMMASK ) ) ;
R [ 7 ] + = 4 ;
break ;
case VMCommands . VM_CALL :
R [ 7 ] - = 4 ;
SetValue ( false , Mem , R [ 7 ] & VM_MEMMASK , IP + 1 ) ;
setIP ( GetValue ( false , Mem , op1 ) ) ;
continue ;
case VMCommands . VM_NOT :
SetValue ( cmd . IsByteMode , Mem , op1 , ~ GetValue ( cmd . IsByteMode , Mem , op1 ) ) ;
break ;
case VMCommands . VM_SHL :
{
int value1 = GetValue ( cmd . IsByteMode , Mem , op1 ) ;
int value2 = GetValue ( cmd . IsByteMode , Mem , op2 ) ;
int result = value1 < < value2 ;
2013-04-28 12:32:55 +01:00
flags =
( VMFlags )
( ( result = = 0 ? ( int ) VMFlags . VM_FZ : ( result & ( int ) VMFlags . VM_FS ) ) |
( ( ( value1 < < ( value2 - 1 ) ) & unchecked ( ( int ) 0x80000000 ) ) ! = 0
? ( int ) VMFlags . VM_FC
: 0 ) ) ;
2013-04-07 10:58:58 +01:00
SetValue ( cmd . IsByteMode , Mem , op1 , result ) ;
}
break ;
case VMCommands . VM_SHR :
{
int value1 = GetValue ( cmd . IsByteMode , Mem , op1 ) ;
int value2 = GetValue ( cmd . IsByteMode , Mem , op2 ) ;
int result = Utility . URShift ( value1 , value2 ) ;
2013-04-28 12:32:55 +01:00
flags =
( VMFlags )
( ( result = = 0 ? ( int ) VMFlags . VM_FZ : ( result & ( int ) VMFlags . VM_FS ) ) |
( ( Utility . URShift ( value1 , ( value2 - 1 ) ) ) & ( int ) VMFlags . VM_FC ) ) ;
2013-04-07 10:58:58 +01:00
SetValue ( cmd . IsByteMode , Mem , op1 , result ) ;
}
break ;
case VMCommands . VM_SAR :
{
int value1 = GetValue ( cmd . IsByteMode , Mem , op1 ) ;
int value2 = GetValue ( cmd . IsByteMode , Mem , op2 ) ;
2013-04-28 12:32:55 +01:00
int result = ( ( int ) value1 ) > > value2 ;
flags =
( VMFlags )
( ( result = = 0 ? ( int ) VMFlags . VM_FZ : ( result & ( int ) VMFlags . VM_FS ) ) |
( ( value1 > > ( value2 - 1 ) ) & ( int ) VMFlags . VM_FC ) ) ;
2013-04-07 10:58:58 +01:00
SetValue ( cmd . IsByteMode , Mem , op1 , result ) ;
}
break ;
case VMCommands . VM_NEG :
{
int result = - GetValue ( cmd . IsByteMode , Mem , op1 ) ;
2013-04-28 12:32:55 +01:00
flags =
( VMFlags )
( result = = 0
? ( int ) VMFlags . VM_FZ
: ( int ) VMFlags . VM_FC | ( result & ( int ) VMFlags . VM_FS ) ) ;
2013-04-07 10:58:58 +01:00
SetValue ( cmd . IsByteMode , Mem , op1 , result ) ;
}
break ;
case VMCommands . VM_NEGB :
SetValue ( true , Mem , op1 , - GetValue ( true , Mem , op1 ) ) ;
break ;
case VMCommands . VM_NEGD :
SetValue ( false , Mem , op1 , - GetValue ( false , Mem , op1 ) ) ;
break ;
case VMCommands . VM_PUSHA :
{
for ( int i = 0 , SP = R [ 7 ] - 4 ; i < regCount ; i + + , SP - = 4 )
{
SetValue ( false , Mem , SP & VM_MEMMASK , R [ i ] ) ;
}
2013-04-28 12:32:55 +01:00
R [ 7 ] - = regCount * 4 ;
2013-04-07 10:58:58 +01:00
}
break ;
case VMCommands . VM_POPA :
{
for ( int i = 0 , SP = R [ 7 ] ; i < regCount ; i + + , SP + = 4 )
R [ 7 - i ] = GetValue ( false , Mem , SP & VM_MEMMASK ) ;
}
break ;
case VMCommands . VM_PUSHF :
R [ 7 ] - = 4 ;
2013-04-28 12:32:55 +01:00
SetValue ( false , Mem , R [ 7 ] & VM_MEMMASK , ( int ) flags ) ;
2013-04-07 10:58:58 +01:00
break ;
case VMCommands . VM_POPF :
2013-04-28 12:32:55 +01:00
flags = ( VMFlags ) GetValue ( false , Mem , R [ 7 ] & VM_MEMMASK ) ;
2013-04-07 10:58:58 +01:00
R [ 7 ] + = 4 ;
break ;
case VMCommands . VM_MOVZX :
SetValue ( false , Mem , op1 , GetValue ( true , Mem , op2 ) ) ;
break ;
case VMCommands . VM_MOVSX :
2013-04-28 12:32:55 +01:00
SetValue ( false , Mem , op1 , ( byte ) GetValue ( true , Mem , op2 ) ) ;
2013-04-07 10:58:58 +01:00
break ;
case VMCommands . VM_XCHG :
{
int value1 = GetValue ( cmd . IsByteMode , Mem , op1 ) ;
SetValue ( cmd . IsByteMode , Mem , op1 , GetValue ( cmd . IsByteMode , Mem , op2 ) ) ;
SetValue ( cmd . IsByteMode , Mem , op2 , value1 ) ;
}
break ;
case VMCommands . VM_MUL :
{
2013-04-28 12:32:55 +01:00
int result =
( int )
( ( ( long ) GetValue ( cmd . IsByteMode , Mem , op1 ) &
0xFFffFFff * ( long ) GetValue ( cmd . IsByteMode , Mem , op2 ) & unchecked ( ( int ) 0xFFffFFff ) ) &
unchecked ( ( int ) 0xFFffFFff ) ) ;
2013-04-07 10:58:58 +01:00
SetValue ( cmd . IsByteMode , Mem , op1 , result ) ;
}
break ;
case VMCommands . VM_DIV :
{
int divider = GetValue ( cmd . IsByteMode , Mem , op2 ) ;
if ( divider ! = 0 )
{
2013-04-28 12:32:55 +01:00
int result = GetValue ( cmd . IsByteMode , Mem , op1 ) / divider ;
2013-04-07 10:58:58 +01:00
SetValue ( cmd . IsByteMode , Mem , op1 , result ) ;
}
}
break ;
case VMCommands . VM_ADC :
{
int value1 = GetValue ( cmd . IsByteMode , Mem , op1 ) ;
2013-04-28 12:32:55 +01:00
int FC = ( int ) ( flags & VMFlags . VM_FC ) ;
int result =
( int )
( ( long ) value1 & 0xFFffFFff + ( long ) GetValue ( cmd . IsByteMode , Mem , op2 ) &
0xFFffFFff + ( long ) FC & unchecked ( ( int ) 0xFFffFFff ) ) ;
2013-04-07 10:58:58 +01:00
if ( cmd . IsByteMode )
{
result & = 0xff ;
}
2013-04-28 12:32:55 +01:00
flags =
( VMFlags )
( ( result < value1 | | result = = value1 & & FC ! = 0 )
? 1
: 0 | ( result = = 0 ? ( int ) VMFlags . VM_FZ : ( result & ( int ) VMFlags . VM_FS ) ) ) ;
2013-04-07 10:58:58 +01:00
SetValue ( cmd . IsByteMode , Mem , op1 , result ) ;
}
break ;
case VMCommands . VM_SBB :
{
int value1 = GetValue ( cmd . IsByteMode , Mem , op1 ) ;
2013-04-28 12:32:55 +01:00
int FC = ( int ) ( flags & VMFlags . VM_FC ) ;
int result =
( int )
( ( long ) value1 & 0xFFffFFff - ( long ) GetValue ( cmd . IsByteMode , Mem , op2 ) &
0xFFffFFff - ( long ) FC & unchecked ( ( int ) 0xFFffFFff ) ) ;
2013-04-07 10:58:58 +01:00
if ( cmd . IsByteMode )
{
result & = 0xff ;
}
2013-04-28 12:32:55 +01:00
flags =
( VMFlags )
( ( result > value1 | | result = = value1 & & FC ! = 0 )
? 1
: 0 | ( result = = 0 ? ( int ) VMFlags . VM_FZ : ( result & ( int ) VMFlags . VM_FS ) ) ) ;
2013-04-07 10:58:58 +01:00
SetValue ( cmd . IsByteMode , Mem , op1 , result ) ;
}
break ;
case VMCommands . VM_RET :
if ( R [ 7 ] > = VM_MEMSIZE )
{
return ( true ) ;
}
setIP ( GetValue ( false , Mem , R [ 7 ] & VM_MEMMASK ) ) ;
R [ 7 ] + = 4 ;
continue ;
case VMCommands . VM_STANDARD :
2013-04-28 12:32:55 +01:00
ExecuteStandardFilter ( ( VMStandardFilters ) ( cmd . Op1 . Data ) ) ;
2013-04-07 10:58:58 +01:00
break ;
case VMCommands . VM_PRINT :
break ;
}
IP + + ;
- - maxOpCount ;
}
}
public void prepare ( byte [ ] code , int codeSize , VMPreparedProgram prg )
{
InitBitInput ( ) ;
int cpLength = System . Math . Min ( MAX_SIZE , codeSize ) ;
// memcpy(inBuf,Code,Min(CodeSize,BitInput::MAX_SIZE));
#if ! PORTABLE
Buffer . BlockCopy ( code , 0 , InBuf , 0 , cpLength ) ;
#else
Array . Copy ( code , 0 , InBuf , 0 , cpLength ) ;
#endif
byte xorSum = 0 ;
for ( int i = 1 ; i < codeSize ; i + + )
{
xorSum ^ = code [ i ] ;
}
AddBits ( 8 ) ;
prg . CommandCount = 0 ;
if ( xorSum = = code [ 0 ] )
{
VMStandardFilters filterType = IsStandardFilter ( code , codeSize ) ;
if ( filterType ! = VMStandardFilters . VMSF_NONE )
{
VMPreparedCommand curCmd = new VMPreparedCommand ( ) ;
curCmd . OpCode = VMCommands . VM_STANDARD ;
2013-04-28 12:32:55 +01:00
curCmd . Op1 . Data = ( int ) filterType ;
2013-04-07 10:58:58 +01:00
curCmd . Op1 . Type = VMOpType . VM_OPNONE ;
curCmd . Op2 . Type = VMOpType . VM_OPNONE ;
codeSize = 0 ;
prg . Commands . Add ( curCmd ) ;
prg . CommandCount = prg . CommandCount + 1 ;
// TODO
// curCmd->Op1.Data=FilterType;
// >>>>>> CurCmd->Op1.Addr=&CurCmd->Op1.Data; <<<<<<<<<< not set
// do i need to ?
// >>>>>> CurCmd->Op2.Addr=&CurCmd->Op2.Data; <<<<<<<<<< "
// CurCmd->Op1.Type=CurCmd->Op2.Type=VM_OPNONE;
// CodeSize=0;
}
int dataFlag = GetBits ( ) ;
AddBits ( 1 ) ;
// Read static data contained in DB operators. This data cannot be
// changed,
// it is a part of VM code, not a filter parameter.
if ( ( dataFlag & 0x8000 ) ! = 0 )
{
2013-04-28 12:32:55 +01:00
long dataSize = ( long ) ( ( long ) ReadData ( this ) & 0xffFFffFFL + 1L ) ;
2013-04-07 10:58:58 +01:00
for ( int i = 0 ; inAddr < codeSize & & i < dataSize ; i + + )
{
2013-04-28 12:32:55 +01:00
prg . StaticData . Add ( ( byte ) ( GetBits ( ) > > 8 ) ) ;
2013-04-07 10:58:58 +01:00
AddBits ( 8 ) ;
}
}
while ( inAddr < codeSize )
{
VMPreparedCommand curCmd = new VMPreparedCommand ( ) ;
int data = GetBits ( ) ;
if ( ( data & 0x8000 ) = = 0 )
{
2013-04-28 12:32:55 +01:00
curCmd . OpCode = ( VMCommands ) ( ( data > > 12 ) ) ;
2013-04-07 10:58:58 +01:00
AddBits ( 4 ) ;
}
else
{
2013-04-28 12:32:55 +01:00
curCmd . OpCode = ( VMCommands ) ( ( data > > 10 ) - 24 ) ;
2013-04-07 10:58:58 +01:00
AddBits ( 6 ) ;
}
2013-04-28 12:32:55 +01:00
if ( ( VMCmdFlags . VM_CmdFlags [ ( int ) curCmd . OpCode ] & VMCmdFlags . VMCF_BYTEMODE ) ! = 0 )
2013-04-07 10:58:58 +01:00
{
curCmd . IsByteMode = ( GetBits ( ) > > 15 ) = = 1 ? true : false ;
AddBits ( 1 ) ;
}
else
{
curCmd . IsByteMode = false ;
}
curCmd . Op1 . Type = VMOpType . VM_OPNONE ;
curCmd . Op2 . Type = VMOpType . VM_OPNONE ;
2013-04-28 12:32:55 +01:00
int opNum = ( VMCmdFlags . VM_CmdFlags [ ( int ) curCmd . OpCode ] & VMCmdFlags . VMCF_OPMASK ) ;
2013-04-07 10:58:58 +01:00
// TODO >>> CurCmd->Op1.Addr=CurCmd->Op2.Addr=NULL; <<<???
if ( opNum > 0 )
{
decodeArg ( curCmd . Op1 , curCmd . IsByteMode ) ;
if ( opNum = = 2 )
decodeArg ( curCmd . Op2 , curCmd . IsByteMode ) ;
else
{
2013-04-28 12:32:55 +01:00
if ( curCmd . Op1 . Type = = VMOpType . VM_OPINT & &
( VMCmdFlags . VM_CmdFlags [ ( int ) curCmd . OpCode ] &
( VMCmdFlags . VMCF_JUMP | VMCmdFlags . VMCF_PROC ) ) ! = 0 )
2013-04-07 10:58:58 +01:00
{
int distance = curCmd . Op1 . Data ;
if ( distance > = 256 )
distance - = 256 ;
else
{
if ( distance > = 136 )
{
distance - = 264 ;
}
else
{
if ( distance > = 16 )
{
distance - = 8 ;
}
else
{
if ( distance > = 8 )
{
distance - = 16 ;
}
}
}
distance + = prg . CommandCount ;
}
curCmd . Op1 . Data = distance ;
}
}
}
prg . CommandCount = ( prg . CommandCount + 1 ) ;
prg . Commands . Add ( curCmd ) ;
}
}
VMPreparedCommand curCmd2 = new VMPreparedCommand ( ) ;
curCmd2 . OpCode = VMCommands . VM_RET ;
// TODO CurCmd->Op1.Addr=&CurCmd->Op1.Data;
// CurCmd->Op2.Addr=&CurCmd->Op2.Data;
curCmd2 . Op1 . Type = VMOpType . VM_OPNONE ;
curCmd2 . Op2 . Type = VMOpType . VM_OPNONE ;
// for (int i=0;i<prg.CmdCount;i++)
// {
// VM_PreparedCommand *Cmd=&Prg->Cmd[I];
// if (Cmd->Op1.Addr==NULL)
// Cmd->Op1.Addr=&Cmd->Op1.Data;
// if (Cmd->Op2.Addr==NULL)
// Cmd->Op2.Addr=&Cmd->Op2.Data;
// }
prg . Commands . Add ( curCmd2 ) ;
prg . CommandCount = prg . CommandCount + 1 ;
// #ifdef VM_OPTIMIZE
if ( codeSize ! = 0 )
{
optimize ( prg ) ;
}
}
private void decodeArg ( VMPreparedOperand op , bool byteMode )
{
int data = GetBits ( ) ;
if ( ( data & 0x8000 ) ! = 0 )
{
op . Type = VMOpType . VM_OPREG ;
op . Data = ( data > > 12 ) & 7 ;
op . Offset = op . Data ;
AddBits ( 4 ) ;
}
else
{
if ( ( data & 0xc000 ) = = 0 )
{
op . Type = VMOpType . VM_OPINT ;
if ( byteMode )
{
op . Data = ( data > > 6 ) & 0xff ;
AddBits ( 10 ) ;
}
else
{
AddBits ( 2 ) ;
op . Data = ReadData ( this ) ;
}
}
else
{
op . Type = VMOpType . VM_OPREGMEM ;
if ( ( data & 0x2000 ) = = 0 )
{
op . Data = ( data > > 10 ) & 7 ;
op . Offset = op . Data ;
op . Base = 0 ;
AddBits ( 6 ) ;
}
else
{
if ( ( data & 0x1000 ) = = 0 )
{
op . Data = ( data > > 9 ) & 7 ;
op . Offset = op . Data ;
AddBits ( 7 ) ;
}
else
{
op . Data = 0 ;
AddBits ( 4 ) ;
}
op . Base = ReadData ( this ) ;
}
}
}
}
private void optimize ( VMPreparedProgram prg )
{
//UPGRADE_NOTE: There is an untranslated Statement. Please refer to original code. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1153'"
List < VMPreparedCommand > commands = prg . Commands ;
//UPGRADE_ISSUE: The following fragment of code could not be parsed and was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1156'"
foreach ( VMPreparedCommand cmd in commands )
{
switch ( cmd . OpCode )
{
case VMCommands . VM_MOV :
cmd . OpCode = cmd . IsByteMode ? VMCommands . VM_MOVB : VMCommands . VM_MOVD ;
continue ;
case VMCommands . VM_CMP :
cmd . OpCode = cmd . IsByteMode ? VMCommands . VM_CMPB : VMCommands . VM_CMPD ;
continue ;
}
2013-04-28 12:32:55 +01:00
if ( ( VMCmdFlags . VM_CmdFlags [ ( int ) cmd . OpCode ] & VMCmdFlags . VMCF_CHFLAGS ) = = 0 )
2013-04-07 10:58:58 +01:00
{
continue ;
}
bool flagsRequired = false ;
for ( int i = commands . IndexOf ( cmd ) + 1 ; i < commands . Count ; i + + )
{
2013-04-28 12:32:55 +01:00
int flags = VMCmdFlags . VM_CmdFlags [ ( int ) commands [ i ] . OpCode ] ;
2013-04-07 10:58:58 +01:00
if ( ( flags & ( VMCmdFlags . VMCF_JUMP | VMCmdFlags . VMCF_PROC | VMCmdFlags . VMCF_USEFLAGS ) ) ! = 0 )
{
flagsRequired = true ;
break ;
}
if ( ( flags & VMCmdFlags . VMCF_CHFLAGS ) ! = 0 )
{
break ;
}
}
if ( flagsRequired )
{
continue ;
}
switch ( cmd . OpCode )
{
case VMCommands . VM_ADD :
cmd . OpCode = cmd . IsByteMode ? VMCommands . VM_ADDB : VMCommands . VM_ADDD ;
continue ;
case VMCommands . VM_SUB :
cmd . OpCode = cmd . IsByteMode ? VMCommands . VM_SUBB : VMCommands . VM_SUBD ;
continue ;
case VMCommands . VM_INC :
cmd . OpCode = cmd . IsByteMode ? VMCommands . VM_INCB : VMCommands . VM_INCD ;
continue ;
case VMCommands . VM_DEC :
cmd . OpCode = cmd . IsByteMode ? VMCommands . VM_DECB : VMCommands . VM_DECD ;
continue ;
case VMCommands . VM_NEG :
cmd . OpCode = cmd . IsByteMode ? VMCommands . VM_NEGB : VMCommands . VM_NEGD ;
continue ;
}
}
}
internal static int ReadData ( BitInput rarVM )
{
int data = rarVM . GetBits ( ) ;
switch ( data & 0xc000 )
{
case 0 :
rarVM . AddBits ( 6 ) ;
return ( ( data > > 10 ) & 0xf ) ;
case 0x4000 :
if ( ( data & 0x3c00 ) = = 0 )
{
2013-04-28 12:32:55 +01:00
data = unchecked ( ( int ) 0xffffff00 ) | ( ( data > > 2 ) & 0xff ) ;
2013-04-07 10:58:58 +01:00
rarVM . AddBits ( 14 ) ;
}
else
{
data = ( data > > 6 ) & 0xff ;
rarVM . AddBits ( 10 ) ;
}
return ( data ) ;
case 0x8000 :
rarVM . AddBits ( 2 ) ;
data = rarVM . GetBits ( ) ;
rarVM . AddBits ( 16 ) ;
return ( data ) ;
default :
rarVM . AddBits ( 2 ) ;
data = ( rarVM . GetBits ( ) < < 16 ) ;
rarVM . AddBits ( 16 ) ;
data | = rarVM . GetBits ( ) ;
rarVM . AddBits ( 16 ) ;
return ( data ) ;
}
}
private VMStandardFilters IsStandardFilter ( byte [ ] code , int codeSize )
{
2013-04-28 12:32:55 +01:00
VMStandardFilterSignature [ ] stdList = new VMStandardFilterSignature [ ]
{
new VMStandardFilterSignature ( 53 , 0xad576887 ,
VMStandardFilters . VMSF_E8 ) ,
new VMStandardFilterSignature ( 57 , 0x3cd7e57e ,
VMStandardFilters . VMSF_E8E9 ) ,
new VMStandardFilterSignature ( 120 , 0x3769893f ,
VMStandardFilters . VMSF_ITANIUM ) ,
new VMStandardFilterSignature ( 29 , 0x0e06077d ,
VMStandardFilters . VMSF_DELTA ) ,
new VMStandardFilterSignature ( 149 , 0x1c2c5dc8 ,
VMStandardFilters . VMSF_RGB ) ,
new VMStandardFilterSignature ( 216 , 0xbc85e701 ,
VMStandardFilters . VMSF_AUDIO ) ,
new VMStandardFilterSignature ( 40 , 0x46b9c560 ,
VMStandardFilters . VMSF_UPCASE )
} ;
2013-04-07 10:58:58 +01:00
uint CodeCRC = RarCRC . CheckCrc ( 0xffffffff , code , 0 , code . Length ) ^ 0xffffffff ;
for ( int i = 0 ; i < stdList . Length ; i + + )
{
if ( stdList [ i ] . CRC = = CodeCRC & & stdList [ i ] . Length = = code . Length )
{
return ( stdList [ i ] . Type ) ;
}
}
return ( VMStandardFilters . VMSF_NONE ) ;
}
private void ExecuteStandardFilter ( VMStandardFilters filterType )
{
switch ( filterType )
{
case VMStandardFilters . VMSF_E8 :
case VMStandardFilters . VMSF_E8E9 :
{
int dataSize = R [ 4 ] ;
2013-04-28 12:32:55 +01:00
long fileOffset = R [ 6 ] & unchecked ( ( int ) 0xFFffFFff ) ;
2013-04-07 10:58:58 +01:00
if ( dataSize > = VM_GLOBALMEMADDR )
{
break ;
}
int fileSize = 0x1000000 ;
2013-04-28 12:32:55 +01:00
byte cmpByte2 = ( byte ) ( ( filterType = = VMStandardFilters . VMSF_E8E9 ) ? 0xe9 : 0xe8 ) ;
for ( int curPos = 0 ; curPos < dataSize - 4 ; )
2013-04-07 10:58:58 +01:00
{
byte curByte = Mem [ curPos + + ] ;
if ( curByte = = 0xe8 | | curByte = = cmpByte2 )
{
// #ifdef PRESENT_INT32
// sint32 Offset=CurPos+FileOffset;
// sint32 Addr=GET_VALUE(false,Data);
// if (Addr<0)
// {
// if (Addr+Offset>=0)
// SET_VALUE(false,Data,Addr+FileSize);
// }
// else
// if (Addr<FileSize)
// SET_VALUE(false,Data,Addr-Offset);
// #else
long offset = curPos + fileOffset ;
long Addr = GetValue ( false , Mem , curPos ) ;
2013-04-28 12:32:55 +01:00
if ( ( Addr & unchecked ( ( int ) 0x80000000 ) ) ! = 0 )
2013-04-07 10:58:58 +01:00
{
2013-04-28 12:32:55 +01:00
if ( ( ( Addr + offset ) & unchecked ( ( int ) 0x80000000 ) ) = = 0 )
SetValue ( false , Mem , curPos , ( int ) Addr + fileSize ) ;
2013-04-07 10:58:58 +01:00
}
else
{
2013-04-28 12:32:55 +01:00
if ( ( ( Addr - fileSize ) & unchecked ( ( int ) 0x80000000 ) ) ! = 0 )
2013-04-07 10:58:58 +01:00
{
2013-04-28 12:32:55 +01:00
SetValue ( false , Mem , curPos , ( int ) ( Addr - offset ) ) ;
2013-04-07 10:58:58 +01:00
}
}
// #endif
curPos + = 4 ;
}
}
}
break ;
case VMStandardFilters . VMSF_ITANIUM :
{
int dataSize = R [ 4 ] ;
2013-04-28 12:32:55 +01:00
long fileOffset = R [ 6 ] & unchecked ( ( int ) 0xFFffFFff ) ;
2013-04-07 10:58:58 +01:00
if ( dataSize > = VM_GLOBALMEMADDR )
{
break ;
}
int curPos = 0 ;
//UPGRADE_NOTE: Final was removed from the declaration of 'Masks '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
2013-04-28 12:32:55 +01:00
byte [ ] Masks = new byte [ ] { 4 , 4 , 6 , 6 , 0 , 0 , 7 , 7 , 4 , 4 , 0 , 0 , 4 , 4 , 0 , 0 } ;
2013-04-07 10:58:58 +01:00
fileOffset = Utility . URShift ( fileOffset , 4 ) ;
while ( curPos < dataSize - 21 )
{
int Byte = ( Mem [ curPos ] & 0x1f ) - 0x10 ;
if ( Byte > = 0 )
{
byte cmdMask = Masks [ Byte ] ;
if ( cmdMask ! = 0 )
for ( int i = 0 ; i < = 2 ; i + + )
if ( ( cmdMask & ( 1 < < i ) ) ! = 0 )
{
2013-04-28 12:32:55 +01:00
int startPos = i * 41 + 5 ;
2013-04-07 10:58:58 +01:00
int opType = filterItanium_GetBits ( curPos , startPos + 37 , 4 ) ;
if ( opType = = 5 )
{
int offset = filterItanium_GetBits ( curPos , startPos + 13 , 20 ) ;
2013-04-28 12:32:55 +01:00
filterItanium_SetBits ( curPos , ( int ) ( offset - fileOffset ) & 0xfffff ,
startPos + 13 , 20 ) ;
2013-04-07 10:58:58 +01:00
}
}
}
curPos + = 16 ;
fileOffset + + ;
}
}
break ;
case VMStandardFilters . VMSF_DELTA :
{
2013-04-28 12:32:55 +01:00
int dataSize = R [ 4 ] & unchecked ( ( int ) 0xFFffFFff ) ;
int channels = R [ 0 ] & unchecked ( ( int ) 0xFFffFFff ) ;
2013-04-07 10:58:58 +01:00
int srcPos = 0 ;
2013-04-28 12:32:55 +01:00
int border = ( dataSize * 2 ) & unchecked ( ( int ) 0xFFffFFff ) ;
SetValue ( false , Mem , VM_GLOBALMEMADDR + 0x20 , ( int ) dataSize ) ;
if ( dataSize > = VM_GLOBALMEMADDR / 2 )
2013-04-07 10:58:58 +01:00
{
break ;
}
// bytes from same channels are grouped to continual data blocks,
// so we need to place them back to their interleaving positions
for ( int curChannel = 0 ; curChannel < channels ; curChannel + + )
{
byte PrevByte = 0 ;
for ( int destPos = dataSize + curChannel ; destPos < border ; destPos + = channels )
{
2013-04-28 12:32:55 +01:00
Mem [ destPos ] = ( PrevByte = ( byte ) ( PrevByte - Mem [ srcPos + + ] ) ) ;
2013-04-07 10:58:58 +01:00
}
}
}
break ;
case VMStandardFilters . VMSF_RGB :
{
// byte *SrcData=Mem,*DestData=SrcData+DataSize;
int dataSize = R [ 4 ] , width = R [ 0 ] - 3 , posR = R [ 1 ] ;
int channels = 3 ;
int srcPos = 0 ;
int destDataPos = dataSize ;
SetValue ( false , Mem , VM_GLOBALMEMADDR + 0x20 , dataSize ) ;
2013-04-28 12:32:55 +01:00
if ( dataSize > = VM_GLOBALMEMADDR / 2 | | posR < 0 )
2013-04-07 10:58:58 +01:00
{
break ;
}
for ( int curChannel = 0 ; curChannel < channels ; curChannel + + )
{
long prevByte = 0 ;
for ( int i = curChannel ; i < dataSize ; i + = channels )
{
long predicted ;
int upperPos = i - width ;
if ( upperPos > = 3 )
{
int upperDataPos = destDataPos + upperPos ;
2013-04-28 12:32:55 +01:00
int upperByte = Mem [ ( int ) upperDataPos ] & 0xff ;
2013-04-07 10:58:58 +01:00
int upperLeftByte = Mem [ upperDataPos - 3 ] & 0xff ;
predicted = prevByte + upperByte - upperLeftByte ;
2013-04-28 12:32:55 +01:00
int pa = System . Math . Abs ( ( int ) ( predicted - prevByte ) ) ;
int pb = System . Math . Abs ( ( int ) ( predicted - upperByte ) ) ;
int pc = System . Math . Abs ( ( int ) ( predicted - upperLeftByte ) ) ;
2013-04-07 10:58:58 +01:00
if ( pa < = pb & & pa < = pc )
{
predicted = prevByte ;
}
else
{
if ( pb < = pc )
{
predicted = upperByte ;
}
else
{
predicted = upperLeftByte ;
}
}
}
else
{
predicted = prevByte ;
}
prevByte = ( predicted - Mem [ srcPos + + ] & 0xff ) & 0xff ;
2013-04-28 12:32:55 +01:00
Mem [ destDataPos + i ] = ( byte ) ( prevByte & 0xff ) ;
2013-04-07 10:58:58 +01:00
}
}
for ( int i = posR , border = dataSize - 2 ; i < border ; i + = 3 )
{
byte G = Mem [ destDataPos + i + 1 ] ;
2013-04-28 12:32:55 +01:00
Mem [ destDataPos + i ] = ( byte ) ( Mem [ destDataPos + i ] + G ) ;
Mem [ destDataPos + i + 2 ] = ( byte ) ( Mem [ destDataPos + i + 2 ] + G ) ;
2013-04-07 10:58:58 +01:00
}
}
break ;
case VMStandardFilters . VMSF_AUDIO :
{
int dataSize = R [ 4 ] , channels = R [ 0 ] ;
int srcPos = 0 ;
int destDataPos = dataSize ;
//byte *SrcData=Mem,*DestData=SrcData+DataSize;
SetValue ( false , Mem , VM_GLOBALMEMADDR + 0x20 , dataSize ) ;
2013-04-28 12:32:55 +01:00
if ( dataSize > = VM_GLOBALMEMADDR / 2 )
2013-04-07 10:58:58 +01:00
{
break ;
}
for ( int curChannel = 0 ; curChannel < channels ; curChannel + + )
{
long prevByte = 0 ;
long prevDelta = 0 ;
long [ ] Dif = new long [ 7 ] ;
int D1 = 0 , D2 = 0 , D3 ;
int K1 = 0 , K2 = 0 , K3 = 0 ;
for ( int i = curChannel , byteCount = 0 ; i < dataSize ; i + = channels , byteCount + + )
{
D3 = D2 ;
2013-04-28 12:32:55 +01:00
D2 = ( int ) ( prevDelta - D1 ) ;
D1 = ( int ) prevDelta ;
2013-04-07 10:58:58 +01:00
2013-04-28 12:32:55 +01:00
long predicted = 8 * prevByte + K1 * D1 + K2 * D2 + K3 * D3 ;
2013-04-07 10:58:58 +01:00
predicted = Utility . URShift ( predicted , 3 ) & 0xff ;
2013-04-28 12:32:55 +01:00
long curByte = ( long ) ( Mem [ srcPos + + ] ) ;
2013-04-07 10:58:58 +01:00
predicted - = curByte ;
2013-04-28 12:32:55 +01:00
Mem [ destDataPos + i ] = ( byte ) predicted ;
prevDelta = ( byte ) ( predicted - prevByte ) ;
2013-04-07 10:58:58 +01:00
//fix java byte
if ( prevDelta > = 128 )
{
prevDelta = 0 - ( 256 - prevDelta ) ;
}
prevByte = predicted ;
//fix java byte
if ( curByte > = 128 )
{
curByte = 0 - ( 256 - curByte ) ;
}
2013-04-28 12:32:55 +01:00
int D = ( ( int ) curByte ) < < 3 ;
2013-04-07 10:58:58 +01:00
Dif [ 0 ] + = System . Math . Abs ( D ) ;
Dif [ 1 ] + = System . Math . Abs ( D - D1 ) ;
Dif [ 2 ] + = System . Math . Abs ( D + D1 ) ;
Dif [ 3 ] + = System . Math . Abs ( D - D2 ) ;
Dif [ 4 ] + = System . Math . Abs ( D + D2 ) ;
Dif [ 5 ] + = System . Math . Abs ( D - D3 ) ;
Dif [ 6 ] + = System . Math . Abs ( D + D3 ) ;
if ( ( byteCount & 0x1f ) = = 0 )
{
long minDif = Dif [ 0 ] , numMinDif = 0 ;
Dif [ 0 ] = 0 ;
for ( int j = 1 ; j < Dif . Length ; j + + )
{
if ( Dif [ j ] < minDif )
{
minDif = Dif [ j ] ;
numMinDif = j ;
}
Dif [ j ] = 0 ;
}
2013-04-28 12:32:55 +01:00
switch ( ( int ) numMinDif )
2013-04-07 10:58:58 +01:00
{
case 1 :
if ( K1 > = - 16 )
K1 - - ;
break ;
case 2 :
if ( K1 < 16 )
K1 + + ;
break ;
case 3 :
if ( K2 > = - 16 )
K2 - - ;
break ;
case 4 :
if ( K2 < 16 )
K2 + + ;
break ;
case 5 :
if ( K3 > = - 16 )
K3 - - ;
break ;
case 6 :
if ( K3 < 16 )
K3 + + ;
break ;
}
}
}
}
}
break ;
case VMStandardFilters . VMSF_UPCASE :
{
int dataSize = R [ 4 ] , srcPos = 0 , destPos = dataSize ;
2013-04-28 12:32:55 +01:00
if ( dataSize > = VM_GLOBALMEMADDR / 2 )
2013-04-07 10:58:58 +01:00
{
break ;
}
while ( srcPos < dataSize )
{
byte curByte = Mem [ srcPos + + ] ;
if ( curByte = = 2 & & ( curByte = Mem [ srcPos + + ] ) ! = 2 )
{
2013-04-28 12:32:55 +01:00
curByte = ( byte ) ( curByte - 32 ) ;
2013-04-07 10:58:58 +01:00
}
Mem [ destPos + + ] = curByte ;
}
SetValue ( false , Mem , VM_GLOBALMEMADDR + 0x1c , destPos - dataSize ) ;
SetValue ( false , Mem , VM_GLOBALMEMADDR + 0x20 , dataSize ) ;
}
break ;
}
}
private void filterItanium_SetBits ( int curPos , int bitField , int bitPos , int bitCount )
{
2013-04-28 12:32:55 +01:00
int inAddr = bitPos / 8 ;
2013-04-07 10:58:58 +01:00
int inBit = bitPos & 7 ;
2013-04-28 12:32:55 +01:00
int andMask = Utility . URShift ( unchecked ( ( int ) 0xffffffff ) , ( 32 - bitCount ) ) ;
2013-04-07 10:58:58 +01:00
andMask = ~ ( andMask < < inBit ) ;
bitField < < = inBit ;
for ( int i = 0 ; i < 4 ; i + + )
{
2013-04-28 12:32:55 +01:00
Mem [ curPos + inAddr + i ] & = ( byte ) ( andMask ) ;
Mem [ curPos + inAddr + i ] | = ( byte ) ( bitField ) ;
andMask = ( Utility . URShift ( andMask , 8 ) ) | unchecked ( ( int ) 0xff000000 ) ;
2013-04-07 10:58:58 +01:00
bitField = Utility . URShift ( bitField , 8 ) ;
}
}
private int filterItanium_GetBits ( int curPos , int bitPos , int bitCount )
{
2013-04-28 12:32:55 +01:00
int inAddr = bitPos / 8 ;
2013-04-07 10:58:58 +01:00
int inBit = bitPos & 7 ;
2013-04-28 12:32:55 +01:00
int bitField = ( int ) ( Mem [ curPos + inAddr + + ] & 0xff ) ;
bitField | = ( int ) ( ( Mem [ curPos + inAddr + + ] & 0xff ) < < 8 ) ;
bitField | = ( int ) ( ( Mem [ curPos + inAddr + + ] & 0xff ) < < 16 ) ;
bitField | = ( int ) ( ( Mem [ curPos + inAddr ] & 0xff ) < < 24 ) ;
2013-04-07 10:58:58 +01:00
bitField = Utility . URShift ( bitField , inBit ) ;
2013-04-28 12:32:55 +01:00
return ( bitField & ( Utility . URShift ( unchecked ( ( int ) 0xffffffff ) , ( 32 - bitCount ) ) ) ) ;
2013-04-07 10:58:58 +01:00
}
public virtual void setMemory ( int pos , byte [ ] data , int offset , int dataSize )
{
if ( pos < VM_MEMSIZE )
{
//&& data!=Mem+Pos)
//memmove(Mem+Pos,Data,Min(DataSize,VM_MEMSIZE-Pos));
for ( int i = 0 ; i < System . Math . Min ( data . Length - offset , dataSize ) ; i + + )
{
if ( ( VM_MEMSIZE - pos ) < i )
{
break ;
}
Mem [ pos + i ] = data [ offset + i ] ;
}
}
}
}
//
}