mirror of
https://github.com/holub/mame
synced 2025-05-04 21:43:05 +03:00
i286 - Fix bunch of fault restarts [Carl]
This commit is contained in:
parent
b6012aaa60
commit
2d60c3dba0
@ -65,6 +65,13 @@ typedef enum {
|
||||
#define SUBB(dst,src) { unsigned res=dst-src; SetCFB(res); SetOFB_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
|
||||
#define SUBW(dst,src) { unsigned res=dst-src; SetCFW(res); SetOFW_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
|
||||
|
||||
// don't modify CF in case fault occurs
|
||||
#define ADCB(dst,src,tmpcf) { unsigned res=dst+src; tmpcf = res & 0x100; SetOFB_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
|
||||
#define ADCW(dst,src,tmpcf) { unsigned res=dst+src; tmpcf = res & 0x10000; SetOFW_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
|
||||
|
||||
#define SBBB(dst,src,tmpcf) { unsigned res=dst-src; tmpcf = res & 0x100; SetOFB_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
|
||||
#define SBBW(dst,src,tmpcf) { unsigned res=dst-src; tmpcf = res & 0x10000; SetOFW_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
|
||||
|
||||
#define ORB(dst,src) dst |= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Byte(dst)
|
||||
#define ORW(dst,src) dst |= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Word(dst)
|
||||
|
||||
@ -101,10 +108,17 @@ typedef enum {
|
||||
#define DefaultSeg(Seg) ((cpustate->seg_prefix && (Seg == DS || Seg == SS)) ? cpustate->prefix_seg : Seg)
|
||||
#define DefaultBase(Seg) ((cpustate->seg_prefix && (Seg == DS || Seg == SS)) ? cpustate->base[cpustate->prefix_seg] : cpustate->base[Seg])
|
||||
|
||||
#ifdef I80286
|
||||
#define GetMemB(Seg,Off) (read_mem_byte(GetMemAddr(cpustate,Seg,Off,1,I80286_READ)))
|
||||
#define GetMemW(Seg,Off) (read_mem_word(GetMemAddr(cpustate,Seg,Off,2,I80286_READ)))
|
||||
#define PutMemB(Seg,Off,x) write_mem_byte(GetMemAddr(cpustate,Seg,Off,1,I80286_WRITE), (x))
|
||||
#define PutMemW(Seg,Off,x) write_mem_word(GetMemAddr(cpustate,Seg,Off,2,I80286_WRITE), (x))
|
||||
#else
|
||||
#define GetMemB(Seg,Off) (read_mem_byte((DefaultBase(Seg) + (Off)) & AMASK))
|
||||
#define GetMemW(Seg,Off) (read_mem_word((DefaultBase(Seg) + (Off)) & AMASK))
|
||||
#define PutMemB(Seg,Off,x) write_mem_byte((DefaultBase(Seg) + (Off)) & AMASK, (x))
|
||||
#define PutMemW(Seg,Off,x) write_mem_word((DefaultBase(Seg) + (Off)) & AMASK, (x))
|
||||
#endif
|
||||
|
||||
#define PEEKBYTE(ea) (read_mem_byte((ea) & AMASK))
|
||||
#define ReadByte(ea) (read_mem_byte((ea) & AMASK))
|
||||
|
@ -16,6 +16,9 @@ static void PREFIX186(_pusha)(i8086_state *cpustate) /* Opcode 0x60 */
|
||||
{
|
||||
unsigned tmp=cpustate->regs.w[SP];
|
||||
|
||||
#ifdef I80286
|
||||
if(PM) i80286_check_permission(cpustate, SS, cpustate->regs.w[SP]-16, 16, I80286_WRITE);
|
||||
#endif
|
||||
ICOUNT -= timing.pusha;
|
||||
PUSH(cpustate->regs.w[AX]);
|
||||
PUSH(cpustate->regs.w[CX]);
|
||||
@ -31,6 +34,9 @@ static unsigned i186_popa_tmp; // hack around GCC 4.6 error because we need the
|
||||
static void PREFIX186(_popa)(i8086_state *cpustate) /* Opcode 0x61 */
|
||||
{
|
||||
|
||||
#ifdef I80286
|
||||
if(PM) i80286_check_permission(cpustate, SS, cpustate->regs.w[SP], 16, I80286_READ);
|
||||
#endif
|
||||
ICOUNT -= timing.popa;
|
||||
POP(cpustate->regs.w[DI]);
|
||||
POP(cpustate->regs.w[SI]);
|
||||
@ -100,6 +106,9 @@ static void PREFIX186(_imul_d8)(i8086_state *cpustate) /* Opcode 0x6b */
|
||||
|
||||
static void PREFIX186(_insb)(i8086_state *cpustate) /* Opcode 0x6c */
|
||||
{
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
ICOUNT -= timing.ins8;
|
||||
PutMemB(ES,cpustate->regs.w[DI],read_port_byte(cpustate->regs.w[DX]));
|
||||
cpustate->regs.w[DI] += cpustate->DirVal;
|
||||
@ -107,6 +116,9 @@ static void PREFIX186(_insb)(i8086_state *cpustate) /* Opcode 0x6c */
|
||||
|
||||
static void PREFIX186(_insw)(i8086_state *cpustate) /* Opcode 0x6d */
|
||||
{
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
ICOUNT -= timing.ins16;
|
||||
PutMemW(ES,cpustate->regs.w[DI],read_port_word(cpustate->regs.w[DX]));
|
||||
cpustate->regs.w[DI] += 2 * cpustate->DirVal;
|
||||
@ -114,6 +126,9 @@ static void PREFIX186(_insw)(i8086_state *cpustate) /* Opcode 0x6d */
|
||||
|
||||
static void PREFIX186(_outsb)(i8086_state *cpustate) /* Opcode 0x6e */
|
||||
{
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
ICOUNT -= timing.outs8;
|
||||
write_port_byte(cpustate->regs.w[DX],GetMemB(DS,cpustate->regs.w[SI]));
|
||||
cpustate->regs.w[SI] += cpustate->DirVal; /* GOL 11/27/01 */
|
||||
@ -121,6 +136,9 @@ static void PREFIX186(_outsb)(i8086_state *cpustate) /* Opcode 0x6e */
|
||||
|
||||
static void PREFIX186(_outsw)(i8086_state *cpustate) /* Opcode 0x6f */
|
||||
{
|
||||
#ifdef I80286
|
||||
if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
|
||||
#endif
|
||||
ICOUNT -= timing.outs16;
|
||||
write_port_word(cpustate->regs.w[DX],GetMemW(DS,cpustate->regs.w[SI]));
|
||||
cpustate->regs.w[SI] += 2 * cpustate->DirVal; /* GOL 11/27/01 */
|
||||
@ -146,17 +164,25 @@ static void PREFIX186(_rotshft_wd8)(i8086_state *cpustate) /* Opcode 0xc1 */
|
||||
|
||||
static void PREFIX186(_enter)(i8086_state *cpustate) /* Opcode 0xc8 */
|
||||
{
|
||||
unsigned nb = FETCH; unsigned i,level;
|
||||
unsigned nb = FETCH;
|
||||
unsigned i,level;
|
||||
UINT16 fp;
|
||||
|
||||
nb += FETCH << 8;
|
||||
#ifdef I80286
|
||||
level = FETCH & 0x1f;
|
||||
if(PM) i80286_check_permission(cpustate, SS, cpustate->regs.w[SP]-2-(level*2), 2+(level*2), I80286_WRITE);
|
||||
#else
|
||||
level = FETCH;
|
||||
#endif
|
||||
ICOUNT -= (level == 0) ? timing.enter0 : (level == 1) ? timing.enter1 : timing.enter_base + level * timing.enter_count;
|
||||
PUSH(cpustate->regs.w[BP]);
|
||||
cpustate->regs.w[BP]=cpustate->regs.w[SP];
|
||||
cpustate->regs.w[SP] -= nb;
|
||||
fp = cpustate->regs.w[SP];
|
||||
for (i=1;i<level;i++)
|
||||
PUSH(GetMemW(SS,cpustate->regs.w[BP]-i*2));
|
||||
if (level) PUSH(cpustate->regs.w[BP]);
|
||||
if (level) PUSH(fp);
|
||||
cpustate->regs.w[BP] = fp;
|
||||
cpustate->regs.w[SP] -= nb;
|
||||
}
|
||||
|
||||
static void PREFIX186(_leave)(i8086_state *cpustate) /* Opcode 0xc9 */
|
||||
|
@ -152,7 +152,7 @@ static void i80286_pop_seg(i80286_state *cpustate, int reg)
|
||||
cpustate->regs.w[SP] += 2;
|
||||
}
|
||||
|
||||
static void i80286_data_descriptor_full(i80286_state *cpustate,int reg, UINT16 selector, int cpl, UINT32 trap)
|
||||
static void i80286_data_descriptor_full(i80286_state *cpustate, int reg, UINT16 selector, int cpl, UINT32 trap, UINT16 offset, int size)
|
||||
{
|
||||
if (PM) {
|
||||
UINT16 desc[3];
|
||||
@ -189,6 +189,10 @@ static void i80286_data_descriptor_full(i80286_state *cpustate,int reg, UINT16 s
|
||||
if (CODE(r) && !READ(r)) throw trap;
|
||||
if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,(IDXTBL(selector)+(trap&1)));
|
||||
}
|
||||
if (offset+size) {
|
||||
if ((CODE(r) || !EXPDOWN(r)) && ((offset+size-1) > LIMIT(desc))) throw (reg==SS)?TRAP(STACK_FAULT,(trap&1)):trap;
|
||||
if (!CODE(r) && EXPDOWN(r) && ((offset <= LIMIT(desc)) || ((offset+size) > 0xffff))) throw (reg==SS)?TRAP(STACK_FAULT,(trap&1)):trap;
|
||||
}
|
||||
|
||||
SET_ACC(desc);
|
||||
WriteWord(addr+4, desc[2]);
|
||||
@ -204,7 +208,7 @@ static void i80286_data_descriptor_full(i80286_state *cpustate,int reg, UINT16 s
|
||||
|
||||
static void i80286_data_descriptor(i80286_state *cpustate, int reg, UINT16 selector)
|
||||
{
|
||||
i80286_data_descriptor_full(cpustate, reg, selector, CPL, TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)));
|
||||
i80286_data_descriptor_full(cpustate, reg, selector, CPL, TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)), 0, 0);
|
||||
}
|
||||
|
||||
static void i80286_switch_task(i80286_state *cpustate, UINT16 ntask, int type)
|
||||
@ -296,7 +300,7 @@ static void i80286_switch_task(i80286_state *cpustate, UINT16 ntask, int type)
|
||||
|
||||
if (type == CALL) cpustate->flags |= 0x4000;
|
||||
cpustate->msw |= 8;
|
||||
i80286_data_descriptor_full(cpustate, SS, ntss[TSS_SS], RPL(ntss[TSS_CS]), TRAP(INVALID_TSS,IDXTBL(ntss[TSS_SS])));
|
||||
i80286_data_descriptor_full(cpustate, SS, ntss[TSS_SS], RPL(ntss[TSS_CS]), TRAP(INVALID_TSS,IDXTBL(ntss[TSS_SS])), 0, 0);
|
||||
|
||||
cpustate->sregs[CS] = IDXTBL(cpustate->sregs[CS]) | RPL(ntss[TSS_CS]); // fixme
|
||||
try {
|
||||
@ -307,8 +311,8 @@ static void i80286_switch_task(i80286_state *cpustate, UINT16 ntask, int type)
|
||||
throw e;
|
||||
}
|
||||
|
||||
i80286_data_descriptor_full(cpustate, ES, ntss[TSS_ES], RPL(ntss[TSS_CS]), TRAP(INVALID_TSS,IDXTBL(ntss[TSS_ES])));
|
||||
i80286_data_descriptor_full(cpustate, DS, ntss[TSS_DS], RPL(ntss[TSS_CS]), TRAP(INVALID_TSS,IDXTBL(ntss[TSS_DS])));
|
||||
i80286_data_descriptor_full(cpustate, ES, ntss[TSS_ES], RPL(ntss[TSS_CS]), TRAP(INVALID_TSS,IDXTBL(ntss[TSS_ES])), 0, 0);
|
||||
i80286_data_descriptor_full(cpustate, DS, ntss[TSS_DS], RPL(ntss[TSS_CS]), TRAP(INVALID_TSS,IDXTBL(ntss[TSS_DS])), 0, 0);
|
||||
}
|
||||
|
||||
static void i80286_code_descriptor(i80286_state *cpustate, UINT16 selector, UINT16 offset, int gate)
|
||||
@ -360,7 +364,7 @@ static void i80286_code_descriptor(i80286_state *cpustate, UINT16 selector, UINT
|
||||
if (!CODE(r) || !SEGDESC(r)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel));
|
||||
if (DPL(r)>CPL) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel));
|
||||
if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(gatesel));
|
||||
if (GATEOFF(desc) > LIMIT(gatedesc)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel));
|
||||
if (GATEOFF(desc) > LIMIT(gatedesc)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
|
||||
|
||||
if (!CONF(r)&&(DPL(r)<CPL)) { // inner call
|
||||
UINT16 tss_ss, tss_sp, oldss, oldsp;
|
||||
@ -373,13 +377,13 @@ static void i80286_code_descriptor(i80286_state *cpustate, UINT16 selector, UINT
|
||||
oldss = cpustate->sregs[SS];
|
||||
oldsp = cpustate->regs.w[SP];
|
||||
oldstk = cpustate->base[SS] + oldsp;
|
||||
i80286_data_descriptor_full(cpustate, SS, tss_ss, DPL(r), TRAP(INVALID_TSS,IDXTBL(tss_ss)));
|
||||
i80286_data_descriptor_full(cpustate, SS, tss_ss, DPL(r), TRAP(INVALID_TSS,IDXTBL(tss_ss)), tss_sp-8-(GATECNT(desc)*2), 8+(GATECNT(desc)*2));
|
||||
cpustate->regs.w[SP] = tss_sp;
|
||||
PUSH(oldss);
|
||||
PUSH(oldsp);
|
||||
for (i = GATECNT(desc)-1; i >= 0; i--)
|
||||
PUSH(ReadWord(oldstk+(i*2)));
|
||||
}
|
||||
} else i80286_check_permission(cpustate, SS, cpustate->regs.w[SP]-4, 4, I80286_READ);
|
||||
SET_ACC(gatedesc);
|
||||
WriteWord(addr+4, gatedesc[2]);
|
||||
cpustate->sregs[CS]=IDXTBL(gatesel) | DPL(r);
|
||||
@ -448,7 +452,7 @@ static void i80286_interrupt_descriptor(i80286_state *cpustate,UINT16 number, in
|
||||
if (!CODE(r) || !SEGDESC(r)) throw TRAP(GENERAL_PROTECTION_FAULT,(IDXTBL(gatesel)+(hwint&&1)));
|
||||
if (DPL(r)>CPL) throw TRAP(GENERAL_PROTECTION_FAULT,(IDXTBL(gatesel)+(hwint&&1)));
|
||||
if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,(IDXTBL(gatesel)+(hwint&&1)));
|
||||
if (GATEOFF(desc) > LIMIT(gatedesc)) throw TRAP(GENERAL_PROTECTION_FAULT,(IDXTBL(gatesel)+(hwint&&1)));
|
||||
if (GATEOFF(desc) > LIMIT(gatedesc)) throw TRAP(GENERAL_PROTECTION_FAULT,(hwint&&1));
|
||||
|
||||
if (!CONF(r)&&(DPL(r)<CPL)) { // inner call
|
||||
UINT16 tss_ss, tss_sp, oldss, oldsp;
|
||||
@ -457,11 +461,11 @@ static void i80286_interrupt_descriptor(i80286_state *cpustate,UINT16 number, in
|
||||
|
||||
oldss = cpustate->sregs[SS];
|
||||
oldsp = cpustate->regs.w[SP];
|
||||
i80286_data_descriptor_full(cpustate, SS, tss_ss, DPL(r), TRAP(INVALID_TSS,(IDXTBL(tss_ss)+(hwint&&1))));
|
||||
i80286_data_descriptor_full(cpustate, SS, tss_ss, DPL(r), TRAP(INVALID_TSS,(IDXTBL(tss_ss)+(hwint&&1))), tss_sp-((error != -1)?12:10), (error != -1)?12:10);
|
||||
cpustate->regs.w[SP] = tss_sp;
|
||||
PUSH(oldss);
|
||||
PUSH(oldsp);
|
||||
}
|
||||
} else i80286_check_permission(cpustate, SS, cpustate->regs.w[SP]-((error != -1)?8:6), (error != -1)?8:6, I80286_READ);
|
||||
SET_ACC(gatedesc);
|
||||
WriteWord(addr+4, gatedesc[2]);
|
||||
PREFIX(_pushf(cpustate));
|
||||
@ -776,9 +780,10 @@ static UINT16 i80286_far_return(i8086_state *cpustate, int iret, int bytes)
|
||||
if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(sel));
|
||||
if (off > LIMIT(desc)) throw TRAP(GENERAL_PROTECTION_FAULT, IDXTBL(sel));
|
||||
if (CPL<RPL(sel)) {
|
||||
i80286_check_permission(cpustate, SS, cpustate->regs.w[SP]+(iret?6:4)+bytes, 4, I80286_READ);
|
||||
newsp = ReadWord(spaddr+((iret?6:4)+bytes));
|
||||
newss = ReadWord(spaddr+((iret?8:6)+bytes));
|
||||
i80286_data_descriptor_full(cpustate, SS, newss, RPL(sel), TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(newss)));
|
||||
i80286_data_descriptor_full(cpustate, SS, newss, RPL(sel), TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(newss)), 0, 0);
|
||||
cpustate->regs.w[SP] = newsp + bytes;
|
||||
} else cpustate->regs.w[SP] += (iret?6:4) + bytes;
|
||||
SET_ACC(desc);
|
||||
@ -855,7 +860,7 @@ static void i80286_check_permission(i8086_state *cpustate, UINT8 check_seg, UINT
|
||||
rights = cpustate->rights[check_seg];
|
||||
trap = i80286_verify(cpustate, cpustate->sregs[check_seg], operation, rights);
|
||||
if ((CODE(rights) || !EXPDOWN(rights)) && ((offset+size-1) > cpustate->limit[check_seg])) trap = GENERAL_PROTECTION_FAULT;
|
||||
if (!CODE(rights) && EXPDOWN(rights) && (offset <= cpustate->limit[check_seg]) && ((offset+size) > 0xffff)) trap = GENERAL_PROTECTION_FAULT;
|
||||
if (!CODE(rights) && EXPDOWN(rights) && ((offset <= cpustate->limit[check_seg]) || ((offset+size) > 0xffff))) trap = GENERAL_PROTECTION_FAULT;
|
||||
|
||||
if ((trap == GENERAL_PROTECTION_FAULT) && (check_seg == SS)) trap = STACK_FAULT;
|
||||
if (trap) throw TRAP(trap, 0);
|
||||
|
@ -13,8 +13,8 @@
|
||||
#define STACK_FAULT 12
|
||||
#define GENERAL_PROTECTION_FAULT 13
|
||||
|
||||
#define PM (cpustate->msw&1)
|
||||
#define CPL (cpustate->sregs[CS]&3)
|
||||
#define PM (cpustate->msw&1)
|
||||
|
||||
static void i80286_trap2(i80286_state *cpustate,UINT32 error);
|
||||
static void i80286_interrupt_descriptor(i80286_state *cpustate,UINT16 number, int trap, int error);
|
||||
@ -40,3 +40,9 @@ enum i80286_operation
|
||||
};
|
||||
|
||||
static void i80286_check_permission(i8086_state *cpustate, UINT8 check_seg, UINT32 offset, int size, i80286_operation operation);
|
||||
|
||||
static inline UINT32 GetMemAddr(i80286_state *cpustate, UINT16 seg, UINT16 off, UINT8 size, i80286_operation op) {
|
||||
seg = DefaultSeg(seg);
|
||||
if(PM) i80286_check_permission(cpustate, seg, off, size, op);
|
||||
return (cpustate->base[seg] + off) & AMASK;
|
||||
}
|
||||
|
@ -138,6 +138,7 @@ static void PREFIX86(_rotate_shift_Byte)(i8086_state *cpustate, unsigned ModRM,
|
||||
}
|
||||
else
|
||||
{
|
||||
int tmpcf = CF;
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base + timing.rot_reg_bit : timing.rot_m8_base + timing.rot_m8_bit;
|
||||
|
||||
switch (ModRM & 0x38)
|
||||
@ -161,19 +162,21 @@ static void PREFIX86(_rotate_shift_Byte)(i8086_state *cpustate, unsigned ModRM,
|
||||
case 0x10: /* RCL eb,count */
|
||||
for (; count > 0; count--)
|
||||
{
|
||||
dst = (dst << 1) + CF;
|
||||
SetCFB(dst);
|
||||
dst = (dst << 1) + tmpcf;
|
||||
tmpcf = (int)((dst & 0x100) != 0);
|
||||
}
|
||||
PutbackRMByte(ModRM,(BYTE)dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
break;
|
||||
case 0x18: /* RCR eb,count */
|
||||
for (; count > 0; count--)
|
||||
{
|
||||
dst = (CF<<8)+dst;
|
||||
cpustate->CarryVal = dst & 0x01;
|
||||
dst = (tmpcf<<8)+dst;
|
||||
tmpcf = dst & 0x01;
|
||||
dst >>= 1;
|
||||
}
|
||||
PutbackRMByte(ModRM,(BYTE)dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
break;
|
||||
case 0x20:
|
||||
case 0x30: /* SHL eb,count */
|
||||
@ -329,6 +332,7 @@ static void PREFIX86(_rotate_shift_Word)(i8086_state *cpustate, unsigned ModRM,
|
||||
}
|
||||
else
|
||||
{
|
||||
int tmpcf = CF;
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base + timing.rot_reg_bit : timing.rot_m8_base + timing.rot_m16_bit;
|
||||
|
||||
switch (ModRM & 0x38)
|
||||
@ -352,19 +356,21 @@ static void PREFIX86(_rotate_shift_Word)(i8086_state *cpustate, unsigned ModRM,
|
||||
case 0x10: /* RCL ew,count */
|
||||
for (; count > 0; count--)
|
||||
{
|
||||
dst = (dst << 1) + CF;
|
||||
SetCFW(dst);
|
||||
dst = (dst << 1) + tmpcf;
|
||||
tmpcf = (int)((dst & 0x10000) != 0);
|
||||
}
|
||||
PutbackRMWord(ModRM,dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
break;
|
||||
case 0x18: /* RCR ew,count */
|
||||
for (; count > 0; count--)
|
||||
{
|
||||
dst = dst + (CF << 16);
|
||||
cpustate->CarryVal = dst & 0x01;
|
||||
dst = dst + (tmpcf << 16);
|
||||
tmpcf = dst & 0x01;
|
||||
dst >>= 1;
|
||||
}
|
||||
PutbackRMWord(ModRM,dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
break;
|
||||
case 0x20:
|
||||
case 0x30: /* SHL ew,count */
|
||||
@ -401,7 +407,6 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
|
||||
loop to continue for CMPS and SCAS instructions. */
|
||||
|
||||
unsigned next = FETCHOP;
|
||||
unsigned count = cpustate->regs.w[CX];
|
||||
|
||||
switch(next)
|
||||
{
|
||||
@ -441,14 +446,14 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_ins8_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
for (; count > 0; count--)
|
||||
while(cpustate->regs.w[CX])
|
||||
{
|
||||
if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
|
||||
PutMemB(ES,cpustate->regs.w[DI],read_port_byte(cpustate->regs.w[DX]));
|
||||
cpustate->regs.w[CX]--;
|
||||
cpustate->regs.w[DI] += cpustate->DirVal;
|
||||
ICOUNT -= timing.rep_ins8_count;
|
||||
}
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
case 0x6d: /* REP INSW */
|
||||
#ifdef I80286
|
||||
@ -457,14 +462,14 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_ins16_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
for (; count > 0; count--)
|
||||
while(cpustate->regs.w[CX])
|
||||
{
|
||||
if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
|
||||
PutMemW(ES,cpustate->regs.w[DI],read_port_word(cpustate->regs.w[DX]));
|
||||
cpustate->regs.w[CX]--;
|
||||
cpustate->regs.w[DI] += 2 * cpustate->DirVal;
|
||||
ICOUNT -= timing.rep_ins16_count;
|
||||
}
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
case 0x6e: /* REP OUTSB */
|
||||
#ifdef I80286
|
||||
@ -473,14 +478,14 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_outs8_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
for (; count > 0; count--)
|
||||
while(cpustate->regs.w[CX])
|
||||
{
|
||||
if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
|
||||
write_port_byte(cpustate->regs.w[DX],GetMemB(DS,cpustate->regs.w[SI]));
|
||||
cpustate->regs.w[CX]--;
|
||||
cpustate->regs.w[SI] += cpustate->DirVal; /* GOL 11/27/01 */
|
||||
ICOUNT -= timing.rep_outs8_count;
|
||||
}
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
case 0x6f: /* REP OUTSW */
|
||||
#ifdef I80286
|
||||
@ -489,55 +494,56 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_outs16_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
for (; count > 0; count--)
|
||||
while(cpustate->regs.w[CX])
|
||||
{
|
||||
if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
|
||||
write_port_word(cpustate->regs.w[DX],GetMemW(DS,cpustate->regs.w[SI]));
|
||||
cpustate->regs.w[CX]--;
|
||||
cpustate->regs.w[SI] += 2 * cpustate->DirVal; /* GOL 11/27/01 */
|
||||
ICOUNT -= timing.rep_outs16_count;
|
||||
}
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
#endif
|
||||
case 0xa4: /* REP MOVSB */
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_movs8_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
for (; count > 0; count--)
|
||||
while(cpustate->regs.w[CX])
|
||||
{
|
||||
BYTE tmp;
|
||||
|
||||
if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
|
||||
tmp = GetMemB(DS,cpustate->regs.w[SI]);
|
||||
PutMemB(ES,cpustate->regs.w[DI], tmp);
|
||||
cpustate->regs.w[CX]--;
|
||||
cpustate->regs.w[DI] += cpustate->DirVal;
|
||||
cpustate->regs.w[SI] += cpustate->DirVal;
|
||||
ICOUNT -= timing.rep_movs8_count;
|
||||
}
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
case 0xa5: /* REP MOVSW */
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_movs16_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
for (; count > 0; count--)
|
||||
while(cpustate->regs.w[CX])
|
||||
{
|
||||
WORD tmp;
|
||||
|
||||
if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
|
||||
tmp = GetMemW(DS,cpustate->regs.w[SI]);
|
||||
PutMemW(ES,cpustate->regs.w[DI], tmp);
|
||||
cpustate->regs.w[CX]--;
|
||||
cpustate->regs.w[DI] += 2 * cpustate->DirVal;
|
||||
cpustate->regs.w[SI] += 2 * cpustate->DirVal;
|
||||
ICOUNT -= timing.rep_movs16_count;
|
||||
}
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
case 0xa6: /* REP(N)E CMPSB */
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_cmps8_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
for (cpustate->ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--)
|
||||
cpustate->ZeroVal = !flagval;
|
||||
while(cpustate->regs.w[CX] && (ZF == flagval))
|
||||
{
|
||||
unsigned dst, src;
|
||||
|
||||
@ -545,17 +551,18 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
|
||||
dst = GetMemB(ES, cpustate->regs.w[DI]);
|
||||
src = GetMemB(DS, cpustate->regs.w[SI]);
|
||||
SUBB(src,dst); /* opposite of the usual convention */
|
||||
cpustate->regs.w[CX]--;
|
||||
cpustate->regs.w[DI] += cpustate->DirVal;
|
||||
cpustate->regs.w[SI] += cpustate->DirVal;
|
||||
ICOUNT -= timing.rep_cmps8_count;
|
||||
}
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
case 0xa7: /* REP(N)E CMPSW */
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_cmps16_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
for (cpustate->ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--)
|
||||
cpustate->ZeroVal = !flagval;
|
||||
while(cpustate->regs.w[CX] && (ZF == flagval))
|
||||
{
|
||||
unsigned dst, src;
|
||||
|
||||
@ -563,69 +570,70 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
|
||||
dst = GetMemW(ES, cpustate->regs.w[DI]);
|
||||
src = GetMemW(DS, cpustate->regs.w[SI]);
|
||||
SUBW(src,dst); /* opposite of the usual convention */
|
||||
cpustate->regs.w[CX]--;
|
||||
cpustate->regs.w[DI] += 2 * cpustate->DirVal;
|
||||
cpustate->regs.w[SI] += 2 * cpustate->DirVal;
|
||||
ICOUNT -= timing.rep_cmps16_count;
|
||||
}
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
case 0xaa: /* REP STOSB */
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_stos8_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
for (; count > 0; count--)
|
||||
while(cpustate->regs.w[CX])
|
||||
{
|
||||
if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
|
||||
PutMemB(ES,cpustate->regs.w[DI],cpustate->regs.b[AL]);
|
||||
cpustate->regs.w[CX]--;
|
||||
cpustate->regs.w[DI] += cpustate->DirVal;
|
||||
ICOUNT -= timing.rep_stos8_count;
|
||||
}
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
case 0xab: /* REP STOSW */
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_stos16_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
for (; count > 0; count--)
|
||||
while(cpustate->regs.w[CX])
|
||||
{
|
||||
if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
|
||||
PutMemW(ES,cpustate->regs.w[DI],cpustate->regs.w[AX]);
|
||||
cpustate->regs.w[CX]--;
|
||||
cpustate->regs.w[DI] += 2 * cpustate->DirVal;
|
||||
ICOUNT -= timing.rep_stos16_count;
|
||||
}
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
case 0xac: /* REP LODSB */
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_lods8_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
for (; count > 0; count--)
|
||||
while(cpustate->regs.w[CX])
|
||||
{
|
||||
if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
|
||||
cpustate->regs.b[AL] = GetMemB(DS,cpustate->regs.w[SI]);
|
||||
cpustate->regs.w[CX]--;
|
||||
cpustate->regs.w[SI] += cpustate->DirVal;
|
||||
ICOUNT -= timing.rep_lods8_count;
|
||||
}
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
case 0xad: /* REP LODSW */
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_lods16_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
for (; count > 0; count--)
|
||||
while(cpustate->regs.w[CX])
|
||||
{
|
||||
if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
|
||||
cpustate->regs.w[AX] = GetMemW(DS,cpustate->regs.w[SI]);
|
||||
cpustate->regs.w[CX]--;
|
||||
cpustate->regs.w[SI] += 2 * cpustate->DirVal;
|
||||
ICOUNT -= timing.rep_lods16_count;
|
||||
}
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
case 0xae: /* REP(N)E SCASB */
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_scas8_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
for (cpustate->ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--)
|
||||
cpustate->ZeroVal = !flagval;
|
||||
while(cpustate->regs.w[CX] && (ZF == flagval))
|
||||
{
|
||||
unsigned src, dst;
|
||||
|
||||
@ -633,16 +641,17 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
|
||||
src = GetMemB(ES, cpustate->regs.w[DI]);
|
||||
dst = cpustate->regs.b[AL];
|
||||
SUBB(dst,src);
|
||||
cpustate->regs.w[CX]--;
|
||||
cpustate->regs.w[DI] += cpustate->DirVal;
|
||||
ICOUNT -= timing.rep_scas8_count;
|
||||
}
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
case 0xaf: /* REP(N)E SCASW */
|
||||
if (!cpustate->rep_in_progress)
|
||||
ICOUNT -= timing.rep_scas16_base;
|
||||
cpustate->rep_in_progress = FALSE;
|
||||
for (cpustate->ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--)
|
||||
cpustate->ZeroVal = !flagval;
|
||||
while(cpustate->regs.w[CX] && (ZF == flagval))
|
||||
{
|
||||
unsigned src, dst;
|
||||
|
||||
@ -650,10 +659,10 @@ static void PREFIX(rep)(i8086_state *cpustate,int flagval)
|
||||
src = GetMemW(ES, cpustate->regs.w[DI]);
|
||||
dst = cpustate->regs.w[AX];
|
||||
SUBW(dst,src);
|
||||
cpustate->regs.w[CX]--;
|
||||
cpustate->regs.w[DI] += 2 * cpustate->DirVal;
|
||||
ICOUNT -= timing.rep_scas16_count;
|
||||
}
|
||||
cpustate->regs.w[CX]=count;
|
||||
break;
|
||||
default:
|
||||
PREFIX(_instruction)[next](cpustate);
|
||||
@ -798,20 +807,24 @@ static void PREFIX86(_pop_cs)(i8086_state *cpustate) /* Opcode 0x0f */
|
||||
|
||||
static void PREFIX86(_adc_br8)(i8086_state *cpustate) /* Opcode 0x10 */
|
||||
{
|
||||
DEF_br8(dst,src);
|
||||
int tmpcf;
|
||||
DEF_br8(dst,src);
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
|
||||
src+=CF;
|
||||
ADDB(dst,src);
|
||||
ADCB(dst,src,tmpcf);
|
||||
PutbackRMByte(ModRM,dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
}
|
||||
|
||||
static void PREFIX86(_adc_wr16)(i8086_state *cpustate) /* Opcode 0x11 */
|
||||
{
|
||||
DEF_wr16(dst,src);
|
||||
int tmpcf;
|
||||
DEF_wr16(dst,src);
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
|
||||
src+=CF;
|
||||
ADDW(dst,src);
|
||||
ADCW(dst,src,tmpcf);
|
||||
PutbackRMWord(ModRM,dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
}
|
||||
|
||||
static void PREFIX86(_adc_r8b)(i8086_state *cpustate) /* Opcode 0x12 */
|
||||
@ -858,20 +871,24 @@ static void PREFIX86(_push_ss)(i8086_state *cpustate) /* Opcode 0x16 */
|
||||
|
||||
static void PREFIX86(_sbb_br8)(i8086_state *cpustate) /* Opcode 0x18 */
|
||||
{
|
||||
DEF_br8(dst,src);
|
||||
int tmpcf;
|
||||
DEF_br8(dst,src);
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
|
||||
src+=CF;
|
||||
SUBB(dst,src);
|
||||
SBBB(dst,src,tmpcf);
|
||||
PutbackRMByte(ModRM,dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
}
|
||||
|
||||
static void PREFIX86(_sbb_wr16)(i8086_state *cpustate) /* Opcode 0x19 */
|
||||
{
|
||||
int tmpcf;
|
||||
DEF_wr16(dst,src);
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
|
||||
src+=CF;
|
||||
SUBW(dst,src);
|
||||
SBBW(dst,src,tmpcf);
|
||||
PutbackRMWord(ModRM,dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
}
|
||||
|
||||
static void PREFIX86(_sbb_r8b)(i8086_state *cpustate) /* Opcode 0x1a */
|
||||
@ -1581,6 +1598,7 @@ static void PREFIX86(_80pre)(i8086_state *cpustate) /* Opcode 0x80 */
|
||||
unsigned ModRM = FETCHOP;
|
||||
unsigned dst = GetRMByte(ModRM);
|
||||
unsigned src = FETCH;
|
||||
int tmpcf;
|
||||
|
||||
switch (ModRM & 0x38)
|
||||
{
|
||||
@ -1596,14 +1614,16 @@ static void PREFIX86(_80pre)(i8086_state *cpustate) /* Opcode 0x80 */
|
||||
break;
|
||||
case 0x10: /* ADC eb,d8 */
|
||||
src+=CF;
|
||||
ADDB(dst,src);
|
||||
ADCB(dst,src,tmpcf);
|
||||
PutbackRMByte(ModRM,dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
|
||||
break;
|
||||
case 0x18: /* SBB eb,b8 */
|
||||
src+=CF;
|
||||
SUBB(dst,src);
|
||||
SBBB(dst,src,tmpcf);
|
||||
PutbackRMByte(ModRM,dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
|
||||
break;
|
||||
case 0x20: /* AND eb,d8 */
|
||||
@ -1634,6 +1654,7 @@ static void PREFIX86(_81pre)(i8086_state *cpustate) /* Opcode 0x81 */
|
||||
unsigned ModRM = FETCH;
|
||||
unsigned dst = GetRMWord(ModRM);
|
||||
unsigned src = FETCH;
|
||||
int tmpcf;
|
||||
src+= (FETCH << 8);
|
||||
|
||||
switch (ModRM & 0x38)
|
||||
@ -1650,14 +1671,16 @@ static void PREFIX86(_81pre)(i8086_state *cpustate) /* Opcode 0x81 */
|
||||
break;
|
||||
case 0x10: /* ADC ew,d16 */
|
||||
src+=CF;
|
||||
ADDW(dst,src);
|
||||
ADCW(dst,src,tmpcf);
|
||||
PutbackRMWord(ModRM,dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
|
||||
break;
|
||||
case 0x18: /* SBB ew,d16 */
|
||||
src+=CF;
|
||||
SUBW(dst,src);
|
||||
SBBW(dst,src,tmpcf);
|
||||
PutbackRMWord(ModRM,dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
|
||||
break;
|
||||
case 0x20: /* AND ew,d16 */
|
||||
@ -1687,6 +1710,7 @@ static void PREFIX86(_82pre)(i8086_state *cpustate) /* Opcode 0x82 */
|
||||
unsigned ModRM = FETCH;
|
||||
unsigned dst = GetRMByte(ModRM);
|
||||
unsigned src = FETCH;
|
||||
int tmpcf;
|
||||
|
||||
switch (ModRM & 0x38)
|
||||
{
|
||||
@ -1702,14 +1726,16 @@ static void PREFIX86(_82pre)(i8086_state *cpustate) /* Opcode 0x82 */
|
||||
break;
|
||||
case 0x10: /* ADC eb,d8 */
|
||||
src+=CF;
|
||||
ADDB(dst,src);
|
||||
ADCB(dst,src,tmpcf);
|
||||
PutbackRMByte(ModRM,dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
|
||||
break;
|
||||
case 0x18: /* SBB eb,d8 */
|
||||
src+=CF;
|
||||
SUBB(dst,src);
|
||||
SBBB(dst,src,tmpcf);
|
||||
PutbackRMByte(ModRM,dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
|
||||
break;
|
||||
case 0x20: /* AND eb,d8 */
|
||||
@ -1739,6 +1765,7 @@ static void PREFIX86(_83pre)(i8086_state *cpustate) /* Opcode 0x83 */
|
||||
unsigned ModRM = FETCH;
|
||||
unsigned dst = GetRMWord(ModRM);
|
||||
unsigned src = (WORD)((INT16)((INT8)FETCH));
|
||||
int tmpcf;
|
||||
|
||||
switch (ModRM & 0x38)
|
||||
{
|
||||
@ -1754,14 +1781,16 @@ static void PREFIX86(_83pre)(i8086_state *cpustate) /* Opcode 0x83 */
|
||||
break;
|
||||
case 0x10: /* ADC ew,d16 */
|
||||
src+=CF;
|
||||
ADDW(dst,src);
|
||||
ADCW(dst,src,tmpcf);
|
||||
PutbackRMWord(ModRM,dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
|
||||
break;
|
||||
case 0x18: /* SBB ew,d16 */
|
||||
src+=CF;
|
||||
SUBW(dst,src);
|
||||
SBBW(dst,src,tmpcf);
|
||||
PutbackRMWord(ModRM,dst);
|
||||
cpustate->CarryVal = tmpcf;
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
|
||||
break;
|
||||
case 0x20: /* AND ew,d16 */
|
||||
@ -1804,16 +1833,16 @@ static void PREFIX86(_xchg_br8)(i8086_state *cpustate) /* Opcode 0x86 */
|
||||
{
|
||||
DEF_br8(dst,src);
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.xchg_rr8 : timing.xchg_rm8;
|
||||
RegByte(ModRM)=dst;
|
||||
PutbackRMByte(ModRM,src);
|
||||
RegByte(ModRM)=dst;
|
||||
}
|
||||
|
||||
static void PREFIX86(_xchg_wr16)(i8086_state *cpustate) /* Opcode 0x87 */
|
||||
{
|
||||
DEF_wr16(dst,src);
|
||||
ICOUNT -= (ModRM >= 0xc0) ? timing.xchg_rr16 : timing.xchg_rm16;
|
||||
RegWord(ModRM)=dst;
|
||||
PutbackRMWord(ModRM,src);
|
||||
RegWord(ModRM)=dst;
|
||||
}
|
||||
|
||||
static void PREFIX86(_mov_br8)(i8086_state *cpustate) /* Opcode 0x88 */
|
||||
@ -2754,6 +2783,7 @@ static void PREFIX(_mov_sregw)(i8086_state *cpustate) /* Opcode 0x8e */
|
||||
PREFIX(_instruction)[FETCHOP](cpustate);
|
||||
break;
|
||||
case 0x08: /* mov cs,ew */
|
||||
PREFIX(_invalid)(cpustate);
|
||||
break; /* doesn't do a jump far */
|
||||
}
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user