2882b26a99
1) Adapt Rockboy to smaller screens (H10, X5, and iPod Nano). 2) Add the ability to use a preset palette on color targets. Choose 'Set Palette' from the main menu. 3) Clean up the code to remove any unused code and variables. 4) Changed tabs to spaces. 5) Disable reading and writing sound when sound is disabled. 6) Disbable writing to the RTC since it is not implemented yet. 7) Minor optimizations from WAC gnuboy CE and iBoy. 8) Massive clean up of code to make it appear consistent. 9) Change all C++ style comments to C style. 10) Completely reorganize dynarec. Add fixmes to all unimplemented opcodes. Add debug writes for all opcodes. Attempt to implement a few opcodes myself. 11) Silence some warnings when built using dynarec. 12) Minor reshuffling of IRAM, may or not offer a speed increase. 13) Include fixes found in the short-lived gnuboy CVS. All in all, there's about a 10% improvement on my test roms when sound is disabled and slight improvement with sound. Especially noticable when there are few sprites on screen and less action is occurring. See FS #6567. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12216 a1c6a512-1295-4272-9138-f99709370657
341 lines
10 KiB
C
341 lines
10 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2005 Michiel van der Kolk, Jens Arnold
|
|
*
|
|
* All files in this archive are subject to the GNU General Public License.
|
|
* See the file COPYING in the source tree root for full license agreement.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "rockmacros.h"
|
|
#include "fb.h"
|
|
#include "input.h"
|
|
#include "lcd-gb.h"
|
|
#include "hw.h"
|
|
#include "config.h"
|
|
|
|
#if (CONFIG_KEYPAD == IPOD_4G_PAD)
|
|
|
|
#define ROCKBOY_PAD_LEFT BUTTON_LEFT
|
|
#define ROCKBOY_PAD_RIGHT BUTTON_RIGHT
|
|
#define ROCKBOY_PAD_UP BUTTON_MENU
|
|
#define ROCKBOY_PAD_DOWN BUTTON_PLAY
|
|
|
|
#elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
|
|
|
|
#define ROCKBOY_PAD_LEFT BUTTON_LEFT
|
|
#define ROCKBOY_PAD_RIGHT BUTTON_RIGHT
|
|
#define ROCKBOY_PAD_UP BUTTON_SCROLL_UP
|
|
#define ROCKBOY_PAD_DOWN BUTTON_SCROLL_DOWN
|
|
|
|
#else
|
|
|
|
#define ROCKBOY_PAD_LEFT BUTTON_LEFT
|
|
#define ROCKBOY_PAD_RIGHT BUTTON_RIGHT
|
|
#define ROCKBOY_PAD_UP BUTTON_UP
|
|
#define ROCKBOY_PAD_DOWN BUTTON_DOWN
|
|
|
|
#endif
|
|
|
|
struct fb fb IBSS_ATTR;
|
|
|
|
extern int debug_trace;
|
|
|
|
unsigned int oldbuttonstate = 0, newbuttonstate,holdbutton;
|
|
#ifdef HAVE_WHEEL_POSITION
|
|
int oldwheel = -1, wheel;
|
|
|
|
static int wheelmap[8] = {
|
|
PAD_UP, /* Top */
|
|
PAD_A, /* Top-right */
|
|
PAD_RIGHT, /* Right */
|
|
PAD_START, /* Bottom-right */
|
|
PAD_DOWN, /* Bottom */
|
|
PAD_SELECT, /* Bottom-left */
|
|
PAD_LEFT, /* Left */
|
|
PAD_B /* Top-left */
|
|
};
|
|
#endif
|
|
|
|
int released, pressed;
|
|
|
|
void ev_poll(void)
|
|
{
|
|
event_t ev;
|
|
newbuttonstate = rb->button_status();
|
|
released = ~newbuttonstate & oldbuttonstate;
|
|
pressed = newbuttonstate & ~oldbuttonstate;
|
|
oldbuttonstate = newbuttonstate;
|
|
#if CONFIG_KEYPAD == IRIVER_H100_PAD
|
|
if (rb->button_hold()&~holdbutton)
|
|
fb.mode=(fb.mode+1)%4;
|
|
holdbutton=rb->button_hold();
|
|
#elif CONFIG_KEYPAD == RECORDER_PAD
|
|
if (pressed & BUTTON_ON)
|
|
fb.mode=(fb.mode+1)%4;
|
|
#endif
|
|
|
|
#ifdef HAVE_WHEEL_POSITION
|
|
/* Get the current wheel position - 0..95 or -1 for untouched */
|
|
wheel = rb->wheel_status();
|
|
|
|
/* Convert to number from 0 to 7 - clockwise from top */
|
|
if ( wheel > 0 ){
|
|
wheel += 6;
|
|
wheel /= 12;
|
|
if ( wheel > 7 ) wheel = 0;
|
|
}
|
|
|
|
if ( wheel != oldwheel ) {
|
|
if (oldwheel >= 0) {
|
|
ev.type = EV_RELEASE;
|
|
ev.code = wheelmap[oldwheel];
|
|
ev_postevent(&ev);
|
|
}
|
|
|
|
if (wheel >= 0) {
|
|
ev.type = EV_PRESS;
|
|
ev.code = wheelmap[wheel];
|
|
ev_postevent(&ev);
|
|
}
|
|
}
|
|
|
|
oldwheel = wheel;
|
|
if(released) {
|
|
ev.type = EV_RELEASE;
|
|
if ( released & (~BUTTON_SELECT) ) { ev.code=PAD_B; ev_postevent(&ev); }
|
|
if ( released & BUTTON_SELECT ) { ev.code=PAD_A; ev_postevent(&ev); }
|
|
}
|
|
if(pressed) { /* button press */
|
|
ev.type = EV_PRESS;
|
|
if ( pressed & (~BUTTON_SELECT) ) { ev.code=PAD_B; ev_postevent(&ev); }
|
|
if ( pressed & BUTTON_SELECT ) { ev.code=PAD_A; ev_postevent(&ev); }
|
|
}
|
|
#else
|
|
if(released) {
|
|
ev.type = EV_RELEASE;
|
|
if(released & ROCKBOY_PAD_LEFT) { ev.code=PAD_LEFT; ev_postevent(&ev); }
|
|
if(released & ROCKBOY_PAD_RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
|
|
if(released & ROCKBOY_PAD_DOWN) { ev.code=PAD_DOWN; ev_postevent(&ev); }
|
|
if(released & ROCKBOY_PAD_UP) { ev.code=PAD_UP; ev_postevent(&ev); }
|
|
if(released & options.A) { ev.code=PAD_A; ev_postevent(&ev); }
|
|
if(released & options.B) { ev.code=PAD_B; ev_postevent(&ev); }
|
|
if(released & options.START) {
|
|
ev.code=PAD_START;
|
|
ev_postevent(&ev);
|
|
}
|
|
if(released & options.SELECT) {
|
|
ev.code=PAD_SELECT;
|
|
ev_postevent(&ev);
|
|
}
|
|
}
|
|
if(pressed) { /* button press */
|
|
ev.type = EV_PRESS;
|
|
if(pressed & ROCKBOY_PAD_LEFT) { ev.code=PAD_LEFT; ev_postevent(&ev); }
|
|
if(pressed & ROCKBOY_PAD_RIGHT) { ev.code=PAD_RIGHT; ev_postevent(&ev);}
|
|
if(pressed & ROCKBOY_PAD_DOWN) { ev.code=PAD_DOWN; ev_postevent(&ev); }
|
|
if(pressed & ROCKBOY_PAD_UP) { ev.code=PAD_UP; ev_postevent(&ev); }
|
|
if(pressed & options.A) { ev.code=PAD_A; ev_postevent(&ev); }
|
|
if(pressed & options.B) { ev.code=PAD_B; ev_postevent(&ev); }
|
|
if(pressed & options.START) {
|
|
ev.code=PAD_START;
|
|
ev_postevent(&ev);
|
|
}
|
|
if(pressed & options.SELECT) {
|
|
ev.code=PAD_SELECT;
|
|
ev_postevent(&ev);
|
|
}
|
|
#endif
|
|
#if CONFIG_KEYPAD == IPOD_4G_PAD
|
|
if(rb->button_hold()) {
|
|
#else
|
|
if(pressed & options.MENU) {
|
|
#endif
|
|
#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
|
|
defined(HAVE_LCD_COLOR)
|
|
#ifdef HAVE_WHEEL_POSITION
|
|
rb->wheel_send_events(true);
|
|
#endif
|
|
if (do_user_menu() == USER_MENU_QUIT)
|
|
#endif
|
|
{
|
|
die("");
|
|
cleanshut=1;
|
|
}
|
|
#ifdef HAVE_WHEEL_POSITION
|
|
rb->wheel_send_events(false);
|
|
#endif
|
|
}
|
|
|
|
#ifndef HAVE_WHEEL_POSITION
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* New frameskip, makes more sense to me and performs as well */
|
|
inline void vid_begin(void)
|
|
{
|
|
static int skip = 0;
|
|
if (skip<options.frameskip)
|
|
{
|
|
skip++;
|
|
fb.enabled=0;
|
|
}
|
|
else
|
|
{
|
|
skip=0;
|
|
fb.enabled=1;
|
|
}
|
|
}
|
|
|
|
void vid_init(void)
|
|
{
|
|
fb.enabled=1;
|
|
fb.ptr=rb->lcd_framebuffer;
|
|
|
|
#if defined(HAVE_LCD_COLOR)
|
|
fb.cc[0].r = 3; /* 8-5 (wasted bits on red) */
|
|
fb.cc[0].l = 11; /* this is the offset to the R bits (16-5) */
|
|
fb.cc[1].r = 2; /* 8-6 (wasted bits on green) */
|
|
fb.cc[1].l = 5; /* This is the offset to the G bits (16-5-6) */
|
|
fb.cc[2].r = 3; /* 8-5 (wasted bits on red) */
|
|
fb.cc[2].l = 0; /* This is the offset to the B bits (16-5-6-5) */
|
|
#else
|
|
fb.mode=3;
|
|
#endif
|
|
}
|
|
|
|
#if !defined(HAVE_LCD_COLOR)
|
|
/* Color targets are handled in lcd.c */
|
|
fb_data *frameb;
|
|
void vid_update(int scanline)
|
|
{
|
|
register int cnt=0;
|
|
int scanline_remapped;
|
|
#if (LCD_HEIGHT == 64) && (LCD_DEPTH == 1) /* Archos */
|
|
int balance = 0;
|
|
if (fb.mode==1)
|
|
scanline-=16;
|
|
else if (fb.mode==2)
|
|
scanline-=8;
|
|
scanline_remapped = scanline / 16;
|
|
frameb = rb->lcd_framebuffer + scanline_remapped * LCD_WIDTH;
|
|
while (cnt < 160) {
|
|
balance += LCD_WIDTH;
|
|
if (balance > 0)
|
|
{
|
|
#if (CONFIG_CPU == SH7034) && !defined(SIMULATOR)
|
|
asm volatile (
|
|
"mov.b @%0,r0 \n"
|
|
"add %1,%0 \n"
|
|
"tst #0x02, r0 \n" /* ~bit 1 */
|
|
"rotcr r1 \n"
|
|
"mov.b @%0,r0 \n"
|
|
"add %1,%0 \n"
|
|
"tst #0x02, r0 \n" /* ~bit 1 */
|
|
"rotcr r1 \n"
|
|
"mov.b @%0,r0 \n"
|
|
"add %1,%0 \n"
|
|
"tst #0x02, r0 \n" /* ~bit 1 */
|
|
"rotcr r1 \n"
|
|
"mov.b @%0,r0 \n"
|
|
"add %1,%0 \n"
|
|
"tst #0x02, r0 \n" /* ~bit 1 */
|
|
"rotcr r1 \n"
|
|
"mov.b @%0,r0 \n"
|
|
"add %1,%0 \n"
|
|
"tst #0x02, r0 \n" /* ~bit 1 */
|
|
"rotcr r1 \n"
|
|
"mov.b @%0,r0 \n"
|
|
"add %1,%0 \n"
|
|
"tst #0x02, r0 \n" /* ~bit 1 */
|
|
"rotcr r1 \n"
|
|
"mov.b @%0,r0 \n"
|
|
"add %1,%0 \n"
|
|
"tst #0x02, r0 \n" /* ~bit 1 */
|
|
"rotcr r1 \n"
|
|
"mov.b @%0,r0 \n"
|
|
"add %1,%0 \n"
|
|
"tst #0x02, r0 \n" /* ~bit 1 */
|
|
"rotcr r1 \n"
|
|
|
|
"shlr16 r1 \n"
|
|
"shlr8 r1 \n"
|
|
"not r1,r1 \n" /* account for negated bits */
|
|
"mov.b r1,@%2 \n"
|
|
: /* outputs */
|
|
: /* inputs */
|
|
/* %0 */ "r"(scan.buf[0] + cnt),
|
|
/* %1 */ "r"(256), /* scan.buf line length */
|
|
/* %2 */ "r"(frameb++)
|
|
: /* clobbers */
|
|
"r0", "r1"
|
|
);
|
|
#else
|
|
register unsigned scrbyte = 0;
|
|
if (scan.buf[0][cnt] & 0x02) scrbyte |= 0x01;
|
|
if (scan.buf[1][cnt] & 0x02) scrbyte |= 0x02;
|
|
if (scan.buf[2][cnt] & 0x02) scrbyte |= 0x04;
|
|
if (scan.buf[3][cnt] & 0x02) scrbyte |= 0x08;
|
|
if (scan.buf[4][cnt] & 0x02) scrbyte |= 0x10;
|
|
if (scan.buf[5][cnt] & 0x02) scrbyte |= 0x20;
|
|
if (scan.buf[6][cnt] & 0x02) scrbyte |= 0x40;
|
|
if (scan.buf[7][cnt] & 0x02) scrbyte |= 0x80;
|
|
*(frameb++) = scrbyte;
|
|
#endif
|
|
balance -= 160;
|
|
}
|
|
cnt ++;
|
|
}
|
|
rb->lcd_update_rect(0, (scanline/2) & ~7, LCD_WIDTH, 8);
|
|
#elif (LCD_HEIGHT == 128) && (LCD_DEPTH == 2) /* iriver H1x0 */
|
|
if (fb.mode==1)
|
|
scanline-=16;
|
|
else if (fb.mode==2)
|
|
scanline-=8;
|
|
scanline_remapped = scanline / 4;
|
|
frameb = rb->lcd_framebuffer + scanline_remapped * LCD_WIDTH;
|
|
while (cnt < 160) {
|
|
*(frameb++) = (scan.buf[0][cnt]&0x3) |
|
|
((scan.buf[1][cnt]&0x3)<<2) |
|
|
((scan.buf[2][cnt]&0x3)<<4) |
|
|
((scan.buf[3][cnt]&0x3)<<6);
|
|
cnt++;
|
|
}
|
|
rb->lcd_update_rect(0, scanline & ~3, LCD_WIDTH, 4);
|
|
#elif defined(HAVE_LCD_COLOR)
|
|
/* handled in lcd.c now */
|
|
#endif /* LCD_HEIGHT */
|
|
}
|
|
#endif
|
|
|
|
long timerresult;
|
|
|
|
void *sys_timer(void)
|
|
{
|
|
/*timerresult=*rb->current_tick;
|
|
return &timerresult;*/
|
|
return 0;
|
|
}
|
|
|
|
/* returns microseconds passed since sys_timer */
|
|
int sys_elapsed(long *oldtick)
|
|
{
|
|
/* int elap,mytime=microtick;
|
|
|
|
elap=mytime-*oldtick;
|
|
*oldtick=mytime;
|
|
return elap; */
|
|
/* return ((*rb->current_tick-(*oldtick))*1000000)/HZ; */
|
|
return *oldtick;
|
|
}
|