Mirror of CollapseOS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

886 lines
17KB

  1. // This unit has been copied from libz80 into Collapse OS and was slighly changed
  2. /* =========================================================
  3. * libz80 - Z80 emulation library
  4. * =========================================================
  5. *
  6. * (C) Gabriel Gambetta (gabriel.gambetta@gmail.com) 2000 - 2012
  7. *
  8. * Version 2.1.0
  9. *
  10. * ---------------------------------------------------------
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; either version 2 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  25. */
  26. #include "z80.h"
  27. #include "string.h"
  28. #define BR (ctx->R1.br)
  29. #define WR (ctx->R1.wr)
  30. #define SETFLAG(F) setFlag(ctx, F)
  31. #define RESFLAG(F) resFlag(ctx, F)
  32. #define GETFLAG(F) getFlag(ctx, F)
  33. #define VALFLAG(F,V) valFlag(ctx, F, V)
  34. /* ---------------------------------------------------------
  35. * Flag tricks
  36. * ---------------------------------------------------------
  37. *
  38. * To avoid repeating entries in the spec files, many operations that look similar are treated as special cases
  39. * of a more general operation.
  40. *
  41. * For example, ADD and ADC are similar in syntax and operation - the difference is that ADC takes the carry flag
  42. * into account.
  43. *
  44. * So we define a general operation doArithmetic(...) which accepts a boolean parameter specifying whether to do
  45. * a Carry-operation or not. Then, when we parse, we can say
  46. *
  47. * (ADD|ADC) ....
  48. * doArithmetic(FLAG_FOR_%1)
  49. *
  50. * and everything works fine.
  51. *
  52. */
  53. /* Flags for doIncDec() */
  54. static const int ID_INC = 0;
  55. static const int ID_DEC = 1;
  56. /* Flags for enable / disable interrupts */
  57. static const int IE_DI = 0;
  58. static const int IE_EI = 1;
  59. /* Flags for doSetRes() */
  60. static const int SR_RES = 0;
  61. static const int SR_SET = 1;
  62. /* Flags for logical / arithmetic operations */
  63. static const int IA_L = 0;
  64. static const int IA_A = 1;
  65. /* Flags for doArithmetic() - F1 = withCarry, F2 = isSub */
  66. static const int F1_ADC = 1;
  67. static const int F1_SBC = 1;
  68. static const int F1_ADD = 0;
  69. static const int F1_SUB = 0;
  70. static const int F2_ADC = 0;
  71. static const int F2_SBC = 1;
  72. static const int F2_ADD = 0;
  73. static const int F2_SUB = 1;
  74. /* Increment or decrement R, preserving bit 7 */
  75. #define INCR (ctx->R = (ctx->R & 0x80) | ((ctx->R + 1) & 0x7f))
  76. #define DECR (ctx->R = (ctx->R & 0x80) | ((ctx->R - 1) & 0x7f))
  77. /* ---------------------------------------------------------
  78. * The opcode implementations
  79. * ---------------------------------------------------------
  80. */
  81. #include "opcodes_decl.h"
  82. typedef enum
  83. {
  84. OP_NONE,
  85. OP_BYTE,
  86. OP_OFFSET,
  87. OP_WORD
  88. } Z80OperandType;
  89. typedef void (*Z80OpcodeFunc) (Z80Context* ctx);
  90. struct Z80OpcodeEntry
  91. {
  92. Z80OpcodeFunc func;
  93. int operand_type;
  94. char* format;
  95. struct Z80OpcodeTable* table;
  96. };
  97. struct Z80OpcodeTable
  98. {
  99. int opcode_offset;
  100. struct Z80OpcodeEntry entries[256];
  101. };
  102. #include "opcodes_table.h"
  103. /* ---------------------------------------------------------
  104. * Data operations
  105. * ---------------------------------------------------------
  106. */
  107. static void write8 (Z80Context* ctx, ushort addr, byte val)
  108. {
  109. ctx->tstates += 3;
  110. ctx->memWrite(ctx->memParam, addr, val);
  111. }
  112. static void write16 (Z80Context* ctx, ushort addr, ushort val)
  113. {
  114. write8(ctx, addr, val);
  115. write8(ctx, addr + 1, val >> 8);
  116. }
  117. static byte read8 (Z80Context* ctx, ushort addr)
  118. {
  119. ctx->tstates += 3;
  120. return ctx->memRead(ctx->memParam, addr);
  121. }
  122. static ushort read16 (Z80Context* ctx, ushort addr)
  123. {
  124. byte lsb = read8(ctx, addr);
  125. byte msb = read8(ctx, addr + 1);
  126. return msb << 8 | lsb;
  127. }
  128. static byte ioRead (Z80Context* ctx, ushort addr)
  129. {
  130. ctx->tstates += 4;
  131. return ctx->ioRead(ctx->ioParam, addr);
  132. }
  133. static void ioWrite (Z80Context* ctx, ushort addr, byte val)
  134. {
  135. ctx->tstates += 4;
  136. ctx->ioWrite(ctx->ioParam, addr, val);
  137. }
  138. /* ---------------------------------------------------------
  139. * Flag operations
  140. * ---------------------------------------------------------
  141. */
  142. /** Sets a flag */
  143. static void setFlag(Z80Context* ctx, Z80Flags flag)
  144. {
  145. BR.F |= flag;
  146. }
  147. /** Resets a flag */
  148. static void resFlag(Z80Context* ctx, Z80Flags flag)
  149. {
  150. BR.F &= ~flag;
  151. }
  152. /** Puts a value in a flag */
  153. static void valFlag(Z80Context* ctx, Z80Flags flag, int val)
  154. {
  155. if (val)
  156. SETFLAG(flag);
  157. else
  158. RESFLAG(flag);
  159. }
  160. /** Returns a flag */
  161. static int getFlag(Z80Context* ctx, Z80Flags flag)
  162. {
  163. return (BR.F & flag) != 0;
  164. }
  165. /* ---------------------------------------------------------
  166. * Flag adjustments
  167. * ---------------------------------------------------------
  168. */
  169. static int parityBit[256] = {
  170. 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  171. 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  172. 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  173. 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  174. 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  175. 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  176. 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  177. 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  178. 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  179. 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  180. 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  181. 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  182. 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
  183. 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  184. 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
  185. 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 };
  186. static void adjustFlags (Z80Context* ctx, byte val)
  187. {
  188. VALFLAG(F_5, (val & F_5) != 0);
  189. VALFLAG(F_3, (val & F_3) != 0);
  190. }
  191. static void adjustFlagSZP (Z80Context* ctx, byte val)
  192. {
  193. VALFLAG(F_S, (val & 0x80) != 0);
  194. VALFLAG(F_Z, (val == 0));
  195. VALFLAG(F_PV, parityBit[val]);
  196. }
  197. /* Adjust flags after AND, OR, XOR */
  198. static void adjustLogicFlag (Z80Context* ctx, int flagH)
  199. {
  200. VALFLAG(F_S, (BR.A & 0x80) != 0);
  201. VALFLAG(F_Z, (BR.A == 0));
  202. VALFLAG(F_H, flagH);
  203. VALFLAG(F_N, 0);
  204. VALFLAG(F_C, 0);
  205. VALFLAG(F_PV, parityBit[BR.A]);
  206. adjustFlags(ctx, BR.A);
  207. }
  208. /* ---------------------------------------------------------
  209. * Condition checks
  210. * ---------------------------------------------------------
  211. */
  212. typedef enum
  213. {
  214. C_,
  215. C_Z,
  216. C_NZ,
  217. C_C,
  218. C_NC,
  219. C_M,
  220. C_P,
  221. C_PE,
  222. C_PO
  223. } Z80Condition;
  224. static int condition(Z80Context* ctx, Z80Condition cond)
  225. {
  226. if (cond == C_)
  227. return 1;
  228. if (cond == C_Z)
  229. return GETFLAG(F_Z);
  230. if (cond == C_NZ)
  231. return !GETFLAG(F_Z);
  232. if (cond == C_C)
  233. return GETFLAG(F_C);
  234. if (cond == C_NC)
  235. return !GETFLAG(F_C);
  236. if (cond == C_M)
  237. return GETFLAG(F_S);
  238. if (cond == C_P)
  239. return !GETFLAG(F_S);
  240. if (cond == C_PE)
  241. return GETFLAG(F_PV);
  242. /* if (cond == C_PO)*/
  243. return !GETFLAG(F_PV);
  244. }
  245. /* ---------------------------------------------------------
  246. * Generic operations
  247. * ---------------------------------------------------------
  248. */
  249. static int doComplement(byte v)
  250. {
  251. if ((v & 0x80) == 0)
  252. return v;
  253. v = ~v;
  254. v &= 0x7F;
  255. v++;
  256. return -v;
  257. }
  258. /** Do an arithmetic operation (ADD, SUB, ADC, SBC y CP) */
  259. static byte doArithmetic (Z80Context* ctx, byte value, int withCarry, int isSub)
  260. {
  261. ushort res; /* To detect carry */
  262. if (isSub)
  263. {
  264. SETFLAG(F_N);
  265. VALFLAG(F_H, (((BR.A & 0x0F) - (value & 0x0F)) & 0x10) != 0);
  266. res = BR.A - value;
  267. if (withCarry && GETFLAG(F_C))
  268. res--;
  269. }
  270. else
  271. {
  272. RESFLAG(F_N);
  273. VALFLAG(F_H, (((BR.A & 0x0F) + (value & 0x0F)) & 0x10) != 0);
  274. res = BR.A + value;
  275. if (withCarry && GETFLAG(F_C))
  276. res++;
  277. }
  278. VALFLAG(F_S, ((res & 0x80) != 0));
  279. VALFLAG(F_C, ((res & 0x100) != 0));
  280. VALFLAG(F_Z, ((res & 0xff) == 0));
  281. int minuend_sign = BR.A & 0x80;
  282. int subtrahend_sign = value & 0x80;
  283. int result_sign = res & 0x80;
  284. int overflow;
  285. if(isSub)
  286. overflow = minuend_sign != subtrahend_sign && result_sign != minuend_sign;
  287. else
  288. overflow = minuend_sign == subtrahend_sign && result_sign != minuend_sign;
  289. VALFLAG(F_PV, overflow);
  290. adjustFlags(ctx, res);
  291. return (byte)(res & 0xFF);
  292. }
  293. /* Do a 16-bit addition, setting the appropriate flags. */
  294. static ushort doAddWord(Z80Context* ctx, ushort a1, ushort a2, int withCarry, int isSub)
  295. {
  296. if(withCarry && GETFLAG(F_C))
  297. a2++;
  298. int sum = a1;
  299. if(isSub)
  300. {
  301. sum -= a2;
  302. VALFLAG(F_H, ((a1 & 0x0fff) - (a2 & 0x0fff)) & 0x1000);
  303. }
  304. else
  305. {
  306. sum += a2;
  307. VALFLAG(F_H, ((a1 & 0x0fff) + (a2 & 0x0fff)) & 0x1000);
  308. }
  309. VALFLAG(F_C, sum & 0x10000);
  310. if(withCarry || isSub)
  311. {
  312. int minuend_sign = a1 & 0x8000;
  313. int subtrahend_sign = a2 & 0x8000;
  314. int result_sign = sum & 0x8000;
  315. int overflow;
  316. if(isSub)
  317. overflow = minuend_sign != subtrahend_sign && result_sign != minuend_sign;
  318. else
  319. overflow = minuend_sign == subtrahend_sign && result_sign != minuend_sign;
  320. VALFLAG(F_PV, overflow);
  321. VALFLAG(F_S, (sum & 0x8000) != 0);
  322. VALFLAG(F_Z, (sum & 0xFFFF) == 0);
  323. }
  324. VALFLAG(F_N, isSub);
  325. adjustFlags(ctx, sum >> 8);
  326. return sum;
  327. }
  328. static void doAND (Z80Context* ctx, byte value)
  329. {
  330. BR.A &= value;
  331. adjustLogicFlag(ctx, 1);
  332. }
  333. static void doOR (Z80Context* ctx, byte value)
  334. {
  335. BR.A |= value;
  336. adjustLogicFlag(ctx, 0);
  337. }
  338. static void doXOR (Z80Context* ctx, byte value)
  339. {
  340. BR.A ^= value;
  341. adjustLogicFlag(ctx, 0);
  342. }
  343. static void doBIT (Z80Context* ctx, int b, byte val)
  344. {
  345. if (val & (1 << b))
  346. RESFLAG(F_Z | F_PV);
  347. else
  348. SETFLAG(F_Z | F_PV);
  349. SETFLAG(F_H);
  350. RESFLAG(F_N);
  351. RESFLAG(F_S);
  352. if ((b == 7) && !GETFLAG(F_Z))
  353. SETFLAG(F_S);
  354. }
  355. static void doBIT_r(Z80Context* ctx, int b, byte val)
  356. {
  357. doBIT(ctx, b, val);
  358. VALFLAG(F_5, val & F_5);
  359. VALFLAG(F_3, val & F_3);
  360. }
  361. static void doBIT_indexed(Z80Context* ctx, int b, ushort address)
  362. {
  363. byte val = read8(ctx, address);
  364. doBIT(ctx, b, val);
  365. VALFLAG(F_5, (address >> 8) & F_5);
  366. VALFLAG(F_3, (address >> 8) & F_3);
  367. }
  368. byte doSetRes (Z80Context* ctx, int bit, int pos, byte val)
  369. {
  370. if (bit)
  371. val |= (1 << pos);
  372. else
  373. val &= ~(1 << pos);
  374. return val;
  375. }
  376. static byte doIncDec (Z80Context* ctx, byte val, int isDec)
  377. {
  378. if (isDec)
  379. {
  380. VALFLAG(F_PV, (val & 0x80) && !((val - 1) & 0x80));
  381. val--;
  382. VALFLAG(F_H, (val & 0x0F) == 0x0F);
  383. }
  384. else
  385. {
  386. VALFLAG(F_PV, !(val & 0x80) && ((val + 1) & 0x80));
  387. val++;
  388. VALFLAG(F_H, !(val & 0x0F));
  389. }
  390. VALFLAG(F_S, ((val & 0x80) != 0));
  391. VALFLAG(F_Z, (val == 0));
  392. VALFLAG(F_N, isDec);
  393. adjustFlags(ctx, val);
  394. return val;
  395. }
  396. static byte doRLC (Z80Context* ctx, int adjFlags, byte val)
  397. {
  398. VALFLAG(F_C, (val & 0x80) != 0);
  399. val <<= 1;
  400. val |= (byte)GETFLAG(F_C);
  401. adjustFlags(ctx, val);
  402. RESFLAG(F_H | F_N);
  403. if (adjFlags)
  404. adjustFlagSZP(ctx, val);
  405. return val;
  406. }
  407. static byte doRL (Z80Context* ctx, int adjFlags, byte val)
  408. {
  409. int CY = GETFLAG(F_C);
  410. VALFLAG(F_C, (val & 0x80) != 0);
  411. val <<= 1;
  412. val |= (byte)CY;
  413. adjustFlags(ctx, val);
  414. RESFLAG(F_H | F_N);
  415. if (adjFlags)
  416. adjustFlagSZP(ctx, val);
  417. return val;
  418. }
  419. static byte doRRC (Z80Context* ctx, int adjFlags, byte val)
  420. {
  421. VALFLAG(F_C, (val & 0x01) != 0);
  422. val >>= 1;
  423. val |= ((byte)GETFLAG(F_C) << 7);
  424. adjustFlags(ctx, val);
  425. RESFLAG(F_H | F_N);
  426. if (adjFlags)
  427. adjustFlagSZP(ctx, val);
  428. return val;
  429. }
  430. static byte doRR (Z80Context* ctx, int adjFlags, byte val)
  431. {
  432. int CY = GETFLAG(F_C);
  433. VALFLAG(F_C, (val & 0x01));
  434. val >>= 1;
  435. val |= (CY << 7);
  436. adjustFlags(ctx, val);
  437. RESFLAG(F_H | F_N);
  438. if (adjFlags)
  439. adjustFlagSZP(ctx, val);
  440. return val;
  441. }
  442. static byte doSL (Z80Context* ctx, byte val, int isArith)
  443. {
  444. VALFLAG(F_C, (val & 0x80) != 0);
  445. val <<= 1;
  446. if (!isArith)
  447. val |= 1;
  448. adjustFlags(ctx, val);
  449. RESFLAG(F_H | F_N);
  450. adjustFlagSZP(ctx, val);
  451. return val;
  452. }
  453. static byte doSR (Z80Context* ctx, byte val, int isArith)
  454. {
  455. int b = val & 0x80;
  456. VALFLAG(F_C, (val & 0x01) != 0);
  457. val >>= 1;
  458. if (isArith)
  459. val |= b;
  460. adjustFlags(ctx, val);
  461. RESFLAG(F_H | F_N);
  462. adjustFlagSZP(ctx, val);
  463. return val;
  464. }
  465. static void doPush (Z80Context* ctx, ushort val)
  466. {
  467. WR.SP--;
  468. WR.SP--;
  469. write16(ctx, WR.SP, val);
  470. }
  471. static ushort doPop (Z80Context* ctx)
  472. {
  473. ushort val;
  474. val = read16(ctx, WR.SP);
  475. WR.SP++;
  476. WR.SP++;
  477. return val;
  478. }
  479. static byte doCP_HL(Z80Context * ctx)
  480. {
  481. byte val = read8(ctx, WR.HL);
  482. byte result = doArithmetic(ctx, val, 0, 1);
  483. adjustFlags(ctx, val);
  484. return result;
  485. }
  486. /* The DAA opcode
  487. * According to the value in A and the flags set, add a value to A
  488. * This algorithm taken from:
  489. * http://www.worldofspectrum.org/faq/reference/z80reference.htm
  490. * and verified against the specification in the Zilog
  491. * Z80 Family CPU User Manual, rev. 04, Dec. 2004, pp. 166-167
  492. */
  493. static void doDAA(Z80Context * ctx) {
  494. int correction_factor = 0x00;
  495. int carry = 0;
  496. if(BR.A > 0x99 || GETFLAG(F_C)) {
  497. correction_factor |= 0x60;
  498. carry = 1;
  499. }
  500. if((BR.A & 0x0f) > 9 || GETFLAG(F_H))
  501. correction_factor |= 0x06;
  502. int a_before = BR.A;
  503. if(GETFLAG(F_N))
  504. BR.A -= correction_factor;
  505. else
  506. BR.A += correction_factor;
  507. VALFLAG(F_H, (a_before ^ BR.A) & 0x10);
  508. VALFLAG(F_C, carry);
  509. VALFLAG(F_S, (BR.A & 0x80) != 0);
  510. VALFLAG(F_Z, (BR.A == 0));
  511. VALFLAG(F_PV, parityBit[BR.A]);
  512. adjustFlags(ctx, BR.A);
  513. }
  514. #include "opcodes_impl.c"
  515. /* ---------------------------------------------------------
  516. * The top-level functions
  517. * ---------------------------------------------------------
  518. */
  519. static void do_execute(Z80Context* ctx)
  520. {
  521. struct Z80OpcodeTable* current = &opcodes_main;
  522. struct Z80OpcodeEntry* entries = current->entries;
  523. Z80OpcodeFunc func;
  524. byte opcode;
  525. int offset = 0;
  526. do
  527. {
  528. if (ctx->exec_int_vector)
  529. {
  530. opcode = ctx->int_vector;
  531. ctx->tstates += 6;
  532. }
  533. else
  534. {
  535. opcode = read8(ctx, ctx->PC + offset);
  536. ctx->PC++;
  537. ctx->tstates += 1;
  538. }
  539. INCR;
  540. func = entries[opcode].func;
  541. if (func != NULL)
  542. {
  543. ctx->PC -= offset;
  544. func(ctx);
  545. ctx->PC += offset;
  546. break;
  547. }
  548. else if (entries[opcode].table != NULL)
  549. {
  550. current = entries[opcode].table;
  551. entries = current->entries;
  552. offset = current->opcode_offset;
  553. if (offset > 0)
  554. DECR;
  555. }
  556. else
  557. {
  558. /* NOP */
  559. break;
  560. }
  561. } while(1);
  562. }
  563. static void unhalt(Z80Context* ctx)
  564. {
  565. if (ctx->halted)
  566. {
  567. ctx->halted = 0;
  568. ctx->PC++;
  569. }
  570. }
  571. static void do_nmi(Z80Context* ctx)
  572. {
  573. unhalt(ctx);
  574. ctx->IFF2 = ctx->IFF1;
  575. ctx->IFF1 = 0;
  576. doPush(ctx, ctx->PC);
  577. ctx->PC = 0x0066;
  578. ctx->nmi_req = 0;
  579. ctx->tstates += 5;
  580. }
  581. static void do_int(Z80Context* ctx)
  582. {
  583. unhalt(ctx);
  584. ctx->IFF1 = 0;
  585. ctx->IFF2 = 0;
  586. ctx->int_req = 0;
  587. if (ctx->IM == 0)
  588. {
  589. ctx->exec_int_vector = 1;
  590. do_execute(ctx);
  591. ctx->exec_int_vector = 0;
  592. }
  593. else if (ctx->IM == 1)
  594. {
  595. doPush(ctx, ctx->PC);
  596. ctx->PC = 0x0038;
  597. ctx->tstates += 7;
  598. }
  599. else if (ctx->IM == 2)
  600. {
  601. doPush(ctx, ctx->PC);
  602. ushort vector_address = (ctx->I << 8) | ctx->int_vector;
  603. ctx->PC = read16(ctx, vector_address);
  604. ctx->tstates += 7;
  605. }
  606. }
  607. void Z80Execute (Z80Context* ctx)
  608. {
  609. if (ctx->nmi_req)
  610. do_nmi(ctx);
  611. else if (ctx->int_req && !ctx->defer_int && ctx->IFF1)
  612. do_int(ctx);
  613. else
  614. {
  615. ctx->defer_int = 0;
  616. do_execute(ctx);
  617. }
  618. }
  619. unsigned Z80ExecuteTStates(Z80Context* ctx, unsigned tstates)
  620. {
  621. ctx->tstates = 0;
  622. while (ctx->tstates < tstates)
  623. Z80Execute(ctx);
  624. return ctx->tstates;
  625. }
  626. void Z80Debug (Z80Context* ctx, char* dump, char* decode)
  627. {
  628. char tmp[20];
  629. struct Z80OpcodeTable* current = &opcodes_main;
  630. struct Z80OpcodeEntry* entries = current->entries;
  631. char* fmt;
  632. byte opcode;
  633. ushort parm;
  634. int offset = 0;
  635. int PC = ctx->PC;
  636. int size = 0;
  637. if (dump)
  638. dump[0] = 0;
  639. if (decode)
  640. decode[0] = 0;
  641. do
  642. {
  643. opcode = read8(ctx, PC + offset);
  644. size++;
  645. PC++;
  646. fmt = entries[opcode].format;
  647. if (fmt != NULL)
  648. {
  649. PC -= offset;
  650. parm = read16(ctx, PC);
  651. if (entries[opcode].operand_type == OP_NONE)
  652. size++;
  653. else
  654. size += 2;
  655. if (entries[opcode].operand_type != OP_WORD)
  656. {
  657. parm &= 0xFF;
  658. size--;
  659. }
  660. if (decode)
  661. sprintf(decode, fmt, parm);
  662. PC += offset;
  663. break;
  664. }
  665. else if (entries[opcode].table != NULL)
  666. {
  667. current = entries[opcode].table;
  668. entries = current->entries;
  669. offset = current->opcode_offset;
  670. }
  671. else
  672. {
  673. if (decode != NULL)
  674. strcpy(decode, "NOP (ignored)");
  675. break;
  676. }
  677. } while(1);
  678. if (dump)
  679. {
  680. for (offset = 0; offset < size; offset++)
  681. {
  682. sprintf(tmp, "%02X", read8(ctx, ctx->PC + offset));
  683. strcat(dump, tmp);
  684. }
  685. }
  686. }
  687. void Z80RESET (Z80Context* ctx)
  688. {
  689. ctx->PC = 0x0000;
  690. BR.F = 0;
  691. ctx->IM = 0;
  692. ctx->IFF1 = ctx->IFF2 = 0;
  693. ctx->R = 0;
  694. ctx->I = 0;
  695. ctx->halted = 0;
  696. ctx->tstates = 0;
  697. ctx->nmi_req = 0;
  698. ctx->int_req = 0;
  699. ctx->defer_int = 0;
  700. ctx->exec_int_vector = 0;
  701. }
  702. void Z80INT (Z80Context* ctx, byte value)
  703. {
  704. ctx->int_req = 1;
  705. ctx->int_vector = value;
  706. }
  707. void Z80NMI (Z80Context* ctx)
  708. {
  709. ctx->nmi_req = 1;
  710. }