...writing my own is more fun than I would have thought!

by (no login)

I'll probably just end up using someone else's code in the long run, but this actually does work. For the MOV instruction only! Adding support for more assembly language instructions would be a trivial but time consuming task. If you don't understand this C++ code, then you don't understand enough about how x86 cpu instructions are encoded (or C++?). If you do know how x86 instructions are encoded, then this probably makes sense to you.

//x86 Virtual CMEM emulation
//Note: x86 CPU emulation is still experimental and is not available in QB64 yet.
struct cpu_struct{
//al,ah,ax,eax (unsigned & signed)
union{
struct{
union{
unsigned __int8 al;
__int8 al_signed;
};
union{
unsigned __int8 ah;
__int8 ah_signed;
};
};
unsigned __int16 ax;
__int16 ax_signed;
unsigned __int32 eax;
__int32 eax_signed;
};
//bl,bh,bx,ebx (unsigned & signed)
union{
struct{
union{
unsigned __int8 bl;
__int8 bl_signed;
};
union{
unsigned __int8 bh;
__int8 bh_signed;
};
};
unsigned __int16 bx;
__int16 bx_signed;
unsigned __int32 ebx;
__int32 ebx_signed;
};
//cl,ch,cx,ecx (unsigned & signed)
union{
struct{
union{
unsigned __int8 cl;
__int8 cl_signed;
};
union{
unsigned __int8 ch;
__int8 ch_signed;
};
};
unsigned __int16 cx;
__int16 cx_signed;
unsigned __int32 ecx;
__int32 ecx_signed;
};
//dl,dh,dx,edx (unsigned & signed)
union{
struct{
union{
unsigned __int8 dl;
__int8 dl_signed;
};
union{
unsigned __int8 dh;
__int8 dh_signed;
};
};
unsigned __int16 dx;
__int16 dx_signed;
unsigned __int32 edx;
__int32 edx_signed;
};
//si,esi (unsigned & signed)
union{
unsigned __int16 si;
__int16 si_signed;
unsigned __int32 esi;
__int32 esi_signed;
};
//di,edi (unsigned & signed)
union{
unsigned __int16 di;
__int16 di_signed;
unsigned __int32 edi;
__int32 edi_signed;
};
//bp,ebp (unsigned & signed)
union{
unsigned __int16 bp;
__int16 bp_signed;
unsigned __int32 ebp;
__int32 ebp_signed;
};
//sp,esp (unsigned & signed)
union{
unsigned __int16 sp;
__int16 sp_signed;
unsigned __int32 esp;
__int32 esp_signed;
};
//cs,ss,ds,es,fs,gs (unsigned & signed)
union{
unsigned __int16 cs;
unsigned __int16 cs_signed;
};
union{
unsigned __int16 ss;
unsigned __int16 ss_signed;
};
union{
unsigned __int16 ds;
unsigned __int16 ds_signed;
};
union{
unsigned __int16 es;
unsigned __int16 es_signed;
};
union{
unsigned __int16 fs;
unsigned __int16 fs_signed;
};
union{
unsigned __int16 gs;
unsigned __int16 gs_signed;
};
//ip,eip (unsigned & signed)
union{
unsigned __int16 ip;
unsigned __int16 ip_signed;
unsigned __int32 eip;
unsigned __int32 eip_signed;
};
//flags
unsigned __int8 overflow_flag;
unsigned __int8 direction_flag;
unsigned __int8 interrupt_flag;
unsigned __int8 trap_flag;
unsigned __int8 sign_flag;
unsigned __int8 zero_flag;
unsigned __int8 auxiliary_flag;
unsigned __int8 parity_flag;
unsigned __int8 carry_flag;
};
cpu_struct cpu;

unsigned __int8 *ip;
unsigned __int8 *seg;
unsigned __int8 *reg8[8];
unsigned __int16 *reg16[8];
unsigned __int32 *reg32[8];
unsigned __int16 *segreg[8];
long a32;
long b32;//size of data to read/write in bits is 32

unsigned __int32 sib(){
static unsigned __int32 i;//sib byte
i=*ip++;
switch(i>>6){
case 0:
return *reg32[i&7]+*reg32[i>>3&7];
break;
case 1:
return *reg32[i&7]+(*reg32[i>>3&7]<<1);
break;
case 2:
return *reg32[i&7]+(*reg32[i>>3&7]<<2);
break;
case 3:
return *reg32[i&7]+(*reg32[i>>3&7]<<3);
break;
}
}

unsigned __int32 sib_mod0(){
//Note: Called when top 2 bits of rm byte before sib byte were 0, base register is ignored
// and replaced with an int32 following the sib byte
static unsigned __int32 i;//sib byte
i=*ip++;
if ((i&7)==5){
switch(i>>6){
case 0:
return (*(unsigned __int32*)((ip+=4)-4))+*reg32[i>>3&7];
break;
case 1:
return (*(unsigned __int32*)((ip+=4)-4))+(*reg32[i>>3&7]<<1);
break;
case 2:
return (*(unsigned __int32*)((ip+=4)-4))+(*reg32[i>>3&7]<<2);
break;
case 3:
return (*(unsigned __int32*)((ip+=4)-4))+(*reg32[i>>3&7]<<3);
break;
}
}
switch(i>>6){
case 0:
return *reg32[i&7]+*reg32[i>>3&7];
break;
case 1:
return *reg32[i&7]+(*reg32[i>>3&7]<<1);
break;
case 2:
return *reg32[i&7]+(*reg32[i>>3&7]<<2);
break;
case 3:
return *reg32[i&7]+(*reg32[i>>3&7]<<3);
break;
}
}

unsigned __int8 *rm8(){
static unsigned __int32 i;//r/m byte
i=*ip++;
switch(i>>6){
case 3:
return reg8[i&7];
break;
case 0:
if (a32){
switch(i&7){
case 0: return seg+cpu.ax; break;
case 1: return seg+cpu.cx; break;
case 2: return seg+cpu.dx; break;
case 3: return seg+cpu.bx; break;
case 4: i=sib(); return seg+(unsigned __int16)sib_mod0(); break;
case 5: return seg+(*(unsigned __int16*)((ip+=4)-4)); break;
case 6: return seg+cpu.si; break;
case 7: return seg+cpu.di; break;
}
}else{
switch(i&7){
case 0: return seg+((unsigned __int16)(cpu.bx+cpu.si)); break;
case 1: return seg+((unsigned __int16)(cpu.bx+cpu.di)); break;
case 2: return seg+((unsigned __int16)(cpu.bp+cpu.si)); break;
case 3: return seg+((unsigned __int16)(cpu.bp+cpu.di)); break;
case 4: return seg+cpu.si; break;
case 5: return seg+cpu.di; break;
case 6: return seg+(*(unsigned __int16*)((ip+=2)-2)); break;
case 7: return seg+cpu.bx; break;
}
}
break;
case 1:
if (a32){
switch(i&7){
case 0: return seg+((unsigned __int16)(cpu.eax+*(__int8*)ip++)); break;
case 1: return seg+((unsigned __int16)(cpu.ecx+*(__int8*)ip++)); break;
case 2: return seg+((unsigned __int16)(cpu.edx+*(__int8*)ip++)); break;
case 3: return seg+((unsigned __int16)(cpu.ebx+*(__int8*)ip++)); break;
case 4: i=sib(); return seg+((unsigned __int16)(i+*(__int8*)ip++)); break;
case 5: return seg+((unsigned __int16)(cpu.ebp+*(__int8*)ip++)); break;
case 6: return seg+((unsigned __int16)(cpu.esi+*(__int8*)ip++)); break;
case 7: return seg+((unsigned __int16)(cpu.edi+*(__int8*)ip++)); break;
}
}else{
switch(i&7){
case 0: return seg+((unsigned __int16)(cpu.bx+cpu.si+*(__int8*)ip++)); break;
case 1: return seg+((unsigned __int16)(cpu.bx+cpu.di+*(__int8*)ip++)); break;
case 2: return seg+((unsigned __int16)(cpu.bp+cpu.si+*(__int8*)ip++)); break;
case 3: return seg+((unsigned __int16)(cpu.bp+cpu.di+*(__int8*)ip++)); break;
case 4: return seg+((unsigned __int16)(cpu.si+*(__int8*)ip++)); break;
case 5: return seg+((unsigned __int16)(cpu.di+*(__int8*)ip++)); break;
case 6: return seg+((unsigned __int16)(cpu.bp+*(__int8*)ip++)); break;
case 7: return seg+((unsigned __int16)(cpu.bx+*(__int8*)ip++)); break;
}
}
break;
case 2:
if (a32){
switch(i&7){
case 0: return seg+((unsigned __int16)(cpu.eax+*(unsigned __int32*)((ip+=4)-4))); break;
case 1: return seg+((unsigned __int16)(cpu.ecx+*(unsigned __int32*)((ip+=4)-4))); break;
case 2: return seg+((unsigned __int16)(cpu.edx+*(unsigned __int32*)((ip+=4)-4))); break;
case 3: return seg+((unsigned __int16)(cpu.ebx+*(unsigned __int32*)((ip+=4)-4))); break;
case 4: i=sib(); return seg+((unsigned __int16)(i+*(unsigned __int32*)((ip+=4)-4))); break;
case 5: return seg+((unsigned __int16)(cpu.ebp+*(unsigned __int32*)((ip+=4)-4))); break;
case 6: return seg+((unsigned __int16)(cpu.esi+*(unsigned __int32*)((ip+=4)-4))); break;
case 7: return seg+((unsigned __int16)(cpu.edi+*(unsigned __int32*)((ip+=4)-4))); break;
}
}else{
switch(i&7){
case 0: return seg+((unsigned __int16)(cpu.bx+cpu.si+*(unsigned __int16*)((ip+=2)-2))); break;
case 1: return seg+((unsigned __int16)(cpu.bx+cpu.di+*(unsigned __int16*)((ip+=2)-2))); break;
case 2: return seg+((unsigned __int16)(cpu.bp+cpu.si+*(unsigned __int16*)((ip+=2)-2))); break;
case 3: return seg+((unsigned __int16)(cpu.bp+cpu.di+*(unsigned __int16*)((ip+=2)-2))); break;
case 4: return seg+((unsigned __int16)(cpu.si+*(unsigned __int16*)((ip+=2)-2))); break;
case 5: return seg+((unsigned __int16)(cpu.di+*(unsigned __int16*)((ip+=2)-2))); break;
case 6: return seg+((unsigned __int16)(cpu.bp+*(unsigned __int16*)((ip+=2)-2))); break;
case 7: return seg+((unsigned __int16)(cpu.bx+*(unsigned __int16*)((ip+=2)-2))); break;
}
}
break;
}
}

don't forget to implement sib in rm16 and rm32
unsigned __int16 *rm16(){
static long i;//r/m byte
i=*ip;
switch(i>>6){
case 3:
ip++;
return reg16[i&7];
break;
case 0:
ip++;
if (a32){
switch(i&7){
case 0: return (unsigned __int16*)(seg+cpu.ax); break;
case 1: return (unsigned __int16*)(seg+cpu.cx); break;
case 2: return (unsigned __int16*)(seg+cpu.dx); break;
case 3: return (unsigned __int16*)(seg+cpu.bx); break;
case 4: exit(90); break;//SIB
case 5: return (unsigned __int16*)(seg+(*(unsigned __int16*)((ip+=4)-4))); break;
case 6: return (unsigned __int16*)(seg+cpu.si); break;
case 7: return (unsigned __int16*)(seg+cpu.di); break;
}
}else{
switch(i&7){
case 0: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bx+cpu.si))); break;
case 1: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bx+cpu.di))); break;
case 2: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bp+cpu.si))); break;
case 3: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bp+cpu.di))); break;
case 4: return (unsigned __int16*)(seg+cpu.si); break;
case 5: return (unsigned __int16*)(seg+cpu.di); break;
case 6: return (unsigned __int16*)(seg+(*(unsigned __int16*)((ip+=2)-2))); break;
case 7: return (unsigned __int16*)(seg+cpu.bx); break;
}
}
break;
case 1:
ip++;
if (a32){
switch(i&7){
case 0: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.eax+*(__int8*)ip++))); break;
case 1: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.ecx+*(__int8*)ip++))); break;
case 2: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.edx+*(__int8*)ip++))); break;
case 3: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.ebx+*(__int8*)ip++))); break;
case 4: exit(90); break;//disp8+SIB
case 5: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.ebp+*(__int8*)ip++))); break;
case 6: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.esi+*(__int8*)ip++))); break;
case 7: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.edi+*(__int8*)ip++))); break;
}
}else{
switch(i&7){
case 0: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bx+cpu.si+*(__int8*)ip++))); break;
case 1: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bx+cpu.di+*(__int8*)ip++))); break;
case 2: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bp+cpu.si+*(__int8*)ip++))); break;
case 3: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bp+cpu.di+*(__int8*)ip++))); break;
case 4: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.si+*(__int8*)ip++))); break;
case 5: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.di+*(__int8*)ip++))); break;
case 6: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bp+*(__int8*)ip++))); break;
case 7: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bx+*(__int8*)ip++))); break;
}
}
break;
case 2:
ip++;
if (a32){
switch(i&7){
case 0: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.eax+*(unsigned __int32*)((ip+=4)-4)))); break;
case 1: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.ecx+*(unsigned __int32*)((ip+=4)-4)))); break;
case 2: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.edx+*(unsigned __int32*)((ip+=4)-4)))); break;
case 3: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.ebx+*(unsigned __int32*)((ip+=4)-4)))); break;
case 4: exit(90); break;//disp32+SIB
case 5: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.ebp+*(unsigned __int32*)((ip+=4)-4)))); break;
case 6: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.esi+*(unsigned __int32*)((ip+=4)-4)))); break;
case 7: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.edi+*(unsigned __int32*)((ip+=4)-4)))); break;
}
}else{
switch(i&7){
case 0: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bx+cpu.si+*(unsigned __int16*)((ip+=2)-2)))); break;
case 1: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bx+cpu.di+*(unsigned __int16*)((ip+=2)-2)))); break;
case 2: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bp+cpu.si+*(unsigned __int16*)((ip+=2)-2)))); break;
case 3: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bp+cpu.di+*(unsigned __int16*)((ip+=2)-2)))); break;
case 4: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.si+*(unsigned __int16*)((ip+=2)-2)))); break;
case 5: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.di+*(unsigned __int16*)((ip+=2)-2)))); break;
case 6: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bp+*(unsigned __int16*)((ip+=2)-2)))); break;
case 7: return (unsigned __int16*)(seg+((unsigned __int16)(cpu.bx+*(unsigned __int16*)((ip+=2)-2)))); break;
}
}
break;
}
}

unsigned __int32 *rm32(){
static long i;//r/m byte
i=*ip;
switch(i>>6){
case 3:
ip++;
return reg32[i&7];
break;
case 0:
ip++;
if (a32){
switch(i&7){
case 0: return (unsigned __int32*)(seg+cpu.ax); break;
case 1: return (unsigned __int32*)(seg+cpu.cx); break;
case 2: return (unsigned __int32*)(seg+cpu.dx); break;
case 3: return (unsigned __int32*)(seg+cpu.bx); break;
case 4: exit(90); break;//SIB
case 5: return (unsigned __int32*)(seg+(*(unsigned __int16*)((ip+=4)-4))); break;
case 6: return (unsigned __int32*)(seg+cpu.si); break;
case 7: return (unsigned __int32*)(seg+cpu.di); break;
}
}else{
switch(i&7){
case 0: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bx+cpu.si))); break;
case 1: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bx+cpu.di))); break;
case 2: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bp+cpu.si))); break;
case 3: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bp+cpu.di))); break;
case 4: return (unsigned __int32*)(seg+cpu.si); break;
case 5: return (unsigned __int32*)(seg+cpu.di); break;
case 6: return (unsigned __int32*)(seg+(*(unsigned __int16*)((ip+=2)-2))); break;
case 7: return (unsigned __int32*)(seg+cpu.bx); break;
}
}
break;
case 1:
ip++;
if (a32){
switch(i&7){
case 0: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.eax+*(__int8*)ip++))); break;
case 1: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.ecx+*(__int8*)ip++))); break;
case 2: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.edx+*(__int8*)ip++))); break;
case 3: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.ebx+*(__int8*)ip++))); break;
case 4: exit(90); break;//disp8+SIB
case 5: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.ebp+*(__int8*)ip++))); break;
case 6: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.esi+*(__int8*)ip++))); break;
case 7: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.edi+*(__int8*)ip++))); break;
}
}else{
switch(i&7){
case 0: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bx+cpu.si+*(__int8*)ip++))); break;
case 1: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bx+cpu.di+*(__int8*)ip++))); break;
case 2: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bp+cpu.si+*(__int8*)ip++))); break;
case 3: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bp+cpu.di+*(__int8*)ip++))); break;
case 4: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.si+*(__int8*)ip++))); break;
case 5: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.di+*(__int8*)ip++))); break;
case 6: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bp+*(__int8*)ip++))); break;
case 7: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bx+*(__int8*)ip++))); break;
}
}
break;
case 2:
ip++;
if (a32){
switch(i&7){
case 0: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.eax+*(unsigned __int32*)((ip+=4)-4)))); break;
case 1: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.ecx+*(unsigned __int32*)((ip+=4)-4)))); break;
case 2: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.edx+*(unsigned __int32*)((ip+=4)-4)))); break;
case 3: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.ebx+*(unsigned __int32*)((ip+=4)-4)))); break;
case 4: exit(90); break;//disp32+SIB
case 5: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.ebp+*(unsigned __int32*)((ip+=4)-4)))); break;
case 6: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.esi+*(unsigned __int32*)((ip+=4)-4)))); break;
case 7: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.edi+*(unsigned __int32*)((ip+=4)-4)))); break;
}
}else{
switch(i&7){
case 0: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bx+cpu.si+*(unsigned __int16*)((ip+=2)-2)))); break;
case 1: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bx+cpu.di+*(unsigned __int16*)((ip+=2)-2)))); break;
case 2: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bp+cpu.si+*(unsigned __int16*)((ip+=2)-2)))); break;
case 3: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bp+cpu.di+*(unsigned __int16*)((ip+=2)-2)))); break;
case 4: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.si+*(unsigned __int16*)((ip+=2)-2)))); break;
case 5: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.di+*(unsigned __int16*)((ip+=2)-2)))); break;
case 6: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bp+*(unsigned __int16*)((ip+=2)-2)))); break;
case 7: return (unsigned __int32*)(seg+((unsigned __int16)(cpu.bx+*(unsigned __int16*)((ip+=2)-2)))); break;
}
}
break;
}
}

unsigned __int8* seg_es_ptr;
unsigned __int8* seg_cs_ptr;
unsigned __int8* seg_ss_ptr;
unsigned __int8* seg_ds_ptr;
unsigned __int8* seg_fs_ptr;
unsigned __int8* seg_gs_ptr;

#define op_r i&7
void cpu_call(){

static long i,i2,i3,x,x2,x3,y,y2,y3;
static unsigned char b,b2,b3;
static unsigned __int8 *uint8p;
static unsigned __int16 *uint16p;
static unsigned __int32 *uint32p;
static unsigned __int8* dseg;
static long r;
ip=(unsigned __int8*)&cmem[cpu.cs*16+cpu.ip];
seg=(unsigned __int8*)&cmem[cpu.ds];

seg_es_ptr=(unsigned __int8*)cmem+cpu.es*16;
seg_cs_ptr=(unsigned __int8*)cmem+cpu.cs*16;
seg_ss_ptr=(unsigned __int8*)cmem+cpu.ss*16;
seg_ds_ptr=(unsigned __int8*)cmem+cpu.ds*16;
seg_fs_ptr=(unsigned __int8*)cmem+cpu.fs*16;
seg_gs_ptr=(unsigned __int8*)cmem+cpu.gs*16;


next_opcode:
b32=0; a32=0; seg=seg_ds_ptr;
i=*ip++;

//read any prefixes
if (i==0x66){b32=1; i=*ip++;}
if (i==0x26){seg=seg_es_ptr; i=*ip++;}
if (i==0x2E){seg=seg_cs_ptr; i=*ip++;}
if (i==0x36){seg=seg_ss_ptr; i=*ip++;}
if (i==0x3E){seg=seg_ds_ptr; i=*ip++;}
if (i==0x64){seg=seg_fs_ptr; i=*ip++;}
if (i==0x65){seg=seg_gs_ptr; i=*ip++;}
if (i==0x67){a32=1; i=*ip++;}

r=*ip>>3&7;

//mov
if (i!=0x8D){
if (i>=0x88&&i<=0x8E){
switch(i){
case 0x88:// /r r/m8,r8
*rm8()=*reg8[r];
break;
case 0x89:// /r r/m16(32),r16(32)
if (b32) *rm32()=*reg32[r]; else *rm16()=*reg16[r];
break;
case 0x8A:// /r r8,r/m8
*reg8[r]=*rm8();
break;
case 0x8B:// /r r16(32),r/m16(32)
if (b32) *reg32[r]=*rm32(); else *reg16[r]=*rm16();
break;
case 0x8C:// /r r/m16,Sreg
*rm16()=*segreg[r];
break;
case 0x8E:// /r Sreg,r/m16
*segreg[r]=*rm16();
if (i2==0) seg_es_ptr=(unsigned __int8*)cmem+*segreg[r]*16;
//CS (i2==1) cannot be set
if (i2==2) seg_ss_ptr=(unsigned __int8*)cmem+*segreg[r]*16;
if (i2==3) seg_ds_ptr=(unsigned __int8*)cmem+*segreg[r]*16;
if (i2==4) seg_fs_ptr=(unsigned __int8*)cmem+*segreg[r]*16;
if (i2==5) seg_gs_ptr=(unsigned __int8*)cmem+*segreg[r]*16;
break;
}
goto done;
}
}
if (i>=0xA0&&i<=0xA3){
switch(i){
case 0xA0:// al,moffs8
cpu.al=*(seg+*(unsigned __int16*)ip); ip+=2;
break;
case 0xA1:// (e)ax,moffs16(32)
if (b32){cpu.eax=*(unsigned __int32*)(seg+*(unsigned __int16*)ip); ip+=2;}else{cpu.ax=*(unsigned __int16*)(seg+*(unsigned __int16*)ip); ip+=2;}
break;
case 0xA2:// moffs8,al
*(seg+*(unsigned __int16*)ip)=cpu.al; ip+=2;
break;
case 0xA3:// moffs16(32),(e)ax
if (b32){*(unsigned __int32*)(seg+*(unsigned __int16*)ip)=cpu.eax; ip+=2;}else{*(unsigned __int16*)(seg+*(unsigned __int16*)ip)=cpu.ax; ip+=2;}
break;
}
goto done;
}
if (i>=0xB0&&i<=0xB7){// +rb reg8,imm8
*reg8[op_r]=*ip++;
goto done;
}
if (i>=0xB8&&i<=0xBF){// +rw(rd) reg16(32),imm16(32)
if (b32){*reg32[op_r]=*(unsigned __int32*)ip; ip+=4;}else{*reg16[op_r]=*(unsigned __int16*)ip; ip+=2;}
goto done;
}
if (i==0xC6){// r/m8,imm8
uint8p=rm8(); *uint8p=*ip++;
goto done;
}
if (i==0xC7){// r/m16(32),imm16(32)
if (b32){uint32p=rm32(); *uint32p=*(unsigned __int32*)ip; ip+=4;}else{uint16p=rm16(); *uint16p=*(unsigned __int16*)ip; ip+=2;}
goto done;
}



MessageBox(NULL,"Unknown Opcode","X86 Error",MB_OK);
exit(i);
done:
if (*ip) goto next_opcode;


exit(cmem[0]);

}

Posted on May 11, 2008, 5:05 AM
from IP address 122.104.40.79

Respond to this message   

Return to Index


Response TitleAuthor and Date
Not bad at all Galleon.... on May 11
This CALL ABSOLUTE QBASIC mouse routine now works in QB64! on May 14
 * Cool! Tell me when your company goes public. I want in on the IPO.Pete on May 14
  * Too much redundancy. Why not check for mouse once? on May 14
   *Not Galleon's... Author = TFM. Galleon is just stating it works in QB64.Pete on May 14
    Great! I guess Interrupt is next. Don't forget 21 for DOS files. on May 14
     * You forgot your asterisk. Since you've been good on parole, I'll let it slide this time.Asterisk Police on May 14
      ** You'ze is an assterisk on May 14
     The code uses interrupts from CALL ABSOLUTEqbguy on May 15
      Here's the INTERRUPT-USING-ABSOLUTE code I use if Galleon wants to test itqbguy on May 15
       Thanks for sharing that one qbguy... on May 16
      RE: Unless we only have interrupt 33 for mouse and all the other ones do nothing. on May 16
       just a quick note to say keep up the good workmennonite on May 16
        Thank you! (+RE: it'll be wonderful when it's open source) on May 16
         I'd be happy to pay for it...Pete on May 16
          Well you could say in the license something about maintaining QBASIC compatibilityqbguy on May 16
           Re: Well you could say in the license something about maintaining QBASIC compatibility on May 22
            You don't need no freaking Liscense! on May 23
             Lawsuits are strickly follow the money but open source makes it volnuerable to abuse. on May 23
              Making it open source has the exact advantage that you stated - contributions by othersrpgfan3233 on May 23
               Look at what happened to FB on May 23
              i address that (common) myth in something i posted recentlymennonite on May 23
               What trademark? There is no trademark... on May 23
                at least offer a serious reply so i know what one looks likemennonite on May 23
                 My view on IP and open sourceroy on May 24
                Cost of filing a trademarkqbguy on May 24
             * Ah, but you forget - FB borrows things from QB _AND_ VB, and it is open source! ;-)rpgfan3233 on May 23
              RPG is one of my favorite people to discuss topics with... on May 23
               * Hmm... You raise some good points that I can't possibly argue against. Great reasoning!rpgfan3233 on May 23
               you're wrong about who can help galleonmennonite on May 24
         * The C++ code is all in the qbx.cpp in the internal folder?qbguy on May 16
          Depending on what C++ code you're looking for, yes, it is.rpgfan3233 on May 23