i186.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. /* i186 instruction implement */
  2. static INLINE2 void i_pusha(void)
  3. {
  4. /* Opcode 0x60 */
  5. unsigned tmp;
  6. unsigned tmp2;
  7. tmp = (WORD)ReadWord(&wregs[SP]);
  8. PushWordReg(AX);
  9. PushWordReg(CX);
  10. PushWordReg(DX);
  11. PushWordReg(BX);
  12. tmp2 = (WORD)ReadWord(&wregs[SP]);
  13. tmp2 -= 2;
  14. WriteWord(&wregs[SP], (WORD)tmp2);
  15. PutMemW(c_stack, (WORD)tmp2, (WORD)tmp);
  16. PushWordReg(BP);
  17. PushWordReg(SI);
  18. PushWordReg(DI);
  19. }
  20. static INLINE2 void i_popa(void)
  21. {
  22. /* Opcode 0x61 */
  23. unsigned tmp;
  24. PopWordReg(DI);
  25. PopWordReg(SI);
  26. PopWordReg(BP);
  27. tmp = (WORD)ReadWord(&wregs[SP]);
  28. tmp += 2;
  29. WriteWord(&wregs[SP], (WORD)tmp);
  30. PopWordReg(BX);
  31. PopWordReg(DX);
  32. PopWordReg(CX);
  33. PopWordReg(AX);
  34. }
  35. static INLINE2 void i_bound(void)
  36. {
  37. /* Opcode 0x62 */
  38. unsigned ModRM = (unsigned)GetMemInc(c_cs, ip);
  39. }
  40. static INLINE2 void i_push_d16(void)
  41. {
  42. /* Opcode 0x68 */
  43. unsigned tmp1;
  44. unsigned tmp2;
  45. tmp1 = GetMemInc(c_cs, ip);
  46. tmp1 |= GetMemInc(c_cs, ip) << 8;
  47. tmp2 = (WORD)ReadWord(&wregs[SP]);
  48. tmp2 -= 2;
  49. WriteWord(&wregs[SP], (WORD)tmp2);
  50. PutMemW(c_stack, (WORD)tmp2, (WORD)tmp1);
  51. }
  52. static INLINE2 void i_imul_d16(void)
  53. {
  54. /* Opcode 0x69 */
  55. INT32 result;
  56. unsigned tmp1;
  57. unsigned tmp2;
  58. unsigned ModRM = GetMemInc(c_cs, ip);
  59. WORD *dest = GetModRMRegW(ModRM);
  60. tmp1 = *(GetModRMRMW(ModRM));
  61. tmp2 = (unsigned)GetMemInc(c_cs, ip);
  62. tmp2 |= (unsigned)GetMemInc(c_cs, ip) << 8;
  63. result = (INT16)(tmp1) * (INT16)(tmp2);
  64. WriteWord(dest, result);
  65. *dest = (INT16)result;
  66. CF = OF = (result >> 16) > 0;
  67. }
  68. static INLINE2 void i_push_d8(void)
  69. {
  70. /* Opcode 0x6a */
  71. unsigned tmp1;
  72. unsigned tmp2;
  73. tmp1 = GetMemInc(c_cs, ip);
  74. tmp2 = (WORD)ReadWord(&wregs[SP]);
  75. tmp2 -= 2;
  76. WriteWord(&wregs[SP], (WORD)tmp2);
  77. PutMemW(c_stack, (WORD)tmp2, (WORD)tmp1);
  78. }
  79. static INLINE2 void i_imul_d8(void)
  80. {
  81. /* Opcode 0x6b */
  82. INT32 result;
  83. unsigned tmp1;
  84. unsigned tmp2;
  85. unsigned ModRM = GetMemInc(c_cs, ip);
  86. WORD *dest = GetModRMRegW(ModRM);
  87. tmp1 = *(GetModRMRMW(ModRM));
  88. tmp2 = (unsigned)GetMemInc(c_cs, ip);
  89. result = (INT16)(tmp1) * (INT16)(tmp2);
  90. WriteWord(dest, result);
  91. *dest = (INT16)result;
  92. CF = OF = (result >> 16) > 0;
  93. }
  94. static INLINE2 void i_insb(void)
  95. {
  96. /* Opcode 0x6c */
  97. ;
  98. }
  99. static INLINE2 void i_insw(void)
  100. {
  101. /* Opcode 0x6d */
  102. ;
  103. }
  104. static INLINE2 void i_outsb(void)
  105. {
  106. /* Opcode 0x6e */
  107. ;
  108. }
  109. static INLINE2 void i_outsw(void)
  110. {
  111. /* Opcode 0x6f */
  112. ;
  113. }
  114. static INLINE2 void i_rotshft_bd8(void)
  115. {
  116. /* Opcode 0xc0 */
  117. unsigned ModRM = GetMemInc(c_cs, ip);
  118. BYTE *dest = GetModRMRMB(ModRM);
  119. unsigned tmp = *dest;
  120. unsigned tmp2;
  121. unsigned count = GetMemInc(c_cs, ip);
  122. switch(ModRM & 0x38) {
  123. case 0x00: /* ROL r/m8, imm8 */
  124. for(; count > 0; count--) {
  125. CF = (tmp & 0x80) != 0;
  126. tmp = (tmp << 1) + CF;
  127. }
  128. *dest = (BYTE)tmp;
  129. break;
  130. case 0x08: /* ROR r/m8, imm8 */
  131. for(; count > 0; count--) {
  132. CF = (tmp & 0x01) != 0;
  133. tmp = (tmp >> 1) + (CF << 7);
  134. }
  135. *dest = (BYTE)tmp;
  136. break;
  137. case 0x10: /* RCL r/m8, imm8 */
  138. for(; count > 0; count--) {
  139. tmp2 = CF;
  140. CF = (tmp & 0x80) != 0;
  141. tmp = (tmp << 1) + tmp2;
  142. }
  143. *dest = (BYTE)tmp;
  144. break;
  145. case 0x18: /* RCR r/m8, imm8 */
  146. for(; count > 0; count--) {
  147. tmp2 = (tmp >> 1) + (CF << 7);
  148. CF = (tmp & 0x01) != 0;
  149. tmp = tmp2;
  150. }
  151. *dest = (BYTE)tmp;
  152. break;
  153. case 0x20: /* SHL r/m8, imm8 */
  154. if(count >= 9) {
  155. CF = 0;
  156. tmp = 0;
  157. } else {
  158. CF = ((tmp << (count - 1)) & 0x80) != 0;
  159. tmp <<= count;
  160. }
  161. AF = 1;
  162. SetZFB(tmp);
  163. SetSFB(tmp);
  164. SetPF(tmp);
  165. *dest = (BYTE)tmp;
  166. break;
  167. case 0x28: /* SHR r/m8, imm8 */
  168. if(count >= 9) {
  169. CF = 0;
  170. tmp = 0;
  171. } else {
  172. CF = ((tmp >> (count - 1)) & 0x1) != 0;
  173. tmp >>= count;
  174. }
  175. SetSFB(tmp);
  176. SetPF(tmp);
  177. SetZFB(tmp);
  178. AF = 1;
  179. *dest = (BYTE)tmp;
  180. break;
  181. case 0x38: /* SAR r/m8, imm8 */
  182. tmp2 = tmp & 0x80;
  183. CF = (((INT8)tmp >> (count - 1)) & 0x01) != 0;
  184. for(; count > 0; count--)
  185. tmp = (tmp >> 1) | tmp2;
  186. SetSFB(tmp);
  187. SetPF(tmp);
  188. SetZFB(tmp);
  189. AF = 1;
  190. *dest = (BYTE)tmp;
  191. break;
  192. default:
  193. break;
  194. }
  195. }
  196. static INLINE2 void i_rotshft_wd8(void)
  197. {
  198. /* Opcode 0xc1 */
  199. unsigned ModRM = GetMemInc(c_cs, ip);
  200. WORD *dest = GetModRMRMW(ModRM);
  201. unsigned tmp = *dest;
  202. unsigned tmp2;
  203. unsigned count = GetMemInc(c_cs, ip);
  204. switch(ModRM & 0x38) {
  205. case 0x00: /* ROL r/m16, imm8 */
  206. for(; count > 0; count--) {
  207. CF = (tmp & 0x80) != 0;
  208. tmp = (tmp << 1) + CF;
  209. }
  210. *dest = (WORD)tmp;
  211. break;
  212. case 0x08: /* ROR r/m16, imm8 */
  213. for(; count > 0; count--) {
  214. CF = (tmp & 0x01) != 0;
  215. tmp = (tmp >> 1) + (CF << 7);
  216. }
  217. *dest = (WORD)tmp;
  218. break;
  219. case 0x10: /* RCL r/m16, imm8 */
  220. for(; count > 0; count--) {
  221. tmp2 = CF;
  222. CF = (tmp & 0x80) != 0;
  223. tmp = (tmp << 1) + tmp2;
  224. }
  225. *dest = (WORD)tmp;
  226. break;
  227. case 0x18: /* RCR r/m16, imm8 */
  228. for(; count > 0; count--) {
  229. tmp2 = (tmp >> 1) + (CF << 7);
  230. CF = (tmp & 0x01) != 0;
  231. tmp = tmp2;
  232. }
  233. *dest = (WORD)tmp;
  234. break;
  235. case 0x20: /* SHL r/m16, imm8 */
  236. if(count >= 9) {
  237. CF = 0;
  238. tmp = 0;
  239. } else {
  240. CF = ((tmp << (count - 1)) & 0x80) != 0;
  241. tmp <<= count;
  242. }
  243. AF = 1;
  244. SetZFB(tmp);
  245. SetSFB(tmp);
  246. SetPF(tmp);
  247. *dest = (WORD)tmp;
  248. break;
  249. case 0x28: /* SHR r/m16, imm8 */
  250. if(count >= 9) {
  251. CF = 0;
  252. tmp = 0;
  253. } else {
  254. CF = ((tmp >> (count - 1)) & 0x1) != 0;
  255. tmp >>= count;
  256. }
  257. SetSFB(tmp);
  258. SetPF(tmp);
  259. SetZFB(tmp);
  260. AF = 1;
  261. *dest = (WORD)tmp;
  262. break;
  263. case 0x38: /* SAR r/m16, imm8 */
  264. tmp2 = tmp & 0x80;
  265. CF = (((INT16)tmp >> (count - 1)) & 0x01) != 0;
  266. for(; count > 0; count--)
  267. tmp = (tmp >> 1) | tmp2;
  268. SetSFB(tmp);
  269. SetPF(tmp);
  270. SetZFB(tmp);
  271. AF = 1;
  272. *dest = (WORD)tmp;
  273. break;
  274. default:
  275. break;
  276. }
  277. }
  278. static INLINE2 void i_enter(void)
  279. {
  280. /* Opcode 0xc8 */
  281. unsigned size;
  282. unsigned level;
  283. unsigned tmp;
  284. unsigned tmp2;
  285. unsigned i;
  286. size = GetMemInc(c_cs, ip);
  287. size |= GetMemInc(c_cs, ip) << 8;
  288. level = GetMemInc(c_cs, ip);
  289. /*
  290. PushWordReg(BP);
  291. tmp = ReadWord(&wregs[SP]);
  292. WriteWord(&wregs[BP], (WORD)tmp);
  293. WriteWord(&wregs[SP], (WORD)(tmp - size));
  294. for(i = 1; i < level; i++) {
  295. tmp = GetMemW(c_stack, ReadWord(&wregs[BP]) - i * 2);
  296. tmp2 = (WORD)(ReadWord(&wregs[SP]) - 2);
  297. WriteWord(&wregs[SP], tmp2);
  298. PutMemW(c_stack, tmp2, tmp);
  299. }
  300. if(level) {
  301. PushWordReg(BP);
  302. }
  303. */
  304. level %= 32;
  305. PushWordReg(BP);
  306. tmp = (WORD)ReadWord(&wregs[SP]);
  307. if(level > 0) {
  308. for(i = 1; i < level; i++) {
  309. tmp2 = (WORD)ReadWord(&wregs[BP]);
  310. tmp2 -= 2;
  311. WriteWord(&wregs[BP], (WORD)tmp2);
  312. PushWordReg(BP);
  313. }
  314. tmp2 = (WORD)ReadWord(&wregs[SP]);
  315. tmp2 -= 2;
  316. WriteWord(&wregs[SP], (WORD)tmp2);
  317. PutMemW(c_stack, tmp2, (WORD)tmp);
  318. }
  319. WriteWord(&wregs[BP], (WORD)tmp);
  320. WriteWord(&wregs[SP], (WORD)(tmp - size));
  321. }
  322. static INLINE2 void i_leave(void)
  323. {
  324. /* Opcode 0xc9 */
  325. unsigned tmp;
  326. tmp = ReadWord(&wregs[BP]);
  327. WriteWord(&wregs[SP], (WORD)tmp);
  328. PopWordReg(BP);
  329. }
  330. static INLINE void i_das(void)
  331. {
  332. /* Opcode 0x2f */
  333. unsigned tmp;
  334. if(((*bregs[AL] & 0x0f) > 9) || AF) {
  335. tmp = *bregs[AL] - 6;
  336. *bregs[AL] = tmp;
  337. CF = CF | ((tmp & 0x100) ? 1 : 0);
  338. AF = 0x10;
  339. } else {
  340. AF = 0;
  341. }
  342. if((*bregs[AL] > 0x9f) || CF) {
  343. *bregs[AL] = *bregs[AL] - 0x60;
  344. CF = 1;
  345. }
  346. }
  347. static INLINE void i_aas(void)
  348. {
  349. /* Opcode 0x3f */
  350. if(((*bregs[AL] & 0x0f) > 9) || AF) {
  351. *bregs[AL] = (BYTE)(*bregs[AL] - 6);
  352. *bregs[AH] = (BYTE)(*bregs[AH] - 1);
  353. AF = 0x10;
  354. CF = 1;
  355. } else {
  356. AF = 0;
  357. CF = 0;
  358. }
  359. *bregs[AL] = *bregs[AL] & 0x0f;
  360. }