From a4d0dacec222cbeb9853b56f4900f5881d67b99b Mon Sep 17 00:00:00 2001 From: Andreas Henriksson Date: Tue, 25 Mar 2008 15:56:13 +0000 Subject: gst/nsf/: Update our internal nosefart to nosefart-2.7-mls to fix segfaults on some files. Fixes bug #498237. Original commit message from CVS: Patch by: Andreas Henriksson * gst/nsf/Makefile.am: * gst/nsf/dis6502.h: * gst/nsf/fds_snd.c: * gst/nsf/fds_snd.h: * gst/nsf/fmopl.c: * gst/nsf/fmopl.h: * gst/nsf/gstnsf.c: * gst/nsf/log.c: * gst/nsf/log.h: * gst/nsf/memguard.c: * gst/nsf/memguard.h: * gst/nsf/mmc5_snd.c: * gst/nsf/mmc5_snd.h: * gst/nsf/nes6502.c: * gst/nsf/nes6502.h: * gst/nsf/nes_apu.c: * gst/nsf/nes_apu.h: * gst/nsf/nsf.c: * gst/nsf/nsf.h: * gst/nsf/osd.h: * gst/nsf/types.h: * gst/nsf/vrc7_snd.c: * gst/nsf/vrc7_snd.h: * gst/nsf/vrcvisnd.c: * gst/nsf/vrcvisnd.h: Update our internal nosefart to nosefart-2.7-mls to fix segfaults on some files. Fixes bug #498237. Remove some // comments, fix some compiler warnings and use pow() instead of a slow, selfmade implementation. --- gst/nsf/Makefile.am | 6 +- gst/nsf/dis6502.h | 16 +- gst/nsf/fds_snd.c | 27 +- gst/nsf/fds_snd.h | 16 +- gst/nsf/fmopl.c | 129 ++++------ gst/nsf/fmopl.h | 1 + gst/nsf/gstnsf.c | 2 +- gst/nsf/log.c | 15 +- gst/nsf/log.h | 16 +- gst/nsf/memguard.c | 401 +++++++++++++++++++++++++++++ gst/nsf/memguard.h | 98 ++++++++ gst/nsf/mmc5_snd.c | 28 +-- gst/nsf/mmc5_snd.h | 16 +- gst/nsf/nes6502.c | 250 ++++++++++++++---- gst/nsf/nes6502.h | 43 +++- gst/nsf/nes_apu.c | 134 ++++++---- gst/nsf/nes_apu.h | 34 ++- gst/nsf/nsf.c | 713 ++++++++++++++++++++++++++++++++++++++++++---------- gst/nsf/nsf.h | 69 ++++- gst/nsf/osd.h | 16 +- gst/nsf/types.h | 74 +++--- gst/nsf/vrc7_snd.c | 30 +-- gst/nsf/vrc7_snd.h | 16 +- gst/nsf/vrcvisnd.c | 27 +- gst/nsf/vrcvisnd.h | 16 +- 25 files changed, 1694 insertions(+), 499 deletions(-) create mode 100644 gst/nsf/memguard.c create mode 100644 gst/nsf/memguard.h (limited to 'gst') diff --git a/gst/nsf/Makefile.am b/gst/nsf/Makefile.am index 75968254..152791e9 100644 --- a/gst/nsf/Makefile.am +++ b/gst/nsf/Makefile.am @@ -9,7 +9,8 @@ NOSEFART_SOURCES=fmopl.c \ fds_snd.c \ nes6502.c \ nsf.c \ - vrcvisnd.c + vrcvisnd.c \ + memguard.c NOSEFART_INCLUDES=fmopl.h \ log.h \ @@ -22,7 +23,8 @@ NOSEFART_INCLUDES=fmopl.h \ nes6502.h \ nsf.h \ types.h \ - vrcvisnd.h + vrcvisnd.h \ + memguard.h libgstnsf_la_SOURCES = gstnsf.c $(NOSEFART_SOURCES) diff --git a/gst/nsf/dis6502.h b/gst/nsf/dis6502.h index 578defe6..4f67afa1 100644 --- a/gst/nsf/dis6502.h +++ b/gst/nsf/dis6502.h @@ -40,10 +40,8 @@ extern void nes6502_disasm(uint32 PC, uint8 P, uint8 A, uint8 X, uint8 Y, uint8 /* ** $Log$ -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.2 2008/03/25 15:56:10 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -51,7 +49,6 @@ extern void nes6502_disasm(uint32 PC, uint8 P, uint8 A, uint8 X, uint8 Y, uint8 ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -70,10 +67,15 @@ extern void nes6502_disasm(uint32 PC, uint8 P, uint8 A, uint8 X, uint8 Y, uint8 ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** 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/gst/nsf/fds_snd.c b/gst/nsf/fds_snd.c index 6ad0d4e4..be118cc2 100644 --- a/gst/nsf/fds_snd.c +++ b/gst/nsf/fds_snd.c @@ -23,7 +23,6 @@ ** $Id$ */ -#include #include "types.h" #include "nes_apu.h" #include "fds_snd.h" @@ -67,7 +66,7 @@ fds_shutdown (void) static apu_memwrite fds_memwrite[] = { {0x4040, 0x4092, fds_write}, - {(uint32) - 1, (uint32) - 1, NULL} + {-1, -1, NULL} }; apuext_t fds_ext = { @@ -81,19 +80,8 @@ apuext_t fds_ext = { /* ** $Log$ -** Revision 1.2 2006/10/17 11:04:14 tpm -** Patch by: Josep Torra Valles -** * gst/nsf/fds_snd.c: -** * gst/nsf/mmc5_snd.c: -** * gst/nsf/nsf.c: -** * gst/nsf/vrc7_snd.c: -** * gst/nsf/vrcvisnd.c: -** Fix some things the Forte compiler warns about (#362626). -** -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.3 2008/03/25 15:56:10 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -101,7 +89,6 @@ apuext_t fds_ext = { ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -120,7 +107,13 @@ apuext_t fds_ext = { ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** 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/gst/nsf/fds_snd.h b/gst/nsf/fds_snd.h index 4ec90f15..23df4a37 100644 --- a/gst/nsf/fds_snd.h +++ b/gst/nsf/fds_snd.h @@ -35,10 +35,8 @@ extern apuext_t fds_ext; /* ** $Log$ -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.2 2008/03/25 15:56:10 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -46,7 +44,6 @@ extern apuext_t fds_ext; ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -65,7 +62,13 @@ extern apuext_t fds_ext; ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** 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 @@ -74,4 +77,3 @@ extern apuext_t fds_ext; ** initial revision ** */ - diff --git a/gst/nsf/fmopl.c b/gst/nsf/fmopl.c index c1e321f3..6e71e5b6 100644 --- a/gst/nsf/fmopl.c +++ b/gst/nsf/fmopl.c @@ -18,9 +18,9 @@ #include #include #include -#include - /* #include "driver.h" *//* use M.A.M.E. */ + /*#include "driver.h" *//* use M.A.M.E. */ #include "fmopl.h" +#include /* MPC - hacks */ #include "types.h" @@ -156,33 +156,16 @@ static const INT32 SL_TABLE[16] = { #define TL_MAX (EG_ENT*2) /* limit(tl + ksr + envelope) + sinwave */ /* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */ -/* TL.TABLE[ 0 to TL_MAX ] : plus section */ -/* TL.TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */ -static union -{ - INT32 *TABLE; - void *TABLE_PTR; -} TL; +/* TL_TABLE[ 0 to TL_MAX ] : plus section */ +/* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */ +static INT32 *TL_TABLE; -/* pointers to TL.TABLE with sinwave output offset */ -static union -{ - INT32 **TABLE; - void *TABLE_PTR; -} SIN; +/* pointers to TL_TABLE with sinwave output offset */ +static INT32 **SIN_TABLE; /* LFO table */ -static union -{ - INT32 *TABLE; - void *TABLE_PTR; -} AMS; - -static union -{ - INT32 *TABLE; - void *TABLE_PTR; -} VIB; +static INT32 *AMS_TABLE; +static INT32 *VIB_TABLE; /* envelope output curve table */ /* attack + decay + OFF */ @@ -193,9 +176,9 @@ static INT32 ENV_CURVE[2 * EG_ENT + 1]; static const UINT32 MUL_TABLE[16] = { /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */ ML (0.50), ML (1.00), ML (2.00), ML (3.00), ML (4.00), ML (5.00), ML (6.00), - ML (7.00), + ML (7.00), ML (8.00), ML (9.00), ML (10.00), ML (10.00), ML (12.00), ML (12.00), - ML (15.00), ML (15.00) + ML (15.00), ML (15.00) }; #undef ML @@ -549,12 +532,10 @@ OPL_CALC_RH (OPL_CH * CH) /* connectoion */ outd[0] += OP_OUT (SLOT, env_out, feedback2) * 2; } - /* SD (17) = mul14[fnum7] + white noise - * TAM (15) = mul15[fnum8] - * TOP (18) = fnum6(mul18[fnum8]+whitenoise) - * HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise - */ + TAM (15) = mul15[fnum8] + TOP (18) = fnum6(mul18[fnum8]+whitenoise) + HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise */ env_sd = OPL_CALC_SLOT (SLOT7_2) + whitenoise; env_tam = OPL_CALC_SLOT (SLOT8_1); env_top = OPL_CALC_SLOT (SLOT8_2); @@ -638,62 +619,62 @@ OPLOpenTable (void) double pom; /* allocate dynamic tables */ - if ((TL.TABLE = malloc (TL_MAX * 2 * sizeof (INT32))) == NULL) + if ((TL_TABLE = malloc (TL_MAX * 2 * sizeof (INT32))) == NULL) return 0; - if ((SIN.TABLE = malloc (SIN_ENT * 4 * sizeof (INT32 *))) == NULL) { - free (TL.TABLE_PTR); + if ((SIN_TABLE = malloc (SIN_ENT * 4 * sizeof (INT32 *))) == NULL) { + free (TL_TABLE); return 0; } - if ((AMS.TABLE = malloc (AMS_ENT * 2 * sizeof (INT32))) == NULL) { - free (TL.TABLE_PTR); - free (SIN.TABLE_PTR); + if ((AMS_TABLE = malloc (AMS_ENT * 2 * sizeof (INT32))) == NULL) { + free (TL_TABLE); + free (SIN_TABLE); return 0; } - if ((VIB.TABLE = malloc (VIB_ENT * 2 * sizeof (INT32))) == NULL) { - free (TL.TABLE_PTR); - free (SIN.TABLE_PTR); - free (AMS.TABLE_PTR); + if ((VIB_TABLE = malloc (VIB_ENT * 2 * sizeof (INT32))) == NULL) { + free (TL_TABLE); + free (SIN_TABLE); + free (AMS_TABLE); return 0; } /* make total level table */ for (t = 0; t < EG_ENT - 1; t++) { rate = ((1 << TL_BITS) - 1) / pow (10, EG_STEP * t / 20); /* dB -> 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]));*/ + TL_TABLE[t] = (int) rate; + TL_TABLE[TL_MAX + t] = -TL_TABLE[t]; +/* LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/ } /* fill volume off area */ for (t = EG_ENT - 1; t < TL_MAX; t++) { - TL.TABLE[t] = TL.TABLE[TL_MAX + t] = 0; + TL_TABLE[t] = TL_TABLE[TL_MAX + t] = 0; } /* make sinwave table (total level offet) */ /* degree 0 = degree 180 = off */ - SIN.TABLE[0] = SIN.TABLE[SIN_ENT / 2] = &TL.TABLE[EG_ENT - 1]; + SIN_TABLE[0] = SIN_TABLE[SIN_ENT / 2] = &TL_TABLE[EG_ENT - 1]; for (s = 1; s <= SIN_ENT / 4; s++) { pom = sin (2 * PI * s / SIN_ENT); /* sin */ pom = 20 * log10 (1 / pom); /* decibel */ - j = (int) (pom / EG_STEP); /* TL.TABLE steps */ + j = (int) (pom / EG_STEP); /* TL_TABLE steps */ /* degree 0 - 90 , degree 180 - 90 : plus section */ - SIN.TABLE[s] = SIN.TABLE[SIN_ENT / 2 - s] = &TL.TABLE[j]; + SIN_TABLE[s] = SIN_TABLE[SIN_ENT / 2 - s] = &TL_TABLE[j]; /* degree 180 - 270 , degree 360 - 270 : minus section */ - SIN.TABLE[SIN_ENT / 2 + s] = SIN.TABLE[SIN_ENT - s] = &TL.TABLE[TL_MAX + j]; + SIN_TABLE[SIN_ENT / 2 + s] = SIN_TABLE[SIN_ENT - s] = &TL_TABLE[TL_MAX + j]; /* LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP));*/ } for (s = 0; s < SIN_ENT; s++) { - SIN.TABLE[SIN_ENT * 1 + s] = - s < (SIN_ENT / 2) ? SIN.TABLE[s] : &TL.TABLE[EG_ENT]; - SIN.TABLE[SIN_ENT * 2 + s] = SIN.TABLE[s % (SIN_ENT / 2)]; - SIN.TABLE[SIN_ENT * 3 + s] = - (s / (SIN_ENT / 4)) & 1 ? &TL.TABLE[EG_ENT] : SIN.TABLE[SIN_ENT * 2 + + SIN_TABLE[SIN_ENT * 1 + s] = + s < (SIN_ENT / 2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT]; + SIN_TABLE[SIN_ENT * 2 + s] = SIN_TABLE[s % (SIN_ENT / 2)]; + SIN_TABLE[SIN_ENT * 3 + s] = + (s / (SIN_ENT / 4)) & 1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT * 2 + s]; } /* envelope counter -> envelope output table */ for (i = 0; i < EG_ENT; i++) { /* ATTACK curve */ - pom = pow (((double) (EG_ENT - 1 - i) / EG_ENT), 8) * EG_ENT; + pom = (float) pow (((double) (EG_ENT - 1 - i) / EG_ENT), 8) * EG_ENT; /* if( pom >= EG_ENT ) pom = EG_ENT-1; */ ENV_CURVE[i] = (int) pom; /* DECAY ,RELEASE curve */ @@ -704,17 +685,17 @@ OPLOpenTable (void) /* make LFO ams table */ for (i = 0; i < AMS_ENT; i++) { pom = (1.0 + sin (2 * PI * i / AMS_ENT)) / 2; /* sin */ - AMS.TABLE[i] = (INT32) ((1.0 / EG_STEP) * pom); /* 1dB */ - AMS.TABLE[AMS_ENT + i] = (INT32) ((4.8 / EG_STEP) * pom); /* 4.8dB */ + AMS_TABLE[i] = (INT32) ((1.0 / EG_STEP) * pom); /* 1dB */ + AMS_TABLE[AMS_ENT + i] = (INT32) ((4.8 / EG_STEP) * pom); /* 4.8dB */ } /* make LFO vibrate table */ for (i = 0; i < VIB_ENT; i++) { /* 100cent = 1seminote = 6% ?? */ pom = (double) VIB_RATE *0.06 * sin (2 * PI * i / VIB_ENT); /* +-100sect step */ - VIB.TABLE[i] = VIB_RATE + (INT32) (pom * 0.07); /* +- 7cent */ - VIB.TABLE[VIB_ENT + i] = VIB_RATE + (INT32) (pom * 0.14); /* +-14cent */ - /* LOG(LOG_INF,("vib %d=%d\n",i,VIB.TABLE[VIB_ENT+i])); */ + VIB_TABLE[i] = VIB_RATE + (INT32) (pom * 0.07); /* +- 7cent */ + VIB_TABLE[VIB_ENT + i] = VIB_RATE + (INT32) (pom * 0.14); /* +-14cent */ + /* LOG(LOG_INF,("vib %d=%d\n",i,VIB_TABLE[VIB_ENT+i])); */ } return 1; } @@ -723,10 +704,10 @@ OPLOpenTable (void) static void OPLCloseTable (void) { - free (TL.TABLE_PTR); - free (SIN.TABLE_PTR); - free (AMS.TABLE_PTR); - free (VIB.TABLE_PTR); + free (TL_TABLE); + free (SIN_TABLE); + free (AMS_TABLE); + free (VIB_TABLE); } /* CSM Key Controll */ @@ -794,8 +775,8 @@ OPLWriteReg (FM_OPL * OPL, int r, int v) int c; for (c = 0; c < OPL->max_ch; c++) { - OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN.TABLE[0]; - OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN.TABLE[0]; + OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0]; + OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0]; } } } @@ -916,8 +897,8 @@ OPLWriteReg (FM_OPL * OPL, int r, int v) { UINT8 rkey = OPL->rythm ^ v; - OPL->ams_table = &AMS.TABLE[v & 0x80 ? AMS_ENT : 0]; - OPL->vib_table = &VIB.TABLE[v & 0x40 ? VIB_ENT : 0]; + OPL->ams_table = &AMS_TABLE[v & 0x80 ? AMS_ENT : 0]; + OPL->vib_table = &VIB_TABLE[v & 0x40 ? VIB_ENT : 0]; OPL->rythm = v & 0x3f; if (OPL->rythm & 0x20) { #if 0 @@ -1022,7 +1003,7 @@ OPLWriteReg (FM_OPL * OPL, int r, int v) CH = &OPL->P_CH[slot / 2]; if (OPL->wavesel) { /* LOG(LOG_INF,("OPL SLOT %d wave select %d\n",slot,v&3)); */ - CH->SLOT[slot & 1].wavetable = &SIN.TABLE[(v & 0x03) * SIN_ENT]; + CH->SLOT[slot & 1].wavetable = &SIN_TABLE[(v & 0x03) * SIN_ENT]; } return; } @@ -1200,7 +1181,7 @@ OPLResetChip (FM_OPL * OPL) /* OPL->P_CH[c].PAN = OPN_CENTER; */ for (s = 0; s < 2; s++) { /* wave table */ - CH->SLOT[s].wavetable = &SIN.TABLE[0]; + CH->SLOT[s].wavetable = &SIN_TABLE[0]; /* CH->SLOT[s].evm = ENV_MOD_RR; */ CH->SLOT[s].evc = EG_OFF; CH->SLOT[s].eve = EG_OFF + 1; @@ -1270,10 +1251,8 @@ OPLCreate (int type, int clock, int rate) void OPLDestroy (FM_OPL * OPL) { - void *t = OPL; - OPL_UnLockTable (); - free (t); + free (OPL); } /* ---------- Option handlers ---------- */ diff --git a/gst/nsf/fmopl.h b/gst/nsf/fmopl.h index 92a2859d..4d87895c 100644 --- a/gst/nsf/fmopl.h +++ b/gst/nsf/fmopl.h @@ -162,3 +162,4 @@ void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length); void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length); #endif + diff --git a/gst/nsf/gstnsf.c b/gst/nsf/gstnsf.c index e8d4441b..25f014b8 100644 --- a/gst/nsf/gstnsf.c +++ b/gst/nsf/gstnsf.c @@ -108,7 +108,7 @@ static void gst_nsfdec_set_property (GObject * object, guint prop_id, static GstElementClass *parent_class = NULL; -//static guint gst_nsfdec_signals[LAST_SIGNAL] = { 0 }; +/* static guint gst_nsfdec_signals[LAST_SIGNAL] = { 0 }; */ GType gst_nsfdec_get_type (void) diff --git a/gst/nsf/log.c b/gst/nsf/log.c index 5d0d168a..f9fa3c25 100644 --- a/gst/nsf/log.c +++ b/gst/nsf/log.c @@ -107,10 +107,8 @@ log_printf (const char *format, ...) /* ** $Log$ -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.2 2008/03/25 15:56:11 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -118,7 +116,6 @@ log_printf (const char *format, ...) ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -137,7 +134,13 @@ log_printf (const char *format, ...) ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** 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/gst/nsf/log.h b/gst/nsf/log.h index 96c37ea4..688fbc01 100644 --- a/gst/nsf/log.h +++ b/gst/nsf/log.h @@ -37,10 +37,8 @@ extern void log_printf(const char *format, ...); /* ** $Log$ -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.2 2008/03/25 15:56:11 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -48,7 +46,6 @@ extern void log_printf(const char *format, ...); ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -67,10 +64,15 @@ extern void log_printf(const char *format, ...); ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** 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/gst/nsf/memguard.c b/gst/nsf/memguard.c new file mode 100644 index 00000000..77774a7f --- /dev/null +++ b/gst/nsf/memguard.c @@ -0,0 +1,401 @@ +/* +** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) +** +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of version 2 of the GNU Library General +** Public License as published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Library General Public License for more details. To obtain a +** copy of the GNU Library General Public License, write to the Free +** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Any permitted reproduction of these routines, in whole or in part, +** must bear this legend. +** +** +** memguard.c +** +** memory allocation wrapper routines +** +** NOTE: based on code (c) 1998 the Retrocade group +** $Id$ +*/ + +#include "types.h" + +/* undefine macro definitions, so we get real calls */ +#undef malloc +#undef free + +#include +#include +#include "memguard.h" +#include "log.h" + + +/* Maximum number of allocated blocks at any one time */ +#define MAX_BLOCKS 16384 + +/* Memory block structure */ +typedef struct memblock_s +{ + void *block_addr; + int block_size; + char *file_name; + int line_num; +} memblock_t; + +boolean mem_debug = TRUE; /* debugging flag */ + + +#ifdef NOFRENDO_DEBUG + +static int mem_blockcount = 0; /* allocated block count */ +static memblock_t *mem_record = NULL; + +#define GUARD_STRING "GgUuAaRrDdSsTtRrIiNnGgBbLlOoCcKk" +#define GUARD_LENGTH 64 /* before and after allocated block */ + + +/* +** Check the memory guard to make sure out of bounds writes have not +** occurred. +*/ +static boolean +mem_checkguardblock (void *data, int guard_size) +{ + uint8 *orig, *chk, *blk; + int i, alloc_size; + + /* get the original pointer */ + orig = (((uint8 *) data) - guard_size); + + /* get the size */ + alloc_size = *((uint32 *) orig); + + /* now skip past the size */ + blk = orig + sizeof (uint32); + + /* check leading guard string */ + chk = GUARD_STRING; + for (i = sizeof (uint32); i < guard_size; i++) { + if (0 == *chk) + chk = GUARD_STRING; + if (*blk != *chk) + return FALSE; + chk++; + blk++; + } + + /* check end of block */ + chk = GUARD_STRING; + blk = ((uint8 *) data) + alloc_size; + for (i = 0; i < guard_size; i++) { + if (0 == *chk) + chk = GUARD_STRING; + if (*blk != *chk) + return FALSE; + chk++; + blk++; + } + + /* we're okay! */ + return TRUE; +} + +/* free a guard block */ +static void +mem_freeguardblock (void *data, int guard_size) +{ + uint8 *orig = (((uint8 *) data) - guard_size); + + free (orig); +} + +/* fill in the memory guard, advance the pointer to the 'real' memory */ +static void * +mem_guardblock (int alloc_size, int guard_size) +{ + void *orig; + uint8 *blk, *chk; + int i; + + /* allocate memory */ + orig = calloc (alloc_size + (guard_size * 2), 1); + if (NULL == orig) + return NULL; + + blk = ((uint8 *) orig); + + /* store the size of the newly allocated block */ + *((uint32 *) blk) = alloc_size; + + /* skip past the size */ + blk += sizeof (uint32); + + /* put guard string at beginning of block */ + chk = GUARD_STRING; + for (i = sizeof (uint32); i < guard_size; i++) { + if (0 == *chk) + chk = GUARD_STRING; + *blk++ = *chk++; + } + + /* check end of block */ + chk = GUARD_STRING; + blk = guard_size + (uint8 *) orig + alloc_size; + for (i = 0; i < guard_size; i++) { + if (0 == *chk) + chk = GUARD_STRING; + *blk++ = *chk++; + } + + return (void *) (guard_size + (uint8 *) orig); +} + + +/* Allocate a bunch of memory to keep track of all memory blocks */ +static void +mem_init (void) +{ + if (mem_record) { + free (mem_record); + mem_record = NULL; + } + + mem_record = calloc (MAX_BLOCKS * sizeof (memblock_t), 1); + ASSERT (mem_record); +} + +/* add a block of memory to the master record */ +static void +mem_addblock (void *data, int block_size, char *file, int line) +{ + int i; + + for (i = 0; i < MAX_BLOCKS; i++) { + if (NULL == mem_record[i].block_addr) { + mem_record[i].block_addr = data; + mem_record[i].block_size = block_size; + mem_record[i].file_name = file; + mem_record[i].line_num = line; + return; + } + } + + ASSERT_MSG ("out of memory blocks."); +} + +/* find an entry in the block record and delete it */ +static void +mem_deleteblock (void *data, char *file, int line) +{ + int i; + char fail[256]; + + for (i = 0; i < MAX_BLOCKS; i++) { + if (data == mem_record[i].block_addr) { + if (FALSE == mem_checkguardblock (mem_record[i].block_addr, GUARD_LENGTH)) { + sprintf (fail, + "mem_deleteblock 0x%08X at line %d of %s -- block corrupt", + (uint32) data, line, file); + ASSERT_MSG (fail); + } + + memset (&mem_record[i], 0, sizeof (memblock_t)); + return; + } + } + + sprintf (fail, "mem_deleteblock 0x%08X at line %d of %s -- block not found", + (uint32) data, line, file); + ASSERT_MSG (fail); +} +#endif /* NOFRENDO_DEBUG */ + +/* allocates memory and clears it */ +#ifdef NOFRENDO_DEBUG +void * +_my_malloc (int size, char *file, int line) +#else +void * +_my_malloc (int size) +#endif +{ + void *temp; + char fail[256]; + +#ifdef NOFRENDO_DEBUG + if (NULL == mem_record && FALSE != mem_debug) + mem_init (); + + if (FALSE != mem_debug) + temp = mem_guardblock (size, GUARD_LENGTH); + else +#endif /* NOFRENDO_DEBUG */ + temp = calloc (sizeof (uint8), size); + + if (NULL == temp) { +#ifdef NOFRENDO_DEBUG + sprintf (fail, "malloc: out of memory at line %d of %s. block size: %d\n", + line, file, size); +#else + sprintf (fail, "malloc: out of memory. block size: %d\n", size); +#endif + ASSERT_MSG (fail); + } +#ifdef NOFRENDO_DEBUG + if (FALSE != mem_debug) + mem_addblock (temp, size, file, line); + + mem_blockcount++; +#endif + + return temp; +} + +/* free a pointer allocated with my_malloc */ +#ifdef NOFRENDO_DEBUG +void +_my_free (void **data, char *file, int line) +#else +void +_my_free (void **data) +#endif +{ + char fail[256]; + + if (NULL == data || NULL == *data + || 0xFFFFFFFF == (uint32) * data || 0xFFFFFFFF == (uint32) data) { +#ifdef NOFRENDO_DEBUG + sprintf (fail, "free: attempted to free NULL pointer at line %d of %s\n", + line, file); +#else + sprintf (fail, "free: attempted to free NULL pointer.\n"); +#endif + ASSERT_MSG (fail); + } +#ifdef NOFRENDO_DEBUG + /* if this is true, we are in REAL trouble */ + if (0 == mem_blockcount) { + ASSERT_MSG ("free: attempted to free memory when no blocks available"); + } + + if (FALSE != mem_debug) + mem_deleteblock (*data, file, line); + + mem_blockcount--; /* dec our block count */ + + if (FALSE != mem_debug) + mem_freeguardblock (*data, GUARD_LENGTH); + else +#endif /* NOFRENDO_DEBUG */ + free (*data); + + *data = NULL; /* NULL our source */ +} + +/* check for orphaned memory handles */ +void +mem_checkleaks (void) +{ +#ifdef NOFRENDO_DEBUG + int i; + + if (FALSE == mem_debug) + return; + + if (mem_blockcount) { + log_printf ("memory leak - %d unfreed block%s\n\n", mem_blockcount, + mem_blockcount == 1 ? "" : "s"); + + for (i = 0; i < MAX_BLOCKS; i++) { + if (mem_record[i].block_addr) { + log_printf ("addr: 0x%08X, size: %d, line %d of %s%s\n", + (uint32) mem_record[i].block_addr, + mem_record[i].block_size, + mem_record[i].line_num, + mem_record[i].file_name, + (FALSE == mem_checkguardblock (mem_record[i].block_addr, + GUARD_LENGTH)) + ? " -- block corrupt" : ""); + } + } + } else + log_printf ("no memory leaks\n"); +#endif +} + +void +mem_checkblocks (void) +{ +#ifdef NOFRENDO_DEBUG + int i; + + if (FALSE == mem_debug) + return; + + for (i = 0; i < MAX_BLOCKS; i++) { + if (mem_record[i].block_addr) { + if (FALSE == mem_checkguardblock (mem_record[i].block_addr, GUARD_LENGTH)) { + log_printf ("addr: 0x%08X, size: %d, line %d of %s -- block corrupt\n", + (uint32) mem_record[i].block_addr, + mem_record[i].block_size, + mem_record[i].line_num, mem_record[i].file_name); + } + } + } +#endif /* NOFRENDO_DEBUG */ +} + +/* +** $Log$ +** Revision 1.3 2008/03/25 15:56:11 slomo +** Patch by: Andreas Henriksson +** * gst/nsf/Makefile.am: +** * gst/nsf/dis6502.h: +** * gst/nsf/fds_snd.c: +** * gst/nsf/fds_snd.h: +** * gst/nsf/fmopl.c: +** * gst/nsf/fmopl.h: +** * gst/nsf/gstnsf.c: +** * gst/nsf/log.c: +** * gst/nsf/log.h: +** * gst/nsf/memguard.c: +** * gst/nsf/memguard.h: +** * gst/nsf/mmc5_snd.c: +** * gst/nsf/mmc5_snd.h: +** * gst/nsf/nes6502.c: +** * gst/nsf/nes6502.h: +** * gst/nsf/nes_apu.c: +** * gst/nsf/nes_apu.h: +** * gst/nsf/nsf.c: +** * gst/nsf/nsf.h: +** * gst/nsf/osd.h: +** * gst/nsf/types.h: +** * gst/nsf/vrc7_snd.c: +** * gst/nsf/vrc7_snd.h: +** * gst/nsf/vrcvisnd.c: +** * gst/nsf/vrcvisnd.h: +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** 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 +** +** Revision 1.7 2000/06/12 01:11:41 matt +** cleaned up some error output for win32 +** +** Revision 1.6 2000/06/09 15:12:25 matt +** initial revision +** +*/ diff --git a/gst/nsf/memguard.h b/gst/nsf/memguard.h new file mode 100644 index 00000000..e306cce8 --- /dev/null +++ b/gst/nsf/memguard.h @@ -0,0 +1,98 @@ +/* +** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) +** +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of version 2 of the GNU Library General +** Public License as published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Library General Public License for more details. To obtain a +** copy of the GNU Library General Public License, write to the Free +** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Any permitted reproduction of these routines, in whole or in part, +** must bear this legend. +** +** +** memguard.h +** +** memory allocation wrapper routines +** $Id$ +*/ + +#ifndef _MEMGUARD_H_ +#define _MEMGUARD_H_ + +#ifdef NOFRENDO_DEBUG + +#define malloc(s) _my_malloc((s), __FILE__, __LINE__) +#define free(d) _my_free((void **) &(d), __FILE__, __LINE__) + +extern void *_my_malloc(int size, char *file, int line); +extern void _my_free(void **data, char *file, int line); + +#else /* Non-debugging versions of calls */ + +#define malloc(s) _my_malloc((s)) +#define free(d) _my_free((void **) &(d)) + +extern void *_my_malloc(int size); +extern void _my_free(void **data); + +#endif /* NOFRENDO_DEBUG */ + + +extern void mem_checkblocks(void); +extern void mem_checkleaks(void); + +extern boolean mem_debug; + +#endif /* _MEMGUARD_H_ */ + +/* +** $Log$ +** Revision 1.3 2008/03/25 15:56:11 slomo +** Patch by: Andreas Henriksson +** * gst/nsf/Makefile.am: +** * gst/nsf/dis6502.h: +** * gst/nsf/fds_snd.c: +** * gst/nsf/fds_snd.h: +** * gst/nsf/fmopl.c: +** * gst/nsf/fmopl.h: +** * gst/nsf/gstnsf.c: +** * gst/nsf/log.c: +** * gst/nsf/log.h: +** * gst/nsf/memguard.c: +** * gst/nsf/memguard.h: +** * gst/nsf/mmc5_snd.c: +** * gst/nsf/mmc5_snd.h: +** * gst/nsf/nes6502.c: +** * gst/nsf/nes6502.h: +** * gst/nsf/nes_apu.c: +** * gst/nsf/nes_apu.h: +** * gst/nsf/nsf.c: +** * gst/nsf/nsf.h: +** * gst/nsf/osd.h: +** * gst/nsf/types.h: +** * gst/nsf/vrc7_snd.c: +** * gst/nsf/vrc7_snd.h: +** * gst/nsf/vrcvisnd.c: +** * gst/nsf/vrcvisnd.h: +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** 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 +** +** Revision 1.4 2000/06/09 15:12:25 matt +** initial revision +** +*/ diff --git a/gst/nsf/mmc5_snd.c b/gst/nsf/mmc5_snd.c index 49984432..09b3ff7b 100644 --- a/gst/nsf/mmc5_snd.c +++ b/gst/nsf/mmc5_snd.c @@ -310,13 +310,13 @@ mmc5_shutdown (void) static apu_memread mmc5_memread[] = { {0x5205, 0x5206, mmc5_read}, - {(uint32) - 1, (uint32) - 1, NULL} + {-1, -1, NULL} }; static apu_memwrite mmc5_memwrite[] = { {0x5000, 0x5015, mmc5_write}, {0x5205, 0x5206, mmc5_write}, - {(uint32) - 1, (uint32) - 1, NULL} + {-1, -1, NULL} }; apuext_t mmc5_ext = { @@ -330,19 +330,8 @@ apuext_t mmc5_ext = { /* ** $Log$ -** Revision 1.2 2006/10/17 11:04:14 tpm -** Patch by: Josep Torra Valles -** * gst/nsf/fds_snd.c: -** * gst/nsf/mmc5_snd.c: -** * gst/nsf/nsf.c: -** * gst/nsf/vrc7_snd.c: -** * gst/nsf/vrcvisnd.c: -** Fix some things the Forte compiler warns about (#362626). -** -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.3 2008/03/25 15:56:11 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -350,7 +339,6 @@ apuext_t mmc5_ext = { ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -369,7 +357,13 @@ apuext_t mmc5_ext = { ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** 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/gst/nsf/mmc5_snd.h b/gst/nsf/mmc5_snd.h index 5107c58a..f0bc99c0 100644 --- a/gst/nsf/mmc5_snd.h +++ b/gst/nsf/mmc5_snd.h @@ -67,10 +67,8 @@ extern apuext_t mmc5_ext; /* ** $Log$ -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.2 2008/03/25 15:56:11 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -78,7 +76,6 @@ extern apuext_t mmc5_ext; ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -97,7 +94,13 @@ extern apuext_t mmc5_ext; ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** 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 @@ -106,4 +109,3 @@ extern apuext_t mmc5_ext; ** initial revision ** */ - diff --git a/gst/nsf/nes6502.c b/gst/nsf/nes6502.c index 28bdc432..e2ed01f7 100644 --- a/gst/nsf/nes6502.c +++ b/gst/nsf/nes6502.c @@ -944,7 +944,7 @@ ADD_CYCLES(cycles); \ } -#define NSF_SEC() \ +#define SEC() \ { \ SET_FLAG(C_FLAG); \ ADD_CYCLES(2); \ @@ -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,82 +1175,209 @@ static uint8 *nes6502_banks[NES6502_NUMBANKS]; 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)) + +#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) +_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) { -#ifdef HOST_LITTLE_ENDIAN + chk_mem_access (acc_ram + address, NES6502_READ_ACCESS); + chk_mem_access (acc_ram + address + 1, NES6502_READ_ACCESS); + +#if defined (HOST_LITTLE_ENDIAN) && defined(HOST_UNALIGN_WORD) /* TODO: this fails if src address is $xFFF */ /* TODO: this fails if host architecture doesn't support byte alignment */ + /* $$$ ben : DONE */ return (uint32) (*(uint16 *) (ram + address)); -#else -#ifdef TARGET_CPU_PPC +#elif defined(TARGET_CPU_PPC) return __lhbrx (ram, address); #else - uint32 x = (uint32) * (uint16 *) (ram + address); - - return (x << 8) | (x >> 8); -#endif /* TARGET_CPU_PPC */ + return READ_SNES_16 (ram, address); +/* uint32 x = (uint32) *(uint16 *)(ram + address); */ +/* return (x << 8) | (x >> 8); */ + /* #endif *//* TARGET_CPU_PPC */ #endif /* HOST_LITTLE_ENDIAN */ } INLINE uint32 bank_readaddress (register uint32 address) { -#ifdef HOST_LITTLE_ENDIAN + +#ifdef NES6502_MEM_ACCESS_CTRL + { + const unsigned int offset = address & NES6502_BANKMASK; + uint8 *addr = acc_nes6502_banks[address >> NES6502_BANKSHIFT]; + + chk_mem_access (addr + offset + 0, NES6502_READ_ACCESS); + chk_mem_access (addr + offset + 1, NES6502_READ_ACCESS); + } +#endif + +#if defined (HOST_LITTLE_ENDIAN) && defined(HOST_UNALIGN_WORD) /* TODO: this fails if src address is $xFFF */ /* TODO: this fails if host architecture doesn't support byte alignment */ + /* $$$ ben : DONE */ return (uint32) (*(uint16 *) (nes6502_banks[address >> NES6502_BANKSHIFT] + (address & NES6502_BANKMASK))); -#else -#ifdef TARGET_CPU_PPC +#elif defined(TARGET_CPU_PPC) return __lhbrx (nes6502_banks[address >> NES6502_BANKSHIFT], address & NES6502_BANKMASK); #else - uint32 x = - (uint32) * (uint16 *) (nes6502_banks[address >> NES6502_BANKSHIFT] + - (address & NES6502_BANKMASK)); - return (x << 8) | (x >> 8); -#endif /* TARGET_CPU_PPC */ + { + const unsigned int offset = address & NES6502_BANKMASK; + + return READ_SNES_16 (nes6502_banks[address >> NES6502_BANKSHIFT], offset); + } +/* uint32 x = (uint32) *(uint16 *)(nes6502_banks[address >> NES6502_BANKSHIFT] + (address & NES6502_BANKMASK)); */ +/* return (x << 8) | (x >> 8); */ + /* #endif *//* TARGET_CPU_PPC */ #endif /* HOST_LITTLE_ENDIAN */ } + /* read a byte of 6502 memory */ static uint8 mem_read (uint32 address) { /* TODO: following cases are N2A03-specific */ /* RAM */ - if (address < 0x800) + 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) +/* else if (address >= 0x6000) */ + else if (address >= 0x8000) { return bank_readbyte (address); + } /* check memory range handlers */ else { for (pmr = pmem_read; pmr->min_range != 0xFFFFFFFF; pmr++) { @@ -1260,6 +1396,7 @@ mem_write (uint32 address, uint8 value) { /* RAM */ if (address < 0x800) { + chk_mem_access (acc_ram + address, NES6502_WRITE_ACCESS); ram[address] = value; return; } @@ -1286,11 +1423,19 @@ nes6502_setcontext (nes6502_context * cpu) 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; @@ -1312,8 +1457,12 @@ nes6502_getcontext (nes6502_context * cpu) 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; @@ -1365,7 +1514,14 @@ 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; @@ -1398,9 +1554,10 @@ 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 */ BRK (); @@ -1641,7 +1798,7 @@ nes6502_execute (int remaining_cycles) break; case 0x38: /* SEC */ - NSF_SEC (); + SEC (); break; case 0x39: /* AND $nnnn,Y */ @@ -2392,25 +2549,18 @@ 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$ -** Revision 1.2 2007/10/08 17:46:44 thaytan -** * gst/librfb/rfbbuffer.c: (rfb_buffer_new_and_alloc): -** * gst/librfb/rfbbuffer.h: -** * gst/librfb/rfbdecoder.c: (rfb_socket_get_buffer): -** * gst/mpegvideoparse/mpegvideoparse.c: (gst_mpegvideoparse_chain): -** * gst/nsf/nes6502.c: (nes6502_execute): -** * gst/real/gstrealaudiodec.c: (gst_real_audio_dec_setcaps): -** * gst/real/gstrealvideodec.c: (open_library): -** * gst/real/gstrealvideodec.h: -** * gst/rtpmanager/gstrtpsession.c: (create_recv_rtp_sink), -** (create_recv_rtcp_sink), (create_send_rtp_sink): -** Fix compiler warnings shown by Forte. -** -** Revision 1.1 2006-07-13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.3 2008/03/25 15:56:11 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -2418,7 +2568,6 @@ nes6502_setdma (int cycles) ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -2437,7 +2586,16 @@ nes6502_setdma (int cycles) ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** Revision 1.2 2003/05/01 22:34:19 benjihan +** New NSF plugin +** +** 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/gst/nsf/nes6502.h b/gst/nsf/nes6502.h index e8ccffd4..15c39013 100644 --- a/gst/nsf/nes6502.h +++ b/gst/nsf/nes6502.h @@ -23,6 +23,9 @@ ** $Id$ */ +/* 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 uint8 nes6502_getbyte(uint32 address); 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,10 +145,8 @@ extern void nes6502_getcontext(nes6502_context *cpu); /* ** $Log$ -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.2 2008/03/25 15:56:12 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -133,7 +154,6 @@ extern void nes6502_getcontext(nes6502_context *cpu); ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -152,7 +172,16 @@ extern void nes6502_getcontext(nes6502_context *cpu); ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** Revision 1.2 2003/05/01 22:34:19 benjihan +** New NSF plugin +** +** 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/gst/nsf/nes_apu.c b/gst/nsf/nes_apu.c index 0e2c9520..47e1d72b 100644 --- a/gst/nsf/nes_apu.c +++ b/gst/nsf/nes_apu.c @@ -57,6 +57,11 @@ static int8 noise_long_lut[APU_NOISE_32K]; 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] = { @@ -103,15 +108,16 @@ void apu_setcontext (apu_t * src_apu) { apu = src_apu; + /* $$$ ben reset eoor string here. */ + SET_APU_ERROR (apu, "no error"); } - /* ** Simple queue routines */ #define APU_QEMPTY() (apu->q_head == apu->q_tail) -static void +static int apu_enqueue (apudata_t * d) { ASSERT (apu); @@ -119,8 +125,12 @@ apu_enqueue (apudata_t * 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 * @@ -130,20 +140,33 @@ apu_dequeue (void) ASSERT (apu); - if (APU_QEMPTY ()) + 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 +int apu_setchan (int chan, boolean enabled) { + const unsigned int max = 6; + int old; + ASSERT (apu); - apu->mix_enable[chan] = enabled; + 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 << chan)) | ((!!enabled) << chan); + } + return old; } /* emulation of the 15-bit shift register the @@ -599,7 +622,7 @@ apu_regwrite (uint32 address, uint8 value) case APU_WRB2: chan = (address & 4) ? 1 : 0; apu->rectangle[chan].regs[2] = value; -// if (apu->rectangle[chan].enabled) +/* if (apu->rectangle[chan].enabled) */ apu->rectangle[chan].freq = APU_TO_FIXED ((((apu->rectangle[chan].regs[3] & 7) << 8) + value) + 1); @@ -610,7 +633,7 @@ apu_regwrite (uint32 address, uint8 value) chan = (address & 4) ? 1 : 0; apu->rectangle[chan].regs[3] = value; -// if (apu->rectangle[chan].enabled) +/* if (apu->rectangle[chan].enabled) */ { apu->rectangle[chan].vbl_length = vbl_lut[value >> 3]; apu->rectangle[chan].env_vol = 0; @@ -640,7 +663,7 @@ apu_regwrite (uint32 address, uint8 value) apu->triangle.holdnote = (value & 0x80) ? TRUE : FALSE; -// if (apu->triangle.enabled) +/* if (apu->triangle.enabled) */ { if (FALSE == apu->triangle.counter_started && apu->triangle.vbl_length) apu->triangle.linear_length = trilength_lut[value & 0x7F]; @@ -652,7 +675,7 @@ apu_regwrite (uint32 address, uint8 value) apu->triangle.regs[1] = value; -// if (apu->triangle.enabled) +/* if (apu->triangle.enabled) */ apu->triangle.freq = APU_TO_FIXED ((((apu->triangle.regs[2] & 7) << 8) + value) + 1); break; @@ -683,7 +706,7 @@ apu_regwrite (uint32 address, uint8 value) else apu->triangle.countmode = COUNTMODE_LOAD; */ -// if (apu->triangle.enabled) +/* if (apu->triangle.enabled) */ { apu->triangle.freq = APU_TO_FIXED ((((value & 7) << 8) + apu->triangle.regs[1]) + 1); @@ -724,7 +747,7 @@ apu_regwrite (uint32 address, uint8 value) case APU_WRD3: apu->noise.regs[2] = value; -// if (apu->noise.enabled) +/* if (apu->noise.enabled) */ { apu->noise.vbl_length = vbl_lut[value >> 3]; apu->noise.env_vol = 0; /* reset envelope */ @@ -843,7 +866,7 @@ apu_read (uint32 address) if (apu->noise.enabled && apu->noise.vbl_length) value |= 0x08; - //if (apu->dmc.dma_length) + /* if (apu->dmc.dma_length) */ /* bodge for timestamp queue */ if (apu->dmc.enabled) value |= 0x10; @@ -859,8 +882,7 @@ apu_read (uint32 address) break; case APU_JOY1: - value = - input_get (INP_ZAPPER | INP_JOYPAD1 + value = input_get (INP_ZAPPER | INP_JOYPAD1 /*| INP_ARKANOID *//*| INP_POWERPAD */ ); break; #endif /* !NSF_PLAYER */ @@ -975,18 +997,18 @@ apu_process (void *buffer, int num_samples) elapsed_cycles += APU_FROM_FIXED (apu->cycle_rate); accum = 0; - if (apu->mix_enable[0]) + if (APU_MIX_ENABLE (0)) accum += apu_rectangle (&apu->rectangle[0]); - if (apu->mix_enable[1]) + if (APU_MIX_ENABLE (1)) accum += apu_rectangle (&apu->rectangle[1]); - if (apu->mix_enable[2]) + if (APU_MIX_ENABLE (2)) accum += apu_triangle (&apu->triangle); - if (apu->mix_enable[3]) + if (APU_MIX_ENABLE (3)) accum += apu_noise (&apu->noise); - if (apu->mix_enable[4]) + if (APU_MIX_ENABLE (4)) accum += apu_dmc (&apu->dmc); - if (apu->ext && apu->mix_enable[5]) + if (apu->ext && APU_MIX_ENABLE (5)) accum += apu->ext->process (); /* do any filtering */ @@ -1013,15 +1035,11 @@ apu_process (void *buffer, int num_samples) /* signed 16-bit output, unsigned 8-bit */ if (16 == apu->sample_bits) { - int16 *t = buffer; - - *t++ = (int16) accum; - buffer = t; + *(int16 *) (buffer) = (int16) accum; + buffer += sizeof (int16); } else { - uint8 *t = buffer; - - *t++ = (accum >> 8) ^ 0x80; - buffer = t; + *(uint8 *) (buffer) = (accum >> 8) ^ 0x80; + buffer += sizeof (uint8); } } @@ -1030,11 +1048,20 @@ apu_process (void *buffer, int num_samples) } /* set the filter type */ -void +/* $$$ 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 @@ -1100,12 +1127,16 @@ 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; @@ -1124,8 +1155,9 @@ apu_create (int sample_rate, int refresh_rate, int sample_bits, boolean stereo) 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); @@ -1142,24 +1174,30 @@ void apu_destroy (apu_t * src_apu) { if (src_apu) { - void *t = src_apu; - if (src_apu->ext) src_apu->ext->shutdown (); - free (t); + free (src_apu); } } -void +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 */ @@ -1172,10 +1210,8 @@ apu_getcyclerate (void) /* ** $Log$ -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.2 2008/03/25 15:56:12 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -1183,7 +1219,6 @@ apu_getcyclerate (void) ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -1202,7 +1237,16 @@ apu_getcyclerate (void) ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** Revision 1.2 2003/04/09 14:50:32 ben +** Clean NSF api. +** +** 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/gst/nsf/nes_apu.h b/gst/nsf/nes_apu.h index fd94798d..01302dfa 100644 --- a/gst/nsf/nes_apu.h +++ b/gst/nsf/nes_apu.h @@ -132,7 +132,7 @@ typedef struct triangle_s /* quasi-hack */ int write_latency; - /* boolean countmode; */ +/* boolean countmode; */ int vbl_length; int linear_length; @@ -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,11 +275,11 @@ 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); @@ -286,6 +289,9 @@ extern void apu_write(uint32 address, uint8 value); /* for visualization */ extern void apu_getpcmdata(void **data, int *num_samples, int *sample_bits); +/* FIXME: added while importing for GStreamer */ +void apu_setcontext(apu_t *src_apu); + #ifdef __cplusplus } @@ -295,10 +301,8 @@ extern void apu_getpcmdata(void **data, int *num_samples, int *sample_bits); /* ** $Log$ -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.2 2008/03/25 15:56:12 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -306,7 +310,6 @@ extern void apu_getpcmdata(void **data, int *num_samples, int *sample_bits); ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -325,7 +328,16 @@ extern void apu_getpcmdata(void **data, int *num_samples, int *sample_bits); ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** Revision 1.2 2003/04/09 14:50:32 ben +** Clean NSF api. +** +** 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/gst/nsf/nsf.c b/gst/nsf/nsf.c index 6fd34bba..a42022fe 100644 --- a/gst/nsf/nsf.c +++ b/gst/nsf/nsf.c @@ -23,6 +23,7 @@ ** $Id$ */ + #include #include #include "types.h" @@ -52,12 +53,16 @@ nsf_setcontext (nsf_t * nsf) static uint8 read_mirrored_ram (uint32 address) { + 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) { + 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; } @@ -66,27 +71,32 @@ 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); } static nes6502_memread default_readhandler[] = { {0x0800, 0x1FFF, read_mirrored_ram}, {0x4000, 0x4017, apu_read}, - {(uint32) - 1, (uint32) - 1, NULL} + {-1, -1, NULL} }; static nes6502_memwrite default_writehandler[] = { {0x0800, 0x1FFF, write_mirrored_ram}, {0x4000, 0x4017, apu_write}, {0x5FF6, 0x5FFF, nsf_bankswitch}, - {(uint32) - 1, (uint32) - 1, NULL} + {-1, -1, NULL} }; static uint8 @@ -251,6 +261,17 @@ 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! */ if (EXT_SOUND_FDS == nsf->ext_sound_type) { @@ -289,12 +310,37 @@ nsf_inittune (nsf_t * nsf) void nsf_frame (nsf_t * nsf) { - /* future expansion =) */ - /*nsf_setcontext(nsf); */ + /* 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,26 +348,38 @@ void nes_shutdown (nsf_t * nsf) { int i; - void *mem; ASSERT (nsf); if (nsf->cpu) { - if (nsf->cpu->mem_page[0]) - free (nsf->cpu->mem_page[0]); + if (nsf->cpu->mem_page[0]) { + 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]) + 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]); } - mem = nsf->cpu; - free (mem); + 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 +int nsf_init (void) { nes6502_init (); + return 0; } /* Initialize NES CPU, hardware, etc. */ @@ -347,19 +405,27 @@ 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) nsf->playback_rate = 1000000 / nsf->pal_speed; @@ -371,9 +437,18 @@ nsf_setup (nsf_t * nsf) else nsf->playback_rate = 60; /* 60 Hz */ } + return 0; +} - nsf->bankswitched = FALSE; +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]) { nsf->bankswitched = TRUE; @@ -388,68 +463,298 @@ 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; - if (NULL == filename && NULL == source) - return NULL; + a = strrchr (fn, '.'); + b = strrchr (fn, '/'); + c = strrchr (fn, '\\'); + if (a <= b || a <= c) { + a = 0; + } + return a; +} + +/* $$$ ben : FILE loader */ +struct nsf_file_loader_t +{ + struct nsf_loader_t loader; + FILE *fp; + char *fname; + int name_allocated; +}; + +static int +nfs_open_file (struct nsf_loader_t *loader) +{ + struct nsf_file_loader_t *floader = (struct nsf_file_loader_t *) loader; + + 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; +} + +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 == source) { - fp = fopen (filename, "rb"); +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); - /* 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); + if (r >= 0) { + r = n - r; + } + return r; +} - if (NULL == strrchr (new_fn, '.')) - strcat (new_fn, ".nsf"); +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; +} - fp = fopen (new_fn, "rb"); +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; - if (NULL == fp) { - void *t = new_fn; + r = fseek (floader->fp, n, SEEK_CUR); + return r; +} - log_printf ("could not find file '%s'\n", new_fn); - free (t); - return NULL; - } - } +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; +} - temp_nsf = malloc (sizeof (nsf_t)); - if (NULL == temp_nsf) - return NULL; +static void +nfs_close_mem (struct nsf_loader_t *loader) +{ + struct nsf_mem_loader_t *mloader = (struct nsf_mem_loader_t *) loader; - /* Read in the header */ - if (NULL == source) { - if (fread (temp_nsf, 1, NSF_HEADER_SIZE, fp) != NSF_HEADER_SIZE) { - log_printf ("error reading file\n"); - free (temp_nsf); - return NULL; - } - } else - memcpy (temp_nsf, source, NSF_HEADER_SIZE); + mloader->data = 0; + mloader->cur = 0; + mloader->len = 0; +} - if (memcmp (temp_nsf->id, NSF_MAGIC, 5)) { - if (NULL == source) { - void *t = new_fn; +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; - log_printf ("%s is not an NSF format file\n", new_fn); - fclose (fp); - free (t); - } - nsf_free (&temp_nsf); + 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; +} + +/* FIXME: not used anywhere */ +#if 0 +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; +} +#endif + +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; } + /* 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); @@ -458,98 +763,236 @@ nsf_load (char *filename, void *source, int length) 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 { + + + /* 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! */ - temp_nsf->data = malloc (temp_nsf->length); + { + 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 ("error allocating memory for NSF data\n"); - nsf_free (&temp_nsf); - return NULL; + log_printf ("nsf : [%s] error allocating nsf data\n", + loader->fname (loader)); + goto error; } - /* seek to end of header, read in data */ - if (NULL == source) { - fseek (fp, NSF_HEADER_SIZE, SEEK_SET); - if (fread (temp_nsf->data, temp_nsf->length, 1, fp) != 1) - log_printf ("error reading end of header\n"); - - fclose (fp); + /* 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; + } - if (new_fn) { - void *t = new_fn; + if (tsongs > songs) { + tsongs = songs; + } - free (t); + /* Copy time info. */ + for (i = 0; i < tsongs; ++i) { + temp_nsf->song_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 (; i < songs; ++i) { + temp_nsf->song_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; } - } else - memcpy (temp_nsf->data, (uint8 *) source + NSF_HEADER_SIZE, - temp_nsf->length); + } + + + /* 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)) { + log_printf ("nsf : error cpu init\n"); + goto error; + } + 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 NULL; } + return 0; +} - return temp_nsf; +/* 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) +nsf_free (nsf_t ** pnsf) { - if (*nsf) { - if ((*nsf)->apu) - apu_destroy ((*nsf)->apu); + nsf_t *nsf; + + if (!pnsf) { + return; + } - nes_shutdown (*nsf); + nsf = *pnsf; + /* $$$ ben : Don't see why passing a pointer to pointer + * is not to clear it :) */ + *pnsf = 0; - if ((*nsf)->data) { - void *mem = (*nsf)->data; + if (nsf) { + if (nsf->apu) + apu_destroy (nsf->apu); - free (mem); - } + nes_shutdown (nsf); - free (*nsf); + if (nsf->data) + free (nsf->data); + + if (nsf->song_frames) + free (nsf->song_frames); + + free (nsf); } } -void +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 +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); /* create the APU */ - if (nsf->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; + /* $$$ 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)); @@ -572,43 +1015,24 @@ nsf_playtrack (nsf_t * nsf, int track, int sample_rate, int sample_bits, apu_reset (); nsf_inittune (nsf); + + return nsf->current_song; } -void +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$ -** Revision 1.4 2006/10/17 11:04:14 tpm -** Patch by: Josep Torra Valles -** * gst/nsf/fds_snd.c: -** * gst/nsf/mmc5_snd.c: -** * gst/nsf/nsf.c: -** * gst/nsf/vrc7_snd.c: -** * gst/nsf/vrcvisnd.c: -** Fix some things the Forte compiler warns about (#362626). -** -** Revision 1.3 2006/07/19 11:43:50 tpm -** * gst/nsf/nsf.c: (nsf_load): -** Really fix compilation. Apparently it's not enough to -** just check the return value for errors, but we need to -** check for short reads as well (now if only we handled -** them too ...). Fixes #347935. -** -** Revision 1.2 2006/07/18 09:36:46 wtay -** * gst/nsf/nsf.c: (nsf_load): -** Fix compilation by not ignoring return values of fread. -** -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.5 2008/03/25 15:56:12 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -616,7 +1040,6 @@ nsf_setfilter (nsf_t * nsf, int filter_type) ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -635,7 +1058,19 @@ nsf_setfilter (nsf_t * nsf, int filter_type) ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** Revision 1.3 2003/05/01 22:34:20 benjihan +** New NSF plugin +** +** Revision 1.2 2003/04/09 14:50:32 ben +** Clean NSF api. +** +** 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/gst/nsf/nsf.h b/gst/nsf/nsf.h index 2f960367..d81bb6fc 100644 --- a/gst/nsf/nsf.h +++ b/gst/nsf/nsf.h @@ -60,7 +60,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 +91,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,26 +107,49 @@ typedef struct nsf_s void (*process)(void *buffer, int num_samples); } 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$ -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.2 2008/03/25 15:56:12 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -125,7 +157,6 @@ extern void nsf_setfilter(nsf_t *nsf, int filter_type); ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -144,7 +175,19 @@ extern void nsf_setfilter(nsf_t *nsf, int filter_type); ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** Revision 1.3 2003/05/01 22:34:20 benjihan +** New NSF plugin +** +** Revision 1.2 2003/04/09 14:50:32 ben +** Clean NSF api. +** +** 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/gst/nsf/osd.h b/gst/nsf/osd.h index 0a2bb64a..bd63a015 100644 --- a/gst/nsf/osd.h +++ b/gst/nsf/osd.h @@ -79,10 +79,8 @@ extern void osd_shutdown(void); /* ** $Log$ -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.2 2008/03/25 15:56:12 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -90,7 +88,6 @@ extern void osd_shutdown(void); ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -109,7 +106,13 @@ extern void osd_shutdown(void); ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** 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 @@ -121,3 +124,4 @@ extern void osd_shutdown(void); ** initial revision ** */ + diff --git a/gst/nsf/types.h b/gst/nsf/types.h index 8ba17e91..98794903 100644 --- a/gst/nsf/types.h +++ b/gst/nsf/types.h @@ -23,16 +23,13 @@ ** $Id$ */ -#ifndef _NSF_TYPES_H_ -#define _NSF_TYPES_H_ +#ifndef _TYPES_H_ +#define _TYPES_H_ -#include /* for types, endianness */ - -#if G_BYTE_ORDER == G_LITTLE_ENDIAN /* Define this if running on little-endian (x86) systems */ -#define HOST_LITTLE_ENDIAN -#else -#undef HOST_LITTLE_ENDIAN + +#ifndef DCPLAYA +# define HOST_LITTLE_ENDIAN #endif #ifdef __GNUC__ @@ -43,15 +40,28 @@ #define INLINE static #endif -typedef gint8 int8; -typedef gint16 int16; -typedef gint32 int32; +/* These should be changed depending on the platform */ + + -typedef guint8 uint8; -typedef guint16 uint16; -typedef guint32 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 guint8 boolean; + typedef unsigned char uint8; + typedef unsigned short uint16; + typedef unsigned int uint32; + +#endif + +typedef uint8 boolean; #ifndef TRUE #define TRUE 1 @@ -66,6 +76,7 @@ typedef guint8 boolean; #ifdef NOFRENDO_DEBUG #include +#include "memguard.h" #include "log.h" #define ASSERT(expr) if (FALSE == (expr))\ {\ @@ -79,33 +90,17 @@ typedef guint8 boolean; exit(1);\ } #else /* Not debugging */ -#include +#include "memguard.h" #define ASSERT(expr) #define ASSERT_MSG(msg) #endif -#endif /* _NSF_TYPES_H_ */ +#endif /* _TYPES_H_ */ /* ** $Log$ -** Revision 1.3 2007/04/17 08:48:34 tpm -** * gst/nsf/types.h: -** Rename #ifndef header guard symbol to something less generic, so -** types.h doesn't get skipped over when compiling on MingW. Include -** GLib headers and use those to set the endianness and the basic -** types so that this isn't entirely broken for non-x86 architectures. -** -** Revision 1.2 2006/07/14 09:11:11 wtay -** * gst/nsf/Makefile.am: -** * gst/nsf/memguard.c: -** * gst/nsf/memguard.h: -** * gst/nsf/types.h: -** Remove crack malloc/free replacement. -** -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.4 2008/03/25 15:56:12 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -113,7 +108,6 @@ typedef guint8 boolean; ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -132,7 +126,13 @@ typedef guint8 boolean; ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** 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/gst/nsf/vrc7_snd.c b/gst/nsf/vrc7_snd.c index 3dafb85f..d606e74d 100644 --- a/gst/nsf/vrc7_snd.c +++ b/gst/nsf/vrc7_snd.c @@ -138,11 +138,9 @@ vrc7_init (void) static void vrc7_shutdown (void) { - void *t = buffer; - vrc7_reset (); OPLDestroy (vrc7.ym3812); - free (t); + free (buffer); } /* channel (0-9), instrument (0-F), volume (0-3F, YM3812 format) */ @@ -312,7 +310,7 @@ vrc7_process (void) static apu_memwrite vrc7_memwrite[] = { {0x9010, 0x9010, vrc7_write}, {0x9030, 0x9030, vrc7_write}, - {(uint32) - 1, (uint32) - 1, NULL} + {-1, -1, NULL} }; apuext_t vrc7_ext = { @@ -326,19 +324,8 @@ apuext_t vrc7_ext = { /* ** $Log$ -** Revision 1.2 2006/10/17 11:04:14 tpm -** Patch by: Josep Torra Valles -** * gst/nsf/fds_snd.c: -** * gst/nsf/mmc5_snd.c: -** * gst/nsf/nsf.c: -** * gst/nsf/vrc7_snd.c: -** * gst/nsf/vrcvisnd.c: -** Fix some things the Forte compiler warns about (#362626). -** -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.3 2008/03/25 15:56:12 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -346,7 +333,6 @@ apuext_t vrc7_ext = { ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -365,7 +351,13 @@ apuext_t vrc7_ext = { ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** 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/gst/nsf/vrc7_snd.h b/gst/nsf/vrc7_snd.h index 9521d4f7..965f7d75 100644 --- a/gst/nsf/vrc7_snd.h +++ b/gst/nsf/vrc7_snd.h @@ -55,10 +55,8 @@ extern apuext_t vrc7_ext; /* ** $Log$ -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.2 2008/03/25 15:56:12 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -66,7 +64,6 @@ extern apuext_t vrc7_ext; ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -85,7 +82,13 @@ extern apuext_t vrc7_ext; ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** 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 @@ -97,3 +100,4 @@ extern apuext_t vrc7_ext; ** initial revision ** */ + diff --git a/gst/nsf/vrcvisnd.c b/gst/nsf/vrcvisnd.c index e9652b56..56e423cf 100644 --- a/gst/nsf/vrcvisnd.c +++ b/gst/nsf/vrcvisnd.c @@ -23,7 +23,6 @@ ** $Id$ */ -#include #include "types.h" #include "vrcvisnd.h" #include "nes_apu.h" @@ -175,7 +174,7 @@ static apu_memwrite vrcvi_memwrite[] = { {0x9000, 0x9002, vrcvi_write}, /* vrc6 */ {0xA000, 0xA002, vrcvi_write}, {0xB000, 0xB002, vrcvi_write}, - {(uint32) - 1, (uint32) - 1, NULL} + {-1, -1, NULL} }; apuext_t vrcvi_ext = { @@ -189,19 +188,8 @@ apuext_t vrcvi_ext = { /* ** $Log$ -** Revision 1.2 2006/10/17 11:04:14 tpm -** Patch by: Josep Torra Valles -** * gst/nsf/fds_snd.c: -** * gst/nsf/mmc5_snd.c: -** * gst/nsf/nsf.c: -** * gst/nsf/vrc7_snd.c: -** * gst/nsf/vrcvisnd.c: -** Fix some things the Forte compiler warns about (#362626). -** -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.3 2008/03/25 15:56:13 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -209,7 +197,6 @@ apuext_t vrcvi_ext = { ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -228,7 +215,13 @@ apuext_t vrcvi_ext = { ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** 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/gst/nsf/vrcvisnd.h b/gst/nsf/vrcvisnd.h index d141aef7..d1cde6fb 100644 --- a/gst/nsf/vrcvisnd.h +++ b/gst/nsf/vrcvisnd.h @@ -64,10 +64,8 @@ extern apuext_t vrcvi_ext; /* ** $Log$ -** Revision 1.1 2006/07/13 15:07:28 wtay -** Based on patches by: Johan Dahlin -** Ronald Bultje -** * configure.ac: +** Revision 1.2 2008/03/25 15:56:13 slomo +** Patch by: Andreas Henriksson ** * gst/nsf/Makefile.am: ** * gst/nsf/dis6502.h: ** * gst/nsf/fds_snd.c: @@ -75,7 +73,6 @@ extern apuext_t vrcvi_ext; ** * gst/nsf/fmopl.c: ** * gst/nsf/fmopl.h: ** * gst/nsf/gstnsf.c: -** * gst/nsf/gstnsf.h: ** * gst/nsf/log.c: ** * gst/nsf/log.h: ** * gst/nsf/memguard.c: @@ -94,7 +91,13 @@ extern apuext_t vrcvi_ext; ** * gst/nsf/vrc7_snd.h: ** * gst/nsf/vrcvisnd.c: ** * gst/nsf/vrcvisnd.h: -** Added NSF decoder plugin. Fixes 151192. +** Update our internal nosefart to nosefart-2.7-mls to fix segfaults +** on some files. Fixes bug #498237. +** Remove some // comments, fix some compiler warnings and use pow() +** instead of a slow, selfmade implementation. +** +** 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 @@ -109,4 +112,3 @@ extern apuext_t vrcvi_ext; ** initial revision ** */ - -- cgit v1.2.1