diff --git a/Makefiles/Makefile.SDL.Win32.MSVC b/Makefiles/Makefile.SDL.Win32.MSVC
index afe4961..0d9191a 100644
--- a/Makefiles/Makefile.SDL.Win32.MSVC
+++ b/Makefiles/Makefile.SDL.Win32.MSVC
@@ -119,11 +119,11 @@ CC = "$(VC_BIN)\cl.exe"
LD = "$(VC_BIN)\link.exe"
COMPILER_FLAGS = /I "$(SDL_INCLUDEPATH)" /I "$(ZLIB_INCLUDEPATH)" /I "$(DIRECTX_INCLUDEPATH)" /I "Src" /I "Src\\OSD" /I "Src\\OSD\\SDL" \
/I "Src\\OSD\\Windows" /Ox /D "SUPERMODEL_WIN32" /D "GLEW_STATIC" /D "_MBCS" /D "_CRT_SECURE_NO_WARNINGS" /MT /Gy /W3 /nologo /c /Zi /GL \
- /D "DEBUG" /DEBUG
+ /DEBUG /Zi #/D "DEBUG" /DEBUG
CFLAGS = $(COMPILER_FLAGS) /TC
CPPFLAGS = $(COMPILER_FLAGS) /TP /EHsc
LFLAGS = /MACHINE:$(ARCH) $(ARCH_LIBS) /LIBPATH:"$(SDL_LIBPATH)" /LIBPATH:"$(ZLIB_LIBPATH)" /LIBPATH:"$(DIRECTX_LIBPATH)" /OUT:"$(OUTFILE)" \
- /MANIFEST:NO /SUBSYSTEM:CONSOLE /NOLOGO /OPT:REF /OPT:ICF /DYNAMICBASE /NXCOMPAT /LTCG #/DEBUG
+ /MANIFEST:NO /SUBSYSTEM:CONSOLE /NOLOGO /OPT:REF /OPT:ICF /DYNAMICBASE /NXCOMPAT /LTCG /DEBUG
OBJ_LIBS = kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib \
odbc32.lib odbccp32.lib OpenGL32.lib GLu32.lib SDL.lib SDLmain.lib zlib.lib dinput8.lib dxguid.lib
@@ -160,10 +160,15 @@ OBJ = $(OBJ_DIR)/PPCDisasm.obj $(OBJ_DIR)/Games.obj $(OBJ_DIR)/INIFile.obj $(OBJ
$(OBJ_DIR)/ROMLoad.obj $(OBJ_DIR)/unzip.obj $(OBJ_DIR)/ioapi.obj $(OBJ_DIR)/Error.obj $(OBJ_DIR)/glew.obj $(OBJ_DIR)/Shader.obj \
$(OBJ_DIR)/Real3D.obj $(OBJ_DIR)/Render3D.obj $(OBJ_DIR)/Models.obj $(OBJ_DIR)/Render2D.obj $(OBJ_DIR)/TileGen.obj \
$(OBJ_DIR)/Model3.obj $(OBJ_DIR)/ppc.obj $(OBJ_DIR)/Main.obj $(OBJ_DIR)/Audio.obj $(OBJ_DIR)/Thread.obj $(OBJ_DIR)/SoundBoard.obj \
- $(OBJ_DIR)/SCSP.obj $(OBJ_DIR)/SCSPDSP.obj $(OBJ_DIR)/M68K.obj $(OBJ_DIR)/m68kcpu.obj $(OBJ_DIR)/m68kopnz.obj $(OBJ_DIR)/m68kopdm.obj \
- $(OBJ_DIR)/m68kopac.obj $(OBJ_DIR)/m68kops.obj $(OBJ_DIR)/IRQ.obj $(OBJ_DIR)/53C810.obj $(OBJ_DIR)/PCI.obj $(OBJ_DIR)/RTC72421.obj \
+ $(OBJ_DIR)/SCSP.obj $(OBJ_DIR)/SCSPDSP.obj $(OBJ_DIR)/68K.obj $(OBJ_DIR)/m68kcpu.obj $(OBJ_DIR)/m68kopnz.obj $(OBJ_DIR)/m68kopdm.obj \
+ $(OBJ_DIR)/m68kopac.obj $(OBJ_DIR)/m68kops.obj $(OBJ_DIR)/DSB.obj $(OBJ_DIR)/Z80.obj \
+ $(OBJ_DIR)/IRQ.obj $(OBJ_DIR)/53C810.obj $(OBJ_DIR)/PCI.obj $(OBJ_DIR)/RTC72421.obj \
$(OBJ_DIR)/MPC10x.obj $(OBJ_DIR)/Input.obj $(OBJ_DIR)/Inputs.obj $(OBJ_DIR)/InputSource.obj $(OBJ_DIR)/InputSystem.obj \
- $(OBJ_DIR)/InputTypes.obj $(OBJ_DIR)/MultiInputSource.obj $(OBJ_DIR)/SDLInputSystem.obj $(OBJ_DIR)/DirectInputSystem.obj
+ $(OBJ_DIR)/InputTypes.obj $(OBJ_DIR)/MultiInputSource.obj $(OBJ_DIR)/SDLInputSystem.obj $(OBJ_DIR)/DirectInputSystem.obj \
+ $(OBJ_DIR)/amp_audio.obj $(OBJ_DIR)/amp_dump.obj $(OBJ_DIR)/amp_getbits.obj $(OBJ_DIR)/amp_getdata.obj $(OBJ_DIR)/amp_huffman.obj \
+ $(OBJ_DIR)/amp_layer2.obj $(OBJ_DIR)/amp_layer3.obj $(OBJ_DIR)/amp_misc2.obj $(OBJ_DIR)/amp_position.obj $(OBJ_DIR)/amp_transform.obj \
+ $(OBJ_DIR)/amp_util.obj
+
# If built-in debugger enabled, include all debugging classes
ifeq ($(strip $(ENABLE_DEBUGGER)),yes)
@@ -278,6 +283,9 @@ $(OBJ_DIR)/%.obj: Src/CPU/PowerPC/%.cpp Src/CPU/PowerPC/%.h Src/CPU/PowerPC/ppc6
$(OBJ_DIR)/%.obj: Src/CPU/68K/%.cpp Src/CPU/68K/%.h $(HEADERS)
$(CC) $< $(CPPFLAGS) /Fo$(OBJ_DIR)/$(*F).obj
+$(OBJ_DIR)/%.obj: Src/CPU/Z80/%.cpp Src/CPU/Z80/%.h $(HEADERS)
+ $(CC) $< $(CPPFLAGS) /Fo$(OBJ_DIR)/$(*F).obj
+
$(OBJ_DIR)/%.obj: Src/Inputs/%.cpp Src/Inputs/%.h $(HEADERS)
$(CC) $< $(CPPFLAGS) /Fo$(OBJ_DIR)/$(*F).obj
@@ -295,3 +303,14 @@ $(OBJ_DIR)/%.obj: Src/Pkgs/%.c Src/Pkgs/%.h
$(OBJ_DIR)/%.obj: Src/Pkgs/%.c
$(CC) $< $(CFLAGS) /Fo$(OBJ_DIR)/$(*F).obj
+
+#
+# AMP MPEG decoder library
+#
+# To eliminate name conflicts, object files have the prefix "amp_" attached.
+#
+$(OBJ_DIR)/amp_%.obj: Src/Sound/MPEG/%.cpp Src/Sound/MPEG/%.h
+ $(CC) $< $(CPPFLAGS) /Fo$(OBJ_DIR)/amp_$(*F).obj
+
+$(OBJ_DIR)/amp_%.obj: Src/Sound/MPEG/%.cpp
+ $(CC) $< $(CPPFLAGS) /Fo$(OBJ_DIR)/amp_$(*F).obj
\ No newline at end of file
diff --git a/Src/CPU/68K/M68K.cpp b/Src/CPU/68K/68K.cpp
similarity index 69%
rename from Src/CPU/68K/M68K.cpp
rename to Src/CPU/68K/68K.cpp
index 29d0e41..4962321 100644
--- a/Src/CPU/68K/M68K.cpp
+++ b/Src/CPU/68K/68K.cpp
@@ -20,7 +20,7 @@
**/
/*
- * M68K.cpp
+ * 68K.cpp
*
* 68K CPU interface. This is presently just a wrapper for the Musashi 68K core
* and therefore, only a single CPU is supported. In the future, we may want to
@@ -30,26 +30,28 @@
#include "Supermodel.h"
#include "Musashi/m68k.h" // Musashi 68K core
+
+/******************************************************************************
+ Internal Context
+
+ An active context must be mapped before calling M68K interface functions. Only
+ the bus and IRQ handlers are copied here; the CPU context is passed directly
+ to Musashi.
+******************************************************************************/
+
+// Bus
+static CBus *Bus = NULL;
+
+// IRQ callback
+static int (*IRQAck)(int nIRQ) = NULL;
+
+
/******************************************************************************
68K Interface
******************************************************************************/
-// Interface function pointers
-static int (*IRQAck)(int nIRQ) = NULL;
-static UINT8 (*Fetch8)(UINT32 addr) = NULL;
-static UINT16 (*Fetch16)(UINT32 addr) = NULL;
-static UINT32 (*Fetch32)(UINT32 addr) = NULL;
-static UINT8 (*Read8)(UINT32 addr) = NULL;
-static UINT16 (*Read16)(UINT32 addr) = NULL;
-static UINT32 (*Read32)(UINT32 addr) = NULL;
-static void (*Write8)(UINT32 addr, UINT8 data) = NULL;
-static void (*Write16)(UINT32 addr, UINT16 data) = NULL;
-static void (*Write32)(UINT32 addr, UINT32 data) = NULL;
-
-extern "C" {
-
// CPU state
-
+
UINT32 M68KGetARegister(int n)
{
m68k_register_t r;
@@ -110,6 +112,7 @@ int M68KRun(int numCycles)
void M68KReset(void)
{
m68k_pulse_reset();
+ DebugLog("68K reset\n");
}
// Callback setup
@@ -119,49 +122,26 @@ void M68KSetIRQCallback(int (*F)(int nIRQ))
IRQAck = F;
}
-void M68KSetFetch8Callback(UINT8 (*F)(UINT32))
+void M68KAttachBus(CBus *BusPtr)
{
- Fetch8 = F;
+ Bus = BusPtr;
+ DebugLog("Attached bus to 68K\n");
}
-void M68KSetFetch16Callback(UINT16 (*F)(UINT32))
+// Context switching
+
+void M68KGetContext(M68KCtx *Dest)
{
- Fetch16 = F;
+ Dest->IRQAck = IRQAck;
+ Dest->Bus = Bus;
+ m68k_get_context(Dest->musashiCtx);
}
-void M68KSetFetch32Callback(UINT32 (*F)(UINT32))
+void M68KSetContext(M68KCtx *Src)
{
- Fetch32 = F;
-}
-
-void M68KSetRead8Callback(UINT8 (*F)(UINT32))
-{
- Read8 = F;
-}
-
-void M68KSetRead16Callback(UINT16 (*F)(UINT32))
-{
- Read16 = F;
-}
-
-void M68KSetRead32Callback(UINT32 (*F)(UINT32))
-{
- Read32 = F;
-}
-
-void M68KSetWrite8Callback(void (*F)(UINT32,UINT8))
-{
- Write8 = F;
-}
-
-void M68KSetWrite16Callback(void (*F)(UINT32,UINT16))
-{
- Write16 = F;
-}
-
-void M68KSetWrite32Callback(void (*F)(UINT32,UINT32))
-{
- Write32 = F;
+ IRQAck = Src->IRQAck;
+ Bus = Src->Bus;
+ m68k_set_context(Src->musashiCtx);
}
// One-time initialization
@@ -171,11 +151,12 @@ BOOL M68KInit(void)
m68k_init();
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
m68k_set_int_ack_callback(M68KIRQCallback);
+ Bus = NULL;
+
+ DebugLog("Initialized 68K\n");
return OKAY;
}
-} // extern "C"
-
/******************************************************************************
Musashi 68K Handlers
@@ -187,55 +168,58 @@ extern "C" {
int M68KIRQCallback(int nIRQ)
{
- if (NULL == IRQAck)
+ if (NULL == IRQAck) // no handler, use default behavior
+ {
+ m68k_set_irq(0); // clear line
return M68K_IRQ_AUTOVECTOR;
+ }
else
return IRQAck(nIRQ);
}
unsigned int FASTCALL M68KFetch8(unsigned int a)
{
- return Fetch8(a);
+ return Bus->Read8(a);
}
unsigned int FASTCALL M68KFetch16(unsigned int a)
{
- return Fetch16(a);
+ return Bus->Read16(a);
}
unsigned int FASTCALL M68KFetch32(unsigned int a)
{
- return Fetch32(a);
+ return Bus->Read32(a);
}
unsigned int FASTCALL M68KRead8(unsigned int a)
{
- return Read8(a);
+ return Bus->Read8(a);
}
unsigned int FASTCALL M68KRead16(unsigned int a)
{
- return Read16(a);
+ return Bus->Read16(a);
}
unsigned int FASTCALL M68KRead32(unsigned int a)
{
- return Read32(a);
+ return Bus->Read32(a);
}
void FASTCALL M68KWrite8(unsigned int a, unsigned int d)
{
- Write8(a, d);
+ Bus->Write8(a, d);
}
void FASTCALL M68KWrite16(unsigned int a, unsigned int d)
{
- Write16(a, d);
+ Bus->Write16(a, d);
}
void FASTCALL M68KWrite32(unsigned int a, unsigned int d)
{
- Write32(a, d);
+ Bus->Write32(a, d);
}
} // extern "C"
diff --git a/Src/CPU/68K/M68K.h b/Src/CPU/68K/68K.h
similarity index 65%
rename from Src/CPU/68K/M68K.h
rename to Src/CPU/68K/68K.h
index 4b08ded..b4a0965 100644
--- a/Src/CPU/68K/M68K.h
+++ b/Src/CPU/68K/68K.h
@@ -20,26 +20,21 @@
**/
/*
- * M68K.h
+ * 68K.h
*
- * Header file for 68K CPU interface. Caution: there is only a single 68K core
- * available to Supermodel right now. Therefore, multiple 68K CPUs are not
- * presently supported. See M68K.c for more details.
+ * Header file for 68K CPU interface. Caution: 68K emulator is not thread-safe.
*
* TO-DO List:
* -----------
* - Optimize things, perhaps by using FASTCALL
*/
-#ifndef INCLUDED_M68K_H
-#define INCLUDED_M68K_H
+#ifndef INCLUDED_68K_H
+#define INCLUDED_68K_H
#include "Types.h"
#include "Musashi/m68k.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "CPU/Bus.h"
// This doesn't work for now (needs to be added to the prototypes in m68k.h for m68k_read_memory*)
//#ifndef FASTCALL
@@ -57,8 +52,44 @@ extern "C" {
#define M68K_IRQ_SPURIOUS M68K_INT_ACK_SPURIOUS // signals a spurious interrupt
+/******************************************************************************
+ CPU Context
+******************************************************************************/
+
+/*
+ * M68KCtx:
+ *
+ * Complete state of a single 68K. Do NOT manipulate these directly. Set the
+ * context and then use the M68K* functions below to attach a bus and IRQ
+ * callback to the active context.
+ */
+typedef struct SM68KCtx
+{
+public:
+ CBus *Bus; // memory handlers
+ int (*IRQAck)(int); // IRQ acknowledge callback
+ unsigned char *musashiCtx; // holds CPU state
+
+ SM68KCtx(void)
+ {
+ Bus = NULL;
+ IRQAck = NULL;
+ musashiCtx = new unsigned char[m68k_context_size()];
+ }
+
+ ~SM68KCtx(void)
+ {
+ Bus = NULL;
+ IRQAck = NULL;
+ delete [] musashiCtx;
+ }
+} M68KCtx;
+
+
/******************************************************************************
68K Interface
+
+ Unless otherwise noted, all functions operate on the active context.
******************************************************************************/
/*
@@ -124,8 +155,8 @@ extern void M68KReset(void);
/*
* M68KSetIRQCallback(F):
*
- * Installs an interrupt acknowledge callback. The default behavior is to
- * always assume autovectored interrupts.
+ * Installs an interrupt acknowledge callback for the currently active CPU. The
+ * default behavior is to always assume autovectored interrupts.
*
* Parameters:
* F Callback function.
@@ -133,44 +164,50 @@ extern void M68KReset(void);
extern void M68KSetIRQCallback(int (*F)(int));
/*
- * M68KSetFetch8Callback(F):
- * M68KSetFetch16Callback(F):
- * M68KSetFetch32Callback(F):
- * M68KSetRead8Callback(F):
- * M68KSetRead16Callback(F):
- * M68KSetRead32Callback(F):
- * M68KSetWrite8Callback(F):
- * M68KSetWrite16Callback(F):
- * M68KSetWrite32Callback(F):
+ * M68KAttachBus(CBus *BusPtr):
*
- * Installs address space handler callbacks. There is no default behavior;
- * these must all be set up before any 68K-related emulation functions are
- * invoked.
+ * Attaches a bus object to the 68K, which will be used to perform all address
+ * space accesses. The 8, 16, and 32-bit read and write handlers are used.
+ * This must be set up before any 68K-related emulation functions are invoked
+ * or the program will crash!
*
* Parameters:
- * F Callback function.
+ * BusPtr Pointer to bus object to use for all address space accesses.
*/
-extern void M68KSetFetch8Callback(UINT8 (*F)(UINT32));
-extern void M68KSetFetch16Callback(UINT16 (*F)(UINT32));
-extern void M68KSetFetch32Callback(UINT32 (*F)(UINT32));
-extern void M68KSetRead8Callback(UINT8 (*F)(UINT32));
-extern void M68KSetRead16Callback(UINT16 (*F)(UINT32));
-extern void M68KSetRead32Callback(UINT32 (*F)(UINT32));
-extern void M68KSetWrite8Callback(void (*F)(UINT32,UINT8));
-extern void M68KSetWrite16Callback(void (*F)(UINT32,UINT16));
-extern void M68KSetWrite32Callback(void (*F)(UINT32,UINT32));
+extern void M68KAttachBus(CBus *BusPtr);
/*
* M68KInit():
*
* Initializes the 68K emulator. Must be called once per program session prior
- * to any other 68K interface calls.
+ * to any 68K emulation functions. A context must be mapped before calling
+ * this.
*
* Returns:
* Always returns OKAY.
*/
extern BOOL M68KInit(void);
+/*
+ * M68KGetContext(M68KCtx *Dest):
+ *
+ * Copies the internal (active) 68K context back to the destination.
+ *
+ * Parameters:
+ * Dest Location to which to copy 68K context.
+ */
+extern void M68KGetContext(M68KCtx *Dest);
+
+/*
+ * M68KSetContext(M68KCtx *Src):
+ *
+ * Sets the specified 68K context by copying it to the internal context.
+ *
+ * Parameters:
+ * Src Location from which to copy 68K context.
+ */
+extern void M68KSetContext(M68KCtx *Src);
+
/******************************************************************************
68K Handlers
@@ -178,6 +215,8 @@ extern BOOL M68KInit(void);
Intended for use directly by the 68K core.
******************************************************************************/
+extern "C" {
+
/*
* M68KIRQCallback(nIRQ):
*
@@ -243,10 +282,7 @@ void FASTCALL M68KWrite8(unsigned int a, unsigned int d);
void FASTCALL M68KWrite16(unsigned int a, unsigned int d);
void FASTCALL M68KWrite32(unsigned int a, unsigned int d);
-
-#ifdef __cplusplus
- }
-#endif
+} // extern "C"
-#endif // INCLUDED_M68K_H
\ No newline at end of file
+#endif // INCLUDED_68K_H
\ No newline at end of file
diff --git a/Src/CPU/68K/Musashi/m68kconf.h b/Src/CPU/68K/Musashi/m68kconf.h
index cda2eac..94ab663 100644
--- a/Src/CPU/68K/Musashi/m68kconf.h
+++ b/Src/CPU/68K/Musashi/m68kconf.h
@@ -203,7 +203,20 @@
Supermodel Interface
******************************************************************************/
-#include "../M68K.h" // Supermodel's 68K interface
+// Supermodel 68K interface (these functions defined in CPU/68K.cpp)
+//#ifndef FASTCALL (this doesn't work for now (needs to be added to the prototypes in m68k.h for m68k_read_memory*)
+ #undef FASTCALL
+ #define FASTCALL
+//#endif
+unsigned int FASTCALL M68KFetch8(unsigned int a);
+unsigned int FASTCALL M68KFetch16(unsigned int a);
+unsigned int FASTCALL M68KFetch32(unsigned int a);
+unsigned int FASTCALL M68KRead8(unsigned int a);
+unsigned int FASTCALL M68KRead16(unsigned int a);
+unsigned int FASTCALL M68KRead32(unsigned int a);
+void FASTCALL M68KWrite8(unsigned int a, unsigned int d);
+void FASTCALL M68KWrite16(unsigned int a, unsigned int d);
+void FASTCALL M68KWrite32(unsigned int a, unsigned int d);
/* Read data relative to the PC */
#define m68k_read_pcrelative_8(address) M68KFetch8(address)
diff --git a/Src/Games.cpp b/Src/Games.cpp
index 4ed74e0..a2c3f7b 100644
--- a/Src/Games.cpp
+++ b/Src/Games.cpp
@@ -23,6 +23,11 @@
* Games.cpp
*
* Model 3 game and ROM information.
+ *
+ * ROMs are loaded in their native orientation. For example, PowerPC and 68K
+ * ROMs will be laid out in memory as they would appear to those processors.
+ * Any byte swapping that is done for performance-enhancing reasons by the
+ * emulator is handled elsewhere.
*/
#include "Supermodel.h"
@@ -42,61 +47,70 @@ const struct GameInfo Model3GameList[] =
0x4000000, // 64 MB of VROM
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_JOYSTICK1|GAME_INPUT_FIGHTING,
+ 0, // no MPEG board
{
// Fixed CROM
- { "CROM", "epr21214c.17", 0x8DC0A85C, 0x200000, 2, 0x0000006, 8, TRUE },
- { "CROM", "epr21215c.18", 0xE2878221, 0x200000, 2, 0x0000004, 8, TRUE },
- { "CROM", "epr21216c.19", 0x867D3A0F, 0x200000, 2, 0x0000002, 8, TRUE },
- { "CROM", "epr21217c.20", 0xEA8C30CE, 0x200000, 2, 0x0000000, 8, TRUE },
-
- // Banked CROM0
- { "CROMxx", "mpr21134.1", 0x65399935, 0x800000, 2, 0x0000006, 8, TRUE },
- { "CROMxx", "mpr21135.2", 0xF3FA7C50, 0x800000, 2, 0x0000004, 8, TRUE },
- { "CROMxx", "mpr21136.3", 0xB730FE50, 0x800000, 2, 0x0000002, 8, TRUE },
- { "CROMxx", "mpr21137.4", 0x3572D417, 0x800000, 2, 0x0000000, 8, TRUE },
-
- // Banked CROM1
- { "CROMxx", "mpr21138.5", 0xA9A2DE2C, 0x800000, 2, 0x2000006, 8, TRUE },
- { "CROMxx", "mpr21139.6", 0x06D441F5, 0x800000, 2, 0x2000004, 8, TRUE },
- { "CROMxx", "mpr21140.7", 0x1390746D, 0x800000, 2, 0x2000002, 8, TRUE },
- { "CROMxx", "mpr21141.8", 0x1D0763CB, 0x800000, 2, 0x2000000, 8, TRUE },
-
- // Banked CROM1
- { "CROMxx", "mpr21142.9", 0xDA35CD51, 0x400000, 2, 0x4000006, 8, TRUE },
- { "CROMxx", "mpr21143.10", 0xDDCADA10, 0x400000, 2, 0x4000004, 8, TRUE },
- { "CROMxx", "mpr21144.11", 0xD93D778C, 0x400000, 2, 0x4000002, 8, TRUE },
- { "CROMxx", "mpr21145.12", 0x0E6A3AE3, 0x400000, 2, 0x4000000, 8, TRUE },
-
- // Banked CROM2 (note: appears at offset 0x6000000 rather than 0x5000000 as expected)
- { "CROMxx", "mpr21146.13", 0x85F55311, 0x400000, 2, 0x6000006, 8, TRUE },
- { "CROMxx", "mpr21147.14", 0xA1F2B73F, 0x400000, 2, 0x6000004, 8, TRUE },
- { "CROMxx", "mpr21148.15", 0x56D980AD, 0x400000, 2, 0x6000002, 8, TRUE },
- { "CROMxx", "mpr21149.16", 0x9E4EBE58, 0x400000, 2, 0x6000000, 8, TRUE },
+ { "CROM", "epr21217c.20", 0xEA8C30CE, 0x200000, 2, 0x0000000, 8, TRUE },
+ { "CROM", "epr21216c.19", 0x867D3A0F, 0x200000, 2, 0x0000002, 8, TRUE },
+ { "CROM", "epr21215c.18", 0xE2878221, 0x200000, 2, 0x0000004, 8, TRUE },
+ { "CROM", "epr21214c.17", 0x8DC0A85C, 0x200000, 2, 0x0000006, 8, TRUE },
// Banked CROM0
- //{ "CROMxx", "mpr21150.22", 0x125201CE, 0x400000, 2, 0x0000004, 8, TRUE },
- //{ "CROMxx", "mpr21151.23", 0x599527B9, 0x400000, 2, 0x0000002, 8, TRUE },
- //{ "CROMxx", "mpr21152.24", 0x0AFDEE87, 0x400000, 2, 0x0000000, 8, TRUE },
- //{ "CROMxx", "mpr21153.25", 0x4155F307, 0x400000, 2, 0x0000006, 8, TRUE },
+ { "CROMxx", "mpr21137.4", 0x3572D417, 0x800000, 2, 0x0000000, 8, TRUE },
+ { "CROMxx", "mpr21136.3", 0xB730FE50, 0x800000, 2, 0x0000002, 8, TRUE },
+ { "CROMxx", "mpr21135.2", 0xF3FA7C50, 0x800000, 2, 0x0000004, 8, TRUE },
+ { "CROMxx", "mpr21134.1", 0x65399935, 0x800000, 2, 0x0000006, 8, TRUE },
+
+ // Banked CROM1
+ { "CROMxx", "mpr21141.8", 0x1D0763CB, 0x800000, 2, 0x2000000, 8, TRUE },
+ { "CROMxx", "mpr21140.7", 0x1390746D, 0x800000, 2, 0x2000002, 8, TRUE },
+ { "CROMxx", "mpr21139.6", 0x06D441F5, 0x800000, 2, 0x2000004, 8, TRUE },
+ { "CROMxx", "mpr21138.5", 0xA9A2DE2C, 0x800000, 2, 0x2000006, 8, TRUE },
+
+ // Banked CROM2
+ { "CROMxx", "mpr21145.12", 0x0E6A3AE3, 0x400000, 2, 0x4000000, 8, TRUE },
+ { "CROMxx", "mpr21144.11", 0xD93D778C, 0x400000, 2, 0x4000002, 8, TRUE },
+ { "CROMxx", "mpr21143.10", 0xDDCADA10, 0x400000, 2, 0x4000004, 8, TRUE },
+ { "CROMxx", "mpr21142.9", 0xDA35CD51, 0x400000, 2, 0x4000006, 8, TRUE },
+
+ // Banked CROM3 (note: appears at offset 0x6000000 rather than 0x5000000 as expected)
+ { "CROMxx", "mpr21149.16", 0x9E4EBE58, 0x400000, 2, 0x6000000, 8, TRUE },
+ { "CROMxx", "mpr21148.15", 0x56D980AD, 0x400000, 2, 0x6000002, 8, TRUE },
+ { "CROMxx", "mpr21147.14", 0xA1F2B73F, 0x400000, 2, 0x6000004, 8, TRUE },
+ { "CROMxx", "mpr21146.13", 0x85F55311, 0x400000, 2, 0x6000006, 8, TRUE },
// Video ROM
- { "VROM", "mpr21154.26", 0x3B76F8E8, 0x400000, 2, 0, 32, FALSE },
- { "VROM", "mpr21155.27", 0xACA19901, 0x400000, 2, 2, 32, FALSE },
- { "VROM", "mpr21156.28", 0x5C9DF226, 0x400000, 2, 4, 32, FALSE },
- { "VROM", "mpr21157.29", 0xF6FB1279, 0x400000, 2, 6, 32, FALSE },
- { "VROM", "mpr21158.30", 0x61707554, 0x400000, 2, 8, 32, FALSE },
- { "VROM", "mpr21159.31", 0xFCC791F5, 0x400000, 2, 10, 32, FALSE },
- { "VROM", "mpr21160.32", 0xB40A38D3, 0x400000, 2, 12, 32, FALSE },
- { "VROM", "mpr21161.33", 0x559063F0, 0x400000, 2, 14, 32, FALSE },
- { "VROM", "mpr21162.34", 0xACC4B2E4, 0x400000, 2, 16, 32, FALSE },
- { "VROM", "mpr21163.35", 0x653C54C7, 0x400000, 2, 18, 32, FALSE },
- { "VROM", "mpr21164.36", 0x902FD1E0, 0x400000, 2, 20, 32, FALSE },
- { "VROM", "mpr21165.37", 0x50B3BE05, 0x400000, 2, 22, 32, FALSE },
- { "VROM", "mpr21166.38", 0x8F87A782, 0x400000, 2, 24, 32, FALSE },
- { "VROM", "mpr21167.39", 0x0F3994D0, 0x400000, 2, 26, 32, FALSE },
- { "VROM", "mpr21168.40", 0xC58BE980, 0x400000, 2, 28, 32, FALSE },
- { "VROM", "mpr21169.41", 0xAA3B2CC0, 0x400000, 2, 30, 32, FALSE },
+ { "VROM", "mpr21154.26", 0x3B76F8E8, 0x400000, 2, 0, 32, FALSE },
+ { "VROM", "mpr21155.27", 0xACA19901, 0x400000, 2, 2, 32, FALSE },
+ { "VROM", "mpr21156.28", 0x5C9DF226, 0x400000, 2, 4, 32, FALSE },
+ { "VROM", "mpr21157.29", 0xF6FB1279, 0x400000, 2, 6, 32, FALSE },
+ { "VROM", "mpr21158.30", 0x61707554, 0x400000, 2, 8, 32, FALSE },
+ { "VROM", "mpr21159.31", 0xFCC791F5, 0x400000, 2, 10, 32, FALSE },
+ { "VROM", "mpr21160.32", 0xB40A38D3, 0x400000, 2, 12, 32, FALSE },
+ { "VROM", "mpr21161.33", 0x559063F0, 0x400000, 2, 14, 32, FALSE },
+ { "VROM", "mpr21162.34", 0xACC4B2E4, 0x400000, 2, 16, 32, FALSE },
+ { "VROM", "mpr21163.35", 0x653C54C7, 0x400000, 2, 18, 32, FALSE },
+ { "VROM", "mpr21164.36", 0x902FD1E0, 0x400000, 2, 20, 32, FALSE },
+ { "VROM", "mpr21165.37", 0x50B3BE05, 0x400000, 2, 22, 32, FALSE },
+ { "VROM", "mpr21166.38", 0x8F87A782, 0x400000, 2, 24, 32, FALSE },
+ { "VROM", "mpr21167.39", 0x0F3994D0, 0x400000, 2, 26, 32, FALSE },
+ { "VROM", "mpr21168.40", 0xC58BE980, 0x400000, 2, 28, 32, FALSE },
+ { "VROM", "mpr21169.41", 0xAA3B2CC0, 0x400000, 2, 30, 32, FALSE },
+
+ // Sound ROMs
+ { "SndProg","epr21218.21", 0x5821001A, 0x80000, 2, 0x000000, 2, TRUE },
+ { "Samples","mpr21150.22", 0x125201CE, 0x400000, 2, 0x000000, 2, FALSE },
+ { "Samples","mpr21152.24", 0x0AFDEE87, 0x400000, 2, 0x400000, 2, FALSE },
+ { "Samples","mpr21151.23", 0x599527B9, 0x400000, 2, 0x800000, 2, FALSE },
+ { "Samples","mpr21153.25", 0x4155F307, 0x400000, 2, 0xC00000, 2, FALSE },
+
+ // Unused ROMs
+ //{ "Prog", "epr21219.ic2", 0x4E042B21, 0x20000, 2, 0x??????, 2, TRUE },
+ //{ "ROM", "mpr21170.ic18", 0xF51F7CE3, 0x400000, 2, 0x??????, 2, FALSE },
+ //{ "ROM", "mpr21171.ic20", 0x8D3BD5B6, 0x400000, 2, 0x??????, 2, FALSE },
+ //{ "ROM", "mpr21172.ic22", 0xBE221E27, 0x400000, 2, 0x??????, 2, FALSE },
+ //{ "ROM", "mpr21173.ic24", 0xCA7226D6, 0x400000, 2, 0x??????, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -114,60 +128,61 @@ const struct GameInfo Model3GameList[] =
0x4000000, // 64 MB of VROM
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_VEHICLE,
+ 0, // no MPEG board
{
// Fixed CROM
- { "CROM", "epr20352.17", 0xC92C2545, 0x200000, 2, 0x0400006, 8, TRUE },
- { "CROM", "epr20354.18", 0xACA62BF8, 0x200000, 2, 0x0400004, 8, TRUE },
- { "CROM", "epr20353.19", 0xBADF5F04, 0x200000, 2, 0x0400002, 8, TRUE },
- { "CROM", "epr20355.20", 0x7A784E67, 0x200000, 2, 0x0400000, 8, TRUE },
-
+ { "CROM", "epr20355.20", 0x7A784E67, 0x200000, 2, 0x0400000, 8, TRUE },
+ { "CROM", "epr20353.19", 0xBADF5F04, 0x200000, 2, 0x0400002, 8, TRUE },
+ { "CROM", "epr20354.18", 0xACA62BF8, 0x200000, 2, 0x0400004, 8, TRUE },
+ { "CROM", "epr20352.17", 0xC92C2545, 0x200000, 2, 0x0400006, 8, TRUE },
+
// Banked CROM0
- { "CROMxx", "mpr20318.1", 0xB0CAD2C8, 0x400000, 2, 0x0000006, 8, TRUE },
- { "CROMxx", "mpr20319.2", 0x228047F3, 0x400000, 2, 0x0000004, 8, TRUE },
- { "CROMxx", "mpr20320.3", 0xEDC9A9E5, 0x400000, 2, 0x0000002, 8, TRUE },
- { "CROMxx", "mpr20321.4", 0x698A97EE, 0x400000, 2, 0x0000000, 8, TRUE },
-
+ { "CROMxx", "mpr20321.4", 0x698A97EE, 0x400000, 2, 0x0000000, 8, TRUE },
+ { "CROMxx", "mpr20320.3", 0xEDC9A9E5, 0x400000, 2, 0x0000002, 8, TRUE },
+ { "CROMxx", "mpr20319.2", 0x228047F3, 0x400000, 2, 0x0000004, 8, TRUE },
+ { "CROMxx", "mpr20318.1", 0xB0CAD2C8, 0x400000, 2, 0x0000006, 8, TRUE },
+
// Banked CROM1
- { "CROMxx", "mpr20322.5", 0x2F69B205, 0x400000, 2, 0x1000006, 8, TRUE },
- { "CROMxx", "mpr20323.6", 0x075DE2AE, 0x400000, 2, 0x1000004, 8, TRUE },
- { "CROMxx", "mpr20324.7", 0x8F5848D0, 0x400000, 2, 0x1000002, 8, TRUE },
- { "CROMxx", "mpr20325.8", 0xCB0EB133, 0x400000, 2, 0x1000000, 8, TRUE },
+ { "CROMxx", "mpr20325.8", 0xCB0EB133, 0x400000, 2, 0x1000000, 8, TRUE },
+ { "CROMxx", "mpr20324.7", 0x8F5848D0, 0x400000, 2, 0x1000002, 8, TRUE },
+ { "CROMxx", "mpr20323.6", 0x075DE2AE, 0x400000, 2, 0x1000004, 8, TRUE },
+ { "CROMxx", "mpr20322.5", 0x2F69B205, 0x400000, 2, 0x1000006, 8, TRUE },
// Banked CROM2
- { "CROMxx", "mpr20326.9", 0xB63E1CB4, 0x400000, 2, 0x2000006, 8, TRUE },
- { "CROMxx", "mpr20327.10", 0xF55F51B2, 0x400000, 2, 0x2000004, 8, TRUE },
- { "CROMxx", "mpr20328.11", 0x5FA5E9F5, 0x400000, 2, 0x2000002, 8, TRUE },
- { "CROMxx", "mpr20329.12", 0x0807EA33, 0x400000, 2, 0x2000000, 8, TRUE },
+ { "CROMxx", "mpr20329.12", 0x0807EA33, 0x400000, 2, 0x2000000, 8, TRUE },
+ { "CROMxx", "mpr20328.11", 0x5FA5E9F5, 0x400000, 2, 0x2000002, 8, TRUE },
+ { "CROMxx", "mpr20327.10", 0xF55F51B2, 0x400000, 2, 0x2000004, 8, TRUE },
+ { "CROMxx", "mpr20326.9", 0xB63E1CB4, 0x400000, 2, 0x2000006, 8, TRUE },
// Banked CROM3
- { "CROMxx", "mpr20330.13", 0xFBC7BBD5, 0x400000, 2, 0x3000006, 8, TRUE },
- { "CROMxx", "mpr20331.14", 0xC4C45FB1, 0x400000, 2, 0x3000004, 8, TRUE },
- { "CROMxx", "mpr20332.15", 0x500DB1EE, 0x400000, 2, 0x3000002, 8, TRUE },
- { "CROMxx", "mpr20333.16", 0x76B8E0FA, 0x400000, 2, 0x3000000, 8, TRUE },
-
- // Banked CROM4
- //{ "CROMxx", "epr20356.21", 0x4E4015D0, 0x80000, 2, 0x3000004, 8, TRUE },
- //{ "CROMxx", "mpr20334.22", 0xDE1D67CD, 0x400000, 2, 0x3000002, 8, TRUE },
- //{ "CROMxx", "mpr20335.24", 0x7300D0A2, 0x400000, 2, 0x3000000, 8, TRUE },
+ { "CROMxx", "mpr20333.16", 0x76B8E0FA, 0x400000, 2, 0x3000000, 8, TRUE },
+ { "CROMxx", "mpr20332.15", 0x500DB1EE, 0x400000, 2, 0x3000002, 8, TRUE },
+ { "CROMxx", "mpr20331.14", 0xC4C45FB1, 0x400000, 2, 0x3000004, 8, TRUE },
+ { "CROMxx", "mpr20330.13", 0xFBC7BBD5, 0x400000, 2, 0x3000006, 8, TRUE },
// Video ROM
- { "VROM", "mpr20336.26", 0x261E3D39, 0x400000, 2, 0, 32, FALSE },
- { "VROM", "mpr20337.27", 0x2C7E9EB8, 0x400000, 2, 2, 32, FALSE },
- { "VROM", "mpr20338.28", 0x0AA626DF, 0x400000, 2, 4, 32, FALSE },
- { "VROM", "mpr20339.29", 0x7AF05417, 0x400000, 2, 6, 32, FALSE },
- { "VROM", "mpr20340.30", 0x82EF4A21, 0x400000, 2, 8, 32, FALSE },
- { "VROM", "mpr20341.31", 0x9373096E, 0x400000, 2, 10, 32, FALSE },
- { "VROM", "mpr20342.32", 0xEF98CD37, 0x400000, 2, 12, 32, FALSE },
- { "VROM", "mpr20343.33", 0x9825A46B, 0x400000, 2, 14, 32, FALSE },
- { "VROM", "mpr20344.34", 0xACBBCD68, 0x400000, 2, 16, 32, FALSE },
- { "VROM", "mpr20345.35", 0x431E7585, 0x400000, 2, 18, 32, FALSE },
- { "VROM", "mpr20346.36", 0x4F87F2D2, 0x400000, 2, 20, 32, FALSE },
- { "VROM", "mpr20347.37", 0x389A2D98, 0x400000, 2, 22, 32, FALSE },
- { "VROM", "mpr20348.38", 0x8BE8D4D2, 0x400000, 2, 24, 32, FALSE },
- { "VROM", "mpr20349.39", 0xA3240428, 0x400000, 2, 26, 32, FALSE },
- { "VROM", "mpr20350.40", 0xC48F9ACE, 0x400000, 2, 28, 32, FALSE },
- { "VROM", "mpr20351.41", 0x1FBD3E10, 0x400000, 2, 30, 32, FALSE },
+ { "VROM", "mpr20336.26", 0x261E3D39, 0x400000, 2, 0, 32, FALSE },
+ { "VROM", "mpr20337.27", 0x2C7E9EB8, 0x400000, 2, 2, 32, FALSE },
+ { "VROM", "mpr20338.28", 0x0AA626DF, 0x400000, 2, 4, 32, FALSE },
+ { "VROM", "mpr20339.29", 0x7AF05417, 0x400000, 2, 6, 32, FALSE },
+ { "VROM", "mpr20340.30", 0x82EF4A21, 0x400000, 2, 8, 32, FALSE },
+ { "VROM", "mpr20341.31", 0x9373096E, 0x400000, 2, 10, 32, FALSE },
+ { "VROM", "mpr20342.32", 0xEF98CD37, 0x400000, 2, 12, 32, FALSE },
+ { "VROM", "mpr20343.33", 0x9825A46B, 0x400000, 2, 14, 32, FALSE },
+ { "VROM", "mpr20344.34", 0xACBBCD68, 0x400000, 2, 16, 32, FALSE },
+ { "VROM", "mpr20345.35", 0x431E7585, 0x400000, 2, 18, 32, FALSE },
+ { "VROM", "mpr20346.36", 0x4F87F2D2, 0x400000, 2, 20, 32, FALSE },
+ { "VROM", "mpr20347.37", 0x389A2D98, 0x400000, 2, 22, 32, FALSE },
+ { "VROM", "mpr20348.38", 0x8BE8D4D2, 0x400000, 2, 24, 32, FALSE },
+ { "VROM", "mpr20349.39", 0xA3240428, 0x400000, 2, 26, 32, FALSE },
+ { "VROM", "mpr20350.40", 0xC48F9ACE, 0x400000, 2, 28, 32, FALSE },
+ { "VROM", "mpr20351.41", 0x1FBD3E10, 0x400000, 2, 30, 32, FALSE },
+
+ // Sound ROMs
+ { "SndProg","epr20356.21", 0x4E4015D0, 0x80000, 2, 0x000000, 2, TRUE },
+ { "Samples","mpr20334.22", 0xDE1D67CD, 0x400000, 2, 0x000000, 2, FALSE },
+ { "Samples","mpr20335.24", 0x7300D0A2, 0x400000, 2, 0x400000, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -185,43 +200,45 @@ const struct GameInfo Model3GameList[] =
0x4000000, // 64 MB of VROM
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_VEHICLE,
+ 0, // no MPEG board
{
// Fixed CROM
- { "CROM", "epr21435.17", 0x9B169446, 0x200000, 2, 0x0000006, 8, TRUE },
- { "CROM", "epr21433.18", 0x60AA9D76, 0x200000, 2, 0x0000004, 8, TRUE },
- { "CROM", "epr21436.19", 0x22BCBCA3, 0x200000, 2, 0x0000002, 8, TRUE },
- { "CROM", "epr21434.20", 0xE028D7CA, 0x200000, 2, 0x0000000, 8, TRUE },
-
- // Banked CROM0
- { "CROMxx", "mpr21423.1", 0x4EE0060A, 0x400000, 2, 0x0000006, 8, TRUE },
- { "CROMxx", "mpr21424.2", 0x25358FDF, 0x400000, 2, 0x0000004, 8, TRUE },
- { "CROMxx", "mpr21425.3", 0xAD235849, 0x400000, 2, 0x0000002, 8, TRUE },
- { "CROMxx", "mpr21426.4", 0xCE77E26E, 0x400000, 2, 0x0000000, 8, TRUE },
+ { "CROM", "epr21434.20", 0xE028D7CA, 0x200000, 2, 0x0000000, 8, TRUE },
+ { "CROM", "epr21436.19", 0x22BCBCA3, 0x200000, 2, 0x0000002, 8, TRUE },
+ { "CROM", "epr21433.18", 0x60AA9D76, 0x200000, 2, 0x0000004, 8, TRUE },
+ { "CROM", "epr21435.17", 0x9B169446, 0x200000, 2, 0x0000006, 8, TRUE },
- // Banked CROM3
- { "CROMxx", "epr21438.21", 0x6815AF9E, 0x80000, 2, 0x1000006, 8, TRUE },
- { "CROMxx", "mpr21427.22", 0x884566F6, 0x400000, 2, 0x1000004, 8, TRUE },
- { "CROMxx", "mpr21431.23", 0x0EF8F7BB, 0x400000, 2, 0x1000002, 8, TRUE },
- { "CROMxx", "mpr21428.24", 0x162D1E43, 0x400000, 2, 0x1000000, 8, TRUE },
+ // Banked CROM0
+ { "CROMxx", "mpr21426.4", 0xCE77E26E, 0x400000, 2, 0x0000000, 8, TRUE },
+ { "CROMxx", "mpr21425.3", 0xAD235849, 0x400000, 2, 0x0000002, 8, TRUE },
+ { "CROMxx", "mpr21424.2", 0x25358FDF, 0x400000, 2, 0x0000004, 8, TRUE },
+ { "CROMxx", "mpr21423.1", 0x4EE0060A, 0x400000, 2, 0x0000006, 8, TRUE },
// Video ROM
- { "VROM", "mpr21407.26", 0x3FFB416C, 0x400000, 2, 0, 32, FALSE },
- { "VROM", "mpr21408.27", 0x3E00A7EF, 0x400000, 2, 2, 32, FALSE },
- { "VROM", "mpr21409.28", 0xA4673BBF, 0x400000, 2, 4, 32, FALSE },
- { "VROM", "mpr21410.29", 0xC9F43B4A, 0x400000, 2, 6, 32, FALSE },
- { "VROM", "mpr21411.30", 0xF14957C7, 0x400000, 2, 8, 32, FALSE },
- { "VROM", "mpr21412.31", 0xEC24091F, 0x400000, 2, 10, 32, FALSE },
- { "VROM", "mpr21413.32", 0xEA9049E0, 0x400000, 2, 12, 32, FALSE },
- { "VROM", "mpr21414.33", 0x79BC5FFD, 0x400000, 2, 14, 32, FALSE },
- { "VROM", "mpr21415.34", 0xF96FE7A2, 0x400000, 2, 16, 32, FALSE },
- { "VROM", "mpr21416.35", 0x84A08B3E, 0x400000, 2, 18, 32, FALSE },
- { "VROM", "mpr21417.36", 0x6094975C, 0x400000, 2, 20, 32, FALSE },
- { "VROM", "mpr21418.37", 0x7BB868BA, 0x400000, 2, 22, 32, FALSE },
- { "VROM", "mpr21419.38", 0xBE7325C2, 0x400000, 2, 24, 32, FALSE },
- { "VROM", "mpr21420.39", 0x8B577E7B, 0x400000, 2, 26, 32, FALSE },
- { "VROM", "mpr21421.40", 0x71E4E9FC, 0x400000, 2, 28, 32, FALSE },
- { "VROM", "mpr21422.41", 0xFECA77A5, 0x400000, 2, 30, 32, FALSE },
+ { "VROM", "mpr21407.26", 0x3FFB416C, 0x400000, 2, 0, 32, FALSE },
+ { "VROM", "mpr21408.27", 0x3E00A7EF, 0x400000, 2, 2, 32, FALSE },
+ { "VROM", "mpr21409.28", 0xA4673BBF, 0x400000, 2, 4, 32, FALSE },
+ { "VROM", "mpr21410.29", 0xC9F43B4A, 0x400000, 2, 6, 32, FALSE },
+ { "VROM", "mpr21411.30", 0xF14957C7, 0x400000, 2, 8, 32, FALSE },
+ { "VROM", "mpr21412.31", 0xEC24091F, 0x400000, 2, 10, 32, FALSE },
+ { "VROM", "mpr21413.32", 0xEA9049E0, 0x400000, 2, 12, 32, FALSE },
+ { "VROM", "mpr21414.33", 0x79BC5FFD, 0x400000, 2, 14, 32, FALSE },
+ { "VROM", "mpr21415.34", 0xF96FE7A2, 0x400000, 2, 16, 32, FALSE },
+ { "VROM", "mpr21416.35", 0x84A08B3E, 0x400000, 2, 18, 32, FALSE },
+ { "VROM", "mpr21417.36", 0x6094975C, 0x400000, 2, 20, 32, FALSE },
+ { "VROM", "mpr21418.37", 0x7BB868BA, 0x400000, 2, 22, 32, FALSE },
+ { "VROM", "mpr21419.38", 0xBE7325C2, 0x400000, 2, 24, 32, FALSE },
+ { "VROM", "mpr21420.39", 0x8B577E7B, 0x400000, 2, 26, 32, FALSE },
+ { "VROM", "mpr21421.40", 0x71E4E9FC, 0x400000, 2, 28, 32, FALSE },
+ { "VROM", "mpr21422.41", 0xFECA77A5, 0x400000, 2, 30, 32, FALSE },
+
+ // Sound ROMs
+ { "SndProg","epr21438.21", 0x6815AF9E, 0x80000, 2, 0x000000, 2, TRUE },
+ { "Samples","mpr21427.22", 0x884566F6, 0x400000, 2, 0x000000, 2, FALSE },
+ { "Samples","mpr21428.24", 0x162D1E43, 0x400000, 2, 0x400000, 2, FALSE },
+ { "Samples","mpr21431.23", 0x0EF8F7BB, 0x400000, 2, 0x800000, 2, FALSE },
+ { "Samples","mpr21432.25", 0x59C0F6DF, 0x400000, 2, 0xC00000, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -239,54 +256,55 @@ const struct GameInfo Model3GameList[] =
0x2000000, // 32 MB of VROM
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_JOYSTICK1,
+ 0, // no MPEG board
{
// Fixed CROM
- { "CROM", "epr-20643.17", 0xDAF02716, 0x80000, 2, 0x0600006, 8, TRUE },
- { "CROM", "epr-20644.18", 0xC28DB2B6, 0x80000, 2, 0x0600004, 8, TRUE },
- { "CROM", "epr-20645.19", 0x8EEFA2B0, 0x80000, 2, 0x0600002, 8, TRUE },
- { "CROM", "epr-20646.20", 0xD740AE06, 0x80000, 2, 0x0600000, 8, TRUE },
-
- // Banked CROM0
- { "CROMxx", "mpr-20256.1", 0x115302AC, 0x400000, 2, 0x0000006, 8, TRUE },
- { "CROMxx", "mpr-20257.2", 0x025BC06D, 0x400000, 2, 0x0000004, 8, TRUE },
- { "CROMxx", "mpr-20258.3", 0x7B78B071, 0x400000, 2, 0x0000002, 8, TRUE },
- { "CROMxx", "mpr-20259.4", 0x40052562, 0x400000, 2, 0x0000000, 8, TRUE },
-
- // Banked CROM1
- { "CROMxx", "mpr-20260.5", 0xC56B4C10, 0x400000, 2, 0x1000006, 8, TRUE },
- { "CROMxx", "mpr-20261.6", 0xB1E9D44A, 0x400000, 2, 0x1000004, 8, TRUE },
- { "CROMxx", "mpr-20262.7", 0x52B0674D, 0x400000, 2, 0x1000002, 8, TRUE },
- { "CROMxx", "mpr-20263.8", 0x1CF4CBA9, 0x400000, 2, 0x1000000, 8, TRUE },
-
- // Banked CROM2
- { "CROMxx", "mpr-20264.9", 0x8D995196, 0x400000, 2, 0x2000006, 8, TRUE },
- { "CROMxx", "mpr-20265.10", 0x28F76E3E, 0x400000, 2, 0x2000004, 8, TRUE },
- { "CROMxx", "mpr-20266.11", 0xABD2DB85, 0x400000, 2, 0x2000002, 8, TRUE },
- { "CROMxx", "mpr-20267.12", 0x48989191, 0x400000, 2, 0x2000000, 8, TRUE },
+ { "CROM", "epr-20646.20", 0xD740AE06, 0x80000, 2, 0x0600000, 8, TRUE },
+ { "CROM", "epr-20645.19", 0x8EEFA2B0, 0x80000, 2, 0x0600002, 8, TRUE },
+ { "CROM", "epr-20644.18", 0xC28DB2B6, 0x80000, 2, 0x0600004, 8, TRUE },
+ { "CROM", "epr-20643.17", 0xDAF02716, 0x80000, 2, 0x0600006, 8, TRUE },
- // Banked CROM3
- { "CROMxx", "epr-20313.21", 0x863A7857, 0x80000, 2, 0x3000004, 8, TRUE },
- { "CROMxx", "mpr-20268.22", 0x3631E93E, 0x400000, 2, 0x3000002, 8, TRUE },
- { "CROMxx", "mpr-20269.24", 0x105A3181, 0x400000, 2, 0x3000000, 8, TRUE },
+ // Banked CROM0
+ { "CROMxx", "mpr-20259.4", 0x40052562, 0x400000, 2, 0x0000000, 8, TRUE },
+ { "CROMxx", "mpr-20258.3", 0x7B78B071, 0x400000, 2, 0x0000002, 8, TRUE },
+ { "CROMxx", "mpr-20257.2", 0x025BC06D, 0x400000, 2, 0x0000004, 8, TRUE },
+ { "CROMxx", "mpr-20256.1", 0x115302AC, 0x400000, 2, 0x0000006, 8, TRUE },
+
+ // Banked CROM1
+ { "CROMxx", "mpr-20263.8", 0x1CF4CBA9, 0x400000, 2, 0x1000000, 8, TRUE },
+ { "CROMxx", "mpr-20262.7", 0x52B0674D, 0x400000, 2, 0x1000002, 8, TRUE },
+ { "CROMxx", "mpr-20261.6", 0xB1E9D44A, 0x400000, 2, 0x1000004, 8, TRUE },
+ { "CROMxx", "mpr-20260.5", 0xC56B4C10, 0x400000, 2, 0x1000006, 8, TRUE },
+
+ // Banked CROM2
+ { "CROMxx", "mpr-20267.12", 0x48989191, 0x400000, 2, 0x2000000, 8, TRUE },
+ { "CROMxx", "mpr-20266.11", 0xABD2DB85, 0x400000, 2, 0x2000002, 8, TRUE },
+ { "CROMxx", "mpr-20265.10", 0x28F76E3E, 0x400000, 2, 0x2000004, 8, TRUE },
+ { "CROMxx", "mpr-20264.9", 0x8D995196, 0x400000, 2, 0x2000006, 8, TRUE },
// Video ROM
- { "VROM", "mpr-20270.26", 0xDF68A7A7, 0x200000, 2, 0, 32, FALSE },
- { "VROM", "mpr-20271.27", 0x4B01C3A4, 0x200000, 2, 2, 32, FALSE },
- { "VROM", "mpr-20272.28", 0xA658DA23, 0x200000, 2, 4, 32, FALSE },
- { "VROM", "mpr-20273.29", 0x577E9FFA, 0x200000, 2, 6, 32, FALSE },
- { "VROM", "mpr-20274.30", 0x7C7056AE, 0x200000, 2, 8, 32, FALSE },
- { "VROM", "mpr-20275.31", 0xE739F77A, 0x200000, 2, 10, 32, FALSE },
- { "VROM", "mpr-20276.32", 0xCBF966C0, 0x200000, 2, 12, 32, FALSE },
- { "VROM", "mpr-20277.33", 0x9C75200B, 0x200000, 2, 14, 32, FALSE },
- { "VROM", "mpr-20278.34", 0xDB3991BA, 0x200000, 2, 16, 32, FALSE },
- { "VROM", "mpr-20279.35", 0x995A11B8, 0x200000, 2, 18, 32, FALSE },
- { "VROM", "mpr-20280.36", 0xC2C8F9F5, 0x200000, 2, 20, 32, FALSE },
- { "VROM", "mpr-20281.37", 0xDA84B967, 0x200000, 2, 22, 32, FALSE },
- { "VROM", "mpr-20282.38", 0x1869FF49, 0x200000, 2, 24, 32, FALSE },
- { "VROM", "mpr-20283.39", 0x7D8FB469, 0x200000, 2, 26, 32, FALSE },
- { "VROM", "mpr-20284.40", 0x5C7F3A6F, 0x200000, 2, 28, 32, FALSE },
- { "VROM", "mpr-20285.41", 0x4AADC573, 0x200000, 2, 30, 32, FALSE },
+ { "VROM", "mpr-20270.26", 0xDF68A7A7, 0x200000, 2, 0, 32, FALSE },
+ { "VROM", "mpr-20271.27", 0x4B01C3A4, 0x200000, 2, 2, 32, FALSE },
+ { "VROM", "mpr-20272.28", 0xA658DA23, 0x200000, 2, 4, 32, FALSE },
+ { "VROM", "mpr-20273.29", 0x577E9FFA, 0x200000, 2, 6, 32, FALSE },
+ { "VROM", "mpr-20274.30", 0x7C7056AE, 0x200000, 2, 8, 32, FALSE },
+ { "VROM", "mpr-20275.31", 0xE739F77A, 0x200000, 2, 10, 32, FALSE },
+ { "VROM", "mpr-20276.32", 0xCBF966C0, 0x200000, 2, 12, 32, FALSE },
+ { "VROM", "mpr-20277.33", 0x9C75200B, 0x200000, 2, 14, 32, FALSE },
+ { "VROM", "mpr-20278.34", 0xDB3991BA, 0x200000, 2, 16, 32, FALSE },
+ { "VROM", "mpr-20279.35", 0x995A11B8, 0x200000, 2, 18, 32, FALSE },
+ { "VROM", "mpr-20280.36", 0xC2C8F9F5, 0x200000, 2, 20, 32, FALSE },
+ { "VROM", "mpr-20281.37", 0xDA84B967, 0x200000, 2, 22, 32, FALSE },
+ { "VROM", "mpr-20282.38", 0x1869FF49, 0x200000, 2, 24, 32, FALSE },
+ { "VROM", "mpr-20283.39", 0x7D8FB469, 0x200000, 2, 26, 32, FALSE },
+ { "VROM", "mpr-20284.40", 0x5C7F3A6F, 0x200000, 2, 28, 32, FALSE },
+ { "VROM", "mpr-20285.41", 0x4AADC573, 0x200000, 2, 30, 32, FALSE },
+
+ // Sound ROMs
+ { "SndProg","epr-20313.21", 0x863A7857, 0x80000, 2, 0x000000, 2, TRUE },
+ { "Samples","mpr-20268.22", 0x3631E93E, 0x400000, 2, 0x000000, 2, FALSE },
+ { "Samples","mpr-20269.24", 0x105A3181, 0x400000, 2, 0x400000, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -304,49 +322,50 @@ const struct GameInfo Model3GameList[] =
0x4000000, // 64 MB of VROM
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_VEHICLE,
+ 0, // no MPEG board
{
// Fixed CROM
- { "CROM", "epr-21062a.17", 0x64B55254, 0x200000, 2, 0x0000006, 8, TRUE },
- { "CROM", "epr-21063a.18", 0x6AB7EB32, 0x200000, 2, 0x0000004, 8, TRUE },
- { "CROM", "epr-21064a.19", 0x2A01F9AD, 0x200000, 2, 0x0000002, 8, TRUE },
- { "CROM", "epr-21065a.20", 0x3223DB1A, 0x200000, 2, 0x0000000, 8, TRUE },
-
+ { "CROM", "epr-21065a.20", 0x3223DB1A, 0x200000, 2, 0x0000000, 8, TRUE },
+ { "CROM", "epr-21064a.19", 0x2A01F9AD, 0x200000, 2, 0x0000002, 8, TRUE },
+ { "CROM", "epr-21063a.18", 0x6AB7EB32, 0x200000, 2, 0x0000004, 8, TRUE },
+ { "CROM", "epr-21062a.17", 0x64B55254, 0x200000, 2, 0x0000006, 8, TRUE },
+
// Banked CROM0
- { "CROMxx", "mpr-21023.1", 0x932A3724, 0x400000, 2, 0x0000006, 8, TRUE },
- { "CROMxx", "mpr-21024.2", 0xEDE859B0, 0x400000, 2, 0x0000004, 8, TRUE },
- { "CROMxx", "mpr-21025.3", 0x6591C66E, 0x400000, 2, 0x0000002, 8, TRUE },
- { "CROMxx", "mpr-21026.4", 0xF4937E3F, 0x400000, 2, 0x0000000, 8, TRUE },
-
+ { "CROMxx", "mpr-21026.4", 0xF4937E3F, 0x400000, 2, 0x0000000, 8, TRUE },
+ { "CROMxx", "mpr-21025.3", 0x6591C66E, 0x400000, 2, 0x0000002, 8, TRUE },
+ { "CROMxx", "mpr-21024.2", 0xEDE859B0, 0x400000, 2, 0x0000004, 8, TRUE },
+ { "CROMxx", "mpr-21023.1", 0x932A3724, 0x400000, 2, 0x0000006, 8, TRUE },
+
// Banked CROM1
- { "CROMxx", "mpr-21027.5", 0x74E1496A, 0x400000, 2, 0x1000006, 8, TRUE },
- { "CROMxx", "mpr-21028.6", 0xDB11F50A, 0x400000, 2, 0x1000004, 8, TRUE },
- { "CROMxx", "mpr-21029.7", 0x89867D8A, 0x400000, 2, 0x1000002, 8, TRUE },
- { "CROMxx", "mpr-21030.8", 0xF8E51BEC, 0x400000, 2, 0x1000000, 8, TRUE },
-
- // Banked CROM3
- { "CROMxx", "epr-21066.21", 0xF7ED2582, 0x80000, 2, 0x2000006, 8, TRUE },
- { "CROMxx", "mpr-21031.22", 0x32F6B23A, 0x400000, 2, 0x2000004, 8, TRUE },
- { "CROMxx", "mpr-21032.23", 0x3D3FF407, 0x400000, 2, 0x2000002, 8, TRUE },
- { "CROMxx", "mpr-21033.24", 0x253D3C70, 0x400000, 2, 0x2000000, 8, TRUE },
+ { "CROMxx", "mpr-21030.8", 0xF8E51BEC, 0x400000, 2, 0x1000000, 8, TRUE },
+ { "CROMxx", "mpr-21029.7", 0x89867D8A, 0x400000, 2, 0x1000002, 8, TRUE },
+ { "CROMxx", "mpr-21028.6", 0xDB11F50A, 0x400000, 2, 0x1000004, 8, TRUE },
+ { "CROMxx", "mpr-21027.5", 0x74E1496A, 0x400000, 2, 0x1000006, 8, TRUE },
// Video ROM
- { "VROM", "mpr-21034.26", 0xACBA5CA6, 0x400000, 2, 0, 32, FALSE },
- { "VROM", "mpr-21035.27", 0x618B7D6A, 0x400000, 2, 2, 32, FALSE },
- { "VROM", "mpr-21036.28", 0x0E665BB2, 0x400000, 2, 4, 32, FALSE },
- { "VROM", "mpr-21037.29", 0x90B98493, 0x400000, 2, 6, 32, FALSE },
- { "VROM", "mpr-21038.30", 0x9B59D2C2, 0x400000, 2, 8, 32, FALSE },
- { "VROM", "mpr-21039.31", 0x61407B07, 0x400000, 2, 10, 32, FALSE },
- { "VROM", "mpr-21040.32", 0xB550C229, 0x400000, 2, 12, 32, FALSE },
- { "VROM", "mpr-21041.33", 0x8F1AC988, 0x400000, 2, 14, 32, FALSE },
- { "VROM", "mpr-21042.34", 0x1DAB621D, 0x400000, 2, 16, 32, FALSE },
- { "VROM", "mpr-21043.35", 0x707015C8, 0x400000, 2, 18, 32, FALSE },
- { "VROM", "mpr-21044.36", 0x776F9580, 0x400000, 2, 20, 32, FALSE },
- { "VROM", "mpr-21045.37", 0xA28AD02F, 0x400000, 2, 22, 32, FALSE },
- { "VROM", "mpr-21046.38", 0x05C995AE, 0x400000, 2, 24, 32, FALSE },
- { "VROM", "mpr-21047.39", 0x06B7826F, 0x400000, 2, 26, 32, FALSE },
- { "VROM", "mpr-21048.40", 0x96849974, 0x400000, 2, 28, 32, FALSE },
- { "VROM", "mpr-21049.41", 0x91E8161A, 0x400000, 2, 30, 32, FALSE },
+ { "VROM", "mpr-21034.26", 0xACBA5CA6, 0x400000, 2, 0, 32, FALSE },
+ { "VROM", "mpr-21035.27", 0x618B7D6A, 0x400000, 2, 2, 32, FALSE },
+ { "VROM", "mpr-21036.28", 0x0E665BB2, 0x400000, 2, 4, 32, FALSE },
+ { "VROM", "mpr-21037.29", 0x90B98493, 0x400000, 2, 6, 32, FALSE },
+ { "VROM", "mpr-21038.30", 0x9B59D2C2, 0x400000, 2, 8, 32, FALSE },
+ { "VROM", "mpr-21039.31", 0x61407B07, 0x400000, 2, 10, 32, FALSE },
+ { "VROM", "mpr-21040.32", 0xB550C229, 0x400000, 2, 12, 32, FALSE },
+ { "VROM", "mpr-21041.33", 0x8F1AC988, 0x400000, 2, 14, 32, FALSE },
+ { "VROM", "mpr-21042.34", 0x1DAB621D, 0x400000, 2, 16, 32, FALSE },
+ { "VROM", "mpr-21043.35", 0x707015C8, 0x400000, 2, 18, 32, FALSE },
+ { "VROM", "mpr-21044.36", 0x776F9580, 0x400000, 2, 20, 32, FALSE },
+ { "VROM", "mpr-21045.37", 0xA28AD02F, 0x400000, 2, 22, 32, FALSE },
+ { "VROM", "mpr-21046.38", 0x05C995AE, 0x400000, 2, 24, 32, FALSE },
+ { "VROM", "mpr-21047.39", 0x06B7826F, 0x400000, 2, 26, 32, FALSE },
+ { "VROM", "mpr-21048.40", 0x96849974, 0x400000, 2, 28, 32, FALSE },
+ { "VROM", "mpr-21049.41", 0x91E8161A, 0x400000, 2, 30, 32, FALSE },
+
+ // Sound ROMs
+ { "SndProg","epr-21066.21", 0xF7ED2582, 0x80000, 2, 0x000000, 2, TRUE },
+ { "Samples","mpr-21031.22", 0x32F6B23A, 0x400000, 2, 0x000000, 2, FALSE },
+ { "Samples","mpr-21033.24", 0x253D3C70, 0x400000, 2, 0x400000, 2, FALSE },
+ { "Samples","mpr-21032.23", 0x3D3FF407, 0x400000, 2, 0x800000, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -364,6 +383,7 @@ const struct GameInfo Model3GameList[] =
0x2000000, // 32 MB of VROM (will need to be mirrored)
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_JOYSTICK1|GAME_INPUT_JOYSTICK2|GAME_INPUT_FIGHTING,
+ 0, // no MPEG board
{
// Fixed CROM
@@ -435,6 +455,7 @@ const struct GameInfo Model3GameList[] =
0x2000000, // 32 MB of VROM (will need to be mirrored)
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_VEHICLE|GAME_INPUT_VR|GAME_INPUT_SHIFT4, // for now, Shift Up/Down mapped to Shift 3/4
+ 0, // no MPEG board
{
// Fixed CROM
@@ -500,6 +521,7 @@ const struct GameInfo Model3GameList[] =
0x2000000, // 32 MB of VROM (will need to be mirrored)
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_VEHICLE|GAME_INPUT_VR|GAME_INPUT_SHIFT4,
+ 1, // DSB1 MPEG board
{
// Fixed CROM (mirroring behavior here is special and handled manually by CModel3)
@@ -548,6 +570,11 @@ const struct GameInfo Model3GameList[] =
{ "SndProg","epr-19692.21", 0xA94F5521, 0x80000, 2, 0, 2, TRUE },
{ "Samples","mpr-19670.22", 0xBD31CC06, 0x400000, 2, 0x000000, 2, FALSE },
{ "Samples","mpr-19671.24", 0x8E8526AB, 0x400000, 2, 0x400000, 2, FALSE },
+ { "DSBProg","epr-19612.2", 0x13978FD4, 0x20000, 2, 0, 2, FALSE },
+ { "DSBMPEG","mpr-19603.57", 0xB1B1765F, 0x200000, 2, 0x000000, 2, FALSE },
+ { "DSBMPEG","mpr-19604.58", 0x6AC85B49, 0x200000, 2, 0x200000, 2, FALSE },
+ { "DSBMPEG","mpr-19605.59", 0xBEC891EB, 0x200000, 2, 0x400000, 2, FALSE },
+ { "DSBMPEG","mpr-19606.60", 0xADAD46B2, 0x200000, 2, 0x600000, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -565,6 +592,7 @@ const struct GameInfo Model3GameList[] =
0x2000000, // 32 MB of VROM (will need to be mirrored)
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_VEHICLE|GAME_INPUT_VR|GAME_INPUT_SHIFT4,
+ 1, // DSB1 MPEG board
{
// Fixed CROM (mirroring behavior here is special and handled manually by CModel3)
@@ -619,6 +647,11 @@ const struct GameInfo Model3GameList[] =
{ "SndProg","epr-20096a.21",0x0FEF288B, 0x80000, 2, 0, 2, TRUE },
{ "Samples","mpr-19670.22", 0xBD31CC06, 0x400000, 2, 0x000000, 2, FALSE },
{ "Samples","mpr-20101.24", 0x66D1E31F, 0x400000, 2, 0x400000, 2, FALSE },
+ { "DSBProg","epr-19612.2", 0x13978FD4, 0x20000, 2, 0, 2, FALSE },
+ { "DSBMPEG","mpr-19603.57", 0xB1B1765F, 0x200000, 2, 0x000000, 2, FALSE },
+ { "DSBMPEG","mpr-19604.58", 0x6AC85B49, 0x200000, 2, 0x200000, 2, FALSE },
+ { "DSBMPEG","mpr-19605.59", 0xBEC891EB, 0x200000, 2, 0x400000, 2, FALSE },
+ { "DSBMPEG","mpr-19606.60", 0xADAD46B2, 0x200000, 2, 0x600000, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -636,6 +669,7 @@ const struct GameInfo Model3GameList[] =
0x2000000, // 32 MB of VROM
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_GUN1|GAME_INPUT_GUN2,
+ 0, // no MPEG board
{
// Fixed CROM
@@ -707,55 +741,63 @@ const struct GameInfo Model3GameList[] =
0x4000000, // 64 MB of VROM
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_TWIN_JOYSTICKS,
+ 0, // no MPEG board
{
// Fixed CROM
- { "CROM", "epr-20686b.20", 0x3EA4DE9F, 0x200000, 2, 0x0000000, 8, TRUE },
- { "CROM", "epr-20685b.19", 0xAE82CB35, 0x200000, 2, 0x0000002, 8, TRUE },
- { "CROM", "epr-20684b.18", 0x1FC15431, 0x200000, 2, 0x0000004, 8, TRUE },
- { "CROM", "epr-20683b.17", 0x59D9C974, 0x200000, 2, 0x0000006, 8, TRUE },
-
+ { "CROM", "epr-20686b.20", 0x3EA4DE9F, 0x200000, 2, 0x0000000, 8, TRUE },
+ { "CROM", "epr-20685b.19", 0xAE82CB35, 0x200000, 2, 0x0000002, 8, TRUE },
+ { "CROM", "epr-20684b.18", 0x1FC15431, 0x200000, 2, 0x0000004, 8, TRUE },
+ { "CROM", "epr-20683b.17", 0x59D9C974, 0x200000, 2, 0x0000006, 8, TRUE },
+
// Banked CROM0
- { "CROMxx", "mpr-20650.4", 0x81F96649, 0x400000, 2, 0x0000000, 8, TRUE },
- { "CROMxx", "mpr-20649.3", 0xb8FD56BA, 0x400000, 2, 0x0000002, 8, TRUE },
- { "CROMxx", "mpr-20648.2", 0x107309E0, 0x400000, 2, 0x0000004, 8, TRUE },
- { "CROMxx", "mpr-20647.1", 0xe8586380, 0x400000, 2, 0x0000006, 8, TRUE },
-
+ { "CROMxx", "mpr-20650.4", 0x81F96649, 0x400000, 2, 0x0000000, 8, TRUE },
+ { "CROMxx", "mpr-20649.3", 0xb8FD56BA, 0x400000, 2, 0x0000002, 8, TRUE },
+ { "CROMxx", "mpr-20648.2", 0x107309E0, 0x400000, 2, 0x0000004, 8, TRUE },
+ { "CROMxx", "mpr-20647.1", 0xe8586380, 0x400000, 2, 0x0000006, 8, TRUE },
+
// Banked CROM1
- { "CROMxx", "mpr-20654.8", 0x763EF905, 0x400000, 2, 0x1000000, 8, TRUE },
- { "CROMxx", "mpr-20653.7", 0x858E6BBA, 0x400000, 2, 0x1000002, 8, TRUE },
- { "CROMxx", "mpr-20652.6", 0x64C6FBB6, 0x400000, 2, 0x1000004, 8, TRUE },
- { "CROMxx", "mpr-20651.5", 0x8373CAB3, 0x400000, 2, 0x1000006, 8, TRUE },
-
+ { "CROMxx", "mpr-20654.8", 0x763EF905, 0x400000, 2, 0x1000000, 8, TRUE },
+ { "CROMxx", "mpr-20653.7", 0x858E6BBA, 0x400000, 2, 0x1000002, 8, TRUE },
+ { "CROMxx", "mpr-20652.6", 0x64C6FBB6, 0x400000, 2, 0x1000004, 8, TRUE },
+ { "CROMxx", "mpr-20651.5", 0x8373CAB3, 0x400000, 2, 0x1000006, 8, TRUE },
+
// Banked CROM2
- { "CROMxx", "mpr-20658.12", 0xB80175B9, 0x400000, 2, 0x2000000, 8, TRUE },
- { "CROMxx", "mpr-20657.11", 0x14BF8964, 0x400000, 2, 0x2000002, 8, TRUE },
- { "CROMxx", "mpr-20656.10", 0x466BEE13, 0x400000, 2, 0x2000004, 8, TRUE },
- { "CROMxx", "mpr-20655.9", 0xF0A471E9, 0x400000, 2, 0x2000006, 8, TRUE },
-
+ { "CROMxx", "mpr-20658.12", 0xB80175B9, 0x400000, 2, 0x2000000, 8, TRUE },
+ { "CROMxx", "mpr-20657.11", 0x14BF8964, 0x400000, 2, 0x2000002, 8, TRUE },
+ { "CROMxx", "mpr-20656.10", 0x466BEE13, 0x400000, 2, 0x2000004, 8, TRUE },
+ { "CROMxx", "mpr-20655.9", 0xF0A471E9, 0x400000, 2, 0x2000006, 8, TRUE },
+
// Banked CROM3
- { "CROMxx", "mpr-20662.16", 0x7130CB61, 0x400000, 2, 0x3000000, 8, TRUE },
- { "CROMxx", "mpr-20661.15", 0x50E6189E, 0x400000, 2, 0x3000002, 8, TRUE },
- { "CROMxx", "mpr-20660.14", 0xD961D385, 0x400000, 2, 0x3000004, 8, TRUE },
- { "CROMxx", "mpr-20659.13", 0xEDB63E7B, 0x400000, 2, 0x3000006, 8, TRUE },
-
+ { "CROMxx", "mpr-20662.16", 0x7130CB61, 0x400000, 2, 0x3000000, 8, TRUE },
+ { "CROMxx", "mpr-20661.15", 0x50E6189E, 0x400000, 2, 0x3000002, 8, TRUE },
+ { "CROMxx", "mpr-20660.14", 0xD961D385, 0x400000, 2, 0x3000004, 8, TRUE },
+ { "CROMxx", "mpr-20659.13", 0xEDB63E7B, 0x400000, 2, 0x3000006, 8, TRUE },
+
// Video ROM
- { "VROM", "mpr-20667.26", 0x321E006F, 0x400000, 2, 0, 32, FALSE },
- { "VROM", "mpr-20668.27", 0xC2DD8053, 0x400000, 2, 2, 32, FALSE },
- { "VROM", "mpr-20669.28", 0x63432497, 0x400000, 2, 4, 32, FALSE },
- { "VROM", "mpr-20670.29", 0xF7B554FD, 0x400000, 2, 6, 32, FALSE },
- { "VROM", "mpr-20671.30", 0xFEE1A49B, 0x400000, 2, 8, 32, FALSE },
- { "VROM", "mpr-20672.31", 0xE4B8C6E6, 0x400000, 2, 10, 32, FALSE },
- { "VROM", "mpr-20673.32", 0xE7B6403B, 0x400000, 2, 12, 32, FALSE },
- { "VROM", "mpr-20674.33", 0x9BE22E13, 0x400000, 2, 14, 32, FALSE },
- { "VROM", "mpr-20675.34", 0x6A7C3862, 0x400000, 2, 16, 32, FALSE },
- { "VROM", "mpr-20676.35", 0xDD299648, 0x400000, 2, 18, 32, FALSE },
- { "VROM", "mpr-20677.36", 0x3FC5F330, 0x400000, 2, 20, 32, FALSE },
- { "VROM", "mpr-20678.37", 0x62F794A1, 0x400000, 2, 22, 32, FALSE },
- { "VROM", "mpr-20679.38", 0x35A37C53, 0x400000, 2, 24, 32, FALSE },
- { "VROM", "mpr-20680.39", 0x81FEC46E, 0x400000, 2, 26, 32, FALSE },
- { "VROM", "mpr-20681.40", 0xD517873B, 0x400000, 2, 28, 32, FALSE },
- { "VROM", "mpr-20682.41", 0x5B43250C, 0x400000, 2, 30, 32, FALSE },
+ { "VROM", "mpr-20667.26", 0x321E006F, 0x400000, 2, 0, 32, FALSE },
+ { "VROM", "mpr-20668.27", 0xC2DD8053, 0x400000, 2, 2, 32, FALSE },
+ { "VROM", "mpr-20669.28", 0x63432497, 0x400000, 2, 4, 32, FALSE },
+ { "VROM", "mpr-20670.29", 0xF7B554FD, 0x400000, 2, 6, 32, FALSE },
+ { "VROM", "mpr-20671.30", 0xFEE1A49B, 0x400000, 2, 8, 32, FALSE },
+ { "VROM", "mpr-20672.31", 0xE4B8C6E6, 0x400000, 2, 10, 32, FALSE },
+ { "VROM", "mpr-20673.32", 0xE7B6403B, 0x400000, 2, 12, 32, FALSE },
+ { "VROM", "mpr-20674.33", 0x9BE22E13, 0x400000, 2, 14, 32, FALSE },
+ { "VROM", "mpr-20675.34", 0x6A7C3862, 0x400000, 2, 16, 32, FALSE },
+ { "VROM", "mpr-20676.35", 0xDD299648, 0x400000, 2, 18, 32, FALSE },
+ { "VROM", "mpr-20677.36", 0x3FC5F330, 0x400000, 2, 20, 32, FALSE },
+ { "VROM", "mpr-20678.37", 0x62F794A1, 0x400000, 2, 22, 32, FALSE },
+ { "VROM", "mpr-20679.38", 0x35A37C53, 0x400000, 2, 24, 32, FALSE },
+ { "VROM", "mpr-20680.39", 0x81FEC46E, 0x400000, 2, 26, 32, FALSE },
+ { "VROM", "mpr-20681.40", 0xD517873B, 0x400000, 2, 28, 32, FALSE },
+ { "VROM", "mpr-20682.41", 0x5B43250C, 0x400000, 2, 30, 32, FALSE },
+
+ // Sound ROMs
+ { "SndProg","epr-20687.21", 0xFA084DE5, 0x80000, 2, 0x000000, 2, TRUE },
+ { "Samples","mpr-20663.22", 0x977EB6A4, 0x400000, 2, 0x000000, 2, FALSE },
+ { "Samples","mpr-20665.24", 0x0EFC0CA8, 0x400000, 2, 0x400000, 2, FALSE },
+ { "Samples","mpr-20664.23", 0x89220782, 0x400000, 2, 0x800000, 2, FALSE },
+ { "Samples","mpr-20666.25", 0x3ECB2606, 0x400000, 2, 0xC00000, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -773,60 +815,61 @@ const struct GameInfo Model3GameList[] =
0x2000000, // 32 MB of VROM
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_JOYSTICK1|GAME_INPUT_JOYSTICK2|GAME_INPUT_SOCCER,
+ 0, // no MPEG board
{
// Fixed CROM
- { "CROM", "epr-20920.20", 0x428D05FC, 0x100000, 2, 0x0400000, 8, TRUE },
- { "CROM", "epr-20919.19", 0x7A0713D2, 0x100000, 2, 0x0400002, 8, TRUE },
- { "CROM", "epr-20918.18", 0x0E9CDC5B, 0x100000, 2, 0x0400004, 8, TRUE },
- { "CROM", "epr-20917.17", 0xC3BBB270, 0x100000, 2, 0x0400006, 8, TRUE },
-
+ { "CROM", "epr-20920.20", 0x428D05FC, 0x100000, 2, 0x0400000, 8, TRUE },
+ { "CROM", "epr-20919.19", 0x7A0713D2, 0x100000, 2, 0x0400002, 8, TRUE },
+ { "CROM", "epr-20918.18", 0x0E9CDC5B, 0x100000, 2, 0x0400004, 8, TRUE },
+ { "CROM", "epr-20917.17", 0xC3BBB270, 0x100000, 2, 0x0400006, 8, TRUE },
+
// Banked CROM0
- { "CROMxx", "mpr-19894.4", 0x09C065CC, 0x400000, 2, 0x0000000, 8, TRUE },
- { "CROMxx", "mpr-19893.3", 0x5C83DCAA, 0x400000, 2, 0x0000002, 8, TRUE },
- { "CROMxx", "mpr-19892.2", 0x8E5D3FE7, 0x400000, 2, 0x0000004, 8, TRUE },
- { "CROMxx", "mpr-19891.1", 0x9ECB0B39, 0x400000, 2, 0x0000006, 8, TRUE },
-
+ { "CROMxx", "mpr-19894.4", 0x09C065CC, 0x400000, 2, 0x0000000, 8, TRUE },
+ { "CROMxx", "mpr-19893.3", 0x5C83DCAA, 0x400000, 2, 0x0000002, 8, TRUE },
+ { "CROMxx", "mpr-19892.2", 0x8E5D3FE7, 0x400000, 2, 0x0000004, 8, TRUE },
+ { "CROMxx", "mpr-19891.1", 0x9ECB0B39, 0x400000, 2, 0x0000006, 8, TRUE },
+
// Banked CROM1
- { "CROMxx", "mpr-19776.8", 0x5B31C7C1, 0x400000, 2, 0x1000000, 8, TRUE },
- { "CROMxx", "mpr-19775.7", 0xA6B32BD9, 0x400000, 2, 0x1000002, 8, TRUE },
- { "CROMxx", "mpr-19774.6", 0x1D61D287, 0x400000, 2, 0x1000004, 8, TRUE },
- { "CROMxx", "mpr-19773.5", 0x4E381AE7, 0x400000, 2, 0x1000006, 8, TRUE },
-
+ { "CROMxx", "mpr-19776.8", 0x5B31C7C1, 0x400000, 2, 0x1000000, 8, TRUE },
+ { "CROMxx", "mpr-19775.7", 0xA6B32BD9, 0x400000, 2, 0x1000002, 8, TRUE },
+ { "CROMxx", "mpr-19774.6", 0x1D61D287, 0x400000, 2, 0x1000004, 8, TRUE },
+ { "CROMxx", "mpr-19773.5", 0x4E381AE7, 0x400000, 2, 0x1000006, 8, TRUE },
+
// Banked CROM2
- { "CROMxx", "mpr-20898.12", 0x94040D37, 0x400000, 2, 0x2000000, 8, TRUE },
- { "CROMxx", "mpr-20897.11", 0xC5CF067A, 0x400000, 2, 0x2000002, 8, TRUE },
- { "CROMxx", "mpr-20896.10", 0xBF1CBD5E, 0x400000, 2, 0x2000004, 8, TRUE },
- { "CROMxx", "mpr-20895.9", 0x9B51CBF5, 0x400000, 2, 0x2000006, 8, TRUE },
-
+ { "CROMxx", "mpr-20898.12", 0x94040D37, 0x400000, 2, 0x2000000, 8, TRUE },
+ { "CROMxx", "mpr-20897.11", 0xC5CF067A, 0x400000, 2, 0x2000002, 8, TRUE },
+ { "CROMxx", "mpr-20896.10", 0xBF1CBD5E, 0x400000, 2, 0x2000004, 8, TRUE },
+ { "CROMxx", "mpr-20895.9", 0x9B51CBF5, 0x400000, 2, 0x2000006, 8, TRUE },
+
// Banked CROM3
- { "CROMxx", "mpr-20902.16", 0xF4D3FF3A, 0x400000, 2, 0x3000000, 8, TRUE },
- { "CROMxx", "mpr-20901.15", 0x3492DDC8, 0x400000, 2, 0x3000002, 8, TRUE },
- { "CROMxx", "mpr-20900.14", 0x7A38B571, 0x400000, 2, 0x3000004, 8, TRUE },
- { "CROMxx", "mpr-20899.13", 0x65422425, 0x400000, 2, 0x3000006, 8, TRUE },
-
+ { "CROMxx", "mpr-20902.16", 0xF4D3FF3A, 0x400000, 2, 0x3000000, 8, TRUE },
+ { "CROMxx", "mpr-20901.15", 0x3492DDC8, 0x400000, 2, 0x3000002, 8, TRUE },
+ { "CROMxx", "mpr-20900.14", 0x7A38B571, 0x400000, 2, 0x3000004, 8, TRUE },
+ { "CROMxx", "mpr-20899.13", 0x65422425, 0x400000, 2, 0x3000006, 8, TRUE },
+
// Video ROM
- { "VROM", "mpr-19787.26", 0x856CC4AD, 0x200000, 2, 0, 32, FALSE },
- { "VROM", "mpr-19788.27", 0x72EF970A, 0x200000, 2, 2, 32, FALSE },
- { "VROM", "mpr-19789.28", 0x076ADD9A, 0x200000, 2, 4, 32, FALSE },
- { "VROM", "mpr-19790.29", 0x74CE238C, 0x200000, 2, 6, 32, FALSE },
- { "VROM", "mpr-19791.30", 0x75A98F96, 0x200000, 2, 8, 32, FALSE },
- { "VROM", "mpr-19792.31", 0x85C81633, 0x200000, 2, 10, 32, FALSE },
- { "VROM", "mpr-19793.32", 0x7F288CC4, 0x200000, 2, 12, 32, FALSE },
- { "VROM", "mpr-19794.33", 0xE0C1C370, 0x200000, 2, 14, 32, FALSE },
- { "VROM", "mpr-19795.34", 0x90989B20, 0x200000, 2, 16, 32, FALSE },
- { "VROM", "mpr-19796.35", 0x5D1AAB8D, 0x200000, 2, 18, 32, FALSE },
- { "VROM", "mpr-19797.36", 0xF5EDC891, 0x200000, 2, 20, 32, FALSE },
- { "VROM", "mpr-19798.37", 0xAE2DA90F, 0x200000, 2, 22, 32, FALSE },
- { "VROM", "mpr-19799.38", 0x92B18AD7, 0x200000, 2, 24, 32, FALSE },
- { "VROM", "mpr-19800.39", 0x4A57B16C, 0x200000, 2, 26, 32, FALSE },
- { "VROM", "mpr-19801.40", 0xBEB79A00, 0x200000, 2, 28, 32, FALSE },
- { "VROM", "mpr-19802.41", 0xF2C3A7B7, 0x200000, 2, 30, 32, FALSE },
-
+ { "VROM", "mpr-19787.26", 0x856CC4AD, 0x200000, 2, 0, 32, FALSE },
+ { "VROM", "mpr-19788.27", 0x72EF970A, 0x200000, 2, 2, 32, FALSE },
+ { "VROM", "mpr-19789.28", 0x076ADD9A, 0x200000, 2, 4, 32, FALSE },
+ { "VROM", "mpr-19790.29", 0x74CE238C, 0x200000, 2, 6, 32, FALSE },
+ { "VROM", "mpr-19791.30", 0x75A98F96, 0x200000, 2, 8, 32, FALSE },
+ { "VROM", "mpr-19792.31", 0x85C81633, 0x200000, 2, 10, 32, FALSE },
+ { "VROM", "mpr-19793.32", 0x7F288CC4, 0x200000, 2, 12, 32, FALSE },
+ { "VROM", "mpr-19794.33", 0xE0C1C370, 0x200000, 2, 14, 32, FALSE },
+ { "VROM", "mpr-19795.34", 0x90989B20, 0x200000, 2, 16, 32, FALSE },
+ { "VROM", "mpr-19796.35", 0x5D1AAB8D, 0x200000, 2, 18, 32, FALSE },
+ { "VROM", "mpr-19797.36", 0xF5EDC891, 0x200000, 2, 20, 32, FALSE },
+ { "VROM", "mpr-19798.37", 0xAE2DA90F, 0x200000, 2, 22, 32, FALSE },
+ { "VROM", "mpr-19799.38", 0x92B18AD7, 0x200000, 2, 24, 32, FALSE },
+ { "VROM", "mpr-19800.39", 0x4A57B16C, 0x200000, 2, 26, 32, FALSE },
+ { "VROM", "mpr-19801.40", 0xBEB79A00, 0x200000, 2, 28, 32, FALSE },
+ { "VROM", "mpr-19802.41", 0xF2C3A7B7, 0x200000, 2, 30, 32, FALSE },
+
// Sound ROMs
- { "SndProg","epr-20921.21", 0x30F032A7, 0x80000, 2, 0, 2, TRUE },
- { "Samples","mpr-20903.22", 0xE343E131, 0x400000, 2, 0x000000, 2, FALSE },
- { "Samples","mpr-20904.24", 0x21A91B84, 0x400000, 2, 0x400000, 2, FALSE },
+ { "SndProg","epr-20921.21", 0x30F032A7, 0x80000, 2, 0x000000, 2, TRUE },
+ { "Samples","mpr-20903.22", 0xE343E131, 0x400000, 2, 0x000000, 2, FALSE },
+ { "Samples","mpr-20904.24", 0x21A91B84, 0x400000, 2, 0x400000, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -844,6 +887,7 @@ const struct GameInfo Model3GameList[] =
0x4000000, // 64 MB of VROM
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_VEHICLE|GAME_INPUT_RALLY|GAME_INPUT_SHIFT4,
+ 2, // no MPEG board
{
// Fixed CROM
@@ -892,6 +936,11 @@ const struct GameInfo Model3GameList[] =
{ "SndProg","epr-20636.21", 0x7139EBF8, 0x80000, 2, 0, 2, TRUE },
{ "Samples","mpr-20614.22", 0xA3930E4A, 0x400000, 2, 0x000000, 2, FALSE },
{ "Samples","mpr-20615.24", 0x62E8A94A, 0x400000, 2, 0x400000, 2, FALSE },
+ { "DSBProg","epr-20641.2", 0xC9B82035, 0x20000, 2, 0, 2, TRUE },
+ { "DSBMPEG","mpr-20637.57", 0xD66E8A02, 0x400000, 2, 0x000000, 2, FALSE },
+ { "DSBMPEG","mpr-20638.58", 0xD1513382, 0x400000, 2, 0x400000, 2, FALSE },
+ { "DSBMPEG","mpr-20639.59", 0xF6603B7B, 0x400000, 2, 0x800000, 2, FALSE },
+ { "DSBMPEG","mpr-20640.60", 0x9EEA07B7, 0x400000, 2, 0xC00000, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -909,6 +958,7 @@ const struct GameInfo Model3GameList[] =
0x4000000, // 64 MB of VROM
0x1000000, // 16 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_VEHICLE|GAME_INPUT_VR|GAME_INPUT_SHIFT4,
+ 2, // DSB2 MPEG board
{
// Fixed CROM
@@ -965,6 +1015,12 @@ const struct GameInfo Model3GameList[] =
{ "Samples","mpr-20868.24", 0xFA0C7EC0, 0x400000, 2, 0x400000, 2, FALSE },
{ "Samples","mpr-20867.23", 0xA579C884, 0x400000, 2, 0x800000, 2, FALSE },
{ "Samples","mpr-20869.25", 0x1F338832, 0x400000, 2, 0xC00000, 2, FALSE },
+ { "DSBProg","epr-20886.ic2", 0x65B05F98, 0x20000, 2, 0, 2, TRUE },
+ { "DSBMPEG","mpr-20887.ic18", 0xA0757684, 0x400000, 2, 0x000000, 2, FALSE },
+ { "DSBMPEG","mpr-20888.ic20", 0xB495FE65, 0x400000, 2, 0x400000, 2, FALSE },
+ { "DSBMPEG","mpr-20889.ic22", 0x18EEC79E, 0x400000, 2, 0x800000, 2, FALSE },
+ { "DSBMPEG","mpr-20890.ic24", 0xAAC96FA2, 0x400000, 2, 0xC00000, 2, FALSE },
+
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -982,6 +1038,7 @@ const struct GameInfo Model3GameList[] =
0x4000000, // 64 MB of VROM
0x1000000, // 16 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_VEHICLE|GAME_INPUT_VR|GAME_INPUT_SHIFT4,
+ 2, // DSB2 MPEG board
{
// Fixed CROM
@@ -1038,6 +1095,11 @@ const struct GameInfo Model3GameList[] =
{ "Samples","mpr-21287.24", 0x06B66F17, 0x400000, 2, 0x400000, 2, FALSE },
{ "Samples","mpr-21286.23", 0x749DFEF0, 0x400000, 2, 0x800000, 2, FALSE },
{ "Samples","mpr-21288.25", 0x14BEE38E, 0x400000, 2, 0xC00000, 2, FALSE },
+ { "DSBProg","epr-20886.ic2", 0x65B05F98, 0x20000, 2, 0, 2, TRUE },
+ { "DSBMPEG","mpr-20887.ic18", 0xA0757684, 0x400000, 2, 0x000000, 2, FALSE },
+ { "DSBMPEG","mpr-20888.ic20", 0xB495FE65, 0x400000, 2, 0x400000, 2, FALSE },
+ { "DSBMPEG","mpr-20889.ic22", 0x18EEC79E, 0x400000, 2, 0x800000, 2, FALSE },
+ { "DSBMPEG","mpr-20890.ic24", 0xAAC96FA2, 0x400000, 2, 0xC00000, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -1055,55 +1117,63 @@ const struct GameInfo Model3GameList[] =
0x4000000, // 64 MB of VROM
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_JOYSTICK1|GAME_INPUT_JOYSTICK2|GAME_INPUT_FIGHTING,
+ 0, // no MPEG board
{
// Fixed CROM
- { "CROM", "epr-20599a.20", 0x9DF02AB9, 0x200000, 2, 0x0000000, 8, TRUE },
- { "CROM", "epr-20598a.19", 0x87BD070F, 0x200000, 2, 0x0000002, 8, TRUE },
- { "CROM", "epr-20597a.18", 0x6FCEE322, 0x200000, 2, 0x0000004, 8, TRUE },
- { "CROM", "epr-20596a.17", 0x969AB801, 0x200000, 2, 0x0000006, 8, TRUE },
-
+ { "CROM", "epr-20599a.20", 0x9DF02AB9, 0x200000, 2, 0x0000000, 8, TRUE },
+ { "CROM", "epr-20598a.19", 0x87BD070F, 0x200000, 2, 0x0000002, 8, TRUE },
+ { "CROM", "epr-20597a.18", 0x6FCEE322, 0x200000, 2, 0x0000004, 8, TRUE },
+ { "CROM", "epr-20596a.17", 0x969AB801, 0x200000, 2, 0x0000006, 8, TRUE },
+
// Banked CROM0
- { "CROMxx", "mpr-20563.4", 0x999848AC, 0x400000, 2, 0x0000000, 8, TRUE },
- { "CROMxx", "mpr-20562.3", 0x96E4942E, 0x400000, 2, 0x0000002, 8, TRUE },
- { "CROMxx", "mpr-20561.2", 0x38A0F112, 0x400000, 2, 0x0000004, 8, TRUE },
- { "CROMxx", "mpr-20560.1", 0xB0F6584D, 0x400000, 2, 0x0000006, 8, TRUE },
-
+ { "CROMxx", "mpr-20563.4", 0x999848AC, 0x400000, 2, 0x0000000, 8, TRUE },
+ { "CROMxx", "mpr-20562.3", 0x96E4942E, 0x400000, 2, 0x0000002, 8, TRUE },
+ { "CROMxx", "mpr-20561.2", 0x38A0F112, 0x400000, 2, 0x0000004, 8, TRUE },
+ { "CROMxx", "mpr-20560.1", 0xB0F6584D, 0x400000, 2, 0x0000006, 8, TRUE },
+
// Banked CROM1
- { "CROMxx", "mpr-20567.8", 0x80F4EBA7, 0x400000, 2, 0x1000000, 8, TRUE },
- { "CROMxx", "mpr-20566.7", 0x2901883B, 0x400000, 2, 0x1000002, 8, TRUE },
- { "CROMxx", "mpr-20565.6", 0xD6BBE638, 0x400000, 2, 0x1000004, 8, TRUE },
- { "CROMxx", "mpr-20564.5", 0xBE69FCA0, 0x400000, 2, 0x1000006, 8, TRUE },
-
+ { "CROMxx", "mpr-20567.8", 0x80F4EBA7, 0x400000, 2, 0x1000000, 8, TRUE },
+ { "CROMxx", "mpr-20566.7", 0x2901883B, 0x400000, 2, 0x1000002, 8, TRUE },
+ { "CROMxx", "mpr-20565.6", 0xD6BBE638, 0x400000, 2, 0x1000004, 8, TRUE },
+ { "CROMxx", "mpr-20564.5", 0xBE69FCA0, 0x400000, 2, 0x1000006, 8, TRUE },
+
// Banked CROM2
- { "CROMxx", "mpr-20571.12", 0x40B459AF, 0x400000, 2, 0x2000000, 8, TRUE },
- { "CROMxx", "mpr-20570.11", 0x2C0D91FC, 0x400000, 2, 0x2000002, 8, TRUE },
- { "CROMxx", "mpr-20569.10", 0x136C014F, 0x400000, 2, 0x2000004, 8, TRUE },
- { "CROMxx", "mpr-20568.9", 0xFF23CF1C, 0x400000, 2, 0x2000006, 8, TRUE },
+ { "CROMxx", "mpr-20571.12", 0x40B459AF, 0x400000, 2, 0x2000000, 8, TRUE },
+ { "CROMxx", "mpr-20570.11", 0x2C0D91FC, 0x400000, 2, 0x2000002, 8, TRUE },
+ { "CROMxx", "mpr-20569.10", 0x136C014F, 0x400000, 2, 0x2000004, 8, TRUE },
+ { "CROMxx", "mpr-20568.9", 0xFF23CF1C, 0x400000, 2, 0x2000006, 8, TRUE },
// Banked CROM3
- { "CROMxx", "mpr-20575.16", 0xEBC99D8A, 0x400000, 2, 0x3000000, 8, TRUE },
- { "CROMxx", "mpr-20574.15", 0x68567771, 0x400000, 2, 0x3000002, 8, TRUE },
- { "CROMxx", "mpr-20573.14", 0xE0DEE793, 0x400000, 2, 0x3000004, 8, TRUE },
- { "CROMxx", "mpr-20572.13", 0xD4A41A0B, 0x400000, 2, 0x3000006, 8, TRUE },
-
+ { "CROMxx", "mpr-20575.16", 0xEBC99D8A, 0x400000, 2, 0x3000000, 8, TRUE },
+ { "CROMxx", "mpr-20574.15", 0x68567771, 0x400000, 2, 0x3000002, 8, TRUE },
+ { "CROMxx", "mpr-20573.14", 0xE0DEE793, 0x400000, 2, 0x3000004, 8, TRUE },
+ { "CROMxx", "mpr-20572.13", 0xD4A41A0B, 0x400000, 2, 0x3000006, 8, TRUE },
+
// Video ROM
- { "VROM", "mpr-20580.26", 0x6D42775E, 0x400000, 2, 0, 32, FALSE },
- { "VROM", "mpr-20581.27", 0xAC9EEC04, 0x400000, 2, 2, 32, FALSE },
- { "VROM", "mpr-20582.28", 0xB202F7BD, 0x400000, 2, 4, 32, FALSE },
- { "VROM", "mpr-20583.29", 0x0D6D508A, 0x400000, 2, 6, 32, FALSE },
- { "VROM", "mpr-20584.30", 0xECCF4DE6, 0x400000, 2, 8, 32, FALSE },
- { "VROM", "mpr-20585.31", 0xB383F4E5, 0x400000, 2, 10, 32, FALSE },
- { "VROM", "mpr-20586.32", 0xE7CD5DFB, 0x400000, 2, 12, 32, FALSE },
- { "VROM", "mpr-20587.33", 0xE2B2ABE1, 0x400000, 2, 14, 32, FALSE },
- { "VROM", "mpr-20588.34", 0x84F4162D, 0x400000, 2, 16, 32, FALSE },
- { "VROM", "mpr-20589.35", 0x4E653D02, 0x400000, 2, 18, 32, FALSE },
- { "VROM", "mpr-20590.36", 0x527049BE, 0x400000, 2, 20, 32, FALSE },
- { "VROM", "mpr-20591.37", 0x3BE20243, 0x400000, 2, 22, 32, FALSE },
- { "VROM", "mpr-20592.38", 0xD7985B28, 0x400000, 2, 24, 32, FALSE },
- { "VROM", "mpr-20593.39", 0xE670C4D3, 0x400000, 2, 26, 32, FALSE },
- { "VROM", "mpr-20594.40", 0x35578240, 0x400000, 2, 28, 32, FALSE },
- { "VROM", "mpr-20595.41", 0x1D4A2CAD, 0x400000, 2, 30, 32, FALSE },
+ { "VROM", "mpr-20580.26", 0x6D42775E, 0x400000, 2, 0, 32, FALSE },
+ { "VROM", "mpr-20581.27", 0xAC9EEC04, 0x400000, 2, 2, 32, FALSE },
+ { "VROM", "mpr-20582.28", 0xB202F7BD, 0x400000, 2, 4, 32, FALSE },
+ { "VROM", "mpr-20583.29", 0x0D6D508A, 0x400000, 2, 6, 32, FALSE },
+ { "VROM", "mpr-20584.30", 0xECCF4DE6, 0x400000, 2, 8, 32, FALSE },
+ { "VROM", "mpr-20585.31", 0xB383F4E5, 0x400000, 2, 10, 32, FALSE },
+ { "VROM", "mpr-20586.32", 0xE7CD5DFB, 0x400000, 2, 12, 32, FALSE },
+ { "VROM", "mpr-20587.33", 0xE2B2ABE1, 0x400000, 2, 14, 32, FALSE },
+ { "VROM", "mpr-20588.34", 0x84F4162D, 0x400000, 2, 16, 32, FALSE },
+ { "VROM", "mpr-20589.35", 0x4E653D02, 0x400000, 2, 18, 32, FALSE },
+ { "VROM", "mpr-20590.36", 0x527049BE, 0x400000, 2, 20, 32, FALSE },
+ { "VROM", "mpr-20591.37", 0x3BE20243, 0x400000, 2, 22, 32, FALSE },
+ { "VROM", "mpr-20592.38", 0xD7985B28, 0x400000, 2, 24, 32, FALSE },
+ { "VROM", "mpr-20593.39", 0xE670C4D3, 0x400000, 2, 26, 32, FALSE },
+ { "VROM", "mpr-20594.40", 0x35578240, 0x400000, 2, 28, 32, FALSE },
+ { "VROM", "mpr-20595.41", 0x1D4A2CAD, 0x400000, 2, 30, 32, FALSE },
+
+ // Sound ROMs
+ { "SndProg","epr-20600a.21",0xF0E7DB7E, 0x80000, 2, 0x000000, 2, TRUE },
+ { "Samples","mpr-20576", 0x1EEB540B, 0x400000, 2, 0x000000, 2, FALSE },
+ { "Samples","mpr-20578", 0xD222F2D4, 0x400000, 2, 0x400000, 2, FALSE },
+ { "Samples","mpr-20577", 0x3B236187, 0x400000, 2, 0x800000, 2, FALSE },
+ { "Samples","mpr-20579", 0x08788436, 0x400000, 2, 0xC00000, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -1121,49 +1191,57 @@ const struct GameInfo Model3GameList[] =
0x4000000, // 64 MB of VROM
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_VEHICLE,
+ 0, // no MPEG board
{
// Fixed CROM
- { "CROM", "epr-20393a.17", 0xB5646556, 0x200000, 2, 0x0000006, 8, TRUE },
- { "CROM", "epr-20394a.18", 0xCE29E2B6, 0x200000, 2, 0x0000004, 8, TRUE },
- { "CROM", "epr-20395a.19", 0x761F4976, 0x200000, 2, 0x0000002, 8, TRUE },
- { "CROM", "epr-20396a.20", 0x16B0106B, 0x200000, 2, 0x0000000, 8, TRUE },
-
+ { "CROM", "epr-20396a.20", 0x16B0106B, 0x200000, 2, 0x0000000, 8, TRUE },
+ { "CROM", "epr-20395a.19", 0x761F4976, 0x200000, 2, 0x0000002, 8, TRUE },
+ { "CROM", "epr-20394a.18", 0xCE29E2B6, 0x200000, 2, 0x0000004, 8, TRUE },
+ { "CROM", "epr-20393a.17", 0xB5646556, 0x200000, 2, 0x0000006, 8, TRUE },
+
// Banked CROM0
- { "CROMxx", "mpr-20361.1", 0xDDB66C2F, 0x400000, 2, 0x0000006, 8, TRUE },
- { "CROMxx", "mpr-20362.2", 0xF7E60DFD, 0x400000, 2, 0x0000004, 8, TRUE },
- { "CROMxx", "mpr-20363.3", 0x3E3CC6FF, 0x400000, 2, 0x0000002, 8, TRUE },
- { "CROMxx", "mpr-20364.4", 0xA2A68EF2, 0x400000, 2, 0x0000000, 8, TRUE },
-
+ { "CROMxx", "mpr-20364.4", 0xA2A68EF2, 0x400000, 2, 0x0000000, 8, TRUE },
+ { "CROMxx", "mpr-20363.3", 0x3E3CC6FF, 0x400000, 2, 0x0000002, 8, TRUE },
+ { "CROMxx", "mpr-20362.2", 0xF7E60DFD, 0x400000, 2, 0x0000004, 8, TRUE },
+ { "CROMxx", "mpr-20361.1", 0xDDB66C2F, 0x400000, 2, 0x0000006, 8, TRUE },
+
// Banked CROM1
- { "CROMxx", "mpr-20365.5", 0x7DD50361, 0x400000, 2, 0x1000006, 8, TRUE },
- { "CROMxx", "mpr-20366.6", 0x45E3850E, 0x400000, 2, 0x1000004, 8, TRUE },
- { "CROMxx", "mpr-20367.7", 0x6C3F9748, 0x400000, 2, 0x1000002, 8, TRUE },
- { "CROMxx", "mpr-20368.8", 0x100C9846, 0x400000, 2, 0x1000000, 8, TRUE },
-
+ { "CROMxx", "mpr-20368.8", 0x100C9846, 0x400000, 2, 0x1000000, 8, TRUE },
+ { "CROMxx", "mpr-20367.7", 0x6C3F9748, 0x400000, 2, 0x1000002, 8, TRUE },
+ { "CROMxx", "mpr-20366.6", 0x45E3850E, 0x400000, 2, 0x1000004, 8, TRUE },
+ { "CROMxx", "mpr-20365.5", 0x7DD50361, 0x400000, 2, 0x1000006, 8, TRUE },
+
// Banked CROM3
- { "CROMxx", "epr-20409.13", 0x58CAAA75, 0x200000, 2, 0x3800006, 8, TRUE },
- { "CROMxx", "epr-20410.14", 0x98B126F2, 0x200000, 2, 0x3800004, 8, TRUE },
- { "CROMxx", "epr-20411.15", 0x848DAAF7, 0x200000, 2, 0x3800002, 8, TRUE },
- { "CROMxx", "epr-20412.16", 0x0D51BB34, 0x200000, 2, 0x3800000, 8, TRUE },
+ { "CROMxx", "epr-20412.16", 0x0D51BB34, 0x200000, 2, 0x3800000, 8, TRUE },
+ { "CROMxx", "epr-20411.15", 0x848DAAF7, 0x200000, 2, 0x3800002, 8, TRUE },
+ { "CROMxx", "epr-20410.14", 0x98B126F2, 0x200000, 2, 0x3800004, 8, TRUE },
+ { "CROMxx", "epr-20409.13", 0x58CAAA75, 0x200000, 2, 0x3800006, 8, TRUE },
// Video ROM
- { "VROM", "mpr-20377.26", 0x4D2887E5, 0x400000, 2, 0, 32, FALSE },
- { "VROM", "mpr-20378.27", 0x5AD7C0EC, 0x400000, 2, 2, 32, FALSE },
- { "VROM", "mpr-20379.28", 0x1E51C9F0, 0x400000, 2, 4, 32, FALSE },
- { "VROM", "mpr-20380.29", 0xE10D35AE, 0x400000, 2, 6, 32, FALSE },
- { "VROM", "mpr-20381.30", 0x76CD36A2, 0x400000, 2, 8, 32, FALSE },
- { "VROM", "mpr-20382.31", 0xF089AE37, 0x400000, 2, 10, 32, FALSE },
- { "VROM", "mpr-20383.32", 0x9E96D3BE, 0x400000, 2, 12, 32, FALSE },
- { "VROM", "mpr-20384.33", 0x5BDFBB52, 0x400000, 2, 14, 32, FALSE },
- { "VROM", "mpr-20385.34", 0x12DB1729, 0x400000, 2, 16, 32, FALSE },
- { "VROM", "mpr-20386.35", 0xDB2CCAF8, 0x400000, 2, 18, 32, FALSE },
- { "VROM", "mpr-20387.36", 0xC5DDE91B, 0x400000, 2, 20, 32, FALSE },
- { "VROM", "mpr-20388.37", 0xAEAA862E, 0x400000, 2, 22, 32, FALSE },
- { "VROM", "mpr-20389.38", 0x49BB6593, 0x400000, 2, 24, 32, FALSE },
- { "VROM", "mpr-20390.39", 0x1D4A8EFE, 0x400000, 2, 26, 32, FALSE },
- { "VROM", "mpr-20391.40", 0x5DC452DC, 0x400000, 2, 28, 32, FALSE },
- { "VROM", "mpr-20392.41", 0x892208CB, 0x400000, 2, 30, 32, FALSE },
+ { "VROM", "mpr-20377.26", 0x4D2887E5, 0x400000, 2, 0, 32, FALSE },
+ { "VROM", "mpr-20378.27", 0x5AD7C0EC, 0x400000, 2, 2, 32, FALSE },
+ { "VROM", "mpr-20379.28", 0x1E51C9F0, 0x400000, 2, 4, 32, FALSE },
+ { "VROM", "mpr-20380.29", 0xE10D35AE, 0x400000, 2, 6, 32, FALSE },
+ { "VROM", "mpr-20381.30", 0x76CD36A2, 0x400000, 2, 8, 32, FALSE },
+ { "VROM", "mpr-20382.31", 0xF089AE37, 0x400000, 2, 10, 32, FALSE },
+ { "VROM", "mpr-20383.32", 0x9E96D3BE, 0x400000, 2, 12, 32, FALSE },
+ { "VROM", "mpr-20384.33", 0x5BDFBB52, 0x400000, 2, 14, 32, FALSE },
+ { "VROM", "mpr-20385.34", 0x12DB1729, 0x400000, 2, 16, 32, FALSE },
+ { "VROM", "mpr-20386.35", 0xDB2CCAF8, 0x400000, 2, 18, 32, FALSE },
+ { "VROM", "mpr-20387.36", 0xC5DDE91B, 0x400000, 2, 20, 32, FALSE },
+ { "VROM", "mpr-20388.37", 0xAEAA862E, 0x400000, 2, 22, 32, FALSE },
+ { "VROM", "mpr-20389.38", 0x49BB6593, 0x400000, 2, 24, 32, FALSE },
+ { "VROM", "mpr-20390.39", 0x1D4A8EFE, 0x400000, 2, 26, 32, FALSE },
+ { "VROM", "mpr-20391.40", 0x5DC452DC, 0x400000, 2, 28, 32, FALSE },
+ { "VROM", "mpr-20392.41", 0x892208CB, 0x400000, 2, 30, 32, FALSE },
+
+ // Sound ROMs
+ { "SndProg","epr-20397.21", 0x5B20B54A, 0x80000, 2, 0x000000, 2, TRUE },
+ { "Samples","mpr-20373.22", 0xC684E8A3, 0x400000, 2, 0x000000, 2, FALSE },
+ { "Samples","mpr-20375.24", 0x906ACE86, 0x400000, 2, 0x400000, 2, FALSE },
+ { "Samples","mpr-20374.23", 0xFCF6EA21, 0x400000, 2, 0x800000, 2, FALSE },
+ { "Samples","mpr-20376.25", 0xDEEED366, 0x400000, 2, 0xC00000, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -1181,49 +1259,57 @@ const struct GameInfo Model3GameList[] =
0x4000000, // 64 MB of VROM
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_ANALOG_JOYSTICK,
+ 0, // no MPEG board
{
// Fixed CROM
- { "CROM", "epr21486.20", 0x940637C2, 0x200000, 2, 0x0000006, 8, TRUE },
- { "CROM", "epr21485.19", 0x58102168, 0x200000, 2, 0x0000004, 8, TRUE },
- { "CROM", "epr21484.18", 0xF68F7703, 0x200000, 2, 0x0000002, 8, TRUE },
- { "CROM", "epr21483.17", 0x64DE433F, 0x200000, 2, 0x0000000, 8, TRUE },
-
+ { "CROM", "epr21483.17", 0x64DE433F, 0x200000, 2, 0x0000000, 8, TRUE },
+ { "CROM", "epr21484.18", 0xF68F7703, 0x200000, 2, 0x0000002, 8, TRUE },
+ { "CROM", "epr21485.19", 0x58102168, 0x200000, 2, 0x0000004, 8, TRUE },
+ { "CROM", "epr21486.20", 0x940637C2, 0x200000, 2, 0x0000006, 8, TRUE },
+
// Banked CROM0
- { "CROMxx", "mpr21454.4", 0x42BDC56C, 0x400000, 2, 0x0000006, 8, TRUE },
- { "CROMxx", "mpr21453.3", 0x01AC050C, 0x400000, 2, 0x0000004, 8, TRUE },
- { "CROMxx", "mpr21452.2", 0x082D98AB, 0x400000, 2, 0x0000002, 8, TRUE },
- { "CROMxx", "mpr21451.1", 0x97FF94A7, 0x400000, 2, 0x0000000, 8, TRUE },
-
+ { "CROMxx", "mpr21451.1", 0x97FF94A7, 0x400000, 2, 0x0000000, 8, TRUE },
+ { "CROMxx", "mpr21452.2", 0x082D98AB, 0x400000, 2, 0x0000002, 8, TRUE },
+ { "CROMxx", "mpr21453.3", 0x01AC050C, 0x400000, 2, 0x0000004, 8, TRUE },
+ { "CROMxx", "mpr21454.4", 0x42BDC56C, 0x400000, 2, 0x0000006, 8, TRUE },
+
// Banked CROM1
- { "CROMxx", "mpr21458.8", 0xB748F5A1, 0x400000, 2, 0x1000000, 8, TRUE },
- { "CROMxx", "mpr21457.7", 0x2034DBD4, 0x400000, 2, 0x1000002, 8, TRUE },
- { "CROMxx", "mpr21456.6", 0x73A50547, 0x400000, 2, 0x1000004, 8, TRUE },
- { "CROMxx", "mpr21455.5", 0x0B4A3CC5, 0x400000, 2, 0x1000006, 8, TRUE },
-
+ { "CROMxx", "mpr21458.8", 0xB748F5A1, 0x400000, 2, 0x1000000, 8, TRUE },
+ { "CROMxx", "mpr21457.7", 0x2034DBD4, 0x400000, 2, 0x1000002, 8, TRUE },
+ { "CROMxx", "mpr21456.6", 0x73A50547, 0x400000, 2, 0x1000004, 8, TRUE },
+ { "CROMxx", "mpr21455.5", 0x0B4A3CC5, 0x400000, 2, 0x1000006, 8, TRUE },
+
// Banked CROM2
- { "CROMxx", "mpr21462.12", 0x03D22EE8, 0x400000, 2, 0x2000000, 8, TRUE },
- { "CROMxx", "mpr21462.11", 0x33D8F0DA, 0x400000, 2, 0x2000002, 8, TRUE },
- { "CROMxx", "mpr21461.10", 0x02268361, 0x400000, 2, 0x2000004, 8, TRUE },
- { "CROMxx", "mpr21460.9", 0x71A7B6B3, 0x400000, 2, 0x2000006, 8, TRUE },
+ { "CROMxx", "mpr21462.12", 0x03D22EE8, 0x400000, 2, 0x2000000, 8, TRUE },
+ { "CROMxx", "mpr21462.11", 0x33D8F0DA, 0x400000, 2, 0x2000002, 8, TRUE },
+ { "CROMxx", "mpr21461.10", 0x02268361, 0x400000, 2, 0x2000004, 8, TRUE },
+ { "CROMxx", "mpr21460.9", 0x71A7B6B3, 0x400000, 2, 0x2000006, 8, TRUE },
// Video ROM
- { "VROM", "mpr21467.26", 0x73635100, 0x400000, 2, 0, 32, FALSE },
- { "VROM", "mpr21468.27", 0x462E5C81, 0x400000, 2, 2, 32, FALSE },
- { "VROM", "mpr21469.28", 0x4BA3F192, 0x400000, 2, 4, 32, FALSE },
- { "VROM", "mpr21470.29", 0x670F0DF5, 0x400000, 2, 6, 32, FALSE },
- { "VROM", "mpr21471.30", 0x1F07E6E3, 0x400000, 2, 8, 32, FALSE },
- { "VROM", "mpr21472.31", 0xE6DC64A3, 0x400000, 2, 10, 32, FALSE },
- { "VROM", "mpr21473.32", 0xD1C9B54A, 0x400000, 2, 12, 32, FALSE },
- { "VROM", "mpr21474.33", 0xAA2F19AE, 0x400000, 2, 14, 32, FALSE },
- { "VROM", "mpr21475.34", 0xBAE9B381, 0x400000, 2, 16, 32, FALSE },
- { "VROM", "mpr21476.35", 0x3833DF51, 0x400000, 2, 18, 32, FALSE },
- { "VROM", "mpr21477.36", 0x46032C35, 0x400000, 2, 20, 32, FALSE },
- { "VROM", "mpr21478.37", 0x35EF75B8, 0x400000, 2, 22, 32, FALSE },
- { "VROM", "mpr21479.38", 0x783E8ECE, 0x400000, 2, 24, 32, FALSE },
- { "VROM", "mpr21480.39", 0xC947BCB8, 0x400000, 2, 26, 32, FALSE },
- { "VROM", "mpr21481.40", 0x6CE566AC, 0x400000, 2, 28, 32, FALSE },
- { "VROM", "mpr21482.41", 0xE995F554, 0x400000, 2, 30, 32, FALSE },
+ { "VROM", "mpr21467.26", 0x73635100, 0x400000, 2, 0, 32, FALSE },
+ { "VROM", "mpr21468.27", 0x462E5C81, 0x400000, 2, 2, 32, FALSE },
+ { "VROM", "mpr21469.28", 0x4BA3F192, 0x400000, 2, 4, 32, FALSE },
+ { "VROM", "mpr21470.29", 0x670F0DF5, 0x400000, 2, 6, 32, FALSE },
+ { "VROM", "mpr21471.30", 0x1F07E6E3, 0x400000, 2, 8, 32, FALSE },
+ { "VROM", "mpr21472.31", 0xE6DC64A3, 0x400000, 2, 10, 32, FALSE },
+ { "VROM", "mpr21473.32", 0xD1C9B54A, 0x400000, 2, 12, 32, FALSE },
+ { "VROM", "mpr21474.33", 0xAA2F19AE, 0x400000, 2, 14, 32, FALSE },
+ { "VROM", "mpr21475.34", 0xBAE9B381, 0x400000, 2, 16, 32, FALSE },
+ { "VROM", "mpr21476.35", 0x3833DF51, 0x400000, 2, 18, 32, FALSE },
+ { "VROM", "mpr21477.36", 0x46032C35, 0x400000, 2, 20, 32, FALSE },
+ { "VROM", "mpr21478.37", 0x35EF75B8, 0x400000, 2, 22, 32, FALSE },
+ { "VROM", "mpr21479.38", 0x783E8ECE, 0x400000, 2, 24, 32, FALSE },
+ { "VROM", "mpr21480.39", 0xC947BCB8, 0x400000, 2, 26, 32, FALSE },
+ { "VROM", "mpr21481.40", 0x6CE566AC, 0x400000, 2, 28, 32, FALSE },
+ { "VROM", "mpr21482.41", 0xE995F554, 0x400000, 2, 30, 32, FALSE },
+
+ // Sound ROMs
+ { "SndProg","epr21487.21", 0xC2942448, 0x80000, 2, 0x000000, 2, TRUE },
+ { "Samples","mpr21463.22", 0x0E6d6C0E, 0x400000, 2, 0x000000, 2, FALSE },
+ { "Samples","mpr21465.24", 0x1A62D925, 0x400000, 2, 0x400000, 2, FALSE },
+ { "Samples","mpr21464.23", 0x8230C1DE, 0x400000, 2, 0x800000, 2, FALSE },
+ { "Samples","mpr21466.25", 0xCA20359E, 0x400000, 2, 0xC00000, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -1241,51 +1327,60 @@ const struct GameInfo Model3GameList[] =
0x4000000, // 64 MB of VROM (will need to be mirrored)
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_ANALOG_JOYSTICK,
+ 0, // no MPEG board
{
// Fixed CROM
- { "CROM", "epr21117.20", 0x3adfcb9d, 0x200000, 2, 0x0000006, 8, TRUE },
- { "CROM", "epr21116.19", 0x0bb9c107, 0x200000, 2, 0x0000004, 8, TRUE },
- { "CROM", "epr21115.18", 0x69e31e85, 0x200000, 2, 0x0000002, 8, TRUE },
- { "CROM", "epr21114.17", 0x58d985f1, 0x200000, 2, 0x0000000, 8, TRUE },
+ { "CROM", "epr21114.17", 0x58D985f1, 0x200000, 2, 0x0000000, 8, TRUE },
+ { "CROM", "epr21115.18", 0x69E31E85, 0x200000, 2, 0x0000002, 8, TRUE },
+ { "CROM", "epr21116.19", 0x0BB9C107, 0x200000, 2, 0x0000004, 8, TRUE },
+ { "CROM", "epr21117.20", 0x3ADFCB9D, 0x200000, 2, 0x0000006, 8, TRUE },
// Banked CROM1
- { "CROMxx", "mpr21085.8", 0x5056ad33, 0x800000, 2, 0x2000006, 8, TRUE },
- { "CROMxx", "mpr21084.7", 0xfdec6a23, 0x800000, 2, 0x2000004, 8, TRUE },
- { "CROMxx", "mpr21083.6", 0xc1c6b554, 0x800000, 2, 0x2000002, 8, TRUE },
- { "CROMxx", "mpr21082.5", 0x2b7224d3, 0x800000, 2, 0x2000000, 8, TRUE },
-
+ { "CROMxx", "mpr21082.5", 0x2B7224D3, 0x800000, 2, 0x2000000, 8, TRUE },
+ { "CROMxx", "mpr21083.6", 0xC1C6B554, 0x800000, 2, 0x2000002, 8, TRUE },
+ { "CROMxx", "mpr21084.7", 0xFDEC6A23, 0x800000, 2, 0x2000004, 8, TRUE },
+ { "CROMxx", "mpr21085.8", 0x5056AD33, 0x800000, 2, 0x2000006, 8, TRUE },
+
// Banked CROM2
- { "CROMxx", "mpr21089.12", 0x2e8f88bd, 0x800000, 2, 0x4000000, 8, TRUE },
- { "CROMxx", "mpr21088.11", 0x7ed71c8c, 0x800000, 2, 0x4000002, 8, TRUE },
- { "CROMxx", "mpr21087.10", 0xcff28641, 0x800000, 2, 0x4000004, 8, TRUE },
- { "CROMxx", "mpr21086.9", 0x3f12e1d0, 0x800000, 2, 0x4000006, 8, TRUE },
+ { "CROMxx", "mpr21089.12", 0x2E8F88BD, 0x800000, 2, 0x4000000, 8, TRUE },
+ { "CROMxx", "mpr21088.11", 0x7ED71C8C, 0x800000, 2, 0x4000002, 8, TRUE },
+ { "CROMxx", "mpr21087.10", 0xCFF28641, 0x800000, 2, 0x4000004, 8, TRUE },
+ { "CROMxx", "mpr21086.9", 0x3F12E1D0, 0x800000, 2, 0x4000006, 8, TRUE },
// Banked CROM3
- { "CROMxx", "mpr21093.16", 0xbdfbf357, 0x800000, 2, 0x6000000, 8, TRUE },
- { "CROMxx", "mpr21092.15", 0x5b1ced40, 0x800000, 2, 0x6000002, 8, TRUE },
- { "CROMxx", "mpr21091.14", 0x10671951, 0x800000, 2, 0x6000004, 8, TRUE },
- { "CROMxx", "mpr21090.13", 0x749d7979, 0x800000, 2, 0x6000006, 8, TRUE },
+ { "CROMxx", "mpr21093.16", 0xBDFBF357, 0x800000, 2, 0x6000000, 8, TRUE },
+ { "CROMxx", "mpr21092.15", 0x5B1CED40, 0x800000, 2, 0x6000002, 8, TRUE },
+ { "CROMxx", "mpr21091.14", 0x10671951, 0x800000, 2, 0x6000004, 8, TRUE },
+ { "CROMxx", "mpr21090.13", 0x749D7979, 0x800000, 2, 0x6000006, 8, TRUE },
// Video ROM
- { "VROM", "mpr21098.26", 0x91e71855, 0x400000, 2, 0, 32, FALSE },
- { "VROM", "mpr21099.27", 0x308a2768, 0x400000, 2, 2, 32, FALSE },
- { "VROM", "mpr21100.28", 0x5149b286, 0x400000, 2, 4, 32, FALSE },
- { "VROM", "mpr21101.29", 0xe9ed4250, 0x400000, 2, 6, 32, FALSE },
- { "VROM", "mpr21102.30", 0x06c6d4fc, 0x400000, 2, 8, 32, FALSE },
- { "VROM", "mpr21103.31", 0x17c4b27a, 0x400000, 2, 10, 32, FALSE },
- { "VROM", "mpr21104.32", 0xf6f80ffb, 0x400000, 2, 12, 32, FALSE },
- { "VROM", "mpr21105.33", 0x99bdb52b, 0x400000, 2, 14, 32, FALSE },
- { "VROM", "mpr21106.34", 0xad2b7981, 0x400000, 2, 16, 32, FALSE },
- { "VROM", "mpr21107.35", 0xe108ff62, 0x400000, 2, 18, 32, FALSE },
- { "VROM", "mpr21108.36", 0xcddc7a6e, 0x400000, 2, 20, 32, FALSE },
- { "VROM", "mpr21109.37", 0x92d6141d, 0x400000, 2, 22, 32, FALSE },
- { "VROM", "mpr21110.38", 0x4d6e3148, 0x400000, 2, 24, 32, FALSE },
- { "VROM", "mpr21111.39", 0x0a046d7a, 0x400000, 2, 26, 32, FALSE },
- { "VROM", "mpr21112.40", 0x9afd9feb, 0x400000, 2, 28, 32, FALSE },
- { "VROM", "mpr21113.41", 0x864bf325, 0x400000, 2, 30, 32, FALSE },
-
+ { "VROM", "mpr21098.26", 0x91E71855, 0x400000, 2, 0, 32, FALSE },
+ { "VROM", "mpr21099.27", 0x308A2768, 0x400000, 2, 2, 32, FALSE },
+ { "VROM", "mpr21100.28", 0x5149B286, 0x400000, 2, 4, 32, FALSE },
+ { "VROM", "mpr21101.29", 0xE9ED4250, 0x400000, 2, 6, 32, FALSE },
+ { "VROM", "mpr21102.30", 0x06C6D4FC, 0x400000, 2, 8, 32, FALSE },
+ { "VROM", "mpr21103.31", 0x17C4B27A, 0x400000, 2, 10, 32, FALSE },
+ { "VROM", "mpr21104.32", 0xF6F80FFB, 0x400000, 2, 12, 32, FALSE },
+ { "VROM", "mpr21105.33", 0x99BDB52B, 0x400000, 2, 14, 32, FALSE },
+ { "VROM", "mpr21106.34", 0xAD2B7981, 0x400000, 2, 16, 32, FALSE },
+ { "VROM", "mpr21107.35", 0xE108FF62, 0x400000, 2, 18, 32, FALSE },
+ { "VROM", "mpr21108.36", 0xCDDC7A6E, 0x400000, 2, 20, 32, FALSE },
+ { "VROM", "mpr21109.37", 0x92D6141D, 0x400000, 2, 22, 32, FALSE },
+ { "VROM", "mpr21110.38", 0x4D6E3148, 0x400000, 2, 24, 32, FALSE },
+ { "VROM", "mpr21111.39", 0x0A046D7A, 0x400000, 2, 26, 32, FALSE },
+ { "VROM", "mpr21112.40", 0x9AFD9FEB, 0x400000, 2, 28, 32, FALSE },
+ { "VROM", "mpr21113.41", 0x864BF325, 0x400000, 2, 30, 32, FALSE },
+
+ // Sound ROMs
+ { "SndProg","epr21118.21", 0x598C00F0, 0x80000, 2, 0x000000, 2, TRUE },
+ { "Samples","mpr21094.22", 0xC262B80A, 0x400000, 2, 0x000000, 2, FALSE },
+ { "Samples","mpr21096.24", 0x0A0021A0, 0x400000, 2, 0x400000, 2, FALSE },
+ { "Samples","mpr21095.23", 0x16D27A0A, 0x400000, 2, 0x800000, 2, FALSE },
+ { "Samples","mpr21097.25", 0x0D8033FC, 0x400000, 2, 0xC00000, 2, FALSE },
+
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
+
}
},
@@ -1301,6 +1396,7 @@ const struct GameInfo Model3GameList[] =
0x4000000, // 64 MB of VROM
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_ANALOG_JOYSTICK,
+ 2, // DSB2 MPEG board
{
// Fixed CROM
@@ -1346,9 +1442,14 @@ const struct GameInfo Model3GameList[] =
{ "VROM", "mpr-21374.41", 0xAE6C4D28, 0x400000, 2, 30, 32, FALSE },
// Sound ROMs
- { "SndProg","epr-21383.21", 0x544d1e28, 0x80000, 2, 0, 2, TRUE },
- { "Samples","mpr-21355.22", 0xc1b2d326, 0x400000, 2, 0x000000, 2, FALSE },
- { "Samples","mpr-21357.24", 0x02703fab, 0x400000, 2, 0x400000, 2, FALSE },
+ { "SndProg","epr-21383.21", 0x544D1E28, 0x80000, 2, 0, 2, TRUE },
+ { "Samples","mpr-21355.22", 0xC1B2D326, 0x400000, 2, 0x000000, 2, FALSE },
+ { "Samples","mpr-21357.24", 0x02703FAB, 0x400000, 2, 0x400000, 2, FALSE },
+ { "DSBProg","ep21384.2", 0x12FA4780, 0x20000, 2, 0, 2, TRUE },
+ { "DSBMPEG","mp21375.18", 0x735157a9, 0x400000, 2, 0x000000, 2, FALSE },
+ { "DSBMPEG","mp21376.20", 0xE635F81E, 0x400000, 2, 0x400000, 2, FALSE },
+ { "DSBMPEG","mp21377.22", 0x720621F8, 0x400000, 2, 0x800000, 2, FALSE },
+ { "DSBMPEG","mp21378.24", 0x1FCF715E, 0x400000, 2, 0xC00000, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -1366,49 +1467,57 @@ const struct GameInfo Model3GameList[] =
0x4000000, // 64 MB of VROM
0x800000, // 8 MB of sample ROMs
GAME_INPUT_COMMON|GAME_INPUT_VEHICLE,
+ 0, // no MPEG board
{
// Fixed CROM
- { "CROM", "epr22898.20", 0xEFB96701, 0x200000, 2, 0x0000000, 8, TRUE },
- { "CROM", "epr22897.19", 0x9755DD8C, 0x200000, 2, 0x0000002, 8, TRUE },
- { "CROM", "epr22896.18", 0x0FF828A8, 0x200000, 2, 0x0000004, 8, TRUE },
- { "CROM", "epr22895.17", 0x07DF16A0, 0x200000, 2, 0x0000006, 8, TRUE },
-
+ { "CROM", "epr22898.20", 0xEFB96701, 0x200000, 2, 0x0000000, 8, TRUE },
+ { "CROM", "epr22897.19", 0x9755DD8C, 0x200000, 2, 0x0000002, 8, TRUE },
+ { "CROM", "epr22896.18", 0x0FF828A8, 0x200000, 2, 0x0000004, 8, TRUE },
+ { "CROM", "epr22895.17", 0x07DF16A0, 0x200000, 2, 0x0000006, 8, TRUE },
+
// Banked CROM0
- { "CROMxx", "mpr22873.4", 0xDD406330, 0x400000, 2, 0x0000000, 8, TRUE },
- { "CROMxx", "mpr22872.3", 0x4FDE63A1, 0x400000, 2, 0x0000002, 8, TRUE },
- { "CROMxx", "mpr22871.2", 0xCF5BB5B5, 0x400000, 2, 0x0000004, 8, TRUE },
- { "CROMxx", "mpr22870.1", 0x52054043, 0x400000, 2, 0x0000006, 8, TRUE },
-
+ { "CROMxx", "mpr22873.4", 0xDD406330, 0x400000, 2, 0x0000000, 8, TRUE },
+ { "CROMxx", "mpr22872.3", 0x4FDE63A1, 0x400000, 2, 0x0000002, 8, TRUE },
+ { "CROMxx", "mpr22871.2", 0xCF5BB5B5, 0x400000, 2, 0x0000004, 8, TRUE },
+ { "CROMxx", "mpr22870.1", 0x52054043, 0x400000, 2, 0x0000006, 8, TRUE },
+
// Banked CROM1
- { "CROMxx", "mpr22877.8", 0xE53B8764, 0x400000, 2, 0x1000000, 8, TRUE },
- { "CROMxx", "mpr22876.7", 0xA7561249, 0x400000, 2, 0x1000002, 8, TRUE },
- { "CROMxx", "mpr22875.6", 0x1BB5C018, 0x400000, 2, 0x1000004, 8, TRUE },
- { "CROMxx", "mpr22874.5", 0x5E990497, 0x400000, 2, 0x1000006, 8, TRUE },
-
+ { "CROMxx", "mpr22877.8", 0xE53B8764, 0x400000, 2, 0x1000000, 8, TRUE },
+ { "CROMxx", "mpr22876.7", 0xA7561249, 0x400000, 2, 0x1000002, 8, TRUE },
+ { "CROMxx", "mpr22875.6", 0x1BB5C018, 0x400000, 2, 0x1000004, 8, TRUE },
+ { "CROMxx", "mpr22874.5", 0x5E990497, 0x400000, 2, 0x1000006, 8, TRUE },
+
// Banked CROM3
- { "CROMxx", "mpr22885.16", 0x3525B46D, 0x400000, 2, 0x3000000, 8, TRUE },
- { "CROMxx", "mpr22884.15", 0x254C3B63, 0x400000, 2, 0x3000002, 8, TRUE },
- { "CROMxx", "mpr22883.14", 0x86D90148, 0x400000, 2, 0x3000004, 8, TRUE },
- { "CROMxx", "mpr22882.13", 0xB161416F, 0x400000, 2, 0x3000006, 8, TRUE },
-
+ { "CROMxx", "mpr22885.16", 0x3525B46D, 0x400000, 2, 0x3000000, 8, TRUE },
+ { "CROMxx", "mpr22884.15", 0x254C3B63, 0x400000, 2, 0x3000002, 8, TRUE },
+ { "CROMxx", "mpr22883.14", 0x86D90148, 0x400000, 2, 0x3000004, 8, TRUE },
+ { "CROMxx", "mpr22882.13", 0xB161416F, 0x400000, 2, 0x3000006, 8, TRUE },
+
// Video ROM
- { "VROM", "mpr22854.26", 0x97A23D16, 0x400000, 2, 0, 32, FALSE },
- { "VROM", "mpr22855.27", 0x7249CDC9, 0x400000, 2, 2, 32, FALSE },
- { "VROM", "mpr22856.28", 0x9C0D1D1B, 0x400000, 2, 4, 32, FALSE },
- { "VROM", "mpr22857.29", 0x44E6CE2B, 0x400000, 2, 6, 32, FALSE },
- { "VROM", "mpr22858.30", 0x0AF40AAE, 0x400000, 2, 8, 32, FALSE },
- { "VROM", "mpr22859.31", 0xC64F0158, 0x400000, 2, 10, 32, FALSE },
- { "VROM", "mpr22860.32", 0x053AF14B, 0x400000, 2, 12, 32, FALSE },
- { "VROM", "mpr22861.33", 0xD26343DA, 0x400000, 2, 14, 32, FALSE },
- { "VROM", "mpr22862.34", 0x38347C14, 0x400000, 2, 16, 32, FALSE },
- { "VROM", "mpr22863.35", 0x28B558E6, 0x400000, 2, 18, 32, FALSE },
- { "VROM", "mpr22864.36", 0x31ED02F6, 0x400000, 2, 20, 32, FALSE },
- { "VROM", "mpr22865.37", 0x3E3A211A, 0x400000, 2, 22, 32, FALSE },
- { "VROM", "mpr22866.38", 0xA863A3C8, 0x400000, 2, 24, 32, FALSE },
- { "VROM", "mpr22867.39", 0x1CE6C7B2, 0x400000, 2, 26, 32, FALSE },
- { "VROM", "mpr22868.40", 0x2DB40CF8, 0x400000, 2, 28, 32, FALSE },
- { "VROM", "mpr22869.41", 0xC6D62634, 0x400000, 2, 30, 32, FALSE },
+ { "VROM", "mpr22854.26", 0x97A23D16, 0x400000, 2, 0, 32, FALSE },
+ { "VROM", "mpr22855.27", 0x7249CDC9, 0x400000, 2, 2, 32, FALSE },
+ { "VROM", "mpr22856.28", 0x9C0D1D1B, 0x400000, 2, 4, 32, FALSE },
+ { "VROM", "mpr22857.29", 0x44E6CE2B, 0x400000, 2, 6, 32, FALSE },
+ { "VROM", "mpr22858.30", 0x0AF40AAE, 0x400000, 2, 8, 32, FALSE },
+ { "VROM", "mpr22859.31", 0xC64F0158, 0x400000, 2, 10, 32, FALSE },
+ { "VROM", "mpr22860.32", 0x053AF14B, 0x400000, 2, 12, 32, FALSE },
+ { "VROM", "mpr22861.33", 0xD26343DA, 0x400000, 2, 14, 32, FALSE },
+ { "VROM", "mpr22862.34", 0x38347C14, 0x400000, 2, 16, 32, FALSE },
+ { "VROM", "mpr22863.35", 0x28B558E6, 0x400000, 2, 18, 32, FALSE },
+ { "VROM", "mpr22864.36", 0x31ED02F6, 0x400000, 2, 20, 32, FALSE },
+ { "VROM", "mpr22865.37", 0x3E3A211A, 0x400000, 2, 22, 32, FALSE },
+ { "VROM", "mpr22866.38", 0xA863A3C8, 0x400000, 2, 24, 32, FALSE },
+ { "VROM", "mpr22867.39", 0x1CE6C7B2, 0x400000, 2, 26, 32, FALSE },
+ { "VROM", "mpr22868.40", 0x2DB40CF8, 0x400000, 2, 28, 32, FALSE },
+ { "VROM", "mpr22869.41", 0xC6D62634, 0x400000, 2, 30, 32, FALSE },
+
+ // Sound ROMs
+ { "SndProg","epr22886.21", 0x374EC1C6, 0x80000, 2, 0x000000, 2, TRUE },
+ { "Samples","mpr22887.22", 0x7D04A867, 0x400000, 2, 0x000000, 2, FALSE },
+ { "Samples","mpr22889.24", 0x4F9BA45D, 0x400000, 2, 0x400000, 2, FALSE },
+ { "Samples","mpr22888.23", 0x018FCF22, 0x400000, 2, 0x800000, 2, FALSE },
+ { "Samples","mpr22890.25", 0xB638BD7C, 0x400000, 2, 0xC00000, 2, FALSE },
{ NULL, NULL, 0, 0, 0, 0, 0, FALSE }
}
@@ -1427,6 +1536,7 @@ const struct GameInfo Model3GameList[] =
0,
0,
0,
+ 0,
{
{ NULL, NULL, 0, 0, 0, 0, FALSE },
diff --git a/Src/Games.h b/Src/Games.h
index c136fd9..575f998 100644
--- a/Src/Games.h
+++ b/Src/Games.h
@@ -74,9 +74,10 @@ struct GameInfo
unsigned vromSize; // size of video ROMs (32 or 64 MB; if 32 MB, will have to be mirrored)
unsigned sampleSize; // size of sample ROMS (8 or 16 MB; if 8 MB, will have to be mirrored)
unsigned inputFlags; // game input types
+ int mpegBoard; // MPEG music board type: 0 = none, 1 = DSB1 (Z80), 2 = DSB2 (68K).
// ROM files
- struct ROMInfo ROM[42];
+ struct ROMInfo ROM[48];
};
diff --git a/Src/Graphics/Render.h b/Src/Graphics/Render.h
deleted file mode 100644
index cea99d3..0000000
--- a/Src/Graphics/Render.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/**
- ** Supermodel
- ** A Sega Model 3 Arcade Emulator.
- ** Copyright 2011 Bart Trzynadlowski
- **
- ** This file is part of Supermodel.
- **
- ** Supermodel is free software: you can redistribute it and/or modify it under
- ** the terms of the GNU General Public License as published by the Free
- ** Software Foundation, either version 3 of the License, or (at your option)
- ** any later version.
- **
- ** Supermodel 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 General Public License for
- ** more details.
- **
- ** You should have received a copy of the GNU General Public License along
- ** with Supermodel. If not, see .
- **/
-
-/*
- * Render.h
- *
- * Header file defining the CRender class: container for both the 2D and 3D
- * renderers.
- */
-
-#ifndef INCLUDED_RENDER_H
-#define INCLUDED_RENDER_H
-
-/*
- * CRender:
- *
- * Tile generator graphics engine. This must be constructed and initialized
- * before being attached to any objects that want to make use of it. Apart from
- * the constructor, all members assume that a global GL device
- * context is available and that GL functions may be called.
- */
-class CRender2D
-{
-public:
- /*
- * BeginFrame(layerFormats):
- *
- * Prepare to render a new frame. Must be called once per frame prior to
- * drawing anything.
- *
- * Parameters:
- * layerFormats A bit field indicating how to interpret each of the
- * four layers: 0=8-bit pixels, 1=4-bit pixels. Bits
- * 3-0 correspond to layers 3-0.
- */
- void BeginFrame(unsigned layerFormats);
-
- /*
- * EndFrame(void):
- *
- * Signals the end of rendering for this frame. Must be called last during
- * the frame.
- */
- void EndFrame(void);
-
- /*
- * WriteVRAM(addr, data):
- *
- * Indicates what will be written next to the tile generator's RAM. The
- * VRAM address must not have yet been updated, to allow the renderer to
- * check for changes. Data is accepted in the same form as the tile
- * generator: the MSB is what was written to addr+3. This function is
- * intended to facilitate on-the-fly decoding of tiles and palette data.
- *
- * Parameters:
- * addr Address in tile generator RAM. Caller must ensure it is
- * clamped to the range 0x000000 to 0x11FFFF because this
- * function does not.
- * data The data to write.
- */
- void WriteVRAM(unsigned addr, UINT32 data);
-
- /*
- * AttachRegisters(regPtr):
- *
- * Attaches tile generator registers. This must be done prior to any
- * rendering otherwise the program may crash with an access violation.
- *
- * Parameters:
- * regPtr Pointer to the base of the tile generator registers.
- * There are assumed to be 64 in all.
- */
- void AttachRegisters(const UINT32 *regPtr);
-
- /*
- * AttachVRAM(vramPtr):
- *
- * Attaches tile generator RAM. This must be done prior to any rendering
- * otherwise the program may crash with an access violation.
- *
- * Parameters:
- * vramPtr Pointer to the base of the tile generator RAM (0x120000
- * bytes). VRAM is assumed to be in little endian format.
- */
- void AttachVRAM(const UINT8 *vramPtr);
-
- /*
- * Init(xOffset, yOffset, xRes, yRes):
- *
- * One-time initialization of the context. Must be called before any other
- * members (meaning it should be called even before being attached to any
- * other objects that want to use it).
- *
- * Parameters:
- * xOffset X offset within OpenGL display surface in pixels.
- * yOffset Y offset.
- * xRes Horizontal resolution of display surface in pixels.
- * yRes Vertical resolution.
- *
- * Returns:
- * OKAY is successful, otherwise FAILED if a non-recoverable error
- * occurred. Prints own error messages.
- */
- BOOL Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes);
-
- /*
- * CRender2D(void):
- * ~CRender2D(void):
- *
- * Constructor and destructor.
- */
- CRender2D(void);
- ~CRender2D(void);
-
-private:
- // Private member functions
- void DrawTile4Bit(unsigned tile, UINT32 *buf, unsigned pitch);
- void DrawTile8Bit(unsigned tile, UINT32 *buf, unsigned pitch);
- void DrawRect(int layerNum, UINT32 *layerSurf, const UINT32 *nameTable, unsigned x, unsigned y, unsigned w, unsigned h);
- void UpdateLayer(int layerNum);
- void DisplayLayer(int layerNum, GLfloat z, GLfloat scroll);
- void Setup2D(void);
-
- // Data received from tile generator device object
- const UINT32 *vram;
- const UINT32 *regs;
-
- // OpenGL data
- GLuint texID[4]; // IDs for the 4 layer textures
- unsigned xPixels, yPixels; // display surface resolution
- unsigned xOffs, yOffs; // offset
-
- // Shader programs and input data locations
- GLuint shaderProgram; // shader program object
- GLuint vertexShader; // vertex shader handle
- GLuint fragmentShader; // fragment shader
- GLuint textureMapLoc; // location of "textureMap" uniform
- GLuint bottomLayerLoc; // uniform
-
-
- // Dirty rectangles (non-zero indicates region is dirty)
- UINT8 dirty[4][64/DIRTY_RECT_HEIGHT][64/DIRTY_RECT_WIDTH];
- BOOL allDirty; // global dirty flag (forces everything to be updated)
-
- // Buffers
- UINT8 *memoryPool; // all memory is allocated here
- UINT32 *surf; // 4 512x512x32bpp pixel surfaces
- UINT32 *pal; // 0x20000 byte (32K colors) palette
-};
-
-
-#endif // INCLUDED_RENDER2D_H
diff --git a/Src/Model3/DSB.cpp b/Src/Model3/DSB.cpp
new file mode 100644
index 0000000..d79ecf9
--- /dev/null
+++ b/Src/Model3/DSB.cpp
@@ -0,0 +1,877 @@
+/**
+ ** Supermodel
+ ** A Sega Model 3 Arcade Emulator.
+ ** Copyright 2011 Bart Trzynadlowski
+ **
+ ** This file is part of Supermodel.
+ **
+ ** Supermodel is free software: you can redistribute it and/or modify it under
+ ** the terms of the GNU General Public License as published by the Free
+ ** Software Foundation, either version 3 of the License, or (at your option)
+ ** any later version.
+ **
+ ** Supermodel 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 General Public License for
+ ** more details.
+ **
+ ** You should have received a copy of the GNU General Public License along
+ ** with Supermodel. If not, see .
+ **/
+
+/*
+ * DSB.cpp
+ *
+ * Sega Digital Sound Board (MPEG audio). Implementation of the CDSB1 and CDSB2
+ * classes. Based on code donated by R. Belmont. Many Bothans died to bring us
+ * this emulation.
+ *
+ * TODO List
+ * ---------
+ * - Music looping on DSB2 does not work in Daytona 2 (will play next track).
+ * - Check actual MPEG sample rate. So far, all games seem to use 32 KHz, which
+ * may be a hardware requirement, but if other sampling rates are allowable,
+ * the code here will fail (it is hard coded for 32 KHz).
+ * - Should we do some bounds checking on the MPEG start/end points?
+ */
+
+#include "Supermodel.h"
+
+
+/******************************************************************************
+ Resampler
+
+ MPEG Layer 2 audio can be 32, 44.1, or 48 KHz. Here, an up-sampling algorithm
+ is provided, which should work for any frequency less than 44.1 KHz and an
+ output frequency of 44.1 KHz. Down-sampling is not yet implemented, but would
+ work in a similar fashion. The chief difference is that the input index would
+ sometimes advance by more than one for a single output sample and the
+ fractions, nFrac and pFrac, would sometimes exceed 1.0.
+
+ Up-Sampling Description
+ -----------------------
+
+ Linear interpolation is used to up-sample. Not as accurate as the Shannon
+ reconstruction equation but it seems to work quite well.
+
+ 1. Linear Interpolation
+
+ Input samples for a given frame (here, this means 1/60Hz, not to be confused
+ with an MPEG frame, which is shorter) are numbered 0 ... L-1 (L samples in
+ total). Output samples are 0 ... M-1.
+
+ For two adjacent input samples at times p ("previous") and n ("next"), in[p]
+ and in[n], and output out[t] at time t, linear interpolation yields:
+
+ out[t] = (n-t)/(n-p) * in[p] + (t-p)/(n-p) * in[n]
+
+ Note that (n-p) = 1/fin (fin being the input sampling frequency).
+
+ Let pFrac = (n-t)/(n-p) and nFrac = (t-p)/(n-p). As t moves from p to n, pFrac
+ moves from 1 to 0 and nFrac from 0 to 1, as we expect.
+
+ If we proceed one output sample at a time, we must add the time difference
+ between output samples, 1/fout, to t. Call this delta_t. If we divide delta_t
+ by (n-p), we can add it directly to nFrac and subtract from pFrac. Therefore:
+
+ delta = (1/fout)/(n-p) = fin/fout
+
+ What happens when nFrac exceeds 1.0 or pFrac goes below 0.0? That can't
+ be allowed to happen -- it means that we've actually moved along the line into
+ the region between the next set of samples. We use pFrac < 0 as the condition
+ to update the input samples.
+
+ It so happens that when fin < fout, pFrac and nFrac will never exceed 1.0. So
+ there is no need to check or mask the fixed point values when using them to
+ interpolate samples.
+
+ 2. Input Buffer Overflows
+
+ For some low sampling rates, particularly those that are a factor of 2 or 4
+ smaller, it is possible that the very last sample or two needed from the input
+ stream will be beyond the end. Fetching two extra samples (which can introduce
+ an update lag of two samples -- imperceptible and inconsequential) fixes this,
+ and so we do it.
+
+ 3. Continuity Between Frames
+
+ The very last output sample will typically sit somewhere between two input
+ samples. It is wrong to start the next frame by assuming everything is lined
+ up again. The first sample of the next frame will often have to be interpol-
+ ated with the last sample of the previous frame. To facilitate this, we check
+ to see how many input samples remain unprocessed when up-sampling is finished,
+ and then copy those to the beginning of the buffer. We then return the number
+ of samples so that the buffer update function will know to skip them.
+
+ We also must maintain the state of pFrac and nFrac to resume interpolation
+ correctly. Therefore, these variables are persistent.
+
+ 4. Fixed Point Arithmetic
+
+ Fixed point arithmetic is used to track fractions. For such numbers, the low
+ 8 bits represent a fraction (0x100 would be 1.0, 0x080 would be 0.5, etc.)
+ and the upper bits are the integral portion.
+******************************************************************************/
+
+void CDSBResampler::Reset(void)
+{
+ // Initial state of fractions (24.8 fixed point)
+ nFrac = 0<<8; // fraction of next sample to use (0->1.0 as x moves p->n)
+ pFrac = 1<<8; // previous sample (1.0->0 as x moves p->n)
+}
+
+// Mixes 16-bit samples (sign extended in a and b)
+static inline INT16 MixAndClip(INT32 a, INT32 b)
+{
+ a += b;
+ if (a > 32767)
+ a = 32767;
+ else if (a < -32768)
+ a = -32768;
+ return (INT16) a;
+}
+
+// Mixes audio and returns number of samples copied back to start of buffer (ie. offset at which new samples should be written)
+int CDSBResampler::UpSampleAndMix(INT16 *outL, INT16 *outR, INT16 *inL, INT16 *inR, int sizeOut, int sizeIn, int outRate, int inRate)
+{
+ int delta = (inRate<<8)/outRate; // (1/fout)/(1/fin)=fin/fout, 24.8 fixed point
+ int outIdx = 0;
+ int inIdx = 0;
+ INT16 leftSample, rightSample;
+
+ while (outIdx < sizeOut)
+ {
+ // nFrac, pFrac will never exceed 1.0 (0x100) (only true if delta does not exceed 1)
+ leftSample = ((int)inL[inIdx]*pFrac+(int)inL[inIdx+1]*nFrac) >> 8; // left channel
+ rightSample = ((int)inR[inIdx]*pFrac+(int)inR[inIdx+1]*nFrac) >> 8; // right channel
+
+
+ outL[outIdx] = MixAndClip(outL[outIdx], leftSample);
+ outR[outIdx] = MixAndClip(outR[outIdx], rightSample);
+ outIdx++;
+
+ // Time step
+ pFrac -= delta;
+ nFrac += delta;
+
+ // Time to move to next samples?
+ if (pFrac <= 0) // when pFrac becomes 0, advance samples, reset pFrac to 1
+ {
+ pFrac += (1<<8);
+ nFrac -= (1<<8);
+ inIdx++; // advance samples (for upsampling only; downsampling may advance by more than one -- add delta every loop iteration)
+
+ }
+ }
+
+ // Copy remaining "active" input samples to start of buffer
+ int i = 0;
+ int j = inIdx;
+ while (j < sizeIn)
+ {
+ inL[i] = inL[j];
+ inR[i] = inR[j];
+ i++;
+ j++;
+ }
+ return i; // first free position in input buffer to copy next MPEG update to
+}
+
+
+/******************************************************************************
+ Digital Sound Board Type 1: Z80 CPU
+******************************************************************************/
+
+UINT8 CDSB1::Read8(UINT32 addr)
+{
+ // ROM: 0x0000-0x7FFF
+ if (addr < 0x8000)
+ return progROM[addr];
+
+ // RAM: 0x8000-0xFFFF
+ return ram[addr&0x7FFF];
+}
+
+void CDSB1::Write8(UINT32 addr, UINT8 data)
+{
+ if (addr >= 0x8000)
+ ram[addr&0x7FFF] = data;
+}
+
+void CDSB1::IOWrite8(UINT32 addr, UINT8 data)
+{
+ switch ((addr&0xFF))
+ {
+ case 0xE0: // MPEG trigger
+ mpegState = data;
+
+ if (data == 0) // stop
+ {
+ MPEG_StopPlaying();
+ return;
+ }
+
+ if (data == 1) // play without loop
+ {
+ MPEG_SetLoop(NULL, 0);
+ //printf("====> Playing %06X\n", mpegStart);
+ MPEG_PlayMemory((const char *) &mpegROM[mpegStart], mpegEnd-mpegStart);
+ return;
+ }
+
+ if (data == 2) // play with loop
+ {
+ //printf("====> Playing %06X\n", mpegStart);
+ MPEG_PlayMemory((const char *) &mpegROM[mpegStart], mpegEnd-mpegStart);
+ return;
+ }
+ break;
+
+ case 0xE2: // MPEG start, high byte
+ startLatch &= 0x00FFFF;
+ startLatch |= ((UINT32)data) << 16;
+ break;
+
+ case 0xE3: // MPEG start, middle byte
+ startLatch &= 0xFF00FF;
+ startLatch |= ((UINT32)data) << 8;
+ break;
+
+ case 0xE4: // MPEG start, low byte
+ startLatch &= 0xFFFF00;
+ startLatch |= data;
+
+ if (mpegState == 0)
+ {
+ mpegStart = startLatch;
+ //printf("mpegStart = %08X\n", mpegStart);
+ }
+ else
+ {
+ loopStart = startLatch;
+ //printf("loopStart = %08X\n", loopStart);
+ // SWA: if loop end is zero, it means "keep previous end marker"
+ if (loopEnd == 0)
+ {
+ MPEG_SetLoop((const char *) &mpegROM[loopStart], mpegEnd-loopStart);
+ }
+ else
+ {
+ MPEG_SetLoop((const char *) &mpegROM[loopStart], loopEnd-loopStart);
+ }
+ }
+
+ break;
+
+ case 0xE5: // MPEG end, high byte
+ endLatch &= 0x00FFFF;
+ endLatch |= ((UINT32)data) << 16;
+ break;
+
+ case 0xE6: // MPEG end, middle byte
+ endLatch &= 0xFF00FF;
+ endLatch |= ((UINT32)data) << 8;
+ break;
+
+ case 0xE7: // MPEG end, low byte
+ endLatch &= 0xFFFF00;
+ endLatch |= data;
+
+ if (mpegState == 0)
+ {
+ mpegEnd = endLatch;
+ //printf("mpegEnd = %08X\n", mpegEnd);
+ }
+ else
+ {
+ loopEnd = endLatch;
+ //printf("loopEnd = %08X\n", loopEnd);
+ MPEG_SetLoop((const char *) &mpegROM[loopStart], loopEnd-loopStart);
+ }
+ break;
+
+ case 0xE8: // MPEG volume
+ break;
+
+ case 0xE9: // MPEG stereo
+ break;
+
+ case 0xF0: // command echo back
+ break;
+
+ default:
+ //printf("Z80 Port %02X=%08X\n", addr, data);
+ break;
+ }
+}
+
+UINT8 CDSB1::IORead8(UINT32 addr)
+{
+ int progress;
+
+ switch ((addr&0xFF))
+ {
+ case 0xE2: // MPEG position, high byte
+ progress = MPEG_GetProgress() + mpegStart; // byte address currently playing
+ return (progress>>16)&0xFF;
+
+ case 0xE3: // MPEG position, middle byte
+ progress = MPEG_GetProgress() + mpegStart;
+ return (progress>>8)&0xFF;
+
+ case 0xE4: // MPEG position, low byte
+ progress = MPEG_GetProgress() + mpegStart;
+ return progress&0xFF;
+
+ case 0xF0: // Latch
+ UINT8 d;
+ d = fifo[fifoIdxR]; // retrieve next command byte
+ if (fifoIdxR != fifoIdxW) // if these are equal, nothing has been written yet (don't advance)
+ {
+ fifoIdxR++;
+ fifoIdxR &= 127;
+ }
+
+ if (fifoIdxR == fifoIdxW) // FIFO empty?
+ status &= ~2; // yes, indicate no commands left
+ else
+ status |= 2;
+
+ Z80.SetINT(FALSE); // clear IRQ
+ //printf("Z80: INT cleared, read from FIFO\n");
+ return d;
+
+ case 0xF1: // Status
+ /*
+ * Bit 0: Must be 1 for most games.
+ * Bit 1: Command pending (used by SWA instead of IRQ)
+ * SWA requires (status&0x38)==0 or else it loops endlessly
+ */
+ return status;
+ }
+
+ //printf("Z80 Port Read %02X\n", addr);
+ return 0;
+}
+
+static int Z80IRQCallback(CZ80 *Z80)
+{
+ return 0x38;
+}
+
+void CDSB1::SendCommand(UINT8 data)
+{
+ /*
+ * Commands are buffered in a FIFO. This probably does not actually exist
+ * on the real DSB but is necessary because the Z80 is not really synced
+ * up with the other CPUs and must process all commands it has received
+ * over the course of a frame at once.
+ */
+ fifo[fifoIdxW++] = data;
+ fifoIdxW &= 127;
+ //printf("Write FIFO: %02X\n", data);
+
+ // Have we caught up to the read pointer?
+#ifdef DEBUG
+ if (fifoIdxW == fifoIdxR)
+ printf("DSB1 FIFO overflow!\n");
+#endif
+}
+
+void CDSB1::RunFrame(INT16 *audioL, INT16 *audioR)
+{
+#ifdef SUPERMODEL_SOUND
+ int cycles;
+
+ // While FIFO not empty, fire interrupts, run for up to one frame
+ for (cycles = (4000000/60)/4; (cycles > 0) && (fifoIdxR != fifoIdxW); )
+ {
+ Z80.SetINT(TRUE); // fire an IRQ to indicate pending command
+ //printf("Z80 INT fired\n");
+ cycles -= Z80.Run(500);
+ }
+
+ // Run remaining cycles
+ Z80.Run(cycles);
+
+ // Decode MPEG for this frame
+ INT16 *mpegFill[2] = { &mpegL[retainedSamples], &mpegR[retainedSamples] };
+ MPEG_Decode(mpegFill, 32000/60-retainedSamples+2);
+ retainedSamples = Resampler.UpSampleAndMix(audioL, audioR, mpegL, mpegR, 44100/60, 32000/60+2, 44100, 32000);
+
+#endif
+}
+
+void CDSB1::Reset(void)
+{
+ MPEG_StopPlaying();
+ Resampler.Reset();
+ retainedSamples = 0;
+
+ memset(fifo, 0, sizeof(fifo));
+ fifoIdxW = fifoIdxR = 0;
+
+ status = 1;
+ mpegState = 0; // why doesn't RB ever init this?
+
+ Z80.Reset();
+ DebugLog("DSB1 Reset\n");
+}
+
+// Offsets of memory regions within DSB2's pool
+#define DSB1_OFFSET_RAM 0 // 32KB Z80 RAM
+#define DSB1_OFFSET_MPEG_LEFT 0x8000 // 1604 bytes (48 KHz max., 1/60th second, 2 extra = 2*(48000/60+2)) left MPEG buffer
+#define DSB1_OFFSET_MPEG_RIGHT 0x8644 // 1604 bytes right MPEG buffer
+#define DSB1_MEMORY_POOL_SIZE (0x8000+0x644+0x644)
+
+BOOL CDSB1::Init(const UINT8 *progROMPtr, const UINT8 *mpegROMPtr)
+{
+ float memSizeMB = (float)DSB1_MEMORY_POOL_SIZE/(float)0x100000;
+
+ // Receive ROM
+ progROM = progROMPtr;
+ mpegROM = mpegROMPtr;
+
+ // Allocate memory pool
+ memoryPool = new(std::nothrow) UINT8[DSB1_MEMORY_POOL_SIZE];
+ if (NULL == memoryPool)
+ return ErrorLog("Insufficient memory for DSB1 board (needs %1.1f MB).", memSizeMB);
+ memset(memoryPool, 0, DSB1_MEMORY_POOL_SIZE);
+
+ // Set up memory pointers
+ ram = &memoryPool[DSB1_OFFSET_RAM];
+ mpegL = (INT16 *) &memoryPool[DSB1_OFFSET_MPEG_LEFT];
+ mpegR = (INT16 *) &memoryPool[DSB1_OFFSET_MPEG_RIGHT];
+
+ // Initialize Z80 CPU
+ Z80.Init(this, Z80IRQCallback);
+
+ // MPEG decoder
+ if (OKAY != MPEG_Init())
+ return ErrorLog("Insufficient memory to initialize MPEG decoder.");
+ retainedSamples = 0;
+
+ return OKAY;
+}
+
+CDSB1::CDSB1(void)
+{
+ progROM = NULL;
+ mpegROM = NULL;
+ memoryPool = NULL;
+ ram = NULL;
+ mpegL = NULL;
+ mpegR = NULL;
+
+ DebugLog("Built DSB1 Board\n");
+}
+
+CDSB1::~CDSB1(void)
+{
+ MPEG_Shutdown();
+
+ if (memoryPool != NULL)
+ {
+ delete [] memoryPool;
+ memoryPool = NULL;
+ }
+
+ progROM = NULL;
+ mpegROM = NULL;
+ ram = NULL;
+ mpegL = NULL;
+ mpegR = NULL;
+
+ DebugLog("Destroyed DSB1 Board\n");
+}
+
+
+/******************************************************************************
+ Digital Sound Board Type 2: 68K CPU
+******************************************************************************/
+
+enum
+{
+ ST_IDLE = 0,
+ ST_GOT14, // start/loop addr
+ ST_14_0,
+ ST_14_1,
+ ST_GOT24, // end addr
+ ST_24_0,
+ ST_24_1,
+ ST_GOT74,
+ ST_GOTA0,
+ ST_GOTA1,
+ ST_GOTA4,
+ ST_GOTA5,
+ ST_GOTB0,
+ ST_GOTB1,
+ ST_GOTB4,
+ ST_GOTB5,
+};
+
+void CDSB2::WriteMPEGFIFO(UINT8 byte)
+{
+ //printf("fifo: %x (state %d)\n", byte, mpegState);
+ switch (mpegState)
+ {
+ case ST_IDLE:
+ if (byte == 0x14) mpegState = ST_GOT14;
+ else if (byte == 0x15) mpegState = ST_GOT14;
+ else if (byte == 0x24) mpegState = ST_GOT24;
+ else if (byte == 0x25) mpegState = ST_GOT24;
+
+ else if (byte == 0x74 || byte == 0x75) // "start play"
+ {
+ MPEG_PlayMemory((const char *) &mpegROM[mpegStart], mpegEnd-mpegStart);
+ mpegState = ST_IDLE;
+ playing = 1;
+ }
+
+ else if (byte == 0x84 || byte == 0x85)
+ {
+ MPEG_StopPlaying();
+ playing = 0;
+ }
+
+ else if (byte == 0xa0) mpegState = ST_GOTA0;
+ else if (byte == 0xa1) mpegState = ST_GOTA1;
+ else if (byte == 0xa4) mpegState = ST_GOTA4;
+ else if (byte == 0xa5) mpegState = ST_GOTA5;
+
+ else if (byte == 0xb0) mpegState = ST_GOTB0;
+ else if (byte == 0xb1) mpegState = ST_GOTB1;
+ else if (byte == 0xb4) mpegState = ST_GOTB4;
+ else if (byte == 0xb5) mpegState = ST_GOTB5;
+
+ break;
+
+ case ST_GOT14:
+ mpegStart &= ~0xff0000;
+ mpegStart |= (byte<<16);
+ mpegState++;
+ break;
+ case ST_14_0:
+ mpegStart &= ~0xff00;
+ mpegStart |= (byte<<8);
+ mpegState++;
+ break;
+ case ST_14_1:
+ mpegStart &= ~0xff;
+ mpegStart |= (byte);
+ mpegState = ST_IDLE;
+
+ if (playing)
+ {
+ //printf("Setting loop point to %x\n", mpegStart);
+ MPEG_PlayMemory((const char *) &mpegROM[mpegStart], mpegEnd-mpegStart);
+ }
+
+ //printf("mpegStart=%x\n", mpegStart);
+ break;
+ case ST_GOT24:
+ mpegEnd &= ~0xff0000;
+ mpegEnd |= (byte<<16);
+ mpegState++;
+ break;
+ case ST_24_0:
+ mpegEnd &= ~0xff00;
+ mpegEnd |= (byte<<8);
+ mpegState++;
+ break;
+ case ST_24_1:
+ mpegEnd &= ~0xff;
+ mpegEnd |= (byte);
+ //printf("mpegEnd=%x\n", mpegEnd);
+
+ // default to full stereo
+// mixer_set_stereo_volume(0, 255, 255);
+// mixer_set_stereo_pan(0, MIXER_PAN_RIGHT, MIXER_PAN_LEFT);
+ mpegState = ST_IDLE;
+ break;
+ case ST_GOTA0:
+ // ch 0 mono
+// mixer_set_stereo_volume(0, 0, 255);
+// printf("ch 0 mono\n");
+// mixer_set_stereo_pan(0, MIXER_PAN_CENTER, MIXER_PAN_CENTER);
+ mpegState = ST_IDLE;
+ break;
+ case ST_GOTA1:
+ mpegState = ST_IDLE;
+ break;
+ case ST_GOTA4:
+ mpegState = ST_IDLE;
+ break;
+ case ST_GOTA5:
+ mpegState = ST_IDLE;
+ break;
+ case ST_GOTB0:
+ mpegState = ST_IDLE;
+ break;
+ case ST_GOTB1:
+ // ch 1 mono
+// printf("ch 1 mono\n");
+// mixer_set_stereo_volume(0, 255, 0);
+// mixer_set_stereo_pan(0, MIXER_PAN_CENTER, MIXER_PAN_CENTER);
+ mpegState = ST_IDLE;
+ break;
+ case ST_GOTB4:
+ mpegState = ST_IDLE;
+ break;
+ case ST_GOTB5:
+ mpegState = ST_IDLE;
+ break;
+ default:
+ break;
+ }
+}
+
+UINT8 CDSB2::Read8(UINT32 addr)
+{
+ if (addr < (128*1024))
+ return progROM[addr^1];
+
+ if (addr == 0xc00001)
+ {
+ return cmdLatch;
+ }
+ if (addr == 0xc00003) // bit 0 = command valid
+ {
+ return 1;
+ }
+
+ if (addr == 0xe80001)
+ {
+ return 0x01; // MPEG busy status: bit 1 = busy
+ } // polled by irq2, stored | 0x10 at f01010
+
+ if ((addr >= 0xf00000) && (addr < 0xf10000))
+ {
+ addr &= 0x1ffff;
+ return ram[addr^1];
+ }
+
+// printf("R8 @ %x\n", addr);
+ return 0;
+}
+
+UINT16 CDSB2::Read16(UINT32 addr)
+{
+ if (addr < (128*1024))
+ {
+ return *(UINT16 *) &progROM[addr];
+ }
+ if ((addr >= 0xf00000) && (addr < 0xf20000))
+ {
+ addr &= 0x1ffff;
+ return *(UINT16 *) &ram[addr];
+ }
+
+// printf("R16 @ %x\n", addr);
+ return 0;
+}
+
+UINT32 CDSB2::Read32(UINT32 addr)
+{
+ UINT32 hi, lo;
+
+ if (addr < (128*1024))
+ {
+ hi = *(UINT16 *) &progROM[addr];
+ lo = *(UINT16 *) &progROM[addr+2];
+ return (hi<<16)|lo;
+ }
+ if ((addr >= 0xf00000) && (addr < 0xf20000))
+ {
+ addr &= 0x1ffff;
+ hi = *(UINT16 *) &ram[addr];
+ lo = *(UINT16 *) &ram[addr+2];
+ return (hi<<16)|lo;
+ }
+// printf("R32 @ %x\n", addr);
+ return 0;
+}
+
+void CDSB2::Write8(UINT32 addr, UINT8 data)
+{
+ if ((addr >= 0xf00000) && (addr < 0xf20000))
+ {
+ addr &= 0x1ffff;
+ ram[addr^1] = data;
+ return;
+ }
+
+ if (addr == 0xd00001) return;
+
+ if (addr == 0xe00003)
+ {
+ WriteMPEGFIFO(data);
+ return;
+ }
+
+// printf("W8: %x @ %x (PC=%x)\n", data, addr, m68k_get_reg(NULL, M68K_REG_PC));
+}
+
+void CDSB2::Write16(UINT32 addr, UINT16 data)
+{
+ if ((addr >= 0xf00000) && (addr < 0xf20000))
+ {
+ addr &= 0x1ffff;
+ *(UINT16 *) &ram[addr] = data;
+ return;
+ }
+// printf("W16: %x @ %x\n", data, addr);
+}
+
+void CDSB2::Write32(UINT32 addr, UINT32 data)
+{
+ if ((addr >= 0xf00000) && (addr < 0xf20000))
+ {
+ addr &= 0x1ffff;
+ *(UINT16 *) &ram[addr+0] = (data>>16);
+ *(UINT16 *) &ram[addr+2] = data&0xFFFF;
+ return;
+ }
+// printf("W32: %x @ %x\n", data, addr);
+}
+
+void CDSB2::SendCommand(UINT8 data)
+{
+ /*
+ * Commands are buffered in a FIFO. This probably does not actually exist
+ * on the real DSB but is necessary because the Z80 is not really synced
+ * up with the other CPUs and must process all commands it has received
+ * over the course of a frame at once.
+ */
+ fifo[fifoIdxW++] = data;
+ fifoIdxW &= 127;
+ //printf("Write FIFO: %02X\n", data);
+
+ // Have we caught up to the read pointer?
+#ifdef DEBUG
+ if (fifoIdxW == fifoIdxR)
+ printf("DSB2 FIFO overflow!\n");
+#endif
+}
+
+
+void CDSB2::RunFrame(INT16 *audioL, INT16 *audioR)
+{
+#ifdef SUPERMODEL_SOUND
+ M68KSetContext(&M68K);
+
+ // While FIFO not empty...
+ while (fifoIdxR != fifoIdxW)
+ {
+ cmdLatch = fifo[fifoIdxR]; // retrieve next command byte
+ fifoIdxR++;
+ fifoIdxR &= 127;
+
+ M68KSetIRQ(1); // indicate pending command
+ //printf("68K INT fired\n");
+ M68KRun(500);
+ }
+
+ // Per-frame interrupt
+ M68KSetIRQ(2);
+ M68KRun(4000000/60);
+
+ M68KGetContext(&M68K);
+
+ // Decode MPEG for this frame
+ INT16 *mpegFill[2] = { &mpegL[retainedSamples], &mpegR[retainedSamples] };
+ MPEG_Decode(mpegFill, 32000/60-retainedSamples+2);
+ retainedSamples = Resampler.UpSampleAndMix(audioL, audioR, mpegL, mpegR, 44100/60, 32000/60+2, 44100, 32000);
+
+#endif
+}
+
+void CDSB2::Reset(void)
+{
+ MPEG_StopPlaying();
+ Resampler.Reset();
+ retainedSamples = 0;
+
+ memset(fifo, 0, sizeof(fifo));
+ fifoIdxW = fifoIdxR = 0;
+
+ mpegState = ST_IDLE;
+ playing = 0;
+
+ M68KSetContext(&M68K);
+ M68KReset();
+ M68KGetContext(&M68K);
+
+ DebugLog("DSB2 Reset\n");
+}
+
+// Offsets of memory regions within DSB2's pool
+#define DSB2_OFFSET_RAM 0 // 128KB 68K RAM
+#define DSB2_OFFSET_MPEG_LEFT 0x20000 // 1604 bytes (48 KHz max., 1/60th second, 2 extra = 2*(48000/60+2)) left MPEG buffer
+#define DSB2_OFFSET_MPEG_RIGHT 0x20644 // 1604 bytes right MPEG buffer
+#define DSB2_MEMORY_POOL_SIZE (0x20000+0x644+0x644)
+
+BOOL CDSB2::Init(const UINT8 *progROMPtr, const UINT8 *mpegROMPtr)
+{
+ float memSizeMB = (float)DSB2_MEMORY_POOL_SIZE/(float)0x100000;
+
+ // Receive ROM
+ progROM = progROMPtr;
+ mpegROM = mpegROMPtr;
+
+ // Allocate memory pool
+ memoryPool = new(std::nothrow) UINT8[DSB2_MEMORY_POOL_SIZE];
+ if (NULL == memoryPool)
+ return ErrorLog("Insufficient memory for DSB2 board (needs %1.1f MB).", memSizeMB);
+ memset(memoryPool, 0, DSB2_MEMORY_POOL_SIZE);
+
+ // Set up memory pointers
+ ram = &memoryPool[DSB2_OFFSET_RAM];
+ mpegL = (INT16 *) &memoryPool[DSB2_OFFSET_MPEG_LEFT];
+ mpegR = (INT16 *) &memoryPool[DSB2_OFFSET_MPEG_RIGHT];
+
+ // Initialize 68K CPU
+ M68KSetContext(&M68K);
+ M68KInit();
+ M68KAttachBus(this);
+ M68KSetIRQCallback(NULL); // use default behavior (autovector, clear interrupt)
+ M68KGetContext(&M68K);
+
+ // MPEG decoder
+ if (OKAY != MPEG_Init())
+ return ErrorLog("Insufficient memory to initialize MPEG decoder.");
+ retainedSamples = 0;
+
+ return OKAY;
+}
+
+CDSB2::CDSB2(void)
+{
+ progROM = NULL;
+ mpegROM = NULL;
+ memoryPool = NULL;
+ ram = NULL;
+ mpegL = NULL;
+ mpegR = NULL;
+
+ DebugLog("Built DSB2 Board\n");
+}
+
+CDSB2::~CDSB2(void)
+{
+ MPEG_Shutdown();
+
+ if (memoryPool != NULL)
+ {
+ delete [] memoryPool;
+ memoryPool = NULL;
+ }
+
+ progROM = NULL;
+ mpegROM = NULL;
+ ram = NULL;
+ mpegL = NULL;
+ mpegR = NULL;
+
+ DebugLog("Destroyed DSB2 Board\n");
+}
\ No newline at end of file
diff --git a/Src/Model3/DSB.h b/Src/Model3/DSB.h
new file mode 100644
index 0000000..590b9d2
--- /dev/null
+++ b/Src/Model3/DSB.h
@@ -0,0 +1,256 @@
+/**
+ ** Supermodel
+ ** A Sega Model 3 Arcade Emulator.
+ ** Copyright 2011 Bart Trzynadlowski
+ **
+ ** This file is part of Supermodel.
+ **
+ ** Supermodel is free software: you can redistribute it and/or modify it under
+ ** the terms of the GNU General Public License as published by the Free
+ ** Software Foundation, either version 3 of the License, or (at your option)
+ ** any later version.
+ **
+ ** Supermodel 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 General Public License for
+ ** more details.
+ **
+ ** You should have received a copy of the GNU General Public License along
+ ** with Supermodel. If not, see .
+ **/
+
+/*
+ * DSB.h
+ *
+ * Header file for the Sega Digital Sound Board (Type 1 and 2) devices. CDSB1
+ * is an implementation of the Z80-based DSB Type 1, and CDSB2 is the 68K-based
+ * Type 2 board. Only one may be active at a time because they rely on non-
+ * reentrant MPEG playback code.
+ */
+
+#ifndef INCLUDED_DSB_H
+#define INCLUDED_DSB_H
+
+#include "Types.h"
+#include "CPU/Bus.h"
+
+
+/******************************************************************************
+ Resampling
+
+ Used internally by the DSB's MPEG code. If this becomes sufficiently generic,
+ it can be moved to Sound/. Not intended for general use for now.
+******************************************************************************/
+
+/*
+ * CDSBResampler:
+ *
+ * Frame-by-frame resampler. Resamples one single frame of audio and maintains
+ * continuity between frames by copying unprocessed input samples to the
+ * beginning of the buffer and retaining the internal interpolation state.
+ *
+ * See DSB.cpp for a detailed description of how this works.
+ *
+ * NOTE: If the sampling frequencies change, it is probably best to call
+ * Reset(). Whether the resampler will otherwise behave correctly and stay
+ * within array bounds has not been verified.
+ *
+ * Designed for use at 60 Hz, for input frequencies of 11.025, 22.05, 16, and
+ * 32 KHz and 44.1 KHz output frequencies. Theoretically, it should be able to
+ * operate on most output frequencies and input frequencies that are simply
+ * lower, but it has not been extensively verified.
+ */
+class CDSBResampler
+{
+public:
+ int UpSampleAndMix(INT16 *outL, INT16 *outR, INT16 *inL, INT16 *inR, int sizeOut, int sizeIn, int outRate, int inRate);
+ void Reset(void);
+private:
+ int nFrac;
+ int pFrac;
+};
+
+
+/******************************************************************************
+ DSB Base Class
+******************************************************************************/
+
+/*
+ * CDSB:
+ *
+ * Abstract base class defining the common interface for both DSB board types.
+ */
+
+class CDSB: public CBus
+{
+public:
+ /*
+ * SendCommand(data):
+ *
+ * Send a MIDI command to the DSB board.
+ */
+ virtual void SendCommand(UINT8 data) = 0;
+
+ /*
+ * RunFrame(audioL, audioR):
+ *
+ * Runs one frame and updates the MPEG audio. Audio is mixed into the
+ * supplied buffers (they are assumed to already contain audio data).
+ *
+ * Parameters:
+ * audioL Left audio channel, one frame (44 KHz, 1/60th second).
+ * audioR Right audio channel.
+ */
+ virtual void RunFrame(INT16 *audioL, INT16 *audioR) = 0;
+
+ /*
+ * Reset(void):
+ *
+ * Resets the DSB. Must be called prior to RunFrame().
+ */
+ virtual void Reset(void) = 0;
+
+ /*
+ * Init(progROMPtr, mpegROMPtr):
+ *
+ * Initializes the DSB board. This member must be called first.
+ *
+ * Parameters:
+ * progROMPtr Program (68K or Z80) ROM.
+ * mpegROMPtr MPEG data ROM.
+ *
+ * Returns:
+ * OKAY if successful, otherwise FAIL.
+ */
+ virtual BOOL Init(const UINT8 *progROMPtr, const UINT8 *mpegROMPtr) = 0;
+};
+
+
+/******************************************************************************
+ DSB Classes
+
+ DSB1 and DSB2 hardware. The base class, CDSB, should ideally be dynamically
+ allocated using one of these. See CDSB for descriptions of member functions.
+******************************************************************************/
+
+/*
+ * CDSB1:
+ *
+ * Sega Digital Sound Board Type 1: Z80 plus custom gate array for MPEG
+ * decoding.
+ */
+class CDSB1: public CDSB
+{
+public:
+ // Read and write handlers for the Z80 (required by CBus)
+ UINT8 IORead8(UINT32 addr);
+ void IOWrite8(UINT32 addr, UINT8 data);
+ UINT8 Read8(UINT32 addr);
+ void Write8(UINT32 addr, UINT8 data);
+
+ // DSB interface (see CDSB definition)
+ void SendCommand(UINT8 data);
+ void RunFrame(INT16 *audioL, INT16 *audioR);
+ void Reset(void);
+ BOOL Init(const UINT8 *progROMPtr, const UINT8 *mpegROMPtr);
+
+ // Constructor and destructor
+ CDSB1(void);
+ ~CDSB1(void);
+
+private:
+ // Resampler
+ CDSBResampler Resampler;
+ int retainedSamples; // how many MPEG samples carried over from previous frame
+
+ // MPEG decode buffers (48KHz, 1/60th second + 2 extra padding samples)
+ INT16 *mpegL, *mpegR;
+
+ // DSB memory
+ const UINT8 *progROM; // Z80 program ROM (passed in from parent object)
+ const UINT8 *mpegROM; // MPEG music ROM
+ UINT8 *memoryPool; // all memory allocated here
+ UINT8 *ram; // Z80 RAM
+
+ // Command FIFO
+ UINT8 fifo[128];
+ int fifoIdxR; // read position
+ int fifoIdxW; // write position
+
+ // MPEG playback variables
+ int mpegStart;
+ int mpegEnd;
+ int mpegState;
+ int loopStart;
+ int loopEnd;
+
+ // Registers
+ UINT32 startLatch; // MPEG start address latch
+ UINT32 endLatch; // MPEG end address latch
+ UINT8 status;
+ UINT8 chain;
+ UINT8 cmdLatch;
+
+ // Z80 CPU
+ CZ80 Z80;
+};
+
+/*
+ * CDSB2:
+ *
+ * Sega Digital Sound Board Type 2: 68K CPU.
+ */
+class CDSB2: public CDSB
+{
+public:
+ // Read and write handlers for the 68K (required by CBus)
+ UINT8 Read8(UINT32 addr);
+ UINT16 Read16(UINT32 addr);
+ UINT32 Read32(UINT32 addr);
+ void Write8(UINT32 addr, UINT8 data);
+ void Write16(UINT32 addr, UINT16 data);
+ void Write32(UINT32 addr, UINT32 data);
+
+ // DSB interface (see definition of CDSB)
+ void SendCommand(UINT8 data);
+ void RunFrame(INT16 *audioL, INT16 *audioR);
+ void Reset(void);
+ BOOL Init(const UINT8 *progROMPtr, const UINT8 *mpegROMPtr);
+
+ // Constructor and destructor
+ CDSB2(void);
+ ~CDSB2(void);
+
+private:
+ // Private helper functions
+ void WriteMPEGFIFO(UINT8 byte);
+
+ // Resampler
+ CDSBResampler Resampler;
+ int retainedSamples; // how many MPEG samples carried over from previous frame
+
+ // MPEG decode buffers (48KHz, 1/60th second + 2 extra padding samples)
+ INT16 *mpegL, *mpegR;
+
+ // DSB memory
+ const UINT8 *progROM; // Z80 program ROM (passed in from parent object)
+ const UINT8 *mpegROM; // MPEG music ROM
+ UINT8 *memoryPool; // all memory allocated here
+ UINT8 *ram; // Z80 RAM
+
+ // Command FIFO
+ UINT8 fifo[128];
+ int fifoIdxR; // read position
+ int fifoIdxW; // write position
+
+ // Registers
+ int cmdLatch;
+ int mpegState;
+ int mpegStart, mpegEnd, playing;
+
+ // M68K CPU
+ M68KCtx M68K;
+};
+
+
+#endif // INCLUDED_DSB_H
diff --git a/Src/Model3/Model3.cpp b/Src/Model3/Model3.cpp
index 2a71980..e156bd6 100644
--- a/Src/Model3/Model3.cpp
+++ b/Src/Model3/Model3.cpp
@@ -1,5 +1,6 @@
//TODO: Update save state file format (must output) MIDI control port; will no longer be compatible with 0.1a save states
-//TODO: should sample roms be byteswapped? They currently are. This could also be done in the game list with the byteswap flag...
+//TODO: Star Wars expects bit 0x80 to be set when reading from MIDI control port. This should be made explicit! Lostwsga may behave similarly
+
/**
** Supermodel
** A Sega Model 3 Arcade Emulator.
@@ -1125,7 +1126,7 @@ void CModel3::Write8(UINT32 addr, UINT8 data)
// Sound Board
case 0x08:
- printf("PPC: %08X=%02X * (PC=%08X, LR=%08X)\n", addr, data, ppc_get_pc(), ppc_get_lr());
+ //printf("PPC: %08X=%02X * (PC=%08X, LR=%08X)\n", addr, data, ppc_get_pc(), ppc_get_lr());
if ((addr&0xF) == 0) // MIDI data port
SoundBoard.WriteMIDIPort(data);
else if ((addr&0xF) == 4) // MIDI control port
@@ -2112,23 +2113,38 @@ void CModel3::RunMainBoardFrame(void)
IRQ.Assert(0x02);
ppc_execute(10000); // TO-DO: Vblank probably needs to be longer. Maybe that's why some games run too fast/slow
- // Sound
+ /*
+ * Sound:
+ *
+ * Bit 0x20 of the MIDI control port appears to enable periodic interrupts,
+ * which are used to send MIDI commands. Often games will write 0x27, send
+ * a series of commands, and write 0x06 to stop. Other games, like Star
+ * Wars Trilogy and Sega Rally 2, will enable interrupts at the beginning
+ * by writing 0x37 and will disable/enable interrupts to control command
+ * output.
+ */
int irqCount = 0;
- while (midiCtrlPort == 0x27) // 27 triggers IRQ sequence, 06 stops it
+ while ((midiCtrlPort&0x20))
+ //while (midiCtrlPort == 0x27) // 27 triggers IRQ sequence, 06 stops it
{
+ // Don't waste time firing MIDI interrupts if game has disabled them
+ if ((IRQ.ReadIRQEnable()&0x40) == 0)
+ break;
+
+ // Process MIDI interrupt
IRQ.Assert(0x40);
- ppc_execute(200);
+ ppc_execute(200); // give PowerPC time to acknowledge IRQ
IRQ.Deassert(0x40);
- ppc_execute(200);
+ ppc_execute(200); // acknowledge that IRQ was deasserted (TODO: is this really needed?)
++irqCount;
- if (irqCount > (128))
+ if (irqCount > 128)
{
- printf("MIDI TIMEOUT!\n");
+ printf("MIDI FIFO OVERFLOW!\n");
break;
}
}
- IRQ.Deassert(0x40);
+ IRQ.Deassert(0x40); //todo: no longer needed, remove it
}
void CModel3::Reset(void)
@@ -2409,9 +2425,11 @@ static void Dump(const char *file, UINT8 *buf, unsigned size, BOOL reverse32, BO
#define OFFSET_VROM 0x9000000 // 64 MB
#define OFFSET_BACKUPRAM 0xD000000 // 128 KB
#define OFFSET_SECURITYRAM 0xD020000 // 128 KB
-#define OFFSET_SOUNDROM 0xD040000 // 512 KB
-#define OFFSET_SAMPLEROM 0xD0C0000 // 16 MB
-#define MEMORY_POOL_SIZE (0x800000+0x800000+0x8000000+0x4000000+0x20000+0x20000+0x80000+0x1000000)
+#define OFFSET_SOUNDROM 0xD040000 // 512 KB (68K sound board program)
+#define OFFSET_SAMPLEROM 0xD0C0000 // 16 MB (sound board samples)
+#define OFFSET_DSBPROGROM 0xE0C0000 // 128 KB (DSB program)
+#define OFFSET_DSBMPEGROM 0xE0E0000 // 16 MB (DSB MPEG data -- Z80 version only uses 8MB)
+#define MEMORY_POOL_SIZE (0x800000+0x800000+0x8000000+0x4000000+0x20000+0x20000+0x80000+0x1000000+0x20000+0x1000000)
const struct GameInfo * CModel3::GetGameInfo(void)
{
@@ -2428,6 +2446,8 @@ BOOL CModel3::LoadROMSet(const struct GameInfo *GameList, const char *zipFile)
{ "VROM", vrom },
{ "SndProg", soundROM },
{ "Samples", sampleROM },
+ { "DSBProg", dsbROM },
+ { "DSBMPEG", mpegROM },
{ NULL, NULL }
};
PPC_CONFIG PPCConfig;
@@ -2450,9 +2470,9 @@ BOOL CModel3::LoadROMSet(const struct GameInfo *GameList, const char *zipFile)
// Byte reverse the PowerPC ROMs (convert to little endian words)
Reverse32(crom, 0x800000+0x8000000);
- // Byte swap 68K ROMs
+ // Byte swap sound board 68K ROMs
Reverse16(soundROM, 0x80000);
- Reverse16(sampleROM, 0x1000000); // is this correct?
+ Reverse16(sampleROM, 0x1000000);
// Initialize CPU and configure hardware (CPU speed is set in Init())
if (Game->step >= 0x20) // Step 2.0+
@@ -2499,6 +2519,26 @@ BOOL CModel3::LoadROMSet(const struct GameInfo *GameList, const char *zipFile)
ppc_set_fetch(PPCFetchRegions);
+ // DSB board (if present)
+ if (Game->mpegBoard == 1) // Z80 board, do not byte swap program ROM
+ {
+ DSB = new(std::nothrow) CDSB1();
+ if (NULL == DSB)
+ return ErrorLog("Insufficient memory for Digital Sound Board object.");
+ if (OKAY != DSB->Init(dsbROM,mpegROM))
+ return FAIL;
+ }
+ else if (Game->mpegBoard == 2) // 68K board
+ {
+ Reverse16(dsbROM, 0x20000); // byte swap program ROM
+ DSB = new(std::nothrow) CDSB2();
+ if (NULL == DSB)
+ return ErrorLog("Insufficient memory for Digital Sound Board object.");
+ if (OKAY != DSB->Init(dsbROM,mpegROM))
+ return FAIL;
+ }
+ SoundBoard.AttachDSB(DSB);
+
// Apply ROM patches
Patch();
@@ -2525,6 +2565,7 @@ void CModel3::AttachInputs(CInputs *InputsPtr)
DebugLog("Model 3 attached inputs\n");
}
+// Model 3 initialization. Some initialization is deferred until ROMs are loaded in LoadROMSet()
BOOL CModel3::Init(unsigned ppcFrequencyParam, BOOL multiThreadedParam)
{
float memSizeMB = (float)MEMORY_POOL_SIZE/(float)0x100000;
@@ -2546,11 +2587,13 @@ BOOL CModel3::Init(unsigned ppcFrequencyParam, BOOL multiThreadedParam)
vrom = &memoryPool[OFFSET_VROM];
soundROM = &memoryPool[OFFSET_SOUNDROM];
sampleROM = &memoryPool[OFFSET_SAMPLEROM];
+ dsbROM = &memoryPool[OFFSET_DSBPROGROM];
+ mpegROM = &memoryPool[OFFSET_DSBMPEGROM];
backupRAM = &memoryPool[OFFSET_BACKUPRAM];
securityRAM = &memoryPool[OFFSET_SECURITYRAM];
SetCROMBank(0xFF);
- // Initialize other devices
+ // Initialize other devices (PowerPC and DSB initialized after ROMs loaded)
IRQ.Init();
PCIBridge.Init();
PCIBus.Init();
@@ -2561,8 +2604,9 @@ BOOL CModel3::Init(unsigned ppcFrequencyParam, BOOL multiThreadedParam)
return FAIL;
if (OKAY != GPU.Init(vrom,this,&IRQ,0x100)) // same for Real3D DMA interrupt
return FAIL;
- if (OKAY != SoundBoard.Init(soundROM,sampleROM,&IRQ,0x40))
+ if (OKAY != SoundBoard.Init(soundROM,sampleROM))
return FAIL;
+
#ifdef SUPERMODEL_DRIVEBOARD
DriveBoard.Init();
#endif
@@ -2589,10 +2633,14 @@ CModel3::CModel3(void)
vrom = NULL;
soundROM = NULL;
sampleROM = NULL;
+ dsbROM = NULL;
+ mpegROM = NULL;
cromBank = NULL;
backupRAM = NULL;
securityRAM = NULL;
+ DSB = NULL;
+
securityPtr = 0;
multiThreaded = true;
@@ -2630,18 +2678,27 @@ CModel3::~CModel3(void)
// Stop all threads
StopThreads();
+ // Free memory
if (memoryPool != NULL)
{
delete [] memoryPool;
memoryPool = NULL;
}
+ if (DSB != NULL)
+ {
+ delete DSB;
+ DSB = NULL;
+ }
+
Game = NULL;
ram = NULL;
crom = NULL;
vrom = NULL;
soundROM = NULL;
sampleROM = NULL;
+ dsbROM = NULL;
+ mpegROM = NULL;
cromBank = NULL;
backupRAM = NULL;
securityRAM = NULL;
diff --git a/Src/Model3/Model3.h b/Src/Model3/Model3.h
index 4bb795a..22af53a 100644
--- a/Src/Model3/Model3.h
+++ b/Src/Model3/Model3.h
@@ -250,7 +250,7 @@ public:
*/
CModel3(void);
~CModel3(void);
-
+
/*
* Private Property.
* Tresspassers will be shot! ;)
@@ -265,14 +265,14 @@ private:
UINT8 ReadSystemRegister(unsigned reg);
void WriteSystemRegister(unsigned reg, UINT8 data);
void Patch(void);
-
+
void RunMainBoardFrame(); // Runs the main board (PPC) for a frame
- bool StartThreads(); // Starts all threads
+ bool StartThreads(); // Starts all threads
void StopThreads(); // Stops all threads
void DeleteThreadObjects(); // Deletes all threads and synchronization objects
-
- static int StartSoundBoardThread(void *data); // Callback to start sound board thread
-#ifdef SUPERMODEL_DRIVEBOARD
+
+ static int StartSoundBoardThread(void *data); // Callback to start sound board thread
+#ifdef SUPERMODEL_DRIVEBOARD
static int StartDriveBoardThread(void *data); // Callback to start drive board thread
#endif
@@ -303,6 +303,8 @@ private:
UINT8 *vrom; // 64 MB VROM (video ROM, visible only to Real3D)
UINT8 *soundROM; // 512 KB sound ROM (68K program)
UINT8 *sampleROM; // 8 MB samples (68K)
+ UINT8 *dsbROM; // 128 KB DSB ROM (Z80 program)
+ UINT8 *mpegROM; // 8 MB DSB MPEG ROM
UINT8 *backupRAM; // 128 KB Backup RAM (battery backed)
UINT8 *securityRAM; // 128 KB Security Board RAM
@@ -318,23 +320,23 @@ private:
unsigned ppcFrequency; // clock frequency (Hz)
// Multiple threading
- bool multiThreaded; // True if should run CPUs in multiple threads, otherwise everything is run in a single thread
- bool startedThreads; // True if threads have been created and started
- CThread *sndBrdThread; // Sound board thread
-#ifdef SUPERMODEL_DRIVEBOARD
- CThread *drvBrdThread; // Drive board thread
-#endif
- bool sndBrdThreadDone; // Flag to indicate sound board thread has finished processing for current frame
-#ifdef SUPERMODEL_DRIVEBOARD
- bool drvBrdThreadDone; // Flag to indicate drive board thread has finished processing for current frame
-#endif
-
- // Thread synchronization objects
- CSemaphore *sndBrdThreadSync;
-#ifdef SUPERMODEL_DRIVEBOARD
- CSemaphore *drvBrdThreadSync;
-#endif
- CMutex *notifyLock;
+ bool multiThreaded; // True if should run CPUs in multiple threads, otherwise everything is run in a single thread
+ bool startedThreads; // True if threads have been created and started
+ CThread *sndBrdThread; // Sound board thread
+#ifdef SUPERMODEL_DRIVEBOARD
+ CThread *drvBrdThread; // Drive board thread
+#endif
+ bool sndBrdThreadDone; // Flag to indicate sound board thread has finished processing for current frame
+#ifdef SUPERMODEL_DRIVEBOARD
+ bool drvBrdThreadDone; // Flag to indicate drive board thread has finished processing for current frame
+#endif
+
+ // Thread synchronization objects
+ CSemaphore *sndBrdThreadSync;
+#ifdef SUPERMODEL_DRIVEBOARD
+ CSemaphore *drvBrdThreadSync;
+#endif
+ CMutex *notifyLock;
CCondVar *notifySync;
// Other devices
@@ -346,7 +348,8 @@ private:
C93C46 EEPROM; // 93C46 EEPROM
CTileGen TileGen; // Sega 2D tile generator
CReal3D GPU; // Real3D graphics hardware
- CSoundBoard SoundBoard; // Sound board
+ CSoundBoard SoundBoard; // Sound board
+ CDSB *DSB; // Digital Sound Board (type determined dynamically at load time)
#ifdef SUPERMODEL_DRIVEBOARD
CDriveBoard DriveBoard; // Drive board
#endif
diff --git a/Src/Model3/SoundBoard.cpp b/Src/Model3/SoundBoard.cpp
index 8b4e50d..94f19e8 100644
--- a/Src/Model3/SoundBoard.cpp
+++ b/Src/Model3/SoundBoard.cpp
@@ -1,4 +1,3 @@
-//TODO: clean up M68K interface. pass a bus pointer (SoundBoard should be derived from it), so that M68K handlers have access to CSoundBoard
//TODO: must store actual value of bank register so we can save it to save states
/**
** Supermodel
@@ -26,11 +25,7 @@
*
* Model 3 sound board. Implementation of the CSoundBoard class. This class can
* only be instantiated once because it relies on global variables (the non-OOP
- * 68K core).
- *
- * TO-DO List
- * ----------
- * - Optimize memory handlers (jump table).
+ * 68K core and an IRQ line).
*
* Bank Switching
* --------------
@@ -62,248 +57,261 @@
#include "Supermodel.h"
-//TEMP: these need to be dynamically allocated in the memory pool
-static INT16 leftBuffer[44100/60],rightBuffer[44100/60];
+// DEBUG
+//#define SUPERMODEL_LOG_AUDIO // define this to log all audio to sound.bin
+#ifdef SUPERMODEL_LOG_AUDIO
static FILE *soundFP;
+#endif
+
/******************************************************************************
68K Access Handlers
******************************************************************************/
-// Memory regions passed out of CSoundBoard object for global access handlers
-static UINT8 *sbRAM1, *sbRAM2;
-static const UINT8 *sbSoundROM, *sbSampleROM, *sbSampleBankLo, *sbSampleBankHi;
-
-static UINT8 Read8(UINT32 a)
+UINT8 CSoundBoard::Read8(UINT32 a)
{
- // SCSP RAM 1
- if ((a >= 0x000000) && (a <= 0x0FFFFF))
- return sbRAM1[a^1];
-
- // SCSP RAM 2
- else if ((a >= 0x200000) && (a <= 0x2FFFFF))
- return sbRAM2[(a-0x200000)^1];
+ switch ((a>>20)&0xF)
+ {
+ case 0x0: // SCSP RAM 1 (master): 000000-0FFFFF
+ return ram1[a^1];
- // Program ROM
- else if ((a >= 0x600000) && (a <= 0x67FFFF))
- return sbSoundROM[(a-0x600000)^1];
-
- // Sample ROM (low 2MB, fixed)
- else if ((a >= 0x800000) && (a <= 0x9FFFFF))
- return sbSampleROM[(a-0x800000)^1];
-
- // Sample ROM (bank)
- else if ((a >= 0xA00000) && (a <= 0xDFFFFF))
- return sbSampleBankLo[(a-0xA00000)^1];
-
- // Sample ROM (bank)
- else if ((a >= 0xE00000) && (a <= 0xFFFFFF))
- return sbSampleBankHi[(a-0xE00000)^1];
-
- // SCSP (Master)
- else if ((a >= 0x100000) && (a <= 0x10FFFF))
+ case 0x1: // SCSP registers (master): 100000-10FFFF (unlike real hardware, we mirror up to 1FFFFF)
return SCSP_Master_r8(a);
- // SCSP (Slave)
- else if ((a >= 0x300000) && (a <= 0x30FFFF))
+ case 0x2: // SCSP RAM 2 (slave): 200000-2FFFFF
+ return ram2[(a&0x0FFFFF)^1];
+
+ case 0x3: // SCSP registers (slave): 300000-30FFFF (unlike real hardware, we mirror up to 3FFFFF)
return SCSP_Slave_r8(a);
- // Unknown
- else
- {
+ case 0x6: // Program ROM: 600000-67FFFF (unlike real hardware, we mirror up to 6FFFFF here)
+ return soundROM[(a&0x07FFFF)^1];
+
+ case 0x8: // Sample ROM (low 2MB, fixed): 800000-9FFFFF
+ case 0x9:
+ return sampleROM[(a&0x1FFFFF)^1];
+
+ case 0xA: // Sample ROM (bank): A00000-DFFFFF
+ case 0xB:
+ case 0xC:
+ case 0xD:
+ return sampleBankLo[(a-0xA00000)^1];
+
+ case 0xE: // Sample ROM (bank): E00000-FFFFFF
+ case 0xF:
+ return sampleBankHi[(a&0x1FFFFF)^1];
+
+ default:
printf("68K: Unknown read8 %06X\n", a);
- return 0;
+ break;
}
+
+ return 0;
}
-static UINT16 Read16(UINT32 a)
+UINT16 CSoundBoard::Read16(UINT32 a)
{
- // SCSP RAM 1
- if ((a >= 0x000000) && (a <= 0x0FFFFF))
- return *(UINT16 *) &sbRAM1[a];
-
- // SCSP RAM 2
- else if ((a >= 0x200000) && (a <= 0x2FFFFF))
- return *(UINT16 *) &sbRAM2[(a-0x200000)];
+ switch ((a>>20)&0xF)
+ {
+ case 0x0: // SCSP RAM 1 (master): 000000-0FFFFF
+ return *(UINT16 *) &ram1[a];
- // Program ROM
- else if ((a >= 0x600000) && (a <= 0x67FFFF))
- return *(UINT16 *) &sbSoundROM[(a-0x600000)];
-
- // Sample ROM (low 2MB, fixed)
- else if ((a >= 0x800000) && (a <= 0x9FFFFF))
- return *(UINT16 *) &sbSampleROM[(a-0x800000)];
-
- // Sample ROM (bank)
- else if ((a >= 0xA00000) && (a <= 0xDFFFFF))
- return *(UINT16 *) &sbSampleBankLo[(a-0xA00000)];
-
- // Sample ROM (bank)
- else if ((a >= 0xE00000) && (a <= 0xFFFFFF))
- return *(UINT16 *) &sbSampleBankHi[(a-0xE00000)];
-
- // SCSP (Master)
- else if ((a >= 0x100000) && (a <= 0x10FFFF))
+ case 0x1: // SCSP registers (master): 100000-10FFFF
return SCSP_Master_r16(a);
- // SCSP (Slave)
- else if ((a >= 0x300000) && (a <= 0x30FFFF))
+ case 0x2: // SCSP RAM 2 (slave): 200000-2FFFFF
+ return *(UINT16 *) &ram2[a&0x0FFFFF];
+
+ case 0x3: // SCSP registers (slave): 300000-30FFFF
return SCSP_Slave_r16(a);
- // Unknown
- else
- {
+ case 0x6: // Program ROM: 600000-67FFFF
+ return *(UINT16 *) &soundROM[a&0x07FFFF];
+
+ case 0x8: // Sample ROM (low 2MB, fixed): 800000-9FFFFF
+ case 0x9:
+ return *(UINT16 *) &sampleROM[a&0x1FFFFF];
+
+ case 0xA: // Sample ROM (bank): A00000-DFFFFF
+ case 0xB:
+ case 0xC:
+ case 0xD:
+ return *(UINT16 *) &sampleBankLo[a-0xA00000];
+
+ case 0xE: // Sample ROM (bank): E00000-FFFFFF
+ case 0xF:
+ return *(UINT16 *) &sampleBankHi[a&0x1FFFFF];
+
+ default:
printf("68K: Unknown read16 %06X\n", a);
- return 0;
+ break;
}
+
+ return 0;
}
-static UINT32 Read32(UINT32 a)
-{
- // SCSP RAM 1
- if ((a >= 0x000000) && (a <= 0x0FFFFF))
- return (Read16(a)<<16)|Read16(a+2);
+UINT32 CSoundBoard::Read32(UINT32 a)
+{
+ UINT32 hi, lo;
- // SCSP RAM 2
- else if ((a >= 0x200000) && (a <= 0x2FFFFF))
- return (Read16(a)<<16)|Read16(a+2);
+ switch ((a>>20)&0xF)
+ {
+ case 0x0: // SCSP RAM 1 (master): 000000-0FFFFF
+ hi = *(UINT16 *) &ram1[a];
+ lo = *(UINT16 *) &ram1[a+2]; // TODO: clamp? Possible bounds hazard.
+ return (hi<<16)|lo;
- // Program ROM
- else if ((a >= 0x600000) && (a <= 0x67FFFF))
- return (Read16(a)<<16)|Read16(a+2);
-
- // Sample ROM (low 2MB, fixed)
- else if ((a >= 0x800000) && (a <= 0x9FFFFF))
- return (Read16(a)<<16)|Read16(a+2);
-
- // Sample ROM (bank)
- else if ((a >= 0xA00000) && (a <= 0xDFFFFF))
- return (Read16(a)<<16)|Read16(a+2);
-
- // Sample ROM (bank)
- else if ((a >= 0xE00000) && (a <= 0xFFFFFF))
- return (Read16(a)<<16)|Read16(a+2);
-
- // SCSP (Master)
- else if ((a >= 0x100000) && (a <= 0x10FFFF))
+ case 0x1: // SCSP registers (master): 100000-10FFFF
return SCSP_Master_r32(a);
- // SCSP (Slave)
- else if ((a >= 0x300000) && (a <= 0x30FFFF))
+ case 0x2: // SCSP RAM 2 (slave): 200000-2FFFFF
+ hi = *(UINT16 *) &ram2[a&0x0FFFFF];
+ lo = *(UINT16 *) &ram2[(a+2)&0x0FFFFF];
+ return (hi<<16)|lo;
+
+ case 0x3: // SCSP registers (slave): 300000-30FFFF
return SCSP_Slave_r32(a);
- // Unknown
- else
- {
+ case 0x6: // Program ROM: 600000-67FFFF
+ hi = *(UINT16 *) &soundROM[a&0x07FFFF];
+ lo = *(UINT16 *) &soundROM[(a+2)&0x07FFFF];
+ return (hi<<16)|lo;
+
+ case 0x8: // Sample ROM (low 2MB, fixed): 800000-9FFFFF
+ case 0x9:
+ hi = *(UINT16 *) &sampleROM[a&0x1FFFFF];
+ lo = *(UINT16 *) &sampleROM[(a+2)&0x1FFFFF];
+ return (hi<<16)|lo;
+
+ case 0xA: // Sample ROM (bank): A00000-DFFFFF
+ case 0xB:
+ case 0xC:
+ case 0xD:
+ hi = *(UINT16 *) &sampleBankLo[a-0xA00000];
+ lo = *(UINT16 *) &sampleBankLo[a+2-0xA00000];
+ return (hi<<16)|lo;
+
+ case 0xE: // Sample ROM (bank): E00000-FFFFFF
+ case 0xF:
+ hi = *(UINT16 *) &sampleBankHi[a&0x1FFFFF];
+ lo = *(UINT16 *) &sampleBankHi[(a+2)&0x1FFFFF];
+ return (hi<<16)|lo;
+
+ default:
printf("68K: Unknown read32 %06X\n", a);
- return 0;
+ break;
}
+
+ return 0;
}
-static void Write8(unsigned int a,unsigned char d)
+void CSoundBoard::Write8(unsigned int a,unsigned char d)
{
-
- // SCSP RAM 1
- if ((a >= 0x000000) && (a <= 0x0FFFFF))
- sbRAM1[a^1] = d;
-
- // SCSP RAM 2
- else if ((a >= 0x200000) && (a <= 0x2FFFFF))
- sbRAM2[(a-0x200000)^1] = d;
-
- // SCSP (Master)
- else if ((a >= 0x100000) && (a <= 0x10FFFF))
- SCSP_Master_w8(a,d);
-
- // SCSP (Slave)
- else if ((a >= 0x300000) && (a <= 0x30FFFF))
- SCSP_Slave_w8(a,d);
-
- // Bank register
- else if (a == 0x400001)
+ switch ((a>>20)&0xF)
{
- if ((d&0x10))
+ case 0x0: // SCSP RAM 1 (master): 000000-0FFFFF
+ ram1[a^1] = d;
+ break;
+
+ case 0x1: // SCSP registers (master): 100000-10FFFF
+ SCSP_Master_w8(a,d);
+ break;
+
+ case 0x2: // SCSP RAM 2 (slave): 200000-2FFFFF
+ ram2[(a&0x0FFFFF)^1] = d;
+ break;
+
+ case 0x3: // SCSP registers (slave): 300000-30FFFF
+ SCSP_Slave_w8(a,d);
+ break;
+
+ default:
+ if (a == 0x400001)
{
- sbSampleBankLo = &sbSampleROM[0xA00000];
- sbSampleBankHi = &sbSampleROM[0xE00000];
+ if ((d&0x10))
+ {
+ sampleBankLo = &sampleROM[0xA00000];
+ sampleBankHi = &sampleROM[0xE00000];
+ }
+ else
+ {
+ sampleBankLo = &sampleROM[0x200000];
+ sampleBankHi = &sampleROM[0x600000];
+ }
}
else
- {
- sbSampleBankLo = &sbSampleROM[0x200000];
- sbSampleBankHi = &sbSampleROM[0x600000];
- }
+ printf("68K: Unknown write8 %06X=%02X\n", a, d);
+ break;
}
-
- // Unknown
- else
- printf("68K: Unknown write8 %06X=%02X\n", a, d);
}
-static void Write16(unsigned int a,unsigned short d)
+void CSoundBoard::Write16(unsigned int a,unsigned short d)
{
+ switch ((a>>20)&0xF)
+ {
+ case 0x0: // SCSP RAM 1 (master): 000000-0FFFFF
+ *(UINT16 *) &ram1[a] = d;
+ break;
- // SCSP RAM 1
- if ((a >= 0x000000) && (a <= 0x0FFFFF))
- *(UINT16 *) &sbRAM1[a] = d;
-
- // SCSP RAM 2
- else if ((a >= 0x200000) && (a <= 0x2FFFFF))
- *(UINT16 *) &sbRAM2[(a-0x200000)] = d;
-
- // SCSP (Master)
- else if ((a >= 0x100000) && (a <= 0x10FFFF))
+ case 0x1: // SCSP registers (master): 100000-10FFFF
SCSP_Master_w16(a,d);
+ break;
- // SCSP (Slave)
- else if ((a >= 0x300000) && (a <= 0x30FFFF))
- SCSP_Slave_w16(a,d);
-
- // Unknown
- else
- printf("68K: Unknown write16 %06X=%04X\n", a, d);
+ case 0x2: // SCSP RAM 2 (slave): 200000-2FFFFF
+ *(UINT16 *) &ram2[a&0x0FFFFF] = d;
+ break;
+ case 0x3: // SCSP registers (slave): 300000-30FFFF
+ SCSP_Slave_w16(a,d);
+ break;
+
+ default:
+ printf("68K: Unknown write16 %06X=%04X\n", a, d);
+ break;
+ }
}
-static void Write32(unsigned int a,unsigned int d)
+void CSoundBoard::Write32(unsigned int a,unsigned int d)
{
- // SCSP RAM 1
- if ((a >= 0x000000) && (a <= 0x0FFFFF))
+ switch ((a>>20)&0xF)
{
- Write16(a,d>>16);
- Write16(a+2,d&0xFFFF);
- }
+ case 0x0: // SCSP RAM 1 (master): 000000-0FFFFF
+ *(UINT16 *) &ram1[a] = (d>>16);
+ *(UINT16 *) &ram1[a+2] = (d&0xFFFF);
+ break;
- // SCSP RAM 2
- else if ((a >= 0x200000) && (a <= 0x2FFFFF))
- {
- Write16(a,d>>16);
- Write16(a+2,d&0xFFFF);
- }
-
- // SCSP (Master)
- else if ((a >= 0x100000) && (a <= 0x10FFFF))
+ case 0x1: // SCSP registers (master): 100000-10FFFF
SCSP_Master_w32(a,d);
+ break;
- // SCSP (Slave)
- else if ((a >= 0x300000) && (a <= 0x30FFFF))
+ case 0x2: // SCSP RAM 2 (slave): 200000-2FFFFF
+ *(UINT16 *) &ram2[a&0x0FFFFF] = (d>>16);
+ *(UINT16 *) &ram2[(a+2)&0x0FFFFF] = (d&0xFFFF);
+ break;
+
+ case 0x3: // SCSP registers (slave): 300000-30FFFF
SCSP_Slave_w32(a,d);
-
- // Unknown
- else
+ break;
+
+ default:
printf("68K: Unknown write32 %06X=%08X\n", a, d);
+ break;
+ }
}
/******************************************************************************
SCSP 68K Callbacks
- The SCSP emulator drives the 68K via callbacks.
+ The SCSP emulator drives the 68K via callbacks. These have to live outside of
+ the CSoundBoard object for now, unfortunately.
******************************************************************************/
// Status of IRQ pins (IPL2-0) on 68K
+// TODO: can we get rid of this global variable altogether?
static int irqLine = 0;
-// Interrupt acknowledge callback (TODO: don't need this, default behavior in M68K.cpp is fine)
+// Interrupt acknowledge callback (TODO: don't need this, default behavior in M68K.cpp should be fine)
int IRQAck(int irqLevel)
{
M68KSetIRQ(0);
@@ -334,41 +342,55 @@ int SCSP68KRunCallback(int numCycles)
/******************************************************************************
- Sound Board Emulation
+ Sound Board Interface
******************************************************************************/
void CSoundBoard::WriteMIDIPort(UINT8 data)
{
SCSP_MidiIn(data);
+ if (NULL != DSB) // DSB receives all commands as well
+ DSB->SendCommand(data);
}
void CSoundBoard::RunFrame(void)
{
#ifdef SUPERMODEL_SOUND
+ // Run sound board first to generate SCSP audio
+ M68KSetContext(&M68K);
SCSP_Update();
+ M68KGetContext(&M68K);
+
+ // Run DSB and mix with existing audio
+ if (NULL != DSB)
+ DSB->RunFrame(audioL, audioR);
// Output the audio buffers
- OutputAudio(44100/60, leftBuffer, rightBuffer);
+ OutputAudio(44100/60, audioL, audioR);
+#ifdef SUPERMODEL_LOG_AUDIO
// Output to binary file
INT16 s;
for (int i = 0; i < 44100/60; i++)
- {
- s = ((UINT16)leftBuffer[i]>>8) | ((leftBuffer[i]&0xFF)<<8);
+ {
+ s = audioL[i];
fwrite(&s, sizeof(INT16), 1, soundFP); // left channel
- s = ((UINT16)rightBuffer[i]>>8) | ((rightBuffer[i]&0xFF)<<8);
+ s = audioR[i];
fwrite(&s, sizeof(INT16), 1, soundFP); // right channel
}
#endif
+#endif
}
void CSoundBoard::Reset(void)
{
- // lets hope he does better... ->
memcpy(ram1, soundROM, 16); // copy 68K vector table
- sbSampleBankLo = &sampleROM[0x200000]; // default banks
- sbSampleBankHi = &sampleROM[0x600000];
+ sampleBankLo = &sampleROM[0x200000]; // default banks
+ sampleBankHi = &sampleROM[0x600000];
+ M68KSetContext(&M68K);
M68KReset();
+ M68KGetContext(&M68K);
+ if (NULL != DSB)
+ DSB->Reset();
DebugLog("Sound Board Reset\n");
}
@@ -377,22 +399,28 @@ void CSoundBoard::Reset(void)
Configuration, Initialization, and Shutdown
******************************************************************************/
+void CSoundBoard::AttachDSB(CDSB *DSBPtr)
+{
+ DSB = DSBPtr;
+ DebugLog("Sound Board connected to DSB\n");
+}
+
// Offsets of memory regions within sound board's pool
#define OFFSET_RAM1 0 // 1 MB SCSP1 RAM
#define OFFSET_RAM2 0x100000 // 1 MB SCSP2 RAM
-#define MEMORY_POOL_SIZE (0x100000+0x100000)
+#define OFFSET_AUDIO_LEFT 0x200000 // 1470 bytes (16 bits, 44.1 KHz, 1/60th second) left audio channel
+#define OFFSET_AUDIO_RIGHT 0x2005BE // 1470 bytes right audio channel
+#define MEMORY_POOL_SIZE (0x100000+0x100000+0x5BE+0x5BE)
-BOOL CSoundBoard::Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr, CIRQ *ppcIRQObjectPtr, unsigned soundIRQBit)
+BOOL CSoundBoard::Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr)
{
float memSizeMB = (float)MEMORY_POOL_SIZE/(float)0x100000;
- // Attach IRQ controller
- ppcIRQ = ppcIRQObjectPtr;
- ppcSoundIRQBit = soundIRQBit;
-
// Receive sound ROMs
soundROM = soundROMPtr;
sampleROM = sampleROMPtr;
+ sampleBankLo = &sampleROM[0x200000];
+ sampleBankHi = &sampleROM[0x600000];
// Allocate all memory for RAM
memoryPool = new(std::nothrow) UINT8[MEMORY_POOL_SIZE];
@@ -403,37 +431,25 @@ BOOL CSoundBoard::Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr, CIRQ
// Set up memory pointers
ram1 = &memoryPool[OFFSET_RAM1];
ram2 = &memoryPool[OFFSET_RAM2];
+ audioL = (INT16 *) &memoryPool[OFFSET_AUDIO_LEFT];
+ audioR = (INT16 *) &memoryPool[OFFSET_AUDIO_RIGHT];
- // Make global copies of memory pointers for 68K access handlers
- sbRAM1 = ram1;
- sbRAM2 = ram2;
- sbSoundROM = soundROM;
- sbSampleROM = sampleROM;
- sbSampleBankLo = &sampleROM[0x200000];
- sbSampleBankHi = &sampleROM[0x600000];
-
// Initialize 68K core
+ M68KSetContext(&M68K);
M68KInit();
+ M68KAttachBus(this);
M68KSetIRQCallback(IRQAck);
- M68KSetFetch8Callback(Read8);
- M68KSetFetch16Callback(Read16);
- M68KSetFetch32Callback(Read32);
- M68KSetRead8Callback(Read8);
- M68KSetRead16Callback(Read16);
- M68KSetRead32Callback(Read32);
- M68KSetWrite8Callback(Write8);
- M68KSetWrite16Callback(Write16);
- M68KSetWrite32Callback(Write32);
+ M68KGetContext(&M68K);
// Initialize SCSPs
- SCSP_SetBuffers(leftBuffer, rightBuffer, 44100/60);
- SCSP_SetCB(SCSP68KRunCallback, SCSP68KIRQCallback, ppcIRQ, ppcSoundIRQBit);
+ SCSP_SetBuffers(audioL, audioR, 44100/60);
+ SCSP_SetCB(SCSP68KRunCallback, SCSP68KIRQCallback);
SCSP_Init(2);
SCSP_SetRAM(0, ram1);
SCSP_SetRAM(1, ram2);
// Binary logging
-#ifdef SUPERMODEL_SOUND
+#ifdef SUPERMODEL_LOG_AUDIO
soundFP = fopen("sound.bin","wb"); // delete existing file
fclose(soundFP);
soundFP = fopen("sound.bin","ab"); // append mode
@@ -444,9 +460,14 @@ BOOL CSoundBoard::Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr, CIRQ
CSoundBoard::CSoundBoard(void)
{
+ DSB = NULL;
memoryPool = NULL;
ram1 = NULL;
ram2 = NULL;
+ audioL = NULL;
+ audioR = NULL;
+ soundROM = NULL;
+ sampleROM = NULL;
DebugLog("Built Sound Board\n");
}
@@ -466,35 +487,15 @@ static void Reverse16(UINT8 *buf, unsigned size)
CSoundBoard::~CSoundBoard(void)
{
-#ifdef SUPERMODEL_SOUND
+#ifdef SUPERMODEL_LOG_AUDIO
// close binary log file
fclose(soundFP);
-//#if 0
- FILE *fp;
-
- Reverse16(ram1, 0x100000);
- Reverse16(ram2, 0x100000);
- fp = fopen("scspRAM1", "wb");
- if (NULL != fp)
- {
- fwrite(ram1, sizeof(UINT8), 0x100000, fp);
- fclose(fp);
- printf("dumped %s\n", "scspRAM1");
-
- }
- fp = fopen("scspRAM2", "wb");
- if (NULL != fp)
- {
- fwrite(ram2, sizeof(UINT8), 0x100000, fp);
- fclose(fp);
- printf("dumped %s\n", "scspRAM2");
-
- }
-//#endif
#endif
SCSP_Deinit();
+ DSB = NULL;
+
if (memoryPool != NULL)
{
delete [] memoryPool;
@@ -502,5 +503,10 @@ CSoundBoard::~CSoundBoard(void)
}
ram1 = NULL;
ram2 = NULL;
+ audioL = NULL;
+ audioR = NULL;
+ soundROM = NULL;
+ sampleROM = NULL;
+
DebugLog("Destroyed Sound Board\n");
}
diff --git a/Src/Model3/SoundBoard.h b/Src/Model3/SoundBoard.h
index 566b892..1d8ec60 100644
--- a/Src/Model3/SoundBoard.h
+++ b/Src/Model3/SoundBoard.h
@@ -28,15 +28,52 @@
#ifndef INCLUDED_SOUNDBOARD_H
#define INCLUDED_SOUNDBOARD_H
+#include "Types.h"
+#include "CPU/Bus.h"
+#include "Model3/DSB.h"
/*
* CSoundBoard:
*
* Model 3 sound board (68K CPU + 2 x SCSP).
*/
-class CSoundBoard
+class CSoundBoard: public CBus
{
public:
+ /*
+ * Read8(addr):
+ * Read16(addr):
+ * Read32(addr):
+ * Read64(addr):
+ *
+ * Read a byte, 16-bit word, or 32-bit long word from the 68K address
+ * space.
+ *
+ * Parameters:
+ * addr Address to read.
+ *
+ * Returns:
+ * Data at the address.
+ */
+ UINT8 Read8(UINT32 addr);
+ UINT16 Read16(UINT32 addr);
+ UINT32 Read32(UINT32 addr);
+
+ /*
+ * Write8(addr, data):
+ * Write16(addr, data):
+ * Write32(addr, data):
+ *
+ * Write a byte, word, or long word to the 68K address space.
+ *
+ * Parameters:
+ * addr Address to write.
+ * data Data to write.
+ */
+ void Write8(UINT32 addr, UINT8 data);
+ void Write16(UINT32 addr, UINT16 data);
+ void Write32(UINT32 addr, UINT32 data);
+
/*
* WriteMIDIPort(data):
*
@@ -61,6 +98,18 @@ public:
*/
void Reset(void);
+ /*
+ * AttachDSB(CDSB *DSBPtr):
+ *
+ * Connects a Digital Sound Board. The sound board passes MIDI commands,
+ * resets the board, and runs it each frame to generate audio. If there is
+ * no DSB, this function does not need to be called.
+ *
+ * Parameters:
+ * DSBPtr Pointer to DSB object.
+ */
+ void AttachDSB(CDSB *DSBPtr);
+
/*
* Init(soundROMPtr, sampleROMPtr):
*
@@ -69,14 +118,12 @@ public:
* Parameters:
* soundROMPtr Pointer to sound ROM (68K program).
* sampleROMPtr Pointer to sample ROM.
- * ppcIRQObjectPtr Pointer to PowerPC-side IRQ object.
- * soundIRQBit IRQ bit mask to use for sound board PowerPC IRQs.
*
* Returns:
* OKAY if successful, FAIL if unable to allocate memory. Prints own
* error messages.
*/
- BOOL Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr, CIRQ *ppcIRQObjectPtr, unsigned soundIRQBit);
+ BOOL Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr);
/*
* CSoundBoard(void):
@@ -88,15 +135,22 @@ public:
~CSoundBoard(void);
private:
- // PowerPC IRQ controller
- CIRQ *ppcIRQ;
- unsigned ppcSoundIRQBit;
+ // Digital Sound Board
+ CDSB *DSB;
+
+ // 68K context
+ M68KCtx M68K;
// Sound board memory
const UINT8 *soundROM; // 68K program ROM (passed in from parent object)
const UINT8 *sampleROM; // 68K sample ROM (passed in from parent object)
+ const UINT8 *sampleBankLo; // sample ROM bank switching
+ const UINT8 *sampleBankHi;
UINT8 *memoryPool; // single allocated region for all sound board RAM
UINT8 *ram1, *ram2; // SCSP1 and SCSP2 RAM
+
+ // Audio
+ INT16 *audioL, *audioR; // left and right audio channels (1/60th second, 44.1 KHz)
};
diff --git a/Src/OSD/SDL/Main.cpp b/Src/OSD/SDL/Main.cpp
index 28c57d2..07338fa 100644
--- a/Src/OSD/SDL/Main.cpp
+++ b/Src/OSD/SDL/Main.cpp
@@ -534,27 +534,6 @@ int Supermodel(const char *zipFile, CInputs *Inputs, unsigned ppcFrequency, BOOL
// Toggle frame limiting
noThrottle = !noThrottle;
printf("Frame limiting: %s\n", noThrottle?"Off":"On");
-/*
- SCSP_MidiIn(0xA0);
- SCSP_MidiIn(0x00);
- SCSP_MidiIn(0x01); // stop?
-
- SCSP_MidiIn(0xA0);
- SCSP_MidiIn(0x11);
- SCSP_MidiIn(0x2E);
-
- SCSP_MidiIn(0xA1);
- SCSP_MidiIn(0x70);
- SCSP_MidiIn(0x03);
-
- SCSP_MidiIn(0xAF);SCSP_MidiIn(0x10);SCSP_MidiIn(0x01);
- */
- SCSP_MidiIn(0xAF);SCSP_MidiIn(0x10);SCSP_MidiIn(0x00);
- //static int snd=0xF;
- //SCSP_MidiIn(0xA0);SCSP_MidiIn(0x11);SCSP_MidiIn(snd++);
- //Sound codes:
- // A0 11 xx (0F=time extend, 11=jumbo left right)
- // AF 10 xx (music -- 01 seems to work)
}
#ifdef SUPERMODEL_DEBUGGER
else if (Inputs->uiEnterDebugger->Pressed())
diff --git a/Src/ROMLoad.cpp b/Src/ROMLoad.cpp
index 00498bd..89610fb 100644
--- a/Src/ROMLoad.cpp
+++ b/Src/ROMLoad.cpp
@@ -68,7 +68,7 @@ static BOOL FindROMByCRCInGame(const struct GameInfo **gamePtr, int *romIdxPtr,
{
if (crc == Game->ROM[j].crc) // found it!
{
- *gamePtr = Game;
+ *gamePtr = Game; // I know this seems redundant, but we do it here because FindROMByCRC() uses this function
*romIdxPtr = j;
return OKAY;
}
@@ -97,6 +97,23 @@ static BOOL FindROMByCRC(const struct GameInfo **gamePtr, int *romIdxPtr, const
return FAIL;
}
+// Returns TRUE if this ROM appears only a single time in the entire game list (ie., it is not shared between games)
+static BOOL ROMIsUnique(const struct GameInfo *GameList, UINT32 crc)
+{
+ int timesFound = 0;
+
+ for (int i = 0; GameList[i].title != NULL; i++)
+ {
+ for (int j = 0; GameList[i].ROM[j].region != NULL; j++)
+ {
+ if (crc == GameList[i].ROM[j].crc)
+ timesFound++;
+ }
+ }
+
+ return (timesFound == 1) ? TRUE : FALSE;
+}
+
static void ByteSwap(UINT8 *buf, unsigned size)
{
unsigned i;
@@ -189,8 +206,9 @@ const struct GameInfo * LoadROMSetFromZIPFile(const struct ROMMap *Map, const st
{
unzFile zf;
unz_file_info fileInfo;
- const struct GameInfo *Game = NULL, *CurGame;
- int romIdx; // index within Game->ROM
+ const struct GameInfo *Game = NULL;
+ const struct GameInfo *CurGame; // this is the game to which the last ROM found is thought to belong
+ int romIdx; // index within Game->ROM
unsigned romsFound[sizeof(Game->ROM)/sizeof(struct ROMInfo)], numROMs;
int err;
unsigned i, n, maxSize;
@@ -205,8 +223,7 @@ const struct GameInfo * LoadROMSetFromZIPFile(const struct ROMMap *Map, const st
return NULL;
}
- // Check ROMs: scan ZIP file for first known ROM and check to ensure all ROMs are present
- memset(romsFound, 0, sizeof(romsFound));
+ // First pass: scan every file and determine the game
err = unzGoToFirstFile(zf);
if (UNZ_OK != err)
{
@@ -221,54 +238,73 @@ const struct GameInfo * LoadROMSetFromZIPFile(const struct ROMMap *Map, const st
continue;
if (OKAY != FindROMByCRC(&CurGame, &romIdx, GameList, Game, fileInfo.crc))
continue;
+
+ // If the ROM appears in multiple games, do not use it to identify the game!
+ if (!ROMIsUnique(GameList, fileInfo.crc))
+ continue;
+
+ // We have a unique ROM used by a single game; identify that game
if (Game == NULL) // this is the first game we've identified within the ZIP
{
Game = CurGame;
- DebugLog("%ROM set identified: %s (%s), %s\n", Game->id, Game->title, zipFile);
+ DebugLog("ROM set identified: %s (%s), %s\n", Game->id, Game->title, zipFile);
}
- else
+ else // we've already identified a game
{
- if (CurGame != Game)
+ if (CurGame != Game) // another game?
{
DebugLog("%s also contains: %s (%s)\n", zipFile, CurGame->id, CurGame->title);
if (multipleGameError == FALSE) // only warn about this once
{
+ printf("ROM=%s\n", CurGame->ROM[romIdx].fileName);
ErrorLog("Multiple games were found in %s; loading \"%s\".", zipFile, Game->title);
multipleGameError = TRUE;
}
}
}
-
- // If we have found a ROM for the correct game, mark it
- if (Game == CurGame)
- romsFound[romIdx] = 1;
}
- if (Game == NULL)
+ // Second pass: check if all ROM files for the identified game are present
+ err = unzGoToFirstFile(zf);
+ if (UNZ_OK != err)
{
- ErrorLog("%s contains no supported games.", zipFile);
+ ErrorLog("Unable to read the contents of %s (code %X)", zipFile, err);
return NULL;
}
+ memset(romsFound, 0, sizeof(romsFound)); // here, romsFound[] indicates which ROMs were found in the ZIP file for the game
+ for (; err != UNZ_END_OF_LIST_OF_FILE; err = unzGoToNextFile(zf))
+ {
+ // Identify the file we're looking at
+ err = unzGetCurrentFileInfo(zf, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
+ if (err != UNZ_OK)
+ continue;
+ // If it's not part of the game we've identified, skip it
+ if (OKAY != FindROMByCRCInGame(&CurGame, &romIdx, Game, fileInfo.crc))
+ continue;
+
+ // If we have found a ROM for the correct game, mark its corresponding indicator
+ romsFound[romIdx] = 1;
+ }
+
// Compute how many ROM files this game has
for (numROMs = 0; Game->ROM[numROMs].region != NULL; numROMs++)
;
-
+
// If not all ROMs were present, tell the user
err = OKAY;
for (i = 0; i < numROMs; i++)
{
if (romsFound[i] == 0)
- err |= ErrorLog("%s (CRC=%08X) is missing from %s.", Game->ROM[i].file, Game->ROM[i].crc, zipFile);
+ err |= ErrorLog("%s (CRC=%08X) is missing from %s.", Game->ROM[i].fileName, Game->ROM[i].crc, zipFile);
}
if (err != OKAY)
{
unzClose(zf);
return NULL;
- //return FAIL;
}
- // Allocate memory for the largest ROM to load
+ // Allocate a scratch buffer big enough to hold the biggest ROM
maxSize = 0;
for (i = 0; i < numROMs; i++)
{
@@ -283,8 +319,8 @@ const struct GameInfo * LoadROMSetFromZIPFile(const struct ROMMap *Map, const st
return NULL;
}
- // Load ROMs
- memset(romsFound, 0, sizeof(romsFound));
+ // Third pass: load the ROMs
+ memset(romsFound, 0, sizeof(romsFound)); // now, romsFound[] is used to indicate whether we successfully loaded the ROM
err = unzGoToFirstFile(zf);
if (UNZ_OK != err)
{
@@ -297,13 +333,14 @@ const struct GameInfo * LoadROMSetFromZIPFile(const struct ROMMap *Map, const st
err = unzGetCurrentFileInfo(zf, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
if (err != UNZ_OK)
continue;
- if (OKAY != FindROMByCRC(&CurGame, &romIdx, GameList, Game, fileInfo.crc))
+
+ // If this ROM is not part of the game we're loading, skip it
+ if (OKAY != FindROMByCRCInGame(&CurGame, &romIdx, Game, fileInfo.crc))
continue;
- if (CurGame == Game) // if ROM belongs to correct game
- {
- if (OKAY == LoadROM(buf, maxSize, Map, &Game->ROM[romIdx], zf, zipFile, loadAll))
- romsFound[romIdx] = 1; // success! mark as loaded
- }
+
+ // Load the ROM and mark that we did so successfully
+ if (OKAY == LoadROM(buf, maxSize, Map, &Game->ROM[romIdx], zf, zipFile, loadAll))
+ romsFound[romIdx] = 1; // success! mark as loaded
}
// Ensure all ROMs were loaded
@@ -315,7 +352,7 @@ const struct GameInfo * LoadROMSetFromZIPFile(const struct ROMMap *Map, const st
if (romsFound[i])
++n;
else
- ErrorLog("Failed to load %s (CRC=%08X) from %s.", Game->ROM[i].file, Game->ROM[i].crc, zipFile);
+ ErrorLog("Failed to load %s (CRC=%08X) from %s.", Game->ROM[i].fileName, Game->ROM[i].crc, zipFile);
}
if (n < numROMs)
err = FAIL;
diff --git a/Src/ROMLoad.h b/Src/ROMLoad.h
index 1d03174..53c23a4 100644
--- a/Src/ROMLoad.h
+++ b/Src/ROMLoad.h
@@ -44,7 +44,7 @@ struct ROMInfo
const char *region; // ROM region identifier (used as a key to search ROMMap)
// Information used to identify files
- const char *file; // file name
+ const char *fileName; // file name
UINT32 crc; // CRC-32 checksum (same as zip format)
unsigned fileSize; // file size in bytes (must be the same as all other ROMs with same region ID)
diff --git a/Src/Sound/MPEG/MPEG.h b/Src/Sound/MPEG/MPEG.h
new file mode 100644
index 0000000..29025d3
--- /dev/null
+++ b/Src/Sound/MPEG/MPEG.h
@@ -0,0 +1,114 @@
+/**
+ ** Supermodel
+ ** A Sega Model 3 Arcade Emulator.
+ ** Copyright 2011 Bart Trzynadlowski
+ **
+ ** This file is part of Supermodel.
+ **
+ ** Supermodel is free software: you can redistribute it and/or modify it under
+ ** the terms of the GNU General Public License as published by the Free
+ ** Software Foundation, either version 3 of the License, or (at your option)
+ ** any later version.
+ **
+ ** Supermodel 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 General Public License for
+ ** more details.
+ **
+ ** You should have received a copy of the GNU General Public License along
+ ** with Supermodel. If not, see .
+ **/
+
+/*
+ * MPEG.cpp
+ *
+ * Header file for MPEG decoder based on AMP by Tomislav Uzalec, modified to
+ * play from memory buffers by R. Belmont for his music player, M1.
+ */
+
+#ifndef INCLUDED_MPEG_H
+#define INCLUDED_MPEG_H
+
+#include "Types.h"
+
+
+/******************************************************************************
+ Functions
+
+ The MPEG decoder is not thread-safe and must not be used by multiple sources.
+ These functions are located in audio.cpp and getbits.cpp.
+******************************************************************************/
+
+/*
+ * MPEG_GetProgress(void):
+ *
+ * Returns:
+ * The current byte offset within the MPEG stream.
+ */
+extern int MPEG_GetProgress(void);
+
+/*
+ * MPEG_SetLoop(loop, loopend):
+ *
+ * Sets the start and end offsets for looped playback.
+ *
+ * Parameters:
+ * loop Start address.
+ * loopend End address.
+ */
+extern void MPEG_SetLoop(const char *loop, int loopend);
+
+/*
+ * MPEG_Decode(outputs, length):
+ *
+ * Decodes the requested number of samples from the currently playing MPEG
+ * stream and updates the internal play position. If an MPEG is not playing,
+ * writes silence (zeros).
+ *
+ * Parameters:
+ * outputs A two-element array of pointers to equal-length signed 16-
+ * bit sample buffers. The first is the left channel and the
+ * second is the right channel. Audio is decoded to these.
+ * length Number of samples to decode.
+ */
+extern void MPEG_Decode(INT16 **outputs, int length);
+
+/*
+ * MPEG_PlayMemory(sa, length):
+ *
+ * Specifies the memory buffer to decode from. This initializes the playback
+ * process and will decode the first MPEG frame internally.
+ *
+ * Parameters:
+ * sa Start address of MPEG stream.
+ * length Length in bytes.
+ */
+extern void MPEG_PlayMemory(const char *sa, int length);
+
+/*
+ * MPEG_StopPlaying(void):
+ *
+ * Stop playing the current MPEG stream. The decoder will return silence.
+ */
+extern void MPEG_StopPlaying(void);
+
+/*
+ * MPEG_Init(void):
+ *
+ * Initializes the MPEG decoder. This should be called once per program
+ * session. Allocates an internal buffer for MPEG decoding.
+ *
+ * Returns:
+ * OKAY if successful, FAIL if internal buffer could not be allocated.
+ */
+extern BOOL MPEG_Init(void);
+
+/*
+ * MPEG_Shutdown(void):
+ *
+ * Shuts down the MPEG decoder. Releases internal memory.
+ */
+extern void MPEG_Shutdown(void);
+
+
+#endif // INCLUDED_MPEG_H
\ No newline at end of file
diff --git a/Src/Sound/MPEG/amp.h b/Src/Sound/MPEG/amp.h
new file mode 100644
index 0000000..7bc0002
--- /dev/null
+++ b/Src/Sound/MPEG/amp.h
@@ -0,0 +1,63 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* these should not be touched
+*/
+#define SYNCWORD 0xfff
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* version
+*/
+#define MAJOR 0
+#define MINOR 7
+#define PATCH 6
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define MAX3(a,b,c) ((a) > (b) ? MAX(a, c) : MAX(b, c))
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+
+/* Debugging flags */
+
+struct debugFlags_t {
+ int audio,args,buffer,buffer2,misc,misc2;
+};
+
+struct debugLookup_t {
+ char *name; int *var;
+};
+
+extern struct debugFlags_t debugFlags;
+
+/* This is only here to keep all the debug stuff together */
+#ifdef AMP_UTIL
+struct debugLookup_t debugLookup[] = {
+ {"audio", &debugFlags.audio},
+ {"args", &debugFlags.args},
+ {"buffer", &debugFlags.buffer},
+ {"buffer2", &debugFlags.buffer2},
+ {"misc", &debugFlags.misc},
+ {"misc2", &debugFlags.misc2},
+ {0,0}
+};
+#endif /* AMP_UTIL */
+
+extern struct debugLookup_t debugLookup[];
+
+
+#ifdef DEBUG
+ #define DB(type,cmd) if (debugFlags.type) { cmd ; }
+#else
+ #define DB(type,cmd)
+#endif
+
+#include "config.h"
+#include "proto.h"
+
+
+extern int AUDIO_BUFFER_SIZE;
diff --git a/Src/Sound/MPEG/audio.cpp b/Src/Sound/MPEG/audio.cpp
new file mode 100644
index 0000000..dee1a23
--- /dev/null
+++ b/Src/Sound/MPEG/audio.cpp
@@ -0,0 +1,396 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* audio.c main amp source file
+ *
+ * Created by: tomislav uzelac Apr 1996
+ * Karl Anders Oygard added the IRIX code, 10 Mar 1997.
+ * Ilkka Karvinen fixed /dev/dsp initialization, 11 Mar 1997.
+ * Lutz Vieweg added the HP/UX code, 14 Mar 1997.
+ * Dan Nelson added FreeBSD modifications, 23 Mar 1997.
+ * Andrew Richards complete reorganisation, new features, 25 Mar 1997
+ * Edouard Lafargue added sajber jukebox support, 12 May 1997
+ */
+
+
+#include "amp.h"
+
+#define AUDIO
+#include "audio.h"
+#include "formats.h"
+#include "getbits.h"
+#include "huffman.h"
+#include "layer2.h"
+#include "layer3.h"
+#include "position.h"
+#include "rtbuf.h"
+#include "transform.h"
+
+//#ifndef __BEOS__
+//typedef int bool;
+//#endif
+
+#include
+#include
+#include "Types.h"
+#include "MPEG.h"
+
+//#include "m1snd.h"
+//#include "oss.h"
+//#include "mpeg.h"
+
+#define BUF_SIZE (1152 * sizeof(short) * 2)
+
+void calculate_t43(void);
+
+static int decoder_init = 0;
+static int cnt = 0;
+static int stream = -1;
+static char *buf0;
+static int playing = 0;
+static int outpos = 0;
+static int mpeg_eof = 0;
+static char *dst, *readbuf;
+static struct AUDIO_HEADER m1hdr;;
+
+void statusDisplay(struct AUDIO_HEADER *header, int frameNo)
+{
+ int minutes,seconds;
+
+ if ((A_SHOW_CNT || A_SHOW_TIME) && !(frameNo%10))
+ msg("\r");
+ if (A_SHOW_CNT && !(frameNo%10) ) {
+ msg("{ %d } ",frameNo);
+ }
+ if (A_SHOW_TIME && !(frameNo%10)) {
+ seconds=frameNo*1152/t_sampling_frequency[header->ID][header->sampling_frequency];
+ minutes=seconds/60;
+ seconds=seconds % 60;
+ msg("[%d:%02d]",minutes,seconds);
+ }
+ if (A_SHOW_CNT || A_SHOW_TIME)
+ fflush(stderr);
+}
+
+// one mpeg frame is 576 samples.
+int decodeMPEGOneFrame(struct AUDIO_HEADER *header)
+{
+ int snd_eof = 0, g;
+
+ if ((g=gethdr(header))!=0) {
+ report_header_error(g);
+ snd_eof=1;
+ return snd_eof;
+ }
+
+ if (header->protection_bit==0) getcrc();
+
+ statusDisplay(header,0);
+
+ if (header->layer==1) {
+ if (layer3_frame(header,cnt)) {
+ warn(" error. blip.\n");
+ return -1;
+ }
+ } else if (header->layer==2)
+ if (layer2_frame(header,cnt)) {
+ warn(" error. blip.\n");
+ return -1;
+ }
+
+ cnt++;
+
+ return snd_eof;
+}
+
+int decodeMPEG(void)
+{
+struct AUDIO_HEADER header;
+int g,snd_eof=0;
+
+ initialise_globals();
+
+ cnt = 0;
+
+ if ((g=gethdr(&header))!=0) {
+ report_header_error(g);
+ return -1;
+ }
+
+ if (header.protection_bit==0) getcrc();
+
+ printf("%d Hz, layer %d\n", t_sampling_frequency[header.ID][header.sampling_frequency], header.layer);
+
+ if (setup_audio(&header)!=0) {
+ warn("Cannot set up audio. Exiting\n");
+ return -1;
+ }
+
+ if (header.layer==1) {
+ if (layer3_frame(&header,cnt)) {
+ warn(" error. blip.\n");
+ return -1;
+ }
+ } else if (header.layer==2)
+ if (layer2_frame(&header,cnt)) {
+ warn(" error. blip.\n");
+ return -1;
+ }
+
+ /*
+ * decoder loop **********************************
+ */
+ snd_eof=0;
+ while (!snd_eof) {
+ while (!snd_eof && ready_audio()) {
+ snd_eof = decodeMPEGOneFrame(&header);
+ }
+ }
+ return 0;
+}
+
+/* call this once at the beginning
+ */
+void initialise_decoder(void)
+{
+ premultiply();
+ imdct_init();
+ calculate_t43();
+}
+
+/* call this before each file is played
+ */
+void initialise_globals(void)
+{
+ append=data=nch=0;
+ f_bdirty=TRUE;
+ bclean_bytes=0;
+
+ memset(s,0,sizeof s);
+ memset(res,0,sizeof res);
+}
+
+void report_header_error(int err)
+{
+ switch (err) {
+ case GETHDR_ERR: die("error reading mpeg bitstream. exiting.\n");
+ break;
+ case GETHDR_NS : warn("this is a file in MPEG 2.5 format, which is not defined\n");
+ warn("by ISO/MPEG. It is \"a special Fraunhofer format\".\n");
+ warn("amp does not support this format. sorry.\n");
+ break;
+ case GETHDR_FL1: warn("ISO/MPEG layer 1 is not supported by amp.\n");
+ break;
+ case GETHDR_FF : warn("free format bitstreams are not supported. sorry.\n");
+ break;
+ case GETHDR_SYN: warn("oops, we're out of sync.\n");
+ break;
+ case GETHDR_EOF:
+ default: ; /* some stupid compilers need the semicolon */
+ }
+}
+
+int setup_audio(struct AUDIO_HEADER *header)
+{
+ return 0;
+}
+
+void close_audio(void)
+{
+}
+
+int ready_audio(void)
+{
+ return 1;
+}
+
+// callback: called by the engine to output a frame of audio
+void printout(void)
+{
+ int j;
+
+ if (nch==2)
+ {
+ j=32 * 18 * 2;
+ }
+ else
+ {
+ j=32 * 18;
+ }
+
+// printf("printout: %x, %d\n", (unsigned int), j*2);
+ memcpy(dst, sample_buffer, j*2);
+
+ dst += j*2;
+ outpos += j/2;
+}
+
+void MPEG_Decode(INT16 **outputs, int length)
+{
+ int i, remaining, bias;
+ INT16 *get;
+
+ remaining = length;
+
+// printf("%d: %x %x\n", length, (unsigned int)outputs[0], (unsigned int)outputs[1]);
+
+ if (!playing)
+ {
+ memset(&outputs[0][0], 0, length * sizeof(INT16));
+ memset(&outputs[1][0], 0, length * sizeof(INT16));
+ return;
+ }
+
+ bias = 0;
+
+ // will we need more data from the decoder?
+ if (outpos < length)
+ {
+ // if there's anything left in the current buffer, drain it first
+ if (outpos != 0)
+ {
+ get = (INT16 *)readbuf;
+
+ for (i = 0; i < outpos; i++)
+ {
+ outputs[1][i] = *get++;
+ outputs[0][i] = *get++;
+ }
+
+ remaining -= outpos;
+ bias = outpos;
+ readbuf += (outpos * 4);
+ }
+
+ outpos = 0;
+ dst = buf0;
+ while ((outpos < remaining) && (playing))
+ {
+ mpeg_eof = decodeMPEGOneFrame(&m1hdr);
+ if (mpeg_eof)
+ {
+ MPEG_StopPlaying();
+ }
+ }
+
+ // reset read pointer
+ readbuf = buf0;
+ }
+
+ get = (INT16 *)readbuf;
+
+ for (i = 0; i < remaining; i++)
+ {
+ outputs[1][i+bias] = *get++;
+ outputs[0][i+bias] = *get++;
+ }
+
+ outpos -= remaining;
+ readbuf += (remaining * 4);
+}
+
+void MPEG_PlayFile(char *filename)
+{
+ memset(buf0, 0, BUF_SIZE);
+
+ in_file = fopen(filename, "rb");
+
+ initialise_globals();
+
+ cnt = 0;
+ mpeg_eof = 0;
+ outpos = 0;
+ dst = buf0;
+ readbuf = buf0;
+
+ gethdr(&m1hdr);
+ if (m1hdr.protection_bit == 0) getcrc();
+
+// printf("%d Hz, layer %d\n", t_sampling_frequency[m1hdr.ID][m1hdr.sampling_frequency], m1hdr.layer);
+
+// stream_set_srate(stream, t_sampling_frequency[m1hdr.ID][m1hdr.sampling_frequency]);
+
+ // prime the stream
+ if (m1hdr.layer == 1)
+ {
+ layer3_frame(&m1hdr, cnt);
+ }
+ else if (m1hdr.layer == 2)
+ {
+ layer2_frame(&m1hdr, cnt);
+ }
+
+ playing = 1;
+}
+
+extern void m1setfile(const char *mstart, int mend);
+void MPEG_PlayMemory(const char *sa, int length)
+{
+ memset(buf0, 0, BUF_SIZE);
+
+ m1setfile(sa, length);
+
+ initialise_globals();
+
+ cnt = 0;
+ mpeg_eof = 0;
+ outpos = 0;
+ dst = buf0;
+ readbuf = buf0;
+
+ gethdr(&m1hdr);
+ if (m1hdr.protection_bit == 0) getcrc();
+
+// printf("%d Hz, layer %d\n", t_sampling_frequency[m1hdr.ID][m1hdr.sampling_frequency], m1hdr.layer);
+
+// stream_set_srate(stream, t_sampling_frequency[m1hdr.ID][m1hdr.sampling_frequency]);
+
+ // prime the stream
+ if (m1hdr.layer == 1)
+ {
+ layer3_frame(&m1hdr, cnt);
+ }
+ else if (m1hdr.layer == 2)
+ {
+ layer2_frame(&m1hdr, cnt);
+ }
+
+ in_file = NULL;
+
+ playing = 1;
+}
+
+void MPEG_StopPlaying(void)
+{
+ if (playing)
+ {
+ playing = 0;
+ if (in_file)
+ fclose(in_file);
+ }
+}
+
+BOOL MPEG_Init(void)
+{
+ if (!decoder_init)
+ {
+ initialise_decoder(); /* initialise decoder */
+ decoder_init = 1;
+ buf0 = new(std::nothrow) char[BUF_SIZE];
+ if (NULL == buf0)
+ return FAIL;
+ memset(buf0, 0, BUF_SIZE);
+ playing = 0;
+ }
+
+ return OKAY;
+}
+
+void MPEG_Shutdown( void )
+{
+ decoder_init = 0;
+ if (buf0 != NULL)
+ delete [] buf0;
+ buf0 = NULL;
+}
+
diff --git a/Src/Sound/MPEG/audio.h b/Src/Sound/MPEG/audio.h
new file mode 100644
index 0000000..0d0bbfb
--- /dev/null
+++ b/Src/Sound/MPEG/audio.h
@@ -0,0 +1,180 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* audio.h some global variables
+ *
+ * Created by: tomislav uzelac Mar/Apr, Jul 96
+ */
+
+#include
+
+struct AUDIO_HEADER {
+ int ID;
+ int layer;
+ int protection_bit;
+ int bitrate_index;
+ int sampling_frequency;
+ int padding_bit;
+ int private_bit;
+ int mode;
+ int mode_extension;
+ int copyright;
+ int original;
+ int emphasis;
+};
+
+struct SIDE_INFO {
+ int main_data_begin;
+ int scfsi[2][4];
+ int part2_3_length[2][2];
+ int big_values[2][2];
+ int global_gain[2][2];
+ int scalefac_compress[2][2];
+ int window_switching_flag[2][2];
+ int block_type[2][2];
+ int mixed_block_flag[2][2];
+ int table_select[2][2][3];
+ int subblock_gain[2][2][3];
+ int region0_count[2][2];
+ int region1_count[2][2];
+ int preflag[2][2];
+ int scalefac_scale[2][2];
+ int count1table_select[2][2];
+};
+
+
+/* global stuff
+*/
+
+extern FILE *in_file,*out_file;
+
+extern void statusDisplay(struct AUDIO_HEADER *header, int frameNo);
+extern int decodeMPEG(void);
+extern void initialise_globals(void);
+extern void report_header_error(int err);
+
+extern int scalefac_l[2][2][22];
+extern int scalefac_s[2][2][13][3];
+extern int t_b8_l[2][3][22];
+extern int t_b8_s[2][3][13];
+extern short t_bitrate[2][3][15];
+
+extern int is[2][578];
+extern float xr[2][32][18];
+
+extern int *t_l,*t_s;
+extern int nch;
+extern int t_sampling_frequency[2][3];
+
+extern int A_QUIET,A_SHOW_CNT,A_FORMAT_WAVE,A_DUMP_BINARY;
+extern int A_WRITE_TO_AUDIO,A_WRITE_TO_FILE;
+extern short pcm_sample[64];
+extern int A_AUDIO_PLAY;
+extern int A_SET_VOLUME,A_SHOW_TIME;
+extern int A_MSG_STDOUT;
+extern int A_DOWNMIX;
+
+/* GUI CONTROL STUFF */
+extern int GUI_PLAY;
+extern int GUI_PLAYING;
+extern int GUI_PAUSE;
+extern int GUI_PAUSED;
+extern int GUI_STOP;
+extern int GUI_STOPPED;
+extern int GUI_FD_TO_PLAY;
+extern int GUI_NEXT_FILE_READY;
+
+/* GUI control stuff */
+extern int send_fd;
+extern int receive_fd;
+
+extern int stop_flag;
+extern int quit_flag;
+
+/* ...
+*/
+
+#ifdef AUDIO
+
+FILE *in_file,*out_file;
+
+int scalefac_l[2][2][22];
+int scalefac_s[2][2][13][3];
+
+int is[2][578];
+float xr[2][32][18];
+
+int *t_l,*t_s;
+int nch;
+int t_sampling_frequency[2][3] = {
+{ 22050 , 24000 , 16000},
+{ 44100 , 48000 , 32000}
+};
+
+/* GUI control stuff */
+int send_fd;
+int receive_fd;
+
+int stop_flag;
+int quit_flag;
+
+int GUI_PLAY,GUI_PLAYING,GUI_STOP,GUI_STOPPED,GUI_PAUSE,GUI_PAUSED;
+int GUI_FD_TO_PLAY,GUI_NEXT_FILE_READY;
+
+int A_QUIET,A_SHOW_CNT,A_FORMAT_WAVE,A_DUMP_BINARY;
+int A_WRITE_TO_FILE;
+int A_AUDIO_PLAY;
+int A_SET_VOLUME, A_SHOW_TIME;
+int A_MSG_STDOUT;
+int A_DOWNMIX;
+
+short pcm_sample[64];
+
+short t_bitrate[2][3][15] = {{
+{0,32,48,56,64,80,96,112,128,144,160,176,192,224,256},
+{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160},
+{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160}
+},{
+{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448},
+{0,32,48,56,64,80,96,112,128,160,192,224,256,320,384},
+{0,32,40,48,56,64,80,96,112,128,160,192,224,256,320}
+}};
+
+/* the last sfb is given implicitly on pg.28. of the standard. scalefactors
+ * for that one are 0, pretab also
+ */
+/* leftmost index denotes ID, so first three tables are for MPEG2 (header->ID==0)
+ * and the other three are for MPEG1 (header->ID==1)
+ */
+/* 22.05, 24, 16 */
+int t_b8_l[2][3][22]={{ /* table B.8b ISO/IEC 11172-3 */
+{5,11,17,23,29,35,43,53,65,79,95,115,139,167,199,237,283,335,395,463,521,575},
+{5,11,17,23,29,35,43,53,65,79,95,113,135,161,193,231,277,331,393,463,539,575},
+{5,11,17,23,29,35,43,53,65,79,95,115,139,167,199,237,283,335,395,463,521,575}
+},{
+{3,7,11,15,19,23,29,35,43,51,61,73,89,109,133,161,195,237,287,341,417,575},
+{3,7,11,15,19,23,29,35,41,49,59,71,87,105,127,155,189,229,275,329,383,575},
+{3,7,11,15,19,23,29,35,43,53,65,81,101,125,155,193,239,295,363,447,549,575}
+}};
+int t_b8_s[2][3][13]={{ /* table B.8b ISO/IEC 11172-3 */
+{3,7,11,17,23,31,41,55,73,99,131,173,191},
+{3,7,11,17,25,35,47,61,79,103,135,179,191},
+{3,7,11,17,25,35,47,61,79,103,133,173,191}
+},{
+{3,7,11,15,21,29,39,51,65,83,105,135,191},
+{3,7,11,15,21,27,37,49,63,79,99,125,191},
+{3,7,11,15,21,29,41,57,77,103,137,179,191}
+}};
+
+int args(int argc,char **argv);
+void initialise_decoder(void);
+int decodeMPEG(void);
+void initialise_globals(void);
+void report_header_error(int err);
+int setup_audio(struct AUDIO_HEADER *header);
+void close_audio(void);
+int ready_audio(void);
+
+void play(char *inFileStr, char *outFileStr);
+
+#endif /* AUDIO */
diff --git a/Src/Sound/MPEG/config.h b/Src/Sound/MPEG/config.h
new file mode 100644
index 0000000..b448ee1
--- /dev/null
+++ b/Src/Sound/MPEG/config.h
@@ -0,0 +1,62 @@
+/* Define to empty if the keyword does not work. */
+/* #undef const */
+
+/* Define if you don't have vprintf but do have _doprnt. */
+/* #undef HAVE_DOPRNT */
+
+/* Define if you have that is POSIX.1 compatible. */
+//#define HAVE_SYS_WAIT_H 1
+
+/* Define if you have the vprintf function. */
+//#define HAVE_VPRINTF 1
+
+/* Define as __inline if that's what the C compiler calls it. */
+/* #undef inline */
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both and . */
+//#define TIME_WITH_SYS_TIME 1
+
+/* Define if you have the mlock function. */
+//#define HAVE_MLOCK 1
+
+/* Define if you have the mlockall function. */
+//#define HAVE_MLOCKALL 1
+
+/* Define if you have the sched_setscheduler function. */
+//#define HAVE_SCHED_SETSCHEDULER 1
+
+/* Define if you have the select function. */
+//#define HAVE_SELECT 1
+
+/* Define if you have the header file. */
+/* #undef HAVE_DMEDIA_AUDIO_H */
+
+/* Define if you have the header file. */
+//#define HAVE_FCNTL_H 1
+
+/* Define if you have the header file. */
+//#define HAVE_LINUX_SOUNDCARD_H 1
+
+/* Define if you have the header file. */
+/* #undef HAVE_MACHINE_SOUNDCARD_H */
+
+/* Define if you have the header file. */
+/* #undef HAVE_SYS_AUDIOIO_H */
+
+/* Define if you have the header file. */
+//#define HAVE_SYS_IOCTL_H 1
+
+/* Define if you have the header file. */
+//#define HAVE_SYS_SELECT_H 1
+
+/* Define if you have the header file. */
+//#define HAVE_SYS_TIME_H 1
+
+/* Define if you have the header file. */
+#define HAVE_UNISTD_H 1
+
+/* define if you want playing to use Linux realtime features */
+/* #undef LINUX_REALTIME */
diff --git a/Src/Sound/MPEG/dump.cpp b/Src/Sound/MPEG/dump.cpp
new file mode 100644
index 0000000..cc53403
--- /dev/null
+++ b/Src/Sound/MPEG/dump.cpp
@@ -0,0 +1,64 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* dump.c binary/hex dump from buffer
+ *
+ * Created by: tomislav uzelac May 1996
+ * Last modified by: tomislav May 31 1997
+ */
+//#include
+#include
+
+#include "audio.h"
+#include "getbits.h"
+
+#define DUMP
+#include "dump.h"
+
+/* no hex dump, sorry
+ */
+void dump(int *length) /* in fact int length[4] */
+{
+int i,j;
+int _data,space=0;
+ printf(" *********** binary dump\n");
+ _data=data;
+ for (i=0;i<4;i++) {
+ for (j=0;j> (7-(_data&7)) )&1 );
+ space++;
+ _data++;
+ _data&=8*BUFFER_SIZE-1;
+ if (!(_data & 7)) {
+ printf(" ");
+ space++;
+ if (space>70) {
+ printf("\n");
+ space=0;
+ }
+ }
+ }
+ printf("~\n");
+ }
+}
+
+void show_header(struct AUDIO_HEADER *header)
+{
+int bitrate=t_bitrate[header->ID][3-header->layer][header->bitrate_index];
+int fs=t_sampling_frequency[header->ID][header->sampling_frequency];
+int mpg,layer;
+char stm[8];
+ if (A_QUIET) return;
+ layer=4-header->layer;
+ if (header->ID==1) mpg=1;
+ else mpg=2;
+ if (header->mode==3) strcpy(stm,"mono");
+ else strcpy(stm,"stereo");
+
+ printf("\n\
+Properties: %s %dHz\n\
+Coding Method: MPEG%1d.0 layer%1d\n\
+Bitrate: %dkbit/s\n"\
+ ,stm,fs,mpg,layer,bitrate);
+}
diff --git a/Src/Sound/MPEG/dump.h b/Src/Sound/MPEG/dump.h
new file mode 100644
index 0000000..79ebbcd
--- /dev/null
+++ b/Src/Sound/MPEG/dump.h
@@ -0,0 +1,18 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+/* dump.h
+ *
+ * Last modified by: tomislav uzelac May 31 1997
+ */
+
+extern void dump(int *length);
+extern void show_header(struct AUDIO_HEADER *header);
+
+#ifdef DUMP
+void dump(int *length);
+void show_header(struct AUDIO_HEADER *header);
+/*
+static char *t_modes[] = {
+ "stereo","joint_stereo","dual_channel","single_channel"};
+*/
+#endif /* DUMP */
diff --git a/Src/Sound/MPEG/formats.h b/Src/Sound/MPEG/formats.h
new file mode 100644
index 0000000..7146258
--- /dev/null
+++ b/Src/Sound/MPEG/formats.h
@@ -0,0 +1,14 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* formats.h
+ *
+ * Created by: tomislav uzelac Dec 22 1996
+ */
+extern void wav_end(struct AUDIO_HEADER *header);
+extern void wav_begin(void);
+
+#ifdef FORMATS
+void wav_end(struct AUDIO_HEADER *header);
+void wav_begin(void);
+#endif /* FORMATS */
diff --git a/Src/Sound/MPEG/getbits.cpp b/Src/Sound/MPEG/getbits.cpp
new file mode 100644
index 0000000..424307e
--- /dev/null
+++ b/Src/Sound/MPEG/getbits.cpp
@@ -0,0 +1,370 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* getbits.c bit level routines, input buffer
+ *
+ * Created by: tomislav uzelac Apr 1996
+ * better synchronization, tomislav uzelac, Apr 23 1997
+ */
+#include
+#include
+#include
+#include "amp.h"
+#include "audio.h"
+#include "formats.h"
+#include "rtbuf.h"
+
+#define GETBITS
+#include "getbits.h"
+
+static const char *fstart, *lstart;
+static int offset, end, eof, lend;
+
+int MPEG_GetProgress(void)
+{
+ if (in_file) return ftell(in_file);
+
+ return offset;
+}
+
+void m1setfile(const char *mstart, int mend)
+{
+ fstart = mstart;
+ offset = 0;
+ eof = 0;
+ end = mend;
+ lstart = NULL;
+}
+
+void MPEG_SetLoop(const char *loop, int loopend)
+{
+ lstart = loop;
+ lend = loopend;
+}
+
+int m1fread(unsigned char *buf, int size1, int size2, void *f)
+{
+ int total = size1 * size2;
+
+ if (in_file) return fread(buf, size1, size2, (FILE *) f);
+
+ // if past EOF
+ if ((total + offset) >= end)
+ {
+ if (lstart == NULL)
+ {
+ total = end - offset;
+ eof = 1;
+ }
+ else
+ {
+ // if past the end, do the xfer in 2 pieces
+ if ((total + offset) > end)
+ {
+ memcpy(buf, fstart + offset, end-offset);
+ buf += (end-offset);
+ total -= (end-offset);
+ }
+
+ fstart = lstart;
+ offset = 0;
+ end = lend;
+ }
+ }
+
+ memcpy(buf, fstart + offset, total);
+
+ offset += total;
+
+ return total;
+}
+
+int m1feof(void *f)
+{
+ if (in_file) return feof((FILE *)f);
+ return eof;
+}
+
+int m1fseek(void *f, int offs, int whence)
+{
+ if (in_file) return fseek((FILE *) f, offs, whence);
+
+ switch (whence)
+ {
+ case SEEK_CUR:
+ if ((offset + offs) < 0)
+ {
+ offset = 0;
+ eof = 0;
+ return -1;
+ }
+ if ((offset + offs) > end)
+ {
+ offset = end;
+ eof = 1;
+ return end;
+ }
+ offset += offs;
+ eof = 0;
+ break;
+ }
+ return 0;
+}
+
+/*
+ * buffer and bit manipulation functions ***************************************
+ */
+static inline int _fillbfr(unsigned int size)
+{
+ _bptr=0;
+ return get_input(_buffer, size);
+}
+
+static inline int readsync()
+{
+ _bptr=0;
+ _buffer[0]=_buffer[1];
+ _buffer[1]=_buffer[2];
+ _buffer[2]=_buffer[3];
+ return get_input(&_buffer[3],1);
+}
+
+static inline unsigned int _getbits(int n)
+{
+unsigned int pos,ret_value;
+
+ pos = _bptr >> 3;
+ ret_value = _buffer[pos] << 24 |
+ _buffer[pos+1] << 16 |
+ _buffer[pos+2] << 8 |
+ _buffer[pos+3];
+ ret_value <<= _bptr & 7;
+ ret_value >>= 32 - n;
+ _bptr += n;
+ return ret_value;
+}
+
+int fillbfr(unsigned int advance)
+{
+int overflow,retval;
+
+ retval=get_input(&buffer[append], advance);
+
+ if ( append + advance >= BUFFER_SIZE ) {
+ overflow = append + advance - BUFFER_SIZE;
+ memcpy (buffer,&buffer[BUFFER_SIZE], overflow);
+ if (overflow < 4) memcpy(&buffer[BUFFER_SIZE],buffer,4);
+ append = overflow;
+ } else {
+ if (append==0) memcpy(&buffer[BUFFER_SIZE],buffer,4);
+ append+=advance;
+ }
+ return retval;
+}
+
+unsigned int getbits(int n)
+{
+ if (n) {
+ unsigned int pos,ret_value;
+
+ pos = data >> 3;
+ ret_value = buffer[pos] << 24 |
+ buffer[pos+1] << 16 |
+ buffer[pos+2] << 8 |
+ buffer[pos+3];
+ ret_value <<= data & 7;
+ ret_value >>= 32 - n;
+
+ data += n;
+ data &= (8*BUFFER_SIZE)-1;
+
+ return ret_value;
+ } else
+ return 0;
+}
+
+/*
+ * header and side info parsing stuff ******************************************
+ */
+static inline void parse_header(struct AUDIO_HEADER *header)
+{
+ header->ID=_getbits(1);
+ header->layer=_getbits(2);
+ header->protection_bit=_getbits(1);
+ header->bitrate_index=_getbits(4);
+ header->sampling_frequency=_getbits(2);
+ header->padding_bit=_getbits(1);
+ header->private_bit=_getbits(1);
+ header->mode=_getbits(2);
+ header->mode_extension=_getbits(2);
+ if (!header->mode) header->mode_extension=0;
+ header->copyright=_getbits(1);
+ header->original=_getbits(1);
+ header->emphasis=_getbits(2);
+}
+
+static inline int header_sanity_check(struct AUDIO_HEADER *header)
+{
+ if ( header->layer==0 ||
+ header->bitrate_index==15 ||
+ header->sampling_frequency==3) return -1;
+
+ /* an additional check to make shure that stuffing never gets mistaken
+ * for a syncword. This rules out some legal layer1 streams, but who
+ * cares about layer1 anyway :-). I must get this right sometime.
+ */
+ if ( header->ID==1 && header->layer==3 && header->protection_bit==1) return -1;
+ return 0;
+}
+
+
+int gethdr(struct AUDIO_HEADER *header)
+{
+int s,retval;
+struct AUDIO_HEADER tmp;
+
+ /* TODO: add a simple byte counter to check only first, say, 1024
+ * bytes for a new header and then return GETHDR_SYN
+ */
+ if ((retval=_fillbfr(4))!=0) return retval;
+
+ for(;;) {
+ while ((s=_getbits(12)) != 0xfff) {
+ if (s==0xffe) {
+ parse_header(&tmp);
+ if (header_sanity_check(&tmp)==0) return GETHDR_NS;
+ }
+ if ((retval=readsync())!=0) return retval;
+ }
+
+ parse_header(&tmp);
+ if (header_sanity_check(&tmp)!=0) {
+ if ((retval=readsync())!=0) return retval;
+ } else break;
+ }
+
+ if (tmp.layer==3) return GETHDR_FL1;
+ /* if (tmp.layer==2) return GETHDR_FL2; */
+ if (tmp.bitrate_index==0) return GETHDR_FF;
+
+ //printf("layer: %d\n", tmp.layer);
+ //printf("sampling frequency: %d\n", tmp.sampling_frequency);
+
+ memcpy(header,&tmp,sizeof(tmp));
+ return 0;
+}
+
+/* dummy function, to get crc out of the way
+*/
+void getcrc()
+{
+ _fillbfr(2);
+ _getbits(16);
+}
+
+/* sizes of side_info:
+ * MPEG1 1ch 17 2ch 32
+ * MPEG2 1ch 9 2ch 17
+ */
+void getinfo(struct AUDIO_HEADER *header,struct SIDE_INFO *info)
+{
+int gr,ch,scfsi_band,region,window;
+int nch;
+ if (header->mode==3) {
+ nch=1;
+ if (header->ID) {
+ _fillbfr(17);
+ info->main_data_begin=_getbits(9);
+ _getbits(5);
+ } else {
+ _fillbfr(9);
+ info->main_data_begin=_getbits(8);
+ _getbits(1);
+ }
+ } else {
+ nch=2;
+ if (header->ID) {
+ _fillbfr(32);
+ info->main_data_begin=_getbits(9);
+ _getbits(3);
+ } else {
+ _fillbfr(17);
+ info->main_data_begin=_getbits(8);
+ _getbits(2);
+ }
+ }
+
+ if (header->ID) for (ch=0;chscfsi[ch][scfsi_band]=_getbits(1);
+
+ for (gr=0;gr<(header->ID ? 2:1);gr++)
+ for (ch=0;chpart2_3_length[gr][ch]=_getbits(12);
+ info->big_values[gr][ch]=_getbits(9);
+ info->global_gain[gr][ch]=_getbits(8);
+ if (header->ID) info->scalefac_compress[gr][ch]=_getbits(4);
+ else info->scalefac_compress[gr][ch]=_getbits(9);
+ info->window_switching_flag[gr][ch]=_getbits(1);
+
+ if (info->window_switching_flag[gr][ch]) {
+ info->block_type[gr][ch]=_getbits(2);
+ info->mixed_block_flag[gr][ch]=_getbits(1);
+
+ for (region=0;region<2;region++)
+ info->table_select[gr][ch][region]=_getbits(5);
+ info->table_select[gr][ch][2]=0;
+
+ for (window=0;window<3;window++)
+ info->subblock_gain[gr][ch][window]=_getbits(3);
+ } else {
+ for (region=0;region<3;region++)
+ info->table_select[gr][ch][region]=_getbits(5);
+
+ info->region0_count[gr][ch]=_getbits(4);
+ info->region1_count[gr][ch]=_getbits(3);
+ info->block_type[gr][ch]=0;
+ }
+
+ if (header->ID) info->preflag[gr][ch]=_getbits(1);
+ info->scalefac_scale[gr][ch]=_getbits(1);
+ info->count1table_select[gr][ch]=_getbits(1);
+ }
+ return;
+}
+
+int dummy_getinfo(int n)
+{
+ n-=4;
+ if ( m1fseek(in_file,n,SEEK_CUR) != 0)
+ {
+ if (m1feof(in_file)) return GETHDR_EOF;
+ else return GETHDR_ERR;
+ }
+ return 0;
+}
+
+int rewind_stream(int nbytes)
+{
+ nbytes+=5;
+ if (m1fseek(in_file, -nbytes, SEEK_CUR) != 0) {
+ /* what if we need to be at the very beginning? */
+ nbytes--;
+ if (m1fseek(in_file, -nbytes, SEEK_CUR) != 0) return GETHDR_ERR;
+ }
+ return 0;
+}
+
+static inline int get_input(unsigned char* bp, unsigned int size)
+{
+#ifdef LINUX_REALTIME
+ return prefetch_get_input(bp,size);
+#else /* LINUX_REALTIME */
+ if ( m1fread( bp , 1, size, in_file) != size)
+ {
+ if (m1feof(in_file)) return GETHDR_EOF;
+ else return GETHDR_ERR;
+ }
+ return 0;
+#endif /* LINUX_REALTIME */
+}
diff --git a/Src/Sound/MPEG/getbits.h b/Src/Sound/MPEG/getbits.h
new file mode 100644
index 0000000..3aa9c5a
--- /dev/null
+++ b/Src/Sound/MPEG/getbits.h
@@ -0,0 +1,79 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* getbits.h
+ *
+ * Created by: tomislav uzelac Apr 1996
+ */
+
+/* gethdr() error codes
+*/
+#define GETHDR_ERR 0x1
+#define GETHDR_NS 0x2
+#define GETHDR_FL1 0x4
+#define GETHDR_FL2 0x8
+#define GETHDR_FF 0x10
+#define GETHDR_SYN 0x20
+#define GETHDR_EOF 0x30
+
+/* buffer for the 'bit reservoir'
+*/
+#define BUFFER_SIZE 4096
+#define BUFFER_AUX 2048
+extern unsigned char buffer[];
+extern int append,data,f_bdirty,bclean_bytes;
+
+/* exports
+*/
+extern int fillbfr(unsigned int advance);
+extern unsigned int getbits(int n);
+extern int gethdr(struct AUDIO_HEADER *header);
+extern void getcrc();
+extern void getinfo(struct AUDIO_HEADER *header,struct SIDE_INFO *info);
+extern int dummy_getinfo(int n);
+extern int rewind_stream(int nbytes);
+
+
+#ifdef GETBITS
+
+/* buffer, AUX is used in case of input buffer "overflow", and its contents
+ * are copied to the beginning of the buffer
+*/
+unsigned char buffer[BUFFER_SIZE+BUFFER_AUX];
+
+/* buffer pointers: append counts in bytes, data in bits
+ */
+int append,data;
+
+/* bit reservoir stuff. f_bdirty must be set to TRUE when starting play!
+ */
+int f_bdirty,bclean_bytes;
+
+/* internal buffer, _bptr holds the position in _bits_
+ */
+static unsigned char _buffer[32];
+static int _bptr;
+
+
+/* buffer and bit manipulation functions
+ */
+static inline int _fillbfr(unsigned int size);
+static inline int readsync();
+static inline int get_input(unsigned char* bp, unsigned int size);
+static inline unsigned int _getbits(int n);
+int fillbfr(unsigned int advance);
+unsigned int getbits(int n);
+int dummy_getinfo(int n);
+int rewind_stream(int nbytes);
+
+/* header and side info parsing stuff
+ */
+static inline void parse_header(struct AUDIO_HEADER *header);
+static inline int header_sanity_check(struct AUDIO_HEADER *header);
+
+int gethdr(struct AUDIO_HEADER *header);
+void getcrc();
+void getinfo(struct AUDIO_HEADER *header,struct SIDE_INFO *info);
+
+#endif /* GETBITS */
+
diff --git a/Src/Sound/MPEG/getdata.cpp b/Src/Sound/MPEG/getdata.cpp
new file mode 100644
index 0000000..fe1f8a5
--- /dev/null
+++ b/Src/Sound/MPEG/getdata.cpp
@@ -0,0 +1,232 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* getdata.c scalefactor & huffman data extraction
+ *
+ * Created by: tomislav uzelac Apr 1996
+ * Last modified by: tomislav uzelac Feb 27 1997
+ */
+#include "amp.h"
+#include "audio.h"
+#include "getbits.h"
+#include "huffman.h"
+
+#define GETDATA
+#include "getdata.h"
+
+/* layer3 scalefactor decoding. should we check for the number
+ * of bits read, just in case?
+ */
+int decode_scalefactors(struct SIDE_INFO *info,struct AUDIO_HEADER *header,int gr,int ch)
+{
+int sfb,window;
+int slen1,slen2;
+int i1,i2,i=0;
+int j,k;
+ if (header->ID==1) {
+ /* this is MPEG-1 scalefactors format, quite different than
+ * the MPEG-2 format.
+ */
+ slen1=t_slen1[info->scalefac_compress[gr][ch]];
+ slen2=t_slen2[info->scalefac_compress[gr][ch]];
+ i1=3*slen1;
+ i2=3*slen2;
+
+ if (info->window_switching_flag[gr][ch] && info->block_type[gr][ch]==2) {
+ if (info->mixed_block_flag[gr][ch]) {
+ for (sfb=0;sfb<8;sfb++) {
+ scalefac_l[gr][ch][sfb]=getbits(slen1);
+ i+=slen1;
+ }
+ for (sfb=3;sfb<6;sfb++) {
+ for (window=0;window<3;window++)
+ scalefac_s[gr][ch][sfb][window]=getbits(slen1);
+ i+=i1;
+ }
+ for (;sfb<12;sfb++) {
+ for (window=0;window<3;window++)
+ scalefac_s[gr][ch][sfb][window]=getbits(slen2);
+ i+=i2;
+ }
+ } else { /* !mixed_block_flag */
+ for (sfb=0;sfb<6;sfb++) {
+ for (window=0;window<3;window++)
+ scalefac_s[gr][ch][sfb][window]=getbits(slen1);
+ i+=i1;
+ }
+ for (;sfb<12;sfb++) {
+ for (window=0;window<3;window++)
+ scalefac_s[gr][ch][sfb][window]=getbits(slen2);
+ i+=i2;
+ }
+ }
+ for (window=0;window<3;window++)
+ scalefac_s[gr][ch][12][window]=0;
+ } else { /* block_type!=2 */
+ if ( !info->scfsi[ch][0] || !gr )
+ for (sfb=0;sfb<6;sfb++) {
+ scalefac_l[gr][ch][sfb]=getbits(slen1);
+ i+=slen1;
+ }
+ else for (sfb=0;sfb<6;sfb++) {
+ scalefac_l[1][ch][sfb]=scalefac_l[0][ch][sfb];
+ }
+ if ( !info->scfsi[ch][1] || !gr )
+ for (sfb=6;sfb<11;sfb++) {
+ scalefac_l[gr][ch][sfb]=getbits(slen1);
+ i+=slen1;
+ }
+ else for (sfb=6;sfb<11;sfb++) {
+ scalefac_l[1][ch][sfb]=scalefac_l[0][ch][sfb];
+ }
+ if ( !info->scfsi[ch][2] || !gr )
+ for (sfb=11;sfb<16;sfb++) {
+ scalefac_l[gr][ch][sfb]=getbits(slen2);
+ i+=slen2;
+ }
+ else for (sfb=11;sfb<16;sfb++) {
+ scalefac_l[1][ch][sfb]=scalefac_l[0][ch][sfb];
+ }
+ if ( !info->scfsi[ch][3] || !gr )
+ for (sfb=16;sfb<21;sfb++) {
+ scalefac_l[gr][ch][sfb]=getbits(slen2);
+ i+=slen2;
+ }
+ else for (sfb=16;sfb<21;sfb++) {
+ scalefac_l[1][ch][sfb]=scalefac_l[0][ch][sfb];
+ }
+ scalefac_l[gr][ch][21]=0;
+ }
+ } else { /* ID==0 */
+ int index=0,index2,spooky_index;
+ int slen[6],nr_of_sfb[6]; /* actually, there's four of each, not five, labelled 1 through 4, but
+ * what's a word of storage compared to one's sanity. so [0] is irellevant.
+ */
+
+ /* ok, so we got 3 indexes.
+ * spooky_index - indicates whether we use the normal set of slen eqs and nr_of_sfb tables
+ * or the one for the right channel of intensity stereo coded frame
+ * index - corresponds to the value of scalefac_compress, as listed in the standard
+ * index2 - 0 for long blocks, 1 for short wo/ mixed_block_flag, 2 for short with it
+ */
+ if ( (header->mode_extension==1 || header->mode_extension==3) && ch==1) { /* right ch... */
+ int int_scalefac_compress=info->scalefac_compress[0][ch]>>1;
+ intensity_scale=info->scalefac_compress[0][1]&1;
+ spooky_index=1;
+ if (int_scalefac_compress < 180) {
+ slen[1]=int_scalefac_compress/36;
+ slen[2]=(int_scalefac_compress%36)/6;
+ slen[3]=(int_scalefac_compress%36)%6;
+ slen[4]=0;
+ info->preflag[0][ch]=0;
+ index=0;
+ }
+ if ( 180 <= int_scalefac_compress && int_scalefac_compress < 244) {
+ slen[1]=((int_scalefac_compress-180)%64)>>4;
+ slen[2]=((int_scalefac_compress-180)%16)>>2;
+ slen[3]=(int_scalefac_compress-180)%4;
+ slen[4]=0;
+ info->preflag[0][ch]=0;
+ index=1;
+ }
+ if ( 244 <= int_scalefac_compress && int_scalefac_compress < 255) {
+ slen[1]=(int_scalefac_compress-244)/3;
+ slen[2]=(int_scalefac_compress-244)%3;
+ slen[3]=0;
+ slen[4]=0;
+ info->preflag[0][ch]=0;
+ index=2;
+ }
+ } else { /* the usual */
+ spooky_index=0;
+ if (info->scalefac_compress[0][ch] < 400) {
+ slen[1]=(info->scalefac_compress[0][ch]>>4)/5;
+ slen[2]=(info->scalefac_compress[0][ch]>>4)%5;
+ slen[3]=(info->scalefac_compress[0][ch]%16)>>2;
+ slen[4]=info->scalefac_compress[0][ch]%4;
+ info->preflag[0][ch]=0;
+ index=0;
+ }
+ if (info->scalefac_compress[0][ch] >= 400 && info->scalefac_compress[0][ch] < 500) {
+ slen[1]=((info->scalefac_compress[0][ch]-400)>>2)/5;
+ slen[2]=((info->scalefac_compress[0][ch]-400)>>2)%5;
+ slen[3]=(info->scalefac_compress[0][ch]-400)%4;
+ slen[4]=0;
+ info->preflag[0][ch]=0;
+ index=1;
+ }
+ if (info->scalefac_compress[0][ch] >= 500 && info->scalefac_compress[0][ch] < 512) {
+ slen[1]=(info->scalefac_compress[0][ch]-500)/3;
+ slen[2]=(info->scalefac_compress[0][ch]-500)%3;
+ slen[3]=0;
+ slen[4]=0;
+ info->preflag[0][ch]=1;
+ index=2;
+ }
+ }
+
+ if (info->window_switching_flag[0][ch] && info->block_type[0][ch]==2)
+ if (info->mixed_block_flag[0][ch]) index2=2;
+ else index2=1;
+ else index2=0;
+
+ for (j=1;j<=4;j++) nr_of_sfb[j]=spooky_table[spooky_index][index][index2][j-1];
+
+ /* now we'll do some actual scalefactor extraction, and a little more.
+ * for each scalefactor band we'll set the value of is_max to indicate
+ * illegal is_pos, since with MPEG2 it's not 'hardcoded' to 7.
+ */
+ if (!info->window_switching_flag[0][ch] || (info->window_switching_flag[0][ch] && info->block_type[0][ch]!=2)) {
+ sfb=0;
+ for (j=1;j<=4;j++)
+ for (k=0;kblock_type[0][ch]==2)
+ {
+ if (!info->mixed_block_flag[0][ch]) {
+ sfb=0;
+ for (j=1;j<=4;j++)
+ for (k=0;k
+#include "audio.h"
+#include "getbits.h"
+
+#define HUFFMAN
+#include "huffman.h"
+
+static inline unsigned int viewbits(int n)
+{
+unsigned int pos,ret_value;
+
+ pos = data >> 3;
+ ret_value = buffer[pos] << 24 |
+ buffer[pos+1] << 16 |
+ buffer[pos+2] << 8 |
+ buffer[pos+3];
+ ret_value <<= data & 7;
+ ret_value >>= 32 - n;
+
+ return ret_value;
+}
+
+static inline void sackbits(int n)
+{
+ data += n;
+ data &= 8*BUFFER_SIZE-1;
+}
+
+/* huffman_decode() is supposed to be faster now
+ * decodes one codeword and returns no. of bits
+ */
+static inline int huffman_decode(int tbl,int *x,int *y)
+{
+unsigned int chunk;
+register unsigned int *h_tab;
+register unsigned int lag;
+register unsigned int half_lag;
+int len;
+
+ h_tab=tables[tbl];
+ chunk=viewbits(19);
+
+ h_tab += h_cue[tbl][chunk >> (19-NC_O)];
+
+ len=(*h_tab>>8)&0x1f;
+
+ /* check for an immediate hit, so we can decode those short codes very fast
+ */
+ if ((*h_tab>>(32-len)) != (chunk>>(19-len))) {
+ if (chunk >> (19-NC_O) < N_CUE-1)
+ lag=(h_cue[tbl][(chunk >> (19-NC_O))+1] -
+ h_cue[tbl][chunk >> (19-NC_O)]);
+ else {
+ /* we strongly depend on h_cue[N_CUE-1] to point to
+ * the last entry in the huffman table, so we should
+ * not get here anyway. if it didn't, we'd have to
+ * have another table with huffman tables lengths, and
+ * it would be a mess. just in case, scream&shout.
+ */
+ printf(" h_cue clobbered. this is a bug. blip.\n");
+ exit (-1);
+ }
+ chunk <<= 32-19;
+ chunk |= 0x1ff;
+
+ half_lag = lag >> 1;
+
+ h_tab += half_lag;
+ lag -= half_lag;
+
+ while (lag > 1) {
+ half_lag = lag >> 1;
+
+ if (*h_tab < chunk)
+ h_tab += half_lag;
+ else
+ h_tab -= half_lag;
+
+ lag -= half_lag;
+ }
+
+ len=(*h_tab>>8)&0x1f;
+ if ((*h_tab>>(32-len)) != (chunk>>(32-len))) {
+ if (*h_tab > chunk)
+ h_tab--;
+ else
+ h_tab++;
+
+ len=(*h_tab>>8)&0x1f;
+ }
+ }
+ sackbits(len);
+ *x=(*h_tab>>4)&0xf;
+ *y=*h_tab&0xf;
+ return len;
+}
+
+static inline int _qsign(int x,int *q)
+{
+int ret_value=0,i;
+ for (i=3;i>=0;i--)
+ if ((x>>i) & 1) {
+ if (getbits(1)) *q++=-1;
+ else *q++=1;
+ ret_value++;
+ }
+ else *q++=0;
+ return ret_value;
+}
+
+int decode_huffman_data(struct SIDE_INFO *info,int gr,int ch,int ssize)
+{
+int l,i,cnt,x,y;
+int q[4],r[3],linbits[3],tr[4]={0,0,0,0};
+int big_value = info->big_values[gr][ch] << 1;
+
+ for (l=0;l<3;l++) {
+ tr[l]=info->table_select[gr][ch][l];
+ linbits[l]=t_linbits[info->table_select[gr][ch][l]];
+ }
+
+ tr[3]=32+info->count1table_select[gr][ch];
+
+ /* we have to be careful here because big_values are not necessarily
+ * aligned with sfb boundaries
+ */
+ if (!info->window_switching_flag[gr][ch] && info->block_type[gr][ch]==0) {
+
+ /* this code needed some cleanup
+ */
+ r[0]=t_l[info->region0_count[gr][ch]] + 1;
+ if (r[0] > big_value)
+ r[0]=r[1]=big_value;
+ else {
+ r[1]=t_l[ info->region0_count[gr][ch] + info->region1_count[gr][ch] + 1 ] + 1;
+ if (r[1] > big_value)
+ r[1]=big_value;
+ }
+ r[2]=big_value;
+
+ } else {
+
+ if (info->block_type[gr][ch]==2 && info->mixed_block_flag[gr][ch]==0)
+ r[0]=3*(t_s[2]+1);
+ else
+ r[0]=t_l[7]+1;
+
+ if (r[0] > big_value)
+ r[0]=big_value;
+
+ r[1]=r[2]=big_value;
+ }
+
+ l=0; cnt=0;
+ for (i=0;i<3;i++) {
+ for (;l0) {
+ x+=getbits(j);
+ cnt+=j;
+ }
+ if (x) {
+ if (getbits(1)) x=-x;
+ cnt++;
+ }
+ if (y==15 && j>0) {
+ y+=getbits(j);
+ cnt+=j;
+ }
+ if (y) {
+ if (getbits(1)) y=-y;
+ cnt++;
+ }
+
+ is[ch][l]=x;
+ is[ch][l+1]=y;
+ }
+ }
+ while ((cnt < info->part2_3_length[gr][ch]-ssize) && (l<576)) {
+ cnt+=huffman_decode(tr[3],&x,&y);
+ cnt+=_qsign(x,q);
+ for (i=0;i<4;i++) is[ch][l+i]=q[i]; /* ziher je ziher, is[578]*/
+ l+=4;
+ }
+
+ /* set position to start of the next gr/ch
+ */
+ if (cnt != info->part2_3_length[gr][ch] - ssize ) {
+ data-=cnt-(info->part2_3_length[gr][ch] - ssize);
+ data&= 8*BUFFER_SIZE - 1;
+ }
+ if (l<576) non_zero[ch]=l;
+ else non_zero[ch]=576;
+ /* zero out everything else
+ */
+ for (;l<576;l++) is[ch][l]=0;
+ return 1;
+}
diff --git a/Src/Sound/MPEG/huffman.h b/Src/Sound/MPEG/huffman.h
new file mode 100644
index 0000000..440d258
--- /dev/null
+++ b/Src/Sound/MPEG/huffman.h
@@ -0,0 +1,259 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* huffman.h
+ *
+ * Created by: tomislav uzelac Mar 1996
+ * Last edited by: tomislav uzelac Mar 8 97
+ */
+
+extern int decode_huffman_data(struct SIDE_INFO *info,int gr,int ch,int ssize);
+
+extern int non_zero[2];
+extern int t_linbits[32];
+
+#ifdef HUFFMAN
+
+static inline unsigned int viewbits(int n);
+static inline void sackbits(int n);
+static inline int huffman_decode(int tbl,int *x,int *y);
+static inline int _qsign(int x,int *q);
+int decode_huffman_data(struct SIDE_INFO *info,int gr,int ch,int ssize);
+
+int non_zero[2]; /* this is 2*bigvalues+4*count1, i guess...*/
+
+#define N_CUE 16
+#define NC_O 4
+
+int t_linbits[32]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13};
+
+/* these are the huffman tables, rearranged for lookup
+*/
+unsigned int h0[1]={0x0};
+unsigned int h1[4]={0x311, 0x20000301, 0x40000210, 0x80000100};
+unsigned int h2[9]={0x622, 0x4000602, 0x8000512, 0x10000521, 0x18000520, 0x20000311, 0x40000301, 0x60000310,
+ 0x80000100};
+unsigned int h3[9]={ 0x622, 0x4000602, 0x8000512, 0x10000521, 0x18000520, 0x20000310, 0x40000211, 0x80000201,
+ 0xc0000200};
+unsigned int h5[16]={0x833, 0x1000823, 0x2000732, 0x4000631, 0x8000713, 0xa000703, 0xc000730, 0xe000722,
+ 0x10000612, 0x14000621, 0x18000602, 0x1c000620, 0x20000311, 0x40000301, 0x60000310, 0x80000100};
+unsigned int h6[16]={0x733, 0x2000703, 0x4000623, 0x8000632, 0xc000630, 0x10000513, 0x18000531, 0x20000522,
+ 0x28000502, 0x30000412, 0x40000421, 0x50000420, 0x60000301, 0x80000211, 0xc0000310, 0xe0000300};
+unsigned int h7[36]={ 0xa55, 0x400a45, 0x800a54, 0xc00a53, 0x1000935, 0x1800944, 0x2000925, 0x2800952,
+ 0x3000815, 0x4000851, 0x5000905, 0x5800934, 0x6000850, 0x7000943, 0x7800933, 0x8000824,
+ 0x9000842, 0xa000714, 0xc000741, 0xe000740, 0x10000804, 0x11000823, 0x12000832, 0x13000803,
+ 0x14000713, 0x16000731, 0x18000730, 0x1a000722, 0x1c000612, 0x20000521, 0x28000602, 0x2c000620,
+ 0x30000411, 0x40000301, 0x60000310, 0x80000100};
+unsigned int h8[36]={0xb55, 0x200b54, 0x400a45, 0x800953, 0x1000a35, 0x1400a44, 0x1800925, 0x2000952,
+ 0x2800905, 0x3000815, 0x4000851, 0x5000934, 0x5800943, 0x6000950, 0x6800933, 0x7000824,
+ 0x8000842, 0x9000814, 0xa000741, 0xc000804, 0xd000840, 0xe000823, 0xf000832, 0x10000813,
+ 0x11000831, 0x12000803, 0x13000830, 0x14000622, 0x18000602, 0x1c000620, 0x20000412, 0x30000421,
+ 0x40000211, 0x80000301, 0xa0000310, 0xc0000200};
+unsigned int h9[36]={ 0x955, 0x800945, 0x1000835, 0x2000853, 0x3000954, 0x3800905, 0x4000844, 0x5000825,
+ 0x6000852, 0x7000815, 0x8000751, 0xa000734, 0xc000743, 0xe000850, 0xf000804, 0x10000724,
+ 0x12000742, 0x14000733, 0x16000740, 0x18000614, 0x1c000641, 0x20000623, 0x24000632, 0x28000513,
+ 0x30000531, 0x38000603, 0x3c000630, 0x40000522, 0x48000502, 0x50000412, 0x60000421, 0x70000420,
+ 0x80000311, 0xa0000301, 0xc0000310, 0xe0000300};
+unsigned int h10[64]={ 0xb77, 0x200b67, 0x400b76, 0x600b57, 0x800b75, 0xa00b66, 0xc00a47, 0x1000a74,
+ 0x1400a56, 0x1800a65, 0x1c00a37, 0x2000a73, 0x2400a46, 0x2800b55, 0x2a00b54, 0x2c00a63,
+ 0x3000927, 0x3800972, 0x4000a64, 0x4400a07, 0x4800970, 0x5000962, 0x5800a45, 0x5c00a35,
+ 0x6000906, 0x6800a53, 0x6c00a44, 0x7000817, 0x8000871, 0x9000936, 0x9800926, 0xa000a25,
+ 0xa400a52, 0xa800915, 0xb000951, 0xb800a34, 0xbc00a43, 0xc000816, 0xd000861, 0xe000860,
+ 0xf000905, 0xf800950, 0x10000924, 0x10800942, 0x11000933, 0x11800904, 0x12000814, 0x13000841,
+ 0x14000840, 0x15000823, 0x16000832, 0x17000803, 0x18000713, 0x1a000731, 0x1c000730, 0x1e000722,
+ 0x20000612, 0x24000621, 0x28000602, 0x2c000620, 0x30000411, 0x40000301, 0x60000310, 0x80000100};
+unsigned int h11[64]={ 0xa77, 0x400a67, 0x800a76, 0xc00a75, 0x1000a66, 0x1400a47, 0x1800a74, 0x1c00b57,
+ 0x1e00b55, 0x2000a56, 0x2400a65, 0x2800937, 0x3000973, 0x3800946, 0x4000a45, 0x4400a54,
+ 0x4800a35, 0x4c00a53, 0x5000827, 0x6000872, 0x7000964, 0x7800907, 0x8000771, 0xa000817,
+ 0xb000870, 0xc000836, 0xd000863, 0xe000860, 0xf000944, 0xf800925, 0x10000952, 0x10800905,
+ 0x11000815, 0x12000762, 0x14000826, 0x15000806, 0x16000716, 0x18000761, 0x1a000851, 0x1b000834,
+ 0x1c000850, 0x1d000943, 0x1d800933, 0x1e000824, 0x1f000842, 0x20000814, 0x21000841, 0x22000804,
+ 0x23000840, 0x24000723, 0x26000732, 0x28000613, 0x2c000631, 0x30000703, 0x32000730, 0x34000622,
+ 0x38000521, 0x40000412, 0x50000502, 0x58000520, 0x60000311, 0x80000301, 0xa0000310, 0xc0000200};
+unsigned int h12[64]={ 0xa77, 0x400a67, 0x800976, 0x1000957, 0x1800975, 0x2000966, 0x2800947, 0x3000974,
+ 0x3800965, 0x4000856, 0x5000837, 0x6000973, 0x6800955, 0x7000827, 0x8000872, 0x9000846,
+ 0xa000864, 0xb000817, 0xc000871, 0xd000907, 0xd800970, 0xe000836, 0xf000863, 0x10000845,
+ 0x11000854, 0x12000844, 0x13000906, 0x13800905, 0x14000726, 0x16000762, 0x18000761, 0x1a000816,
+ 0x1b000860, 0x1c000835, 0x1d000853, 0x1e000825, 0x1f000852, 0x20000715, 0x22000751, 0x24000734,
+ 0x26000743, 0x28000850, 0x29000804, 0x2a000724, 0x2c000742, 0x2e000714, 0x30000633, 0x34000641,
+ 0x38000623, 0x3c000632, 0x40000740, 0x42000703, 0x44000630, 0x48000513, 0x50000531, 0x58000522,
+ 0x60000412, 0x70000421, 0x80000502, 0x88000520, 0x90000400, 0xa0000311, 0xc0000301, 0xe0000310};
+unsigned int h13[256]={
+ 0x13fe, 0x33fc, 0x52fd, 0x91ed, 0x110ff, 0x210ef, 0x310df, 0x410ee,
+ 0x510cf, 0x610de, 0x710bf, 0x810fb, 0x910ce, 0xa10dc, 0xb11af, 0xb91e9,
+ 0xc0fec, 0xe0fdd, 0x1010fa, 0x1110cd, 0x120fbe, 0x140feb, 0x160f9f, 0x180ff9,
+ 0x1a0fea, 0x1c0fbd, 0x1e0fdb, 0x200f8f, 0x220ff8, 0x240fcc, 0x2610ae, 0x27109e,
+ 0x280f8e, 0x2a107f, 0x2b107e, 0x2c0ef7, 0x300eda, 0x340fad, 0x360fbc, 0x380fcb,
+ 0x3a0ff6, 0x3c0e6f, 0x400ee8, 0x440e5f, 0x480e9d, 0x4c0ed9, 0x500ef5, 0x540ee7,
+ 0x580eac, 0x5c0ebb, 0x600e4f, 0x640ef4, 0x680fca, 0x6a0fe6, 0x6c0ef3, 0x700d3f,
+ 0x780e8d, 0x7c0ed8, 0x800d2f, 0x880df2, 0x900e6e, 0x940e9c, 0x980d0f, 0xa00ec9,
+ 0xa40e5e, 0xa80dab, 0xb00e7d, 0xb40ed7, 0xb80d4e, 0xc00ec8, 0xc40ed6, 0xc80d3e,
+ 0xd00db9, 0xd80e9b, 0xdc0eaa, 0xe00c1f, 0xf00cf1, 0x1000cf0, 0x1100dba, 0x1180de5,
+ 0x1200de4, 0x1280d8c, 0x1300d6d, 0x1380de3, 0x1400ce2, 0x1500d2e, 0x1580d0e, 0x1600c1e,
+ 0x1700ce1, 0x1800de0, 0x1880d5d, 0x1900dd5, 0x1980d7c, 0x1a00dc7, 0x1a80d4d, 0x1b00d8b,
+ 0x1b80db8, 0x1c00dd4, 0x1c80d9a, 0x1d00da9, 0x1d80d6c, 0x1e00cc6, 0x1f00c3d, 0x2000dd3,
+ 0x2080d7b, 0x2100c2d, 0x2200cd2, 0x2300c1d, 0x2400cb7, 0x2500d5c, 0x2580dc5, 0x2600d99,
+ 0x2680d7a, 0x2700cc3, 0x2800da7, 0x2880d97, 0x2900c4b, 0x2a00bd1, 0x2c00c0d, 0x2d00cd0,
+ 0x2e00c8a, 0x2f00ca8, 0x3000c4c, 0x3100cc4, 0x3200c6b, 0x3300cb6, 0x3400b3c, 0x3600b2c,
+ 0x3800bc2, 0x3a00b5b, 0x3c00cb5, 0x3d00c89, 0x3e00b1c, 0x4000bc1, 0x4200c98, 0x4300c0c,
+ 0x4400bc0, 0x4600cb4, 0x4700c6a, 0x4800ca6, 0x4900c79, 0x4a00b3b, 0x4c00bb3, 0x4e00c88,
+ 0x4f00c5a, 0x5000b2b, 0x5200ca5, 0x5300c69, 0x5400ba4, 0x5600c78, 0x5700c87, 0x5800b94,
+ 0x5a00c77, 0x5b00c76, 0x5c00ab2, 0x6000a1b, 0x6400ab1, 0x6800b0b, 0x6a00bb0, 0x6c00b96,
+ 0x6e00b4a, 0x7000b3a, 0x7200ba3, 0x7400b59, 0x7600b95, 0x7800a2a, 0x7c00aa2, 0x8000a1a,
+ 0x8400aa1, 0x8800b0a, 0x8a00b68, 0x8c00aa0, 0x9000b86, 0x9200b49, 0x9400a93, 0x9800b39,
+ 0x9a00b58, 0x9c00b85, 0x9e00b67, 0xa000a29, 0xa400a92, 0xa800b57, 0xaa00b75, 0xac00a38,
+ 0xb000a83, 0xb400b66, 0xb600b47, 0xb800b74, 0xba00b56, 0xbc00b65, 0xbe00b73, 0xc000919,
+ 0xc800991, 0xd000a09, 0xd400a90, 0xd800a48, 0xdc00a84, 0xe000a72, 0xe400b46, 0xe600b64,
+ 0xe800928, 0xf000982, 0xf800918, 0x10000a37, 0x10400a27, 0x10800917, 0x11000971, 0x11800a55,
+ 0x11c00a07, 0x12000a70, 0x12400a36, 0x12800a63, 0x12c00a45, 0x13000a54, 0x13400a26, 0x13800a62,
+ 0x13c00a35, 0x14000881, 0x15000908, 0x15800980, 0x16000916, 0x16800961, 0x17000906, 0x17800960,
+ 0x18000a53, 0x18400a44, 0x18800925, 0x19000952, 0x19800905, 0x1a000815, 0x1b000851, 0x1c000934,
+ 0x1c800943, 0x1d000950, 0x1d800924, 0x1e000942, 0x1e800933, 0x1f000814, 0x20000741, 0x22000804,
+ 0x23000840, 0x24000823, 0x25000832, 0x26000713, 0x28000731, 0x2a000703, 0x2c000730, 0x2e000722,
+ 0x30000612, 0x34000621, 0x38000602, 0x3c000620, 0x40000411, 0x50000401, 0x60000310, 0x80000100};
+unsigned int h15[256]={ 0xdff, 0x80def, 0x100dfe, 0x180ddf, 0x200cee, 0x300dfd, 0x380dcf, 0x400dfc,
+ 0x480dde, 0x500ded, 0x580dbf, 0x600cfb, 0x700dce, 0x780dec, 0x800cdd, 0x900caf,
+ 0xa00cfa, 0xb00cbe, 0xc00ceb, 0xd00ccd, 0xe00cdc, 0xf00c9f, 0x1000cf9, 0x1100cea,
+ 0x1200cbd, 0x1300cdb, 0x1400c8f, 0x1500cf8, 0x1600ccc, 0x1700c9e, 0x1800ce9, 0x1900c7f,
+ 0x1a00cf7, 0x1b00cad, 0x1c00cda, 0x1d00cbc, 0x1e00c6f, 0x1f00dae, 0x1f80d0f, 0x2000bcb,
+ 0x2200bf6, 0x2400c8e, 0x2500ce8, 0x2600c5f, 0x2700c9d, 0x2800bf5, 0x2a00b7e, 0x2c00be7,
+ 0x2e00bac, 0x3000bca, 0x3200bbb, 0x3400cd9, 0x3500c8d, 0x3600b4f, 0x3800bf4, 0x3a00b3f,
+ 0x3c00bf3, 0x3e00bd8, 0x4000be6, 0x4200b2f, 0x4400bf2, 0x4600c6e, 0x4700cf0, 0x4800b1f,
+ 0x4a00bf1, 0x4c00b9c, 0x4e00bc9, 0x5000b5e, 0x5200bab, 0x5400bba, 0x5600be5, 0x5800b7d,
+ 0x5a00bd7, 0x5c00b4e, 0x5e00be4, 0x6000b8c, 0x6200bc8, 0x6400b3e, 0x6600b6d, 0x6800bd6,
+ 0x6a00be3, 0x6c00b9b, 0x6e00bb9, 0x7000b2e, 0x7200baa, 0x7400be2, 0x7600b1e, 0x7800be1,
+ 0x7a00c0e, 0x7b00ce0, 0x7c00b5d, 0x7e00bd5, 0x8000b7c, 0x8200bc7, 0x8400b4d, 0x8600b8b,
+ 0x8800ad4, 0x8c00bb8, 0x8e00b9a, 0x9000ba9, 0x9200b6c, 0x9400bc6, 0x9600b3d, 0x9800ad3,
+ 0x9c00ad2, 0xa000b2d, 0xa200b0d, 0xa400a1d, 0xa800a7b, 0xac00ab7, 0xb000ad1, 0xb400b5c,
+ 0xb600bd0, 0xb800ac5, 0xbc00a8a, 0xc000aa8, 0xc400a4c, 0xc800ac4, 0xcc00a6b, 0xd000ab6,
+ 0xd400b99, 0xd600b0c, 0xd800a3c, 0xdc00ac3, 0xe000a7a, 0xe400aa7, 0xe800aa6, 0xec00bc0,
+ 0xee00b0b, 0xf0009c2, 0xf800a2c, 0xfc00a5b, 0x10000ab5, 0x10400a1c, 0x10800a89, 0x10c00a98,
+ 0x11000ac1, 0x11400a4b, 0x11800ab4, 0x11c00a6a, 0x12000a3b, 0x12400a79, 0x128009b3, 0x13000a97,
+ 0x13400a88, 0x13800a2b, 0x13c00a5a, 0x140009b2, 0x14800aa5, 0x14c00a1b, 0x150009b1, 0x15800ab0,
+ 0x15c00a69, 0x16000a96, 0x16400a4a, 0x16800aa4, 0x16c00a78, 0x17000a87, 0x17400a3a, 0x178009a3,
+ 0x18000959, 0x18800995, 0x1900092a, 0x198009a2, 0x1a00091a, 0x1a8009a1, 0x1b000a0a, 0x1b400aa0,
+ 0x1b800968, 0x1c000986, 0x1c800949, 0x1d000994, 0x1d800939, 0x1e000993, 0x1e800a77, 0x1ec00a09,
+ 0x1f000958, 0x1f800985, 0x20000929, 0x20800967, 0x21000976, 0x21800992, 0x22000891, 0x23000919,
+ 0x23800990, 0x24000948, 0x24800984, 0x25000957, 0x25800975, 0x26000938, 0x26800983, 0x27000966,
+ 0x27800947, 0x28000828, 0x29000882, 0x2a000818, 0x2b000881, 0x2c000974, 0x2c800908, 0x2d000980,
+ 0x2d800956, 0x2e000965, 0x2e800937, 0x2f000973, 0x2f800946, 0x30000827, 0x31000872, 0x32000864,
+ 0x33000817, 0x34000855, 0x35000871, 0x36000907, 0x36800970, 0x37000836, 0x38000863, 0x39000845,
+ 0x3a000854, 0x3b000826, 0x3c000862, 0x3d000816, 0x3e000906, 0x3e800960, 0x3f000835, 0x40000761,
+ 0x42000853, 0x43000844, 0x44000725, 0x46000752, 0x48000715, 0x4a000751, 0x4c000805, 0x4d000850,
+ 0x4e000734, 0x50000743, 0x52000724, 0x54000742, 0x56000733, 0x58000641, 0x5c000714, 0x5e000704,
+ 0x60000623, 0x64000632, 0x68000740, 0x6a000703, 0x6c000613, 0x70000631, 0x74000630, 0x78000522,
+ 0x80000512, 0x88000521, 0x90000502, 0x98000520, 0xa0000311, 0xc0000401, 0xd0000410, 0xe0000300};
+unsigned int h16[256]={ 0xbef, 0x200bfe, 0x400bdf, 0x600bfd, 0x800bcf, 0xa00bfc, 0xc00bbf, 0xe00bfb,
+ 0x1000aaf, 0x1400bfa, 0x1600b9f, 0x1800bf9, 0x1a00bf8, 0x1c00a8f, 0x2000a7f, 0x2400af7,
+ 0x2800a6f, 0x2c00af6, 0x30008ff, 0x4000a5f, 0x4400af5, 0x480094f, 0x50009f4, 0x58009f3,
+ 0x60009f0, 0x6800a3f, 0x6c010ce, 0x6c111ec, 0x6c191dd, 0x6c20fde, 0x6c40fe9, 0x6c610ea,
+ 0x6c710d9, 0x6c80eee, 0x6cc0fed, 0x6ce0feb, 0x6d00ebe, 0x6d40ecd, 0x6d80fdc, 0x6da0fdb,
+ 0x6dc0eae, 0x6e00ecc, 0x6e40fad, 0x6e60fda, 0x6e80f7e, 0x6ea0fac, 0x6ec0eca, 0x6f00fc9,
+ 0x6f20f7d, 0x6f40e5e, 0x6f80dbd, 0x70008f2, 0x800092f, 0x880090f, 0x900081f, 0xa0008f1,
+ 0xb000d9e, 0xb080ebc, 0xb0c0ecb, 0xb100e8e, 0xb140ee8, 0xb180e9d, 0xb1c0ee7, 0xb200ebb,
+ 0xb240e8d, 0xb280ed8, 0xb2c0e6e, 0xb300de6, 0xb380d9c, 0xb400eab, 0xb440eba, 0xb480ee5,
+ 0xb4c0ed7, 0xb500d4e, 0xb580ee4, 0xb5c0e8c, 0xb600dc8, 0xb680d3e, 0xb700d6d, 0xb780ed6,
+ 0xb7c0e9b, 0xb800eb9, 0xb840eaa, 0xb880de1, 0xb900dd4, 0xb980eb8, 0xb9c0ea9, 0xba00d7b,
+ 0xba80eb7, 0xbac0ed0, 0xbb00ce3, 0xbc00d0e, 0xbc80de0, 0xbd00d5d, 0xbd80dd5, 0xbe00d7c,
+ 0xbe80dc7, 0xbf00d4d, 0xbf80d8b, 0xc000d9a, 0xc080d6c, 0xc100dc6, 0xc180d3d, 0xc200d5c,
+ 0xc280dc5, 0xc300c0d, 0xc400d8a, 0xc480da8, 0xc500d99, 0xc580d4c, 0xc600db6, 0xc680d7a,
+ 0xc700c3c, 0xc800d5b, 0xc880d89, 0xc900c1c, 0xca00cc0, 0xcb00d98, 0xcb80d79, 0xcc00be2,
+ 0xce00c2e, 0xcf00c1e, 0xd000cd3, 0xd100c2d, 0xd200cd2, 0xd300cd1, 0xd400c3b, 0xd500d97,
+ 0xd580d88, 0xd600b1d, 0xd800cc4, 0xd900c6b, 0xda00cc3, 0xdb00ca7, 0xdc00b2c, 0xde00cc2,
+ 0xdf00cb5, 0xe000cc1, 0xe100c0c, 0xe200c4b, 0xe300cb4, 0xe400c6a, 0xe500ca6, 0xe600bb3,
+ 0xe800c5a, 0xe900ca5, 0xea00b2b, 0xec00bb2, 0xee00b1b, 0xf000bb1, 0xf200c0b, 0xf300cb0,
+ 0xf400c69, 0xf500c96, 0xf600c4a, 0xf700ca4, 0xf800c78, 0xf900c87, 0xfa00ba3, 0xfc00c3a,
+ 0xfd00c59, 0xfe00b2a, 0x10000c95, 0x10100c68, 0x10200ba1, 0x10400c86, 0x10500c77, 0x10600b94,
+ 0x10800c49, 0x10900c57, 0x10a00b67, 0x10c00aa2, 0x11000a1a, 0x11400b0a, 0x11600ba0, 0x11800b39,
+ 0x11a00b93, 0x11c00b58, 0x11e00b85, 0x12000a29, 0x12400a92, 0x12800b76, 0x12a00b09, 0x12c00a19,
+ 0x13000a91, 0x13400b90, 0x13600b48, 0x13800b84, 0x13a00b75, 0x13c00b38, 0x13e00b83, 0x14000b66,
+ 0x14200b28, 0x14400a82, 0x14800b47, 0x14a00b74, 0x14c00a18, 0x15000a81, 0x15400a80, 0x15800b08,
+ 0x15a00b56, 0x15c00a37, 0x16000a73, 0x16400b65, 0x16600b46, 0x16800a27, 0x16c00a72, 0x17000b64,
+ 0x17200b55, 0x17400a07, 0x17800917, 0x18000971, 0x18800a70, 0x18c00a36, 0x19000a63, 0x19400a45,
+ 0x19800a54, 0x19c00a26, 0x1a000962, 0x1a800916, 0x1b000961, 0x1b800a06, 0x1bc00a60, 0x1c000953,
+ 0x1c800a35, 0x1cc00a44, 0x1d000925, 0x1d800952, 0x1e000851, 0x1f000915, 0x1f800905, 0x20000934,
+ 0x20800943, 0x21000950, 0x21800924, 0x22000942, 0x22800933, 0x23000814, 0x24000841, 0x25000904,
+ 0x25800940, 0x26000823, 0x27000832, 0x28000713, 0x2a000731, 0x2c000803, 0x2d000830, 0x2e000722,
+ 0x30000612, 0x34000621, 0x38000602, 0x3c000620, 0x40000411, 0x50000401, 0x60000310, 0x80000100};
+unsigned int h24[256]={ 0x8ef, 0x10008fe, 0x20008df, 0x30008fd, 0x40008cf, 0x50008fc, 0x60008bf, 0x70008fb,
+ 0x80007fa, 0xa0008af, 0xb00089f, 0xc0007f9, 0xe0007f8, 0x1000088f, 0x1100087f, 0x120007f7,
+ 0x1400076f, 0x160007f6, 0x1800075f, 0x1a0007f5, 0x1c00074f, 0x1e0007f4, 0x2000073f, 0x220007f3,
+ 0x2400072f, 0x260007f2, 0x280007f1, 0x2a00081f, 0x2b0008f0, 0x2c00090f, 0x2c800bee, 0x2ca00bde,
+ 0x2cc00bed, 0x2ce00bce, 0x2d000bec, 0x2d200bdd, 0x2d400bbe, 0x2d600beb, 0x2d800bcd, 0x2da00bdc,
+ 0x2dc00bae, 0x2de00bea, 0x2e000bbd, 0x2e200bdb, 0x2e400bcc, 0x2e600b9e, 0x2e800be9, 0x2ea00bad,
+ 0x2ec00bda, 0x2ee00bbc, 0x2f000bcb, 0x2f200b8e, 0x2f400be8, 0x2f600b9d, 0x2f800bd9, 0x2fa00b7e,
+ 0x2fc00be7, 0x2fe00bac, 0x300004ff, 0x40000bca, 0x40200bbb, 0x40400b8d, 0x40600bd8, 0x40800c0e,
+ 0x40900ce0, 0x40a00b0d, 0x40c00ae6, 0x41000b6e, 0x41200b9c, 0x41400ac9, 0x41800a5e, 0x41c00aba,
+ 0x42000ae5, 0x42400bab, 0x42600b7d, 0x42800ad7, 0x42c00ae4, 0x43000a8c, 0x43400ac8, 0x43800b4e,
+ 0x43a00b2e, 0x43c00a3e, 0x44000a6d, 0x44400ad6, 0x44800ae3, 0x44c00a9b, 0x45000ab9, 0x45400aaa,
+ 0x45800ae2, 0x45c00a1e, 0x46000ae1, 0x46400a5d, 0x46800ad5, 0x46c00a7c, 0x47000ac7, 0x47400a4d,
+ 0x47800a8b, 0x47c00ab8, 0x48000ad4, 0x48400a9a, 0x48800aa9, 0x48c00a6c, 0x49000ac6, 0x49400a3d,
+ 0x49800ad3, 0x49c00a2d, 0x4a000ad2, 0x4a400a1d, 0x4a800a7b, 0x4ac00ab7, 0x4b000ad1, 0x4b400a5c,
+ 0x4b800ac5, 0x4bc00a8a, 0x4c000aa8, 0x4c400a99, 0x4c800a4c, 0x4cc00ac4, 0x4d000a6b, 0x4d400ab6,
+ 0x4d800bd0, 0x4da00b0c, 0x4dc00a3c, 0x4e000ac3, 0x4e400a7a, 0x4e800aa7, 0x4ec00a2c, 0x4f000ac2,
+ 0x4f400a5b, 0x4f800ab5, 0x4fc00a1c, 0x50000a89, 0x50400a98, 0x50800ac1, 0x50c00a4b, 0x51000bc0,
+ 0x51200b0b, 0x51400a3b, 0x51800bb0, 0x51a00b0a, 0x51c00a1a, 0x520009b4, 0x52800a6a, 0x52c00aa6,
+ 0x53000a79, 0x53400a97, 0x53800ba0, 0x53a00b09, 0x53c00a90, 0x540009b3, 0x54800988, 0x55000a2b,
+ 0x55400a5a, 0x558009b2, 0x56000aa5, 0x56400a1b, 0x56800ab1, 0x56c00a69, 0x57000996, 0x578009a4,
+ 0x58000a4a, 0x58400a78, 0x58800987, 0x5900093a, 0x598009a3, 0x5a000959, 0x5a800995, 0x5b00092a,
+ 0x5b8009a2, 0x5c0009a1, 0x5c800968, 0x5d000986, 0x5d800977, 0x5e000949, 0x5e800994, 0x5f000939,
+ 0x5f800993, 0x60000958, 0x60800985, 0x61000929, 0x61800967, 0x62000976, 0x62800992, 0x63000919,
+ 0x63800991, 0x64000948, 0x64800984, 0x65000957, 0x65800975, 0x66000938, 0x66800983, 0x67000966,
+ 0x67800928, 0x68000982, 0x68800918, 0x69000947, 0x69800974, 0x6a000981, 0x6a800a08, 0x6ac00a80,
+ 0x6b000956, 0x6b800965, 0x6c000917, 0x6c800a07, 0x6cc00a70, 0x6d000873, 0x6e000937, 0x6e800927,
+ 0x6f000872, 0x70000846, 0x71000864, 0x72000855, 0x73000871, 0x74000836, 0x75000863, 0x76000845,
+ 0x77000854, 0x78000826, 0x79000862, 0x7a000816, 0x7b000861, 0x7c000906, 0x7c800960, 0x7d000835,
+ 0x7e000853, 0x7f000844, 0x80000825, 0x81000852, 0x82000815, 0x83000905, 0x83800950, 0x84000751,
+ 0x86000834, 0x87000843, 0x88000724, 0x8a000742, 0x8c000733, 0x8e000714, 0x90000741, 0x92000804,
+ 0x93000840, 0x94000723, 0x96000732, 0x98000613, 0x9c000631, 0xa0000703, 0xa2000730, 0xa4000622,
+ 0xa8000512, 0xb0000521, 0xb8000602, 0xbc000620, 0xc0000411, 0xd0000401, 0xe0000410, 0xf0000400};
+unsigned int hA[16]={ 0x6b0, 0x40006f0, 0x80006d0, 0xc0006e0, 0x10000670, 0x14000650, 0x18000590, 0x20000560,
+ 0x28000530, 0x300005a0, 0x380005c0, 0x40000420, 0x50000410, 0x60000440, 0x70000480, 0x80000100};
+unsigned int hB[16]={ 0x4f0, 0x100004e0, 0x200004d0, 0x300004c0, 0x400004b0, 0x500004a0, 0x60000490, 0x70000480,
+ 0x80000470, 0x90000460, 0xa0000450, 0xb0000440, 0xc0000430, 0xd0000420, 0xe0000410, 0xf0000400};
+
+/* now the cues, remember to change these tables if you change N_CUE
+*/
+unsigned char h_cue[34][N_CUE]={
+{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+{0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3},
+{0,3,5,5,6,6,7,7,8,8,8,8,8,8,8,8},
+{0,3,5,5,6,6,6,6,7,7,7,7,8,8,8,8},
+{0,8,12,12,13,13,14,14,15,15,15,15,15,15,15,15},
+{0,8,12,12,13,13,14,14,15,15,15,15,15,15,15,15},
+{0,5,7,9,10,11,12,12,13,13,13,13,14,14,15,15},
+{0,20,29,32,33,33,34,34,35,35,35,35,35,35,35,35},
+{0,23,30,31,32,32,32,32,33,33,34,34,35,35,35,35},
+{0,15,21,24,27,29,30,31,32,32,33,33,34,34,35,35},
+{0,42,56,60,61,61,62,62,63,63,63,63,63,63,63,63},
+{0,30,45,53,57,58,60,60,61,61,62,62,63,63,63,63},
+{0,23,37,46,50,54,56,57,58,60,61,61,62,62,63,63},
+{0,203,238,248,252,253,254,254,255,255,255,255,255,255,255,255},
+{0,132,178,205,223,233,240,245,248,250,252,252,253,254,255,255},
+{0,132,178,205,223,233,240,245,248,250,252,252,253,254,255,255},
+{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
+{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
+{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
+{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
+{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
+{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
+{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
+{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
+{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
+{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
+{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
+{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
+{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
+{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
+{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
+{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
+{0,4,7,9,11,12,13,14,15,15,15,15,15,15,15,15},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
+};
+
+/* h4->h5, h14->h15 as suggested by Fraunhofer
+ * tomislav Aug 21 1997
+ */
+unsigned int *tables[34]={h0,h1,h2,h3,h5,h5,h6,h7,h8,h9,h10,h11,h12,h13,h15,h15,
+ h16,h16,h16,h16,h16,h16,h16,h16,h24,h24,h24,h24,h24,h24,h24,h24,hA,hB};
+#endif /* HUFFMAN */
diff --git a/Src/Sound/MPEG/layer2.cpp b/Src/Sound/MPEG/layer2.cpp
new file mode 100644
index 0000000..852dcdc
--- /dev/null
+++ b/Src/Sound/MPEG/layer2.cpp
@@ -0,0 +1,324 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* layer2.c MPEG audio layer2 support
+ *
+ * Created by: Tomislav Uzelac Mar 1996
+ * merged with amp, May 19 1997
+ */
+#include "amp.h"
+#include "audio.h"
+#include "getbits.h"
+#include "transform.h"
+
+#define LAYER2
+#include "layer2.h"
+
+int layer2_frame(struct AUDIO_HEADER *header,int cnt)
+{
+int i,s,sb,ch,gr,bitrate,bound=0;
+char (*nbal)[],(*bit_alloc_index)[][16];
+unsigned char allocation[2][32];
+unsigned char scfsi[2][32];
+float scalefactor[2][32][3];
+float subband_sample[2][32][36];
+int sblimit,nlevels,grouping;
+
+float c,d;
+int no_of_bits,mpi;
+unsigned short sb_sample_buf[3];
+
+int hsize,fs,mean_frame_size;
+
+ bit_alloc_index=(char (*)[][16])&t_alloc0;
+ nbal=(char (*)[])&t_nbal0; // shut up compiler
+ sblimit = 0;
+
+ hsize=4;
+ if (header->protection_bit==0) hsize+=2;
+
+ bitrate=t_bitrate[header->ID][3-header->layer][header->bitrate_index];
+ fs=t_sampling_frequency[header->ID][header->sampling_frequency];
+ if (header->ID) mean_frame_size=144000*bitrate/fs;
+ else mean_frame_size=72000*bitrate/fs;
+
+ /* layers 1 and 2 do not have a 'bit reservoir'
+ */
+ append=data=0;
+
+ fillbfr(mean_frame_size + header->padding_bit - hsize);
+
+ switch (header->mode)
+ {
+ case 0 :
+ case 2 : nch=2; bound=32; bitrate=bitrate/2;
+ break;
+ case 3 : nch=1; bound=32;
+ break;
+ case 1 : nch=2; bitrate=bitrate/2; bound=(header->mode_extension+1)*4;
+ }
+
+ if (header->ID==1) switch (header->sampling_frequency) {
+ case 0 : switch (bitrate) /* 0 = 44.1 kHz */
+ {
+ case 56 :
+ case 64 :
+ case 80 : bit_alloc_index=(char (*)[][16])&t_alloc0;
+ nbal=(char (*)[])&t_nbal0;
+ sblimit=27;
+ break;
+ case 96 :
+ case 112 :
+ case 128 :
+ case 160 :
+ case 192 : bit_alloc_index=(char (*)[][16])&t_alloc1;
+ nbal=(char (*)[])&t_nbal1;
+ sblimit=30;
+ break;
+ case 32 :
+ case 48 : bit_alloc_index=(char (*)[][16])&t_alloc2;
+ nbal=(char (*)[])&t_nbal2;
+ sblimit=8;
+ break;
+ default : printf(" bit alloc info no gud ");
+ }
+ break;
+ case 1 : switch (bitrate) /* 1 = 48 kHz */
+ {
+ case 56 :
+ case 64 :
+ case 80 :
+ case 96 :
+ case 112 :
+ case 128 :
+ case 160 :
+ case 192 : bit_alloc_index=(char (*)[][16])&t_alloc0;
+ nbal=(char (*)[])&t_nbal0;
+ sblimit=27;
+ break;
+ case 32 :
+ case 48 : bit_alloc_index=(char (*)[][16])&t_alloc2;
+ nbal=(char (*)[])&t_nbal2;
+ sblimit=8;
+ break;
+ default : printf(" bit alloc info no gud ");
+ }
+ break;
+ case 2 : switch (bitrate) /* 2 = 32 kHz */
+ {
+ case 56 :
+ case 64 :
+ case 80 : bit_alloc_index=(char (*)[][16])&t_alloc0;
+ nbal=(char (*)[])&t_nbal0;
+ sblimit=27;
+ break;
+ case 96 :
+ case 112 :
+ case 128 :
+ case 160 :
+ case 192 : bit_alloc_index=(char (*)[][16])&t_alloc1;
+ nbal=(char (*)[])&t_nbal1;
+ sblimit=30;
+ break;
+ case 32 :
+ case 48 : bit_alloc_index=(char (*)[][16])&t_alloc3;
+ nbal=(char (*)[])&t_nbal3;
+ sblimit=12;
+ break;
+ default : printf("bit alloc info not ok\n");
+ }
+ break;
+ default : printf("sampling freq. not ok/n");
+ } else {
+ bit_alloc_index=(char (*)[][16])&t_allocMPG2;
+ nbal=(char (*)[])&t_nbalMPG2;
+ sblimit=30;
+ }
+
+/*
+ * bit allocation per subband per channel decoding *****************************
+ */
+
+ if (bound==32) bound=sblimit; /* bound=32 means there is no intensity stereo */
+
+ for (sb=0;sb>2];
+ }
+ }
+ } else
+ for (s=0;s<3;s++) subband_sample[ch][sb][3*gr+s]=0;
+
+
+ /*
+ * joint stereo ********************************************
+ */
+
+ for (sb=bound;sb>2];
+ }
+ }
+
+ } else for (s=0;s<3;s++) {
+ subband_sample[0][sb][3*gr+s]=0;
+ subband_sample[1][sb][3*gr+s]=0;
+ }
+
+ /*
+ * the rest *******************************************
+ */
+ for (sb=sblimit;sb<32;sb++)
+ for (ch=0;chmode!=3) {
+ for (ch=0;chmode!=3) nch=2;
+
+ return 0;
+}
+/****************************************************************************/
+/****************************************************************************/
+
+void convert_samplecode(unsigned int samplecode,unsigned int nlevels,unsigned short* sb_sample_buf)
+{
+int i;
+
+ for (i=0;i<3;i++) {
+ *sb_sample_buf=samplecode%nlevels;
+ samplecode=samplecode/nlevels;
+ sb_sample_buf++;
+ }
+}
+
+float requantize_sample(unsigned short s4,unsigned short nlevels,float c,float d,float factor)
+{
+register float s,s2,s3;
+s3=(float) (-1.0+s4*2.0/(nlevels+1));
+s2=c*(s3+d);
+s=factor*s2;
+return s;
+}
diff --git a/Src/Sound/MPEG/layer2.h b/Src/Sound/MPEG/layer2.h
new file mode 100644
index 0000000..5dacc4f
--- /dev/null
+++ b/Src/Sound/MPEG/layer2.h
@@ -0,0 +1,190 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+/* layer2.h
+ * Tomislav Uzelac - cca. Feb 1996
+ */
+
+
+extern int layer2_frame(struct AUDIO_HEADER *header,int cnt);
+
+#ifdef LAYER2
+
+int layer2_frame(struct AUDIO_HEADER *header,int cnt);
+float requantize_sample(unsigned short s4,unsigned short nlevels,float c,float d,float factor);
+void convert_samplecode(unsigned int samplecode,unsigned int nlevels,unsigned short* sb_sample_buf);
+
+char t_nbal0[27]={4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2};
+char t_nbal1[30]={4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2};
+char t_nbal2[8] ={4,4,3,3,3,3,3,3};
+char t_nbal3[12]={4,4,3,3,3,3,3,3,3,3,3,3};
+char t_nbalMPG2[30]={4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};
+
+char t_alloc0[27][16] = { /* table B.2a ISO/IEC 11172-3 */
+{0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17},
+{0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17},
+{0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,17},
+{0,1,2,17},
+{0,1,2,17},
+{0,1,2,17}};
+
+char t_alloc1[30][16] = { /* table B.2b ISO/IEC 11172-3 */
+{0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17},
+{0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17},
+{0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,3,4,5,6,17},
+{0,1,2,17},
+{0,1,2,17},
+{0,1,2,17},
+{0,1,2,17},
+{0,1,2,17},
+{0,1,2,17},
+{0,1,2,17}};
+
+char t_alloc2[8][16] = { /* table B.2c ISO/IEC 11172-3 */
+{0,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16},
+{0,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16},
+{0,1,2,4,5,6,7,127},
+{0,1,2,4,5,6,7,127},
+{0,1,2,4,5,6,7,127},
+{0,1,2,4,5,6,7,127},
+{0,1,2,4,5,6,7,127},
+{0,1,2,4,5,6,7,127}};
+
+char t_alloc3[12][16] = { /* table B.2d ISO/IEC 11172-3 */
+{0,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16},
+{0,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16},
+{0,1,2,4,5,6,7,127},
+{0,1,2,4,5,6,7,127},
+{0,1,2,4,5,6,7,127},
+{0,1,2,4,5,6,7,127},
+{0,1,2,4,5,6,7,127},
+{0,1,2,4,5,6,7,127},
+{0,1,2,4,5,6,7,127},
+{0,1,2,4,5,6,7,127},
+{0,1,2,4,5,6,7,127},
+{0,1,2,4,5,6,7,127}};
+
+char t_allocMPG2[30][16] = { /* table B.1. ISO/IEC 13818-3 */
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
+{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
+{0,1,2,4,5,6,7,8},
+{0,1,2,4,5,6,7,8},
+{0,1,2,4,5,6,7,8},
+{0,1,2,4,5,6,7,8},
+{0,1,2,4,5,6,7,8},
+{0,1,2,4,5,6,7,8},
+{0,1,2,4,5,6,7,8},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4},
+{0,1,2,4}};
+
+double t_scalefactor[64] = {
+2.00000000000000, 1.58740105196820, 1.25992104989487,
+1.00000000000000, 0.79370052598410, 0.62996052494744, 0.50000000000000,
+0.39685026299205, 0.31498026247372, 0.25000000000000, 0.19842513149602,
+0.15749013123686, 0.12500000000000, 0.09921256574801, 0.07874506561843,
+0.06250000000000, 0.04960628287401, 0.03937253280921, 0.03125000000000,
+0.02480314143700, 0.01968626640461, 0.01562500000000, 0.01240157071850,
+0.00984313320230, 0.00781250000000, 0.00620078535925, 0.00492156660115,
+0.00390625000000, 0.00310039267963, 0.00246078330058, 0.00195312500000,
+0.00155019633981, 0.00123039165029, 0.00097656250000, 0.00077509816991,
+0.00061519582514, 0.00048828125000, 0.00038754908495, 0.00030759791257,
+0.00024414062500, 0.00019377454248, 0.00015379895629, 0.00012207031250,
+0.00009688727124, 0.00007689947814, 0.00006103515625, 0.00004844363562,
+0.00003844973907, 0.00003051757813, 0.00002422181781, 0.00001922486954,
+0.00001525878906, 0.00001211090890, 0.00000961243477, 0.00000762939453,
+0.00000605545445, 0.00000480621738, 0.00000381469727, 0.00000302772723,
+0.00000240310869, 0.00000190734863, 0.00000151386361, 0.00000120155435,
+1E-20};
+
+double t_c[18] = { 0,
+ 1.33333333333, 1.60000000000, 1.14285714286,
+ 1.77777777777, 1.06666666666, 1.03225806452,
+ 1.01587301587, 1.00787401575, 1.00392156863,
+ 1.00195694716, 1.00097751711, 1.00048851979,
+ 1.00024420024, 1.00012208522, 1.00006103888,
+ 1.00003051851, 1.00001525902 };
+
+double t_d[18] = {0,
+ 0.500000000, 0.500000000, 0.250000000, 0.500000000,
+ 0.125000000, 0.062500000, 0.031250000, 0.015625000,
+ 0.007812500, 0.003906250, 0.001953125, 0.0009765625,
+ 0.00048828125,0.00024414063,0.00012207031,
+ 0.00006103516,0.00003051758 };
+
+float t_dd[18]={ -1.0f, -0.5f, -0.5f, -0.75f, -0.5f, -0.875f, -0.9375f, -0.96875f, -0.984375f,
+-0.992188f, -0.996094f, -0.998047f, -0.999023f, -0.999512f, -0.999756f, -0.999878f, -0.999939f,
+-0.999969f};
+
+char t_grouping[18]={0,3,5,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+/*
+int t_nlevels[18] = {0,3,5,7,9,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535};
+*/
+int t_nlevels[18] = {0,3,7,7,15,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535};
+
+
+float t_nli[18]={ 0.0f, 0.5f, 0.25f, 0.25f, 0.125f, 0.125f, 0.0625f, 0.03125f, 0.015625f, 0.0078125f, 0.00390625f,
+0.00195313f, 0.000976563f, 0.000488281f, 0.000244141f, 0.00012207f, 6.10352e-05f, 3.05176e-05f};
+
+int t_bpc[18] = {0,5,7,3,10,4,5,6,7,8,9,10,11,12,13,14,15,16};
+
+#endif /* LAYER2 */
diff --git a/Src/Sound/MPEG/layer3.cpp b/Src/Sound/MPEG/layer3.cpp
new file mode 100644
index 0000000..a0161fb
--- /dev/null
+++ b/Src/Sound/MPEG/layer3.cpp
@@ -0,0 +1,197 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* layer3.c layer3 audio decoding
+ *
+ * Created by: tomislav uzelac Mar 1 97
+ * Last modified by:
+ */
+#include "amp.h"
+#include "audio.h"
+#include "dump.h"
+#include "getbits.h"
+#include "getdata.h"
+#include "huffman.h"
+#include "misc2.h"
+#include "rtbuf.h"
+#include "transform.h"
+
+#define LAYER3
+#include "layer3.h"
+
+void requantize_downmix(int gr,struct SIDE_INFO *info,struct AUDIO_HEADER *header);
+
+/* this function decodes one layer3 audio frame, except for the header decoding
+ * which is done in main() [audio.c]. returns 0 if everything is ok.
+ */
+int layer3_frame(struct AUDIO_HEADER *header,int cnt)
+{
+static struct SIDE_INFO info;
+
+int gr,ch,sb,i;
+int mean_frame_size,bitrate,fs,hsize,ssize;
+
+/* we need these later, hsize is the size of header+side_info
+*/
+ if (header->ID)
+ if (header->mode==3) {
+ nch=1;
+ hsize=21;
+ } else {
+ nch=2;
+ hsize=36;
+ }
+ else
+ if (header->mode==3) {
+ nch=1;
+ hsize=13;
+ } else {
+ nch=2;
+ hsize=21;
+ }
+
+/* crc increases hsize by 2
+*/
+ if (header->protection_bit==0) hsize+=2;
+
+
+/* read layer3 specific side_info
+*/
+ getinfo(header,&info);
+
+
+/* MPEG2 only has one granule
+*/
+ bitrate=t_bitrate[header->ID][3-header->layer][header->bitrate_index];
+ fs=t_sampling_frequency[header->ID][header->sampling_frequency];
+ if (header->ID) mean_frame_size=144000*bitrate/fs;
+ else mean_frame_size=72000*bitrate/fs;
+
+
+/* check if mdb is too big for the first few frames. this means that
+ * a part of the stream could be missing. We must still fill the buffer
+ *
+ * don't forget to (re)initialise bclean_bytes to 0, and f_bdirty to FALSE!!!
+ */
+ if (f_bdirty)
+ {
+ if (info.main_data_begin > bclean_bytes) {
+ fillbfr(mean_frame_size + header->padding_bit - hsize);
+ bclean_bytes+=mean_frame_size + header->padding_bit - hsize;
+ /* warn(" frame %d discarded, incomplete main_data\n",cnt); */
+ return 0;
+ } else {
+ /* re-initialise */
+ f_bdirty=FALSE;
+ bclean_bytes=0;
+ }
+ }
+
+/* now update the data 'pointer' (counting in bits) according to
+ * the main_data_begin information
+ */
+ data = 8 * ((append - info.main_data_begin) & (BUFFER_SIZE-1));
+
+
+/* read into the buffer all bytes up to the start of next header
+*/
+ fillbfr(mean_frame_size + header->padding_bit - hsize);
+
+
+/* these two should go away
+*/
+ t_l=&t_b8_l[header->ID][header->sampling_frequency][0];
+ t_s=&t_b8_s[header->ID][header->sampling_frequency][0];
+
+/* debug/dump stuff
+*/
+ if (A_DUMP_BINARY) dump((int *)info.part2_3_length);
+
+/* decode the scalefactors and huffman data
+ * this part needs to be enhanced for error robustness
+ */
+ for (gr=0;gr < ((header->ID) ? 2 : 1);gr++) {
+ for (ch=0;chmode!=1 || (header->mode==1 && header->mode_extension==0))
+ for (ch=0;chmode!=3) nch=2;
+
+ } /* for (gr... */
+
+ /* return status: 0 for ok, errors will be added
+ */
+ return 0;
+}
+
diff --git a/Src/Sound/MPEG/layer3.h b/Src/Sound/MPEG/layer3.h
new file mode 100644
index 0000000..d8c08ed
--- /dev/null
+++ b/Src/Sound/MPEG/layer3.h
@@ -0,0 +1,16 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* layer3.h
+ *
+ * Created by: tomislav uzelac Mar 1 97
+ * Last modified by:
+ */
+
+extern int layer3_frame(struct AUDIO_HEADER *header,int cnt);
+
+#ifdef LAYER3
+
+int layer3_frame(struct AUDIO_HEADER *header,int cnt);
+
+#endif /* LAYER3 */
diff --git a/Src/Sound/MPEG/misc2.cpp b/Src/Sound/MPEG/misc2.cpp
new file mode 100644
index 0000000..fd5b7e5
--- /dev/null
+++ b/Src/Sound/MPEG/misc2.cpp
@@ -0,0 +1,822 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* misc2.c requantization, stereo processing, reordering(shortbl) and antialiasing butterflies
+ *
+ * misc.c was created by tomislav uzelac in May 1996, and was completely awful
+ * Created by: tomislav uzelac Dec 22 1996
+ * some more speed injected, cca. Jun 1 1997
+ */
+#include
+#include
+
+#include "amp.h"
+#include "audio.h"
+#include "getdata.h"
+#include "huffman.h"
+
+#define MISC2
+#include "misc2.h"
+
+/*
+ * fras == Formula for Requantization and All Scaling **************************
+ */
+static inline float fras_l(int sfb,int global_gain,int scalefac_scale,int scalefac,int preflag)
+{
+register int a,scale;
+ /*
+ if (scalefac_scale) scale=2;
+ else scale=1;
+ */
+ scale=scalefac_scale+1;
+ a= global_gain -210 -(scalefac << scale);
+ if (preflag) a-=(t_pretab[sfb] << scale);
+
+/* bugfix, Mar 13 97: shifting won't produce a legal result if we shift by more than 31
+ * since global_gain<256, this can only occur for (very) negative values of a.
+*/
+ if (a < -127) return 0;
+
+/* a minor change here as well, no point in abs() if we now that a<0
+*/
+ if (a>=0) return tab[a&3]*(1 << (a>>2));
+ else return tabi[(-a)&3]/(1 << ((-a) >> 2));
+}
+
+static inline float fras_s(int global_gain,int subblock_gain,int scalefac_scale,int scalefac)
+{
+int a;
+ a=global_gain - 210 - (subblock_gain << 3);
+ if (scalefac_scale) a-= (scalefac << 2);
+ else a-= (scalefac << 1);
+
+ if (a < -127) return 0;
+
+ if (a>=0) return tab[a&3]*(1 << (a>>2));
+ else return tabi[(-a)&3]/(1 << ((-a) >> 2));
+}
+
+/* this should be faster than pow()
+ */
+static inline float fras2(int is,float a)
+{
+ if (is > 0) return t_43[is]*a;
+ else return -t_43[-is]*a;
+}
+
+/*
+ * requantize_mono *************************************************************
+ */
+
+/* generally, the two channels do not have to be of the same block type - that's why we do two passes with requantize_mono.
+ * if ms or intensity stereo is enabled we do a single pass with requantize_ms because both channels are same block type
+ */
+
+void requantize_mono(int gr,int ch,struct SIDE_INFO *info,struct AUDIO_HEADER *header)
+{
+int l,i,sfb;
+float a;
+int global_gain=info->global_gain[gr][ch];
+int scalefac_scale=info->scalefac_scale[gr][ch];
+int sfreq=header->sampling_frequency;
+
+
+ no_of_imdcts[0]=no_of_imdcts[1]=32;
+
+ if (info->window_switching_flag[gr][ch] && info->block_type[gr][ch]==2)
+ if (info->mixed_block_flag[gr][ch]) {
+ /*
+ * requantize_mono - mixed blocks/long block part **********************
+ */
+ int window,window_len,preflag=0; /* pretab is all zero in this low frequency area */
+ int scalefac=scalefac_l[gr][ch][0];
+
+ l=0;sfb=0;
+ a=fras_l(sfb,global_gain,scalefac_scale,scalefac,preflag);
+ while (l<36) {
+ xr[ch][0][l]=fras2(is[ch][l],a);
+ if (l==t_l[sfb]) {
+ scalefac=scalefac_l[gr][ch][++sfb];
+ a=fras_l(sfb,global_gain,scalefac_scale,scalefac,preflag);
+ }
+ l++;
+ }
+ /*
+ * requantize_mono - mixed blocks/short block part *********************
+ */
+ sfb=3;
+ window_len=t_s[sfb]-t_s[sfb-1];
+ while (lsubblock_gain[gr][ch][window];
+ a=fras_s(global_gain,subblock_gain,scalefac_scale,scalefac);
+ for (i=0;iID][sfreq][l]]=fras2(is[ch][l],a);
+ l++;
+ }
+ }
+ sfb++;
+ window_len=t_s[sfb]-t_s[sfb-1];
+ }
+ while (l<576) xr[ch][0][t_reorder[header->ID][sfreq][l++]]=0;
+ } else {
+ /*
+ * requantize mono - short blocks **************************************
+ */
+ int window,window_len;
+
+ sfb=0; l=0;
+ window_len=t_s[0]+1;
+ while (lsubblock_gain[gr][ch][window];
+ float a=fras_s(global_gain,subblock_gain,scalefac_scale,scalefac);
+ for (i=0;iID][sfreq][l]]=fras2(is[ch][l],a);
+ l++;
+ }
+ }
+ sfb++;
+ window_len=t_s[sfb]-t_s[sfb-1];
+ }
+ while (l<576) xr[ch][0][t_reorder[header->ID][sfreq][l++]]=0;
+ }
+ else {
+ /* long blocks */
+ int preflag=info->preflag[gr][ch];
+ int scalefac=scalefac_l[gr][ch][0];
+
+ sfb=0; l=0;
+ a=fras_l(sfb,global_gain,scalefac_scale,scalefac,preflag);
+ while (lmode_extension==1 || header->mode_extension==3) {
+ if (info->window_switching_flag[gr][0] && info->block_type[gr][0]==2) {
+
+ /* find that isbound!
+ */
+ tmp=non_zero[1];
+ sfb=0; while ((3*t_s[sfb]+2) < tmp && sfb < 12) sfb++;
+ while ((isbound[0]<0 || isbound[1]<0 || isbound[2]<0) && !(info->mixed_block_flag[gr][0] && sfb<3) && sfb) {
+ for (window=0;window<3;window++) {
+ if (sfb==0) {
+ window_len=t_s[0]+1;
+ tmp=(window+1)*window_len - 1;
+ } else {
+ window_len=t_s[sfb]-t_s[sfb-1];
+ tmp=(3*t_s[sfb-1]+2) + (window+1)*window_len;
+ }
+ if (isbound[window] < 0)
+ for (i=0;imixed_block_flag[gr][0])
+ {
+ if (isbound[0]<0 && isbound[1]<0 && isbound[2]<0)
+ {
+ tmp=35;
+ while (is[1][tmp] == 0) tmp--;
+ sfb=0; while (t_l[sfb] < tmp && sfb < 21) sfb++;
+ isbound[0]=isbound[1]=isbound[2]=t_l[sfb]+1;
+ }
+ else for (window=0;window<3;window++)
+ if (isbound[window]<0) isbound[window]=36;
+ }
+ if (header->ID==1) isbound[0]=isbound[1]=isbound[2]=MAX(isbound[0],MAX(isbound[1],isbound[2]));
+
+ /* just how many imdcts?
+ */
+ tmp=non_zero[0];
+ sfb=0; while ((3*t_s[sfb]+2) < tmp && sfb < 12) sfb++;
+ no_of_imdcts[0]=no_of_imdcts[1]=(t_s[sfb]-1)/6+1;
+ } else {
+
+ /* long blocks now
+ */
+ tmp=non_zero[1];
+ while (is[1][tmp] == 0) tmp--;
+ sfb=0; while (t_l[sfb] < tmp && sfb < 21) sfb++;
+ isbound[0]=isbound[1]=isbound[2]=t_l[sfb]+1;
+ no_of_imdcts[0]=no_of_imdcts[1]=(non_zero[0]-1)/18+1;
+ }
+ if (header->mode_extension==1) ms_flag=0;
+ else ms_flag=1;
+ } else {
+
+ /* intensity stereo is, regretably, turned off
+ */
+ ms_flag=1;
+
+ /* i really put a lot of work in this, but it still looks like shit (works, though)
+ */
+ if (!info->window_switching_flag[gr][0] || (info->window_switching_flag[gr][0] && info->block_type[gr][0]!=2))
+ isbound[0]=isbound[1]=isbound[2]=(MAX(non_zero[0],non_zero[1]));
+ else isbound[0]=isbound[1]=isbound[2]=576;
+
+ if (info->window_switching_flag[gr][0] && info->block_type[gr][0]==2) {
+ /* should do for mixed blocks too, though i havent tested... */
+ tmp=(MAX(non_zero[0],non_zero[1]))/3;
+ sfb=0; while (t_s[sfb]=576) return; /* brrr... */
+
+ if ((is_pos != IS_ILLEGAL) && (header->ID==1)) {
+ ftmp=fras2(is[0][l],a[0]);
+ xr[0][0][pos]=(1-t_is[is_pos])*ftmp;
+ xr[1][0][pos]=t_is[is_pos]*ftmp;
+ return;
+ }
+
+ if ((is_pos != IS_ILLEGAL) && (header->ID==0)) {
+ ftmp=fras2(is[0][l],a[0]);
+ if (is_pos&1) {
+ xr[0][0][pos]= t_is2[intensity_scale][(is_pos+1)>>1] * ftmp;
+ xr[1][0][pos]= ftmp;
+ } else {
+ xr[0][0][pos]= ftmp;
+ xr[1][0][pos]= t_is2[intensity_scale][is_pos>>1] * ftmp;
+ }
+ return;
+ }
+
+ if (ms_flag) {
+ Mi=fras2(is[0][l],a[0]);
+ Si=fras2(is[1][l],a[1]);
+ xr[0][0][pos]=(Mi+Si)*i_sq2;
+ xr[1][0][pos]=(Mi-Si)*i_sq2;
+ } else {
+ xr[0][0][pos]=fras2(is[0][l],a[0]);
+ xr[1][0][pos]=fras2(is[1][l],a[1]);
+ }
+}
+
+static inline void stereo_l(int l,float a[2],int ms_flag,int is_pos,struct AUDIO_HEADER *header)
+{
+float ftmp,Mi,Si;
+ if (l>=576) return;
+
+/* new code by ???
+*/
+ if (is_pos != IS_ILLEGAL) {
+ ftmp = fras2(is[0][l], a[0]);
+ if (header -> ID ==1) {
+ xr[0][0][l] = (1 - t_is[is_pos]) * ftmp;
+ xr[1][0][l] = t_is[is_pos] * ftmp;
+ return;
+ } else if (is_pos & 1) {
+ xr[0][0][l] = t_is2[intensity_scale][(is_pos + 1) >> 1] * ftmp;
+ xr[1][0][l] = ftmp;
+ } else {
+ xr[0][0][l] = ftmp;
+ xr[1][0][l] = t_is2[intensity_scale][is_pos >> 1] * ftmp;
+ }
+ return;
+ }
+
+ if (ms_flag) {
+ Mi=fras2(is[0][l],a[0]);
+ Si=fras2(is[1][l],a[1]);
+ xr[0][0][l]=(Mi+Si)*i_sq2;
+ xr[1][0][l]=(Mi-Si)*i_sq2;
+ } else {
+ xr[0][0][l]=fras2(is[0][l],a[0]);
+ xr[1][0][l]=fras2(is[1][l],a[1]);
+ }
+
+}
+
+
+/*
+ * requantize_ms ***************************************************************
+ */
+void requantize_ms(int gr,struct SIDE_INFO *info,struct AUDIO_HEADER *header)
+{
+int l,sfb,ms_flag,is_pos,i,ch;
+int *global_gain,subblock_gain[2],*scalefac_scale,scalefac[2],isbound[3];
+int sfreq=header->sampling_frequency;
+int id = header->ID;
+float a[2];
+
+memset(a, 0, sizeof(a));
+
+global_gain=info->global_gain[gr];
+scalefac_scale=info->scalefac_scale[gr];
+
+ if (info->window_switching_flag[gr][0] && info->block_type[gr][0]==2)
+ if (info->mixed_block_flag[gr][0]) {
+ /*
+ * mixed blocks w/stereo processing - long block part ******************
+ */
+ int window,window_len;
+ int preflag[2]={0,0};
+
+ ms_flag=find_isbound(isbound,gr,info,header);
+
+ sfb=0; l=0;
+ for (ch=0;ch<2;ch++) {
+ scalefac[ch]=scalefac_l[gr][ch][0];
+ a[ch]=fras_l(0,global_gain[ch],scalefac_scale[ch],scalefac[ch],preflag[ch]);
+ }
+
+
+ while (l<36) {
+ int is_pos;
+ if (lsubblock_gain[gr][0][window];
+ subblock_gain[1]=info->subblock_gain[gr][1][window];
+ scalefac[0]=scalefac_s[gr][0][sfb][window];
+ scalefac[1]=scalefac_s[gr][1][sfb][window];
+
+ if (t_s[sfb] < isbound[window]) {
+ is_pos=IS_ILLEGAL;
+ a[0]=fras_s(global_gain[0],subblock_gain[0],scalefac_scale[0],scalefac[0]);
+ a[1]=fras_s(global_gain[1],subblock_gain[1],scalefac_scale[1],scalefac[1]);
+ } else {
+ is_pos=scalefac[1];
+ if (id==1) /* MPEG1 */
+ {
+ if (is_pos==7) is_pos=IS_ILLEGAL;
+ }
+ else /* MPEG2 */
+ {
+ if (is_pos==is_max[sfb+6]) is_pos=IS_ILLEGAL;
+ }
+
+ a[0]=fras_s(global_gain[0],subblock_gain[0],scalefac_scale[0],scalefac[0]);
+ }
+
+ for (i=0;isubblock_gain[gr][0][window];
+ subblock_gain[1]=info->subblock_gain[gr][1][window];
+ scalefac[0]=scalefac_s[gr][0][sfb][window];
+ scalefac[1]=scalefac_s[gr][1][sfb][window];
+
+ if (t_s[sfb] < isbound[window]) {
+ is_pos=IS_ILLEGAL;
+ a[0]=fras_s(global_gain[0],subblock_gain[0],scalefac_scale[0],scalefac[0]);
+ a[1]=fras_s(global_gain[1],subblock_gain[1],scalefac_scale[1],scalefac[1]);
+ } else {
+ is_pos=scalefac[1];
+ if (id==1) /* MPEG1 */
+ {
+ if (is_pos==7) is_pos=IS_ILLEGAL;
+ }
+ else /* MPEG2 */
+ {
+ if (is_pos==is_max[sfb+6]) is_pos=IS_ILLEGAL;
+ }
+ a[0]=fras_s(global_gain[0],subblock_gain[0],scalefac_scale[0],scalefac[0]);
+ }
+
+ for (i=0;ipreflag[gr];
+
+ ms_flag=find_isbound(isbound,gr,info,header);
+
+ sfb=0; l=0;
+ scalefac[0]=scalefac_l[gr][0][sfb];
+ a[0]=fras_l(sfb,global_gain[0],scalefac_scale[0],scalefac[0],preflag[0]);
+ scalefac[1]=scalefac_l[gr][1][sfb];
+ a[1]=fras_l(sfb,global_gain[1],scalefac_scale[1],scalefac[1],preflag[1]);
+
+ /* no intensity stereo part
+ */
+ if (ms_flag)
+ while (l< isbound[0]) {
+#if defined(PENTIUM_RDTSC)
+
+unsigned int cnt4, cnt3, cnt2, cnt1;
+static int min_cycles = 99999999;
+
+ __asm__(".byte 0x0f,0x31" : "=a" (cnt1), "=d" (cnt4));
+#endif
+
+ {
+ register float Mi = fras2(is[0][l],a[0]);
+ register float Si = fras2(is[1][l],a[1]);
+ register float tmp = i_sq2;
+ xr[0][0][l]=(Mi+Si)*tmp;
+ xr[1][0][l]=(Mi-Si)*tmp;
+ }
+
+#if defined(PENTIUM_RDTSC)
+ __asm__(".byte 0x0f,0x31" : "=a" (cnt2), "=d" (cnt4));
+
+ if (cnt2-cnt1 < min_cycles) {
+ min_cycles = cnt2-cnt1;
+ printf("%d cycles\n", min_cycles);
+ }
+
+#endif
+ if (l==t_l[sfb]) {
+#if defined(PENTIUM_RDTSC2)
+
+unsigned int cnt4, cnt2, cnt1;
+static int min_cycles = 99999999;
+
+ __asm__(".byte 0x0f,0x31" : "=a" (cnt1), "=d" (cnt4));
+#endif
+
+ sfb++;
+ scalefac[0]=scalefac_l[gr][0][sfb];
+ a[0]=fras_l(sfb,global_gain[0],scalefac_scale[0],scalefac[0],preflag[0]);
+ scalefac[1]=scalefac_l[gr][1][sfb];
+ a[1]=fras_l(sfb,global_gain[1],scalefac_scale[1],scalefac[1],preflag[1]);
+#if defined(PENTIUM_RDTSC2)
+ __asm__(".byte 0x0f,0x31" : "=a" (cnt2), "=d" (cnt4));
+
+ if (cnt2-cnt1 < min_cycles) {
+ min_cycles = cnt2-cnt1;
+ printf("%d cycles, sfb %d\n", min_cycles, sfb);
+ }
+
+#endif
+ }
+ l++;
+ }
+ else
+ while (l< isbound[0]) {
+ xr[0][0][l]=fras2(is[0][l],a[0]);
+ xr[1][0][l]=fras2(is[1][l],a[1]);
+ if (l==t_l[sfb]) {
+ sfb++;
+ scalefac[0]=scalefac_l[gr][0][sfb];
+ a[0]=fras_l(sfb,global_gain[0],scalefac_scale[0],scalefac[0],preflag[0]);
+ scalefac[1]=scalefac_l[gr][1][sfb];
+ a[1]=fras_l(sfb,global_gain[1],scalefac_scale[1],scalefac[1],preflag[1]);
+ }
+ l++;
+ }
+
+
+ /* intensity stereo part
+ */
+ while (l<(MAX(non_zero[0],non_zero[1]))) {
+ int is_pos=scalefac[1];
+
+ if (id==1) /* MPEG1 */
+ {
+ if (is_pos==7) is_pos=IS_ILLEGAL;
+ }
+ else /* MPEG2 */
+ {
+ if (is_pos==is_max[sfb]) is_pos=IS_ILLEGAL;
+ }
+ stereo_l(l,a,ms_flag,is_pos,header);
+
+ if (l==t_l[sfb]) {
+ sfb++;
+ scalefac[0]=scalefac_l[gr][0][sfb];
+ scalefac[1]=scalefac_l[gr][1][sfb];
+ a[0]=fras_l(sfb,global_gain[0],scalefac_scale[0],scalefac[0],preflag[0]);
+ }
+ l++;
+ }
+
+ while (l<576) {
+ xr[0][0][l]=0;
+ xr[1][0][l]=0;
+ l++;
+ }
+ }
+}
+
+/*
+ * requantize_downmix **********************************************************
+ */
+void requantize_downmix(int gr,struct SIDE_INFO *info,struct AUDIO_HEADER *header)
+{
+int l,sfb,ms_flag,i;
+int *global_gain,subblock_gain[2],*scalefac_scale,scalefac[2];
+int sfreq=header->sampling_frequency;
+int id = header->ID;
+float a[2];
+
+ /* first set some variables
+ */
+ global_gain=info->global_gain[gr];
+ scalefac_scale=info->scalefac_scale[gr];
+
+ if (header->mode_extension==2 || header->mode_extension==3) ms_flag=1;
+ else ms_flag=0;
+
+ /* ... and then we're off for requantization
+ */
+ if (info->window_switching_flag[gr][0] && info->block_type[gr][0]==2)
+ if (info->mixed_block_flag[gr][0]) {
+ die("mixed block? hmmmm...., downmix for mixed blocks is not yet implemented\n");
+ } else {
+ int window,window_len;
+ int isbound[3];
+ int is_pos;
+
+ memset(isbound, 0, sizeof(isbound));
+
+ sfb=0; l=0; window_len=t_s[0]+1;
+
+ while (l<(MAX(non_zero[0],non_zero[1]))) {
+ for (window=0;window<3;window++) {
+ subblock_gain[0]=info->subblock_gain[gr][0][window];
+ subblock_gain[1]=info->subblock_gain[gr][1][window];
+ scalefac[0]=scalefac_s[gr][0][sfb][window];
+ is_pos=scalefac[1]=scalefac_s[gr][1][sfb][window];
+
+ if (t_s[sfb] < isbound[window]) {
+ a[0]=fras_s(global_gain[0],subblock_gain[0],scalefac_scale[0],scalefac[0]);
+ if (ms_flag) {
+ for (i=0;i>1];
+ xr[0][0][t_reorder[id][sfreq][l]] = ftmp;
+ l++;
+ }
+ }
+ }
+ window_len = -t_s[sfb++];
+ window_len += t_s[sfb];
+ }
+ while (l<576) {
+ xr[0][0][l]=0;
+ l++;
+ }
+ }
+ else {
+ int *preflag=info->preflag[gr];
+ int isbound;
+
+ if (header->mode_extension==1 || header->mode_extension==3) {
+ int tmp=non_zero[1];
+ while (is[1][tmp] == 0) tmp--;
+ sfb=0; while (t_l[sfb] < tmp && sfb < 21) sfb++;
+ isbound=t_l[sfb]+1;
+ no_of_imdcts[0]=no_of_imdcts[1]=(non_zero[0]-1)/18+1;
+ } else {
+ isbound=(MAX(non_zero[0],non_zero[1]));
+ no_of_imdcts[0]=no_of_imdcts[1]=(isbound-1)/18+1;
+ }
+
+ sfb=0; l=0;
+ scalefac[0]=scalefac_l[gr][0][sfb];
+ a[0]=fras_l(sfb,global_gain[0],scalefac_scale[0],scalefac[0],preflag[0]);
+ scalefac[1]=scalefac_l[gr][1][sfb];
+ a[1]=fras_l(sfb,global_gain[1],scalefac_scale[1],scalefac[1],preflag[1]);
+
+ /* no intensity stereo part
+ */
+ if (ms_flag)
+ while (l < isbound) {
+ register float Mi = fras2(is[0][l],a[0]);
+ register float tmp = i_sq2;
+ xr[0][0][l]=Mi*tmp;
+
+ if (l==t_l[sfb]) {
+ sfb++;
+ scalefac[0]=scalefac_l[gr][0][sfb];
+ a[0]=fras_l(sfb,global_gain[0],scalefac_scale[0],scalefac[0],preflag[0]);
+ scalefac[1]=scalefac_l[gr][1][sfb];
+ }
+ l++;
+ }
+ else
+ while (l < isbound) {
+ register float tmp1=fras2(is[0][l],a[0]);
+ register float tmp2=fras2(is[1][l],a[1]);
+ xr[0][0][l]=(tmp1+tmp2)*0.5f;
+ if (l==t_l[sfb]) {
+ sfb++;
+ scalefac[0]=scalefac_l[gr][0][sfb];
+ a[0]=fras_l(sfb,global_gain[0],scalefac_scale[0],scalefac[0],preflag[0]);
+ scalefac[1]=scalefac_l[gr][1][sfb];
+ a[1]=fras_l(sfb,global_gain[1],scalefac_scale[1],scalefac[1],preflag[1]);
+ }
+ l++;
+ }
+ /* intensity stereo part
+ */
+ while (l<(MAX(non_zero[0],non_zero[1]))) {
+ int is_pos=scalefac[1];
+ register float ftmp=fras2(is[0][l], a[0]);
+
+ if (id==0 && is_pos>1];
+ }
+
+ xr[0][0][l] = ftmp;
+
+ if (l==t_l[sfb]) {
+ sfb++;
+ scalefac[0]=scalefac_l[gr][0][sfb];
+ a[0]=fras_l(sfb,global_gain[0],scalefac_scale[0],scalefac[0],preflag[0]);
+ scalefac[1]=scalefac_l[gr][1][sfb];
+ }
+ l++;
+ }
+
+ /* _always_ zero out everything else
+ */
+ while (l<576) {
+ xr[0][0][l]=0;
+ l++;
+ }
+ }
+}
+
+/*
+ * antialiasing butterflies ****************************************************
+ *
+ */
+void alias_reduction(int ch)
+{
+unsigned int sb;
+
+ for (sb=1;sb<32;sb++) {
+ float *x = xr[ch][sb];
+ register float a, b;
+
+ a = x[0];
+ b = x[-1];
+ x[-1] = b * Cs[0] - a * Ca[0];
+ x[0] = a * Cs[0] + b * Ca[0];
+
+ a = x[1];
+ b = x[-2];
+ x[-2] = b * Cs[1] - a * Ca[1];
+ x[1] = a * Cs[1] + b * Ca[1];
+
+ a = x[2];
+ b = x[-3];
+ x[-3] = b * Cs[2] - a * Ca[2];
+ x[2] = a * Cs[2] + b * Ca[2];
+
+ a = x[3];
+ b = x[-4];
+ x[-4] = b * Cs[3] - a * Ca[3];
+ x[3] = a * Cs[3] + b * Ca[3];
+
+ a = x[4];
+ b = x[-5];
+ x[-5] = b * Cs[4] - a * Ca[4];
+ x[4] = a * Cs[4] + b * Ca[4];
+
+ a = x[5];
+ b = x[-6];
+ x[-6] = b * Cs[5] - a * Ca[5];
+ x[5] = a * Cs[5] + b * Ca[5];
+
+ a = x[6];
+ b = x[-7];
+ x[-7] = b * Cs[6] - a * Ca[6];
+ x[6] = a * Cs[6] + b * Ca[6];
+
+ a = x[7];
+ b = x[-8];
+ x[-8] = b * Cs[7] - a * Ca[7];
+ x[7] = a * Cs[7] + b * Ca[7];
+ }
+}
+
+/* calculating t_43 instead of having that big table in misc2.h
+ */
+
+void calculate_t43(void)
+{
+int i;
+ for (i=0;i<8192;i++)
+ t_43[i]=(float)pow((float)i,1.33333333333f);
+}
diff --git a/Src/Sound/MPEG/misc2.h b/Src/Sound/MPEG/misc2.h
new file mode 100644
index 0000000..51fc987
--- /dev/null
+++ b/Src/Sound/MPEG/misc2.h
@@ -0,0 +1,253 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* misc2.h
+ *
+ * Created by: tomislav uzelac May 1996
+ * Last modified by: tomislav uzelac Jan 8 1997
+ */
+
+extern void requantize_mono(int gr,int ch,struct SIDE_INFO *info,struct AUDIO_HEADER *header);
+extern void requantize_ms(int gr,struct SIDE_INFO *info,struct AUDIO_HEADER *header);
+extern void alias_reduction(int ch);
+extern void calculate_t43(void);
+
+extern int no_of_imdcts[2];
+
+#ifdef MISC2
+
+#define i_sq2 0.707106781188
+#define IS_ILLEGAL 0xfeed
+
+void requantize_mono(int gr,int ch,struct SIDE_INFO *info,struct AUDIO_HEADER *header);
+void requantize_ms(int gr,struct SIDE_INFO *info,struct AUDIO_HEADER *header);
+void alias_reduction(int ch);
+
+static inline float fras_l(int sfb,int global_gain,int scalefac_scale,int scalefac,int preflag);
+static inline float fras_s(int global_gain,int subblock_gain,int scalefac_scale,int scalefac);
+static inline float fras2(int is,float a);
+static int find_isbound(int isbound[3],int gr,struct SIDE_INFO *info,struct AUDIO_HEADER *header);
+static inline void stereo_s(int l,float a[2],int pos,int ms_flag,int is_pos,struct AUDIO_HEADER *header);
+static inline void stereo_l(int l,float a[2],int ms_flag,int is_pos,struct AUDIO_HEADER *header);
+
+int no_of_imdcts[2];
+
+static const int t_pretab[22]={0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0};
+static const float t_is[7]={ 1.0f, 0.788675134596f, 0.633974596215f,
+ 0.5f, 0.366025403784f, 0.211324865405f, 0.0f};
+static const float t_is2[2][32]={
+{ 1.0f, 0.840896f, 0.707107f, 0.594604f, 0.5f, 0.420448f,
+ 0.353553f, 0.297302f, 0.25f, 0.210224f, 0.176777f, 0.148651f,
+ 0.125f, 0.105112f, 0.0883883f, 0.0743254f},
+{ 1.0f, 0.707107f, 0.5f, 0.353553f, 0.25f, 0.176777f,
+ 0.125f, 0.0883883f, 0.0625f, 0.0441942f, 0.03125f, 0.0220971f,
+ 0.015625f, 0.0110485f, 0.0078125f, 0.00552427f}
+};
+static const float t_downmix[2][32]={
+{ 1.000000f, 0.920448f, 0.853554f, 0.797302f, 0.750000f, 0.710224f,
+ 0.676776f, 0.648651f, 0.625000f, 0.605112f, 0.588389f, 0.574326f,
+ 0.562500f, 0.552556f, 0.544194f, 0.537163f},
+{ 1.000000f, 0.853554f, 0.750000f, 0.676776f, 0.625000f, 0.588389f,
+ 0.562500f, 0.544194f, 0.531250f, 0.522097f, 0.515625f, 0.511049f,
+ 0.507813f, 0.505524f, 0.503906f, 0.502762f}
+};
+
+static const float Cs[8]={0.857492925712f, 0.881741997318f, 0.949628649103f,
+ 0.983314592492f, 0.995517816065f, 0.999160558175f,
+ 0.999899195243f, 0.999993155067f};
+static const float Ca[8]={-0.5144957554270f, -0.4717319685650f, -0.3133774542040f,
+ -0.1819131996110f, -0.0945741925262f, -0.0409655828852f,
+ -0.0141985685725f, -0.00369997467375f};
+static const float tab[4]={1.0f,1.189207115f,1.414213562f,1.6817928301f};
+static const float tabi[4]={1.0f,0.840896415f,0.707106781f,0.594603557f};
+
+static float t_43[8192];
+
+
+/* leftmost index denotes header->ID, so first three are for MPEG2
+ * and the others are for MPEG1
+ */
+static const short t_reorder[2][3][576]={{
+{ 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 4, 5, 18, 19, 10, 11, 24, 25,
+ 16, 17, 30, 31, 20, 21, 22, 23, 26, 27, 28, 29, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 90, 91,
+ 78, 79, 80, 81, 82, 83, 96, 97, 84, 85, 86, 87, 88, 89, 102, 103, 92, 93, 94, 95,
+ 108, 109, 110, 111, 112, 113, 98, 99, 100, 101, 114, 115, 116, 117, 118, 119, 104, 105, 106, 107,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 144, 145, 146, 147, 148, 149, 162, 163,
+ 132, 133, 134, 135, 136, 137, 150, 151, 152, 153, 154, 155, 168, 169, 138, 139, 140, 141, 142, 143,
+ 156, 157, 158, 159, 160, 161, 174, 175, 164, 165, 166, 167, 180, 181, 182, 183, 184, 185, 198, 199,
+ 200, 201, 202, 203, 216, 217, 170, 171, 172, 173, 186, 187, 188, 189, 190, 191, 204, 205, 206, 207,
+ 208, 209, 222, 223, 176, 177, 178, 179, 192, 193, 194, 195, 196, 197, 210, 211, 212, 213, 214, 215,
+ 228, 229, 218, 219, 220, 221, 234, 235, 236, 237, 238, 239, 252, 253, 254, 255, 256, 257, 270, 271,
+ 272, 273, 274, 275, 288, 289, 290, 291, 224, 225, 226, 227, 240, 241, 242, 243, 244, 245, 258, 259,
+ 260, 261, 262, 263, 276, 277, 278, 279, 280, 281, 294, 295, 296, 297, 230, 231, 232, 233, 246, 247,
+ 248, 249, 250, 251, 264, 265, 266, 267, 268, 269, 282, 283, 284, 285, 286, 287, 300, 301, 302, 303,
+ 292, 293, 306, 307, 308, 309, 310, 311, 324, 325, 326, 327, 328, 329, 342, 343, 344, 345, 346, 347,
+ 360, 361, 362, 363, 364, 365, 378, 379, 380, 381, 382, 383, 298, 299, 312, 313, 314, 315, 316, 317,
+ 330, 331, 332, 333, 334, 335, 348, 349, 350, 351, 352, 353, 366, 367, 368, 369, 370, 371, 384, 385,
+ 386, 387, 388, 389, 304, 305, 318, 319, 320, 321, 322, 323, 336, 337, 338, 339, 340, 341, 354, 355,
+ 356, 357, 358, 359, 372, 373, 374, 375, 376, 377, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399,
+ 400, 401, 414, 415, 416, 417, 418, 419, 432, 433, 434, 435, 436, 437, 450, 451, 452, 453, 454, 455,
+ 468, 469, 470, 471, 472, 473, 486, 487, 488, 489, 490, 491, 504, 505, 506, 507, 508, 509, 402, 403,
+ 404, 405, 406, 407, 420, 421, 422, 423, 424, 425, 438, 439, 440, 441, 442, 443, 456, 457, 458, 459,
+ 460, 461, 474, 475, 476, 477, 478, 479, 492, 493, 494, 495, 496, 497, 510, 511, 512, 513, 514, 515,
+ 408, 409, 410, 411, 412, 413, 426, 427, 428, 429, 430, 431, 444, 445, 446, 447, 448, 449, 462, 463,
+ 464, 465, 466, 467, 480, 481, 482, 483, 484, 485, 498, 499, 500, 501, 502, 503, 516, 517, 518, 519,
+ 520, 521, 522, 523, 524, 525, 526, 527, 540, 541, 542, 543, 544, 545, 558, 559, 560, 561, 562, 563,
+ 528, 529, 530, 531, 532, 533, 546, 547, 548, 549, 550, 551, 564, 565, 566, 567, 568, 569, 534, 535,
+ 536, 537, 538, 539, 552, 553, 554, 555, 556, 557, 570, 571, 572, 573, 574, 575},
+
+{ 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 4, 5, 18, 19, 10, 11, 24, 25,
+ 16, 17, 30, 31, 20, 21, 22, 23, 26, 27, 28, 29, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 72, 73, 60, 61, 62, 63, 64, 65, 78, 79, 66, 67, 68, 69, 70, 71, 84, 85, 74, 75,
+ 76, 77, 90, 91, 92, 93, 94, 95, 80, 81, 82, 83, 96, 97, 98, 99, 100, 101, 86, 87,
+ 88, 89, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 126, 127, 128, 129, 130, 131,
+ 114, 115, 116, 117, 118, 119, 132, 133, 134, 135, 136, 137, 120, 121, 122, 123, 124, 125, 138, 139,
+ 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 162, 163, 164, 165, 166, 167, 180, 181, 150, 151,
+ 152, 153, 154, 155, 168, 169, 170, 171, 172, 173, 186, 187, 156, 157, 158, 159, 160, 161, 174, 175,
+ 176, 177, 178, 179, 192, 193, 182, 183, 184, 185, 198, 199, 200, 201, 202, 203, 216, 217, 218, 219,
+ 220, 221, 234, 235, 188, 189, 190, 191, 204, 205, 206, 207, 208, 209, 222, 223, 224, 225, 226, 227,
+ 240, 241, 194, 195, 196, 197, 210, 211, 212, 213, 214, 215, 228, 229, 230, 231, 232, 233, 246, 247,
+ 236, 237, 238, 239, 252, 253, 254, 255, 256, 257, 270, 271, 272, 273, 274, 275, 288, 289, 290, 291,
+ 292, 293, 306, 307, 242, 243, 244, 245, 258, 259, 260, 261, 262, 263, 276, 277, 278, 279, 280, 281,
+ 294, 295, 296, 297, 298, 299, 312, 313, 248, 249, 250, 251, 264, 265, 266, 267, 268, 269, 282, 283,
+ 284, 285, 286, 287, 300, 301, 302, 303, 304, 305, 318, 319, 308, 309, 310, 311, 324, 325, 326, 327,
+ 328, 329, 342, 343, 344, 345, 346, 347, 360, 361, 362, 363, 364, 365, 378, 379, 380, 381, 382, 383,
+ 396, 397, 398, 399, 314, 315, 316, 317, 330, 331, 332, 333, 334, 335, 348, 349, 350, 351, 352, 353,
+ 366, 367, 368, 369, 370, 371, 384, 385, 386, 387, 388, 389, 402, 403, 404, 405, 320, 321, 322, 323,
+ 336, 337, 338, 339, 340, 341, 354, 355, 356, 357, 358, 359, 372, 373, 374, 375, 376, 377, 390, 391,
+ 392, 393, 394, 395, 408, 409, 410, 411, 400, 401, 414, 415, 416, 417, 418, 419, 432, 433, 434, 435,
+ 436, 437, 450, 451, 452, 453, 454, 455, 468, 469, 470, 471, 472, 473, 486, 487, 488, 489, 490, 491,
+ 504, 505, 506, 507, 508, 509, 522, 523, 524, 525, 526, 527, 406, 407, 420, 421, 422, 423, 424, 425,
+ 438, 439, 440, 441, 442, 443, 456, 457, 458, 459, 460, 461, 474, 475, 476, 477, 478, 479, 492, 493,
+ 494, 495, 496, 497, 510, 511, 512, 513, 514, 515, 528, 529, 530, 531, 532, 533, 412, 413, 426, 427,
+ 428, 429, 430, 431, 444, 445, 446, 447, 448, 449, 462, 463, 464, 465, 466, 467, 480, 481, 482, 483,
+ 484, 485, 498, 499, 500, 501, 502, 503, 516, 517, 518, 519, 520, 521, 534, 535, 536, 537, 538, 539,
+ 540, 541, 542, 543, 544, 545, 558, 559, 560, 561, 562, 563, 546, 547, 548, 549, 550, 551, 564, 565,
+ 566, 567, 568, 569, 552, 553, 554, 555, 556, 557, 570, 571, 572, 573, 574, 575},
+
+{ 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 4, 5, 18, 19, 10, 11, 24, 25,
+ 16, 17, 30, 31, 20, 21, 22, 23, 26, 27, 28, 29, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 72, 73, 60, 61, 62, 63, 64, 65, 78, 79, 66, 67, 68, 69, 70, 71, 84, 85, 74, 75,
+ 76, 77, 90, 91, 92, 93, 94, 95, 80, 81, 82, 83, 96, 97, 98, 99, 100, 101, 86, 87,
+ 88, 89, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 126, 127, 128, 129, 130, 131,
+ 114, 115, 116, 117, 118, 119, 132, 133, 134, 135, 136, 137, 120, 121, 122, 123, 124, 125, 138, 139,
+ 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 162, 163, 164, 165, 166, 167, 180, 181, 150, 151,
+ 152, 153, 154, 155, 168, 169, 170, 171, 172, 173, 186, 187, 156, 157, 158, 159, 160, 161, 174, 175,
+ 176, 177, 178, 179, 192, 193, 182, 183, 184, 185, 198, 199, 200, 201, 202, 203, 216, 217, 218, 219,
+ 220, 221, 234, 235, 188, 189, 190, 191, 204, 205, 206, 207, 208, 209, 222, 223, 224, 225, 226, 227,
+ 240, 241, 194, 195, 196, 197, 210, 211, 212, 213, 214, 215, 228, 229, 230, 231, 232, 233, 246, 247,
+ 236, 237, 238, 239, 252, 253, 254, 255, 256, 257, 270, 271, 272, 273, 274, 275, 288, 289, 290, 291,
+ 292, 293, 306, 307, 242, 243, 244, 245, 258, 259, 260, 261, 262, 263, 276, 277, 278, 279, 280, 281,
+ 294, 295, 296, 297, 298, 299, 312, 313, 248, 249, 250, 251, 264, 265, 266, 267, 268, 269, 282, 283,
+ 284, 285, 286, 287, 300, 301, 302, 303, 304, 305, 318, 319, 308, 309, 310, 311, 324, 325, 326, 327,
+ 328, 329, 342, 343, 344, 345, 346, 347, 360, 361, 362, 363, 364, 365, 378, 379, 380, 381, 382, 383,
+ 396, 397, 314, 315, 316, 317, 330, 331, 332, 333, 334, 335, 348, 349, 350, 351, 352, 353, 366, 367,
+ 368, 369, 370, 371, 384, 385, 386, 387, 388, 389, 402, 403, 320, 321, 322, 323, 336, 337, 338, 339,
+ 340, 341, 354, 355, 356, 357, 358, 359, 372, 373, 374, 375, 376, 377, 390, 391, 392, 393, 394, 395,
+ 408, 409, 398, 399, 400, 401, 414, 415, 416, 417, 418, 419, 432, 433, 434, 435, 436, 437, 450, 451,
+ 452, 453, 454, 455, 468, 469, 470, 471, 472, 473, 486, 487, 488, 489, 490, 491, 504, 505, 506, 507,
+ 508, 509, 404, 405, 406, 407, 420, 421, 422, 423, 424, 425, 438, 439, 440, 441, 442, 443, 456, 457,
+ 458, 459, 460, 461, 474, 475, 476, 477, 478, 479, 492, 493, 494, 495, 496, 497, 510, 511, 512, 513,
+ 514, 515, 410, 411, 412, 413, 426, 427, 428, 429, 430, 431, 444, 445, 446, 447, 448, 449, 462, 463,
+ 464, 465, 466, 467, 480, 481, 482, 483, 484, 485, 498, 499, 500, 501, 502, 503, 516, 517, 518, 519,
+ 520, 521, 522, 523, 524, 525, 526, 527, 540, 541, 542, 543, 544, 545, 558, 559, 560, 561, 562, 563,
+ 528, 529, 530, 531, 532, 533, 546, 547, 548, 549, 550, 551, 564, 565, 566, 567, 568, 569, 534, 535,
+ 536, 537, 538, 539, 552, 553, 554, 555, 556, 557, 570, 571, 572, 573, 574, 575}
+},
+{
+{ 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 4, 5, 18, 19, 10, 11, 24, 25,
+ 16, 17, 30, 31, 20, 21, 22, 23, 26, 27, 28, 29, 32, 33, 34, 35, 36, 37, 38, 39,
+ 42, 43, 44, 45, 48, 49, 50, 51, 40, 41, 54, 55, 56, 57, 46, 47, 60, 61, 62, 63,
+ 52, 53, 66, 67, 68, 69, 58, 59, 72, 73, 74, 75, 76, 77, 64, 65, 78, 79, 80, 81,
+ 82, 83, 70, 71, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 108, 109, 110, 111,
+ 96, 97, 98, 99, 100, 101, 114, 115, 116, 117, 102, 103, 104, 105, 106, 107, 120, 121, 122, 123,
+ 112, 113, 126, 127, 128, 129, 130, 131, 144, 145, 146, 147, 118, 119, 132, 133, 134, 135, 136, 137,
+ 150, 151, 152, 153, 124, 125, 138, 139, 140, 141, 142, 143, 156, 157, 158, 159, 148, 149, 162, 163,
+ 164, 165, 166, 167, 180, 181, 182, 183, 184, 185, 154, 155, 168, 169, 170, 171, 172, 173, 186, 187,
+ 188, 189, 190, 191, 160, 161, 174, 175, 176, 177, 178, 179, 192, 193, 194, 195, 196, 197, 198, 199,
+ 200, 201, 202, 203, 216, 217, 218, 219, 220, 221, 234, 235, 236, 237, 238, 239, 204, 205, 206, 207,
+ 208, 209, 222, 223, 224, 225, 226, 227, 240, 241, 242, 243, 244, 245, 210, 211, 212, 213, 214, 215,
+ 228, 229, 230, 231, 232, 233, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 270, 271,
+ 272, 273, 274, 275, 288, 289, 290, 291, 292, 293, 306, 307, 308, 309, 258, 259, 260, 261, 262, 263,
+ 276, 277, 278, 279, 280, 281, 294, 295, 296, 297, 298, 299, 312, 313, 314, 315, 264, 265, 266, 267,
+ 268, 269, 282, 283, 284, 285, 286, 287, 300, 301, 302, 303, 304, 305, 318, 319, 320, 321, 310, 311,
+ 324, 325, 326, 327, 328, 329, 342, 343, 344, 345, 346, 347, 360, 361, 362, 363, 364, 365, 378, 379,
+ 380, 381, 382, 383, 396, 397, 398, 399, 316, 317, 330, 331, 332, 333, 334, 335, 348, 349, 350, 351,
+ 352, 353, 366, 367, 368, 369, 370, 371, 384, 385, 386, 387, 388, 389, 402, 403, 404, 405, 322, 323,
+ 336, 337, 338, 339, 340, 341, 354, 355, 356, 357, 358, 359, 372, 373, 374, 375, 376, 377, 390, 391,
+ 392, 393, 394, 395, 408, 409, 410, 411, 400, 401, 414, 415, 416, 417, 418, 419, 432, 433, 434, 435,
+ 436, 437, 450, 451, 452, 453, 454, 455, 468, 469, 470, 471, 472, 473, 486, 487, 488, 489, 490, 491,
+ 504, 505, 506, 507, 508, 509, 522, 523, 524, 525, 526, 527, 540, 541, 542, 543, 544, 545, 558, 559,
+ 560, 561, 562, 563, 406, 407, 420, 421, 422, 423, 424, 425, 438, 439, 440, 441, 442, 443, 456, 457,
+ 458, 459, 460, 461, 474, 475, 476, 477, 478, 479, 492, 493, 494, 495, 496, 497, 510, 511, 512, 513,
+ 514, 515, 528, 529, 530, 531, 532, 533, 546, 547, 548, 549, 550, 551, 564, 565, 566, 567, 568, 569,
+ 412, 413, 426, 427, 428, 429, 430, 431, 444, 445, 446, 447, 448, 449, 462, 463, 464, 465, 466, 467,
+ 480, 481, 482, 483, 484, 485, 498, 499, 500, 501, 502, 503, 516, 517, 518, 519, 520, 521, 534, 535,
+ 536, 537, 538, 539, 552, 553, 554, 555, 556, 557, 570, 571, 572, 573, 574, 575},
+
+{ 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 4, 5, 18, 19, 10, 11, 24, 25,
+ 16, 17, 30, 31, 20, 21, 22, 23, 26, 27, 28, 29, 32, 33, 34, 35, 36, 37, 38, 39,
+ 42, 43, 44, 45, 48, 49, 50, 51, 40, 41, 54, 55, 56, 57, 46, 47, 60, 61, 62, 63,
+ 52, 53, 66, 67, 68, 69, 58, 59, 72, 73, 74, 75, 64, 65, 78, 79, 80, 81, 70, 71,
+ 84, 85, 86, 87, 76, 77, 90, 91, 92, 93, 94, 95, 108, 109, 82, 83, 96, 97, 98, 99,
+ 100, 101, 114, 115, 88, 89, 102, 103, 104, 105, 106, 107, 120, 121, 110, 111, 112, 113, 126, 127,
+ 128, 129, 130, 131, 144, 145, 116, 117, 118, 119, 132, 133, 134, 135, 136, 137, 150, 151, 122, 123,
+ 124, 125, 138, 139, 140, 141, 142, 143, 156, 157, 146, 147, 148, 149, 162, 163, 164, 165, 166, 167,
+ 180, 181, 182, 183, 152, 153, 154, 155, 168, 169, 170, 171, 172, 173, 186, 187, 188, 189, 158, 159,
+ 160, 161, 174, 175, 176, 177, 178, 179, 192, 193, 194, 195, 184, 185, 198, 199, 200, 201, 202, 203,
+ 216, 217, 218, 219, 220, 221, 234, 235, 190, 191, 204, 205, 206, 207, 208, 209, 222, 223, 224, 225,
+ 226, 227, 240, 241, 196, 197, 210, 211, 212, 213, 214, 215, 228, 229, 230, 231, 232, 233, 246, 247,
+ 236, 237, 238, 239, 252, 253, 254, 255, 256, 257, 270, 271, 272, 273, 274, 275, 288, 289, 290, 291,
+ 242, 243, 244, 245, 258, 259, 260, 261, 262, 263, 276, 277, 278, 279, 280, 281, 294, 295, 296, 297,
+ 248, 249, 250, 251, 264, 265, 266, 267, 268, 269, 282, 283, 284, 285, 286, 287, 300, 301, 302, 303,
+ 292, 293, 306, 307, 308, 309, 310, 311, 324, 325, 326, 327, 328, 329, 342, 343, 344, 345, 346, 347,
+ 360, 361, 362, 363, 364, 365, 298, 299, 312, 313, 314, 315, 316, 317, 330, 331, 332, 333, 334, 335,
+ 348, 349, 350, 351, 352, 353, 366, 367, 368, 369, 370, 371, 304, 305, 318, 319, 320, 321, 322, 323,
+ 336, 337, 338, 339, 340, 341, 354, 355, 356, 357, 358, 359, 372, 373, 374, 375, 376, 377, 378, 379,
+ 380, 381, 382, 383, 396, 397, 398, 399, 400, 401, 414, 415, 416, 417, 418, 419, 432, 433, 434, 435,
+ 436, 437, 450, 451, 452, 453, 454, 455, 468, 469, 470, 471, 472, 473, 486, 487, 488, 489, 490, 491,
+ 504, 505, 506, 507, 508, 509, 522, 523, 524, 525, 526, 527, 540, 541, 542, 543, 544, 545, 558, 559,
+ 560, 561, 562, 563, 384, 385, 386, 387, 388, 389, 402, 403, 404, 405, 406, 407, 420, 421, 422, 423,
+ 424, 425, 438, 439, 440, 441, 442, 443, 456, 457, 458, 459, 460, 461, 474, 475, 476, 477, 478, 479,
+ 492, 493, 494, 495, 496, 497, 510, 511, 512, 513, 514, 515, 528, 529, 530, 531, 532, 533, 546, 547,
+ 548, 549, 550, 551, 564, 565, 566, 567, 568, 569, 390, 391, 392, 393, 394, 395, 408, 409, 410, 411,
+ 412, 413, 426, 427, 428, 429, 430, 431, 444, 445, 446, 447, 448, 449, 462, 463, 464, 465, 466, 467,
+ 480, 481, 482, 483, 484, 485, 498, 499, 500, 501, 502, 503, 516, 517, 518, 519, 520, 521, 534, 535,
+ 536, 537, 538, 539, 552, 553, 554, 555, 556, 557, 570, 571, 572, 573, 574, 575},
+
+{ 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 4, 5, 18, 19, 10, 11, 24, 25,
+ 16, 17, 30, 31, 20, 21, 22, 23, 26, 27, 28, 29, 32, 33, 34, 35, 36, 37, 38, 39,
+ 42, 43, 44, 45, 48, 49, 50, 51, 40, 41, 54, 55, 56, 57, 46, 47, 60, 61, 62, 63,
+ 52, 53, 66, 67, 68, 69, 58, 59, 72, 73, 74, 75, 76, 77, 64, 65, 78, 79, 80, 81,
+ 82, 83, 70, 71, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 108, 109, 110, 111,
+ 112, 113, 96, 97, 98, 99, 100, 101, 114, 115, 116, 117, 118, 119, 102, 103, 104, 105, 106, 107,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 144, 145, 146, 147, 148, 149, 162, 163,
+ 164, 165, 132, 133, 134, 135, 136, 137, 150, 151, 152, 153, 154, 155, 168, 169, 170, 171, 138, 139,
+ 140, 141, 142, 143, 156, 157, 158, 159, 160, 161, 174, 175, 176, 177, 166, 167, 180, 181, 182, 183,
+ 184, 185, 198, 199, 200, 201, 202, 203, 216, 217, 218, 219, 220, 221, 172, 173, 186, 187, 188, 189,
+ 190, 191, 204, 205, 206, 207, 208, 209, 222, 223, 224, 225, 226, 227, 178, 179, 192, 193, 194, 195,
+ 196, 197, 210, 211, 212, 213, 214, 215, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
+ 252, 253, 254, 255, 256, 257, 270, 271, 272, 273, 274, 275, 288, 289, 290, 291, 292, 293, 306, 307,
+ 240, 241, 242, 243, 244, 245, 258, 259, 260, 261, 262, 263, 276, 277, 278, 279, 280, 281, 294, 295,
+ 296, 297, 298, 299, 312, 313, 246, 247, 248, 249, 250, 251, 264, 265, 266, 267, 268, 269, 282, 283,
+ 284, 285, 286, 287, 300, 301, 302, 303, 304, 305, 318, 319, 308, 309, 310, 311, 324, 325, 326, 327,
+ 328, 329, 342, 343, 344, 345, 346, 347, 360, 361, 362, 363, 364, 365, 378, 379, 380, 381, 382, 383,
+ 396, 397, 398, 399, 400, 401, 314, 315, 316, 317, 330, 331, 332, 333, 334, 335, 348, 349, 350, 351,
+ 352, 353, 366, 367, 368, 369, 370, 371, 384, 385, 386, 387, 388, 389, 402, 403, 404, 405, 406, 407,
+ 320, 321, 322, 323, 336, 337, 338, 339, 340, 341, 354, 355, 356, 357, 358, 359, 372, 373, 374, 375,
+ 376, 377, 390, 391, 392, 393, 394, 395, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419,
+ 432, 433, 434, 435, 436, 437, 450, 451, 452, 453, 454, 455, 468, 469, 470, 471, 472, 473, 486, 487,
+ 488, 489, 490, 491, 504, 505, 506, 507, 508, 509, 522, 523, 524, 525, 526, 527, 420, 421, 422, 423,
+ 424, 425, 438, 439, 440, 441, 442, 443, 456, 457, 458, 459, 460, 461, 474, 475, 476, 477, 478, 479,
+ 492, 493, 494, 495, 496, 497, 510, 511, 512, 513, 514, 515, 528, 529, 530, 531, 532, 533, 426, 427,
+ 428, 429, 430, 431, 444, 445, 446, 447, 448, 449, 462, 463, 464, 465, 466, 467, 480, 481, 482, 483,
+ 484, 485, 498, 499, 500, 501, 502, 503, 516, 517, 518, 519, 520, 521, 534, 535, 536, 537, 538, 539,
+ 540, 541, 542, 543, 544, 545, 558, 559, 560, 561, 562, 563, 546, 547, 548, 549, 550, 551, 564, 565,
+ 566, 567, 568, 569, 552, 553, 554, 555, 556, 557, 570, 571, 572, 573, 574, 575}
+}};
+
+#endif
diff --git a/Src/Sound/MPEG/position.cpp b/Src/Sound/MPEG/position.cpp
new file mode 100644
index 0000000..0e231f8
--- /dev/null
+++ b/Src/Sound/MPEG/position.cpp
@@ -0,0 +1,103 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+/* position.c ffwd/rew within a stream
+ *
+ * Creted by: Tomislav Uzelac, May 10 1997
+ */
+#include
+#include
+#include "amp.h"
+#include "audio.h"
+#include "getbits.h"
+
+#define POSITION
+#include "position.h"
+
+/* Returns the number of frames actually skipped, -1 on error.
+ *
+ * Values in header are not changed if retval!=nframes.
+ * This is not necessary because gethdr() doesn't clobber
+ * the contents of header, but I don't want to rely on that.
+ */
+int ffwd(struct AUDIO_HEADER *header, int nframes)
+{
+int cnt=0,g;
+int hsize,bitrate,fs,mean_frame_size;
+struct AUDIO_HEADER tmp;
+ memcpy(&tmp,header,sizeof(tmp));
+
+ while (cnt < nframes) {
+ if (tmp.ID)
+ if (tmp.mode==3) hsize=21;
+ else hsize=36;
+ else
+ if (tmp.mode==3) hsize=13;
+ else hsize=21;
+ if (tmp.protection_bit==0) hsize+=2;
+ if ((g=dummy_getinfo(hsize))) /* dummy_getinfo: reads hsize-4 bytes */
+ switch (g) {
+ case GETHDR_EOF: return cnt;
+ case GETHDR_ERR:
+ default: return -1;
+ }
+
+ bitrate=t_bitrate[tmp.ID][3-tmp.layer][tmp.bitrate_index];
+ fs=t_sampling_frequency[tmp.ID][tmp.sampling_frequency];
+ if (tmp.ID) mean_frame_size=144000*bitrate/fs;
+ else mean_frame_size=72000*bitrate/fs;
+ fillbfr(mean_frame_size + tmp.padding_bit - hsize);
+
+ if ((g=gethdr(&tmp)))
+ switch (g) {
+ case GETHDR_EOF: return cnt;
+ case GETHDR_ERR:
+ default: return -1;
+ }
+ cnt++;
+ }
+
+ memcpy(header,&tmp,sizeof(tmp));
+ return cnt;
+}
+
+/* Mostly the same as ffwd. Some streams might be 'tough', i.e.
+ * the ones switching bitrates.
+ */
+int rew(struct AUDIO_HEADER *header, int nframes)
+{
+int cnt=0;
+int bitrate,fs,mean_frame_size;
+struct AUDIO_HEADER tmp;
+ memcpy(&tmp,header,sizeof(tmp));
+
+ while (cnt < nframes) {
+ /* ffwd/rew functions are to be called right after the header has been parsed
+ * so we have to go back one frame + 4 bytes + 1 byte (in case padding was used).
+ */
+ bitrate=t_bitrate[tmp.ID][3-tmp.layer][tmp.bitrate_index];
+ fs=t_sampling_frequency[tmp.ID][tmp.sampling_frequency];
+ if (tmp.ID) mean_frame_size=144000*bitrate/fs;
+ else mean_frame_size=72000*bitrate/fs;
+
+ if (rewind_stream(mean_frame_size) !=0) {
+ memcpy(header,&tmp,sizeof(tmp));
+ return cnt;
+ }
+ if ((gethdr(&tmp))) return -1;
+ cnt++;
+ }
+ /* We have to make sure that the bit reservoir contains enough data.
+ * Hopefully, layer3_frame will take care of that.
+ */
+ f_bdirty=TRUE;
+ bclean_bytes=0;
+
+ memcpy(header,&tmp,sizeof(tmp));
+ return cnt;
+}
+
+/* TODO: after the gethdr function is enhanced with the counter to count
+ * the number of bytes to search for the next syncword, make the call to
+ * gethdr() from rew() have that counter something like (frame_size-1) so
+ * that we don't go back again and again to the same header. (not very important)
+ */
diff --git a/Src/Sound/MPEG/position.h b/Src/Sound/MPEG/position.h
new file mode 100644
index 0000000..cce0856
--- /dev/null
+++ b/Src/Sound/MPEG/position.h
@@ -0,0 +1,10 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+extern int ffwd(struct AUDIO_HEADER *header, int nframes);
+extern int rew(struct AUDIO_HEADER *header, int nframes);
+
+#ifdef POSITION
+int ffwd(struct AUDIO_HEADER *header, int nframes);
+int rew(struct AUDIO_HEADER *header, int nframes);
+#endif
diff --git a/Src/Sound/MPEG/proto.h b/Src/Sound/MPEG/proto.h
new file mode 100644
index 0000000..3524812
--- /dev/null
+++ b/Src/Sound/MPEG/proto.h
@@ -0,0 +1,26 @@
+/* From: util.c */
+void die(char *, ...);
+void warn(char *, ...);
+void msg(char *, ...);
+void debugSetup(char *);
+void debugOptions();
+
+/* From: audioIO_.c */
+void audioOpen(int frequency, int stereo, int volume);
+void audioSetVolume(int);
+void audioFlush();
+void audioClose();
+int audioWrite(char *, int);
+int getAudioFd();
+void audioBufferOn(int);
+
+
+/* From: buffer.c */
+void printout(void);
+int audioBufferOpen(int, int, int);
+void audioBufferClose();
+void audioBufferWrite(char *, int);
+void audioBufferFlush();
+
+/* From: audio.c */
+void displayUsage();
diff --git a/Src/Sound/MPEG/rtbuf.h b/Src/Sound/MPEG/rtbuf.h
new file mode 100644
index 0000000..de67400
--- /dev/null
+++ b/Src/Sound/MPEG/rtbuf.h
@@ -0,0 +1,63 @@
+/*****************************************************************************/
+
+/*
+ * rtbuf.h -- Linux realtime audio output.
+ *
+ * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This is the Linux realtime sound output driver
+ */
+
+/*****************************************************************************/
+
+#include "config.h"
+
+#ifndef HAVE_MLOCKALL
+#undef LINUX_REALTIME
+#endif
+
+#ifndef HAVE_SCHED_SETSCHEDULER
+#undef LINUX_REALTIME
+#endif
+
+#if 0
+#ifndef _POSIX_MEMLOCK
+#undef LINUX_REALTIME
+#endif
+
+#ifndef _POSIX_PRIORITY_SCHEDULING
+#undef LINUX_REALTIME
+#endif
+#endif
+
+#ifdef LINUX_REALTIME
+
+int prefetch_get_input(unsigned char *bp, int bytes);
+int rt_play(char *file);
+void rt_printout(short *sbuf, int ln);
+int setup_fancy_audio(struct AUDIO_HEADER *mpegheader);
+int start_fancy_audio(struct AUDIO_HEADER *mpegheader);
+int stop_fancy_audio(void);
+int block_fancy_audio(int snd_eof);
+int ready_fancy_audio(void);
+void cleanup_fancy_audio(void);
+void prefetch_initial_fill(void);
+int set_realtime_priority(void);
+
+#endif /* LINUX_REALTIME */
+
diff --git a/Src/Sound/MPEG/transform.cpp b/Src/Sound/MPEG/transform.cpp
new file mode 100644
index 0000000..03dfbb3
--- /dev/null
+++ b/Src/Sound/MPEG/transform.cpp
@@ -0,0 +1,1518 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* transform.c imdct and polyphase(DCT) transforms
+ *
+ * Created by: tomislav uzelac May 1996
+ * Karl Anders Oygard optimized this for speed, Mar 13 97
+ * Some optimisations based on ideas from Michael Hipp's mpg123 package
+ */
+
+/*
+ * Comments for this file:
+ *
+ * The polyphase algorithm is clearly the most cpu consuming part of mpeg 1
+ * layer 3 decoding. Thus, there has been some effort to optimise this
+ * particular algorithm. Currently, everything has been kept in straight C
+ * with no assembler optimisations, but in order to provide efficient paths
+ * for different architectures, alternative implementations of some
+ * critical sections has been done. You may want to experiment with these,
+ * to see which suits your architecture better.
+ *
+ * Selection of the different implementations is done with the following
+ * defines:
+ *
+ * HAS_AUTOINCREMENT
+ *
+ * Define this if your architecture supports preincrementation of
+ * pointers when referencing (applies to e.g. 68k)
+ *
+ * For those who are optimising amp, check out the Pentium rdtsc code
+ * (define PENTIUM_RDTSC). This code uses the rdtsc counter for showing
+ * how many cycles are spent in different parts of the code.
+ */
+
+#include
+
+#include "audio.h"
+#include "getdata.h"
+#include "misc2.h"
+
+#define TRANSFORM
+#include "transform.h"
+
+#define PI12 0.261799387f
+#define PI36 0.087266462f
+
+void imdct_init()
+{
+ int i;
+
+ for(i=0;i<36;i++) /* 0 */
+ win[0][i] = (float) sin(PI36 *(i+0.5));
+ for(i=0;i<18;i++) /* 1 */
+ win[1][i] = (float) sin(PI36 *(i+0.5));
+ for(i=18;i<24;i++)
+ win[1][i] = 1.0f;
+ for(i=24;i<30;i++)
+ win[1][i] = (float) sin(PI12 *(i+0.5-18));
+ for(i=30;i<36;i++)
+ win[1][i] = 0.0f;
+ for(i=0;i<6;i++) /* 3 */
+ win[3][i] = 0.0f;
+ for(i=6;i<12;i++)
+ win[3][i] = (float) sin(PI12 * (i+ 0.5 - 6.0));
+ for(i=12;i<18;i++)
+ win[3][i] = 1.0f;
+ for(i=18;i<36;i++)
+ win[3][i] = (float) sin(PI36 * (i + 0.5));
+}
+
+/* This uses Byeong Gi Lee's Fast Cosine Transform algorithm to decompose
+ the 36 point and 12 point IDCT's into 9 point and 3 point IDCT's,
+ respectively. Then the 9 point IDCT is computed by a modified version of
+ Mikko Tommila's IDCT algorithm, based on the WFTA. See his comments
+ before the first 9 point IDCT. The 3 point IDCT is already efficient to
+ implement. -- Jeff Tsay. */
+/* I got the unrolled IDCT from Jeff Tsay; the code is presumably by
+ Francois-Raymond Boyer - I unrolled it a little further. tu */
+
+void imdct(int win_type,int sb,int ch)
+{
+/*------------------------------------------------------------------*/
+/* */
+/* Function: Calculation of the inverse MDCT */
+/* In the case of short blocks the 3 output vectors are already */
+/* overlapped and added in this modul. */
+/* */
+/* New layer3 */
+/* */
+/*------------------------------------------------------------------*/
+
+ float tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11;
+
+ register float save;
+ float pp1, pp2;
+ float *win_bt;
+ int i, p, ss;
+ float *in = xr[ch][sb];
+ float *s_p = s[ch][sb];
+ float *res_p = res[sb];
+ float out[36];
+
+ if(win_type == 2){
+ for(p=0;p<36;p+=9) {
+ out[p] = out[p+1] = out[p+2] = out[p+3] =
+ out[p+4] = out[p+5] = out[p+6] = out[p+7] =
+ out[p+8] = 0.0f;
+ }
+
+ for(ss=0;ss<18;ss+=6) {
+
+ /*
+ * 12 point IMDCT
+ */
+
+ /* Begin 12 point IDCT */
+
+ /* Input aliasing for 12 pt IDCT */
+ in[5+ss]+=in[4+ss];in[4+ss]+=in[3+ss];in[3+ss]+=in[2+ss];
+ in[2+ss]+=in[1+ss];in[1+ss]+=in[0+ss];
+
+ /* Input aliasing on odd indices (for 6 point IDCT) */
+ in[5+ss] += in[3+ss]; in[3+ss] += in[1+ss];
+
+ /* 3 point IDCT on even indices */
+
+ pp2 = in[4+ss] * 0.500000000f;
+ pp1 = in[2+ss] * 0.866025403f;
+ save = in[0+ss] + pp2;
+ tmp1 = in[0+ss] - in[4+ss];
+ tmp0 = save + pp1;
+ tmp2 = save - pp1;
+
+ /* End 3 point IDCT on even indices */
+
+ /* 3 point IDCT on odd indices (for 6 point IDCT) */
+
+ pp2 = in[5+ss] * 0.500000000f;
+ pp1 = in[3+ss] * 0.866025403f;
+ save = in[1+ss] + pp2;
+ tmp4 = in[1+ss] - in[5+ss];
+ tmp5 = save + pp1;
+ tmp3 = save - pp1;
+
+ /* End 3 point IDCT on odd indices */
+
+ /* Twiddle factors on odd indices (for 6 point IDCT) */
+
+ tmp3 *= 1.931851653f;
+ tmp4 *= 0.707106781f;
+ tmp5 *= 0.517638090f;
+
+ /* Output butterflies on 2 3 point IDCT's (for 6 point IDCT) */
+
+ save = tmp0;
+ tmp0 += tmp5;
+ tmp5 = save - tmp5;
+
+ save = tmp1;
+ tmp1 += tmp4;
+ tmp4 = save - tmp4;
+
+ save = tmp2;
+ tmp2 += tmp3;
+ tmp3 = save - tmp3;
+
+ /* End 6 point IDCT */
+
+ /* Twiddle factors on indices (for 12 point IDCT) */
+
+ tmp0 *= 0.504314480f;
+ tmp1 *= 0.541196100f;
+ tmp2 *= 0.630236207f;
+ tmp3 *= 0.821339815f;
+ tmp4 *= 1.306562965f;
+ tmp5 *= 3.830648788f;
+
+ /* End 12 point IDCT */
+
+ /* Shift to 12 point modified IDCT, multiply by window type 2 */
+ tmp8 = tmp0 * -0.793353340f;
+ tmp9 = tmp0 * -0.608761429f;
+ tmp7 = tmp1 * -0.923879532f;
+ tmp10 = tmp1 * -0.382683432f;
+ tmp6 = tmp2 * -0.991444861f;
+ tmp11 = tmp2 * -0.130526192f;
+
+ tmp0 = tmp3;
+ tmp1 = tmp4 * 0.382683432f;
+ tmp2 = tmp5 * 0.608761429f;
+
+ tmp3 = tmp5 * -0.793353340f;
+ tmp4 = tmp4 * -0.923879532f;
+ tmp5 = tmp0 * -0.991444861f;
+
+ tmp0 *= 0.130526192f;
+
+ out[ss + 6] += tmp0;
+ out[ss + 7] += tmp1;
+ out[ss + 8] += tmp2;
+ out[ss + 9] += tmp3;
+ out[ss + 10] += tmp4;
+ out[ss + 11] += tmp5;
+ out[ss + 12] += tmp6;
+ out[ss + 13] += tmp7;
+ out[ss + 14] += tmp8;
+ out[ss + 15] += tmp9;
+ out[ss + 16] += tmp10;
+ out[ss + 17] += tmp11;
+
+ }
+ if (sb&1) {
+ for (i=0;i<18;i+=2) res_p[i]=out[i] + s_p[i];
+ for (i=1;i<18;i+=2) res_p[i]=-out[i] - s_p[i];
+ } else
+ for (i=0;i<18;i++) res_p[i]=out[i] + s_p[i];
+ for (i=18;i<36;i++) s_p[i-18]=out[i];
+
+ } else {
+/*
+ * 36 point IDCT ****************************************************************
+ */
+ float tmp[18];
+
+ /* input aliasing for 36 point IDCT */
+ in[17]+=in[16]; in[16]+=in[15]; in[15]+=in[14]; in[14]+=in[13];
+ in[13]+=in[12]; in[12]+=in[11]; in[11]+=in[10]; in[10]+=in[9];
+ in[9] +=in[8]; in[8] +=in[7]; in[7] +=in[6]; in[6] +=in[5];
+ in[5] +=in[4]; in[4] +=in[3]; in[3] +=in[2]; in[2] +=in[1];
+ in[1] +=in[0];
+
+ /* 18 point IDCT for odd indices */
+
+ /* input aliasing for 18 point IDCT */
+ in[17]+=in[15]; in[15]+=in[13]; in[13]+=in[11]; in[11]+=in[9];
+ in[9] +=in[7]; in[7] +=in[5]; in[5] +=in[3]; in[3] +=in[1];
+
+
+{
+ float tmp0,tmp1,tmp2,tmp3,tmp4,tmp0_,tmp1_,tmp2_,tmp3_;
+ float tmp0o,tmp1o,tmp2o,tmp3o,tmp4o,tmp0_o,tmp1_o,tmp2_o,tmp3_o;
+
+/* Fast 9 Point Inverse Discrete Cosine Transform
+//
+// By Francois-Raymond Boyer
+// mailto:boyerf@iro.umontreal.ca
+// http://www.iro.umontreal.ca/~boyerf
+//
+// The code has been optimized for Intel processors
+// (takes a lot of time to convert float to and from iternal FPU representation)
+//
+// It is a simple "factorization" of the IDCT matrix.
+*/
+ /* 9 point IDCT on even indices */
+ {
+ /* 5 points on odd indices (not realy an IDCT) */
+ float i0 = in[0]+in[0];
+ float i0p12 = i0 + in[12];
+
+ tmp0 = i0p12 + in[4]*1.8793852415718f + in[8]*1.532088886238f + in[16]*0.34729635533386f;
+ tmp1 = i0 + in[4] - in[8] - in[12] - in[12] - in[16];
+ tmp2 = i0p12 - in[4]*0.34729635533386f - in[8]*1.8793852415718f + in[16]*1.532088886238f;
+ tmp3 = i0p12 - in[4]*1.532088886238f + in[8]*0.34729635533386f - in[16]*1.8793852415718f;
+ tmp4 = in[0] - in[4] + in[8] - in[12] + in[16];
+ }
+ {
+ float i6_ = in[6]*1.732050808f;
+
+ tmp0_ = in[2]*1.9696155060244f + i6_ + in[10]*1.2855752193731f + in[14]*0.68404028665134f;
+ tmp1_ = (in[2] - in[10] - in[14])*1.732050808f;
+ tmp2_ = in[2]*1.2855752193731f - i6_ - in[10]*0.68404028665134f + in[14]*1.9696155060244f;
+ tmp3_ = in[2]*0.68404028665134f - i6_ + in[10]*1.9696155060244f - in[14]*1.2855752193731f;
+ }
+
+ /* 9 point IDCT on odd indices */
+ {
+ /* 5 points on odd indices (not realy an IDCT) */
+ float i0 = in[0+1]+in[0+1];
+ float i0p12 = i0 + in[12+1];
+
+ tmp0o = i0p12 + in[4+1]*1.8793852415718f + in[8+1]*1.532088886238f + in[16+1]*0.34729635533386f;
+ tmp1o = i0 + in[4+1] - in[8+1] - in[12+1] - in[12+1] - in[16+1];
+ tmp2o = i0p12 - in[4+1]*0.34729635533386f - in[8+1]*1.8793852415718f + in[16+1]*1.532088886238f;
+ tmp3o = i0p12 - in[4+1]*1.532088886238f + in[8+1]*0.34729635533386f - in[16+1]*1.8793852415718f;
+ tmp4o = (in[0+1] - in[4+1] + in[8+1] - in[12+1] + in[16+1])*0.707106781f; /* Twiddled */
+ }
+ {
+ /* 4 points on even indices */
+ float i6_ = in[6+1]*1.732050808f; /* Sqrt[3] */
+
+ tmp0_o = in[2+1]*1.9696155060244f + i6_ + in[10+1]*1.2855752193731f + in[14+1]*0.68404028665134f;
+ tmp1_o = (in[2+1] - in[10+1] - in[14+1])*1.732050808f;
+ tmp2_o = in[2+1]*1.2855752193731f - i6_ - in[10+1]*0.68404028665134f + in[14+1]*1.9696155060244f;
+ tmp3_o = in[2+1]*0.68404028665134f - i6_ + in[10+1]*1.9696155060244f - in[14+1]*1.2855752193731f;
+ }
+
+ /* Twiddle factors on odd indices
+ // and
+ // Butterflies on 9 point IDCT's
+ // and
+ // twiddle factors for 36 point IDCT
+ */
+ {
+ float e, o;
+ e = tmp0 + tmp0_; o = (tmp0o + tmp0_o)*0.501909918f; tmp[0] = (e + o)*(-0.500476342f*.5f); tmp[17] = (e - o)*(-11.46279281f*.5f);
+ e = tmp1 + tmp1_; o = (tmp1o + tmp1_o)*0.517638090f; tmp[1] = (e + o)*(-0.504314480f*.5f); tmp[16] = (e - o)*(-3.830648788f*.5f);
+ e = tmp2 + tmp2_; o = (tmp2o + tmp2_o)*0.551688959f; tmp[2] = (e + o)*(-0.512139757f*.5f); tmp[15] = (e - o)*(-2.310113158f*.5f);
+ e = tmp3 + tmp3_; o = (tmp3o + tmp3_o)*0.610387294f; tmp[3] = (e + o)*(-0.524264562f*.5f); tmp[14] = (e - o)*(-1.662754762f*.5f);
+ tmp[4] = (tmp4 + tmp4o)*(-0.541196100f); tmp[13] = (tmp4 - tmp4o)*(-1.306562965f);
+ e = tmp3 - tmp3_; o = (tmp3o - tmp3_o)*0.871723397f; tmp[5] = (e + o)*(-0.563690973f*.5f); tmp[12] = (e - o)*(-1.082840285f*.5f);
+ e = tmp2 - tmp2_; o = (tmp2o - tmp2_o)*1.183100792f; tmp[6] = (e + o)*(-0.592844523f*.5f); tmp[11] = (e - o)*(-0.930579498f*.5f);
+ e = tmp1 - tmp1_; o = (tmp1o - tmp1_o)*1.931851653f; tmp[7] = (e + o)*(-0.630236207f*.5f); tmp[10] = (e - o)*(-0.821339815f*.5f);
+ e = tmp0 - tmp0_; o = (tmp0o - tmp0_o)*5.736856623f; tmp[8] = (e + o)*(-0.678170852f*.5f); tmp[9] = (e - o)*(-0.740093616f*.5f);
+ }
+ }
+ /* shift to modified IDCT */
+ win_bt = win[win_type];
+
+ if (sb&1) {
+ res_p[0] = -tmp[9] * win_bt[0] + s_p[0];
+ res_p[1] =-(-tmp[10] * win_bt[1] + s_p[1]);
+ res_p[2] = -tmp[11] * win_bt[2] + s_p[2];
+ res_p[3] =-(-tmp[12] * win_bt[3] + s_p[3]);
+ res_p[4] = -tmp[13] * win_bt[4] + s_p[4];
+ res_p[5] =-(-tmp[14] * win_bt[5] + s_p[5]);
+ res_p[6] = -tmp[15] * win_bt[6] + s_p[6];
+ res_p[7] =-(-tmp[16] * win_bt[7] + s_p[7]);
+ res_p[8] = -tmp[17] * win_bt[8] + s_p[8];
+
+ res_p[9] = -(tmp[17] * win_bt[9] + s_p[9]);
+ res_p[10]= tmp[16] * win_bt[10] + s_p[10];
+ res_p[11]=-(tmp[15] * win_bt[11] + s_p[11]);
+ res_p[12]= tmp[14] * win_bt[12] + s_p[12];
+ res_p[13]=-(tmp[13] * win_bt[13] + s_p[13]);
+ res_p[14]= tmp[12] * win_bt[14] + s_p[14];
+ res_p[15]=-(tmp[11] * win_bt[15] + s_p[15]);
+ res_p[16]= tmp[10] * win_bt[16] + s_p[16];
+ res_p[17]=-(tmp[9] * win_bt[17] + s_p[17]);
+ } else {
+ res_p[0] = -tmp[9] * win_bt[0] + s_p[0];
+ res_p[1] = -tmp[10] * win_bt[1] + s_p[1];
+ res_p[2] = -tmp[11] * win_bt[2] + s_p[2];
+ res_p[3] = -tmp[12] * win_bt[3] + s_p[3];
+ res_p[4] = -tmp[13] * win_bt[4] + s_p[4];
+ res_p[5] = -tmp[14] * win_bt[5] + s_p[5];
+ res_p[6] = -tmp[15] * win_bt[6] + s_p[6];
+ res_p[7] = -tmp[16] * win_bt[7] + s_p[7];
+ res_p[8] = -tmp[17] * win_bt[8] + s_p[8];
+
+ res_p[9] = tmp[17] * win_bt[9] + s_p[9];
+ res_p[10]= tmp[16] * win_bt[10] + s_p[10];
+ res_p[11]= tmp[15] * win_bt[11] + s_p[11];
+ res_p[12]= tmp[14] * win_bt[12] + s_p[12];
+ res_p[13]= tmp[13] * win_bt[13] + s_p[13];
+ res_p[14]= tmp[12] * win_bt[14] + s_p[14];
+ res_p[15]= tmp[11] * win_bt[15] + s_p[15];
+ res_p[16]= tmp[10] * win_bt[16] + s_p[16];
+ res_p[17]= tmp[9] * win_bt[17] + s_p[17];
+ }
+
+ s_p[0]= tmp[8] * win_bt[18];
+ s_p[1]= tmp[7] * win_bt[19];
+ s_p[2]= tmp[6] * win_bt[20];
+ s_p[3]= tmp[5] * win_bt[21];
+ s_p[4]= tmp[4] * win_bt[22];
+ s_p[5]= tmp[3] * win_bt[23];
+ s_p[6]= tmp[2] * win_bt[24];
+ s_p[7]= tmp[1] * win_bt[25];
+ s_p[8]= tmp[0] * win_bt[26];
+
+ s_p[9]= tmp[0] * win_bt[27];
+ s_p[10]= tmp[1] * win_bt[28];
+ s_p[11]= tmp[2] * win_bt[29];
+ s_p[12]= tmp[3] * win_bt[30];
+ s_p[13]= tmp[4] * win_bt[31];
+ s_p[14]= tmp[5] * win_bt[32];
+ s_p[15]= tmp[6] * win_bt[33];
+ s_p[16]= tmp[7] * win_bt[34];
+ s_p[17]= tmp[8] * win_bt[35];
+ }
+}
+
+/* fast DCT according to Lee[84]
+ * reordering according to Konstantinides[94]
+ */
+void poly(const int ch,int f)
+{
+static float u[2][2][17][16]; /* no v[][], it's redundant */
+static int u_start[2]={0,0}; /* first element of u[][] */
+static int u_div[2]={0,0}; /* which part of u[][] is currently used */
+int start = u_start[ch];
+int div = u_div[ch];
+float (*u_p)[16];
+
+#if defined(PENTIUM_RDTSC)
+unsigned int cnt4, cnt3, cnt2, cnt1;
+static int min_cycles = 99999999;
+
+ __asm__(".byte 0x0f,0x31" : "=a" (cnt1), "=d" (cnt4));
+#endif
+
+ {
+ float d16,d17,d18,d19,d20,d21,d22,d23,d24,d25,d26,d27,d28,d29,d30,d31;
+ float d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15;
+
+ /* step 1: initial reordering and 1st (16 wide) butterflies
+ */
+
+ d0 = res[ 0][f]; d16=(d0 - res[31][f]) * b1; d0 += res[31][f];
+ d1 = res[ 1][f]; d17=(d1 - res[30][f]) * b3; d1 += res[30][f];
+ d3 = res[ 2][f]; d19=(d3 - res[29][f]) * b5; d3 += res[29][f];
+ d2 = res[ 3][f]; d18=(d2 - res[28][f]) * b7; d2 += res[28][f];
+ d6 = res[ 4][f]; d22=(d6 - res[27][f]) * b9; d6 += res[27][f];
+ d7 = res[ 5][f]; d23=(d7 - res[26][f]) * b11; d7 += res[26][f];
+ d5 = res[ 6][f]; d21=(d5 - res[25][f]) * b13; d5 += res[25][f];
+ d4 = res[ 7][f]; d20=(d4 - res[24][f]) * b15; d4 += res[24][f];
+ d12= res[ 8][f]; d28=(d12 - res[23][f]) * b17; d12+= res[23][f];
+ d13= res[ 9][f]; d29=(d13 - res[22][f]) * b19; d13+= res[22][f];
+ d15= res[10][f]; d31=(d15 - res[21][f]) * b21; d15+= res[21][f];
+ d14= res[11][f]; d30=(d14 - res[20][f]) * b23; d14+= res[20][f];
+ d10= res[12][f]; d26=(d10 - res[19][f]) * b25; d10+= res[19][f];
+ d11= res[13][f]; d27=(d11 - res[18][f]) * b27; d11+= res[18][f];
+ d9 = res[14][f]; d25=(d9 - res[17][f]) * b29; d9 += res[17][f];
+ d8 = res[15][f]; d24=(d8 - res[16][f]) * b31; d8 += res[16][f];
+
+ {
+ float c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15;
+
+/* a test to see what can be done with memory separation
+ * first we process indexes 0-15
+*/
+ c0 = d0 + d8 ; c8 = ( d0 - d8 ) * b2;
+ c1 = d1 + d9 ; c9 = ( d1 - d9 ) * b6;
+ c2 = d2 + d10; c10= ( d2 - d10) * b14;
+ c3 = d3 + d11; c11= ( d3 - d11) * b10;
+ c4 = d4 + d12; c12= ( d4 - d12) * b30;
+ c5 = d5 + d13; c13= ( d5 - d13) * b26;
+ c6 = d6 + d14; c14= ( d6 - d14) * b18;
+ c7 = d7 + d15; c15= ( d7 - d15) * b22;
+
+ /* step 3: 4-wide butterflies
+ */
+ d0 = c0 + c4 ; d4 = ( c0 - c4 ) * b4;
+ d1 = c1 + c5 ; d5 = ( c1 - c5 ) * b12;
+ d2 = c2 + c6 ; d6 = ( c2 - c6 ) * b28;
+ d3 = c3 + c7 ; d7 = ( c3 - c7 ) * b20;
+
+ d8 = c8 + c12; d12= ( c8 - c12) * b4;
+ d9 = c9 + c13; d13= ( c9 - c13) * b12;
+ d10= c10+ c14; d14= (c10 - c14) * b28;
+ d11= c11+ c15; d15= (c11 - c15) * b20;
+
+
+ /* step 4: 2-wide butterflies
+ */
+ {
+ float rb8 = b8;
+ float rb24 = b24;
+
+/**/ c0 = d0 + d2 ; c2 = ( d0 - d2 ) * rb8;
+ c1 = d1 + d3 ; c3 = ( d1 - d3 ) * rb24;
+/**/ c4 = d4 + d6 ; c6 = ( d4 - d6 ) * rb8;
+ c5 = d5 + d7 ; c7 = ( d5 - d7 ) * rb24;
+/**/ c8 = d8 + d10; c10= ( d8 - d10) * rb8;
+ c9 = d9 + d11; c11= ( d9 - d11) * rb24;
+/**/ c12= d12+ d14; c14= (d12 - d14) * rb8;
+ c13= d13+ d15; c15= (d13 - d15) * rb24;
+ }
+
+ /* step 5: 1-wide butterflies
+ */
+ {
+ float rb16 = b16;
+
+ /* this is a little 'hacked up'
+ */
+ d0 = (-c0 -c1) * 2; d1 = ( c0 - c1 ) * rb16;
+ d2 = c2 + c3; d3 = ( c2 - c3 ) * rb16;
+ d3 -= d2;
+
+ d4 = c4 +c5; d5 = ( c4 - c5 ) * rb16;
+ d5 += d4;
+ d7 = -d5;
+ d7 += ( c6 - c7 ) * rb16; d6 = +c6 +c7;
+
+ d8 = c8 + c9 ; d9 = ( c8 - c9 ) * rb16;
+ d11= +d8 +d9;
+ d11 +=(c10 - c11) * rb16; d10= c10+ c11;
+
+ d12 = c12+ c13; d13 = (c12 - c13) * rb16;
+ d13 += -d8-d9+d12;
+ d14 = c14+ c15; d15 = (c14 - c15) * rb16;
+ d15-=d11;
+ d14 += -d8 -d10;
+ }
+
+ /* step 6: final resolving & reordering
+ * the other 32 are stored for use with the next granule
+ */
+
+ u_p = (float (*)[16]) &u[ch][div][0][start];
+
+/*16*/ u_p[ 0][0] =+d1 ;
+ u_p[ 2][0] = +d9 -d14;
+/*20*/ u_p[ 4][0] = +d5 -d6;
+ u_p[ 6][0] = -d10 +d13;
+/*24*/ u_p[ 8][0] =d3;
+ u_p[10][0] = -d8 -d9 +d11 -d13;
+/*28*/ u_p[12][0] = +d7;
+ u_p[14][0] = +d15;
+
+ /* the other 32 are stored for use with the next granule
+ */
+
+ u_p = (float (*)[16]) &u[ch][!div][0][start];
+
+/*0*/ u_p[16][0] = d0;
+ u_p[14][0] = -(+d8 );
+/*4*/ u_p[12][0] = -(+d4 );
+ u_p[10][0] = -(-d8 +d12 );
+/*8*/ u_p[ 8][0] = -(+d2 );
+ u_p[ 6][0] = -(+d8 +d10 -d12 );
+/*12*/ u_p[ 4][0] = -(-d4 +d6 );
+ u_p[ 2][0] = -d14;
+ u_p[ 0][0] = -d1;
+ }
+
+ {
+ float c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15;
+
+/* memory separation, second part
+*/
+/* 2
+*/
+ c0=d16 + d24; c8= (d16 - d24) * b2;
+ c1=d17 + d25; c9= (d17 - d25) * b6;
+ c2=d18 + d26; c10= (d18 - d26) * b14;
+ c3=d19 + d27; c11= (d19 - d27) * b10;
+ c4=d20 + d28; c12= (d20 - d28) * b30;
+ c5=d21 + d29; c13= (d21 - d29) * b26;
+ c6=d22 + d30; c14= (d22 - d30) * b18;
+ c7=d23 + d31; c15= (d23 - d31) * b22;
+
+/* 3
+*/
+ d16= c0+ c4; d20= (c0 - c4) * b4;
+ d17= c1+ c5; d21= (c1 - c5) * b12;
+ d18= c2+ c6; d22= (c2 - c6) * b28;
+ d19= c3+ c7; d23= (c3 - c7) * b20;
+
+ d24= c8+ c12; d28= (c8 - c12) * b4;
+ d25= c9+ c13; d29= (c9 - c13) * b12;
+ d26= c10+ c14; d30= (c10 - c14) * b28;
+ d27= c11+ c15; d31= (c11 - c15) * b20;
+
+/* 4
+*/
+ {
+ float rb8 = b8;
+ float rb24 = b24;
+
+/**/ c0= d16+ d18; c2= (d16 - d18) * rb8;
+ c1= d17+ d19; c3= (d17 - d19) * rb24;
+/**/ c4= d20+ d22; c6= (d20 - d22) * rb8;
+ c5= d21+ d23; c7= (d21 - d23) * rb24;
+/**/ c8= d24+ d26; c10= (d24 - d26) * rb8;
+ c9= d25+ d27; c11= (d25 - d27) * rb24;
+/**/ c12= d28+ d30; c14= (d28 - d30) * rb8;
+ c13= d29+ d31; c15= (d29 - d31) * rb24;
+ }
+
+/* 5
+*/
+ {
+ float rb16 = b16;
+ d16= c0+ c1; d17= (c0 - c1) * rb16;
+ d18= c2+ c3; d19= (c2 - c3) * rb16;
+
+ d20= c4+ c5; d21= (c4 - c5) * rb16;
+ d20+=d16; d21+=d17;
+ d22= c6+ c7; d23= (c6 - c7) * rb16;
+ d22+=d16; d22+=d18;
+ d23+=d16; d23+=d17; d23+=d19;
+
+
+ d24= c8+ c9; d25= (c8 - c9) * rb16;
+ d26= c10+ c11; d27= (c10 - c11) * rb16;
+ d26+=d24;
+ d27+=d24; d27+=d25;
+
+ d28= c12+ c13; d29= (c12 - c13) * rb16;
+ d28-=d20; d29+=d28; d29-=d21;
+ d30= c14+ c15; d31= (c14 - c15) * rb16;
+ d30-=d22;
+ d31-=d23;
+ }
+
+ /* step 6: final resolving & reordering
+ * the other 32 are stored for use with the next granule
+ */
+
+ u_p = (float (*)[16]) &u[ch][!div][0][start];
+
+ u_p[ 1][0] = -(+d30 );
+ u_p[ 3][0] = -(+d22 -d26 );
+ u_p[ 5][0] = -(-d18 -d20 +d26 );
+ u_p[ 7][0] = -(+d18 -d28 );
+ u_p[ 9][0] = -(+d28 );
+ u_p[11][0] = -(+d20 -d24 );
+ u_p[13][0] = -(-d16 +d24 );
+ u_p[15][0] = -(+d16 );
+
+ /* the other 32 are stored for use with the next granule
+ */
+
+ u_p = (float (*)[16]) &u[ch][div][0][start];
+
+ u_p[15][0] = +d31;
+ u_p[13][0] = +d23 -d27;
+ u_p[11][0] = -d19 -d20 -d21 +d27;
+ u_p[ 9][0] = +d19 -d29;
+ u_p[ 7][0] = -d18 +d29;
+ u_p[ 5][0] = +d18 +d20 +d21 -d25 -d26;
+ u_p[ 3][0] = -d17 -d22 +d25 +d26;
+ u_p[ 1][0] = +d17 -d30;
+ }
+ }
+
+#if defined(PENTIUM_RDTSC)
+ __asm__(".byte 0x0f,0x31" : "=a" (cnt3), "=d" (cnt4));
+#endif
+
+ /* we're doing dewindowing and calculating final samples now
+ */
+
+#if defined(ARCH_i586)
+ /* x86 assembler optimisations. These optimisations are tuned
+ specifically for Intel Pentiums. */
+
+ asm("movl $15,%%eax\n\t"\
+ "1:\n\t"\
+ "flds (%0)\n\t"\
+ "fmuls (%1)\n\t"\
+ "flds 4(%0)\n\t"\
+ "fmuls 4(%1)\n\t"\
+ "flds 8(%0)\n\t"\
+ "fmuls 8(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 12(%0)\n\t"\
+ "fmuls 12(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 16(%0)\n\t"\
+ "fmuls 16(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 20(%0)\n\t"\
+ "fmuls 20(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 24(%0)\n\t"\
+ "fmuls 24(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 28(%0)\n\t"\
+ "fmuls 28(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 32(%0)\n\t"\
+ "fmuls 32(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 36(%0)\n\t"\
+ "fmuls 36(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 40(%0)\n\t"\
+ "fmuls 40(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 44(%0)\n\t"\
+ "fmuls 44(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 48(%0)\n\t"\
+ "fmuls 48(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 52(%0)\n\t"\
+ "fmuls 52(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 56(%0)\n\t"\
+ "fmuls 56(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 60(%0)\n\t"\
+ "fmuls 60(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "addl $64,%0\n\t"\
+ "addl $128,%1\n\t"\
+ "subl $4,%%esp\n\t"\
+ "faddp\n\t"\
+ "fistpl (%%esp)\n\t"\
+ "popl %%ecx\n\t"\
+ "cmpl $32767,%%ecx\n\t"\
+ "jle 2f\n\t"\
+ "movw $32767,%%cx\n\t"\
+ "jmp 3f\n\t"\
+ "2: cmpl $-32768,%%ecx\n\t"\
+ "jge 3f\n\t"\
+ "movw $-32768,%%cx\n\t"\
+ "3: movw %%cx,(%2)\n\t"\
+ "addl %3,%2\n\t"\
+ "decl %%eax\n\t"\
+ "jns 1b\n\t"\
+
+ "testb $1,%4\n\t"\
+ "je 4f\n\t"
+
+ "flds (%0)\n\t"\
+ "fmuls (%1)\n\t"\
+ "flds 8(%0)\n\t"\
+ "fmuls 8(%1)\n\t"\
+ "flds 16(%0)\n\t"\
+ "fmuls 16(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 24(%0)\n\t"\
+ "fmuls 24(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 32(%0)\n\t"\
+ "fmuls 32(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 40(%0)\n\t"\
+ "fmuls 40(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 48(%0)\n\t"\
+ "fmuls 48(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 56(%0)\n\t"\
+ "fmuls 56(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "subl $4,%%esp\n\t"\
+ "subl $64,%0\n\t"\
+ "subl $192,%1\n\t"\
+ "faddp\n\t"\
+ "fistpl (%%esp)\n\t"\
+ "popl %%ecx\n\t"\
+ "cmpl $32767,%%ecx\n\t"\
+ "jle 2f\n\t"\
+ "movw $32767,%%cx\n\t"\
+ "jmp 3f\n\t"\
+ "2: cmpl $-32768,%%ecx\n\t"\
+ "jge 3f\n\t"\
+ "movw $-32768,%%cx\n\t"\
+ "3: movw %%cx,(%2)\n\t"\
+
+ "movl %5,%%ecx\n\t"\
+ "sall $3,%%ecx\n\t"\
+ "addl %%ecx,%1\n\t"\
+ "addl %3,%2\n\t"\
+ "movl $14,%%eax\n\t"\
+
+ "1:flds 4(%0)\n\t"\
+ "fmuls 56(%1)\n\t"\
+ "flds (%0)\n\t"\
+ "fmuls 60(%1)\n\t"\
+ "flds 12(%0)\n\t"\
+ "fmuls 48(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "fsubp\n\t"\
+ "flds 8(%0)\n\t"\
+ "fmuls 52(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 20(%0)\n\t"\
+ "fmuls 40(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "fsubrp\n\t"\
+ "flds 16(%0)\n\t"\
+ "fmuls 44(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 28(%0)\n\t"\
+ "fmuls 32(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "fsubrp\n\t"\
+ "flds 24(%0)\n\t"\
+ "fmuls 36(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 36(%0)\n\t"\
+ "fmuls 24(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "fsubrp\n\t"\
+ "flds 32(%0)\n\t"\
+ "fmuls 28(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 44(%0)\n\t"\
+ "fmuls 16(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "fsubrp\n\t"\
+ "flds 40(%0)\n\t"\
+ "fmuls 20(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 52(%0)\n\t"\
+ "fmuls 8(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "fsubrp\n\t"\
+ "flds 48(%0)\n\t"\
+ "fmuls 12(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 60(%0)\n\t"\
+ "fmuls (%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "fsubrp\n\t"\
+ "flds 56(%0)\n\t"\
+ "fmuls 4(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "subl $64,%0\n\t"\
+ "subl $128,%1\n\t"\
+ "subl $4,%%esp\n\t"\
+ "fsubp\n\t"\
+ "fistpl (%%esp)\n\t"\
+ "popl %%ecx\n\t"\
+ "cmpl $32767,%%ecx\n\t"\
+ "jle 2f\n\t"\
+ "movw $32767,%%cx\n\t"\
+ "jmp 3f\n\t"\
+ "2: cmpl $-32768,%%ecx\n\t"\
+ "jge 3f\n\t"\
+ "movw $-32768,%%cx\n\t"\
+ "3: movw %%cx,(%2)\n\t"\
+ "addl %3,%2\n\t"\
+ "decl %%eax\n\t"\
+ "jns 1b\n\t"\
+ "jmp 5f\n\t"\
+
+ "4:flds 4(%0)\n\t"\
+ "fmuls 4(%1)\n\t"\
+ "flds 12(%0)\n\t"\
+ "fmuls 12(%1)\n\t"\
+ "flds 20(%0)\n\t"\
+ "fmuls 20(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 28(%0)\n\t"\
+ "fmuls 28(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 36(%0)\n\t"\
+ "fmuls 36(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 44(%0)\n\t"\
+ "fmuls 44(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 52(%0)\n\t"\
+ "fmuls 52(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 60(%0)\n\t"\
+ "fmuls 60(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "subl $4,%%esp\n\t"\
+ "subl $64,%0\n\t"\
+ "subl $192,%1\n\t"\
+ "faddp\n\t"\
+ "fistpl (%%esp)\n\t"\
+ "popl %%ecx\n\t"\
+ "cmpl $32767,%%ecx\n\t"\
+ "jle 2f\n\t"\
+ "movw $32767,%%cx\n\t"\
+ "jmp 3f\n\t"\
+ "2: cmpl $-32768,%%ecx\n\t"\
+ "jge 3f\n\t"\
+ "movw $-32768,%%cx\n\t"\
+ "3: movw %%cx,(%2)\n\t"\
+
+ "movl %5,%%ecx\n\t"\
+ "sall $3,%%ecx\n\t"\
+ "addl %%ecx,%1\n\t"\
+ "addl %3,%2\n\t"\
+
+ "movl $14,%%eax\n\t"\
+ "1:flds (%0)\n\t"\
+ "fmuls 60(%1)\n\t"\
+ "flds 4(%0)\n\t"\
+ "fmuls 56(%1)\n\t"\
+ "flds 8(%0)\n\t"\
+ "fmuls 52(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "fsubp\n\t"\
+ "flds 12(%0)\n\t"\
+ "fmuls 48(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 16(%0)\n\t"\
+ "fmuls 44(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "fsubrp\n\t"\
+ "flds 20(%0)\n\t"\
+ "fmuls 40(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 24(%0)\n\t"\
+ "fmuls 36(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "fsubrp\n\t"\
+ "flds 28(%0)\n\t"\
+ "fmuls 32(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 32(%0)\n\t"\
+ "fmuls 28(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "fsubrp\n\t"\
+ "flds 36(%0)\n\t"\
+ "fmuls 24(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 40(%0)\n\t"\
+ "fmuls 20(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "fsubrp\n\t"\
+ "flds 44(%0)\n\t"\
+ "fmuls 16(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 48(%0)\n\t"\
+ "fmuls 12(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "fsubrp\n\t"\
+ "flds 52(%0)\n\t"\
+ "fmuls 8(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "flds 56(%0)\n\t"\
+ "fmuls 4(%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "fsubrp\n\t"\
+ "flds 60(%0)\n\t"\
+ "fmuls (%1)\n\t"\
+ "fxch %%st(2)\n\t"\
+ "faddp\n\t"\
+ "subl $64,%0\n\t"\
+ "subl $128,%1\n\t"\
+ "subl $4,%%esp\n\t"\
+ "fsubp\n\t"\
+ "fistpl (%%esp)\n\t"\
+ "popl %%ecx\n\t"\
+ "cmpl $32767,%%ecx\n\t"\
+ "jle 2f\n\t"\
+ "movw $32767,%%cx\n\t"\
+ "jmp 3f\n\t"\
+ "2: cmpl $-32768,%%ecx\n\t"\
+ "jge 3f\n\t"\
+ "movw $-32768,%%cx\n\t"\
+ "3: movw %%cx,(%2)\n\t"\
+ "addl %3,%2\n\t"\
+ "decl %%eax\n\t"\
+ "jns 1b\n\t"\
+
+ "5:"\
+ : : "b" (u[ch][div]), "d" (t_dewindow[0] + 16 - start), "S" (&sample_buffer[f>>(2-nch)][nch==2?0:(f&1?16:0)][ch]), "m" (sizeof(short) * nch), "m" (div), "m" (start)\
+ : "eax", "ecx", "memory");
+#else
+ {
+ short *samples = (&sample_buffer[f>>(2-nch)][nch==2?0:(f&1?16:0)][ch]);
+ int out, j;
+
+#define PUT_SAMPLE(out) \
+ if (out > 32767) \
+ *samples = 32767; \
+ else \
+ if (out < -32768) \
+ *samples = -32768; \
+ else \
+ *samples = out; \
+ \
+ samples += nch;
+
+#if defined(SUPERHACK)
+ /* These is a simple implementation which should be nicer to the
+ cache; computation of samples are done in one pass rather than
+ two. However, for various reasons which I do not have time to
+ investigate, it runs quite a lot slower than two pass
+ computations. If you have time, you are welcome to look into
+ it. */
+
+ {
+ float (*u_ptr)[16] = u[ch][div];
+ const float *dewindow2 = t_dewindow[0] + start;
+
+ {
+ float outf1, outf2, outf3, outf4;
+
+ outf1 = u_ptr[0][ 0] * dewindow[0x0];
+ outf2 = u_ptr[0][ 1] * dewindow[0x1];
+ outf3 = u_ptr[0][ 2] * dewindow[0x2];
+ outf4 = u_ptr[0][ 3] * dewindow[0x3];
+ outf1 += u_ptr[0][ 4] * dewindow[0x4];
+ outf2 += u_ptr[0][ 5] * dewindow[0x5];
+ outf3 += u_ptr[0][ 6] * dewindow[0x6];
+ outf4 += u_ptr[0][ 7] * dewindow[0x7];
+ outf1 += u_ptr[0][ 8] * dewindow[0x8];
+ outf2 += u_ptr[0][ 9] * dewindow[0x9];
+ outf3 += u_ptr[0][10] * dewindow[0xa];
+ outf4 += u_ptr[0][11] * dewindow[0xb];
+ outf1 += u_ptr[0][12] * dewindow[0xc];
+ outf2 += u_ptr[0][13] * dewindow[0xd];
+ outf3 += u_ptr[0][14] * dewindow[0xe];
+ outf4 += u_ptr[0][15] * dewindow[0xf];
+
+ out = outf1 + outf2 + outf3 + outf4;
+
+ dewindow += 32;
+ dewindow2 += 32;
+ u_ptr++;
+
+ if (out > 32767)
+ samples[0] = 32767;
+ else
+ if (out < -32768)
+ samples[0] = -32768;
+ else
+ samples[0] = out;
+ }
+
+ if (div & 0x1) {
+ for (j = 1; j < 16; ++j) {
+ float outf1, outf2, outf3, outf4;
+
+ outf1 = u_ptr[0][ 0] * dewindow[0x0];
+ outf3 = u_ptr[0][ 0] * dewindow2[0xf];
+ outf2 = u_ptr[0][ 1] * dewindow[0x1];
+ outf4 = u_ptr[0][ 1] * dewindow2[0xe];
+ outf1 += u_ptr[0][ 2] * dewindow[0x2];
+ outf3 += u_ptr[0][ 2] * dewindow2[0xd];
+ outf2 += u_ptr[0][ 3] * dewindow[0x3];
+ outf4 += u_ptr[0][ 3] * dewindow2[0xc];
+ outf1 += u_ptr[0][ 4] * dewindow[0x4];
+ outf3 += u_ptr[0][ 4] * dewindow2[0xb];
+ outf2 += u_ptr[0][ 5] * dewindow[0x5];
+ outf4 += u_ptr[0][ 5] * dewindow2[0xa];
+ outf1 += u_ptr[0][ 6] * dewindow[0x6];
+ outf3 += u_ptr[0][ 6] * dewindow2[0x9];
+ outf2 += u_ptr[0][ 7] * dewindow[0x7];
+ outf4 += u_ptr[0][ 7] * dewindow2[0x8];
+ outf1 += u_ptr[0][ 8] * dewindow[0x8];
+ outf3 += u_ptr[0][ 8] * dewindow2[0x7];
+ outf2 += u_ptr[0][ 9] * dewindow[0x9];
+ outf4 += u_ptr[0][ 9] * dewindow2[0x6];
+ outf1 += u_ptr[0][10] * dewindow[0xa];
+ outf3 += u_ptr[0][10] * dewindow2[0x5];
+ outf2 += u_ptr[0][11] * dewindow[0xb];
+ outf4 += u_ptr[0][11] * dewindow2[0x4];
+ outf1 += u_ptr[0][12] * dewindow[0xc];
+ outf3 += u_ptr[0][12] * dewindow2[0x3];
+ outf2 += u_ptr[0][13] * dewindow[0xd];
+ outf4 += u_ptr[0][13] * dewindow2[0x2];
+ outf1 += u_ptr[0][14] * dewindow[0xe];
+ outf3 += u_ptr[0][14] * dewindow2[0x1];
+ outf2 += u_ptr[0][15] * dewindow[0xf];
+ outf4 += u_ptr[0][15] * dewindow2[0x0];
+
+ dewindow += 32;
+ dewindow2 += 32;
+ u_ptr++;
+
+ out = outf1 + outf2;
+
+ if (out > 32767)
+ samples[j * 2] = 32767;
+ else
+ if (out < -32768)
+ samples[j * 2] = -32768;
+ else
+ samples[j * 2] = out;
+
+ out = outf4 - outf3;
+
+ if (out > 32767)
+ samples[64 - (j * 2)] = 32767;
+ else
+ if (out < -32768)
+ samples[64 - (j * 2)] = -32768;
+ else
+ samples[64 - (j * 2)] = out;
+ }
+
+ {
+ float outf2, outf4;
+
+ outf2 = u_ptr[0][ 0] * dewindow[0x0];
+ outf4 = u_ptr[0][ 2] * dewindow[0x2];
+ outf2 += u_ptr[0][ 4] * dewindow[0x4];
+ outf4 += u_ptr[0][ 6] * dewindow[0x6];
+ outf2 += u_ptr[0][ 8] * dewindow[0x8];
+ outf4 += u_ptr[0][10] * dewindow[0xa];
+ outf2 += u_ptr[0][12] * dewindow[0xc];
+ outf4 += u_ptr[0][14] * dewindow[0xe];
+
+ out = outf2 + outf4;
+
+ if (out > 32767)
+ samples[16 * 2] = 32767;
+ else
+ if (out < -32768)
+ samples[16 * 2] = -32768;
+ else
+ samples[16 * 2] = out;
+ }
+ } else {
+ for (j = 1; j < 16; ++j) {
+ float outf1, outf2, outf3, outf4;
+
+ outf1 = u_ptr[0][ 0] * dewindow[0x0];
+ outf3 = u_ptr[0][ 0] * dewindow2[0xf];
+ outf2 = u_ptr[0][ 1] * dewindow[0x1];
+ outf4 = u_ptr[0][ 1] * dewindow2[0xe];
+ outf1 += u_ptr[0][ 2] * dewindow[0x2];
+ outf3 += u_ptr[0][ 2] * dewindow2[0xd];
+ outf2 += u_ptr[0][ 3] * dewindow[0x3];
+ outf4 += u_ptr[0][ 3] * dewindow2[0xc];
+ outf1 += u_ptr[0][ 4] * dewindow[0x4];
+ outf3 += u_ptr[0][ 4] * dewindow2[0xb];
+ outf2 += u_ptr[0][ 5] * dewindow[0x5];
+ outf4 += u_ptr[0][ 5] * dewindow2[0xa];
+ outf1 += u_ptr[0][ 6] * dewindow[0x6];
+ outf3 += u_ptr[0][ 6] * dewindow2[0x9];
+ outf2 += u_ptr[0][ 7] * dewindow[0x7];
+ outf4 += u_ptr[0][ 7] * dewindow2[0x8];
+ outf1 += u_ptr[0][ 8] * dewindow[0x8];
+ outf3 += u_ptr[0][ 8] * dewindow2[0x7];
+ outf2 += u_ptr[0][ 9] * dewindow[0x9];
+ outf4 += u_ptr[0][ 9] * dewindow2[0x6];
+ outf1 += u_ptr[0][10] * dewindow[0xa];
+ outf3 += u_ptr[0][10] * dewindow2[0x5];
+ outf2 += u_ptr[0][11] * dewindow[0xb];
+ outf4 += u_ptr[0][11] * dewindow2[0x4];
+ outf1 += u_ptr[0][12] * dewindow[0xc];
+ outf3 += u_ptr[0][12] * dewindow2[0x3];
+ outf2 += u_ptr[0][13] * dewindow[0xd];
+ outf4 += u_ptr[0][13] * dewindow2[0x2];
+ outf1 += u_ptr[0][14] * dewindow[0xe];
+ outf3 += u_ptr[0][14] * dewindow2[0x1];
+ outf2 += u_ptr[0][15] * dewindow[0xf];
+ outf4 += u_ptr[0][15] * dewindow2[0x0];
+
+ dewindow += 32;
+ dewindow2 += 32;
+ u_ptr++;
+
+ out = outf1 + outf2;
+
+ if (out > 32767)
+ samples[j * 2] = 32767;
+ else
+ if (out < -32768)
+ samples[j * 2] = -32768;
+ else
+ samples[j * 2] = out;
+
+ out = outf3 - outf4;
+
+ if (out > 32767)
+ samples[64 - (j * 2)] = 32767;
+ else
+ if (out < -32768)
+ samples[64 - (j * 2)] = -32768;
+ else
+ samples[64 - (j * 2)] = out;
+ }
+
+ {
+ float outf2, outf4;
+
+ outf2 = u_ptr[0][ 1] * dewindow[0x1];
+ outf4 = u_ptr[0][ 3] * dewindow[0x3];
+ outf2 += u_ptr[0][ 5] * dewindow[0x5];
+ outf4 += u_ptr[0][ 7] * dewindow[0x7];
+ outf2 += u_ptr[0][ 9] * dewindow[0x9];
+ outf4 += u_ptr[0][11] * dewindow[0xb];
+ outf2 += u_ptr[0][13] * dewindow[0xd];
+ outf4 += u_ptr[0][15] * dewindow[0xf];
+
+ out = outf2 + outf4;
+
+ if (out > 32767)
+ samples[16 * 2] = 32767;
+ else
+ if (out < -32768)
+ samples[16 * 2] = -32768;
+ else
+ samples[16 * 2] = out;
+ }
+ }
+ }
+#elif defined(HAS_AUTOINCREMENT)
+ const float *dewindow = t_dewindow[0] + 15 - start;
+
+ /* This is tuned specifically for architectures with
+ autoincrement and -decrement. */
+
+ {
+ float *u_ptr = (float*) u[ch][div];
+
+ u_ptr--;
+
+ for (j = 0; j < 16; ++j) {
+ float outf1, outf2, outf3, outf4;
+
+ outf1 = *++u_ptr * *++dewindow;
+ outf2 = *++u_ptr * *++dewindow;
+ outf3 = *++u_ptr * *++dewindow;
+ outf4 = *++u_ptr * *++dewindow;
+ outf1 += *++u_ptr * *++dewindow;
+ outf2 += *++u_ptr * *++dewindow;
+ outf3 += *++u_ptr * *++dewindow;
+ outf4 += *++u_ptr * *++dewindow;
+ outf1 += *++u_ptr * *++dewindow;
+ outf2 += *++u_ptr * *++dewindow;
+ outf3 += *++u_ptr * *++dewindow;
+ outf4 += *++u_ptr * *++dewindow;
+ outf1 += *++u_ptr * *++dewindow;
+ outf2 += *++u_ptr * *++dewindow;
+ outf3 += *++u_ptr * *++dewindow;
+ outf4 += *++u_ptr * *++dewindow;
+
+ out = outf1 + outf2 + outf3 + outf4;
+
+ dewindow += 16;
+
+ PUT_SAMPLE(out)
+ }
+
+ if (div & 0x1) {
+ {
+ float outf2, outf4;
+
+ outf2 = u_ptr[ 1] * dewindow[0x1];
+ outf4 = u_ptr[ 3] * dewindow[0x3];
+ outf2 += u_ptr[ 5] * dewindow[0x5];
+ outf4 += u_ptr[ 7] * dewindow[0x7];
+ outf2 += u_ptr[ 9] * dewindow[0x9];
+ outf4 += u_ptr[11] * dewindow[0xb];
+ outf2 += u_ptr[13] * dewindow[0xd];
+ outf4 += u_ptr[15] * dewindow[0xf];
+
+ out = outf2 + outf4;
+
+ PUT_SAMPLE(out)
+ }
+
+ dewindow -= 31;
+ dewindow += start;
+ dewindow += start;
+ u_ptr -= 16;
+
+ for (; j < 31; ++j) {
+ float outf1, outf2, outf3, outf4;
+
+ outf1 = *++u_ptr * *--dewindow;
+ outf2 = *++u_ptr * *--dewindow;
+ outf3 = *++u_ptr * *--dewindow;
+ outf4 = *++u_ptr * *--dewindow;
+ outf1 += *++u_ptr * *--dewindow;
+ outf2 += *++u_ptr * *--dewindow;
+ outf3 += *++u_ptr * *--dewindow;
+ outf4 += *++u_ptr * *--dewindow;
+ outf1 += *++u_ptr * *--dewindow;
+ outf2 += *++u_ptr * *--dewindow;
+ outf3 += *++u_ptr * *--dewindow;
+ outf4 += *++u_ptr * *--dewindow;
+ outf1 += *++u_ptr * *--dewindow;
+ outf2 += *++u_ptr * *--dewindow;
+ outf3 += *++u_ptr * *--dewindow;
+ outf4 += *++u_ptr * *--dewindow;
+
+ out = outf2 - outf1 + outf4 - outf3;
+
+ dewindow -= 16;
+ u_ptr -= 32;
+
+ PUT_SAMPLE(out)
+ }
+ } else {
+ {
+ float outf2, outf4;
+
+ outf2 = u_ptr[ 2] * dewindow[ 0x2];
+ outf4 = u_ptr[ 4] * dewindow[ 0x4];
+ outf2 += u_ptr[ 6] * dewindow[ 0x6];
+ outf4 += u_ptr[ 8] * dewindow[ 0x8];
+ outf2 += u_ptr[10] * dewindow[ 0xa];
+ outf4 += u_ptr[12] * dewindow[ 0xc];
+ outf2 += u_ptr[14] * dewindow[ 0xe];
+ outf4 += u_ptr[16] * dewindow[0x10];
+
+ out = outf2 + outf4;
+
+ PUT_SAMPLE(out)
+ }
+
+ dewindow -= 31;
+ dewindow += start;
+ dewindow += start;
+ u_ptr -= 16;
+
+ for (; j < 31; ++j) {
+ float outf1, outf2, outf3, outf4;
+
+ outf1 = *++u_ptr * *--dewindow;
+ outf2 = *++u_ptr * *--dewindow;
+ outf3 = *++u_ptr * *--dewindow;
+ outf4 = *++u_ptr * *--dewindow;
+ outf1 += *++u_ptr * *--dewindow;
+ outf2 += *++u_ptr * *--dewindow;
+ outf3 += *++u_ptr * *--dewindow;
+ outf4 += *++u_ptr * *--dewindow;
+ outf1 += *++u_ptr * *--dewindow;
+ outf2 += *++u_ptr * *--dewindow;
+ outf3 += *++u_ptr * *--dewindow;
+ outf4 += *++u_ptr * *--dewindow;
+ outf1 += *++u_ptr * *--dewindow;
+ outf2 += *++u_ptr * *--dewindow;
+ outf3 += *++u_ptr * *--dewindow;
+ outf4 += *++u_ptr * *--dewindow;
+
+ out = outf1 - outf2 + outf3 - outf4;
+
+ dewindow -= 16;
+ u_ptr -= 32;
+
+ PUT_SAMPLE(out)
+ }
+ }
+ }
+#else
+ const float *dewindow = t_dewindow[0] + 16 - start;
+
+ /* These optimisations are tuned specifically for architectures
+ without autoincrement and -decrement. */
+
+ {
+ float (*u_ptr)[16] = u[ch][div];
+
+ for (j = 0; j < 16; ++j) {
+ float outf1, outf2, outf3, outf4;
+
+ outf1 = u_ptr[0][ 0] * dewindow[0x0];
+ outf2 = u_ptr[0][ 1] * dewindow[0x1];
+ outf3 = u_ptr[0][ 2] * dewindow[0x2];
+ outf4 = u_ptr[0][ 3] * dewindow[0x3];
+ outf1 += u_ptr[0][ 4] * dewindow[0x4];
+ outf2 += u_ptr[0][ 5] * dewindow[0x5];
+ outf3 += u_ptr[0][ 6] * dewindow[0x6];
+ outf4 += u_ptr[0][ 7] * dewindow[0x7];
+ outf1 += u_ptr[0][ 8] * dewindow[0x8];
+ outf2 += u_ptr[0][ 9] * dewindow[0x9];
+ outf3 += u_ptr[0][10] * dewindow[0xa];
+ outf4 += u_ptr[0][11] * dewindow[0xb];
+ outf1 += u_ptr[0][12] * dewindow[0xc];
+ outf2 += u_ptr[0][13] * dewindow[0xd];
+ outf3 += u_ptr[0][14] * dewindow[0xe];
+ outf4 += u_ptr[0][15] * dewindow[0xf];
+
+ out = (int) (outf1 + outf2 + outf3 + outf4);
+
+ dewindow += 32;
+ u_ptr++;
+
+ PUT_SAMPLE(out)
+ }
+
+ if (div & 0x1) {
+ {
+ float outf2, outf4;
+
+ outf2 = u_ptr[0][ 0] * dewindow[0x0];
+ outf4 = u_ptr[0][ 2] * dewindow[0x2];
+ outf2 += u_ptr[0][ 4] * dewindow[0x4];
+ outf4 += u_ptr[0][ 6] * dewindow[0x6];
+ outf2 += u_ptr[0][ 8] * dewindow[0x8];
+ outf4 += u_ptr[0][10] * dewindow[0xa];
+ outf2 += u_ptr[0][12] * dewindow[0xc];
+ outf4 += u_ptr[0][14] * dewindow[0xe];
+
+ out = (int) (outf2 + outf4);
+
+ PUT_SAMPLE(out)
+ }
+
+ dewindow -= 48;
+ dewindow += start;
+ dewindow += start;
+
+ for (; j < 31; ++j) {
+ float outf1, outf2, outf3, outf4;
+
+ --u_ptr;
+
+ outf1 = u_ptr[0][ 0] * dewindow[0xf];
+ outf2 = u_ptr[0][ 1] * dewindow[0xe];
+ outf3 = u_ptr[0][ 2] * dewindow[0xd];
+ outf4 = u_ptr[0][ 3] * dewindow[0xc];
+ outf1 += u_ptr[0][ 4] * dewindow[0xb];
+ outf2 += u_ptr[0][ 5] * dewindow[0xa];
+ outf3 += u_ptr[0][ 6] * dewindow[0x9];
+ outf4 += u_ptr[0][ 7] * dewindow[0x8];
+ outf1 += u_ptr[0][ 8] * dewindow[0x7];
+ outf2 += u_ptr[0][ 9] * dewindow[0x6];
+ outf3 += u_ptr[0][10] * dewindow[0x5];
+ outf4 += u_ptr[0][11] * dewindow[0x4];
+ outf1 += u_ptr[0][12] * dewindow[0x3];
+ outf2 += u_ptr[0][13] * dewindow[0x2];
+ outf3 += u_ptr[0][14] * dewindow[0x1];
+ outf4 += u_ptr[0][15] * dewindow[0x0];
+
+ out = (int) (-outf1 + outf2 - outf3 + outf4);
+
+ dewindow -= 32;
+
+ PUT_SAMPLE(out)
+ }
+ } else {
+ {
+ float outf2, outf4;
+
+ outf2 = u_ptr[0][ 1] * dewindow[0x1];
+ outf4 = u_ptr[0][ 3] * dewindow[0x3];
+ outf2 += u_ptr[0][ 5] * dewindow[0x5];
+ outf4 += u_ptr[0][ 7] * dewindow[0x7];
+ outf2 += u_ptr[0][ 9] * dewindow[0x9];
+ outf4 += u_ptr[0][11] * dewindow[0xb];
+ outf2 += u_ptr[0][13] * dewindow[0xd];
+ outf4 += u_ptr[0][15] * dewindow[0xf];
+
+ out = (int) (outf2 + outf4);
+
+ PUT_SAMPLE(out)
+ }
+
+ dewindow -= 48;
+ dewindow += start;
+ dewindow += start;
+
+ for (; j < 31; ++j) {
+ float outf1, outf2, outf3, outf4;
+
+ --u_ptr;
+
+ outf1 = u_ptr[0][ 0] * dewindow[0xf];
+ outf2 = u_ptr[0][ 1] * dewindow[0xe];
+ outf3 = u_ptr[0][ 2] * dewindow[0xd];
+ outf4 = u_ptr[0][ 3] * dewindow[0xc];
+ outf1 += u_ptr[0][ 4] * dewindow[0xb];
+ outf2 += u_ptr[0][ 5] * dewindow[0xa];
+ outf3 += u_ptr[0][ 6] * dewindow[0x9];
+ outf4 += u_ptr[0][ 7] * dewindow[0x8];
+ outf1 += u_ptr[0][ 8] * dewindow[0x7];
+ outf2 += u_ptr[0][ 9] * dewindow[0x6];
+ outf3 += u_ptr[0][10] * dewindow[0x5];
+ outf4 += u_ptr[0][11] * dewindow[0x4];
+ outf1 += u_ptr[0][12] * dewindow[0x3];
+ outf2 += u_ptr[0][13] * dewindow[0x2];
+ outf3 += u_ptr[0][14] * dewindow[0x1];
+ outf4 += u_ptr[0][15] * dewindow[0x0];
+
+ out = (int) (outf1 - outf2 + outf3 - outf4);
+
+ dewindow -= 32;
+
+ PUT_SAMPLE(out)
+ }
+ }
+ }
+#endif
+ }
+#endif
+
+ --u_start[ch];
+ u_start[ch] &= 0xf;
+ u_div[ch]=u_div[ch] ? 0 : 1;
+
+#if defined(PENTIUM_RDTSC)
+ __asm__(".byte 0x0f,0x31" : "=a" (cnt2), "=d" (cnt4));
+
+ if (cnt2-cnt1 < min_cycles) {
+ min_cycles = cnt2-cnt1;
+ printf("%d, %d cycles, %d\n", cnt3-cnt1, min_cycles, start);
+ }
+#endif
+}
+
+void premultiply()
+{
+ int i,t;
+
+ for (i = 0; i < 17; ++i)
+ for (t = 0; t < 32; ++t)
+ t_dewindow[i][t] *= 16383.5f;
+}
diff --git a/Src/Sound/MPEG/transform.h b/Src/Sound/MPEG/transform.h
new file mode 100644
index 0000000..2c846f4
--- /dev/null
+++ b/Src/Sound/MPEG/transform.h
@@ -0,0 +1,168 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+*/
+
+/* transform.h tables galore
+ *
+ * Created by: tomislav uzelac May 1996
+ * Last modified by: tomislav uzelac Mar 1 97
+ */
+extern void imdct_init();
+extern void imdct(int win_type,int sb,int ch);
+extern void poly(int ch,int i);
+extern void premultiply();
+
+extern short sample_buffer[18][32][2];
+extern float res[32][18];
+extern float s[2][32][18];
+
+#ifdef TRANSFORM
+
+void imdct_init();
+void imdct(int win_type,int sb,int ch);
+void poly(int ch,int i);
+void premultiply();
+
+short sample_buffer[18][32][2];
+float s[2][32][18];
+float res[32][18];
+float win[4][36];
+
+static const float t_sin[4][36]={{
+ -0.032160f, 0.103553f, -0.182543f, 0.266729f, -0.353554f, 0.440377f,
+ -0.524563f, 0.603553f, -0.674947f, 0.736575f, -0.786566f, 0.823400f,
+ -0.845957f, 0.853554f, -0.845957f, 0.823399f, -0.786566f, 0.736575f,
+ -0.674947f, 0.603553f, -0.524564f, 0.440378f, -0.353553f, 0.266729f,
+ -0.182544f, 0.103553f, -0.032160f, -0.029469f, 0.079459f, -0.116293f,
+ 0.138851f, -0.146446f, 0.138851f, -0.116293f, 0.079459f, -0.029469f
+},{
+ -0.032160f, 0.103553f, -0.182543f, 0.266729f, -0.353554f, 0.440377f,
+ -0.524563f, 0.603553f, -0.674947f, 0.736575f, -0.786566f, 0.823400f,
+ -0.845957f, 0.853554f, -0.845957f, 0.823399f, -0.786566f, 0.736575f,
+ -0.675590f, 0.608761f, -0.537300f, 0.461749f, -0.382683f, 0.300706f,
+ -0.214588f, 0.120590f, -0.034606f, -0.026554f, 0.049950f, -0.028251f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f
+},{
+ -0.103553f, 0.353554f, -0.603553f, 0.786566f, -0.853554f, 0.786566f,
+ -0.603553f, 0.353553f, -0.103553f, -0.079459f, 0.146446f, -0.079459f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f
+},{
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ -0.127432f, 0.379410f, -0.608182f, 0.792598f, -0.915976f, 0.967944f,
+ -0.953717f, 0.923880f, -0.887011f, 0.843391f, -0.793353f, 0.737277f,
+ -0.674947f, 0.603553f, -0.524564f, 0.440378f, -0.353553f, 0.266729f,
+ -0.182544f, 0.103553f, -0.032160f, -0.029469f, 0.079459f, -0.116293f,
+ 0.138851f, -0.146446f, 0.138851f, -0.116293f, 0.079459f, -0.029469f
+}};
+
+static const float t_2cos[4][18]={
+{ -0.174311f, -0.517638f, -0.845237f, -1.147153f, -1.414214f, -1.638304f, -1.812616f, -1.931852f, -1.992389f,
+ 0.174311f, 0.517638f, 0.845237f, 1.147153f, 1.414214f, 1.638304f, 1.812616f, 1.931852f, 1.992389f},
+{ -0.174311f, -0.517638f, -0.845237f, -1.147153f, -1.414214f, -1.638304f, -1.812616f, -1.931852f, -1.992389f,
+ 0.174311f, 0.517638f, 0.845237f, 1.147153f, 1.414214f, 1.638304f, 1.812616f, 1.931852f, 1.992389f},
+{ -0.517638f, -1.41421f, -1.93185f, 0.517638f, 1.41421f, 1.93185f,0,0,0,0,0,0,0,0,0,0,0,0},
+{ -0.174311f, -0.517638f, -0.845237f, -1.147153f, -1.414214f, -1.638304f, -1.812616f, -1.931852f, -1.992389f,
+ 0.174311f, 0.517638f, 0.845237f, 1.147153f, 1.414214f, 1.638304f, 1.812616f, 1.931852f, 1.992389f}
+};
+
+static const float b1 = 1.997590912f; static const float b2 = 1.990369453f; static const float b3 = 1.978353019f;
+static const float b4 = 1.961570560f; static const float b5 = 1.940062506f; static const float b6 = 1.913880671f;
+static const float b7 = 1.883088130f; static const float b8 = 1.847759065f; static const float b9 = 1.807978586f;
+static const float b10= 1.763842529f; static const float b11= 1.715457220f; static const float b12= 1.662939225f;
+static const float b13= 1.606415063f; static const float b14= 1.546020907f; static const float b15= 1.481902251f;
+static const float b16= 1.414213562f; static const float b17= 1.343117910f; static const float b18= 1.268786568f;
+static const float b19= 1.191398609f; static const float b20= 1.111140466f; static const float b21= 1.028205488f;
+static const float b22= 0.942793474f; static const float b23= 0.855110187f; static const float b24= 0.765366865f;
+static const float b25= 0.673779707f; static const float b26= 0.580569355f; static const float b27= 0.485960360f;
+static const float b28= 0.390180644f; static const float b29= 0.293460949f; static const float b30= 0.196034281f;
+static const float b31= 0.098135349f;
+
+static float t_dewindow[17][32] = {{
+ 0.000000000f,-0.000442505f, 0.003250122f,-0.007003784f, 0.031082153f,-0.078628540f, 0.100311279f,-0.572036743f,
+ 1.144989014f, 0.572036743f, 0.100311279f, 0.078628540f, 0.031082153f, 0.007003784f, 0.003250122f, 0.000442505f,
+ 0.000000000f,-0.000442505f, 0.003250122f,-0.007003784f, 0.031082153f,-0.078628540f, 0.100311279f,-0.572036743f,
+ 1.144989014f, 0.572036743f, 0.100311279f, 0.078628540f, 0.031082153f, 0.007003784f, 0.003250122f, 0.000442505f,
+},{
+-0.000015259f,-0.000473022f, 0.003326416f,-0.007919312f, 0.030517578f,-0.084182739f, 0.090927124f,-0.600219727f,
+ 1.144287109f, 0.543823242f, 0.108856201f, 0.073059082f, 0.031478882f, 0.006118774f, 0.003173828f, 0.000396729f,
+-0.000015259f,-0.000473022f, 0.003326416f,-0.007919312f, 0.030517578f,-0.084182739f, 0.090927124f,-0.600219727f,
+ 1.144287109f, 0.543823242f, 0.108856201f, 0.073059082f, 0.031478882f, 0.006118774f, 0.003173828f, 0.000396729f,
+},{
+-0.000015259f,-0.000534058f, 0.003387451f,-0.008865356f, 0.029785156f,-0.089706421f, 0.080688477f,-0.628295898f,
+ 1.142211914f, 0.515609741f, 0.116577148f, 0.067520142f, 0.031738281f, 0.005294800f, 0.003082275f, 0.000366211f,
+-0.000015259f,-0.000534058f, 0.003387451f,-0.008865356f, 0.029785156f,-0.089706421f, 0.080688477f,-0.628295898f,
+ 1.142211914f, 0.515609741f, 0.116577148f, 0.067520142f, 0.031738281f, 0.005294800f, 0.003082275f, 0.000366211f,
+},{
+-0.000015259f,-0.000579834f, 0.003433228f,-0.009841919f, 0.028884888f,-0.095169067f, 0.069595337f,-0.656219482f,
+ 1.138763428f, 0.487472534f, 0.123474121f, 0.061996460f, 0.031845093f, 0.004486084f, 0.002990723f, 0.000320435f,
+-0.000015259f,-0.000579834f, 0.003433228f,-0.009841919f, 0.028884888f,-0.095169067f, 0.069595337f,-0.656219482f,
+ 1.138763428f, 0.487472534f, 0.123474121f, 0.061996460f, 0.031845093f, 0.004486084f, 0.002990723f, 0.000320435f,
+},{
+-0.000015259f,-0.000625610f, 0.003463745f,-0.010848999f, 0.027801514f,-0.100540161f, 0.057617187f,-0.683914185f,
+ 1.133926392f, 0.459472656f, 0.129577637f, 0.056533813f, 0.031814575f, 0.003723145f, 0.002899170f, 0.000289917f,
+-0.000015259f,-0.000625610f, 0.003463745f,-0.010848999f, 0.027801514f,-0.100540161f, 0.057617187f,-0.683914185f,
+ 1.133926392f, 0.459472656f, 0.129577637f, 0.056533813f, 0.031814575f, 0.003723145f, 0.002899170f, 0.000289917f,
+},{
+-0.000015259f,-0.000686646f, 0.003479004f,-0.011886597f, 0.026535034f,-0.105819702f, 0.044784546f,-0.711318970f,
+ 1.127746582f, 0.431655884f, 0.134887695f, 0.051132202f, 0.031661987f, 0.003005981f, 0.002792358f, 0.000259399f,
+-0.000015259f,-0.000686646f, 0.003479004f,-0.011886597f, 0.026535034f,-0.105819702f, 0.044784546f,-0.711318970f,
+ 1.127746582f, 0.431655884f, 0.134887695f, 0.051132202f, 0.031661987f, 0.003005981f, 0.002792358f, 0.000259399f,
+},{
+-0.000015259f,-0.000747681f, 0.003479004f,-0.012939453f, 0.025085449f,-0.110946655f, 0.031082153f,-0.738372803f,
+ 1.120223999f, 0.404083252f, 0.139450073f, 0.045837402f, 0.031387329f, 0.002334595f, 0.002685547f, 0.000244141f,
+-0.000015259f,-0.000747681f, 0.003479004f,-0.012939453f, 0.025085449f,-0.110946655f, 0.031082153f,-0.738372803f,
+ 1.120223999f, 0.404083252f, 0.139450073f, 0.045837402f, 0.031387329f, 0.002334595f, 0.002685547f, 0.000244141f,
+},{
+-0.000030518f,-0.000808716f, 0.003463745f,-0.014022827f, 0.023422241f,-0.115921021f, 0.016510010f,-0.765029907f,
+ 1.111373901f, 0.376800537f, 0.143264771f, 0.040634155f, 0.031005859f, 0.001693726f, 0.002578735f, 0.000213623f,
+-0.000030518f,-0.000808716f, 0.003463745f,-0.014022827f, 0.023422241f,-0.115921021f, 0.016510010f,-0.765029907f,
+ 1.111373901f, 0.376800537f, 0.143264771f, 0.040634155f, 0.031005859f, 0.001693726f, 0.002578735f, 0.000213623f,
+},{
+-0.000030518f,-0.000885010f, 0.003417969f,-0.015121460f, 0.021575928f,-0.120697021f, 0.001068115f,-0.791213989f,
+ 1.101211548f, 0.349868774f, 0.146362305f, 0.035552979f, 0.030532837f, 0.001098633f, 0.002456665f, 0.000198364f,
+-0.000030518f,-0.000885010f, 0.003417969f,-0.015121460f, 0.021575928f,-0.120697021f, 0.001068115f,-0.791213989f,
+ 1.101211548f, 0.349868774f, 0.146362305f, 0.035552979f, 0.030532837f, 0.001098633f, 0.002456665f, 0.000198364f,
+},{
+-0.000030518f,-0.000961304f, 0.003372192f,-0.016235352f, 0.019531250f,-0.125259399f,-0.015228271f,-0.816864014f,
+ 1.089782715f, 0.323318481f, 0.148773193f, 0.030609131f, 0.029937744f, 0.000549316f, 0.002349854f, 0.000167847f,
+-0.000030518f,-0.000961304f, 0.003372192f,-0.016235352f, 0.019531250f,-0.125259399f,-0.015228271f,-0.816864014f,
+ 1.089782715f, 0.323318481f, 0.148773193f, 0.030609131f, 0.029937744f, 0.000549316f, 0.002349854f, 0.000167847f,
+},{
+-0.000030518f,-0.001037598f, 0.003280640f,-0.017349243f, 0.017257690f,-0.129562378f,-0.032379150f,-0.841949463f,
+ 1.077117920f, 0.297210693f, 0.150497437f, 0.025817871f, 0.029281616f, 0.000030518f, 0.002243042f, 0.000152588f,
+-0.000030518f,-0.001037598f, 0.003280640f,-0.017349243f, 0.017257690f,-0.129562378f,-0.032379150f,-0.841949463f,
+ 1.077117920f, 0.297210693f, 0.150497437f, 0.025817871f, 0.029281616f, 0.000030518f, 0.002243042f, 0.000152588f,
+},{
+-0.000045776f,-0.001113892f, 0.003173828f,-0.018463135f, 0.014801025f,-0.133590698f,-0.050354004f,-0.866363525f,
+ 1.063217163f, 0.271591187f, 0.151596069f, 0.021179199f, 0.028533936f,-0.000442505f, 0.002120972f, 0.000137329f,
+-0.000045776f,-0.001113892f, 0.003173828f,-0.018463135f, 0.014801025f,-0.133590698f,-0.050354004f,-0.866363525f,
+ 1.063217163f, 0.271591187f, 0.151596069f, 0.021179199f, 0.028533936f,-0.000442505f, 0.002120972f, 0.000137329f,
+},{
+-0.000045776f,-0.001205444f, 0.003051758f,-0.019577026f, 0.012115479f,-0.137298584f,-0.069168091f,-0.890090942f,
+ 1.048156738f, 0.246505737f, 0.152069092f, 0.016708374f, 0.027725220f,-0.000869751f, 0.002014160f, 0.000122070f,
+-0.000045776f,-0.001205444f, 0.003051758f,-0.019577026f, 0.012115479f,-0.137298584f,-0.069168091f,-0.890090942f,
+ 1.048156738f, 0.246505737f, 0.152069092f, 0.016708374f, 0.027725220f,-0.000869751f, 0.002014160f, 0.000122070f,
+},{
+-0.000061035f,-0.001296997f, 0.002883911f,-0.020690918f, 0.009231567f,-0.140670776f,-0.088775635f,-0.913055420f,
+ 1.031936646f, 0.221984863f, 0.151962280f, 0.012420654f, 0.026840210f,-0.001266479f, 0.001907349f, 0.000106812f,
+-0.000061035f,-0.001296997f, 0.002883911f,-0.020690918f, 0.009231567f,-0.140670776f,-0.088775635f,-0.913055420f,
+ 1.031936646f, 0.221984863f, 0.151962280f, 0.012420654f, 0.026840210f,-0.001266479f, 0.001907349f, 0.000106812f,
+},{
+-0.000061035f,-0.001388550f, 0.002700806f,-0.021789551f, 0.006134033f,-0.143676758f,-0.109161377f,-0.935195923f,
+ 1.014617920f, 0.198059082f, 0.151306152f, 0.008316040f, 0.025909424f,-0.001617432f, 0.001785278f, 0.000106812f,
+-0.000061035f,-0.001388550f, 0.002700806f,-0.021789551f, 0.006134033f,-0.143676758f,-0.109161377f,-0.935195923f,
+ 1.014617920f, 0.198059082f, 0.151306152f, 0.008316040f, 0.025909424f,-0.001617432f, 0.001785278f, 0.000106812f,
+},{
+-0.000076294f,-0.001480103f, 0.002487183f,-0.022857666f, 0.002822876f,-0.146255493f,-0.130310059f,-0.956481934f,
+ 0.996246338f, 0.174789429f, 0.150115967f, 0.004394531f, 0.024932861f,-0.001937866f, 0.001693726f, 0.000091553f,
+-0.000076294f,-0.001480103f, 0.002487183f,-0.022857666f, 0.002822876f,-0.146255493f,-0.130310059f,-0.956481934f,
+ 0.996246338f, 0.174789429f, 0.150115967f, 0.004394531f, 0.024932861f,-0.001937866f, 0.001693726f, 0.000091553f,
+},{
+-0.000076294f,-0.001586914f, 0.002227783f,-0.023910522f,-0.000686646f,-0.148422241f,-0.152206421f,-0.976852417f,
+ 0.976852417f, 0.152206421f, 0.148422241f, 0.000686646f, 0.023910522f,-0.002227783f, 0.001586914f, 0.000076294f,
+-0.000076294f,-0.001586914f, 0.002227783f,-0.023910522f,-0.000686646f,-0.148422241f,-0.152206421f,-0.976852417f,
+ 0.976852417f, 0.152206421f, 0.148422241f, 0.000686646f, 0.023910522f,-0.002227783f, 0.001586914f, 0.000076294f,
+} };
+#endif /* TRANSFORM */
diff --git a/Src/Sound/MPEG/util.cpp b/Src/Sound/MPEG/util.cpp
new file mode 100644
index 0000000..30b6d44
--- /dev/null
+++ b/Src/Sound/MPEG/util.cpp
@@ -0,0 +1,110 @@
+/* this file is a part of amp software
+
+ util.c: created by Andrew Richards
+
+*/
+
+#define AMP_UTIL
+#include "amp.h"
+
+#include
+#include
+#include
+
+#include "audio.h"
+
+struct debugFlags_t debugFlags;
+
+
+/* die - for terminal conditions prints the error message and exits */
+/* can not be suppressed with -q,-quiet */
+void
+die(char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap,fmt);
+ vfprintf(stderr, fmt, ap);
+}
+
+
+/* warn - for warning messages. Can be suppressed by -q,-quiet */
+void
+warn(char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap,fmt);
+ if (!A_QUIET) {
+ fprintf(stderr,"Warning: ");
+ vfprintf(stderr, fmt, ap);
+ }
+}
+
+
+/* msg - for general output. Can be suppressed by -q,-quiet. Output */
+/* goes to stderr so it doesn't conflict with stdout output */
+void
+msg(char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap,fmt);
+
+ if (!A_QUIET)
+ {
+ if (A_MSG_STDOUT) {
+ vfprintf(stdout, fmt, ap);
+ fflush(stdout);
+ } else {
+ vfprintf(stderr, fmt, ap);
+ fflush(stderr);
+ }
+ }
+}
+
+void
+debugOptions()
+{
+ int idx;
+ msg("Possible options are: ");
+ for(idx=0;debugLookup[idx].name!=0;idx++)
+ msg("%s,",debugLookup[idx].name);
+ msg("\010 \n");
+}
+
+
+/* debugSetup - if debugging is turned on sets up the debug flags from */
+/* the command line arguments */
+
+void
+debugSetup(char *dbgFlags)
+{
+#ifndef DEBUG
+ warn("Debugging has not been compiled into this version of amp\n");
+#else
+ char *ptr;
+ int idx;
+
+ memset(&debugFlags,0,sizeof(debugFlags));
+
+ ptr=strtok(dbgFlags,",");
+ while(ptr) {
+ for(idx=0;debugLookup[idx].name!=0;idx++) {
+ if (strcmp(debugLookup[idx].name,ptr)==0) {
+ *(debugLookup[idx].var)=1;
+ break;
+ }
+ }
+ if (debugLookup[idx].name==0) {
+ warn("Debug option, %s, does not exist\n",ptr);
+ debugOptions();
+ exit(1);
+ }
+ ptr=strtok(NULL,",");
+ }
+
+ DB(args,
+ for(idx=0;debugLookup[idx].name!=0;idx++)
+ printf("Flag: %s = %d\n",debugLookup[idx].name,*(debugLookup[idx].var));
+ );
+#endif
+}
+
diff --git a/Src/Sound/SCSP.cpp b/Src/Sound/SCSP.cpp
index aaed44d..56357c5 100644
--- a/Src/Sound/SCSP.cpp
+++ b/Src/Sound/SCSP.cpp
@@ -113,8 +113,6 @@ unsigned int RevR,RevW;
#define DWORD UINT32
#endif
-static CIRQ *ppcIRQ;
-static unsigned ppcSoundIRQBit;
static int (*Run68kCB)(int cycles);
static void (*Int68kCB)(int irq);
static void (*RetIntCB)();
@@ -745,7 +743,7 @@ void SCSP_UpdateSlotReg(int s,int r)
if(KEYONB(s2) && (!s2->active || (s2->active && s2->EG.state==RELEASE)))
{
DebugLog("KEYON %d",sl);
- printf("68K: KEYON %d\n",sl);
+ //printf("68K: KEYON %d\n",sl);
SCSP_StartSlot(s2);
}
if(!KEYONB(s2) && s2->active)
@@ -1851,12 +1849,10 @@ void SCSP_Update()
SCSP_DoMasterSamples(length);
}
-void SCSP_SetCB(int (*Run68k)(int cycles),void (*Int68k)(int irq), CIRQ *ppcIRQObjectPtr, unsigned ppcIRQBit)
+void SCSP_SetCB(int (*Run68k)(int cycles),void (*Int68k)(int irq))
{
Int68kCB=Int68k;
Run68kCB=Run68k;
- ppcIRQ = ppcIRQObjectPtr;
- ppcSoundIRQBit = ppcIRQBit;
}
void SCSP_MidiIn(BYTE val)
@@ -1872,7 +1868,7 @@ void SCSP_MidiIn(BYTE val)
void SCSP_MidiOutW(BYTE val)
{
- printf("68K: MIDI out\n");
+ //printf("68K: MIDI out\n");
DebugLog("Midi Out Buffer push %02X",val);
MidiStack[MidiOutW++]=val;
MidiOutW&=7;
diff --git a/Src/Sound/SCSP.h b/Src/Sound/SCSP.h
index feb803c..6c8af8f 100644
--- a/Src/Sound/SCSP.h
+++ b/Src/Sound/SCSP.h
@@ -36,7 +36,7 @@ unsigned char SCSP_r8(unsigned int addr);
unsigned short SCSP_r16(unsigned int addr);
unsigned int SCSP_r32(unsigned int addr);
-void SCSP_SetCB(int (*Run68k)(int cycles),void (*Int68k)(int irq), CIRQ *ppcIRQObjectPtr, unsigned soundIRQBit);
+void SCSP_SetCB(int (*Run68k)(int cycles),void (*Int68k)(int irq));
void SCSP_Update();
void SCSP_MidiIn(unsigned char);
void SCSP_MidiOutW(unsigned char);
diff --git a/Src/Supermodel.h b/Src/Supermodel.h
index 52cadcf..b77a910 100644
--- a/Src/Supermodel.h
+++ b/Src/Supermodel.h
@@ -147,7 +147,7 @@ extern void InfoLog(const char *fmt, ...);
#include "CPU/Bus.h"
#include "CPU/PowerPC/PPCDisasm.h"
#include "CPU/PowerPC/ppc.h"
-#include "CPU/68K/M68K.h"
+#include "CPU/68K/68K.h"
#include "CPU/Z80/Z80.h"
#include "Inputs/Input.h"
#include "Inputs/Inputs.h"
@@ -164,7 +164,9 @@ extern void InfoLog(const char *fmt, ...);
#include "Model3/TileGen.h"
#include "Model3/Real3D.h"
#include "Sound/SCSP.h"
+#include "Sound/MPEG/MPEG.h"
#include "Model3/SoundBoard.h"
+#include "Model3/DSB.h"
#include "Model3/Model3.h"
/******************************************************************************