Mirror of CollapseOS
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3344 lines
91KB

  1. /* Extracted from the Fake86 project and heavily modified to run within
  2. the Collapse OS project with its simple needs.
  3. */
  4. /*
  5. Fake86: A portable, open-source 8086 PC emulator.
  6. Copyright (C)2010-2013 Mike Chambers
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. #include <stdint.h>
  20. #include <stdio.h>
  21. #include "cpu.h"
  22. #define StepIP(x) ip += x
  23. #define signext(value) (int16_t)(int8_t)(value)
  24. #define signext32(value) (int32_t)(int16_t)(value)
  25. #define getsegreg(regid) segregs[regid]
  26. #define putsegreg(regid, writeval) segregs[regid] = writeval
  27. // Warning: those macros below *can't* be called with reg*l and reg*h
  28. #define getreg8(regid) regs.byteregs[byteregtable[regid]]
  29. #define putreg8(regid, writeval) regs.byteregs[byteregtable[regid]] = writeval
  30. #define makeflagsword() \
  31. ( \
  32. 2 | (uint16_t) cf | ((uint16_t) pf << 2) | ((uint16_t) af << 4) | ((uint16_t) zf << 6) | ((uint16_t) sf << 7) | \
  33. ((uint16_t) tf << 8) | ((uint16_t) ifl << 9) | ((uint16_t) df << 10) | ((uint16_t) of << 11) \
  34. )
  35. #define decodeflagsword(x) { \
  36. temp16 = x; \
  37. cf = temp16 & 1; \
  38. pf = (temp16 >> 2) & 1; \
  39. af = (temp16 >> 4) & 1; \
  40. zf = (temp16 >> 6) & 1; \
  41. sf = (temp16 >> 7) & 1; \
  42. tf = (temp16 >> 8) & 1; \
  43. ifl = (temp16 >> 9) & 1; \
  44. df = (temp16 >> 10) & 1; \
  45. of = (temp16 >> 11) & 1; \
  46. }
  47. #define modregrm() { \
  48. addrbyte = getmem8(segregs[regcs], ip); \
  49. StepIP(1); \
  50. mode = addrbyte >> 6; \
  51. reg = (addrbyte >> 3) & 7; \
  52. rm = addrbyte & 7; \
  53. switch(mode) \
  54. { \
  55. case 0: \
  56. if(rm == 6) { \
  57. disp16 = getmem16(segregs[regcs], ip); \
  58. StepIP(2); \
  59. } \
  60. if(((rm == 2) || (rm == 3)) && !segoverride) { \
  61. useseg = segregs[regss]; \
  62. } \
  63. break; \
  64. \
  65. case 1: \
  66. disp16 = signext(getmem8(segregs[regcs], ip)); \
  67. StepIP(1); \
  68. if(((rm == 2) || (rm == 3) || (rm == 6)) && !segoverride) { \
  69. useseg = segregs[regss]; \
  70. } \
  71. break; \
  72. \
  73. case 2: \
  74. disp16 = getmem16(segregs[regcs], ip); \
  75. StepIP(2); \
  76. if(((rm == 2) || (rm == 3) || (rm == 6)) && !segoverride) { \
  77. useseg = segregs[regss]; \
  78. } \
  79. break; \
  80. \
  81. default: \
  82. disp8 = 0; \
  83. disp16 = 0; \
  84. } \
  85. }
  86. uint8_t byteregtable[8] = { regal, regcl, regdl, regbl, regah, regch, regdh, regbh };
  87. static const uint8_t parity[0x100] = {
  88. 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  89. 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  90. 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  91. 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  92. 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  93. 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  94. 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  95. 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
  96. };
  97. uint8_t RAM[0x100000];
  98. INTHOOK INTHOOKS[0x100] = {0};
  99. uint8_t opcode, segoverride, reptype, hltstate = 0;
  100. uint16_t segregs[4], savecs, saveip, ip, useseg, oldsp;
  101. uint8_t tempcf, oldcf, cf, pf, af, zf, sf, tf, ifl, df, of, mode, reg, rm;
  102. uint16_t oper1, oper2, res16, disp16, temp16, dummy, stacksize, frametemp;
  103. uint8_t oper1b, oper2b, res8, disp8, temp8, nestlev, addrbyte;
  104. uint32_t temp1, temp2, temp3, temp4, temp5, temp32, tempaddr32, ea;
  105. uint64_t totalexec;
  106. union _bytewordregs_ regs;
  107. uint8_t portram[0x10000];
  108. void intcall86(uint8_t intnum);
  109. static void portout (uint16_t portnum, uint8_t value) {}
  110. static void portout16 (uint16_t portnum, uint16_t value) {}
  111. static uint8_t portin (uint16_t portnum) { return 0; }
  112. static uint16_t portin16 (uint16_t portnum) { return 0; }
  113. void write86 (uint32_t addr32, uint8_t value) {
  114. tempaddr32 = addr32 & 0xFFFFF;
  115. RAM[tempaddr32] = value;
  116. }
  117. void writew86 (uint32_t addr32, uint16_t value) {
  118. write86(addr32, (uint8_t) value);
  119. write86(addr32 + 1, (uint8_t) (value >> 8) );
  120. }
  121. uint8_t read86 (uint32_t addr32) {
  122. addr32 &= 0xFFFFF;
  123. return (RAM[addr32]);
  124. }
  125. uint16_t readw86 (uint32_t addr32) {
  126. return ( (uint16_t) read86 (addr32) | (uint16_t) (read86 (addr32 + 1) << 8) );
  127. }
  128. static void flag_szp8 (uint8_t value) {
  129. if (!value) {
  130. zf = 1;
  131. }
  132. else {
  133. zf = 0; /* set or clear zero flag */
  134. }
  135. if (value & 0x80) {
  136. sf = 1;
  137. }
  138. else {
  139. sf = 0; /* set or clear sign flag */
  140. }
  141. pf = parity[value]; /* retrieve parity state from lookup table */
  142. }
  143. static void flag_szp16 (uint16_t value) {
  144. if (!value) {
  145. zf = 1;
  146. }
  147. else {
  148. zf = 0; /* set or clear zero flag */
  149. }
  150. if (value & 0x8000) {
  151. sf = 1;
  152. }
  153. else {
  154. sf = 0; /* set or clear sign flag */
  155. }
  156. pf = parity[value & 255]; /* retrieve parity state from lookup table */
  157. }
  158. static void flag_log8 (uint8_t value) {
  159. flag_szp8 (value);
  160. cf = 0;
  161. of = 0; /* bitwise logic ops always clear carry and overflow */
  162. }
  163. static void flag_log16 (uint16_t value) {
  164. flag_szp16 (value);
  165. cf = 0;
  166. of = 0; /* bitwise logic ops always clear carry and overflow */
  167. }
  168. static void flag_adc8 (uint8_t v1, uint8_t v2, uint8_t v3) {
  169. /* v1 = destination operand, v2 = source operand, v3 = carry flag */
  170. uint16_t dst;
  171. dst = (uint16_t) v1 + (uint16_t) v2 + (uint16_t) v3;
  172. flag_szp8 ( (uint8_t) dst);
  173. if ( ( (dst ^ v1) & (dst ^ v2) & 0x80) == 0x80) {
  174. of = 1;
  175. }
  176. else {
  177. of = 0; /* set or clear overflow flag */
  178. }
  179. if (dst & 0xFF00) {
  180. cf = 1;
  181. }
  182. else {
  183. cf = 0; /* set or clear carry flag */
  184. }
  185. if ( ( (v1 ^ v2 ^ dst) & 0x10) == 0x10) {
  186. af = 1;
  187. }
  188. else {
  189. af = 0; /* set or clear auxilliary flag */
  190. }
  191. }
  192. static void flag_adc16 (uint16_t v1, uint16_t v2, uint16_t v3) {
  193. uint32_t dst;
  194. dst = (uint32_t) v1 + (uint32_t) v2 + (uint32_t) v3;
  195. flag_szp16 ( (uint16_t) dst);
  196. if ( ( ( (dst ^ v1) & (dst ^ v2) ) & 0x8000) == 0x8000) {
  197. of = 1;
  198. }
  199. else {
  200. of = 0;
  201. }
  202. if (dst & 0xFFFF0000) {
  203. cf = 1;
  204. }
  205. else {
  206. cf = 0;
  207. }
  208. if ( ( (v1 ^ v2 ^ dst) & 0x10) == 0x10) {
  209. af = 1;
  210. }
  211. else {
  212. af = 0;
  213. }
  214. }
  215. static void flag_add8 (uint8_t v1, uint8_t v2) {
  216. /* v1 = destination operand, v2 = source operand */
  217. uint16_t dst;
  218. dst = (uint16_t) v1 + (uint16_t) v2;
  219. flag_szp8 ( (uint8_t) dst);
  220. if (dst & 0xFF00) {
  221. cf = 1;
  222. }
  223. else {
  224. cf = 0;
  225. }
  226. if ( ( (dst ^ v1) & (dst ^ v2) & 0x80) == 0x80) {
  227. of = 1;
  228. }
  229. else {
  230. of = 0;
  231. }
  232. if ( ( (v1 ^ v2 ^ dst) & 0x10) == 0x10) {
  233. af = 1;
  234. }
  235. else {
  236. af = 0;
  237. }
  238. }
  239. static void flag_add16 (uint16_t v1, uint16_t v2) {
  240. /* v1 = destination operand, v2 = source operand */
  241. uint32_t dst;
  242. dst = (uint32_t) v1 + (uint32_t) v2;
  243. flag_szp16 ( (uint16_t) dst);
  244. if (dst & 0xFFFF0000) {
  245. cf = 1;
  246. }
  247. else {
  248. cf = 0;
  249. }
  250. if ( ( (dst ^ v1) & (dst ^ v2) & 0x8000) == 0x8000) {
  251. of = 1;
  252. }
  253. else {
  254. of = 0;
  255. }
  256. if ( ( (v1 ^ v2 ^ dst) & 0x10) == 0x10) {
  257. af = 1;
  258. }
  259. else {
  260. af = 0;
  261. }
  262. }
  263. static void flag_sbb8 (uint8_t v1, uint8_t v2, uint8_t v3) {
  264. /* v1 = destination operand, v2 = source operand, v3 = carry flag */
  265. uint16_t dst;
  266. v2 += v3;
  267. dst = (uint16_t) v1 - (uint16_t) v2;
  268. flag_szp8 ( (uint8_t) dst);
  269. if (dst & 0xFF00) {
  270. cf = 1;
  271. }
  272. else {
  273. cf = 0;
  274. }
  275. if ( (dst ^ v1) & (v1 ^ v2) & 0x80) {
  276. of = 1;
  277. }
  278. else {
  279. of = 0;
  280. }
  281. if ( (v1 ^ v2 ^ dst) & 0x10) {
  282. af = 1;
  283. }
  284. else {
  285. af = 0;
  286. }
  287. }
  288. static void flag_sbb16 (uint16_t v1, uint16_t v2, uint16_t v3) {
  289. /* v1 = destination operand, v2 = source operand, v3 = carry flag */
  290. uint32_t dst;
  291. v2 += v3;
  292. dst = (uint32_t) v1 - (uint32_t) v2;
  293. flag_szp16 ( (uint16_t) dst);
  294. if (dst & 0xFFFF0000) {
  295. cf = 1;
  296. }
  297. else {
  298. cf = 0;
  299. }
  300. if ( (dst ^ v1) & (v1 ^ v2) & 0x8000) {
  301. of = 1;
  302. }
  303. else {
  304. of = 0;
  305. }
  306. if ( (v1 ^ v2 ^ dst) & 0x10) {
  307. af = 1;
  308. }
  309. else {
  310. af = 0;
  311. }
  312. }
  313. static void flag_sub8 (uint8_t v1, uint8_t v2) {
  314. /* v1 = destination operand, v2 = source operand */
  315. uint16_t dst;
  316. dst = (uint16_t) v1 - (uint16_t) v2;
  317. flag_szp8 ( (uint8_t) dst);
  318. if (dst & 0xFF00) {
  319. cf = 1;
  320. }
  321. else {
  322. cf = 0;
  323. }
  324. if ( (dst ^ v1) & (v1 ^ v2) & 0x80) {
  325. of = 1;
  326. }
  327. else {
  328. of = 0;
  329. }
  330. if ( (v1 ^ v2 ^ dst) & 0x10) {
  331. af = 1;
  332. }
  333. else {
  334. af = 0;
  335. }
  336. }
  337. static void flag_sub16 (uint16_t v1, uint16_t v2) {
  338. /* v1 = destination operand, v2 = source operand */
  339. uint32_t dst;
  340. dst = (uint32_t) v1 - (uint32_t) v2;
  341. flag_szp16 ( (uint16_t) dst);
  342. if (dst & 0xFFFF0000) {
  343. cf = 1;
  344. }
  345. else {
  346. cf = 0;
  347. }
  348. if ( (dst ^ v1) & (v1 ^ v2) & 0x8000) {
  349. of = 1;
  350. }
  351. else {
  352. of = 0;
  353. }
  354. if ( (v1 ^ v2 ^ dst) & 0x10) {
  355. af = 1;
  356. }
  357. else {
  358. af = 0;
  359. }
  360. }
  361. static void op_adc8() {
  362. res8 = oper1b + oper2b + cf;
  363. flag_adc8 (oper1b, oper2b, cf);
  364. }
  365. static void op_adc16() {
  366. res16 = oper1 + oper2 + cf;
  367. flag_adc16 (oper1, oper2, cf);
  368. }
  369. static void op_add8() {
  370. res8 = oper1b + oper2b;
  371. flag_add8 (oper1b, oper2b);
  372. }
  373. static void op_add16() {
  374. res16 = oper1 + oper2;
  375. flag_add16 (oper1, oper2);
  376. }
  377. static void op_and8() {
  378. res8 = oper1b & oper2b;
  379. flag_log8 (res8);
  380. }
  381. static void op_and16() {
  382. res16 = oper1 & oper2;
  383. flag_log16 (res16);
  384. }
  385. static void op_or8() {
  386. res8 = oper1b | oper2b;
  387. flag_log8 (res8);
  388. }
  389. static void op_or16() {
  390. res16 = oper1 | oper2;
  391. flag_log16 (res16);
  392. }
  393. static void op_xor8() {
  394. res8 = oper1b ^ oper2b;
  395. flag_log8 (res8);
  396. }
  397. static void op_xor16() {
  398. res16 = oper1 ^ oper2;
  399. flag_log16 (res16);
  400. }
  401. static void op_sub8() {
  402. res8 = oper1b - oper2b;
  403. flag_sub8 (oper1b, oper2b);
  404. }
  405. static void op_sub16() {
  406. res16 = oper1 - oper2;
  407. flag_sub16 (oper1, oper2);
  408. }
  409. static void op_sbb8() {
  410. res8 = oper1b - (oper2b + cf);
  411. flag_sbb8 (oper1b, oper2b, cf);
  412. }
  413. static void op_sbb16() {
  414. res16 = oper1 - (oper2 + cf);
  415. flag_sbb16 (oper1, oper2, cf);
  416. }
  417. static void getea (uint8_t rmval) {
  418. uint32_t tempea;
  419. tempea = 0;
  420. switch (mode) {
  421. case 0:
  422. switch (rmval) {
  423. case 0:
  424. tempea = regs.wordregs[regbx] + regs.wordregs[regsi];
  425. break;
  426. case 1:
  427. tempea = regs.wordregs[regbx] + regs.wordregs[regdi];
  428. break;
  429. case 2:
  430. tempea = regs.wordregs[regbp] + regs.wordregs[regsi];
  431. break;
  432. case 3:
  433. tempea = regs.wordregs[regbp] + regs.wordregs[regdi];
  434. break;
  435. case 4:
  436. tempea = regs.wordregs[regsi];
  437. break;
  438. case 5:
  439. tempea = regs.wordregs[regdi];
  440. break;
  441. case 6:
  442. tempea = disp16;
  443. break;
  444. case 7:
  445. tempea = regs.wordregs[regbx];
  446. break;
  447. }
  448. break;
  449. case 1:
  450. case 2:
  451. switch (rmval) {
  452. case 0:
  453. tempea = regs.wordregs[regbx] + regs.wordregs[regsi] + disp16;
  454. break;
  455. case 1:
  456. tempea = regs.wordregs[regbx] + regs.wordregs[regdi] + disp16;
  457. break;
  458. case 2:
  459. tempea = regs.wordregs[regbp] + regs.wordregs[regsi] + disp16;
  460. break;
  461. case 3:
  462. tempea = regs.wordregs[regbp] + regs.wordregs[regdi] + disp16;
  463. break;
  464. case 4:
  465. tempea = regs.wordregs[regsi] + disp16;
  466. break;
  467. case 5:
  468. tempea = regs.wordregs[regdi] + disp16;
  469. break;
  470. case 6:
  471. tempea = regs.wordregs[regbp] + disp16;
  472. break;
  473. case 7:
  474. tempea = regs.wordregs[regbx] + disp16;
  475. break;
  476. }
  477. break;
  478. }
  479. ea = (tempea & 0xFFFF) + (useseg << 4);
  480. }
  481. static void push (uint16_t pushval) {
  482. regs.wordregs[regsp] = regs.wordregs[regsp] - 2;
  483. putmem16 (segregs[regss], regs.wordregs[regsp], pushval);
  484. }
  485. static uint16_t pop() {
  486. uint16_t tempval;
  487. tempval = getmem16 (segregs[regss], regs.wordregs[regsp]);
  488. regs.wordregs[regsp] = regs.wordregs[regsp] + 2;
  489. return tempval;
  490. }
  491. static uint16_t readrm16 (uint8_t rmval) {
  492. if (mode < 3) {
  493. getea (rmval);
  494. return read86 (ea) | ( (uint16_t) read86 (ea + 1) << 8);
  495. }
  496. else {
  497. return getreg16 (rmval);
  498. }
  499. }
  500. static uint8_t readrm8 (uint8_t rmval) {
  501. if (mode < 3) {
  502. getea (rmval);
  503. return read86 (ea);
  504. }
  505. else {
  506. return getreg8 (rmval);
  507. }
  508. }
  509. static void writerm16 (uint8_t rmval, uint16_t value) {
  510. if (mode < 3) {
  511. getea (rmval);
  512. write86 (ea, value & 0xFF);
  513. write86 (ea + 1, value >> 8);
  514. }
  515. else {
  516. putreg16 (rmval, value);
  517. }
  518. }
  519. static void writerm8 (uint8_t rmval, uint8_t value) {
  520. if (mode < 3) {
  521. getea (rmval);
  522. write86 (ea, value);
  523. }
  524. else {
  525. putreg8 (rmval, value);
  526. }
  527. }
  528. static uint8_t op_grp2_8 (uint8_t cnt) {
  529. uint16_t s;
  530. uint16_t shift;
  531. uint16_t oldcf;
  532. uint16_t msb;
  533. s = oper1b;
  534. oldcf = cf;
  535. cnt &= 0x1F;
  536. switch (reg) {
  537. case 0: /* ROL r/m8 */
  538. for (shift = 1; shift <= cnt; shift++) {
  539. if (s & 0x80) {
  540. cf = 1;
  541. }
  542. else {
  543. cf = 0;
  544. }
  545. s = s << 1;
  546. s = s | cf;
  547. }
  548. if (cnt == 1) {
  549. //of = cf ^ ( (s >> 7) & 1);
  550. if ((s & 0x80) && cf) of = 1; else of = 0;
  551. } else of = 0;
  552. break;
  553. case 1: /* ROR r/m8 */
  554. for (shift = 1; shift <= cnt; shift++) {
  555. cf = s & 1;
  556. s = (s >> 1) | (cf << 7);
  557. }
  558. if (cnt == 1) {
  559. of = (s >> 7) ^ ( (s >> 6) & 1);
  560. }
  561. break;
  562. case 2: /* RCL r/m8 */
  563. for (shift = 1; shift <= cnt; shift++) {
  564. oldcf = cf;
  565. if (s & 0x80) {
  566. cf = 1;
  567. }
  568. else {
  569. cf = 0;
  570. }
  571. s = s << 1;
  572. s = s | oldcf;
  573. }
  574. if (cnt == 1) {
  575. of = cf ^ ( (s >> 7) & 1);
  576. }
  577. break;
  578. case 3: /* RCR r/m8 */
  579. for (shift = 1; shift <= cnt; shift++) {
  580. oldcf = cf;
  581. cf = s & 1;
  582. s = (s >> 1) | (oldcf << 7);
  583. }
  584. if (cnt == 1) {
  585. of = (s >> 7) ^ ( (s >> 6) & 1);
  586. }
  587. break;
  588. case 4:
  589. case 6: /* SHL r/m8 */
  590. for (shift = 1; shift <= cnt; shift++) {
  591. if (s & 0x80) {
  592. cf = 1;
  593. }
  594. else {
  595. cf = 0;
  596. }
  597. s = (s << 1) & 0xFF;
  598. }
  599. if ( (cnt == 1) && (cf == (s >> 7) ) ) {
  600. of = 0;
  601. }
  602. else {
  603. of = 1;
  604. }
  605. flag_szp8 ( (uint8_t) s);
  606. break;
  607. case 5: /* SHR r/m8 */
  608. if ( (cnt == 1) && (s & 0x80) ) {
  609. of = 1;
  610. }
  611. else {
  612. of = 0;
  613. }
  614. for (shift = 1; shift <= cnt; shift++) {
  615. cf = s & 1;
  616. s = s >> 1;
  617. }
  618. flag_szp8 ( (uint8_t) s);
  619. break;
  620. case 7: /* SAR r/m8 */
  621. for (shift = 1; shift <= cnt; shift++) {
  622. msb = s & 0x80;
  623. cf = s & 1;
  624. s = (s >> 1) | msb;
  625. }
  626. of = 0;
  627. flag_szp8 ( (uint8_t) s);
  628. break;
  629. }
  630. return s & 0xFF;
  631. }
  632. static uint16_t op_grp2_16 (uint8_t cnt) {
  633. uint32_t s;
  634. uint32_t shift;
  635. uint32_t oldcf;
  636. uint32_t msb;
  637. s = oper1;
  638. oldcf = cf;
  639. cnt &= 0x1F;
  640. switch (reg) {
  641. case 0: /* ROL r/m8 */
  642. for (shift = 1; shift <= cnt; shift++) {
  643. if (s & 0x8000) {
  644. cf = 1;
  645. }
  646. else {
  647. cf = 0;
  648. }
  649. s = s << 1;
  650. s = s | cf;
  651. }
  652. if (cnt == 1) {
  653. of = cf ^ ( (s >> 15) & 1);
  654. }
  655. break;
  656. case 1: /* ROR r/m8 */
  657. for (shift = 1; shift <= cnt; shift++) {
  658. cf = s & 1;
  659. s = (s >> 1) | (cf << 15);
  660. }
  661. if (cnt == 1) {
  662. of = (s >> 15) ^ ( (s >> 14) & 1);
  663. }
  664. break;
  665. case 2: /* RCL r/m8 */
  666. for (shift = 1; shift <= cnt; shift++) {
  667. oldcf = cf;
  668. if (s & 0x8000) {
  669. cf = 1;
  670. }
  671. else {
  672. cf = 0;
  673. }
  674. s = s << 1;
  675. s = s | oldcf;
  676. }
  677. if (cnt == 1) {
  678. of = cf ^ ( (s >> 15) & 1);
  679. }
  680. break;
  681. case 3: /* RCR r/m8 */
  682. for (shift = 1; shift <= cnt; shift++) {
  683. oldcf = cf;
  684. cf = s & 1;
  685. s = (s >> 1) | (oldcf << 15);
  686. }
  687. if (cnt == 1) {
  688. of = (s >> 15) ^ ( (s >> 14) & 1);
  689. }
  690. break;
  691. case 4:
  692. case 6: /* SHL r/m8 */
  693. for (shift = 1; shift <= cnt; shift++) {
  694. if (s & 0x8000) {
  695. cf = 1;
  696. }
  697. else {
  698. cf = 0;
  699. }
  700. s = (s << 1) & 0xFFFF;
  701. }
  702. if ( (cnt == 1) && (cf == (s >> 15) ) ) {
  703. of = 0;
  704. }
  705. else {
  706. of = 1;
  707. }
  708. flag_szp16 ( (uint16_t) s);
  709. break;
  710. case 5: /* SHR r/m8 */
  711. if ( (cnt == 1) && (s & 0x8000) ) {
  712. of = 1;
  713. }
  714. else {
  715. of = 0;
  716. }
  717. for (shift = 1; shift <= cnt; shift++) {
  718. cf = s & 1;
  719. s = s >> 1;
  720. }
  721. flag_szp16 ( (uint16_t) s);
  722. break;
  723. case 7: /* SAR r/m8 */
  724. for (shift = 1; shift <= cnt; shift++) {
  725. msb = s & 0x8000;
  726. cf = s & 1;
  727. s = (s >> 1) | msb;
  728. }
  729. of = 0;
  730. flag_szp16 ( (uint16_t) s);
  731. break;
  732. }
  733. return (uint16_t) s & 0xFFFF;
  734. }
  735. static void op_div8 (uint16_t valdiv, uint8_t divisor) {
  736. if (divisor == 0) {
  737. intcall86 (0);
  738. return;
  739. }
  740. if ( (valdiv / (uint16_t) divisor) > 0xFF) {
  741. intcall86 (0);
  742. return;
  743. }
  744. regs.byteregs[regah] = valdiv % (uint16_t) divisor;
  745. regs.byteregs[regal] = valdiv / (uint16_t) divisor;
  746. }
  747. static void op_idiv8 (uint16_t valdiv, uint8_t divisor) {
  748. uint16_t s1;
  749. uint16_t s2;
  750. uint16_t d1;
  751. uint16_t d2;
  752. int sign;
  753. if (divisor == 0) {
  754. intcall86 (0);
  755. return;
  756. }
  757. s1 = valdiv;
  758. s2 = divisor;
  759. sign = ( ( (s1 ^ s2) & 0x8000) != 0);
  760. s1 = (s1 < 0x8000) ? s1 : ( (~s1 + 1) & 0xffff);
  761. s2 = (s2 < 0x8000) ? s2 : ( (~s2 + 1) & 0xffff);
  762. d1 = s1 / s2;
  763. d2 = s1 % s2;
  764. if (d1 & 0xFF00) {
  765. intcall86 (0);
  766. return;
  767. }
  768. if (sign) {
  769. d1 = (~d1 + 1) & 0xff;
  770. d2 = (~d2 + 1) & 0xff;
  771. }
  772. regs.byteregs[regah] = (uint8_t) d2;
  773. regs.byteregs[regal] = (uint8_t) d1;
  774. }
  775. static void op_grp3_8() {
  776. oper1 = signext (oper1b);
  777. oper2 = signext (oper2b);
  778. switch (reg) {
  779. case 0:
  780. case 1: /* TEST */
  781. flag_log8 (oper1b & getmem8 (segregs[regcs], ip) );
  782. StepIP (1);
  783. break;
  784. case 2: /* NOT */
  785. res8 = ~oper1b;
  786. break;
  787. case 3: /* NEG */
  788. res8 = (~oper1b) + 1;
  789. flag_sub8 (0, oper1b);
  790. if (res8 == 0) {
  791. cf = 0;
  792. }
  793. else {
  794. cf = 1;
  795. }
  796. break;
  797. case 4: /* MUL */
  798. temp1 = (uint32_t) oper1b * (uint32_t) regs.byteregs[regal];
  799. regs.wordregs[regax] = temp1 & 0xFFFF;
  800. flag_szp8 ( (uint8_t) temp1);
  801. if (regs.byteregs[regah]) {
  802. cf = 1;
  803. of = 1;
  804. }
  805. else {
  806. cf = 0;
  807. of = 0;
  808. }
  809. break;
  810. case 5: /* IMUL */
  811. oper1 = signext (oper1b);
  812. temp1 = signext (regs.byteregs[regal]);
  813. temp2 = oper1;
  814. if ( (temp1 & 0x80) == 0x80) {
  815. temp1 = temp1 | 0xFFFFFF00;
  816. }
  817. if ( (temp2 & 0x80) == 0x80) {
  818. temp2 = temp2 | 0xFFFFFF00;
  819. }
  820. temp3 = (temp1 * temp2) & 0xFFFF;
  821. regs.wordregs[regax] = temp3 & 0xFFFF;
  822. if (regs.byteregs[regah]) {
  823. cf = 1;
  824. of = 1;
  825. }
  826. else {
  827. cf = 0;
  828. of = 0;
  829. }
  830. break;
  831. case 6: /* DIV */
  832. op_div8 (regs.wordregs[regax], oper1b);
  833. break;
  834. case 7: /* IDIV */
  835. op_idiv8 (regs.wordregs[regax], oper1b);
  836. break;
  837. }
  838. }
  839. static void op_div16 (uint32_t valdiv, uint16_t divisor) {
  840. if (divisor == 0) {
  841. intcall86 (0);
  842. return;
  843. }
  844. if ( (valdiv / (uint32_t) divisor) > 0xFFFF) {
  845. intcall86 (0);
  846. return;
  847. }
  848. regs.wordregs[regdx] = valdiv % (uint32_t) divisor;
  849. regs.wordregs[regax] = valdiv / (uint32_t) divisor;
  850. }
  851. static void op_idiv16 (uint32_t valdiv, uint16_t divisor) {
  852. uint32_t d1;
  853. uint32_t d2;
  854. uint32_t s1;
  855. uint32_t s2;
  856. int sign;
  857. if (divisor == 0) {
  858. intcall86 (0);
  859. return;
  860. }
  861. s1 = valdiv;
  862. s2 = divisor;
  863. s2 = (s2 & 0x8000) ? (s2 | 0xffff0000) : s2;
  864. sign = ( ( (s1 ^ s2) & 0x80000000) != 0);
  865. s1 = (s1 < 0x80000000) ? s1 : ( (~s1 + 1) & 0xffffffff);
  866. s2 = (s2 < 0x80000000) ? s2 : ( (~s2 + 1) & 0xffffffff);
  867. d1 = s1 / s2;
  868. d2 = s1 % s2;
  869. if (d1 & 0xFFFF0000) {
  870. intcall86 (0);
  871. return;
  872. }
  873. if (sign) {
  874. d1 = (~d1 + 1) & 0xffff;
  875. d2 = (~d2 + 1) & 0xffff;
  876. }
  877. regs.wordregs[regax] = d1;
  878. regs.wordregs[regdx] = d2;
  879. }
  880. static void op_grp3_16() {
  881. switch (reg) {
  882. case 0:
  883. case 1: /* TEST */
  884. flag_log16 (oper1 & getmem16 (segregs[regcs], ip) );
  885. StepIP (2);
  886. break;
  887. case 2: /* NOT */
  888. res16 = ~oper1;
  889. break;
  890. case 3: /* NEG */
  891. res16 = (~oper1) + 1;
  892. flag_sub16 (0, oper1);
  893. if (res16) {
  894. cf = 1;
  895. }
  896. else {
  897. cf = 0;
  898. }
  899. break;
  900. case 4: /* MUL */
  901. temp1 = (uint32_t) oper1 * (uint32_t) regs.wordregs[regax];
  902. regs.wordregs[regax] = temp1 & 0xFFFF;
  903. regs.wordregs[regdx] = temp1 >> 16;
  904. flag_szp16 ( (uint16_t) temp1);
  905. if (regs.wordregs[regdx]) {
  906. cf = 1;
  907. of = 1;
  908. }
  909. else {
  910. cf = 0;
  911. of = 0;
  912. }
  913. break;
  914. case 5: /* IMUL */
  915. temp1 = regs.wordregs[regax];
  916. temp2 = oper1;
  917. if (temp1 & 0x8000) {
  918. temp1 |= 0xFFFF0000;
  919. }
  920. if (temp2 & 0x8000) {
  921. temp2 |= 0xFFFF0000;
  922. }
  923. temp3 = temp1 * temp2;
  924. regs.wordregs[regax] = temp3 & 0xFFFF; /* into register ax */
  925. regs.wordregs[regdx] = temp3 >> 16; /* into register dx */
  926. if (regs.wordregs[regdx]) {
  927. cf = 1;
  928. of = 1;
  929. }
  930. else {
  931. cf = 0;
  932. of = 0;
  933. }
  934. break;
  935. case 6: /* DIV */
  936. op_div16 ( ( (uint32_t) regs.wordregs[regdx] << 16) + regs.wordregs[regax], oper1);
  937. break;
  938. case 7: /* DIV */
  939. op_idiv16 ( ( (uint32_t) regs.wordregs[regdx] << 16) + regs.wordregs[regax], oper1);
  940. break;
  941. }
  942. }
  943. static void op_grp5() {
  944. switch (reg) {
  945. case 0: /* INC Ev */
  946. oper2 = 1;
  947. tempcf = cf;
  948. op_add16();
  949. cf = tempcf;
  950. writerm16 (rm, res16);
  951. break;
  952. case 1: /* DEC Ev */
  953. oper2 = 1;
  954. tempcf = cf;
  955. op_sub16();
  956. cf = tempcf;
  957. writerm16 (rm, res16);
  958. break;
  959. case 2: /* CALL Ev */
  960. push (ip);
  961. ip = oper1;
  962. break;
  963. case 3: /* CALL Mp */
  964. push (segregs[regcs]);
  965. push (ip);
  966. getea (rm);
  967. ip = (uint16_t) read86 (ea) + (uint16_t) read86 (ea + 1) * 256;
  968. segregs[regcs] = (uint16_t) read86 (ea + 2) + (uint16_t) read86 (ea + 3) * 256;
  969. break;
  970. case 4: /* JMP Ev */
  971. ip = oper1;
  972. break;
  973. case 5: /* JMP Mp */
  974. getea (rm);
  975. ip = (uint16_t) read86 (ea) + (uint16_t) read86 (ea + 1) * 256;
  976. segregs[regcs] = (uint16_t) read86 (ea + 2) + (uint16_t) read86 (ea + 3) * 256;
  977. break;
  978. case 6: /* PUSH Ev */
  979. push (oper1);
  980. break;
  981. }
  982. }
  983. void intcall86(uint8_t intnum) {
  984. if (intnum == 0) {
  985. fprintf(stderr, "INT 0 called, halting\n");
  986. hltstate = 1;
  987. return;
  988. }
  989. if (INTHOOKS[intnum] != NULL) {
  990. INTHOOKS[intnum]();
  991. return;
  992. }
  993. fprintf(stderr, "Unknown INT called: %x\n", intnum);
  994. /*push (makeflagsword() );
  995. push (segregs[regcs]);
  996. push (ip);
  997. segregs[regcs] = getmem16 (0, (uint16_t) intnum * 4 + 2);
  998. ip = getmem16 (0, (uint16_t) intnum * 4);
  999. ifl = 0;
  1000. tf = 0;*/
  1001. }
  1002. int exec86(int execloops) {
  1003. int loopcount;
  1004. uint8_t docontinue;
  1005. static uint16_t firstip;
  1006. for (loopcount = 0; loopcount < execloops; loopcount++) {
  1007. if (hltstate) return 0;
  1008. reptype = 0;
  1009. segoverride = 0;
  1010. useseg = segregs[regds];
  1011. docontinue = 0;
  1012. firstip = ip;
  1013. while (!docontinue) {
  1014. segregs[regcs] = segregs[regcs] & 0xFFFF;
  1015. ip = ip & 0xFFFF;
  1016. savecs = segregs[regcs];
  1017. saveip = ip;
  1018. opcode = getmem8 (segregs[regcs], ip);
  1019. StepIP (1);
  1020. switch (opcode) {
  1021. /* segment prefix check */
  1022. case 0x2E: /* segment segregs[regcs] */
  1023. useseg = segregs[regcs];
  1024. segoverride = 1;
  1025. break;
  1026. case 0x3E: /* segment segregs[regds] */
  1027. useseg = segregs[regds];
  1028. segoverride = 1;
  1029. break;
  1030. case 0x26: /* segment segregs[reges] */
  1031. useseg = segregs[reges];
  1032. segoverride = 1;
  1033. break;
  1034. case 0x36: /* segment segregs[regss] */
  1035. useseg = segregs[regss];
  1036. segoverride = 1;
  1037. break;
  1038. /* repetition prefix check */
  1039. case 0xF3: /* REP/REPE/REPZ */
  1040. reptype = 1;
  1041. break;
  1042. case 0xF2: /* REPNE/REPNZ */
  1043. reptype = 2;
  1044. break;
  1045. default:
  1046. docontinue = 1;
  1047. break;
  1048. }
  1049. }
  1050. totalexec++;
  1051. switch (opcode) {
  1052. case 0x0: /* 00 ADD Eb Gb */
  1053. modregrm();
  1054. oper1b = readrm8 (rm);
  1055. oper2b = getreg8 (reg);
  1056. op_add8();
  1057. writerm8 (rm, res8);
  1058. break;
  1059. case 0x1: /* 01 ADD Ev Gv */
  1060. modregrm();
  1061. oper1 = readrm16 (rm);
  1062. oper2 = getreg16 (reg);
  1063. op_add16();
  1064. writerm16 (rm, res16);
  1065. break;
  1066. case 0x2: /* 02 ADD Gb Eb */
  1067. modregrm();
  1068. oper1b = getreg8 (reg);
  1069. oper2b = readrm8 (rm);
  1070. op_add8();
  1071. putreg8 (reg, res8);
  1072. break;
  1073. case 0x3: /* 03 ADD Gv Ev */
  1074. modregrm();
  1075. oper1 = getreg16 (reg);
  1076. oper2 = readrm16 (rm);
  1077. op_add16();
  1078. putreg16 (reg, res16);
  1079. break;
  1080. case 0x4: /* 04 ADD regs.byteregs[regal] Ib */
  1081. oper1b = regs.byteregs[regal];
  1082. oper2b = getmem8 (segregs[regcs], ip);
  1083. StepIP (1);
  1084. op_add8();
  1085. regs.byteregs[regal] = res8;
  1086. break;
  1087. case 0x5: /* 05 ADD eAX Iv */
  1088. oper1 = regs.wordregs[regax];
  1089. oper2 = getmem16 (segregs[regcs], ip);
  1090. StepIP (2);
  1091. op_add16();
  1092. regs.wordregs[regax] = res16;
  1093. break;
  1094. case 0x6: /* 06 PUSH segregs[reges] */
  1095. push (segregs[reges]);
  1096. break;
  1097. case 0x7: /* 07 POP segregs[reges] */
  1098. segregs[reges] = pop();
  1099. break;
  1100. case 0x8: /* 08 OR Eb Gb */
  1101. modregrm();
  1102. oper1b = readrm8 (rm);
  1103. oper2b = getreg8 (reg);
  1104. op_or8();
  1105. writerm8 (rm, res8);
  1106. break;
  1107. case 0x9: /* 09 OR Ev Gv */
  1108. modregrm();
  1109. oper1 = readrm16 (rm);
  1110. oper2 = getreg16 (reg);
  1111. op_or16();
  1112. writerm16 (rm, res16);
  1113. break;
  1114. case 0xA: /* 0A OR Gb Eb */
  1115. modregrm();
  1116. oper1b = getreg8 (reg);
  1117. oper2b = readrm8 (rm);
  1118. op_or8();
  1119. putreg8 (reg, res8);
  1120. break;
  1121. case 0xB: /* 0B OR Gv Ev */
  1122. modregrm();
  1123. oper1 = getreg16 (reg);
  1124. oper2 = readrm16 (rm);
  1125. op_or16();
  1126. putreg16 (reg, res16);
  1127. break;
  1128. case 0xC: /* 0C OR regs.byteregs[regal] Ib */
  1129. oper1b = regs.byteregs[regal];
  1130. oper2b = getmem8 (segregs[regcs], ip);
  1131. StepIP (1);
  1132. op_or8();
  1133. regs.byteregs[regal] = res8;
  1134. break;
  1135. case 0xD: /* 0D OR eAX Iv */
  1136. oper1 = regs.wordregs[regax];
  1137. oper2 = getmem16 (segregs[regcs], ip);
  1138. StepIP (2);
  1139. op_or16();
  1140. regs.wordregs[regax] = res16;
  1141. break;
  1142. case 0xE: /* 0E PUSH segregs[regcs] */
  1143. push (segregs[regcs]);
  1144. break;
  1145. case 0x10: /* 10 ADC Eb Gb */
  1146. modregrm();
  1147. oper1b = readrm8 (rm);
  1148. oper2b = getreg8 (reg);
  1149. op_adc8();
  1150. writerm8 (rm, res8);
  1151. break;
  1152. case 0x11: /* 11 ADC Ev Gv */
  1153. modregrm();
  1154. oper1 = readrm16 (rm);
  1155. oper2 = getreg16 (reg);
  1156. op_adc16();
  1157. writerm16 (rm, res16);
  1158. break;
  1159. case 0x12: /* 12 ADC Gb Eb */
  1160. modregrm();
  1161. oper1b = getreg8 (reg);
  1162. oper2b = readrm8 (rm);
  1163. op_adc8();
  1164. putreg8 (reg, res8);
  1165. break;
  1166. case 0x13: /* 13 ADC Gv Ev */
  1167. modregrm();
  1168. oper1 = getreg16 (reg);
  1169. oper2 = readrm16 (rm);
  1170. op_adc16();
  1171. putreg16 (reg, res16);
  1172. break;
  1173. case 0x14: /* 14 ADC regs.byteregs[regal] Ib */
  1174. oper1b = regs.byteregs[regal];
  1175. oper2b = getmem8 (segregs[regcs], ip);
  1176. StepIP (1);
  1177. op_adc8();
  1178. regs.byteregs[regal] = res8;
  1179. break;
  1180. case 0x15: /* 15 ADC eAX Iv */
  1181. oper1 = regs.wordregs[regax];
  1182. oper2 = getmem16 (segregs[regcs], ip);
  1183. StepIP (2);
  1184. op_adc16();
  1185. regs.wordregs[regax] = res16;
  1186. break;
  1187. case 0x16: /* 16 PUSH segregs[regss] */
  1188. push (segregs[regss]);
  1189. break;
  1190. case 0x17: /* 17 POP segregs[regss] */
  1191. segregs[regss] = pop();
  1192. break;
  1193. case 0x18: /* 18 SBB Eb Gb */
  1194. modregrm();
  1195. oper1b = readrm8 (rm);
  1196. oper2b = getreg8 (reg);
  1197. op_sbb8();
  1198. writerm8 (rm, res8);
  1199. break;
  1200. case 0x19: /* 19 SBB Ev Gv */
  1201. modregrm();
  1202. oper1 = readrm16 (rm);
  1203. oper2 = getreg16 (reg);
  1204. op_sbb16();
  1205. writerm16 (rm, res16);
  1206. break;
  1207. case 0x1A: /* 1A SBB Gb Eb */
  1208. modregrm();
  1209. oper1b = getreg8 (reg);
  1210. oper2b = readrm8 (rm);
  1211. op_sbb8();
  1212. putreg8 (reg, res8);
  1213. break;
  1214. case 0x1B: /* 1B SBB Gv Ev */
  1215. modregrm();
  1216. oper1 = getreg16 (reg);
  1217. oper2 = readrm16 (rm);
  1218. op_sbb16();
  1219. putreg16 (reg, res16);
  1220. break;
  1221. case 0x1C: /* 1C SBB regs.byteregs[regal] Ib */
  1222. oper1b = regs.byteregs[regal];
  1223. oper2b = getmem8 (segregs[regcs], ip);
  1224. StepIP (1);
  1225. op_sbb8();
  1226. regs.byteregs[regal] = res8;
  1227. break;
  1228. case 0x1D: /* 1D SBB eAX Iv */
  1229. oper1 = regs.wordregs[regax];
  1230. oper2 = getmem16 (segregs[regcs], ip);
  1231. StepIP (2);
  1232. op_sbb16();
  1233. regs.wordregs[regax] = res16;
  1234. break;
  1235. case 0x1E: /* 1E PUSH segregs[regds] */
  1236. push (segregs[regds]);
  1237. break;
  1238. case 0x1F: /* 1F POP segregs[regds] */
  1239. segregs[regds] = pop();
  1240. break;
  1241. case 0x20: /* 20 AND Eb Gb */
  1242. modregrm();
  1243. oper1b = readrm8 (rm);
  1244. oper2b = getreg8 (reg);
  1245. op_and8();
  1246. writerm8 (rm, res8);
  1247. break;
  1248. case 0x21: /* 21 AND Ev Gv */
  1249. modregrm();
  1250. oper1 = readrm16 (rm);
  1251. oper2 = getreg16 (reg);
  1252. op_and16();
  1253. writerm16 (rm, res16);
  1254. break;
  1255. case 0x22: /* 22 AND Gb Eb */
  1256. modregrm();
  1257. oper1b = getreg8 (reg);
  1258. oper2b = readrm8 (rm);
  1259. op_and8();
  1260. putreg8 (reg, res8);
  1261. break;
  1262. case 0x23: /* 23 AND Gv Ev */
  1263. modregrm();
  1264. oper1 = getreg16 (reg);
  1265. oper2 = readrm16 (rm);
  1266. op_and16();
  1267. putreg16 (reg, res16);
  1268. break;
  1269. case 0x24: /* 24 AND regs.byteregs[regal] Ib */
  1270. oper1b = regs.byteregs[regal];
  1271. oper2b = getmem8 (segregs[regcs], ip);
  1272. StepIP (1);
  1273. op_and8();
  1274. regs.byteregs[regal] = res8;
  1275. break;
  1276. case 0x25: /* 25 AND eAX Iv */
  1277. oper1 = regs.wordregs[regax];
  1278. oper2 = getmem16 (segregs[regcs], ip);
  1279. StepIP (2);
  1280. op_and16();
  1281. regs.wordregs[regax] = res16;
  1282. break;
  1283. case 0x27: /* 27 DAA */
  1284. if ( ( (regs.byteregs[regal] & 0xF) > 9) || (af == 1) ) {
  1285. oper1 = regs.byteregs[regal] + 6;
  1286. regs.byteregs[regal] = oper1 & 255;
  1287. if (oper1 & 0xFF00) {
  1288. cf = 1;
  1289. }
  1290. else {
  1291. cf = 0;
  1292. }
  1293. af = 1;
  1294. }
  1295. else {
  1296. //af = 0;
  1297. }
  1298. if ( (regs.byteregs[regal] > 0x9F) || (cf == 1) ) {
  1299. regs.byteregs[regal] = regs.byteregs[regal] + 0x60;
  1300. cf = 1;
  1301. }
  1302. else {
  1303. //cf = 0;
  1304. }
  1305. regs.byteregs[regal] = regs.byteregs[regal] & 255;
  1306. flag_szp8 (regs.byteregs[regal]);
  1307. break;
  1308. case 0x28: /* 28 SUB Eb Gb */
  1309. modregrm();
  1310. oper1b = readrm8 (rm);
  1311. oper2b = getreg8 (reg);
  1312. op_sub8();
  1313. writerm8 (rm, res8);
  1314. break;
  1315. case 0x29: /* 29 SUB Ev Gv */
  1316. modregrm();
  1317. oper1 = readrm16 (rm);
  1318. oper2 = getreg16 (reg);
  1319. op_sub16();
  1320. writerm16 (rm, res16);
  1321. break;
  1322. case 0x2A: /* 2A SUB Gb Eb */
  1323. modregrm();
  1324. oper1b = getreg8 (reg);
  1325. oper2b = readrm8 (rm);
  1326. op_sub8();
  1327. putreg8 (reg, res8);
  1328. break;
  1329. case 0x2B: /* 2B SUB Gv Ev */
  1330. modregrm();
  1331. oper1 = getreg16 (reg);
  1332. oper2 = readrm16 (rm);
  1333. op_sub16();
  1334. putreg16 (reg, res16);
  1335. break;
  1336. case 0x2C: /* 2C SUB regs.byteregs[regal] Ib */
  1337. oper1b = regs.byteregs[regal];
  1338. oper2b = getmem8 (segregs[regcs], ip);
  1339. StepIP (1);
  1340. op_sub8();
  1341. regs.byteregs[regal] = res8;
  1342. break;
  1343. case 0x2D: /* 2D SUB eAX Iv */
  1344. oper1 = regs.wordregs[regax];
  1345. oper2 = getmem16 (segregs[regcs], ip);
  1346. StepIP (2);
  1347. op_sub16();
  1348. regs.wordregs[regax] = res16;
  1349. break;
  1350. case 0x2F: /* 2F DAS */
  1351. if ( ( (regs.byteregs[regal] & 15) > 9) || (af == 1) ) {
  1352. oper1 = regs.byteregs[regal] - 6;
  1353. regs.byteregs[regal] = oper1 & 255;
  1354. if (oper1 & 0xFF00) {
  1355. cf = 1;
  1356. }
  1357. else {
  1358. cf = 0;
  1359. }
  1360. af = 1;
  1361. }
  1362. else {
  1363. af = 0;
  1364. }
  1365. if ( ( (regs.byteregs[regal] & 0xF0) > 0x90) || (cf == 1) ) {
  1366. regs.byteregs[regal] = regs.byteregs[regal] - 0x60;
  1367. cf = 1;
  1368. }
  1369. else {
  1370. cf = 0;
  1371. }
  1372. flag_szp8 (regs.byteregs[regal]);
  1373. break;
  1374. case 0x30: /* 30 XOR Eb Gb */
  1375. modregrm();
  1376. oper1b = readrm8 (rm);
  1377. oper2b = getreg8 (reg);
  1378. op_xor8();
  1379. writerm8 (rm, res8);
  1380. break;
  1381. case 0x31: /* 31 XOR Ev Gv */
  1382. modregrm();
  1383. oper1 = readrm16 (rm);
  1384. oper2 = getreg16 (reg);
  1385. op_xor16();
  1386. writerm16 (rm, res16);
  1387. break;
  1388. case 0x32: /* 32 XOR Gb Eb */
  1389. modregrm();
  1390. oper1b = getreg8 (reg);
  1391. oper2b = readrm8 (rm);
  1392. op_xor8();
  1393. putreg8 (reg, res8);
  1394. break;
  1395. case 0x33: /* 33 XOR Gv Ev */
  1396. modregrm();
  1397. oper1 = getreg16 (reg);
  1398. oper2 = readrm16 (rm);
  1399. op_xor16();
  1400. putreg16 (reg, res16);
  1401. break;
  1402. case 0x34: /* 34 XOR regs.byteregs[regal] Ib */
  1403. oper1b = regs.byteregs[regal];
  1404. oper2b = getmem8 (segregs[regcs], ip);
  1405. StepIP (1);
  1406. op_xor8();
  1407. regs.byteregs[regal] = res8;
  1408. break;
  1409. case 0x35: /* 35 XOR eAX Iv */
  1410. oper1 = regs.wordregs[regax];
  1411. oper2 = getmem16 (segregs[regcs], ip);
  1412. StepIP (2);
  1413. op_xor16();
  1414. regs.wordregs[regax] = res16;
  1415. break;
  1416. case 0x37: /* 37 AAA ASCII */
  1417. if ( ( (regs.byteregs[regal] & 0xF) > 9) || (af == 1) ) {
  1418. regs.byteregs[regal] = regs.byteregs[regal] + 6;
  1419. regs.byteregs[regah] = regs.byteregs[regah] + 1;
  1420. af = 1;
  1421. cf = 1;
  1422. }
  1423. else {
  1424. af = 0;
  1425. cf = 0;
  1426. }
  1427. regs.byteregs[regal] = regs.byteregs[regal] & 0xF;
  1428. break;
  1429. case 0x38: /* 38 CMP Eb Gb */
  1430. modregrm();
  1431. oper1b = readrm8 (rm);
  1432. oper2b = getreg8 (reg);
  1433. flag_sub8 (oper1b, oper2b);
  1434. break;
  1435. case 0x39: /* 39 CMP Ev Gv */
  1436. modregrm();
  1437. oper1 = readrm16 (rm);
  1438. oper2 = getreg16 (reg);
  1439. flag_sub16 (oper1, oper2);
  1440. break;
  1441. case 0x3A: /* 3A CMP Gb Eb */
  1442. modregrm();
  1443. oper1b = getreg8 (reg);
  1444. oper2b = readrm8 (rm);
  1445. flag_sub8 (oper1b, oper2b);
  1446. break;
  1447. case 0x3B: /* 3B CMP Gv Ev */
  1448. modregrm();
  1449. oper1 = getreg16 (reg);
  1450. oper2 = readrm16 (rm);
  1451. flag_sub16 (oper1, oper2);
  1452. break;
  1453. case 0x3C: /* 3C CMP regs.byteregs[regal] Ib */
  1454. oper1b = regs.byteregs[regal];
  1455. oper2b = getmem8 (segregs[regcs], ip);
  1456. StepIP (1);
  1457. flag_sub8 (oper1b, oper2b);
  1458. break;
  1459. case 0x3D: /* 3D CMP eAX Iv */
  1460. oper1 = regs.wordregs[regax];
  1461. oper2 = getmem16 (segregs[regcs], ip);
  1462. StepIP (2);
  1463. flag_sub16 (oper1, oper2);
  1464. break;
  1465. case 0x3F: /* 3F AAS ASCII */
  1466. if ( ( (regs.byteregs[regal] & 0xF) > 9) || (af == 1) ) {
  1467. regs.byteregs[regal] = regs.byteregs[regal] - 6;
  1468. regs.byteregs[regah] = regs.byteregs[regah] - 1;
  1469. af = 1;
  1470. cf = 1;
  1471. }
  1472. else {
  1473. af = 0;
  1474. cf = 0;
  1475. }
  1476. regs.byteregs[regal] = regs.byteregs[regal] & 0xF;
  1477. break;
  1478. case 0x40: /* 40 INC eAX */
  1479. oldcf = cf;
  1480. oper1 = regs.wordregs[regax];
  1481. oper2 = 1;
  1482. op_add16();
  1483. cf = oldcf;
  1484. regs.wordregs[regax] = res16;
  1485. break;
  1486. case 0x41: /* 41 INC eCX */
  1487. oldcf = cf;
  1488. oper1 = regs.wordregs[regcx];
  1489. oper2 = 1;
  1490. op_add16();
  1491. cf = oldcf;
  1492. regs.wordregs[regcx] = res16;
  1493. break;
  1494. case 0x42: /* 42 INC eDX */
  1495. oldcf = cf;
  1496. oper1 = regs.wordregs[regdx];
  1497. oper2 = 1;
  1498. op_add16();
  1499. cf = oldcf;
  1500. regs.wordregs[regdx] = res16;
  1501. break;
  1502. case 0x43: /* 43 INC eBX */
  1503. oldcf = cf;
  1504. oper1 = regs.wordregs[regbx];
  1505. oper2 = 1;
  1506. op_add16();
  1507. cf = oldcf;
  1508. regs.wordregs[regbx] = res16;
  1509. break;
  1510. case 0x44: /* 44 INC eSP */
  1511. oldcf = cf;
  1512. oper1 = regs.wordregs[regsp];
  1513. oper2 = 1;
  1514. op_add16();
  1515. cf = oldcf;
  1516. regs.wordregs[regsp] = res16;
  1517. break;
  1518. case 0x45: /* 45 INC eBP */
  1519. oldcf = cf;
  1520. oper1 = regs.wordregs[regbp];
  1521. oper2 = 1;
  1522. op_add16();
  1523. cf = oldcf;
  1524. regs.wordregs[regbp] = res16;
  1525. break;
  1526. case 0x46: /* 46 INC eSI */
  1527. oldcf = cf;
  1528. oper1 = regs.wordregs[regsi];
  1529. oper2 = 1;
  1530. op_add16();
  1531. cf = oldcf;
  1532. regs.wordregs[regsi] = res16;
  1533. break;
  1534. case 0x47: /* 47 INC eDI */
  1535. oldcf = cf;
  1536. oper1 = regs.wordregs[regdi];
  1537. oper2 = 1;
  1538. op_add16();
  1539. cf = oldcf;
  1540. regs.wordregs[regdi] = res16;
  1541. break;
  1542. case 0x48: /* 48 DEC eAX */
  1543. oldcf = cf;
  1544. oper1 = regs.wordregs[regax];
  1545. oper2 = 1;
  1546. op_sub16();
  1547. cf = oldcf;
  1548. regs.wordregs[regax] = res16;
  1549. break;
  1550. case 0x49: /* 49 DEC eCX */
  1551. oldcf = cf;
  1552. oper1 = regs.wordregs[regcx];
  1553. oper2 = 1;
  1554. op_sub16();
  1555. cf = oldcf;
  1556. regs.wordregs[regcx] = res16;
  1557. break;
  1558. case 0x4A: /* 4A DEC eDX */
  1559. oldcf = cf;
  1560. oper1 = regs.wordregs[regdx];
  1561. oper2 = 1;
  1562. op_sub16();
  1563. cf = oldcf;
  1564. regs.wordregs[regdx] = res16;
  1565. break;
  1566. case 0x4B: /* 4B DEC eBX */
  1567. oldcf = cf;
  1568. oper1 = regs.wordregs[regbx];
  1569. oper2 = 1;
  1570. op_sub16();
  1571. cf = oldcf;
  1572. regs.wordregs[regbx] = res16;
  1573. break;
  1574. case 0x4C: /* 4C DEC eSP */
  1575. oldcf = cf;
  1576. oper1 = regs.wordregs[regsp];
  1577. oper2 = 1;
  1578. op_sub16();
  1579. cf = oldcf;
  1580. regs.wordregs[regsp] = res16;
  1581. break;
  1582. case 0x4D: /* 4D DEC eBP */
  1583. oldcf = cf;
  1584. oper1 = regs.wordregs[regbp];
  1585. oper2 = 1;
  1586. op_sub16();
  1587. cf = oldcf;
  1588. regs.wordregs[regbp] = res16;
  1589. break;
  1590. case 0x4E: /* 4E DEC eSI */
  1591. oldcf = cf;
  1592. oper1 = regs.wordregs[regsi];
  1593. oper2 = 1;
  1594. op_sub16();
  1595. cf = oldcf;
  1596. regs.wordregs[regsi] = res16;
  1597. break;
  1598. case 0x4F: /* 4F DEC eDI */
  1599. oldcf = cf;
  1600. oper1 = regs.wordregs[regdi];
  1601. oper2 = 1;
  1602. op_sub16();
  1603. cf = oldcf;
  1604. regs.wordregs[regdi] = res16;
  1605. break;
  1606. case 0x50: /* 50 PUSH eAX */
  1607. push (regs.wordregs[regax]);
  1608. break;
  1609. case 0x51: /* 51 PUSH eCX */
  1610. push (regs.wordregs[regcx]);
  1611. break;
  1612. case 0x52: /* 52 PUSH eDX */
  1613. push (regs.wordregs[regdx]);
  1614. break;
  1615. case 0x53: /* 53 PUSH eBX */
  1616. push (regs.wordregs[regbx]);
  1617. break;
  1618. case 0x54: /* 54 PUSH eSP */
  1619. #ifdef USE_286_STYLE_PUSH_SP
  1620. push (regs.wordregs[regsp]);
  1621. #else
  1622. push (regs.wordregs[regsp] - 2);
  1623. #endif
  1624. break;
  1625. case 0x55: /* 55 PUSH eBP */
  1626. push (regs.wordregs[regbp]);
  1627. break;
  1628. case 0x56: /* 56 PUSH eSI */
  1629. push (regs.wordregs[regsi]);
  1630. break;
  1631. case 0x57: /* 57 PUSH eDI */
  1632. push (regs.wordregs[regdi]);
  1633. break;
  1634. case 0x58: /* 58 POP eAX */
  1635. regs.wordregs[regax] = pop();
  1636. break;
  1637. case 0x59: /* 59 POP eCX */
  1638. regs.wordregs[regcx] = pop();
  1639. break;
  1640. case 0x5A: /* 5A POP eDX */
  1641. regs.wordregs[regdx] = pop();
  1642. break;
  1643. case 0x5B: /* 5B POP eBX */
  1644. regs.wordregs[regbx] = pop();
  1645. break;
  1646. case 0x5C: /* 5C POP eSP */
  1647. regs.wordregs[regsp] = pop();
  1648. break;
  1649. case 0x5D: /* 5D POP eBP */
  1650. regs.wordregs[regbp] = pop();
  1651. break;
  1652. case 0x5E: /* 5E POP eSI */
  1653. regs.wordregs[regsi] = pop();
  1654. break;
  1655. case 0x5F: /* 5F POP eDI */
  1656. regs.wordregs[regdi] = pop();
  1657. break;
  1658. #ifndef CPU_8086
  1659. case 0x60: /* 60 PUSHA (80186+) */
  1660. oldsp = regs.wordregs[regsp];
  1661. push (regs.wordregs[regax]);
  1662. push (regs.wordregs[regcx]);
  1663. push (regs.wordregs[regdx]);
  1664. push (regs.wordregs[regbx]);
  1665. push (oldsp);
  1666. push (regs.wordregs[regbp]);
  1667. push (regs.wordregs[regsi]);
  1668. push (regs.wordregs[regdi]);
  1669. break;
  1670. case 0x61: /* 61 POPA (80186+) */
  1671. regs.wordregs[regdi] = pop();
  1672. regs.wordregs[regsi] = pop();
  1673. regs.wordregs[regbp] = pop();
  1674. dummy = pop();
  1675. regs.wordregs[regbx] = pop();
  1676. regs.wordregs[regdx] = pop();
  1677. regs.wordregs[regcx] = pop();
  1678. regs.wordregs[regax] = pop();
  1679. break;
  1680. case 0x62: /* 62 BOUND Gv, Ev (80186+) */
  1681. modregrm();
  1682. getea (rm);
  1683. if (signext32 (getreg16 (reg) ) < signext32 ( getmem16 (ea >> 4, ea & 15) ) ) {
  1684. intcall86 (5); //bounds check exception
  1685. }
  1686. else {
  1687. ea += 2;
  1688. if (signext32 (getreg16 (reg) ) > signext32 ( getmem16 (ea >> 4, ea & 15) ) ) {
  1689. intcall86(5); //bounds check exception
  1690. }
  1691. }
  1692. break;
  1693. case 0x68: /* 68 PUSH Iv (80186+) */
  1694. push (getmem16 (segregs[regcs], ip) );
  1695. StepIP (2);
  1696. break;
  1697. case 0x69: /* 69 IMUL Gv Ev Iv (80186+) */
  1698. modregrm();
  1699. temp1 = readrm16 (rm);
  1700. temp2 = getmem16 (segregs[regcs], ip);
  1701. StepIP (2);
  1702. if ( (temp1 & 0x8000L) == 0x8000L) {
  1703. temp1 = temp1 | 0xFFFF0000L;
  1704. }
  1705. if ( (temp2 & 0x8000L) == 0x8000L) {
  1706. temp2 = temp2 | 0xFFFF0000L;
  1707. }
  1708. temp3 = temp1 * temp2;
  1709. putreg16 (reg, temp3 & 0xFFFFL);
  1710. if (temp3 & 0xFFFF0000L) {
  1711. cf = 1;
  1712. of = 1;
  1713. }
  1714. else {
  1715. cf = 0;
  1716. of = 0;
  1717. }
  1718. break;
  1719. case 0x6A: /* 6A PUSH Ib (80186+) */
  1720. push (getmem8 (segregs[regcs], ip) );
  1721. StepIP (1);
  1722. break;
  1723. case 0x6B: /* 6B IMUL Gv Eb Ib (80186+) */
  1724. modregrm();
  1725. temp1 = readrm16 (rm);
  1726. temp2 = signext (getmem8 (segregs[regcs], ip) );
  1727. StepIP (1);
  1728. if ( (temp1 & 0x8000L) == 0x8000L) {
  1729. temp1 = temp1 | 0xFFFF0000L;
  1730. }
  1731. if ( (temp2 & 0x8000L) == 0x8000L) {
  1732. temp2 = temp2 | 0xFFFF0000L;
  1733. }
  1734. temp3 = temp1 * temp2;
  1735. putreg16 (reg, temp3 & 0xFFFFL);
  1736. if (temp3 & 0xFFFF0000L) {
  1737. cf = 1;
  1738. of = 1;
  1739. }
  1740. else {
  1741. cf = 0;
  1742. of = 0;
  1743. }
  1744. break;
  1745. case 0x6C: /* 6E INSB */
  1746. if (reptype && (regs.wordregs[regcx] == 0) ) {
  1747. break;
  1748. }
  1749. putmem8 (useseg, regs.wordregs[regsi], portin (regs.wordregs[regdx]) );
  1750. if (df) {
  1751. regs.wordregs[regsi] = regs.wordregs[regsi] - 1;
  1752. regs.wordregs[regdi] = regs.wordregs[regdi] - 1;
  1753. }
  1754. else {
  1755. regs.wordregs[regsi] = regs.wordregs[regsi] + 1;
  1756. regs.wordregs[regdi] = regs.wordregs[regdi] + 1;
  1757. }
  1758. if (reptype) {
  1759. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  1760. }
  1761. totalexec++;
  1762. loopcount++;
  1763. if (!reptype) {
  1764. break;
  1765. }
  1766. ip = firstip;
  1767. break;
  1768. case 0x6D: /* 6F INSW */
  1769. if (reptype && (regs.wordregs[regcx] == 0) ) {
  1770. break;
  1771. }
  1772. putmem16 (useseg, regs.wordregs[regsi], portin16 (regs.wordregs[regdx]) );
  1773. if (df) {
  1774. regs.wordregs[regsi] = regs.wordregs[regsi] - 2;
  1775. regs.wordregs[regdi] = regs.wordregs[regdi] - 2;
  1776. }
  1777. else {
  1778. regs.wordregs[regsi] = regs.wordregs[regsi] + 2;
  1779. regs.wordregs[regdi] = regs.wordregs[regdi] + 2;
  1780. }
  1781. if (reptype) {
  1782. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  1783. }
  1784. totalexec++;
  1785. loopcount++;
  1786. if (!reptype) {
  1787. break;
  1788. }
  1789. ip = firstip;
  1790. break;
  1791. case 0x6E: /* 6E OUTSB */
  1792. if (reptype && (regs.wordregs[regcx] == 0) ) {
  1793. break;
  1794. }
  1795. portout (regs.wordregs[regdx], getmem8 (useseg, regs.wordregs[regsi]) );
  1796. if (df) {
  1797. regs.wordregs[regsi] = regs.wordregs[regsi] - 1;
  1798. regs.wordregs[regdi] = regs.wordregs[regdi] - 1;
  1799. }
  1800. else {
  1801. regs.wordregs[regsi] = regs.wordregs[regsi] + 1;
  1802. regs.wordregs[regdi] = regs.wordregs[regdi] + 1;
  1803. }
  1804. if (reptype) {
  1805. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  1806. }
  1807. totalexec++;
  1808. loopcount++;
  1809. if (!reptype) {
  1810. break;
  1811. }
  1812. ip = firstip;
  1813. break;
  1814. case 0x6F: /* 6F OUTSW */
  1815. if (reptype && (regs.wordregs[regcx] == 0) ) {
  1816. break;
  1817. }
  1818. portout16 (regs.wordregs[regdx], getmem16 (useseg, regs.wordregs[regsi]) );
  1819. if (df) {
  1820. regs.wordregs[regsi] = regs.wordregs[regsi] - 2;
  1821. regs.wordregs[regdi] = regs.wordregs[regdi] - 2;
  1822. }
  1823. else {
  1824. regs.wordregs[regsi] = regs.wordregs[regsi] + 2;
  1825. regs.wordregs[regdi] = regs.wordregs[regdi] + 2;
  1826. }
  1827. if (reptype) {
  1828. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  1829. }
  1830. totalexec++;
  1831. loopcount++;
  1832. if (!reptype) {
  1833. break;
  1834. }
  1835. ip = firstip;
  1836. break;
  1837. #endif
  1838. case 0x70: /* 70 JO Jb */
  1839. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1840. StepIP (1);
  1841. if (of) {
  1842. ip = ip + temp16;
  1843. }
  1844. break;
  1845. case 0x71: /* 71 JNO Jb */
  1846. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1847. StepIP (1);
  1848. if (!of) {
  1849. ip = ip + temp16;
  1850. }
  1851. break;
  1852. case 0x72: /* 72 JB Jb */
  1853. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1854. StepIP (1);
  1855. if (cf) {
  1856. ip = ip + temp16;
  1857. }
  1858. break;
  1859. case 0x73: /* 73 JNB Jb */
  1860. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1861. StepIP (1);
  1862. if (!cf) {
  1863. ip = ip + temp16;
  1864. }
  1865. break;
  1866. case 0x74: /* 74 JZ Jb */
  1867. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1868. StepIP (1);
  1869. if (zf) {
  1870. ip = ip + temp16;
  1871. }
  1872. break;
  1873. case 0x75: /* 75 JNZ Jb */
  1874. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1875. StepIP (1);
  1876. if (!zf) {
  1877. ip = ip + temp16;
  1878. }
  1879. break;
  1880. case 0x76: /* 76 JBE Jb */
  1881. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1882. StepIP (1);
  1883. if (cf || zf) {
  1884. ip = ip + temp16;
  1885. }
  1886. break;
  1887. case 0x77: /* 77 JA Jb */
  1888. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1889. StepIP (1);
  1890. if (!cf && !zf) {
  1891. ip = ip + temp16;
  1892. }
  1893. break;
  1894. case 0x78: /* 78 JS Jb */
  1895. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1896. StepIP (1);
  1897. if (sf) {
  1898. ip = ip + temp16;
  1899. }
  1900. break;
  1901. case 0x79: /* 79 JNS Jb */
  1902. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1903. StepIP (1);
  1904. if (!sf) {
  1905. ip = ip + temp16;
  1906. }
  1907. break;
  1908. case 0x7A: /* 7A JPE Jb */
  1909. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1910. StepIP (1);
  1911. if (pf) {
  1912. ip = ip + temp16;
  1913. }
  1914. break;
  1915. case 0x7B: /* 7B JPO Jb */
  1916. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1917. StepIP (1);
  1918. if (!pf) {
  1919. ip = ip + temp16;
  1920. }
  1921. break;
  1922. case 0x7C: /* 7C JL Jb */
  1923. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1924. StepIP (1);
  1925. if (sf != of) {
  1926. ip = ip + temp16;
  1927. }
  1928. break;
  1929. case 0x7D: /* 7D JGE Jb */
  1930. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1931. StepIP (1);
  1932. if (sf == of) {
  1933. ip = ip + temp16;
  1934. }
  1935. break;
  1936. case 0x7E: /* 7E JLE Jb */
  1937. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1938. StepIP (1);
  1939. if ( (sf != of) || zf) {
  1940. ip = ip + temp16;
  1941. }
  1942. break;
  1943. case 0x7F: /* 7F JG Jb */
  1944. temp16 = signext (getmem8 (segregs[regcs], ip) );
  1945. StepIP (1);
  1946. if (!zf && (sf == of) ) {
  1947. ip = ip + temp16;
  1948. }
  1949. break;
  1950. case 0x80:
  1951. case 0x82: /* 80/82 GRP1 Eb Ib */
  1952. modregrm();
  1953. oper1b = readrm8 (rm);
  1954. oper2b = getmem8 (segregs[regcs], ip);
  1955. StepIP (1);
  1956. switch (reg) {
  1957. case 0:
  1958. op_add8();
  1959. break;
  1960. case 1:
  1961. op_or8();
  1962. break;
  1963. case 2:
  1964. op_adc8();
  1965. break;
  1966. case 3:
  1967. op_sbb8();
  1968. break;
  1969. case 4:
  1970. op_and8();
  1971. break;
  1972. case 5:
  1973. op_sub8();
  1974. break;
  1975. case 6:
  1976. op_xor8();
  1977. break;
  1978. case 7:
  1979. flag_sub8 (oper1b, oper2b);
  1980. break;
  1981. default:
  1982. break; /* to avoid compiler warnings */
  1983. }
  1984. if (reg < 7) {
  1985. writerm8 (rm, res8);
  1986. }
  1987. break;
  1988. case 0x81: /* 81 GRP1 Ev Iv */
  1989. case 0x83: /* 83 GRP1 Ev Ib */
  1990. modregrm();
  1991. oper1 = readrm16 (rm);
  1992. if (opcode == 0x81) {
  1993. oper2 = getmem16 (segregs[regcs], ip);
  1994. StepIP (2);
  1995. }
  1996. else {
  1997. oper2 = signext (getmem8 (segregs[regcs], ip) );
  1998. StepIP (1);
  1999. }
  2000. switch (reg) {
  2001. case 0:
  2002. op_add16();
  2003. break;
  2004. case 1:
  2005. op_or16();
  2006. break;
  2007. case 2:
  2008. op_adc16();
  2009. break;
  2010. case 3:
  2011. op_sbb16();
  2012. break;
  2013. case 4:
  2014. op_and16();
  2015. break;
  2016. case 5:
  2017. op_sub16();
  2018. break;
  2019. case 6:
  2020. op_xor16();
  2021. break;
  2022. case 7:
  2023. flag_sub16 (oper1, oper2);
  2024. break;
  2025. default:
  2026. break; /* to avoid compiler warnings */
  2027. }
  2028. if (reg < 7) {
  2029. writerm16 (rm, res16);
  2030. }
  2031. break;
  2032. case 0x84: /* 84 TEST Gb Eb */
  2033. modregrm();
  2034. oper1b = getreg8 (reg);
  2035. oper2b = readrm8 (rm);
  2036. flag_log8 (oper1b & oper2b);
  2037. break;
  2038. case 0x85: /* 85 TEST Gv Ev */
  2039. modregrm();
  2040. oper1 = getreg16 (reg);
  2041. oper2 = readrm16 (rm);
  2042. flag_log16 (oper1 & oper2);
  2043. break;
  2044. case 0x86: /* 86 XCHG Gb Eb */
  2045. modregrm();
  2046. oper1b = getreg8 (reg);
  2047. putreg8 (reg, readrm8 (rm) );
  2048. writerm8 (rm, oper1b);
  2049. break;
  2050. case 0x87: /* 87 XCHG Gv Ev */
  2051. modregrm();
  2052. oper1 = getreg16 (reg);
  2053. putreg16 (reg, readrm16 (rm) );
  2054. writerm16 (rm, oper1);
  2055. break;
  2056. case 0x88: /* 88 MOV Eb Gb */
  2057. modregrm();
  2058. writerm8 (rm, getreg8 (reg) );
  2059. break;
  2060. case 0x89: /* 89 MOV Ev Gv */
  2061. modregrm();
  2062. writerm16 (rm, getreg16 (reg) );
  2063. break;
  2064. case 0x8A: /* 8A MOV Gb Eb */
  2065. modregrm();
  2066. putreg8 (reg, readrm8 (rm) );
  2067. break;
  2068. case 0x8B: /* 8B MOV Gv Ev */
  2069. modregrm();
  2070. putreg16 (reg, readrm16 (rm) );
  2071. break;
  2072. case 0x8C: /* 8C MOV Ew Sw */
  2073. modregrm();
  2074. writerm16 (rm, getsegreg (reg) );
  2075. break;
  2076. case 0x8D: /* 8D LEA Gv M */
  2077. modregrm();
  2078. getea (rm);
  2079. putreg16 (reg, ea - segbase (useseg) );
  2080. break;
  2081. case 0x8E: /* 8E MOV Sw Ew */
  2082. modregrm();
  2083. putsegreg (reg, readrm16 (rm) );
  2084. break;
  2085. case 0x8F: /* 8F POP Ev */
  2086. modregrm();
  2087. writerm16 (rm, pop() );
  2088. break;
  2089. case 0x90: /* 90 NOP */
  2090. break;
  2091. case 0x91: /* 91 XCHG eCX eAX */
  2092. oper1 = regs.wordregs[regcx];
  2093. regs.wordregs[regcx] = regs.wordregs[regax];
  2094. regs.wordregs[regax] = oper1;
  2095. break;
  2096. case 0x92: /* 92 XCHG eDX eAX */
  2097. oper1 = regs.wordregs[regdx];
  2098. regs.wordregs[regdx] = regs.wordregs[regax];
  2099. regs.wordregs[regax] = oper1;
  2100. break;
  2101. case 0x93: /* 93 XCHG eBX eAX */
  2102. oper1 = regs.wordregs[regbx];
  2103. regs.wordregs[regbx] = regs.wordregs[regax];
  2104. regs.wordregs[regax] = oper1;
  2105. break;
  2106. case 0x94: /* 94 XCHG eSP eAX */
  2107. oper1 = regs.wordregs[regsp];
  2108. regs.wordregs[regsp] = regs.wordregs[regax];
  2109. regs.wordregs[regax] = oper1;
  2110. break;
  2111. case 0x95: /* 95 XCHG eBP eAX */
  2112. oper1 = regs.wordregs[regbp];
  2113. regs.wordregs[regbp] = regs.wordregs[regax];
  2114. regs.wordregs[regax] = oper1;
  2115. break;
  2116. case 0x96: /* 96 XCHG eSI eAX */
  2117. oper1 = regs.wordregs[regsi];
  2118. regs.wordregs[regsi] = regs.wordregs[regax];
  2119. regs.wordregs[regax] = oper1;
  2120. break;
  2121. case 0x97: /* 97 XCHG eDI eAX */
  2122. oper1 = regs.wordregs[regdi];
  2123. regs.wordregs[regdi] = regs.wordregs[regax];
  2124. regs.wordregs[regax] = oper1;
  2125. break;
  2126. case 0x98: /* 98 CBW */
  2127. if ( (regs.byteregs[regal] & 0x80) == 0x80) {
  2128. regs.byteregs[regah] = 0xFF;
  2129. }
  2130. else {
  2131. regs.byteregs[regah] = 0;
  2132. }
  2133. break;
  2134. case 0x99: /* 99 CWD */
  2135. if ( (regs.byteregs[regah] & 0x80) == 0x80) {
  2136. regs.wordregs[regdx] = 0xFFFF;
  2137. }
  2138. else {
  2139. regs.wordregs[regdx] = 0;
  2140. }
  2141. break;
  2142. case 0x9A: /* 9A CALL Ap */
  2143. oper1 = getmem16 (segregs[regcs], ip);
  2144. StepIP (2);
  2145. oper2 = getmem16 (segregs[regcs], ip);
  2146. StepIP (2);
  2147. push (segregs[regcs]);
  2148. push (ip);
  2149. ip = oper1;
  2150. segregs[regcs] = oper2;
  2151. break;
  2152. case 0x9B: /* 9B WAIT */
  2153. break;
  2154. case 0x9C: /* 9C PUSHF */
  2155. push (makeflagsword() | 0xF800);
  2156. break;
  2157. case 0x9D: /* 9D POPF */
  2158. temp16 = pop();
  2159. decodeflagsword (temp16);
  2160. break;
  2161. case 0x9E: /* 9E SAHF */
  2162. decodeflagsword ( (makeflagsword() & 0xFF00) | regs.byteregs[regah]);
  2163. break;
  2164. case 0x9F: /* 9F LAHF */
  2165. regs.byteregs[regah] = makeflagsword() & 0xFF;
  2166. break;
  2167. case 0xA0: /* A0 MOV regs.byteregs[regal] Ob */
  2168. regs.byteregs[regal] = getmem8 (useseg, getmem16 (segregs[regcs], ip) );
  2169. StepIP (2);
  2170. break;
  2171. case 0xA1: /* A1 MOV eAX Ov */
  2172. oper1 = getmem16 (useseg, getmem16 (segregs[regcs], ip) );
  2173. StepIP (2);
  2174. regs.wordregs[regax] = oper1;
  2175. break;
  2176. case 0xA2: /* A2 MOV Ob regs.byteregs[regal] */
  2177. putmem8 (useseg, getmem16 (segregs[regcs], ip), regs.byteregs[regal]);
  2178. StepIP (2);
  2179. break;
  2180. case 0xA3: /* A3 MOV Ov eAX */
  2181. putmem16 (useseg, getmem16 (segregs[regcs], ip), regs.wordregs[regax]);
  2182. StepIP (2);
  2183. break;
  2184. case 0xA4: /* A4 MOVSB */
  2185. if (reptype && (regs.wordregs[regcx] == 0) ) {
  2186. break;
  2187. }
  2188. putmem8 (segregs[reges], regs.wordregs[regdi], getmem8 (useseg, regs.wordregs[regsi]) );
  2189. if (df) {
  2190. regs.wordregs[regsi] = regs.wordregs[regsi] - 1;
  2191. regs.wordregs[regdi] = regs.wordregs[regdi] - 1;
  2192. }
  2193. else {
  2194. regs.wordregs[regsi] = regs.wordregs[regsi] + 1;
  2195. regs.wordregs[regdi] = regs.wordregs[regdi] + 1;
  2196. }
  2197. if (reptype) {
  2198. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  2199. }
  2200. totalexec++;
  2201. loopcount++;
  2202. if (!reptype) {
  2203. break;
  2204. }
  2205. ip = firstip;
  2206. break;
  2207. case 0xA5: /* A5 MOVSW */
  2208. if (reptype && (regs.wordregs[regcx] == 0) ) {
  2209. break;
  2210. }
  2211. putmem16 (segregs[reges], regs.wordregs[regdi], getmem16 (useseg, regs.wordregs[regsi]) );
  2212. if (df) {
  2213. regs.wordregs[regsi] = regs.wordregs[regsi] - 2;
  2214. regs.wordregs[regdi] = regs.wordregs[regdi] - 2;
  2215. }
  2216. else {
  2217. regs.wordregs[regsi] = regs.wordregs[regsi] + 2;
  2218. regs.wordregs[regdi] = regs.wordregs[regdi] + 2;
  2219. }
  2220. if (reptype) {
  2221. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  2222. }
  2223. totalexec++;
  2224. loopcount++;
  2225. if (!reptype) {
  2226. break;
  2227. }
  2228. ip = firstip;
  2229. break;
  2230. case 0xA6: /* A6 CMPSB */
  2231. if (reptype && (regs.wordregs[regcx] == 0) ) {
  2232. break;
  2233. }
  2234. oper1b = getmem8 (useseg, regs.wordregs[regsi]);
  2235. oper2b = getmem8 (segregs[reges], regs.wordregs[regdi]);
  2236. if (df) {
  2237. regs.wordregs[regsi] = regs.wordregs[regsi] - 1;
  2238. regs.wordregs[regdi] = regs.wordregs[regdi] - 1;
  2239. }
  2240. else {
  2241. regs.wordregs[regsi] = regs.wordregs[regsi] + 1;
  2242. regs.wordregs[regdi] = regs.wordregs[regdi] + 1;
  2243. }
  2244. flag_sub8 (oper1b, oper2b);
  2245. if (reptype) {
  2246. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  2247. }
  2248. if ( (reptype == 1) && !zf) {
  2249. break;
  2250. }
  2251. else if ( (reptype == 2) && (zf == 1) ) {
  2252. break;
  2253. }
  2254. totalexec++;
  2255. loopcount++;
  2256. if (!reptype) {
  2257. break;
  2258. }
  2259. ip = firstip;
  2260. break;
  2261. case 0xA7: /* A7 CMPSW */
  2262. if (reptype && (regs.wordregs[regcx] == 0) ) {
  2263. break;
  2264. }
  2265. oper1 = getmem16 (useseg,regs.wordregs[regsi]);
  2266. oper2 = getmem16 (segregs[reges], regs.wordregs[regdi]);
  2267. if (df) {
  2268. regs.wordregs[regsi] = regs.wordregs[regsi] - 2;
  2269. regs.wordregs[regdi] = regs.wordregs[regdi] - 2;
  2270. }
  2271. else {
  2272. regs.wordregs[regsi] = regs.wordregs[regsi] + 2;
  2273. regs.wordregs[regdi] = regs.wordregs[regdi] + 2;
  2274. }
  2275. flag_sub16 (oper1, oper2);
  2276. if (reptype) {
  2277. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  2278. }
  2279. if ( (reptype == 1) && !zf) {
  2280. break;
  2281. }
  2282. if ( (reptype == 2) && (zf == 1) ) {
  2283. break;
  2284. }
  2285. totalexec++;
  2286. loopcount++;
  2287. if (!reptype) {
  2288. break;
  2289. }
  2290. ip = firstip;
  2291. break;
  2292. case 0xA8: /* A8 TEST regs.byteregs[regal] Ib */
  2293. oper1b = regs.byteregs[regal];
  2294. oper2b = getmem8 (segregs[regcs], ip);
  2295. StepIP (1);
  2296. flag_log8 (oper1b & oper2b);
  2297. break;
  2298. case 0xA9: /* A9 TEST eAX Iv */
  2299. oper1 = regs.wordregs[regax];
  2300. oper2 = getmem16 (segregs[regcs], ip);
  2301. StepIP (2);
  2302. flag_log16 (oper1 & oper2);
  2303. break;
  2304. case 0xAA: /* AA STOSB */
  2305. if (reptype && (regs.wordregs[regcx] == 0) ) {
  2306. break;
  2307. }
  2308. putmem8 (segregs[reges], regs.wordregs[regdi], regs.byteregs[regal]);
  2309. if (df) {
  2310. regs.wordregs[regdi] = regs.wordregs[regdi] - 1;
  2311. }
  2312. else {
  2313. regs.wordregs[regdi] = regs.wordregs[regdi] + 1;
  2314. }
  2315. if (reptype) {
  2316. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  2317. }
  2318. totalexec++;
  2319. loopcount++;
  2320. if (!reptype) {
  2321. break;
  2322. }
  2323. ip = firstip;
  2324. break;
  2325. case 0xAB: /* AB STOSW */
  2326. if (reptype && (regs.wordregs[regcx] == 0) ) {
  2327. break;
  2328. }
  2329. putmem16 (segregs[reges], regs.wordregs[regdi], regs.wordregs[regax]);
  2330. if (df) {
  2331. regs.wordregs[regdi] = regs.wordregs[regdi] - 2;
  2332. }
  2333. else {
  2334. regs.wordregs[regdi] = regs.wordregs[regdi] + 2;
  2335. }
  2336. if (reptype) {
  2337. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  2338. }
  2339. totalexec++;
  2340. loopcount++;
  2341. if (!reptype) {
  2342. break;
  2343. }
  2344. ip = firstip;
  2345. break;
  2346. case 0xAC: /* AC LODSB */
  2347. if (reptype && (regs.wordregs[regcx] == 0) ) {
  2348. break;
  2349. }
  2350. regs.byteregs[regal] = getmem8 (useseg, regs.wordregs[regsi]);
  2351. if (df) {
  2352. regs.wordregs[regsi] = regs.wordregs[regsi] - 1;
  2353. }
  2354. else {
  2355. regs.wordregs[regsi] = regs.wordregs[regsi] + 1;
  2356. }
  2357. if (reptype) {
  2358. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  2359. }
  2360. totalexec++;
  2361. loopcount++;
  2362. if (!reptype) {
  2363. break;
  2364. }
  2365. ip = firstip;
  2366. break;
  2367. case 0xAD: /* AD LODSW */
  2368. if (reptype && (regs.wordregs[regcx] == 0) ) {
  2369. break;
  2370. }
  2371. oper1 = getmem16 (useseg, regs.wordregs[regsi]);
  2372. regs.wordregs[regax] = oper1;
  2373. if (df) {
  2374. regs.wordregs[regsi] = regs.wordregs[regsi] - 2;
  2375. }
  2376. else {
  2377. regs.wordregs[regsi] = regs.wordregs[regsi] + 2;
  2378. }
  2379. if (reptype) {
  2380. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  2381. }
  2382. totalexec++;
  2383. loopcount++;
  2384. if (!reptype) {
  2385. break;
  2386. }
  2387. ip = firstip;
  2388. break;
  2389. case 0xAE: /* AE SCASB */
  2390. if (reptype && (regs.wordregs[regcx] == 0) ) {
  2391. break;
  2392. }
  2393. oper1b = regs.byteregs[regal];
  2394. oper2b = getmem8 (segregs[reges], regs.wordregs[regdi]);
  2395. flag_sub8 (oper1b, oper2b);
  2396. if (df) {
  2397. regs.wordregs[regdi] = regs.wordregs[regdi] - 1;
  2398. }
  2399. else {
  2400. regs.wordregs[regdi] = regs.wordregs[regdi] + 1;
  2401. }
  2402. if (reptype) {
  2403. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  2404. }
  2405. if ( (reptype == 1) && !zf) {
  2406. break;
  2407. }
  2408. else if ( (reptype == 2) && (zf == 1) ) {
  2409. break;
  2410. }
  2411. totalexec++;
  2412. loopcount++;
  2413. if (!reptype) {
  2414. break;
  2415. }
  2416. ip = firstip;
  2417. break;
  2418. case 0xAF: /* AF SCASW */
  2419. if (reptype && (regs.wordregs[regcx] == 0) ) {
  2420. break;
  2421. }
  2422. oper1 = regs.wordregs[regax];
  2423. oper2 = getmem16 (segregs[reges], regs.wordregs[regdi]);
  2424. flag_sub16 (oper1, oper2);
  2425. if (df) {
  2426. regs.wordregs[regdi] = regs.wordregs[regdi] - 2;
  2427. }
  2428. else {
  2429. regs.wordregs[regdi] = regs.wordregs[regdi] + 2;
  2430. }
  2431. if (reptype) {
  2432. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  2433. }
  2434. if ( (reptype == 1) && !zf) {
  2435. break;
  2436. }
  2437. else if ( (reptype == 2) & (zf == 1) ) {
  2438. break;
  2439. }
  2440. totalexec++;
  2441. loopcount++;
  2442. if (!reptype) {
  2443. break;
  2444. }
  2445. ip = firstip;
  2446. break;
  2447. case 0xB0: /* B0 MOV regs.byteregs[regal] Ib */
  2448. regs.byteregs[regal] = getmem8 (segregs[regcs], ip);
  2449. StepIP (1);
  2450. break;
  2451. case 0xB1: /* B1 MOV regs.byteregs[regcl] Ib */
  2452. regs.byteregs[regcl] = getmem8 (segregs[regcs], ip);
  2453. StepIP (1);
  2454. break;
  2455. case 0xB2: /* B2 MOV regs.byteregs[regdl] Ib */
  2456. regs.byteregs[regdl] = getmem8 (segregs[regcs], ip);
  2457. StepIP (1);
  2458. break;
  2459. case 0xB3: /* B3 MOV regs.byteregs[regbl] Ib */
  2460. regs.byteregs[regbl] = getmem8 (segregs[regcs], ip);
  2461. StepIP (1);
  2462. break;
  2463. case 0xB4: /* B4 MOV regs.byteregs[regah] Ib */
  2464. regs.byteregs[regah] = getmem8 (segregs[regcs], ip);
  2465. StepIP (1);
  2466. break;
  2467. case 0xB5: /* B5 MOV regs.byteregs[regch] Ib */
  2468. regs.byteregs[regch] = getmem8 (segregs[regcs], ip);
  2469. StepIP (1);
  2470. break;
  2471. case 0xB6: /* B6 MOV regs.byteregs[regdh] Ib */
  2472. regs.byteregs[regdh] = getmem8 (segregs[regcs], ip);
  2473. StepIP (1);
  2474. break;
  2475. case 0xB7: /* B7 MOV regs.byteregs[regbh] Ib */
  2476. regs.byteregs[regbh] = getmem8 (segregs[regcs], ip);
  2477. StepIP (1);
  2478. break;
  2479. case 0xB8: /* B8 MOV eAX Iv */
  2480. oper1 = getmem16 (segregs[regcs], ip);
  2481. StepIP (2);
  2482. regs.wordregs[regax] = oper1;
  2483. break;
  2484. case 0xB9: /* B9 MOV eCX Iv */
  2485. oper1 = getmem16 (segregs[regcs], ip);
  2486. StepIP (2);
  2487. regs.wordregs[regcx] = oper1;
  2488. break;
  2489. case 0xBA: /* BA MOV eDX Iv */
  2490. oper1 = getmem16 (segregs[regcs], ip);
  2491. StepIP (2);
  2492. regs.wordregs[regdx] = oper1;
  2493. break;
  2494. case 0xBB: /* BB MOV eBX Iv */
  2495. oper1 = getmem16 (segregs[regcs], ip);
  2496. StepIP (2);
  2497. regs.wordregs[regbx] = oper1;
  2498. break;
  2499. case 0xBC: /* BC MOV eSP Iv */
  2500. regs.wordregs[regsp] = getmem16 (segregs[regcs], ip);
  2501. StepIP (2);
  2502. break;
  2503. case 0xBD: /* BD MOV eBP Iv */
  2504. regs.wordregs[regbp] = getmem16 (segregs[regcs], ip);
  2505. StepIP (2);
  2506. break;
  2507. case 0xBE: /* BE MOV eSI Iv */
  2508. regs.wordregs[regsi] = getmem16 (segregs[regcs], ip);
  2509. StepIP (2);
  2510. break;
  2511. case 0xBF: /* BF MOV eDI Iv */
  2512. regs.wordregs[regdi] = getmem16 (segregs[regcs], ip);
  2513. StepIP (2);
  2514. break;
  2515. case 0xC0: /* C0 GRP2 byte imm8 (80186+) */
  2516. modregrm();
  2517. oper1b = readrm8 (rm);
  2518. oper2b = getmem8 (segregs[regcs], ip);
  2519. StepIP (1);
  2520. writerm8 (rm, op_grp2_8 (oper2b) );
  2521. break;
  2522. case 0xC1: /* C1 GRP2 word imm8 (80186+) */
  2523. modregrm();
  2524. oper1 = readrm16 (rm);
  2525. oper2 = getmem8 (segregs[regcs], ip);
  2526. StepIP (1);
  2527. writerm16 (rm, op_grp2_16 ( (uint8_t) oper2) );
  2528. break;
  2529. case 0xC2: /* C2 RET Iw */
  2530. oper1 = getmem16 (segregs[regcs], ip);
  2531. ip = pop();
  2532. regs.wordregs[regsp] = regs.wordregs[regsp] + oper1;
  2533. break;
  2534. case 0xC3: /* C3 RET */
  2535. ip = pop();
  2536. break;
  2537. case 0xC4: /* C4 LES Gv Mp */
  2538. modregrm();
  2539. getea (rm);
  2540. putreg16 (reg, read86 (ea) + read86 (ea + 1) * 256);
  2541. segregs[reges] = read86 (ea + 2) + read86 (ea + 3) * 256;
  2542. break;
  2543. case 0xC5: /* C5 LDS Gv Mp */
  2544. modregrm();
  2545. getea (rm);
  2546. putreg16 (reg, read86 (ea) + read86 (ea + 1) * 256);
  2547. segregs[regds] = read86 (ea + 2) + read86 (ea + 3) * 256;
  2548. break;
  2549. case 0xC6: /* C6 MOV Eb Ib */
  2550. modregrm();
  2551. writerm8 (rm, getmem8 (segregs[regcs], ip) );
  2552. StepIP (1);
  2553. break;
  2554. case 0xC7: /* C7 MOV Ev Iv */
  2555. modregrm();
  2556. writerm16 (rm, getmem16 (segregs[regcs], ip) );
  2557. StepIP (2);
  2558. break;
  2559. case 0xC8: /* C8 ENTER (80186+) */
  2560. stacksize = getmem16 (segregs[regcs], ip);
  2561. StepIP (2);
  2562. nestlev = getmem8 (segregs[regcs], ip);
  2563. StepIP (1);
  2564. push (regs.wordregs[regbp]);
  2565. frametemp = regs.wordregs[regsp];
  2566. if (nestlev) {
  2567. for (temp16 = 1; temp16 < nestlev; temp16++) {
  2568. regs.wordregs[regbp] = regs.wordregs[regbp] - 2;
  2569. push (regs.wordregs[regbp]);
  2570. }
  2571. push (regs.wordregs[regsp]);
  2572. }
  2573. regs.wordregs[regbp] = frametemp;
  2574. regs.wordregs[regsp] = regs.wordregs[regbp] - stacksize;
  2575. break;
  2576. case 0xC9: /* C9 LEAVE (80186+) */
  2577. regs.wordregs[regsp] = regs.wordregs[regbp];
  2578. regs.wordregs[regbp] = pop();
  2579. break;
  2580. case 0xCA: /* CA RETF Iw */
  2581. oper1 = getmem16 (segregs[regcs], ip);
  2582. ip = pop();
  2583. segregs[regcs] = pop();
  2584. regs.wordregs[regsp] = regs.wordregs[regsp] + oper1;
  2585. break;
  2586. case 0xCB: /* CB RETF */
  2587. ip = pop();;
  2588. segregs[regcs] = pop();
  2589. break;
  2590. case 0xCC: /* CC INT 3 */
  2591. intcall86 (3);
  2592. break;
  2593. case 0xCD: /* CD INT Ib */
  2594. oper1b = getmem8 (segregs[regcs], ip);
  2595. StepIP (1);
  2596. intcall86 (oper1b);
  2597. break;
  2598. case 0xCE: /* CE INTO */
  2599. if (of) {
  2600. intcall86 (4);
  2601. }
  2602. break;
  2603. case 0xCF: /* CF IRET */
  2604. ip = pop();
  2605. segregs[regcs] = pop();
  2606. decodeflagsword (pop() );
  2607. /*
  2608. * if (net.enabled) net.canrecv = 1;
  2609. */
  2610. break;
  2611. case 0xD0: /* D0 GRP2 Eb 1 */
  2612. modregrm();
  2613. oper1b = readrm8 (rm);
  2614. writerm8 (rm, op_grp2_8 (1) );
  2615. break;
  2616. case 0xD1: /* D1 GRP2 Ev 1 */
  2617. modregrm();
  2618. oper1 = readrm16 (rm);
  2619. writerm16 (rm, op_grp2_16 (1) );
  2620. break;
  2621. case 0xD2: /* D2 GRP2 Eb regs.byteregs[regcl] */
  2622. modregrm();
  2623. oper1b = readrm8 (rm);
  2624. writerm8 (rm, op_grp2_8 (regs.byteregs[regcl]) );
  2625. break;
  2626. case 0xD3: /* D3 GRP2 Ev regs.byteregs[regcl] */
  2627. modregrm();
  2628. oper1 = readrm16 (rm);
  2629. writerm16 (rm, op_grp2_16 (regs.byteregs[regcl]) );
  2630. break;
  2631. case 0xD4: /* D4 AAM I0 */
  2632. oper1 = getmem8 (segregs[regcs], ip);
  2633. StepIP (1);
  2634. if (!oper1) {
  2635. intcall86 (0);
  2636. break;
  2637. } /* division by zero */
  2638. regs.byteregs[regah] = (regs.byteregs[regal] / oper1) & 255;
  2639. regs.byteregs[regal] = (regs.byteregs[regal] % oper1) & 255;
  2640. flag_szp16 (regs.wordregs[regax]);
  2641. break;
  2642. case 0xD5: /* D5 AAD I0 */
  2643. oper1 = getmem8 (segregs[regcs], ip);
  2644. StepIP (1);
  2645. regs.byteregs[regal] = (regs.byteregs[regah] * oper1 + regs.byteregs[regal]) & 255;
  2646. regs.byteregs[regah] = 0;
  2647. flag_szp16 (regs.byteregs[regah] * oper1 + regs.byteregs[regal]);
  2648. sf = 0;
  2649. break;
  2650. case 0xD6: /* D6 XLAT on V20/V30, SALC on 8086/8088 */
  2651. case 0xD7: /* D7 XLAT */
  2652. regs.byteregs[regal] = read86(useseg * 16 + (regs.wordregs[regbx]) + regs.byteregs[regal]);
  2653. break;
  2654. case 0xD8:
  2655. case 0xD9:
  2656. case 0xDA:
  2657. case 0xDB:
  2658. case 0xDC:
  2659. case 0xDE:
  2660. case 0xDD:
  2661. case 0xDF: /* escape to x87 FPU (unsupported) */
  2662. modregrm();
  2663. break;
  2664. case 0xE0: /* E0 LOOPNZ Jb */
  2665. temp16 = signext (getmem8 (segregs[regcs], ip) );
  2666. StepIP (1);
  2667. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  2668. if ( (regs.wordregs[regcx]) && !zf) {
  2669. ip = ip + temp16;
  2670. }
  2671. break;
  2672. case 0xE1: /* E1 LOOPZ Jb */
  2673. temp16 = signext (getmem8 (segregs[regcs], ip) );
  2674. StepIP (1);
  2675. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  2676. if (regs.wordregs[regcx] && (zf == 1) ) {
  2677. ip = ip + temp16;
  2678. }
  2679. break;
  2680. case 0xE2: /* E2 LOOP Jb */
  2681. temp16 = signext (getmem8 (segregs[regcs], ip) );
  2682. StepIP (1);
  2683. regs.wordregs[regcx] = regs.wordregs[regcx] - 1;
  2684. if (regs.wordregs[regcx]) {
  2685. ip = ip + temp16;
  2686. }
  2687. break;
  2688. case 0xE3: /* E3 JCXZ Jb */
  2689. temp16 = signext (getmem8 (segregs[regcs], ip) );
  2690. StepIP (1);
  2691. if (!regs.wordregs[regcx]) {
  2692. ip = ip + temp16;
  2693. }
  2694. break;
  2695. case 0xE4: /* E4 IN regs.byteregs[regal] Ib */
  2696. oper1b = getmem8 (segregs[regcs], ip);
  2697. StepIP (1);
  2698. regs.byteregs[regal] = (uint8_t) portin (oper1b);
  2699. break;
  2700. case 0xE5: /* E5 IN eAX Ib */
  2701. oper1b = getmem8 (segregs[regcs], ip);
  2702. StepIP (1);
  2703. regs.wordregs[regax] = portin16 (oper1b);
  2704. break;
  2705. case 0xE6: /* E6 OUT Ib regs.byteregs[regal] */
  2706. oper1b = getmem8 (segregs[regcs], ip);
  2707. StepIP (1);
  2708. portout (oper1b, regs.byteregs[regal]);
  2709. break;
  2710. case 0xE7: /* E7 OUT Ib eAX */
  2711. oper1b = getmem8 (segregs[regcs], ip);
  2712. StepIP (1);
  2713. portout16 (oper1b, regs.wordregs[regax]);
  2714. break;
  2715. case 0xE8: /* E8 CALL Jv */
  2716. oper1 = getmem16 (segregs[regcs], ip);
  2717. StepIP (2);
  2718. push (ip);
  2719. ip = ip + oper1;
  2720. break;
  2721. case 0xE9: /* E9 JMP Jv */
  2722. oper1 = getmem16 (segregs[regcs], ip);
  2723. StepIP (2);
  2724. ip = ip + oper1;
  2725. break;
  2726. case 0xEA: /* EA JMP Ap */
  2727. oper1 = getmem16 (segregs[regcs], ip);
  2728. StepIP (2);
  2729. oper2 = getmem16 (segregs[regcs], ip);
  2730. ip = oper1;
  2731. segregs[regcs] = oper2;
  2732. break;
  2733. case 0xEB: /* EB JMP Jb */
  2734. oper1 = signext (getmem8 (segregs[regcs], ip) );
  2735. StepIP (1);
  2736. ip = ip + oper1;
  2737. break;
  2738. case 0xEC: /* EC IN regs.byteregs[regal] regdx */
  2739. oper1 = regs.wordregs[regdx];
  2740. regs.byteregs[regal] = (uint8_t) portin (oper1);
  2741. break;
  2742. case 0xED: /* ED IN eAX regdx */
  2743. oper1 = regs.wordregs[regdx];
  2744. regs.wordregs[regax] = portin16 (oper1);
  2745. break;
  2746. case 0xEE: /* EE OUT regdx regs.byteregs[regal] */
  2747. oper1 = regs.wordregs[regdx];
  2748. portout (oper1, regs.byteregs[regal]);
  2749. break;
  2750. case 0xEF: /* EF OUT regdx eAX */
  2751. oper1 = regs.wordregs[regdx];
  2752. portout16 (oper1, regs.wordregs[regax]);
  2753. break;
  2754. case 0xF0: /* F0 LOCK */
  2755. break;
  2756. case 0xF4: /* F4 HLT */
  2757. hltstate = 1;
  2758. break;
  2759. case 0xF5: /* F5 CMC */
  2760. if (!cf) {
  2761. cf = 1;
  2762. }
  2763. else {
  2764. cf = 0;
  2765. }
  2766. break;
  2767. case 0xF6: /* F6 GRP3a Eb */
  2768. modregrm();
  2769. oper1b = readrm8 (rm);
  2770. op_grp3_8();
  2771. if ( (reg > 1) && (reg < 4) ) {
  2772. writerm8 (rm, res8);
  2773. }
  2774. break;
  2775. case 0xF7: /* F7 GRP3b Ev */
  2776. modregrm();
  2777. oper1 = readrm16 (rm);
  2778. op_grp3_16();
  2779. if ( (reg > 1) && (reg < 4) ) {
  2780. writerm16 (rm, res16);
  2781. }
  2782. break;
  2783. case 0xF8: /* F8 CLC */
  2784. cf = 0;
  2785. break;
  2786. case 0xF9: /* F9 STC */
  2787. cf = 1;
  2788. break;
  2789. case 0xFA: /* FA CLI */
  2790. ifl = 0;
  2791. break;
  2792. case 0xFB: /* FB STI */
  2793. ifl = 1;
  2794. break;
  2795. case 0xFC: /* FC CLD */
  2796. df = 0;
  2797. break;
  2798. case 0xFD: /* FD STD */
  2799. df = 1;
  2800. break;
  2801. case 0xFE: /* FE GRP4 Eb */
  2802. modregrm();
  2803. oper1b = readrm8 (rm);
  2804. oper2b = 1;
  2805. if (!reg) {
  2806. tempcf = cf;
  2807. res8 = oper1b + oper2b;
  2808. flag_add8 (oper1b, oper2b);
  2809. cf = tempcf;
  2810. writerm8 (rm, res8);
  2811. }
  2812. else {
  2813. tempcf = cf;
  2814. res8 = oper1b - oper2b;
  2815. flag_sub8 (oper1b, oper2b);
  2816. cf = tempcf;
  2817. writerm8 (rm, res8);
  2818. }
  2819. break;
  2820. case 0xFF: /* FF GRP5 Ev */
  2821. modregrm();
  2822. oper1 = readrm16 (rm);
  2823. op_grp5();
  2824. break;
  2825. default:
  2826. intcall86 (6); /* trip invalid opcode exception (this occurs on the 80186+, 8086/8088 CPUs treat them as NOPs. */
  2827. /* technically they aren't exactly like NOPs in most cases, but for our pursoses, that's accurate enough. */
  2828. break;
  2829. }
  2830. }
  2831. return 1;
  2832. }
  2833. void reset86(uint16_t startip) {
  2834. segregs[regcs] = 0;
  2835. ip = startip;
  2836. hltstate = 0;
  2837. }