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.
 
 
 
 
 

119 line
2.8 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. #include "io.h"
  4. #include "logging.h"
  5. /*
  6. Initialize an IO object.
  7. */
  8. void io_init(IO *io, VDP *vdp, PSG *psg)
  9. {
  10. io->vdp = vdp;
  11. io->psg = psg;
  12. }
  13. /*
  14. "Power on" the IO object.
  15. */
  16. void io_power(IO *io)
  17. {
  18. io->ports[0x00] = 0xC0; // Overseas mode, NTSC
  19. io->ports[0x01] = 0x7F;
  20. io->ports[0x02] = 0xFF;
  21. io->ports[0x03] = 0x00;
  22. io->ports[0x04] = 0xFF;
  23. io->ports[0x05] = 0x00;
  24. }
  25. /*
  26. Return whether the IRQ line is currently active.
  27. */
  28. bool io_check_irq(IO *io)
  29. {
  30. return vdp_assert_irq(io->vdp);
  31. }
  32. /*
  33. Read from one of the system ports, which are numbered from 0x00 to 0x06.
  34. */
  35. static uint8_t read_system_port(IO *io, uint8_t port)
  36. {
  37. switch (port) {
  38. case 0x00:
  39. // TODO: MSB is state of START button
  40. return (io->ports[port] & 0x7F) | (0 << 7);
  41. case 0x01:
  42. case 0x02:
  43. case 0x03:
  44. case 0x04:
  45. case 0x05:
  46. return io->ports[port];
  47. }
  48. return 0xFF;
  49. }
  50. /*
  51. Write to one of the system ports, which are numbered from 0x00 to 0x06.
  52. */
  53. static void write_system_port(IO *io, uint8_t port, uint8_t value)
  54. {
  55. switch (port) {
  56. case 0x01:
  57. case 0x02:
  58. case 0x03:
  59. io->ports[port] = value;
  60. break;
  61. case 0x05:
  62. io->ports[port] = value & 0xF8;
  63. break;
  64. case 0x06:
  65. psg_stereo(io->psg, value);
  66. break;
  67. }
  68. }
  69. /*
  70. Read and return a byte from the given port.
  71. */
  72. uint8_t io_port_read(IO *io, uint8_t port)
  73. {
  74. if (port <= 0x06)
  75. return read_system_port(io, port);
  76. else if (port <= 0x3F)
  77. return 0xFF;
  78. else if (port <= 0x7F && !(port % 2))
  79. return io->vdp->v_counter;
  80. else if (port <= 0x7F)
  81. return io->vdp->h_counter;
  82. else if (port <= 0xBF && !(port % 2))
  83. return vdp_read_data(io->vdp);
  84. else if (port <= 0xBF)
  85. return vdp_read_control(io->vdp);
  86. else if (port == 0xCD || port == 0xDC)
  87. return 0xFF; // TODO: Return the I/O port A/B register
  88. else if (port == 0xC1 || port == 0xDD)
  89. return 0xFF; // TODO: Return the I/O port B/misc. register
  90. else
  91. return 0xFF;
  92. }
  93. /*
  94. Write a byte to the given port.
  95. */
  96. void io_port_write(IO *io, uint8_t port, uint8_t value)
  97. {
  98. if (port <= 0x06)
  99. write_system_port(io, port, value);
  100. else if (port <= 0x3F && !(port % 2))
  101. return; // TODO: Write to memory control register
  102. else if (port <= 0x3F)
  103. return; // TODO: Write to I/O control register
  104. else if (port <= 0x7F)
  105. psg_write(io->psg, value);
  106. else if (port <= 0xBF && !(port % 2))
  107. vdp_write_data(io->vdp, value);
  108. else if (port <= 0xBF)
  109. vdp_write_control(io->vdp, value);
  110. }