svp.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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/pico_int.h>
  29. #include <cpu/drc/cmn.h>
  30. #include "compiler.h"
  31. #define SVP_CYCLES_LINE 850
  32. svp_t *svp = NULL;
  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. #ifdef _SVP_DRC
  53. if ((PicoIn.opt & POPT_EN_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. #ifdef _SVP_DRC
  70. if ((PicoIn.opt & POPT_EN_DRC) && svp_dyn_ready)
  71. ssp1601_dyn_run(SVP_CYCLES_LINE * count);
  72. else
  73. #endif
  74. {
  75. ssp1601_run(SVP_CYCLES_LINE * count);
  76. svp_dyn_ready = 0; // just in case
  77. }
  78. // test mode
  79. //if (Pico.m.frame_count == 13) PicoIn.pad[0] |= 0xff;
  80. }
  81. static int PicoSVPDma(u32 source, int len, unsigned short **base, u32 *mask)
  82. {
  83. if (source < Pico.romsize) // Rom
  84. {
  85. *base = (unsigned short *)(Pico.rom + (source & 0xfe0000));
  86. *mask = 0x1ffff;
  87. return source - 2;
  88. }
  89. else if ((source & 0xfe0000) == 0x300000)
  90. {
  91. elprintf(EL_VDPDMA|EL_SVP, "SVP DmaSlow from %06x, len=%i", source, len);
  92. *base = (unsigned short *)svp->dram;
  93. *mask = 0x1ffff;
  94. return source - 2;
  95. }
  96. else
  97. elprintf(EL_VDPDMA|EL_SVP|EL_ANOMALY, "SVP FIXME unhandled DmaSlow from %06x, len=%i", source, len);
  98. return 0;
  99. }
  100. void PicoSVPInit(void)
  101. {
  102. #ifdef _SVP_DRC
  103. // this is to unmap tcache and make
  104. // mem available for large ROMs, MCD, etc.
  105. drc_cmn_cleanup();
  106. #endif
  107. }
  108. static void PicoSVPExit(void)
  109. {
  110. #ifdef _SVP_DRC
  111. ssp1601_dyn_exit();
  112. #endif
  113. }
  114. void PicoSVPStartup(void)
  115. {
  116. int ret;
  117. elprintf(EL_STATUS, "SVP startup");
  118. ret = PicoCartResize(Pico.romsize + sizeof(*svp));
  119. if (ret != 0) {
  120. elprintf(EL_STATUS|EL_SVP, "OOM for SVP data");
  121. return;
  122. }
  123. svp = (void *) ((char *)Pico.rom + Pico.romsize);
  124. memset(svp, 0, sizeof(*svp));
  125. // init SVP compiler
  126. svp_dyn_ready = 0;
  127. #ifdef _SVP_DRC
  128. if (PicoIn.opt & POPT_EN_DRC) {
  129. if (ssp1601_dyn_startup())
  130. return;
  131. svp_dyn_ready = 1;
  132. }
  133. #endif
  134. // init ok, setup hooks..
  135. PicoCartMemSetup = PicoSVPMemSetup;
  136. PicoDmaHook = PicoSVPDma;
  137. PicoResetHook = PicoSVPReset;
  138. PicoLineHook = PicoSVPLine;
  139. PicoCartUnloadHook = PicoSVPExit;
  140. // save state stuff
  141. svp_states[0].ptr = svp->iram_rom;
  142. svp_states[1].ptr = svp->dram;
  143. svp_states[2].ptr = &svp->ssp1601;
  144. carthw_chunks = svp_states;
  145. PicoIn.AHW |= PAHW_SVP;
  146. }