svp.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // The SVP chip emulator
  2. // (c) Copyright 2008, Grazvydas "notaz" Ignotas
  3. // Free for non-commercial use.
  4. // For commercial use, separate licencing terms must be obtained.
  5. #include "../../pico_int.h"
  6. #include "compiler.h"
  7. #if defined(__linux__) && defined(ARM)
  8. #include <sys/mman.h>
  9. #endif
  10. svp_t *svp = NULL;
  11. int PicoSVPCycles = 850; // cycles/line, just a guess
  12. static int svp_dyn_ready = 0;
  13. /* save state stuff */
  14. typedef enum {
  15. CHUNK_IRAM = CHUNK_CARTHW,
  16. CHUNK_DRAM,
  17. CHUNK_SSP
  18. } chunk_name_e;
  19. static carthw_state_chunk svp_states[] =
  20. {
  21. { CHUNK_IRAM, 0x800, NULL },
  22. { CHUNK_DRAM, sizeof(svp->dram), NULL },
  23. { CHUNK_SSP, sizeof(svp->ssp1601) - sizeof(svp->ssp1601.drc), NULL },
  24. { 0, 0, NULL }
  25. };
  26. static void PicoSVPReset(void)
  27. {
  28. elprintf(EL_SVP, "SVP reset");
  29. memcpy(svp->iram_rom + 0x800, Pico.rom + 0x800, 0x20000 - 0x800);
  30. ssp1601_reset(&svp->ssp1601);
  31. #ifndef PSP
  32. if ((PicoOpt&POPT_EN_SVP_DRC) && svp_dyn_ready)
  33. ssp1601_dyn_reset(&svp->ssp1601);
  34. #endif
  35. }
  36. static void PicoSVPLine(void)
  37. {
  38. int count = 1;
  39. #if defined(ARM) || defined(PSP)
  40. // performance hack
  41. static int delay_lines = 0;
  42. delay_lines++;
  43. if ((Pico.m.scanline&0xf) != 0xf && Pico.m.scanline != 261 && Pico.m.scanline != 311)
  44. return;
  45. count = delay_lines;
  46. delay_lines = 0;
  47. #endif
  48. #ifndef PSP
  49. if ((PicoOpt&POPT_EN_SVP_DRC) && svp_dyn_ready)
  50. ssp1601_dyn_run(PicoSVPCycles * count);
  51. else
  52. #endif
  53. {
  54. ssp1601_run(PicoSVPCycles * count);
  55. svp_dyn_ready = 0; // just in case
  56. }
  57. // test mode
  58. //if (Pico.m.frame_count == 13) PicoPad[0] |= 0xff;
  59. }
  60. static int PicoSVPDma(unsigned int source, int len, unsigned short **srcp, unsigned short **limitp)
  61. {
  62. if (source < Pico.romsize) // Rom
  63. {
  64. source -= 2;
  65. *srcp = (unsigned short *)(Pico.rom + (source&~1));
  66. *limitp = (unsigned short *)(Pico.rom + Pico.romsize);
  67. return 1;
  68. }
  69. else if ((source & 0xfe0000) == 0x300000)
  70. {
  71. elprintf(EL_VDPDMA|EL_SVP, "SVP DmaSlow from %06x, len=%i", source, len);
  72. source &= 0x1fffe;
  73. source -= 2;
  74. *srcp = (unsigned short *)(svp->dram + source);
  75. *limitp = (unsigned short *)(svp->dram + sizeof(svp->dram));
  76. return 1;
  77. }
  78. else
  79. elprintf(EL_VDPDMA|EL_SVP|EL_ANOMALY, "SVP FIXME unhandled DmaSlow from %06x, len=%i", source, len);
  80. return 0;
  81. }
  82. void PicoSVPInit(void)
  83. {
  84. #if defined(__linux__) && defined(ARM)
  85. int ret;
  86. ret = munmap(tcache, SSP_DRC_SIZE);
  87. printf("munmap tcache: %i\n", ret);
  88. #endif
  89. }
  90. static void PicoSVPShutdown(void)
  91. {
  92. #if defined(__linux__) && defined(ARM)
  93. // also unmap tcache
  94. PicoSVPInit();
  95. #endif
  96. }
  97. void PicoSVPStartup(void)
  98. {
  99. void *tmp;
  100. elprintf(EL_STATUS, "SVP startup");
  101. tmp = realloc(Pico.rom, 0x200000 + sizeof(*svp));
  102. if (tmp == NULL)
  103. {
  104. elprintf(EL_STATUS|EL_SVP, "OOM for SVP data");
  105. return;
  106. }
  107. //PicoOpt &= ~0x20000;
  108. Pico.rom = tmp;
  109. svp = (void *) ((char *)tmp + 0x200000);
  110. memset(svp, 0, sizeof(*svp));
  111. #if defined(__linux__) && defined(ARM)
  112. tmp = mmap(tcache, SSP_DRC_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
  113. printf("mmap tcache: %p, asked %p\n", tmp, tcache);
  114. #endif
  115. // init SVP compiler
  116. svp_dyn_ready = 0;
  117. #ifndef PSP
  118. if (PicoOpt&POPT_EN_SVP_DRC) {
  119. if (ssp1601_dyn_startup()) return;
  120. svp_dyn_ready = 1;
  121. }
  122. #endif
  123. // init ok, setup hooks..
  124. PicoCartMemSetup = PicoSVPMemSetup;
  125. PicoDmaHook = PicoSVPDma;
  126. PicoResetHook = PicoSVPReset;
  127. PicoLineHook = PicoSVPLine;
  128. PicoCartUnloadHook = PicoSVPShutdown;
  129. // save state stuff
  130. svp_states[0].ptr = svp->iram_rom;
  131. svp_states[1].ptr = svp->dram;
  132. svp_states[2].ptr = &svp->ssp1601;
  133. carthw_chunks = svp_states;
  134. PicoAHW |= PAHW_SVP;
  135. }