An emulator, assembler, and disassembler for the Sega Game Gear
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

z80_flags.inc.c 6.2 KiB

8 anos atrás
8 anos atrás
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /* Copyright (C) 2014-2016 Ben Kurtovic <ben.kurtovic@gmail.com>
  2. Released under the terms of the MIT License. See LICENSE for details. */
  3. #define POS(x) (!((x) & 0x80))
  4. #define NEG(x) ((x) & 0x80)
  5. #define CARRY(lh, op, rh) (((lh) op (rh)) & 0x100)
  6. #define HALF(lh, op, rh) ((((lh) & 0x0F) op ((rh) & 0x0F)) & 0x10)
  7. #define ZERO(x) ((x) == 0)
  8. #define SIGN(x) NEG(x)
  9. #define SUB 1
  10. #define CARRY2(lh, op, rh) (((lh) op (rh)) & 0x10000)
  11. #define OV_ADD(lh, rh, res) \
  12. (POS(lh) && POS(rh) && NEG(res) || NEG(lh) && NEG(rh) && POS(res))
  13. #define OV_SUB(lh, rh, res) \
  14. (POS(lh) && NEG(rh) && NEG(res) || NEG(lh) && POS(rh) && POS(res))
  15. #define PARITY(x) (!(__builtin_popcount(x) % 2))
  16. #define F3(x) ((x) & 0x08)
  17. #define F5(x) ((x) & 0x20)
  18. /*
  19. Set the flags for an 8-bit ADD or ADC instruction.
  20. */
  21. static inline void set_flags_add8(Z80 *z80, uint16_t rh)
  22. {
  23. uint8_t lh = z80->regs.a;
  24. uint8_t res = lh + rh;
  25. set_flags(z80, CARRY(lh, +, rh), !SUB, OV_ADD(lh, rh, res), F3(res),
  26. HALF(lh, +, rh), F5(res), ZERO(res), SIGN(res), 0xFF);
  27. }
  28. /*
  29. Set the flags for an 8-bit SUB or SBC instruction.
  30. */
  31. static inline void set_flags_sub8(Z80 *z80, uint16_t rh)
  32. {
  33. uint8_t lh = z80->regs.a;
  34. uint8_t res = lh - rh;
  35. set_flags(z80, CARRY(lh, -, rh), SUB, OV_SUB(lh, rh, res), F3(res),
  36. HALF(lh, -, rh), F5(res), ZERO(res), SIGN(res), 0xFF);
  37. }
  38. /*
  39. Set the flags for a CP instruction.
  40. */
  41. static inline void set_flags_cp(Z80 *z80, uint16_t rh)
  42. {
  43. uint8_t lh = z80->regs.a;
  44. uint8_t res = lh - rh;
  45. set_flags(z80, CARRY(lh, -, rh), SUB, OV_SUB(lh, rh, res), F3(rh),
  46. HALF(lh, -, rh), F5(rh), ZERO(res), SIGN(res), 0xFF);
  47. }
  48. /*
  49. Set the flags for an AND, XOR, or OR instruction.
  50. */
  51. static inline void set_flags_bitwise(Z80 *z80, uint8_t res, bool is_and)
  52. {
  53. set_flags(z80, 0, 0, PARITY(res), F3(res), is_and, F5(res), ZERO(res),
  54. SIGN(res), 0xFF);
  55. }
  56. /*
  57. Set the flags for an 8-bit INC instruction.
  58. */
  59. static inline void set_flags_inc(Z80 *z80, uint8_t val)
  60. {
  61. uint8_t res = val + 1;
  62. set_flags(z80, 0, !SUB, OV_ADD(val, 1, res), F3(res), HALF(val, +, 1),
  63. F5(res), ZERO(res), SIGN(res), 0xFE);
  64. }
  65. /*
  66. Set the flags for an 8-bit DEC instruction.
  67. */
  68. static inline void set_flags_dec(Z80 *z80, uint8_t val)
  69. {
  70. uint8_t res = val - 1;
  71. set_flags(z80, 0, SUB, OV_SUB(val, 1, res), F3(res), HALF(val, -, 1),
  72. F5(res), ZERO(res), SIGN(res), 0xFE);
  73. }
  74. /*
  75. Set the flags for a 16-bit ADD instruction.
  76. */
  77. static inline void set_flags_add16(Z80 *z80, uint16_t lh, uint16_t rh)
  78. {
  79. uint16_t res = lh + rh;
  80. set_flags(z80, CARRY2(lh, +, rh), !SUB, 0, F3(res >> 8),
  81. HALF(lh >> 8, +, rh >> 8), F5(res >> 8), 0, 0, 0x3B);
  82. }
  83. /*
  84. Set the flags for a 16-bit ADC instruction.
  85. */
  86. static inline void set_flags_adc16(Z80 *z80, uint16_t lh, uint32_t rh)
  87. {
  88. uint16_t res = lh + rh;
  89. set_flags(z80, CARRY2(lh, +, rh), !SUB, OV_ADD(lh >> 8, rh >> 8, res >> 8),
  90. F3(res >> 8), HALF(lh >> 8, +, rh >> 8), F5(res >> 8), ZERO(res),
  91. SIGN(res >> 8), 0xFF);
  92. }
  93. /*
  94. Set the flags for a 16-bit SBC instruction.
  95. */
  96. static inline void set_flags_sbc16(Z80 *z80, uint16_t lh, uint32_t rh)
  97. {
  98. uint16_t res = lh - rh;
  99. set_flags(z80, CARRY2(lh, -, rh), SUB, OV_SUB(lh >> 8, rh >> 8, res >> 8),
  100. F3(res >> 8), HALF(lh >> 8, -, rh >> 8), F5(res >> 8), ZERO(res),
  101. SIGN(res >> 8), 0xFF);
  102. }
  103. /*
  104. Set the flags for a BIT instruction.
  105. */
  106. static inline void set_flags_bit(Z80 *z80, uint8_t val, uint8_t bit)
  107. {
  108. bool z = ZERO((val >> bit) & 1);
  109. if (z)
  110. set_flags(z80, 0, 0, z, 0, 1, 0, z, 0, 0xFE);
  111. else
  112. set_flags(z80, 0, 0, z, bit == 3, 1, bit == 5, z, bit == 7, 0xFE);
  113. }
  114. /*
  115. Set the flags for a RLCA/RLA/RRCA/RRA instruction.
  116. */
  117. static inline void set_flags_bitrota(Z80 *z80, uint8_t bit)
  118. {
  119. uint8_t a = z80->regs.a;
  120. set_flags(z80, bit, 0, 0, F3(a), 0, F5(a), 0, 0, 0x3B);
  121. }
  122. /*
  123. Set the flags for a RLC/RL/RRC/RR/SLA/SRA/SL1/SRL instruction.
  124. */
  125. static inline void set_flags_bitshift(Z80 *z80, uint8_t res, uint8_t bit)
  126. {
  127. set_flags(z80, bit, 0, PARITY(res), F3(res), 0, F5(res), ZERO(res),
  128. SIGN(res), 0xFF);
  129. }
  130. /*
  131. Set the flags for a DAA instruction.
  132. */
  133. static inline void set_flags_daa(Z80 *z80, uint8_t old, uint8_t adjust)
  134. {
  135. uint8_t res = z80->regs.a;
  136. bool c = adjust >= 0x60;
  137. bool h = get_flag(z80, FLAG_SUBTRACT) ?
  138. (get_flag(z80, FLAG_HALFCARRY) && (old & 0x0F) < 0x06) :
  139. ((old & 0x0F) > 0x09);
  140. set_flags(z80, c, 0, PARITY(res), F3(res), h, F5(res), ZERO(res),
  141. SIGN(res), 0xFD);
  142. }
  143. /*
  144. Set the flags for a CPL instruction.
  145. */
  146. static inline void set_flags_cpl(Z80 *z80)
  147. {
  148. uint8_t res = z80->regs.a;
  149. set_flags(z80, 0, 1, 0, F3(res), 1, F5(res), 0, 0, 0x3A);
  150. }
  151. /*
  152. Set the flags for a NEG instruction.
  153. */
  154. static inline void set_flags_neg(Z80 *z80)
  155. {
  156. uint8_t res = z80->regs.a;
  157. uint8_t val = -res;
  158. set_flags(z80, CARRY(0, -, val), SUB, OV_SUB(0, val, res), F3(res),
  159. HALF(0, -, val), F5(res), ZERO(res), SIGN(res), 0xFF);
  160. }
  161. /*
  162. Set the flags for a CCF instruction.
  163. */
  164. static inline void set_flags_ccf(Z80 *z80)
  165. {
  166. uint8_t val = z80->regs.a;
  167. bool c = get_flag(z80, FLAG_CARRY);
  168. set_flags(z80, 1 - c, 0, 0, F3(val), c, F5(val), 0, 0, 0x3B);
  169. }
  170. /*
  171. Set the flags for a SCF instruction.
  172. */
  173. static inline void set_flags_scf(Z80 *z80)
  174. {
  175. uint8_t val = z80->regs.a;
  176. set_flags(z80, 1, 0, 0, F3(val), 0, F5(val), 0, 0, 0x3B);
  177. }
  178. /*
  179. Set the flags for a LDI/LDIR/LDD/LDDR instruction.
  180. */
  181. static inline void set_flags_blockxfer(Z80 *z80, uint8_t val)
  182. {
  183. bool pv = z80->regs.bc != 0;
  184. uint8_t res = val + z80->regs.a;
  185. set_flags(z80, 0, 0, pv, res & 0x08, 0, res & 0x02, 0, 0, 0x3E);
  186. }
  187. /*
  188. Set the flags for an IN instruction.
  189. */
  190. static inline void set_flags_in(Z80 *z80, uint8_t val)
  191. {
  192. set_flags(z80, 0, 0, PARITY(val), F3(val), 0, F5(val), ZERO(val),
  193. SIGN(val), 0xFE);
  194. }
  195. /*
  196. Set the flags for an INI/INIR/IND/INDR/OUTI/OTIR/OUTD/OTDR instruction.
  197. */
  198. static inline void set_flags_blockio(Z80 *z80)
  199. {
  200. set_flags_dec(z80, z80->regs.b);
  201. }
  202. #undef POS
  203. #undef NEG
  204. #undef CARRY
  205. #undef HALF
  206. #undef ZERO
  207. #undef SIGN
  208. #undef SUB
  209. #undef CARRY2
  210. #undef OV_ADD
  211. #undef OV_SUB
  212. #undef PARITY
  213. #undef F3
  214. #undef F5