GP2X A Great Emulation Doc.


Excellent! Linked on a Spanish forum and only available to members there. Thanks!
 
Click on the first link [file] in this thread's first post. It goes directly to the file.
 
yaustar posted on Aug 19 2006 at 11:40 PM said:
Click on the first link [file] in this thread's first post. It goes directly to the file.

Very tired at the moment. :unsure: Thanks for pointing that one out
 
Last edited by a moderator:
ASK posted on Aug 20 2006 at 05:31 AM said:
Excellent! Linked on a Spanish forum and only available to members there. Thanks!
Sorry :unsure:.
http://personales.ac.upc.edu/vmoya/emulation.html
http://personales.ac.upc.edu/vmoya/docs/emuprog.pdf

Code:
typedef struct codeblock{
	unsigned char* buffer;
	unsigned short size;
	unsigned short indxemitter;
}

Code:
codeblock CB;
CB.buffer = (unsigned char*)malloc(128);
CB.size = 128;
CB.indxbuffer = 0;

void (*executeBlock)() = (void(*)())CB.buffer;
executeBlock(); 
// Assembly code: CALL CB.buffer

Code:
CB.buffer[CB.indxbuffer++] = 0xC3;
executeBlock();

Assembly code:

		 CALL bloque
		 NOP
		 ......

bloque:  RET

Code:
#include "./../global/types.h"

#ifndef __DYNAREC_H__
#define __DYNAREC_H__

typedef struct codeblock
{
	BYTE* buffer;
	DWORD indxemitter;
	DWORD size;
}
codeblock;

/**
 * initCodeBlock
 * Init a code block
 */
void initCodeBlock(codeblock* CB, WORD size);

/**
 * freeCodeBlock
 * Free a code block
 */
void freeCodeBlock(codeblock* CB);

/**
 * executeBlock
 * Exectute a block of code
 */
void executeBlock(codeblock* CB);

/**
 * emitteByte
 * Emitte a byte in codeblock
 */
void emitteByte(register codeblock* CB, BYTE value);

/**
 * emitetWord
 * Emitte a word in codeblock
 */
void emitteWord(register codeblock* CB, WORD value);

/**
 * emitteDWord
 * Emitte a dword in codeblock
 */
void emitteDWord(register codeblock* CB, DWORD value);

#endif //__DYNAREC_H__

Code:
#include "dynarec.h"
#include <assert.h>

void executeBlock(codeblock* CB)
{
	/* Transform the block in a function */
	void (*CBFunction)() = (void(*)())CB->buffer;
	/* Call the block */
	CBFunction();
}

void initCodeBlock(codeblock* CB, WORD size)
{
	CB->buffer = (BYTE*)malloc(size);
	assert(CB->buffer);

	CB->indxemitter = 0;
	CB->size = size;
}

void freeCodeBlock(codeblock* CB)
{
	free(CB->buffer);
	CB->indxemitter = 0;
	CB->size=0;
}

void emitteByte(register codeblock* CB, BYTE value)
{
	CB->buffer[CB->indxemitter++] = value;
}

void emitteWord(register codeblock* CB, WORD value)
{
	*((WORD*)(CB->buffer+CB->indxemitter)) = value;
	CB->indxemitter+=2;
}

void emitteDWord(register codeblock* CB, DWORD value)
{
	*((DWORD*)(CB->buffer+CB->indxemitter)) = value;
	CB->indxemitter+=4;
}

Code:
#include "../../global/types.h"
#include "../dynarec.h"
#include "x86emitter_macros.h"

#ifndef __X86EMITTER_H__
#define __X86EMITTER_H__

typedef enum
{
	EAX = 0, EBX = 3, ECX = 1, EDX = 2,
	ESI = 6, EDI = 7, EBP = 5, ESP = 4
}
X86RegType;

/**
 * emitteH_x86_ModRM
 * The ModRM and SIB bytes follow the opcode byte(s) in many of the processor
 * instructions. They contain the following information:
 • Indexing type or register number to be used in the instruction
 • Register to be used, or more information to select the instruction
 • Base, index, and scale information
 */
void emitteH_x86_ModRM(codeblock* CB,BYTE mod,BYTE rm,X86RegType reg);

/**
 * emitteH_x86_SibSB
 * The ModRM and SIB bytes follow the opcode byte(s) in many of the processor
 * instructions. They contain the following information:
 • Indexing type or register number to be used in the instruction
 • Register to be used, or more information to select the instruction
 • Base, index, and scale information
 */
void emitteH_x86_SibSB(codeblock* CB,BYTE sib,BYTE rm,BYTE index);

/**
 * emit_x86_ret
 * The ret opcode for return
 * of a called function
 */
void x86_x86_ret(codeblock* CB);

/**
 * emit_x86_mov16RtoM
 */
void emit_x86_mov16RtoM(codeblock* CB,X86RegType from,DWORD to);

/**
 * emit_x86_mov16RtoM
 */
void emit_x86_mov16MtoR(codeblock* CB,DWORD from, X86RegType to);

/**
 * emit_x86_mov16ItoR
 */
void emit_x86_mov16ItoR(codeblock* CB,X86RegType to,WORD value);
#endif //__X86EMITTER__
< - >​

Code:
#include "x86emitter.h"

void emitteH_x86_ModRM(codeblock* CB,BYTE mod,BYTE rm,X86RegType reg)
{
	emitteByte(CB,(mod<<6)|(rm<<4)|(reg));
}

void emitteH_x86_SibSB(codeblock* CB,BYTE sib,BYTE rm,BYTE index)
{
	emitteByte(CB,(sib<<6)|(rm<<4)|(index));
}

void emit_x86_ret(register codeblock* CB)
{
	/* Opcode RET */
	emitteByte(CB, 0xC3);
}

void emit_x86_mov16RtoM(codeblock* CB,X86RegType from,DWORD to)
{
	/* Operand size prefix */
	emitteByte(CB, 0x66);
	emitteByte(CB, 0x89);
	/* Addressing form */
	emitteH_x86_ModRM(CB,0,from,DISP32);
	/* Inm Dir */
	emitteDWord(CB, to);
}

void emit_x86_mov16MtoR(codeblock* CB,DWORD from, X86RegType to)
{
	/* Operand size prefix */
	emitteByte(CB, 0x66);
	emitteByte(CB, 0x8B);
	/* Addressing form */
	emitteH_x86_ModRM(CB,0,to,DISP32);
	/* Inm Dir */
	emitteDWord(CB, from);
}

void emit_x86_mov16ItoR(codeblock* CB,X86RegType to,WORD value)
{
	/* Operand size prefix */
	emitteByte(CB, 0x66);
	emitteByte(CB, 0xB8|to);
	/* Inm Num */
	emitteWord(CB, value);
}

Code:
#include "../../global/types.h"

#ifndef __X86EMITTER_MACROS_H__
#define __X86EMITTER_MACROS_H__

#define DISP32	5

#endif //__X86EMITTER_MACROS__




Binary format:

Opcodes:


Code:
	unsigned int value = 0;
	printf("value: %u", value);

	codeblock CB;
	initCodeBlock(&CB, 64);

	emit_x86_mov16ItoR(&CB,EAX,13);
	emit_x86_mov16RtoM(&CB,EAX,(DWORD)&value);
	emit_x86_ret(&CB); // No sus olvide xD
	executeBlock(&CB);

	freeCodeBlock(&CB);

	printf("value: %u", value);

CodeBlock:
Move 13 ---> EAX
Move EAX ---> [&value]
Return

OUPUT: "value: 13"

Code:
emitteByte(CB, 0x66);
emitteByte(CB, 0x89); // 1000 100w Where w=1.
emitteH_x86_ModRM(CB,0,from,DISP32); // Mod=0, Reg=EAX, R/M=DISP32
emitteDWord(CB, to); // 4 Bytes of address
 
Last edited by a moderator:
Back
Top