1
0
Fork 0
forked from len0rd/rockbox

Allow rockboy to run while music is playing with smaller roms. Works on players that do not use the IRAM macros. Only tested on the Gigabeat as I think that is the only player that will run rockboy well with music. Also simplified the sound and reduced the code size a bit.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13199 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Karl Kurbjun 2007-04-18 07:41:31 +00:00
parent 521d6a5e1f
commit c3dcc87aa4
9 changed files with 176 additions and 176 deletions

View file

@ -41,19 +41,17 @@ void emu_run(void)
#ifdef HAVE_ADJUSTABLE_CPU_FREQ #ifdef HAVE_ADJUSTABLE_CPU_FREQ
rb->cpu_boost(true); rb->cpu_boost(true);
#endif #endif
while(!shut) while(!shut)
{ {
cpu_emulate(2280); cpu_emulate(2280);
while (R_LY > 0 && R_LY < 144) while (R_LY > 0 && R_LY < 144)
emu_step(); emu_step();
/* rtc_tick(); */ /* RTC support not implemented */ rtc_tick(); /* RTC support not implemented */
if(options.sound) if(options.sound || !plugbuf)
{
sound_mix(); sound_mix();
pcm_submit();
}
doevents(); doevents();
vid_begin(); vid_begin();
@ -70,11 +68,11 @@ void emu_run(void)
frames++; frames++;
framesin++; framesin++;
if(*rb->current_tick-timeten>=20) if(*rb->current_tick-timeten>=10)
{ {
timeten=*rb->current_tick; timeten=*rb->current_tick;
if(framesin<12) options.frameskip++; if(framesin<6) options.frameskip++;
if(framesin>12) options.frameskip--; if(framesin>6) options.frameskip--;
if(options.frameskip>options.maxskip) options.frameskip=options.maxskip; if(options.frameskip>options.maxskip) options.frameskip=options.maxskip;
if(options.frameskip<0) options.frameskip=0; if(options.frameskip<0) options.frameskip=0;
framesin=0; framesin=0;

View file

@ -1,8 +1,3 @@
#include <stdio.h>
#include <string.h>
#include "rockmacros.h" #include "rockmacros.h"
#include "defs.h" #include "defs.h"
#include "regs.h" #include "regs.h"
@ -13,11 +8,58 @@
#include "save.h" #include "save.h"
#include "sound.h" #include "sound.h"
/* From http://www.semis.demon.co.uk/Gameboy/Gbspec.txt (4/17/2007)
* Cartridge type:
* 0 - ROM ONLY 12 - ROM+MBC3+RAM
* 1 - ROM+MBC1 13 - ROM+MBC3+RAM+BATT
* 2 - ROM+MBC1+RAM 19 - ROM+MBC5
* 3 - ROM+MBC1+RAM+BATT 1A - ROM+MBC5+RAM
* 5 - ROM+MBC2 1B - ROM+MBC5+RAM+BATT
* 6 - ROM+MBC2+BATTERY 1C - ROM+MBC5+RUMBLE
* 8 - ROM+RAM 1D - ROM+MBC5+RUMBLE+SRAM
* 9 - ROM+RAM+BATTERY 1E - ROM+MBC5+RUMBLE+SRAM+BATT
* B - ROM+MMM01 1F - Pocket Camera
* C - ROM+MMM01+SRAM FD - Bandai TAMA5
* D - ROM+MMM01+SRAM+BATT FE - Hudson HuC-3
* F - ROM+MBC3+TIMER+BATT FF - Hudson HuC-1
* 10 - ROM+MBC3+TIMER+RAM+BATT
* 11 - ROM+MBC3
*/
static int mbc_table[256] = static int mbc_table[256] =
{ {
0, 1, 1, 1, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, MBC_NONE,
3, 3, 3, 3, 0, 0, 0, 0, 0, 5, 5, 5, MBC_RUMBLE, MBC_RUMBLE, MBC_RUMBLE, 0, MBC_MBC1,
MBC_MBC1,
MBC_MBC1 | MBC_BAT,
0,
MBC_MBC2,
MBC_MBC2 | MBC_BAT,
0,
0,
MBC_BAT,
0,
0,
0,
MBC_BAT,
0,
MBC_MBC3 | MBC_BAT | MBC_RTC,
MBC_MBC3 | MBC_BAT | MBC_RTC,
MBC_MBC3,
MBC_MBC3,
MBC_MBC3 | MBC_BAT,
0,
0,
0,
0,
0,
MBC_MBC5,
MBC_MBC5,
MBC_MBC5 | MBC_BAT,
MBC_RUMBLE,
MBC_RUMBLE,
MBC_RUMBLE | MBC_BAT,
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -34,46 +76,29 @@ static int mbc_table[256] =
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MBC_HUC3, MBC_HUC1 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
MBC_HUC3,
MBC_HUC1
}; };
static int rtc_table[256] = static unsigned short romsize_table[56] =
{ {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 8, 16, 32, 64, 128, 256,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 512, 0, 0, 0, 0, 0, 0, 0,
0 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 128, 128, 128, 0
/* 0, 0, 0, 0, 72, 80, 96 -- actual values but bad to use these! */
}; };
static int batt_table[256] = /* Ram size should be no larger then 16 banks 1Mbit */
static unsigned char ramsize_table[5] =
{ {
0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 4, 16
1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
0
}; };
static int romsize_table[256] =
{
2, 4, 8, 16, 32, 64, 128, 256, 512,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 128, 128, 128
/* 0, 0, 72, 80, 96 -- actual values but bad to use these! */
};
static int ramsize_table[256] =
{
1, 1, 1, 4, 16,
4 /* FIXME - what value should this be?! */
};
static char *romfile; static char *romfile;
static char sramfile[500]; static char sramfile[500];
static char rtcfile[500]; static char rtcfile[500];
@ -100,24 +125,23 @@ static void initmem(void *mem, int size)
static byte *loadfile(int fd, int *len) static byte *loadfile(int fd, int *len)
{ {
int c, l = 0, p = 0; int c;
byte *d;
byte *d, buf[512]; *len=lseek(fd,0,SEEK_END);
d=malloc(32768); d=malloc((*len)*sizeof(char)+64);
for(;;) if(d==0)
{ {
c = read(fd, buf, sizeof buf); die("Not enough memory");
if (c <= 0) break; return 0;
l += c;
memcpy(d+p, buf, c);
p += c;
} }
setmallocpos(d+p+64); lseek(fd,0,SEEK_SET);
*len = l;
c = read(fd, d, *len);
return d; return d;
} }
int rom_load(void) int rom_load(void)
{ {
int fd; int fd;
@ -126,13 +150,19 @@ int rom_load(void)
fd = open(romfile, O_RDONLY); fd = open(romfile, O_RDONLY);
if (fd<0) { if (fd<0)
die("cannot open rom file"); {
die(romfile); die("cannot open rom file %s", romfile);
return 1; return 1;
} }
data = loadfile(fd, &len); data = loadfile(fd, &len);
close(fd);
if(data==0)
{
die("Not Enough Memory");
return 1;
}
header = data; /* no zip. = decompress(data, &len); */ header = data; /* no zip. = decompress(data, &len); */
memcpy(rom.name, header+0x0134, 16); memcpy(rom.name, header+0x0134, 16);
@ -141,17 +171,22 @@ int rom_load(void)
rom.name[16] = 0; rom.name[16] = 0;
c = header[0x0147]; c = header[0x0147];
mbc.type = mbc_table[c]; mbc.type = mbc_table[c]&(MBC_MBC1|MBC_MBC2|MBC_MBC3|MBC_MBC5|MBC_RUMBLE|MBC_HUC1|MBC_HUC3);
mbc.batt = (batt_table[c] && !nobatt) || forcebatt; mbc.batt = ((mbc_table[c]&MBC_BAT) && !nobatt) || forcebatt;
rtc.batt = rtc_table[c]; rtc.batt = mbc_table[c]&MBC_RTC;
mbc.romsize = romsize_table[header[0x0148]];
mbc.ramsize = ramsize_table[header[0x0149]];
if (!mbc.romsize) { if(header[0x0148]<10 || (header[0x0148]>51 && header[0x0148]<55))
mbc.romsize = romsize_table[header[0x0148]];
else
{
die("unknown ROM size %02X\n", header[0x0148]); die("unknown ROM size %02X\n", header[0x0148]);
return 1; return 1;
} }
if (!mbc.ramsize) {
if(header[0x0149]<5)
mbc.ramsize = ramsize_table[header[0x0149]];
else
{
die("unknown SRAM size %02X\n", header[0x0149]); die("unknown SRAM size %02X\n", header[0x0149]);
return 1; return 1;
} }
@ -160,7 +195,17 @@ int rom_load(void)
rom.bank = (void *) data; /* realloc(data, rlen); */ rom.bank = (void *) data; /* realloc(data, rlen); */
if (rlen > len) memset(rom.bank[0]+len, 0xff, rlen - len); if (rlen > len) memset(rom.bank[0]+len, 0xff, rlen - len);
/* This is the size of the ram on the cartridge
* See http://www.semis.demon.co.uk/Gameboy/Gbspec.txt
* for a full description. (8192*number of banks)
*/
ram.sbank = malloc(8192 * mbc.ramsize); ram.sbank = malloc(8192 * mbc.ramsize);
if(ram.sbank==0 && mbc.ramsize!=0)
{
die("Not enough Memory");
return 1;
}
/* ram.ibank = malloc(4096*8); */ /* ram.ibank = malloc(4096*8); */
initmem(ram.sbank, 8192 * mbc.ramsize); initmem(ram.sbank, 8192 * mbc.ramsize);
@ -172,8 +217,6 @@ int rom_load(void)
c = header[0x0143]; c = header[0x0143];
hw.cgb = ((c == 0x80) || (c == 0xc0)) && !forcedmg; hw.cgb = ((c == 0x80) || (c == 0xc0)) && !forcedmg;
close(fd);
return 0; return 0;
} }

View file

@ -1,6 +1,3 @@
#include <stdio.h>
#include <string.h>
#include "rockmacros.h" #include "rockmacros.h"
#include "input.h" #include "input.h"
#include "emu.h" #include "emu.h"

View file

@ -1,19 +1,18 @@
#ifndef __MEM_H__ #ifndef __MEM_H__
#define __MEM_H__ #define __MEM_H__
#include "defs.h" #include "defs.h"
#define MBC_NONE 0 #define MBC_NONE 0
#define MBC_MBC1 1 #define MBC_MBC1 1
#define MBC_MBC2 2 #define MBC_MBC2 2
#define MBC_MBC3 3 #define MBC_MBC3 4
#define MBC_MBC5 5 #define MBC_MBC5 8
#define MBC_RUMBLE 15 #define MBC_RUMBLE 16
#define MBC_HUC1 0xC1 #define MBC_HUC1 32
#define MBC_HUC3 0xC3 #define MBC_HUC3 64
#define MBC_RTC 128
#define MBC_BAT 256
struct mbc struct mbc
{ {

View file

@ -2,30 +2,14 @@
#include "defs.h" #include "defs.h"
#include "pcm.h" #include "pcm.h"
/*#define ONEBUF*/
/* Note: I think the single buffer implementation is more
* responsive with sound(less lag) but it creates more
* choppyness overall to the sound. 2 buffer's don't seem to
* make a difference, but 4 buffers is definately noticable
*/
struct pcm pcm IBSS_ATTR; struct pcm pcm IBSS_ATTR;
bool sound = 1; #define N_BUFS 2
#ifdef ONEBUF
#define N_BUFS 1
#else
#define N_BUFS 4
#endif
#define BUF_SIZE 1024 #define BUF_SIZE 1024
#if CONFIG_CODEC == SWCODEC && !defined(SIMULATOR) #if CONFIG_CODEC == SWCODEC && !defined(SIMULATOR)
#ifndef ONEBUF bool doneplay=1;
static short curbuf,gmcurbuf;
#else
bool doneplay=0;
#endif
static unsigned char *buf=0; static unsigned char *buf=0;
static unsigned short *gmbuf; static unsigned short *gmbuf;
@ -34,31 +18,28 @@ static bool newly_started;
void get_more(unsigned char** start, size_t* size) void get_more(unsigned char** start, size_t* size)
{ {
#ifdef ONEBUF *start = (unsigned char*)(&gmbuf[pcm.len*doneplay]);
doneplay=1;
*start = (unsigned char*)(gmbuf);
#else
*start = (unsigned char*)(&gmbuf[pcm.len*curbuf]);
#endif
*size = BUF_SIZE*sizeof(short); *size = BUF_SIZE*sizeof(short);
} }
void pcm_init(void) void pcm_init(void)
{ {
if(plugbuf)
return;
newly_started = true; newly_started = true;
pcm.hz = 11025; pcm.hz = 11025;
pcm.stereo = 1; pcm.stereo = 1;
pcm.len = BUF_SIZE; pcm.len = BUF_SIZE;
if(!buf){ if(!buf)
{
buf = my_malloc(pcm.len * N_BUFS); buf = my_malloc(pcm.len * N_BUFS);
gmbuf = my_malloc(pcm.len * N_BUFS*sizeof (short)); gmbuf = my_malloc(pcm.len * N_BUFS*sizeof (short));
pcm.buf = buf; pcm.buf = buf;
pcm.pos = 0; pcm.pos = 0;
#ifndef ONEBUF
curbuf = gmcurbuf= 0;
#endif
memset(gmbuf, 0, pcm.len * N_BUFS *sizeof(short)); memset(gmbuf, 0, pcm.len * N_BUFS *sizeof(short));
memset(buf, 0, pcm.len * N_BUFS); memset(buf, 0, pcm.len * N_BUFS);
} }
@ -78,29 +59,22 @@ void pcm_close(void)
int pcm_submit(void) int pcm_submit(void)
{ {
if (!options.sound) return 1;
register int i; register int i;
if (!sound) {
pcm.pos = 0;
return 0;
}
if (pcm.pos < pcm.len) return 1; if (pcm.pos < pcm.len) return 1;
#ifndef ONEBUF doneplay=!doneplay;
curbuf = (curbuf + 1) % N_BUFS;
pcm.buf = buf + pcm.len * curbuf; if(doneplay)
#endif pcm.buf = buf + pcm.len;
else
pcm.buf = buf;
pcm.pos = 0; pcm.pos = 0;
/* gotta convert the 8 bit buffer to 16 */ /* gotta convert the 8 bit buffer to 16 */
for(i=0; i<pcm.len;i++) for(i=0; i<pcm.len;i++)
#ifdef ONEBUF gmbuf[i+pcm.len*doneplay] = (pcm.buf[i]<<8)-0x8000;
gmbuf[i] = (pcm.buf[i]<<8)-0x8000;
#else
gmbuf[i+pcm.len*curbuf] = (pcm.buf[i]<<8)-0x8000;
#endif
if(newly_started) if(newly_started)
{ {
@ -108,13 +82,6 @@ int pcm_submit(void)
newly_started = false; newly_started = false;
} }
/* this while loop and done play are in place to make sure the sound timing
* is correct(although it's not)
*/
#ifdef ONEBUF
while(doneplay==0) rb->yield();
doneplay=0;
#endif
return 1; return 1;
} }
#else #else

View file

@ -65,12 +65,6 @@ void* memcpy(void* dst, const void* src, size_t size)
return rb->memcpy(dst, src, size); return rb->memcpy(dst, src, size);
} }
void setmallocpos(void *pointer)
{
audio_bufferpointer = pointer;
audio_buffer_free = audio_bufferpointer - audio_bufferbase;
}
void setoptions (void) void setoptions (void)
{ {
int fd; int fd;
@ -197,9 +191,18 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
rb->splash(HZ*3, "Play gameboy ROM file! (.gb/.gbc)"); rb->splash(HZ*3, "Play gameboy ROM file! (.gb/.gbc)");
return PLUGIN_OK; return PLUGIN_OK;
} }
if(rb->audio_status())
{
audio_bufferbase = audio_bufferpointer
= rb->plugin_get_buffer((int *)&audio_buffer_free);
plugbuf=true;
}
else
{
audio_bufferbase = audio_bufferpointer audio_bufferbase = audio_bufferpointer
= rb->plugin_get_audio_buffer((int *)&audio_buffer_free); = rb->plugin_get_audio_buffer((int *)&audio_buffer_free);
plugbuf=false;
}
#if MEM <= 8 && !defined(SIMULATOR) #if MEM <= 8 && !defined(SIMULATOR)
/* loaded as an overlay plugin, protect from overwriting ourselves */ /* loaded as an overlay plugin, protect from overwriting ourselves */
if ((unsigned)(plugin_start_addr - (unsigned char *)audio_bufferbase) if ((unsigned)(plugin_start_addr - (unsigned char *)audio_bufferbase)
@ -226,6 +229,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
rb->splash(HZ/2, errormsg); rb->splash(HZ/2, errormsg);
return PLUGIN_ERROR; return PLUGIN_ERROR;
} }
if(!rb->audio_status())
pcm_close(); pcm_close();
rb->splash(HZ/2, "Shutting down"); rb->splash(HZ/2, "Shutting down");

View file

@ -31,7 +31,6 @@ extern int shut,cleanshut;
void vid_init(void); void vid_init(void);
inline void vid_begin(void); inline void vid_begin(void);
void die(char *message, ...); void die(char *message, ...);
void setmallocpos(void *pointer);
void *sys_timer(void); void *sys_timer(void);
int sys_elapsed(long *oldtick); int sys_elapsed(long *oldtick);
int pcm_submit(void); int pcm_submit(void);
@ -122,6 +121,8 @@ struct options {
int pal; int pal;
}; };
bool plugbuf;
extern struct options options; extern struct options options;
#define savedir "/.rockbox/rockboy" #define savedir "/.rockbox/rockboy"

View file

@ -1,7 +1,4 @@
#include "rockmacros.h" #include "rockmacros.h"
#include <stdio.h>
#include "defs.h" #include "defs.h"
#include "cpu-gb.h" #include "cpu-gb.h"
@ -13,8 +10,6 @@
#include "mem.h" #include "mem.h"
#include "sound.h" #include "sound.h"
#ifdef ROCKBOX_LITTLE_ENDIAN #ifdef ROCKBOX_LITTLE_ENDIAN
#define LIL(x) (x) #define LIL(x) (x)
#else #else

View file

@ -1,6 +1,3 @@
#include "rockmacros.h" #include "rockmacros.h"
#include "defs.h" #include "defs.h"
#include "pcm.h" #include "pcm.h"
@ -125,7 +122,6 @@ void sound_reset(void)
void sound_mix(void) void sound_mix(void)
{ {
if(!options.sound) return;
int s, l, r, f, n; int s, l, r, f, n;
if (!RATE || cpu.snd < RATE) return; if (!RATE || cpu.snd < RATE) return;