|
|
| version 1.6, 2003/11/21 06:51:11 | version 1.18, 2003/12/28 08:05:19 |
|---|---|
| Line 1 | Line 1 |
| #include "compiler.h" | #include "compiler.h" |
| #include "i286.h" | #include "cpucore.h" |
| #include "i286c.h" | #include "i286c.h" |
| #include "memory.h" | |
| #include "i286c.mcr" | #include "i286c.mcr" |
| 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) { | I286_0F _sgdt(UINT op) { |
| UINT32 addr; | |
| I286_WORKCLOCK(11); | I286_WORKCLOCK(11); |
| if (op < 0xc0) { | if (op < 0xc0) { |
| UINT16 ad = c_get_ea[op](); | addr = CALC_EA(op); |
| i286_memorywrite_w(ad + EA_FIX, i286reg.GDTR.limit); | i286_memorywrite_w(addr, I286_GDTR.limit); |
| ad += 2; | i286_memorywrite_w(addr + 2, I286_GDTR.base); |
| i286_memorywrite_w(ad + EA_FIX, i286reg.GDTR.base); | i286_memorywrite_w(addr + 4, (REG16)(0xff00 + I286_GDTR.base24)); |
| ad += 2; | |
| i286_memorywrite_w(ad + EA_FIX, | |
| (UINT16)(0xff00 + i286reg.GDTR.base24)); | |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP - 2); | INT_NUM(6, I286_IP - 2); |
| Line 24 I286_0F _sgdt(UINT op) { | Line 114 I286_0F _sgdt(UINT op) { |
| I286_0F _sidt(UINT op) { | I286_0F _sidt(UINT op) { |
| UINT32 addr; | |
| I286_WORKCLOCK(12); | I286_WORKCLOCK(12); |
| if (op < 0xc0) { | if (op < 0xc0) { |
| UINT16 ad = c_get_ea[op](); | addr = CALC_EA(op); |
| i286_memorywrite_w(ad + EA_FIX, i286reg.IDTR.limit); | i286_memorywrite_w(addr, I286_IDTR.limit); |
| ad += 2; | i286_memorywrite_w(addr + 2, I286_IDTR.base); |
| i286_memorywrite_w(ad + EA_FIX, i286reg.IDTR.base); | i286_memorywrite_w(addr + 4, (REG16)(0xff00 + I286_IDTR.base24)); |
| ad += 2; | |
| i286_memorywrite_w(ad + EA_FIX, | |
| (UINT16)(0xff00 + i286reg.IDTR.base24)); | |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP - 2); | INT_NUM(6, I286_IP - 2); |
| Line 41 I286_0F _sidt(UINT op) { | Line 130 I286_0F _sidt(UINT op) { |
| I286_0F _lgdt(UINT op) { | I286_0F _lgdt(UINT op) { |
| UINT32 addr; | |
| I286_WORKCLOCK(11); | I286_WORKCLOCK(11); |
| if (op < 0xc0) { | if (op < 0xc0) { |
| UINT16 ad = c_get_ea[op](); | addr = CALC_EA(op); |
| i286reg.GDTR.limit = i286_memoryread_w(ad + EA_FIX); | I286_GDTR.limit = i286_memoryread_w(addr); |
| ad += 2; | I286_GDTR.base = i286_memoryread_w(addr + 2); |
| i286reg.GDTR.base = i286_memoryread_w(ad + EA_FIX); | I286_GDTR.base24 = i286_memoryread(addr + 4); |
| ad += 2; | |
| i286reg.GDTR.base24 = i286_memoryread(ad + EA_FIX); | |
| ad++; | |
| i286reg.GDTR.reserved = i286_memoryread(ad + EA_FIX); | |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP - 2); | INT_NUM(6, I286_IP - 2); |
| Line 59 I286_0F _lgdt(UINT op) { | Line 146 I286_0F _lgdt(UINT op) { |
| I286_0F _lidt(UINT op) { | I286_0F _lidt(UINT op) { |
| I286_WORKCLOCK(11); | UINT32 addr; |
| I286_WORKCLOCK(12); | |
| if (op < 0xc0) { | if (op < 0xc0) { |
| UINT16 ad = c_get_ea[op](); | addr = CALC_EA(op); |
| i286reg.IDTR.limit = i286_memoryread_w(ad + EA_FIX); | I286_IDTR.limit = i286_memoryread_w(addr); |
| ad += 2; | I286_IDTR.base = i286_memoryread_w(addr + 2); |
| i286reg.IDTR.base = i286_memoryread_w(ad + EA_FIX); | I286_IDTR.base24 = i286_memoryread(addr + 4); |
| ad += 2; | |
| i286reg.IDTR.base24 = i286_memoryread(ad + EA_FIX); | |
| ad++; | |
| i286reg.IDTR.reserved = i286_memoryread(ad + EA_FIX); | |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP - 2); | INT_NUM(6, I286_IP - 2); |
| Line 78 I286_0F _lidt(UINT op) { | Line 163 I286_0F _lidt(UINT op) { |
| I286_0F _smsw(UINT op) { | I286_0F _smsw(UINT op) { |
| if (op >= 0xc0) { | if (op >= 0xc0) { |
| I286_WORKCLOCK(3); | I286_WORKCLOCK(2); |
| *(REG16_B20(op)) = i286reg.MSW; | *(REG16_B20(op)) = I286_MSW; |
| } | } |
| else { | else { |
| I286_WORKCLOCK(6); | I286_WORKCLOCK(3); |
| i286_memorywrite_w(c_calc_ea_dst[op](), i286reg.MSW); | i286_memorywrite_w(CALC_EA(op), I286_MSW); |
| } | } |
| } | } |
| I286_0F _lmsw(UINT op) { | I286_0F _lmsw(UINT op) { |
| REG16 msw; | |
| if (op >= 0xc0) { | if (op >= 0xc0) { |
| I286_WORKCLOCK(2); | I286_WORKCLOCK(3); |
| i286reg.MSW = *(REG16_B20(op)); | msw = *(REG16_B20(op)); |
| } | } |
| else { | else { |
| I286_WORKCLOCK(3); | I286_WORKCLOCK(6); |
| i286reg.MSW = i286_memoryread_w(c_calc_ea_dst[op]()); | msw = i286_memoryread_w(CALC_EA(op)); |
| } | |
| I286_MSW = msw | (I286_MSW & MSW_PE); | |
| if (msw & MSW_PE) { | |
| TRACEOUT(("Protect 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[] = { | static const I286OP_0F cts1_table[] = { |
| _sgdt, _sidt, | _sgdt, _sidt, _lgdt, _lidt, |
| _lgdt, _lidt, | _smsw, _smsw, _lmsw, _lmsw}; |
| _smsw, _smsw, | |
| _lmsw, _lmsw}; | |
| I286_0F _loadall286(void) { | I286_0F _loadall286(void) { |
| UINT16 tmp; | UINT16 tmp; |
| UINT32 base; | |
| I286_WORKCLOCK(195); | I286_WORKCLOCK(195); |
| i286reg.MSW = LOADINTELWORD(mem + 0x804); | I286_MSW = LOADINTELWORD(mem + 0x804); |
| I286_TR = LOADINTELWORD(mem + 0x816); // ver0.73 | |
| tmp = LOADINTELWORD(mem + 0x818); | tmp = LOADINTELWORD(mem + 0x818); |
| I286_OV = tmp & O_FLAG; | I286_OV = tmp & O_FLAG; |
| I286_FLAG = tmp & (0xfff ^ O_FLAG); | I286_FLAG = tmp & (0xfff ^ O_FLAG); |
| I286_TRAP = ((tmp & 0x300) == 0x300); | I286_TRAP = ((tmp & 0x300) == 0x300); |
| I286_IP = LOADINTELWORD(mem + 0x81a); | I286_IP = LOADINTELWORD(mem + 0x81a); |
| I286_LDTR = LOADINTELWORD(mem + 0x81c); // ver0.73 | |
| I286_DS = LOADINTELWORD(mem + 0x81e); | I286_DS = LOADINTELWORD(mem + 0x81e); |
| I286_SS = LOADINTELWORD(mem + 0x820); | I286_SS = LOADINTELWORD(mem + 0x820); |
| I286_CS = LOADINTELWORD(mem + 0x822); | I286_CS = LOADINTELWORD(mem + 0x822); |
| Line 129 I286_0F _loadall286(void) { | Line 225 I286_0F _loadall286(void) { |
| I286_DX = LOADINTELWORD(mem + 0x830); | I286_DX = LOADINTELWORD(mem + 0x830); |
| I286_CX = LOADINTELWORD(mem + 0x832); | I286_CX = LOADINTELWORD(mem + 0x832); |
| I286_AX = LOADINTELWORD(mem + 0x834); | I286_AX = LOADINTELWORD(mem + 0x834); |
| ES_BASE = LOADINTELDWORD(mem + 0x836) & 0x00ffffff; | base = LOADINTELDWORD(mem + 0x836) & 0x00ffffff; |
| CS_BASE = LOADINTELDWORD(mem + 0x83c) & 0x00ffffff; | ES_BASE = base; |
| SS_BASE = LOADINTELDWORD(mem + 0x842) & 0x00ffffff; | base = LOADINTELDWORD(mem + 0x83c) & 0x00ffffff; |
| SS_FIX = SS_BASE; | CS_BASE = base; |
| DS_BASE = LOADINTELDWORD(mem + 0x848) & 0x00ffffff; | base = LOADINTELDWORD(mem + 0x842) & 0x00ffffff; |
| DS_FIX = DS_BASE; | 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 | I286IRQCHECKTERM |
| } | } |
| Line 147 I286EXT i286c_cts(void) { | Line 264 I286EXT i286c_cts(void) { |
| ip = I286_IP; | ip = I286_IP; |
| GET_PCBYTE(op); | 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); | GET_PCBYTE(op2); |
| cts1_table[(op2 >> 3) & 7](op2); | cts1_table[(op2 >> 3) & 7](op2); |
| } | } |
| Line 155 I286EXT i286c_cts(void) { | Line 281 I286EXT i286c_cts(void) { |
| _loadall286(); | _loadall286(); |
| } | } |
| else { | else { |
| I286_WORKCLOCK(20); | |
| INT_NUM(6, ip - 1); | INT_NUM(6, ip - 1); |
| } | } |
| } | } |