svp.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * The SVP chip emulator
  3. *
  4. * Copyright (c) Gražvydas "notaz" Ignotas, 2008
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * * Neither the name of the organization nor the
  14. * names of its contributors may be used to endorse or promote products
  15. * derived from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  18. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  23. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  24. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  25. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  26. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #include "../../pico_int.h"
  29. #include "../../cpu/drc/cmn.h"
  30. #include "compiler.h"
  31. svp_t *svp = NULL;
  32. int PicoSVPCycles = 850; // cycles/line, just a guess
  33. static int svp_dyn_ready = 0;
  34. /* save state stuff */
  35. typedef enum {
  36. CHUNK_IRAM = CHUNK_CARTHW,
  37. CHUNK_DRAM,
  38. CHUNK_SSP
  39. } chunk_name_e;
  40. static carthw_state_chunk svp_states[] =
  41. {
  42. { CHUNK_IRAM, 0x800, NULL },
  43. { CHUNK_DRAM, sizeof(svp->dram), NULL },
  44. { CHUNK_SSP, sizeof(svp->ssp1601) - sizeof(svp->ssp1601.drc), NULL },
  45. { 0, 0, NULL }
  46. };
  47. static void PicoSVPReset(void)
  48. {
  49. elprintf(EL_SVP, "SVP reset");
  50. memcpy(svp->iram_rom + 0x800, Pico.rom + 0x800, 0x20000 - 0x800);
  51. ssp1601_reset(&svp->ssp1601);
  52. #ifndef PSP
  53. if ((PicoOpt&POPT_EN_SVP_DRC) && svp_dyn_ready)
  54. ssp1601_dyn_reset(&svp->ssp1601);
  55. #endif
  56. }
  57. static void PicoSVPLine(void)
  58. {
  59. int count = 1;
  60. #if defined(ARM) || defined(PSP)
  61. // performance hack
  62. static int delay_lines = 0;
  63. delay_lines++;
  64. if ((Pico.m.scanline&0xf) != 0xf && Pico.m.scanline != 261 && Pico.m.scanline != 311)
  65. return;
  66. count = delay_lines;
  67. delay_lines = 0;
  68. #endif
  69. #ifndef PSP
  70. if ((PicoOpt&POPT_EN_SVP_DRC) && svp_dyn_ready)
  71. ssp1601_dyn_run(PicoSVPCycles * count);
  72. else
  73. #endif
  74. {
  75. ssp1601_run(PicoSVPCycles * count);
  76. svp_dyn_ready = 0; // just in case
  77. }
  78. // test mode
  79. //if (Pico.m.frame_count == 13) PicoPad[0] |= 0xff;
  80. }
  81. static int PicoSVPDma(unsigned int source, int len, unsigned short **srcp, unsigned short **limitp)
  82. {
  83. if (source < Pico.romsize) // Rom
  84. {
  85. source -= 2;
  86. *srcp = (unsigned short *)(Pico.rom + (source&~1));
  87. *limitp = (unsigned short *)(Pico.rom + Pico.romsize);
  88. return 1;
  89. }
  90. else if ((source & 0xfe0000) == 0x300000)
  91. {
  92. elprintf(EL_VDPDMA|EL_SVP, "SVP DmaSlow from %06x, len=%i", source, len);
  93. source &= 0x1fffe;
  94. source -= 2;
  95. *srcp = (unsigned short *)(svp->dram + source);
  96. *limitp = (unsigned short *)(svp->dram + sizeof(svp->dram));
  97. return 1;
  98. }
  99. else
  100. elprintf(EL_VDPDMA|EL_SVP|EL_ANOMALY, "SVP FIXME unhandled DmaSlow from %06x, len=%i", source, len);
  101. return 0;
  102. }
  103. void PicoSVPInit(void)
  104. {
  105. #ifndef PSP
  106. // this is to unmap tcache and make
  107. // mem available for large ROMs, MCD, etc.
  108. drc_cmn_cleanup();
  109. #endif
  110. }
  111. static void PicoSVPExit(void)
  112. {
  113. #ifndef PSP
  114. ssp1601_dyn_exit();
  115. #endif
  116. }
  117. void PicoSVPStartup(void)
  118. {
  119. int ret;
  120. elprintf(EL_STATUS, "SVP startup");
  121. ret = PicoCartResize(Pico.romsize + sizeof(*svp));
  122. if (ret != 0) {
  123. elprintf(EL_STATUS|EL_SVP, "OOM for SVP data");
  124. return;
  125. }
  126. svp = (void *) ((char *)Pico.rom + Pico.romsize);
  127. memset(svp, 0, sizeof(*svp));
  128. // init SVP compiler
  129. svp_dyn_ready = 0;
  130. #ifndef PSP
  131. if (PicoOpt & POPT_EN_SVP_DRC) {
  132. if (ssp1601_dyn_startup())
  133. return;
  134. svp_dyn_ready = 1;
  135. }
  136. #endif
  137. // init ok, setup hooks..
  138. PicoCartMemSetup = PicoSVPMemSetup;
  139. PicoDmaHook = PicoSVPDma;
  140. PicoResetHook = PicoSVPReset;
  141. PicoLineHook = PicoSVPLine;
  142. PicoCartUnloadHook = PicoSVPExit;
  143. // save state stuff
  144. svp_states[0].ptr = svp->iram_rom;
  145. svp_states[1].ptr = svp->dram;
  146. svp_states[2].ptr = &svp->ssp1601;
  147. carthw_chunks = svp_states;
  148. PicoAHW |= PAHW_SVP;
  149. }