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.
 
 
 
 
 

146 lignes
3.3 KiB

  1. /* Copyright (C) 2014-2017 Ben Kurtovic <ben.kurtovic@gmail.com>
  2. Released under the terms of the MIT License. See LICENSE for details. */
  3. #include "io.h"
  4. #include "logging.h"
  5. /*
  6. Initialize an IO object.
  7. */
  8. void io_init(IO *io, MMU *mmu, VDP *vdp, PSG *psg)
  9. {
  10. io->vdp = vdp;
  11. io->mmu = mmu;
  12. io->psg = psg;
  13. }
  14. /*
  15. "Power on" the IO object.
  16. */
  17. void io_power(IO *io)
  18. {
  19. io->ports[0x00] = 0xC0; // Overseas mode, NTSC
  20. io->ports[0x01] = 0x7F;
  21. io->ports[0x02] = 0xFF;
  22. io->ports[0x03] = 0x00;
  23. io->ports[0x04] = 0xFF;
  24. io->ports[0x05] = 0x00;
  25. io->buttons = 0xFF;
  26. io->start = true;
  27. }
  28. /*
  29. Return whether the IRQ line is currently active.
  30. */
  31. bool io_check_irq(IO *io)
  32. {
  33. return vdp_assert_irq(io->vdp);
  34. }
  35. /*
  36. Set the state of the given joystick button.
  37. */
  38. void io_set_button(IO *io, uint8_t button, bool state)
  39. {
  40. io->buttons = (io->buttons & ~(1 << button)) | ((!state) << button);
  41. }
  42. /*
  43. Set the state of the start button.
  44. */
  45. void io_set_start(IO *io, bool state)
  46. {
  47. io->start = !state;
  48. }
  49. /*
  50. Read from one of the system ports, which are numbered from 0x00 to 0x06.
  51. */
  52. static uint8_t read_system_port(IO *io, uint8_t port)
  53. {
  54. switch (port) {
  55. case 0x00:
  56. return (io->ports[port] & 0x7F) | (io->start << 7);
  57. case 0x01:
  58. case 0x02:
  59. case 0x03:
  60. case 0x04:
  61. case 0x05:
  62. return io->ports[port];
  63. }
  64. return 0xFF;
  65. }
  66. /*
  67. Write to one of the system ports, which are numbered from 0x00 to 0x06.
  68. */
  69. static void write_system_port(IO *io, uint8_t port, uint8_t value)
  70. {
  71. switch (port) {
  72. case 0x01:
  73. case 0x02:
  74. case 0x03:
  75. io->ports[port] = value;
  76. break;
  77. case 0x05:
  78. io->ports[port] = value & 0xF8;
  79. break;
  80. case 0x06:
  81. psg_stereo(io->psg, value);
  82. break;
  83. }
  84. }
  85. /*
  86. Write to the memory control port, $3E.
  87. */
  88. static void write_memory_control(IO *io, uint8_t value)
  89. {
  90. io->mmu->bios_enabled = !(value & 0x08);
  91. }
  92. /*
  93. Read and return a byte from the given port.
  94. */
  95. uint8_t io_port_read(IO *io, uint8_t port)
  96. {
  97. if (port <= 0x06)
  98. return read_system_port(io, port);
  99. else if (port <= 0x3F)
  100. return 0xFF;
  101. else if (port <= 0x7F && !(port % 2))
  102. return io->vdp->v_counter;
  103. else if (port <= 0x7F)
  104. return io->vdp->h_counter;
  105. else if (port <= 0xBF && !(port % 2))
  106. return vdp_read_data(io->vdp);
  107. else if (port <= 0xBF)
  108. return vdp_read_control(io->vdp);
  109. else if (port == 0xCD || port == 0xDC)
  110. return io->buttons;
  111. else if (port == 0xC1 || port == 0xDD)
  112. return 0xFF; // B/Misc port, always set (unless in SMS mode?)
  113. else
  114. return 0xFF;
  115. }
  116. /*
  117. Write a byte to the given port.
  118. */
  119. void io_port_write(IO *io, uint8_t port, uint8_t value)
  120. {
  121. if (port <= 0x06)
  122. write_system_port(io, port, value);
  123. else if (port <= 0x3F && !(port % 2))
  124. write_memory_control(io, value);
  125. else if (port <= 0x3F)
  126. return; // TODO: Write to I/O control register
  127. else if (port <= 0x7F)
  128. psg_write(io->psg, value);
  129. else if (port <= 0xBF && !(port % 2))
  130. vdp_write_data(io->vdp, value);
  131. else if (port <= 0xBF)
  132. vdp_write_control(io->vdp, value);
  133. }