diff -Nru mupen64plus-rsp-hle-1.99.5/LICENSES mupen64plus-rsp-hle-2.0/LICENSES --- mupen64plus-rsp-hle-1.99.5/LICENSES 2012-03-10 17:54:03.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/LICENSES 2013-07-03 14:07:45.000000000 +0000 @@ -3,8 +3,9 @@ Mupen64Plus-rsp-hle is licensed under the GNU General Public License version 2. -The authors of Mupen64Plus are: +The authors of Mupen64Plus-rsp-hle are: * Richard Goedeken (Richard42) + * Bobby Smiles * John Chadwick (NMN) * James Hood (Ebenblues) * Scott Gorman (okaygo) diff -Nru mupen64plus-rsp-hle-1.99.5/RELEASE mupen64plus-rsp-hle-2.0/RELEASE --- mupen64plus-rsp-hle-1.99.5/RELEASE 2012-03-10 17:54:03.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/RELEASE 2013-07-03 14:07:45.000000000 +0000 @@ -1,6 +1,16 @@ RSP High-Level Emulation plugin for Mupen64Plus ----------------------------------------------- +Mupen64Plus-rsp-hle v2.0 - July 4, 2013 +------------------------------------------------- + - Add support for MusyX ucode detection + - support JPEG decoding used in Pokemon Stadium Japan + - lots of refactoring to clean up code + - Project files for Visual Studio 2012 + - Makefile changes + - add support for PowerPC and MinGW32 builds + - add cross-compiling support to build Win32 executables (MXE) under Linux + Mupen64Plus-rsp-hle v1.99.5 - March 10, 2012 ------------------------------------------------- - Handle JPEG decompression, used in Ogre Battle 64 and Pokemon Stadium diff -Nru mupen64plus-rsp-hle-1.99.5/debian/changelog mupen64plus-rsp-hle-2.0/debian/changelog --- mupen64plus-rsp-hle-1.99.5/debian/changelog 2012-06-08 22:59:55.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/debian/changelog 2013-07-05 20:53:05.000000000 +0000 @@ -1,3 +1,64 @@ +mupen64plus-rsp-hle (2.0-1) unstable; urgency=low + + * New Upstream Version + * Upload to unstable + * debian/control: + - Build-Depend on debhelper 9.20130604 for support of parameters when + detecting targets in dh_auto_* + * debian/rules: + - Work around new debhelper 9.20130624 dh_auto_{clean,test} behavior + which is causing a FTBFS by adding an explicit + override_dh_auto_{clean,test} rule + * debian/watch: + - Verify new upstream versions using GPG key 954F81B094AA5BB226F5 + + -- Sven Eckelmann Fri, 05 Jul 2013 22:53:00 +0200 + +mupen64plus-rsp-hle (2.0~rc2+1+3d76355d095c-2) experimental; urgency=low + + * Remove unused dependency to libsdl1.2-dev in debian/control + * Update debian/copyright + + -- Sven Eckelmann Sun, 23 Jun 2013 13:25:17 +0200 + +mupen64plus-rsp-hle (2.0~rc2+1+3d76355d095c-1) experimental; urgency=low + + * New Upstream Snapshot from 3d76355d095c456eb32677cb65feb775ef24d896 + * Enable link-time optimization in debian/rules similar to upstream + + -- Sven Eckelmann Wed, 05 Jun 2013 13:25:15 +0200 + +mupen64plus-rsp-hle (1.99.5+25+a77acef394fd-1) experimental; urgency=low + + * New Upstream Snapshot from a77acef394fdc331160e0e583b4f45f557b1b97c + * Disable extra debug code in release builds with -DNDEBUG in + debian/rules + + -- Sven Eckelmann Fri, 08 Feb 2013 10:15:39 +0100 + +mupen64plus-rsp-hle (1.99.5+11+bf4a5b4315de-1) experimental; urgency=low + + * New Upstream Snapshot from bf4a5b4315de9214efde317b2f3c9367880c9d8f + * Upgraded to policy 3.9.4, no changes required + * Remove obsolete DM-Upload-Allowed in debian/control + + -- Sven Eckelmann Sun, 02 Dec 2012 22:32:24 +0100 + +mupen64plus-rsp-hle (1.99.5+8+1e306f08d231-1) experimental; urgency=low + + * New Upstream Snapshot from 1e306f08d231ffc677723e93a4b84a3ba7503058 + + -- Sven Eckelmann Tue, 11 Sep 2012 21:21:51 +0200 + +mupen64plus-rsp-hle (1.99.5+6+0d5a734e9425-1) experimental; urgency=low + + * New Upstream Snapshot from 0d5a734e942501a78d199d53ad0099ce87855d3a + * debian/patches: + - Remove upstream merged gcc_lto.patch, pokemon_stadium_sound.patch + zelda_graphics_glitches.patch + + -- Sven Eckelmann Sun, 17 Jun 2012 00:51:47 +0200 + mupen64plus-rsp-hle (1.99.5-3) unstable; urgency=low * debian/patches: diff -Nru mupen64plus-rsp-hle-1.99.5/debian/control mupen64plus-rsp-hle-2.0/debian/control --- mupen64plus-rsp-hle-1.99.5/debian/control 2012-06-08 22:59:55.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/debian/control 2013-07-05 20:53:05.000000000 +0000 @@ -3,16 +3,14 @@ Priority: optional Maintainer: Tobias Loose Uploaders: Sven Eckelmann -DM-Upload-Allowed: yes -Standards-Version: 3.9.3 +Standards-Version: 3.9.4 Homepage: http://code.google.com/p/mupen64plus/ Vcs-Git: git://anonscm.debian.org/collab-maint/mupen64plus-rsp-hle.git Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/mupen64plus-rsp-hle.git Build-Depends: - debhelper (>= 9), + debhelper (>= 9.20130604), dpkg-dev (>= 1.16.1.1), libmupen64plus-dev (>= 1.99.5), - libsdl1.2-dev | libsdl-dev, Package: mupen64plus-rsp-hle Architecture: any-i386 any-amd64 diff -Nru mupen64plus-rsp-hle-1.99.5/debian/copyright mupen64plus-rsp-hle-2.0/debian/copyright --- mupen64plus-rsp-hle-1.99.5/debian/copyright 2012-06-08 22:59:55.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/debian/copyright 2013-07-05 20:53:05.000000000 +0000 @@ -14,11 +14,7 @@ 2008-2009, Richard 'Richard42' Goedeken License: GPL-2+ -Files: src/idict.c -Copyright: 2012, Bobby Smiles -License: GPL-2+ - -Files: src/ipeg.c src/main.c +Files: src/ipeg.c src/main.c src/alist.c src/cicx105.c Copyright: 2002, Hacktarux 2009, Richard 'Richard42' Goedeken 2012, Bobby Smiles diff -Nru mupen64plus-rsp-hle-1.99.5/debian/patches/gcc_lto.patch mupen64plus-rsp-hle-2.0/debian/patches/gcc_lto.patch --- mupen64plus-rsp-hle-1.99.5/debian/patches/gcc_lto.patch 2012-06-08 22:59:55.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/debian/patches/gcc_lto.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -Description: Enable experimental support for link-time optimization -Author: Sven Eckelmann - ---- -diff --git a/projects/unix/Makefile b/projects/unix/Makefile -index b50545b17f44365586c9d21d5500f6728e34f32b..5deda7ea62e3e86aac9a2ad3681249a46e19ad4e 100644 ---- a/projects/unix/Makefile -+++ b/projects/unix/Makefile -@@ -249,6 +249,7 @@ targets: - @echo " DESTDIR=path == path to prepend to all installation paths (only for packagers)" - @echo " Debugging Options:" - @echo " DEBUG=1 == add debugging symbols" -+ @echo " LTO=1 == enable experimental build with link-time optimization" - @echo " V=1 == show verbose compiler output" - - all: $(TARGET) -@@ -270,6 +271,11 @@ CFLAGS += -MD - -include $(OBJECTS:.o=.d) - - CXXFLAGS += $(CFLAGS) -+ifeq ($(LTO), 1) -+ CFLAGS += -flto -+ CXXFLAGS += -flto -+ LDFLAGS += -fuse-linker-plugin $(CXXFLAGS) -+endif - - # standard build rules - $(OBJDIR)/%.o: $(SRCDIR)/%.c diff -Nru mupen64plus-rsp-hle-1.99.5/debian/patches/pokemon_stadium_sound.patch mupen64plus-rsp-hle-2.0/debian/patches/pokemon_stadium_sound.patch --- mupen64plus-rsp-hle-1.99.5/debian/patches/pokemon_stadium_sound.patch 2012-06-08 22:59:55.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/debian/patches/pokemon_stadium_sound.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,377 +0,0 @@ -Description: Fix sound in pokemon statium -Author: Bobby Smiles -Origin: backport, https://bitbucket.org/richard42/mupen64plus-rsp-hle/changeset/13894f74faa9 https://bitbucket.org/richard42/mupen64plus-rsp-hle/changeset/b8ab5963bad3 - ---- -diff --git a/src/main.c b/src/main.c -index 736310a9ac32c055a96e6599efe8e094fb4c6235..0142d781bdfd2069b71e3a786fc1a242c915c077 100644 ---- a/src/main.c -+++ b/src/main.c -@@ -42,6 +42,53 @@ static int l_PluginInit = 0; - - /* local functions */ - -+ -+static void dump_binary(char *filename, unsigned char *bytes, unsigned size) -+{ -+ FILE *f; -+ -+ // if file already exists, do nothing -+ f = fopen(filename, "r"); -+ if (f == NULL) -+ { -+ // else we write bytes to the file -+ f= fopen(filename, "wb"); -+ if (f != NULL) { -+ if (fwrite(bytes, 1, size, f) != size) -+ { -+ DebugMessage(M64MSG_ERROR, "Writing error on %s", filename); -+ } -+ fclose(f); -+ } -+ else -+ { -+ DebugMessage(M64MSG_ERROR, "Couldn't open %s for writing !", filename); -+ } -+ } -+ else -+ { -+ fclose(f); -+ } -+} -+ -+ -+/** -+ * Try to figure if the RSP was launched using osSpTask* functions -+ * and not run directly (in which case DMEM[0xfc0-0xfff] is meaningless). -+ * -+ * Previously, the ucode_size field was used to determine this, -+ * but it is not robust enough (hi Pokemon Stadium !) because games could write anything -+ * in this field : most ucode_boot discard the value and just use 0xf7f anyway. -+ * -+ * Using ucode_boot_size should be more robust in this regard. -+ **/ -+static int is_run_through_task(OSTask_t* task) -+{ -+ return (task->ucode_boot_size <= 0x1000 -+ && task->ucode_boot_size >= 0); -+} -+ -+ - /** - * Simulate the effect of setting the TASKDONE bit (aliased to SIG2) - * and executing a break instruction (setting HALT and BROKE bits). -@@ -57,6 +104,13 @@ static void taskdone() - // - // 0x203 = TASKDONE | BROKE | HALT - *rsp.SP_STATUS_REG |= 0x203; -+ -+ // if INTERRUPT_ON_BREAK we generate the interrupt -+ if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) -+ { -+ *rsp.MI_INTR_REG |= 0x1; -+ rsp.CheckInterrupts(); -+ } - } - - -@@ -109,8 +163,6 @@ static int audio_ucode(OSTask_t *task) - } - } - --// data = (short*)(rsp.RDRAM + task->ucode_data); -- - for (i = 0; i < (task->data_size/4); i += 2) - { - inst1 = p_alist[i]; -@@ -193,140 +245,179 @@ EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, int *Plugi - - EXPORT unsigned int CALL DoRspCycles(unsigned int Cycles) - { -- OSTask_t *task = (OSTask_t*)(rsp.DMEM + 0xFC0); -+ OSTask_t *task = (OSTask_t*)(rsp.DMEM + 0xfc0); -+ int run_through_task = is_run_through_task(task); -+ - unsigned int i, sum=0; - -- if( task->type == 1 && task->data_ptr != 0 && GraphicsHle) -- { -- if (rsp.ProcessDlistList != NULL) -- { -- rsp.ProcessDlistList(); -- } -- taskdone(); -- if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) -- { -- *rsp.MI_INTR_REG |= 0x1; -- rsp.CheckInterrupts(); -- } -+ char filename[256]; - -- *rsp.DPC_STATUS_REG &= ~0x0002; -- return Cycles; -- } -- else if (task->type == 2 && AudioHle) -+ if (run_through_task) - { -- if (rsp.ProcessAlistList != NULL) -- { -- rsp.ProcessAlistList(); -- } -- taskdone(); -- if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) -- { -- *rsp.MI_INTR_REG |= 0x1; -- rsp.CheckInterrupts(); -- } -- return Cycles; -- } -- else if (task->type == 7) -- { -- rsp.ShowCFB(); -- } -+ // most ucode_boot procedure copy 0xf80 bytes of ucode whatever the ucode_size is. -+ // For practical purpose we use a ucode_size = min(0xf80, task->ucode_size) -+ unsigned int ucode_size = (task->ucode_size > 0xf80) ? 0xf80 : task->ucode_size; - -- taskdone(); -- if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) -- { -- *rsp.MI_INTR_REG |= 0x1; -- rsp.CheckInterrupts(); -- } -- -- if (task->ucode_size <= 0x1000) -- for (i=0; i<(task->ucode_size/2); i++) -+ for (i=0; iucode + i); -+ -+ switch(task->type) -+ { -+ case 1: // GFX -+ { -+ if (GraphicsHle && rsp.ProcessDlistList != NULL) -+ { -+ rsp.ProcessDlistList(); -+ taskdone(); -+ *rsp.DPC_STATUS_REG &= ~0x0002; -+ return Cycles; -+ } -+ else -+ { -+ DebugMessage(M64MSG_WARNING, "GFX ucode through rsp plugin is not implemented"); -+ } -+ break; -+ } -+ -+ case 2: // AUDIO -+ { -+ if (AudioHle && rsp.ProcessAlistList != NULL) -+ { -+ rsp.ProcessAlistList(); -+ taskdone(); -+ return Cycles; -+ } -+ else -+ { -+ if (audio_ucode(task) == 0) -+ { -+ taskdone(); -+ return Cycles; -+ } -+ } -+ break; -+ } -+ -+ case 4: // JPEG -+ { -+ switch(sum) -+ { -+ case 0x2caa6: // Pokemon Stadium {1,2} jpg decompression -+ ps_jpg_uncompress(task); -+ taskdone(); -+ return Cycles; -+ case 0x130de: // Ogre Battle background decompression -+ ob_jpg_uncompress(task); -+ taskdone(); -+ return Cycles; -+ } -+ break; -+ } -+ -+ case 7: // CFB -+ { -+ rsp.ShowCFB(); -+ taskdone(); -+ return Cycles; -+ break; -+ } -+ } -+ -+ DebugMessage(M64MSG_WARNING, "unknown OSTask: sum %x PC:%x", sum, *rsp.SP_PC_REG); -+ -+ sprintf(&filename[0], "task_%x.log", sum); -+ -+ -+ // dump task -+ FILE *f = fopen(filename, "r"); -+ if (f == NULL) -+ { -+ f = fopen(filename, "w"); -+ fprintf(f, -+ "type = %d\n" -+ "flags = %d\n" -+ "ucode_boot = %#08x size = %#x\n" -+ "ucode = %#08x size = %#x\n" -+ "ucode_data = %#08x size = %#x\n" -+ "dram_stack = %#08x size = %#x\n" -+ "output_buff = %#08x *size = %#x\n" -+ "data = %#08x size = %#x\n" -+ "yield_data = %#08x size = %#x\n", -+ task->type, task->flags, -+ task->ucode_boot, task->ucode_boot_size, -+ task->ucode, task->ucode_size, -+ task->ucode_data, task->ucode_data_size, -+ task->dram_stack, task->dram_stack_size, -+ task->output_buff, task->output_buff_size, -+ task->data_ptr, task->data_size, -+ task->yield_data_ptr, task->yield_data_size); -+ fclose(f); -+ } -+ else -+ { -+ fclose(f); -+ } -+ -+ -+ // dump ucode_boot -+ sprintf(&filename[0], "ucode_boot_%x.bin", sum); -+ dump_binary(filename, rsp.RDRAM + (task->ucode_boot & 0x7fffff), task->ucode_boot_size); -+ -+ // dump ucode -+ if (task->ucode != 0) -+ { -+ sprintf(&filename[0], "ucode_%x.bin", sum); -+ dump_binary(filename, rsp.RDRAM + (task->ucode & 0x7fffff), ucode_size); -+ } -+ -+ // dump ucode_data -+ if (task->ucode_data != 0) -+ { -+ sprintf(&filename[0], "ucode_data_%x.bin", sum); -+ dump_binary(filename, rsp.RDRAM + (task->ucode_data & 0x7fffff), task->ucode_data_size); -+ } -+ -+ // dump data -+ if (task->data_ptr != 0) -+ { -+ sprintf(&filename[0], "data_%x.bin", sum); -+ dump_binary(filename, rsp.RDRAM + (task->data_ptr & 0x7fffff), task->data_size); -+ } -+ } - else -+ { -+ // For ucodes that are not run using the osSpTask* functions -+ -+ // Try to identify the RSP code we should run - for (i=0; i<(0x1000/2); i++) - sum += *(rsp.IMEM + i); - -- -- if (task->ucode_size > 0x1000) -- { - switch(sum) - { -- case 0x9E2: // banjo tooie (U) boot code -+ // CIC 6105 IPL3 run some code on the RSP -+ // We only emulate the part that modify RDRAM -+ // -+ // It is used for instance in Banjo Tooie, Zelda, Perfect Dark... -+ case 0x9E2: // banjo tooie (U) -+ case 0x9F2: // banjo tooie (E) - { - int i,j; -- memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1e8); -+ memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1f0); - for (j=0; j<0xfc; j++) - for (i=0; i<8; i++) - *(rsp.RDRAM+((0x2fb1f0+j*0xff0+i)^S8))=*(rsp.IMEM+((0x120+j*8+i)^S8)); -- } - return Cycles; -- case 0x9F2: // banjo tooie (E) + zelda oot (E) boot code -- { -- int i,j; -- memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1e8); -- for (j=0; j<0xfc; j++) -- for (i=0; i<8; i++) -- *(rsp.RDRAM+((0x2fb1f0+j*0xff0+i)^S8))=*(rsp.IMEM+((0x120+j*8+i)^S8)); - } -- return Cycles; - } -- } -- else -- { -- switch(task->type) -- { -- case 2: // audio -- if (audio_ucode(task) == 0) -- return Cycles; -- break; -- case 4: // jpeg -- switch(sum) -- { -- case 0x278: // used by zelda during boot -- taskdone(); -- return Cycles; -- case 0x2e4fc: // used by pokemon stadium {1,2} for jpg decompression -- ps_jpg_uncompress(task); -- taskdone(); -- return Cycles; -- case 0x130de: // used by ogre battle for background decompression -- ob_jpg_uncompress(task); -- taskdone(); -- return Cycles; -- default: -- DebugMessage(M64MSG_WARNING, "unknown jpeg task: sum:%x", sum); -- } -- break; -- } -- } - -- { -- FILE *f; -- DebugMessage(M64MSG_WARNING, "unknown task: type:%d sum:%x PC:%lx", (int)task->type, sum, (unsigned long) rsp.SP_PC_REG); -+ DebugMessage(M64MSG_WARNING, "unknown RSP code: sum: %x PC:%x", sum, *rsp.SP_PC_REG); - -- if (task->ucode_size <= 0x1000) -- { -- f = fopen("imem.dat", "wb"); -- if (f == NULL || fwrite(rsp.RDRAM + task->ucode, 1, task->ucode_size, f) != task->ucode_size) -- DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file imem.dat"); -- fclose(f); -+ // dump IMEM & DMEM for further analysis -+ sprintf(&filename[0], "imem_%x.bin", sum); -+ dump_binary(filename, rsp.IMEM, 0x1000); - -- f = fopen("dmem.dat", "wb"); -- if (f == NULL || fwrite(rsp.RDRAM + task->ucode_data, 1, task->ucode_data_size, f) != task->ucode_data_size) -- DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file dmem.dat"); -- fclose(f); -- } -- else -- { -- f = fopen("imem.dat", "wb"); -- if (f == NULL || fwrite(rsp.IMEM, 1, 0x1000, f) != 0x1000) -- DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file imem.dat"); -- fclose(f); -- -- f = fopen("dmem.dat", "wb"); -- if (f == NULL || fwrite(rsp.DMEM, 1, 0x1000, f) != 0x1000) -- DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file dmem.dat"); -- fclose(f); -- } -+ sprintf(&filename[0], "dmem_%x.bin", sum); -+ dump_binary(filename, rsp.DMEM, 0x1000); - } - - return Cycles; diff -Nru mupen64plus-rsp-hle-1.99.5/debian/patches/series mupen64plus-rsp-hle-2.0/debian/patches/series --- mupen64plus-rsp-hle-1.99.5/debian/patches/series 2012-06-08 22:59:55.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -pokemon_stadium_sound.patch -zelda_graphics_glitches.patch -gcc_lto.patch diff -Nru mupen64plus-rsp-hle-1.99.5/debian/patches/zelda_graphics_glitches.patch mupen64plus-rsp-hle-2.0/debian/patches/zelda_graphics_glitches.patch --- mupen64plus-rsp-hle-1.99.5/debian/patches/zelda_graphics_glitches.patch 2012-06-08 22:59:55.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/debian/patches/zelda_graphics_glitches.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -Description: Readded jpeg task 278 used during Zelda OOT boot -Author: Bobby Smiles -Origin: upstream, https://bitbucket.org/richard42/mupen64plus-rsp-hle/changeset/27234e46cfe5 - ---- -diff --git a/src/jpeg.c b/src/jpeg.c -index 67f5ef489d6a9f8009484eb29a0402afc792b0b8..c51e611200322cebf03d6c6ade8e0c94613bffd0 100644 ---- a/src/jpeg.c -+++ b/src/jpeg.c -@@ -364,7 +364,7 @@ void ps_jpg_uncompress(OSTask_t *task) - } - - // Texel Formatting (RGBA16) -- offset = ps_jpg_data.pMacroBlocks + oMBsize*mb; -+ offset = ps_jpg_data.pMacroBlocks + iMBsize*mb; - y_offset = 0; - u_offset = oMBsize/2; - -diff --git a/src/main.c b/src/main.c -index 0142d781bdfd2069b71e3a786fc1a242c915c077..c72c3422233a9b6ce0785e0b35ac87b9e091eda8 100644 ---- a/src/main.c -+++ b/src/main.c -@@ -302,7 +302,10 @@ EXPORT unsigned int CALL DoRspCycles(unsigned int Cycles) - { - switch(sum) - { -- case 0x2caa6: // Pokemon Stadium {1,2} jpg decompression -+ case 0x278: // Zelda OOT during boot -+ taskdone(); -+ return Cycles; -+ case 0x2caa6: // Zelda OOT, Pokemon Stadium {1,2} jpg decompression - ps_jpg_uncompress(task); - taskdone(); - return Cycles; diff -Nru mupen64plus-rsp-hle-1.99.5/debian/rules mupen64plus-rsp-hle-2.0/debian/rules --- mupen64plus-rsp-hle-1.99.5/debian/rules 2012-06-08 22:59:55.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/debian/rules 2013-07-05 20:53:05.000000000 +0000 @@ -2,12 +2,13 @@ # -*- makefile -*- export DEB_BUILD_MAINT_OPTIONS=hardening=+all,-pie +export DEB_CFLAGS_MAINT_APPEND=-flto export DEB_LDFLAGS_MAINT_APPEND=-Wl,--as-needed DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) DEB_HOST_GNU_CPU ?= $(shell dpkg-architecture -qDEB_HOST_GNU_CPU) DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_OS) -MAKEOPTIONS = V=1 UNAME='$(DEB_HOST_ARCH_OS)' HOST_CPU='$(DEB_HOST_GNU_CPU)' APIDIR=/usr/include/mupen64plus/ DEBUG=1 PREFIX=/usr/ LIBDIR="/usr/lib/$(DEB_HOST_MULTIARCH)" PIC=1 OPTFLAGS="" LTO=1 +MAKEOPTIONS = V=1 UNAME='$(DEB_HOST_ARCH_OS)' HOST_CPU='$(DEB_HOST_GNU_CPU)' APIDIR=/usr/include/mupen64plus/ DEBUG=1 PREFIX=/usr/ LIBDIR="/usr/lib/$(DEB_HOST_MULTIARCH)" PIC=1 OPTFLAGS="-DNDEBUG" DBG_PACKAGE=$(shell dpkg-parsechangelog|grep '^Source: '|sed 's/^Source:\s*//')-dbg @@ -17,6 +18,12 @@ get-orig-source: $(CURDIR)/debian/get-orig-source.sh +override_dh_auto_test: + # otherwise dh_auto_test fails with debhelper 9.20130624 + +override_dh_auto_clean: + dh_auto_clean -- $(MAKEOPTIONS) + override_dh_auto_build: dh_auto_build -- all $(MAKEOPTIONS) @@ -30,4 +37,4 @@ dh_installchangelogs RELEASE .PHONY: binary binary-arch binary-indep build build-arch build-indep clean install install-arch install-indep \ - get-orig-source override_dh_auto_build override_dh_auto_install override_dh_strip override_dh_installchangelogs + get-orig-source override_dh_auto_clean override_dh_auto_test override_dh_auto_build override_dh_auto_install override_dh_strip override_dh_installchangelogs diff -Nru mupen64plus-rsp-hle-1.99.5/debian/source/include-binaries mupen64plus-rsp-hle-2.0/debian/source/include-binaries --- mupen64plus-rsp-hle-1.99.5/debian/source/include-binaries 1970-01-01 00:00:00.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/debian/source/include-binaries 2013-07-05 20:53:05.000000000 +0000 @@ -0,0 +1 @@ +debian/upstream-signing-key.pgp Binary files /tmp/KLNWCyER63/mupen64plus-rsp-hle-1.99.5/debian/upstream-signing-key.pgp and /tmp/btpRjDtTZX/mupen64plus-rsp-hle-2.0/debian/upstream-signing-key.pgp differ diff -Nru mupen64plus-rsp-hle-1.99.5/debian/watch mupen64plus-rsp-hle-2.0/debian/watch --- mupen64plus-rsp-hle-1.99.5/debian/watch 2012-06-08 22:59:55.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/debian/watch 2013-07-05 20:53:05.000000000 +0000 @@ -1,4 +1,5 @@ version=3 -http://bitbucket.org/richard42/mupen64plus-rsp-hle/downloads/ \ +opts="pgpsigurlmangle=s/$/.asc/" \ + http://bitbucket.org/richard42/mupen64plus-rsp-hle/downloads/ \ /richard42/mupen64plus-rsp-hle/downloads/mupen64plus-rsp-hle-src-(.*).tar.gz diff -Nru mupen64plus-rsp-hle-1.99.5/projects/msvc11/mupen64plus-rsp-hle.vcxproj mupen64plus-rsp-hle-2.0/projects/msvc11/mupen64plus-rsp-hle.vcxproj --- mupen64plus-rsp-hle-1.99.5/projects/msvc11/mupen64plus-rsp-hle.vcxproj 1970-01-01 00:00:00.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/projects/msvc11/mupen64plus-rsp-hle.vcxproj 2013-07-03 14:07:45.000000000 +0000 @@ -0,0 +1,114 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {2EC7CEE3-C7A7-4F2E-B2C8-4DF6AFEC3E9A} + mupen64plusrsphle + Win32Proj + + + + DynamicLibrary + MultiByte + true + v110 + + + DynamicLibrary + MultiByte + v110 + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..\mupen64plus-core\src\api;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;inline=__inline;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + EditAndContinue + Default + + + true + Windows + MachineX86 + + + + + ..\..\..\mupen64plus-core\src\api;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;inline=__inline;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + Default + + + true + Windows + true + true + MachineX86 + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -Nru mupen64plus-rsp-hle-1.99.5/projects/msvc8/mupen64plus-rsp-hle.vcproj mupen64plus-rsp-hle-2.0/projects/msvc8/mupen64plus-rsp-hle.vcproj --- mupen64plus-rsp-hle-1.99.5/projects/msvc8/mupen64plus-rsp-hle.vcproj 2012-03-10 17:54:03.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/projects/msvc8/mupen64plus-rsp-hle.vcproj 2013-07-03 14:07:45.000000000 +0000 @@ -179,7 +179,11 @@ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > + + + + + + + + + + diff -Nru mupen64plus-rsp-hle-1.99.5/projects/unix/Makefile mupen64plus-rsp-hle-2.0/projects/unix/Makefile --- mupen64plus-rsp-hle-1.99.5/projects/unix/Makefile 2012-03-10 17:54:03.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/projects/unix/Makefile 2013-07-03 14:07:45.000000000 +0000 @@ -22,7 +22,7 @@ # Makefile for Mupen64 HLE RSP plugin in Mupen64plus. # detect operating system -UNAME = $(shell uname -s) +UNAME ?= $(shell uname -s) OS := NONE ifeq ("$(UNAME)","Linux") OS = LINUX @@ -60,6 +60,12 @@ SO_EXTENSION = so SHARED = -shared endif +ifeq ("$(patsubst MINGW%,MINGW,$(UNAME))","MINGW") + OS = MINGW + SO_EXTENSION = dll + SHARED = -shared + PIC = 0 +endif ifeq ("$(OS)","NONE") $(error OS type "$(UNAME)" not supported. Please file bug report at 'http://code.google.com/p/mupen64plus/issues') endif @@ -83,7 +89,7 @@ ARCH_DETECTED := 32BITS PIC ?= 0 endif -ifneq ("$(filter ppc powerpc,$(HOST_CPU))","") +ifneq ("$(filter ppc macppc socppc powerpc,$(HOST_CPU))","") CPU := PPC ARCH_DETECTED := 32BITS BIG_ENDIAN := 1 @@ -97,13 +103,22 @@ PIC ?= 1 $(warning Architecture "$(HOST_CPU)" not officially supported.') endif +ifneq ("$(filter arm%,$(HOST_CPU))","") + ifeq ("$(filter arm%b,$(HOST_CPU))","") + CPU := ARM + ARCH_DETECTED := 32BITS + PIC ?= 1 + $(warning Architecture "$(HOST_CPU)" not officially supported.') + endif +endif ifeq ("$(CPU)","NONE") $(error CPU type "$(HOST_CPU)" not supported. Please file bug report at 'http://code.google.com/p/mupen64plus/issues') endif # base CFLAGS, LDLIBS, and LDFLAGS -OPTFLAGS ?= -O3 -CFLAGS += $(OPTFLAGS) -ffast-math -fno-strict-aliasing -fvisibility=hidden -I../../src +OPTFLAGS ?= -O3 -flto +WARNFLAGS ?= -Wall +CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -ffast-math -fno-strict-aliasing -fvisibility=hidden -I../../src CXXFLAGS += -fvisibility-inlines-hidden LDFLAGS += $(SHARED) @@ -111,10 +126,8 @@ # On 32-bit x86 systems we do not want to use -fPIC because we don't have to and it has a big performance penalty on this arch ifeq ($(PIC), 1) CFLAGS += -fPIC - LDFLAGS += -fPIC else CFLAGS += -fno-PIC - LDFLAGS += -fno-PIC endif ifeq ($(BIG_ENDIAN), 1) @@ -127,7 +140,7 @@ $(error Do not use the BITS=32 option with FreeBSD, use -m32 and -m elf_i386) endif CFLAGS += -m32 - LDFLAGS += -m32 -Wl,-m,elf_i386 + LDFLAGS += -Wl,-m,elf_i386 endif # set special flags per-system @@ -136,13 +149,24 @@ LDFLAGS += -Wl,-version-script,$(SRCDIR)/rsp_api_export.ver endif ifeq ($(OS), OSX) + # Select the proper SDK + # Also, SDKs are stored in a different location since XCode 4.3 + OSX_SDK ?= $(shell sw_vers -productVersion | cut -f1 -f2 -d .) + OSX_XCODEMAJ = $(shell xcodebuild -version | grep '[0-9]*\.[0-9]*' | cut -f2 -d ' ' | cut -f1 -d .) + OSX_XCODEMIN = $(shell xcodebuild -version | grep '[0-9]*\.[0-9]*' | cut -f2 -d ' ' | cut -f2 -d .) + OSX_XCODEGE43 = $(shell echo "`expr $(OSX_XCODEMAJ) \>= 4``expr $(OSX_XCODEMIN) \>= 3`") + ifeq ($(OSX_XCODEGE43), 11) + OSX_SYSROOT := /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs + else + OSX_SYSROOT := /Developer/SDKs + endif + ifeq ($(CPU), X86) ifeq ($(ARCH_DETECTED), 64BITS) - CFLAGS += -pipe -arch x86_64 -mmacosx-version-min=10.5 -isysroot /Developer/SDKs/MacOSX10.5.sdk - LDFLAGS += -arch x86_64 + CFLAGS += -pipe -arch x86_64 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk else - CFLAGS += -pipe -mmmx -msse -fomit-frame-pointer -arch i686 -mmacosx-version-min=10.5 -isysroot /Developer/SDKs/MacOSX10.5.sdk - LDFLAGS += -arch i686 + CFLAGS += -pipe -mmmx -msse -fomit-frame-pointer -arch i686 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk + LDFLAGS += -read_only_relocs suppress endif endif endif @@ -179,21 +203,23 @@ endif # set base program pointers and flags -CC ?= gcc -CXX ?= g++ +CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ RM ?= rm -f INSTALL ?= install MKDIR ?= mkdir -p COMPILE.c = $(Q_CC)$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c COMPILE.cc = $(Q_CXX)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -LINK.o = $(Q_LD)$(CXX) $(LDFLAGS) $(TARGET_ARCH) +LINK.o = $(Q_LD)$(CXX) $(CXXFLAGS) $(LDFLAGS) $(TARGET_ARCH) # set special flags for given Makefile parameters ifeq ($(DEBUG),1) CFLAGS += -g INSTALL_STRIP_FLAG ?= else - INSTALL_STRIP_FLAG ?= -s + ifneq ($(OS),OSX) + INSTALL_STRIP_FLAG ?= -s + endif endif # set installation options @@ -208,13 +234,14 @@ endif SRCDIR = ../../src -OBJDIR = _obj +OBJDIR = _obj$(POSTFIX) # list of source files to compile SOURCE = \ $(SRCDIR)/main.c \ + $(SRCDIR)/alist.c \ + $(SRCDIR)/cicx105.c \ $(SRCDIR)/jpeg.c \ - $(SRCDIR)/idct.c \ $(SRCDIR)/ucode3.cpp \ $(SRCDIR)/ucode2.cpp \ $(SRCDIR)/ucode1.cpp \ @@ -227,7 +254,7 @@ $(shell $(MKDIR) $(OBJDIRS)) # build targets -TARGET = mupen64plus-rsp-hle.$(SO_EXTENSION) +TARGET = mupen64plus-rsp-hle$(POSTFIX).$(SO_EXTENSION) targets: @echo "Mupen64Plus-rsp-hle makefile. " @@ -240,8 +267,10 @@ @echo " Options:" @echo " BITS=32 == build 32-bit binaries on 64-bit machine" @echo " APIDIR=path == path to find Mupen64Plus Core headers" - @echo " OPTFLAGS=flag == compiler optimization (default: -O3)" + @echo " OPTFLAGS=flag == compiler optimization (default: -O3 -flto)" + @echo " WARNFLAGS=flag == compiler warning levels (default: -Wall)" @echo " PIC=(1|0) == Force enable/disable of position independent code" + @echo " POSTFIX=name == String added to the name of the the build (default: '')" @echo " Install Options:" @echo " PREFIX=path == install/uninstall prefix (default: /usr/local)" @echo " LIBDIR=path == library prefix (default: PREFIX/lib)" @@ -261,7 +290,7 @@ $(RM) "$(DESTDIR)$(PLUGINDIR)/$(TARGET)" clean: - $(RM) -r ./_obj $(TARGET) + $(RM) -r $(OBJDIR) $(TARGET) rebuild: clean all diff -Nru mupen64plus-rsp-hle-1.99.5/src/alist.c mupen64plus-rsp-hle-2.0/src/alist.c --- mupen64plus-rsp-hle-1.99.5/src/alist.c 1970-01-01 00:00:00.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/src/alist.c 2013-07-03 14:07:45.000000000 +0000 @@ -0,0 +1,82 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Mupen64plus-rsp-hle - alist.c * + * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * + * Copyright (C) 2012 Bobby Smiles * + * Copyright (C) 2009 Richard Goedeken * + * Copyright (C) 2002 Hacktarux * + * * + * 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "hle.h" +#include "alist_internal.h" + +// FIXME: this decomposition into 3 ABI is not accurate, +// there are a least 9 or 10 different ABI, each with one or a few revisions +// for a total of almost 16 differents audio ucode. +// +// ABI2 in fact is a mix of at least 7 differents ABI which are mostly compatible +// but not totally, that's why there is a isZeldaABI/isMKABI workaround. +// +extern const acmd_callback_t ABI1[0x10]; +extern const acmd_callback_t ABI2[0x20]; +extern const acmd_callback_t ABI3[0x10]; + +/* local functions */ +static void alist_process(const acmd_callback_t abi[], unsigned int abi_size) +{ + u32 inst1, inst2; + unsigned int acmd; + const OSTask_t * const task = get_task(); + + const unsigned int *alist = (unsigned int*)(rsp.RDRAM + task->data_ptr); + const unsigned int * const alist_end = alist + (task->data_size >> 2); + + while (alist != alist_end) + { + inst1 = *(alist++); + inst2 = *(alist++); + + acmd = inst1 >> 24; + + if (acmd < abi_size) + { + (*abi[acmd])(inst1, inst2); + } + else + { + DebugMessage(M64MSG_WARNING, "Invalid ABI command %u", acmd); + } + } +} + +/* global functions */ +void alist_process_ABI1() +{ + alist_process(ABI1, 0x10); +} + +void alist_process_ABI2() +{ + alist_process(ABI2, 0x20); +} + +void alist_process_ABI3() +{ + alist_process(ABI3, 0x10); +} + + diff -Nru mupen64plus-rsp-hle-1.99.5/src/alist.h mupen64plus-rsp-hle-2.0/src/alist.h --- mupen64plus-rsp-hle-1.99.5/src/alist.h 1970-01-01 00:00:00.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/src/alist.h 2013-07-03 14:07:45.000000000 +0000 @@ -0,0 +1,33 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Mupen64plus-rsp-hle - alist.h * + * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * + * Copyright (C) 2002 Hacktarux * + * * + * 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef ALIST_H +#define ALIST_H + +void alist_process_ABI1(); +void alist_process_ABI2(); +void alist_process_ABI3(); + +// FIXME: to remove when isZeldaABI/isMKABI workaround is gone +void init_ucode2(); + +#endif + diff -Nru mupen64plus-rsp-hle-1.99.5/src/alist_internal.h mupen64plus-rsp-hle-2.0/src/alist_internal.h --- mupen64plus-rsp-hle-1.99.5/src/alist_internal.h 1970-01-01 00:00:00.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/src/alist_internal.h 2013-07-03 14:07:45.000000000 +0000 @@ -0,0 +1,50 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Mupen64plus-rsp-hle - alist_internal.h * + * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * + * Copyright (C) 2002 Hacktarux * + * * + * 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef ALIST_INTERNAL_H +#define ALIST_INTERNAL_H + +#include "hle.h" + +typedef void (*acmd_callback_t)(u32 inst1, u32 inst2); + +/* + * Audio flags + */ + +#define A_INIT 0x01 +#define A_CONTINUE 0x00 +#define A_LOOP 0x02 +#define A_OUT 0x02 +#define A_LEFT 0x02 +#define A_RIGHT 0x00 +#define A_VOL 0x04 +#define A_RATE 0x00 +#define A_AUX 0x08 +#define A_NOAUX 0x00 +#define A_MAIN 0x00 +#define A_MIX 0x10 + +extern u16 AudioInBuffer, AudioOutBuffer, AudioCount; +extern u16 AudioAuxA, AudioAuxC, AudioAuxE; +extern u32 loopval; // Value set by A_SETLOOP : Possible conflict with SETVOLUME??? + +#endif diff -Nru mupen64plus-rsp-hle-1.99.5/src/cicx105.c mupen64plus-rsp-hle-2.0/src/cicx105.c --- mupen64plus-rsp-hle-1.99.5/src/cicx105.c 1970-01-01 00:00:00.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/src/cicx105.c 2013-07-03 14:07:45.000000000 +0000 @@ -0,0 +1,55 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Mupen64plus-rsp-hle - cicx105.c * + * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * + * Copyright (C) 2012 Bobby Smiles * + * Copyright (C) 2009 Richard Goedeken * + * Copyright (C) 2002 Hacktarux * + * * + * 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include + +#include "hle.h" + +/** + * During IPL3 stage of CIC x105 games, the RSP performs some checks and transactions + * necessary for booting the game. + * + * We only implement the needed DMA transactions for booting. + * + * Found in Banjo-Tooie, Zelda, Perfect Dark, ...) + **/ +void cicx105_ucode() +{ + // memcpy is okay to use because access constrains are met (alignment, size) + unsigned int i; + unsigned char * dst = rsp.RDRAM + 0x2fb1f0; + unsigned char * src = rsp.IMEM + 0x120; + + /* dma_read(0x1120, 0x1e8, 0x1e8) */ + memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1f0); + + /* dma_write(0x1120, 0x2fb1f0, 0xfe817000) */ + for (i = 0; i < 24; ++i) + { + memcpy(dst, src, 8); + dst += 0xff0; + src += 0x8; + + } +} + diff -Nru mupen64plus-rsp-hle-1.99.5/src/cicx105.h mupen64plus-rsp-hle-2.0/src/cicx105.h --- mupen64plus-rsp-hle-1.99.5/src/cicx105.h 1970-01-01 00:00:00.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/src/cicx105.h 2013-07-03 14:07:45.000000000 +0000 @@ -0,0 +1,28 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Mupen64plus-rsp-hle - cicx105.h * + * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * + * Copyright (C) 2002 Hacktarux * + * * + * 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef CICX105_H +#define CICX105_H + +void cicx105_ucode(); + +#endif + diff -Nru mupen64plus-rsp-hle-1.99.5/src/hle.h mupen64plus-rsp-hle-2.0/src/hle.h --- mupen64plus-rsp-hle-1.99.5/src/hle.h 2012-03-10 17:54:03.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/src/hle.h 2013-07-03 14:07:45.000000000 +0000 @@ -25,7 +25,7 @@ #define M64P_PLUGIN_PROTOTYPES 1 #include "m64p_plugin.h" -#define RSP_HLE_VERSION 0x016305 +#define RSP_HLE_VERSION 0x020000 #define RSP_PLUGIN_API_VERSION 0x020000 #ifdef M64P_BIG_ENDIAN @@ -49,24 +49,6 @@ typedef signed int s32; typedef signed long long s64; -//#define ACMD_SIZE 32 -/* - * Audio flags - */ - -#define A_INIT 0x01 -#define A_CONTINUE 0x00 -#define A_LOOP 0x02 -#define A_OUT 0x02 -#define A_LEFT 0x02 -#define A_RIGHT 0x00 -#define A_VOL 0x04 -#define A_RATE 0x00 -#define A_AUX 0x08 -#define A_NOAUX 0x00 -#define A_MAIN 0x00 -#define A_MIX 0x10 - extern RSP_INFO rsp; typedef struct @@ -96,23 +78,12 @@ unsigned int yield_data_size; } OSTask_t; -void DebugMessage(int level, const char *message, ...); - -void idct(short *iblock, short *oblock); +static inline const OSTask_t * const get_task() +{ + return (OSTask_t*)(rsp.DMEM + 0xfc0); +} -void ps_jpg_uncompress(OSTask_t *task); -void ob_jpg_uncompress(OSTask_t *task); -/*void ucode1(OSTask_t *task); -void ucode2(OSTask_t *task); -void ucode3(OSTask_t *task); -void init_ucode1();*/ -void init_ucode2(); - -extern u32 inst1, inst2; -extern u16 AudioInBuffer, AudioOutBuffer, AudioCount; -extern u16 AudioAuxA, AudioAuxC, AudioAuxE; -extern u32 loopval; // Value set by A_SETLOOP : Possible conflict with SETVOLUME??? -//extern u32 UCData, UDataLen; +void DebugMessage(int level, const char *message, ...); #endif diff -Nru mupen64plus-rsp-hle-1.99.5/src/idct.c mupen64plus-rsp-hle-2.0/src/idct.c --- mupen64plus-rsp-hle-1.99.5/src/idct.c 2012-03-10 17:54:03.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/src/idct.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Mupen64plus-rsp-hle - idct.c * - * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * - * Copyright (C) 2012 Bobby Smiles * - * * - * 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., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/** - * Fast 2D IDCT using separable formulation and normalization - * Computations use single precision floats - * Implementation based on Wikipedia : - * http://fr.wikipedia.org/wiki/Transform%C3%A9e_en_cosinus_discr%C3%A8te - **/ - -// Normalized to C4 = 1 -#define C3 1.175875602f -#define C6 0.541196100f - -#define K1 0.765366865f // C2-C6 -#define K2 -1.847759065f // -C2-C6 -#define K3 -0.390180644f // C5-C3 -#define K4 -1.961570561f // -C5-C3 -#define K5 1.501321110f // C1+C3-C5-C7 -#define K6 2.053119869f // C1+C3-C5+C7 -#define K7 3.072711027f // C1+C3+C5-C7 -#define K8 0.298631336f // -C1+C3+C5-C7 -#define K9 -0.899976223f // C7-C3 -#define K10 -2.562915448f // -C1-C3 - - -static void idct_1d(float *x, float *dst, unsigned every) -{ - float e[4]; - float f[4]; - float x26, x1357, x15, x37, x17, x35; - - x15 = K3 * (x[1] + x[5]); - x37 = K4 * (x[3] + x[7]); - x17 = K9 * (x[1] + x[7]); - x35 = K10 * (x[3] + x[5]); - x1357 = C3 * (x[1] + x[3] + x[5] + x[7]); - x26 = C6 * (x[2] + x[6]); - - f[0] = x[0] + x[4]; - f[1] = x[0] - x[4]; - f[2] = x26 + K1*x[2]; - f[3] = x26 + K2*x[6]; - - e[0] = x1357 + x15 + K5*x[1] + x17; - e[1] = x1357 + x37 + K7*x[3] + x35; - e[2] = x1357 + x15 + K6*x[5] + x35; - e[3] = x1357 + x37 + K8*x[7] + x17; - - *dst = f[0] + f[2] + e[0]; dst += every; - *dst = f[1] + f[3] + e[1]; dst += every; - *dst = f[1] - f[3] + e[2]; dst += every; - *dst = f[0] - f[2] + e[3]; dst += every; - *dst = f[0] - f[2] - e[3]; dst += every; - *dst = f[1] - f[3] - e[2]; dst += every; - *dst = f[1] + f[3] - e[1]; dst += every; - *dst = f[0] + f[2] - e[0]; dst += every; -} - - -void idct(short *iblock, short *oblock) -{ - float x[8]; - float tblock[64]; // temporary block - - unsigned i = 0; - unsigned j = 0; - - // idct 1d on rows (+transposition) - for(i=0; i<8; i++) { - for(j=0; j < 8; j++) { - x[j] = (float)iblock[i*8+j]; - } - - idct_1d(&x[0], &tblock[i], 8); - } - - // idct 1d on columns (thanks to previous transposition) - for(i=0; i<8; i++) { - idct_1d(&tblock[i*8], &x[0], 1); - - // c4 = 1 normalization implies a division by 8 - for(j=0; j < 8; j++) { - oblock[i+j*8] = (short)x[j] >> 3; - } - } -} - diff -Nru mupen64plus-rsp-hle-1.99.5/src/jpeg.c mupen64plus-rsp-hle-2.0/src/jpeg.c --- mupen64plus-rsp-hle-1.99.5/src/jpeg.c 2012-03-10 17:54:03.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/src/jpeg.c 2013-07-03 14:07:45.000000000 +0000 @@ -21,17 +21,65 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include +#include #include -#include +#include #define M64P_PLUGIN_PROTOTYPES 1 #include "m64p_types.h" #include "m64p_plugin.h" #include "hle.h" -// transposed JPEG QTable -static unsigned QTable_T[64] = +#define SUBBLOCK_SIZE 64 + +typedef void (*tile_line_emitter_t)(const int16_t *y, const int16_t *u, uint32_t address); +typedef void (*std_macroblock_decoder_t)(int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE]); + +/* rdram operations */ +// FIXME: these functions deserve their own module +static void rdram_read_many_u16(uint16_t *dst, uint32_t address, unsigned int count); +static void rdram_write_many_u16(const uint16_t *src, uint32_t address, unsigned int count); +static uint32_t rdram_read_u32(uint32_t address); +static void rdram_write_many_u32(const uint32_t *src, uint32_t address, unsigned int count); + +/* standard jpeg ucode decoder */ +static void jpeg_decode_std(const char * const version, const std_macroblock_decoder_t decode_mb, const tile_line_emitter_t emit_line); + +/* helper functions */ +static uint8_t clamp_u8(int16_t x); +static int16_t clamp_s12(int16_t x); +static int16_t clamp_s16(int32_t x); +static uint16_t clamp_RGBA_component(int16_t x); + +/* pixel conversion & foratting */ +static uint32_t GetUYVY(int16_t y1, int16_t y2, int16_t u, int16_t v); +static uint16_t GetRGBA(int16_t y, int16_t u, int16_t v); + +/* tile line emitters */ +static void EmitYUVTileLine(const int16_t *y, const int16_t *u, uint32_t address); +static void EmitRGBATileLine(const int16_t *y, const int16_t *u, uint32_t address); + +/* macroblocks operations */ +static void DecodeMacroblock1(int16_t *macroblock, int32_t *y_dc, int32_t *u_dc, int32_t *v_dc, const int16_t *qtable); +static void DecodeMacroblock2(int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE]); +static void DecodeMacroblock3(int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE]); +static void EmitTilesMode0(const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address); +static void EmitTilesMode2(const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address); + +/* subblocks operations */ +static void TransposeSubBlock(int16_t *dst, const int16_t *src); +static void ZigZagSubBlock(int16_t *dst, const int16_t *src); +static void ReorderSubBlock(int16_t *dst, const int16_t *src, const unsigned int *table); +static void MultSubBlocks(int16_t *dst, const int16_t *src1, const int16_t *src2, unsigned int shift); +static void ScaleSubBlock(int16_t *dst, const int16_t *src, int16_t scale); +static void RShiftSubBlock(int16_t *dst, const int16_t *src, unsigned int shift); +static void InverseDCT1D(const float * const x, float *dst, unsigned int stride); +static void InverseDCTSubBlock(int16_t *dst, const int16_t *src); +static void RescaleYSubBlock(int16_t *dst, const int16_t *src); +static void RescaleUVSubBlock(int16_t *dst, const int16_t *src); + +/* transposed dequantization table */ +static const int16_t DEFAULT_QTABLE[SUBBLOCK_SIZE] = { 16, 12, 14, 14, 18, 24, 49, 72, 11, 12, 13, 17, 22, 35, 64, 92, @@ -43,8 +91,8 @@ 61, 55, 56, 62, 77, 92, 101, 99 }; -// ZigZag indices -static unsigned ZigZag[64] = +/* zig-zag indices */ +static const unsigned int ZIGZAG_TABLE[SUBBLOCK_SIZE] = { 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, @@ -56,8 +104,8 @@ 35, 36, 48, 49, 57, 58, 62, 63 }; -// Lazy way of transposing a block -static unsigned Transpose[64] = +/* transposition indices */ +static const unsigned int TRANSPOSE_TABLE[SUBBLOCK_SIZE] = { 0, 8, 16, 24, 32, 40, 48, 56, 1, 9, 17, 25, 33, 41, 49, 57, @@ -69,372 +117,567 @@ 7, 15, 23, 31, 39, 47, 55, 63 }; -static const unsigned char clamp(short x) + + +/* IDCT related constants + * Cn = alpha * cos(n * PI / 16) (alpha is chosen such as C4 = 1) */ +static const float IDCT_C3 = 1.175875602f; +static const float IDCT_C6 = 0.541196100f; +static const float IDCT_K[10] = { - return (x & (0xff00)) ? ((-x) >> 15) & 0xff : x; -} + 0.765366865f, /* C2-C6 */ + -1.847759065f, /* -C2-C6 */ + -0.390180644f, /* C5-C3 */ + -1.961570561f, /* -C5-C3 */ + 1.501321110f, /* C1+C3-C5-C7 */ + 2.053119869f, /* C1+C3-C5+C7 */ + 3.072711027f, /* C1+C3+C5-C7 */ + 0.298631336f, /* -C1+C3+C5-C7 */ + -0.899976223f, /* C7-C3 */ + -2.562915448f /* -C1-C3 */ +}; + -static short saturate(int x) +/* global functions */ + +/*************************************************************************** + * JPEG decoding ucode found in Japanese exclusive version of Pokemon Stadium. + **************************************************************************/ +void jpeg_decode_PS0() { - if (x > 32767) { x = 32767; } else if (x < -32768) { x = -32768; } - return x; + jpeg_decode_std("PS0", DecodeMacroblock3, EmitYUVTileLine); } +/*************************************************************************** + * JPEG decoding ucode found in Ocarina of Time, Pokemon Stadium 1 and + * Pokemon Stadium 2. + **************************************************************************/ +void jpeg_decode_PS() +{ + jpeg_decode_std("PS", DecodeMacroblock2, EmitRGBATileLine); +} -void ob_jpg_uncompress(OSTask_t *task) +/*************************************************************************** + * JPEG decoding ucode found in Ogre Battle and Bottom of the 9th. + **************************************************************************/ +void jpeg_decode_OB() { - // Fetch arguments - unsigned pBuffer = task->data_ptr; - unsigned nMacroBlocks = task->data_size; - signed QScale = task->yield_data_size; - - // Rescale QTable if needed - unsigned i; - unsigned qtable[64]; - unsigned mb; - - int y_dc = 0; - int u_dc = 0; - int v_dc = 0; - - DebugMessage(M64MSG_VERBOSE, "OB Task: *buffer=%x, #MB=%d, Qscale=%d\n", pBuffer, nMacroBlocks, QScale); - - if (QScale != 0) { - if (QScale > 0) { - for(i = 0; i < 64; i++) { - unsigned q = QTable_T[i] * QScale; - if (q > 32767) q = 32767; - qtable[i] = q; - } + int16_t qtable[SUBBLOCK_SIZE]; + unsigned int mb; + + int32_t y_dc = 0; + int32_t u_dc = 0; + int32_t v_dc = 0; + + const OSTask_t * const task = get_task(); + + uint32_t address = task->data_ptr; + const unsigned int macroblock_count = task->data_size; + const int qscale = task->yield_data_size; + + DebugMessage(M64MSG_VERBOSE, "jpeg_decode_OB: *buffer=%x, #MB=%d, qscale=%d", + address, + macroblock_count, + qscale); + + if (qscale != 0) + { + if (qscale > 0) + { + ScaleSubBlock(qtable, DEFAULT_QTABLE, qscale); } - else { - unsigned Shift = -QScale; - for(i = 0; i < 64; i++) { - qtable[i] = QTable_T[i] >> Shift; - } + else + { + RShiftSubBlock(qtable, DEFAULT_QTABLE, -qscale); } } - // foreach MB - for(mb=0; mb < nMacroBlocks; mb++) { - unsigned sb; - short macroblock[2][0x300/2]; - unsigned y_offset = 0; - - // load MB into short_buffer - unsigned offset = pBuffer + 0x300*mb; - for(i = 0; i < 0x300/2; i++) { - unsigned short s = rsp.RDRAM[(offset+0)^S8]; - s <<= 8; - s += rsp.RDRAM[(offset+1)^S8]; - macroblock[0][i] = s; - offset += 2; - } + for (mb = 0; mb < macroblock_count; ++mb) + { + int16_t macroblock[6*SUBBLOCK_SIZE]; - // foreach SB - for(sb = 0; sb < 6; sb++) { + rdram_read_many_u16((uint16_t*)macroblock, address, 6*SUBBLOCK_SIZE); + DecodeMacroblock1(macroblock, &y_dc, &u_dc, &v_dc, (qscale != 0) ? qtable : NULL); + EmitTilesMode2(EmitYUVTileLine, macroblock, address); - // apply delta to DC - int dc = (signed)macroblock[0][sb*0x40]; - switch(sb) { - case 0: case 1: case 2: case 3: y_dc += dc; macroblock[1][sb*0x40] = y_dc & 0xffff; break; - case 4: u_dc += dc; macroblock[1][sb*0x40] = u_dc & 0xffff; break; - case 5: v_dc += dc; macroblock[1][sb*0x40] = v_dc & 0xffff; break; - } - - // zigzag reordering - for(i = 1; i < 64; i++) { - macroblock[1][sb*0x40+i] = macroblock[0][sb*0x40+ZigZag[i]]; - } - - // Apply Dequantization - if (QScale != 0) { - for(i = 0; i < 64; i++) { - int v = macroblock[1][sb*0x40+i] * qtable[i]; - macroblock[1][sb*0x40+i] = saturate(v); - } - } - - // Transpose - for(i = 0; i < 64; i++) { - macroblock[0][sb*0x40+i] = macroblock[1][sb*0x40+Transpose[i]]; - } - - // Apply Invert Discrete Cosinus Transform - idct(¯oblock[0][sb*0x40], ¯oblock[1][sb*0x40]); - - // Clamp values between [0..255] - for(i = 0; i < 64; i++) { - macroblock[0][sb*0x40+i] = clamp(macroblock[1][sb*0x40+i]); - } - } + address += (2*6*SUBBLOCK_SIZE); + } +} + + +/* local functions */ +static void jpeg_decode_std(const char * const version, const std_macroblock_decoder_t decode_mb, const tile_line_emitter_t emit_line) +{ + int16_t qtables[3][SUBBLOCK_SIZE]; + unsigned int mb; + uint32_t address; + uint32_t macroblock_count; + uint32_t mode; + uint32_t qtableY_ptr; + uint32_t qtableU_ptr; + uint32_t qtableV_ptr; + unsigned int subblock_count; + unsigned int macroblock_size; + int16_t *macroblock; + const OSTask_t * const task = get_task(); + + if (task->flags & 0x1) + { + DebugMessage(M64MSG_WARNING, "jpeg_decode_%s: task yielding not implemented", version); + return; + } + + address = rdram_read_u32(task->data_ptr); + macroblock_count = rdram_read_u32(task->data_ptr + 4); + mode = rdram_read_u32(task->data_ptr + 8); + qtableY_ptr = rdram_read_u32(task->data_ptr + 12); + qtableU_ptr = rdram_read_u32(task->data_ptr + 16); + qtableV_ptr = rdram_read_u32(task->data_ptr + 20); + + DebugMessage(M64MSG_VERBOSE, "jpeg_decode_%s: *buffer=%x, #MB=%d, mode=%d, *Qy=%x, *Qu=%x, *Qv=%x", + version, + address, + macroblock_count, + mode, + qtableY_ptr, + qtableU_ptr, + qtableV_ptr); + + if (mode != 0 && mode != 2) + { + DebugMessage(M64MSG_WARNING, "jpeg_decode_%s: invalid mode %d", version, mode); + return; + } + + subblock_count = mode + 4; + macroblock_size = 2*subblock_count*SUBBLOCK_SIZE; + + rdram_read_many_u16((uint16_t*)qtables[0], qtableY_ptr, SUBBLOCK_SIZE); + rdram_read_many_u16((uint16_t*)qtables[1], qtableU_ptr, SUBBLOCK_SIZE); + rdram_read_many_u16((uint16_t*)qtables[2], qtableV_ptr, SUBBLOCK_SIZE); + + macroblock = malloc(sizeof(*macroblock) * macroblock_size); + if (!macroblock) + { + DebugMessage(M64MSG_WARNING, "jpeg_decode_%s: could not allocate macroblock", version); + return; + } - // Texel Formatting - offset = pBuffer + 0x300*mb; - for(i = 0; i < 8; i++) { - // U - rsp.RDRAM[(offset+0x00)^S8] = (unsigned char)macroblock[0][(0x200 + i*0x10)/2]; - rsp.RDRAM[(offset+0x04)^S8] = (unsigned char)macroblock[0][(0x202 + i*0x10)/2]; - rsp.RDRAM[(offset+0x08)^S8] = (unsigned char)macroblock[0][(0x204 + i*0x10)/2]; - rsp.RDRAM[(offset+0x0c)^S8] = (unsigned char)macroblock[0][(0x206 + i*0x10)/2]; - rsp.RDRAM[(offset+0x10)^S8] = (unsigned char)macroblock[0][(0x208 + i*0x10)/2]; - rsp.RDRAM[(offset+0x14)^S8] = (unsigned char)macroblock[0][(0x20a + i*0x10)/2]; - rsp.RDRAM[(offset+0x18)^S8] = (unsigned char)macroblock[0][(0x20c + i*0x10)/2]; - rsp.RDRAM[(offset+0x1c)^S8] = (unsigned char)macroblock[0][(0x20e + i*0x10)/2]; - rsp.RDRAM[(offset+0x20)^S8] = (unsigned char)macroblock[0][(0x200 + i*0x10)/2]; - rsp.RDRAM[(offset+0x24)^S8] = (unsigned char)macroblock[0][(0x202 + i*0x10)/2]; - rsp.RDRAM[(offset+0x28)^S8] = (unsigned char)macroblock[0][(0x204 + i*0x10)/2]; - rsp.RDRAM[(offset+0x2c)^S8] = (unsigned char)macroblock[0][(0x206 + i*0x10)/2]; - rsp.RDRAM[(offset+0x30)^S8] = (unsigned char)macroblock[0][(0x208 + i*0x10)/2]; - rsp.RDRAM[(offset+0x34)^S8] = (unsigned char)macroblock[0][(0x20a + i*0x10)/2]; - rsp.RDRAM[(offset+0x38)^S8] = (unsigned char)macroblock[0][(0x20c + i*0x10)/2]; - rsp.RDRAM[(offset+0x3c)^S8] = (unsigned char)macroblock[0][(0x20e + i*0x10)/2]; - - // V - rsp.RDRAM[(offset+0x02)^S8] = (unsigned char)macroblock[0][(0x280 + i*0x10)/2]; - rsp.RDRAM[(offset+0x06)^S8] = (unsigned char)macroblock[0][(0x282 + i*0x10)/2]; - rsp.RDRAM[(offset+0x0a)^S8] = (unsigned char)macroblock[0][(0x284 + i*0x10)/2]; - rsp.RDRAM[(offset+0x0e)^S8] = (unsigned char)macroblock[0][(0x286 + i*0x10)/2]; - rsp.RDRAM[(offset+0x12)^S8] = (unsigned char)macroblock[0][(0x288 + i*0x10)/2]; - rsp.RDRAM[(offset+0x16)^S8] = (unsigned char)macroblock[0][(0x28a + i*0x10)/2]; - rsp.RDRAM[(offset+0x1a)^S8] = (unsigned char)macroblock[0][(0x28c + i*0x10)/2]; - rsp.RDRAM[(offset+0x1e)^S8] = (unsigned char)macroblock[0][(0x28e + i*0x10)/2]; - rsp.RDRAM[(offset+0x22)^S8] = (unsigned char)macroblock[0][(0x280 + i*0x10)/2]; - rsp.RDRAM[(offset+0x26)^S8] = (unsigned char)macroblock[0][(0x282 + i*0x10)/2]; - rsp.RDRAM[(offset+0x2a)^S8] = (unsigned char)macroblock[0][(0x284 + i*0x10)/2]; - rsp.RDRAM[(offset+0x2e)^S8] = (unsigned char)macroblock[0][(0x286 + i*0x10)/2]; - rsp.RDRAM[(offset+0x32)^S8] = (unsigned char)macroblock[0][(0x288 + i*0x10)/2]; - rsp.RDRAM[(offset+0x36)^S8] = (unsigned char)macroblock[0][(0x28a + i*0x10)/2]; - rsp.RDRAM[(offset+0x3a)^S8] = (unsigned char)macroblock[0][(0x28c + i*0x10)/2]; - rsp.RDRAM[(offset+0x3e)^S8] = (unsigned char)macroblock[0][(0x28e + i*0x10)/2]; - - // Ya/Yb - rsp.RDRAM[(offset+0x01)^S8] = (unsigned char)macroblock[0][(y_offset + 0x00)/2]; - rsp.RDRAM[(offset+0x03)^S8] = (unsigned char)macroblock[0][(y_offset + 0x02)/2]; - rsp.RDRAM[(offset+0x05)^S8] = (unsigned char)macroblock[0][(y_offset + 0x04)/2]; - rsp.RDRAM[(offset+0x07)^S8] = (unsigned char)macroblock[0][(y_offset + 0x06)/2]; - rsp.RDRAM[(offset+0x09)^S8] = (unsigned char)macroblock[0][(y_offset + 0x08)/2]; - rsp.RDRAM[(offset+0x0b)^S8] = (unsigned char)macroblock[0][(y_offset + 0x0a)/2]; - rsp.RDRAM[(offset+0x0d)^S8] = (unsigned char)macroblock[0][(y_offset + 0x0c)/2]; - rsp.RDRAM[(offset+0x0f)^S8] = (unsigned char)macroblock[0][(y_offset + 0x0e)/2]; - rsp.RDRAM[(offset+0x21)^S8] = (unsigned char)macroblock[0][(y_offset + 0x10)/2]; - rsp.RDRAM[(offset+0x23)^S8] = (unsigned char)macroblock[0][(y_offset + 0x12)/2]; - rsp.RDRAM[(offset+0x25)^S8] = (unsigned char)macroblock[0][(y_offset + 0x14)/2]; - rsp.RDRAM[(offset+0x27)^S8] = (unsigned char)macroblock[0][(y_offset + 0x16)/2]; - rsp.RDRAM[(offset+0x29)^S8] = (unsigned char)macroblock[0][(y_offset + 0x18)/2]; - rsp.RDRAM[(offset+0x2b)^S8] = (unsigned char)macroblock[0][(y_offset + 0x1a)/2]; - rsp.RDRAM[(offset+0x2d)^S8] = (unsigned char)macroblock[0][(y_offset + 0x1c)/2]; - rsp.RDRAM[(offset+0x2f)^S8] = (unsigned char)macroblock[0][(y_offset + 0x1e)/2]; - - // Ya+1/Yb+1 - rsp.RDRAM[(offset+0x11)^S8] = (unsigned char)macroblock[0][(y_offset + 0x80)/2]; - rsp.RDRAM[(offset+0x13)^S8] = (unsigned char)macroblock[0][(y_offset + 0x82)/2]; - rsp.RDRAM[(offset+0x15)^S8] = (unsigned char)macroblock[0][(y_offset + 0x84)/2]; - rsp.RDRAM[(offset+0x17)^S8] = (unsigned char)macroblock[0][(y_offset + 0x86)/2]; - rsp.RDRAM[(offset+0x19)^S8] = (unsigned char)macroblock[0][(y_offset + 0x88)/2]; - rsp.RDRAM[(offset+0x1b)^S8] = (unsigned char)macroblock[0][(y_offset + 0x8a)/2]; - rsp.RDRAM[(offset+0x1d)^S8] = (unsigned char)macroblock[0][(y_offset + 0x8c)/2]; - rsp.RDRAM[(offset+0x1f)^S8] = (unsigned char)macroblock[0][(y_offset + 0x8e)/2]; - rsp.RDRAM[(offset+0x31)^S8] = (unsigned char)macroblock[0][(y_offset + 0x90)/2]; - rsp.RDRAM[(offset+0x33)^S8] = (unsigned char)macroblock[0][(y_offset + 0x92)/2]; - rsp.RDRAM[(offset+0x35)^S8] = (unsigned char)macroblock[0][(y_offset + 0x94)/2]; - rsp.RDRAM[(offset+0x37)^S8] = (unsigned char)macroblock[0][(y_offset + 0x96)/2]; - rsp.RDRAM[(offset+0x39)^S8] = (unsigned char)macroblock[0][(y_offset + 0x98)/2]; - rsp.RDRAM[(offset+0x3b)^S8] = (unsigned char)macroblock[0][(y_offset + 0x9a)/2]; - rsp.RDRAM[(offset+0x3d)^S8] = (unsigned char)macroblock[0][(y_offset + 0x9c)/2]; - rsp.RDRAM[(offset+0x3f)^S8] = (unsigned char)macroblock[0][(y_offset + 0x9e)/2]; + for (mb = 0; mb < macroblock_count; ++mb) + { + rdram_read_many_u16((uint16_t*)macroblock, address, macroblock_size >> 1); + decode_mb(macroblock, subblock_count, (const int16_t (*)[SUBBLOCK_SIZE])qtables); - offset += 0x40; - y_offset += (i == 3) ? 0xa0 : 0x20; + if (mode == 0) + { + EmitTilesMode0(emit_line, macroblock, address); + } + else + { + EmitTilesMode2(emit_line, macroblock, address); } + + address += macroblock_size; } + free(macroblock); } +static uint8_t clamp_u8(int16_t x) +{ + return (x & (0xff00)) ? ((-x) >> 15) & 0xff : x; +} + +static int16_t clamp_s12(int16_t x) +{ + if (x < -0x800) { x = -0x800; } else if (x > 0x7f0) { x = 0x7f0; } + return x; +} +static int16_t clamp_s16(int32_t x) +{ + if (x > 32767) { x = 32767; } else if (x < -32768) { x = -32768; } + return x; +} -static short yuv2rgba16_clamp(short x) +static uint16_t clamp_RGBA_component(int16_t x) { if (x > 0xff0) { x = 0xff0; } else if (x < 0) { x = 0; } return (x & 0xf80); } - -static unsigned short yuv2rgba16(float y, float u, float v) +static uint32_t GetUYVY(int16_t y1, int16_t y2, int16_t u, int16_t v) { - unsigned short r, g, b; + return (uint32_t)clamp_u8(u) << 24 + | (uint32_t)clamp_u8(y1) << 16 + | (uint32_t)clamp_u8(v) << 8 + | (uint32_t)clamp_u8(y2); +} - r = yuv2rgba16_clamp((short)(y + 1.4025*v)); - g = yuv2rgba16_clamp((short)(y - 0.3443*u - 0.7144*v)); - b = yuv2rgba16_clamp((short)(y + 1.7729*u )); +static uint16_t GetRGBA(int16_t y, int16_t u, int16_t v) +{ + const float fY = (float)y + 2048.0f; + const float fU = (float)u; + const float fV = (float)v; + + const uint16_t r = clamp_RGBA_component((int16_t)(fY + 1.4025*fV)); + const uint16_t g = clamp_RGBA_component((int16_t)(fY - 0.3443*fU - 0.7144*fV)); + const uint16_t b = clamp_RGBA_component((int16_t)(fY + 1.7729*fU )); return (r << 4) | (g >> 1) | (b >> 6) | 1; } +static void EmitYUVTileLine(const int16_t *y, const int16_t *u, uint32_t address) +{ + uint32_t uyvy[8]; + + const int16_t * const v = u + SUBBLOCK_SIZE; + const int16_t * const y2 = y + SUBBLOCK_SIZE; + + uyvy[0] = GetUYVY(y[0], y[1], u[0], v[0]); + uyvy[1] = GetUYVY(y[2], y[3], u[1], v[1]); + uyvy[2] = GetUYVY(y[4], y[5], u[2], v[2]); + uyvy[3] = GetUYVY(y[6], y[7], u[3], v[3]); + uyvy[4] = GetUYVY(y2[0], y2[1], u[4], v[4]); + uyvy[5] = GetUYVY(y2[2], y2[3], u[5], v[5]); + uyvy[6] = GetUYVY(y2[4], y2[5], u[6], v[6]); + uyvy[7] = GetUYVY(y2[6], y2[7], u[7], v[7]); + + rdram_write_many_u32(uyvy, address, 8); +} + +static void EmitRGBATileLine(const int16_t *y, const int16_t *u, uint32_t address) +{ + uint16_t rgba[16]; + + const int16_t * const v = u + SUBBLOCK_SIZE; + const int16_t * const y2 = y + SUBBLOCK_SIZE; + + rgba[0] = GetRGBA(y[0], u[0], v[0]); + rgba[1] = GetRGBA(y[1], u[0], v[0]); + rgba[2] = GetRGBA(y[2], u[1], v[1]); + rgba[3] = GetRGBA(y[3], u[1], v[1]); + rgba[4] = GetRGBA(y[4], u[2], v[2]); + rgba[5] = GetRGBA(y[5], u[2], v[2]); + rgba[6] = GetRGBA(y[6], u[3], v[3]); + rgba[7] = GetRGBA(y[7], u[3], v[3]); + rgba[8] = GetRGBA(y2[0], u[4], v[4]); + rgba[9] = GetRGBA(y2[1], u[4], v[4]); + rgba[10] = GetRGBA(y2[2], u[5], v[5]); + rgba[11] = GetRGBA(y2[3], u[5], v[5]); + rgba[12] = GetRGBA(y2[4], u[6], v[6]); + rgba[13] = GetRGBA(y2[5], u[6], v[6]); + rgba[14] = GetRGBA(y2[6], u[7], v[7]); + rgba[15] = GetRGBA(y2[7], u[7], v[7]); + + rdram_write_many_u16(rgba, address, 16); +} -void ps_jpg_uncompress(OSTask_t *task) +static void EmitTilesMode0(const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address) { - unsigned int iMBsize, oMBsize, nSubBlocks, mb; + unsigned int i; - // arguments for pokemon stadium jpg decompression - static struct + unsigned int y_offset = 0; + unsigned int u_offset = 2*SUBBLOCK_SIZE; + + for (i = 0; i < 8; ++i) { - unsigned pMacroBlocks; // address of Macroblocks - unsigned nMacroBlocks; // # of Macroblocks - unsigned mode; // specify subsampling mode (as far as I understand) - unsigned pQTables[3]; // address of QTable for Y,U,V channel - } ps_jpg_data; + emit_line(¯oblock[y_offset], ¯oblock[u_offset], address); + + y_offset += 8; + u_offset += 8; + address += 32; + } +} - short QTables[3][64]; +static void EmitTilesMode2(const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address) +{ + unsigned int i; - unsigned i,j; + unsigned int y_offset = 0; + unsigned int u_offset = 4*SUBBLOCK_SIZE; - // We don't support task yielding - if (task->flags & 0x1) { - DebugMessage(M64MSG_VERBOSE, "ps_jpg_uncompress doesn't support task yielding"); - return; + for (i = 0; i < 8; ++i) + { + emit_line(¯oblock[y_offset], ¯oblock[u_offset], address); + emit_line(¯oblock[y_offset + 8], ¯oblock[u_offset], address + 32); + + y_offset += (i == 3) ? SUBBLOCK_SIZE+16 : 16; + u_offset += 8; + address += 64; } +} - // Fetch arguments - memcpy(&ps_jpg_data, rsp.RDRAM+task->data_ptr, sizeof(ps_jpg_data)); +static void DecodeMacroblock1(int16_t *macroblock, int32_t *y_dc, int32_t *u_dc, int32_t *v_dc, const int16_t *qtable) +{ + int sb; + + for (sb = 0; sb < 6; ++sb) + { + int16_t tmp_sb[SUBBLOCK_SIZE]; - DebugMessage(M64MSG_VERBOSE, "SB Task: *MB=%x, #MB=%d, mode=%d, *Qy=%x, *Qu=%x, Qv=%x", - ps_jpg_data.pMacroBlocks, - ps_jpg_data.nMacroBlocks, - ps_jpg_data.mode, - ps_jpg_data.pQTables[0], - ps_jpg_data.pQTables[1], - ps_jpg_data.pQTables[2]); - - // Setup input & output MB size, and #of subblocks - iMBsize = (ps_jpg_data.mode == 0) ? 0x200 : 0x300; - oMBsize = (ps_jpg_data.mode == 0) ? 0x100 : 0x200; - nSubBlocks = ps_jpg_data.mode + 4; - - // Load QTables - for(j = 0; j < 3; j++) { - for(i = 0; i < 64; i++) { - unsigned short s = rsp.RDRAM[(ps_jpg_data.pQTables[j] + 2*i)^S8]; - s <<= 8; - s |= rsp.RDRAM[(ps_jpg_data.pQTables[j] + 2*i+1)^S8]; - QTables[j][i] = s; + /* update DC */ + int32_t dc = (int32_t)macroblock[0]; + switch(sb) + { + case 0: case 1: case 2: case 3: + *y_dc += dc; macroblock[0] = *y_dc & 0xffff; break; + case 4: *u_dc += dc; macroblock[0] = *u_dc & 0xffff; break; + case 5: *v_dc += dc; macroblock[0] = *v_dc & 0xffff; break; } + + ZigZagSubBlock(tmp_sb, macroblock); + if (qtable != NULL) { MultSubBlocks(tmp_sb, tmp_sb, qtable, 0); } + TransposeSubBlock(macroblock, tmp_sb); + InverseDCTSubBlock(macroblock, macroblock); + + macroblock += SUBBLOCK_SIZE; } +} - // foreach MB - for(mb=0; mb < ps_jpg_data.nMacroBlocks; mb++) { - unsigned sb; - short macroblock[2][0x300/2]; - unsigned int y_offset, u_offset; - - // load MB into short_buffer - unsigned offset = ps_jpg_data.pMacroBlocks + iMBsize*mb; - for(i = 0; i < iMBsize/2; i++) { - unsigned short s = rsp.RDRAM[(offset+0)^S8]; - s <<= 8; - s |= rsp.RDRAM[(offset+1)^S8]; - macroblock[0][i] = s; - offset += 2; - } +static void DecodeMacroblock2(int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE]) +{ + unsigned int sb; + unsigned int q = 0; - // Apply Dequantization (Y subblocks) - for(sb = 0; sb < nSubBlocks-2; sb++) { - for(i = 0; i < 64; i++) { - int v = macroblock[0][sb*0x40+i]*QTables[0][i]; - macroblock[0][sb*0x40+i] = saturate(v) << 4; - } - } + for (sb = 0; sb < subblock_count; ++sb) + { + int16_t tmp_sb[SUBBLOCK_SIZE]; + const int isChromaSubBlock = (subblock_count - sb <= 2); - // Apply Dequantization (U,V subblocks) - for(j = 1; sb < nSubBlocks; sb++, j++) { - for(i = 0; i < 64; i++) { - int v = macroblock[0][sb*0x40+i]*QTables[j][i]; - macroblock[0][sb*0x40+i] = saturate(v) << 4; - } - } + if (isChromaSubBlock) { ++q; } - // foreach SubBlocks - for(sb = 0; sb < nSubBlocks; sb++) { - // ZigZag (transposed) - for(i = 0; i < 64; i++) { - macroblock[1][sb*0x40+i] = macroblock[0][sb*0x40+ZigZag[i]]; - } + MultSubBlocks(macroblock, macroblock, qtables[q], 4); + ZigZagSubBlock(tmp_sb, macroblock); + InverseDCTSubBlock(macroblock, tmp_sb); - // Apply Invert Discrete Cosinus Transform - idct(¯oblock[1][sb*0x40], ¯oblock[0][sb*0x40]); - } + macroblock += SUBBLOCK_SIZE; + } + +} - // Texel Formatting (RGBA16) - offset = ps_jpg_data.pMacroBlocks + oMBsize*mb; - y_offset = 0; - u_offset = oMBsize/2; +static void DecodeMacroblock3(int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE]) +{ + unsigned int sb; + unsigned int q = 0; - if (ps_jpg_data.mode == 0) - { - // I have not encountered this case in Pokemon stadium (but ucode disassembly say so...) + for (sb = 0; sb < subblock_count; ++sb) + { + int16_t tmp_sb[SUBBLOCK_SIZE]; + const int isChromaSubBlock = (subblock_count - sb <= 2); + + if (isChromaSubBlock) { ++q; } + + MultSubBlocks(macroblock, macroblock, qtables[q], 4); + ZigZagSubBlock(tmp_sb, macroblock); + InverseDCTSubBlock(macroblock, tmp_sb); - unsigned short rgba[16]; - for(i = 0; i < 8; i++) { - rgba[0] = yuv2rgba16((float)macroblock[0][y_offset+0]+2048.0f, (float)macroblock[0][u_offset+0], (float)macroblock[0][u_offset+64+0]); - rgba[1] = yuv2rgba16((float)macroblock[0][y_offset+1]+2048.0f, (float)macroblock[0][u_offset+0], (float)macroblock[0][u_offset+64+0]); - rgba[2] = yuv2rgba16((float)macroblock[0][y_offset+2]+2048.0f, (float)macroblock[0][u_offset+1], (float)macroblock[0][u_offset+64+1]); - rgba[3] = yuv2rgba16((float)macroblock[0][y_offset+3]+2048.0f, (float)macroblock[0][u_offset+1], (float)macroblock[0][u_offset+64+1]); - rgba[4] = yuv2rgba16((float)macroblock[0][y_offset+4]+2048.0f, (float)macroblock[0][u_offset+2], (float)macroblock[0][u_offset+64+2]); - rgba[5] = yuv2rgba16((float)macroblock[0][y_offset+5]+2048.0f, (float)macroblock[0][u_offset+2], (float)macroblock[0][u_offset+64+2]); - rgba[6] = yuv2rgba16((float)macroblock[0][y_offset+6]+2048.0f, (float)macroblock[0][u_offset+3], (float)macroblock[0][u_offset+64+3]); - rgba[7] = yuv2rgba16((float)macroblock[0][y_offset+7]+2048.0f, (float)macroblock[0][u_offset+3], (float)macroblock[0][u_offset+64+3]); - - rgba[8] = yuv2rgba16((float)macroblock[0][y_offset+64+0]+2048.0f, (float)macroblock[0][u_offset+4], (float)macroblock[0][u_offset+64+4]); - rgba[9] = yuv2rgba16((float)macroblock[0][y_offset+64+1]+2048.0f, (float)macroblock[0][u_offset+4], (float)macroblock[0][u_offset+64+4]); - rgba[10] = yuv2rgba16((float)macroblock[0][y_offset+64+2]+2048.0f, (float)macroblock[0][u_offset+5], (float)macroblock[0][u_offset+64+5]); - rgba[11] = yuv2rgba16((float)macroblock[0][y_offset+64+3]+2048.0f, (float)macroblock[0][u_offset+5], (float)macroblock[0][u_offset+64+5]); - rgba[12] = yuv2rgba16((float)macroblock[0][y_offset+64+4]+2048.0f, (float)macroblock[0][u_offset+6], (float)macroblock[0][u_offset+64+6]); - rgba[13] = yuv2rgba16((float)macroblock[0][y_offset+64+5]+2048.0f, (float)macroblock[0][u_offset+6], (float)macroblock[0][u_offset+64+6]); - rgba[14] = yuv2rgba16((float)macroblock[0][y_offset+64+6]+2048.0f, (float)macroblock[0][u_offset+7], (float)macroblock[0][u_offset+64+7]); - rgba[15] = yuv2rgba16((float)macroblock[0][y_offset+64+7]+2048.0f, (float)macroblock[0][u_offset+7], (float)macroblock[0][u_offset+64+7]); - - for(j = 0; j < 16; j++) { - rsp.RDRAM[(offset++)^S8] = (unsigned char)(rgba[j] >> 8); - rsp.RDRAM[(offset++)^S8] = (unsigned char)(rgba[j] & 0xff); - } - - y_offset += 8; - u_offset += 8; - } + if (isChromaSubBlock) + { + RescaleUVSubBlock(macroblock, macroblock); } else { - unsigned short rgba[32]; - for(i = 0; i < 8; i++) { - for(j = 0; j < 2; j++) { - rgba[j*16+0] = yuv2rgba16((float)macroblock[0][y_offset+0]+2048.0f, (float)macroblock[0][u_offset+0], (float)macroblock[0][u_offset+64+0]); - rgba[j*16+1] = yuv2rgba16((float)macroblock[0][y_offset+1]+2048.0f, (float)macroblock[0][u_offset+0], (float)macroblock[0][u_offset+64+0]); - rgba[j*16+2] = yuv2rgba16((float)macroblock[0][y_offset+2]+2048.0f, (float)macroblock[0][u_offset+1], (float)macroblock[0][u_offset+64+1]); - rgba[j*16+3] = yuv2rgba16((float)macroblock[0][y_offset+3]+2048.0f, (float)macroblock[0][u_offset+1], (float)macroblock[0][u_offset+64+1]); - rgba[j*16+4] = yuv2rgba16((float)macroblock[0][y_offset+4]+2048.0f, (float)macroblock[0][u_offset+2], (float)macroblock[0][u_offset+64+2]); - rgba[j*16+5] = yuv2rgba16((float)macroblock[0][y_offset+5]+2048.0f, (float)macroblock[0][u_offset+2], (float)macroblock[0][u_offset+64+2]); - rgba[j*16+6] = yuv2rgba16((float)macroblock[0][y_offset+6]+2048.0f, (float)macroblock[0][u_offset+3], (float)macroblock[0][u_offset+64+3]); - rgba[j*16+7] = yuv2rgba16((float)macroblock[0][y_offset+7]+2048.0f, (float)macroblock[0][u_offset+3], (float)macroblock[0][u_offset+64+3]); - - rgba[j*16+8] = yuv2rgba16((float)macroblock[0][y_offset+64+0]+2048.0f, (float)macroblock[0][u_offset+4], (float)macroblock[0][u_offset+64+4]); - rgba[j*16+9] = yuv2rgba16((float)macroblock[0][y_offset+64+1]+2048.0f, (float)macroblock[0][u_offset+4], (float)macroblock[0][u_offset+64+4]); - rgba[j*16+10] = yuv2rgba16((float)macroblock[0][y_offset+64+2]+2048.0f, (float)macroblock[0][u_offset+5], (float)macroblock[0][u_offset+64+5]); - rgba[j*16+11] = yuv2rgba16((float)macroblock[0][y_offset+64+3]+2048.0f, (float)macroblock[0][u_offset+5], (float)macroblock[0][u_offset+64+5]); - rgba[j*16+12] = yuv2rgba16((float)macroblock[0][y_offset+64+4]+2048.0f, (float)macroblock[0][u_offset+6], (float)macroblock[0][u_offset+64+6]); - rgba[j*16+13] = yuv2rgba16((float)macroblock[0][y_offset+64+5]+2048.0f, (float)macroblock[0][u_offset+6], (float)macroblock[0][u_offset+64+6]); - rgba[j*16+14] = yuv2rgba16((float)macroblock[0][y_offset+64+6]+2048.0f, (float)macroblock[0][u_offset+7], (float)macroblock[0][u_offset+64+7]); - rgba[j*16+15] = yuv2rgba16((float)macroblock[0][y_offset+64+7]+2048.0f, (float)macroblock[0][u_offset+7], (float)macroblock[0][u_offset+64+7]); - y_offset += 8; - } - - for(j = 0; j < 32; j++) { - rsp.RDRAM[(offset++)^S8] = (unsigned char)(rgba[j] >> 8); - rsp.RDRAM[(offset++)^S8] = (unsigned char)(rgba[j] & 0xff); - } - - if (i == 3) y_offset += 64; - u_offset += 8; - } + RescaleYSubBlock(macroblock, macroblock); } + + macroblock += SUBBLOCK_SIZE; + } +} + +static void TransposeSubBlock(int16_t *dst, const int16_t *src) +{ + ReorderSubBlock(dst, src, TRANSPOSE_TABLE); +} + +static void ZigZagSubBlock(int16_t *dst, const int16_t *src) +{ + ReorderSubBlock(dst, src, ZIGZAG_TABLE); +} + +static void ReorderSubBlock(int16_t *dst, const int16_t *src, const unsigned int *table) +{ + unsigned int i; + + /* source and destination sublocks cannot overlap */ + assert(abs(dst - src) > SUBBLOCK_SIZE); + + for (i = 0; i < SUBBLOCK_SIZE; ++i) + { + dst[i] = src[table[i]]; + } +} + +static void MultSubBlocks(int16_t *dst, const int16_t *src1, const int16_t *src2, unsigned int shift) +{ + unsigned int i; + + for (i = 0; i < SUBBLOCK_SIZE; ++i) + { + int32_t v = src1[i] * src2[i]; + dst[i] = clamp_s16(v) << shift; + } +} + +static void ScaleSubBlock(int16_t *dst, const int16_t *src, int16_t scale) +{ + unsigned int i; + + for (i = 0; i < SUBBLOCK_SIZE; ++i) + { + int32_t v = src[i] * scale; + dst[i] = clamp_s16(v); + } +} + +static void RShiftSubBlock(int16_t *dst, const int16_t *src, unsigned int shift) +{ + unsigned int i; + + for (i = 0; i < SUBBLOCK_SIZE; ++i) + { + dst[i] = src[i] >> shift; + } +} + +/*************************************************************************** + * Fast 2D IDCT using separable formulation and normalization + * Computations use single precision floats + * Implementation based on Wikipedia : + * http://fr.wikipedia.org/wiki/Transform%C3%A9e_en_cosinus_discr%C3%A8te + **************************************************************************/ +static void InverseDCT1D(const float * const x, float *dst, unsigned int stride) +{ + float e[4]; + float f[4]; + float x26, x1357, x15, x37, x17, x35; + + x15 = IDCT_K[2] * (x[1] + x[5]); + x37 = IDCT_K[3] * (x[3] + x[7]); + x17 = IDCT_K[8] * (x[1] + x[7]); + x35 = IDCT_K[9] * (x[3] + x[5]); + x1357 = IDCT_C3 * (x[1] + x[3] + x[5] + x[7]); + x26 = IDCT_C6 * (x[2] + x[6]); + + f[0] = x[0] + x[4]; + f[1] = x[0] - x[4]; + f[2] = x26 + IDCT_K[0]*x[2]; + f[3] = x26 + IDCT_K[1]*x[6]; + + e[0] = x1357 + x15 + IDCT_K[4]*x[1] + x17; + e[1] = x1357 + x37 + IDCT_K[6]*x[3] + x35; + e[2] = x1357 + x15 + IDCT_K[5]*x[5] + x35; + e[3] = x1357 + x37 + IDCT_K[7]*x[7] + x17; + + *dst = f[0] + f[2] + e[0]; dst += stride; + *dst = f[1] + f[3] + e[1]; dst += stride; + *dst = f[1] - f[3] + e[2]; dst += stride; + *dst = f[0] - f[2] + e[3]; dst += stride; + *dst = f[0] - f[2] - e[3]; dst += stride; + *dst = f[1] - f[3] - e[2]; dst += stride; + *dst = f[1] + f[3] - e[1]; dst += stride; + *dst = f[0] + f[2] - e[0]; dst += stride; +} + +static void InverseDCTSubBlock(int16_t *dst, const int16_t *src) +{ + float x[8]; + float block[SUBBLOCK_SIZE]; + unsigned int i, j; + + /* idct 1d on rows (+transposition) */ + for (i = 0; i < 8; ++i) + { + for (j = 0; j < 8; ++j) + { + x[j] = (float)src[i*8+j]; + } + + InverseDCT1D(x, &block[i], 8); + } + + /* idct 1d on columns (thanks to previous transposition) */ + for (i = 0; i < 8; ++i) + { + InverseDCT1D(&block[i*8], x, 1); + + /* C4 = 1 normalization implies a division by 8 */ + for (j = 0; j < 8; ++j) + { + dst[i+j*8] = (int16_t)x[j] >> 3; + } + } +} + +static void RescaleYSubBlock(int16_t *dst, const int16_t *src) +{ + unsigned int i; + + for (i = 0; i < SUBBLOCK_SIZE; ++i) + { + dst[i] = (((uint32_t)(clamp_s12(src[i]) + 0x800) * 0xdb0) >> 16) + 0x10; + } +} + +static void RescaleUVSubBlock(int16_t *dst, const int16_t *src) +{ + unsigned int i; + + for (i = 0; i < SUBBLOCK_SIZE; ++i) + { + dst[i] = (((int)clamp_s12(src[i]) * 0xe00) >> 16) + 0x80; + } +} + + + +/* FIXME: assume presence of expansion pack */ +#define MEMMASK 0x7fffff + +static void rdram_read_many_u16(uint16_t *dst, uint32_t address, unsigned int count) +{ + while (count != 0) + { + uint16_t s = rsp.RDRAM[((address++)^S8) & MEMMASK]; + s <<= 8; + s |= rsp.RDRAM[((address++)^S8) & MEMMASK]; + + *(dst++) = s; + + --count; + } +} + +static void rdram_write_many_u16(const uint16_t *src, uint32_t address, unsigned int count) +{ + while (count != 0) + { + rsp.RDRAM[((address++)^S8) & MEMMASK] = (uint8_t)(*src >> 8); + rsp.RDRAM[((address++)^S8) & MEMMASK] = (uint8_t)(*(src++) & 0xff); + + --count; + } +} + +static uint32_t rdram_read_u32(uint32_t address) +{ + uint32_t r = rsp.RDRAM[((address++) ^ S8) & MEMMASK]; r <<= 8; + r |= rsp.RDRAM[((address++) ^ S8) & MEMMASK]; r <<= 8; + r |= rsp.RDRAM[((address++) ^ S8) & MEMMASK]; r <<= 8; + r |= rsp.RDRAM[((address++) ^ S8) & MEMMASK]; + + return r; +} + +static void rdram_write_many_u32(const uint32_t *src, uint32_t address, unsigned int count) +{ + while (count != 0) + { + rsp.RDRAM[((address++)^S8) & MEMMASK] = (uint8_t)(*src >> 24); + rsp.RDRAM[((address++)^S8) & MEMMASK] = (uint8_t)(*src >> 16); + rsp.RDRAM[((address++)^S8) & MEMMASK] = (uint8_t)(*src >> 8); + rsp.RDRAM[((address++)^S8) & MEMMASK] = (uint8_t)(*(src++) & 0xff); + + --count; } } diff -Nru mupen64plus-rsp-hle-1.99.5/src/jpeg.h mupen64plus-rsp-hle-2.0/src/jpeg.h --- mupen64plus-rsp-hle-1.99.5/src/jpeg.h 1970-01-01 00:00:00.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/src/jpeg.h 2013-07-03 14:07:45.000000000 +0000 @@ -0,0 +1,30 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Mupen64plus-rsp-hle - jpeg.h * + * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * + * Copyright (C) 2002 Hacktarux * + * * + * 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef JPEG_H +#define JPEG_H + +void jpeg_decode_PS0(); +void jpeg_decode_PS(); +void jpeg_decode_OB(); + +#endif + diff -Nru mupen64plus-rsp-hle-1.99.5/src/main.c mupen64plus-rsp-hle-2.0/src/main.c --- mupen64plus-rsp-hle-1.99.5/src/main.c 2012-03-10 17:54:03.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/src/main.c 2013-07-03 14:07:45.000000000 +0000 @@ -30,97 +30,274 @@ #include "m64p_common.h" #include "m64p_plugin.h" #include "hle.h" +#include "alist.h" +#include "cicx105.h" +#include "jpeg.h" + +#define min(a,b) (((a) < (b)) ? (a) : (b)) + +/* some rsp status flags */ +#define RSP_STATUS_HALT 0x1 +#define RSP_STATUS_BROKE 0x2 +#define RSP_STATUS_INTR_ON_BREAK 0x40 +#define RSP_STATUS_TASKDONE 0x200 + +/* some rdp status flags */ +#define DP_STATUS_FREEZE 0x2 + +/* some mips interface interrupt flags */ +#define MI_INTR_SP 0x1 + + +/* helper functions prototypes */ +static unsigned int sum_bytes(const unsigned char *bytes, unsigned int size); +static void dump_binary(const char * const filename, const unsigned char * const bytes, + unsigned int size); +static void dump_task(const char * const filename, const OSTask_t * const task); + +static void handle_unknown_task(unsigned int sum); +static void handle_unknown_non_task(unsigned int sum); /* global variables */ RSP_INFO rsp; /* local variables */ -static const int AudioHle = 0, GraphicsHle = 1; +static const int FORWARD_AUDIO = 0, FORWARD_GFX = 1; static void (*l_DebugCallback)(void *, int, const char *) = NULL; static void *l_DebugCallContext = NULL; static int l_PluginInit = 0; /* local functions */ + /** - * Simulate the effect of setting the TASKDONE bit (aliased to SIG2) - * and executing a break instruction (setting HALT and BROKE bits). + * Try to figure if the RSP was launched using osSpTask* functions + * and not run directly (in which case DMEM[0xfc0-0xfff] is meaningless). + * + * Previously, the ucode_size field was used to determine this, + * but it is not robust enough (hi Pokemon Stadium !) because games could write anything + * in this field : most ucode_boot discard the value and just use 0xf7f anyway. + * + * Using ucode_boot_size should be more robust in this regard. **/ -static void taskdone() +static int is_task() +{ + return (get_task()->ucode_boot_size <= 0x1000); +} + +static void rsp_break(unsigned int setbits) { - // On hardware writing to SP_STATUS_REG is an indirect way of changing its content. - // For instance, in order to set the TASKDONE bit (bit 9), one should write 0x4000 - // to the SP_STATUS_REG : Read Access & Write Access don't have the same semantic. - // - // Here, this indirect way of changing the status register is bypassed : - // we modify the bits directly. - // - // 0x203 = TASKDONE | BROKE | HALT - *rsp.SP_STATUS_REG |= 0x203; + *rsp.SP_STATUS_REG |= setbits | RSP_STATUS_BROKE | RSP_STATUS_HALT; + + if ((*rsp.SP_STATUS_REG & RSP_STATUS_INTR_ON_BREAK)) + { + *rsp.MI_INTR_REG |= MI_INTR_SP; + rsp.CheckInterrupts(); + } } +static void forward_gfx_task() +{ + if (rsp.ProcessDlistList != NULL) + { + rsp.ProcessDlistList(); + *rsp.DPC_STATUS_REG &= ~DP_STATUS_FREEZE; + } +} -static int audio_ucode_detect(OSTask_t *task) +static void forward_audio_task() { - if (*(unsigned int*)(rsp.RDRAM + task->ucode_data + 0) != 0x1) + if (rsp.ProcessAlistList != NULL) { - if (*(rsp.RDRAM + task->ucode_data + (0 ^ (3-S8))) == 0xF) - return 4; + rsp.ProcessAlistList(); + } +} + +static void show_cfb() +{ + if (rsp.ShowCFB != NULL) + { + rsp.ShowCFB(); + } +} + +static int try_fast_audio_dispatching() +{ + /* identify audio ucode by using the content of ucode_data */ + const OSTask_t * const task = get_task(); + const unsigned char * const udata_ptr = rsp.RDRAM + task->ucode_data; + + if (*(unsigned int*)(udata_ptr + 0) == 0x00000001) + { + if (*(unsigned int*)(udata_ptr + 0x30) == 0xf0000f00) + { + /** + * Many games including: + * Super Mario 64, Diddy Kong Racing, BlastCorp, GoldenEye, ... (most common) + **/ + alist_process_ABI1(); return 1; + } else - return 3; + { + /** + * Mario Kart / Wave Race, + * LylatWars, + * FZeroX, + * Yoshi Story, + * 1080 Snowboarding, + * Zelda Ocarina of Time, + * Zelda Majoras Mask / Pokemon Stadium 2, + * Animal Crossing + * + * FIXME: in fact, all these games do not share the same ABI. + * That's the reason of the workaround in ucode2.cpp with isZeldaABI and isMKABI + **/ + alist_process_ABI2(); return 1; + } } else { - if (*(unsigned int*)(rsp.RDRAM + task->ucode_data + 0x30) == 0xF0000F00) - return 1; + if (*(unsigned int*)(udata_ptr + 0x10) == 0x00000001) + { + /** + * Musyx ucode found in following games: + * RogueSquadron, ResidentEvil2, SnowCrossPolaris, TheWorldIsNotEnough, + * RugratsInParis, NBAShowTime, HydroThunder, Tarzan, + * GauntletLegend, Rush2049, IndianaJones, BattleForNaboo + * TODO: implement ucode + **/ + DebugMessage(M64MSG_WARNING, "MusyX ucode not implemented."); + /* return 1; */ + } else - return 2; + { + /** + * Many games including: + * Pokemon Stadium, Banjo Kazooie, Donkey Kong, Banjo Tooie, Jet Force Gemini, + * Mickey SpeedWay USA, Perfect Dark, Conker Bad Fur Day ... + **/ + alist_process_ABI3(); return 1; + } } + + return 0; } -extern void (*ABI1[0x20])(); -extern void (*ABI2[0x20])(); -extern void (*ABI3[0x20])(); +static int try_fast_task_dispatching() +{ + /* identify task ucode by its type */ + const OSTask_t * const task = get_task(); + + switch (task->type) + { + case 1: if (FORWARD_GFX) { forward_gfx_task(); return 1; } break; + + case 2: + if (FORWARD_AUDIO) { forward_audio_task(); return 1; } + else if (try_fast_audio_dispatching()) { return 1; } + break; -static void (*ABI[0x20])(); + case 7: show_cfb(); return 1; + } -u32 inst1, inst2; + return 0; +} + +static void normal_task_dispatching() +{ + const OSTask_t * const task = get_task(); + const unsigned int sum = + sum_bytes(rsp.RDRAM + task->ucode, min(task->ucode_size, 0xf80) >> 1); + + switch (sum) + { + /* StoreVe12: found in Zelda Ocarina of Time [misleading task->type == 4] */ + case 0x278: /* Nothing to emulate */ return; + + /* GFX: Twintris [misleading task->type == 0] */ + case 0x212ee: + if (FORWARD_GFX) { forward_gfx_task(); return; } + break; + + /* JPEG: found in Pokemon Stadium J */ + case 0x2c85a: jpeg_decode_PS0(); return; + + /* JPEG: found in Zelda Ocarina of Time, Pokemon Stadium 1, Pokemon Stadium 2 */ + case 0x2caa6: jpeg_decode_PS(); return; + + /* JPEG: found in Ogre Battle, Bottom of the 9th */ + case 0x130de: jpeg_decode_OB(); return; + } + + handle_unknown_task(sum); +} -static int audio_ucode(OSTask_t *task) +static void non_task_dispatching() { - unsigned int *p_alist = (unsigned int*)(rsp.RDRAM + task->data_ptr); - unsigned int i; + const unsigned int sum = sum_bytes(rsp.IMEM, 0x1000 >> 1); - switch(audio_ucode_detect(task)) + switch(sum) { - case 1: // mario ucode - memcpy( ABI, ABI1, sizeof(ABI[0])*0x20 ); - break; - case 2: // banjo kazooie ucode - memcpy( ABI, ABI2, sizeof(ABI[0])*0x20 ); - break; - case 3: // zelda ucode - memcpy( ABI, ABI3, sizeof(ABI[0])*0x20 ); - break; - default: - { - DebugMessage(M64MSG_WARNING, "unknown audio ucode"); - return -1; - } + /* CIC x105 ucode (used during boot of CIC x105 games) */ + case 0x9e2: /* CIC 6105 */ + case 0x9f2: /* CIC 7105 */ + cicx105_ucode(); return; } -// data = (short*)(rsp.RDRAM + task->ucode_data); + handle_unknown_non_task(sum); +} + +static void handle_unknown_task(unsigned int sum) +{ + char filename[256]; + const OSTask_t * const task = get_task(); + + DebugMessage(M64MSG_WARNING, "unknown OSTask: sum %x PC:%x", sum, *rsp.SP_PC_REG); + + sprintf(&filename[0], "task_%x.log", sum); + dump_task(filename, task); + + // dump ucode_boot + sprintf(&filename[0], "ucode_boot_%x.bin", sum); + dump_binary(filename, rsp.RDRAM + (task->ucode_boot & 0x7fffff), task->ucode_boot_size); - for (i = 0; i < (task->data_size/4); i += 2) + // dump ucode + if (task->ucode != 0) { - inst1 = p_alist[i]; - inst2 = p_alist[i+1]; - ABI[inst1 >> 24](); + sprintf(&filename[0], "ucode_%x.bin", sum); + dump_binary(filename, rsp.RDRAM + (task->ucode & 0x7fffff), 0xf80); } - return 0; + // dump ucode_data + if (task->ucode_data != 0) + { + sprintf(&filename[0], "ucode_data_%x.bin", sum); + dump_binary(filename, rsp.RDRAM + (task->ucode_data & 0x7fffff), task->ucode_data_size); + } + + // dump data + if (task->data_ptr != 0) + { + sprintf(&filename[0], "data_%x.bin", sum); + dump_binary(filename, rsp.RDRAM + (task->data_ptr & 0x7fffff), task->data_size); + } } +static void handle_unknown_non_task(unsigned int sum) +{ + char filename[256]; + + DebugMessage(M64MSG_WARNING, "unknown RSP code: sum: %x PC:%x", sum, *rsp.SP_PC_REG); + + // dump IMEM & DMEM for further analysis + sprintf(&filename[0], "imem_%x.bin", sum); + dump_binary(filename, rsp.IMEM, 0x1000); + + sprintf(&filename[0], "dmem_%x.bin", sum); + dump_binary(filename, rsp.DMEM, 0x1000); +} + + /* Global functions */ void DebugMessage(int level, const char *message, ...) { @@ -193,157 +370,107 @@ EXPORT unsigned int CALL DoRspCycles(unsigned int Cycles) { - OSTask_t *task = (OSTask_t*)(rsp.DMEM + 0xFC0); - unsigned int i, sum=0; - - if( task->type == 1 && task->data_ptr != 0 && GraphicsHle) + if (is_task()) { - if (rsp.ProcessDlistList != NULL) - { - rsp.ProcessDlistList(); - } - taskdone(); - if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) - { - *rsp.MI_INTR_REG |= 0x1; - rsp.CheckInterrupts(); - } - - *rsp.DPC_STATUS_REG &= ~0x0002; - return Cycles; + if (!try_fast_task_dispatching()) { normal_task_dispatching(); } + rsp_break(RSP_STATUS_TASKDONE); } - else if (task->type == 2 && AudioHle) - { - if (rsp.ProcessAlistList != NULL) - { - rsp.ProcessAlistList(); - } - taskdone(); - if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) - { - *rsp.MI_INTR_REG |= 0x1; - rsp.CheckInterrupts(); - } - return Cycles; - } - else if (task->type == 7) + else { - rsp.ShowCFB(); + non_task_dispatching(); + rsp_break(0); } - taskdone(); - if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) - { - *rsp.MI_INTR_REG |= 0x1; - rsp.CheckInterrupts(); - } + return Cycles; +} - if (task->ucode_size <= 0x1000) - for (i=0; i<(task->ucode_size/2); i++) - sum += *(rsp.RDRAM + task->ucode + i); - else - for (i=0; i<(0x1000/2); i++) - sum += *(rsp.IMEM + i); +EXPORT void CALL InitiateRSP(RSP_INFO Rsp_Info, unsigned int *CycleCount) +{ + rsp = Rsp_Info; +} +EXPORT void CALL RomClosed(void) +{ + memset(rsp.DMEM, 0, 0x1000); + memset(rsp.IMEM, 0, 0x1000); - if (task->ucode_size > 0x1000) - { - switch(sum) - { - case 0x9E2: // banjo tooie (U) boot code - { - int i,j; - memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1e8); - for (j=0; j<0xfc; j++) - for (i=0; i<8; i++) - *(rsp.RDRAM+((0x2fb1f0+j*0xff0+i)^S8))=*(rsp.IMEM+((0x120+j*8+i)^S8)); - } - return Cycles; - case 0x9F2: // banjo tooie (E) + zelda oot (E) boot code + init_ucode2(); +} + + +/* local helper functions */ +static unsigned int sum_bytes(const unsigned char *bytes, unsigned int size) +{ + unsigned int sum = 0; + const unsigned char * const bytes_end = bytes + size; + + while (bytes != bytes_end) + sum += *bytes++; + + return sum; +} + + +static void dump_binary(const char * const filename, const unsigned char * const bytes, + unsigned int size) +{ + FILE *f; + + // if file already exists, do nothing + f = fopen(filename, "r"); + if (f == NULL) + { + // else we write bytes to the file + f= fopen(filename, "wb"); + if (f != NULL) { + if (fwrite(bytes, 1, size, f) != size) { - int i,j; - memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1e8); - for (j=0; j<0xfc; j++) - for (i=0; i<8; i++) - *(rsp.RDRAM+((0x2fb1f0+j*0xff0+i)^S8))=*(rsp.IMEM+((0x120+j*8+i)^S8)); + DebugMessage(M64MSG_ERROR, "Writing error on %s", filename); } - return Cycles; + fclose(f); + } + else + { + DebugMessage(M64MSG_ERROR, "Couldn't open %s for writing !", filename); } } else { - switch(task->type) - { - case 2: // audio - if (audio_ucode(task) == 0) - return Cycles; - break; - case 4: // jpeg - switch(sum) - { - case 0x278: // used by zelda during boot - taskdone(); - return Cycles; - case 0x2e4fc: // used by pokemon stadium {1,2} for jpg decompression - ps_jpg_uncompress(task); - taskdone(); - return Cycles; - case 0x130de: // used by ogre battle for background decompression - ob_jpg_uncompress(task); - taskdone(); - return Cycles; - default: - DebugMessage(M64MSG_WARNING, "unknown jpeg task: sum:%x", sum); - } - break; - } + fclose(f); } +} - { +static void dump_task(const char * const filename, const OSTask_t * const task) +{ FILE *f; - DebugMessage(M64MSG_WARNING, "unknown task: type:%d sum:%x PC:%lx", (int)task->type, sum, (unsigned long) rsp.SP_PC_REG); - if (task->ucode_size <= 0x1000) + f = fopen(filename, "r"); + if (f == NULL) { - f = fopen("imem.dat", "wb"); - if (f == NULL || fwrite(rsp.RDRAM + task->ucode, 1, task->ucode_size, f) != task->ucode_size) - DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file imem.dat"); - fclose(f); - - f = fopen("dmem.dat", "wb"); - if (f == NULL || fwrite(rsp.RDRAM + task->ucode_data, 1, task->ucode_data_size, f) != task->ucode_data_size) - DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file dmem.dat"); + f = fopen(filename, "w"); + fprintf(f, + "type = %d\n" + "flags = %d\n" + "ucode_boot = %#08x size = %#x\n" + "ucode = %#08x size = %#x\n" + "ucode_data = %#08x size = %#x\n" + "dram_stack = %#08x size = %#x\n" + "output_buff = %#08x *size = %#x\n" + "data = %#08x size = %#x\n" + "yield_data = %#08x size = %#x\n", + task->type, task->flags, + task->ucode_boot, task->ucode_boot_size, + task->ucode, task->ucode_size, + task->ucode_data, task->ucode_data_size, + task->dram_stack, task->dram_stack_size, + task->output_buff, task->output_buff_size, + task->data_ptr, task->data_size, + task->yield_data_ptr, task->yield_data_size); fclose(f); } else { - f = fopen("imem.dat", "wb"); - if (f == NULL || fwrite(rsp.IMEM, 1, 0x1000, f) != 0x1000) - DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file imem.dat"); - fclose(f); - - f = fopen("dmem.dat", "wb"); - if (f == NULL || fwrite(rsp.DMEM, 1, 0x1000, f) != 0x1000) - DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file dmem.dat"); fclose(f); } - } - - return Cycles; -} - -EXPORT void CALL InitiateRSP(RSP_INFO Rsp_Info, unsigned int *CycleCount) -{ - rsp = Rsp_Info; -} - -EXPORT void CALL RomClosed(void) -{ - int i; - for (i=0; i<0x1000; i++) - rsp.DMEM[i] = rsp.IMEM[i] = 0; - - //init_ucode1(); - init_ucode2(); } diff -Nru mupen64plus-rsp-hle-1.99.5/src/ucode1.cpp mupen64plus-rsp-hle-2.0/src/ucode1.cpp --- mupen64plus-rsp-hle-1.99.5/src/ucode1.cpp 2012-03-10 17:54:03.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/src/ucode1.cpp 2013-07-03 14:07:45.000000000 +0000 @@ -24,10 +24,9 @@ extern "C" { #include "hle.h" + #include "alist_internal.h" } -extern "C" void (*ABI1[])(void); - //#include "rsp.h" //#define SAFE_MEMORY /* @@ -95,7 +94,7 @@ #define MEMMASK 0x3FFFFF #endif -static void SPNOOP (void) { +static void SPNOOP (u32 inst1, u32 inst2) { //MessageBox (NULL, "Unknown Audio Command in ABI 1", "Audio HLE Error", MB_OK); } @@ -124,7 +123,7 @@ short hleMixerWorkArea[256]; u16 adpcmtable[0x88]; -u16 ResampleLUT [0x200] = { +extern const u16 ResampleLUT [0x200] = { 0x0C39, 0x66AD, 0x0D46, 0xFFDF, 0x0B39, 0x6696, 0x0E5F, 0xFFD8, 0x0A44, 0x6669, 0x0F83, 0xFFD0, 0x095A, 0x6626, 0x10B4, 0xFFC8, 0x087D, 0x65CD, 0x11F0, 0xFFBF, 0x07AB, 0x655E, 0x1338, 0xFFB6, @@ -159,7 +158,7 @@ 0xFFD8, 0x0E5F, 0x6696, 0x0B39, 0xFFDF, 0x0D46, 0x66AD, 0x0C39 }; -static void CLEARBUFF (void) { +static void CLEARBUFF (u32 inst1, u32 inst2) { u32 addr = (u32)(inst1 & 0xffff); u32 count = (u32)(inst2 & 0xffff); addr &= 0xFFFC; @@ -168,7 +167,7 @@ //FILE *dfile = fopen ("d:\\envmix.txt", "wt"); -static void ENVMIXER (void) { +static void ENVMIXER (u32 inst1, u32 inst2) { //static int envmixcnt = 0; u8 flags = (u8)((inst1 >> 16) & 0xff); u32 addy = (inst2 & 0xFFFFFF);// + SEGMENTS[(inst2>>24)&0xf]; @@ -393,7 +392,7 @@ memcpy(rsp.RDRAM+addy, (u8 *)hleMixerWorkArea,80); } -static void RESAMPLE (void) { +static void RESAMPLE (u32 inst1, u32 inst2) { unsigned char Flags=(u8)((inst1>>16)&0xff); unsigned int Pitch=((inst1&0xffff))<<1; u32 addy = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf]; @@ -469,7 +468,7 @@ *(u16 *)(rsp.RDRAM+addy+10) = Accum; } -static void SETVOL (void) { +static void SETVOL (u32 inst1, u32 inst2) { // Might be better to unpack these depending on the flags... u8 flags = (u8)((inst1 >> 16) & 0xff); u16 vol = (s16)(inst1 & 0xffff); @@ -514,15 +513,15 @@ } } -static void UNKNOWN (void) {} +static void UNKNOWN (u32 inst1, u32 inst2) {} -static void SETLOOP (void) { +static void SETLOOP (u32 inst1, u32 inst2) { loopval = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf]; //VolTrg_Left = (s16)(loopval>>16); // m_LeftVol //VolRamp_Left = (s16)(loopval); // m_LeftVolTarget } -static void ADPCM (void) { // Work in progress! :) +static void ADPCM (u32 inst1, u32 inst2) { // Work in progress! :) unsigned char Flags=(u8)(inst1>>16)&0xff; //unsigned short Gain=(u16)(inst1&0xffff); unsigned int Address=(inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf]; @@ -767,7 +766,7 @@ memcpy(&rsp.RDRAM[Address],out,32); } -static void LOADBUFF (void) { // memcpy causes static... endianess issue :( +static void LOADBUFF (u32 inst1, u32 inst2) { // memcpy causes static... endianess issue :( u32 v0; //u32 cnt; if (AudioCount == 0) @@ -776,7 +775,7 @@ memcpy (BufferSpace+(AudioInBuffer&0xFFFC), rsp.RDRAM+v0, (AudioCount+3)&0xFFFC); } -static void SAVEBUFF (void) { // memcpy causes static... endianess issue :( +static void SAVEBUFF (u32 inst1, u32 inst2) { // memcpy causes static... endianess issue :( u32 v0; //u32 cnt; if (AudioCount == 0) @@ -785,7 +784,7 @@ memcpy (rsp.RDRAM+v0, BufferSpace+(AudioOutBuffer&0xFFFC), (AudioCount+3)&0xFFFC); } -static void SETBUFF (void) { // Should work ;-) +static void SETBUFF (u32 inst1, u32 inst2) { // Should work ;-) if ((inst1 >> 0x10) & 0x8) { // A_AUX - Auxillary Sound Buffer Settings AudioAuxA = u16(inst1); AudioAuxC = u16((inst2 >> 0x10)); @@ -797,7 +796,7 @@ } } -static void DMEMMOVE (void) { // Doesn't sound just right?... will fix when HLE is ready - 03-11-01 +static void DMEMMOVE (u32 inst1, u32 inst2) { // Doesn't sound just right?... will fix when HLE is ready - 03-11-01 u32 v0, v1; u32 cnt; if ((inst2 & 0xffff)==0) @@ -816,7 +815,7 @@ } } -static void LOADADPCM (void) { // Loads an ADPCM table - Works 100% Now 03-13-01 +static void LOADADPCM (u32 inst1, u32 inst2) { // Loads an ADPCM table - Works 100% Now 03-13-01 u32 v0; v0 = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf]; /* if (v0 > (1024*1024*8)) @@ -841,7 +840,7 @@ } -static void INTERLEAVE (void) { // Works... - 3-11-01 +static void INTERLEAVE (u32 inst1, u32 inst2) { // Works... - 3-11-01 u32 inL, inR; u16 *outbuff = (u16 *)(AudioOutBuffer+BufferSpace); u16 *inSrcR; @@ -875,7 +874,7 @@ } -static void MIXER (void) { // Fixed a sign issue... 03-14-01 +static void MIXER (u32 inst1, u32 inst2) { // Fixed a sign issue... 03-14-01 u32 dmemin = (u16)(inst2 >> 0x10); u32 dmemout = (u16)(inst2 & 0xFFFF); //u8 flags = (u8)((inst1 >> 16) & 0xff); @@ -910,15 +909,13 @@ //Command: RESAMPLE - Calls: 48 - Total Time: 276354 - Avg Time: 5757.38 - Percent: 22.95% -void (*ABI1[0x20])(void) = { // TOP Performace Hogs: MIXER, RESAMPLE, ENVMIXER +extern "C" const acmd_callback_t ABI1[0x10] = { // TOP Performace Hogs: MIXER, RESAMPLE, ENVMIXER SPNOOP , ADPCM , CLEARBUFF, ENVMIXER , LOADBUFF, RESAMPLE , SAVEBUFF, UNKNOWN, - SETBUFF, SETVOL, DMEMMOVE , LOADADPCM , MIXER , INTERLEAVE, UNKNOWN , SETLOOP, - SPNOOP , SPNOOP, SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP, - SPNOOP , SPNOOP, SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP + SETBUFF, SETVOL, DMEMMOVE , LOADADPCM , MIXER , INTERLEAVE, UNKNOWN , SETLOOP }; /* BACKUPS -void MIXER (void) { // Fixed a sign issue... 03-14-01 +void MIXER (u32 inst1, u32 inst2) { // Fixed a sign issue... 03-14-01 u16 dmemin = (u16)(inst2 >> 0x10); u16 dmemout = (u16)(inst2 & 0xFFFF); u16 gain = (u16)(inst1 & 0xFFFF); diff -Nru mupen64plus-rsp-hle-1.99.5/src/ucode2.cpp mupen64plus-rsp-hle-2.0/src/ucode2.cpp --- mupen64plus-rsp-hle-1.99.5/src/ucode2.cpp 2012-03-10 17:54:03.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/src/ucode2.cpp 2013-07-03 14:07:45.000000000 +0000 @@ -26,13 +26,12 @@ extern "C" { #include "m64p_types.h" #include "hle.h" + #include "alist_internal.h" } -extern "C" void (*ABI2[])(void); - extern u8 BufferSpace[0x10000]; -static void SPNOOP (void) { +static void SPNOOP (u32 inst1, u32 inst2) { DebugMessage(M64MSG_ERROR, "Unknown/Unimplemented Audio Command %i in ABI 2", (int)(inst1 >> 24)); } extern u16 AudioInBuffer; // 0x0000(T8) @@ -43,14 +42,14 @@ extern u16 adpcmtable[0x88]; -extern u16 ResampleLUT [0x200]; +extern const u16 ResampleLUT [0x200]; bool isMKABI = false; bool isZeldaABI = false; -void init_ucode2() { isMKABI = isZeldaABI = false; } +extern "C" void init_ucode2() { isMKABI = isZeldaABI = false; } -static void LOADADPCM2 (void) { // Loads an ADPCM table - Works 100% Now 03-13-01 +static void LOADADPCM2 (u32 inst1, u32 inst2) { // Loads an ADPCM table - Works 100% Now 03-13-01 u32 v0; v0 = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf]; u16 *table = (u16 *)(rsp.RDRAM+v0); // Zelda2 Specific... @@ -71,17 +70,17 @@ } } -static void SETLOOP2 (void) { +static void SETLOOP2 (u32 inst1, u32 inst2) { loopval = inst2 & 0xffffff; // No segment? } -static void SETBUFF2 (void) { +static void SETBUFF2 (u32 inst1, u32 inst2) { AudioInBuffer = u16(inst1); // 0x00 AudioOutBuffer = u16((inst2 >> 0x10)); // 0x02 AudioCount = u16(inst2); // 0x04 } -static void ADPCM2 (void) { // Verified to be 100% Accurate... +static void ADPCM2 (u32 inst1, u32 inst2) { // Verified to be 100% Accurate... unsigned char Flags=(u8)(inst1>>16)&0xff; //unsigned short Gain=(u16)(inst1&0xffff); unsigned int Address=(inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf]; @@ -357,21 +356,21 @@ memcpy(&rsp.RDRAM[Address],out,32); } -static void CLEARBUFF2 (void) { +static void CLEARBUFF2 (u32 inst1, u32 inst2) { u16 addr = (u16)(inst1 & 0xffff); u16 count = (u16)(inst2 & 0xffff); if (count > 0) memset(BufferSpace+addr, 0, count); } -static void LOADBUFF2 (void) { // Needs accuracy verification... +static void LOADBUFF2 (u32 inst1, u32 inst2) { // Needs accuracy verification... u32 v0; u32 cnt = (((inst1 >> 0xC)+3)&0xFFC); v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf]; memcpy (BufferSpace+(inst1&0xfffc), rsp.RDRAM+v0, (cnt+3)&0xFFFC); } -static void SAVEBUFF2 (void) { // Needs accuracy verification... +static void SAVEBUFF2 (u32 inst1, u32 inst2) { // Needs accuracy verification... u32 v0; u32 cnt = (((inst1 >> 0xC)+3)&0xFFC); v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf]; @@ -379,7 +378,7 @@ } -static void MIXER2 (void) { // Needs accuracy verification... +static void MIXER2 (u32 inst1, u32 inst2) { // Needs accuracy verification... u16 dmemin = (u16)(inst2 >> 0x10); u16 dmemout = (u16)(inst2 & 0xFFFF); u32 count = ((inst1 >> 12) & 0xFF0); @@ -401,7 +400,7 @@ } -static void RESAMPLE2 (void) { +static void RESAMPLE2 (u32 inst1, u32 inst2) { unsigned char Flags=(u8)((inst1>>16)&0xff); unsigned int Pitch=((inst1&0xffff))<<1; u32 addy = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf]; @@ -463,7 +462,7 @@ //memcpy (RSWORK, src+srcPtr, 0x8); } -static void DMEMMOVE2 (void) { // Needs accuracy verification... +static void DMEMMOVE2 (u32 inst1, u32 inst2) { // Needs accuracy verification... u32 v0, v1; u32 cnt; if ((inst2 & 0xffff)==0) @@ -482,10 +481,10 @@ } } -u32 t3, s5, s6; -u16 env[8]; +static u32 t3, s5, s6; +static u16 env[8]; -static void ENVSETUP1 (void) { +static void ENVSETUP1 (u32 inst1, u32 inst2) { u32 tmp; //fprintf (dfile, "ENVSETUP1: inst1 = %08X, inst2 = %08X\n", inst1, inst2); @@ -499,7 +498,7 @@ //fprintf (dfile, " t3 = %X / s5 = %X / s6 = %X / env[4] = %X / env[5] = %X\n", t3, s5, s6, env[4], env[5]); } -static void ENVSETUP2 (void) { +static void ENVSETUP2 (u32 inst1, u32 inst2) { u32 tmp; //fprintf (dfile, "ENVSETUP2: inst1 = %08X, inst2 = %08X\n", inst1, inst2); @@ -514,7 +513,7 @@ //fprintf (dfile, " env[0] = %X / env[1] = %X / env[2] = %X / env[3] = %X\n", env[0], env[1], env[2], env[3]); } -static void ENVMIXER2 (void) { +static void ENVMIXER2 (u32 inst1, u32 inst2) { //fprintf (dfile, "ENVMIXER: inst1 = %08X, inst2 = %08X\n", inst1, inst2); s16 *bufft6, *bufft7, *buffs0, *buffs1; @@ -617,7 +616,7 @@ } } -static void DUPLICATE2(void) { +static void DUPLICATE2(u32 inst1, u32 inst2) { unsigned short Count = (inst1 >> 16) & 0xff; unsigned short In = inst1&0xffff; unsigned short Out = (inst2>>16); @@ -633,7 +632,7 @@ } } /* -static void INTERL2 (void) { // Make your own... +static void INTERL2 (u32 inst1, u32 inst2) { // Make your own... short Count = inst1 & 0xffff; unsigned short Out = inst2 & 0xffff; unsigned short In = (inst2 >> 16); @@ -664,7 +663,7 @@ } */ -static void INTERL2 (void) { +static void INTERL2 (u32 inst1, u32 inst2) { short Count = inst1 & 0xffff; unsigned short Out = inst2 & 0xffff; unsigned short In = (inst2 >> 16); @@ -680,7 +679,7 @@ } } -static void INTERLEAVE2 (void) { // Needs accuracy verification... +static void INTERLEAVE2 (u32 inst1, u32 inst2) { // Needs accuracy verification... u32 inL, inR; u16 *outbuff; u16 *inSrcR; @@ -721,7 +720,7 @@ } } -static void ADDMIXER (void) { +static void ADDMIXER (u32 inst1, u32 inst2) { short Count = (inst1 >> 12) & 0x00ff0; u16 InBuffer = (inst2 >> 16); u16 OutBuffer = inst2 & 0xffff; @@ -738,7 +737,7 @@ } } -static void HILOGAIN (void) { +static void HILOGAIN (u32 inst1, u32 inst2) { u16 cnt = inst1 & 0xffff; u16 out = (inst2 >> 16) & 0xffff; s16 hi = (s16)((inst1 >> 4) & 0xf000); @@ -760,7 +759,7 @@ } } -static void FILTER2 (void) { +static void FILTER2 (u32 inst1, u32 inst2) { static int cnt = 0; static s16 *lutt6; static s16 *lutt5; @@ -885,9 +884,9 @@ memcpy (BufferSpace+(inst1&0xffff), outbuff, cnt); } -static void SEGMENT2 (void) { +static void SEGMENT2 (u32 inst1, u32 inst2) { if (isZeldaABI) { - FILTER2 (); + FILTER2 (inst1, inst2); return; } if ((inst1 & 0xffffff) == 0) { @@ -896,11 +895,11 @@ } else { isMKABI = false; isZeldaABI = true; - FILTER2 (); + FILTER2 (inst1, inst2); } } -static void UNKNOWN (void) { +static void UNKNOWN (u32 inst1, u32 inst2) { } /* void (*ABI2[0x20])(void) = { @@ -910,7 +909,7 @@ SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP };*/ -void (*ABI2[0x20])(void) = { +extern "C" const acmd_callback_t ABI2[0x20] = { SPNOOP , ADPCM2, CLEARBUFF2, UNKNOWN, ADDMIXER, RESAMPLE2, UNKNOWN, SEGMENT2, SETBUFF2 , DUPLICATE2, DMEMMOVE2, LOADADPCM2, MIXER2, INTERLEAVE2, HILOGAIN, SETLOOP2, SPNOOP, INTERL2 , ENVSETUP1, ENVMIXER2, LOADBUFF2, SAVEBUFF2, ENVSETUP2, SPNOOP, diff -Nru mupen64plus-rsp-hle-1.99.5/src/ucode3.cpp mupen64plus-rsp-hle-2.0/src/ucode3.cpp --- mupen64plus-rsp-hle-1.99.5/src/ucode3.cpp 2012-03-10 17:54:03.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/src/ucode3.cpp 2013-07-03 14:07:45.000000000 +0000 @@ -26,15 +26,16 @@ extern "C" { #include "m64p_types.h" #include "hle.h" + #include "alist_internal.h" } -extern "C" void (*ABI3[])(void); - -static void SPNOOP (void) { +/* +static void SPNOOP (u32 inst1, u32 inst2) { DebugMessage(M64MSG_ERROR, "Unknown/Unimplemented Audio Command %i in ABI 3", (int)(inst1 >> 24)); } +*/ -extern u16 ResampleLUT [0x200]; +extern const u16 ResampleLUT [0x200]; extern u32 loopval; @@ -56,7 +57,7 @@ extern u8 BufferSpace[0x10000]; /* -static void SETVOL3 (void) { // Swapped Rate_Left and Vol +static void SETVOL3 (u32 inst1, u32 inst2) { // Swapped Rate_Left and Vol u8 Flags = (u8)(inst1 >> 0x10); if (Flags & 0x4) { // 288 if (Flags & 0x2) { // 290 @@ -73,7 +74,7 @@ } } */ -static void SETVOL3 (void) { +static void SETVOL3 (u32 inst1, u32 inst2) { u8 Flags = (u8)(inst1 >> 0x10); if (Flags & 0x4) { // 288 if (Flags & 0x2) { // 290 @@ -91,7 +92,7 @@ } } -static void ENVMIXER3 (void) { +static void ENVMIXER3 (u32 inst1, u32 inst2) { u8 flags = (u8)((inst1 >> 16) & 0xff); u32 addy = (inst2 & 0xFFFFFF); @@ -249,13 +250,13 @@ memcpy(rsp.RDRAM+addy, (u8 *)hleMixerWorkArea,80); } -static void CLEARBUFF3 (void) { +static void CLEARBUFF3 (u32 inst1, u32 inst2) { u16 addr = (u16)(inst1 & 0xffff); u16 count = (u16)(inst2 & 0xffff); memset(BufferSpace+addr+0x4f0, 0, count); } -static void MIXER3 (void) { // Needs accuracy verification... +static void MIXER3 (u32 inst1, u32 inst2) { // Needs accuracy verification... u16 dmemin = (u16)(inst2 >> 0x10) + 0x4f0; u16 dmemout = (u16)(inst2 & 0xFFFF) + 0x4f0; //u8 flags = (u8)((inst1 >> 16) & 0xff); @@ -275,7 +276,7 @@ } } -static void LOADBUFF3 (void) { +static void LOADBUFF3 (u32 inst1, u32 inst2) { u32 v0; u32 cnt = (((inst1 >> 0xC)+3)&0xFFC); v0 = (inst2 & 0xfffffc); @@ -283,7 +284,7 @@ memcpy (BufferSpace+src, rsp.RDRAM+v0, cnt); } -static void SAVEBUFF3 (void) { +static void SAVEBUFF3 (u32 inst1, u32 inst2) { u32 v0; u32 cnt = (((inst1 >> 0xC)+3)&0xFFC); v0 = (inst2 & 0xfffffc); @@ -291,7 +292,7 @@ memcpy (rsp.RDRAM+v0, BufferSpace+src, cnt); } -static void LOADADPCM3 (void) { // Loads an ADPCM table - Works 100% Now 03-13-01 +static void LOADADPCM3 (u32 inst1, u32 inst2) { // Loads an ADPCM table - Works 100% Now 03-13-01 u32 v0; v0 = (inst2 & 0xffffff); //memcpy (dmem+0x3f0, rsp.RDRAM+v0, inst1&0xffff); @@ -313,7 +314,7 @@ } } -static void DMEMMOVE3 (void) { // Needs accuracy verification... +static void DMEMMOVE3 (u32 inst1, u32 inst2) { // Needs accuracy verification... u32 v0, v1; u32 cnt; v0 = (inst1 & 0xFFFF) + 0x4f0; @@ -326,11 +327,11 @@ } } -static void SETLOOP3 (void) { +static void SETLOOP3 (u32 inst1, u32 inst2) { loopval = (inst2 & 0xffffff); } -static void ADPCM3 (void) { // Verified to be 100% Accurate... +static void ADPCM3 (u32 inst1, u32 inst2) { // Verified to be 100% Accurate... unsigned char Flags=(u8)(inst2>>0x1c)&0xff; //unsigned short Gain=(u16)(inst1&0xffff); unsigned int Address=(inst1 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf]; @@ -586,7 +587,7 @@ memcpy(&rsp.RDRAM[Address],out,32); } -static void RESAMPLE3 (void) { +static void RESAMPLE3 (u32 inst1, u32 inst2) { unsigned char Flags=(u8)((inst2>>0x1e)); unsigned int Pitch=((inst2>>0xe)&0xffff)<<1; u32 addy = (inst1 & 0xffffff); @@ -684,7 +685,7 @@ *(u16 *)(rsp.RDRAM+addy+10) = Accum; } -static void INTERLEAVE3 (void) { // Needs accuracy verification... +static void INTERLEAVE3 (u32 inst1, u32 inst2) { // Needs accuracy verification... //u32 inL, inR; u16 *outbuff = (u16 *)(BufferSpace + 0x4f0);//(u16 *)(AudioOutBuffer+dmem); u16 *inSrcR; @@ -726,7 +727,7 @@ } } -//static void UNKNOWN (void); +//static void UNKNOWN (u32 inst1, u32 inst2); /* typedef struct { unsigned char sync; @@ -752,12 +753,12 @@ FILE *mp3dat; */ -static void WHATISTHIS (void) { +static void WHATISTHIS (u32 inst1, u32 inst2) { } //static FILE *fp = fopen ("d:\\mp3info.txt", "wt"); u32 setaddr; -static void MP3ADDY (void) { +static void MP3ADDY (u32 inst1, u32 inst2) { setaddr = (inst2 & 0xffffff); } @@ -770,7 +771,7 @@ extern "C" { extern char *pDMEM; } -void MP3 (void); +void MP3 (u32 inst1, u32 inst2); /* { // return; @@ -819,17 +820,15 @@ (integrated-services-digital-network) to be the future high-bandwidth pipe to the home. */ -static void DISABLE (void) { +static void DISABLE (u32 inst1, u32 inst2) { //MessageBox (NULL, "Help", "ABI 3 Command 0", MB_OK); //ChangeABI (5); } -void (*ABI3[0x20])(void) = { +extern "C" const acmd_callback_t ABI3[0x10] = { DISABLE , ADPCM3 , CLEARBUFF3, ENVMIXER3 , LOADBUFF3, RESAMPLE3 , SAVEBUFF3, MP3, - MP3ADDY, SETVOL3, DMEMMOVE3 , LOADADPCM3 , MIXER3 , INTERLEAVE3, WHATISTHIS , SETLOOP3, - SPNOOP , SPNOOP, SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP, - SPNOOP , SPNOOP, SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP + MP3ADDY, SETVOL3, DMEMMOVE3 , LOADADPCM3 , MIXER3 , INTERLEAVE3, WHATISTHIS , SETLOOP3 }; diff -Nru mupen64plus-rsp-hle-1.99.5/src/ucode3mp3.cpp mupen64plus-rsp-hle-2.0/src/ucode3mp3.cpp --- mupen64plus-rsp-hle-1.99.5/src/ucode3mp3.cpp 2012-03-10 17:54:03.000000000 +0000 +++ mupen64plus-rsp-hle-2.0/src/ucode3mp3.cpp 2013-07-03 14:07:45.000000000 +0000 @@ -25,9 +25,10 @@ extern "C" { #include "hle.h" + #include "alist_internal.h" } -static u16 DeWindowLUT [0x420] = { +static const u16 DeWindowLUT [0x420] = { 0x0000, 0xFFF3, 0x005D, 0xFF38, 0x037A, 0xF736, 0x0B37, 0xC00E, 0x7FFF, 0x3FF2, 0x0B37, 0x08CA, 0x037A, 0x00C8, 0x005D, 0x000D, 0x0000, 0xFFF3, 0x005D, 0xFF38, 0x037A, 0xF736, 0x0B37, 0xC00E, @@ -203,13 +204,13 @@ static void InnerLoop (); - u32 inPtr, outPtr; +static u32 inPtr, outPtr; - u32 t6;// = 0x08A0; // I think these are temporary storage buffers - u32 t5;// = 0x0AC0; - u32 t4;// = (inst1 & 0x1E); +static u32 t6;// = 0x08A0; // I think these are temporary storage buffers +static u32 t5;// = 0x0AC0; +static u32 t4;// = (inst1 & 0x1E); -void MP3 () { +void MP3 (u32 inst1, u32 inst2) { // Initialization Code u32 readPtr; // s5 u32 writePtr; // s6