All GPF's are now enabled again; LEA reg,reg now correctly sets the register to the last computed effective address (undocumented behavior).

This commit is contained in:
OBattler
2016-08-10 04:43:13 +02:00
parent 8d39f0ac76
commit 723b685327
7 changed files with 51 additions and 10 deletions

View File

@@ -140,6 +140,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat)
if (writelookup2[addr >> 12] != -1) if (writelookup2[addr >> 12] != -1)
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
} }
cpu_state.last_ea = eaaddr;
} }
static inline void fetch_ea_16_long(uint32_t rmdat) static inline void fetch_ea_16_long(uint32_t rmdat)
@@ -182,6 +183,7 @@ static inline void fetch_ea_16_long(uint32_t rmdat)
if (writelookup2[addr >> 12] != -1) if (writelookup2[addr >> 12] != -1)
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
} }
cpu_state.last_ea = eaaddr;
} }
#define fetch_ea_16(rmdat) cpu_state.pc++; mod=(rmdat >> 6) & 3; reg=(rmdat >> 3) & 7; rm = rmdat & 7; if (mod != 3) { fetch_ea_16_long(rmdat); if (abrt) return 1; } #define fetch_ea_16(rmdat) cpu_state.pc++; mod=(rmdat >> 6) & 3; reg=(rmdat >> 3) & 7; rm = rmdat & 7; if (mod != 3) { fetch_ea_16_long(rmdat); if (abrt) return 1; }

View File

@@ -28,6 +28,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat)
if (writelookup2[addr >> 12] != -1) if (writelookup2[addr >> 12] != -1)
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
} }
cpu_state.last_ea = eaaddr;
} }
static inline void fetch_ea_16_long(uint32_t rmdat) static inline void fetch_ea_16_long(uint32_t rmdat)
@@ -43,6 +44,7 @@ static inline void fetch_ea_16_long(uint32_t rmdat)
if (writelookup2[addr >> 12] != -1) if (writelookup2[addr >> 12] != -1)
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
} }
cpu_state.last_ea = eaaddr;
} }
#define fetch_ea_16(rmdat) cpu_state.pc++; if (mod != 3) fetch_ea_16_long(rmdat); #define fetch_ea_16(rmdat) cpu_state.pc++; if (mod != 3) fetch_ea_16_long(rmdat);

View File

@@ -18,11 +18,13 @@ static inline void PUSH_W(uint16_t val)
{ {
writememw(ss, ESP - 2, val); if (abrt) return; writememw(ss, ESP - 2, val); if (abrt) return;
ESP -= 2; ESP -= 2;
cpu_state.last_ea = ESP;
} }
else else
{ {
writememw(ss, (SP - 2) & 0xFFFF, val); if (abrt) return; writememw(ss, (SP - 2) & 0xFFFF, val); if (abrt) return;
SP -= 2; SP -= 2;
cpu_state.last_ea = SP;
} }
} }
@@ -32,11 +34,13 @@ static inline void PUSH_L(uint32_t val)
{ {
writememl(ss, ESP - 4, val); if (abrt) return; writememl(ss, ESP - 4, val); if (abrt) return;
ESP -= 4; ESP -= 4;
cpu_state.last_ea = ESP;
} }
else else
{ {
writememl(ss, (SP - 4) & 0xFFFF, val); if (abrt) return; writememl(ss, (SP - 4) & 0xFFFF, val); if (abrt) return;
SP -= 4; SP -= 4;
cpu_state.last_ea = SP;
} }
} }
@@ -47,11 +51,13 @@ static inline uint16_t POP_W()
{ {
ret = readmemw(ss, ESP); if (abrt) return 0; ret = readmemw(ss, ESP); if (abrt) return 0;
ESP += 2; ESP += 2;
cpu_state.last_ea = ESP;
} }
else else
{ {
ret = readmemw(ss, SP); if (abrt) return 0; ret = readmemw(ss, SP); if (abrt) return 0;
SP += 2; SP += 2;
cpu_state.last_ea = SP;
} }
return ret; return ret;
} }
@@ -63,11 +69,13 @@ static inline uint32_t POP_L()
{ {
ret = readmeml(ss, ESP); if (abrt) return 0; ret = readmeml(ss, ESP); if (abrt) return 0;
ESP += 4; ESP += 4;
cpu_state.last_ea = ESP;
} }
else else
{ {
ret = readmeml(ss, SP); if (abrt) return 0; ret = readmeml(ss, SP); if (abrt) return 0;
SP += 4; SP += 4;
cpu_state.last_ea = SP;
} }
return ret; return ret;
} }
@@ -79,11 +87,13 @@ static inline uint16_t POP_W_seg(uint32_t seg)
{ {
ret = readmemw(seg, ESP); if (abrt) return 0; ret = readmemw(seg, ESP); if (abrt) return 0;
ESP += 2; ESP += 2;
cpu_state.last_ea = ESP;
} }
else else
{ {
ret = readmemw(seg, SP); if (abrt) return 0; ret = readmemw(seg, SP); if (abrt) return 0;
SP += 2; SP += 2;
cpu_state.last_ea = SP;
} }
return ret; return ret;
} }
@@ -95,11 +105,13 @@ static inline uint32_t POP_L_seg(uint32_t seg)
{ {
ret = readmeml(seg, ESP); if (abrt) return 0; ret = readmeml(seg, ESP); if (abrt) return 0;
ESP += 4; ESP += 4;
cpu_state.last_ea = ESP;
} }
else else
{ {
ret = readmeml(seg, SP); if (abrt) return 0; ret = readmeml(seg, SP); if (abrt) return 0;
SP += 4; SP += 4;
cpu_state.last_ea = SP;
} }
return ret; return ret;
} }

View File

@@ -383,11 +383,15 @@ static void fetcheal()
if (rm&4) FETCHADD(9); if (rm&4) FETCHADD(9);
else FETCHADD(11+slowrm[rm]); else FETCHADD(11+slowrm[rm]);
break; break;
case 3:
if (!(rm&4)) FETCHADD(2+slowrm[rm]);
return;
} }
eaaddr+=(*mod1add[0][rm])+(*mod1add[1][rm]); eaaddr+=(*mod1add[0][rm])+(*mod1add[1][rm]);
easeg=*mod1seg[rm]; easeg=*mod1seg[rm];
eaaddr&=0xFFFF; eaaddr&=0xFFFF;
} }
last_ea = eaaddr;
} }
static inline uint8_t geteab() static inline uint8_t geteab()
@@ -1173,6 +1177,7 @@ void execx86(int cycs)
if (ssegs) ss=oldss; if (ssegs) ss=oldss;
writememw(ss,((SP-2)&0xFFFF),ES); writememw(ss,((SP-2)&0xFFFF),ES);
SP-=2; SP-=2;
cpu_state.last_ea = SP;
cycles-=14; cycles-=14;
break; break;
case 0x07: /*POP ES*/ case 0x07: /*POP ES*/
@@ -1180,6 +1185,7 @@ void execx86(int cycs)
tempw=readmemw(ss,SP); tempw=readmemw(ss,SP);
loadseg(tempw,&_es); loadseg(tempw,&_es);
SP+=2; SP+=2;
cpu_state.last_ea = SP;
cycles-=12; cycles-=12;
break; break;
@@ -1236,6 +1242,7 @@ void execx86(int cycs)
if (ssegs) ss=oldss; if (ssegs) ss=oldss;
writememw(ss,((SP-2)&0xFFFF),CS); writememw(ss,((SP-2)&0xFFFF),CS);
SP-=2; SP-=2;
cpu_state.last_ea = SP;
cycles-=14; cycles-=14;
break; break;
case 0x0F: /*POP CS - 8088/8086 only*/ case 0x0F: /*POP CS - 8088/8086 only*/
@@ -1243,6 +1250,7 @@ void execx86(int cycs)
tempw=readmemw(ss,SP); tempw=readmemw(ss,SP);
loadseg(tempw,&_cs); loadseg(tempw,&_cs);
SP+=2; SP+=2;
cpu_state.last_ea = SP;
cycles-=12; cycles-=12;
break; break;
@@ -1296,12 +1304,14 @@ void execx86(int cycs)
writememw(ss,((SP-2)&0xFFFF),SS); writememw(ss,((SP-2)&0xFFFF),SS);
SP-=2; SP-=2;
cycles-=14; cycles-=14;
cpu_state.last_ea = SP;
break; break;
case 0x17: /*POP SS*/ case 0x17: /*POP SS*/
if (ssegs) ss=oldss; if (ssegs) ss=oldss;
tempw=readmemw(ss,SP); tempw=readmemw(ss,SP);
loadseg(tempw,&_ss); loadseg(tempw,&_ss);
SP+=2; SP+=2;
cpu_state.last_ea = SP;
noint=1; noint=1;
cycles-=12; cycles-=12;
// output=1; // output=1;
@@ -1360,6 +1370,7 @@ void execx86(int cycs)
if (ssegs) ss=oldss; if (ssegs) ss=oldss;
writememw(ss,((SP-2)&0xFFFF),DS); writememw(ss,((SP-2)&0xFFFF),DS);
SP-=2; SP-=2;
cpu_state.last_ea = SP;
cycles-=14; cycles-=14;
break; break;
case 0x1F: /*POP DS*/ case 0x1F: /*POP DS*/
@@ -1368,6 +1379,7 @@ void execx86(int cycs)
loadseg(tempw,&_ds); loadseg(tempw,&_ds);
if (ssegs) oldds=ds; if (ssegs) oldds=ds;
SP+=2; SP+=2;
cpu_state.last_ea = SP;
cycles-=12; cycles-=12;
break; break;
@@ -1672,6 +1684,7 @@ void execx86(int cycs)
case 0x54: case 0x55: case 0x56: case 0x57: case 0x54: case 0x55: case 0x56: case 0x57:
if (ssegs) ss=oldss; if (ssegs) ss=oldss;
SP-=2; SP-=2;
cpu_state.last_ea = SP;
writememw(ss,SP,cpu_state.regs[opcode&7].w); writememw(ss,SP,cpu_state.regs[opcode&7].w);
cycles-=15; cycles-=15;
break; break;
@@ -1679,6 +1692,7 @@ void execx86(int cycs)
case 0x5C: case 0x5D: case 0x5E: case 0x5F: case 0x5C: case 0x5D: case 0x5E: case 0x5F:
if (ssegs) ss=oldss; if (ssegs) ss=oldss;
SP+=2; SP+=2;
cpu_state.last_ea = SP;
cpu_state.regs[opcode&7].w=readmemw(ss,(SP-2)&0xFFFF); cpu_state.regs[opcode&7].w=readmemw(ss,(SP-2)&0xFFFF);
cycles-=12; cycles-=12;
break; break;
@@ -2059,7 +2073,7 @@ void execx86(int cycs)
case 0x8D: /*LEA*/ case 0x8D: /*LEA*/
fetchea(); fetchea();
cpu_state.regs[reg].w=eaaddr; cpu_state.regs[reg].w=(mod == 3)?cpu_state.last_ea:eaaddr;
cycles-=2; cycles-=2;
break; break;
@@ -2100,6 +2114,7 @@ void execx86(int cycs)
if (ssegs) ss=oldss; if (ssegs) ss=oldss;
tempw=readmemw(ss,SP); tempw=readmemw(ss,SP);
SP+=2; SP+=2;
cpu_state.last_ea = SP;
seteaw(tempw); seteaw(tempw);
cycles-=25; cycles-=25;
break; break;
@@ -2136,6 +2151,7 @@ void execx86(int cycs)
writememw(ss,(SP-2)&0xFFFF,tempw3); writememw(ss,(SP-2)&0xFFFF,tempw3);
writememw(ss,(SP-4)&0xFFFF,tempw4); writememw(ss,(SP-4)&0xFFFF,tempw4);
SP-=4; SP-=4;
cpu_state.last_ea = SP;
cycles-=36; cycles-=36;
FETCHCLEAR(); FETCHCLEAR();
break; break;
@@ -2146,12 +2162,14 @@ void execx86(int cycs)
if (ssegs) ss=oldss; if (ssegs) ss=oldss;
writememw(ss,((SP-2)&0xFFFF),flags|0xF000); writememw(ss,((SP-2)&0xFFFF),flags|0xF000);
SP-=2; SP-=2;
cpu_state.last_ea = SP;
cycles-=14; cycles-=14;
break; break;
case 0x9D: /*POPF*/ case 0x9D: /*POPF*/
if (ssegs) ss=oldss; if (ssegs) ss=oldss;
flags=readmemw(ss,SP)&0xFFF; flags=readmemw(ss,SP)&0xFFF;
SP+=2; SP+=2;
cpu_state.last_ea = SP;
cycles-=12; cycles-=12;
break; break;
case 0x9E: /*SAHF*/ case 0x9E: /*SAHF*/
@@ -2881,6 +2899,7 @@ void execx86(int cycs)
break; break;
case 0xD7: /*XLAT*/ case 0xD7: /*XLAT*/
addr=BX+AL; addr=BX+AL;
cpu_state.last_ea = addr;
AL=readmemb(ds+addr); AL=readmemb(ds+addr);
cycles-=11; cycles-=11;
break; break;
@@ -2945,6 +2964,7 @@ void execx86(int cycs)
// writememb(ss+((SP-1)&0xFFFF),pc>>8); // writememb(ss+((SP-1)&0xFFFF),pc>>8);
writememw(ss,((SP-2)&0xFFFF),cpu_state.pc); writememw(ss,((SP-2)&0xFFFF),cpu_state.pc);
SP-=2; SP-=2;
cpu_state.last_ea = SP;
cpu_state.pc+=tempw; cpu_state.pc+=tempw;
cycles-=23; cycles-=23;
FETCHCLEAR(); FETCHCLEAR();
@@ -3346,6 +3366,7 @@ void execx86(int cycs)
if (ssegs) ss=oldss; if (ssegs) ss=oldss;
writememw(ss,(SP-2)&0xFFFF,cpu_state.pc); writememw(ss,(SP-2)&0xFFFF,cpu_state.pc);
SP-=2; SP-=2;
cpu_state.last_ea = SP;
cpu_state.pc=tempw; cpu_state.pc=tempw;
// printf("FF 10\n"); // printf("FF 10\n");
cycles-=((mod==3)?20:29); cycles-=((mod==3)?20:29);
@@ -3363,6 +3384,7 @@ void execx86(int cycs)
writememw(ss,(SP-2)&0xFFFF,tempw3); writememw(ss,(SP-2)&0xFFFF,tempw3);
writememw(ss,((SP-4)&0xFFFF),tempw4); writememw(ss,((SP-4)&0xFFFF),tempw4);
SP-=4; SP-=4;
cpu_state.last_ea = SP;
cycles-=53; cycles-=53;
FETCHCLEAR(); FETCHCLEAR();
break; break;
@@ -3387,6 +3409,7 @@ void execx86(int cycs)
if (ssegs) ss=oldss; if (ssegs) ss=oldss;
writememw(ss,((SP-2)&0xFFFF),tempw); writememw(ss,((SP-2)&0xFFFF),tempw);
SP-=2; SP-=2;
cpu_state.last_ea = SP;
cycles-=((mod==3)?15:24); cycles-=((mod==3)?15:24);
break; break;

View File

@@ -108,6 +108,7 @@ struct
uint32_t flags_op1, flags_op2; uint32_t flags_op1, flags_op2;
uint32_t pc; uint32_t pc;
uint32_t last_ea;
} cpu_state; } cpu_state;
/*x86reg regs[8];*/ /*x86reg regs[8];*/

View File

@@ -329,16 +329,16 @@ static int opMOV_a32_EAX(uint32_t fetchdat)
static int opLEA_w_a16(uint32_t fetchdat) static int opLEA_w_a16(uint32_t fetchdat)
{ {
fetch_ea_16(fetchdat); fetch_ea_16(fetchdat);
ILLEGAL_ON(mod == 3); // ILLEGAL_ON(mod == 3);
cpu_state.regs[reg].w = eaaddr; cpu_state.regs[reg].w = (mod == 3) ? (cpu_state.last_ea & 0xffff) : eaaddr;
CLOCK_CYCLES(timing_rr); CLOCK_CYCLES(timing_rr);
return 0; return 0;
} }
static int opLEA_w_a32(uint32_t fetchdat) static int opLEA_w_a32(uint32_t fetchdat)
{ {
fetch_ea_32(fetchdat); fetch_ea_32(fetchdat);
ILLEGAL_ON(mod == 3); // ILLEGAL_ON(mod == 3);
cpu_state.regs[reg].w = eaaddr; cpu_state.regs[reg].w = (mod == 3) ? (cpu_state.last_ea & 0xffff) : eaaddr;
CLOCK_CYCLES(timing_rr); CLOCK_CYCLES(timing_rr);
return 0; return 0;
} }
@@ -346,16 +346,16 @@ static int opLEA_w_a32(uint32_t fetchdat)
static int opLEA_l_a16(uint32_t fetchdat) static int opLEA_l_a16(uint32_t fetchdat)
{ {
fetch_ea_16(fetchdat); fetch_ea_16(fetchdat);
ILLEGAL_ON(mod == 3); // ILLEGAL_ON(mod == 3);
cpu_state.regs[reg].l = eaaddr & 0xffff; cpu_state.regs[reg].l = ((mod == 3) ? cpu_state.last_ea : eaaddr) & 0xffff;
CLOCK_CYCLES(timing_rr); CLOCK_CYCLES(timing_rr);
return 0; return 0;
} }
static int opLEA_l_a32(uint32_t fetchdat) static int opLEA_l_a32(uint32_t fetchdat)
{ {
fetch_ea_32(fetchdat); fetch_ea_32(fetchdat);
ILLEGAL_ON(mod == 3); // ILLEGAL_ON(mod == 3);
cpu_state.regs[reg].l = eaaddr; cpu_state.regs[reg].l = (mod == 3) ? cpu_state.last_ea : eaaddr;
CLOCK_CYCLES(timing_rr); CLOCK_CYCLES(timing_rr);
return 0; return 0;
} }
@@ -366,6 +366,7 @@ static int opXLAT_a16(uint32_t fetchdat)
{ {
uint32_t addr = (BX + AL)&0xFFFF; uint32_t addr = (BX + AL)&0xFFFF;
uint8_t temp; uint8_t temp;
last_ea = addr;
temp = readmemb(ea_seg->base, addr); temp = readmemb(ea_seg->base, addr);
if (abrt) return 1; if (abrt) return 1;
AL = temp; AL = temp;
@@ -376,6 +377,7 @@ static int opXLAT_a32(uint32_t fetchdat)
{ {
uint32_t addr = EBX + AL; uint32_t addr = EBX + AL;
uint8_t temp; uint8_t temp;
last_ea = addr;
temp = readmemb(ea_seg->base, addr); temp = readmemb(ea_seg->base, addr);
if (abrt) return 1; if (abrt) return 1;
AL = temp; AL = temp;

View File

@@ -145,7 +145,6 @@ void x86_doabrt(int x86_abrt)
} }
void x86gpf(char *s, uint16_t error) void x86gpf(char *s, uint16_t error)
{ {
if (error == 0x82) return;
pclog("GPF %04X : %s\n", error, s); pclog("GPF %04X : %s\n", error, s);
abrt = ABRT_GPF; abrt = ABRT_GPF;
abrt_error = error; abrt_error = error;