restore some hw regs on exit to startup values
[libpicofe.git] / gp2x / plat.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdarg.h>
5
6 #include "plat_gp2x.h"
7 #include "soc.h"
8 #include "warm.h"
9 #include "../common/plat.h"
10 #include "../common/readpng.h"
11 #include "../common/menu.h"
12 #include "../common/emu.h"
13 #include "../linux/sndout_oss.h"
14
15 #include <pico/pico.h>
16
17 /* GP2X local */
18 int default_cpu_clock;
19 void *gp2x_screens[4];
20
21 void gp2x_video_changemode(int bpp)
22 {
23         gp2x_video_changemode_ll(bpp);
24
25         gp2x_memset_all_buffers(0, 0, 320*240*2);
26         gp2x_video_flip();
27 }
28
29 static void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len)
30 {
31         char *dst;
32         if (buffers & (1<<0)) { dst = (char *)gp2x_screens[0] + offset; if (dst != data) memcpy(dst, data, len); }
33         if (buffers & (1<<1)) { dst = (char *)gp2x_screens[1] + offset; if (dst != data) memcpy(dst, data, len); }
34         if (buffers & (1<<2)) { dst = (char *)gp2x_screens[2] + offset; if (dst != data) memcpy(dst, data, len); }
35         if (buffers & (1<<3)) { dst = (char *)gp2x_screens[3] + offset; if (dst != data) memcpy(dst, data, len); }
36 }
37
38 void gp2x_memcpy_all_buffers(void *data, int offset, int len)
39 {
40         gp2x_memcpy_buffers(0xf, data, offset, len);
41 }
42
43 void gp2x_memset_all_buffers(int offset, int byte, int len)
44 {
45         memset((char *)gp2x_screens[0] + offset, byte, len);
46         memset((char *)gp2x_screens[1] + offset, byte, len);
47         memset((char *)gp2x_screens[2] + offset, byte, len);
48         memset((char *)gp2x_screens[3] + offset, byte, len);
49 }
50
51 void gp2x_make_fb_bufferable(int yes)
52 {
53         int ret = 0;
54         
55         yes = yes ? 1 : 0;
56         ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[0], 320*240*2);
57         ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[1], 320*240*2);
58         ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[2], 320*240*2);
59         ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[3], 320*240*2);
60
61         if (ret)
62                 fprintf(stderr, "could not make fb buferable.\n");
63         else
64                 printf("made fb buferable.\n");
65 }
66
67 /* common */
68 char cpu_clk_name[16] = "GP2X CPU clocks";
69
70 void plat_video_menu_enter(int is_rom_loaded)
71 {
72         if (is_rom_loaded)
73         {
74                 // darken the active framebuffer
75                 memset(g_screen_ptr, 0, 320*8*2);
76                 menu_darken_bg((char *)g_screen_ptr + 320*8*2, 320*224, 1);
77                 memset((char *)g_screen_ptr + 320*232*2, 0, 320*8*2);
78         }
79         else
80         {
81                 // should really only happen once, on startup..
82                 readpng(g_screen_ptr, "skin/background.png", READPNG_BG);
83         }
84
85         // copy to buffer2
86         gp2x_memcpy_buffers((1<<2), g_screen_ptr, 0, 320*240*2);
87
88         // switch to 16bpp
89         gp2x_video_changemode_ll(16);
90         gp2x_video_RGB_setscaling(0, 320, 240);
91         gp2x_video_flip2();
92 }
93
94 void plat_video_menu_begin(void)
95 {
96         memcpy(g_screen_ptr, gp2x_screens[2], 320*240*2);
97 }
98
99 void plat_video_menu_end(void)
100 {
101         // FIXME
102         // gp2x_video_flush_cache();
103         gp2x_video_flip2();
104 }
105
106 void plat_validate_config(void)
107 {
108         gp2x_soc_t soc;
109
110         soc = soc_detect();
111         if (soc != SOCID_MMSP2)
112                 PicoOpt &= ~POPT_EXT_FM;
113
114         if (currentConfig.gamma < 10 || currentConfig.gamma > 300)
115                 currentConfig.gamma = 100;
116
117         if (currentConfig.CPUclock < 10 || currentConfig.CPUclock > 1024)
118                 currentConfig.CPUclock = default_cpu_clock;
119 }
120
121 void plat_early_init(void)
122 {
123         gp2x_soc_t soc;
124
125         soc = soc_detect();
126         switch (soc)
127         {
128         case SOCID_MMSP2:
129                 default_cpu_clock = 200;
130                 break;
131         case SOCID_POLLUX:
132                 strcpy(cpu_clk_name, "Wiz CPU clock");
133                 default_cpu_clock = 533;
134                 break;
135         default:
136                 fprintf(stderr, "could not recognize SoC, bailing out.\n");
137                 exit(1);
138         }
139 }
140
141 void plat_init(void)
142 {
143         gp2x_soc_t soc;
144
145         soc = soc_detect();
146         switch (soc)
147         {
148         case SOCID_MMSP2:
149                 mmsp2_init();
150                 break;
151         case SOCID_POLLUX:
152                 pollux_init();
153                 menu_plat_setup(1);
154                 break;
155         default:
156                 break;
157         }
158
159         warm_init();
160
161         gp2x_memset_all_buffers(0, 0, 320*240*2);
162
163         // snd
164         sndout_oss_init();
165 }
166
167 void plat_finish(void)
168 {
169         gp2x_soc_t soc;
170
171         warm_finish();
172
173         soc = soc_detect();
174         switch (soc)
175         {
176         case SOCID_MMSP2:
177                 mmsp2_finish();
178                 break;
179         case SOCID_POLLUX:
180                 pollux_finish();
181                 break;
182         }
183
184         sndout_oss_exit();
185 }
186
187 void lprintf(const char *fmt, ...)
188 {
189         va_list vl;
190
191         va_start(vl, fmt);
192         vprintf(fmt, vl);
193         va_end(vl);
194 }
195