mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 08:46:40 +00:00
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 <andreas at fatal dot set> * 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.
This commit is contained in:
parent
09ec92549f
commit
a4d0dacec2
26 changed files with 1736 additions and 506 deletions
35
ChangeLog
35
ChangeLog
|
@ -1,3 +1,38 @@
|
|||
2008-03-25 Sebastian Dröge <slomo@circular-chaos.org>
|
||||
|
||||
Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
|
||||
* 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.
|
||||
|
||||
2008-03-25 Sebastian Dröge <slomo@circular-chaos.org>
|
||||
|
||||
Patch by: Ed Catmur <ed at catmur dot co dot uk>
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.2 2008/03/25 15:56:10 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
** $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#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 <josep at fluendo com>
|
||||
** * 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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.3 2008/03/25 15:56:10 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
|
|
|
@ -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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.2 2008/03/25 15:56:10 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
129
gst/nsf/fmopl.c
129
gst/nsf/fmopl.c
|
@ -18,9 +18,9 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <math.h>
|
||||
/* #include "driver.h" *//* use M.A.M.E. */
|
||||
/*#include "driver.h" *//* use M.A.M.E. */
|
||||
#include "fmopl.h"
|
||||
#include <math.h>
|
||||
|
||||
/* 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 ---------- */
|
||||
|
|
|
@ -162,3 +162,4 @@ void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length);
|
|||
void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.2 2008/03/25 15:56:11 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
|
|
|
@ -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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.2 2008/03/25 15:56:11 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
401
gst/nsf/memguard.c
Normal file
401
gst/nsf/memguard.c
Normal file
|
@ -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 <string.h>
|
||||
#include <stdlib.h>
|
||||
#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 <andreas at fatal dot set>
|
||||
** * 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
|
||||
**
|
||||
*/
|
98
gst/nsf/memguard.h
Normal file
98
gst/nsf/memguard.h
Normal file
|
@ -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 <andreas at fatal dot set>
|
||||
** * 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
|
||||
**
|
||||
*/
|
|
@ -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 <josep at fluendo com>
|
||||
** * 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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.3 2008/03/25 15:56:11 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
|
|
|
@ -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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.2 2008/03/25 15:56:11 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
|
@ -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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.3 2008/03/25 15:56:11 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
|
|
|
@ -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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.2 2008/03/25 15:56:12 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
|
|
|
@ -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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.2 2008/03/25 15:56:12 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
|
|
|
@ -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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.2 2008/03/25 15:56:12 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
|
|
725
gst/nsf/nsf.c
725
gst/nsf/nsf.c
|
@ -23,6 +23,7 @@
|
|||
** $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#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]);
|
||||
for (i = 5; i <= 7; i++) {
|
||||
if (nsf->cpu->mem_page[i])
|
||||
free (nsf->cpu->mem_page[i]);
|
||||
if (nsf->cpu->mem_page[0]) {
|
||||
free (nsf->cpu->mem_page[0]); /*tracks 1 and 2 of lifeforce hang here. */
|
||||
}
|
||||
mem = nsf->cpu;
|
||||
free (mem);
|
||||
for (i = 5; i <= 7; i++) {
|
||||
if (nsf->cpu->mem_page[i]) {
|
||||
free (nsf->cpu->mem_page[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NES6502_MEM_ACCESS_CTRL
|
||||
if (nsf->cpu->acc_mem_page[0]) {
|
||||
free (nsf->cpu->acc_mem_page[0]);
|
||||
}
|
||||
for (i = 5; i <= 7; i++) {
|
||||
if (nsf->cpu->acc_mem_page[i]) {
|
||||
free (nsf->cpu->acc_mem_page[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
free (nsf->cpu);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
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;
|
||||
}
|
||||
|
||||
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,66 +463,296 @@ 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;
|
||||
}
|
||||
|
||||
if (NULL == source) {
|
||||
fp = fopen (filename, "rb");
|
||||
/* $$$ ben : FILE loader */
|
||||
struct nsf_file_loader_t
|
||||
{
|
||||
struct nsf_loader_t loader;
|
||||
FILE *fp;
|
||||
char *fname;
|
||||
int name_allocated;
|
||||
};
|
||||
|
||||
/* Didn't find the file? Maybe the .NSF extension was omitted */
|
||||
if (NULL == fp) {
|
||||
new_fn = malloc (strlen (filename) + 5);
|
||||
if (NULL == new_fn)
|
||||
return NULL;
|
||||
strcpy (new_fn, filename);
|
||||
static int
|
||||
nfs_open_file (struct nsf_loader_t *loader)
|
||||
{
|
||||
struct nsf_file_loader_t *floader = (struct nsf_file_loader_t *) loader;
|
||||
|
||||
if (NULL == strrchr (new_fn, '.'))
|
||||
strcat (new_fn, ".nsf");
|
||||
floader->name_allocated = 0;
|
||||
floader->fp = 0;
|
||||
if (!floader->fname) {
|
||||
return -1;
|
||||
}
|
||||
floader->fp = fopen (floader->fname, "rb");
|
||||
if (!floader->fp) {
|
||||
char *fname, *ext;
|
||||
|
||||
fp = fopen (new_fn, "rb");
|
||||
|
||||
if (NULL == fp) {
|
||||
void *t = new_fn;
|
||||
|
||||
log_printf ("could not find file '%s'\n", new_fn);
|
||||
free (t);
|
||||
return NULL;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
nfs_read_file (struct nsf_loader_t *loader, void *data, int n)
|
||||
{
|
||||
struct nsf_file_loader_t *floader = (struct nsf_file_loader_t *) loader;
|
||||
int r = fread (data, 1, n, floader->fp);
|
||||
|
||||
if (r >= 0) {
|
||||
r = n - r;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
nfs_length_file (struct nsf_loader_t *loader)
|
||||
{
|
||||
struct nsf_file_loader_t *floader = (struct nsf_file_loader_t *) loader;
|
||||
long save, pos;
|
||||
|
||||
save = ftell (floader->fp);
|
||||
fseek (floader->fp, 0, SEEK_END);
|
||||
pos = ftell (floader->fp);
|
||||
fseek (floader->fp, save, SEEK_SET);
|
||||
return pos;
|
||||
}
|
||||
|
||||
static int
|
||||
nfs_skip_file (struct nsf_loader_t *loader, int n)
|
||||
{
|
||||
struct nsf_file_loader_t *floader = (struct nsf_file_loader_t *) loader;
|
||||
int r;
|
||||
|
||||
r = fseek (floader->fp, n, SEEK_CUR);
|
||||
return r;
|
||||
}
|
||||
|
||||
static const char *
|
||||
nfs_fname_file (struct nsf_loader_t *loader)
|
||||
{
|
||||
struct nsf_file_loader_t *floader = (struct nsf_file_loader_t *) loader;
|
||||
|
||||
return floader->fname ? floader->fname : "<null>";
|
||||
}
|
||||
|
||||
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, "<mem(%p,%u)>",
|
||||
mloader->data, (unsigned int) mloader->len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nfs_close_mem (struct nsf_loader_t *loader)
|
||||
{
|
||||
struct nsf_mem_loader_t *mloader = (struct nsf_mem_loader_t *) loader;
|
||||
|
||||
mloader->data = 0;
|
||||
mloader->cur = 0;
|
||||
mloader->len = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nfs_read_mem (struct nsf_loader_t *loader, void *data, int n)
|
||||
{
|
||||
struct nsf_mem_loader_t *mloader = (struct nsf_mem_loader_t *) loader;
|
||||
int rem;
|
||||
|
||||
if (n <= 0) {
|
||||
return n;
|
||||
}
|
||||
if (!mloader->data) {
|
||||
return -1;
|
||||
}
|
||||
rem = mloader->len - mloader->cur;
|
||||
if (rem > n) {
|
||||
rem = n;
|
||||
}
|
||||
memcpy (data, mloader->data + mloader->cur, rem);
|
||||
mloader->cur += rem;
|
||||
return n - rem;
|
||||
}
|
||||
|
||||
static int
|
||||
nfs_length_mem (struct nsf_loader_t *loader)
|
||||
{
|
||||
struct nsf_mem_loader_t *mloader = (struct nsf_mem_loader_t *) loader;
|
||||
|
||||
return mloader->len;
|
||||
}
|
||||
|
||||
static int
|
||||
nfs_skip_mem (struct nsf_loader_t *loader, int n)
|
||||
{
|
||||
struct nsf_mem_loader_t *mloader = (struct nsf_mem_loader_t *) loader;
|
||||
unsigned long goal = mloader->cur + n;
|
||||
|
||||
mloader->cur = (goal > mloader->len) ? mloader->len : goal;
|
||||
return goal - mloader->cur;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
return NULL;
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
|
||||
if (memcmp (temp_nsf->id, NSF_MAGIC, 5)) {
|
||||
if (NULL == source) {
|
||||
void *t = new_fn;
|
||||
|
||||
log_printf ("%s is not an NSF format file\n", new_fn);
|
||||
fclose (fp);
|
||||
free (t);
|
||||
}
|
||||
nsf_free (&temp_nsf);
|
||||
return NULL;
|
||||
/* 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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/* Allocate NSF space, and load it up! */
|
||||
temp_nsf->data = malloc (temp_nsf->length);
|
||||
if (NULL == temp_nsf->data) {
|
||||
log_printf ("error allocating memory for NSF data\n");
|
||||
nsf_free (&temp_nsf);
|
||||
return NULL;
|
||||
if (temp_nsf->length <= 0) {
|
||||
log_printf ("nsf : [%s] not an NSF format file (missing 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");
|
||||
/* Allocate NSF space, and load it up! */
|
||||
{
|
||||
int len = temp_nsf->length;
|
||||
|
||||
fclose (fp);
|
||||
#ifdef NES6502_MEM_ACCESS_CTRL
|
||||
/* $$$ twice memory for access control shadow mem. */
|
||||
len <<= 1;
|
||||
#endif
|
||||
temp_nsf->data = malloc (len);
|
||||
}
|
||||
if (NULL == temp_nsf->data) {
|
||||
log_printf ("nsf : [%s] error allocating nsf data\n",
|
||||
loader->fname (loader));
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Read data */
|
||||
if (loader->read (loader, temp_nsf->data, temp_nsf->length)) {
|
||||
log_printf ("nsf : [%s] error reading NSF data\n", loader->fname (loader));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (new_fn) {
|
||||
void *t = new_fn;
|
||||
/* 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;
|
||||
|
||||
free (t);
|
||||
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;
|
||||
}
|
||||
} else
|
||||
memcpy (temp_nsf->data, (uint8 *) source + NSF_HEADER_SIZE,
|
||||
temp_nsf->length);
|
||||
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 (tsongs > songs) {
|
||||
tsongs = songs;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Close "file" */
|
||||
loader->close (loader);
|
||||
loader = 0;
|
||||
|
||||
/* Set up some variables */
|
||||
nsf_setup (temp_nsf);
|
||||
|
||||
temp_nsf->apu = NULL; /* just make sure */
|
||||
|
||||
if (nsf_cpuinit (temp_nsf)) {
|
||||
nsf_free (&temp_nsf);
|
||||
return NULL;
|
||||
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 0;
|
||||
}
|
||||
|
||||
/* Load a ROM image into memory */
|
||||
nsf_t *
|
||||
nsf_load (const char *filename, void *source, int length)
|
||||
{
|
||||
struct nsf_loader_t *loader = 0;
|
||||
|
||||
/* $$$ ben : new loader */
|
||||
if (filename) {
|
||||
nsf_file_loader.fname = (char *) filename;
|
||||
loader = &nsf_file_loader.loader;
|
||||
} else {
|
||||
nsf_mem_loader.data = source;
|
||||
nsf_mem_loader.len = length;
|
||||
nsf_mem_loader.fname[0] = 0;
|
||||
loader = &nsf_mem_loader.loader;
|
||||
}
|
||||
return nsf_load_extended (loader);
|
||||
}
|
||||
|
||||
/* Free an NSF */
|
||||
void
|
||||
nsf_free (nsf_t ** nsf)
|
||||
nsf_free (nsf_t ** pnsf)
|
||||
{
|
||||
if (*nsf) {
|
||||
if ((*nsf)->apu)
|
||||
apu_destroy ((*nsf)->apu);
|
||||
nsf_t *nsf;
|
||||
|
||||
nes_shutdown (*nsf);
|
||||
if (!pnsf) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((*nsf)->data) {
|
||||
void *mem = (*nsf)->data;
|
||||
nsf = *pnsf;
|
||||
/* $$$ ben : Don't see why passing a pointer to pointer
|
||||
* is not to clear it :) */
|
||||
*pnsf = 0;
|
||||
|
||||
free (mem);
|
||||
}
|
||||
if (nsf) {
|
||||
if (nsf->apu)
|
||||
apu_destroy (nsf->apu);
|
||||
|
||||
free (*nsf);
|
||||
nes_shutdown (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 <josep at fluendo com>
|
||||
** * 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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.5 2008/03/25 15:56:12 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
|
|
|
@ -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;
|
||||
|
||||
/* Function prototypes */
|
||||
extern void nsf_init(void);
|
||||
/* $$$ ben : Generic loader struct */
|
||||
struct nsf_loader_t {
|
||||
/* Init and open. */
|
||||
int (*open)(struct nsf_loader_t * loader);
|
||||
|
||||
extern nsf_t *nsf_load(char *filename, void *source, int length);
|
||||
/* 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 int nsf_init(void);
|
||||
|
||||
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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.2 2008/03/25 15:56:12 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
|
|
|
@ -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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.2 2008/03/25 15:56:12 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
|
@ -23,16 +23,13 @@
|
|||
** $Id$
|
||||
*/
|
||||
|
||||
#ifndef _NSF_TYPES_H_
|
||||
#define _NSF_TYPES_H_
|
||||
#ifndef _TYPES_H_
|
||||
#define _TYPES_H_
|
||||
|
||||
#include <glib.h> /* 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;
|
||||
|
||||
typedef guint8 boolean;
|
||||
|
||||
#ifdef __BEOS__ /* added by Eli Dayan (for compiling under BeOS) */
|
||||
|
||||
/* use types in the BeOS Support Kit instead */
|
||||
#include <be/support/SupportDefs.h>
|
||||
#elif defined (DCPLAYA) /* $$$ added by ben (for compiling with dcplaya) */
|
||||
# include <arch/types.h>
|
||||
#else
|
||||
typedef char int8;
|
||||
typedef short int16;
|
||||
typedef int int32;
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
|
||||
#endif
|
||||
|
||||
typedef uint8 boolean;
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
|
@ -66,6 +76,7 @@ typedef guint8 boolean;
|
|||
|
||||
#ifdef NOFRENDO_DEBUG
|
||||
#include <stdlib.h>
|
||||
#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 <stdlib.h>
|
||||
#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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.4 2008/03/25 15:56:12 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
|
|
|
@ -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 <josep at fluendo com>
|
||||
** * 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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.3 2008/03/25 15:56:12 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
|
|
|
@ -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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.2 2008/03/25 15:56:12 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
** $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#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 <josep at fluendo com>
|
||||
** * 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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.3 2008/03/25 15:56:13 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
|
|
|
@ -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 <johan at gnome dot org>
|
||||
** Ronald Bultje <rbultje at ronald dot bitfreak dot net>
|
||||
** * configure.ac:
|
||||
** Revision 1.2 2008/03/25 15:56:13 slomo
|
||||
** Patch by: Andreas Henriksson <andreas at fatal dot set>
|
||||
** * 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
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
Loading…
Reference in a new issue