Mirror of CollapseOS
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

3403 lignes
92KB

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