--- np2/i286c/i286c_0f.c 2003/10/19 14:56:15 1.4 +++ np2/i286c/i286c_0f.c 2004/01/08 16:29:56 1.19 @@ -1,22 +1,111 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286c.h" #include "i286c.mcr" -#include "memory.h" -#include "nevent.h" +I286_0F _sldt(UINT op) { + + if (op >= 0xc0) { + I286_WORKCLOCK(2); + *(REG16_B20(op)) = I286_LDTR; + } + else { + I286_WORKCLOCK(3); + i286_memorywrite_w(CALC_EA(op), I286_LDTR); + } +} + +I286_0F _str(UINT op) { + + if (op >= 0xc0) { + I286_WORKCLOCK(3); + *(REG16_B20(op)) = I286_TR; + } + else { + I286_WORKCLOCK(6); + i286_memorywrite_w(CALC_EA(op), I286_TR); + } +} + +I286_0F _lldt(UINT op) { + + REG16 r; + UINT32 addr; + + if (op >= 0xc0) { + I286_WORKCLOCK(17); + r = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(19); + r = i286_memoryread_w(CALC_EA(op)); + } + addr = i286c_selector(r); + I286_LDTR = r; + I286_LDTRC.limit = i286_memoryread_w(addr); + I286_LDTRC.base = i286_memoryread_w(addr + 2); + I286_LDTRC.base24 = i286_memoryread(addr + 4); +} + +I286_0F _ltr(UINT op) { + + REG16 r; + UINT32 addr; + + if (op >= 0xc0) { + I286_WORKCLOCK(17); + r = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(19); + r = i286_memoryread_w(CALC_EA(op)); + } + addr = i286c_selector(r); + I286_TR = r; + I286_TRC.limit = i286_memoryread_w(addr); + I286_TRC.base = i286_memoryread_w(addr + 2); + I286_TRC.base24 = i286_memoryread(addr + 4); +} + +I286_0F _verr(UINT op) { + + REG16 r; + + if (op >= 0xc0) { + I286_WORKCLOCK(14); + r = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(16); + r = i286_memoryread_w(CALC_EA(op)); + } +} + +I286_0F _verw(UINT op) { + + REG16 r; + + if (op >= 0xc0) { + I286_WORKCLOCK(14); + r = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(16); + r = i286_memoryread_w(CALC_EA(op)); + } +} + I286_0F _sgdt(UINT op) { + UINT32 addr; + I286_WORKCLOCK(11); if (op < 0xc0) { - UINT16 ad = c_get_ea[op](); - i286_memorywrite_w(ad + EA_FIX, i286reg.GDTR.limit); - ad += 2; - i286_memorywrite_w(ad + EA_FIX, i286reg.GDTR.base); - ad += 2; - i286_memorywrite_w(ad + EA_FIX, - (UINT16)(0xff00 + i286reg.GDTR.base24)); + addr = CALC_EA(op); + i286_memorywrite_w(addr, I286_GDTR.limit); + i286_memorywrite_w(addr + 2, I286_GDTR.base); + i286_memorywrite_w(addr + 4, (REG16)(0xff00 + I286_GDTR.base24)); } else { INT_NUM(6, I286_IP - 2); @@ -25,15 +114,14 @@ I286_0F _sgdt(UINT op) { I286_0F _sidt(UINT op) { + UINT32 addr; + I286_WORKCLOCK(12); if (op < 0xc0) { - UINT16 ad = c_get_ea[op](); - i286_memorywrite_w(ad + EA_FIX, i286reg.IDTR.limit); - ad += 2; - i286_memorywrite_w(ad + EA_FIX, i286reg.IDTR.base); - ad += 2; - i286_memorywrite_w(ad + EA_FIX, - (UINT16)(0xff00 + i286reg.IDTR.base24)); + addr = CALC_EA(op); + i286_memorywrite_w(addr, I286_IDTR.limit); + i286_memorywrite_w(addr + 2, I286_IDTR.base); + i286_memorywrite_w(addr + 4, (REG16)(0xff00 + I286_IDTR.base24)); } else { INT_NUM(6, I286_IP - 2); @@ -42,16 +130,14 @@ I286_0F _sidt(UINT op) { I286_0F _lgdt(UINT op) { + UINT32 addr; + I286_WORKCLOCK(11); if (op < 0xc0) { - UINT16 ad = c_get_ea[op](); - i286reg.GDTR.limit = i286_memoryread_w(ad + EA_FIX); - ad += 2; - i286reg.GDTR.base = i286_memoryread_w(ad + EA_FIX); - ad += 2; - i286reg.GDTR.base24 = i286_memoryread(ad + EA_FIX); - ad++; - i286reg.GDTR.reserved = i286_memoryread(ad + EA_FIX); + addr = CALC_EA(op); + I286_GDTR.limit = i286_memoryread_w(addr); + I286_GDTR.base = i286_memoryread_w(addr + 2); + I286_GDTR.base24 = i286_memoryread(addr + 4); } else { INT_NUM(6, I286_IP - 2); @@ -60,16 +146,14 @@ I286_0F _lgdt(UINT op) { I286_0F _lidt(UINT op) { - I286_WORKCLOCK(11); + UINT32 addr; + + I286_WORKCLOCK(12); if (op < 0xc0) { - UINT16 ad = c_get_ea[op](); - i286reg.IDTR.limit = i286_memoryread_w(ad + EA_FIX); - ad += 2; - i286reg.IDTR.base = i286_memoryread_w(ad + EA_FIX); - ad += 2; - i286reg.IDTR.base24 = i286_memoryread(ad + EA_FIX); - ad++; - i286reg.IDTR.reserved = i286_memoryread(ad + EA_FIX); + addr = CALC_EA(op); + I286_IDTR.limit = i286_memoryread_w(addr); + I286_IDTR.base = i286_memoryread_w(addr + 2); + I286_IDTR.base24 = i286_memoryread(addr + 4); } else { INT_NUM(6, I286_IP - 2); @@ -79,45 +163,56 @@ I286_0F _lidt(UINT op) { I286_0F _smsw(UINT op) { if (op >= 0xc0) { - I286_WORKCLOCK(3); - *(reg16_b20[op]) = i286reg.MSW; + I286_WORKCLOCK(2); + *(REG16_B20(op)) = I286_MSW; } else { - I286_WORKCLOCK(6); - i286_memorywrite_w(c_calc_ea_dst[op](), i286reg.MSW); + I286_WORKCLOCK(3); + i286_memorywrite_w(CALC_EA(op), I286_MSW); } } I286_0F _lmsw(UINT op) { + REG16 msw; + if (op >= 0xc0) { - I286_WORKCLOCK(2); - i286reg.MSW = *(reg16_b20[op]); + I286_WORKCLOCK(3); + msw = *(REG16_B20(op)); } else { - I286_WORKCLOCK(3); - i286reg.MSW = i286_memoryread_w(c_calc_ea_dst[op]()); + I286_WORKCLOCK(6); + msw = i286_memoryread_w(CALC_EA(op)); + } + I286_MSW = msw | (I286_MSW & MSW_PE); + if (msw & MSW_PE) { + TRACEOUT(("80286 ProtectMode Enable... / MSW=%.4x", I286_MSW)); } } +static const I286OP_0F cts0_table[] = { + _sldt, _str, _lldt, _ltr, + _verr, _verw, _verr, _verw}; + static const I286OP_0F cts1_table[] = { - _sgdt, _sidt, - _lgdt, _lidt, - _smsw, _smsw, - _lmsw, _lmsw}; + _sgdt, _sidt, _lgdt, _lidt, + _smsw, _smsw, _lmsw, _lmsw}; I286_0F _loadall286(void) { UINT16 tmp; + UINT32 base; I286_WORKCLOCK(195); - i286reg.MSW = LOADINTELWORD(mem + 0x804); + I286_MSW = LOADINTELWORD(mem + 0x804); + I286_TR = LOADINTELWORD(mem + 0x816); // ver0.73 tmp = LOADINTELWORD(mem + 0x818); I286_OV = tmp & O_FLAG; I286_FLAG = tmp & (0xfff ^ O_FLAG); I286_TRAP = ((tmp & 0x300) == 0x300); I286_IP = LOADINTELWORD(mem + 0x81a); + I286_LDTR = LOADINTELWORD(mem + 0x81c); // ver0.73 I286_DS = LOADINTELWORD(mem + 0x81e); I286_SS = LOADINTELWORD(mem + 0x820); I286_CS = LOADINTELWORD(mem + 0x822); @@ -130,12 +225,33 @@ I286_0F _loadall286(void) { I286_DX = LOADINTELWORD(mem + 0x830); I286_CX = LOADINTELWORD(mem + 0x832); I286_AX = LOADINTELWORD(mem + 0x834); - ES_BASE = LOADINTELDWORD(mem + 0x836) & 0x00ffffff; - CS_BASE = LOADINTELDWORD(mem + 0x83c) & 0x00ffffff; - SS_BASE = LOADINTELDWORD(mem + 0x842) & 0x00ffffff; - SS_FIX = SS_BASE; - DS_BASE = LOADINTELDWORD(mem + 0x848) & 0x00ffffff; - DS_FIX = DS_BASE; + base = LOADINTELDWORD(mem + 0x836) & 0x00ffffff; + ES_BASE = base; + base = LOADINTELDWORD(mem + 0x83c) & 0x00ffffff; + CS_BASE = base; + base = LOADINTELDWORD(mem + 0x842) & 0x00ffffff; + SS_BASE = base; + SS_FIX = base; + base = LOADINTELDWORD(mem + 0x848) & 0x00ffffff; + DS_BASE = base; + DS_FIX = base; + + I286_GDTR.base = LOADINTELWORD(mem + 0x84e); + *(UINT16 *)(&I286_GDTR.base24) = LOADINTELWORD(mem + 0x850); + I286_GDTR.limit = LOADINTELWORD(mem + 0x852); + + I286_LDTRC.base = LOADINTELWORD(mem + 0x854); + *(UINT16 *)(&I286_LDTRC.base24) = LOADINTELWORD(mem + 0x856); + I286_LDTRC.limit = LOADINTELWORD(mem + 0x858); + + I286_IDTR.base = LOADINTELWORD(mem + 0x85a); + *(UINT16 *)(&I286_IDTR.base24) = LOADINTELWORD(mem + 0x85c); + I286_IDTR.limit = LOADINTELWORD(mem + 0x85e); + + I286_TRC.base = LOADINTELWORD(mem + 0x860); + *(UINT16 *)(&I286_TRC.base24) = LOADINTELWORD(mem + 0x8620); + I286_TRC.limit = LOADINTELWORD(mem + 0x864); + I286IRQCHECKTERM } @@ -148,7 +264,16 @@ I286EXT i286c_cts(void) { ip = I286_IP; GET_PCBYTE(op); - if (op == 1) { + if (op == 0) { + if (!(I286_MSW & MSW_PE)) { + INT_NUM(6, ip - 1); + } + else { + GET_PCBYTE(op2); + cts0_table[(op2 >> 3) & 7](op2); + } + } + else if (op == 1) { GET_PCBYTE(op2); cts1_table[(op2 >> 3) & 7](op2); } @@ -156,7 +281,6 @@ I286EXT i286c_cts(void) { _loadall286(); } else { - I286_WORKCLOCK(20); INT_NUM(6, ip - 1); } }