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

127 lines
3.3 KiB

  1. /* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
  2. Released under the terms of the MIT License. See LICENSE for details. */
  3. #include "logging.h"
  4. #include "z80.h"
  5. #define FLAG_CARRY 0
  6. #define FLAG_SUBTRACT 1
  7. #define FLAG_PARITY 2
  8. #define FLAG_OVERFLOW 2
  9. #define FLAG_HALFCARRY 4
  10. #define FLAG_ZERO 6
  11. #define FLAG_SIGN 7
  12. /*
  13. Initialize a Z80 object.
  14. */
  15. void z80_init(Z80 *z80, uint64_t clock_speed)
  16. {
  17. z80->clock_speed = clock_speed;
  18. }
  19. /*
  20. Power on the Z80, setting registers to their default values.
  21. */
  22. void z80_power(Z80 *z80)
  23. {
  24. Z80RegFile *regfile = &z80->regfile;
  25. regfile->a = regfile->f = 0xFF;
  26. regfile->b = regfile->c = 0xFF;
  27. regfile->d = regfile->e = 0xFF;
  28. regfile->h = regfile->l = 0xFF;
  29. regfile->a_ = regfile->f_ = 0xFF;
  30. regfile->b_ = regfile->c_ = 0xFF;
  31. regfile->d_ = regfile->e_ = 0xFF;
  32. regfile->h_ = regfile->l_ = 0xFF;
  33. regfile->ix = 0xFFFF;
  34. regfile->iy = 0xFFFF;
  35. regfile->sp = 0xFFFF;
  36. regfile->pc = 0x0000;
  37. regfile->i = 0xFF;
  38. regfile->r = 0xFF;
  39. regfile->im_a = regfile->im_b = 0;
  40. regfile->iff1 = regfile->iff2 = 0;
  41. }
  42. /*
  43. Return whether a particular flag is set in the F register.
  44. */
  45. static inline bool get_flag(Z80 *z80, uint8_t flag)
  46. {
  47. return z80->regfile.f & (1 << flag);
  48. }
  49. /*
  50. Return whether a particular flag is set in the F' register.
  51. */
  52. static inline bool get_shadow_flag(Z80 *z80, uint8_t flag)
  53. {
  54. return z80->regfile.f_ & (1 << flag);
  55. }
  56. /*
  57. Return the CPU's current interrupt mode.
  58. */
  59. static inline uint8_t get_interrupt_mode(Z80 *z80)
  60. {
  61. if (!z80->regfile.im_a)
  62. return 0;
  63. if (!z80->regfile.im_b)
  64. return 1;
  65. return 2;
  66. }
  67. #ifdef DEBUG_MODE
  68. /*
  69. DEBUG FUNCTION: Print out all register values to stdout.
  70. */
  71. void z80_dump_registers(Z80 *z80)
  72. {
  73. Z80RegFile *regfile = &z80->regfile;
  74. DEBUG("Dumping Z80 register values:")
  75. DEBUG("- AF: 0x%02X%02X (C: %u, N: %u, P/V: %u, H: %u, Z: %u, S: %u)",
  76. regfile->a, regfile->f,
  77. get_flag(z80, FLAG_CARRY),
  78. get_flag(z80, FLAG_SUBTRACT),
  79. get_flag(z80, FLAG_PARITY),
  80. get_flag(z80, FLAG_HALFCARRY),
  81. get_flag(z80, FLAG_ZERO),
  82. get_flag(z80, FLAG_SIGN))
  83. DEBUG("- BC: 0x%02X%02X", regfile->b, regfile->c)
  84. DEBUG("- DE: 0x%02X%02X", regfile->d, regfile->e)
  85. DEBUG("- HL: 0x%02X%02X", regfile->h, regfile->l)
  86. DEBUG("- AF': 0x%02X%02X (C: %u, N: %u, P/V: %u, H: %u, Z: %u, S: %u)",
  87. regfile->a_, regfile->f_,
  88. get_shadow_flag(z80, FLAG_CARRY),
  89. get_shadow_flag(z80, FLAG_SUBTRACT),
  90. get_shadow_flag(z80, FLAG_PARITY),
  91. get_shadow_flag(z80, FLAG_HALFCARRY),
  92. get_shadow_flag(z80, FLAG_ZERO),
  93. get_shadow_flag(z80, FLAG_SIGN))
  94. DEBUG("- BC': 0x%02X%02X", regfile->b_, regfile->c_)
  95. DEBUG("- DE': 0x%02X%02X", regfile->d_, regfile->e_)
  96. DEBUG("- HL': 0x%02X%02X", regfile->h_, regfile->l_)
  97. DEBUG("- IX: 0x%04X", regfile->ix)
  98. DEBUG("- IY: 0x%04X", regfile->iy)
  99. DEBUG("- SP: 0x%04X", regfile->sp)
  100. DEBUG("- PC: 0x%04X", regfile->pc)
  101. DEBUG("- I: 0x%2X", regfile->i)
  102. DEBUG("- R: 0x%2X", regfile->r)
  103. DEBUG("- IM: 0b%u%u (mode: %u)", regfile->im_a, regfile->im_b, get_interrupt_mode(z80))
  104. DEBUG("- IFF1: %u", regfile->iff1)
  105. DEBUG("- IFF2: %u", regfile->iff2)
  106. }
  107. #endif