Interpreter and dynamic recompiler now present in a single binary.

This commit is contained in:
TomW 2015-08-21 20:55:36 +01:00
commit f339f00315
25 changed files with 365 additions and 1208 deletions

899
src/386.c
View file

@ -1,4 +1,3 @@
#ifndef DYNAREC
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
@ -14,9 +13,11 @@
#define CPU_BLOCK_END()
extern int codegen_flags_changed;
x86seg *ea_seg;
int nmi_enable = 1;
extern int nmi_enable;
int inscounts[256];
uint32_t oldpc2;
@ -25,10 +26,10 @@ int trap;
int cpl_override=0;
extern int cpl_override;
int has_fpu;
int fpucount=0;
extern int fpucount;
int times;
uint16_t rds;
uint16_t ea_rseg;
@ -46,7 +47,7 @@ uint32_t rmdat32;
#define rmdat rmdat32
#define fetchdat rmdat32
uint32_t backupregs[16];
int oddeven=0;
extern int oddeven;
int inttype,abrt;
@ -180,897 +181,16 @@ static inline void fetch_ea_16_long(uint32_t rmdat)
#include "x86_flags.h"
void x86_int(int num)
{
uint32_t addr;
// pclog("x86_int\n");
flags_rebuild();
pc=oldpc;
if (msw&1)
{
pmodeint(num,0);
}
else
{
if (stack32)
{
writememw(ss,ESP-2,flags);
writememw(ss,ESP-4,CS);
writememw(ss,ESP-6,pc);
ESP-=6;
}
else
{
writememw(ss,((SP-2)&0xFFFF),flags);
writememw(ss,((SP-4)&0xFFFF),CS);
writememw(ss,((SP-6)&0xFFFF),pc);
SP-=6;
}
addr = (num << 2) + idt.base;
flags&=~I_FLAG;
flags&=~T_FLAG;
oxpc=pc;
pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2));
}
cycles-=70;
CPU_BLOCK_END();
}
void x86_int_sw(int num)
{
uint32_t addr;
// pclog("x86_int\n");
flags_rebuild();
if (msw&1)
{
pmodeint(num,1);
}
else
{
if (stack32)
{
writememw(ss,ESP-2,flags);
writememw(ss,ESP-4,CS);
writememw(ss,ESP-6,pc);
ESP-=6;
}
else
{
writememw(ss,((SP-2)&0xFFFF),flags);
writememw(ss,((SP-4)&0xFFFF),CS);
writememw(ss,((SP-6)&0xFFFF),pc);
SP-=6;
}
addr = (num << 2) + idt.base;
flags&=~I_FLAG;
flags&=~T_FLAG;
oxpc=pc;
pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2));
}
cycles-=70;
trap = 0;
CPU_BLOCK_END();
}
void x86illegal()
{
uint16_t addr;
// pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode);
// if (output)
// {
// dumpregs();
// exit(-1);
// }
x86_int(6);
}
int rep386(int fv)
{
uint8_t temp;
uint32_t c;//=CX;
uint8_t temp2;
uint16_t tempw,tempw2,of;
uint32_t ipc=oldpc;//pc-1;
uint32_t oldds;
uint32_t rep32=op32;
uint32_t templ,templ2;
int tempz;
int tempi;
flags_rebuild();
of = flags;
// if (output) pclog("REP32 %04X %04X ",use32,rep32);
startrep:
temp=opcode2=readmemb(cs,pc); pc++;
// if (firstrepcycle && temp==0xA5) pclog("REP MOVSW %06X:%04X %06X:%04X\n",ds,SI,es,DI);
// if (output) pclog("REP %02X %04X\n",temp,ipc);
c=(rep32&0x200)?ECX:CX;
/* if (rep32 && (msw&1))
{
if (temp!=0x67 && temp!=0x66 && (rep32|temp)!=0x1AB && (rep32|temp)!=0x3AB) pclog("32-bit REP %03X %08X %04X:%06X\n",temp|rep32,c,CS,pc);
}*/
switch (temp|rep32)
{
case 0xC3: case 0x1C3: case 0x2C3: case 0x3C3:
pc--;
break;
case 0x08:
pc=ipc+1;
break;
case 0x26: case 0x126: case 0x226: case 0x326: /*ES:*/
ea_seg = &_es;
goto startrep;
break;
case 0x2E: case 0x12E: case 0x22E: case 0x32E: /*CS:*/
ea_seg = &_cs;
goto startrep;
case 0x36: case 0x136: case 0x236: case 0x336: /*SS:*/
ea_seg = &_ss;
goto startrep;
case 0x3E: case 0x13E: case 0x23E: case 0x33E: /*DS:*/
ea_seg = &_ds;
goto startrep;
case 0x64: case 0x164: case 0x264: case 0x364: /*FS:*/
ea_seg = &_fs;
goto startrep;
case 0x65: case 0x165: case 0x265: case 0x365: /*GS:*/
ea_seg = &_gs;
goto startrep;
case 0x66: case 0x166: case 0x266: case 0x366: /*Data size prefix*/
rep32 = (rep32 & 0x200) | ((use32 ^ 0x100) & 0x100);
goto startrep;
case 0x67: case 0x167: case 0x267: case 0x367: /*Address size prefix*/
rep32 = (rep32 & 0x100) | ((use32 ^ 0x200) & 0x200);
goto startrep;
case 0x6C: case 0x16C: /*REP INSB*/
if (c>0)
{
checkio_perm(DX);
temp2=inb(DX);
writememb(es,DI,temp2);
if (abrt) break;
if (flags&D_FLAG) DI--;
else DI++;
c--;
cycles-=15;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x26C: case 0x36C: /*REP INSB*/
if (c>0)
{
checkio_perm(DX);
temp2=inb(DX);
writememb(es,EDI,temp2);
if (abrt) break;
if (flags&D_FLAG) EDI--;
else EDI++;
c--;
cycles-=15;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x6D: /*REP INSW*/
if (c>0)
{
tempw=inw(DX);
writememw(es,DI,tempw);
if (abrt) break;
if (flags&D_FLAG) DI-=2;
else DI+=2;
c--;
cycles-=15;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x16D: /*REP INSL*/
if (c>0)
{
templ=inl(DX);
writememl(es,DI,templ);
if (abrt) break;
if (flags&D_FLAG) DI-=4;
else DI+=4;
c--;
cycles-=15;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x26D: /*REP INSW*/
if (c>0)
{
tempw=inw(DX);
writememw(es,EDI,tempw);
if (abrt) break;
if (flags&D_FLAG) EDI-=2;
else EDI+=2;
c--;
cycles-=15;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x36D: /*REP INSL*/
if (c>0)
{
templ=inl(DX);
writememl(es,EDI,templ);
if (abrt) break;
if (flags&D_FLAG) EDI-=4;
else EDI+=4;
c--;
cycles-=15;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x6E: case 0x16E: /*REP OUTSB*/
if (c>0)
{
temp2 = readmemb(ea_seg->base, SI);
if (abrt) break;
checkio_perm(DX);
outb(DX,temp2);
if (flags&D_FLAG) SI--;
else SI++;
c--;
cycles-=14;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x26E: case 0x36E: /*REP OUTSB*/
if (c>0)
{
temp2 = readmemb(ea_seg->base, ESI);
if (abrt) break;
checkio_perm(DX);
outb(DX,temp2);
if (flags&D_FLAG) ESI--;
else ESI++;
c--;
cycles-=14;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x6F: /*REP OUTSW*/
if (c>0)
{
tempw = readmemw(ea_seg->base, SI);
if (abrt) break;
// pclog("OUTSW %04X -> %04X\n",SI,tempw);
outw(DX,tempw);
if (flags&D_FLAG) SI-=2;
else SI+=2;
c--;
cycles-=14;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x16F: /*REP OUTSL*/
if (c > 0)
{
templ = readmeml(ea_seg->base, SI);
if (abrt) break;
outl(DX, templ);
if (flags & D_FLAG) SI -= 4;
else SI += 4;
c--;
cycles -= 14;
}
if (c > 0) { firstrepcycle = 0; pc = ipc; }
else firstrepcycle = 1;
break;
case 0x26F: /*REP OUTSW*/
if (c>0)
{
tempw = readmemw(ea_seg->base, ESI);
if (abrt) break;
outw(DX,tempw);
if (flags&D_FLAG) ESI-=2;
else ESI+=2;
c--;
cycles-=14;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x36F: /*REP OUTSL*/
if (c > 0)
{
templ = readmeml(ea_seg->base, ESI);
if (abrt) break;
outl(DX, templ);
if (flags & D_FLAG) ESI -= 4;
else ESI += 4;
c--;
cycles -= 14;
}
if (c > 0) { firstrepcycle = 0; pc = ipc; }
else firstrepcycle = 1;
break;
case 0x90: case 0x190: /*REP NOP*/
case 0x290: case 0x390:
break;
case 0xA4: case 0x1A4: /*REP MOVSB*/
if (c>0)
{
CHECK_WRITE_REP(&_es, DI, DI);
temp2 = readmemb(ea_seg->base, SI); if (abrt) break;
writememb(es,DI,temp2); if (abrt) break;
// if (output==3) pclog("MOVSB %08X:%04X -> %08X:%04X %02X\n",ds,SI,es,DI,temp2);
if (flags&D_FLAG) { DI--; SI--; }
else { DI++; SI++; }
c--;
cycles-=(is486)?3:4;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x2A4: case 0x3A4: /*REP MOVSB*/
if (c>0)
{
CHECK_WRITE_REP(&_es, EDI, EDI);
temp2 = readmemb(ea_seg->base, ESI); if (abrt) break;
writememb(es,EDI,temp2); if (abrt) break;
if (flags&D_FLAG) { EDI--; ESI--; }
else { EDI++; ESI++; }
c--;
cycles-=(is486)?3:4;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0xA5: /*REP MOVSW*/
if (c>0)
{
CHECK_WRITE_REP(&_es, DI, DI+1);
tempw = readmemw(ea_seg->base, SI); if (abrt) break;
writememw(es,DI,tempw); if (abrt) break;
if (flags&D_FLAG) { DI-=2; SI-=2; }
else { DI+=2; SI+=2; }
c--;
cycles-=(is486)?3:4;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x1A5: /*REP MOVSL*/
if (c>0)
{
CHECK_WRITE_REP(&_es, DI, DI+3);
templ = readmeml(ea_seg->base, SI); if (abrt) break;
// pclog("MOVSD %08X from %08X to %08X (%04X:%08X)\n", templ, ds+SI, es+DI, CS, pc);
writememl(es,DI,templ); if (abrt) break;
if (flags&D_FLAG) { DI-=4; SI-=4; }
else { DI+=4; SI+=4; }
c--;
cycles-=(is486)?3:4;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x2A5: /*REP MOVSW*/
if (c>0)
{
CHECK_WRITE_REP(&_es, EDI, EDI+1);
tempw = readmemw(ea_seg->base, ESI); if (abrt) break;
writememw(es,EDI,tempw); if (abrt) break;
// if (output) pclog("Written %04X from %08X to %08X %i %08X %04X %08X %04X\n",tempw,ds+ESI,es+EDI,c,ds,ES,es,ES);
if (flags&D_FLAG) { EDI-=2; ESI-=2; }
else { EDI+=2; ESI+=2; }
c--;
cycles-=(is486)?3:4;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x3A5: /*REP MOVSL*/
if (c>0)
{
CHECK_WRITE_REP(&_es, EDI, EDI+3);
templ = readmeml(ea_seg->base, ESI); if (abrt) break;
// if ((EDI&0xFFFF0000)==0xA0000) cycles-=12;
writememl(es,EDI,templ); if (abrt) break;
// if (output) pclog("Load %08X from %08X to %08X %04X %08X %04X %08X\n",templ,ESI,EDI,DS,ds,ES,es);
if (flags&D_FLAG) { EDI-=4; ESI-=4; }
else { EDI+=4; ESI+=4; }
c--;
cycles-=(is486)?3:4;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0xA6: case 0x1A6: /*REP CMPSB*/
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
temp = readmemb(ea_seg->base, SI);
temp2=readmemb(es,DI);
if (abrt) { flags=of; break; }
if (flags&D_FLAG) { DI--; SI--; }
else { DI++; SI++; }
c--;
cycles-=(is486)?7:9;
setsub8(temp,temp2);
tempz = (ZF_SET()) ? 1 : 0;
}
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
else firstrepcycle=1;
break;
case 0x2A6: case 0x3A6: /*REP CMPSB*/
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
temp = readmemb(ea_seg->base, ESI);
temp2=readmemb(es,EDI);
if (abrt) { flags=of; break; }
if (flags&D_FLAG) { EDI--; ESI--; }
else { EDI++; ESI++; }
c--;
cycles-=(is486)?7:9;
setsub8(temp,temp2);
tempz = (ZF_SET()) ? 1 : 0;
}
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
else firstrepcycle=1;
break;
case 0xA7: /*REP CMPSW*/
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
// pclog("CMPSW %05X %05X %08X %08X ", ds+SI, es+DI, readlookup2[(ds+SI)>>12], readlookup2[(es+DI)>>12]);
tempw = readmemw(ea_seg->base, SI);
tempw2=readmemw(es,DI);
// pclog("%04X %04X %02X\n", tempw, tempw2, ram[8]);
if (abrt) { flags=of; break; }
if (flags&D_FLAG) { DI-=2; SI-=2; }
else { DI+=2; SI+=2; }
c--;
cycles-=(is486)?7:9;
setsub16(tempw,tempw2);
tempz = (ZF_SET()) ? 1 : 0;
}
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
else firstrepcycle=1;
break;
case 0x1A7: /*REP CMPSL*/
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
templ = readmeml(ea_seg->base, SI);
templ2=readmeml(es,DI);
if (abrt) { flags=of; break; }
if (flags&D_FLAG) { DI-=4; SI-=4; }
else { DI+=4; SI+=4; }
c--;
cycles-=(is486)?7:9;
setsub32(templ,templ2);
tempz = (ZF_SET()) ? 1 : 0;
}
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
else firstrepcycle=1;
break;
case 0x2A7: /*REP CMPSW*/
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
tempw = readmemw(ea_seg->base, ESI);
tempw2=readmemw(es,EDI);
if (abrt) { flags=of; break; }
if (flags&D_FLAG) { EDI-=2; ESI-=2; }
else { EDI+=2; ESI+=2; }
c--;
cycles-=(is486)?7:9;
setsub16(tempw,tempw2);
tempz = (ZF_SET()) ? 1 : 0;
}
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
else firstrepcycle=1;
break;
case 0x3A7: /*REP CMPSL*/
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
templ = readmeml(ea_seg->base, ESI);
templ2=readmeml(es,EDI);
if (abrt) { flags=of; break; }
if (flags&D_FLAG) { EDI-=4; ESI-=4; }
else { EDI+=4; ESI+=4; }
c--;
cycles-=(is486)?7:9;
setsub32(templ,templ2);
tempz = (ZF_SET()) ? 1 : 0;
}
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
else firstrepcycle=1;
break;
case 0xAA: case 0x1AA: /*REP STOSB*/
if (c>0)
{
CHECK_WRITE_REP(&_es, DI, DI);
writememb(es,DI,AL);
if (abrt) break;
if (flags&D_FLAG) DI--;
else DI++;
c--;
cycles-=(is486)?4:5;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x2AA: case 0x3AA: /*REP STOSB*/
if (c>0)
{
CHECK_WRITE_REP(&_es, EDI, EDI);
writememb(es,EDI,AL);
if (abrt) break;
if (flags&D_FLAG) EDI--;
else EDI++;
c--;
cycles-=(is486)?4:5;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0xAB: /*REP STOSW*/
if (c>0)
{
CHECK_WRITE_REP(&_es, DI, DI+1);
writememw(es,DI,AX);
if (abrt) break;
if (flags&D_FLAG) DI-=2;
else DI+=2;
c--;
cycles-=(is486)?4:5;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x2AB: /*REP STOSW*/
if (c>0)
{
CHECK_WRITE_REP(&_es, EDI, EDI+1);
writememw(es,EDI,AX);
if (abrt) break;
if (flags&D_FLAG) EDI-=2;
else EDI+=2;
c--;
cycles-=(is486)?4:5;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x1AB: /*REP STOSL*/
if (c>0)
{
CHECK_WRITE_REP(&_es, DI, DI+3);
writememl(es,DI,EAX);
if (abrt) break;
if (flags&D_FLAG) DI-=4;
else DI+=4;
c--;
cycles-=(is486)?4:5;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x3AB: /*REP STOSL*/
if (c>0)
{
CHECK_WRITE_REP(&_es, EDI, EDI+3);
writememl(es,EDI,EAX);
if (abrt) break;
if (flags&D_FLAG) EDI-=4;
else EDI+=4;
c--;
cycles-=(is486)?4:5;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0xAC: case 0x1AC: /*REP LODSB*/
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc);
if (c>0)
{
AL = readmemb(ea_seg->base, SI);
if (abrt) break;
if (flags&D_FLAG) SI--;
else SI++;
c--;
cycles-=5;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x2AC: case 0x3AC: /*REP LODSB*/
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc);
if (c>0)
{
AL = readmemb(ea_seg->base, ESI);
if (abrt) break;
if (flags&D_FLAG) ESI--;
else ESI++;
c--;
cycles-=5;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0xAD: /*REP LODSW*/
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc);
if (c>0)
{
AX = readmemw(ea_seg->base, SI);
if (abrt) break;
if (flags&D_FLAG) SI-=2;
else SI+=2;
c--;
cycles-=5;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x1AD: /*REP LODSL*/
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc);
if (c>0)
{
EAX = readmeml(ea_seg->base, SI);
if (abrt) break;
if (flags&D_FLAG) SI-=4;
else SI+=4;
c--;
cycles-=5;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x2AD: /*REP LODSW*/
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc);
if (c>0)
{
AX = readmemw(ea_seg->base, ESI);
if (abrt) break;
if (flags&D_FLAG) ESI-=2;
else ESI+=2;
c--;
cycles-=5;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x3AD: /*REP LODSL*/
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc);
if (c>0)
{
EAX = readmeml(ea_seg->base, ESI);
if (abrt) break;
if (flags&D_FLAG) ESI-=4;
else ESI+=4;
c--;
cycles-=5;
}
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0xAE: case 0x1AE: /*REP SCASB*/
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc);
// tempz=(fv)?1:0;
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
temp2=readmemb(es,DI);
if (abrt) { flags=of; break; }
setsub8(AL,temp2);
tempz = (ZF_SET()) ? 1 : 0;
if (flags&D_FLAG) DI--;
else DI++;
c--;
cycles-=(is486)?5:8;
}
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
else firstrepcycle=1;
break;
case 0x2AE: case 0x3AE: /*REP SCASB*/
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc);
// tempz=(fv)?1:0;
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
temp2=readmemb(es,EDI);
if (abrt) { flags=of; break; }
// if (output) pclog("Compare %02X,%02X\n",temp2,AL);
setsub8(AL,temp2);
tempz = (ZF_SET()) ? 1 : 0;
if (flags&D_FLAG) EDI--;
else EDI++;
c--;
cycles-=(is486)?5:8;
}
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
else firstrepcycle=1;
break;
case 0xAF: /*REP SCASW*/
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc);
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
tempw=readmemw(es,DI);
if (abrt) { flags=of; break; }
setsub16(AX,tempw);
tempz = (ZF_SET()) ? 1 : 0;
if (flags&D_FLAG) DI-=2;
else DI+=2;
c--;
cycles-=(is486)?5:8;
}
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
else firstrepcycle=1;
break;
case 0x1AF: /*REP SCASL*/
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc);
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
templ=readmeml(es,DI);
if (abrt) { flags=of; break; }
setsub32(EAX,templ);
tempz = (ZF_SET()) ? 1 : 0;
if (flags&D_FLAG) DI-=4;
else DI+=4;
c--;
cycles-=(is486)?5:8;
}
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
else firstrepcycle=1;
break;
case 0x2AF: /*REP SCASW*/
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc);
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
tempw=readmemw(es,EDI);
if (abrt) { flags=of; break; }
setsub16(AX,tempw);
tempz = (ZF_SET()) ? 1 : 0;
if (flags&D_FLAG) EDI-=2;
else EDI+=2;
c--;
cycles-=(is486)?5:8;
}
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
else firstrepcycle=1;
break;
case 0x3AF: /*REP SCASL*/
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc);
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
templ=readmeml(es,EDI);
if (abrt) { flags=of; break; }
setsub32(EAX,templ);
tempz = (ZF_SET()) ? 1 : 0;
if (flags&D_FLAG) EDI-=4;
else EDI+=4;
c--;
cycles-=(is486)?5:8;
}
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
else firstrepcycle=1;
break;
default:
pc=ipc;
cycles-=20;
pclog("Bad REP %02X %i\n", temp, rep32 >> 8);
x86illegal();
}
if (rep32&0x200) ECX=c;
else CX=c;
// if (output) pclog("%03X %03X\n",rep32,use32);
return 1;
}
int checkio(int port)
{
uint16_t t;
uint8_t d;
cpl_override = 1;
t = readmemw(tr.base, 0x66);
cpl_override = 0;
// pclog("CheckIO 1 %08X\n",tr.base);
if (abrt) return 0;
// pclog("CheckIO %04X %01X %01X %02X %04X %04X %08X ",CS,CPL,IOPL,port,t,t+(port>>3),tr.base+t+(port>>3));
if ((t+(port>>3))>tr.limit) return 1;
cpl_override = 1;
d = readmemb386l(0, tr.base + t + (port >> 3));
// d=readmemb(tr.base,t+(port>>3));
cpl_override = 0;
// pclog("%02X %02X\n",d,d&(1<<(port&7)));
return d&(1<<(port&7));
}
#define getbytef() ((uint8_t)(fetchdat)); pc++
#define getwordf() ((uint16_t)(fetchdat)); pc+=2
#define getbyte2f() ((uint8_t)(fetchdat>>8)); pc++
#define getword2f() ((uint16_t)(fetchdat>>8)); pc+=2
int xout=0;
#define divexcp() { \
pclog("Divide exception at %04X(%06X):%04X\n",CS,cs,pc); \
x86_int(0); \
}
int divl(uint32_t val)
{
if (val==0)
{
divexcp();
return 1;
}
uint64_t num=(((uint64_t)EDX)<<32)|EAX;
uint64_t quo=num/val;
uint32_t rem=num%val;
uint32_t quo32=(uint32_t)(quo&0xFFFFFFFF);
if (quo!=(uint64_t)quo32)
{
divexcp();
return 1;
}
EDX=rem;
EAX=quo32;
return 0;
}
int idivl(int32_t val)
{
if (val==0)
{
divexcp();
return 1;
}
int64_t num=(((uint64_t)EDX)<<32)|EAX;
int64_t quo=num/val;
int32_t rem=num%val;
int32_t quo32=(int32_t)(quo&0xFFFFFFFF);
if (quo!=(int64_t)quo32)
{
divexcp();
return 1;
}
EDX=rem;
EAX=quo32;
return 0;
}
void cpu_386_flags_extract()
{
flags_extract();
}
void cpu_386_flags_rebuild()
{
flags_rebuild();
}
extern int xout;
int oldi;
uint32_t testr[9];
int dontprint=0;
extern int dontprint;
#undef NOTRM
#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\
@ -1084,7 +204,7 @@ int dontprint=0;
#define CLOCK_CYCLES(c) cycles -= (c)
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
#include "386_ops.h"
#include "x86_ops.h"
#undef NOTRM
#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\
@ -1258,4 +378,3 @@ opcodestart:
timer_end_period(cycles);
}
}
#endif

View file

@ -1,4 +1,3 @@
#ifdef DYNAREC
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
@ -532,7 +531,7 @@ int rep386(int fv)
// cpu_notreps++;
break;
case 0xA4: case 0x1A4: /*REP MOVSB*/
while (c > 0 && cycles > 0)
while (c > 0)
{
CHECK_WRITE_REP(&_es, DI, DI);
temp2 = readmemb(ea_seg->base, SI); if (abrt) break;
@ -543,13 +542,15 @@ int rep386(int fv)
c--;
cycles-=(is486)?3:4;
ins++;
if (cycles < 0)
break;
}
ins--;
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x2A4: case 0x3A4: /*REP MOVSB*/
while (c > 0 && cycles > 0)
while (c > 0)
{
CHECK_WRITE_REP(&_es, EDI, EDI);
temp2 = readmemb(ea_seg->base, ESI); if (abrt) break;
@ -559,13 +560,15 @@ int rep386(int fv)
c--;
cycles-=(is486)?3:4;
ins++;
if (cycles < 0)
break;
}
ins--;
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0xA5: /*REP MOVSW*/
while (c > 0 && cycles > 0)
while (c > 0)
{
CHECK_WRITE_REP(&_es, DI, DI+1);
tempw = readmemw(ea_seg->base, SI); if (abrt) break;
@ -575,13 +578,15 @@ int rep386(int fv)
c--;
cycles-=(is486)?3:4;
ins++;
if (cycles < 0)
break;
}
ins--;
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x1A5: /*REP MOVSL*/
while (c > 0 && cycles > 0)
while (c > 0)
{
CHECK_WRITE_REP(&_es, DI, DI+3);
templ = readmeml(ea_seg->base, SI); if (abrt) break;
@ -592,13 +597,15 @@ int rep386(int fv)
c--;
cycles-=(is486)?3:4;
ins++;
if (cycles < 0)
break;
}
ins--;
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x2A5: /*REP MOVSW*/
while (c > 0 && cycles > 0)
while (c > 0)
{
CHECK_WRITE_REP(&_es, EDI, EDI+1);
tempw = readmemw(ea_seg->base, ESI); if (abrt) break;
@ -609,13 +616,15 @@ int rep386(int fv)
c--;
cycles-=(is486)?3:4;
ins++;
if (cycles < 0)
break;
}
ins--;
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x3A5: /*REP MOVSL*/
while (c > 0 && cycles > 0)
while (c > 0)
{
CHECK_WRITE_REP(&_es, EDI, EDI+3);
templ = readmeml(ea_seg->base, ESI); if (abrt) break;
@ -627,6 +636,8 @@ int rep386(int fv)
c--;
cycles-=(is486)?3:4;
ins++;
if (cycles < 0)
break;
}
ins--;
if (c>0) { firstrepcycle=0; pc=ipc; }
@ -745,7 +756,7 @@ int rep386(int fv)
break;
case 0xAA: case 0x1AA: /*REP STOSB*/
while (c > 0 && cycles > 0)
while (c > 0)
{
CHECK_WRITE_REP(&_es, DI, DI);
writememb(es,DI,AL);
@ -755,13 +766,15 @@ int rep386(int fv)
c--;
cycles-=(is486)?4:5;
ins++;
if (cycles < 0)
break;
}
ins--;
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x2AA: case 0x3AA: /*REP STOSB*/
while (c > 0 && cycles > 0)
while (c > 0)
{
CHECK_WRITE_REP(&_es, EDI, EDI);
writememb(es,EDI,AL);
@ -771,13 +784,15 @@ int rep386(int fv)
c--;
cycles-=(is486)?4:5;
ins++;
if (cycles < 0)
break;
}
ins--;
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0xAB: /*REP STOSW*/
while (c > 0 && cycles > 0)
while (c > 0)
{
CHECK_WRITE_REP(&_es, DI, DI+1);
writememw(es,DI,AX);
@ -787,13 +802,15 @@ int rep386(int fv)
c--;
cycles-=(is486)?4:5;
ins++;
if (cycles < 0)
break;
}
ins--;
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x2AB: /*REP STOSW*/
while (c > 0 && cycles > 0)
while (c > 0)
{
CHECK_WRITE_REP(&_es, EDI, EDI+1);
writememw(es,EDI,AX);
@ -803,13 +820,15 @@ int rep386(int fv)
c--;
cycles-=(is486)?4:5;
ins++;
if (cycles < 0)
break;
}
ins--;
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x1AB: /*REP STOSL*/
while (c > 0 && cycles > 0)
while (c > 0)
{
CHECK_WRITE_REP(&_es, DI, DI+3);
writememl(es,DI,EAX);
@ -819,13 +838,15 @@ int rep386(int fv)
c--;
cycles-=(is486)?4:5;
ins++;
if (cycles < 0)
break;
}
ins--;
if (c>0) { firstrepcycle=0; pc=ipc; }
else firstrepcycle=1;
break;
case 0x3AB: /*REP STOSL*/
while (c > 0 && cycles > 0)
while (c > 0)
{
CHECK_WRITE_REP(&_es, EDI, EDI+3);
writememl(es,EDI,EAX);
@ -835,6 +856,8 @@ int rep386(int fv)
c--;
cycles-=(is486)?4:5;
ins++;
if (cycles < 0)
break;
}
ins--;
if (c>0) { firstrepcycle=0; pc=ipc; }
@ -935,7 +958,7 @@ int rep386(int fv)
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc);
// tempz=(fv)?1:0;
tempz = (fv) ? 1 : 0;
while ((c > 0) && (fv == tempz) && (cycles > 0))
while ((c > 0) && (fv == tempz))
{
temp2=readmemb(es,DI);
if (abrt) { flags=of; break; }
@ -946,6 +969,8 @@ int rep386(int fv)
c--;
cycles-=(is486)?5:8;
ins++;
if (cycles < 0)
break;
}
ins--;
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
@ -956,7 +981,7 @@ int rep386(int fv)
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc);
// tempz=(fv)?1:0;
tempz = (fv) ? 1 : 0;
while ((c > 0) && (fv == tempz) && (cycles > 0))
while ((c > 0) && (fv == tempz))
{
temp2=readmemb(es,EDI);
if (abrt) { flags=of; break; }
@ -968,6 +993,8 @@ int rep386(int fv)
c--;
cycles-=(is486)?5:8;
ins++;
if (cycles < 0)
break;
}
ins--;
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
@ -977,7 +1004,7 @@ int rep386(int fv)
cpu_notreps++;
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc);
tempz = (fv) ? 1 : 0;
while ((c > 0) && (fv == tempz) && (cycles > 0))
while ((c > 0) && (fv == tempz))
{
tempw=readmemw(es,DI);
if (abrt) { flags=of; break; }
@ -988,6 +1015,8 @@ int rep386(int fv)
c--;
cycles-=(is486)?5:8;
ins++;
if (cycles < 0)
break;
}
ins--;
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
@ -997,7 +1026,7 @@ int rep386(int fv)
cpu_notreps++;
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc);
tempz = (fv) ? 1 : 0;
while ((c > 0) && (fv == tempz) && (cycles > 0))
while ((c > 0) && (fv == tempz))
{
templ=readmeml(es,DI);
if (abrt) { flags=of; break; }
@ -1008,6 +1037,8 @@ int rep386(int fv)
c--;
cycles-=(is486)?5:8;
ins++;
if (cycles < 0)
break;
}
ins--;
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
@ -1017,7 +1048,7 @@ int rep386(int fv)
cpu_notreps++;
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc);
tempz = (fv) ? 1 : 0;
while ((c > 0) && (fv == tempz) && (cycles > 0))
while ((c > 0) && (fv == tempz))
{
tempw=readmemw(es,EDI);
if (abrt) { flags=of; break; }
@ -1028,6 +1059,8 @@ int rep386(int fv)
c--;
cycles-=(is486)?5:8;
ins++;
if (cycles < 0)
break;
}
ins--;
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
@ -1037,7 +1070,7 @@ int rep386(int fv)
cpu_notreps++;
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc);
tempz = (fv) ? 1 : 0;
while ((c > 0) && (fv == tempz) && (cycles > 0))
while ((c > 0) && (fv == tempz))
{
templ=readmeml(es,EDI);
if (abrt) { flags=of; break; }
@ -1048,6 +1081,8 @@ int rep386(int fv)
c--;
cycles-=(is486)?5:8;
ins++;
if (cycles < 0)
break;
}
ins--;
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
@ -1163,7 +1198,7 @@ int dontprint=0;
//#define CACHE_ON() 0
static int cycles_main = 0;
void exec386(int cycs)
void exec386_dynarec(int cycs)
{
uint8_t temp;
uint32_t addr;
@ -1476,4 +1511,3 @@ inrecomp=0;
cycles_main -= (cycles_start - cycles);
}
}
#endif

View file

@ -1,4 +1,3 @@
#ifdef DYNAREC
#include "ibm.h"
#include "cpu.h"
#include "x86.h"
@ -56,4 +55,3 @@ static inline void fetch_ea_16_long(uint32_t rmdat)
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
#include "386_ops.h"
#endif

View file

@ -653,9 +653,7 @@ void resetx86()
mmu_perm=4;
memset(inscounts, 0, sizeof(inscounts));
x86seg_reset();
#ifdef DYNAREC
codegen_reset();
#endif
x86_was_reset = 1;
}

View file

@ -191,39 +191,41 @@ static int list_proc(int msg, DIALOG *d, int c);
static DIALOG configure_dialog[] =
{
{d_shadow_box_proc, 0, 0, 236*2,272,0,0xffffff,0,0, 0,0,0,0,0}, // 0
{d_shadow_box_proc, 0, 0, 236*2,292,0,0xffffff,0,0, 0,0,0,0,0}, // 0
{d_button_proc, 176, 248, 50, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1
{d_button_proc, 246, 248, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2
{d_button_proc, 176, 268, 50, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1
{d_button_proc, 246, 268, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2
{list_proc, 70*2, 12, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_model, 0, 0},
{list_proc, 70*2, 32, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_video, 0, 0},
{list_proc, 70*2, 52, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_cpumanu, 0, 0}, //5
{d_list_proc, 70*2, 72, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_cpu, 0, 0},
{d_list_proc, 70*2, 92, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_cache, 0, 0},
{d_list_proc, 70*2, 112, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_vidspeed, 0, 0},
{list_proc, 70*2, 132, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_sound, 0, 0}, //9
{list_proc, 70*2, 72, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_cpu, 0, 0},
{d_list_proc, 70*2, 112, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_cache, 0, 0},
{d_list_proc, 70*2, 132, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_vidspeed, 0, 0},
{list_proc, 70*2, 152, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_sound, 0, 0}, //9
{d_edit_proc, 70*2, 156, 32, 14, 0, 0xffffff, 0, 0, 3, 0, mem_size_str, 0, 0},
{d_edit_proc, 70*2, 176, 32, 14, 0, 0xffffff, 0, 0, 3, 0, mem_size_str, 0, 0},
{d_text_proc, 98*2, 156, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "MB", 0, 0},
{d_text_proc, 98*2, 176, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "MB", 0, 0},
{d_check_proc, 14*2, 172, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "CMS / Game Blaster", 0, 0},
{d_check_proc, 14*2, 188, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Gravis Ultrasound", 0, 0},
{d_check_proc, 14*2, 204, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Innovation SSI-2001", 0, 0},
{d_check_proc, 14*2, 220, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Composite CGA", 0, 0},
{d_check_proc, 14*2, 236, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Voodoo Graphics", 0, 0},
{d_check_proc, 14*2, 192, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "CMS / Game Blaster", 0, 0},
{d_check_proc, 14*2, 208, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Gravis Ultrasound", 0, 0},
{d_check_proc, 14*2, 224, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Innovation SSI-2001", 0, 0},
{d_check_proc, 14*2, 240, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Composite CGA", 0, 0},
{d_check_proc, 14*2, 256, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Voodoo Graphics", 0, 0},
{d_text_proc, 16*2, 16, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Machine :", 0, 0},
{d_text_proc, 16*2, 36, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Video :", 0, 0},
{d_text_proc, 16*2, 56, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "CPU type :", 0, 0},
{d_text_proc, 16*2, 76, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "CPU :", 0, 0},
{d_text_proc, 16*2, 96, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Cache :", 0, 0},
{d_text_proc, 16*2, 116, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Video speed :", 0, 0},
{d_text_proc, 16*2, 136, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Soundcard :", 0, 0},
{d_text_proc, 16*2, 156, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Memory :", 0, 0},
{d_text_proc, 16*2, 116, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Cache :", 0, 0},
{d_text_proc, 16*2, 136, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Video speed :", 0, 0},
{d_text_proc, 16*2, 156, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Soundcard :", 0, 0},
{d_text_proc, 16*2, 176, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Memory :", 0, 0},
{d_check_proc, 14*2, 92, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Dynamic Recompiler", 0, 0},
{0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL}
};
@ -236,6 +238,10 @@ static int list_proc(int msg, DIALOG *d, int c)
if (d->d1 != old)
{
int new_model = model_list[configure_dialog[3].d1].num;
int new_cpu_m = configure_dialog[5].d1;
int new_cpu = configure_dialog[6].d1;
int new_dynarec = configure_dialog[25].flags & D_SELECTED;
int cpu_flags;
reset_list();
@ -244,6 +250,11 @@ static int list_proc(int msg, DIALOG *d, int c)
else
configure_dialog[4].flags &= ~D_DISABLED;
cpu_flags = models[new_model].cpu[new_cpu_m].cpus[new_cpu].cpu_flags;
configure_dialog[25].flags = (((cpu_flags & CPU_SUPPORTS_DYNAREC) && new_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC)) ? D_SELECTED : 0;
if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC))
configure_dialog[25].flags |= D_DISABLED;
return D_REDRAW;
}
@ -286,6 +297,7 @@ static void reset_list()
int settings_configure()
{
int c, d;
int cpu_flags;
memset(model_list, 0, sizeof(model_list));
memset(video_list, 0, sizeof(video_list));
@ -391,6 +403,11 @@ pclog("video_card_available : %i\n", c);
configure_dialog[16].flags &= ~D_SELECTED;
sprintf(mem_size_str, "%i", mem_size);
cpu_flags = models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_flags;
configure_dialog[25].flags = (((cpu_flags & CPU_SUPPORTS_DYNAREC) && cpu_use_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC)) ? D_SELECTED : 0;
if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC))
configure_dialog[25].flags |= D_DISABLED;
while (1)
{
@ -413,6 +430,7 @@ pclog("video_card_available : %i\n", c);
int new_GUS = (configure_dialog[13].flags & D_SELECTED) ? 1 : 0;
int new_SSI2001 = (configure_dialog[14].flags & D_SELECTED) ? 1 : 0;
int new_voodoo = (configure_dialog[16].flags & D_SELECTED) ? 1 : 0;
int new_dynarec = (configure_dialog[25].flags & D_SELECTED) ? 1 : 0;
sscanf(mem_size_str, "%i", &new_mem_size);
if (new_mem_size < 1 || new_mem_size > 256)
@ -423,7 +441,8 @@ pclog("video_card_available : %i\n", c);
if (new_model != model || new_gfxcard != gfxcard || new_mem_size != mem_size ||
new_has_fpu != hasfpu || new_GAMEBLASTER != GAMEBLASTER || new_GUS != GUS ||
new_SSI2001 != SSI2001 || new_sndcard != sound_card_current || new_voodoo != voodoo_enabled)
new_SSI2001 != SSI2001 || new_sndcard != sound_card_current || new_voodoo != voodoo_enabled ||
new_dynarec != cpu_use_dynarec)
{
if (alert("This will reset PCem!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) != 1)
continue;
@ -439,6 +458,7 @@ pclog("video_card_available : %i\n", c);
SSI2001 = new_SSI2001;
sound_card_current = new_sndcard;
voodoo_enabled = new_voodoo;
cpu_use_dynarec = new_dynarec;
mem_resize();
loadbios();

View file

@ -1,5 +1,3 @@
#ifdef DYNAREC
#include "ibm.h"
#include "x86_ops.h"
#include "mem.h"
@ -19,5 +17,3 @@ void codegen_timing_set(codegen_timing_t *timing)
codegen_timing_block_start = timing->block_start;
codegen_timing_block_end = timing->block_end;
}
#endif

View file

@ -1,5 +1,3 @@
#ifdef DYNAREC
#ifdef __amd64__
#include "codegen_x86-64.h"
#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32
@ -165,5 +163,3 @@ extern int codegen_fpu_entered;
extern int codegen_fpu_loaded_iq[8];
extern int codegen_reg_loaded[8];
#endif

View file

@ -1,5 +1,3 @@
#ifdef DYNAREC
#include "ibm.h"
#include "x86.h"
#include "x86_ops.h"
@ -495,5 +493,3 @@ RecompOpFn recomp_opcodes_df[512] =
/*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
#endif

View file

@ -1,5 +1,3 @@
#ifdef DYNAREC
#include "ibm.h"
#include "cpu.h"
#include "x86.h"
@ -375,4 +373,3 @@ codegen_timing_t codegen_timing_486 =
codegen_timing_486_block_start,
codegen_timing_486_block_end
};
#endif

View file

@ -9,8 +9,6 @@
- MMX latencies
*/
#ifdef DYNAREC
#include "ibm.h"
#include "cpu.h"
#include "x86.h"
@ -1061,4 +1059,3 @@ codegen_timing_t codegen_timing_pentium =
codegen_timing_pentium_block_start,
codegen_timing_pentium_block_end
};
#endif

View file

@ -1,4 +1,3 @@
#ifdef DYNAREC
#ifdef __amd64__
#include <stdlib.h>
@ -1229,4 +1228,3 @@ void codegen_check_abrt()
}
#endif
#endif

View file

@ -1,4 +1,3 @@
#ifdef DYNAREC
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32
#include <stdlib.h>
@ -1015,4 +1014,3 @@ void codegen_check_abrt()
}
#endif
#endif

300
src/cpu.c
View file

@ -3,12 +3,9 @@
#include "model.h"
#include "io.h"
#include "x86_ops.h"
#ifdef DYNAREC
#include "mem.h"
#include "codegen.h"
#endif
#ifdef DYNAREC
OpFn *x86_dynarec_opcodes;
OpFn *x86_dynarec_opcodes_0f;
OpFn *x86_dynarec_opcodes_d8_a16;
@ -27,7 +24,6 @@ OpFn *x86_dynarec_opcodes_de_a16;
OpFn *x86_dynarec_opcodes_de_a32;
OpFn *x86_dynarec_opcodes_df_a16;
OpFn *x86_dynarec_opcodes_df_a32;
#endif
OpFn *x86_opcodes;
OpFn *x86_opcodes_0f;
@ -66,6 +62,7 @@ int cpu_busspeed;
int cpu_hasrdtsc;
int cpu_hasMMX, cpu_hasMSR;
int cpu_hasCR4;
int cpu_use_dynarec;
uint64_t cpu_CR4_mask;
@ -109,228 +106,226 @@ static struct
CPU cpus_8088[] =
{
/*8088 standard*/
{"8088/4.77", CPU_8088, 0, 4772727, 1, 0, 0, 0},
{"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0},
{"8088/10", CPU_8088, 2, 10000000, 1, 0, 0, 0},
{"8088/12", CPU_8088, 3, 12000000, 1, 0, 0, 0},
{"8088/16", CPU_8088, 4, 16000000, 1, 0, 0, 0},
{"8088/4.77", CPU_8088, 0, 4772727, 1, 0, 0, 0, 0},
{"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0},
{"8088/10", CPU_8088, 2, 10000000, 1, 0, 0, 0, 0},
{"8088/12", CPU_8088, 3, 12000000, 1, 0, 0, 0, 0},
{"8088/16", CPU_8088, 4, 16000000, 1, 0, 0, 0, 0},
{"", -1, 0, 0, 0, 0}
};
CPU cpus_pcjr[] =
{
/*8088 PCjr*/
{"8088/4.77", CPU_8088, 0, 4772727, 1, 0, 0, 0},
{"8088/4.77", CPU_8088, 0, 4772727, 1, 0, 0, 0, 0},
{"", -1, 0, 0, 0, 0}
};
CPU cpus_8086[] =
{
/*8086 standard*/
{"8086/7.16", CPU_8086, 1, 3579545*2, 1, 0, 0, 0},
{"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0},
{"8086/9.54", CPU_8086, 1, (3579545*8)/3, 1, 0, 0, 0},
{"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0},
{"8086/12", CPU_8086, 3, 12000000, 1, 0, 0, 0},
{"8086/16", CPU_8086, 4, 16000000, 1, 0, 0, 0},
{"8086/7.16", CPU_8086, 1, 3579545*2, 1, 0, 0, 0, 0},
{"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0},
{"8086/9.54", CPU_8086, 1, (3579545*8)/3, 1, 0, 0, 0, 0},
{"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0, 0},
{"8086/12", CPU_8086, 3, 12000000, 1, 0, 0, 0, 0},
{"8086/16", CPU_8086, 4, 16000000, 1, 0, 0, 0, 0},
{"", -1, 0, 0, 0, 0}
};
CPU cpus_pc1512[] =
{
/*8086 Amstrad*/
{"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0},
{"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0},
{"", -1, 0, 0, 0, 0}
};
CPU cpus_286[] =
{
/*286*/
{"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0},
{"286/8", CPU_286, 1, 8000000, 1, 0, 0, 0},
{"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0},
{"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0},
{"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0},
{"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0},
{"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0},
{"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0},
{"286/8", CPU_286, 1, 8000000, 1, 0, 0, 0, 0},
{"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0},
{"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0},
{"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0},
{"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0},
{"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0},
{"", -1, 0, 0, 0, 0}
};
CPU cpus_ibmat[] =
{
/*286*/
{"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0},
{"286/8", CPU_286, 0, 8000000, 1, 0, 0, 0},
{"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0},
{"286/8", CPU_286, 0, 8000000, 1, 0, 0, 0, 0},
{"", -1, 0, 0, 0, 0}
};
CPU cpus_i386[] =
{
/*i386*/
{"i386SX/16", CPU_386SX, 0, 16000000, 1, 0x2308, 0, 0},
{"i386SX/20", CPU_386SX, 1, 20000000, 1, 0x2308, 0, 0},
{"i386SX/25", CPU_386SX, 2, 25000000, 1, 0x2308, 0, 0},
{"i386SX/33", CPU_386SX, 3, 33333333, 1, 0x2308, 0, 0},
{"i386DX/16", CPU_386DX, 0, 16000000, 1, 0x0308, 0, 0},
{"i386DX/20", CPU_386DX, 1, 20000000, 1, 0x0308, 0, 0},
{"i386DX/25", CPU_386DX, 2, 25000000, 1, 0x0308, 0, 0},
{"i386DX/33", CPU_386DX, 3, 33333333, 1, 0x0308, 0, 0},
{"i386SX/16", CPU_386SX, 0, 16000000, 1, 0x2308, 0, 0, 0},
{"i386SX/20", CPU_386SX, 1, 20000000, 1, 0x2308, 0, 0, 0},
{"i386SX/25", CPU_386SX, 2, 25000000, 1, 0x2308, 0, 0, 0},
{"i386SX/33", CPU_386SX, 3, 33333333, 1, 0x2308, 0, 0, 0},
{"i386DX/16", CPU_386DX, 0, 16000000, 1, 0x0308, 0, 0, 0},
{"i386DX/20", CPU_386DX, 1, 20000000, 1, 0x0308, 0, 0, 0},
{"i386DX/25", CPU_386DX, 2, 25000000, 1, 0x0308, 0, 0, 0},
{"i386DX/33", CPU_386DX, 3, 33333333, 1, 0x0308, 0, 0, 0},
{"", -1, 0, 0, 0}
};
CPU cpus_acer[] =
{
/*i386*/
{"i386SX/25", CPU_386SX, 2, 25000000, 1, 0x2308, 0, 0},
{"i386SX/25", CPU_386SX, 2, 25000000, 1, 0x2308, 0, 0, 0},
{"", -1, 0, 0, 0}
};
CPU cpus_Am386[] =
{
/*Am386*/
{"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0x2308, 0, 0},
{"Am386SX/20", CPU_386SX, 1, 20000000, 1, 0x2308, 0, 0},
{"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0x2308, 0, 0},
{"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0x2308, 0, 0},
{"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0x2308, 0, 0},
{"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0x0308, 0, 0},
{"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0x0308, 0, 0},
{"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0x0308, 0, 0},
{"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0x2308, 0, 0, 0},
{"Am386SX/20", CPU_386SX, 1, 20000000, 1, 0x2308, 0, 0, 0},
{"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0x2308, 0, 0, 0},
{"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0x2308, 0, 0, 0},
{"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0x2308, 0, 0, 0},
{"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0x0308, 0, 0, 0},
{"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0x0308, 0, 0, 0},
{"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0x0308, 0, 0, 0},
{"", -1, 0, 0, 0}
};
CPU cpus_486SDLC[] =
{
/*Cx486SLC/DLC*/
{"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0, 0x0000},
{"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0, 0x0000},
{"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0, 0x0000},
{"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0, 0x0006},
{"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0, 0x0006},
{"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0, 0x0006},
{"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0, 0x0001},
{"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0, 0x0001},
{"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0, 0x0001},
{"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0, 0x0007},
{"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0, 0x0007},
{"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0, 0x0007},
{"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0, 0x0007},
{"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0, 0x0000, 0},
{"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0, 0x0000, 0},
{"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0, 0x0000, 0},
{"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0, 0x0006, 0},
{"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0, 0x0006, 0},
{"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0, 0x0006, 0},
{"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0, 0x0001, 0},
{"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0, 0x0001, 0},
{"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0, 0x0001, 0},
{"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0, 0x0007, 0},
{"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0, 0x0007, 0},
{"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0, 0x0007, 0},
{"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0, 0x0007, 0},
{"", -1, 0, 0, 0}
};
CPU cpus_i486[] =
{
/*i486*/
{"i486SX/16", CPU_i486SX, 0, 16000000, 1, 0x42a, 0, 0},
{"i486SX/20", CPU_i486SX, 1, 20000000, 1, 0x42a, 0, 0},
{"i486SX/25", CPU_i486SX, 2, 25000000, 1, 0x42a, 0, 0},
{"i486SX/33", CPU_i486SX, 3, 33333333, 1, 0x42a, 0, 0},
{"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 0x45b, 0, 0},
{"i486DX/25", CPU_i486DX, 2, 25000000, 1, 0x404, 0, 0},
{"i486DX/33", CPU_i486DX, 3, 33333333, 1, 0x404, 0, 0},
{"i486DX/50", CPU_i486DX, 5, 50000000, 1, 0x404, 0, 0},
{"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 0x430, 0, 0},
{"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 0x430, 0, 0},
{"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 0x430, 0, 0},
{"iDX4/75", CPU_i486DX, 7, 75000000, 3, 0x481, 0x481, 0}, /*CPUID available on DX4, >= 75 MHz*/
{"iDX4/100", CPU_i486DX,10, 100000000, 3, 0x481, 0x481, 0}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/
#ifdef DYNAREC
{"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 0x1531, 0x1531, 0},
{"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 0x1532, 0x1532, 0},
#endif
{"i486SX/16", CPU_i486SX, 0, 16000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC},
{"i486SX/20", CPU_i486SX, 1, 20000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC},
{"i486SX/25", CPU_i486SX, 2, 25000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC},
{"i486SX/33", CPU_i486SX, 3, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC},
{"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC},
{"i486DX/25", CPU_i486DX, 2, 25000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC},
{"i486DX/33", CPU_i486DX, 3, 33333333, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC},
{"i486DX/50", CPU_i486DX, 5, 50000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC},
{"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC},
{"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC},
{"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC},
{"iDX4/75", CPU_i486DX, 7, 75000000, 3, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC}, /*CPUID available on DX4, >= 75 MHz*/
{"iDX4/100", CPU_i486DX,10, 100000000, 3, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/
{"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"", -1, 0, 0, 0}
};
CPU cpus_Am486[] =
{
/*Am486/5x86*/
{"Am486SX/33", CPU_Am486SX, 3, 33333333, 1, 0x42a, 0, 0},
{"Am486SX/40", CPU_Am486SX, 4, 40000000, 1, 0x42a, 0, 0},
{"Am486SX2/50", CPU_Am486SX, 5, 50000000, 2, 0x45b, 0x45b, 0}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
{"Am486SX2/66", CPU_Am486SX, 6, 66666666, 2, 0x45b, 0x45b, 0}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/
{"Am486DX/33", CPU_Am486DX, 3, 33333333, 1, 0x430, 0, 0},
{"Am486DX/40", CPU_Am486DX, 4, 40000000, 1, 0x430, 0, 0},
{"Am486DX2/50", CPU_Am486DX, 5, 50000000, 2, 0x470, 0x470, 0},
{"Am486DX2/66", CPU_Am486DX, 6, 66666666, 2, 0x470, 0x470, 0},
{"Am486DX2/80", CPU_Am486DX, 8, 80000000, 2, 0x470, 0x470, 0},
{"Am486DX4/75", CPU_Am486DX, 7, 75000000, 3, 0x482, 0x482, 0},
{"Am486DX4/90", CPU_Am486DX, 9, 90000000, 3, 0x482, 0x482, 0},
{"Am486DX4/100", CPU_Am486DX, 10, 100000000, 3, 0x482, 0x482, 0},
{"Am486DX4/120", CPU_Am486DX, 11, 120000000, 3, 0x482, 0x482, 0},
{"Am5x86/P75", CPU_Am486DX, 12, 133333333, 4, 0x4e0, 0x4e0, 0},
{"Am5x86/P75+", CPU_Am486DX, 13, 150000000, 4, 0x4e0, 0x4e0, 0},
{"Am486SX/33", CPU_Am486SX, 3, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC},
{"Am486SX/40", CPU_Am486SX, 4, 40000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC},
{"Am486SX2/50", CPU_Am486SX, 5, 50000000, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
{"Am486SX2/66", CPU_Am486SX, 6, 66666666, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/
{"Am486DX/33", CPU_Am486DX, 3, 33333333, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC},
{"Am486DX/40", CPU_Am486DX, 4, 40000000, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC},
{"Am486DX2/50", CPU_Am486DX, 5, 50000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC},
{"Am486DX2/66", CPU_Am486DX, 6, 66666666, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC},
{"Am486DX2/80", CPU_Am486DX, 8, 80000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC},
{"Am486DX4/75", CPU_Am486DX, 7, 75000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC},
{"Am486DX4/90", CPU_Am486DX, 9, 90000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC},
{"Am486DX4/100", CPU_Am486DX, 10, 100000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC},
{"Am486DX4/120", CPU_Am486DX, 11, 120000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC},
{"Am5x86/P75", CPU_Am486DX, 12, 133333333, 4, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC},
{"Am5x86/P75+", CPU_Am486DX, 13, 150000000, 4, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC},
{"", -1, 0, 0, 0}
};
CPU cpus_Cx486[] =
{
/*Cx486/5x86*/
{"Cx486S/25", CPU_Cx486S, 2, 25000000, 1, 0x420, 0, 0x0010},
{"Cx486S/33", CPU_Cx486S, 3, 33333333, 1, 0x420, 0, 0x0010},
{"Cx486S/40", CPU_Cx486S, 4, 40000000, 1, 0x420, 0, 0x0010},
{"Cx486DX/33", CPU_Cx486DX, 3, 33333333, 1, 0x430, 0, 0x051a},
{"Cx486DX/40", CPU_Cx486DX, 4, 40000000, 1, 0x430, 0, 0x051a},
{"Cx486DX2/50", CPU_Cx486DX, 5, 50000000, 2, 0x430, 0, 0x081b},
{"Cx486DX2/66", CPU_Cx486DX, 6, 66666666, 2, 0x430, 0, 0x0b1b},
{"Cx486DX2/80", CPU_Cx486DX, 8, 80000000, 2, 0x430, 0, 0x311b},
{"Cx486DX4/75", CPU_Cx486DX, 7, 75000000, 3, 0x480, 0, 0x361f},
{"Cx486DX4/100", CPU_Cx486DX, 10, 100000000, 3, 0x480, 0, 0x361f},
{"Cx5x86/100", CPU_Cx5x86, 10, 100000000, 3, 0x480, 0, 0x002f},
{"Cx5x86/120", CPU_Cx5x86, 11, 120000000, 3, 0x480, 0, 0x002f},
{"Cx5x86/133", CPU_Cx5x86, 12, 133333333, 4, 0x480, 0, 0x002f},
{"Cx486S/25", CPU_Cx486S, 2, 25000000, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC},
{"Cx486S/33", CPU_Cx486S, 3, 33333333, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC},
{"Cx486S/40", CPU_Cx486S, 4, 40000000, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC},
{"Cx486DX/33", CPU_Cx486DX, 3, 33333333, 1, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC},
{"Cx486DX/40", CPU_Cx486DX, 4, 40000000, 1, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC},
{"Cx486DX2/50", CPU_Cx486DX, 5, 50000000, 2, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC},
{"Cx486DX2/66", CPU_Cx486DX, 6, 66666666, 2, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC},
{"Cx486DX2/80", CPU_Cx486DX, 8, 80000000, 2, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC},
{"Cx486DX4/75", CPU_Cx486DX, 7, 75000000, 3, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC},
{"Cx486DX4/100", CPU_Cx486DX, 10, 100000000, 3, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC},
{"Cx5x86/100", CPU_Cx5x86, 10, 100000000, 3, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC},
{"Cx5x86/120", CPU_Cx5x86, 11, 120000000, 3, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC},
{"Cx5x86/133", CPU_Cx5x86, 12, 133333333, 4, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC},
{"", -1, 0, 0, 0}
};
CPU cpus_WinChip[] =
{
/*IDT WinChip*/
{"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 0x540, 0x540, 0},
{"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 0x540, 0x540, 0},
{"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 0x540, 0x540, 0},
{"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 0x540, 0x540, 0},
{"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 0x540, 0x540, 0},
{"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 0x540, 0x540, 0},
{"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 0x540, 0x540, 0},
{"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 0x540, 0x540, 0},
{"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 0x540, 0x540, 0},
{"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 0x540, 0x540, 0},
{"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 0x540, 0x540, 0},
{"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
{"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
{"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
{"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
{"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
{"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
{"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
{"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
{"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
{"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
{"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC},
{"", -1, 0, 0, 0}
};
#ifdef DYNAREC
CPU cpus_Pentium5V[] =
{
/*Intel Pentium (5V, socket 4)*/
{"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 0x52c, 0x52c, 0},
{"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 0x52c, 0x52c, 0},
{"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"", -1, 0, 0, 0}
};
CPU cpus_Pentium[] =
{
/*Intel Pentium*/
{"Pentium 75", CPU_PENTIUM, 7, 75000000, 2, 0x52c, 0x52c, 0},
{"Pentium 90", CPU_PENTIUM, 9, 90000000, 2, 0x52c, 0x52c, 0},
{"Pentium 100", CPU_PENTIUM, 10, 100000000, 2, 0x52c, 0x52c, 0},
{"Pentium 120", CPU_PENTIUM, 11, 120000000, 2, 0x52c, 0x52c, 0},
{"Pentium 133", CPU_PENTIUM, 12, 133333333, 2, 0x52c, 0x52c, 0},
{"Pentium 150", CPU_PENTIUM, 12, 150000000, 3, 0x52c, 0x52c, 0},
{"Pentium 166", CPU_PENTIUM, 12, 166666666, 3, 0x52c, 0x52c, 0},
{"Pentium 200", CPU_PENTIUM, 12, 200000000, 3, 0x52c, 0x52c, 0},
{"Pentium MMX 166", CPU_PENTIUMMMX, 12, 166666666, 3, 0x543, 0x543, 0},
{"Pentium MMX 200", CPU_PENTIUMMMX, 12, 200000000, 3, 0x543, 0x543, 0},
{"Pentium MMX 233", CPU_PENTIUMMMX, 12, 233333333, 4, 0x543, 0x543, 0},
{"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 12, 120000000, 2, 0x543, 0x543, 0},
{"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 12, 133333333, 2, 0x543, 0x543, 0},
{"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 12, 150000000, 3, 0x544, 0x544, 0},
{"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 12, 166666666, 3, 0x544, 0x544, 0},
{"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 12, 200000000, 3, 0x581, 0x581, 0},
{"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 12, 233333333, 4, 0x581, 0x581, 0},
{"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 12, 266666666, 4, 0x582, 0x582, 0},
{"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 12, 300000000, 5, 0x582, 0x582, 0},
{"Pentium 75", CPU_PENTIUM, 7, 75000000, 2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium 90", CPU_PENTIUM, 9, 90000000, 2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium 100", CPU_PENTIUM, 10, 100000000, 2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium 120", CPU_PENTIUM, 11, 120000000, 2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium 133", CPU_PENTIUM, 12, 133333333, 2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium 150", CPU_PENTIUM, 12, 150000000, 3, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium 166", CPU_PENTIUM, 12, 166666666, 3, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium 200", CPU_PENTIUM, 12, 200000000, 3, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium MMX 166", CPU_PENTIUMMMX, 12, 166666666, 3, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium MMX 200", CPU_PENTIUMMMX, 12, 200000000, 3, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Pentium MMX 233", CPU_PENTIUMMMX, 12, 233333333, 4, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 12, 120000000, 2, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 12, 133333333, 2, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 12, 150000000, 3, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 12, 166666666, 3, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 12, 200000000, 3, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 12, 233333333, 4, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 12, 266666666, 4, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 12, 300000000, 5, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
{"", -1, 0, 0, 0}
};
#endif
void cpu_set_edx()
{
EDX = models[model].cpu[cpu_manufacturer].cpus[cpu].edx_reset;
@ -372,12 +367,8 @@ void cpu_set()
pclog("hasfpu - %i\n",hasfpu);
pclog("is486 - %i %i\n",is486,cpu_s->cpu_type);
#ifdef DYNAREC
x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f);
#else
x86_setopcodes(ops_386, ops_386_0f);
#endif
#ifdef DYNAREC
if (hasfpu)
{
x86_dynarec_opcodes_d8_a16 = dynarec_ops_fpu_d8_a16;
@ -417,7 +408,7 @@ void cpu_set()
x86_dynarec_opcodes_df_a16 = dynarec_ops_nofpu_a32;
}
codegen_timing_set(&codegen_timing_486);
#endif
if (hasfpu)
{
x86_opcodes_d8_a16 = ops_fpu_d8_a16;
@ -466,11 +457,7 @@ void cpu_set()
break;
case CPU_286:
#ifdef DYNAREC
x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f);
#else
x86_setopcodes(ops_286, ops_286_0f);
#endif
timing_rr = 2; /*register dest - register src*/
timing_rm = 7; /*register dest - memory src*/
timing_mr = 7; /*memory dest - register src*/
@ -583,11 +570,7 @@ void cpu_set()
break;
case CPU_WINCHIP:
#ifdef DYNAREC
x86_setopcodes(ops_386, ops_winchip_0f, dynarec_ops_386, dynarec_ops_winchip_0f);
#else
x86_setopcodes(ops_386, ops_winchip_0f);
#endif
timing_rr = 1; /*register dest - register src*/
timing_rm = 2; /*register dest - memory src*/
timing_mr = 3; /*memory dest - register src*/
@ -604,7 +587,6 @@ void cpu_set()
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
break;
#ifdef DYNAREC
case CPU_PENTIUM:
x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f);
timing_rr = 1; /*register dest - register src*/
@ -644,7 +626,6 @@ void cpu_set()
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
codegen_timing_set(&codegen_timing_pentium);
break;
#endif
default:
fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type);
@ -736,7 +717,7 @@ void cpu_CPUID()
else
EAX = 0;
break;
#ifdef DYNAREC
case CPU_PENTIUM:
if (!EAX)
{
@ -772,7 +753,6 @@ void cpu_CPUID()
else
EAX = 0;
break;
#endif
}
}
@ -809,7 +789,7 @@ void cpu_RDMSR()
break;
}
break;
#ifdef DYNAREC
case CPU_PENTIUM:
case CPU_PENTIUMMMX:
EAX = EDX = 0;
@ -821,7 +801,6 @@ void cpu_RDMSR()
break;
}
break;
#endif
}
}
@ -860,7 +839,7 @@ void cpu_WRMSR()
break;
}
break;
#ifdef DYNAREC
case CPU_PENTIUM:
case CPU_PENTIUMMMX:
switch (ECX)
@ -870,7 +849,6 @@ void cpu_WRMSR()
break;
}
break;
#endif
}
}
@ -897,7 +875,6 @@ uint8_t cyrix_read(uint16_t addr, void *priv)
return 0xff;
}
#ifdef DYNAREC
void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f, OpFn *dynarec_opcodes, OpFn *dynarec_opcodes_0f)
{
x86_opcodes = opcodes;
@ -905,10 +882,3 @@ void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f, OpFn *dynarec_opcodes, OpFn
x86_dynarec_opcodes = dynarec_opcodes;
x86_dynarec_opcodes_0f = dynarec_opcodes_0f;
}
#else
void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f)
{
x86_opcodes = opcodes;
x86_opcodes_0f = opcodes_0f;
}
#endif

View file

@ -24,10 +24,8 @@ extern int cpu, cpu_manufacturer;
/*586 class CPUs*/
#define CPU_WINCHIP 14
#ifdef DYNAREC
#define CPU_PENTIUM 15
#define CPU_PENTIUMMMX 16
#endif
#define MANU_INTEL 0
#define MANU_AMD 1
@ -52,6 +50,7 @@ typedef struct
uint32_t edx_reset;
uint32_t cpuid_model;
uint16_t cyrix_id;
int cpu_flags;
} CPU;
extern CPU cpus_8088[];
@ -64,10 +63,8 @@ extern CPU cpus_i486[];
extern CPU cpus_Am486[];
extern CPU cpus_Cx486[];
extern CPU cpus_WinChip[];
#ifdef DYNAREC
extern CPU cpus_Pentium5V[];
extern CPU cpus_Pentium[];
#endif
extern CPU cpus_pcjr[];
extern CPU cpus_pc1512[];
@ -91,6 +88,9 @@ extern int cpu_hasCR4;
extern uint64_t cpu_CR4_mask;
#define CPU_SUPPORTS_DYNAREC 1
#define CPU_REQUIRES_DYNAREC 2
extern uint64_t tsc;
void cyrix_write(uint16_t addr, uint8_t val, void *priv);
@ -100,3 +100,5 @@ extern int is8086;
void cpu_RDMSR();
void cpu_WRMSR();
extern int cpu_use_dynarec;

View file

@ -114,9 +114,7 @@ typedef struct
uint8_t access;
uint16_t seg;
uint32_t limit_low, limit_high;
#ifdef DYNAREC
int checked; /*Non-zero if selector is known to be valid*/
#endif
} x86seg;
x86seg gdt,ldt,idt,tr;

View file

@ -15,10 +15,8 @@
#include "x86.h"
#include "cpu.h"
#include "rom.h"
#if DYNAREC
#include "x86_ops.h"
#include "codegen.h"
#endif
page_t *pages;
page_t **page_lookup;
@ -647,9 +645,7 @@ void flushmmucache()
exit(-1);
}
}*/
#if DYNAREC
codegen_flush();
#endif
}
void flushmmucache_nopc()
@ -925,11 +921,10 @@ void addwritelookup(uint32_t virt, uint32_t phys)
}
// if (page_lookup[virt >> 12] && (writelookup2[virt>>12] != 0xffffffff))
// fatal("Bad write mapping\n");
#if DYNAREC
if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page)
page_lookup[virt >> 12] = &pages[phys >> 12];//(uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)];
else
#endif
writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)];
// pclog("addwritelookup %08x %08x %p %p %016llx %p\n", virt, phys, (void *)page_lookup[virt >> 12], (void *)writelookup2[virt >> 12], pages[phys >> 12].dirty_mask, (void *)&pages[phys >> 12]);
writelookupp[writelnext] = mmu_perm;
@ -1396,33 +1391,27 @@ uint32_t mem_read_raml(uint32_t addr, void *priv)
void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p)
{
#if DYNAREC
uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
// pclog("mem_write_ramb_page: %08x %02x %08x %llx %llx\n", addr, val, cs+pc, p->dirty_mask, mask);
p->dirty_mask |= mask;
#endif
p->mem[addr & 0xfff] = val;
}
void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p)
{
#if DYNAREC
uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
if ((addr & 0x3f) == 0x3f)
mask |= (mask << 1);
// pclog("mem_write_ramw_page: %08x %04x %08x\n", addr, val, cs+pc);
p->dirty_mask |= mask;
#endif
*(uint16_t *)&p->mem[addr & 0xfff] = val;
}
void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p)
{
#if DYNAREC
uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
if ((addr & 0x3f) >= 0x3d)
mask |= (mask << 1);
// pclog("mem_write_raml_page: %08x %08x %08x\n", addr, val, cs+pc);
p->dirty_mask |= mask;
#endif
*(uint32_t *)&p->mem[addr & 0xfff] = val;
}
@ -1512,7 +1501,6 @@ void mem_updatecache()
void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr)
{
#ifdef DYNAREC
start_addr &= ~PAGE_MASK_MASK;
end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK;
@ -1522,7 +1510,6 @@ void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr)
pages[start_addr >> 12].dirty_mask |= mask;
}
#endif
}
static inline int mem_mapping_read_allowed(uint32_t flags, int state)

View file

@ -102,14 +102,9 @@ MODEL models[] =
{"AMI WinBIOS 486", ROM_WIN486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_ali1429_init},
/* {"AMI WinBIOS 486 PCI", ROM_PCI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_um8881f_init},*/
{"Award SiS 496/497", ROM_SIS496, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_sis496_init},
#ifdef DYNAREC
{"Intel Premiere/PCI", ROM_REVENGE, { "Intel", cpus_Pentium5V, "", NULL, "", NULL}, 0, at_batman_init},
{"Intel Advanced/EV", ROM_ENDEAVOR, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "", NULL}, 0, at_endeavor_init},
{"Award 430VX PCI", ROM_430VX, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "", NULL}, 0, at_i430vx_init},
#else
{"Intel Advanced/EV", ROM_ENDEAVOR, { "IDT", cpus_WinChip, "", NULL, "", NULL}, 0, at_endeavor_init},
{"Award 430VX PCI", ROM_430VX, { "IDT", cpus_WinChip, "", NULL, "", NULL}, 0, at_i430vx_init},
#endif
{"", -1, {"", 0, "", 0, "", 0}, 0}
};

View file

@ -8,10 +8,8 @@
#include "amstrad.h"
#include "cdrom-ioctl.h"
#include "mem.h"
#ifdef DYNAREC
#include "x86_ops.h"
#include "codegen.h"
#endif
#include "cdrom-null.h"
#include "config.h"
#include "cpu.h"
@ -207,9 +205,7 @@ void initpc()
loadconfig(NULL);
pclog("Config loaded\n");
#if DYNAREC
codegen_init();
#endif
cpuspeed2=(AT)?2:1;
// cpuspeed2=cpuspeed;
@ -349,9 +345,19 @@ void runpc()
startblit();
clockrate = models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed;
if (is386) exec386(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100);
else if (AT) exec386(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100);
else execx86(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100);
if (is386)
{
if (cpu_use_dynarec)
exec386_dynarec(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100);
else
exec386(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100);
}
else if (AT)
exec386(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100);
else
execx86(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100);
keyboard_poll_host();
keyboard_process();
// checkkeys();
@ -374,7 +380,7 @@ void runpc()
segareads=egareads;
segawrites=egawrites;
scycles_lost = cycles_lost;
#if DYNAREC
cpu_recomp_blocks_latched = cpu_recomp_blocks;
cpu_recomp_ins_latched = cpu_recomp_ins;
cpu_recomp_full_ins_latched = cpu_recomp_full_ins;
@ -396,7 +402,7 @@ void runpc()
cpu_recomp_removed = 0;
cpu_reps = 0;
cpu_notreps = 0;
#endif
updatestatus=1;
readlnum=writelnum=0;
egareads=egawrites=0;
@ -501,6 +507,7 @@ void loadconfig(char *fn)
romset = model_getromset();
cpu_manufacturer = config_get_int(NULL, "cpu_manufacturer", 0);
cpu = config_get_int(NULL, "cpu", 0);
cpu_use_dynarec = config_get_int(NULL, "cpu_use_dynarec", 0);
gfxcard = config_get_int(NULL, "gfxcard", 0);
video_speed = config_get_int(NULL, "video_speed", 3);
@ -563,6 +570,7 @@ void saveconfig()
config_set_int(NULL, "model", model);
config_set_int(NULL, "cpu_manufacturer", cpu_manufacturer);
config_set_int(NULL, "cpu", cpu);
config_set_int(NULL, "cpu_use_dynarec", cpu_use_dynarec);
config_set_int(NULL, "gfxcard", gfxcard);
config_set_int(NULL, "video_speed", video_speed);

View file

@ -55,39 +55,40 @@ BEGIN
END
END
ConfigureDlg DIALOGEX 0, 0, 232+40, 272
ConfigureDlg DIALOGEX 0, 0, 232+40, 292
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Configure PCem"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,64,248,50,14, WS_TABSTOP
PUSHBUTTON "Cancel",IDCANCEL,128,248,50,14, WS_TABSTOP
DEFPUSHBUTTON "OK",IDOK,64,268,50,14, WS_TABSTOP
PUSHBUTTON "Cancel",IDCANCEL,128,268,50,14, WS_TABSTOP
COMBOBOX IDC_COMBO1,62,16,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBOVID,62,36,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure", IDC_CONFIGUREVID, 224, 36, 40, 14, WS_TABSTOP
COMBOBOX IDC_COMBOCPUM,62,56,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBO3,62,76,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBOCHC,62,96,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBOSPD,62,116,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBOSND,62,136,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure", IDC_CONFIGURESND, 224, 136, 40, 14, WS_TABSTOP
EDITTEXT IDC_MEMTEXT, 62, 152, 36, 14, ES_AUTOHSCROLL | ES_NUMBER
CONTROL "", IDC_MEMSPIN, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 98, 152, 12, 14
LTEXT "MB", IDC_STATIC, 98, 152, 40, 10
CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,172,118,10
CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,188,118,10
CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,204,118,10
CONTROL "Composite CGA",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,220,118,10
CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,236,118,10
PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 236, 40, 14, WS_TABSTOP
CONTROL "Dynamic Recompiler",IDC_CHECKDYNAREC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,96,118,10
COMBOBOX IDC_COMBOCHC,62,116,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBOSPD,62,136,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBOSND,62,156,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure", IDC_CONFIGURESND, 224, 156, 40, 14, WS_TABSTOP
EDITTEXT IDC_MEMTEXT, 62, 172, 36, 14, ES_AUTOHSCROLL | ES_NUMBER
CONTROL "", IDC_MEMSPIN, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 98, 172, 12, 14
LTEXT "MB", IDC_STATIC, 98, 172, 40, 10
CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,192,118,10
CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,208,118,10
CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,224,118,10
CONTROL "Composite CGA",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,240,118,10
CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,256,118,10
PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 256, 40, 14, WS_TABSTOP
LTEXT "Machine :",IDC_STATIC,15,16,40,10
LTEXT "Video :",IDC_STATIC,15,36,34,10
LTEXT "CPU type :",IDC_STATIC,15,56,34,10
LTEXT "CPU :",IDC_STATIC,15,76,34,10
LTEXT "Cache :",IDC_STATIC,15,96,40,10
LTEXT "Video speed :",IDC_STATIC,15,116,40,10
LTEXT "Soundcard :",IDC_STATIC,15,136,40,10
LTEXT "Memory :",IDC_STATIC,15,156,40,10
LTEXT "Cache :",IDC_STATIC,15,116,40,10
LTEXT "Video speed :",IDC_STATIC,15,136,40,10
LTEXT "Soundcard :",IDC_STATIC,15,156,40,10
LTEXT "Memory :",IDC_STATIC,15,176,40,10
END
HdConfDlg DIALOGEX 0, 0, 210, 312

View file

@ -41,6 +41,7 @@
#define IDC_CHECKGUS 1014
#define IDC_CHECKSSI 1015
#define IDC_CHECKVOODOO 1016
#define IDC_CHECKDYNAREC 1017
#define IDC_STATIC 1020
#define IDC_EDIT1 1030
#define IDC_EDIT2 1031

View file

@ -27,6 +27,8 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR
int rom, gfx, mem, fpu;
int temp_cpu, temp_cpu_m, temp_model;
int temp_GAMEBLASTER, temp_GUS, temp_SSI2001, temp_voodoo, temp_sound_card_current;
int temp_dynarec;
int cpu_flags;
// pclog("Dialog msg %i %08X\n",message,message);
switch (message)
{
@ -137,6 +139,14 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR
h=GetDlgItem(hdlg, IDC_CHECKVOODOO);
SendMessage(h, BM_SETCHECK, voodoo_enabled, 0);
cpu_flags = models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[cpu].cpu_flags;
h=GetDlgItem(hdlg, IDC_CHECKDYNAREC);
if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC))
EnableWindow(h, FALSE);
else
EnableWindow(h, TRUE);
SendMessage(h, BM_SETCHECK, ((cpu_flags & CPU_SUPPORTS_DYNAREC) && cpu_use_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC), 0);
h = GetDlgItem(hdlg, IDC_COMBOCHC);
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"A little");
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"A bit");
@ -215,7 +225,13 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR
h = GetDlgItem(hdlg, IDC_COMBOSND);
temp_sound_card_current = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)];
if (temp_model != model || gfx != gfxcard || mem != mem_size || fpu != hasfpu || temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS || temp_SSI2001 != SSI2001 || temp_sound_card_current != sound_card_current || temp_voodoo != voodoo_enabled)
h = GetDlgItem(hdlg, IDC_CHECKDYNAREC);
temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0);
if (temp_model != model || gfx != gfxcard || mem != mem_size ||
fpu != hasfpu || temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS ||
temp_SSI2001 != SSI2001 || temp_sound_card_current != sound_card_current ||
temp_voodoo != voodoo_enabled || temp_dynarec != cpu_use_dynarec)
{
if (MessageBox(NULL,"This will reset PCem!\nOkay to continue?","PCem",MB_OKCANCEL)==IDOK)
{
@ -230,6 +246,7 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR
SSI2001 = temp_SSI2001;
sound_card_current = temp_sound_card_current;
voodoo_enabled = temp_voodoo;
cpu_use_dynarec = temp_dynarec;
mem_resize();
loadbios();
@ -319,6 +336,17 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR
}
if (temp_cpu >= c) temp_cpu = c - 1;
SendMessage(h, CB_SETCURSEL, temp_cpu, 0);
h = GetDlgItem(hdlg, IDC_CHECKDYNAREC);
temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0);
cpu_flags = models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags;
h=GetDlgItem(hdlg, IDC_CHECKDYNAREC);
if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC))
EnableWindow(h, FALSE);
else
EnableWindow(h, TRUE);
SendMessage(h, BM_SETCHECK, ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC), 0);
}
break;
case IDC_COMBOCPUM:
@ -341,6 +369,39 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR
}
if (temp_cpu >= c) temp_cpu = c - 1;
SendMessage(h, CB_SETCURSEL, temp_cpu, 0);
h = GetDlgItem(hdlg, IDC_CHECKDYNAREC);
temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0);
cpu_flags = models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags;
h=GetDlgItem(hdlg, IDC_CHECKDYNAREC);
if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC))
EnableWindow(h, FALSE);
else
EnableWindow(h, TRUE);
SendMessage(h, BM_SETCHECK, ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC), 0);
}
break;
case IDC_COMBO3:
if (HIWORD(wParam) == CBN_SELCHANGE)
{
h = GetDlgItem(hdlg, IDC_COMBO1);
temp_model = listtomodel[SendMessage(h, CB_GETCURSEL, 0, 0)];
h = GetDlgItem(hdlg, IDC_COMBOCPUM);
temp_cpu_m = SendMessage(h, CB_GETCURSEL, 0, 0);
h=GetDlgItem(hdlg, IDC_COMBO3);
temp_cpu = SendMessage(h, CB_GETCURSEL, 0, 0);
h = GetDlgItem(hdlg, IDC_CHECKDYNAREC);
temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0);
cpu_flags = models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags;
h=GetDlgItem(hdlg, IDC_CHECKDYNAREC);
if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC))
EnableWindow(h, FALSE);
else
EnableWindow(h, TRUE);
SendMessage(h, BM_SETCHECK, ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC), 0);
}
break;

View file

@ -8,11 +8,9 @@
#include "video.h"
#include "resources.h"
#include "win.h"
#ifdef DYNAREC
#include "x86_ops.h"
#include "mem.h"
#include "codegen.h"
#endif
HWND status_hwnd;
int status_is_open = 0;
@ -37,33 +35,32 @@ static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR
sprintf(device_s,
"CPU speed : %f MIPS\n"
"FPU speed : %f MFLOPS\n\n"
#ifndef DYNAREC
"Cache misses (read) : %i/sec\n"
"Cache misses (write) : %i/sec\n\n"
#endif
/* "Cache misses (read) : %i/sec\n"
"Cache misses (write) : %i/sec\n\n"*/
"Video throughput (read) : %i bytes/sec\n"
"Video throughput (write) : %i bytes/sec\n\n"
"Effective clockspeed : %iHz\n\n"
"Timer 0 frequency : %fHz\n\n"
"CPU time : %f%% (%f%%)\n"
#ifdef DYNAREC
"New blocks : %i\nOld blocks : %i\nRecompiled speed : %f MIPS\nAverage size : %f\n"
"Flushes : %i\nEvicted : %i\nReused : %i\nRemoved : %i\nReal speed : %f MIPS"
// "\nFully recompiled ins %% : %f%%"
#endif
,mips,
flops,
#ifndef DYNAREC
/*#ifndef DYNAREC
sreadlnum,
swritelnum,
#endif
#endif*/
segareads,
segawrites,
clockrate - (sreadlnum*memwaitstate) - (swritelnum*memwaitstate) - scycles_lost,
pit_timer0_freq(),
((double)main_time * 100.0) / status_diff,
((double)main_time * 100.0) / timer_freq
#ifdef DYNAREC
, cpu_new_blocks_latched, cpu_recomp_blocks_latched, (double)cpu_recomp_ins_latched / 1000000.0, (double)cpu_recomp_ins_latched/cpu_recomp_blocks_latched,
cpu_recomp_flushes_latched, cpu_recomp_evicted_latched,
cpu_recomp_reuse_latched, cpu_recomp_removed_latched,
@ -71,18 +68,16 @@ static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR
((double)cpu_recomp_ins_latched / 1000000.0) / ((double)main_time / timer_freq)
// ((double)cpu_recomp_full_ins_latched / (double)cpu_recomp_ins_latched) * 100.0
// cpu_reps_latched, cpu_notreps_latched
#endif
);
main_time = 0;
#ifndef DYNAREC
/*#ifndef DYNAREC
device_add_status_info(device_s, 4096);
#endif
#endif*/
SendDlgItemMessage(hdlg, IDC_STEXT_DEVICE, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s);
#ifdef DYNAREC
device_s[0] = 0;
device_add_status_info(device_s, 4096);
SendDlgItemMessage(hdlg, IDC_STEXT1, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s);
#endif
}
return TRUE;

View file

@ -3,7 +3,6 @@
typedef int (*OpFn)(uint32_t fetchdat);
#ifdef DYNAREC
void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f, OpFn *dynarec_opcodes, OpFn *dynarec_opcodes_0f);
extern OpFn *x86_dynarec_opcodes;
@ -54,9 +53,6 @@ extern OpFn dynarec_ops_fpu_df_a16[256];
extern OpFn dynarec_ops_fpu_df_a32[256];
extern OpFn dynarec_ops_nofpu_a16[256];
extern OpFn dynarec_ops_nofpu_a32[256];
#else
void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f);
#endif
extern OpFn *x86_opcodes;
extern OpFn *x86_opcodes_0f;

View file

@ -70,9 +70,9 @@ static int opSAHF(uint32_t fetchdat)
flags_rebuild();
flags = (flags & 0xff00) | (AH & 0xd5) | 2;
CLOCK_CYCLES(3);
#ifdef DYNAREC
codegen_flags_changed = 0;
#endif
return 0;
}
static int opLAHF(uint32_t fetchdat)
@ -130,9 +130,9 @@ static int opPOPF_286(uint32_t fetchdat)
flags_extract();
CLOCK_CYCLES(5);
#ifdef DYNAREC
codegen_flags_changed = 0;
#endif
return 0;
}
static int opPOPF(uint32_t fetchdat)
@ -153,9 +153,9 @@ static int opPOPF(uint32_t fetchdat)
flags_extract();
CLOCK_CYCLES(5);
#ifdef DYNAREC
codegen_flags_changed = 0;
#endif
return 0;
}
static int opPOPFD(uint32_t fetchdat)
@ -183,8 +183,8 @@ static int opPOPFD(uint32_t fetchdat)
flags_extract();
CLOCK_CYCLES(5);
#ifdef DYNAREC
codegen_flags_changed = 0;
#endif
return 0;
}

View file

@ -396,9 +396,7 @@ void loadseg(uint16_t seg, x86seg *s)
#ifndef CS_ACCESSED
}
#endif
#ifdef DYNAREC
s->checked = 0;
#endif
}
else
{
@ -407,9 +405,7 @@ void loadseg(uint16_t seg, x86seg *s)
s->seg = seg;
if (s == &_ss)
stack32 = 0;
#ifdef DYNAREC
s->checked = 1;
#endif
}
}