pico.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * PicoDrive
  3. * (C) notaz, 2008
  4. *
  5. * This work is licensed under the terms of MAME license.
  6. * See COPYING file in the top-level directory.
  7. */
  8. #include "../pico_int.h"
  9. // x: 0x03c - 0x19d
  10. // y: 0x1fc - 0x2f7
  11. // 0x2f8 - 0x3f3
  12. picohw_state PicoPicohw;
  13. static int prev_line_cnt_irq3 = 0, prev_line_cnt_irq5 = 0;
  14. static int fifo_bytes_line = (16000<<16)/60/262/2;
  15. static const int guessed_rates[] = { 8000, 14000, 12000, 14000, 16000, 18000, 16000, 16000 }; // ?
  16. #define PICOHW_FIFO_IRQ_THRESHOLD 12
  17. PICO_INTERNAL void PicoReratePico(void)
  18. {
  19. int rate = guessed_rates[PicoPicohw.r12 & 7];
  20. if (Pico.m.pal)
  21. fifo_bytes_line = (rate<<16)/50/312/2;
  22. else fifo_bytes_line = (rate<<16)/60/262/2;
  23. PicoPicoPCMRerate(rate);
  24. }
  25. static void PicoLinePico(void)
  26. {
  27. PicoPicohw.line_counter++;
  28. #if 1
  29. if ((PicoPicohw.r12 & 0x4003) && PicoPicohw.line_counter - prev_line_cnt_irq3 > 200) {
  30. prev_line_cnt_irq3 = PicoPicohw.line_counter;
  31. // just a guess/hack, allows 101 Dalmantians to boot
  32. elprintf(EL_PICOHW, "irq3");
  33. SekInterrupt(3);
  34. return;
  35. }
  36. #endif
  37. if (PicoPicohw.fifo_bytes > 0)
  38. {
  39. PicoPicohw.fifo_line_bytes += fifo_bytes_line;
  40. if (PicoPicohw.fifo_line_bytes >= (1<<16)) {
  41. PicoPicohw.fifo_bytes -= PicoPicohw.fifo_line_bytes >> 16;
  42. PicoPicohw.fifo_line_bytes &= 0xffff;
  43. if (PicoPicohw.fifo_bytes < 0)
  44. PicoPicohw.fifo_bytes = 0;
  45. }
  46. }
  47. else
  48. PicoPicohw.fifo_line_bytes = 0;
  49. #if 1
  50. if (PicoPicohw.fifo_bytes_prev >= PICOHW_FIFO_IRQ_THRESHOLD &&
  51. PicoPicohw.fifo_bytes < PICOHW_FIFO_IRQ_THRESHOLD) {
  52. prev_line_cnt_irq3 = PicoPicohw.line_counter; // ?
  53. elprintf(EL_PICOHW, "irq3, fb=%i", PicoPicohw.fifo_bytes);
  54. SekInterrupt(3);
  55. }
  56. PicoPicohw.fifo_bytes_prev = PicoPicohw.fifo_bytes;
  57. #endif
  58. #if 0
  59. if (PicoPicohw.line_counter - prev_line_cnt_irq5 > 512) {
  60. prev_line_cnt_irq5 = PicoPicohw.line_counter;
  61. elprintf(EL_PICOHW, "irq5");
  62. SekInterrupt(5);
  63. }
  64. #endif
  65. }
  66. static void PicoResetPico(void)
  67. {
  68. PicoPicoPCMReset();
  69. PicoPicohw.xpcm_ptr = PicoPicohw.xpcm_buffer;
  70. }
  71. PICO_INTERNAL void PicoInitPico(void)
  72. {
  73. elprintf(EL_STATUS, "Pico startup");
  74. PicoLineHook = PicoLinePico;
  75. PicoResetHook = PicoResetPico;
  76. PicoAHW = PAHW_PICO;
  77. memset(&PicoPicohw, 0, sizeof(PicoPicohw));
  78. PicoPicohw.pen_pos[0] = 0x03c + 320/2;
  79. PicoPicohw.pen_pos[1] = 0x200 + 240/2;
  80. prev_line_cnt_irq3 = prev_line_cnt_irq5 = 0;
  81. // map version register
  82. PicoDetectRegion();
  83. switch (Pico.m.hardware >> 6) {
  84. case 0: PicoPicohw.r1 = 0x00; break;
  85. case 1: PicoPicohw.r1 = 0x00; break;
  86. case 2: PicoPicohw.r1 = 0x40; break;
  87. case 3: PicoPicohw.r1 = 0x20; break;
  88. }
  89. }