host sample rate support for Pico
[picodrive.git] / Pico / Pico / Pico.c
1 #include "../PicoInt.h"
2
3 // x: 0x03c - 0x19d
4 // y: 0x1fc - 0x2f7
5 //    0x2f8 - 0x3f3
6 picohw_state PicoPicohw;
7
8 static int prev_line_cnt_irq3 = 0, prev_line_cnt_irq5 = 0;
9 static int fifo_bytes_line = (16000<<16)/60/262/2; // fifo bytes/line. FIXME: other rates, modes
10
11 PICO_INTERNAL void PicoReratePico(void)
12 {
13   if (Pico.m.pal)
14        fifo_bytes_line = (16000<<16)/50/312/2;
15   else fifo_bytes_line = (16000<<16)/60/262/2;
16   PicoPicoPCMRerate();
17 }
18
19 static void PicoLinePico(int count)
20 {
21   PicoPicohw.line_counter += count;
22
23 #if 1
24   if ((PicoPicohw.r12 & 0x4003) && PicoPicohw.line_counter - prev_line_cnt_irq3 > 200) {
25     prev_line_cnt_irq3 = PicoPicohw.line_counter;
26     // just a guess/hack, allows 101 Dalmantians to boot
27     elprintf(EL_ANOMALY, "irq3");
28     SekInterrupt(3);
29     return;
30   }
31
32   if (PicoPicohw.fifo_bytes == 16) {
33     prev_line_cnt_irq3 = PicoPicohw.line_counter;
34     elprintf(EL_ANOMALY, "irq3, fb=%i", PicoPicohw.fifo_bytes);
35     SekInterrupt(3);
36     PicoPicohw.fifo_bytes--;
37     return;
38   }
39 #endif
40
41   if (PicoPicohw.fifo_bytes > 0)
42   {
43     PicoPicohw.fifo_line_bytes += fifo_bytes_line * count;
44     if (PicoPicohw.fifo_line_bytes >= (1<<16)) {
45       PicoPicohw.fifo_bytes -= PicoPicohw.fifo_line_bytes >> 16;
46       PicoPicohw.fifo_line_bytes &= 0xffff;
47       if (PicoPicohw.fifo_bytes < 0)
48         PicoPicohw.fifo_bytes = 0;
49     }
50   }
51   else
52     PicoPicohw.fifo_line_bytes = 0;
53
54 #if 0
55   if (PicoPicohw.line_counter - prev_line_cnt_irq5 > 512) {
56     prev_line_cnt_irq5 = PicoPicohw.line_counter;
57     elprintf(EL_ANOMALY, "irq5");
58     SekInterrupt(5);
59   }
60 #endif
61 }
62
63 static void PicoResetPico(void)
64 {
65   PicoPicoPCMReset();
66   PicoPicohw.xpcm_ptr = PicoPicohw.xpcm_buffer;
67 }
68
69 PICO_INTERNAL int PicoInitPico(void)
70 {
71   elprintf(EL_STATUS, "Pico detected");
72   PicoLineHook = PicoLinePico;
73   PicoResetHook = PicoResetPico;
74
75   PicoAHW = PAHW_PICO;
76   memset(&PicoPicohw, 0, sizeof(PicoPicohw));
77   PicoPicohw.pen_pos[0] = 0x03c + 352/2;
78   PicoPicohw.pen_pos[1] = 0x200 + 252/2;
79   prev_line_cnt_irq3 = prev_line_cnt_irq5 = 0;
80
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
90   return 0;
91 }
92