Mirror of CollapseOS
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

3317 行
90KB

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