# HG changeset patch # User Darren Salt # Date 1208455520 -3600 # Node ID 76975dc027f11b77187b1b4de4070db01743782b # Parent 52c396b980df167ed1050cd71abc42c221b8829f Update nosefart decoder library to 2.7-mls; port our patches as needed. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ xine-lib (1.1.12.1) 2008-??-?? - Buffer overflow in the NSF demuxer which may allow remote attackers to cause a denial of service (crash) or possibly execute arbitrary code via an NSF file with a long title or copyright message. (SA29850) + * Updated nosefart decoder library to current upstream (2.7-mls). xine-lib (1.1.12) 2008-04-14 * Security fixes: diff --git a/src/libxineadec/nosefart/dis6502.c b/src/libxineadec/nosefart/dis6502.c --- a/src/libxineadec/nosefart/dis6502.c +++ b/src/libxineadec/nosefart/dis6502.c @@ -20,7 +20,7 @@ ** dis6502.c ** ** 6502 disassembler based on code from John Saeger -** $Id: dis6502.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ +** $Id: dis6502.c,v 1.1 2003/04/08 20:53:00 ben Exp $ */ #include "types.h" @@ -462,11 +462,8 @@ void nes6502_disasm(uint32 PC, uint8 P, /* ** $Log: dis6502.c,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:00 ben +** Adding more files... ** ** Revision 1.4 2000/06/09 15:12:25 matt ** initial revision diff --git a/src/libxineadec/nosefart/dis6502.h b/src/libxineadec/nosefart/dis6502.h --- a/src/libxineadec/nosefart/dis6502.h +++ b/src/libxineadec/nosefart/dis6502.h @@ -20,7 +20,7 @@ ** dis6502.h ** ** 6502 disassembler header -** $Id: dis6502.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ +** $Id: dis6502.h,v 1.1 2003/04/08 20:53:00 ben Exp $ */ #ifndef _DIS6502_H_ @@ -40,11 +40,8 @@ extern void nes6502_disasm(uint32 PC, ui /* ** $Log: dis6502.h,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:00 ben +** Adding more files... ** ** Revision 1.4 2000/06/09 15:12:25 matt ** initial revision diff --git a/src/libxineadec/nosefart/fds_snd.c b/src/libxineadec/nosefart/fds_snd.c --- a/src/libxineadec/nosefart/fds_snd.c +++ b/src/libxineadec/nosefart/fds_snd.c @@ -20,7 +20,7 @@ ** fds_snd.c ** ** Famicom Disk System sound emulation -** $Id: fds_snd.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ +** $Id: fds_snd.c,v 1.1 2003/04/08 20:53:00 ben Exp $ */ #include "types.h" @@ -76,11 +76,8 @@ apuext_t fds_ext = /* ** $Log: fds_snd.c,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:00 ben +** Adding more files... ** ** Revision 1.3 2000/07/03 02:18:53 matt ** much better external module exporting diff --git a/src/libxineadec/nosefart/fds_snd.h b/src/libxineadec/nosefart/fds_snd.h --- a/src/libxineadec/nosefart/fds_snd.h +++ b/src/libxineadec/nosefart/fds_snd.h @@ -20,7 +20,7 @@ ** fds_snd.h ** ** Famicom Disk System sound emulation -** $Id: fds_snd.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ +** $Id: fds_snd.h,v 1.1 2003/04/08 20:53:00 ben Exp $ */ #ifndef _FDS_SND_H_ @@ -35,11 +35,8 @@ extern apuext_t fds_ext; /* ** $Log: fds_snd.h,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:00 ben +** Adding more files... ** ** Revision 1.2 2000/06/20 04:06:16 matt ** migrated external sound definition to apu module diff --git a/src/libxineadec/nosefart/fmopl.c b/src/libxineadec/nosefart/fmopl.c --- a/src/libxineadec/nosefart/fmopl.c +++ b/src/libxineadec/nosefart/fmopl.c @@ -18,9 +18,9 @@ #include #include #include -#include //#include "driver.h" /* use M.A.M.E. */ #include "fmopl.h" +#include /* MPC - hacks */ #include "types.h" @@ -217,6 +217,19 @@ static INT32 feedback2; /* connect for #define LOG(n,x) if( (n)>=LOG_LEVEL ) log_printf x /* --------------------- subroutines --------------------- */ + +/* There's no good reason why I should have to do this, but using "pow" +(the POSIX fuction) causes it to not compile on my machine +--Matthew Strait */ +double mypow(float base, int power) +{ + int ans = 1, k; + + for( k = 0; k < power; k++) + ans *= (int)base; + + return ans; +} INLINE int Limit( int val, int max, int min ) { if ( val > max ) @@ -615,7 +628,7 @@ static int OPLOpenTable( void ) } /* make total level table */ for (t = 0;t < EG_ENT-1 ;t++){ - rate = ((1< voltage */ + rate = ((1< voltage */ TL_TABLE[ t] = (int)rate; TL_TABLE[TL_MAX+t] = -TL_TABLE[t]; /* LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/ @@ -650,7 +663,7 @@ static int OPLOpenTable( void ) for (i=0; i= EG_ENT ) pom = EG_ENT-1; */ ENV_CURVE[i] = (int)pom; /* DECAY ,RELEASE curve */ @@ -1321,3 +1334,5 @@ int OPLTimerOver(FM_OPL *OPL,int c) if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); return OPL->status>>7; } + + diff --git a/src/libxineadec/nosefart/fmopl.h b/src/libxineadec/nosefart/fmopl.h --- a/src/libxineadec/nosefart/fmopl.h +++ b/src/libxineadec/nosefart/fmopl.h @@ -162,3 +162,4 @@ void Y8950UpdateOne(FM_OPL *OPL, INT16 * void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length); #endif + diff --git a/src/libxineadec/nosefart/log.c b/src/libxineadec/nosefart/log.c --- a/src/libxineadec/nosefart/log.c +++ b/src/libxineadec/nosefart/log.c @@ -20,7 +20,7 @@ ** log.c ** ** Error logging functions -** $Id: log.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ +** $Id: log.c,v 1.1 2003/04/08 20:46:46 ben Exp $ */ #include @@ -103,11 +103,8 @@ void log_printf(const char *format, ... /* ** $Log: log.c,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:46:46 ben +** add new input for NES music file. ** ** Revision 1.5 2000/06/26 04:55:33 matt ** minor change diff --git a/src/libxineadec/nosefart/log.h b/src/libxineadec/nosefart/log.h --- a/src/libxineadec/nosefart/log.h +++ b/src/libxineadec/nosefart/log.h @@ -20,7 +20,7 @@ ** log.h ** ** Error logging header file -** $Id: log.h,v 1.3 2006/04/21 23:15:45 dsalt Exp $ +** $Id: log.h,v 1.1 2003/04/08 20:46:46 ben Exp $ */ #ifndef _LOG_H_ @@ -38,14 +38,8 @@ extern void log_printf(const char *forma /* ** $Log: log.h,v $ -** Revision 1.3 2006/04/21 23:15:45 dsalt -** Add printf format attributes. -** -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:46:46 ben +** add new input for NES music file. ** ** Revision 1.4 2000/06/09 15:12:25 matt ** initial revision diff --git a/src/libxineadec/nosefart/memguard.c b/src/libxineadec/nosefart/memguard.c --- a/src/libxineadec/nosefart/memguard.c +++ b/src/libxineadec/nosefart/memguard.c @@ -22,7 +22,7 @@ ** memory allocation wrapper routines ** ** NOTE: based on code (c) 1998 the Retrocade group -** $Id: memguard.c,v 1.4 2004/02/20 19:53:39 komadori Exp $ +** $Id: memguard.c,v 1.1 2003/04/08 20:46:46 ben Exp $ */ #include "types.h" @@ -372,38 +372,8 @@ void mem_checkblocks(void) /* ** $Log: memguard.c,v $ -** Revision 1.4 2004/02/20 19:53:39 komadori -** Fixed detection of linux framebuffer support. Included xineutils.h in dsputil_mlib.c and added to diff_to_ffmpeg_cvs.txt. Fixed function prototype in dsputil_mlib.c (should be sent back to ffmpeg-dev at some point). Fixed includes in nosefart. Fixed nested comments and includes in goom. -** -** Revision 1.3 2004/02/19 02:50:25 rockyb -** Mandrake patches from -** http://cvs.mandrakesoft.com/cgi-bin/cvsweb.cgi/SPECS/xine-lib/ -** via Goetz Waschk who reports: -** -** The amd64 patch (xine-lib-1-rc0a-amd64.patch) sets some conservative -** CFLAGS for amd64, -** -** the lib64 patch (xine-lib-1-rc0a-lib64.patch) replaces hardcoded -** /lib to support the lib64 library dir on amd64, -** -** the directfb patch (xine-lib-1-rc2-no-directfb.patch) adds a -** configure option to disable directfb, -** -** the linuxfb patch (xine-lib-1-rc3a-no-linuxfb.patch) does the same -** for linux framebuffer and -** -** the 64bit fixes patch (xine-lib-1-rc3-64bit-fixes.patch) doesn't -** apply at the moment against the CVS -- demux_ogg.c was not applied. -** it includes some 64 bit pointer and other fixes for 64bit architectures. -** from Gwenole Beauchesne -** -** I haven't tested other than apply and compile. -** -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:46:46 ben +** add new input for NES music file. ** ** Revision 1.8 2000/06/26 04:54:48 matt ** simplified and made more robust diff --git a/src/libxineadec/nosefart/memguard.h b/src/libxineadec/nosefart/memguard.h --- a/src/libxineadec/nosefart/memguard.h +++ b/src/libxineadec/nosefart/memguard.h @@ -20,7 +20,7 @@ ** memguard.h ** ** memory allocation wrapper routines -** $Id: memguard.h,v 1.2 2003/03/01 02:23:01 storri Exp $ +** $Id: memguard.h,v 1.1 2003/04/08 20:46:46 ben Exp $ */ #ifndef _MEMGUARD_H_ @@ -54,11 +54,8 @@ extern boolean mem_debug; /* ** $Log: memguard.h,v $ -** Revision 1.2 2003/03/01 02:23:01 storri -** Added new line at end of file to remove compiler warning. -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:46:46 ben +** add new input for NES music file. ** ** Revision 1.5 2000/06/26 04:54:48 matt ** simplified and made more robust @@ -67,4 +64,3 @@ extern boolean mem_debug; ** initial revision ** */ - diff --git a/src/libxineadec/nosefart/mmc5_snd.c b/src/libxineadec/nosefart/mmc5_snd.c --- a/src/libxineadec/nosefart/mmc5_snd.c +++ b/src/libxineadec/nosefart/mmc5_snd.c @@ -20,7 +20,7 @@ ** mmc5_snd.c ** ** Nintendo MMC5 sound emulation -** $Id: mmc5_snd.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ +** $Id: mmc5_snd.c,v 1.1 2003/04/08 20:53:01 ben Exp $ */ #include @@ -333,11 +333,8 @@ apuext_t mmc5_ext = /* ** $Log: mmc5_snd.c,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:01 ben +** Adding more files... ** ** Revision 1.6 2000/07/04 04:51:41 matt ** cleanups diff --git a/src/libxineadec/nosefart/mmc5_snd.h b/src/libxineadec/nosefart/mmc5_snd.h --- a/src/libxineadec/nosefart/mmc5_snd.h +++ b/src/libxineadec/nosefart/mmc5_snd.h @@ -20,7 +20,7 @@ ** mmc5_snd.h ** ** Nintendo MMC5 sound emulation header -** $Id: mmc5_snd.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ +** $Id: mmc5_snd.h,v 1.1 2003/04/08 20:53:01 ben Exp $ */ #ifndef _MMC5_SND_H_ @@ -67,11 +67,8 @@ extern apuext_t mmc5_ext; /* ** $Log: mmc5_snd.h,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:01 ben +** Adding more files... ** ** Revision 1.2 2000/06/20 04:06:16 matt ** migrated external sound definition to apu module diff --git a/src/libxineadec/nosefart/nes6502.c b/src/libxineadec/nosefart/nes6502.c --- a/src/libxineadec/nosefart/nes6502.c +++ b/src/libxineadec/nosefart/nes6502.c @@ -20,7 +20,7 @@ ** nes6502.c ** ** NES custom 6502 (2A03) CPU implementation -** $Id: nes6502.c,v 1.2 2003/01/09 19:50:03 jkeil Exp $ +** $Id: nes6502.c,v 1.2 2003/05/01 22:34:19 benjihan Exp $ */ @@ -1117,8 +1117,17 @@ */ /* register push/pull */ -#define PUSH(value) stack_page[S--] = (uint8) (value) -#define PULL() stack_page[++S] +#ifdef NES6502_MEM_ACCESS_CTRL + +# define PUSH(value) stack_push((S--),(value)) +# define PULL() stack_pull((++S)) + +#else + +# define PUSH(value) stack_page[S--] = (uint8) (value) +# define PULL() stack_page[++S] + +#endif /* #ifdef NES6502_MEM_ACCESS_CTRL */ /* Sets the Z and N flags based on given data, taken from precomputed table */ #define SET_NZ_FLAGS(value) P &= ~(N_FLAG | Z_FLAG); \ @@ -1166,37 +1175,136 @@ static uint8 *ram = NULL; static uint8 *ram = NULL; static uint8 *stack_page = NULL; +/* access flag for memory + * $$$ ben : I add this for the playing time calculation. + * Only if compiled with NES6502_MEM_ACCESS. + */ +#ifdef NES6502_MEM_ACCESS_CTRL + +uint8 *acc_nes6502_banks[NES6502_NUMBANKS]; +static uint8 *acc_ram = NULL; +static uint8 *acc_stack_page = NULL; +uint8 nes6502_mem_access = 0; + +/* $$$ ben : + * Set memory access check flags, and store ORed frame global check + * for music time calculation. + */ +static void chk_mem_access(uint8 * access, int flags) +{ + uint8 oldchk = * access; + if ((oldchk&flags) != flags) { + nes6502_mem_access |= flags; + *access = oldchk|flags; + } +} + +INLINE void stack_push(uint8 s, uint8 v) +{ + chk_mem_access(acc_stack_page+s, NES6502_WRITE_ACCESS); + stack_page[s] = v; +} + +INLINE uint8 stack_pull(uint8 s) +{ + chk_mem_access(acc_stack_page+s, NES6502_READ_ACCESS); + return stack_page[s]; +} + +INLINE uint8 zp_read(register uint32 addr) +{ + chk_mem_access(acc_ram+addr, NES6502_READ_ACCESS); + return ram[addr]; +} + +INLINE void zp_write(register uint32 addr, uint8 v) +{ + chk_mem_access(acc_ram+addr, NES6502_WRITE_ACCESS); + ram[addr] = v; +} + +#define ZP_READ(addr) zp_read((addr)) +#define ZP_WRITE(addr, value) zp_write((addr),(value)) + +#define bank_readbyte(address) _bank_readbyte((address), NES6502_READ_ACCESS) +#define bank_readbyte_pc(address) _bank_readbyte((address), NES6502_EXE_ACCESS) + +#else +# define chk_mem_access(access, flags) /* ** Zero-page helper macros */ - #define ZP_READ(addr) ram[(addr)] #define ZP_WRITE(addr, value) ram[(addr)] = (uint8) (value) +#define bank_readbyte(address) _bank_readbyte((address)) +#define bank_readbyte_pc(address) _bank_readbyte((address)) -INLINE uint8 bank_readbyte(register uint32 address) +#endif /* #ifdef NES6502_MEM_ACCESS_CTRL */ + +#ifdef NES6502_MEM_ACCESS_CTRL +int max_access[NES6502_NUMBANKS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +INLINE uint8 _bank_readbyte(register uint32 address, const uint8 flags) +#else +INLINE uint8 _bank_readbyte(register uint32 address) +#endif { ASSERT(nes6502_banks[address >> NES6502_BANKSHIFT]); + +#ifdef NES6502_MEM_ACCESS_CTRL + //printf("chk_mem_access(acc_nes6502_banks[%d] + %d, %d)\n", address>>NES6502_BANKSHIFT, address & NES6502_BANKMASK, flags); + + if((address & NES6502_BANKMASK) > max_access[address>>NES6502_BANKSHIFT]) + { + max_access[address>>NES6502_BANKSHIFT] = address & NES6502_BANKMASK; + //printf("max_access[%d] increased to %d\n", address>>NES6502_BANKSHIFT, max_access[address>>NES6502_BANKSHIFT]); + } +#endif + chk_mem_access(acc_nes6502_banks[address>>NES6502_BANKSHIFT] + + (address & NES6502_BANKMASK), + flags); + return nes6502_banks[address >> NES6502_BANKSHIFT][address & NES6502_BANKMASK]; } + INLINE void bank_writebyte(register uint32 address, register uint8 value) { ASSERT(nes6502_banks[address >> NES6502_BANKSHIFT]); + +#ifdef NES6502_MEM_ACCESS_CTRL + //printf("chk_mem_access(acc_nes6502_banks[%d] + %d, %d)\n", address>>NES6502_BANKSHIFT, address & NES6502_BANKMASK, NES6502_WRITE_ACCESS); + + if((address & NES6502_BANKMASK) > max_access[address>>NES6502_BANKSHIFT]) + { + max_access[address>>NES6502_BANKSHIFT] = address & NES6502_BANKMASK; + //printf("max_access[%d] increased to %d\n", address>>NES6502_BANKSHIFT, max_access[address>>NES6502_BANKSHIFT]); + } +#endif + + chk_mem_access(acc_nes6502_banks[address>>NES6502_BANKSHIFT] + + (address & NES6502_BANKMASK), + NES6502_WRITE_ACCESS); + nes6502_banks[address >> NES6502_BANKSHIFT][address & NES6502_BANKMASK] = value; } +/* Read a 16bit word */ +#define READ_SNES_16(bank,offset) \ +(\ + (offset) [ (uint8 *) (bank) ] |\ + ((unsigned int)( ((offset)+1) [ (uint8 *) (bank) ] ) << 8)\ +) + INLINE uint32 zp_address(register uint8 address) { - uint8 *x = ram + address; - return (x[1] << 8) | x[0]; -} + chk_mem_access(acc_ram+address, NES6502_READ_ACCESS); + chk_mem_access(acc_ram+address+1, NES6502_READ_ACCESS); -INLINE uint32 bank_readaddress(register uint32 address) -{ - uint8 *x = nes6502_banks[address >> NES6502_BANKSHIFT] + (address & NES6502_BANKMASK); - return (x[1] << 8) | x[0]; + uint8 *x = ram + address; + return (x[1] << 8) | x[0]; } /* read a byte of 6502 memory */ @@ -1204,12 +1312,15 @@ static uint8 mem_read(uint32 address) { /* TODO: following cases are N2A03-specific */ /* RAM */ - if (address < 0x800) - return ram[address]; + if (address < 0x800) { + chk_mem_access(acc_ram + address, NES6502_READ_ACCESS); + return ram[address]; + } /* always paged memory */ // else if (address >= 0x6000) - else if (address >= 0x8000) - return bank_readbyte(address); + else if (address >= 0x8000) { + return bank_readbyte(address); + } /* check memory range handlers */ else { @@ -1224,12 +1335,18 @@ static uint8 mem_read(uint32 address) return bank_readbyte(address); } +INLINE uint32 bank_readaddress(register uint32 address) +{ + return mem_read (address) | mem_read ((address + 1) & 0xFFFF) << 8; +} + /* write a byte of data to 6502 memory */ static void mem_write(uint32 address, uint8 value) { /* RAM */ if (address < 0x800) { + chk_mem_access(acc_ram + address, NES6502_WRITE_ACCESS); ram[address] = value; return; } @@ -1258,11 +1375,19 @@ void nes6502_setcontext(nes6502_context ASSERT(cpu); /* Set the page pointers */ - for (loop = 0; loop < NES6502_NUMBANKS; loop++) + for (loop = 0; loop < NES6502_NUMBANKS; loop++) { nes6502_banks[loop] = cpu->mem_page[loop]; +#ifdef NES6502_MEM_ACCESS_CTRL + acc_nes6502_banks[loop] = cpu->acc_mem_page[loop]; +#endif + } ram = nes6502_banks[0]; /* quicker zero-page/RAM references */ stack_page = ram + STACK_OFFSET; +#ifdef NES6502_MEM_ACCESS_CTRL + acc_ram = acc_nes6502_banks[0]; /* quicker zero-page/RAM references */ + acc_stack_page = acc_ram + STACK_OFFSET; +#endif pmem_read = cpu->read_handler; pmem_write = cpu->write_handler; @@ -1283,8 +1408,12 @@ void nes6502_getcontext(nes6502_context int loop; /* Set the page pointers */ - for (loop = 0; loop < NES6502_NUMBANKS; loop++) + for (loop = 0; loop < NES6502_NUMBANKS; loop++) { cpu->mem_page[loop] = nes6502_banks[loop]; +#ifdef NES6502_MEM_ACCESS_CTRL + cpu->acc_mem_page[loop] = acc_nes6502_banks[loop]; +#endif + } cpu->read_handler = pmem_read; cpu->write_handler = pmem_write; @@ -1333,7 +1462,14 @@ int nes6502_execute(int remaining_cycles GET_GLOBAL_REGS(); +#ifdef NES6502_MEM_ACCESS_CTRL + /* reset global memory access for this execute loop. */ + nes6502_mem_access = 0; +#endif + /* Continue until we run out of cycles */ + + while (remaining_cycles > 0) { instruction_cycles = 0; @@ -1373,9 +1509,10 @@ int nes6502_execute(int remaining_cycles /* Fetch instruction */ //nes6502_disasm(PC, P, A, X, Y, S); - opcode = bank_readbyte(PC++); + opcode = bank_readbyte_pc(PC++); /* Execute instruction */ + switch (opcode) { case 0x00: /* BRK */ @@ -2363,16 +2500,20 @@ void nes6502_setdma(int cycles) dma_cycles += cycles; } +#ifdef NES6502_MEM_ACCESS_CTRL +void nes6502_chk_mem_access(uint8 * access, int flags) +{ + chk_mem_access(access, flags); +} +#endif + /* ** $Log: nes6502.c,v $ -** Revision 1.2 2003/01/09 19:50:03 jkeil -** NSF audio files were crashing on SPARC. +** Revision 1.2 2003/05/01 22:34:19 benjihan +** New NSF plugin ** -** - Define the correct HOST_ENDIAN for SPARC -** - remove unaligned memory accesses -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:00 ben +** Adding more files... ** ** Revision 1.6 2000/07/04 04:50:07 matt ** minor change to includes diff --git a/src/libxineadec/nosefart/nes6502.h b/src/libxineadec/nosefart/nes6502.h --- a/src/libxineadec/nosefart/nes6502.h +++ b/src/libxineadec/nosefart/nes6502.h @@ -20,8 +20,11 @@ ** nes6502.h ** ** NES custom 6502 CPU definitions / prototypes -** $Id: nes6502.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ +** $Id: nes6502.h,v 1.2 2003/05/01 22:34:19 benjihan Exp $ */ + +/* straitm */ +#include "types.h" /* NOTE: 16-bit addresses avoided like the plague: use 32-bit values ** wherever humanly possible @@ -47,6 +50,17 @@ #define NES6502_BANKMASK ((0x10000 / NES6502_NUMBANKS) - 1) +/* Add memory access control flags. This is a ram shadow memory that holds + * for each memory bytes access flags for read, write and execute access. + * The nes6502_mem_access holds all new access (all mode all location). It is + * used to determine if the player has loop in playing time calculation. + */ +#ifdef NES6502_MEM_ACCESS_CTRL +extern uint8 nes6502_mem_access; +# define NES6502_READ_ACCESS 1 +# define NES6502_WRITE_ACCESS 2 +# define NES6502_EXE_ACCESS 4 +#endif /* #ifdef NES6502_MEM_ACCESS_CTRL */ /* P (flag) register bitmasks */ #define N_FLAG 0x80 @@ -87,7 +101,10 @@ typedef struct typedef struct { - uint8 *mem_page[NES6502_NUMBANKS]; /* memory page pointers */ + uint8 * mem_page[NES6502_NUMBANKS]; /* memory page pointers */ +#ifdef NES6502_MEM_ACCESS_CTRL + uint8 * acc_mem_page[NES6502_NUMBANKS]; /* memory access page pointer */ +#endif nes6502_memread *read_handler; nes6502_memwrite *write_handler; int dma_cycles; @@ -110,6 +127,12 @@ extern uint32 nes6502_getcycles(boolean extern uint32 nes6502_getcycles(boolean reset_flag); extern void nes6502_setdma(int cycles); +#ifdef NES6502_MEM_ACCESS_CTRL +extern void nes6502_chk_mem_access(uint8 * access, int flags); +#else +#define nes6502_chk_mem_access(access,flags) +#endif + /* Context get/set */ extern void nes6502_setcontext(nes6502_context *cpu); extern void nes6502_getcontext(nes6502_context *cpu); @@ -122,11 +145,11 @@ extern void nes6502_getcontext(nes6502_c /* ** $Log: nes6502.h,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... +** Revision 1.2 2003/05/01 22:34:19 benjihan +** New NSF plugin ** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:00 ben +** Adding more files... ** ** Revision 1.4 2000/06/09 15:12:25 matt ** initial revision diff --git a/src/libxineadec/nosefart/nes_apu.c b/src/libxineadec/nosefart/nes_apu.c --- a/src/libxineadec/nosefart/nes_apu.c +++ b/src/libxineadec/nosefart/nes_apu.c @@ -20,7 +20,7 @@ ** nes_apu.c ** ** NES APU emulation -** $Id: nes_apu.c,v 1.4 2005/05/07 09:11:39 valtri Exp $ +** $Id: nes_apu.c,v 1.2 2003/04/09 14:50:32 ben Exp $ */ #include @@ -57,6 +57,11 @@ static int8 noise_short_lut[APU_NOISE_93 static int8 noise_short_lut[APU_NOISE_93]; #endif /* !REALTIME_NOISE */ +/* $$$ ben : last error */ +#define SET_APU_ERROR(APU,X) \ +if (APU) (APU)->errstr = "apu: " X; else + +#define APU_MIX_ENABLE(BIT) (apu->mix_enable&(1<<(BIT))) /* vblank length table used for rectangles, triangle, noise */ static const uint8 vbl_length[32] = @@ -102,27 +107,31 @@ const int dmc_clocks[16] = /* ratios of pos/neg pulse for rectangle waves */ static const int duty_lut[4] = { 2, 4, 8, 12 }; -#if 0 /* unused */ -static void apu_setcontext(apu_t *src_apu) +void apu_setcontext(apu_t *src_apu) { apu = src_apu; + /* $$$ ben reset eoor string here. */ + SET_APU_ERROR(apu,"no error"); } -#endif /* ** Simple queue routines */ #define APU_QEMPTY() (apu->q_head == apu->q_tail) -static void apu_enqueue(apudata_t *d) +static int apu_enqueue(apudata_t *d) { ASSERT(apu); apu->queue[apu->q_head] = *d; apu->q_head = (apu->q_head + 1) & APUQUEUE_MASK; - if (APU_QEMPTY()) + if (APU_QEMPTY()) { log_printf("apu: queue overflow\n"); + SET_APU_ERROR(apu,"queue overflow"); + return -1; + } + return 0; } static apudata_t *apu_dequeue(void) @@ -131,19 +140,32 @@ static apudata_t *apu_dequeue(void) ASSERT(apu); - if (APU_QEMPTY()) - log_printf("apu: queue empty\n"); - + if (APU_QEMPTY()) { + log_printf("apu: queue empty\n"); + SET_APU_ERROR(apu,"queue empty"); + /* $$$ ben : should return 0 ??? */ + } loc = apu->q_tail; apu->q_tail = (apu->q_tail + 1) & APUQUEUE_MASK; return &apu->queue[loc]; } -void apu_setchan(int chan, boolean enabled) +int apu_setchan(int chan, boolean enabled) { - ASSERT(apu); - apu->mix_enable[chan] = enabled; + const unsigned int max = 6; + int old; + + ASSERT(apu); + if ((unsigned int)chan >= max) { + SET_APU_ERROR(apu,"channel out of range"); + return -1; + } + old = (apu->mix_enable>>chan) & 1; + if (enabled != (boolean)-1) { + apu->mix_enable = (apu->mix_enable & ~(1<cycle_rate); accum = 0; - if (apu->mix_enable[0]) accum += apu_rectangle(&apu->rectangle[0]); - if (apu->mix_enable[1]) accum += apu_rectangle(&apu->rectangle[1]); - if (apu->mix_enable[2]) accum += apu_triangle(&apu->triangle); - if (apu->mix_enable[3]) accum += apu_noise(&apu->noise); - if (apu->mix_enable[4]) accum += apu_dmc(&apu->dmc); + if (APU_MIX_ENABLE(0)) accum += apu_rectangle(&apu->rectangle[0]); + if (APU_MIX_ENABLE(1)) accum += apu_rectangle(&apu->rectangle[1]); + if (APU_MIX_ENABLE(2)) accum += apu_triangle(&apu->triangle); + if (APU_MIX_ENABLE(3)) accum += apu_noise(&apu->noise); + if (APU_MIX_ENABLE(4)) accum += apu_dmc(&apu->dmc); - if (apu->ext && apu->mix_enable[5]) accum += apu->ext->process(); + if (apu->ext && APU_MIX_ENABLE(5)) accum += apu->ext->process(); /* do any filtering */ if (APU_FILTER_NONE != apu->filter_type) @@ -1012,11 +1034,12 @@ void apu_process(void *buffer, int num_s /* signed 16-bit output, unsigned 8-bit */ if (16 == apu->sample_bits) { - *((int16 *) buffer) = (int16) accum; - buffer = (int16 *) buffer + 1; - } else { - *((uint8 *) buffer) = (accum >> 8) ^ 0x80; - buffer = (int8 *) buffer + 1; + *(int16 *)(buffer) = (int16) accum; + buffer += sizeof(int16); + } + else { + *(uint8 *)(buffer) = (accum >> 8) ^ 0x80; + buffer += sizeof(uint8); } } @@ -1025,10 +1048,18 @@ void apu_process(void *buffer, int num_s } /* set the filter type */ -void apu_setfilter(int filter_type) +/* $$$ ben : + * Add a get feature (filter_type == -1) and returns old filter type + */ +int apu_setfilter(int filter_type) { + int old; ASSERT(apu); - apu->filter_type = filter_type; + old = apu->filter_type; + if (filter_type != -1) { + apu->filter_type = filter_type; + } + return old; } void apu_reset(void) @@ -1090,12 +1121,15 @@ apu_t *apu_create(int sample_rate, int r apu_t *apu_create(int sample_rate, int refresh_rate, int sample_bits, boolean stereo) { apu_t *temp_apu; - int channel; +/* int channel; */ temp_apu = malloc(sizeof(apu_t)); if (NULL == temp_apu) return NULL; + /* $$$ ben : safety net, in case we forgot to init something */ + memset(temp_apu,0,sizeof(apu_t)); + SET_APU_ERROR(temp_apu,"no error"); temp_apu->sample_rate = sample_rate; temp_apu->refresh_rate = refresh_rate; temp_apu->sample_bits = sample_bits; @@ -1114,8 +1148,9 @@ apu_t *apu_create(int sample_rate, int r apu_setactive(temp_apu); apu_reset(); - for (channel = 0; channel < 6; channel++) - apu_setchan(channel, TRUE); + temp_apu->mix_enable = 0x3F; +/* for (channel = 0; channel < 6; channel++) */ +/* apu_setchan(channel, TRUE); */ apu_setfilter(APU_FILTER_LOWPASS); @@ -1137,15 +1172,23 @@ void apu_destroy(apu_t *src_apu) } } -void apu_setext(apu_t *src_apu, apuext_t *ext) +int apu_setext(apu_t *src_apu, apuext_t *ext) { ASSERT(src_apu); + + /* $$$ ben : seem cleaner like this */ + if (src_apu->ext) { + src_apu->ext->shutdown(); + } src_apu->ext = ext; /* initialize it */ if (src_apu->ext) src_apu->ext->init(); + + /* $$$ ben : May be one day extension int () will return error code */ + return 0; } /* this exists for external mixing routines */ @@ -1157,18 +1200,11 @@ int32 apu_getcyclerate(void) /* ** $Log: nes_apu.c,v $ -** Revision 1.4 2005/05/07 09:11:39 valtri -** *BUGFIX* -** gcc4 patches from Dams Nadé (livna.org) and Keenan Pepper. +** Revision 1.2 2003/04/09 14:50:32 ben +** Clean NSF api. ** -** Revision 1.3 2004/12/12 06:55:59 athp -** Code cleanups and elimination of some compiler warnings; patch courtesy of AL13N -** -** Revision 1.2 2003/08/25 21:51:43 f1rmb -** Reduce GCC verbosity (various prototype declaration fixes). ffmpeg, wine and fft*post are untouched (fft: for now). -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:01 ben +** Adding more files... ** ** Revision 1.19 2000/07/04 04:53:26 matt ** minor changes, sound amplification diff --git a/src/libxineadec/nosefart/nes_apu.h b/src/libxineadec/nosefart/nes_apu.h --- a/src/libxineadec/nosefart/nes_apu.h +++ b/src/libxineadec/nosefart/nes_apu.h @@ -20,7 +20,7 @@ ** nes_apu.h ** ** NES APU emulation header file -** $Id: nes_apu.h,v 1.2 2003/01/09 19:50:03 jkeil Exp $ +** $Id: nes_apu.h,v 1.2 2003/04/09 14:50:32 ben Exp $ */ #ifndef _NES_APU_H_ @@ -249,7 +249,7 @@ typedef struct apu_s void *buffer; /* pointer to output buffer */ int num_samples; - boolean mix_enable[6]; + int mix_enable; /* $$$ben : should improve emulation */ int filter_type; int32 cycle_rate; @@ -260,6 +260,9 @@ typedef struct apu_s void (*process)(void *buffer, int num_samples); + /* $$$ ben : last error string */ + const char * errstr; + /* external sound chip */ apuext_t *ext; } apu_t; @@ -272,13 +275,14 @@ extern "C" { /* Function prototypes */ extern apu_t *apu_create(int sample_rate, int refresh_rate, int sample_bits, boolean stereo); extern void apu_destroy(apu_t *apu); -extern void apu_setext(apu_t *apu, apuext_t *ext); -extern void apu_setfilter(int filter_type); +extern int apu_setext(apu_t *apu, apuext_t *ext); +extern int apu_setfilter(int filter_type); extern void apu_process(void *buffer, int num_samples); extern void apu_reset(void); -extern void apu_setchan(int chan, boolean enabled); +extern int apu_setchan(int chan, boolean enabled); extern int32 apu_getcyclerate(void); extern apu_t *apu_getcontext(void); +extern void apu_setcontext(apu_t *src_apu); extern uint8 apu_read(uint32 address); extern void apu_write(uint32 address, uint8 value); @@ -295,14 +299,11 @@ extern void apu_getpcmdata(void **data, /* ** $Log: nes_apu.h,v $ -** Revision 1.2 2003/01/09 19:50:03 jkeil -** NSF audio files were crashing on SPARC. +** Revision 1.2 2003/04/09 14:50:32 ben +** Clean NSF api. ** -** - Define the correct HOST_ENDIAN for SPARC -** - remove unaligned memory accesses -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:01 ben +** Adding more files... ** ** Revision 1.12 2000/07/04 04:54:48 matt ** minor changes that helped with MAME diff --git a/src/libxineadec/nosefart/nsf.c b/src/libxineadec/nosefart/nsf.c --- a/src/libxineadec/nosefart/nsf.c +++ b/src/libxineadec/nosefart/nsf.c @@ -20,8 +20,9 @@ ** nsf.c ** ** NSF loading/saving related functions -** $Id: nsf.c,v 1.4 2006/09/26 00:52:17 dgp85 Exp $ +** $Id: nsf.c,v 1.3 2003/05/01 22:34:20 benjihan Exp $ */ + #include #include @@ -50,25 +51,34 @@ static void nsf_setcontext(nsf_t *nsf) static uint8 read_mirrored_ram(uint32 address) { - return cur_nsf->cpu->mem_page[0][address & 0x7FF]; + nes6502_chk_mem_access(&cur_nsf->cpu->acc_mem_page[0][address & 0x7FF], + NES6502_READ_ACCESS); + return cur_nsf->cpu->mem_page[0][address & 0x7FF]; } static void write_mirrored_ram(uint32 address, uint8 value) { - cur_nsf->cpu->mem_page[0][address & 0x7FF] = value; + nes6502_chk_mem_access(&cur_nsf->cpu->acc_mem_page[0][address & 0x7FF], + NES6502_WRITE_ACCESS); + cur_nsf->cpu->mem_page[0][address & 0x7FF] = value; } /* can be used for both banked and non-bankswitched NSFs */ static void nsf_bankswitch(uint32 address, uint8 value) { int cpu_page; + int roffset; uint8 *offset; cpu_page = address & 0x0F; - offset = (cur_nsf->data - (cur_nsf->load_addr & 0x0FFF)) + (value << 12); + roffset = -(cur_nsf->load_addr & 0x0FFF) + ((int)value << 12); + offset = cur_nsf->data + roffset; nes6502_getcontext(cur_nsf->cpu); cur_nsf->cpu->mem_page[cpu_page] = offset; +#ifdef NES6502_MEM_ACCESS_CTRL + cur_nsf->cpu->acc_mem_page[cpu_page] = offset + cur_nsf->length; +#endif nes6502_setcontext(cur_nsf->cpu); } @@ -248,6 +258,18 @@ static void nsf_inittune(nsf_t *nsf) memset(nsf->cpu->mem_page[6], 0, 0x1000); memset(nsf->cpu->mem_page[7], 0, 0x1000); +#ifdef NES6502_MEM_ACCESS_CTRL + memset(nsf->cpu->acc_mem_page[0], 0, 0x800); + memset(nsf->cpu->acc_mem_page[6], 0, 0x1000); + memset(nsf->cpu->acc_mem_page[7], 0, 0x1000); + memset(nsf->data+nsf->length, 0, nsf->length); +#endif + nsf->cur_frame = 0; +/* nsf->last_access_frame = 0; */ + nsf->cur_frame_end = !nsf->song_frames + ? 0 + : nsf->song_frames[nsf->current_song]; + if (nsf->bankswitched) { /* the first hack of the NSF spec! */ @@ -289,11 +311,39 @@ static void nsf_inittune(nsf_t *nsf) void nsf_frame(nsf_t *nsf) { - //nsf_setcontext(nsf); /* future expansion =) */ + // This is how Matthew Conte left it + //nsf_setcontext(nsf); /* future expansion =) */ + + // This was suggested by Arne Morten Kvarving, who says: +/* Also, I fixed a bug that prevented Nosefart to play multiple tunes at + one time (actually it was just a few missing setcontext calls in the + playback routine, it had a nice TODO commented beside it. You had to set + the cpu and apu contexts not just the nsf context). + + it will affect any player that tries to use nosefart to play more than one + tune at a time. +*/ + nsf_setcontext(nsf); + apu_setcontext(nsf->apu); + nes6502_setcontext(nsf->cpu); /* one frame of NES processing */ nsf_setup_routine(nsf->play_addr, 0, 0); nes6502_execute((int) NES_FRAME_CYCLES); + + ++nsf->cur_frame; +#if defined(NES6502_MEM_ACCESS_CTRL) && 0 + if (nes6502_mem_access) { + uint32 sec = + (nsf->last_access_frame + nsf->playback_rate - 1) / nsf->playback_rate; + nsf->last_access_frame = nsf->cur_frame; + fprintf(stderr,"nsf : memory access [%x] at frame #%u [%u:%02u]\n", + nes6502_mem_access, + nsf->last_access_frame, + sec/60, sec%60); + } +#endif + } /* Deallocate memory */ @@ -302,23 +352,40 @@ static void nes_shutdown(nsf_t *nsf) int i; ASSERT(nsf); - + if (nsf->cpu) { if (nsf->cpu->mem_page[0]) - free(nsf->cpu->mem_page[0]); - for (i = 5; i <= 7; i++) - { - if (nsf->cpu->mem_page[i]) - free(nsf->cpu->mem_page[i]); + { + free(nsf->cpu->mem_page[0]);/*tracks 1 and 2 of lifeforce hang here.*/ + } + for (i = 5; i <= 7; i++) { + if (nsf->cpu->mem_page[i]) + { + free(nsf->cpu->mem_page[i]); + } } + +#ifdef NES6502_MEM_ACCESS_CTRL + if (nsf->cpu->acc_mem_page[0]) + { + free(nsf->cpu->acc_mem_page[0]); + } + for (i = 5; i <= 7; i++) { + if (nsf->cpu->acc_mem_page[i]) + { + free(nsf->cpu->acc_mem_page[i]); + } + } +#endif free(nsf->cpu); } } -void nsf_init(void) +int nsf_init(void) { nes6502_init(); + return 0; } /* Initialize NES CPU, hardware, etc. */ @@ -344,18 +411,27 @@ static int nsf_cpuinit(nsf_t *nsf) return -1; } +#ifdef NES6502_MEM_ACCESS_CTRL + nsf->cpu->acc_mem_page[0] = malloc(0x800); + if (NULL == nsf->cpu->acc_mem_page[0]) + return -1; + /* allocate some space for the NSF "player" MMC5 EXRAM, and WRAM */ + for (i = 5; i <= 7; i++) + { + nsf->cpu->acc_mem_page[i] = malloc(0x1000); + if (NULL == nsf->cpu->acc_mem_page[i]) + return -1; + } +#endif + nsf->cpu->read_handler = nsf_readhandler; nsf->cpu->write_handler = nsf_writehandler; return 0; } -static void nsf_setup(nsf_t *nsf) +static unsigned int nsf_playback_rate(nsf_t *nsf) { - int i; - - nsf->current_song = nsf->start_song; - if (nsf->pal_ntsc_bits & NSF_DEDICATED_PAL) { if (nsf->pal_speed) @@ -370,9 +446,17 @@ static void nsf_setup(nsf_t *nsf) else nsf->playback_rate = 60; /* 60 Hz */ } + return 0; +} + +static void nsf_setup(nsf_t *nsf) +{ + int i; + + nsf->current_song = nsf->start_song; + nsf_playback_rate(nsf); nsf->bankswitched = FALSE; - for (i = 0; i < 8; i++) { if (nsf->bankswitch_info[i]) @@ -389,212 +473,559 @@ static void nsf_setup(nsf_t *nsf) #define SWAP_16(x) (((uint16) x >> 8) | (((uint16) x & 0xFF) << 8)) #endif /* !HOST_LITTLE_ENDIAN */ -/* Load a ROM image into memory */ -nsf_t *nsf_load(char *filename, void *source, int length) +/* $$$ ben : find extension. Should be OK with DOS, but not with some + * OS like RiscOS ... */ +static char * find_ext(char *fn) { - FILE *fp = NULL; - char *new_fn = NULL; - nsf_t *temp_nsf; + char * a, * b, * c; + a = strrchr(fn,'.'); + b = strrchr(fn,'/'); + c = strrchr(fn,'\\'); + if (a <= b || a <= c) { + a = 0; + } + return a; +} - if (NULL == filename && NULL == source) - return NULL; - - if (NULL == source) - { - fp = fopen(filename, "rb"); +/* $$$ ben : FILE loader */ +struct nsf_file_loader_t { + struct nsf_loader_t loader; + FILE *fp; + char * fname; + int name_allocated; +}; - /* Didn't find the file? Maybe the .NSF extension was omitted */ - if (NULL == fp) - { - new_fn = malloc(strlen(filename) + 5); - if (NULL == new_fn) - return NULL; - strcpy(new_fn, filename); +static int nfs_open_file(struct nsf_loader_t *loader) +{ + struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; - if (NULL == strrchr(new_fn, '.')) - strcat(new_fn, ".nsf"); + floader->name_allocated = 0; + floader->fp = 0; + if (!floader->fname) { + return -1; + } + floader->fp = fopen(floader->fname,"rb"); + if (!floader->fp) { + char * fname, * ext; + ext = find_ext(floader->fname); + if (ext) { + /* There was an extension, so we do not change it */ + return -1; + } + fname = malloc(strlen(floader->fname) + 5); + if (!fname) { + return -1; + } + /* try with .nsf extension. */ + strcpy(fname, floader->fname); + strcat(fname, ".nsf"); + floader->fp = fopen(fname,"rb"); + if (!floader->fp) { + free(fname); + return -1; + } + floader->fname = fname; + floader->name_allocated = 1; + } + return 0; +} - fp = fopen(new_fn, "rb"); +static void nfs_close_file(struct nsf_loader_t *loader) +{ + struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; + if (floader->fp) { + fclose(floader->fp); + floader->fp = 0; + } + if (floader->fname && floader->name_allocated) { + free(floader->fname); + floader->fname = 0; + floader->name_allocated = 0; + } +} - if (NULL == fp) - { - log_printf("could not find file '%s'\n", new_fn); - free(new_fn); - return NULL; - } +static int nfs_read_file(struct nsf_loader_t *loader, void *data, int n) +{ + struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; + int r = fread(data, 1, n, floader->fp); + if (r >= 0) { + r = n-r; + } + return r; +} + +static int nfs_length_file(struct nsf_loader_t *loader) +{ + struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; + long save, pos; + save = ftell(floader->fp); + fseek(floader->fp, 0, SEEK_END); + pos = ftell(floader->fp); + fseek(floader->fp, save, SEEK_SET); + return pos; +} + +static int nfs_skip_file(struct nsf_loader_t *loader, int n) +{ + struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; + int r; + r = fseek(floader->fp, n, SEEK_CUR); + return r; +} + +static const char * nfs_fname_file(struct nsf_loader_t *loader) +{ + struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; + return floader->fname ? floader->fname : ""; +} + +static struct nsf_file_loader_t nsf_file_loader = { + { + nfs_open_file, + nfs_close_file, + nfs_read_file, + nfs_length_file, + nfs_skip_file, + nfs_fname_file + }, + 0,0,0 +}; + +struct nsf_mem_loader_t { + struct nsf_loader_t loader; + uint8 *data; + unsigned long cur; + unsigned long len; + char fname[32]; +}; + +static int nfs_open_mem(struct nsf_loader_t *loader) +{ + struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; + if (!mloader->data) { + return -1; + } + mloader->cur = 0; + sprintf(mloader->fname,"", + mloader->data, (unsigned int)mloader->len); + return 0; +} + +static void nfs_close_mem(struct nsf_loader_t *loader) +{ + struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; + mloader->data = 0; + mloader->cur = 0; + mloader->len = 0; +} + +static int nfs_read_mem(struct nsf_loader_t *loader, void *data, int n) +{ + struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; + int rem; + if (n <= 0) { + return n; + } + if (!mloader->data) { + return -1; + } + rem = mloader->len - mloader->cur; + if (rem > n) { + rem = n; + } + memcpy(data, mloader->data + mloader->cur, rem); + mloader->cur += rem; + return n - rem; +} + +static int nfs_length_mem(struct nsf_loader_t *loader) +{ + struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; + return mloader->len; +} + +static int nfs_skip_mem(struct nsf_loader_t *loader, int n) +{ + struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; + unsigned long goal = mloader->cur + n; + mloader->cur = (goal > mloader->len) ? mloader->len : goal; + return goal - mloader->cur; +} + +static const char * nfs_fname_mem(struct nsf_loader_t *loader) +{ + struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; + return mloader->fname; +} + +static const char *nsf_fname_null (struct nsf_loader_t *loader) +{ + return ""; +} + +static struct nsf_mem_loader_t nsf_mem_loader = { + { nfs_open_mem, nfs_close_mem, nfs_read_mem, nfs_length_mem, nfs_skip_mem }, + 0,0,0 +}; + +nsf_t * nsf_load_extended(struct nsf_loader_t * loader) +{ + nsf_t *temp_nsf = 0; + int length; + char id[6]; + + struct { + uint8 magic[4]; /* always "NESM" */ + uint8 type[4]; /* defines extension type */ + uint8 size[4]; /* extension data size (this struct include) */ + } nsf_file_ext; + + /* no loader ! */ + if (!loader) { + return NULL; + } + + /* Open the "file" */ + if (loader->open(loader) < 0) { + return NULL; + } + + if (!loader->fname) + loader->fname = nsf_fname_null; //nfs_fname_mem; + + /* Get file size, and exit if there is not enough data for NSF header + * and more since it does not make sens to have header without data. + */ + length = loader->length(loader); + /* For version 2, we do not need file length. just check error later. */ +#if 0 + if (length <= NSF_HEADER_SIZE) { + log_printf("nsf : [%s] not an NSF format file\n", + loader->fname(loader)); + goto error; + } +#endif + + /* Read magic */ + if (loader->read(loader, id, 5)) { + log_printf("nsf : [%s] error reading magic number\n", + loader->fname(loader)); + goto error; + } + + /* Check magic */ + if (memcmp(id, NSF_MAGIC, 5)) { + log_printf("nsf : [%s] is not an NSF format file\n", + loader->fname(loader)); + goto error; + } + + /* $$$ ben : Now the file should be an NSF, we can start allocating. + * first : the nsf struct + */ + temp_nsf = malloc(sizeof(nsf_t)); + + if (NULL == temp_nsf) { + log_printf("nsf : [%s] error allocating nsf header\n", + loader->fname(loader)); + goto error; + } + /* $$$ ben : safety net */ + memset(temp_nsf,0,sizeof(nsf_t)); + /* Copy magic ID */ + memcpy(temp_nsf,id,5); + + /* Read header (without MAGIC) */ + if (loader->read(loader, (int8 *)temp_nsf+5, NSF_HEADER_SIZE - 5)) { + log_printf("nsf : [%s] error reading nsf header\n", + loader->fname(loader)); + goto error; + } + + /* fixup endianness */ + temp_nsf->load_addr = SWAP_16(temp_nsf->load_addr); + temp_nsf->init_addr = SWAP_16(temp_nsf->init_addr); + temp_nsf->play_addr = SWAP_16(temp_nsf->play_addr); + temp_nsf->ntsc_speed = SWAP_16(temp_nsf->ntsc_speed); + temp_nsf->pal_speed = SWAP_16(temp_nsf->pal_speed); + + /* we're now at position 80h */ + + + /* Here comes the specific codes for spec version 2 */ + + temp_nsf->length = 0; + + if (temp_nsf->version > 1) { + /* Get specified data size in reserved field (3 bytes). */ + temp_nsf->length = 0 + + temp_nsf->reserved[0] + + (temp_nsf->reserved[1]<<8) + + (temp_nsf->reserved[2]<<16); + + } + /* no specified size : try to guess with file length. */ + if (!temp_nsf->length) { + temp_nsf->length = length - NSF_HEADER_SIZE; + } + + if (temp_nsf->length <= 0) { + log_printf("nsf : [%s] not an NSF format file (missing data)\n", + loader->fname(loader)); + goto error; + } + + /* Allocate NSF space, and load it up! */ + { + int len = temp_nsf->length; +#ifdef NES6502_MEM_ACCESS_CTRL + /* $$$ twice memory for access control shadow mem. */ + len <<= 1; +#endif + temp_nsf->data = malloc(len); + } + if (NULL == temp_nsf->data) { + log_printf("nsf : [%s] error allocating nsf data\n", + loader->fname(loader)); + goto error; + } + + /* Read data */ + if (loader->read(loader, temp_nsf->data, temp_nsf->length)) { + log_printf("nsf : [%s] error reading NSF data\n", + loader->fname(loader)); + goto error; + } + + /* Here comes the second part of spec > 1 : get extension */ + while (!loader->read(loader, &nsf_file_ext, sizeof(nsf_file_ext)) + && !memcmp(nsf_file_ext.magic,id,4)) { + /* Got a NESM extension here. Checks for known extension type : + * right now, the only extension is "TIME" which give songs length. + * in frames. + */ + int size; + size = 0 + + nsf_file_ext.size[0] + + (nsf_file_ext.size[1] << 8) + + (nsf_file_ext.size[2] << 16) + + (nsf_file_ext.size[3] << 24); + + if (size < sizeof(nsf_file_ext)) { + log_printf("nsf : [%s] corrupt extension size (%d)\n", + loader->fname(loader), size); + /* Not a fatal error here. Just skip extension loading. */ + break; + } + size -= sizeof(nsf_file_ext); + + if (!temp_nsf->song_frames + && !memcmp(nsf_file_ext.type,"TIME", 4) + && !(size & 3) + && (size >= 2*4) + && (size <= 256*4)) { + + uint8 tmp_time[256][4]; + int tsongs = size >> 2; + int i; + int songs = temp_nsf->num_songs; + + /* Add 1 for 0 which contains total time for all songs. */ + ++songs; + + if (loader->read(loader, tmp_time, size)) { + log_printf("nsf : [%s] missing extension data\n", + loader->fname(loader)); + /* Not a fatal error here. Just skip extension loading. */ + break; } - } + /* Alloc song_frames for songs (not tsongs). */ + temp_nsf->song_frames = malloc(sizeof(*temp_nsf->song_frames) * songs); + if (!temp_nsf->song_frames) { + log_printf("nsf : [%s] extension alloc failed\n", + loader->fname(loader)); + /* Not a fatal error here. Just skip extension loading. */ + break; + } - temp_nsf = malloc(sizeof(nsf_t)); - if (NULL == temp_nsf) { - fclose(fp); - free(new_fn); - return NULL; - } + if (tsongs > songs) { + tsongs = songs; + } + + /* Copy time info. */ + for (i=0; isong_frames[i] = 0 + | tmp_time[i][0] + | (tmp_time[i][1] << 8) + | (tmp_time[i][2] << 16) + | (tmp_time[i][2] << 24); + } + /* Clear missing (safety net). */ + for (; isong_frames[i] = 0; + } + } else if (loader->skip(loader, size)) { + log_printf("nsf : [%s] extension skip failed\n", + loader->fname(loader)); + /* Not a fatal error here. Just skip extension loading. */ + break; + } + } + - /* Read in the header */ - if (NULL == source) - fread(temp_nsf, 1, NSF_HEADER_SIZE, fp); - else - memcpy(temp_nsf, source, NSF_HEADER_SIZE); - - if (memcmp(temp_nsf->id, NSF_MAGIC, 5)) - { - if (NULL == source) - { - log_printf("%s is not an NSF format file\n", new_fn); - fclose(fp); - free(new_fn); - } - nsf_free(&temp_nsf); - return NULL; - } - - /* fixup endianness */ - temp_nsf->load_addr = SWAP_16(temp_nsf->load_addr); - temp_nsf->init_addr = SWAP_16(temp_nsf->init_addr); - temp_nsf->play_addr = SWAP_16(temp_nsf->play_addr); - temp_nsf->ntsc_speed = SWAP_16(temp_nsf->ntsc_speed); - temp_nsf->pal_speed = SWAP_16(temp_nsf->pal_speed); - - /* we're now at position 80h */ - if (NULL == source) - { - fseek(fp, 0, SEEK_END); - temp_nsf->length = ftell(fp) - NSF_HEADER_SIZE; - } - else - { - temp_nsf->length = length - NSF_HEADER_SIZE; - } - - /* Allocate NSF space, and load it up! */ - temp_nsf->data = malloc(temp_nsf->length); - if (NULL == temp_nsf->data) - { - log_printf("error allocating memory for NSF data\n"); - nsf_free(&temp_nsf); - return NULL; - } - - /* seek to end of header, read in data */ - if (NULL == source) - { - fseek(fp, NSF_HEADER_SIZE, SEEK_SET); - fread(temp_nsf->data, temp_nsf->length, 1, fp); - - fclose(fp); - - if (new_fn) - free(new_fn); - } - else - memcpy(temp_nsf->data, (uint8 *) source + NSF_HEADER_SIZE, length - NSF_HEADER_SIZE); + /* Close "file" */ + loader->close(loader); + loader = 0; /* Set up some variables */ nsf_setup(temp_nsf); - temp_nsf->apu = NULL; /* just make sure */ - if (nsf_cpuinit(temp_nsf)) - { - nsf_free(&temp_nsf); - return NULL; + if (nsf_cpuinit(temp_nsf)) { + log_printf("nsf : error cpu init\n"); + goto error; } + return temp_nsf; - return temp_nsf; + /* $$$ ben : some people tell that goto are not clean. I am not agree with + * them. In most case, it allow to avoid code duplications, which are as + * most people know a source of error... Here we are sure of being clean + */ + error: + if (loader) { + loader->close(loader); + } + if (temp_nsf) { + nsf_free(&temp_nsf); + } + return 0; +} + +/* Load a ROM image into memory */ +nsf_t *nsf_load(const char *filename, void *source, int length) +{ + struct nsf_loader_t * loader = 0; + + /* $$$ ben : new loader */ + if (filename) { + nsf_file_loader.fname = (char *)filename; + loader = &nsf_file_loader.loader; + } else { + nsf_mem_loader.data = source; + nsf_mem_loader.len = length; + nsf_mem_loader.fname[0] = 0; + loader = &nsf_mem_loader.loader; + } + return nsf_load_extended(loader); } /* Free an NSF */ -void nsf_free(nsf_t **nsf) +void nsf_free(nsf_t **pnsf) { - if (*nsf) - { - if ((*nsf)->apu) - apu_destroy((*nsf)->apu); + nsf_t *nsf; - nes_shutdown(*nsf); + if (!pnsf) { + return; + } - if ((*nsf)->data) - free((*nsf)->data); + nsf = *pnsf; + /* $$$ ben : Don't see why passing a pointer to pointer + * is not to clear it :) */ + *pnsf = 0; - free(*nsf); - } + if (nsf) { + if (nsf->apu) + apu_destroy(nsf->apu); + + nes_shutdown(nsf); + + if (nsf->data) + free(nsf->data); + + if (nsf->song_frames) + free (nsf->song_frames); + + free(nsf); + } } -void nsf_setchan(nsf_t *nsf, int chan, boolean enabled) +int nsf_setchan(nsf_t *nsf, int chan, boolean enabled) { - if (nsf) - { - nsf_setcontext(nsf); - apu_setchan(chan, enabled); - } + if (!nsf) + return -1; + + nsf_setcontext(nsf); + return apu_setchan(chan, enabled); } -void nsf_playtrack(nsf_t *nsf, int track, int sample_rate, int sample_bits, boolean stereo) +int nsf_playtrack(nsf_t *nsf, int track, int sample_rate, int sample_bits, + boolean stereo) { - ASSERT(nsf); + if (!nsf) { + return -1; + } - /* make this NSF the current context */ - nsf_setcontext(nsf); + /* make this NSF the current context */ + nsf_setcontext(nsf); - /* create the APU */ - if (nsf->apu) - apu_destroy(nsf->apu); + /* create the APU */ + if (nsf->apu) { + apu_destroy(nsf->apu); + } - nsf->apu = apu_create(sample_rate, nsf->playback_rate, sample_bits, stereo); - if (NULL == nsf->apu) - { - nsf_free(&nsf); - return; - } + nsf->apu = apu_create(sample_rate, nsf->playback_rate, sample_bits, stereo); + if (NULL == nsf->apu) + { + /* $$$ ben : from my point of view this is not clean. Function should + * never destroy object it has not created... + */ + /* nsf_free(&nsf); */ + return -1; + } - apu_setext(nsf->apu, nsf_getext(nsf)); + apu_setext(nsf->apu, nsf_getext(nsf)); - /* go ahead and init all the read/write handlers */ - build_address_handlers(nsf); + /* go ahead and init all the read/write handlers */ + build_address_handlers(nsf); + + /* convenience? */ + nsf->process = nsf->apu->process; + + nes6502_setcontext(nsf->cpu); - /* convenience? */ - nsf->process = nsf->apu->process; + if (track > nsf->num_songs) + track = nsf->num_songs; + else if (track < 1) + track = 1; - nes6502_setcontext(nsf->cpu); + nsf->current_song = track; + + apu_reset(); - if (track > nsf->num_songs) - track = nsf->num_songs; - else if (track < 1) - track = 1; + nsf_inittune(nsf); - nsf->current_song = track; - - apu_reset(); - - nsf_inittune(nsf); + return nsf->current_song; } -void nsf_setfilter(nsf_t *nsf, int filter_type) +int nsf_setfilter(nsf_t *nsf, int filter_type) { - if (nsf) - { - nsf_setcontext(nsf); - apu_setfilter(filter_type); - } + if (!nsf) { + return -1; + } + nsf_setcontext(nsf); + return apu_setfilter(filter_type); } /* ** $Log: nsf.c,v $ -** Revision 1.4 2006/09/26 00:52:17 dgp85 -** Free the filename string and close the file pointer when returning. +** Revision 1.3 2003/05/01 22:34:20 benjihan +** New NSF plugin ** -** Found by Coverity Scan. +** Revision 1.2 2003/04/09 14:50:32 ben +** Clean NSF api. ** -** Revision 1.3 2003/08/25 21:51:43 f1rmb -** Reduce GCC verbosity (various prototype declaration fixes). ffmpeg, wine and fft*post are untouched (fft: for now). -** -** Revision 1.2 2003/01/09 18:36:40 jkeil -** memcpy copies too much, corrupts malloc heap -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:00 ben +** Adding more files... ** ** Revision 1.14 2000/07/05 14:54:45 matt ** fix for naughty Crystalis rip diff --git a/src/libxineadec/nosefart/nsf.h b/src/libxineadec/nosefart/nsf.h --- a/src/libxineadec/nosefart/nsf.h +++ b/src/libxineadec/nosefart/nsf.h @@ -20,7 +20,7 @@ ** nsf.h ** ** NSF loading/saving related defines / prototypes -** $Id: nsf.h,v 1.3 2007/01/18 21:34:10 dgp85 Exp $ +** $Id: nsf.h,v 1.3 2003/05/01 22:34:20 benjihan Exp $ */ #ifndef _NSF_H_ @@ -29,6 +29,8 @@ #include "osd.h" #include "nes6502.h" #include "nes_apu.h" + +#include "config.h" #define NSF_MAGIC "NESM\x1A" @@ -60,7 +62,8 @@ enum { NSF_FILTER_NONE, NSF_FILTER_LOWPASS, - NSF_FILTER_WEIGHTED + NSF_FILTER_WEIGHTED, + NSF_FILTER_MAX, /* $$$ ben : add this one for range chacking */ }; typedef struct nsf_s @@ -90,6 +93,14 @@ typedef struct nsf_s uint8 current_song; /* current song */ boolean bankswitched; /* is bankswitched? */ + /* $$$ ben : Playing time ... */ + uint32 cur_frame; + uint32 cur_frame_end; + uint32 * song_frames; + + /* $$$ ben : Last error string */ + const char * errstr; + /* CPU and APU contexts */ nes6502_context *cpu; apu_t *apu; @@ -98,30 +109,55 @@ typedef struct nsf_s void (*process)(void *buffer, int num_samples); } __PACKED__ nsf_t; +/* $$$ ben : Generic loader struct */ +struct nsf_loader_t { + /* Init and open. */ + int (*open)(struct nsf_loader_t * loader); + + /* Close and shutdown. */ + void (*close) (struct nsf_loader_t * loader); + + /* This function should return <0 on error, else the number of byte NOT read. + * that way a simple 0 test tell us if read was complete. + */ + int (*read) (struct nsf_loader_t * loader, void *data, int n); + + /* Get file length. */ + int (*length) (struct nsf_loader_t * loader); + + /* Skip n bytes. */ + int (*skip) (struct nsf_loader_t * loader,int n); + + /* Get filename (for debug). */ + const char * (*fname) (struct nsf_loader_t * loader); + +}; + /* Function prototypes */ -extern void nsf_init(void); +extern int nsf_init(void); -extern nsf_t *nsf_load(char *filename, void *source, int length); +extern nsf_t * nsf_load_extended(struct nsf_loader_t * loader); +extern nsf_t *nsf_load(const char *filename, void *source, int length); extern void nsf_free(nsf_t **nsf_info); -extern void nsf_playtrack(nsf_t *nsf, int track, int sample_rate, int sample_bits, - boolean stereo); +extern int nsf_playtrack(nsf_t *nsf, int track, int sample_rate, + int sample_bits, boolean stereo); extern void nsf_frame(nsf_t *nsf); -extern void nsf_setchan(nsf_t *nsf, int chan, boolean enabled); -extern void nsf_setfilter(nsf_t *nsf, int filter_type); +extern int nsf_setchan(nsf_t *nsf, int chan, boolean enabled); +extern int nsf_setfilter(nsf_t *nsf, int filter_type); #endif /* _NSF_H_ */ /* ** $Log: nsf.h,v $ -** Revision 1.3 2007/01/18 21:34:10 dgp85 -** __attribute__(packed) is used on the struct, not on its members. +** Revision 1.3 2003/05/01 22:34:20 benjihan +** New NSF plugin ** -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... +** Revision 1.2 2003/04/09 14:50:32 ben +** Clean NSF api. ** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:00 ben +** Adding more files... ** ** Revision 1.11 2000/07/04 04:59:24 matt ** removed DOS-specific stuff diff --git a/src/libxineadec/nosefart/osd.h b/src/libxineadec/nosefart/osd.h --- a/src/libxineadec/nosefart/osd.h +++ b/src/libxineadec/nosefart/osd.h @@ -20,7 +20,7 @@ ** osd.h ** ** O/S dependent routine defintions (must be customized) -** $Id: osd.h,v 1.2 2003/07/12 12:31:14 mroi Exp $ +** $Id: osd.h,v 1.1 2003/04/08 20:46:46 ben Exp $ */ #ifndef _OSD_H_ @@ -79,12 +79,8 @@ extern void osd_shutdown(void); /* ** $Log: osd.h,v $ -** Revision 1.2 2003/07/12 12:31:14 mroi -** - adding support for the Intel compiler icc -** - general multipass compilation make targets -** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:46:46 ben +** add new input for NES music file. ** ** Revision 1.7 2000/07/04 04:45:33 matt ** moved INLINE define into types.h @@ -96,3 +92,4 @@ extern void osd_shutdown(void); ** initial revision ** */ + diff --git a/src/libxineadec/nosefart/types.h b/src/libxineadec/nosefart/types.h --- a/src/libxineadec/nosefart/types.h +++ b/src/libxineadec/nosefart/types.h @@ -20,7 +20,7 @@ ** types.h ** ** Data type definitions -** $Id: types.h,v 1.4 2004/08/27 19:33:37 valtri Exp $ +** $Id: types.h,v 1.1 2003/04/08 20:46:46 ben Exp $ */ #ifndef _NOSEFART_TYPES_H_ @@ -46,13 +46,25 @@ #endif /* These should be changed depending on the platform */ -typedef char int8; -typedef short int16; -typedef int int32; -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint32; + + +#ifdef __BEOS__ /* added by Eli Dayan (for compiling under BeOS) */ + + /* use types in the BeOS Support Kit instead */ + #include +#elif defined (DCPLAYA) /* $$$ added by ben (for compiling with dcplaya) */ +# include +#else + typedef char int8; + typedef short int16; + typedef int int32; + + typedef unsigned char uint8; + typedef unsigned short uint16; + typedef unsigned int uint32; + +#endif typedef uint8 boolean; @@ -92,40 +104,8 @@ typedef uint8 boolean; /* ** $Log: types.h,v $ -** Revision 1.4 2004/08/27 19:33:37 valtri -** MINGW32 port. Engine library and most of plugins compiles now. -** -** List of some changes: -** - replaced some _MSC_VER by more common WIN32 -** - define INTLDIR, remove -static flag for included intl -** - shared more common CFLAGS with DEBUG_CFLAGS -** - use WIN32_CFLAGS for all building -** - separate some flags into THREAD_CFLAGS_CONFIG, -** THREAD_CFLAGS_CONFIG and ZLIB_LIB_CONFIG for public xine-config, -** automatically use internal libs if necessary -** - don't warn about missing X for mingw and cygwin -** - libw32dll disabled for WIN32 (making native loader would be -** interesting, or porting wine code to Windows? :->) -** - DVB and RTP disabled for WIN32, not ported yet -** - fix build and fix a warning in cdda -** - fix build for nosefart and libfaad -** - implement configure option --disable-freetype -** - sync libxine.pc and xine-config.in -** - add -liberty to goom under WIN32 -** - move original build files from included phread and zlib into archives -** and replace them by autotools -** -** Revision 1.3 2003/01/11 15:53:53 tmmm -** make the Nosefart engine aware of the config's WORDS_BIGENDIAN #define -** -** Revision 1.2 2003/01/09 19:50:04 jkeil -** NSF audio files were crashing on SPARC. -** -** - Define the correct HOST_ENDIAN for SPARC -** - remove unaligned memory accesses -** -** Revision 1.1 2003/01/08 07:04:36 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:46:46 ben +** add new input for NES music file. ** ** Revision 1.7 2000/07/04 04:46:44 matt ** moved INLINE define from osd.h diff --git a/src/libxineadec/nosefart/version.h b/src/libxineadec/nosefart/version.h --- a/src/libxineadec/nosefart/version.h +++ b/src/libxineadec/nosefart/version.h @@ -20,7 +20,7 @@ ** version.h ** ** Program name / version definitions -** $Id: version.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ +** $Id: version.h,v 1.1 2003/04/08 20:46:46 ben Exp $ */ #ifndef _VERSION_H_ @@ -32,17 +32,14 @@ #define APP_STRING "Nofrendo" #endif /* NSF_PLAYER */ -#define APP_VERSION "1.92" +#define APP_VERSION "2.3-mls" #endif /* _VERSION_H_ */ /* ** $Log: version.h,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:36 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:46:46 ben +** add new input for NES music file. ** ** Revision 1.7 2000/07/04 04:46:55 matt ** updated version number diff --git a/src/libxineadec/nosefart/vrc7_snd.c b/src/libxineadec/nosefart/vrc7_snd.c --- a/src/libxineadec/nosefart/vrc7_snd.c +++ b/src/libxineadec/nosefart/vrc7_snd.c @@ -21,7 +21,7 @@ ** ** VRCVII sound hardware emulation ** Thanks to Charles MacDonald (cgfm2@hooked.net) for donating code. -** $Id: vrc7_snd.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ +** $Id: vrc7_snd.c,v 1.1 2003/04/08 20:53:01 ben Exp $ */ #include @@ -323,11 +323,8 @@ apuext_t vrc7_ext = /* ** $Log: vrc7_snd.c,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:36 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:01 ben +** Adding more files... ** ** Revision 1.5 2000/07/04 04:51:02 matt ** made data types stricter diff --git a/src/libxineadec/nosefart/vrc7_snd.h b/src/libxineadec/nosefart/vrc7_snd.h --- a/src/libxineadec/nosefart/vrc7_snd.h +++ b/src/libxineadec/nosefart/vrc7_snd.h @@ -22,7 +22,7 @@ ** VRCVII (Konami MMC) sound hardware emulation header ** Thanks to Charles MacDonald (cgfm2@hooked.net) for donating code. ** -** $Id: vrc7_snd.h,v 1.1 2003/01/08 07:04:36 tmmm Exp $ +** $Id: vrc7_snd.h,v 1.1 2003/04/08 20:53:01 ben Exp $ */ #ifndef _VRC7_SND_H_ @@ -55,8 +55,8 @@ extern apuext_t vrc7_ext; /* ** $Log: vrc7_snd.h,v $ -** Revision 1.1 2003/01/08 07:04:36 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:01 ben +** Adding more files... ** ** Revision 1.3 2000/07/04 04:51:02 matt ** made data types stricter @@ -68,3 +68,4 @@ extern apuext_t vrc7_ext; ** initial revision ** */ + diff --git a/src/libxineadec/nosefart/vrcvisnd.c b/src/libxineadec/nosefart/vrcvisnd.c --- a/src/libxineadec/nosefart/vrcvisnd.c +++ b/src/libxineadec/nosefart/vrcvisnd.c @@ -20,7 +20,7 @@ ** vrcvisnd.c ** ** VRCVI sound hardware emulation -** $Id: vrcvisnd.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ +** $Id: vrcvisnd.c,v 1.1 2003/04/08 20:53:01 ben Exp $ */ #include "types.h" @@ -183,11 +183,8 @@ apuext_t vrcvi_ext = /* ** $Log: vrcvisnd.c,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:36 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:01 ben +** Adding more files... ** ** Revision 1.9 2000/07/04 04:51:41 matt ** cleanups diff --git a/src/libxineadec/nosefart/vrcvisnd.h b/src/libxineadec/nosefart/vrcvisnd.h --- a/src/libxineadec/nosefart/vrcvisnd.h +++ b/src/libxineadec/nosefart/vrcvisnd.h @@ -20,7 +20,7 @@ ** vrcvisnd.h ** ** VRCVI (Konami MMC) sound hardware emulation header -** $Id: vrcvisnd.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ +** $Id: vrcvisnd.h,v 1.1 2003/04/08 20:53:01 ben Exp $ */ #ifndef _VRCVISND_H_ @@ -64,11 +64,8 @@ extern apuext_t vrcvi_ext; /* ** $Log: vrcvisnd.h,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:36 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:01 ben +** Adding more files... ** ** Revision 1.7 2000/06/20 04:06:16 matt ** migrated external sound definition to apu module