I've begun writing an X86 emu for the PSP using code from my other project.
I don't want to use DOSbox because instead of "building DOS into the emulator," it's going to be easier to emulate the DOS binaries.
I've written about 75% of the code so far, but I need a FEW more opcodes (doesn't include the FPU and 0x0F opcodes yet).
I'm writing it in Windows currently.
ANY HELP WILL BE APPRECIATED!
Here's the code so far:
http://jamesseph.phpwebhosting.com/user ... x86emu.rar
Understanding my code (if you wish to help):
flag_ops.inc - contains the flag operations, which are opcodes that change the flags one way or another. So, shl, shr, and add are in there.
vm.h - contains the defines to the registers and misc stuff.
types.h - read these before you start! These are the datatypes which I use.
regs.inc - many of you will think "why did he line the registers like that?" It's simple, it makes mod-r/m byte access faster.
vm.c - contains the switch statement to the individual opcodes. (I'll change it to an array when it's done, this just makes coding easier)
util_ops.inc - MOST IMPORTANT OF ALL I'd say to understanding the emulator. I use defines which are basic but people might overlook them.
If you understand these defines, then you're perfect for the project:
//Reads a dword from RAM
#define vm_ddw() ((dword*)(vm_code + a_rm.address))
//Reads a word from RAM
#define vm_dw() ((word*)(vm_code + a_rm.address))
//Reads a byte from RAM
#define vm_db() ((byte*)(vm_code + a_rm.address))
//Reads a dword from RAM
#define vm_pdw() *((dword*)(vm_code + a_rm.address))
//Reads a word from RAM
#define vm_pw() *((word*)(vm_code + a_rm.address))
//Reads a byte from RAM
#define vm_pb() *((byte*)(vm_code + a_rm.address))
//This is used to check if the mode R/M byte is register to register or not
//Basicly, if a_rm.mode (that's the data from the mod r/m byte) is not 3, do the first statement, if not do the other, check the example below
#define vm_ar(a_a, a_b) if(a_rm.mode != 3) { a_a; } else { a_b; }
//Sample opcode:
case 0x31:
////printf("XOR r/m, reg\n");
vm_rm(); //This fills out the MOD R/M BYTE sttructure
if(vm_prefix[PS]) //Checks if the PREFIX SIZE is there, if not, then use the 16bit version of the opcode, else use the 32bit version
{
vm_ar(vm_xor32(vm_ddw(), vm_reg32[a_rm.reg]), vm_xor32(&vm_reg32[a_rm.rm], vm_reg32[a_rm.reg]));
}
else
{
vm_ar(vm_xor16(vm_dw(), *vm_reg16[a_rm.reg]), vm_xor16(vm_reg16[a_rm.rm], *vm_reg16[a_rm.reg])); //Now, what vm_ar does is interchange between XOR16(MEMORY, REGISTER) and XOR16(REGISTER, REGISTER) depending on the MOD R/M BYTE sttructure
}
break;