123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- /* i186 instruction implement */
- static INLINE2 void i_pusha(void)
- {
- /* Opcode 0x60 */
- unsigned tmp;
- unsigned tmp2;
- tmp = (WORD)ReadWord(&wregs[SP]);
- PushWordReg(AX);
- PushWordReg(CX);
- PushWordReg(DX);
- PushWordReg(BX);
- tmp2 = (WORD)ReadWord(&wregs[SP]);
- tmp2 -= 2;
- WriteWord(&wregs[SP], (WORD)tmp2);
- PutMemW(c_stack, (WORD)tmp2, (WORD)tmp);
- PushWordReg(BP);
- PushWordReg(SI);
- PushWordReg(DI);
- }
- static INLINE2 void i_popa(void)
- {
- /* Opcode 0x61 */
- unsigned tmp;
- PopWordReg(DI);
- PopWordReg(SI);
- PopWordReg(BP);
- tmp = (WORD)ReadWord(&wregs[SP]);
- tmp += 2;
- WriteWord(&wregs[SP], (WORD)tmp);
- PopWordReg(BX);
- PopWordReg(DX);
- PopWordReg(CX);
- PopWordReg(AX);
- }
- static INLINE2 void i_bound(void)
- {
- /* Opcode 0x62 */
- unsigned ModRM = (unsigned)GetMemInc(c_cs, ip);
- }
- static INLINE2 void i_push_d16(void)
- {
- /* Opcode 0x68 */
- unsigned tmp1;
- unsigned tmp2;
- tmp1 = GetMemInc(c_cs, ip);
- tmp1 |= GetMemInc(c_cs, ip) << 8;
- tmp2 = (WORD)ReadWord(&wregs[SP]);
- tmp2 -= 2;
- WriteWord(&wregs[SP], (WORD)tmp2);
- PutMemW(c_stack, (WORD)tmp2, (WORD)tmp1);
- }
- static INLINE2 void i_imul_d16(void)
- {
- /* Opcode 0x69 */
- INT32 result;
- unsigned tmp1;
- unsigned tmp2;
- unsigned ModRM = GetMemInc(c_cs, ip);
- WORD *dest = GetModRMRegW(ModRM);
- tmp1 = *(GetModRMRMW(ModRM));
- tmp2 = (unsigned)GetMemInc(c_cs, ip);
- tmp2 |= (unsigned)GetMemInc(c_cs, ip) << 8;
- result = (INT16)(tmp1) * (INT16)(tmp2);
- WriteWord(dest, result);
- *dest = (INT16)result;
- CF = OF = (result >> 16) > 0;
- }
- static INLINE2 void i_push_d8(void)
- {
- /* Opcode 0x6a */
- unsigned tmp1;
- unsigned tmp2;
- tmp1 = GetMemInc(c_cs, ip);
- tmp2 = (WORD)ReadWord(&wregs[SP]);
- tmp2 -= 2;
- WriteWord(&wregs[SP], (WORD)tmp2);
- PutMemW(c_stack, (WORD)tmp2, (WORD)tmp1);
- }
- static INLINE2 void i_imul_d8(void)
- {
- /* Opcode 0x6b */
- INT32 result;
- unsigned tmp1;
- unsigned tmp2;
- unsigned ModRM = GetMemInc(c_cs, ip);
- WORD *dest = GetModRMRegW(ModRM);
- tmp1 = *(GetModRMRMW(ModRM));
- tmp2 = (unsigned)GetMemInc(c_cs, ip);
- result = (INT16)(tmp1) * (INT16)(tmp2);
- WriteWord(dest, result);
- *dest = (INT16)result;
- CF = OF = (result >> 16) > 0;
- }
- static INLINE2 void i_insb(void)
- {
- /* Opcode 0x6c */
- ;
- }
- static INLINE2 void i_insw(void)
- {
- /* Opcode 0x6d */
- ;
- }
- static INLINE2 void i_outsb(void)
- {
- /* Opcode 0x6e */
- ;
- }
- static INLINE2 void i_outsw(void)
- {
- /* Opcode 0x6f */
- ;
- }
- static INLINE2 void i_rotshft_bd8(void)
- {
- /* Opcode 0xc0 */
- unsigned ModRM = GetMemInc(c_cs, ip);
- BYTE *dest = GetModRMRMB(ModRM);
- unsigned tmp = *dest;
- unsigned tmp2;
- unsigned count = GetMemInc(c_cs, ip);
-
- switch(ModRM & 0x38) {
- case 0x00: /* ROL r/m8, imm8 */
- for(; count > 0; count--) {
- CF = (tmp & 0x80) != 0;
- tmp = (tmp << 1) + CF;
- }
- *dest = (BYTE)tmp;
- break;
- case 0x08: /* ROR r/m8, imm8 */
- for(; count > 0; count--) {
- CF = (tmp & 0x01) != 0;
- tmp = (tmp >> 1) + (CF << 7);
- }
- *dest = (BYTE)tmp;
- break;
- case 0x10: /* RCL r/m8, imm8 */
- for(; count > 0; count--) {
- tmp2 = CF;
- CF = (tmp & 0x80) != 0;
- tmp = (tmp << 1) + tmp2;
- }
- *dest = (BYTE)tmp;
- break;
- case 0x18: /* RCR r/m8, imm8 */
- for(; count > 0; count--) {
- tmp2 = (tmp >> 1) + (CF << 7);
- CF = (tmp & 0x01) != 0;
- tmp = tmp2;
- }
- *dest = (BYTE)tmp;
- break;
- case 0x20: /* SHL r/m8, imm8 */
- if(count >= 9) {
- CF = 0;
- tmp = 0;
- } else {
- CF = ((tmp << (count - 1)) & 0x80) != 0;
- tmp <<= count;
- }
- AF = 1;
- SetZFB(tmp);
- SetSFB(tmp);
- SetPF(tmp);
- *dest = (BYTE)tmp;
- break;
- case 0x28: /* SHR r/m8, imm8 */
- if(count >= 9) {
- CF = 0;
- tmp = 0;
- } else {
- CF = ((tmp >> (count - 1)) & 0x1) != 0;
- tmp >>= count;
- }
- SetSFB(tmp);
- SetPF(tmp);
- SetZFB(tmp);
- AF = 1;
- *dest = (BYTE)tmp;
- break;
- case 0x38: /* SAR r/m8, imm8 */
- tmp2 = tmp & 0x80;
- CF = (((INT8)tmp >> (count - 1)) & 0x01) != 0;
- for(; count > 0; count--)
- tmp = (tmp >> 1) | tmp2;
- SetSFB(tmp);
- SetPF(tmp);
- SetZFB(tmp);
- AF = 1;
- *dest = (BYTE)tmp;
- break;
- default:
- break;
- }
- }
- static INLINE2 void i_rotshft_wd8(void)
- {
- /* Opcode 0xc1 */
- unsigned ModRM = GetMemInc(c_cs, ip);
- WORD *dest = GetModRMRMW(ModRM);
- unsigned tmp = *dest;
- unsigned tmp2;
- unsigned count = GetMemInc(c_cs, ip);
-
- switch(ModRM & 0x38) {
- case 0x00: /* ROL r/m16, imm8 */
- for(; count > 0; count--) {
- CF = (tmp & 0x80) != 0;
- tmp = (tmp << 1) + CF;
- }
- *dest = (WORD)tmp;
- break;
- case 0x08: /* ROR r/m16, imm8 */
- for(; count > 0; count--) {
- CF = (tmp & 0x01) != 0;
- tmp = (tmp >> 1) + (CF << 7);
- }
- *dest = (WORD)tmp;
- break;
- case 0x10: /* RCL r/m16, imm8 */
- for(; count > 0; count--) {
- tmp2 = CF;
- CF = (tmp & 0x80) != 0;
- tmp = (tmp << 1) + tmp2;
- }
- *dest = (WORD)tmp;
- break;
- case 0x18: /* RCR r/m16, imm8 */
- for(; count > 0; count--) {
- tmp2 = (tmp >> 1) + (CF << 7);
- CF = (tmp & 0x01) != 0;
- tmp = tmp2;
- }
- *dest = (WORD)tmp;
- break;
- case 0x20: /* SHL r/m16, imm8 */
- if(count >= 9) {
- CF = 0;
- tmp = 0;
- } else {
- CF = ((tmp << (count - 1)) & 0x80) != 0;
- tmp <<= count;
- }
- AF = 1;
- SetZFB(tmp);
- SetSFB(tmp);
- SetPF(tmp);
- *dest = (WORD)tmp;
- break;
- case 0x28: /* SHR r/m16, imm8 */
- if(count >= 9) {
- CF = 0;
- tmp = 0;
- } else {
- CF = ((tmp >> (count - 1)) & 0x1) != 0;
- tmp >>= count;
- }
- SetSFB(tmp);
- SetPF(tmp);
- SetZFB(tmp);
- AF = 1;
- *dest = (WORD)tmp;
- break;
- case 0x38: /* SAR r/m16, imm8 */
- tmp2 = tmp & 0x80;
- CF = (((INT16)tmp >> (count - 1)) & 0x01) != 0;
- for(; count > 0; count--)
- tmp = (tmp >> 1) | tmp2;
- SetSFB(tmp);
- SetPF(tmp);
- SetZFB(tmp);
- AF = 1;
- *dest = (WORD)tmp;
- break;
- default:
- break;
- }
- }
- static INLINE2 void i_enter(void)
- {
- /* Opcode 0xc8 */
- unsigned size;
- unsigned level;
- unsigned tmp;
- unsigned tmp2;
- unsigned i;
-
- size = GetMemInc(c_cs, ip);
- size |= GetMemInc(c_cs, ip) << 8;
- level = GetMemInc(c_cs, ip);
- /*
- PushWordReg(BP);
- tmp = ReadWord(&wregs[SP]);
- WriteWord(&wregs[BP], (WORD)tmp);
- WriteWord(&wregs[SP], (WORD)(tmp - size));
- for(i = 1; i < level; i++) {
- tmp = GetMemW(c_stack, ReadWord(&wregs[BP]) - i * 2);
- tmp2 = (WORD)(ReadWord(&wregs[SP]) - 2);
- WriteWord(&wregs[SP], tmp2);
- PutMemW(c_stack, tmp2, tmp);
- }
- if(level) {
- PushWordReg(BP);
- }
- */
- level %= 32;
- PushWordReg(BP);
- tmp = (WORD)ReadWord(&wregs[SP]);
- if(level > 0) {
- for(i = 1; i < level; i++) {
- tmp2 = (WORD)ReadWord(&wregs[BP]);
- tmp2 -= 2;
- WriteWord(&wregs[BP], (WORD)tmp2);
- PushWordReg(BP);
- }
- tmp2 = (WORD)ReadWord(&wregs[SP]);
- tmp2 -= 2;
- WriteWord(&wregs[SP], (WORD)tmp2);
- PutMemW(c_stack, tmp2, (WORD)tmp);
- }
- WriteWord(&wregs[BP], (WORD)tmp);
- WriteWord(&wregs[SP], (WORD)(tmp - size));
- }
- static INLINE2 void i_leave(void)
- {
- /* Opcode 0xc9 */
- unsigned tmp;
- tmp = ReadWord(&wregs[BP]);
- WriteWord(&wregs[SP], (WORD)tmp);
- PopWordReg(BP);
- }
- static INLINE void i_das(void)
- {
- /* Opcode 0x2f */
- unsigned tmp;
- if(((*bregs[AL] & 0x0f) > 9) || AF) {
- tmp = *bregs[AL] - 6;
- *bregs[AL] = tmp;
- CF = CF | ((tmp & 0x100) ? 1 : 0);
- AF = 0x10;
- } else {
- AF = 0;
- }
- if((*bregs[AL] > 0x9f) || CF) {
- *bregs[AL] = *bregs[AL] - 0x60;
- CF = 1;
- }
- }
- static INLINE void i_aas(void)
- {
- /* Opcode 0x3f */
- if(((*bregs[AL] & 0x0f) > 9) || AF) {
- *bregs[AL] = (BYTE)(*bregs[AL] - 6);
- *bregs[AH] = (BYTE)(*bregs[AH] - 1);
- AF = 0x10;
- CF = 1;
- } else {
- AF = 0;
- CF = 0;
- }
- *bregs[AL] = *bregs[AL] & 0x0f;
- }
|