bsnes/snesreader/unrar/rarvm.hpp

113 lines
2.8 KiB
C++
Raw Permalink Normal View History

Update to bsnes v063 release. Time for another (hopefully) stable release. The changelog has all updates since the last stable release. Most notably, this release features substantial accuracy improvements all around. Almost all of them represent brand new findings never before seen in any SNES emulator. Changelog: - fixed off-by-one buffer size issue in S-PPU RTO calculations [PiCiJi] - added XML parser - added XML-based memory mapping system - moved header-based memory mapping code into snesreader library - added some linker flags for Fedora [belegdol] - added cheat code database; with codes for over 1,500 games [mightymo] - fixed a bug where S-CPU IRQs were being tested one cycle early on direct page indexed read opcodes - added global cheat system enable/disable checkbox to cheat code editor - fixed bug in overflow calculation of S-CPU ADC and SBC opcodes in BCD mode [blargg] - emulated the S-CPU ALU MUL and DIV hardware delays with partial result calculation steps [blargg] - controller port read now returns real-time results of B button when strobe latch is raised - major improvements to emulation of the S-SMP TEST register [blargg, byuu] - fixed DSP2 memory map [Overload] - "Apply Patch" checkbox will now scan UPS patch folder if one is set in the paths section - fixed S-CPU TSC negative flag calculation in emulation mode [address] - added "make uninstall" command to Makefile for Linux users - S-CPU (H)DMA now updates the S-CPU MDR; fixes a freeze in Speedy Gonzales - Stage 6-1 - very substantial code cleanups and optimizations as a result of moving from C++98 to C++0x
2010-03-28 15:46:44 +00:00
#ifndef _RAR_VM_
#define _RAR_VM_
#define VM_STANDARDFILTERS
#ifndef SFX_MODULE
#define VM_OPTIMIZE
#endif
#define VM_MEMSIZE 0x40000
#define VM_MEMMASK (VM_MEMSIZE-1)
#define VM_GLOBALMEMADDR 0x3C000
#define VM_GLOBALMEMSIZE 0x2000
#define VM_FIXEDGLOBALSIZE 64
enum VM_Commands
{
VM_MOV, VM_CMP, VM_ADD, VM_SUB, VM_JZ, VM_JNZ, VM_INC, VM_DEC,
VM_JMP, VM_XOR, VM_AND, VM_OR, VM_TEST, VM_JS, VM_JNS, VM_JB,
VM_JBE, VM_JA, VM_JAE, VM_PUSH, VM_POP, VM_CALL, VM_RET, VM_NOT,
VM_SHL, VM_SHR, VM_SAR, VM_NEG, VM_PUSHA,VM_POPA, VM_PUSHF,VM_POPF,
VM_MOVZX,VM_MOVSX,VM_XCHG, VM_MUL, VM_DIV, VM_ADC, VM_SBB, VM_PRINT,
#ifdef VM_OPTIMIZE
VM_MOVB, VM_MOVD, VM_CMPB, VM_CMPD,
VM_ADDB, VM_ADDD, VM_SUBB, VM_SUBD, VM_INCB, VM_INCD, VM_DECB, VM_DECD,
VM_NEGB, VM_NEGD,
#endif
VM_STANDARD
};
enum VM_StandardFilters {
VMSF_NONE, VMSF_E8, VMSF_E8E9, VMSF_ITANIUM, VMSF_RGB, VMSF_AUDIO,
VMSF_DELTA, VMSF_UPCASE
};
enum VM_Flags {VM_FC=1,VM_FZ=2,VM_FS=0x80000000};
enum VM_OpType {VM_OPREG,VM_OPINT,VM_OPREGMEM,VM_OPNONE};
struct VM_PreparedOperand
{
VM_OpType Type;
uint Data;
uint Base;
uint *Addr;
};
struct VM_PreparedCommand
{
VM_Commands OpCode;
bool ByteMode;
VM_PreparedOperand Op1,Op2;
};
struct VM_PreparedProgram
{
VM_PreparedProgram( Rar_Error_Handler* eh ) : Cmd( eh ), GlobalData( eh ), StaticData( eh )
{AltCmd=NULL;}
Array<VM_PreparedCommand> Cmd;
VM_PreparedCommand *AltCmd;
int CmdCount;
Array<byte> GlobalData;
Array<byte> StaticData; // static data contained in DB operators
uint InitR[7];
byte *FilteredData;
unsigned int FilteredDataSize;
};
class RarVM:private BitInput
{
private:
inline uint GetValue(bool ByteMode,uint *Addr);
inline void SetValue(bool ByteMode,uint *Addr,uint Value);
inline uint* GetOperand(VM_PreparedOperand *CmdOp);
void DecodeArg(VM_PreparedOperand &Op,bool ByteMode);
#ifdef VM_OPTIMIZE
void Optimize(VM_PreparedProgram *Prg);
#endif
bool ExecuteCode(VM_PreparedCommand *PreparedCode,int CodeSize);
#ifdef VM_STANDARDFILTERS
VM_StandardFilters IsStandardFilter(byte *Code,int CodeSize);
void ExecuteStandardFilter(VM_StandardFilters FilterType);
unsigned int FilterItanium_GetBits(byte *Data,int BitPos,int BitCount);
void FilterItanium_SetBits(byte *Data,unsigned int BitField,int BitPos,
int BitCount);
#endif
byte *Mem;
uint R[8];
uint Flags;
public:
RarVM();
~RarVM();
void Init();
void handle_mem_error( Rar_Error_Handler& );
friend class Unpack;
void Prepare(byte *Code,int CodeSize,VM_PreparedProgram *Prg);
void Execute(VM_PreparedProgram *Prg);
void SetLowEndianValue(uint *Addr,uint Value);
void SetMemory(unsigned int Pos,byte *Data,unsigned int DataSize);
static uint ReadData(BitInput &Inp);
};
#endif