An emulator, assembler, and disassembler for the Sega Game Gear
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.
 
 
 
 
 

101 lignes
2.6 KiB

  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 OV_ADD(lh, rh, res) \
  11. (POS(lh) && POS(rh) && NEG(res) || NEG(lh) && NEG(rh) && POS(res))
  12. #define OV_SUB(lh, rh, res) \
  13. (POS(lh) && NEG(rh) && NEG(res) || NEG(lh) && POS(rh) && POS(res))
  14. #define PARITY(x) (!(__builtin_popcount(x) % 2))
  15. #define F3(x) ((x) & 0x08)
  16. #define F5(x) ((x) & 0x20)
  17. /*
  18. Set the flags for an 8-bit ADD or ADC instruction.
  19. */
  20. static inline void set_flags_add8(Z80 *z80, uint16_t rh)
  21. {
  22. uint8_t lh = z80->regs.a;
  23. uint8_t res = lh + rh;
  24. set_flags(z80, CARRY(lh, +, rh), !SUB, OV_ADD(lh, rh, res), F3(res),
  25. HALF(lh, +, rh), F5(res), ZERO(res), SIGN(res), 0xFF);
  26. }
  27. /*
  28. Set the flags for an 8-bit SUB or SBC instruction.
  29. */
  30. static inline void set_flags_sub8(Z80 *z80, uint16_t rh)
  31. {
  32. uint8_t lh = z80->regs.a;
  33. uint8_t res = lh - rh;
  34. set_flags(z80, CARRY(lh, -, rh), SUB, OV_SUB(lh, rh, res), F3(res),
  35. HALF(lh, -, rh), F5(res), ZERO(res), SIGN(res), 0xFF);
  36. }
  37. /*
  38. Set the flags for a CP instruction.
  39. */
  40. static inline void set_flags_cp(Z80 *z80, uint16_t rh)
  41. {
  42. uint8_t lh = z80->regs.a;
  43. uint8_t res = lh - rh;
  44. set_flags(z80, CARRY(lh, -, rh), SUB, OV_SUB(lh, rh, res), F3(rh),
  45. HALF(lh, -, rh), F5(rh), ZERO(res), SIGN(res), 0xFF);
  46. }
  47. /*
  48. Set the flags for an AND, XOR, or OR instruction.
  49. */
  50. static inline void set_flags_bitwise(Z80 *z80, uint8_t res, bool is_and)
  51. {
  52. set_flags(z80, 0, 0, PARITY(res), F3(res), is_and, F5(res), ZERO(res),
  53. SIGN(res), 0xFF);
  54. }
  55. /*
  56. Set the flags for an 8-bit INC instruction.
  57. */
  58. static inline void set_flags_inc(Z80 *z80, uint8_t val)
  59. {
  60. uint8_t res = val + 1;
  61. set_flags(z80, 0, !SUB, OV_ADD(val, 1, res), F3(res), HALF(val, +, 1),
  62. F5(res), ZERO(res), SIGN(res), 0xFE);
  63. }
  64. /*
  65. Set the flags for an 8-bit DEC instruction.
  66. */
  67. static inline void set_flags_dec(Z80 *z80, uint8_t val)
  68. {
  69. uint8_t res = val - 1;
  70. set_flags(z80, 0, SUB, OV_SUB(val, 1, res), F3(res), HALF(val, -, 1),
  71. F5(res), ZERO(res), SIGN(res), 0xFE);
  72. }
  73. // set_flags(Z80 *z80,
  74. // bool c, bool n, bool pv, bool f3, bool h, bool f5, bool z, bool s,
  75. // uint8_t mask)
  76. #undef POS
  77. #undef NEG
  78. #undef CARRY
  79. #undef HALF
  80. #undef ZERO
  81. #undef SIGN
  82. #undef SUB
  83. #undef OV_ADD
  84. #undef OV_SUB
  85. #undef PARITY
  86. #undef F3
  87. #undef F5