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