1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Björn Stenberg
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
23 #include <timefuncs.h>
38 #include "mp3_playback.h"
39 #include "backlight.h"
43 #ifdef HAVE_LCD_BITMAP
50 #include "plugin-win32.h"
51 #define PREFIX(_x_) _x_
54 #define PREFIX(_x_) x11_ ## _x_
57 #define PREFIX(_x_) _x_
60 #define PLUGIN_BUFFER_SIZE 0x8000
63 static unsigned char pluginbuf
[PLUGIN_BUFFER_SIZE
];
65 extern unsigned char pluginbuf
[];
66 extern void bitswap(unsigned char *data
, int length
);
69 static bool plugin_loaded
= false;
70 static int plugin_size
= 0;
72 static void (*pfn_timer
)(void) = NULL
; /* user timer handler */
74 static void (*pfn_tsr_exit
)(void) = NULL
; /* TSR exit callback */
76 static int plugin_test(int api_version
, int model
, int memsize
);
78 static struct plugin_api rockbox_api
= {
88 #ifdef HAVE_LCD_CHARCELLS
90 lcd_get_locked_pattern
,
121 (open_func
)PREFIX(open
),
125 (creat_func
)PREFIX(creat
),
144 /* strings and memory */
169 /* new stuff at the end, sort into place next time the API gets incompatible */
171 #ifndef HAVE_LCD_CHARCELLS
172 &lcd_framebuffer
[0][0],
177 plugin_get_mp3_buffer
,
188 backlight_set_timeout
,
192 #ifdef HAVE_LCD_BITMAP
196 plugin_register_timer
,
197 plugin_unregister_timer
,
211 mpeg_has_changed_track
,
215 int plugin_load(char* plugin
, void* parameter
)
217 enum plugin_status (*plugin_start
)(struct plugin_api
* api
, void* param
);
226 #ifdef HAVE_LCD_BITMAP
230 if (pfn_tsr_exit
!= NULL
) /* if we have a resident old plugin: */
232 pfn_tsr_exit(); /* force it to exit now */
236 #ifdef HAVE_LCD_BITMAP
238 xm
= lcd_getxmargin();
239 ym
= lcd_getymargin();
247 snprintf(path
, sizeof path
, "%s", plugin
);
249 snprintf(path
, sizeof path
, "archos%s", plugin
);
251 pd
= dlopen(path
, RTLD_NOW
);
253 snprintf(buf
, sizeof buf
, "Can't open %s", plugin
);
254 splash(HZ
*2, true, buf
);
255 DEBUGF("dlopen(%s): %s\n",path
,dlerror());
260 plugin_start
= dlsym(pd
, "plugin_start");
262 plugin_start
= dlsym(pd
, "_plugin_start");
264 splash(HZ
*2, true, "Can't find entry point");
270 fd
= open(plugin
, O_RDONLY
);
272 snprintf(buf
, sizeof buf
, str(LANG_PLUGIN_CANT_OPEN
), plugin
);
273 splash(HZ
*2, true, buf
);
277 plugin_start
= (void*)&pluginbuf
;
278 plugin_size
= read(fd
, plugin_start
, PLUGIN_BUFFER_SIZE
);
280 if (plugin_size
< 0) {
282 snprintf(buf
, sizeof buf
, str(LANG_READ_FAILED
), plugin
);
283 splash(HZ
*2, true, buf
);
286 if (plugin_size
== 0) {
287 /* loaded a 0-byte plugin, implying it's not for this model */
288 splash(HZ
*2, true, str(LANG_PLUGIN_WRONG_MODEL
));
293 plugin_loaded
= true;
294 rc
= plugin_start(&rockbox_api
, parameter
);
295 plugin_loaded
= false;
301 case PLUGIN_USB_CONNECTED
:
302 return PLUGIN_USB_CONNECTED
;
304 case PLUGIN_WRONG_API_VERSION
:
305 splash(HZ
*2, true, str(LANG_PLUGIN_WRONG_VERSION
));
308 case PLUGIN_WRONG_MODEL
:
309 splash(HZ
*2, true, str(LANG_PLUGIN_WRONG_MODEL
));
313 splash(HZ
*2, true, str(LANG_PLUGIN_ERROR
));
321 #ifdef HAVE_LCD_BITMAP
322 /* restore margins */
323 lcd_setmargins(xm
,ym
);
329 /* Returns a pointer to the portion of the plugin buffer that is not already
330 being used. If no plugin is loaded, returns the entire plugin buffer */
331 void* plugin_get_buffer(int* buffer_size
)
337 if (plugin_size
>= PLUGIN_BUFFER_SIZE
)
340 *buffer_size
= PLUGIN_BUFFER_SIZE
-plugin_size
;
341 buffer_pos
= plugin_size
;
345 *buffer_size
= PLUGIN_BUFFER_SIZE
;
349 return &pluginbuf
[buffer_pos
];
352 /* Returns a pointer to the mp3 buffer.
353 Playback gets stopped, to avoid conflicts. */
354 void* plugin_get_mp3_buffer(int* buffer_size
)
357 static unsigned char buf
[1700*1024];
358 *buffer_size
= sizeof(buf
);
362 talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
363 *buffer_size
= mp3end
- mp3buf
;
369 /* Register a periodic time callback, called every "cycles" CPU clocks.
370 Note that this function will be called in interrupt context! */
371 int plugin_register_timer(int cycles
, int prio
, void (*timer_callback
)(void))
373 int phi
= 0; /* bits for the prescaler */
376 while (cycles
> 0x10000)
377 { /* work out the smallest prescaler that makes it fit */
383 if (prescale
> 8 || cycles
== 0 || prio
< 1 || prio
> 15)
384 return 0; /* error, we can't do such period, bad argument */
386 and_b(~0x10, &TSTR
); /* Stop the timer 4 */
387 and_b(~0x10, &TSNC
); /* No synchronization */
388 and_b(~0x10, &TMDR
); /* Operate normally */
390 pfn_timer
= timer_callback
; /* install 2nd level ISR */
393 TIER4
= 0xF9; /* Enable GRA match interrupt */
395 GRA4
= (unsigned short)(cycles
- 1);
396 TCR4
= 0x20 | phi
; /* clear at GRA match, set prescaler */
397 IPRD
= (IPRD
& 0xFF0F) | prio
<< 4; /* interrupt priority */
398 or_b(0x10, &TSTR
); /* start timer 4 */
400 return cycles
* prescale
; /* return the actual period, in CPU clocks */
403 /* disable the user timer */
404 void plugin_unregister_timer(void)
406 and_b(~0x10, &TSTR
); /* stop the timer 4 */
407 IPRD
= (IPRD
& 0xFF0F); /* disable interrupt */
411 /* interrupt handler for user timer */
415 if (pfn_timer
!= NULL
)
416 pfn_timer(); /* call the user timer function */
417 and_b(~0x01, &TSR4
); /* clear the interrupt */
419 #endif /* #ifndef SIMULATOR */
421 /* The plugin wants to stay resident after leaving its main function, e.g.
422 runs from timer or own thread. The callback is registered to later
423 instruct it to free its resources before a new plugin gets loaded. */
424 void plugin_tsr(void (*exit_callback
)(void))
426 pfn_tsr_exit
= exit_callback
; /* remember the callback for later */
430 static int plugin_test(int api_version
, int model
, int memsize
)
432 if (api_version
< PLUGIN_MIN_API_VERSION
||
433 api_version
> PLUGIN_API_VERSION
)
434 return PLUGIN_WRONG_API_VERSION
;
437 return PLUGIN_WRONG_MODEL
;
440 return PLUGIN_WRONG_MODEL
;