Updated LazyUSF
parent
c6e4436366
commit
ec40c5041c
Frameworks/lazyusf
lazyusf.xcodeproj
Plugins/HighlyComplete/HighlyComplete
|
@ -14,21 +14,22 @@
|
||||||
8378416E18C6E56B002C4FE5 /* alist_naudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378415818C6E56B002C4FE5 /* alist_naudio.c */; };
|
8378416E18C6E56B002C4FE5 /* alist_naudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378415818C6E56B002C4FE5 /* alist_naudio.c */; };
|
||||||
8378416F18C6E56B002C4FE5 /* alist_nead.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378415918C6E56B002C4FE5 /* alist_nead.c */; };
|
8378416F18C6E56B002C4FE5 /* alist_nead.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378415918C6E56B002C4FE5 /* alist_nead.c */; };
|
||||||
8378417018C6E56B002C4FE5 /* arithmetics.h in Headers */ = {isa = PBXBuildFile; fileRef = 8378415A18C6E56B002C4FE5 /* arithmetics.h */; };
|
8378417018C6E56B002C4FE5 /* arithmetics.h in Headers */ = {isa = PBXBuildFile; fileRef = 8378415A18C6E56B002C4FE5 /* arithmetics.h */; };
|
||||||
8378417118C6E56B002C4FE5 /* audio_hle.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378415B18C6E56B002C4FE5 /* audio_hle.c */; };
|
|
||||||
8378417218C6E56B002C4FE5 /* audio_hle.h in Headers */ = {isa = PBXBuildFile; fileRef = 8378415C18C6E56B002C4FE5 /* audio_hle.h */; };
|
|
||||||
8378417318C6E56B002C4FE5 /* cicx105.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378415D18C6E56B002C4FE5 /* cicx105.c */; };
|
8378417318C6E56B002C4FE5 /* cicx105.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378415D18C6E56B002C4FE5 /* cicx105.c */; };
|
||||||
8378417418C6E56B002C4FE5 /* cicx105.h in Headers */ = {isa = PBXBuildFile; fileRef = 8378415E18C6E56B002C4FE5 /* cicx105.h */; };
|
8378417418C6E56B002C4FE5 /* cicx105.h in Headers */ = {isa = PBXBuildFile; fileRef = 8378415E18C6E56B002C4FE5 /* cicx105.h */; };
|
||||||
8378417518C6E56B002C4FE5 /* jpeg.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378415F18C6E56B002C4FE5 /* jpeg.c */; };
|
8378417518C6E56B002C4FE5 /* jpeg.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378415F18C6E56B002C4FE5 /* jpeg.c */; };
|
||||||
8378417618C6E56B002C4FE5 /* jpeg.h in Headers */ = {isa = PBXBuildFile; fileRef = 8378416018C6E56B002C4FE5 /* jpeg.h */; };
|
8378417618C6E56B002C4FE5 /* jpeg.h in Headers */ = {isa = PBXBuildFile; fileRef = 8378416018C6E56B002C4FE5 /* jpeg.h */; };
|
||||||
8378417718C6E56B002C4FE5 /* main_hle.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378416118C6E56B002C4FE5 /* main_hle.c */; };
|
|
||||||
8378417818C6E56B002C4FE5 /* main_hle.h in Headers */ = {isa = PBXBuildFile; fileRef = 8378416218C6E56B002C4FE5 /* main_hle.h */; };
|
|
||||||
8378417918C6E56B002C4FE5 /* memory_hle.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378416318C6E56B002C4FE5 /* memory_hle.c */; };
|
|
||||||
8378417A18C6E56B002C4FE5 /* memory_hle.h in Headers */ = {isa = PBXBuildFile; fileRef = 8378416418C6E56B002C4FE5 /* memory_hle.h */; };
|
|
||||||
8378417B18C6E56B002C4FE5 /* mp3.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378416518C6E56B002C4FE5 /* mp3.c */; };
|
8378417B18C6E56B002C4FE5 /* mp3.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378416518C6E56B002C4FE5 /* mp3.c */; };
|
||||||
8378417C18C6E56B002C4FE5 /* musyx.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378416618C6E56B002C4FE5 /* musyx.c */; };
|
8378417C18C6E56B002C4FE5 /* musyx.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378416618C6E56B002C4FE5 /* musyx.c */; };
|
||||||
8378417D18C6E56B002C4FE5 /* musyx.h in Headers */ = {isa = PBXBuildFile; fileRef = 8378416718C6E56B002C4FE5 /* musyx.h */; };
|
8378417D18C6E56B002C4FE5 /* musyx.h in Headers */ = {isa = PBXBuildFile; fileRef = 8378416718C6E56B002C4FE5 /* musyx.h */; };
|
||||||
8378417E18C6E56B002C4FE5 /* plugin_hle.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378416818C6E56B002C4FE5 /* plugin_hle.c */; };
|
837841C018C847B2002C4FE5 /* audio.c in Sources */ = {isa = PBXBuildFile; fileRef = 837841B818C847B2002C4FE5 /* audio.c */; };
|
||||||
8378417F18C6E56B002C4FE5 /* plugin_hle.h in Headers */ = {isa = PBXBuildFile; fileRef = 8378416918C6E56B002C4FE5 /* plugin_hle.h */; };
|
837841C118C847B2002C4FE5 /* audio.h in Headers */ = {isa = PBXBuildFile; fileRef = 837841B918C847B2002C4FE5 /* audio.h */; };
|
||||||
|
837841C418C847B2002C4FE5 /* memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 837841BC18C847B2002C4FE5 /* memory.c */; };
|
||||||
|
837841C518C847B2002C4FE5 /* memory.h in Headers */ = {isa = PBXBuildFile; fileRef = 837841BD18C847B2002C4FE5 /* memory.h */; };
|
||||||
|
837841C618C847B2002C4FE5 /* plugin.c in Sources */ = {isa = PBXBuildFile; fileRef = 837841BE18C847B2002C4FE5 /* plugin.c */; };
|
||||||
|
83A2249218CAC28500FE4173 /* hle_external.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A2248E18CAC28500FE4173 /* hle_external.h */; };
|
||||||
|
83A2249318CAC28500FE4173 /* hle_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A2248F18CAC28500FE4173 /* hle_internal.h */; };
|
||||||
|
83A2249418CAC28500FE4173 /* hle.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A2249018CAC28500FE4173 /* hle.c */; };
|
||||||
|
83A2249518CAC28500FE4173 /* hle.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A2249118CAC28500FE4173 /* hle.h */; };
|
||||||
83C8B6AB18AF58080071B040 /* audio.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8B65918AF58080071B040 /* audio.c */; };
|
83C8B6AB18AF58080071B040 /* audio.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8B65918AF58080071B040 /* audio.c */; };
|
||||||
83C8B6AC18AF58080071B040 /* audio.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B65A18AF58080071B040 /* audio.h */; };
|
83C8B6AC18AF58080071B040 /* audio.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B65A18AF58080071B040 /* audio.h */; };
|
||||||
83C8B6AD18AF58080071B040 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B65B18AF58080071B040 /* config.h */; };
|
83C8B6AD18AF58080071B040 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B65B18AF58080071B040 /* config.h */; };
|
||||||
|
@ -119,21 +120,22 @@
|
||||||
8378415818C6E56B002C4FE5 /* alist_naudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alist_naudio.c; sourceTree = "<group>"; };
|
8378415818C6E56B002C4FE5 /* alist_naudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alist_naudio.c; sourceTree = "<group>"; };
|
||||||
8378415918C6E56B002C4FE5 /* alist_nead.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alist_nead.c; sourceTree = "<group>"; };
|
8378415918C6E56B002C4FE5 /* alist_nead.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alist_nead.c; sourceTree = "<group>"; };
|
||||||
8378415A18C6E56B002C4FE5 /* arithmetics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = arithmetics.h; sourceTree = "<group>"; };
|
8378415A18C6E56B002C4FE5 /* arithmetics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = arithmetics.h; sourceTree = "<group>"; };
|
||||||
8378415B18C6E56B002C4FE5 /* audio_hle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = audio_hle.c; sourceTree = "<group>"; };
|
|
||||||
8378415C18C6E56B002C4FE5 /* audio_hle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audio_hle.h; sourceTree = "<group>"; };
|
|
||||||
8378415D18C6E56B002C4FE5 /* cicx105.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cicx105.c; sourceTree = "<group>"; };
|
8378415D18C6E56B002C4FE5 /* cicx105.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cicx105.c; sourceTree = "<group>"; };
|
||||||
8378415E18C6E56B002C4FE5 /* cicx105.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cicx105.h; sourceTree = "<group>"; };
|
8378415E18C6E56B002C4FE5 /* cicx105.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cicx105.h; sourceTree = "<group>"; };
|
||||||
8378415F18C6E56B002C4FE5 /* jpeg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jpeg.c; sourceTree = "<group>"; };
|
8378415F18C6E56B002C4FE5 /* jpeg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jpeg.c; sourceTree = "<group>"; };
|
||||||
8378416018C6E56B002C4FE5 /* jpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = jpeg.h; sourceTree = "<group>"; };
|
8378416018C6E56B002C4FE5 /* jpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = jpeg.h; sourceTree = "<group>"; };
|
||||||
8378416118C6E56B002C4FE5 /* main_hle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main_hle.c; sourceTree = "<group>"; };
|
|
||||||
8378416218C6E56B002C4FE5 /* main_hle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = main_hle.h; sourceTree = "<group>"; };
|
|
||||||
8378416318C6E56B002C4FE5 /* memory_hle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = memory_hle.c; sourceTree = "<group>"; };
|
|
||||||
8378416418C6E56B002C4FE5 /* memory_hle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memory_hle.h; sourceTree = "<group>"; };
|
|
||||||
8378416518C6E56B002C4FE5 /* mp3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mp3.c; sourceTree = "<group>"; };
|
8378416518C6E56B002C4FE5 /* mp3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mp3.c; sourceTree = "<group>"; };
|
||||||
8378416618C6E56B002C4FE5 /* musyx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = musyx.c; sourceTree = "<group>"; };
|
8378416618C6E56B002C4FE5 /* musyx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = musyx.c; sourceTree = "<group>"; };
|
||||||
8378416718C6E56B002C4FE5 /* musyx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = musyx.h; sourceTree = "<group>"; };
|
8378416718C6E56B002C4FE5 /* musyx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = musyx.h; sourceTree = "<group>"; };
|
||||||
8378416818C6E56B002C4FE5 /* plugin_hle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = plugin_hle.c; sourceTree = "<group>"; };
|
837841B818C847B2002C4FE5 /* audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = audio.c; sourceTree = "<group>"; };
|
||||||
8378416918C6E56B002C4FE5 /* plugin_hle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugin_hle.h; sourceTree = "<group>"; };
|
837841B918C847B2002C4FE5 /* audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audio.h; sourceTree = "<group>"; };
|
||||||
|
837841BC18C847B2002C4FE5 /* memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = memory.c; sourceTree = "<group>"; };
|
||||||
|
837841BD18C847B2002C4FE5 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memory.h; sourceTree = "<group>"; };
|
||||||
|
837841BE18C847B2002C4FE5 /* plugin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = plugin.c; sourceTree = "<group>"; };
|
||||||
|
83A2248E18CAC28500FE4173 /* hle_external.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hle_external.h; sourceTree = "<group>"; };
|
||||||
|
83A2248F18CAC28500FE4173 /* hle_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hle_internal.h; sourceTree = "<group>"; };
|
||||||
|
83A2249018CAC28500FE4173 /* hle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hle.c; sourceTree = "<group>"; };
|
||||||
|
83A2249118CAC28500FE4173 /* hle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hle.h; sourceTree = "<group>"; };
|
||||||
83C8B62218AF57770071B040 /* lazyusf.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = lazyusf.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
83C8B62218AF57770071B040 /* lazyusf.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = lazyusf.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
83C8B65918AF58080071B040 /* audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = audio.c; sourceTree = "<group>"; };
|
83C8B65918AF58080071B040 /* audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = audio.c; sourceTree = "<group>"; };
|
||||||
83C8B65A18AF58080071B040 /* audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audio.h; sourceTree = "<group>"; };
|
83C8B65A18AF58080071B040 /* audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audio.h; sourceTree = "<group>"; };
|
||||||
|
@ -232,6 +234,15 @@
|
||||||
8378415318C6E56B002C4FE5 /* rsp_hle */ = {
|
8378415318C6E56B002C4FE5 /* rsp_hle */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
83A2248E18CAC28500FE4173 /* hle_external.h */,
|
||||||
|
83A2248F18CAC28500FE4173 /* hle_internal.h */,
|
||||||
|
83A2249018CAC28500FE4173 /* hle.c */,
|
||||||
|
83A2249118CAC28500FE4173 /* hle.h */,
|
||||||
|
837841B818C847B2002C4FE5 /* audio.c */,
|
||||||
|
837841B918C847B2002C4FE5 /* audio.h */,
|
||||||
|
837841BC18C847B2002C4FE5 /* memory.c */,
|
||||||
|
837841BD18C847B2002C4FE5 /* memory.h */,
|
||||||
|
837841BE18C847B2002C4FE5 /* plugin.c */,
|
||||||
8378415418C6E56B002C4FE5 /* alist.c */,
|
8378415418C6E56B002C4FE5 /* alist.c */,
|
||||||
8378415518C6E56B002C4FE5 /* alist.h */,
|
8378415518C6E56B002C4FE5 /* alist.h */,
|
||||||
8378415618C6E56B002C4FE5 /* alist_audio.c */,
|
8378415618C6E56B002C4FE5 /* alist_audio.c */,
|
||||||
|
@ -239,21 +250,13 @@
|
||||||
8378415818C6E56B002C4FE5 /* alist_naudio.c */,
|
8378415818C6E56B002C4FE5 /* alist_naudio.c */,
|
||||||
8378415918C6E56B002C4FE5 /* alist_nead.c */,
|
8378415918C6E56B002C4FE5 /* alist_nead.c */,
|
||||||
8378415A18C6E56B002C4FE5 /* arithmetics.h */,
|
8378415A18C6E56B002C4FE5 /* arithmetics.h */,
|
||||||
8378415B18C6E56B002C4FE5 /* audio_hle.c */,
|
|
||||||
8378415C18C6E56B002C4FE5 /* audio_hle.h */,
|
|
||||||
8378415D18C6E56B002C4FE5 /* cicx105.c */,
|
8378415D18C6E56B002C4FE5 /* cicx105.c */,
|
||||||
8378415E18C6E56B002C4FE5 /* cicx105.h */,
|
8378415E18C6E56B002C4FE5 /* cicx105.h */,
|
||||||
8378415F18C6E56B002C4FE5 /* jpeg.c */,
|
8378415F18C6E56B002C4FE5 /* jpeg.c */,
|
||||||
8378416018C6E56B002C4FE5 /* jpeg.h */,
|
8378416018C6E56B002C4FE5 /* jpeg.h */,
|
||||||
8378416118C6E56B002C4FE5 /* main_hle.c */,
|
|
||||||
8378416218C6E56B002C4FE5 /* main_hle.h */,
|
|
||||||
8378416318C6E56B002C4FE5 /* memory_hle.c */,
|
|
||||||
8378416418C6E56B002C4FE5 /* memory_hle.h */,
|
|
||||||
8378416518C6E56B002C4FE5 /* mp3.c */,
|
8378416518C6E56B002C4FE5 /* mp3.c */,
|
||||||
8378416618C6E56B002C4FE5 /* musyx.c */,
|
8378416618C6E56B002C4FE5 /* musyx.c */,
|
||||||
8378416718C6E56B002C4FE5 /* musyx.h */,
|
8378416718C6E56B002C4FE5 /* musyx.h */,
|
||||||
8378416818C6E56B002C4FE5 /* plugin_hle.c */,
|
|
||||||
8378416918C6E56B002C4FE5 /* plugin_hle.h */,
|
|
||||||
);
|
);
|
||||||
path = rsp_hle;
|
path = rsp_hle;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -413,10 +416,12 @@
|
||||||
83C8B6FA18AF58090071B040 /* usf.h in Headers */,
|
83C8B6FA18AF58090071B040 /* usf.h in Headers */,
|
||||||
83C8B6AC18AF58080071B040 /* audio.h in Headers */,
|
83C8B6AC18AF58080071B040 /* audio.h in Headers */,
|
||||||
8378416D18C6E56B002C4FE5 /* alist_internal.h in Headers */,
|
8378416D18C6E56B002C4FE5 /* alist_internal.h in Headers */,
|
||||||
|
837841C118C847B2002C4FE5 /* audio.h in Headers */,
|
||||||
8378417618C6E56B002C4FE5 /* jpeg.h in Headers */,
|
8378417618C6E56B002C4FE5 /* jpeg.h in Headers */,
|
||||||
83C8B6B118AF58080071B040 /* dma.h in Headers */,
|
83C8B6B118AF58080071B040 /* dma.h in Headers */,
|
||||||
|
83A2249518CAC28500FE4173 /* hle.h in Headers */,
|
||||||
83C8B6AD18AF58080071B040 /* config.h in Headers */,
|
83C8B6AD18AF58080071B040 /* config.h in Headers */,
|
||||||
8378417F18C6E56B002C4FE5 /* plugin_hle.h in Headers */,
|
83A2249318CAC28500FE4173 /* hle_internal.h in Headers */,
|
||||||
83C8B6B518AF58080071B040 /* interpreter_cpu.h in Headers */,
|
83C8B6B518AF58080071B040 /* interpreter_cpu.h in Headers */,
|
||||||
83C8B6B918AF58080071B040 /* main.h in Headers */,
|
83C8B6B918AF58080071B040 /* main.h in Headers */,
|
||||||
83C8B6F418AF58090071B040 /* rsp.h in Headers */,
|
83C8B6F418AF58090071B040 /* rsp.h in Headers */,
|
||||||
|
@ -430,16 +435,13 @@
|
||||||
83C8B6B718AF58080071B040 /* interpreter_ops.h in Headers */,
|
83C8B6B718AF58080071B040 /* interpreter_ops.h in Headers */,
|
||||||
83C8B6B318AF58080071B040 /* exception.h in Headers */,
|
83C8B6B318AF58080071B040 /* exception.h in Headers */,
|
||||||
83C8B6AF18AF58080071B040 /* cpu.h in Headers */,
|
83C8B6AF18AF58080071B040 /* cpu.h in Headers */,
|
||||||
8378417818C6E56B002C4FE5 /* main_hle.h in Headers */,
|
|
||||||
83C8B6F118AF58090071B040 /* vsubc.h in Headers */,
|
83C8B6F118AF58090071B040 /* vsubc.h in Headers */,
|
||||||
83C8B6F018AF58090071B040 /* vsub.h in Headers */,
|
83C8B6F018AF58090071B040 /* vsub.h in Headers */,
|
||||||
8378417218C6E56B002C4FE5 /* audio_hle.h in Headers */,
|
|
||||||
83C8B6E018AF58080071B040 /* vmudn.h in Headers */,
|
83C8B6E018AF58080071B040 /* vmudn.h in Headers */,
|
||||||
83C8B6EF18AF58090071B040 /* vsaw.h in Headers */,
|
83C8B6EF18AF58090071B040 /* vsaw.h in Headers */,
|
||||||
83C8B6C918AF58080071B040 /* shuffle.h in Headers */,
|
83C8B6C918AF58080071B040 /* shuffle.h in Headers */,
|
||||||
83C8B6DD18AF58080071B040 /* vmudh.h in Headers */,
|
83C8B6DD18AF58080071B040 /* vmudh.h in Headers */,
|
||||||
83C8B6E118AF58080071B040 /* vmulf.h in Headers */,
|
83C8B6E118AF58080071B040 /* vmulf.h in Headers */,
|
||||||
8378417A18C6E56B002C4FE5 /* memory_hle.h in Headers */,
|
|
||||||
83C8B6CE18AF58080071B040 /* vch.h in Headers */,
|
83C8B6CE18AF58080071B040 /* vch.h in Headers */,
|
||||||
83C8B6CB18AF58080071B040 /* vadd.h in Headers */,
|
83C8B6CB18AF58080071B040 /* vadd.h in Headers */,
|
||||||
83C8B6D618AF58080071B040 /* vmacu.h in Headers */,
|
83C8B6D618AF58080071B040 /* vmacu.h in Headers */,
|
||||||
|
@ -456,9 +458,11 @@
|
||||||
83C8B6D418AF58080071B040 /* vmacf.h in Headers */,
|
83C8B6D418AF58080071B040 /* vmacf.h in Headers */,
|
||||||
83C8B6DC18AF58080071B040 /* vmrg.h in Headers */,
|
83C8B6DC18AF58080071B040 /* vmrg.h in Headers */,
|
||||||
83C8B6C718AF58080071B040 /* clamp.h in Headers */,
|
83C8B6C718AF58080071B040 /* clamp.h in Headers */,
|
||||||
|
83A2249218CAC28500FE4173 /* hle_external.h in Headers */,
|
||||||
83C8B6D718AF58080071B040 /* vmadh.h in Headers */,
|
83C8B6D718AF58080071B040 /* vmadh.h in Headers */,
|
||||||
83C8B6F318AF58090071B040 /* vxor.h in Headers */,
|
83C8B6F318AF58090071B040 /* vxor.h in Headers */,
|
||||||
83C8B6EC18AF58090071B040 /* vrsq.h in Headers */,
|
83C8B6EC18AF58090071B040 /* vrsq.h in Headers */,
|
||||||
|
837841C518C847B2002C4FE5 /* memory.h in Headers */,
|
||||||
83C8B6D018AF58080071B040 /* vcr.h in Headers */,
|
83C8B6D018AF58080071B040 /* vcr.h in Headers */,
|
||||||
8378416B18C6E56B002C4FE5 /* alist.h in Headers */,
|
8378416B18C6E56B002C4FE5 /* alist.h in Headers */,
|
||||||
83C8B6EA18AF58090071B040 /* vrcph.h in Headers */,
|
83C8B6EA18AF58090071B040 /* vrcph.h in Headers */,
|
||||||
|
@ -552,15 +556,17 @@
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
837841C618C847B2002C4FE5 /* plugin.c in Sources */,
|
||||||
83C8B6F518AF58090071B040 /* tlb.c in Sources */,
|
83C8B6F518AF58090071B040 /* tlb.c in Sources */,
|
||||||
83C8B6C318AF58080071B040 /* rsp.c in Sources */,
|
83C8B6C318AF58080071B040 /* rsp.c in Sources */,
|
||||||
83C8B6BD18AF58080071B040 /* pif.c in Sources */,
|
83C8B6BD18AF58080071B040 /* pif.c in Sources */,
|
||||||
83C8B6B418AF58080071B040 /* interpreter_cpu.c in Sources */,
|
83C8B6B418AF58080071B040 /* interpreter_cpu.c in Sources */,
|
||||||
8378417118C6E56B002C4FE5 /* audio_hle.c in Sources */,
|
837841C018C847B2002C4FE5 /* audio.c in Sources */,
|
||||||
8378417518C6E56B002C4FE5 /* jpeg.c in Sources */,
|
8378417518C6E56B002C4FE5 /* jpeg.c in Sources */,
|
||||||
8378417C18C6E56B002C4FE5 /* musyx.c in Sources */,
|
8378417C18C6E56B002C4FE5 /* musyx.c in Sources */,
|
||||||
8378417B18C6E56B002C4FE5 /* mp3.c in Sources */,
|
8378417B18C6E56B002C4FE5 /* mp3.c in Sources */,
|
||||||
8378416F18C6E56B002C4FE5 /* alist_nead.c in Sources */,
|
8378416F18C6E56B002C4FE5 /* alist_nead.c in Sources */,
|
||||||
|
837841C418C847B2002C4FE5 /* memory.c in Sources */,
|
||||||
83C8B6B618AF58080071B040 /* interpreter_ops.c in Sources */,
|
83C8B6B618AF58080071B040 /* interpreter_ops.c in Sources */,
|
||||||
8378416C18C6E56B002C4FE5 /* alist_audio.c in Sources */,
|
8378416C18C6E56B002C4FE5 /* alist_audio.c in Sources */,
|
||||||
83C8B6BA18AF58080071B040 /* memory.c in Sources */,
|
83C8B6BA18AF58080071B040 /* memory.c in Sources */,
|
||||||
|
@ -569,13 +575,11 @@
|
||||||
8378416A18C6E56B002C4FE5 /* alist.c in Sources */,
|
8378416A18C6E56B002C4FE5 /* alist.c in Sources */,
|
||||||
83C8B6AE18AF58080071B040 /* cpu.c in Sources */,
|
83C8B6AE18AF58080071B040 /* cpu.c in Sources */,
|
||||||
83C8B6AB18AF58080071B040 /* audio.c in Sources */,
|
83C8B6AB18AF58080071B040 /* audio.c in Sources */,
|
||||||
|
83A2249418CAC28500FE4173 /* hle.c in Sources */,
|
||||||
8378416E18C6E56B002C4FE5 /* alist_naudio.c in Sources */,
|
8378416E18C6E56B002C4FE5 /* alist_naudio.c in Sources */,
|
||||||
8378417718C6E56B002C4FE5 /* main_hle.c in Sources */,
|
|
||||||
83C8B6B218AF58080071B040 /* exception.c in Sources */,
|
83C8B6B218AF58080071B040 /* exception.c in Sources */,
|
||||||
8378417918C6E56B002C4FE5 /* memory_hle.c in Sources */,
|
|
||||||
83C8B6BF18AF58080071B040 /* registers.c in Sources */,
|
83C8B6BF18AF58080071B040 /* registers.c in Sources */,
|
||||||
83C8B6F918AF58090071B040 /* usf.c in Sources */,
|
83C8B6F918AF58090071B040 /* usf.c in Sources */,
|
||||||
8378417E18C6E56B002C4FE5 /* plugin_hle.c in Sources */,
|
|
||||||
83C8B6B818AF58080071B040 /* main.c in Sources */,
|
83C8B6B818AF58080071B040 /* main.c in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
#include "rsp.h"
|
#include "rsp.h"
|
||||||
|
|
||||||
#include "../rsp_hle/main.h"
|
#include "../rsp_hle/hle.h"
|
||||||
|
|
||||||
void real_run_rsp(usf_state_t * state, uint32_t cycles)
|
void real_run_rsp(usf_state_t * state, uint32_t cycles)
|
||||||
{
|
{
|
||||||
|
@ -49,7 +49,7 @@ void real_run_rsp(usf_state_t * state, uint32_t cycles)
|
||||||
case 0x00000002: /* OSTask.type == M_AUDTASK */
|
case 0x00000002: /* OSTask.type == M_AUDTASK */
|
||||||
if (state->enable_hle_audio == 0)
|
if (state->enable_hle_audio == 0)
|
||||||
break;
|
break;
|
||||||
hle_execute(state);
|
hle_execute(&state->hle);
|
||||||
SP_STATUS_REG |= 0x00000203;
|
SP_STATUS_REG |= 0x00000203;
|
||||||
if (SP_STATUS_REG & 0x00000040) /* SP_STATUS_INTR_BREAK */
|
if (SP_STATUS_REG & 0x00000040) /* SP_STATUS_INTR_BREAK */
|
||||||
{
|
{
|
||||||
|
@ -80,5 +80,30 @@ int32_t init_rsp(usf_state_t * state)
|
||||||
state->CR[0xD] = &DPC_BUFBUSY_REG;
|
state->CR[0xD] = &DPC_BUFBUSY_REG;
|
||||||
state->CR[0xE] = &DPC_PIPEBUSY_REG;
|
state->CR[0xE] = &DPC_PIPEBUSY_REG;
|
||||||
state->CR[0xF] = &DPC_TMEM_REG;
|
state->CR[0xF] = &DPC_TMEM_REG;
|
||||||
|
|
||||||
|
hle_init(&state->hle,
|
||||||
|
state->N64MEM,
|
||||||
|
state->DMEM,
|
||||||
|
state->IMEM,
|
||||||
|
&MI_INTR_REG,
|
||||||
|
&SP_MEM_ADDR_REG,
|
||||||
|
&SP_DRAM_ADDR_REG,
|
||||||
|
&SP_RD_LEN_REG,
|
||||||
|
&SP_WR_LEN_REG,
|
||||||
|
&SP_STATUS_REG,
|
||||||
|
&SP_DMA_FULL_REG,
|
||||||
|
&SP_DMA_BUSY_REG,
|
||||||
|
&SP_PC_REG,
|
||||||
|
&SP_SEMAPHORE_REG,
|
||||||
|
&DPC_START_REG,
|
||||||
|
&DPC_END_REG,
|
||||||
|
&DPC_CURRENT_REG,
|
||||||
|
&DPC_STATUS_REG,
|
||||||
|
&DPC_CLOCK_REG,
|
||||||
|
&DPC_BUFBUSY_REG,
|
||||||
|
&DPC_PIPEBUSY_REG,
|
||||||
|
&DPC_TMEM_REG,
|
||||||
|
state);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#define _RSP_H_
|
#define _RSP_H_
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define INLINE __inline
|
#define INLINE __forceinline
|
||||||
#define NOINLINE __declspec(noinline)
|
#define NOINLINE __declspec(noinline)
|
||||||
#define ALIGNED _declspec(align(16))
|
#define ALIGNED _declspec(align(16))
|
||||||
#else
|
#else
|
||||||
|
@ -42,7 +42,7 @@ typedef unsigned char byte;
|
||||||
typedef uint32_t RCPREG;
|
typedef uint32_t RCPREG;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NOINLINE void message(usf_state_t * state, const char* body, int priority)
|
NOINLINE static void message(usf_state_t * state, const char* body, int priority)
|
||||||
{
|
{
|
||||||
(void)body;
|
(void)body;
|
||||||
(void)priority;
|
(void)priority;
|
||||||
|
@ -55,7 +55,7 @@ NOINLINE void message(usf_state_t * state, const char* body, int priority)
|
||||||
*/
|
*/
|
||||||
#define CHARACTERS_PER_LINE (80)
|
#define CHARACTERS_PER_LINE (80)
|
||||||
/* typical standard DOS text file limit per line */
|
/* typical standard DOS text file limit per line */
|
||||||
NOINLINE void update_conf(const char* source)
|
NOINLINE static void update_conf(const char* source)
|
||||||
{
|
{
|
||||||
(void)source;
|
(void)source;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ extern void step_SP_commands(usf_state_t * state, int PC, uint32_t inst);
|
||||||
#include "vu/vu.h"
|
#include "vu/vu.h"
|
||||||
|
|
||||||
/* Allocate the RSP CPU loop to its own functional space. */
|
/* Allocate the RSP CPU loop to its own functional space. */
|
||||||
NOINLINE extern void run_task(usf_state_t * state);
|
NOINLINE static void run_task(usf_state_t * state);
|
||||||
#include "execute.h"
|
#include "execute.h"
|
||||||
|
|
||||||
#ifdef SP_EXECUTE_LOG
|
#ifdef SP_EXECUTE_LOG
|
||||||
|
|
|
@ -44,7 +44,7 @@ NOINLINE static void res_S(usf_state_t * state)
|
||||||
|
|
||||||
#define SLOT_OFF (BASE_OFF + 0x000)
|
#define SLOT_OFF (BASE_OFF + 0x000)
|
||||||
#define LINK_OFF (BASE_OFF + 0x004)
|
#define LINK_OFF (BASE_OFF + 0x004)
|
||||||
void set_PC(usf_state_t * state, int address)
|
static void set_PC(usf_state_t * state, int address)
|
||||||
{
|
{
|
||||||
state->temp_PC = 0x04001000 + (address & 0xFFC);
|
state->temp_PC = 0x04001000 + (address & 0xFFC);
|
||||||
#ifndef EMULATE_STATIC_PC
|
#ifndef EMULATE_STATIC_PC
|
||||||
|
@ -72,11 +72,11 @@ void set_PC(usf_state_t * state, int address)
|
||||||
#define WES(address) ((address) ^ ((ENDIAN) & 00))
|
#define WES(address) ((address) ^ ((ENDIAN) & 00))
|
||||||
#define SR_B(s, i) (*(byte *)(((byte *)(state->SR + s)) + BES(i)))
|
#define SR_B(s, i) (*(byte *)(((byte *)(state->SR + s)) + BES(i)))
|
||||||
#define SR_S(s, i) (*(short *)(((byte *)(state->SR + s)) + HES(i)))
|
#define SR_S(s, i) (*(short *)(((byte *)(state->SR + s)) + HES(i)))
|
||||||
#define SE(x, b) (-(x & (1 << b)) | (x & ~(~0 << b)))
|
#define SE(x, b) (-((signed int)x & (1 << b)) | (x & ~(~0 << b)))
|
||||||
#define ZE(x, b) (+(x & (1 << b)) | (x & ~(~0 << b)))
|
#define ZE(x, b) (+(x & (1 << b)) | (x & ~(~0 << b)))
|
||||||
|
|
||||||
extern void ULW(usf_state_t *, int rd, uint32_t addr);
|
static void ULW(usf_state_t *, int rd, uint32_t addr);
|
||||||
extern void USW(usf_state_t *, int rs, uint32_t addr);
|
static void USW(usf_state_t *, int rs, uint32_t addr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All other behaviors defined below this point in the file are specific to
|
* All other behaviors defined below this point in the file are specific to
|
||||||
|
@ -320,21 +320,21 @@ void SP_DMA_WRITE(usf_state_t * state)
|
||||||
*/
|
*/
|
||||||
#define VR_S(vt,element) (*(short *)((byte *)(state->VR[vt]) + element))
|
#define VR_S(vt,element) (*(short *)((byte *)(state->VR[vt]) + element))
|
||||||
|
|
||||||
extern unsigned short get_VCO(usf_state_t * state);
|
static unsigned short get_VCO(usf_state_t * state);
|
||||||
extern unsigned short get_VCC(usf_state_t * state);
|
static unsigned short get_VCC(usf_state_t * state);
|
||||||
extern unsigned char get_VCE(usf_state_t * state);
|
static unsigned char get_VCE(usf_state_t * state);
|
||||||
extern void set_VCO(usf_state_t * state, unsigned short VCO);
|
static void set_VCO(usf_state_t * state, unsigned short VCO);
|
||||||
extern void set_VCC(usf_state_t * state, unsigned short VCC);
|
static void set_VCC(usf_state_t * state, unsigned short VCC);
|
||||||
extern void set_VCE(usf_state_t * state, unsigned char VCE);
|
static void set_VCE(usf_state_t * state, unsigned char VCE);
|
||||||
|
|
||||||
unsigned short rwR_VCE(usf_state_t * state)
|
static unsigned short rwR_VCE(usf_state_t * state)
|
||||||
{ /* never saw a game try to read VCE out to a scalar GPR yet */
|
{ /* never saw a game try to read VCE out to a scalar GPR yet */
|
||||||
register unsigned short ret_slot;
|
register unsigned short ret_slot;
|
||||||
|
|
||||||
ret_slot = 0x00 | (unsigned short)get_VCE(state);
|
ret_slot = 0x00 | (unsigned short)get_VCE(state);
|
||||||
return (ret_slot);
|
return (ret_slot);
|
||||||
}
|
}
|
||||||
void rwW_VCE(usf_state_t * state, unsigned short VCE)
|
static void rwW_VCE(usf_state_t * state, unsigned short VCE)
|
||||||
{ /* never saw a game try to write VCE using a scalar GPR yet */
|
{ /* never saw a game try to write VCE using a scalar GPR yet */
|
||||||
register int i;
|
register int i;
|
||||||
|
|
||||||
|
|
|
@ -21,19 +21,20 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#else
|
||||||
|
#include "mystdbool.h"
|
||||||
|
#endif
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../usf.h"
|
|
||||||
|
|
||||||
#include "alist_internal.h"
|
#include "alist_internal.h"
|
||||||
#include "arithmetics.h"
|
#include "arithmetics.h"
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
|
#include "hle_external.h"
|
||||||
|
#include "hle_internal.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "plugin.h"
|
|
||||||
|
|
||||||
#include "../usf_internal.h"
|
|
||||||
|
|
||||||
struct ramp_t
|
struct ramp_t
|
||||||
{
|
{
|
||||||
|
@ -50,9 +51,9 @@ static void swap(int16_t **a, int16_t **b)
|
||||||
*a = tmp;
|
*a = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int16_t* sample(usf_state_t * state, unsigned pos)
|
static int16_t* sample(struct hle_t* hle, unsigned pos)
|
||||||
{
|
{
|
||||||
return (int16_t*)state->BufferSpace + (pos ^ S);
|
return (int16_t*)hle->alist_buffer + (pos ^ S);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sample_mix(int16_t* dst, int16_t src, int16_t gain)
|
static void sample_mix(int16_t* dst, int16_t src, int16_t gain)
|
||||||
|
@ -70,11 +71,13 @@ static void alist_envmix_mix(size_t n, int16_t** dst, const int16_t* gains, int1
|
||||||
|
|
||||||
static int16_t ramp_step(struct ramp_t* ramp)
|
static int16_t ramp_step(struct ramp_t* ramp)
|
||||||
{
|
{
|
||||||
|
bool target_reached;
|
||||||
|
|
||||||
ramp->value += ramp->step;
|
ramp->value += ramp->step;
|
||||||
|
|
||||||
bool target_reached = (ramp->step <= 0)
|
target_reached = (ramp->step <= 0)
|
||||||
? (ramp->value <= ramp->target)
|
? (ramp->value <= ramp->target)
|
||||||
: (ramp->value >= ramp->target);
|
: (ramp->value >= ramp->target);
|
||||||
|
|
||||||
if (target_reached)
|
if (target_reached)
|
||||||
{
|
{
|
||||||
|
@ -82,17 +85,17 @@ static int16_t ramp_step(struct ramp_t* ramp)
|
||||||
ramp->step = 0;
|
ramp->step = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ramp->value >> 16);
|
return (int16_t)(ramp->value >> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* global functions */
|
/* global functions */
|
||||||
void alist_process(usf_state_t* state, const acmd_callback_t abi[], unsigned int abi_size)
|
void alist_process(struct hle_t* hle, const acmd_callback_t abi[], unsigned int abi_size)
|
||||||
{
|
{
|
||||||
uint32_t w1, w2;
|
uint32_t w1, w2;
|
||||||
unsigned int acmd;
|
unsigned int acmd;
|
||||||
|
|
||||||
const uint32_t *alist = dram_u32(state, *dmem_u32(state, TASK_DATA_PTR));
|
const uint32_t *alist = dram_u32(hle, *dmem_u32(hle, TASK_DATA_PTR));
|
||||||
const uint32_t *const alist_end = alist + (*dmem_u32(state, TASK_DATA_SIZE) >> 2);
|
const uint32_t *const alist_end = alist + (*dmem_u32(hle, TASK_DATA_SIZE) >> 2);
|
||||||
|
|
||||||
while (alist != alist_end) {
|
while (alist != alist_end) {
|
||||||
w1 = *(alist++);
|
w1 = *(alist++);
|
||||||
|
@ -101,96 +104,96 @@ void alist_process(usf_state_t* state, const acmd_callback_t abi[], unsigned int
|
||||||
acmd = (w1 >> 24) & 0x7f;
|
acmd = (w1 >> 24) & 0x7f;
|
||||||
|
|
||||||
if (acmd < abi_size)
|
if (acmd < abi_size)
|
||||||
(*abi[acmd])(state, w1, w2);
|
(*abi[acmd])(hle, w1, w2);
|
||||||
else
|
else
|
||||||
DebugMessage(state, M64MSG_WARNING, "Invalid ABI command %u", acmd);
|
HleWarnMessage(hle->user_defined, "Invalid ABI command %u", acmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t alist_get_address(usf_state_t* state, uint32_t so, const uint32_t *segments, size_t n)
|
uint32_t alist_get_address(struct hle_t* hle, uint32_t so, const uint32_t *segments, size_t n)
|
||||||
{
|
{
|
||||||
uint8_t segment = (so >> 24);
|
uint8_t segment = (so >> 24);
|
||||||
uint32_t offset = (so & 0xffffff);
|
uint32_t offset = (so & 0xffffff);
|
||||||
|
|
||||||
if (segment >= n) {
|
if (segment >= n) {
|
||||||
DebugMessage(state, M64MSG_WARNING, "Invalid segment %u", segment);
|
HleWarnMessage(hle->user_defined, "Invalid segment %u", segment);
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return segments[segment] + offset;
|
return segments[segment] + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_set_address(usf_state_t* state, uint32_t so, uint32_t *segments, size_t n)
|
void alist_set_address(struct hle_t* hle, uint32_t so, uint32_t *segments, size_t n)
|
||||||
{
|
{
|
||||||
uint8_t segment = (so >> 24);
|
uint8_t segment = (so >> 24);
|
||||||
uint32_t offset = (so & 0xffffff);
|
uint32_t offset = (so & 0xffffff);
|
||||||
|
|
||||||
if (segment >= n) {
|
if (segment >= n) {
|
||||||
DebugMessage(state, M64MSG_WARNING, "Invalid segment %u", segment);
|
HleWarnMessage(hle->user_defined, "Invalid segment %u", segment);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
segments[segment] = offset;
|
segments[segment] = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_clear(usf_state_t* state, uint16_t dmem, uint16_t count)
|
void alist_clear(struct hle_t* hle, uint16_t dmem, uint16_t count)
|
||||||
{
|
{
|
||||||
while(count != 0) {
|
while(count != 0) {
|
||||||
state->BufferSpace[(dmem++)^S8] = 0;
|
hle->alist_buffer[(dmem++)^S8] = 0;
|
||||||
--count;
|
--count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_load(usf_state_t* state, uint16_t dmem, uint32_t address, uint16_t count)
|
void alist_load(struct hle_t* hle, uint16_t dmem, uint32_t address, uint16_t count)
|
||||||
{
|
{
|
||||||
/* enforce DMA alignment constraints */
|
/* enforce DMA alignment constraints */
|
||||||
dmem &= ~3;
|
dmem &= ~3;
|
||||||
address &= ~7;
|
address &= ~7;
|
||||||
count = align(count, 8);
|
count = align(count, 8);
|
||||||
memcpy(state->BufferSpace + dmem, state->N64MEM + address, count);
|
memcpy(hle->alist_buffer + dmem, hle->dram + address, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_save(usf_state_t* state, uint16_t dmem, uint32_t address, uint16_t count)
|
void alist_save(struct hle_t* hle, uint16_t dmem, uint32_t address, uint16_t count)
|
||||||
{
|
{
|
||||||
/* enforce DMA alignment constraints */
|
/* enforce DMA alignment constraints */
|
||||||
dmem &= ~3;
|
dmem &= ~3;
|
||||||
address &= ~7;
|
address &= ~7;
|
||||||
count = align(count, 8);
|
count = align(count, 8);
|
||||||
memcpy(state->N64MEM + address, state->BufferSpace + dmem, count);
|
memcpy(hle->dram + address, hle->alist_buffer + dmem, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_move(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint16_t count)
|
void alist_move(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count)
|
||||||
{
|
{
|
||||||
while (count != 0) {
|
while (count != 0) {
|
||||||
state->BufferSpace[(dmemo++)^S8] = state->BufferSpace[(dmemi++)^S8];
|
hle->alist_buffer[(dmemo++)^S8] = hle->alist_buffer[(dmemi++)^S8];
|
||||||
--count;
|
--count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_copy_every_other_sample(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint16_t count)
|
void alist_copy_every_other_sample(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count)
|
||||||
{
|
{
|
||||||
while (count != 0) {
|
while (count != 0) {
|
||||||
*(uint16_t*)(state->BufferSpace + (dmemo^S8)) = *(uint16_t*)(state->BufferSpace + (dmemi^S8));
|
*(uint16_t*)(hle->alist_buffer + (dmemo^S8)) = *(uint16_t*)(hle->alist_buffer + (dmemi^S8));
|
||||||
dmemo += 2;
|
dmemo += 2;
|
||||||
dmemi += 4;
|
dmemi += 4;
|
||||||
--count;
|
--count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_repeat64(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint8_t count)
|
void alist_repeat64(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint8_t count)
|
||||||
{
|
{
|
||||||
uint16_t buffer[64];
|
uint16_t buffer[64];
|
||||||
|
|
||||||
memcpy(buffer, state->BufferSpace + dmemi, 128);
|
memcpy(buffer, hle->alist_buffer + dmemi, 128);
|
||||||
|
|
||||||
while(count != 0) {
|
while(count != 0) {
|
||||||
memcpy(state->BufferSpace + dmemo, buffer, 128);
|
memcpy(hle->alist_buffer + dmemo, buffer, 128);
|
||||||
dmemo += 128;
|
dmemo += 128;
|
||||||
--count;
|
--count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_copy_blocks(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint16_t block_size, uint8_t count)
|
void alist_copy_blocks(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t block_size, uint8_t count)
|
||||||
{
|
{
|
||||||
int block_left = count;
|
int block_left = count;
|
||||||
|
|
||||||
|
@ -200,7 +203,7 @@ void alist_copy_blocks(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint1
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
memcpy(state->BufferSpace + dmemo, state->BufferSpace + dmemi, 0x20);
|
memcpy(hle->alist_buffer + dmemo, hle->alist_buffer + dmemi, 0x20);
|
||||||
bytes_left -= 0x20;
|
bytes_left -= 0x20;
|
||||||
|
|
||||||
dmemi += 0x20;
|
dmemi += 0x20;
|
||||||
|
@ -212,11 +215,11 @@ void alist_copy_blocks(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint1
|
||||||
} while(block_left > 0);
|
} while(block_left > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_interleave(usf_state_t* state, uint16_t dmemo, uint16_t left, uint16_t right, uint16_t count)
|
void alist_interleave(struct hle_t* hle, uint16_t dmemo, uint16_t left, uint16_t right, uint16_t count)
|
||||||
{
|
{
|
||||||
uint16_t *dst = (uint16_t*)(state->BufferSpace + dmemo);
|
uint16_t *dst = (uint16_t*)(hle->alist_buffer + dmemo);
|
||||||
const uint16_t *srcL = (uint16_t*)(state->BufferSpace + left);
|
const uint16_t *srcL = (uint16_t*)(hle->alist_buffer + left);
|
||||||
const uint16_t *srcR = (uint16_t*)(state->BufferSpace + right);
|
const uint16_t *srcR = (uint16_t*)(hle->alist_buffer + right);
|
||||||
|
|
||||||
count >>= 2;
|
count >>= 2;
|
||||||
|
|
||||||
|
@ -243,7 +246,7 @@ void alist_interleave(usf_state_t* state, uint16_t dmemo, uint16_t left, uint16_
|
||||||
|
|
||||||
|
|
||||||
void alist_envmix_exp(
|
void alist_envmix_exp(
|
||||||
usf_state_t* state,
|
struct hle_t* hle,
|
||||||
bool init,
|
bool init,
|
||||||
bool aux,
|
bool aux,
|
||||||
uint16_t dmem_dl, uint16_t dmem_dr,
|
uint16_t dmem_dl, uint16_t dmem_dr,
|
||||||
|
@ -257,11 +260,11 @@ void alist_envmix_exp(
|
||||||
{
|
{
|
||||||
size_t n = (aux) ? 4 : 2;
|
size_t n = (aux) ? 4 : 2;
|
||||||
|
|
||||||
const int16_t* const in = (int16_t*)(state->BufferSpace + dmemi);
|
const int16_t* const in = (int16_t*)(hle->alist_buffer + dmemi);
|
||||||
int16_t* const dl = (int16_t*)(state->BufferSpace + dmem_dl);
|
int16_t* const dl = (int16_t*)(hle->alist_buffer + dmem_dl);
|
||||||
int16_t* const dr = (int16_t*)(state->BufferSpace + dmem_dr);
|
int16_t* const dr = (int16_t*)(hle->alist_buffer + dmem_dr);
|
||||||
int16_t* const wl = (int16_t*)(state->BufferSpace + dmem_wl);
|
int16_t* const wl = (int16_t*)(hle->alist_buffer + dmem_wl);
|
||||||
int16_t* const wr = (int16_t*)(state->BufferSpace + dmem_wr);
|
int16_t* const wr = (int16_t*)(hle->alist_buffer + dmem_wr);
|
||||||
|
|
||||||
struct ramp_t ramps[2];
|
struct ramp_t ramps[2];
|
||||||
int32_t exp_seq[2];
|
int32_t exp_seq[2];
|
||||||
|
@ -281,7 +284,7 @@ void alist_envmix_exp(
|
||||||
exp_seq[0] = (vol[0] * rate[0]);
|
exp_seq[0] = (vol[0] * rate[0]);
|
||||||
exp_seq[1] = (vol[1] * rate[1]);
|
exp_seq[1] = (vol[1] * rate[1]);
|
||||||
} else {
|
} else {
|
||||||
memcpy((uint8_t *)save_buffer, (state->N64MEM + address), 80);
|
memcpy((uint8_t *)save_buffer, (hle->dram + address), 80);
|
||||||
wet = *(int16_t *)(save_buffer + 0); /* 0-1 */
|
wet = *(int16_t *)(save_buffer + 0); /* 0-1 */
|
||||||
dry = *(int16_t *)(save_buffer + 2); /* 2-3 */
|
dry = *(int16_t *)(save_buffer + 2); /* 2-3 */
|
||||||
ramps[0].target = *(int32_t *)(save_buffer + 4); /* 4-5 */
|
ramps[0].target = *(int32_t *)(save_buffer + 4); /* 4-5 */
|
||||||
|
@ -335,19 +338,19 @@ void alist_envmix_exp(
|
||||||
|
|
||||||
*(int16_t *)(save_buffer + 0) = wet; /* 0-1 */
|
*(int16_t *)(save_buffer + 0) = wet; /* 0-1 */
|
||||||
*(int16_t *)(save_buffer + 2) = dry; /* 2-3 */
|
*(int16_t *)(save_buffer + 2) = dry; /* 2-3 */
|
||||||
*(int32_t *)(save_buffer + 4) = ramps[0].target; /* 4-5 */
|
*(int32_t *)(save_buffer + 4) = (int32_t)ramps[0].target; /* 4-5 */
|
||||||
*(int32_t *)(save_buffer + 6) = ramps[1].target; /* 6-7 */
|
*(int32_t *)(save_buffer + 6) = (int32_t)ramps[1].target; /* 6-7 */
|
||||||
*(int32_t *)(save_buffer + 8) = exp_rates[0]; /* 8-9 (save_buffer is a 16bit pointer) */
|
*(int32_t *)(save_buffer + 8) = exp_rates[0]; /* 8-9 (save_buffer is a 16bit pointer) */
|
||||||
*(int32_t *)(save_buffer + 10) = exp_rates[1]; /* 10-11 */
|
*(int32_t *)(save_buffer + 10) = exp_rates[1]; /* 10-11 */
|
||||||
*(int32_t *)(save_buffer + 12) = exp_seq[0]; /* 12-13 */
|
*(int32_t *)(save_buffer + 12) = exp_seq[0]; /* 12-13 */
|
||||||
*(int32_t *)(save_buffer + 14) = exp_seq[1]; /* 14-15 */
|
*(int32_t *)(save_buffer + 14) = exp_seq[1]; /* 14-15 */
|
||||||
*(int32_t *)(save_buffer + 16) = ramps[0].value; /* 12-13 */
|
*(int32_t *)(save_buffer + 16) = (int32_t)ramps[0].value; /* 12-13 */
|
||||||
*(int32_t *)(save_buffer + 18) = ramps[1].value; /* 14-15 */
|
*(int32_t *)(save_buffer + 18) = (int32_t)ramps[1].value; /* 14-15 */
|
||||||
memcpy(state->N64MEM + address, (uint8_t *)save_buffer, 80);
|
memcpy(hle->dram + address, (uint8_t *)save_buffer, 80);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_envmix_lin(
|
void alist_envmix_lin(
|
||||||
usf_state_t* state,
|
struct hle_t* hle,
|
||||||
bool init,
|
bool init,
|
||||||
uint16_t dmem_dl, uint16_t dmem_dr,
|
uint16_t dmem_dl, uint16_t dmem_dr,
|
||||||
uint16_t dmem_wl, uint16_t dmem_wr,
|
uint16_t dmem_wl, uint16_t dmem_wr,
|
||||||
|
@ -362,11 +365,11 @@ void alist_envmix_lin(
|
||||||
struct ramp_t ramps[2];
|
struct ramp_t ramps[2];
|
||||||
int16_t save_buffer[40];
|
int16_t save_buffer[40];
|
||||||
|
|
||||||
const int16_t * const in = (int16_t*)(state->BufferSpace + dmemi);
|
const int16_t * const in = (int16_t*)(hle->alist_buffer + dmemi);
|
||||||
int16_t* const dl = (int16_t*)(state->BufferSpace + dmem_dl);
|
int16_t* const dl = (int16_t*)(hle->alist_buffer + dmem_dl);
|
||||||
int16_t* const dr = (int16_t*)(state->BufferSpace + dmem_dr);
|
int16_t* const dr = (int16_t*)(hle->alist_buffer + dmem_dr);
|
||||||
int16_t* const wl = (int16_t*)(state->BufferSpace + dmem_wl);
|
int16_t* const wl = (int16_t*)(hle->alist_buffer + dmem_wl);
|
||||||
int16_t* const wr = (int16_t*)(state->BufferSpace + dmem_wr);
|
int16_t* const wr = (int16_t*)(hle->alist_buffer + dmem_wr);
|
||||||
|
|
||||||
if (init) {
|
if (init) {
|
||||||
ramps[0].step = rate[0] / 8;
|
ramps[0].step = rate[0] / 8;
|
||||||
|
@ -377,7 +380,7 @@ void alist_envmix_lin(
|
||||||
ramps[1].target = (target[1] << 16);
|
ramps[1].target = (target[1] << 16);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memcpy((uint8_t *)save_buffer, state->N64MEM + address, 80);
|
memcpy((uint8_t *)save_buffer, hle->dram + address, 80);
|
||||||
wet = *(int16_t *)(save_buffer + 0); /* 0-1 */
|
wet = *(int16_t *)(save_buffer + 0); /* 0-1 */
|
||||||
dry = *(int16_t *)(save_buffer + 2); /* 2-3 */
|
dry = *(int16_t *)(save_buffer + 2); /* 2-3 */
|
||||||
ramps[0].target = *(int16_t *)(save_buffer + 4) << 16; /* 4-5 */
|
ramps[0].target = *(int16_t *)(save_buffer + 4) << 16; /* 4-5 */
|
||||||
|
@ -410,17 +413,17 @@ void alist_envmix_lin(
|
||||||
|
|
||||||
*(int16_t *)(save_buffer + 0) = wet; /* 0-1 */
|
*(int16_t *)(save_buffer + 0) = wet; /* 0-1 */
|
||||||
*(int16_t *)(save_buffer + 2) = dry; /* 2-3 */
|
*(int16_t *)(save_buffer + 2) = dry; /* 2-3 */
|
||||||
*(int16_t *)(save_buffer + 4) = ramps[0].target >> 16; /* 4-5 */
|
*(int16_t *)(save_buffer + 4) = (int16_t)ramps[0].target >> 16; /* 4-5 */
|
||||||
*(int16_t *)(save_buffer + 6) = ramps[1].target >> 16; /* 6-7 */
|
*(int16_t *)(save_buffer + 6) = (int16_t)ramps[1].target >> 16; /* 6-7 */
|
||||||
*(int32_t *)(save_buffer + 8) = ramps[0].step; /* 8-9 (save_buffer is a 16bit pointer) */
|
*(int32_t *)(save_buffer + 8) = (int32_t)ramps[0].step; /* 8-9 (save_buffer is a 16bit pointer) */
|
||||||
*(int32_t *)(save_buffer + 10) = ramps[1].step; /* 10-11 */
|
*(int32_t *)(save_buffer + 10) = (int32_t)ramps[1].step; /* 10-11 */
|
||||||
*(int32_t *)(save_buffer + 16) = ramps[0].value; /* 16-17 */
|
*(int32_t *)(save_buffer + 16) = (int32_t)ramps[0].value; /* 16-17 */
|
||||||
*(int32_t *)(save_buffer + 18) = ramps[1].value; /* 18-19 */
|
*(int32_t *)(save_buffer + 18) = (int32_t)ramps[1].value; /* 18-19 */
|
||||||
memcpy(state->N64MEM + address, (uint8_t *)save_buffer, 80);
|
memcpy(hle->dram + address, (uint8_t *)save_buffer, 80);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_envmix_nead(
|
void alist_envmix_nead(
|
||||||
usf_state_t* state,
|
struct hle_t* hle,
|
||||||
bool swap_wet_LR,
|
bool swap_wet_LR,
|
||||||
uint16_t dmem_dl,
|
uint16_t dmem_dl,
|
||||||
uint16_t dmem_dr,
|
uint16_t dmem_dr,
|
||||||
|
@ -432,15 +435,15 @@ void alist_envmix_nead(
|
||||||
uint16_t *env_steps,
|
uint16_t *env_steps,
|
||||||
const int16_t *xors)
|
const int16_t *xors)
|
||||||
{
|
{
|
||||||
|
int16_t *in = (int16_t*)(hle->alist_buffer + dmemi);
|
||||||
|
int16_t *dl = (int16_t*)(hle->alist_buffer + dmem_dl);
|
||||||
|
int16_t *dr = (int16_t*)(hle->alist_buffer + dmem_dr);
|
||||||
|
int16_t *wl = (int16_t*)(hle->alist_buffer + dmem_wl);
|
||||||
|
int16_t *wr = (int16_t*)(hle->alist_buffer + dmem_wr);
|
||||||
|
|
||||||
/* make sure count is a multiple of 8 */
|
/* make sure count is a multiple of 8 */
|
||||||
count = align(count, 8);
|
count = align(count, 8);
|
||||||
|
|
||||||
int16_t *in = (int16_t*)(state->BufferSpace + dmemi);
|
|
||||||
int16_t *dl = (int16_t*)(state->BufferSpace + dmem_dl);
|
|
||||||
int16_t *dr = (int16_t*)(state->BufferSpace + dmem_dr);
|
|
||||||
int16_t *wl = (int16_t*)(state->BufferSpace + dmem_wl);
|
|
||||||
int16_t *wr = (int16_t*)(state->BufferSpace + dmem_wr);
|
|
||||||
|
|
||||||
if (swap_wet_LR)
|
if (swap_wet_LR)
|
||||||
swap(&wl, &wr);
|
swap(&wl, &wr);
|
||||||
|
|
||||||
|
@ -472,10 +475,10 @@ void alist_envmix_nead(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void alist_mix(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t gain)
|
void alist_mix(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t gain)
|
||||||
{
|
{
|
||||||
int16_t *dst = (int16_t*)(state->BufferSpace + dmemo);
|
int16_t *dst = (int16_t*)(hle->alist_buffer + dmemo);
|
||||||
const int16_t *src = (int16_t*)(state->BufferSpace + dmemi);
|
const int16_t *src = (int16_t*)(hle->alist_buffer + dmemi);
|
||||||
|
|
||||||
count >>= 1;
|
count >>= 1;
|
||||||
|
|
||||||
|
@ -488,9 +491,9 @@ void alist_mix(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint16_t coun
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_multQ44(usf_state_t* state, uint16_t dmem, uint16_t count, int8_t gain)
|
void alist_multQ44(struct hle_t* hle, uint16_t dmem, uint16_t count, int8_t gain)
|
||||||
{
|
{
|
||||||
int16_t *dst = (int16_t*)(state->BufferSpace + dmem);
|
int16_t *dst = (int16_t*)(hle->alist_buffer + dmem);
|
||||||
|
|
||||||
count >>= 1;
|
count >>= 1;
|
||||||
|
|
||||||
|
@ -502,10 +505,10 @@ void alist_multQ44(usf_state_t* state, uint16_t dmem, uint16_t count, int8_t gai
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_add(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint16_t count)
|
void alist_add(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count)
|
||||||
{
|
{
|
||||||
int16_t *dst = (int16_t*)(state->BufferSpace + dmemo);
|
int16_t *dst = (int16_t*)(hle->alist_buffer + dmemo);
|
||||||
const int16_t *src = (int16_t*)(state->BufferSpace + dmemi);
|
const int16_t *src = (int16_t*)(hle->alist_buffer + dmemi);
|
||||||
|
|
||||||
count >>= 1;
|
count >>= 1;
|
||||||
|
|
||||||
|
@ -518,38 +521,38 @@ void alist_add(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint16_t coun
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void alist_resample_reset(usf_state_t* state, uint16_t pos, uint32_t* pitch_accu)
|
static void alist_resample_reset(struct hle_t* hle, uint16_t pos, uint32_t* pitch_accu)
|
||||||
{
|
{
|
||||||
unsigned k;
|
unsigned k;
|
||||||
|
|
||||||
for(k = 0; k < 4; ++k)
|
for(k = 0; k < 4; ++k)
|
||||||
*sample(state, pos + k) = 0;
|
*sample(hle, pos + k) = 0;
|
||||||
|
|
||||||
*pitch_accu = 0;
|
*pitch_accu = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void alist_resample_load(usf_state_t* state, uint32_t address, uint16_t pos, uint32_t* pitch_accu)
|
static void alist_resample_load(struct hle_t* hle, uint32_t address, uint16_t pos, uint32_t* pitch_accu)
|
||||||
{
|
{
|
||||||
*sample(state, pos + 0) = *dram_u16(state, address + 0);
|
*sample(hle, pos + 0) = *dram_u16(hle, address + 0);
|
||||||
*sample(state, pos + 1) = *dram_u16(state, address + 2);
|
*sample(hle, pos + 1) = *dram_u16(hle, address + 2);
|
||||||
*sample(state, pos + 2) = *dram_u16(state, address + 4);
|
*sample(hle, pos + 2) = *dram_u16(hle, address + 4);
|
||||||
*sample(state, pos + 3) = *dram_u16(state, address + 6);
|
*sample(hle, pos + 3) = *dram_u16(hle, address + 6);
|
||||||
|
|
||||||
*pitch_accu = *dram_u16(state, address + 8);
|
*pitch_accu = *dram_u16(hle, address + 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void alist_resample_save(usf_state_t* state, uint32_t address, uint16_t pos, uint32_t pitch_accu)
|
static void alist_resample_save(struct hle_t* hle, uint32_t address, uint16_t pos, uint32_t pitch_accu)
|
||||||
{
|
{
|
||||||
*dram_u16(state, address + 0) = *sample(state, pos + 0);
|
*dram_u16(hle, address + 0) = *sample(hle, pos + 0);
|
||||||
*dram_u16(state, address + 2) = *sample(state, pos + 1);
|
*dram_u16(hle, address + 2) = *sample(hle, pos + 1);
|
||||||
*dram_u16(state, address + 4) = *sample(state, pos + 2);
|
*dram_u16(hle, address + 4) = *sample(hle, pos + 2);
|
||||||
*dram_u16(state, address + 6) = *sample(state, pos + 3);
|
*dram_u16(hle, address + 6) = *sample(hle, pos + 3);
|
||||||
|
|
||||||
*dram_u16(state, address + 8) = pitch_accu;
|
*dram_u16(hle, address + 8) = pitch_accu;
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_resample(
|
void alist_resample(
|
||||||
usf_state_t* state,
|
struct hle_t* hle,
|
||||||
bool init,
|
bool init,
|
||||||
bool flag2,
|
bool flag2,
|
||||||
uint16_t dmemo,
|
uint16_t dmemo,
|
||||||
|
@ -566,21 +569,21 @@ void alist_resample(
|
||||||
ipos -= 4;
|
ipos -= 4;
|
||||||
|
|
||||||
if (flag2)
|
if (flag2)
|
||||||
DebugMessage(state, M64MSG_WARNING, "alist_resample: flag2 is not implemented");
|
HleWarnMessage(hle->user_defined, "alist_resample: flag2 is not implemented");
|
||||||
|
|
||||||
if (init)
|
if (init)
|
||||||
alist_resample_reset(state, ipos, &pitch_accu);
|
alist_resample_reset(hle, ipos, &pitch_accu);
|
||||||
else
|
else
|
||||||
alist_resample_load(state, address, ipos, &pitch_accu);
|
alist_resample_load(hle, address, ipos, &pitch_accu);
|
||||||
|
|
||||||
while (count != 0) {
|
while (count != 0) {
|
||||||
const int16_t* lut = RESAMPLE_LUT + ((pitch_accu & 0xfc00) >> 8);
|
const int16_t* lut = RESAMPLE_LUT + ((pitch_accu & 0xfc00) >> 8);
|
||||||
|
|
||||||
*sample(state, opos++) = clamp_s16(
|
*sample(hle, opos++) = clamp_s16(
|
||||||
((*sample(state, ipos ) * lut[0]) >> 15) +
|
((*sample(hle, ipos ) * lut[0]) >> 15) +
|
||||||
((*sample(state, ipos + 1) * lut[1]) >> 15) +
|
((*sample(hle, ipos + 1) * lut[1]) >> 15) +
|
||||||
((*sample(state, ipos + 2) * lut[2]) >> 15) +
|
((*sample(hle, ipos + 2) * lut[2]) >> 15) +
|
||||||
((*sample(state, ipos + 3) * lut[3]) >> 15));
|
((*sample(hle, ipos + 3) * lut[3]) >> 15));
|
||||||
|
|
||||||
pitch_accu += pitch;
|
pitch_accu += pitch;
|
||||||
ipos += (pitch_accu >> 16);
|
ipos += (pitch_accu >> 16);
|
||||||
|
@ -588,11 +591,11 @@ void alist_resample(
|
||||||
--count;
|
--count;
|
||||||
}
|
}
|
||||||
|
|
||||||
alist_resample_save(state, address, ipos, pitch_accu);
|
alist_resample_save(hle, address, ipos, pitch_accu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_resample_zoh(
|
void alist_resample_zoh(
|
||||||
usf_state_t* state,
|
struct hle_t* hle,
|
||||||
uint16_t dmemo,
|
uint16_t dmemo,
|
||||||
uint16_t dmemi,
|
uint16_t dmemi,
|
||||||
uint16_t count,
|
uint16_t count,
|
||||||
|
@ -605,7 +608,7 @@ void alist_resample_zoh(
|
||||||
|
|
||||||
while(count != 0) {
|
while(count != 0) {
|
||||||
|
|
||||||
*sample(state, opos++) = *sample(state, ipos);
|
*sample(hle, opos++) = *sample(hle, ipos);
|
||||||
|
|
||||||
pitch_accu += pitch;
|
pitch_accu += pitch;
|
||||||
ipos += (pitch_accu >> 16);
|
ipos += (pitch_accu >> 16);
|
||||||
|
@ -614,15 +617,17 @@ void alist_resample_zoh(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef unsigned int (*adpcm_predict_frame_t)(usf_state_t* state, int16_t* dst, uint16_t dmemi, unsigned char scale);
|
typedef unsigned int (*adpcm_predict_frame_t)(struct hle_t* hle,
|
||||||
|
int16_t* dst, uint16_t dmemi, unsigned char scale);
|
||||||
|
|
||||||
static unsigned int adpcm_predict_frame_4bits(usf_state_t* state, int16_t* dst, uint16_t dmemi, unsigned char scale)
|
static unsigned int adpcm_predict_frame_4bits(struct hle_t* hle,
|
||||||
|
int16_t* dst, uint16_t dmemi, unsigned char scale)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned int rshift = (scale < 12) ? 12 - scale : 0;
|
unsigned int rshift = (scale < 12) ? 12 - scale : 0;
|
||||||
|
|
||||||
for(i = 0; i < 8; ++i) {
|
for(i = 0; i < 8; ++i) {
|
||||||
uint8_t byte = state->BufferSpace[(dmemi++)^S8];
|
uint8_t byte = hle->alist_buffer[(dmemi++)^S8];
|
||||||
|
|
||||||
*(dst++) = adpcm_predict_sample(byte, 0xf0, 8, rshift);
|
*(dst++) = adpcm_predict_sample(byte, 0xf0, 8, rshift);
|
||||||
*(dst++) = adpcm_predict_sample(byte, 0x0f, 12, rshift);
|
*(dst++) = adpcm_predict_sample(byte, 0x0f, 12, rshift);
|
||||||
|
@ -631,13 +636,14 @@ static unsigned int adpcm_predict_frame_4bits(usf_state_t* state, int16_t* dst,
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int adpcm_predict_frame_2bits(usf_state_t* state, int16_t* dst, uint16_t dmemi, unsigned char scale)
|
static unsigned int adpcm_predict_frame_2bits(struct hle_t* hle,
|
||||||
|
int16_t* dst, uint16_t dmemi, unsigned char scale)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned int rshift = (scale < 14) ? 14 - scale : 0;
|
unsigned int rshift = (scale < 14) ? 14 - scale : 0;
|
||||||
|
|
||||||
for(i = 0; i < 4; ++i) {
|
for(i = 0; i < 4; ++i) {
|
||||||
uint8_t byte = state->BufferSpace[(dmemi++)^S8];
|
uint8_t byte = hle->alist_buffer[(dmemi++)^S8];
|
||||||
|
|
||||||
*(dst++) = adpcm_predict_sample(byte, 0xc0, 8, rshift);
|
*(dst++) = adpcm_predict_sample(byte, 0xc0, 8, rshift);
|
||||||
*(dst++) = adpcm_predict_sample(byte, 0x30, 10, rshift);
|
*(dst++) = adpcm_predict_sample(byte, 0x30, 10, rshift);
|
||||||
|
@ -649,7 +655,7 @@ static unsigned int adpcm_predict_frame_2bits(usf_state_t* state, int16_t* dst,
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_adpcm(
|
void alist_adpcm(
|
||||||
usf_state_t* state,
|
struct hle_t* hle,
|
||||||
bool init,
|
bool init,
|
||||||
bool loop,
|
bool loop,
|
||||||
bool two_bit_per_sample,
|
bool two_bit_per_sample,
|
||||||
|
@ -660,55 +666,60 @@ void alist_adpcm(
|
||||||
uint32_t loop_address,
|
uint32_t loop_address,
|
||||||
uint32_t last_frame_address)
|
uint32_t last_frame_address)
|
||||||
{
|
{
|
||||||
assert((count & 0x1f) == 0);
|
|
||||||
|
|
||||||
int16_t last_frame[16];
|
int16_t last_frame[16];
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (init)
|
|
||||||
memset(last_frame, 0, 16*sizeof(last_frame[0]));
|
|
||||||
else
|
|
||||||
dram_load_u16(state, (uint16_t*)last_frame, (loop) ? loop_address : last_frame_address, 16);
|
|
||||||
|
|
||||||
for(i = 0; i < 16; ++i, dmemo += 2)
|
|
||||||
*(int16_t*)(state->BufferSpace + (dmemo ^ S16)) = last_frame[i];
|
|
||||||
|
|
||||||
adpcm_predict_frame_t predict_frame = (two_bit_per_sample)
|
adpcm_predict_frame_t predict_frame = (two_bit_per_sample)
|
||||||
? adpcm_predict_frame_2bits
|
? adpcm_predict_frame_2bits
|
||||||
: adpcm_predict_frame_4bits;
|
: adpcm_predict_frame_4bits;
|
||||||
|
|
||||||
|
assert((count & 0x1f) == 0);
|
||||||
|
|
||||||
|
if (init)
|
||||||
|
memset(last_frame, 0, 16*sizeof(last_frame[0]));
|
||||||
|
else
|
||||||
|
dram_load_u16(hle, (uint16_t*)last_frame, (loop) ? loop_address : last_frame_address, 16);
|
||||||
|
|
||||||
|
for(i = 0; i < 16; ++i, dmemo += 2)
|
||||||
|
*(int16_t*)(hle->alist_buffer + (dmemo ^ S16)) = last_frame[i];
|
||||||
|
|
||||||
while (count != 0) {
|
while (count != 0) {
|
||||||
int16_t frame[16];
|
int16_t frame[16];
|
||||||
uint8_t code = state->BufferSpace[(dmemi++)^S8];
|
uint8_t code = hle->alist_buffer[(dmemi++)^S8];
|
||||||
unsigned char scale = (code & 0xf0) >> 4;
|
unsigned char scale = (code & 0xf0) >> 4;
|
||||||
const int16_t* const cb_entry = codebook + ((code & 0xf) << 4);
|
const int16_t* const cb_entry = codebook + ((code & 0xf) << 4);
|
||||||
|
|
||||||
dmemi += predict_frame(state, frame, dmemi, scale);
|
dmemi += predict_frame(hle, frame, dmemi, scale);
|
||||||
|
|
||||||
adpcm_compute_residuals(last_frame , frame , cb_entry, last_frame + 14, 8);
|
adpcm_compute_residuals(last_frame , frame , cb_entry, last_frame + 14, 8);
|
||||||
adpcm_compute_residuals(last_frame + 8, frame + 8, cb_entry, last_frame + 6 , 8);
|
adpcm_compute_residuals(last_frame + 8, frame + 8, cb_entry, last_frame + 6 , 8);
|
||||||
|
|
||||||
for(i = 0; i < 16; ++i, dmemo += 2)
|
for(i = 0; i < 16; ++i, dmemo += 2)
|
||||||
*(int16_t*)(state->BufferSpace + (dmemo ^ S16)) = last_frame[i];
|
*(int16_t*)(hle->alist_buffer + (dmemo ^ S16)) = last_frame[i];
|
||||||
|
|
||||||
count -= 32;
|
count -= 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
dram_store_u16(state, (uint16_t*)last_frame, last_frame_address, 16);
|
dram_store_u16(hle, (uint16_t*)last_frame, last_frame_address, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void alist_filter(usf_state_t* state, uint16_t dmem, uint16_t count, uint32_t address, const uint32_t* lut_address)
|
void alist_filter(
|
||||||
|
struct hle_t* hle,
|
||||||
|
uint16_t dmem,
|
||||||
|
uint16_t count,
|
||||||
|
uint32_t address,
|
||||||
|
const uint32_t* lut_address)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int16_t outbuff[0x3c0];
|
int16_t outbuff[0x3c0];
|
||||||
int16_t *outp = outbuff;
|
int16_t *outp = outbuff;
|
||||||
|
|
||||||
int16_t* const lutt6 = (int16_t*)(state->N64MEM + lut_address[0]);
|
int16_t* const lutt6 = (int16_t*)(hle->dram + lut_address[0]);
|
||||||
int16_t* const lutt5 = (int16_t*)(state->N64MEM + lut_address[1]);
|
int16_t* const lutt5 = (int16_t*)(hle->dram + lut_address[1]);
|
||||||
|
|
||||||
int16_t* in1 = (int16_t*)(state->N64MEM + address);
|
int16_t* in1 = (int16_t*)(hle->dram + address);
|
||||||
int16_t* in2 = (int16_t*)(state->BufferSpace + dmem);
|
int16_t* in2 = (int16_t*)(hle->alist_buffer + dmem);
|
||||||
|
|
||||||
|
|
||||||
for (x = 0; x < 8; ++x) {
|
for (x = 0; x < 8; ++x) {
|
||||||
|
@ -804,12 +815,12 @@ void alist_filter(usf_state_t* state, uint16_t dmem, uint16_t count, uint32_t ad
|
||||||
outp += 8;
|
outp += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(state->N64MEM + address, in2 - 8, 16);
|
memcpy(hle->dram + address, in2 - 8, 16);
|
||||||
memcpy(state->BufferSpace + dmem, outbuff, count);
|
memcpy(hle->alist_buffer + dmem, outbuff, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_polef(
|
void alist_polef(
|
||||||
usf_state_t* state,
|
struct hle_t* hle,
|
||||||
bool init,
|
bool init,
|
||||||
uint16_t dmemo,
|
uint16_t dmemo,
|
||||||
uint16_t dmemi,
|
uint16_t dmemi,
|
||||||
|
@ -818,7 +829,7 @@ void alist_polef(
|
||||||
int16_t* table,
|
int16_t* table,
|
||||||
uint32_t address)
|
uint32_t address)
|
||||||
{
|
{
|
||||||
int16_t *dst = (int16_t*)(state->BufferSpace + dmemo);
|
int16_t *dst = (int16_t*)(hle->alist_buffer + dmemo);
|
||||||
|
|
||||||
const int16_t* const h1 = table;
|
const int16_t* const h1 = table;
|
||||||
int16_t* const h2 = table + 8;
|
int16_t* const h2 = table + 8;
|
||||||
|
@ -834,8 +845,8 @@ void alist_polef(
|
||||||
l2 = 0;
|
l2 = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
l1 = *dram_u16(state, address + 4);
|
l1 = *dram_u16(hle, address + 4);
|
||||||
l2 = *dram_u16(state, address + 6);
|
l2 = *dram_u16(hle, address + 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < 8; ++i) {
|
for(i = 0; i < 8; ++i) {
|
||||||
|
@ -848,7 +859,7 @@ void alist_polef(
|
||||||
int16_t frame[8];
|
int16_t frame[8];
|
||||||
|
|
||||||
for(i = 0; i < 8; ++i, dmemi += 2) {
|
for(i = 0; i < 8; ++i, dmemi += 2) {
|
||||||
frame[i] = *(int16_t*)(state->BufferSpace + (dmemi ^ S16));
|
frame[i] = *(int16_t*)(hle->alist_buffer + (dmemi ^ S16));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < 8; ++i) {
|
for(i = 0; i < 8; ++i) {
|
||||||
|
@ -864,5 +875,5 @@ void alist_polef(
|
||||||
count -= 16;
|
count -= 16;
|
||||||
} while (count != 0);
|
} while (count != 0);
|
||||||
|
|
||||||
dram_store_u16(state, (uint16_t*)(dst - 4), address, 4);
|
dram_store_u16(hle, (uint16_t*)(dst - 4), address, 4);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,25 +22,104 @@
|
||||||
#ifndef ALIST_H
|
#ifndef ALIST_H
|
||||||
#define ALIST_H
|
#define ALIST_H
|
||||||
|
|
||||||
void alist_process_audio(usf_state_t* state);
|
#include <stdint.h>
|
||||||
void alist_process_audio_ge(usf_state_t* state);
|
|
||||||
void alist_process_audio_bc(usf_state_t* state);
|
enum { N_SEGMENTS = 16 };
|
||||||
void alist_process_nead_mk(usf_state_t* state);
|
|
||||||
void alist_process_nead_sfj(usf_state_t* state);
|
/* alist_audio state */
|
||||||
void alist_process_nead_sf(usf_state_t* state);
|
struct alist_audio_t {
|
||||||
void alist_process_nead_fz(usf_state_t* state);
|
/* segments */
|
||||||
void alist_process_nead_wrjb(usf_state_t* state);
|
uint32_t segments[N_SEGMENTS];
|
||||||
void alist_process_nead_ys(usf_state_t* state);
|
|
||||||
void alist_process_nead_1080(usf_state_t* state);
|
/* main buffers */
|
||||||
void alist_process_nead_oot(usf_state_t* state);
|
uint16_t in;
|
||||||
void alist_process_nead_mm(usf_state_t* state);
|
uint16_t out;
|
||||||
void alist_process_nead_mmb(usf_state_t* state);
|
uint16_t count;
|
||||||
void alist_process_nead_ac(usf_state_t* state);
|
|
||||||
void alist_process_naudio(usf_state_t* state);
|
/* auxiliary buffers */
|
||||||
void alist_process_naudio_bk(usf_state_t* state);
|
uint16_t dry_right;
|
||||||
void alist_process_naudio_dk(usf_state_t* state);
|
uint16_t wet_left;
|
||||||
void alist_process_naudio_mp3(usf_state_t* state);
|
uint16_t wet_right;
|
||||||
void alist_process_naudio_cbfd(usf_state_t* state);
|
|
||||||
|
/* gains */
|
||||||
|
int16_t dry;
|
||||||
|
int16_t wet;
|
||||||
|
|
||||||
|
/* envelopes (0:left, 1:right) */
|
||||||
|
int16_t vol[2];
|
||||||
|
int16_t target[2];
|
||||||
|
int32_t rate[2];
|
||||||
|
|
||||||
|
/* ADPCM loop point address */
|
||||||
|
uint32_t loop;
|
||||||
|
|
||||||
|
/* storage for ADPCM table and polef coefficients */
|
||||||
|
int16_t table[16 * 8];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* alist_naudio state */
|
||||||
|
struct alist_naudio_t {
|
||||||
|
/* gains */
|
||||||
|
int16_t dry;
|
||||||
|
int16_t wet;
|
||||||
|
|
||||||
|
/* envelopes (0:left, 1:right) */
|
||||||
|
int16_t vol[2];
|
||||||
|
int16_t target[2];
|
||||||
|
int32_t rate[2];
|
||||||
|
|
||||||
|
/* ADPCM loop point address */
|
||||||
|
uint32_t loop;
|
||||||
|
|
||||||
|
/* storage for ADPCM table and polef coefficients */
|
||||||
|
int16_t table[16 * 8];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* alist_nead state */
|
||||||
|
struct alist_nead_t {
|
||||||
|
/* main buffers */
|
||||||
|
uint16_t in;
|
||||||
|
uint16_t out;
|
||||||
|
uint16_t count;
|
||||||
|
|
||||||
|
/* envmixer ramps */
|
||||||
|
uint16_t env_values[3];
|
||||||
|
uint16_t env_steps[3];
|
||||||
|
|
||||||
|
/* ADPCM loop point address */
|
||||||
|
uint32_t loop;
|
||||||
|
|
||||||
|
/* storage for ADPCM table and polef coefficients */
|
||||||
|
int16_t table[16 * 8];
|
||||||
|
|
||||||
|
/* filter audio command state */
|
||||||
|
uint16_t filter_count;
|
||||||
|
uint32_t filter_lut_address[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hle_t;
|
||||||
|
|
||||||
|
void alist_process_audio (struct hle_t* hle);
|
||||||
|
void alist_process_audio_ge(struct hle_t* hle);
|
||||||
|
void alist_process_audio_bc(struct hle_t* hle);
|
||||||
|
|
||||||
|
void alist_process_nead_mk (struct hle_t* hle);
|
||||||
|
void alist_process_nead_sfj (struct hle_t* hle);
|
||||||
|
void alist_process_nead_sf (struct hle_t* hle);
|
||||||
|
void alist_process_nead_fz (struct hle_t* hle);
|
||||||
|
void alist_process_nead_wrjb(struct hle_t* hle);
|
||||||
|
void alist_process_nead_ys (struct hle_t* hle);
|
||||||
|
void alist_process_nead_1080(struct hle_t* hle);
|
||||||
|
void alist_process_nead_oot (struct hle_t* hle);
|
||||||
|
void alist_process_nead_mm (struct hle_t* hle);
|
||||||
|
void alist_process_nead_mmb (struct hle_t* hle);
|
||||||
|
void alist_process_nead_ac (struct hle_t* hle);
|
||||||
|
|
||||||
|
void alist_process_naudio (struct hle_t* hle);
|
||||||
|
void alist_process_naudio_bk (struct hle_t* hle);
|
||||||
|
void alist_process_naudio_dk (struct hle_t* hle);
|
||||||
|
void alist_process_naudio_mp3 (struct hle_t* hle);
|
||||||
|
void alist_process_naudio_cbfd(struct hle_t* hle);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -21,41 +21,42 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#else
|
||||||
|
#include "mystdbool.h"
|
||||||
|
#endif
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../usf.h"
|
|
||||||
|
|
||||||
#include "alist_internal.h"
|
#include "alist_internal.h"
|
||||||
|
#include "hle_internal.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
#include "../usf_internal.h"
|
enum { DMEM_BASE = 0x5c0 };
|
||||||
|
|
||||||
/* state moved to usf_internal.h */
|
|
||||||
|
|
||||||
/* helper functions */
|
/* helper functions */
|
||||||
static uint32_t get_address(usf_state_t* state, uint32_t so)
|
static uint32_t get_address(struct hle_t* hle, uint32_t so)
|
||||||
{
|
{
|
||||||
return alist_get_address(state, so, state->l_alist_audio.segments, N_SEGMENTS);
|
return alist_get_address(hle, so, hle->alist_audio.segments, N_SEGMENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_address(usf_state_t* state, uint32_t so)
|
static void set_address(struct hle_t* hle, uint32_t so)
|
||||||
{
|
{
|
||||||
alist_set_address(state, so, state->l_alist_audio.segments, N_SEGMENTS);
|
alist_set_address(hle, so, hle->alist_audio.segments, N_SEGMENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_segments(usf_state_t* state)
|
static void clear_segments(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
memset(state->l_alist_audio.segments, 0, N_SEGMENTS*sizeof(state->l_alist_audio.segments[0]));
|
memset(hle->alist_audio.segments, 0, N_SEGMENTS*sizeof(hle->alist_audio.segments[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* audio commands definition */
|
/* audio commands definition */
|
||||||
static void SPNOOP(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void SPNOOP(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CLEARBUFF(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void CLEARBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t dmem = w1 + DMEM_BASE;
|
uint16_t dmem = w1 + DMEM_BASE;
|
||||||
uint16_t count = w2;
|
uint16_t count = w2;
|
||||||
|
@ -63,124 +64,124 @@ static void CLEARBUFF(usf_state_t* state, uint32_t w1, uint32_t w2)
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
alist_clear(state, dmem, align(count, 16));
|
alist_clear(hle, dmem, align(count, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ENVMIXER(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void ENVMIXER(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t flags = (w1 >> 16);
|
uint8_t flags = (w1 >> 16);
|
||||||
uint32_t address = get_address(state, w2);
|
uint32_t address = get_address(hle, w2);
|
||||||
|
|
||||||
alist_envmix_exp(
|
alist_envmix_exp(
|
||||||
state,
|
hle,
|
||||||
flags & A_INIT,
|
flags & A_INIT,
|
||||||
flags & A_AUX,
|
flags & A_AUX,
|
||||||
state->l_alist_audio.out, state->l_alist_audio.dry_right,
|
hle->alist_audio.out, hle->alist_audio.dry_right,
|
||||||
state->l_alist_audio.wet_left, state->l_alist_audio.wet_right,
|
hle->alist_audio.wet_left, hle->alist_audio.wet_right,
|
||||||
state->l_alist_audio.in, state->l_alist_audio.count,
|
hle->alist_audio.in, hle->alist_audio.count,
|
||||||
state->l_alist_audio.dry, state->l_alist_audio.wet,
|
hle->alist_audio.dry, hle->alist_audio.wet,
|
||||||
state->l_alist_audio.vol,
|
hle->alist_audio.vol,
|
||||||
state->l_alist_audio.target,
|
hle->alist_audio.target,
|
||||||
state->l_alist_audio.rate,
|
hle->alist_audio.rate,
|
||||||
address);
|
address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RESAMPLE(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void RESAMPLE(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t flags = (w1 >> 16);
|
uint8_t flags = (w1 >> 16);
|
||||||
uint16_t pitch = w1;
|
uint16_t pitch = w1;
|
||||||
uint32_t address = get_address(state, w2);
|
uint32_t address = get_address(hle, w2);
|
||||||
|
|
||||||
alist_resample(
|
alist_resample(
|
||||||
state,
|
hle,
|
||||||
flags & 0x1,
|
flags & 0x1,
|
||||||
flags & 0x2,
|
flags & 0x2,
|
||||||
state->l_alist_audio.out,
|
hle->alist_audio.out,
|
||||||
state->l_alist_audio.in,
|
hle->alist_audio.in,
|
||||||
align(state->l_alist_audio.count, 16),
|
align(hle->alist_audio.count, 16),
|
||||||
pitch << 1,
|
pitch << 1,
|
||||||
address);
|
address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SETVOL(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void SETVOL(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t flags = (w1 >> 16);
|
uint8_t flags = (w1 >> 16);
|
||||||
|
|
||||||
if (flags & A_AUX) {
|
if (flags & A_AUX) {
|
||||||
state->l_alist_audio.dry = w1;
|
hle->alist_audio.dry = w1;
|
||||||
state->l_alist_audio.wet = w2;
|
hle->alist_audio.wet = w2;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unsigned lr = (flags & A_LEFT) ? 0 : 1;
|
unsigned lr = (flags & A_LEFT) ? 0 : 1;
|
||||||
|
|
||||||
if (flags & A_VOL)
|
if (flags & A_VOL)
|
||||||
state->l_alist_audio.vol[lr] = w1;
|
hle->alist_audio.vol[lr] = w1;
|
||||||
else {
|
else {
|
||||||
state->l_alist_audio.target[lr] = w1;
|
hle->alist_audio.target[lr] = w1;
|
||||||
state->l_alist_audio.rate[lr] = w2;
|
hle->alist_audio.rate[lr] = w2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SETLOOP(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void SETLOOP(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
state->l_alist_audio.loop = get_address(state, w2);
|
hle->alist_audio.loop = get_address(hle, w2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ADPCM(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void ADPCM(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t flags = (w1 >> 16);
|
uint8_t flags = (w1 >> 16);
|
||||||
uint32_t address = get_address(state, w2);
|
uint32_t address = get_address(hle, w2);
|
||||||
|
|
||||||
alist_adpcm(
|
alist_adpcm(
|
||||||
state,
|
hle,
|
||||||
flags & 0x1,
|
flags & 0x1,
|
||||||
flags & 0x2,
|
flags & 0x2,
|
||||||
false, /* unsupported in this ucode */
|
false, /* unsupported in this ucode */
|
||||||
state->l_alist_audio.out,
|
hle->alist_audio.out,
|
||||||
state->l_alist_audio.in,
|
hle->alist_audio.in,
|
||||||
align(state->l_alist_audio.count, 32),
|
align(hle->alist_audio.count, 32),
|
||||||
state->l_alist_audio.table,
|
hle->alist_audio.table,
|
||||||
state->l_alist_audio.loop,
|
hle->alist_audio.loop,
|
||||||
address);
|
address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LOADBUFF(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void LOADBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint32_t address = get_address(state, w2);
|
uint32_t address = get_address(hle, w2);
|
||||||
|
|
||||||
if (state->l_alist_audio.count == 0)
|
if (hle->alist_audio.count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
alist_load(state, state->l_alist_audio.in, address, state->l_alist_audio.count);
|
alist_load(hle, hle->alist_audio.in, address, hle->alist_audio.count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SAVEBUFF(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void SAVEBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint32_t address = get_address(state, w2);
|
uint32_t address = get_address(hle, w2);
|
||||||
|
|
||||||
if (state->l_alist_audio.count == 0)
|
if (hle->alist_audio.count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
alist_save(state, state->l_alist_audio.out, address, state->l_alist_audio.count);
|
alist_save(hle, hle->alist_audio.out, address, hle->alist_audio.count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SETBUFF(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void SETBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t flags = (w1 >> 16);
|
uint8_t flags = (w1 >> 16);
|
||||||
|
|
||||||
if (flags & A_AUX) {
|
if (flags & A_AUX) {
|
||||||
state->l_alist_audio.dry_right = w1 + DMEM_BASE;
|
hle->alist_audio.dry_right = w1 + DMEM_BASE;
|
||||||
state->l_alist_audio.wet_left = (w2 >> 16) + DMEM_BASE;
|
hle->alist_audio.wet_left = (w2 >> 16) + DMEM_BASE;
|
||||||
state->l_alist_audio.wet_right = w2 + DMEM_BASE;
|
hle->alist_audio.wet_right = w2 + DMEM_BASE;
|
||||||
} else {
|
} else {
|
||||||
state->l_alist_audio.in = w1 + DMEM_BASE;
|
hle->alist_audio.in = w1 + DMEM_BASE;
|
||||||
state->l_alist_audio.out = (w2 >> 16) + DMEM_BASE;
|
hle->alist_audio.out = (w2 >> 16) + DMEM_BASE;
|
||||||
state->l_alist_audio.count = w2;
|
hle->alist_audio.count = w2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DMEMMOVE(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void DMEMMOVE(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t dmemi = w1 + DMEM_BASE;
|
uint16_t dmemi = w1 + DMEM_BASE;
|
||||||
uint16_t dmemo = (w2 >> 16) + DMEM_BASE;
|
uint16_t dmemo = (w2 >> 16) + DMEM_BASE;
|
||||||
|
@ -189,67 +190,67 @@ static void DMEMMOVE(usf_state_t* state, uint32_t w1, uint32_t w2)
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
alist_move(state, dmemo, dmemi, align(count, 16));
|
alist_move(hle, dmemo, dmemi, align(count, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LOADADPCM(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void LOADADPCM(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t count = w1;
|
uint16_t count = w1;
|
||||||
uint32_t address = get_address(state, w2);
|
uint32_t address = get_address(hle, w2);
|
||||||
|
|
||||||
dram_load_u16(state, (uint16_t*)state->l_alist_audio.table, address, align(count, 8) >> 1);
|
dram_load_u16(hle, (uint16_t*)hle->alist_audio.table, address, align(count, 8) >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void INTERLEAVE(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void INTERLEAVE(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t left = (w2 >> 16) + DMEM_BASE;
|
uint16_t left = (w2 >> 16) + DMEM_BASE;
|
||||||
uint16_t right = w2 + DMEM_BASE;
|
uint16_t right = w2 + DMEM_BASE;
|
||||||
|
|
||||||
if (state->l_alist_audio.count == 0)
|
if (hle->alist_audio.count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
alist_interleave(state, state->l_alist_audio.out, left, right, align(state->l_alist_audio.count, 16));
|
alist_interleave(hle, hle->alist_audio.out, left, right, align(hle->alist_audio.count, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MIXER(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void MIXER(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
int16_t gain = w1;
|
int16_t gain = w1;
|
||||||
uint16_t dmemi = (w2 >> 16) + DMEM_BASE;
|
uint16_t dmemi = (w2 >> 16) + DMEM_BASE;
|
||||||
uint16_t dmemo = w2 + DMEM_BASE;
|
uint16_t dmemo = w2 + DMEM_BASE;
|
||||||
|
|
||||||
if (state->l_alist_audio.count == 0)
|
if (hle->alist_audio.count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
alist_mix(state, dmemo, dmemi, align(state->l_alist_audio.count, 32), gain);
|
alist_mix(hle, dmemo, dmemi, align(hle->alist_audio.count, 32), gain);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SEGMENT(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void SEGMENT(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
set_address(state, w2);
|
set_address(hle, w2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void POLEF(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void POLEF(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t flags = (w1 >> 16);
|
uint8_t flags = (w1 >> 16);
|
||||||
uint16_t gain = w1;
|
uint16_t gain = w1;
|
||||||
uint32_t address = get_address(state, w2);
|
uint32_t address = get_address(hle, w2);
|
||||||
|
|
||||||
if (state->l_alist_audio.count == 0)
|
if (hle->alist_audio.count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
alist_polef(
|
alist_polef(
|
||||||
state,
|
hle,
|
||||||
flags & A_INIT,
|
flags & A_INIT,
|
||||||
state->l_alist_audio.out,
|
hle->alist_audio.out,
|
||||||
state->l_alist_audio.in,
|
hle->alist_audio.in,
|
||||||
align(state->l_alist_audio.count, 16),
|
align(hle->alist_audio.count, 16),
|
||||||
gain,
|
gain,
|
||||||
state->l_alist_audio.table,
|
hle->alist_audio.table,
|
||||||
address);
|
address);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* global functions */
|
/* global functions */
|
||||||
void alist_process_audio(usf_state_t* state)
|
void alist_process_audio(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
static const acmd_callback_t ABI[0x10] = {
|
static const acmd_callback_t ABI[0x10] = {
|
||||||
SPNOOP, ADPCM , CLEARBUFF, ENVMIXER,
|
SPNOOP, ADPCM , CLEARBUFF, ENVMIXER,
|
||||||
|
@ -258,11 +259,11 @@ void alist_process_audio(usf_state_t* state)
|
||||||
MIXER, INTERLEAVE, POLEF, SETLOOP
|
MIXER, INTERLEAVE, POLEF, SETLOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
clear_segments(state);
|
clear_segments(hle);
|
||||||
alist_process(state, ABI, 0x10);
|
alist_process(hle, ABI, 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_audio_ge(usf_state_t* state)
|
void alist_process_audio_ge(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
/* TODO: see what differs from alist_process_audio */
|
/* TODO: see what differs from alist_process_audio */
|
||||||
static const acmd_callback_t ABI[0x10] = {
|
static const acmd_callback_t ABI[0x10] = {
|
||||||
|
@ -272,11 +273,11 @@ void alist_process_audio_ge(usf_state_t* state)
|
||||||
MIXER, INTERLEAVE, POLEF, SETLOOP
|
MIXER, INTERLEAVE, POLEF, SETLOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
clear_segments(state);
|
clear_segments(hle);
|
||||||
alist_process(state, ABI, 0x10);
|
alist_process(hle, ABI, 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_audio_bc(usf_state_t* state)
|
void alist_process_audio_bc(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
/* TODO: see what differs from alist_process_audio */
|
/* TODO: see what differs from alist_process_audio */
|
||||||
static const acmd_callback_t ABI[0x10] = {
|
static const acmd_callback_t ABI[0x10] = {
|
||||||
|
@ -286,6 +287,6 @@ void alist_process_audio_bc(usf_state_t* state)
|
||||||
MIXER, INTERLEAVE, POLEF, SETLOOP
|
MIXER, INTERLEAVE, POLEF, SETLOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
clear_segments(state);
|
clear_segments(hle);
|
||||||
alist_process(state, ABI, 0x10);
|
alist_process(hle, ABI, 0x10);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,26 +22,32 @@
|
||||||
#ifndef ALIST_INTERNAL_H
|
#ifndef ALIST_INTERNAL_H
|
||||||
#define ALIST_INTERNAL_H
|
#define ALIST_INTERNAL_H
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#else
|
||||||
|
#include "mystdbool.h"
|
||||||
|
#endif
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
typedef void (*acmd_callback_t)(usf_state_t* state, uint32_t w1, uint32_t w2);
|
struct hle_t;
|
||||||
|
|
||||||
void alist_process(usf_state_t* state, const acmd_callback_t abi[], unsigned int abi_size);
|
typedef void (*acmd_callback_t)(struct hle_t* hle, uint32_t w1, uint32_t w2);
|
||||||
uint32_t alist_get_address(usf_state_t* state, uint32_t so, const uint32_t *segments, size_t n);
|
|
||||||
void alist_set_address(usf_state_t* state, uint32_t so, uint32_t *segments, size_t n);
|
void alist_process(struct hle_t* hle, const acmd_callback_t abi[], unsigned int abi_size);
|
||||||
void alist_clear(usf_state_t* state, uint16_t dmem, uint16_t count);
|
uint32_t alist_get_address(struct hle_t* hle, uint32_t so, const uint32_t *segments, size_t n);
|
||||||
void alist_load(usf_state_t* state, uint16_t dmem, uint32_t address, uint16_t count);
|
void alist_set_address(struct hle_t* hle, uint32_t so, uint32_t *segments, size_t n);
|
||||||
void alist_save(usf_state_t* state, uint16_t dmem, uint32_t address, uint16_t count);
|
void alist_clear(struct hle_t* hle, uint16_t dmem, uint16_t count);
|
||||||
void alist_move(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint16_t count);
|
void alist_load(struct hle_t* hle, uint16_t dmem, uint32_t address, uint16_t count);
|
||||||
void alist_copy_every_other_sample(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint16_t count);
|
void alist_save(struct hle_t* hle, uint16_t dmem, uint32_t address, uint16_t count);
|
||||||
void alist_repeat64(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint8_t count);
|
void alist_move(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count);
|
||||||
void alist_copy_blocks(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint16_t block_size, uint8_t count);
|
void alist_copy_every_other_sample(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count);
|
||||||
void alist_interleave(usf_state_t* state, uint16_t dmemo, uint16_t left, uint16_t right, uint16_t count);
|
void alist_repeat64(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint8_t count);
|
||||||
|
void alist_copy_blocks(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t block_size, uint8_t count);
|
||||||
|
void alist_interleave(struct hle_t* hle, uint16_t dmemo, uint16_t left, uint16_t right, uint16_t count);
|
||||||
|
|
||||||
void alist_envmix_exp(
|
void alist_envmix_exp(
|
||||||
usf_state_t* state,
|
struct hle_t* hle,
|
||||||
bool init,
|
bool init,
|
||||||
bool aux,
|
bool aux,
|
||||||
uint16_t dmem_dl, uint16_t dmem_dr,
|
uint16_t dmem_dl, uint16_t dmem_dr,
|
||||||
|
@ -54,7 +60,7 @@ void alist_envmix_exp(
|
||||||
uint32_t address);
|
uint32_t address);
|
||||||
|
|
||||||
void alist_envmix_lin(
|
void alist_envmix_lin(
|
||||||
usf_state_t* state,
|
struct hle_t* hle,
|
||||||
bool init,
|
bool init,
|
||||||
uint16_t dmem_dl, uint16_t dmem_dr,
|
uint16_t dmem_dl, uint16_t dmem_dr,
|
||||||
uint16_t dmem_wl, uint16_t dmem_wr,
|
uint16_t dmem_wl, uint16_t dmem_wr,
|
||||||
|
@ -66,7 +72,7 @@ void alist_envmix_lin(
|
||||||
uint32_t address);
|
uint32_t address);
|
||||||
|
|
||||||
void alist_envmix_nead(
|
void alist_envmix_nead(
|
||||||
usf_state_t* state,
|
struct hle_t* hle,
|
||||||
bool swap_wet_LR,
|
bool swap_wet_LR,
|
||||||
uint16_t dmem_dl,
|
uint16_t dmem_dl,
|
||||||
uint16_t dmem_dr,
|
uint16_t dmem_dr,
|
||||||
|
@ -78,12 +84,12 @@ void alist_envmix_nead(
|
||||||
uint16_t *env_steps,
|
uint16_t *env_steps,
|
||||||
const int16_t *xors);
|
const int16_t *xors);
|
||||||
|
|
||||||
void alist_mix(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t gain);
|
void alist_mix(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t gain);
|
||||||
void alist_multQ44(usf_state_t* state, uint16_t dmem, uint16_t count, int8_t gain);
|
void alist_multQ44(struct hle_t* hle, uint16_t dmem, uint16_t count, int8_t gain);
|
||||||
void alist_add(usf_state_t* state, uint16_t dmemo, uint16_t dmemi, uint16_t count);
|
void alist_add(struct hle_t* hle, uint16_t dmemo, uint16_t dmemi, uint16_t count);
|
||||||
|
|
||||||
void alist_adpcm(
|
void alist_adpcm(
|
||||||
usf_state_t* state,
|
struct hle_t* hle,
|
||||||
bool init,
|
bool init,
|
||||||
bool loop,
|
bool loop,
|
||||||
bool two_bit_per_sample,
|
bool two_bit_per_sample,
|
||||||
|
@ -95,14 +101,14 @@ void alist_adpcm(
|
||||||
uint32_t last_frame_address);
|
uint32_t last_frame_address);
|
||||||
|
|
||||||
void alist_resample(
|
void alist_resample(
|
||||||
usf_state_t* state,
|
struct hle_t* hle,
|
||||||
bool init,
|
bool init,
|
||||||
bool flag2,
|
bool flag2,
|
||||||
uint16_t dmemo, uint16_t dmemi, uint16_t count,
|
uint16_t dmemo, uint16_t dmemi, uint16_t count,
|
||||||
uint32_t pitch, uint32_t address);
|
uint32_t pitch, uint32_t address);
|
||||||
|
|
||||||
void alist_resample_zoh(
|
void alist_resample_zoh(
|
||||||
usf_state_t* state,
|
struct hle_t* hle,
|
||||||
uint16_t dmemo,
|
uint16_t dmemo,
|
||||||
uint16_t dmemi,
|
uint16_t dmemi,
|
||||||
uint16_t count,
|
uint16_t count,
|
||||||
|
@ -110,14 +116,14 @@ void alist_resample_zoh(
|
||||||
uint32_t pitch_accu);
|
uint32_t pitch_accu);
|
||||||
|
|
||||||
void alist_filter(
|
void alist_filter(
|
||||||
usf_state_t* state,
|
struct hle_t* hle,
|
||||||
uint16_t dmem,
|
uint16_t dmem,
|
||||||
uint16_t count,
|
uint16_t count,
|
||||||
uint32_t address,
|
uint32_t address,
|
||||||
const uint32_t* lut_address);
|
const uint32_t* lut_address);
|
||||||
|
|
||||||
void alist_polef(
|
void alist_polef(
|
||||||
usf_state_t* state,
|
struct hle_t* hle,
|
||||||
bool init,
|
bool init,
|
||||||
uint16_t dmemo,
|
uint16_t dmemo,
|
||||||
uint16_t dmemi,
|
uint16_t dmemi,
|
||||||
|
|
|
@ -21,49 +21,61 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#else
|
||||||
|
#include "mystdbool.h"
|
||||||
|
#endif
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "../usf.h"
|
|
||||||
|
|
||||||
#include "alist_internal.h"
|
#include "alist_internal.h"
|
||||||
|
#include "hle_external.h"
|
||||||
|
#include "hle_internal.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "plugin.h"
|
|
||||||
|
|
||||||
#include "../usf_internal.h"
|
void MP3(struct hle_t* hle, uint32_t w1, uint32_t w2);
|
||||||
|
|
||||||
|
enum { NAUDIO_COUNT = 0x170 }; /* ie 184 samples */
|
||||||
|
enum {
|
||||||
|
NAUDIO_MAIN = 0x4f0,
|
||||||
|
NAUDIO_MAIN2 = 0x660,
|
||||||
|
NAUDIO_DRY_LEFT = 0x9d0,
|
||||||
|
NAUDIO_DRY_RIGHT = 0xb40,
|
||||||
|
NAUDIO_WET_LEFT = 0xcb0,
|
||||||
|
NAUDIO_WET_RIGHT = 0xe20
|
||||||
|
};
|
||||||
|
|
||||||
void MP3(usf_state_t* state, uint32_t w1, uint32_t w2);
|
|
||||||
|
|
||||||
/* audio commands definition */
|
/* audio commands definition */
|
||||||
static void UNKNOWN(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void UNKNOWN(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t acmd = (w1 >> 24);
|
uint8_t acmd = (w1 >> 24);
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_WARNING,
|
HleWarnMessage(hle->user_defined,
|
||||||
"Unknown audio comand %d: %08x %08x",
|
"Unknown audio command %d: %08x %08x",
|
||||||
acmd, w1, w2);
|
acmd, w1, w2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void SPNOOP(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void SPNOOP(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NAUDIO_0000(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void NAUDIO_0000(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
/* ??? */
|
/* ??? */
|
||||||
UNKNOWN(state, w1, w2);
|
UNKNOWN(hle, w1, w2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NAUDIO_02B0(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void NAUDIO_02B0(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
/* ??? */
|
uint32_t rate = (hle->alist_naudio.rate[1] & 0xffff0000) | (w2 & 0xffff);
|
||||||
/* UNKNOWN(state, w1, w2); commented to avoid constant spamming during gameplay */
|
hle->alist_naudio.rate[1] = rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NAUDIO_14(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void NAUDIO_14(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
if (state->l_alist_naudio.table[0] == 0 && state->l_alist_naudio.table[1] == 0) {
|
if (hle->alist_naudio.table[0] == 0 && hle->alist_naudio.table[1] == 0) {
|
||||||
|
|
||||||
uint8_t flags = (w1 >> 16);
|
uint8_t flags = (w1 >> 16);
|
||||||
uint16_t gain = w1;
|
uint16_t gain = w1;
|
||||||
|
@ -73,49 +85,50 @@ static void NAUDIO_14(usf_state_t* state, uint32_t w1, uint32_t w2)
|
||||||
uint16_t dmem = (select_main == 0) ? NAUDIO_MAIN : NAUDIO_MAIN2;
|
uint16_t dmem = (select_main == 0) ? NAUDIO_MAIN : NAUDIO_MAIN2;
|
||||||
|
|
||||||
alist_polef(
|
alist_polef(
|
||||||
state,
|
hle,
|
||||||
flags & A_INIT,
|
flags & A_INIT,
|
||||||
dmem,
|
dmem,
|
||||||
dmem,
|
dmem,
|
||||||
NAUDIO_COUNT,
|
NAUDIO_COUNT,
|
||||||
gain,
|
gain,
|
||||||
state->l_alist_naudio.table,
|
hle->alist_naudio.table,
|
||||||
address);
|
address);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "NAUDIO_14: non null codebook[0-3] case not implemented.");
|
HleWarnMessage(hle->user_defined,
|
||||||
|
"NAUDIO_14: non null codebook[0-3] case not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SETVOL(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void SETVOL(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t flags = (w1 >> 16);
|
uint8_t flags = (w1 >> 16);
|
||||||
|
|
||||||
if (flags & 0x4) {
|
if (flags & 0x4) {
|
||||||
if (flags & 0x2) {
|
if (flags & 0x2) {
|
||||||
state->l_alist_naudio.vol[0] = w1;
|
hle->alist_naudio.vol[0] = w1;
|
||||||
state->l_alist_naudio.dry = (w2 >> 16);
|
hle->alist_naudio.dry = (w2 >> 16);
|
||||||
state->l_alist_naudio.wet = w2;
|
hle->alist_naudio.wet = w2;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
state->l_alist_naudio.target[1] = w1;
|
hle->alist_naudio.target[1] = w1;
|
||||||
state->l_alist_naudio.rate[1] = w2;
|
hle->alist_naudio.rate[1] = w2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
state->l_alist_naudio.target[0] = w1;
|
hle->alist_naudio.target[0] = w1;
|
||||||
state->l_alist_naudio.rate[0] = w2;
|
hle->alist_naudio.rate[0] = w2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ENVMIXER(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void ENVMIXER(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t flags = (w1 >> 16);
|
uint8_t flags = (w1 >> 16);
|
||||||
uint32_t address = (w2 & 0xffffff);
|
uint32_t address = (w2 & 0xffffff);
|
||||||
|
|
||||||
state->l_alist_naudio.vol[1] = w1;
|
hle->alist_naudio.vol[1] = w1;
|
||||||
|
|
||||||
alist_envmix_lin(
|
alist_envmix_lin(
|
||||||
state,
|
hle,
|
||||||
flags & 0x1,
|
flags & 0x1,
|
||||||
NAUDIO_DRY_LEFT,
|
NAUDIO_DRY_LEFT,
|
||||||
NAUDIO_DRY_RIGHT,
|
NAUDIO_DRY_RIGHT,
|
||||||
|
@ -123,72 +136,72 @@ static void ENVMIXER(usf_state_t* state, uint32_t w1, uint32_t w2)
|
||||||
NAUDIO_WET_RIGHT,
|
NAUDIO_WET_RIGHT,
|
||||||
NAUDIO_MAIN,
|
NAUDIO_MAIN,
|
||||||
NAUDIO_COUNT,
|
NAUDIO_COUNT,
|
||||||
state->l_alist_naudio.dry,
|
hle->alist_naudio.dry,
|
||||||
state->l_alist_naudio.wet,
|
hle->alist_naudio.wet,
|
||||||
state->l_alist_naudio.vol,
|
hle->alist_naudio.vol,
|
||||||
state->l_alist_naudio.target,
|
hle->alist_naudio.target,
|
||||||
state->l_alist_naudio.rate,
|
hle->alist_naudio.rate,
|
||||||
address);
|
address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CLEARBUFF(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void CLEARBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t dmem = w1 + NAUDIO_MAIN;
|
uint16_t dmem = w1 + NAUDIO_MAIN;
|
||||||
uint16_t count = w2;
|
uint16_t count = w2;
|
||||||
|
|
||||||
alist_clear(state, dmem, count);
|
alist_clear(hle, dmem, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MIXER(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void MIXER(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
int16_t gain = w1;
|
int16_t gain = w1;
|
||||||
uint16_t dmemi = (w2 >> 16) + NAUDIO_MAIN;
|
uint16_t dmemi = (w2 >> 16) + NAUDIO_MAIN;
|
||||||
uint16_t dmemo = w2 + NAUDIO_MAIN;
|
uint16_t dmemo = w2 + NAUDIO_MAIN;
|
||||||
|
|
||||||
alist_mix(state, dmemo, dmemi, NAUDIO_COUNT, gain);
|
alist_mix(hle, dmemo, dmemi, NAUDIO_COUNT, gain);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LOADBUFF(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void LOADBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t count = (w1 >> 12) & 0xfff;
|
uint16_t count = (w1 >> 12) & 0xfff;
|
||||||
uint16_t dmem = (w1 & 0xfff) + NAUDIO_MAIN;
|
uint16_t dmem = (w1 & 0xfff) + NAUDIO_MAIN;
|
||||||
uint32_t address = (w2 & 0xffffff);
|
uint32_t address = (w2 & 0xffffff);
|
||||||
|
|
||||||
alist_load(state, dmem, address, count);
|
alist_load(hle, dmem, address, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SAVEBUFF(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void SAVEBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t count = (w1 >> 12) & 0xfff;
|
uint16_t count = (w1 >> 12) & 0xfff;
|
||||||
uint16_t dmem = (w1 & 0xfff) + NAUDIO_MAIN;
|
uint16_t dmem = (w1 & 0xfff) + NAUDIO_MAIN;
|
||||||
uint32_t address = (w2 & 0xffffff);
|
uint32_t address = (w2 & 0xffffff);
|
||||||
|
|
||||||
alist_save(state, dmem, address, count);
|
alist_save(hle, dmem, address, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LOADADPCM(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void LOADADPCM(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t count = w1;
|
uint16_t count = w1;
|
||||||
uint32_t address = (w2 & 0xffffff);
|
uint32_t address = (w2 & 0xffffff);
|
||||||
|
|
||||||
dram_load_u16(state, (uint16_t*)state->l_alist_naudio.table, address, count >> 1);
|
dram_load_u16(hle, (uint16_t*)hle->alist_naudio.table, address, count >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DMEMMOVE(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void DMEMMOVE(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t dmemi = w1 + NAUDIO_MAIN;
|
uint16_t dmemi = w1 + NAUDIO_MAIN;
|
||||||
uint16_t dmemo = (w2 >> 16) + NAUDIO_MAIN;
|
uint16_t dmemo = (w2 >> 16) + NAUDIO_MAIN;
|
||||||
uint16_t count = w2;
|
uint16_t count = w2;
|
||||||
|
|
||||||
alist_move(state, dmemo, dmemi, (count + 3) & ~3);
|
alist_move(hle, dmemo, dmemi, (count + 3) & ~3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SETLOOP(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void SETLOOP(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
state->l_alist_naudio.loop = (w2 & 0xffffff);
|
hle->alist_naudio.loop = (w2 & 0xffffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ADPCM(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void ADPCM(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint32_t address = (w1 & 0xffffff);
|
uint32_t address = (w1 & 0xffffff);
|
||||||
uint8_t flags = (w2 >> 28);
|
uint8_t flags = (w2 >> 28);
|
||||||
|
@ -197,19 +210,19 @@ static void ADPCM(usf_state_t* state, uint32_t w1, uint32_t w2)
|
||||||
uint16_t dmemo = (w2 & 0xfff) + NAUDIO_MAIN;
|
uint16_t dmemo = (w2 & 0xfff) + NAUDIO_MAIN;
|
||||||
|
|
||||||
alist_adpcm(
|
alist_adpcm(
|
||||||
state,
|
hle,
|
||||||
flags & 0x1,
|
flags & 0x1,
|
||||||
flags & 0x2,
|
flags & 0x2,
|
||||||
false, /* unsuported by this ucode */
|
false, /* unsuported by this ucode */
|
||||||
dmemo,
|
dmemo,
|
||||||
dmemi,
|
dmemi,
|
||||||
(count + 0x1f) & ~0x1f,
|
(count + 0x1f) & ~0x1f,
|
||||||
state->l_alist_naudio.table,
|
hle->alist_naudio.table,
|
||||||
state->l_alist_naudio.loop,
|
hle->alist_naudio.loop,
|
||||||
address);
|
address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RESAMPLE(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void RESAMPLE(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint32_t address = (w1 & 0xffffff);
|
uint32_t address = (w1 & 0xffffff);
|
||||||
uint8_t flags = (w2 >> 30);
|
uint8_t flags = (w2 >> 30);
|
||||||
|
@ -218,7 +231,7 @@ static void RESAMPLE(usf_state_t* state, uint32_t w1, uint32_t w2)
|
||||||
uint16_t dmemo = (w2 & 0x3) ? NAUDIO_MAIN2 : NAUDIO_MAIN;
|
uint16_t dmemo = (w2 & 0x3) ? NAUDIO_MAIN2 : NAUDIO_MAIN;
|
||||||
|
|
||||||
alist_resample(
|
alist_resample(
|
||||||
state,
|
hle,
|
||||||
flags & 0x1,
|
flags & 0x1,
|
||||||
false, /* TODO: check which ABI supports it */
|
false, /* TODO: check which ABI supports it */
|
||||||
dmemo,
|
dmemo,
|
||||||
|
@ -228,17 +241,17 @@ static void RESAMPLE(usf_state_t* state, uint32_t w1, uint32_t w2)
|
||||||
address);
|
address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void INTERLEAVE(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void INTERLEAVE(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
alist_interleave(state, NAUDIO_MAIN, NAUDIO_DRY_LEFT, NAUDIO_DRY_RIGHT, NAUDIO_COUNT);
|
alist_interleave(hle, NAUDIO_MAIN, NAUDIO_DRY_LEFT, NAUDIO_DRY_RIGHT, NAUDIO_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MP3ADDY(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void MP3ADDY(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/* global functions */
|
/* global functions */
|
||||||
void alist_process_naudio(usf_state_t* state)
|
void alist_process_naudio(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
static const acmd_callback_t ABI[0x10] = {
|
static const acmd_callback_t ABI[0x10] = {
|
||||||
SPNOOP, ADPCM, CLEARBUFF, ENVMIXER,
|
SPNOOP, ADPCM, CLEARBUFF, ENVMIXER,
|
||||||
|
@ -247,10 +260,10 @@ void alist_process_naudio(usf_state_t* state)
|
||||||
MIXER, INTERLEAVE, NAUDIO_02B0, SETLOOP
|
MIXER, INTERLEAVE, NAUDIO_02B0, SETLOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x10);
|
alist_process(hle, ABI, 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_naudio_bk(usf_state_t* state)
|
void alist_process_naudio_bk(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
/* TODO: see what differs from alist_process_naudio */
|
/* TODO: see what differs from alist_process_naudio */
|
||||||
static const acmd_callback_t ABI[0x10] = {
|
static const acmd_callback_t ABI[0x10] = {
|
||||||
|
@ -260,10 +273,10 @@ void alist_process_naudio_bk(usf_state_t* state)
|
||||||
MIXER, INTERLEAVE, NAUDIO_02B0, SETLOOP
|
MIXER, INTERLEAVE, NAUDIO_02B0, SETLOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x10);
|
alist_process(hle, ABI, 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_naudio_dk(usf_state_t* state)
|
void alist_process_naudio_dk(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
/* TODO: see what differs from alist_process_naudio */
|
/* TODO: see what differs from alist_process_naudio */
|
||||||
static const acmd_callback_t ABI[0x10] = {
|
static const acmd_callback_t ABI[0x10] = {
|
||||||
|
@ -273,10 +286,10 @@ void alist_process_naudio_dk(usf_state_t* state)
|
||||||
MIXER, INTERLEAVE, NAUDIO_02B0, SETLOOP
|
MIXER, INTERLEAVE, NAUDIO_02B0, SETLOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x10);
|
alist_process(hle, ABI, 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_naudio_mp3(usf_state_t* state)
|
void alist_process_naudio_mp3(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
static const acmd_callback_t ABI[0x10] = {
|
static const acmd_callback_t ABI[0x10] = {
|
||||||
UNKNOWN, ADPCM, CLEARBUFF, ENVMIXER,
|
UNKNOWN, ADPCM, CLEARBUFF, ENVMIXER,
|
||||||
|
@ -285,10 +298,10 @@ void alist_process_naudio_mp3(usf_state_t* state)
|
||||||
MIXER, INTERLEAVE, NAUDIO_14, SETLOOP
|
MIXER, INTERLEAVE, NAUDIO_14, SETLOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x10);
|
alist_process(hle, ABI, 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_naudio_cbfd(usf_state_t* state)
|
void alist_process_naudio_cbfd(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
/* TODO: see what differs from alist_process_naudio_mp3 */
|
/* TODO: see what differs from alist_process_naudio_mp3 */
|
||||||
static const acmd_callback_t ABI[0x10] = {
|
static const acmd_callback_t ABI[0x10] = {
|
||||||
|
@ -298,5 +311,5 @@ void alist_process_naudio_cbfd(usf_state_t* state)
|
||||||
MIXER, INTERLEAVE, NAUDIO_14, SETLOOP
|
MIXER, INTERLEAVE, NAUDIO_14, SETLOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x10);
|
alist_process(hle, ABI, 0x10);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,78 +21,77 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#else
|
||||||
|
#include "mystdbool.h"
|
||||||
|
#endif
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "../usf.h"
|
|
||||||
|
|
||||||
#include "alist_internal.h"
|
#include "alist_internal.h"
|
||||||
|
#include "hle_external.h"
|
||||||
|
#include "hle_internal.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "plugin.h"
|
|
||||||
|
|
||||||
#include "../usf_internal.h"
|
|
||||||
|
|
||||||
/* remove windows define to 0x06 */
|
/* remove windows define to 0x06 */
|
||||||
#ifdef DUPLICATE
|
#ifdef DUPLICATE
|
||||||
#undef DUPLICATE
|
#undef DUPLICATE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* audio commands definition */
|
/* audio commands definition */
|
||||||
static void UNKNOWN(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void UNKNOWN(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t acmd = (w1 >> 24);
|
uint8_t acmd = (w1 >> 24);
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_WARNING,
|
HleWarnMessage(hle->user_defined,
|
||||||
"Unknown audio comand %d: %08x %08x",
|
"Unknown audio command %d: %08x %08x",
|
||||||
acmd, w1, w2);
|
acmd, w1, w2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void SPNOOP(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void SPNOOP(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LOADADPCM(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void LOADADPCM(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t count = w1;
|
uint16_t count = w1;
|
||||||
uint32_t address = (w2 & 0xffffff);
|
uint32_t address = (w2 & 0xffffff);
|
||||||
|
|
||||||
dram_load_u16(state, (uint16_t*)state->l_alist_nead.table, address, count >> 1);
|
dram_load_u16(hle, (uint16_t*)hle->alist_nead.table, address, count >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SETLOOP(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void SETLOOP(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
state->l_alist_nead.loop = w2 & 0xffffff;
|
hle->alist_nead.loop = w2 & 0xffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SETBUFF(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void SETBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
state->l_alist_nead.in = w1;
|
hle->alist_nead.in = w1;
|
||||||
state->l_alist_nead.out = (w2 >> 16);
|
hle->alist_nead.out = (w2 >> 16);
|
||||||
state->l_alist_nead.count = w2;
|
hle->alist_nead.count = w2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ADPCM(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void ADPCM(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t flags = (w1 >> 16);
|
uint8_t flags = (w1 >> 16);
|
||||||
uint32_t address = (w2 & 0xffffff);
|
uint32_t address = (w2 & 0xffffff);
|
||||||
|
|
||||||
alist_adpcm(
|
alist_adpcm(
|
||||||
state,
|
hle,
|
||||||
flags & 0x1,
|
flags & 0x1,
|
||||||
flags & 0x2,
|
flags & 0x2,
|
||||||
flags & 0x4,
|
flags & 0x4,
|
||||||
state->l_alist_nead.out,
|
hle->alist_nead.out,
|
||||||
state->l_alist_nead.in,
|
hle->alist_nead.in,
|
||||||
(state->l_alist_nead.count + 0x1f) & ~0x1f,
|
(hle->alist_nead.count + 0x1f) & ~0x1f,
|
||||||
state->l_alist_nead.table,
|
hle->alist_nead.table,
|
||||||
state->l_alist_nead.loop,
|
hle->alist_nead.loop,
|
||||||
address);
|
address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CLEARBUFF(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void CLEARBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t dmem = w1;
|
uint16_t dmem = w1;
|
||||||
uint16_t count = w2;
|
uint16_t count = w2;
|
||||||
|
@ -100,70 +99,70 @@ static void CLEARBUFF(usf_state_t* state, uint32_t w1, uint32_t w2)
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
alist_clear(state, dmem, count);
|
alist_clear(hle, dmem, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LOADBUFF(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void LOADBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t count = (w1 >> 12) & 0xfff;
|
uint16_t count = (w1 >> 12) & 0xfff;
|
||||||
uint16_t dmem = (w1 & 0xfff);
|
uint16_t dmem = (w1 & 0xfff);
|
||||||
uint32_t address = (w2 & 0xffffff);
|
uint32_t address = (w2 & 0xffffff);
|
||||||
|
|
||||||
alist_load(state, dmem, address, count);
|
alist_load(hle, dmem, address, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SAVEBUFF(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void SAVEBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t count = (w1 >> 12) & 0xfff;
|
uint16_t count = (w1 >> 12) & 0xfff;
|
||||||
uint16_t dmem = (w1 & 0xfff);
|
uint16_t dmem = (w1 & 0xfff);
|
||||||
uint32_t address = (w2 & 0xffffff);
|
uint32_t address = (w2 & 0xffffff);
|
||||||
|
|
||||||
alist_save(state, dmem, address, count);
|
alist_save(hle, dmem, address, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MIXER(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void MIXER(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t count = (w1 >> 12) & 0xff0;
|
uint16_t count = (w1 >> 12) & 0xff0;
|
||||||
int16_t gain = w1;
|
int16_t gain = w1;
|
||||||
uint16_t dmemi = (w2 >> 16);
|
uint16_t dmemi = (w2 >> 16);
|
||||||
uint16_t dmemo = w2;
|
uint16_t dmemo = w2;
|
||||||
|
|
||||||
alist_mix(state, dmemo, dmemi, count, gain);
|
alist_mix(hle, dmemo, dmemi, count, gain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void RESAMPLE(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void RESAMPLE(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t flags = (w1 >> 16);
|
uint8_t flags = (w1 >> 16);
|
||||||
uint16_t pitch = w1;
|
uint16_t pitch = w1;
|
||||||
uint32_t address = (w2 & 0xffffff);
|
uint32_t address = (w2 & 0xffffff);
|
||||||
|
|
||||||
alist_resample(
|
alist_resample(
|
||||||
state,
|
hle,
|
||||||
flags & 0x1,
|
flags & 0x1,
|
||||||
false, /* TODO: check which ABI supports it */
|
false, /* TODO: check which ABI supports it */
|
||||||
state->l_alist_nead.out,
|
hle->alist_nead.out,
|
||||||
state->l_alist_nead.in,
|
hle->alist_nead.in,
|
||||||
(state->l_alist_nead.count + 0xf) & ~0xf,
|
(hle->alist_nead.count + 0xf) & ~0xf,
|
||||||
pitch << 1,
|
pitch << 1,
|
||||||
address);
|
address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RESAMPLE_ZOH(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void RESAMPLE_ZOH(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t pitch = w1;
|
uint16_t pitch = w1;
|
||||||
uint16_t pitch_accu = w2;
|
uint16_t pitch_accu = w2;
|
||||||
|
|
||||||
alist_resample_zoh(
|
alist_resample_zoh(
|
||||||
state,
|
hle,
|
||||||
state->l_alist_nead.out,
|
hle->alist_nead.out,
|
||||||
state->l_alist_nead.in,
|
hle->alist_nead.in,
|
||||||
state->l_alist_nead.count,
|
hle->alist_nead.count,
|
||||||
pitch << 1,
|
pitch << 1,
|
||||||
pitch_accu);
|
pitch_accu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DMEMMOVE(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void DMEMMOVE(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t dmemi = w1;
|
uint16_t dmemi = w1;
|
||||||
uint16_t dmemo = (w2 >> 16);
|
uint16_t dmemo = (w2 >> 16);
|
||||||
|
@ -172,194 +171,194 @@ static void DMEMMOVE(usf_state_t* state, uint32_t w1, uint32_t w2)
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
alist_move(state, dmemo, dmemi, (count + 3) & ~3);
|
alist_move(hle, dmemo, dmemi, (count + 3) & ~3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ENVSETUP1_MK(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void ENVSETUP1_MK(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
state->l_alist_nead.env_values[2] = (w1 >> 8) & 0xff00;
|
hle->alist_nead.env_values[2] = (w1 >> 8) & 0xff00;
|
||||||
state->l_alist_nead.env_steps[2] = 0;
|
hle->alist_nead.env_steps[2] = 0;
|
||||||
state->l_alist_nead.env_steps[0] = (w2 >> 16);
|
hle->alist_nead.env_steps[0] = (w2 >> 16);
|
||||||
state->l_alist_nead.env_steps[1] = w2;
|
hle->alist_nead.env_steps[1] = w2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ENVSETUP1(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void ENVSETUP1(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
state->l_alist_nead.env_values[2] = (w1 >> 8) & 0xff00;
|
hle->alist_nead.env_values[2] = (w1 >> 8) & 0xff00;
|
||||||
state->l_alist_nead.env_steps[2] = w1;
|
hle->alist_nead.env_steps[2] = w1;
|
||||||
state->l_alist_nead.env_steps[0] = (w2 >> 16);
|
hle->alist_nead.env_steps[0] = (w2 >> 16);
|
||||||
state->l_alist_nead.env_steps[1] = w2;
|
hle->alist_nead.env_steps[1] = w2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ENVSETUP2(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void ENVSETUP2(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
state->l_alist_nead.env_values[0] = (w2 >> 16);
|
hle->alist_nead.env_values[0] = (w2 >> 16);
|
||||||
state->l_alist_nead.env_values[1] = w2;
|
hle->alist_nead.env_values[1] = w2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ENVMIXER_MK(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void ENVMIXER_MK(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
int16_t xors[4];
|
int16_t xors[4];
|
||||||
|
|
||||||
uint16_t dmemi = (w1 >> 12) & 0xff0;
|
uint16_t dmemi = (w1 >> 12) & 0xff0;
|
||||||
uint8_t count = (w1 >> 8) & 0xff;
|
uint8_t count = (w1 >> 8) & 0xff;
|
||||||
xors[2] = 0; /* unsupported by this ucode */
|
|
||||||
xors[3] = 0; /* unsupported by this ucode */
|
|
||||||
xors[0] = 0 - (int16_t)((w1 & 0x2) >> 1);
|
|
||||||
xors[1] = 0 - (int16_t)((w1 & 0x1) );
|
|
||||||
uint16_t dmem_dl = (w2 >> 20) & 0xff0;
|
uint16_t dmem_dl = (w2 >> 20) & 0xff0;
|
||||||
uint16_t dmem_dr = (w2 >> 12) & 0xff0;
|
uint16_t dmem_dr = (w2 >> 12) & 0xff0;
|
||||||
uint16_t dmem_wl = (w2 >> 4) & 0xff0;
|
uint16_t dmem_wl = (w2 >> 4) & 0xff0;
|
||||||
uint16_t dmem_wr = (w2 << 4) & 0xff0;
|
uint16_t dmem_wr = (w2 << 4) & 0xff0;
|
||||||
|
xors[2] = 0; /* unsupported by this ucode */
|
||||||
|
xors[3] = 0; /* unsupported by this ucode */
|
||||||
|
xors[0] = 0 - (int16_t)((w1 & 0x2) >> 1);
|
||||||
|
xors[1] = 0 - (int16_t)((w1 & 0x1) );
|
||||||
|
|
||||||
alist_envmix_nead(
|
alist_envmix_nead(
|
||||||
state,
|
hle,
|
||||||
false, /* unsupported by this ucode */
|
false, /* unsupported by this ucode */
|
||||||
dmem_dl, dmem_dr,
|
dmem_dl, dmem_dr,
|
||||||
dmem_wl, dmem_wr,
|
dmem_wl, dmem_wr,
|
||||||
dmemi, count,
|
dmemi, count,
|
||||||
state->l_alist_nead.env_values,
|
hle->alist_nead.env_values,
|
||||||
state->l_alist_nead.env_steps,
|
hle->alist_nead.env_steps,
|
||||||
xors);
|
xors);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ENVMIXER(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void ENVMIXER(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
int16_t xors[4];
|
int16_t xors[4];
|
||||||
|
|
||||||
uint16_t dmemi = (w1 >> 12) & 0xff0;
|
uint16_t dmemi = (w1 >> 12) & 0xff0;
|
||||||
uint8_t count = (w1 >> 8) & 0xff;
|
uint8_t count = (w1 >> 8) & 0xff;
|
||||||
bool swap_wet_LR = (w1 >> 4) & 0x1;
|
bool swap_wet_LR = (w1 >> 4) & 0x1;
|
||||||
xors[2] = 0 - (int16_t)((w1 & 0x8) >> 1);
|
|
||||||
xors[3] = 0 - (int16_t)((w1 & 0x4) >> 1);
|
|
||||||
xors[0] = 0 - (int16_t)((w1 & 0x2) >> 1);
|
|
||||||
xors[1] = 0 - (int16_t)((w1 & 0x1) );
|
|
||||||
uint16_t dmem_dl = (w2 >> 20) & 0xff0;
|
uint16_t dmem_dl = (w2 >> 20) & 0xff0;
|
||||||
uint16_t dmem_dr = (w2 >> 12) & 0xff0;
|
uint16_t dmem_dr = (w2 >> 12) & 0xff0;
|
||||||
uint16_t dmem_wl = (w2 >> 4) & 0xff0;
|
uint16_t dmem_wl = (w2 >> 4) & 0xff0;
|
||||||
uint16_t dmem_wr = (w2 << 4) & 0xff0;
|
uint16_t dmem_wr = (w2 << 4) & 0xff0;
|
||||||
|
xors[2] = 0 - (int16_t)((w1 & 0x8) >> 1);
|
||||||
|
xors[3] = 0 - (int16_t)((w1 & 0x4) >> 1);
|
||||||
|
xors[0] = 0 - (int16_t)((w1 & 0x2) >> 1);
|
||||||
|
xors[1] = 0 - (int16_t)((w1 & 0x1) );
|
||||||
|
|
||||||
alist_envmix_nead(
|
alist_envmix_nead(
|
||||||
state,
|
hle,
|
||||||
swap_wet_LR,
|
swap_wet_LR,
|
||||||
dmem_dl, dmem_dr,
|
dmem_dl, dmem_dr,
|
||||||
dmem_wl, dmem_wr,
|
dmem_wl, dmem_wr,
|
||||||
dmemi, count,
|
dmemi, count,
|
||||||
state->l_alist_nead.env_values,
|
hle->alist_nead.env_values,
|
||||||
state->l_alist_nead.env_steps,
|
hle->alist_nead.env_steps,
|
||||||
xors);
|
xors);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DUPLICATE(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void DUPLICATE(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t count = (w1 >> 16);
|
uint8_t count = (w1 >> 16);
|
||||||
uint16_t dmemi = w1;
|
uint16_t dmemi = w1;
|
||||||
uint16_t dmemo = (w2 >> 16);
|
uint16_t dmemo = (w2 >> 16);
|
||||||
|
|
||||||
alist_repeat64(state, dmemo, dmemi, count);
|
alist_repeat64(hle, dmemo, dmemi, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void INTERL(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void INTERL(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t count = w1;
|
uint16_t count = w1;
|
||||||
uint16_t dmemi = (w2 >> 16);
|
uint16_t dmemi = (w2 >> 16);
|
||||||
uint16_t dmemo = w2;
|
uint16_t dmemo = w2;
|
||||||
|
|
||||||
alist_copy_every_other_sample(state, dmemo, dmemi, count);
|
alist_copy_every_other_sample(hle, dmemo, dmemi, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void INTERLEAVE_MK(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void INTERLEAVE_MK(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t left = (w2 >> 16);
|
uint16_t left = (w2 >> 16);
|
||||||
uint16_t right = w2;
|
uint16_t right = w2;
|
||||||
|
|
||||||
if (state->l_alist_nead.count == 0)
|
if (hle->alist_nead.count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
alist_interleave(state, state->l_alist_nead.out, left, right, state->l_alist_nead.count);
|
alist_interleave(hle, hle->alist_nead.out, left, right, hle->alist_nead.count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void INTERLEAVE(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void INTERLEAVE(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t count = ((w1 >> 12) & 0xff0);
|
uint16_t count = ((w1 >> 12) & 0xff0);
|
||||||
uint16_t dmemo = w1;
|
uint16_t dmemo = w1;
|
||||||
uint16_t left = (w2 >> 16);
|
uint16_t left = (w2 >> 16);
|
||||||
uint16_t right = w2;
|
uint16_t right = w2;
|
||||||
|
|
||||||
alist_interleave(state, dmemo, left, right, count);
|
alist_interleave(hle, dmemo, left, right, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ADDMIXER(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void ADDMIXER(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint16_t count = (w1 >> 12) & 0xff0;
|
uint16_t count = (w1 >> 12) & 0xff0;
|
||||||
uint16_t dmemi = (w2 >> 16);
|
uint16_t dmemi = (w2 >> 16);
|
||||||
uint16_t dmemo = w2;
|
uint16_t dmemo = w2;
|
||||||
|
|
||||||
alist_add(state, dmemo, dmemi, count);
|
alist_add(hle, dmemo, dmemi, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HILOGAIN(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void HILOGAIN(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
int8_t gain = (w1 >> 16); /* Q4.4 signed */
|
int8_t gain = (w1 >> 16); /* Q4.4 signed */
|
||||||
uint16_t count = w1;
|
uint16_t count = w1;
|
||||||
uint16_t dmem = (w2 >> 16);
|
uint16_t dmem = (w2 >> 16);
|
||||||
|
|
||||||
alist_multQ44(state, dmem, count, gain);
|
alist_multQ44(hle, dmem, count, gain);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FILTER(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void FILTER(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t flags = (w1 >> 16);
|
uint8_t flags = (w1 >> 16);
|
||||||
uint32_t address = (w2 & 0xffffff);
|
uint32_t address = (w2 & 0xffffff);
|
||||||
|
|
||||||
if (flags > 1) {
|
if (flags > 1) {
|
||||||
state->l_alist_nead.filter_count = w1;
|
hle->alist_nead.filter_count = w1;
|
||||||
state->l_alist_nead.filter_lut_address[0] = address; /* t6 */
|
hle->alist_nead.filter_lut_address[0] = address; /* t6 */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uint16_t dmem = w1;
|
uint16_t dmem = w1;
|
||||||
|
|
||||||
state->l_alist_nead.filter_lut_address[1] = address + 0x10; /* t5 */
|
hle->alist_nead.filter_lut_address[1] = address + 0x10; /* t5 */
|
||||||
alist_filter(state, dmem, state->l_alist_nead.filter_count, address, state->l_alist_nead.filter_lut_address);
|
alist_filter(hle, dmem, hle->alist_nead.filter_count, address, hle->alist_nead.filter_lut_address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SEGMENT(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void SEGMENT(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NEAD_16(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void NEAD_16(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t count = (w1 >> 16);
|
uint8_t count = (w1 >> 16);
|
||||||
uint16_t dmemi = w1;
|
uint16_t dmemi = w1;
|
||||||
uint16_t dmemo = (w2 >> 16);
|
uint16_t dmemo = (w2 >> 16);
|
||||||
uint16_t block_size = w2;
|
uint16_t block_size = w2;
|
||||||
|
|
||||||
alist_copy_blocks(state, dmemo, dmemi, block_size, count);
|
alist_copy_blocks(hle, dmemo, dmemi, block_size, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void POLEF(usf_state_t* state, uint32_t w1, uint32_t w2)
|
static void POLEF(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
{
|
{
|
||||||
uint8_t flags = (w1 >> 16);
|
uint8_t flags = (w1 >> 16);
|
||||||
uint16_t gain = w1;
|
uint16_t gain = w1;
|
||||||
uint32_t address = (w2 & 0xffffff);
|
uint32_t address = (w2 & 0xffffff);
|
||||||
|
|
||||||
if (state->l_alist_nead.count == 0)
|
if (hle->alist_nead.count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
alist_polef(
|
alist_polef(
|
||||||
state,
|
hle,
|
||||||
flags & A_INIT,
|
flags & A_INIT,
|
||||||
state->l_alist_nead.out,
|
hle->alist_nead.out,
|
||||||
state->l_alist_nead.in,
|
hle->alist_nead.in,
|
||||||
state->l_alist_nead.count,
|
hle->alist_nead.count,
|
||||||
gain,
|
gain,
|
||||||
state->l_alist_nead.table,
|
hle->alist_nead.table,
|
||||||
address);
|
address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void alist_process_nead_mk(usf_state_t* state)
|
void alist_process_nead_mk(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
static const acmd_callback_t ABI[0x20] = {
|
static const acmd_callback_t ABI[0x20] = {
|
||||||
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
|
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
|
||||||
|
@ -372,10 +371,10 @@ void alist_process_nead_mk(usf_state_t* state)
|
||||||
SPNOOP, SPNOOP, SPNOOP, SPNOOP
|
SPNOOP, SPNOOP, SPNOOP, SPNOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x20);
|
alist_process(hle, ABI, 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_nead_sf(usf_state_t* state)
|
void alist_process_nead_sf(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
static const acmd_callback_t ABI[0x20] = {
|
static const acmd_callback_t ABI[0x20] = {
|
||||||
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
|
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
|
||||||
|
@ -388,10 +387,10 @@ void alist_process_nead_sf(usf_state_t* state)
|
||||||
SPNOOP, SPNOOP, SPNOOP, SPNOOP
|
SPNOOP, SPNOOP, SPNOOP, SPNOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x20);
|
alist_process(hle, ABI, 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_nead_sfj(usf_state_t* state)
|
void alist_process_nead_sfj(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
static const acmd_callback_t ABI[0x20] = {
|
static const acmd_callback_t ABI[0x20] = {
|
||||||
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
|
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
|
||||||
|
@ -404,10 +403,10 @@ void alist_process_nead_sfj(usf_state_t* state)
|
||||||
SPNOOP, SPNOOP, SPNOOP, SPNOOP
|
SPNOOP, SPNOOP, SPNOOP, SPNOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x20);
|
alist_process(hle, ABI, 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_nead_fz(usf_state_t* state)
|
void alist_process_nead_fz(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
static const acmd_callback_t ABI[0x20] = {
|
static const acmd_callback_t ABI[0x20] = {
|
||||||
UNKNOWN, ADPCM, CLEARBUFF, SPNOOP,
|
UNKNOWN, ADPCM, CLEARBUFF, SPNOOP,
|
||||||
|
@ -420,10 +419,10 @@ void alist_process_nead_fz(usf_state_t* state)
|
||||||
SPNOOP, SPNOOP, SPNOOP, SPNOOP
|
SPNOOP, SPNOOP, SPNOOP, SPNOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x20);
|
alist_process(hle, ABI, 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_nead_wrjb(usf_state_t* state)
|
void alist_process_nead_wrjb(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
static const acmd_callback_t ABI[0x20] = {
|
static const acmd_callback_t ABI[0x20] = {
|
||||||
SPNOOP, ADPCM, CLEARBUFF, UNKNOWN,
|
SPNOOP, ADPCM, CLEARBUFF, UNKNOWN,
|
||||||
|
@ -436,10 +435,10 @@ void alist_process_nead_wrjb(usf_state_t* state)
|
||||||
SPNOOP, SPNOOP, SPNOOP, SPNOOP
|
SPNOOP, SPNOOP, SPNOOP, SPNOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x20);
|
alist_process(hle, ABI, 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_nead_ys(usf_state_t* state)
|
void alist_process_nead_ys(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
static const acmd_callback_t ABI[0x18] = {
|
static const acmd_callback_t ABI[0x18] = {
|
||||||
UNKNOWN, ADPCM, CLEARBUFF, UNKNOWN,
|
UNKNOWN, ADPCM, CLEARBUFF, UNKNOWN,
|
||||||
|
@ -450,10 +449,10 @@ void alist_process_nead_ys(usf_state_t* state)
|
||||||
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
|
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x18);
|
alist_process(hle, ABI, 0x18);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_nead_1080(usf_state_t* state)
|
void alist_process_nead_1080(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
static const acmd_callback_t ABI[0x18] = {
|
static const acmd_callback_t ABI[0x18] = {
|
||||||
UNKNOWN, ADPCM, CLEARBUFF, UNKNOWN,
|
UNKNOWN, ADPCM, CLEARBUFF, UNKNOWN,
|
||||||
|
@ -464,10 +463,10 @@ void alist_process_nead_1080(usf_state_t* state)
|
||||||
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
|
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x18);
|
alist_process(hle, ABI, 0x18);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_nead_oot(usf_state_t* state)
|
void alist_process_nead_oot(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
static const acmd_callback_t ABI[0x18] = {
|
static const acmd_callback_t ABI[0x18] = {
|
||||||
UNKNOWN, ADPCM, CLEARBUFF, UNKNOWN,
|
UNKNOWN, ADPCM, CLEARBUFF, UNKNOWN,
|
||||||
|
@ -478,10 +477,10 @@ void alist_process_nead_oot(usf_state_t* state)
|
||||||
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
|
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x18);
|
alist_process(hle, ABI, 0x18);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_nead_mm(usf_state_t* state)
|
void alist_process_nead_mm(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
static const acmd_callback_t ABI[0x18] = {
|
static const acmd_callback_t ABI[0x18] = {
|
||||||
UNKNOWN, ADPCM, CLEARBUFF, SPNOOP,
|
UNKNOWN, ADPCM, CLEARBUFF, SPNOOP,
|
||||||
|
@ -492,10 +491,10 @@ void alist_process_nead_mm(usf_state_t* state)
|
||||||
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
|
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x18);
|
alist_process(hle, ABI, 0x18);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_nead_mmb(usf_state_t* state)
|
void alist_process_nead_mmb(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
static const acmd_callback_t ABI[0x18] = {
|
static const acmd_callback_t ABI[0x18] = {
|
||||||
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
|
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
|
||||||
|
@ -506,10 +505,10 @@ void alist_process_nead_mmb(usf_state_t* state)
|
||||||
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
|
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x18);
|
alist_process(hle, ABI, 0x18);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alist_process_nead_ac(usf_state_t* state)
|
void alist_process_nead_ac(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
static const acmd_callback_t ABI[0x18] = {
|
static const acmd_callback_t ABI[0x18] = {
|
||||||
UNKNOWN, ADPCM, CLEARBUFF, SPNOOP,
|
UNKNOWN, ADPCM, CLEARBUFF, SPNOOP,
|
||||||
|
@ -520,5 +519,5 @@ void alist_process_nead_ac(usf_state_t* state)
|
||||||
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
|
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
alist_process(state, ABI, 0x18);
|
alist_process(hle, ABI, 0x18);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,13 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
static inline int16_t clamp_s16(int_fast32_t x)
|
#ifdef _MSC_VER
|
||||||
|
#define INLINE __forceinline
|
||||||
|
#else
|
||||||
|
#define INLINE __attribute__((always_inline))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
INLINE static int16_t clamp_s16(int_fast32_t x)
|
||||||
{
|
{
|
||||||
x = (x < INT16_MIN) ? INT16_MIN: x;
|
x = (x < INT16_MIN) ? INT16_MIN: x;
|
||||||
x = (x > INT16_MAX) ? INT16_MAX: x;
|
x = (x > INT16_MAX) ? INT16_MAX: x;
|
||||||
|
|
|
@ -77,8 +77,6 @@ int32_t rdot(size_t n, const int16_t *x, const int16_t *y)
|
||||||
void adpcm_compute_residuals(int16_t* dst, const int16_t* src,
|
void adpcm_compute_residuals(int16_t* dst, const int16_t* src,
|
||||||
const int16_t* cb_entry, const int16_t* last_samples, size_t count)
|
const int16_t* cb_entry, const int16_t* last_samples, size_t count)
|
||||||
{
|
{
|
||||||
assert(count <= 8);
|
|
||||||
|
|
||||||
const int16_t* const book1 = cb_entry;
|
const int16_t* const book1 = cb_entry;
|
||||||
const int16_t* const book2 = cb_entry + 8;
|
const int16_t* const book2 = cb_entry + 8;
|
||||||
|
|
||||||
|
@ -87,6 +85,8 @@ void adpcm_compute_residuals(int16_t* dst, const int16_t* src,
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
assert(count <= 8);
|
||||||
|
|
||||||
for(i = 0; i < count; ++i) {
|
for(i = 0; i < count; ++i) {
|
||||||
int32_t accu = (int32_t)src[i] << 11;
|
int32_t accu = (int32_t)src[i] << 11;
|
||||||
accu += book1[i]*l1 + book2[i]*l2 + rdot(i, book2, src);
|
accu += book1[i]*l1 + book2[i]*l2 + rdot(i, book2, src);
|
||||||
|
|
|
@ -29,7 +29,13 @@ extern const int16_t RESAMPLE_LUT[64 * 4];
|
||||||
|
|
||||||
int32_t rdot(size_t n, const int16_t *x, const int16_t *y);
|
int32_t rdot(size_t n, const int16_t *x, const int16_t *y);
|
||||||
|
|
||||||
static inline int16_t adpcm_predict_sample(uint8_t byte, uint8_t mask,
|
#ifdef _MSC_VER
|
||||||
|
#define INLINE __forceinline
|
||||||
|
#else
|
||||||
|
#define INLINE __attribute__((always_inline))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
INLINE static int16_t adpcm_predict_sample(uint8_t byte, uint8_t mask,
|
||||||
unsigned lshift, unsigned rshift)
|
unsigned lshift, unsigned rshift)
|
||||||
{
|
{
|
||||||
int16_t sample = (uint16_t)(byte & mask) << lshift;
|
int16_t sample = (uint16_t)(byte & mask) << lshift;
|
||||||
|
|
|
@ -23,12 +23,7 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../usf.h"
|
#include "hle_internal.h"
|
||||||
|
|
||||||
#include "plugin.h"
|
|
||||||
#include "cicx105.h"
|
|
||||||
|
|
||||||
#include "../usf_internal.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* During IPL3 stage of CIC x105 games, the RSP performs some checks and transactions
|
* During IPL3 stage of CIC x105 games, the RSP performs some checks and transactions
|
||||||
|
@ -38,15 +33,15 @@
|
||||||
*
|
*
|
||||||
* Found in Banjo-Tooie, Zelda, Perfect Dark, ...)
|
* Found in Banjo-Tooie, Zelda, Perfect Dark, ...)
|
||||||
**/
|
**/
|
||||||
void cicx105_ucode(usf_state_t* state)
|
void cicx105_ucode(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
/* memcpy is okay to use because access constrains are met (alignment, size) */
|
/* memcpy is okay to use because access constrains are met (alignment, size) */
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned char *dst = state->N64MEM + 0x2fb1f0;
|
unsigned char *dst = hle->dram + 0x2fb1f0;
|
||||||
unsigned char *src = state->IMEM + 0x120;
|
unsigned char *src = hle->imem + 0x120;
|
||||||
|
|
||||||
/* dma_read(0x1120, 0x1e8, 0x1e8) */
|
/* dma_read(0x1120, 0x1e8, 0x1e8) */
|
||||||
memcpy(state->IMEM + 0x120, state->N64MEM + 0x1e8, 0x1f0);
|
memcpy(hle->imem + 0x120, hle->dram + 0x1e8, 0x1f0);
|
||||||
|
|
||||||
/* dma_write(0x1120, 0x2fb1f0, 0xfe817000) */
|
/* dma_write(0x1120, 0x2fb1f0, 0xfe817000) */
|
||||||
for (i = 0; i < 24; ++i) {
|
for (i = 0; i < 24; ++i) {
|
||||||
|
|
|
@ -22,7 +22,9 @@
|
||||||
#ifndef CICX105_H
|
#ifndef CICX105_H
|
||||||
#define CICX105_H
|
#define CICX105_H
|
||||||
|
|
||||||
void cicx105_ucode(usf_state_t* state);
|
struct hle_t;
|
||||||
|
|
||||||
|
void cicx105_ucode(struct hle_t* hle);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,449 @@
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Mupen64plus-rsp-hle - hle.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. *
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#include <stdbool.h>
|
||||||
|
#else
|
||||||
|
#include "mystdbool.h"
|
||||||
|
#endif
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef ENABLE_TASK_DUMP
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "hle_external.h"
|
||||||
|
#include "hle_internal.h"
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
|
#include "alist.h"
|
||||||
|
#include "cicx105.h"
|
||||||
|
#include "jpeg.h"
|
||||||
|
#include "musyx.h"
|
||||||
|
|
||||||
|
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
|
||||||
|
/* some rsp status flags */
|
||||||
|
#define SP_STATUS_HALT 0x1
|
||||||
|
#define SP_STATUS_BROKE 0x2
|
||||||
|
#define SP_STATUS_INTR_ON_BREAK 0x40
|
||||||
|
#define SP_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 bool is_task(struct hle_t* hle);
|
||||||
|
static void rsp_break(struct hle_t* hle, unsigned int setbits);
|
||||||
|
static void forward_gfx_task(struct hle_t* hle);
|
||||||
|
static bool try_fast_audio_dispatching(struct hle_t* hle);
|
||||||
|
static bool try_fast_task_dispatching(struct hle_t* hle);
|
||||||
|
static void normal_task_dispatching(struct hle_t* hle);
|
||||||
|
static void non_task_dispatching(struct hle_t* hle);
|
||||||
|
|
||||||
|
#ifdef ENABLE_TASK_DUMP
|
||||||
|
static void dump_binary(const char *const filename, const unsigned char *const bytes,
|
||||||
|
unsigned int size);
|
||||||
|
static void dump_task(struct hle_t* hle, const char *const filename);
|
||||||
|
static void dump_unknown_task(struct hle_t* hle, unsigned int sum);
|
||||||
|
static void dump_unknown_non_task(struct hle_t* hle, unsigned int sum);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* local variables */
|
||||||
|
static const bool FORWARD_AUDIO = false, FORWARD_GFX = true;
|
||||||
|
|
||||||
|
/* Global functions */
|
||||||
|
void hle_init(struct hle_t* hle,
|
||||||
|
unsigned char* dram,
|
||||||
|
unsigned char* dmem,
|
||||||
|
unsigned char* imem,
|
||||||
|
unsigned int* mi_intr,
|
||||||
|
unsigned int* sp_mem_addr,
|
||||||
|
unsigned int* sp_dram_addr,
|
||||||
|
unsigned int* sp_rd_length,
|
||||||
|
unsigned int* sp_wr_length,
|
||||||
|
unsigned int* sp_status,
|
||||||
|
unsigned int* sp_dma_full,
|
||||||
|
unsigned int* sp_dma_busy,
|
||||||
|
unsigned int* sp_pc,
|
||||||
|
unsigned int* sp_semaphore,
|
||||||
|
unsigned int* dpc_start,
|
||||||
|
unsigned int* dpc_end,
|
||||||
|
unsigned int* dpc_current,
|
||||||
|
unsigned int* dpc_status,
|
||||||
|
unsigned int* dpc_clock,
|
||||||
|
unsigned int* dpc_bufbusy,
|
||||||
|
unsigned int* dpc_pipebusy,
|
||||||
|
unsigned int* dpc_tmem,
|
||||||
|
void* user_defined)
|
||||||
|
{
|
||||||
|
hle->dram = dram;
|
||||||
|
hle->dmem = dmem;
|
||||||
|
hle->imem = imem;
|
||||||
|
hle->mi_intr = mi_intr;
|
||||||
|
hle->sp_mem_addr = sp_mem_addr;
|
||||||
|
hle->sp_dram_addr = sp_dram_addr;
|
||||||
|
hle->sp_rd_length = sp_rd_length;
|
||||||
|
hle->sp_wr_length = sp_wr_length;
|
||||||
|
hle->sp_status = sp_status;
|
||||||
|
hle->sp_dma_full = sp_dma_full;
|
||||||
|
hle->sp_dma_busy = sp_dma_busy;
|
||||||
|
hle->sp_pc = sp_pc;
|
||||||
|
hle->sp_semaphore = sp_semaphore;
|
||||||
|
hle->dpc_start = dpc_start;
|
||||||
|
hle->dpc_end = dpc_end;
|
||||||
|
hle->dpc_current = dpc_current;
|
||||||
|
hle->dpc_status = dpc_status;
|
||||||
|
hle->dpc_clock = dpc_clock;
|
||||||
|
hle->dpc_bufbusy = dpc_bufbusy;
|
||||||
|
hle->dpc_pipebusy = dpc_pipebusy;
|
||||||
|
hle->dpc_tmem = dpc_tmem;
|
||||||
|
hle->user_defined = user_defined;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hle_execute(struct hle_t* hle)
|
||||||
|
{
|
||||||
|
if (is_task(hle)) {
|
||||||
|
if (!try_fast_task_dispatching(hle))
|
||||||
|
normal_task_dispatching(hle);
|
||||||
|
rsp_break(hle, SP_STATUS_TASKDONE);
|
||||||
|
} else {
|
||||||
|
non_task_dispatching(hle);
|
||||||
|
rsp_break(hle, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* local 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 bool is_task(struct hle_t* hle)
|
||||||
|
{
|
||||||
|
return (*dmem_u32(hle, TASK_UCODE_BOOT_SIZE) <= 0x1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rsp_break(struct hle_t* hle, unsigned int setbits)
|
||||||
|
{
|
||||||
|
*hle->sp_status |= setbits | SP_STATUS_BROKE | SP_STATUS_HALT;
|
||||||
|
|
||||||
|
if ((*hle->sp_status & SP_STATUS_INTR_ON_BREAK)) {
|
||||||
|
*hle->mi_intr |= MI_INTR_SP;
|
||||||
|
HleCheckInterrupts(hle->user_defined);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void forward_gfx_task(struct hle_t* hle)
|
||||||
|
{
|
||||||
|
HleProcessDlistList(hle->user_defined);
|
||||||
|
*hle->dpc_status &= ~DP_STATUS_FREEZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool try_fast_audio_dispatching(struct hle_t* hle)
|
||||||
|
{
|
||||||
|
/* identify audio ucode by using the content of ucode_data */
|
||||||
|
uint32_t ucode_data = *dmem_u32(hle, TASK_UCODE_DATA);
|
||||||
|
uint32_t v;
|
||||||
|
|
||||||
|
if (*dram_u32(hle, ucode_data) == 0x00000001) {
|
||||||
|
if (*dram_u32(hle, ucode_data + 0x30) == 0xf0000f00) {
|
||||||
|
v = *dram_u32(hle, ucode_data + 0x28);
|
||||||
|
switch(v)
|
||||||
|
{
|
||||||
|
case 0x1e24138c: /* audio ABI (most common) */
|
||||||
|
alist_process_audio(hle); return true;
|
||||||
|
case 0x1dc8138c: /* GoldenEye */
|
||||||
|
alist_process_audio_ge(hle); return true;
|
||||||
|
case 0x1e3c1390: /* BlastCorp, DiddyKongRacing */
|
||||||
|
alist_process_audio_bc(hle); return true;
|
||||||
|
default:
|
||||||
|
HleWarnMessage(hle->user_defined, "ABI1 identification regression: v=%08x", v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
v = *dram_u32(hle, ucode_data + 0x10);
|
||||||
|
switch(v)
|
||||||
|
{
|
||||||
|
case 0x11181350: /* MarioKart, WaveRace (E) */
|
||||||
|
alist_process_nead_mk(hle); return true;
|
||||||
|
case 0x111812e0: /* StarFox (J) */
|
||||||
|
alist_process_nead_sfj(hle); return true;
|
||||||
|
case 0x110412ac: /* WaveRace (J RevB) */
|
||||||
|
alist_process_nead_wrjb(hle); return true;
|
||||||
|
case 0x110412cc: /* StarFox/LylatWars (except J) */
|
||||||
|
alist_process_nead_sf(hle); return true;
|
||||||
|
case 0x1cd01250: /* FZeroX */
|
||||||
|
alist_process_nead_fz(hle); return true;
|
||||||
|
case 0x1f08122c: /* YoshisStory */
|
||||||
|
alist_process_nead_ys(hle); return true;
|
||||||
|
case 0x1f38122c: /* 1080° Snowboarding */
|
||||||
|
alist_process_nead_1080(hle); return true;
|
||||||
|
case 0x1f681230: /* Zelda OoT / Zelda MM (J, J RevA) */
|
||||||
|
alist_process_nead_oot(hle); return true;
|
||||||
|
case 0x1f801250: /* Zelda MM (except J, J RevA, E Beta), PokemonStadium 2 */
|
||||||
|
alist_process_nead_mm(hle); return true;
|
||||||
|
case 0x109411f8: /* Zelda MM (E Beta) */
|
||||||
|
alist_process_nead_mmb(hle); return true;
|
||||||
|
case 0x1eac11b8: /* AnimalCrossing */
|
||||||
|
alist_process_nead_ac(hle); return true;
|
||||||
|
case 0x00010010: /* MusyX v2 (IndianaJones, BattleForNaboo) */
|
||||||
|
musyx_v2_task(hle); return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
HleWarnMessage(hle->user_defined, "ABI2 identification regression: v=%08x", v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
v = *dram_u32(hle, ucode_data + 0x10);
|
||||||
|
switch(v)
|
||||||
|
{
|
||||||
|
case 0x00000001: /* MusyX v1
|
||||||
|
RogueSquadron, ResidentEvil2, PolarisSnoCross,
|
||||||
|
TheWorldIsNotEnough, RugratsInParis, NBAShowTime,
|
||||||
|
HydroThunder, Tarzan, GauntletLegend, Rush2049 */
|
||||||
|
musyx_v1_task(hle); return true;
|
||||||
|
case 0x0000127c: /* naudio (many games) */
|
||||||
|
alist_process_naudio(hle); return true;
|
||||||
|
case 0x00001280: /* BanjoKazooie */
|
||||||
|
alist_process_naudio_bk(hle); return true;
|
||||||
|
case 0x1c58126c: /* DonkeyKong */
|
||||||
|
alist_process_naudio_dk(hle); return true;
|
||||||
|
case 0x1ae8143c: /* BanjoTooie, JetForceGemini, MickeySpeedWayUSA, PerfectDark */
|
||||||
|
alist_process_naudio_mp3(hle); return true;
|
||||||
|
case 0x1ab0140c: /* ConkerBadFurDay */
|
||||||
|
alist_process_naudio_cbfd(hle); return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
HleWarnMessage(hle->user_defined, "ABI3 identification regression: v=%08x", v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool try_fast_task_dispatching(struct hle_t* hle)
|
||||||
|
{
|
||||||
|
/* identify task ucode by its type */
|
||||||
|
switch (*dmem_u32(hle, TASK_TYPE)) {
|
||||||
|
case 1:
|
||||||
|
if (FORWARD_GFX) {
|
||||||
|
forward_gfx_task(hle);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if (FORWARD_AUDIO) {
|
||||||
|
HleProcessAlistList(hle->user_defined);
|
||||||
|
return true;
|
||||||
|
} else if (try_fast_audio_dispatching(hle))
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
HleShowCFB(hle->user_defined);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void normal_task_dispatching(struct hle_t* hle)
|
||||||
|
{
|
||||||
|
const unsigned int sum =
|
||||||
|
sum_bytes((void*)dram_u32(hle, *dmem_u32(hle, TASK_UCODE)), min(*dmem_u32(hle, 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(hle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* JPEG: found in Pokemon Stadium J */
|
||||||
|
case 0x2c85a:
|
||||||
|
jpeg_decode_PS0(hle);
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* JPEG: found in Zelda Ocarina of Time, Pokemon Stadium 1, Pokemon Stadium 2 */
|
||||||
|
case 0x2caa6:
|
||||||
|
jpeg_decode_PS(hle);
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* JPEG: found in Ogre Battle, Bottom of the 9th */
|
||||||
|
case 0x130de:
|
||||||
|
case 0x278b0:
|
||||||
|
jpeg_decode_OB(hle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HleWarnMessage(hle->user_defined, "unknown OSTask: sum: %x PC:%x", sum, *hle->sp_pc);
|
||||||
|
#ifdef ENABLE_TASK_DUMP
|
||||||
|
dump_unknown_task(hle, sum);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void non_task_dispatching(struct hle_t* hle)
|
||||||
|
{
|
||||||
|
const unsigned int sum = sum_bytes(hle->imem, 0x1000 >> 1);
|
||||||
|
|
||||||
|
switch (sum) {
|
||||||
|
/* CIC x105 ucode (used during boot of CIC x105 games) */
|
||||||
|
case 0x9e2: /* CIC 6105 */
|
||||||
|
case 0x9f2: /* CIC 7105 */
|
||||||
|
cicx105_ucode(hle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HleWarnMessage(hle->user_defined, "unknown RSP code: sum: %x PC:%x", sum, *hle->sp_pc);
|
||||||
|
#ifdef ENABLE_TASK_DUMP
|
||||||
|
dump_unknown_non_task(hle, sum);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ENABLE_TASK_DUMP
|
||||||
|
static void dump_unknown_task(struct hle_t* hle, unsigned int sum)
|
||||||
|
{
|
||||||
|
char filename[256];
|
||||||
|
uint32_t ucode = *dmem_u32(hle, TASK_UCODE);
|
||||||
|
uint32_t ucode_data = *dmem_u32(hle, TASK_UCODE_DATA);
|
||||||
|
uint32_t data_ptr = *dmem_u32(hle, TASK_DATA_PTR);
|
||||||
|
|
||||||
|
sprintf(&filename[0], "task_%x.log", sum);
|
||||||
|
dump_task(hle, filename);
|
||||||
|
|
||||||
|
/* dump ucode_boot */
|
||||||
|
sprintf(&filename[0], "ucode_boot_%x.bin", sum);
|
||||||
|
dump_binary(filename, (void*)dram_u32(hle, *dmem_u32(hle, TASK_UCODE_BOOT)), *dmem_u32(hle, TASK_UCODE_BOOT_SIZE));
|
||||||
|
|
||||||
|
/* dump ucode */
|
||||||
|
if (ucode != 0) {
|
||||||
|
sprintf(&filename[0], "ucode_%x.bin", sum);
|
||||||
|
dump_binary(filename, (void*)dram_u32(hle, ucode), 0xf80);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dump ucode_data */
|
||||||
|
if (ucode_data != 0) {
|
||||||
|
sprintf(&filename[0], "ucode_data_%x.bin", sum);
|
||||||
|
dump_binary(filename, (void*)dram_u32(hle, ucode_data), *dmem_u32(hle, TASK_UCODE_DATA_SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dump data */
|
||||||
|
if (data_ptr != 0) {
|
||||||
|
sprintf(&filename[0], "data_%x.bin", sum);
|
||||||
|
dump_binary(filename, (void*)dram_u32(hle, data_ptr), *dmem_u32(hle, TASK_DATA_SIZE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_unknown_non_task(struct hle_t* hle, unsigned int sum)
|
||||||
|
{
|
||||||
|
char filename[256];
|
||||||
|
|
||||||
|
/* dump IMEM & DMEM for further analysis */
|
||||||
|
sprintf(&filename[0], "imem_%x.bin", sum);
|
||||||
|
dump_binary(filename, hle->imem, 0x1000);
|
||||||
|
|
||||||
|
sprintf(&filename[0], "dmem_%x.bin", sum);
|
||||||
|
dump_binary(filename, hle->dmem, 0x1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
hleErrorMessage(hle->user_defined, "Writing error on %s", filename);
|
||||||
|
fclose(f);
|
||||||
|
} else
|
||||||
|
hleErrorMessage(hle->user_defined, "Couldn't open %s for writing !", filename);
|
||||||
|
} else
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_task(struct hle_t* hle, const char *const filename)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
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",
|
||||||
|
*dmem_u32(hle, TASK_TYPE),
|
||||||
|
*dmem_u32(hle, TASK_FLAGS),
|
||||||
|
*dmem_u32(hle, TASK_UCODE_BOOT), *dmem_u32(hle, TASK_UCODE_BOOT_SIZE),
|
||||||
|
*dmem_u32(hle, TASK_UCODE), *dmem_u32(hle, TASK_UCODE_SIZE),
|
||||||
|
*dmem_u32(hle, TASK_UCODE_DATA), *dmem_u32(hle, TASK_UCODE_DATA_SIZE),
|
||||||
|
*dmem_u32(hle, TASK_DRAM_STACK), *dmem_u32(hle, TASK_DRAM_STACK_SIZE),
|
||||||
|
*dmem_u32(hle, TASK_OUTPUT_BUFF), *dmem_u32(hle, TASK_OUTPUT_BUFF_SIZE),
|
||||||
|
*dmem_u32(hle, TASK_DATA_PTR), *dmem_u32(hle, TASK_DATA_SIZE),
|
||||||
|
*dmem_u32(hle, TASK_YIELD_DATA_PTR), *dmem_u32(hle, TASK_YIELD_DATA_SIZE));
|
||||||
|
fclose(f);
|
||||||
|
} else
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,54 @@
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Mupen64plus-rsp-hle - hle.h *
|
||||||
|
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||||
|
* Copyright (C) 2014 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. *
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef HLE_H
|
||||||
|
#define HLE_H
|
||||||
|
|
||||||
|
#include "hle_internal.h"
|
||||||
|
|
||||||
|
void hle_init(struct hle_t* hle,
|
||||||
|
unsigned char* dram,
|
||||||
|
unsigned char* dmem,
|
||||||
|
unsigned char* imem,
|
||||||
|
unsigned int* mi_intr,
|
||||||
|
unsigned int* sp_mem_addr,
|
||||||
|
unsigned int* sp_dram_addr,
|
||||||
|
unsigned int* sp_rd_length,
|
||||||
|
unsigned int* sp_wr_length,
|
||||||
|
unsigned int* sp_status,
|
||||||
|
unsigned int* sp_dma_full,
|
||||||
|
unsigned int* sp_dma_busy,
|
||||||
|
unsigned int* sp_pc,
|
||||||
|
unsigned int* sp_semaphore,
|
||||||
|
unsigned int* dpc_start,
|
||||||
|
unsigned int* dpc_end,
|
||||||
|
unsigned int* dpc_current,
|
||||||
|
unsigned int* dpc_status,
|
||||||
|
unsigned int* dpc_clock,
|
||||||
|
unsigned int* dpc_bufbusy,
|
||||||
|
unsigned int* dpc_pipebusy,
|
||||||
|
unsigned int* dpc_tmem,
|
||||||
|
void* user_defined);
|
||||||
|
|
||||||
|
void hle_execute(struct hle_t* hle);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
* Mupen64plus-rsp-hle - main.h *
|
* Mupen64plus-rsp-hle - hle_external.h *
|
||||||
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||||
* Copyright (C) 2014 Bobby Smiles *
|
* Copyright (C) 2014 Bobby Smiles *
|
||||||
* *
|
* *
|
||||||
|
@ -19,10 +19,20 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
#ifndef MAIN_H
|
#ifndef HLE_EXTERNAL_H
|
||||||
#define MAIN_H
|
#define HLE_EXTERNAL_H
|
||||||
|
|
||||||
void hle_execute(usf_state_t* state);
|
/* users of the hle core are expected to define these functions */
|
||||||
|
|
||||||
|
void HleVerboseMessage(void* user_defined, const char *message, ...);
|
||||||
|
void HleErrorMessage(void* user_defined, const char *message, ...);
|
||||||
|
void HleWarnMessage(void* user_defined, const char *message, ...);
|
||||||
|
|
||||||
|
void HleCheckInterrupts(void* user_defined);
|
||||||
|
void HleProcessDlistList(void* user_defined);
|
||||||
|
void HleProcessAlistList(void* user_defined);
|
||||||
|
void HleProcessRdpList(void* user_defined);
|
||||||
|
void HleShowCFB(void* user_defined);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Mupen64plus-rsp-hle - hle_internal.h *
|
||||||
|
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||||
|
* Copyright (C) 2014 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. *
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef HLE_INTERNAL_H
|
||||||
|
#define HLE_INTERNAL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "alist.h"
|
||||||
|
|
||||||
|
/* rsp hle internal state - internal usage only */
|
||||||
|
struct hle_t
|
||||||
|
{
|
||||||
|
unsigned char* dram;
|
||||||
|
unsigned char* dmem;
|
||||||
|
unsigned char* imem;
|
||||||
|
|
||||||
|
unsigned int* mi_intr;
|
||||||
|
|
||||||
|
unsigned int* sp_mem_addr;
|
||||||
|
unsigned int* sp_dram_addr;
|
||||||
|
unsigned int* sp_rd_length;
|
||||||
|
unsigned int* sp_wr_length;
|
||||||
|
unsigned int* sp_status;
|
||||||
|
unsigned int* sp_dma_full;
|
||||||
|
unsigned int* sp_dma_busy;
|
||||||
|
unsigned int* sp_pc;
|
||||||
|
unsigned int* sp_semaphore;
|
||||||
|
|
||||||
|
unsigned int* dpc_start;
|
||||||
|
unsigned int* dpc_end;
|
||||||
|
unsigned int* dpc_current;
|
||||||
|
unsigned int* dpc_status;
|
||||||
|
unsigned int* dpc_clock;
|
||||||
|
unsigned int* dpc_bufbusy;
|
||||||
|
unsigned int* dpc_pipebusy;
|
||||||
|
unsigned int* dpc_tmem;
|
||||||
|
|
||||||
|
/* for user convenience, this will be passed to "external" functions */
|
||||||
|
void* user_defined;
|
||||||
|
|
||||||
|
|
||||||
|
/* alist.c */
|
||||||
|
uint8_t alist_buffer[0x1000];
|
||||||
|
|
||||||
|
/* alist_audio.c */
|
||||||
|
struct alist_audio_t alist_audio;
|
||||||
|
|
||||||
|
/* alist_naudio.c */
|
||||||
|
struct alist_naudio_t alist_naudio;
|
||||||
|
|
||||||
|
/* alist_nead.c */
|
||||||
|
struct alist_nead_t alist_nead;
|
||||||
|
|
||||||
|
/* mp3.c */
|
||||||
|
uint8_t mp3_buffer[0x1000];
|
||||||
|
/* FIXME: rewrite mp3 module to avoid these */
|
||||||
|
uint32_t mp3_inPtr;
|
||||||
|
uint32_t mp3_outPtr;
|
||||||
|
uint32_t mp3_t6;
|
||||||
|
uint32_t mp3_t5;
|
||||||
|
uint32_t mp3_t4;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -25,21 +25,18 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "../usf.h"
|
|
||||||
|
|
||||||
#include "arithmetics.h"
|
#include "arithmetics.h"
|
||||||
|
#include "hle_external.h"
|
||||||
|
#include "hle_internal.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "plugin.h"
|
|
||||||
|
|
||||||
#include "../usf_internal.h"
|
|
||||||
|
|
||||||
#define SUBBLOCK_SIZE 64
|
#define SUBBLOCK_SIZE 64
|
||||||
|
|
||||||
typedef void (*tile_line_emitter_t)(usf_state_t* state, const int16_t *y, const int16_t *u, uint32_t address);
|
typedef void (*tile_line_emitter_t)(struct hle_t* hle, const int16_t *y, const int16_t *u, uint32_t address);
|
||||||
typedef void (*subblock_transform_t)(int16_t *dst, const int16_t *src);
|
typedef void (*subblock_transform_t)(int16_t *dst, const int16_t *src);
|
||||||
|
|
||||||
/* standard jpeg ucode decoder */
|
/* standard jpeg ucode decoder */
|
||||||
static void jpeg_decode_std(usf_state_t* state,
|
static void jpeg_decode_std(struct hle_t* hle,
|
||||||
const char *const version,
|
const char *const version,
|
||||||
const subblock_transform_t transform_luma,
|
const subblock_transform_t transform_luma,
|
||||||
const subblock_transform_t transform_chroma,
|
const subblock_transform_t transform_chroma,
|
||||||
|
@ -55,8 +52,8 @@ 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);
|
static uint16_t GetRGBA(int16_t y, int16_t u, int16_t v);
|
||||||
|
|
||||||
/* tile line emitters */
|
/* tile line emitters */
|
||||||
static void EmitYUVTileLine(usf_state_t* state, const int16_t *y, const int16_t *u, uint32_t address);
|
static void EmitYUVTileLine(struct hle_t* hle, const int16_t *y, const int16_t *u, uint32_t address);
|
||||||
static void EmitRGBATileLine(usf_state_t* state, const int16_t *y, const int16_t *u, uint32_t address);
|
static void EmitRGBATileLine(struct hle_t* hle, const int16_t *y, const int16_t *u, uint32_t address);
|
||||||
|
|
||||||
/* macroblocks operations */
|
/* macroblocks operations */
|
||||||
static void decode_macroblock_ob(int16_t *macroblock, int32_t *y_dc, int32_t *u_dc, int32_t *v_dc, const int16_t *qtable);
|
static void decode_macroblock_ob(int16_t *macroblock, int32_t *y_dc, int32_t *u_dc, int32_t *v_dc, const int16_t *qtable);
|
||||||
|
@ -65,8 +62,8 @@ static void decode_macroblock_std(const subblock_transform_t transform_luma,
|
||||||
int16_t *macroblock,
|
int16_t *macroblock,
|
||||||
unsigned int subblock_count,
|
unsigned int subblock_count,
|
||||||
const int16_t qtables[3][SUBBLOCK_SIZE]);
|
const int16_t qtables[3][SUBBLOCK_SIZE]);
|
||||||
static void EmitTilesMode0(usf_state_t* state, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address);
|
static void EmitTilesMode0(struct hle_t* hle, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address);
|
||||||
static void EmitTilesMode2(usf_state_t* state, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address);
|
static void EmitTilesMode2(struct hle_t* hle, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address);
|
||||||
|
|
||||||
/* subblocks operations */
|
/* subblocks operations */
|
||||||
static void TransposeSubBlock(int16_t *dst, const int16_t *src);
|
static void TransposeSubBlock(int16_t *dst, const int16_t *src);
|
||||||
|
@ -141,24 +138,24 @@ static const float IDCT_K[10] = {
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* JPEG decoding ucode found in Japanese exclusive version of Pokemon Stadium.
|
* JPEG decoding ucode found in Japanese exclusive version of Pokemon Stadium.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void jpeg_decode_PS0(usf_state_t* state)
|
void jpeg_decode_PS0(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
jpeg_decode_std(state, "PS0", RescaleYSubBlock, RescaleUVSubBlock, EmitYUVTileLine);
|
jpeg_decode_std(hle, "PS0", RescaleYSubBlock, RescaleUVSubBlock, EmitYUVTileLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* JPEG decoding ucode found in Ocarina of Time, Pokemon Stadium 1 and
|
* JPEG decoding ucode found in Ocarina of Time, Pokemon Stadium 1 and
|
||||||
* Pokemon Stadium 2.
|
* Pokemon Stadium 2.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void jpeg_decode_PS(usf_state_t* state)
|
void jpeg_decode_PS(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
jpeg_decode_std(state, "PS", NULL, NULL, EmitRGBATileLine);
|
jpeg_decode_std(hle, "PS", NULL, NULL, EmitRGBATileLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* JPEG decoding ucode found in Ogre Battle and Bottom of the 9th.
|
* JPEG decoding ucode found in Ogre Battle and Bottom of the 9th.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void jpeg_decode_OB(usf_state_t* state)
|
void jpeg_decode_OB(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
int16_t qtable[SUBBLOCK_SIZE];
|
int16_t qtable[SUBBLOCK_SIZE];
|
||||||
unsigned int mb;
|
unsigned int mb;
|
||||||
|
@ -167,15 +164,15 @@ void jpeg_decode_OB(usf_state_t* state)
|
||||||
int32_t u_dc = 0;
|
int32_t u_dc = 0;
|
||||||
int32_t v_dc = 0;
|
int32_t v_dc = 0;
|
||||||
|
|
||||||
uint32_t address = *dmem_u32(state, TASK_DATA_PTR);
|
uint32_t address = *dmem_u32(hle, TASK_DATA_PTR);
|
||||||
const unsigned int macroblock_count = *dmem_u32(state, TASK_DATA_SIZE);
|
const unsigned int macroblock_count = *dmem_u32(hle, TASK_DATA_SIZE);
|
||||||
const int qscale = *dmem_u32(state, TASK_YIELD_DATA_SIZE);
|
const int qscale = *dmem_u32(hle, TASK_YIELD_DATA_SIZE);
|
||||||
|
|
||||||
DebugMessage(state,
|
HleVerboseMessage(hle->user_defined,
|
||||||
M64MSG_VERBOSE, "jpeg_decode_OB: *buffer=%x, #MB=%d, qscale=%d",
|
"jpeg_decode_OB: *buffer=%x, #MB=%d, qscale=%d",
|
||||||
address,
|
address,
|
||||||
macroblock_count,
|
macroblock_count,
|
||||||
qscale);
|
qscale);
|
||||||
|
|
||||||
if (qscale != 0) {
|
if (qscale != 0) {
|
||||||
if (qscale > 0)
|
if (qscale > 0)
|
||||||
|
@ -187,9 +184,9 @@ void jpeg_decode_OB(usf_state_t* state)
|
||||||
for (mb = 0; mb < macroblock_count; ++mb) {
|
for (mb = 0; mb < macroblock_count; ++mb) {
|
||||||
int16_t macroblock[6 * SUBBLOCK_SIZE];
|
int16_t macroblock[6 * SUBBLOCK_SIZE];
|
||||||
|
|
||||||
dram_load_u16(state, (uint16_t *)macroblock, address, 6 * SUBBLOCK_SIZE);
|
dram_load_u16(hle, (uint16_t *)macroblock, address, 6 * SUBBLOCK_SIZE);
|
||||||
decode_macroblock_ob(macroblock, &y_dc, &u_dc, &v_dc, (qscale != 0) ? qtable : NULL);
|
decode_macroblock_ob(macroblock, &y_dc, &u_dc, &v_dc, (qscale != 0) ? qtable : NULL);
|
||||||
EmitTilesMode2(state, EmitYUVTileLine, macroblock, address);
|
EmitTilesMode2(hle, EmitYUVTileLine, macroblock, address);
|
||||||
|
|
||||||
address += (2 * 6 * SUBBLOCK_SIZE);
|
address += (2 * 6 * SUBBLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
@ -197,7 +194,7 @@ void jpeg_decode_OB(usf_state_t* state)
|
||||||
|
|
||||||
|
|
||||||
/* local functions */
|
/* local functions */
|
||||||
static void jpeg_decode_std(usf_state_t* state,
|
static void jpeg_decode_std(struct hle_t* hle,
|
||||||
const char *const version,
|
const char *const version,
|
||||||
const subblock_transform_t transform_luma,
|
const subblock_transform_t transform_luma,
|
||||||
const subblock_transform_t transform_chroma,
|
const subblock_transform_t transform_chroma,
|
||||||
|
@ -217,49 +214,52 @@ static void jpeg_decode_std(usf_state_t* state,
|
||||||
int16_t macroblock[6 * SUBBLOCK_SIZE];
|
int16_t macroblock[6 * SUBBLOCK_SIZE];
|
||||||
uint32_t data_ptr;
|
uint32_t data_ptr;
|
||||||
|
|
||||||
if (*dmem_u32(state, TASK_FLAGS) & 0x1) {
|
if (*dmem_u32(hle, TASK_FLAGS) & 0x1) {
|
||||||
DebugMessage(state, M64MSG_WARNING, "jpeg_decode_%s: task yielding not implemented", version);
|
HleWarnMessage(hle->user_defined,
|
||||||
|
"jpeg_decode_%s: task yielding not implemented", version);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data_ptr = *dmem_u32(state, TASK_DATA_PTR);
|
data_ptr = *dmem_u32(hle, TASK_DATA_PTR);
|
||||||
address = *dram_u32(state, data_ptr);
|
address = *dram_u32(hle, data_ptr);
|
||||||
macroblock_count = *dram_u32(state, data_ptr + 4);
|
macroblock_count = *dram_u32(hle, data_ptr + 4);
|
||||||
mode = *dram_u32(state, data_ptr + 8);
|
mode = *dram_u32(hle, data_ptr + 8);
|
||||||
qtableY_ptr = *dram_u32(state, data_ptr + 12);
|
qtableY_ptr = *dram_u32(hle, data_ptr + 12);
|
||||||
qtableU_ptr = *dram_u32(state, data_ptr + 16);
|
qtableU_ptr = *dram_u32(hle, data_ptr + 16);
|
||||||
qtableV_ptr = *dram_u32(state, data_ptr + 20);
|
qtableV_ptr = *dram_u32(hle, data_ptr + 20);
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "jpeg_decode_%s: *buffer=%x, #MB=%d, mode=%d, *Qy=%x, *Qu=%x, *Qv=%x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
version,
|
"jpeg_decode_%s: *buffer=%x, #MB=%d, mode=%d, *Qy=%x, *Qu=%x, *Qv=%x",
|
||||||
address,
|
version,
|
||||||
macroblock_count,
|
address,
|
||||||
mode,
|
macroblock_count,
|
||||||
qtableY_ptr,
|
mode,
|
||||||
qtableU_ptr,
|
qtableY_ptr,
|
||||||
qtableV_ptr);
|
qtableU_ptr,
|
||||||
|
qtableV_ptr);
|
||||||
|
|
||||||
if (mode != 0 && mode != 2) {
|
if (mode != 0 && mode != 2) {
|
||||||
DebugMessage(state, M64MSG_WARNING, "jpeg_decode_%s: invalid mode %d", version, mode);
|
HleWarnMessage(hle->user_defined,
|
||||||
|
"jpeg_decode_%s: invalid mode %d", version, mode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
subblock_count = mode + 4;
|
subblock_count = mode + 4;
|
||||||
macroblock_size = subblock_count * SUBBLOCK_SIZE;
|
macroblock_size = subblock_count * SUBBLOCK_SIZE;
|
||||||
|
|
||||||
dram_load_u16(state, (uint16_t *)qtables[0], qtableY_ptr, SUBBLOCK_SIZE);
|
dram_load_u16(hle, (uint16_t *)qtables[0], qtableY_ptr, SUBBLOCK_SIZE);
|
||||||
dram_load_u16(state, (uint16_t *)qtables[1], qtableU_ptr, SUBBLOCK_SIZE);
|
dram_load_u16(hle, (uint16_t *)qtables[1], qtableU_ptr, SUBBLOCK_SIZE);
|
||||||
dram_load_u16(state, (uint16_t *)qtables[2], qtableV_ptr, SUBBLOCK_SIZE);
|
dram_load_u16(hle, (uint16_t *)qtables[2], qtableV_ptr, SUBBLOCK_SIZE);
|
||||||
|
|
||||||
for (mb = 0; mb < macroblock_count; ++mb) {
|
for (mb = 0; mb < macroblock_count; ++mb) {
|
||||||
dram_load_u16(state, (uint16_t *)macroblock, address, macroblock_size);
|
dram_load_u16(hle, (uint16_t *)macroblock, address, macroblock_size);
|
||||||
decode_macroblock_std(transform_luma, transform_chroma,
|
decode_macroblock_std(transform_luma, transform_chroma,
|
||||||
macroblock, subblock_count, (const int16_t (*)[SUBBLOCK_SIZE])qtables);
|
macroblock, subblock_count, (const int16_t (*)[SUBBLOCK_SIZE])qtables);
|
||||||
|
|
||||||
if (mode == 0)
|
if (mode == 0)
|
||||||
EmitTilesMode0(state, emit_line, macroblock, address);
|
EmitTilesMode0(hle, emit_line, macroblock, address);
|
||||||
else
|
else
|
||||||
EmitTilesMode2(state, emit_line, macroblock, address);
|
EmitTilesMode2(hle, emit_line, macroblock, address);
|
||||||
|
|
||||||
address += 2 * macroblock_size;
|
address += 2 * macroblock_size;
|
||||||
}
|
}
|
||||||
|
@ -309,7 +309,7 @@ static uint16_t GetRGBA(int16_t y, int16_t u, int16_t v)
|
||||||
return (r << 4) | (g >> 1) | (b >> 6) | 1;
|
return (r << 4) | (g >> 1) | (b >> 6) | 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EmitYUVTileLine(usf_state_t* state, const int16_t *y, const int16_t *u, uint32_t address)
|
static void EmitYUVTileLine(struct hle_t* hle, const int16_t *y, const int16_t *u, uint32_t address)
|
||||||
{
|
{
|
||||||
uint32_t uyvy[8];
|
uint32_t uyvy[8];
|
||||||
|
|
||||||
|
@ -325,10 +325,10 @@ static void EmitYUVTileLine(usf_state_t* state, const int16_t *y, const int16_t
|
||||||
uyvy[6] = GetUYVY(y2[4], y2[5], u[6], v[6]);
|
uyvy[6] = GetUYVY(y2[4], y2[5], u[6], v[6]);
|
||||||
uyvy[7] = GetUYVY(y2[6], y2[7], u[7], v[7]);
|
uyvy[7] = GetUYVY(y2[6], y2[7], u[7], v[7]);
|
||||||
|
|
||||||
dram_store_u32(state, uyvy, address, 8);
|
dram_store_u32(hle, uyvy, address, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EmitRGBATileLine(usf_state_t* state, const int16_t *y, const int16_t *u, uint32_t address)
|
static void EmitRGBATileLine(struct hle_t* hle, const int16_t *y, const int16_t *u, uint32_t address)
|
||||||
{
|
{
|
||||||
uint16_t rgba[16];
|
uint16_t rgba[16];
|
||||||
|
|
||||||
|
@ -352,10 +352,10 @@ static void EmitRGBATileLine(usf_state_t* state, const int16_t *y, const int16_t
|
||||||
rgba[14] = GetRGBA(y2[6], u[7], v[7]);
|
rgba[14] = GetRGBA(y2[6], u[7], v[7]);
|
||||||
rgba[15] = GetRGBA(y2[7], u[7], v[7]);
|
rgba[15] = GetRGBA(y2[7], u[7], v[7]);
|
||||||
|
|
||||||
dram_store_u16(state, rgba, address, 16);
|
dram_store_u16(hle, rgba, address, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EmitTilesMode0(usf_state_t* state, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address)
|
static void EmitTilesMode0(struct hle_t* hle, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -363,7 +363,7 @@ static void EmitTilesMode0(usf_state_t* state, const tile_line_emitter_t emit_li
|
||||||
unsigned int u_offset = 2 * SUBBLOCK_SIZE;
|
unsigned int u_offset = 2 * SUBBLOCK_SIZE;
|
||||||
|
|
||||||
for (i = 0; i < 8; ++i) {
|
for (i = 0; i < 8; ++i) {
|
||||||
emit_line(state, ¯oblock[y_offset], ¯oblock[u_offset], address);
|
emit_line(hle, ¯oblock[y_offset], ¯oblock[u_offset], address);
|
||||||
|
|
||||||
y_offset += 8;
|
y_offset += 8;
|
||||||
u_offset += 8;
|
u_offset += 8;
|
||||||
|
@ -371,7 +371,7 @@ static void EmitTilesMode0(usf_state_t* state, const tile_line_emitter_t emit_li
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EmitTilesMode2(usf_state_t* state, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address)
|
static void EmitTilesMode2(struct hle_t* hle, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -379,8 +379,8 @@ static void EmitTilesMode2(usf_state_t* state, const tile_line_emitter_t emit_li
|
||||||
unsigned int u_offset = 4 * SUBBLOCK_SIZE;
|
unsigned int u_offset = 4 * SUBBLOCK_SIZE;
|
||||||
|
|
||||||
for (i = 0; i < 8; ++i) {
|
for (i = 0; i < 8; ++i) {
|
||||||
emit_line(state, ¯oblock[y_offset], ¯oblock[u_offset], address);
|
emit_line(hle, ¯oblock[y_offset], ¯oblock[u_offset], address);
|
||||||
emit_line(state, ¯oblock[y_offset + 8], ¯oblock[u_offset], address + 32);
|
emit_line(hle, ¯oblock[y_offset + 8], ¯oblock[u_offset], address + 32);
|
||||||
|
|
||||||
y_offset += (i == 3) ? SUBBLOCK_SIZE + 16 : 16;
|
y_offset += (i == 3) ? SUBBLOCK_SIZE + 16 : 16;
|
||||||
u_offset += 8;
|
u_offset += 8;
|
||||||
|
|
|
@ -22,9 +22,11 @@
|
||||||
#ifndef JPEG_H
|
#ifndef JPEG_H
|
||||||
#define JPEG_H
|
#define JPEG_H
|
||||||
|
|
||||||
void jpeg_decode_PS0(usf_state_t* state);
|
struct hle_t;
|
||||||
void jpeg_decode_PS(usf_state_t* state);
|
|
||||||
void jpeg_decode_OB(usf_state_t* state);
|
void jpeg_decode_PS0(struct hle_t* hle);
|
||||||
|
void jpeg_decode_PS(struct hle_t* hle);
|
||||||
|
void jpeg_decode_OB(struct hle_t* hle);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,393 +0,0 @@
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
||||||
* Mupen64plus-rsp-hle - main.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 <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef ENABLE_TASK_DUMP
|
|
||||||
#include <stdio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../usf.h"
|
|
||||||
|
|
||||||
#include "memory.h"
|
|
||||||
#include "plugin.h"
|
|
||||||
|
|
||||||
#include "alist.h"
|
|
||||||
#include "cicx105.h"
|
|
||||||
#include "jpeg.h"
|
|
||||||
#include "musyx.h"
|
|
||||||
|
|
||||||
#include "../exception.h"
|
|
||||||
#include "../registers.h"
|
|
||||||
|
|
||||||
#include "../usf_internal.h"
|
|
||||||
|
|
||||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
|
||||||
|
|
||||||
#define SP_STATUS_INTR_ON_BREAK 0x40
|
|
||||||
#define SP_STATUS_TASKDONE 0x200
|
|
||||||
|
|
||||||
/* some rdp status flags */
|
|
||||||
#define DP_STATUS_FREEZE 0x2
|
|
||||||
|
|
||||||
|
|
||||||
/* helper functions prototypes */
|
|
||||||
static unsigned int sum_bytes(const unsigned char *bytes, unsigned int size);
|
|
||||||
static bool is_task(usf_state_t* state);
|
|
||||||
static void rsp_break(usf_state_t* state, unsigned int setbits);
|
|
||||||
static void forward_gfx_task(usf_state_t* state);
|
|
||||||
static void forward_audio_task(usf_state_t* state);
|
|
||||||
static void show_cfb(usf_state_t* state);
|
|
||||||
static bool try_fast_audio_dispatching(usf_state_t* state);
|
|
||||||
static bool try_fast_task_dispatching(usf_state_t* state);
|
|
||||||
static void normal_task_dispatching(usf_state_t* state);
|
|
||||||
static void non_task_dispatching(usf_state_t* state);
|
|
||||||
|
|
||||||
#ifdef ENABLE_TASK_DUMP
|
|
||||||
static void dump_binary(usf_state_t* state, const char *const filename, const unsigned char *const bytes,
|
|
||||||
unsigned int size);
|
|
||||||
static void dump_task(usf_state_t* state, const char *const filename);
|
|
||||||
static void dump_unknown_task(usf_state_t* state, unsigned int sum);
|
|
||||||
static void dump_unknown_non_task(usf_state_t* state, unsigned int sum);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* local variables */
|
|
||||||
static const bool FORWARD_AUDIO = false, FORWARD_GFX = true;
|
|
||||||
|
|
||||||
/* Global functions */
|
|
||||||
void hle_execute(usf_state_t* state)
|
|
||||||
{
|
|
||||||
if (is_task(state)) {
|
|
||||||
if (!try_fast_task_dispatching(state))
|
|
||||||
normal_task_dispatching(state);
|
|
||||||
rsp_break(state, SP_STATUS_TASKDONE);
|
|
||||||
} else {
|
|
||||||
non_task_dispatching(state);
|
|
||||||
rsp_break(state, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* local 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 bool is_task(usf_state_t* state)
|
|
||||||
{
|
|
||||||
return (*dmem_u32(state, TASK_UCODE_BOOT_SIZE) <= 0x1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rsp_break(usf_state_t* state, unsigned int setbits)
|
|
||||||
{
|
|
||||||
SP_STATUS_REG |= setbits | SP_STATUS_BROKE | SP_STATUS_HALT;
|
|
||||||
|
|
||||||
if ((SP_STATUS_REG & SP_STATUS_INTR_ON_BREAK)) {
|
|
||||||
MI_INTR_REG |= MI_INTR_SP;
|
|
||||||
CheckInterrupts(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool try_fast_audio_dispatching(usf_state_t* state)
|
|
||||||
{
|
|
||||||
/* identify audio ucode by using the content of ucode_data */
|
|
||||||
uint32_t ucode_data = *dmem_u32(state, TASK_UCODE_DATA);
|
|
||||||
uint32_t v;
|
|
||||||
|
|
||||||
if (*dram_u32(state, ucode_data) == 0x00000001) {
|
|
||||||
if (*dram_u32(state, ucode_data + 0x30) == 0xf0000f00) {
|
|
||||||
v = *dram_u32(state, ucode_data + 0x28);
|
|
||||||
switch(v)
|
|
||||||
{
|
|
||||||
case 0x1e24138c: /* audio ABI (most common) */
|
|
||||||
alist_process_audio(state); return true;
|
|
||||||
case 0x1dc8138c: /* GoldenEye */
|
|
||||||
alist_process_audio_ge(state); return true;
|
|
||||||
case 0x1e3c1390: /* BlastCorp, DiddyKongRacing */
|
|
||||||
alist_process_audio_bc(state); return true;
|
|
||||||
default:
|
|
||||||
DebugMessage(state, M64MSG_WARNING, "ABI1 identification regression: v=%08x", v);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v = *dram_u32(state, ucode_data + 0x10);
|
|
||||||
switch(v)
|
|
||||||
{
|
|
||||||
case 0x11181350: /* MarioKart, WaveRace (E) */
|
|
||||||
alist_process_nead_mk(state); return true;
|
|
||||||
case 0x111812e0: /* StarFox (J) */
|
|
||||||
alist_process_nead_sfj(state); return true;
|
|
||||||
case 0x110412ac: /* WaveRace (J RevB) */
|
|
||||||
alist_process_nead_wrjb(state); return true;
|
|
||||||
case 0x110412cc: /* StarFox/LylatWars (except J) */
|
|
||||||
alist_process_nead_sf(state); return true;
|
|
||||||
case 0x1cd01250: /* FZeroX */
|
|
||||||
alist_process_nead_fz(state); return true;
|
|
||||||
case 0x1f08122c: /* YoshisStory */
|
|
||||||
alist_process_nead_ys(state); return true;
|
|
||||||
case 0x1f38122c: /* 1080° Snowboarding */
|
|
||||||
alist_process_nead_1080(state); return true;
|
|
||||||
case 0x1f681230: /* Zelda OoT / Zelda MM (J, J RevA) */
|
|
||||||
alist_process_nead_oot(state); return true;
|
|
||||||
case 0x1f801250: /* Zelda MM (except J, J RevA, E Beta), PokemonStadium 2 */
|
|
||||||
alist_process_nead_mm(state); return true;
|
|
||||||
case 0x109411f8: /* Zelda MM (E Beta) */
|
|
||||||
alist_process_nead_mmb(state); return true;
|
|
||||||
case 0x1eac11b8: /* AnimalCrossing */
|
|
||||||
alist_process_nead_ac(state); return true;
|
|
||||||
case 0x00010010: /* MusyX v2 (IndianaJones, BattleForNaboo) */
|
|
||||||
musyx_v2_task(state); return true;
|
|
||||||
|
|
||||||
default:
|
|
||||||
DebugMessage(state, M64MSG_WARNING, "ABI2 identification regression: v=%08x", v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v = *dram_u32(state, ucode_data + 0x10);
|
|
||||||
switch(v)
|
|
||||||
{
|
|
||||||
case 0x00000001: /* MusyX v1
|
|
||||||
RogueSquadron, ResidentEvil2, PolarisSnoCross,
|
|
||||||
TheWorldIsNotEnough, RugratsInParis, NBAShowTime,
|
|
||||||
HydroThunder, Tarzan, GauntletLegend, Rush2049 */
|
|
||||||
musyx_v1_task(state); return true;
|
|
||||||
case 0x0000127c: /* naudio (many games) */
|
|
||||||
alist_process_naudio(state); return true;
|
|
||||||
case 0x00001280: /* BanjoKazooie */
|
|
||||||
alist_process_naudio_bk(state); return true;
|
|
||||||
case 0x1c58126c: /* DonkeyKong */
|
|
||||||
alist_process_naudio_dk(state); return true;
|
|
||||||
case 0x1ae8143c: /* BanjoTooie, JetForceGemini, MickeySpeedWayUSA, PerfectDark */
|
|
||||||
alist_process_naudio_mp3(state); return true;
|
|
||||||
case 0x1ab0140c: /* ConkerBadFurDay */
|
|
||||||
alist_process_naudio_cbfd(state); return true;
|
|
||||||
|
|
||||||
default:
|
|
||||||
DebugMessage(state, M64MSG_WARNING, "ABI3 identification regression: v=%08x", v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool try_fast_task_dispatching(usf_state_t* state)
|
|
||||||
{
|
|
||||||
/* identify task ucode by its type */
|
|
||||||
switch (*dmem_u32(state, TASK_TYPE)) {
|
|
||||||
case 1:
|
|
||||||
/*if (FORWARD_GFX) {
|
|
||||||
forward_gfx_task();
|
|
||||||
return true;
|
|
||||||
}*/
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
/*if (FORWARD_AUDIO) {
|
|
||||||
forward_audio_task();
|
|
||||||
return true;
|
|
||||||
} else*/ if (try_fast_audio_dispatching(state))
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 7:
|
|
||||||
/*show_cfb();*/
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void normal_task_dispatching(usf_state_t* state)
|
|
||||||
{
|
|
||||||
const unsigned int sum =
|
|
||||||
sum_bytes((void*)dram_u32(state, *dmem_u32(state, TASK_UCODE)), min(*dmem_u32(state, 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(state);
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* JPEG: found in Zelda Ocarina of Time, Pokemon Stadium 1, Pokemon Stadium 2 */
|
|
||||||
case 0x2caa6:
|
|
||||||
jpeg_decode_PS(state);
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* JPEG: found in Ogre Battle, Bottom of the 9th */
|
|
||||||
case 0x130de:
|
|
||||||
case 0x278b0:
|
|
||||||
jpeg_decode_OB(state);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_WARNING, "unknown OSTask: sum: %x PC:%x", sum, SP_PC_REG);
|
|
||||||
#ifdef ENABLE_TASK_DUMP
|
|
||||||
dump_unknown_task(state, sum);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void non_task_dispatching(usf_state_t* state)
|
|
||||||
{
|
|
||||||
const unsigned int sum = sum_bytes(state->IMEM, 0x1000 >> 1);
|
|
||||||
|
|
||||||
switch (sum) {
|
|
||||||
/* CIC x105 ucode (used during boot of CIC x105 games) */
|
|
||||||
case 0x9e2: /* CIC 6105 */
|
|
||||||
case 0x9f2: /* CIC 7105 */
|
|
||||||
cicx105_ucode(state);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_WARNING, "unknown RSP code: sum: %x PC:%x", sum, SP_PC_REG);
|
|
||||||
#ifdef ENABLE_TASK_DUMP
|
|
||||||
dump_unknown_non_task(state, sum);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_TASK_DUMP
|
|
||||||
static void dump_unknown_task(usf_state_t* state, unsigned int sum)
|
|
||||||
{
|
|
||||||
char filename[256];
|
|
||||||
uint32_t ucode = *dmem_u32(state, TASK_UCODE);
|
|
||||||
uint32_t ucode_data = *dmem_u32(state, TASK_UCODE_DATA);
|
|
||||||
uint32_t data_ptr = *dmem_u32(state, TASK_DATA_PTR);
|
|
||||||
|
|
||||||
sprintf(&filename[0], "task_%x.log", sum);
|
|
||||||
dump_task(state, filename);
|
|
||||||
|
|
||||||
/* dump ucode_boot */
|
|
||||||
sprintf(&filename[0], "ucode_boot_%x.bin", sum);
|
|
||||||
dump_binary(state, filename, (void*)dram_u32(state, *dmem_u32(state, TASK_UCODE_BOOT)), *dmem_u32(state, TASK_UCODE_BOOT_SIZE));
|
|
||||||
|
|
||||||
/* dump ucode */
|
|
||||||
if (ucode != 0) {
|
|
||||||
sprintf(&filename[0], "ucode_%x.bin", sum);
|
|
||||||
dump_binary(state, filename, (void*)dram_u32(state, ucode), 0xf80);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* dump ucode_data */
|
|
||||||
if (ucode_data != 0) {
|
|
||||||
sprintf(&filename[0], "ucode_data_%x.bin", sum);
|
|
||||||
dump_binary(state, filename, (void*)dram_u32(state, ucode_data), *dmem_u32(state, TASK_UCODE_DATA_SIZE));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* dump data */
|
|
||||||
if (data_ptr != 0) {
|
|
||||||
sprintf(&filename[0], "data_%x.bin", sum);
|
|
||||||
dump_binary(state, filename, (void*)dram_u32(state, data_ptr), *dmem_u32(state, TASK_DATA_SIZE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dump_unknown_non_task(usf_state_t* state, unsigned int sum)
|
|
||||||
{
|
|
||||||
char filename[256];
|
|
||||||
|
|
||||||
/* dump IMEM & DMEM for further analysis */
|
|
||||||
sprintf(&filename[0], "imem_%x.bin", sum);
|
|
||||||
dump_binary(state, filename, state->IMEM, 0x1000);
|
|
||||||
|
|
||||||
sprintf(&filename[0], "dmem_%x.bin", sum);
|
|
||||||
dump_binary(state, filename, state->DMEM, 0x1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dump_binary(usf_state_t* state, 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)
|
|
||||||
DebugMessage(state, M64MSG_ERROR, "Writing error on %s", filename);
|
|
||||||
fclose(f);
|
|
||||||
} else
|
|
||||||
DebugMessage(state, M64MSG_ERROR, "Couldn't open %s for writing !", filename);
|
|
||||||
} else
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dump_task(usf_state_t* state, const char *const filename)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
|
|
||||||
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",
|
|
||||||
*dmem_u32(state, TASK_TYPE),
|
|
||||||
*dmem_u32(state, TASK_FLAGS),
|
|
||||||
*dmem_u32(state, TASK_UCODE_BOOT), *dmem_u32(state, TASK_UCODE_BOOT_SIZE),
|
|
||||||
*dmem_u32(state, TASK_UCODE), *dmem_u32(state, TASK_UCODE_SIZE),
|
|
||||||
*dmem_u32(state, TASK_UCODE_DATA), *dmem_u32(state, TASK_UCODE_DATA_SIZE),
|
|
||||||
*dmem_u32(state, TASK_DRAM_STACK), *dmem_u32(state, TASK_DRAM_STACK_SIZE),
|
|
||||||
*dmem_u32(state, TASK_OUTPUT_BUFF), *dmem_u32(state, TASK_OUTPUT_BUFF_SIZE),
|
|
||||||
*dmem_u32(state, TASK_DATA_PTR), *dmem_u32(state, TASK_DATA_SIZE),
|
|
||||||
*dmem_u32(state, TASK_YIELD_DATA_PTR), *dmem_u32(state, TASK_YIELD_DATA_SIZE));
|
|
||||||
fclose(f);
|
|
||||||
} else
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -21,107 +21,103 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../usf.h"
|
|
||||||
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
#include "../usf_internal.h"
|
|
||||||
|
|
||||||
/* Global functions */
|
/* Global functions */
|
||||||
void dmem_load_u8 (usf_state_t* state, uint8_t* dst, uint16_t address, size_t count)
|
void dmem_load_u8(struct hle_t* hle, uint8_t* dst, uint16_t address, size_t count)
|
||||||
{
|
{
|
||||||
while (count != 0) {
|
while (count != 0) {
|
||||||
*(dst++) = *dmem_u8(state, address);
|
*(dst++) = *dmem_u8(hle, address);
|
||||||
address += 1;
|
address += 1;
|
||||||
--count;
|
--count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmem_load_u16(usf_state_t* state, uint16_t* dst, uint16_t address, size_t count)
|
void dmem_load_u16(struct hle_t* hle, uint16_t* dst, uint16_t address, size_t count)
|
||||||
{
|
{
|
||||||
while (count != 0) {
|
while (count != 0) {
|
||||||
*(dst++) = *dmem_u16(state, address);
|
*(dst++) = *dmem_u16(hle, address);
|
||||||
address += 2;
|
address += 2;
|
||||||
--count;
|
--count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmem_load_u32(usf_state_t* state, uint32_t* dst, uint16_t address, size_t count)
|
void dmem_load_u32(struct hle_t* hle, uint32_t* dst, uint16_t address, size_t count)
|
||||||
{
|
{
|
||||||
/* Optimization for uint32_t */
|
/* Optimization for uint32_t */
|
||||||
memcpy(dst, dmem_u32(state, address), count * sizeof(uint32_t));
|
memcpy(dst, dmem_u32(hle, address), count * sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmem_store_u8 (usf_state_t* state, const uint8_t* src, uint16_t address, size_t count)
|
void dmem_store_u8(struct hle_t* hle, const uint8_t* src, uint16_t address, size_t count)
|
||||||
{
|
{
|
||||||
while (count != 0) {
|
while (count != 0) {
|
||||||
*dmem_u8(state, address) = *(src++);
|
*dmem_u8(hle, address) = *(src++);
|
||||||
address += 1;
|
address += 1;
|
||||||
--count;
|
--count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmem_store_u16(usf_state_t* state, const uint16_t* src, uint16_t address, size_t count)
|
void dmem_store_u16(struct hle_t* hle, const uint16_t* src, uint16_t address, size_t count)
|
||||||
{
|
{
|
||||||
while (count != 0) {
|
while (count != 0) {
|
||||||
*dmem_u16(state, address) = *(src++);
|
*dmem_u16(hle, address) = *(src++);
|
||||||
address += 2;
|
address += 2;
|
||||||
--count;
|
--count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmem_store_u32(usf_state_t* state, const uint32_t* src, uint16_t address, size_t count)
|
void dmem_store_u32(struct hle_t* hle, const uint32_t* src, uint16_t address, size_t count)
|
||||||
{
|
{
|
||||||
/* Optimization for uint32_t */
|
/* Optimization for uint32_t */
|
||||||
memcpy(dmem_u32(state, address), src, count * sizeof(uint32_t));
|
memcpy(dmem_u32(hle, address), src, count * sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dram_load_u8 (usf_state_t* state, uint8_t* dst, uint32_t address, size_t count)
|
void dram_load_u8(struct hle_t* hle, uint8_t* dst, uint32_t address, size_t count)
|
||||||
{
|
{
|
||||||
while (count != 0) {
|
while (count != 0) {
|
||||||
*(dst++) = *dram_u8(state, address);
|
*(dst++) = *dram_u8(hle, address);
|
||||||
address += 1;
|
address += 1;
|
||||||
--count;
|
--count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dram_load_u16(usf_state_t* state, uint16_t* dst, uint32_t address, size_t count)
|
void dram_load_u16(struct hle_t* hle, uint16_t* dst, uint32_t address, size_t count)
|
||||||
{
|
{
|
||||||
while (count != 0) {
|
while (count != 0) {
|
||||||
*(dst++) = *dram_u16(state, address);
|
*(dst++) = *dram_u16(hle, address);
|
||||||
address += 2;
|
address += 2;
|
||||||
--count;
|
--count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dram_load_u32(usf_state_t* state, uint32_t* dst, uint32_t address, size_t count)
|
void dram_load_u32(struct hle_t* hle, uint32_t* dst, uint32_t address, size_t count)
|
||||||
{
|
{
|
||||||
/* Optimization for uint32_t */
|
/* Optimization for uint32_t */
|
||||||
memcpy(dst, dram_u32(state, address), count * sizeof(uint32_t));
|
memcpy(dst, dram_u32(hle, address), count * sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void dram_store_u8 (usf_state_t* state, const uint8_t* src, uint32_t address, size_t count)
|
void dram_store_u8(struct hle_t* hle, const uint8_t* src, uint32_t address, size_t count)
|
||||||
{
|
{
|
||||||
while (count != 0) {
|
while (count != 0) {
|
||||||
*dram_u8(state, address) = *(src++);
|
*dram_u8(hle, address) = *(src++);
|
||||||
address += 1;
|
address += 1;
|
||||||
--count;
|
--count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dram_store_u16(usf_state_t* state, const uint16_t* src, uint32_t address, size_t count)
|
void dram_store_u16(struct hle_t* hle, const uint16_t* src, uint32_t address, size_t count)
|
||||||
{
|
{
|
||||||
while (count != 0) {
|
while (count != 0) {
|
||||||
*dram_u16(state, address) = *(src++);
|
*dram_u16(hle, address) = *(src++);
|
||||||
address += 2;
|
address += 2;
|
||||||
--count;
|
--count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dram_store_u32(usf_state_t* state, const uint32_t* src, uint32_t address, size_t count)
|
void dram_store_u32(struct hle_t* hle, const uint32_t* src, uint32_t address, size_t count)
|
||||||
{
|
{
|
||||||
/* Optimization for uint32_t */
|
/* Optimization for uint32_t */
|
||||||
memcpy(dram_u32(state, address), src, count * sizeof(uint32_t));
|
memcpy(dram_u32(hle, address), src, count * sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "../usf.h"
|
#include "hle_internal.h"
|
||||||
#include "../usf_internal.h"
|
|
||||||
|
|
||||||
#include "plugin.h"
|
|
||||||
|
|
||||||
#ifdef M64P_BIG_ENDIAN
|
#ifdef M64P_BIG_ENDIAN
|
||||||
#define S 0
|
#define S 0
|
||||||
|
@ -60,59 +57,65 @@ enum {
|
||||||
TASK_YIELD_DATA_SIZE = 0xffc
|
TASK_YIELD_DATA_SIZE = 0xffc
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline unsigned int align(unsigned int x, unsigned amount)
|
#ifdef _MSC_VER
|
||||||
|
#define INLINE __forceinline
|
||||||
|
#else
|
||||||
|
#define INLINE __attribute__((always_inline))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
INLINE static unsigned int align(unsigned int x, unsigned amount)
|
||||||
{
|
{
|
||||||
--amount;
|
--amount;
|
||||||
return (x + amount) & ~amount;
|
return (x + amount) & ~amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t* const dmem_u8(usf_state_t* state, uint16_t address)
|
INLINE static uint8_t* const dmem_u8(struct hle_t* hle, uint16_t address)
|
||||||
{
|
{
|
||||||
return (uint8_t*)(&state->DMEM[(address & 0xfff) ^ S8]);
|
return (uint8_t*)(&hle->dmem[(address & 0xfff) ^ S8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint16_t* const dmem_u16(usf_state_t* state, uint16_t address)
|
INLINE static uint16_t* const dmem_u16(struct hle_t* hle, uint16_t address)
|
||||||
{
|
{
|
||||||
assert((address & 1) == 0);
|
assert((address & 1) == 0);
|
||||||
return (uint16_t*)(&state->DMEM[(address & 0xfff) ^ S16]);
|
return (uint16_t*)(&hle->dmem[(address & 0xfff) ^ S16]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t* const dmem_u32(usf_state_t* state, uint16_t address)
|
INLINE static uint32_t* const dmem_u32(struct hle_t* hle, uint16_t address)
|
||||||
{
|
{
|
||||||
assert((address & 3) == 0);
|
assert((address & 3) == 0);
|
||||||
return (uint32_t*)(&state->DMEM[(address & 0xfff)]);
|
return (uint32_t*)(&hle->dmem[(address & 0xfff)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t* const dram_u8(usf_state_t* state, uint32_t address)
|
INLINE static uint8_t* const dram_u8(struct hle_t* hle, uint32_t address)
|
||||||
{
|
{
|
||||||
return (uint8_t*)&state->N64MEM[(address & 0xffffff) ^ S8];
|
return (uint8_t*)&hle->dram[(address & 0xffffff) ^ S8];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint16_t* const dram_u16(usf_state_t* state, uint32_t address)
|
INLINE static uint16_t* const dram_u16(struct hle_t* hle, uint32_t address)
|
||||||
{
|
{
|
||||||
assert((address & 1) == 0);
|
assert((address & 1) == 0);
|
||||||
return (uint16_t*)&state->N64MEM[(address & 0xffffff) ^ S16];
|
return (uint16_t*)&hle->dram[(address & 0xffffff) ^ S16];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t* const dram_u32(usf_state_t* state, uint32_t address)
|
INLINE static uint32_t* const dram_u32(struct hle_t* hle, uint32_t address)
|
||||||
{
|
{
|
||||||
assert((address & 3) == 0);
|
assert((address & 3) == 0);
|
||||||
return (uint32_t*)&state->N64MEM[address & 0xffffff];
|
return (uint32_t*)&hle->dram[address & 0xffffff];
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmem_load_u8 (usf_state_t* state, uint8_t* dst, uint16_t address, size_t count);
|
void dmem_load_u8 (struct hle_t* hle, uint8_t* dst, uint16_t address, size_t count);
|
||||||
void dmem_load_u16(usf_state_t* state, uint16_t* dst, uint16_t address, size_t count);
|
void dmem_load_u16(struct hle_t* hle, uint16_t* dst, uint16_t address, size_t count);
|
||||||
void dmem_load_u32(usf_state_t* state, uint32_t* dst, uint16_t address, size_t count);
|
void dmem_load_u32(struct hle_t* hle, uint32_t* dst, uint16_t address, size_t count);
|
||||||
void dmem_store_u8 (usf_state_t* state, const uint8_t* src, uint16_t address, size_t count);
|
void dmem_store_u8 (struct hle_t* hle, const uint8_t* src, uint16_t address, size_t count);
|
||||||
void dmem_store_u16(usf_state_t* state, const uint16_t* src, uint16_t address, size_t count);
|
void dmem_store_u16(struct hle_t* hle, const uint16_t* src, uint16_t address, size_t count);
|
||||||
void dmem_store_u32(usf_state_t* state, const uint32_t* src, uint16_t address, size_t count);
|
void dmem_store_u32(struct hle_t* hle, const uint32_t* src, uint16_t address, size_t count);
|
||||||
|
|
||||||
void dram_load_u8 (usf_state_t* state, uint8_t* dst, uint32_t address, size_t count);
|
void dram_load_u8 (struct hle_t* hle, uint8_t* dst, uint32_t address, size_t count);
|
||||||
void dram_load_u16(usf_state_t* state, uint16_t* dst, uint32_t address, size_t count);
|
void dram_load_u16(struct hle_t* hle, uint16_t* dst, uint32_t address, size_t count);
|
||||||
void dram_load_u32(usf_state_t* state, uint32_t* dst, uint32_t address, size_t count);
|
void dram_load_u32(struct hle_t* hle, uint32_t* dst, uint32_t address, size_t count);
|
||||||
void dram_store_u8 (usf_state_t* state, const uint8_t* src, uint32_t address, size_t count);
|
void dram_store_u8 (struct hle_t* hle, const uint8_t* src, uint32_t address, size_t count);
|
||||||
void dram_store_u16(usf_state_t* state, const uint16_t* src, uint32_t address, size_t count);
|
void dram_store_u16(struct hle_t* hle, const uint16_t* src, uint32_t address, size_t count);
|
||||||
void dram_store_u32(usf_state_t* state, const uint32_t* src, uint32_t address, size_t count);
|
void dram_store_u32(struct hle_t* hle, const uint32_t* src, uint32_t address, size_t count);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,9 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "../usf.h"
|
#include "hle_external.h"
|
||||||
|
#include "hle_internal.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "plugin.h"
|
|
||||||
|
|
||||||
#include "../usf_internal.h"
|
|
||||||
|
|
||||||
static const uint16_t DeWindowLUT [0x420] = {
|
static const uint16_t DeWindowLUT [0x420] = {
|
||||||
0x0000, 0xFFF3, 0x005D, 0xFF38, 0x037A, 0xF736, 0x0B37, 0xC00E,
|
0x0000, 0xFFF3, 0x005D, 0xFF38, 0x037A, 0xF736, 0x0B37, 0xC00E,
|
||||||
|
@ -165,7 +162,7 @@ static const uint16_t DeWindowLUT [0x420] = {
|
||||||
0x0B37, 0xF736, 0x037A, 0xFF38, 0x005D, 0xFFF3, 0x0000, 0x0000
|
0x0B37, 0xF736, 0x037A, 0xFF38, 0x005D, 0xFFF3, 0x0000, 0x0000
|
||||||
};
|
};
|
||||||
|
|
||||||
static void MP3AB0(usf_state_t* state)
|
static void MP3AB0(int32_t* v)
|
||||||
{
|
{
|
||||||
/* Part 2 - 100% Accurate */
|
/* Part 2 - 100% Accurate */
|
||||||
static const uint16_t LUT2[8] = {
|
static const uint16_t LUT2[8] = {
|
||||||
|
@ -176,35 +173,34 @@ static void MP3AB0(usf_state_t* state)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
state->mp3_v[16 + i] = state->mp3_v[0 + i] + state->mp3_v[8 + i];
|
v[16 + i] = v[0 + i] + v[8 + i];
|
||||||
state->mp3_v[24 + i] = ((state->mp3_v[0 + i] - state->mp3_v[8 + i]) * LUT2[i]) >> 0x10;
|
v[24 + i] = ((v[0 + i] - v[8 + i]) * LUT2[i]) >> 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Part 3: 4-wide butterflies */
|
/* Part 3: 4-wide butterflies */
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
state->mp3_v[0 + i] = state->mp3_v[16 + i] + state->mp3_v[20 + i];
|
v[0 + i] = v[16 + i] + v[20 + i];
|
||||||
state->mp3_v[4 + i] = ((state->mp3_v[16 + i] - state->mp3_v[20 + i]) * LUT3[i]) >> 0x10;
|
v[4 + i] = ((v[16 + i] - v[20 + i]) * LUT3[i]) >> 0x10;
|
||||||
|
|
||||||
state->mp3_v[8 + i] = state->mp3_v[24 + i] + state->mp3_v[28 + i];
|
v[8 + i] = v[24 + i] + v[28 + i];
|
||||||
state->mp3_v[12 + i] = ((state->mp3_v[24 + i] - state->mp3_v[28 + i]) * LUT3[i]) >> 0x10;
|
v[12 + i] = ((v[24 + i] - v[28 + i]) * LUT3[i]) >> 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Part 4: 2-wide butterflies - 100% Accurate */
|
/* Part 4: 2-wide butterflies - 100% Accurate */
|
||||||
|
|
||||||
for (i = 0; i < 16; i += 4) {
|
for (i = 0; i < 16; i += 4) {
|
||||||
state->mp3_v[16 + i] = state->mp3_v[0 + i] + state->mp3_v[2 + i];
|
v[16 + i] = v[0 + i] + v[2 + i];
|
||||||
state->mp3_v[18 + i] = ((state->mp3_v[0 + i] - state->mp3_v[2 + i]) * 0xEC84) >> 0x10;
|
v[18 + i] = ((v[0 + i] - v[2 + i]) * 0xEC84) >> 0x10;
|
||||||
|
|
||||||
state->mp3_v[17 + i] = state->mp3_v[1 + i] + state->mp3_v[3 + i];
|
v[17 + i] = v[1 + i] + v[3 + i];
|
||||||
state->mp3_v[19 + i] = ((state->mp3_v[1 + i] - state->mp3_v[3 + i]) * 0x61F8) >> 0x10;
|
v[19 + i] = ((v[1 + i] - v[3 + i]) * 0x61F8) >> 0x10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void InnerLoop(usf_state_t* state);
|
static void InnerLoop(struct hle_t* hle);
|
||||||
|
|
||||||
|
void MP3(struct hle_t* hle, uint32_t w1, uint32_t w2)
|
||||||
void MP3(usf_state_t* state, uint32_t w1, uint32_t w2)
|
|
||||||
{
|
{
|
||||||
/* Initialization Code */
|
/* Initialization Code */
|
||||||
uint32_t readPtr; /* s5 */
|
uint32_t readPtr; /* s5 */
|
||||||
|
@ -213,37 +209,37 @@ void MP3(usf_state_t* state, uint32_t w1, uint32_t w2)
|
||||||
int cnt, cnt2;
|
int cnt, cnt2;
|
||||||
|
|
||||||
/* I think these are temporary storage buffers */
|
/* I think these are temporary storage buffers */
|
||||||
state->mp3_t6 = 0x08A0;
|
hle->mp3_t6 = 0x08A0;
|
||||||
state->mp3_t5 = 0x0AC0;
|
hle->mp3_t5 = 0x0AC0;
|
||||||
state->mp3_t4 = (w1 & 0x1E);
|
hle->mp3_t4 = (w1 & 0x1E);
|
||||||
|
|
||||||
writePtr = w2 & 0xFFFFFF;
|
writePtr = w2 & 0xFFFFFF;
|
||||||
readPtr = writePtr;
|
readPtr = writePtr;
|
||||||
/* Just do that for efficiency... may remove and use directly later anyway */
|
/* Just do that for efficiency... may remove and use directly later anyway */
|
||||||
memcpy(state->mp3data + 0xCE8, state->N64MEM + readPtr, 8);
|
memcpy(hle->mp3_buffer + 0xCE8, hle->dram + readPtr, 8);
|
||||||
/* This must be a header byte or whatnot */
|
/* This must be a header byte or whatnot */
|
||||||
readPtr += 8;
|
readPtr += 8;
|
||||||
|
|
||||||
for (cnt = 0; cnt < 0x480; cnt += 0x180) {
|
for (cnt = 0; cnt < 0x480; cnt += 0x180) {
|
||||||
/* DMA: 0xCF0 <- RDRAM[s5] : 0x180 */
|
/* DMA: 0xCF0 <- RDRAM[s5] : 0x180 */
|
||||||
memcpy(state->mp3data + 0xCF0, state->N64MEM + readPtr, 0x180);
|
memcpy(hle->mp3_buffer + 0xCF0, hle->dram + readPtr, 0x180);
|
||||||
state->mp3_inPtr = 0xCF0; /* s7 */
|
hle->mp3_inPtr = 0xCF0; /* s7 */
|
||||||
state->mp3_outPtr = 0xE70; /* s3 */
|
hle->mp3_outPtr = 0xE70; /* s3 */
|
||||||
/* --------------- Inner Loop Start -------------------- */
|
/* --------------- Inner Loop Start -------------------- */
|
||||||
for (cnt2 = 0; cnt2 < 0x180; cnt2 += 0x40) {
|
for (cnt2 = 0; cnt2 < 0x180; cnt2 += 0x40) {
|
||||||
state->mp3_t6 &= 0xFFE0;
|
hle->mp3_t6 &= 0xFFE0;
|
||||||
state->mp3_t5 &= 0xFFE0;
|
hle->mp3_t5 &= 0xFFE0;
|
||||||
state->mp3_t6 |= state->mp3_t4;
|
hle->mp3_t6 |= hle->mp3_t4;
|
||||||
state->mp3_t5 |= state->mp3_t4;
|
hle->mp3_t5 |= hle->mp3_t4;
|
||||||
InnerLoop(state);
|
InnerLoop(hle);
|
||||||
state->mp3_t4 = (state->mp3_t4 - 2) & 0x1E;
|
hle->mp3_t4 = (hle->mp3_t4 - 2) & 0x1E;
|
||||||
tmp = state->mp3_t6;
|
tmp = hle->mp3_t6;
|
||||||
state->mp3_t6 = state->mp3_t5;
|
hle->mp3_t6 = hle->mp3_t5;
|
||||||
state->mp3_t5 = tmp;
|
hle->mp3_t5 = tmp;
|
||||||
state->mp3_inPtr += 0x40;
|
hle->mp3_inPtr += 0x40;
|
||||||
}
|
}
|
||||||
/* --------------- Inner Loop End -------------------- */
|
/* --------------- Inner Loop End -------------------- */
|
||||||
memcpy(state->N64MEM + writePtr, state->mp3data + 0xe70, 0x180);
|
memcpy(hle->dram + writePtr, hle->mp3_buffer + 0xe70, 0x180);
|
||||||
writePtr += 0x180;
|
writePtr += 0x180;
|
||||||
readPtr += 0x180;
|
readPtr += 0x180;
|
||||||
}
|
}
|
||||||
|
@ -251,7 +247,7 @@ void MP3(usf_state_t* state, uint32_t w1, uint32_t w2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void InnerLoop(usf_state_t* state)
|
static void InnerLoop(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
/* Part 1: 100% Accurate */
|
/* Part 1: 100% Accurate */
|
||||||
|
|
||||||
|
@ -277,310 +273,311 @@ static void InnerLoop(usf_state_t* state)
|
||||||
int32_t hi0;
|
int32_t hi0;
|
||||||
int32_t hi1;
|
int32_t hi1;
|
||||||
int32_t vt;
|
int32_t vt;
|
||||||
|
int32_t v[32];
|
||||||
|
|
||||||
state->mp3_v[0] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x00 ^ S16));
|
v[0] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x00 ^ S16));
|
||||||
state->mp3_v[31] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x3E ^ S16));
|
v[31] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x3E ^ S16));
|
||||||
state->mp3_v[0] += state->mp3_v[31];
|
v[0] += v[31];
|
||||||
state->mp3_v[1] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x02 ^ S16));
|
v[1] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x02 ^ S16));
|
||||||
state->mp3_v[30] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x3C ^ S16));
|
v[30] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x3C ^ S16));
|
||||||
state->mp3_v[1] += state->mp3_v[30];
|
v[1] += v[30];
|
||||||
state->mp3_v[2] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x06 ^ S16));
|
v[2] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x06 ^ S16));
|
||||||
state->mp3_v[28] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x38 ^ S16));
|
v[28] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x38 ^ S16));
|
||||||
state->mp3_v[2] += state->mp3_v[28];
|
v[2] += v[28];
|
||||||
state->mp3_v[3] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x04 ^ S16));
|
v[3] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x04 ^ S16));
|
||||||
state->mp3_v[29] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x3A ^ S16));
|
v[29] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x3A ^ S16));
|
||||||
state->mp3_v[3] += state->mp3_v[29];
|
v[3] += v[29];
|
||||||
|
|
||||||
state->mp3_v[4] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x0E ^ S16));
|
v[4] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x0E ^ S16));
|
||||||
state->mp3_v[24] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x30 ^ S16));
|
v[24] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x30 ^ S16));
|
||||||
state->mp3_v[4] += state->mp3_v[24];
|
v[4] += v[24];
|
||||||
state->mp3_v[5] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x0C ^ S16));
|
v[5] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x0C ^ S16));
|
||||||
state->mp3_v[25] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x32 ^ S16));
|
v[25] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x32 ^ S16));
|
||||||
state->mp3_v[5] += state->mp3_v[25];
|
v[5] += v[25];
|
||||||
state->mp3_v[6] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x08 ^ S16));
|
v[6] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x08 ^ S16));
|
||||||
state->mp3_v[27] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x36 ^ S16));
|
v[27] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x36 ^ S16));
|
||||||
state->mp3_v[6] += state->mp3_v[27];
|
v[6] += v[27];
|
||||||
state->mp3_v[7] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x0A ^ S16));
|
v[7] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x0A ^ S16));
|
||||||
state->mp3_v[26] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x34 ^ S16));
|
v[26] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x34 ^ S16));
|
||||||
state->mp3_v[7] += state->mp3_v[26];
|
v[7] += v[26];
|
||||||
|
|
||||||
state->mp3_v[8] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x1E ^ S16));
|
v[8] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x1E ^ S16));
|
||||||
state->mp3_v[16] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x20 ^ S16));
|
v[16] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x20 ^ S16));
|
||||||
state->mp3_v[8] += state->mp3_v[16];
|
v[8] += v[16];
|
||||||
state->mp3_v[9] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x1C ^ S16));
|
v[9] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x1C ^ S16));
|
||||||
state->mp3_v[17] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x22 ^ S16));
|
v[17] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x22 ^ S16));
|
||||||
state->mp3_v[9] += state->mp3_v[17];
|
v[9] += v[17];
|
||||||
state->mp3_v[10] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x18 ^ S16));
|
v[10] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x18 ^ S16));
|
||||||
state->mp3_v[19] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x26 ^ S16));
|
v[19] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x26 ^ S16));
|
||||||
state->mp3_v[10] += state->mp3_v[19];
|
v[10] += v[19];
|
||||||
state->mp3_v[11] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x1A ^ S16));
|
v[11] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x1A ^ S16));
|
||||||
state->mp3_v[18] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x24 ^ S16));
|
v[18] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x24 ^ S16));
|
||||||
state->mp3_v[11] += state->mp3_v[18];
|
v[11] += v[18];
|
||||||
|
|
||||||
state->mp3_v[12] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x10 ^ S16));
|
v[12] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x10 ^ S16));
|
||||||
state->mp3_v[23] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x2E ^ S16));
|
v[23] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x2E ^ S16));
|
||||||
state->mp3_v[12] += state->mp3_v[23];
|
v[12] += v[23];
|
||||||
state->mp3_v[13] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x12 ^ S16));
|
v[13] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x12 ^ S16));
|
||||||
state->mp3_v[22] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x2C ^ S16));
|
v[22] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x2C ^ S16));
|
||||||
state->mp3_v[13] += state->mp3_v[22];
|
v[13] += v[22];
|
||||||
state->mp3_v[14] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x16 ^ S16));
|
v[14] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x16 ^ S16));
|
||||||
state->mp3_v[20] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x28 ^ S16));
|
v[20] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x28 ^ S16));
|
||||||
state->mp3_v[14] += state->mp3_v[20];
|
v[14] += v[20];
|
||||||
state->mp3_v[15] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x14 ^ S16));
|
v[15] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x14 ^ S16));
|
||||||
state->mp3_v[21] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x2A ^ S16));
|
v[21] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x2A ^ S16));
|
||||||
state->mp3_v[15] += state->mp3_v[21];
|
v[15] += v[21];
|
||||||
|
|
||||||
/* Part 2-4 */
|
/* Part 2-4 */
|
||||||
|
|
||||||
MP3AB0(state);
|
MP3AB0(v);
|
||||||
|
|
||||||
/* Part 5 - 1-Wide Butterflies - 100% Accurate but need SSVs!!! */
|
/* Part 5 - 1-Wide Butterflies - 100% Accurate but need SSVs!!! */
|
||||||
|
|
||||||
t0 = state->mp3_t6 + 0x100;
|
t0 = hle->mp3_t6 + 0x100;
|
||||||
t1 = state->mp3_t6 + 0x200;
|
t1 = hle->mp3_t6 + 0x200;
|
||||||
t2 = state->mp3_t5 + 0x100;
|
t2 = hle->mp3_t5 + 0x100;
|
||||||
t3 = state->mp3_t5 + 0x200;
|
t3 = hle->mp3_t5 + 0x200;
|
||||||
|
|
||||||
/* 0x13A8 */
|
/* 0x13A8 */
|
||||||
state->mp3_v[1] = 0;
|
v[1] = 0;
|
||||||
state->mp3_v[11] = ((state->mp3_v[16] - state->mp3_v[17]) * 0xB504) >> 0x10;
|
v[11] = ((v[16] - v[17]) * 0xB504) >> 0x10;
|
||||||
|
|
||||||
state->mp3_v[16] = -state->mp3_v[16] - state->mp3_v[17];
|
v[16] = -v[16] - v[17];
|
||||||
state->mp3_v[2] = state->mp3_v[18] + state->mp3_v[19];
|
v[2] = v[18] + v[19];
|
||||||
/* ** Store state->mp3_v[11] -> (T6 + 0)** */
|
/* ** Store v[11] -> (T6 + 0)** */
|
||||||
*(int16_t *)(state->mp3data + ((state->mp3_t6 + (short)0x0))) = (short)state->mp3_v[11];
|
*(int16_t *)(hle->mp3_buffer + ((hle->mp3_t6 + (short)0x0))) = (short)v[11];
|
||||||
|
|
||||||
|
|
||||||
state->mp3_v[11] = -state->mp3_v[11];
|
v[11] = -v[11];
|
||||||
/* ** Store state->mp3_v[16] -> (T3 + 0)** */
|
/* ** Store v[16] -> (T3 + 0)** */
|
||||||
*(int16_t *)(state->mp3data + ((t3 + (short)0x0))) = (short)state->mp3_v[16];
|
*(int16_t *)(hle->mp3_buffer + ((t3 + (short)0x0))) = (short)v[16];
|
||||||
/* ** Store state->mp3_v[11] -> (T5 + 0)** */
|
/* ** Store v[11] -> (T5 + 0)** */
|
||||||
*(int16_t *)(state->mp3data + ((state->mp3_t5 + (short)0x0))) = (short)state->mp3_v[11];
|
*(int16_t *)(hle->mp3_buffer + ((hle->mp3_t5 + (short)0x0))) = (short)v[11];
|
||||||
/* 0x13E8 - Verified.... */
|
/* 0x13E8 - Verified.... */
|
||||||
state->mp3_v[2] = -state->mp3_v[2];
|
v[2] = -v[2];
|
||||||
/* ** Store state->mp3_v[2] -> (T2 + 0)** */
|
/* ** Store v[2] -> (T2 + 0)** */
|
||||||
*(int16_t *)(state->mp3data + ((t2 + (short)0x0))) = (short)state->mp3_v[2];
|
*(int16_t *)(hle->mp3_buffer + ((t2 + (short)0x0))) = (short)v[2];
|
||||||
state->mp3_v[3] = (((state->mp3_v[18] - state->mp3_v[19]) * 0x16A09) >> 0x10) + state->mp3_v[2];
|
v[3] = (((v[18] - v[19]) * 0x16A09) >> 0x10) + v[2];
|
||||||
/* ** Store state->mp3_v[3] -> (T0 + 0)** */
|
/* ** Store v[3] -> (T0 + 0)** */
|
||||||
*(int16_t *)(state->mp3data + ((t0 + (short)0x0))) = (short)state->mp3_v[3];
|
*(int16_t *)(hle->mp3_buffer + ((t0 + (short)0x0))) = (short)v[3];
|
||||||
/* 0x1400 - Verified */
|
/* 0x1400 - Verified */
|
||||||
state->mp3_v[4] = -state->mp3_v[20] - state->mp3_v[21];
|
v[4] = -v[20] - v[21];
|
||||||
state->mp3_v[6] = state->mp3_v[22] + state->mp3_v[23];
|
v[6] = v[22] + v[23];
|
||||||
state->mp3_v[5] = ((state->mp3_v[20] - state->mp3_v[21]) * 0x16A09) >> 0x10;
|
v[5] = ((v[20] - v[21]) * 0x16A09) >> 0x10;
|
||||||
/* ** Store state->mp3_v[4] -> (T3 + 0xFF80) */
|
/* ** Store v[4] -> (T3 + 0xFF80) */
|
||||||
*(int16_t *)(state->mp3data + ((t3 + (short)0xFF80))) = (short)state->mp3_v[4];
|
*(int16_t *)(hle->mp3_buffer + ((t3 + (short)0xFF80))) = (short)v[4];
|
||||||
state->mp3_v[7] = ((state->mp3_v[22] - state->mp3_v[23]) * 0x2D413) >> 0x10;
|
v[7] = ((v[22] - v[23]) * 0x2D413) >> 0x10;
|
||||||
state->mp3_v[5] = state->mp3_v[5] - state->mp3_v[4];
|
v[5] = v[5] - v[4];
|
||||||
state->mp3_v[7] = state->mp3_v[7] - state->mp3_v[5];
|
v[7] = v[7] - v[5];
|
||||||
state->mp3_v[6] = state->mp3_v[6] + state->mp3_v[6];
|
v[6] = v[6] + v[6];
|
||||||
state->mp3_v[5] = state->mp3_v[5] - state->mp3_v[6];
|
v[5] = v[5] - v[6];
|
||||||
state->mp3_v[4] = -state->mp3_v[4] - state->mp3_v[6];
|
v[4] = -v[4] - v[6];
|
||||||
/* *** Store state->mp3_v[7] -> (T1 + 0xFF80) */
|
/* *** Store v[7] -> (T1 + 0xFF80) */
|
||||||
*(int16_t *)(state->mp3data + ((t1 + (short)0xFF80))) = (short)state->mp3_v[7];
|
*(int16_t *)(hle->mp3_buffer + ((t1 + (short)0xFF80))) = (short)v[7];
|
||||||
/* *** Store state->mp3_v[4] -> (T2 + 0xFF80) */
|
/* *** Store v[4] -> (T2 + 0xFF80) */
|
||||||
*(int16_t *)(state->mp3data + ((t2 + (short)0xFF80))) = (short)state->mp3_v[4];
|
*(int16_t *)(hle->mp3_buffer + ((t2 + (short)0xFF80))) = (short)v[4];
|
||||||
/* *** Store state->mp3_v[5] -> (T0 + 0xFF80) */
|
/* *** Store v[5] -> (T0 + 0xFF80) */
|
||||||
*(int16_t *)(state->mp3data + ((t0 + (short)0xFF80))) = (short)state->mp3_v[5];
|
*(int16_t *)(hle->mp3_buffer + ((t0 + (short)0xFF80))) = (short)v[5];
|
||||||
state->mp3_v[8] = state->mp3_v[24] + state->mp3_v[25];
|
v[8] = v[24] + v[25];
|
||||||
|
|
||||||
|
|
||||||
state->mp3_v[9] = ((state->mp3_v[24] - state->mp3_v[25]) * 0x16A09) >> 0x10;
|
v[9] = ((v[24] - v[25]) * 0x16A09) >> 0x10;
|
||||||
state->mp3_v[2] = state->mp3_v[8] + state->mp3_v[9];
|
v[2] = v[8] + v[9];
|
||||||
state->mp3_v[11] = ((state->mp3_v[26] - state->mp3_v[27]) * 0x2D413) >> 0x10;
|
v[11] = ((v[26] - v[27]) * 0x2D413) >> 0x10;
|
||||||
state->mp3_v[13] = ((state->mp3_v[28] - state->mp3_v[29]) * 0x2D413) >> 0x10;
|
v[13] = ((v[28] - v[29]) * 0x2D413) >> 0x10;
|
||||||
|
|
||||||
state->mp3_v[10] = state->mp3_v[26] + state->mp3_v[27];
|
v[10] = v[26] + v[27];
|
||||||
state->mp3_v[10] = state->mp3_v[10] + state->mp3_v[10];
|
v[10] = v[10] + v[10];
|
||||||
state->mp3_v[12] = state->mp3_v[28] + state->mp3_v[29];
|
v[12] = v[28] + v[29];
|
||||||
state->mp3_v[12] = state->mp3_v[12] + state->mp3_v[12];
|
v[12] = v[12] + v[12];
|
||||||
state->mp3_v[14] = state->mp3_v[30] + state->mp3_v[31];
|
v[14] = v[30] + v[31];
|
||||||
state->mp3_v[3] = state->mp3_v[8] + state->mp3_v[10];
|
v[3] = v[8] + v[10];
|
||||||
state->mp3_v[14] = state->mp3_v[14] + state->mp3_v[14];
|
v[14] = v[14] + v[14];
|
||||||
state->mp3_v[13] = (state->mp3_v[13] - state->mp3_v[2]) + state->mp3_v[12];
|
v[13] = (v[13] - v[2]) + v[12];
|
||||||
state->mp3_v[15] = (((state->mp3_v[30] - state->mp3_v[31]) * 0x5A827) >> 0x10) - (state->mp3_v[11] + state->mp3_v[2]);
|
v[15] = (((v[30] - v[31]) * 0x5A827) >> 0x10) - (v[11] + v[2]);
|
||||||
state->mp3_v[14] = -(state->mp3_v[14] + state->mp3_v[14]) + state->mp3_v[3];
|
v[14] = -(v[14] + v[14]) + v[3];
|
||||||
state->mp3_v[17] = state->mp3_v[13] - state->mp3_v[10];
|
v[17] = v[13] - v[10];
|
||||||
state->mp3_v[9] = state->mp3_v[9] + state->mp3_v[14];
|
v[9] = v[9] + v[14];
|
||||||
/* ** Store state->mp3_v[9] -> (T6 + 0x40) */
|
/* ** Store v[9] -> (T6 + 0x40) */
|
||||||
*(int16_t *)(state->mp3data + ((state->mp3_t6 + (short)0x40))) = (short)state->mp3_v[9];
|
*(int16_t *)(hle->mp3_buffer + ((hle->mp3_t6 + (short)0x40))) = (short)v[9];
|
||||||
state->mp3_v[11] = state->mp3_v[11] - state->mp3_v[13];
|
v[11] = v[11] - v[13];
|
||||||
/* ** Store state->mp3_v[17] -> (T0 + 0xFFC0) */
|
/* ** Store v[17] -> (T0 + 0xFFC0) */
|
||||||
*(int16_t *)(state->mp3data + ((t0 + (short)0xFFC0))) = (short)state->mp3_v[17];
|
*(int16_t *)(hle->mp3_buffer + ((t0 + (short)0xFFC0))) = (short)v[17];
|
||||||
state->mp3_v[12] = state->mp3_v[8] - state->mp3_v[12];
|
v[12] = v[8] - v[12];
|
||||||
/* ** Store state->mp3_v[11] -> (T0 + 0x40) */
|
/* ** Store v[11] -> (T0 + 0x40) */
|
||||||
*(int16_t *)(state->mp3data + ((t0 + (short)0x40))) = (short)state->mp3_v[11];
|
*(int16_t *)(hle->mp3_buffer + ((t0 + (short)0x40))) = (short)v[11];
|
||||||
state->mp3_v[8] = -state->mp3_v[8];
|
v[8] = -v[8];
|
||||||
/* ** Store state->mp3_v[15] -> (T1 + 0xFFC0) */
|
/* ** Store v[15] -> (T1 + 0xFFC0) */
|
||||||
*(int16_t *)(state->mp3data + ((t1 + (short)0xFFC0))) = (short)state->mp3_v[15];
|
*(int16_t *)(hle->mp3_buffer + ((t1 + (short)0xFFC0))) = (short)v[15];
|
||||||
state->mp3_v[10] = -state->mp3_v[10] - state->mp3_v[12];
|
v[10] = -v[10] - v[12];
|
||||||
/* ** Store state->mp3_v[12] -> (T2 + 0x40) */
|
/* ** Store v[12] -> (T2 + 0x40) */
|
||||||
*(int16_t *)(state->mp3data + ((t2 + (short)0x40))) = (short)state->mp3_v[12];
|
*(int16_t *)(hle->mp3_buffer + ((t2 + (short)0x40))) = (short)v[12];
|
||||||
/* ** Store state->mp3_v[8] -> (T3 + 0xFFC0) */
|
/* ** Store v[8] -> (T3 + 0xFFC0) */
|
||||||
*(int16_t *)(state->mp3data + ((t3 + (short)0xFFC0))) = (short)state->mp3_v[8];
|
*(int16_t *)(hle->mp3_buffer + ((t3 + (short)0xFFC0))) = (short)v[8];
|
||||||
/* ** Store state->mp3_v[14] -> (T5 + 0x40) */
|
/* ** Store v[14] -> (T5 + 0x40) */
|
||||||
*(int16_t *)(state->mp3data + ((state->mp3_t5 + (short)0x40))) = (short)state->mp3_v[14];
|
*(int16_t *)(hle->mp3_buffer + ((hle->mp3_t5 + (short)0x40))) = (short)v[14];
|
||||||
/* ** Store state->mp3_v[10] -> (T2 + 0xFFC0) */
|
/* ** Store v[10] -> (T2 + 0xFFC0) */
|
||||||
*(int16_t *)(state->mp3data + ((t2 + (short)0xFFC0))) = (short)state->mp3_v[10];
|
*(int16_t *)(hle->mp3_buffer + ((t2 + (short)0xFFC0))) = (short)v[10];
|
||||||
/* 0x14FC - Verified... */
|
/* 0x14FC - Verified... */
|
||||||
|
|
||||||
/* Part 6 - 100% Accurate */
|
/* Part 6 - 100% Accurate */
|
||||||
|
|
||||||
state->mp3_v[0] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x00 ^ S16));
|
v[0] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x00 ^ S16));
|
||||||
state->mp3_v[31] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x3E ^ S16));
|
v[31] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x3E ^ S16));
|
||||||
state->mp3_v[0] -= state->mp3_v[31];
|
v[0] -= v[31];
|
||||||
state->mp3_v[1] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x02 ^ S16));
|
v[1] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x02 ^ S16));
|
||||||
state->mp3_v[30] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x3C ^ S16));
|
v[30] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x3C ^ S16));
|
||||||
state->mp3_v[1] -= state->mp3_v[30];
|
v[1] -= v[30];
|
||||||
state->mp3_v[2] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x06 ^ S16));
|
v[2] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x06 ^ S16));
|
||||||
state->mp3_v[28] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x38 ^ S16));
|
v[28] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x38 ^ S16));
|
||||||
state->mp3_v[2] -= state->mp3_v[28];
|
v[2] -= v[28];
|
||||||
state->mp3_v[3] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x04 ^ S16));
|
v[3] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x04 ^ S16));
|
||||||
state->mp3_v[29] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x3A ^ S16));
|
v[29] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x3A ^ S16));
|
||||||
state->mp3_v[3] -= state->mp3_v[29];
|
v[3] -= v[29];
|
||||||
|
|
||||||
state->mp3_v[4] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x0E ^ S16));
|
v[4] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x0E ^ S16));
|
||||||
state->mp3_v[24] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x30 ^ S16));
|
v[24] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x30 ^ S16));
|
||||||
state->mp3_v[4] -= state->mp3_v[24];
|
v[4] -= v[24];
|
||||||
state->mp3_v[5] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x0C ^ S16));
|
v[5] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x0C ^ S16));
|
||||||
state->mp3_v[25] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x32 ^ S16));
|
v[25] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x32 ^ S16));
|
||||||
state->mp3_v[5] -= state->mp3_v[25];
|
v[5] -= v[25];
|
||||||
state->mp3_v[6] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x08 ^ S16));
|
v[6] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x08 ^ S16));
|
||||||
state->mp3_v[27] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x36 ^ S16));
|
v[27] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x36 ^ S16));
|
||||||
state->mp3_v[6] -= state->mp3_v[27];
|
v[6] -= v[27];
|
||||||
state->mp3_v[7] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x0A ^ S16));
|
v[7] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x0A ^ S16));
|
||||||
state->mp3_v[26] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x34 ^ S16));
|
v[26] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x34 ^ S16));
|
||||||
state->mp3_v[7] -= state->mp3_v[26];
|
v[7] -= v[26];
|
||||||
|
|
||||||
state->mp3_v[8] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x1E ^ S16));
|
v[8] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x1E ^ S16));
|
||||||
state->mp3_v[16] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x20 ^ S16));
|
v[16] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x20 ^ S16));
|
||||||
state->mp3_v[8] -= state->mp3_v[16];
|
v[8] -= v[16];
|
||||||
state->mp3_v[9] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x1C ^ S16));
|
v[9] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x1C ^ S16));
|
||||||
state->mp3_v[17] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x22 ^ S16));
|
v[17] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x22 ^ S16));
|
||||||
state->mp3_v[9] -= state->mp3_v[17];
|
v[9] -= v[17];
|
||||||
state->mp3_v[10] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x18 ^ S16));
|
v[10] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x18 ^ S16));
|
||||||
state->mp3_v[19] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x26 ^ S16));
|
v[19] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x26 ^ S16));
|
||||||
state->mp3_v[10] -= state->mp3_v[19];
|
v[10] -= v[19];
|
||||||
state->mp3_v[11] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x1A ^ S16));
|
v[11] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x1A ^ S16));
|
||||||
state->mp3_v[18] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x24 ^ S16));
|
v[18] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x24 ^ S16));
|
||||||
state->mp3_v[11] -= state->mp3_v[18];
|
v[11] -= v[18];
|
||||||
|
|
||||||
state->mp3_v[12] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x10 ^ S16));
|
v[12] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x10 ^ S16));
|
||||||
state->mp3_v[23] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x2E ^ S16));
|
v[23] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x2E ^ S16));
|
||||||
state->mp3_v[12] -= state->mp3_v[23];
|
v[12] -= v[23];
|
||||||
state->mp3_v[13] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x12 ^ S16));
|
v[13] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x12 ^ S16));
|
||||||
state->mp3_v[22] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x2C ^ S16));
|
v[22] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x2C ^ S16));
|
||||||
state->mp3_v[13] -= state->mp3_v[22];
|
v[13] -= v[22];
|
||||||
state->mp3_v[14] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x16 ^ S16));
|
v[14] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x16 ^ S16));
|
||||||
state->mp3_v[20] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x28 ^ S16));
|
v[20] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x28 ^ S16));
|
||||||
state->mp3_v[14] -= state->mp3_v[20];
|
v[14] -= v[20];
|
||||||
state->mp3_v[15] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x14 ^ S16));
|
v[15] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x14 ^ S16));
|
||||||
state->mp3_v[21] = *(int16_t *)(state->mp3data + state->mp3_inPtr + (0x2A ^ S16));
|
v[21] = *(int16_t *)(hle->mp3_buffer + hle->mp3_inPtr + (0x2A ^ S16));
|
||||||
state->mp3_v[15] -= state->mp3_v[21];
|
v[15] -= v[21];
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
state->mp3_v[0 + i] = (state->mp3_v[0 + i] * LUT6[i]) >> 0x10;
|
v[0 + i] = (v[0 + i] * LUT6[i]) >> 0x10;
|
||||||
state->mp3_v[0] = state->mp3_v[0] + state->mp3_v[0];
|
v[0] = v[0] + v[0];
|
||||||
state->mp3_v[1] = state->mp3_v[1] + state->mp3_v[1];
|
v[1] = v[1] + v[1];
|
||||||
state->mp3_v[2] = state->mp3_v[2] + state->mp3_v[2];
|
v[2] = v[2] + v[2];
|
||||||
state->mp3_v[3] = state->mp3_v[3] + state->mp3_v[3];
|
v[3] = v[3] + v[3];
|
||||||
state->mp3_v[4] = state->mp3_v[4] + state->mp3_v[4];
|
v[4] = v[4] + v[4];
|
||||||
state->mp3_v[5] = state->mp3_v[5] + state->mp3_v[5];
|
v[5] = v[5] + v[5];
|
||||||
state->mp3_v[6] = state->mp3_v[6] + state->mp3_v[6];
|
v[6] = v[6] + v[6];
|
||||||
state->mp3_v[7] = state->mp3_v[7] + state->mp3_v[7];
|
v[7] = v[7] + v[7];
|
||||||
state->mp3_v[12] = state->mp3_v[12] + state->mp3_v[12];
|
v[12] = v[12] + v[12];
|
||||||
state->mp3_v[13] = state->mp3_v[13] + state->mp3_v[13];
|
v[13] = v[13] + v[13];
|
||||||
state->mp3_v[15] = state->mp3_v[15] + state->mp3_v[15];
|
v[15] = v[15] + v[15];
|
||||||
|
|
||||||
MP3AB0(state);
|
MP3AB0(v);
|
||||||
|
|
||||||
/* Part 7: - 100% Accurate + SSV - Unoptimized */
|
/* Part 7: - 100% Accurate + SSV - Unoptimized */
|
||||||
|
|
||||||
state->mp3_v[0] = (state->mp3_v[17] + state->mp3_v[16]) >> 1;
|
v[0] = (v[17] + v[16]) >> 1;
|
||||||
state->mp3_v[1] = ((state->mp3_v[17] * (int)((short)0xA57E * 2)) + (state->mp3_v[16] * 0xB504)) >> 0x10;
|
v[1] = ((v[17] * (int)((short)0xA57E * 2)) + (v[16] * 0xB504)) >> 0x10;
|
||||||
state->mp3_v[2] = -state->mp3_v[18] - state->mp3_v[19];
|
v[2] = -v[18] - v[19];
|
||||||
state->mp3_v[3] = ((state->mp3_v[18] - state->mp3_v[19]) * 0x16A09) >> 0x10;
|
v[3] = ((v[18] - v[19]) * 0x16A09) >> 0x10;
|
||||||
state->mp3_v[4] = state->mp3_v[20] + state->mp3_v[21] + state->mp3_v[0];
|
v[4] = v[20] + v[21] + v[0];
|
||||||
state->mp3_v[5] = (((state->mp3_v[20] - state->mp3_v[21]) * 0x16A09) >> 0x10) + state->mp3_v[1];
|
v[5] = (((v[20] - v[21]) * 0x16A09) >> 0x10) + v[1];
|
||||||
state->mp3_v[6] = (((state->mp3_v[22] + state->mp3_v[23]) << 1) + state->mp3_v[0]) - state->mp3_v[2];
|
v[6] = (((v[22] + v[23]) << 1) + v[0]) - v[2];
|
||||||
state->mp3_v[7] = (((state->mp3_v[22] - state->mp3_v[23]) * 0x2D413) >> 0x10) + state->mp3_v[0] + state->mp3_v[1] + state->mp3_v[3];
|
v[7] = (((v[22] - v[23]) * 0x2D413) >> 0x10) + v[0] + v[1] + v[3];
|
||||||
/* 0x16A8 */
|
/* 0x16A8 */
|
||||||
/* Save state->mp3_v[0] -> (T3 + 0xFFE0) */
|
/* Save v[0] -> (T3 + 0xFFE0) */
|
||||||
*(int16_t *)(state->mp3data + ((t3 + (short)0xFFE0))) = (short) - state->mp3_v[0];
|
*(int16_t *)(hle->mp3_buffer + ((t3 + (short)0xFFE0))) = (short) - v[0];
|
||||||
state->mp3_v[8] = state->mp3_v[24] + state->mp3_v[25];
|
v[8] = v[24] + v[25];
|
||||||
state->mp3_v[9] = ((state->mp3_v[24] - state->mp3_v[25]) * 0x16A09) >> 0x10;
|
v[9] = ((v[24] - v[25]) * 0x16A09) >> 0x10;
|
||||||
state->mp3_v[10] = ((state->mp3_v[26] + state->mp3_v[27]) << 1) + state->mp3_v[8];
|
v[10] = ((v[26] + v[27]) << 1) + v[8];
|
||||||
state->mp3_v[11] = (((state->mp3_v[26] - state->mp3_v[27]) * 0x2D413) >> 0x10) + state->mp3_v[8] + state->mp3_v[9];
|
v[11] = (((v[26] - v[27]) * 0x2D413) >> 0x10) + v[8] + v[9];
|
||||||
state->mp3_v[12] = state->mp3_v[4] - ((state->mp3_v[28] + state->mp3_v[29]) << 1);
|
v[12] = v[4] - ((v[28] + v[29]) << 1);
|
||||||
/* ** Store v12 -> (T2 + 0x20) */
|
/* ** Store v12 -> (T2 + 0x20) */
|
||||||
*(int16_t *)(state->mp3data + ((t2 + (short)0x20))) = (short)state->mp3_v[12];
|
*(int16_t *)(hle->mp3_buffer + ((t2 + (short)0x20))) = (short)v[12];
|
||||||
state->mp3_v[13] = (((state->mp3_v[28] - state->mp3_v[29]) * 0x2D413) >> 0x10) - state->mp3_v[12] - state->mp3_v[5];
|
v[13] = (((v[28] - v[29]) * 0x2D413) >> 0x10) - v[12] - v[5];
|
||||||
state->mp3_v[14] = state->mp3_v[30] + state->mp3_v[31];
|
v[14] = v[30] + v[31];
|
||||||
state->mp3_v[14] = state->mp3_v[14] + state->mp3_v[14];
|
v[14] = v[14] + v[14];
|
||||||
state->mp3_v[14] = state->mp3_v[14] + state->mp3_v[14];
|
v[14] = v[14] + v[14];
|
||||||
state->mp3_v[14] = state->mp3_v[6] - state->mp3_v[14];
|
v[14] = v[6] - v[14];
|
||||||
state->mp3_v[15] = (((state->mp3_v[30] - state->mp3_v[31]) * 0x5A827) >> 0x10) - state->mp3_v[7];
|
v[15] = (((v[30] - v[31]) * 0x5A827) >> 0x10) - v[7];
|
||||||
/* Store v14 -> (T5 + 0x20) */
|
/* Store v14 -> (T5 + 0x20) */
|
||||||
*(int16_t *)(state->mp3data + ((state->mp3_t5 + (short)0x20))) = (short)state->mp3_v[14];
|
*(int16_t *)(hle->mp3_buffer + ((hle->mp3_t5 + (short)0x20))) = (short)v[14];
|
||||||
state->mp3_v[14] = state->mp3_v[14] + state->mp3_v[1];
|
v[14] = v[14] + v[1];
|
||||||
/* Store state->mp3_v[14] -> (T6 + 0x20) */
|
/* Store v[14] -> (T6 + 0x20) */
|
||||||
*(int16_t *)(state->mp3data + ((state->mp3_t6 + (short)0x20))) = (short)state->mp3_v[14];
|
*(int16_t *)(hle->mp3_buffer + ((hle->mp3_t6 + (short)0x20))) = (short)v[14];
|
||||||
/* Store state->mp3_v[15] -> (T1 + 0xFFE0) */
|
/* Store v[15] -> (T1 + 0xFFE0) */
|
||||||
*(int16_t *)(state->mp3data + ((t1 + (short)0xFFE0))) = (short)state->mp3_v[15];
|
*(int16_t *)(hle->mp3_buffer + ((t1 + (short)0xFFE0))) = (short)v[15];
|
||||||
state->mp3_v[9] = state->mp3_v[9] + state->mp3_v[10];
|
v[9] = v[9] + v[10];
|
||||||
state->mp3_v[1] = state->mp3_v[1] + state->mp3_v[6];
|
v[1] = v[1] + v[6];
|
||||||
state->mp3_v[6] = state->mp3_v[10] - state->mp3_v[6];
|
v[6] = v[10] - v[6];
|
||||||
state->mp3_v[1] = state->mp3_v[9] - state->mp3_v[1];
|
v[1] = v[9] - v[1];
|
||||||
/* Store state->mp3_v[6] -> (T5 + 0x60) */
|
/* Store v[6] -> (T5 + 0x60) */
|
||||||
*(int16_t *)(state->mp3data + ((state->mp3_t5 + (short)0x60))) = (short)state->mp3_v[6];
|
*(int16_t *)(hle->mp3_buffer + ((hle->mp3_t5 + (short)0x60))) = (short)v[6];
|
||||||
state->mp3_v[10] = state->mp3_v[10] + state->mp3_v[2];
|
v[10] = v[10] + v[2];
|
||||||
state->mp3_v[10] = state->mp3_v[4] - state->mp3_v[10];
|
v[10] = v[4] - v[10];
|
||||||
/* Store state->mp3_v[10] -> (T2 + 0xFFA0) */
|
/* Store v[10] -> (T2 + 0xFFA0) */
|
||||||
*(int16_t *)(state->mp3data + ((t2 + (short)0xFFA0))) = (short)state->mp3_v[10];
|
*(int16_t *)(hle->mp3_buffer + ((t2 + (short)0xFFA0))) = (short)v[10];
|
||||||
state->mp3_v[12] = state->mp3_v[2] - state->mp3_v[12];
|
v[12] = v[2] - v[12];
|
||||||
/* Store state->mp3_v[12] -> (T2 + 0xFFE0) */
|
/* Store v[12] -> (T2 + 0xFFE0) */
|
||||||
*(int16_t *)(state->mp3data + ((t2 + (short)0xFFE0))) = (short)state->mp3_v[12];
|
*(int16_t *)(hle->mp3_buffer + ((t2 + (short)0xFFE0))) = (short)v[12];
|
||||||
state->mp3_v[5] = state->mp3_v[4] + state->mp3_v[5];
|
v[5] = v[4] + v[5];
|
||||||
state->mp3_v[4] = state->mp3_v[8] - state->mp3_v[4];
|
v[4] = v[8] - v[4];
|
||||||
/* Store state->mp3_v[4] -> (T2 + 0x60) */
|
/* Store v[4] -> (T2 + 0x60) */
|
||||||
*(int16_t *)(state->mp3data + ((t2 + (short)0x60))) = (short)state->mp3_v[4];
|
*(int16_t *)(hle->mp3_buffer + ((t2 + (short)0x60))) = (short)v[4];
|
||||||
state->mp3_v[0] = state->mp3_v[0] - state->mp3_v[8];
|
v[0] = v[0] - v[8];
|
||||||
/* Store state->mp3_v[0] -> (T3 + 0xFFA0) */
|
/* Store v[0] -> (T3 + 0xFFA0) */
|
||||||
*(int16_t *)(state->mp3data + ((t3 + (short)0xFFA0))) = (short)state->mp3_v[0];
|
*(int16_t *)(hle->mp3_buffer + ((t3 + (short)0xFFA0))) = (short)v[0];
|
||||||
state->mp3_v[7] = state->mp3_v[7] - state->mp3_v[11];
|
v[7] = v[7] - v[11];
|
||||||
/* Store state->mp3_v[7] -> (T1 + 0xFFA0) */
|
/* Store v[7] -> (T1 + 0xFFA0) */
|
||||||
*(int16_t *)(state->mp3data + ((t1 + (short)0xFFA0))) = (short)state->mp3_v[7];
|
*(int16_t *)(hle->mp3_buffer + ((t1 + (short)0xFFA0))) = (short)v[7];
|
||||||
state->mp3_v[11] = state->mp3_v[11] - state->mp3_v[3];
|
v[11] = v[11] - v[3];
|
||||||
/* Store state->mp3_v[1] -> (T6 + 0x60) */
|
/* Store v[1] -> (T6 + 0x60) */
|
||||||
*(int16_t *)(state->mp3data + ((state->mp3_t6 + (short)0x60))) = (short)state->mp3_v[1];
|
*(int16_t *)(hle->mp3_buffer + ((hle->mp3_t6 + (short)0x60))) = (short)v[1];
|
||||||
state->mp3_v[11] = state->mp3_v[11] - state->mp3_v[5];
|
v[11] = v[11] - v[5];
|
||||||
/* Store state->mp3_v[11] -> (T0 + 0x60) */
|
/* Store v[11] -> (T0 + 0x60) */
|
||||||
*(int16_t *)(state->mp3data + ((t0 + (short)0x60))) = (short)state->mp3_v[11];
|
*(int16_t *)(hle->mp3_buffer + ((t0 + (short)0x60))) = (short)v[11];
|
||||||
state->mp3_v[3] = state->mp3_v[3] - state->mp3_v[13];
|
v[3] = v[3] - v[13];
|
||||||
/* Store state->mp3_v[3] -> (T0 + 0x20) */
|
/* Store v[3] -> (T0 + 0x20) */
|
||||||
*(int16_t *)(state->mp3data + ((t0 + (short)0x20))) = (short)state->mp3_v[3];
|
*(int16_t *)(hle->mp3_buffer + ((t0 + (short)0x20))) = (short)v[3];
|
||||||
state->mp3_v[13] = state->mp3_v[13] + state->mp3_v[2];
|
v[13] = v[13] + v[2];
|
||||||
/* Store state->mp3_v[13] -> (T0 + 0xFFE0) */
|
/* Store v[13] -> (T0 + 0xFFE0) */
|
||||||
*(int16_t *)(state->mp3data + ((t0 + (short)0xFFE0))) = (short)state->mp3_v[13];
|
*(int16_t *)(hle->mp3_buffer + ((t0 + (short)0xFFE0))) = (short)v[13];
|
||||||
state->mp3_v[2] = (state->mp3_v[5] - state->mp3_v[2]) - state->mp3_v[9];
|
v[2] = (v[5] - v[2]) - v[9];
|
||||||
/* Store state->mp3_v[2] -> (T0 + 0xFFA0) */
|
/* Store v[2] -> (T0 + 0xFFA0) */
|
||||||
*(int16_t *)(state->mp3data + ((t0 + (short)0xFFA0))) = (short)state->mp3_v[2];
|
*(int16_t *)(hle->mp3_buffer + ((t0 + (short)0xFFA0))) = (short)v[2];
|
||||||
/* 0x7A8 - Verified... */
|
/* 0x7A8 - Verified... */
|
||||||
|
|
||||||
/* Step 8 - Dewindowing */
|
/* Step 8 - Dewindowing */
|
||||||
|
|
||||||
addptr = state->mp3_t6 & 0xFFE0;
|
addptr = hle->mp3_t6 & 0xFFE0;
|
||||||
|
|
||||||
offset = 0x10 - (state->mp3_t4 >> 1);
|
offset = 0x10 - (hle->mp3_t4 >> 1);
|
||||||
for (x = 0; x < 8; x++) {
|
for (x = 0; x < 8; x++) {
|
||||||
int32_t v0;
|
int32_t v0;
|
||||||
int32_t v18;
|
int32_t v18;
|
||||||
v2 = v4 = v6 = v8 = 0;
|
v2 = v4 = v6 = v8 = 0;
|
||||||
|
|
||||||
for (i = 7; i >= 0; i--) {
|
for (i = 7; i >= 0; i--) {
|
||||||
v2 += ((int) * (int16_t *)(state->mp3data + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
|
v2 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
|
||||||
v4 += ((int) * (int16_t *)(state->mp3data + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
|
v4 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
|
||||||
v6 += ((int) * (int16_t *)(state->mp3data + (addptr) + 0x20) * (short)DeWindowLUT[offset + 0x20] + 0x4000) >> 0xF;
|
v6 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x20) * (short)DeWindowLUT[offset + 0x20] + 0x4000) >> 0xF;
|
||||||
v8 += ((int) * (int16_t *)(state->mp3data + (addptr) + 0x30) * (short)DeWindowLUT[offset + 0x28] + 0x4000) >> 0xF;
|
v8 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x30) * (short)DeWindowLUT[offset + 0x28] + 0x4000) >> 0xF;
|
||||||
addptr += 2;
|
addptr += 2;
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
|
@ -589,34 +586,34 @@ static void InnerLoop(usf_state_t* state)
|
||||||
/* Clamp(v0); */
|
/* Clamp(v0); */
|
||||||
/* Clamp(v18); */
|
/* Clamp(v18); */
|
||||||
/* clamp??? */
|
/* clamp??? */
|
||||||
*(int16_t *)(state->mp3data + (state->mp3_outPtr ^ S16)) = v0;
|
*(int16_t *)(hle->mp3_buffer + (hle->mp3_outPtr ^ S16)) = v0;
|
||||||
*(int16_t *)(state->mp3data + ((state->mp3_outPtr + 2)^S16)) = v18;
|
*(int16_t *)(hle->mp3_buffer + ((hle->mp3_outPtr + 2)^S16)) = v18;
|
||||||
state->mp3_outPtr += 4;
|
hle->mp3_outPtr += 4;
|
||||||
addptr += 0x30;
|
addptr += 0x30;
|
||||||
offset += 0x38;
|
offset += 0x38;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = 0x10 - (state->mp3_t4 >> 1) + 8 * 0x40;
|
offset = 0x10 - (hle->mp3_t4 >> 1) + 8 * 0x40;
|
||||||
v2 = v4 = 0;
|
v2 = v4 = 0;
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
v2 += ((int) * (int16_t *)(state->mp3data + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
|
v2 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
|
||||||
v2 += ((int) * (int16_t *)(state->mp3data + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
|
v2 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
|
||||||
addptr += 2;
|
addptr += 2;
|
||||||
offset++;
|
offset++;
|
||||||
v4 += ((int) * (int16_t *)(state->mp3data + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
|
v4 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
|
||||||
v4 += ((int) * (int16_t *)(state->mp3data + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
|
v4 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
|
||||||
addptr += 2;
|
addptr += 2;
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
mult6 = *(int32_t *)(state->mp3data + 0xCE8);
|
mult6 = *(int32_t *)(hle->mp3_buffer + 0xCE8);
|
||||||
mult4 = *(int32_t *)(state->mp3data + 0xCEC);
|
mult4 = *(int32_t *)(hle->mp3_buffer + 0xCEC);
|
||||||
if (state->mp3_t4 & 0x2) {
|
if (hle->mp3_t4 & 0x2) {
|
||||||
v2 = (v2 **(uint32_t *)(state->mp3data + 0xCE8)) >> 0x10;
|
v2 = (v2 **(uint32_t *)(hle->mp3_buffer + 0xCE8)) >> 0x10;
|
||||||
*(int16_t *)(state->mp3data + (state->mp3_outPtr ^ S16)) = v2;
|
*(int16_t *)(hle->mp3_buffer + (hle->mp3_outPtr ^ S16)) = v2;
|
||||||
} else {
|
} else {
|
||||||
v4 = (v4 **(uint32_t *)(state->mp3data + 0xCE8)) >> 0x10;
|
v4 = (v4 **(uint32_t *)(hle->mp3_buffer + 0xCE8)) >> 0x10;
|
||||||
*(int16_t *)(state->mp3data + (state->mp3_outPtr ^ S16)) = v4;
|
*(int16_t *)(hle->mp3_buffer + (hle->mp3_outPtr ^ S16)) = v4;
|
||||||
mult4 = *(uint32_t *)(state->mp3data + 0xCE8);
|
mult4 = *(uint32_t *)(hle->mp3_buffer + 0xCE8);
|
||||||
}
|
}
|
||||||
addptr -= 0x50;
|
addptr -= 0x50;
|
||||||
|
|
||||||
|
@ -625,17 +622,17 @@ static void InnerLoop(usf_state_t* state)
|
||||||
int32_t v18;
|
int32_t v18;
|
||||||
v2 = v4 = v6 = v8 = 0;
|
v2 = v4 = v6 = v8 = 0;
|
||||||
|
|
||||||
offset = (0x22F - (state->mp3_t4 >> 1) + x * 0x40);
|
offset = (0x22F - (hle->mp3_t4 >> 1) + x * 0x40);
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
v2 += ((int) * (int16_t *)(state->mp3data + (addptr) + 0x20) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
|
v2 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x20) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
|
||||||
v2 -= ((int) * (int16_t *)(state->mp3data + ((addptr + 2)) + 0x20) * (short)DeWindowLUT[offset + 0x01] + 0x4000) >> 0xF;
|
v2 -= ((int) * (int16_t *)(hle->mp3_buffer + ((addptr + 2)) + 0x20) * (short)DeWindowLUT[offset + 0x01] + 0x4000) >> 0xF;
|
||||||
v4 += ((int) * (int16_t *)(state->mp3data + (addptr) + 0x30) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
|
v4 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x30) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
|
||||||
v4 -= ((int) * (int16_t *)(state->mp3data + ((addptr + 2)) + 0x30) * (short)DeWindowLUT[offset + 0x09] + 0x4000) >> 0xF;
|
v4 -= ((int) * (int16_t *)(hle->mp3_buffer + ((addptr + 2)) + 0x30) * (short)DeWindowLUT[offset + 0x09] + 0x4000) >> 0xF;
|
||||||
v6 += ((int) * (int16_t *)(state->mp3data + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x20] + 0x4000) >> 0xF;
|
v6 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x20] + 0x4000) >> 0xF;
|
||||||
v6 -= ((int) * (int16_t *)(state->mp3data + ((addptr + 2)) + 0x00) * (short)DeWindowLUT[offset + 0x21] + 0x4000) >> 0xF;
|
v6 -= ((int) * (int16_t *)(hle->mp3_buffer + ((addptr + 2)) + 0x00) * (short)DeWindowLUT[offset + 0x21] + 0x4000) >> 0xF;
|
||||||
v8 += ((int) * (int16_t *)(state->mp3data + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x28] + 0x4000) >> 0xF;
|
v8 += ((int) * (int16_t *)(hle->mp3_buffer + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x28] + 0x4000) >> 0xF;
|
||||||
v8 -= ((int) * (int16_t *)(state->mp3data + ((addptr + 2)) + 0x10) * (short)DeWindowLUT[offset + 0x29] + 0x4000) >> 0xF;
|
v8 -= ((int) * (int16_t *)(hle->mp3_buffer + ((addptr + 2)) + 0x10) * (short)DeWindowLUT[offset + 0x29] + 0x4000) >> 0xF;
|
||||||
addptr += 4;
|
addptr += 4;
|
||||||
offset += 2;
|
offset += 2;
|
||||||
}
|
}
|
||||||
|
@ -644,13 +641,13 @@ static void InnerLoop(usf_state_t* state)
|
||||||
/* Clamp(v0); */
|
/* Clamp(v0); */
|
||||||
/* Clamp(v18); */
|
/* Clamp(v18); */
|
||||||
/* clamp??? */
|
/* clamp??? */
|
||||||
*(int16_t *)(state->mp3data + ((state->mp3_outPtr + 2)^S16)) = v0;
|
*(int16_t *)(hle->mp3_buffer + ((hle->mp3_outPtr + 2)^S16)) = v0;
|
||||||
*(int16_t *)(state->mp3data + ((state->mp3_outPtr + 4)^S16)) = v18;
|
*(int16_t *)(hle->mp3_buffer + ((hle->mp3_outPtr + 4)^S16)) = v18;
|
||||||
state->mp3_outPtr += 4;
|
hle->mp3_outPtr += 4;
|
||||||
addptr -= 0x50;
|
addptr -= 0x50;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = state->mp3_outPtr;
|
tmp = hle->mp3_outPtr;
|
||||||
hi0 = mult6;
|
hi0 = mult6;
|
||||||
hi1 = mult4;
|
hi1 = mult4;
|
||||||
|
|
||||||
|
@ -658,44 +655,44 @@ static void InnerLoop(usf_state_t* state)
|
||||||
hi1 = (int)hi1 >> 0x10;
|
hi1 = (int)hi1 >> 0x10;
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
/* v0 */
|
/* v0 */
|
||||||
vt = (*(int16_t *)(state->mp3data + ((tmp - 0x40)^S16)) * hi0);
|
vt = (*(int16_t *)(hle->mp3_buffer + ((tmp - 0x40)^S16)) * hi0);
|
||||||
if (vt > 32767) {
|
if (vt > 32767) {
|
||||||
vt = 32767;
|
vt = 32767;
|
||||||
} else {
|
} else {
|
||||||
if (vt < -32767)
|
if (vt < -32767)
|
||||||
vt = -32767;
|
vt = -32767;
|
||||||
}
|
}
|
||||||
*(int16_t *)((uint8_t *)state->mp3data + ((tmp - 0x40)^S16)) = (int16_t)vt;
|
*(int16_t *)((uint8_t *)hle->mp3_buffer + ((tmp - 0x40)^S16)) = (int16_t)vt;
|
||||||
|
|
||||||
/* v17 */
|
/* v17 */
|
||||||
vt = (*(int16_t *)(state->mp3data + ((tmp - 0x30)^S16)) * hi0);
|
vt = (*(int16_t *)(hle->mp3_buffer + ((tmp - 0x30)^S16)) * hi0);
|
||||||
if (vt > 32767) {
|
if (vt > 32767) {
|
||||||
vt = 32767;
|
vt = 32767;
|
||||||
} else {
|
} else {
|
||||||
if (vt < -32767)
|
if (vt < -32767)
|
||||||
vt = -32767;
|
vt = -32767;
|
||||||
}
|
}
|
||||||
*(int16_t *)((uint8_t *)state->mp3data + ((tmp - 0x30)^S16)) = vt;
|
*(int16_t *)((uint8_t *)hle->mp3_buffer + ((tmp - 0x30)^S16)) = vt;
|
||||||
|
|
||||||
/* v2 */
|
/* v2 */
|
||||||
vt = (*(int16_t *)(state->mp3data + ((tmp - 0x1E)^S16)) * hi1);
|
vt = (*(int16_t *)(hle->mp3_buffer + ((tmp - 0x1E)^S16)) * hi1);
|
||||||
if (vt > 32767) {
|
if (vt > 32767) {
|
||||||
vt = 32767;
|
vt = 32767;
|
||||||
} else {
|
} else {
|
||||||
if (vt < -32767)
|
if (vt < -32767)
|
||||||
vt = -32767;
|
vt = -32767;
|
||||||
}
|
}
|
||||||
*(int16_t *)((uint8_t *)state->mp3data + ((tmp - 0x1E)^S16)) = vt;
|
*(int16_t *)((uint8_t *)hle->mp3_buffer + ((tmp - 0x1E)^S16)) = vt;
|
||||||
|
|
||||||
/* v4 */
|
/* v4 */
|
||||||
vt = (*(int16_t *)(state->mp3data + ((tmp - 0xE)^S16)) * hi1);
|
vt = (*(int16_t *)(hle->mp3_buffer + ((tmp - 0xE)^S16)) * hi1);
|
||||||
if (vt > 32767) {
|
if (vt > 32767) {
|
||||||
vt = 32767;
|
vt = 32767;
|
||||||
} else {
|
} else {
|
||||||
if (vt < -32767)
|
if (vt < -32767)
|
||||||
vt = -32767;
|
vt = -32767;
|
||||||
}
|
}
|
||||||
*(int16_t *)((uint8_t *)state->mp3data + ((tmp - 0xE)^S16)) = vt;
|
*(int16_t *)((uint8_t *)hle->mp3_buffer + ((tmp - 0xE)^S16)) = vt;
|
||||||
tmp += 2;
|
tmp += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,19 +19,20 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#else
|
||||||
|
#include "mystdbool.h"
|
||||||
|
#endif
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "../usf.h"
|
|
||||||
|
|
||||||
#include "arithmetics.h"
|
#include "arithmetics.h"
|
||||||
#include "memory.h"
|
|
||||||
#include "plugin.h"
|
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
|
#include "hle_external.h"
|
||||||
#include "../usf_internal.h"
|
#include "hle_internal.h"
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
/* various constants */
|
/* various constants */
|
||||||
enum { SUBFRAME_SIZE = 192 };
|
enum { SUBFRAME_SIZE = 192 };
|
||||||
|
@ -134,27 +135,28 @@ typedef void (*mix_sfx_with_main_subframes_t)(musyx_t *musyx, const int16_t *sub
|
||||||
const uint16_t* gains);
|
const uint16_t* gains);
|
||||||
|
|
||||||
/* helper functions prototypes */
|
/* helper functions prototypes */
|
||||||
static void load_base_vol(usf_state_t* state, int32_t *base_vol, uint32_t address);
|
static void load_base_vol(struct hle_t* hle, int32_t *base_vol, uint32_t address);
|
||||||
static void save_base_vol(usf_state_t* state, const int32_t *base_vol, uint32_t address);
|
static void save_base_vol(struct hle_t* hle, const int32_t *base_vol, uint32_t address);
|
||||||
static void update_base_vol(usf_state_t* state, int32_t *base_vol,
|
static void update_base_vol(struct hle_t* hle, int32_t *base_vol,
|
||||||
uint32_t voice_mask, uint32_t last_sample_ptr,
|
uint32_t voice_mask, uint32_t last_sample_ptr,
|
||||||
uint8_t mask_15, uint32_t ptr_24);
|
uint8_t mask_15, uint32_t ptr_24);
|
||||||
|
|
||||||
static void init_subframes_v1(musyx_t *musyx);
|
static void init_subframes_v1(musyx_t *musyx);
|
||||||
static void init_subframes_v2(musyx_t *musyx);
|
static void init_subframes_v2(musyx_t *musyx);
|
||||||
|
|
||||||
static uint32_t voice_stage(usf_state_t* state, musyx_t *musyx, uint32_t voice_ptr,
|
static uint32_t voice_stage(struct hle_t* hle, musyx_t *musyx,
|
||||||
uint32_t last_sample_ptr);
|
uint32_t voice_ptr, uint32_t last_sample_ptr);
|
||||||
|
|
||||||
static void dma_cat8(usf_state_t* state, uint8_t *dst, uint32_t catsrc_ptr);
|
static void dma_cat8(struct hle_t* hle, uint8_t *dst, uint32_t catsrc_ptr);
|
||||||
static void dma_cat16(usf_state_t* state, uint16_t *dst, uint32_t catsrc_ptr);
|
static void dma_cat16(struct hle_t* hle, uint16_t *dst, uint32_t catsrc_ptr);
|
||||||
|
|
||||||
static void load_samples_PCM16(usf_state_t* state, uint32_t voice_ptr, int16_t *samples,
|
static void load_samples_PCM16(struct hle_t* hle, uint32_t voice_ptr, int16_t *samples,
|
||||||
unsigned *segbase, unsigned *offset);
|
unsigned *segbase, unsigned *offset);
|
||||||
static void load_samples_ADPCM(usf_state_t* state, uint32_t voice_ptr, int16_t *samples,
|
static void load_samples_ADPCM(struct hle_t* hle, uint32_t voice_ptr, int16_t *samples,
|
||||||
unsigned *segbase, unsigned *offset);
|
unsigned *segbase, unsigned *offset);
|
||||||
|
|
||||||
static void adpcm_decode_frames(usf_state_t* state, int16_t *dst, const uint8_t *src,
|
static void adpcm_decode_frames(struct hle_t* hle,
|
||||||
|
int16_t *dst, const uint8_t *src,
|
||||||
const int16_t *table, uint8_t count,
|
const int16_t *table, uint8_t count,
|
||||||
uint8_t skip_samples);
|
uint8_t skip_samples);
|
||||||
|
|
||||||
|
@ -162,11 +164,12 @@ static void adpcm_predict_frame(int16_t *dst, const uint8_t *src,
|
||||||
const uint8_t *nibbles,
|
const uint8_t *nibbles,
|
||||||
unsigned int rshift);
|
unsigned int rshift);
|
||||||
|
|
||||||
static void mix_voice_samples(usf_state_t* state, musyx_t *musyx, uint32_t voice_ptr,
|
static void mix_voice_samples(struct hle_t* hle, musyx_t *musyx,
|
||||||
const int16_t *samples, unsigned segbase,
|
uint32_t voice_ptr, const int16_t *samples,
|
||||||
unsigned offset, uint32_t last_sample_ptr);
|
unsigned segbase, unsigned offset, uint32_t last_sample_ptr);
|
||||||
|
|
||||||
static void sfx_stage(usf_state_t* state, mix_sfx_with_main_subframes_t mix_sfx_with_main_subframes,
|
static void sfx_stage(struct hle_t* hle,
|
||||||
|
mix_sfx_with_main_subframes_t mix_sfx_with_main_subframes,
|
||||||
musyx_t *musyx, uint32_t sfx_ptr, uint16_t idx);
|
musyx_t *musyx, uint32_t sfx_ptr, uint16_t idx);
|
||||||
|
|
||||||
static void mix_sfx_with_main_subframes_v1(musyx_t *musyx, const int16_t *subframe,
|
static void mix_sfx_with_main_subframes_v1(musyx_t *musyx, const int16_t *subframe,
|
||||||
|
@ -179,9 +182,11 @@ static void mix_subframes(int16_t *y, const int16_t *x, int16_t hgain);
|
||||||
static void mix_fir4(int16_t *y, const int16_t *x, int16_t hgain, const int16_t *hcoeffs);
|
static void mix_fir4(int16_t *y, const int16_t *x, int16_t hgain, const int16_t *hcoeffs);
|
||||||
|
|
||||||
|
|
||||||
static void interleave_stage_v1(usf_state_t* state, musyx_t *musyx, uint32_t output_ptr);
|
static void interleave_stage_v1(struct hle_t* hle, musyx_t *musyx,
|
||||||
|
uint32_t output_ptr);
|
||||||
|
|
||||||
static void interleave_stage_v2(usf_state_t* state, musyx_t *musyx, uint16_t mask_16, uint32_t ptr_18,
|
static void interleave_stage_v2(struct hle_t* hle, musyx_t *musyx,
|
||||||
|
uint16_t mask_16, uint32_t ptr_18,
|
||||||
uint32_t ptr_1c, uint32_t output_ptr);
|
uint32_t ptr_1c, uint32_t output_ptr);
|
||||||
|
|
||||||
static int32_t dot4(const int16_t *x, const int16_t *y)
|
static int32_t dot4(const int16_t *x, const int16_t *y)
|
||||||
|
@ -198,129 +203,132 @@ static int32_t dot4(const int16_t *x, const int16_t *y)
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* MusyX v1 audio ucode
|
* MusyX v1 audio ucode
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void musyx_v1_task(usf_state_t* state)
|
void musyx_v1_task(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
uint32_t sfd_ptr = *dmem_u32(state, TASK_DATA_PTR);
|
uint32_t sfd_ptr = *dmem_u32(hle, TASK_DATA_PTR);
|
||||||
uint32_t sfd_count = *dmem_u32(state, TASK_DATA_SIZE);
|
uint32_t sfd_count = *dmem_u32(hle, TASK_DATA_SIZE);
|
||||||
uint32_t state_ptr;
|
uint32_t state_ptr;
|
||||||
musyx_t musyx;
|
musyx_t musyx;
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "musyx_v1_task: *data=%x, #SF=%d",
|
HleVerboseMessage(hle->user_defined,
|
||||||
sfd_ptr,
|
"musyx_v1_task: *data=%x, #SF=%d",
|
||||||
sfd_count);
|
sfd_ptr,
|
||||||
|
sfd_count);
|
||||||
|
|
||||||
state_ptr = *dram_u32(state, sfd_ptr + SFD_STATE_PTR);
|
state_ptr = *dram_u32(hle, sfd_ptr + SFD_STATE_PTR);
|
||||||
|
|
||||||
/* load initial state */
|
/* load initial state */
|
||||||
load_base_vol(state, musyx.base_vol, state_ptr + STATE_BASE_VOL);
|
load_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL);
|
||||||
dram_load_u16(state, (uint16_t *)musyx.cc0, state_ptr + STATE_CC0, SUBFRAME_SIZE);
|
dram_load_u16(hle, (uint16_t *)musyx.cc0, state_ptr + STATE_CC0, SUBFRAME_SIZE);
|
||||||
dram_load_u16(state, (uint16_t *)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V1,
|
dram_load_u16(hle, (uint16_t *)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V1,
|
||||||
4);
|
4);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* parse SFD structure */
|
/* parse SFD structure */
|
||||||
uint16_t sfx_index = *dram_u16(state, sfd_ptr + SFD_SFX_INDEX);
|
uint16_t sfx_index = *dram_u16(hle, sfd_ptr + SFD_SFX_INDEX);
|
||||||
uint32_t voice_mask = *dram_u32(state, sfd_ptr + SFD_VOICE_BITMASK);
|
uint32_t voice_mask = *dram_u32(hle, sfd_ptr + SFD_VOICE_BITMASK);
|
||||||
uint32_t sfx_ptr = *dram_u32(state, sfd_ptr + SFD_SFX_PTR);
|
uint32_t sfx_ptr = *dram_u32(hle, sfd_ptr + SFD_SFX_PTR);
|
||||||
uint32_t voice_ptr = sfd_ptr + SFD_VOICES;
|
uint32_t voice_ptr = sfd_ptr + SFD_VOICES;
|
||||||
uint32_t last_sample_ptr = state_ptr + STATE_LAST_SAMPLE;
|
uint32_t last_sample_ptr = state_ptr + STATE_LAST_SAMPLE;
|
||||||
uint32_t output_ptr;
|
uint32_t output_ptr;
|
||||||
|
|
||||||
/* initialize internal subframes using updated base volumes */
|
/* initialize internal subframes using updated base volumes */
|
||||||
update_base_vol(state, musyx.base_vol, voice_mask, last_sample_ptr, 0, 0);
|
update_base_vol(hle, musyx.base_vol, voice_mask, last_sample_ptr, 0, 0);
|
||||||
init_subframes_v1(&musyx);
|
init_subframes_v1(&musyx);
|
||||||
|
|
||||||
/* active voices get mixed into L,R,cc0,e50 subframes (optional) */
|
/* active voices get mixed into L,R,cc0,e50 subframes (optional) */
|
||||||
output_ptr = voice_stage(state, &musyx, voice_ptr, last_sample_ptr);
|
output_ptr = voice_stage(hle, &musyx, voice_ptr, last_sample_ptr);
|
||||||
|
|
||||||
/* apply delay-based effects (optional) */
|
/* apply delay-based effects (optional) */
|
||||||
sfx_stage(state, mix_sfx_with_main_subframes_v1,
|
sfx_stage(hle, mix_sfx_with_main_subframes_v1,
|
||||||
&musyx, sfx_ptr, sfx_index);
|
&musyx, sfx_ptr, sfx_index);
|
||||||
|
|
||||||
/* emit interleaved L,R subframes */
|
/* emit interleaved L,R subframes */
|
||||||
interleave_stage_v1(state, &musyx, output_ptr);
|
interleave_stage_v1(hle, &musyx, output_ptr);
|
||||||
|
|
||||||
--sfd_count;
|
--sfd_count;
|
||||||
if (sfd_count == 0)
|
if (sfd_count == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
sfd_ptr += SFD_VOICES + MAX_VOICES * VOICE_SIZE;
|
sfd_ptr += SFD_VOICES + MAX_VOICES * VOICE_SIZE;
|
||||||
state_ptr = *dram_u32(state, sfd_ptr + SFD_STATE_PTR);
|
state_ptr = *dram_u32(hle, sfd_ptr + SFD_STATE_PTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* writeback updated state */
|
/* writeback updated state */
|
||||||
save_base_vol(state, musyx.base_vol, state_ptr + STATE_BASE_VOL);
|
save_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL);
|
||||||
dram_store_u16(state, (uint16_t *)musyx.cc0, state_ptr + STATE_CC0, SUBFRAME_SIZE);
|
dram_store_u16(hle, (uint16_t *)musyx.cc0, state_ptr + STATE_CC0, SUBFRAME_SIZE);
|
||||||
dram_store_u16(state, (uint16_t *)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V1,
|
dram_store_u16(hle, (uint16_t *)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V1,
|
||||||
4);
|
4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* MusyX v2 audio ucode
|
* MusyX v2 audio ucode
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
void musyx_v2_task(usf_state_t* state)
|
void musyx_v2_task(struct hle_t* hle)
|
||||||
{
|
{
|
||||||
uint32_t sfd_ptr = *dmem_u32(state, TASK_DATA_PTR);
|
uint32_t sfd_ptr = *dmem_u32(hle, TASK_DATA_PTR);
|
||||||
uint32_t sfd_count = *dmem_u32(state, TASK_DATA_SIZE);
|
uint32_t sfd_count = *dmem_u32(hle, TASK_DATA_SIZE);
|
||||||
musyx_t musyx;
|
musyx_t musyx;
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "musyx_v2_task: *data=%x, #SF=%d",
|
HleVerboseMessage(hle->user_defined,
|
||||||
sfd_ptr,
|
"musyx_v2_task: *data=%x, #SF=%d",
|
||||||
sfd_count);
|
sfd_ptr,
|
||||||
|
sfd_count);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* parse SFD structure */
|
/* parse SFD structure */
|
||||||
uint16_t sfx_index = *dram_u16(state, sfd_ptr + SFD_SFX_INDEX);
|
uint16_t sfx_index = *dram_u16(hle, sfd_ptr + SFD_SFX_INDEX);
|
||||||
uint32_t voice_mask = *dram_u32(state, sfd_ptr + SFD_VOICE_BITMASK);
|
uint32_t voice_mask = *dram_u32(hle, sfd_ptr + SFD_VOICE_BITMASK);
|
||||||
uint32_t state_ptr = *dram_u32(state, sfd_ptr + SFD_STATE_PTR);
|
uint32_t state_ptr = *dram_u32(hle, sfd_ptr + SFD_STATE_PTR);
|
||||||
uint32_t sfx_ptr = *dram_u32(state, sfd_ptr + SFD_SFX_PTR);
|
uint32_t sfx_ptr = *dram_u32(hle, sfd_ptr + SFD_SFX_PTR);
|
||||||
uint32_t voice_ptr = sfd_ptr + SFD2_VOICES;
|
uint32_t voice_ptr = sfd_ptr + SFD2_VOICES;
|
||||||
|
|
||||||
uint32_t ptr_10 = *dram_u32(state, sfd_ptr + SFD2_10_PTR);
|
uint32_t ptr_10 = *dram_u32(hle, sfd_ptr + SFD2_10_PTR);
|
||||||
uint8_t mask_14 = *dram_u8 (state, sfd_ptr + SFD2_14_BITMASK);
|
uint8_t mask_14 = *dram_u8 (hle, sfd_ptr + SFD2_14_BITMASK);
|
||||||
uint8_t mask_15 = *dram_u8 (state, sfd_ptr + SFD2_15_BITMASK);
|
uint8_t mask_15 = *dram_u8 (hle, sfd_ptr + SFD2_15_BITMASK);
|
||||||
uint16_t mask_16 = *dram_u16(state, sfd_ptr + SFD2_16_BITMASK);
|
uint16_t mask_16 = *dram_u16(hle, sfd_ptr + SFD2_16_BITMASK);
|
||||||
uint32_t ptr_18 = *dram_u32(state, sfd_ptr + SFD2_18_PTR);
|
uint32_t ptr_18 = *dram_u32(hle, sfd_ptr + SFD2_18_PTR);
|
||||||
uint32_t ptr_1c = *dram_u32(state, sfd_ptr + SFD2_1C_PTR);
|
uint32_t ptr_1c = *dram_u32(hle, sfd_ptr + SFD2_1C_PTR);
|
||||||
uint32_t ptr_20 = *dram_u32(state, sfd_ptr + SFD2_20_PTR);
|
uint32_t ptr_20 = *dram_u32(hle, sfd_ptr + SFD2_20_PTR);
|
||||||
uint32_t ptr_24 = *dram_u32(state, sfd_ptr + SFD2_24_PTR);
|
uint32_t ptr_24 = *dram_u32(hle, sfd_ptr + SFD2_24_PTR);
|
||||||
|
|
||||||
uint32_t last_sample_ptr = state_ptr + STATE_LAST_SAMPLE;
|
uint32_t last_sample_ptr = state_ptr + STATE_LAST_SAMPLE;
|
||||||
uint32_t output_ptr;
|
uint32_t output_ptr;
|
||||||
|
|
||||||
/* load state */
|
/* load state */
|
||||||
load_base_vol(state, musyx.base_vol, state_ptr + STATE_BASE_VOL);
|
load_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL);
|
||||||
dram_load_u16(state, (uint16_t *)musyx.subframe_740_last4,
|
dram_load_u16(hle, (uint16_t *)musyx.subframe_740_last4,
|
||||||
state_ptr + STATE_740_LAST4_V2, 4);
|
state_ptr + STATE_740_LAST4_V2, 4);
|
||||||
|
|
||||||
/* initialize internal subframes using updated base volumes */
|
/* initialize internal subframes using updated base volumes */
|
||||||
update_base_vol(state, musyx.base_vol, voice_mask, last_sample_ptr, mask_15, ptr_24);
|
update_base_vol(hle, musyx.base_vol, voice_mask, last_sample_ptr, mask_15, ptr_24);
|
||||||
init_subframes_v2(&musyx);
|
init_subframes_v2(&musyx);
|
||||||
|
|
||||||
if (ptr_10) {
|
if (ptr_10) {
|
||||||
/* TODO */
|
/* TODO */
|
||||||
DebugMessage(state, M64MSG_WARNING, "ptr_10=%08x mask_14=%02x ptr_24=%08x",
|
HleWarnMessage(hle->user_defined,
|
||||||
ptr_10, mask_14, ptr_24);
|
"ptr_10=%08x mask_14=%02x ptr_24=%08x",
|
||||||
|
ptr_10, mask_14, ptr_24);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* active voices get mixed into L,R,cc0,e50 subframes (optional) */
|
/* active voices get mixed into L,R,cc0,e50 subframes (optional) */
|
||||||
output_ptr = voice_stage(state, &musyx, voice_ptr, last_sample_ptr);
|
output_ptr = voice_stage(hle, &musyx, voice_ptr, last_sample_ptr);
|
||||||
|
|
||||||
/* apply delay-based effects (optional) */
|
/* apply delay-based effects (optional) */
|
||||||
sfx_stage(state, mix_sfx_with_main_subframes_v2,
|
sfx_stage(hle, mix_sfx_with_main_subframes_v2,
|
||||||
&musyx, sfx_ptr, sfx_index);
|
&musyx, sfx_ptr, sfx_index);
|
||||||
|
|
||||||
dram_store_u16(state, (uint16_t*)musyx.left, output_ptr , SUBFRAME_SIZE);
|
dram_store_u16(hle, (uint16_t*)musyx.left, output_ptr , SUBFRAME_SIZE);
|
||||||
dram_store_u16(state, (uint16_t*)musyx.right, output_ptr + 2*SUBFRAME_SIZE, SUBFRAME_SIZE);
|
dram_store_u16(hle, (uint16_t*)musyx.right, output_ptr + 2*SUBFRAME_SIZE, SUBFRAME_SIZE);
|
||||||
dram_store_u16(state, (uint16_t*)musyx.cc0, output_ptr + 4*SUBFRAME_SIZE, SUBFRAME_SIZE);
|
dram_store_u16(hle, (uint16_t*)musyx.cc0, output_ptr + 4*SUBFRAME_SIZE, SUBFRAME_SIZE);
|
||||||
|
|
||||||
/* store state */
|
/* store state */
|
||||||
save_base_vol(state, musyx.base_vol, state_ptr + STATE_BASE_VOL);
|
save_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL);
|
||||||
dram_store_u16(state, (uint16_t*)musyx.subframe_740_last4,
|
dram_store_u16(hle, (uint16_t*)musyx.subframe_740_last4,
|
||||||
state_ptr + STATE_740_LAST4_V2, 4);
|
state_ptr + STATE_740_LAST4_V2, 4);
|
||||||
|
|
||||||
if (mask_16)
|
if (mask_16)
|
||||||
interleave_stage_v2(state, &musyx, mask_16, ptr_18, ptr_1c, ptr_20);
|
interleave_stage_v2(hle, &musyx, mask_16, ptr_18, ptr_1c, ptr_20);
|
||||||
|
|
||||||
--sfd_count;
|
--sfd_count;
|
||||||
if (sfd_count == 0)
|
if (sfd_count == 0)
|
||||||
|
@ -334,39 +342,40 @@ void musyx_v2_task(usf_state_t* state)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void load_base_vol(usf_state_t* state, int32_t *base_vol, uint32_t address)
|
static void load_base_vol(struct hle_t* hle, int32_t *base_vol, uint32_t address)
|
||||||
{
|
{
|
||||||
base_vol[0] = ((uint32_t)(*dram_u16(state, address)) << 16) | (*dram_u16(state, address + 8));
|
base_vol[0] = ((uint32_t)(*dram_u16(hle, address)) << 16) | (*dram_u16(hle, address + 8));
|
||||||
base_vol[1] = ((uint32_t)(*dram_u16(state, address + 2)) << 16) | (*dram_u16(state, address + 10));
|
base_vol[1] = ((uint32_t)(*dram_u16(hle, address + 2)) << 16) | (*dram_u16(hle, address + 10));
|
||||||
base_vol[2] = ((uint32_t)(*dram_u16(state, address + 4)) << 16) | (*dram_u16(state, address + 12));
|
base_vol[2] = ((uint32_t)(*dram_u16(hle, address + 4)) << 16) | (*dram_u16(hle, address + 12));
|
||||||
base_vol[3] = ((uint32_t)(*dram_u16(state, address + 6)) << 16) | (*dram_u16(state, address + 14));
|
base_vol[3] = ((uint32_t)(*dram_u16(hle, address + 6)) << 16) | (*dram_u16(hle, address + 14));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void save_base_vol(usf_state_t* state, const int32_t *base_vol, uint32_t address)
|
static void save_base_vol(struct hle_t* hle, const int32_t *base_vol, uint32_t address)
|
||||||
{
|
{
|
||||||
unsigned k;
|
unsigned k;
|
||||||
|
|
||||||
for (k = 0; k < 4; ++k) {
|
for (k = 0; k < 4; ++k) {
|
||||||
*dram_u16(state, address) = (uint16_t)(base_vol[k] >> 16);
|
*dram_u16(hle, address) = (uint16_t)(base_vol[k] >> 16);
|
||||||
address += 2;
|
address += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (k = 0; k < 4; ++k) {
|
for (k = 0; k < 4; ++k) {
|
||||||
*dram_u16(state, address) = (uint16_t)(base_vol[k]);
|
*dram_u16(hle, address) = (uint16_t)(base_vol[k]);
|
||||||
address += 2;
|
address += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_base_vol(usf_state_t* state, int32_t *base_vol,
|
static void update_base_vol(struct hle_t* hle, int32_t *base_vol,
|
||||||
uint32_t voice_mask, uint32_t last_sample_ptr,
|
uint32_t voice_mask, uint32_t last_sample_ptr,
|
||||||
uint8_t mask_15, uint32_t ptr_24)
|
uint8_t mask_15, uint32_t ptr_24)
|
||||||
{
|
{
|
||||||
unsigned i, k;
|
unsigned i, k;
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "base_vol voice_mask = %08x", voice_mask);
|
HleVerboseMessage(hle->user_defined, "base_vol voice_mask = %08x", voice_mask);
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "BEFORE: base_vol = %08x %08x %08x %08x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
base_vol[0], base_vol[1], base_vol[2], base_vol[3]);
|
"BEFORE: base_vol = %08x %08x %08x %08x",
|
||||||
|
base_vol[0], base_vol[1], base_vol[2], base_vol[3]);
|
||||||
|
|
||||||
/* optim: skip voices contributions entirely if voice_mask is empty */
|
/* optim: skip voices contributions entirely if voice_mask is empty */
|
||||||
if (voice_mask != 0) {
|
if (voice_mask != 0) {
|
||||||
|
@ -376,7 +385,7 @@ static void update_base_vol(usf_state_t* state, int32_t *base_vol,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (k = 0; k < 4; ++k)
|
for (k = 0; k < 4; ++k)
|
||||||
base_vol[k] += (int16_t)*dram_u16(state, last_sample_ptr + k * 2);
|
base_vol[k] += (int16_t)*dram_u16(hle, last_sample_ptr + k * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +397,7 @@ static void update_base_vol(usf_state_t* state, int32_t *base_vol,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for(k = 0; k < 4; ++k)
|
for(k = 0; k < 4; ++k)
|
||||||
base_vol[k] += (int16_t)*dram_u16(state, ptr_24 + k * 2);
|
base_vol[k] += (int16_t)*dram_u16(hle, ptr_24 + k * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,8 +405,9 @@ static void update_base_vol(usf_state_t* state, int32_t *base_vol,
|
||||||
for (k = 0; k < 4; ++k)
|
for (k = 0; k < 4; ++k)
|
||||||
base_vol[k] = (base_vol[k] * 0x0000f850) >> 16;
|
base_vol[k] = (base_vol[k] * 0x0000f850) >> 16;
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "AFTER: base_vol = %08x %08x %08x %08x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
base_vol[0], base_vol[1], base_vol[2], base_vol[3]);
|
"AFTER: base_vol = %08x %08x %08x %08x",
|
||||||
|
base_vol[0], base_vol[1], base_vol[2], base_vol[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -449,16 +459,16 @@ static void init_subframes_v2(musyx_t *musyx)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process voices, and returns interleaved subframe destination address */
|
/* Process voices, and returns interleaved subframe destination address */
|
||||||
static uint32_t voice_stage(usf_state_t* state, musyx_t *musyx, uint32_t voice_ptr,
|
static uint32_t voice_stage(struct hle_t* hle, musyx_t *musyx,
|
||||||
uint32_t last_sample_ptr)
|
uint32_t voice_ptr, uint32_t last_sample_ptr)
|
||||||
{
|
{
|
||||||
uint32_t output_ptr;
|
uint32_t output_ptr;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
/* voice stage can be skipped if first voice has no samples */
|
/* voice stage can be skipped if first voice has no samples */
|
||||||
if (*dram_u16(state, voice_ptr + VOICE_CATSRC_0 + CATSRC_SIZE1) == 0) {
|
if (*dram_u16(hle, voice_ptr + VOICE_CATSRC_0 + CATSRC_SIZE1) == 0) {
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "Skipping Voice stage");
|
HleVerboseMessage(hle->user_defined, "Skipping Voice stage");
|
||||||
output_ptr = *dram_u32(state, voice_ptr + VOICE_INTERLEAVED_PTR);
|
output_ptr = *dram_u32(hle, voice_ptr + VOICE_INTERLEAVED_PTR);
|
||||||
} else {
|
} else {
|
||||||
/* otherwise process voices until a non null output_ptr is encountered */
|
/* otherwise process voices until a non null output_ptr is encountered */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -467,19 +477,19 @@ static uint32_t voice_stage(usf_state_t* state, musyx_t *musyx, uint32_t voice_p
|
||||||
unsigned segbase;
|
unsigned segbase;
|
||||||
unsigned offset;
|
unsigned offset;
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "Processing Voice #%d", i);
|
HleVerboseMessage(hle->user_defined, "Processing Voice #%d", i);
|
||||||
|
|
||||||
if (*dram_u8(state, voice_ptr + VOICE_ADPCM_FRAMES) == 0)
|
if (*dram_u8(hle, voice_ptr + VOICE_ADPCM_FRAMES) == 0)
|
||||||
load_samples_PCM16(state, voice_ptr, samples, &segbase, &offset);
|
load_samples_PCM16(hle, voice_ptr, samples, &segbase, &offset);
|
||||||
else
|
else
|
||||||
load_samples_ADPCM(state, voice_ptr, samples, &segbase, &offset);
|
load_samples_ADPCM(hle, voice_ptr, samples, &segbase, &offset);
|
||||||
|
|
||||||
/* mix them with each internal subframes */
|
/* mix them with each internal subframes */
|
||||||
mix_voice_samples(state, musyx, voice_ptr, samples, segbase, offset,
|
mix_voice_samples(hle, musyx, voice_ptr, samples, segbase, offset,
|
||||||
last_sample_ptr + i * 8);
|
last_sample_ptr + i * 8);
|
||||||
|
|
||||||
/* check break condition */
|
/* check break condition */
|
||||||
output_ptr = *dram_u32(state, voice_ptr + VOICE_INTERLEAVED_PTR);
|
output_ptr = *dram_u32(hle, voice_ptr + VOICE_INTERLEAVED_PTR);
|
||||||
if (output_ptr != 0)
|
if (output_ptr != 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -492,76 +502,78 @@ static uint32_t voice_stage(usf_state_t* state, musyx_t *musyx, uint32_t voice_p
|
||||||
return output_ptr;
|
return output_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dma_cat8(usf_state_t* state, uint8_t *dst, uint32_t catsrc_ptr)
|
static void dma_cat8(struct hle_t* hle, uint8_t *dst, uint32_t catsrc_ptr)
|
||||||
{
|
{
|
||||||
uint32_t ptr1 = *dram_u32(state, catsrc_ptr + CATSRC_PTR1);
|
uint32_t ptr1 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR1);
|
||||||
uint32_t ptr2 = *dram_u32(state, catsrc_ptr + CATSRC_PTR2);
|
uint32_t ptr2 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR2);
|
||||||
uint16_t size1 = *dram_u16(state, catsrc_ptr + CATSRC_SIZE1);
|
uint16_t size1 = *dram_u16(hle, catsrc_ptr + CATSRC_SIZE1);
|
||||||
uint16_t size2 = *dram_u16(state, catsrc_ptr + CATSRC_SIZE2);
|
uint16_t size2 = *dram_u16(hle, catsrc_ptr + CATSRC_SIZE2);
|
||||||
|
|
||||||
size_t count1 = size1;
|
size_t count1 = size1;
|
||||||
size_t count2 = size2;
|
size_t count2 = size2;
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "dma_cat: %08x %08x %04x %04x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
ptr1,
|
"dma_cat: %08x %08x %04x %04x",
|
||||||
ptr2,
|
ptr1,
|
||||||
size1,
|
ptr2,
|
||||||
size2);
|
size1,
|
||||||
|
size2);
|
||||||
|
|
||||||
dram_load_u8(state, dst, ptr1, count1);
|
dram_load_u8(hle, dst, ptr1, count1);
|
||||||
|
|
||||||
if (size2 == 0)
|
if (size2 == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dram_load_u8(state, dst + count1, ptr2, count2);
|
dram_load_u8(hle, dst + count1, ptr2, count2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dma_cat16(usf_state_t* state, uint16_t *dst, uint32_t catsrc_ptr)
|
static void dma_cat16(struct hle_t* hle, uint16_t *dst, uint32_t catsrc_ptr)
|
||||||
{
|
{
|
||||||
uint32_t ptr1 = *dram_u32(state, catsrc_ptr + CATSRC_PTR1);
|
uint32_t ptr1 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR1);
|
||||||
uint32_t ptr2 = *dram_u32(state, catsrc_ptr + CATSRC_PTR2);
|
uint32_t ptr2 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR2);
|
||||||
uint16_t size1 = *dram_u16(state, catsrc_ptr + CATSRC_SIZE1);
|
uint16_t size1 = *dram_u16(hle, catsrc_ptr + CATSRC_SIZE1);
|
||||||
uint16_t size2 = *dram_u16(state, catsrc_ptr + CATSRC_SIZE2);
|
uint16_t size2 = *dram_u16(hle, catsrc_ptr + CATSRC_SIZE2);
|
||||||
|
|
||||||
size_t count1 = size1 >> 1;
|
size_t count1 = size1 >> 1;
|
||||||
size_t count2 = size2 >> 1;
|
size_t count2 = size2 >> 1;
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "dma_cat: %08x %08x %04x %04x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
ptr1,
|
"dma_cat: %08x %08x %04x %04x",
|
||||||
ptr2,
|
ptr1,
|
||||||
size1,
|
ptr2,
|
||||||
size2);
|
size1,
|
||||||
|
size2);
|
||||||
|
|
||||||
dram_load_u16(state, dst, ptr1, count1);
|
dram_load_u16(hle, dst, ptr1, count1);
|
||||||
|
|
||||||
if (size2 == 0)
|
if (size2 == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dram_load_u16(state, dst + count1, ptr2, count2);
|
dram_load_u16(hle, dst + count1, ptr2, count2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_samples_PCM16(usf_state_t* state, uint32_t voice_ptr, int16_t *samples,
|
static void load_samples_PCM16(struct hle_t* hle, uint32_t voice_ptr, int16_t *samples,
|
||||||
unsigned *segbase, unsigned *offset)
|
unsigned *segbase, unsigned *offset)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint8_t u8_3e = *dram_u8(state, voice_ptr + VOICE_SKIP_SAMPLES);
|
uint8_t u8_3e = *dram_u8(hle, voice_ptr + VOICE_SKIP_SAMPLES);
|
||||||
uint16_t u16_40 = *dram_u16(state, voice_ptr + VOICE_U16_40);
|
uint16_t u16_40 = *dram_u16(hle, voice_ptr + VOICE_U16_40);
|
||||||
uint16_t u16_42 = *dram_u16(state, voice_ptr + VOICE_U16_42);
|
uint16_t u16_42 = *dram_u16(hle, voice_ptr + VOICE_U16_42);
|
||||||
|
|
||||||
unsigned count = align(u16_40 + u8_3e, 4);
|
unsigned count = align(u16_40 + u8_3e, 4);
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "Format: PCM16");
|
HleVerboseMessage(hle->user_defined, "Format: PCM16");
|
||||||
|
|
||||||
*segbase = SAMPLE_BUFFER_SIZE - count;
|
*segbase = SAMPLE_BUFFER_SIZE - count;
|
||||||
*offset = u8_3e;
|
*offset = u8_3e;
|
||||||
|
|
||||||
dma_cat16(state, (uint16_t *)samples + *segbase, voice_ptr + VOICE_CATSRC_0);
|
dma_cat16(hle, (uint16_t *)samples + *segbase, voice_ptr + VOICE_CATSRC_0);
|
||||||
|
|
||||||
if (u16_42 != 0)
|
if (u16_42 != 0)
|
||||||
dma_cat16(state, (uint16_t *)samples, voice_ptr + VOICE_CATSRC_1);
|
dma_cat16(hle, (uint16_t *)samples, voice_ptr + VOICE_CATSRC_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_samples_ADPCM(usf_state_t* state, uint32_t voice_ptr, int16_t *samples,
|
static void load_samples_ADPCM(struct hle_t* hle, uint32_t voice_ptr, int16_t *samples,
|
||||||
unsigned *segbase, unsigned *offset)
|
unsigned *segbase, unsigned *offset)
|
||||||
{
|
{
|
||||||
/* decompressed samples cannot exceed 0x400 bytes;
|
/* decompressed samples cannot exceed 0x400 bytes;
|
||||||
|
@ -569,33 +581,34 @@ static void load_samples_ADPCM(usf_state_t* state, uint32_t voice_ptr, int16_t *
|
||||||
uint8_t buffer[SAMPLE_BUFFER_SIZE * 2 * 5 / 16];
|
uint8_t buffer[SAMPLE_BUFFER_SIZE * 2 * 5 / 16];
|
||||||
int16_t adpcm_table[128];
|
int16_t adpcm_table[128];
|
||||||
|
|
||||||
uint8_t u8_3c = *dram_u8(state, voice_ptr + VOICE_ADPCM_FRAMES );
|
uint8_t u8_3c = *dram_u8(hle, voice_ptr + VOICE_ADPCM_FRAMES );
|
||||||
uint8_t u8_3d = *dram_u8(state, voice_ptr + VOICE_ADPCM_FRAMES + 1);
|
uint8_t u8_3d = *dram_u8(hle, voice_ptr + VOICE_ADPCM_FRAMES + 1);
|
||||||
uint8_t u8_3e = *dram_u8(state, voice_ptr + VOICE_SKIP_SAMPLES );
|
uint8_t u8_3e = *dram_u8(hle, voice_ptr + VOICE_SKIP_SAMPLES );
|
||||||
uint8_t u8_3f = *dram_u8(state, voice_ptr + VOICE_SKIP_SAMPLES + 1);
|
uint8_t u8_3f = *dram_u8(hle, voice_ptr + VOICE_SKIP_SAMPLES + 1);
|
||||||
uint32_t adpcm_table_ptr = *dram_u32(state, voice_ptr + VOICE_ADPCM_TABLE_PTR);
|
uint32_t adpcm_table_ptr = *dram_u32(hle, voice_ptr + VOICE_ADPCM_TABLE_PTR);
|
||||||
unsigned count;
|
unsigned count;
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "Format: ADPCM");
|
HleVerboseMessage(hle->user_defined, "Format: ADPCM");
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "Loading ADPCM table: %08x", adpcm_table_ptr);
|
HleVerboseMessage(hle->user_defined, "Loading ADPCM table: %08x", adpcm_table_ptr);
|
||||||
dram_load_u16(state, (uint16_t *)adpcm_table, adpcm_table_ptr, 128);
|
dram_load_u16(hle, (uint16_t *)adpcm_table, adpcm_table_ptr, 128);
|
||||||
|
|
||||||
count = u8_3c << 5;
|
count = u8_3c << 5;
|
||||||
|
|
||||||
*segbase = SAMPLE_BUFFER_SIZE - count;
|
*segbase = SAMPLE_BUFFER_SIZE - count;
|
||||||
*offset = u8_3e & 0x1f;
|
*offset = u8_3e & 0x1f;
|
||||||
|
|
||||||
dma_cat8(state, buffer, voice_ptr + VOICE_CATSRC_0);
|
dma_cat8(hle, buffer, voice_ptr + VOICE_CATSRC_0);
|
||||||
adpcm_decode_frames(state, samples + *segbase, buffer, adpcm_table, u8_3c, u8_3e);
|
adpcm_decode_frames(hle, samples + *segbase, buffer, adpcm_table, u8_3c, u8_3e);
|
||||||
|
|
||||||
if (u8_3d != 0) {
|
if (u8_3d != 0) {
|
||||||
dma_cat8(state, buffer, voice_ptr + VOICE_CATSRC_1);
|
dma_cat8(hle, buffer, voice_ptr + VOICE_CATSRC_1);
|
||||||
adpcm_decode_frames(state, samples, buffer, adpcm_table, u8_3d, u8_3f);
|
adpcm_decode_frames(hle, samples, buffer, adpcm_table, u8_3d, u8_3f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adpcm_decode_frames(usf_state_t* state, int16_t *dst, const uint8_t *src,
|
static void adpcm_decode_frames(struct hle_t* hle,
|
||||||
|
int16_t *dst, const uint8_t *src,
|
||||||
const int16_t *table, uint8_t count,
|
const int16_t *table, uint8_t count,
|
||||||
uint8_t skip_samples)
|
uint8_t skip_samples)
|
||||||
{
|
{
|
||||||
|
@ -604,8 +617,9 @@ static void adpcm_decode_frames(usf_state_t* state, int16_t *dst, const uint8_t
|
||||||
unsigned i;
|
unsigned i;
|
||||||
bool jump_gap = false;
|
bool jump_gap = false;
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "ADPCM decode: count=%d, skip=%d", count,
|
HleVerboseMessage(hle->user_defined,
|
||||||
skip_samples);
|
"ADPCM decode: count=%d, skip=%d",
|
||||||
|
count, skip_samples);
|
||||||
|
|
||||||
if (skip_samples >= 32) {
|
if (skip_samples >= 32) {
|
||||||
jump_gap = true;
|
jump_gap = true;
|
||||||
|
@ -656,20 +670,20 @@ static void adpcm_predict_frame(int16_t *dst, const uint8_t *src,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mix_voice_samples(usf_state_t* state, musyx_t *musyx, uint32_t voice_ptr,
|
static void mix_voice_samples(struct hle_t* hle, musyx_t *musyx,
|
||||||
const int16_t *samples, unsigned segbase,
|
uint32_t voice_ptr, const int16_t *samples,
|
||||||
unsigned offset, uint32_t last_sample_ptr)
|
unsigned segbase, unsigned offset, uint32_t last_sample_ptr)
|
||||||
{
|
{
|
||||||
int i, k;
|
int i, k;
|
||||||
|
|
||||||
/* parse VOICE structure */
|
/* parse VOICE structure */
|
||||||
const uint16_t pitch_q16 = *dram_u16(state, voice_ptr + VOICE_PITCH_Q16);
|
const uint16_t pitch_q16 = *dram_u16(hle, voice_ptr + VOICE_PITCH_Q16);
|
||||||
const uint16_t pitch_shift = *dram_u16(state, voice_ptr + VOICE_PITCH_SHIFT); /* Q4.12 */
|
const uint16_t pitch_shift = *dram_u16(hle, voice_ptr + VOICE_PITCH_SHIFT); /* Q4.12 */
|
||||||
|
|
||||||
const uint16_t end_point = *dram_u16(state, voice_ptr + VOICE_END_POINT);
|
const uint16_t end_point = *dram_u16(hle, voice_ptr + VOICE_END_POINT);
|
||||||
const uint16_t restart_point = *dram_u16(state, voice_ptr + VOICE_RESTART_POINT);
|
const uint16_t restart_point = *dram_u16(hle, voice_ptr + VOICE_RESTART_POINT);
|
||||||
|
|
||||||
const uint16_t u16_4e = *dram_u16(state, voice_ptr + VOICE_U16_4E);
|
const uint16_t u16_4e = *dram_u16(hle, voice_ptr + VOICE_U16_4E);
|
||||||
|
|
||||||
/* init values and pointers */
|
/* init values and pointers */
|
||||||
const int16_t *sample = samples + segbase + offset + u16_4e;
|
const int16_t *sample = samples + segbase + offset + u16_4e;
|
||||||
|
@ -686,27 +700,27 @@ static void mix_voice_samples(usf_state_t* state, musyx_t *musyx, uint32_t voice
|
||||||
int16_t *v4_dst[4];
|
int16_t *v4_dst[4];
|
||||||
int16_t v4[4];
|
int16_t v4[4];
|
||||||
|
|
||||||
dram_load_u32(state, (uint32_t *)v4_env, voice_ptr + VOICE_ENV_BEGIN, 4);
|
dram_load_u32(hle, (uint32_t *)v4_env, voice_ptr + VOICE_ENV_BEGIN, 4);
|
||||||
dram_load_u32(state, (uint32_t *)v4_env_step, voice_ptr + VOICE_ENV_STEP, 4);
|
dram_load_u32(hle, (uint32_t *)v4_env_step, voice_ptr + VOICE_ENV_STEP, 4);
|
||||||
|
|
||||||
v4_dst[0] = musyx->left;
|
v4_dst[0] = musyx->left;
|
||||||
v4_dst[1] = musyx->right;
|
v4_dst[1] = musyx->right;
|
||||||
v4_dst[2] = musyx->cc0;
|
v4_dst[2] = musyx->cc0;
|
||||||
v4_dst[3] = musyx->e50;
|
v4_dst[3] = musyx->e50;
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE,
|
HleVerboseMessage(hle->user_defined,
|
||||||
"Voice debug: segbase=%d"
|
"Voice debug: segbase=%d"
|
||||||
"\tu16_4e=%04x\n"
|
"\tu16_4e=%04x\n"
|
||||||
"\tpitch: frac0=%04x shift=%04x\n"
|
"\tpitch: frac0=%04x shift=%04x\n"
|
||||||
"\tend_point=%04x restart_point=%04x\n"
|
"\tend_point=%04x restart_point=%04x\n"
|
||||||
"\tenv = %08x %08x %08x %08x\n"
|
"\tenv = %08x %08x %08x %08x\n"
|
||||||
"\tenv_step = %08x %08x %08x %08x\n",
|
"\tenv_step = %08x %08x %08x %08x\n",
|
||||||
segbase,
|
segbase,
|
||||||
u16_4e,
|
u16_4e,
|
||||||
pitch_q16, pitch_shift,
|
pitch_q16, pitch_shift,
|
||||||
end_point, restart_point,
|
end_point, restart_point,
|
||||||
v4_env[0], v4_env[1], v4_env[2], v4_env[3],
|
v4_env[0], v4_env[1], v4_env[2], v4_env[3],
|
||||||
v4_env_step[0], v4_env_step[1], v4_env_step[2], v4_env_step[3]);
|
v4_env_step[0], v4_env_step[1], v4_env_step[2], v4_env_step[3]);
|
||||||
|
|
||||||
for (i = 0; i < SUBFRAME_SIZE; ++i) {
|
for (i = 0; i < SUBFRAME_SIZE; ++i) {
|
||||||
/* update sample and lut pointers and then pitch_accu */
|
/* update sample and lut pointers and then pitch_accu */
|
||||||
|
@ -739,14 +753,15 @@ static void mix_voice_samples(usf_state_t* state, musyx_t *musyx, uint32_t voice
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save last resampled sample */
|
/* save last resampled sample */
|
||||||
dram_store_u16(state, (uint16_t *)v4, last_sample_ptr, 4);
|
dram_store_u16(hle, (uint16_t *)v4, last_sample_ptr, 4);
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "last_sample = %04x %04x %04x %04x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
v4[0], v4[1], v4[2], v4[3]);
|
"last_sample = %04x %04x %04x %04x",
|
||||||
|
v4[0], v4[1], v4[2], v4[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void sfx_stage(usf_state_t* state, mix_sfx_with_main_subframes_t mix_sfx_with_main_subframes,
|
static void sfx_stage(struct hle_t* hle, mix_sfx_with_main_subframes_t mix_sfx_with_main_subframes,
|
||||||
musyx_t *musyx, uint32_t sfx_ptr, uint16_t idx)
|
musyx_t *musyx, uint32_t sfx_ptr, uint16_t idx)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -769,44 +784,46 @@ static void sfx_stage(usf_state_t* state, mix_sfx_with_main_subframes_t mix_sfx_
|
||||||
int16_t fir4_hgain;
|
int16_t fir4_hgain;
|
||||||
uint16_t sfx_gains[2];
|
uint16_t sfx_gains[2];
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "SFX: %08x, idx=%d", sfx_ptr, idx);
|
HleVerboseMessage(hle->user_defined, "SFX: %08x, idx=%d", sfx_ptr, idx);
|
||||||
|
|
||||||
if (sfx_ptr == 0)
|
if (sfx_ptr == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* load sfx parameters */
|
/* load sfx parameters */
|
||||||
cbuffer_ptr = *dram_u32(state, sfx_ptr + SFX_CBUFFER_PTR);
|
cbuffer_ptr = *dram_u32(hle, sfx_ptr + SFX_CBUFFER_PTR);
|
||||||
cbuffer_length = *dram_u32(state, sfx_ptr + SFX_CBUFFER_LENGTH);
|
cbuffer_length = *dram_u32(hle, sfx_ptr + SFX_CBUFFER_LENGTH);
|
||||||
|
|
||||||
tap_count = *dram_u16(state, sfx_ptr + SFX_TAP_COUNT);
|
tap_count = *dram_u16(hle, sfx_ptr + SFX_TAP_COUNT);
|
||||||
|
|
||||||
dram_load_u32(state, tap_delays, sfx_ptr + SFX_TAP_DELAYS, 8);
|
dram_load_u32(hle, tap_delays, sfx_ptr + SFX_TAP_DELAYS, 8);
|
||||||
dram_load_u16(state, (uint16_t *)tap_gains, sfx_ptr + SFX_TAP_GAINS, 8);
|
dram_load_u16(hle, (uint16_t *)tap_gains, sfx_ptr + SFX_TAP_GAINS, 8);
|
||||||
|
|
||||||
fir4_hgain = *dram_u16(state, sfx_ptr + SFX_FIR4_HGAIN);
|
fir4_hgain = *dram_u16(hle, sfx_ptr + SFX_FIR4_HGAIN);
|
||||||
dram_load_u16(state, (uint16_t *)fir4_hcoeffs, sfx_ptr + SFX_FIR4_HCOEFFS, 4);
|
dram_load_u16(hle, (uint16_t *)fir4_hcoeffs, sfx_ptr + SFX_FIR4_HCOEFFS, 4);
|
||||||
|
|
||||||
sfx_gains[0] = *dram_u16(state, sfx_ptr + SFX_U16_3C);
|
sfx_gains[0] = *dram_u16(hle, sfx_ptr + SFX_U16_3C);
|
||||||
sfx_gains[1] = *dram_u16(state, sfx_ptr + SFX_U16_3E);
|
sfx_gains[1] = *dram_u16(hle, sfx_ptr + SFX_U16_3E);
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "cbuffer: ptr=%08x length=%x", cbuffer_ptr,
|
HleVerboseMessage(hle->user_defined,
|
||||||
cbuffer_length);
|
"cbuffer: ptr=%08x length=%x", cbuffer_ptr,
|
||||||
|
cbuffer_length);
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "fir4: hgain=%04x hcoeff=%04x %04x %04x %04x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
fir4_hgain, fir4_hcoeffs[0], fir4_hcoeffs[1], fir4_hcoeffs[2],
|
"fir4: hgain=%04x hcoeff=%04x %04x %04x %04x",
|
||||||
fir4_hcoeffs[3]);
|
fir4_hgain,
|
||||||
|
fir4_hcoeffs[0], fir4_hcoeffs[1], fir4_hcoeffs[2], fir4_hcoeffs[3]);
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE,
|
HleVerboseMessage(hle->user_defined,
|
||||||
"tap count=%d\n"
|
"tap count=%d\n"
|
||||||
"delays: %08x %08x %08x %08x %08x %08x %08x %08x\n"
|
"delays: %08x %08x %08x %08x %08x %08x %08x %08x\n"
|
||||||
"gains: %04x %04x %04x %04x %04x %04x %04x %04x",
|
"gains: %04x %04x %04x %04x %04x %04x %04x %04x",
|
||||||
tap_count,
|
tap_count,
|
||||||
tap_delays[0], tap_delays[1], tap_delays[2], tap_delays[3],
|
tap_delays[0], tap_delays[1], tap_delays[2], tap_delays[3],
|
||||||
tap_delays[4], tap_delays[5], tap_delays[6], tap_delays[7],
|
tap_delays[4], tap_delays[5], tap_delays[6], tap_delays[7],
|
||||||
tap_gains[0], tap_gains[1], tap_gains[2], tap_gains[3],
|
tap_gains[0], tap_gains[1], tap_gains[2], tap_gains[3],
|
||||||
tap_gains[4], tap_gains[5], tap_gains[6], tap_gains[7]);
|
tap_gains[4], tap_gains[5], tap_gains[6], tap_gains[7]);
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "sfx_gains=%04x %04x", sfx_gains[0], sfx_gains[1]);
|
HleVerboseMessage(hle->user_defined, "sfx_gains=%04x %04x", sfx_gains[0], sfx_gains[1]);
|
||||||
|
|
||||||
/* mix up to 8 delayed subframes */
|
/* mix up to 8 delayed subframes */
|
||||||
memset(subframe, 0, SUBFRAME_SIZE * sizeof(subframe[0]));
|
memset(subframe, 0, SUBFRAME_SIZE * sizeof(subframe[0]));
|
||||||
|
@ -817,12 +834,12 @@ static void sfx_stage(usf_state_t* state, mix_sfx_with_main_subframes_t mix_sfx_
|
||||||
dpos += cbuffer_length;
|
dpos += cbuffer_length;
|
||||||
dlength = SUBFRAME_SIZE;
|
dlength = SUBFRAME_SIZE;
|
||||||
|
|
||||||
if (dpos + SUBFRAME_SIZE > cbuffer_length) {
|
if ((uint32_t)(dpos + SUBFRAME_SIZE) > cbuffer_length) {
|
||||||
dlength = cbuffer_length - dpos;
|
dlength = cbuffer_length - dpos;
|
||||||
dram_load_u16(state, (uint16_t *)delayed + dlength, cbuffer_ptr, SUBFRAME_SIZE - dlength);
|
dram_load_u16(hle, (uint16_t *)delayed + dlength, cbuffer_ptr, SUBFRAME_SIZE - dlength);
|
||||||
}
|
}
|
||||||
|
|
||||||
dram_load_u16(state, (uint16_t *)delayed, cbuffer_ptr + dpos * 2, dlength);
|
dram_load_u16(hle, (uint16_t *)delayed, cbuffer_ptr + dpos * 2, dlength);
|
||||||
|
|
||||||
mix_subframes(subframe, delayed, tap_gains[i]);
|
mix_subframes(subframe, delayed, tap_gains[i]);
|
||||||
}
|
}
|
||||||
|
@ -834,7 +851,7 @@ static void sfx_stage(usf_state_t* state, mix_sfx_with_main_subframes_t mix_sfx_
|
||||||
memcpy(buffer, musyx->subframe_740_last4, 4 * sizeof(int16_t));
|
memcpy(buffer, musyx->subframe_740_last4, 4 * sizeof(int16_t));
|
||||||
memcpy(musyx->subframe_740_last4, subframe + SUBFRAME_SIZE - 4, 4 * sizeof(int16_t));
|
memcpy(musyx->subframe_740_last4, subframe + SUBFRAME_SIZE - 4, 4 * sizeof(int16_t));
|
||||||
mix_fir4(musyx->e50, buffer + 1, fir4_hgain, fir4_hcoeffs);
|
mix_fir4(musyx->e50, buffer + 1, fir4_hgain, fir4_hcoeffs);
|
||||||
dram_store_u16(state, (uint16_t *)musyx->e50, cbuffer_ptr + pos * 2, SUBFRAME_SIZE);
|
dram_store_u16(hle, (uint16_t *)musyx->e50, cbuffer_ptr + pos * 2, SUBFRAME_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mix_sfx_with_main_subframes_v1(musyx_t *musyx, const int16_t *subframe,
|
static void mix_sfx_with_main_subframes_v1(musyx_t *musyx, const int16_t *subframe,
|
||||||
|
@ -894,7 +911,7 @@ static void mix_fir4(int16_t *y, const int16_t *x, int16_t hgain, const int16_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void interleave_stage_v1(usf_state_t* state, musyx_t *musyx, uint32_t output_ptr)
|
static void interleave_stage_v1(struct hle_t* hle, musyx_t *musyx, uint32_t output_ptr)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
@ -905,14 +922,14 @@ static void interleave_stage_v1(usf_state_t* state, musyx_t *musyx, uint32_t out
|
||||||
int16_t *right;
|
int16_t *right;
|
||||||
uint32_t *dst;
|
uint32_t *dst;
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "interleave: %08x", output_ptr);
|
HleVerboseMessage(hle->user_defined, "interleave: %08x", output_ptr);
|
||||||
|
|
||||||
base_left = clamp_s16(musyx->base_vol[0]);
|
base_left = clamp_s16(musyx->base_vol[0]);
|
||||||
base_right = clamp_s16(musyx->base_vol[1]);
|
base_right = clamp_s16(musyx->base_vol[1]);
|
||||||
|
|
||||||
left = musyx->left;
|
left = musyx->left;
|
||||||
right = musyx->right;
|
right = musyx->right;
|
||||||
dst = dram_u32(state, output_ptr);
|
dst = dram_u32(hle, output_ptr);
|
||||||
|
|
||||||
for (i = 0; i < SUBFRAME_SIZE; ++i) {
|
for (i = 0; i < SUBFRAME_SIZE; ++i) {
|
||||||
uint16_t l = clamp_s16(*(left++) + base_left);
|
uint16_t l = clamp_s16(*(left++) + base_left);
|
||||||
|
@ -922,7 +939,8 @@ static void interleave_stage_v1(usf_state_t* state, musyx_t *musyx, uint32_t out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void interleave_stage_v2(usf_state_t* state, musyx_t *musyx, uint16_t mask_16, uint32_t ptr_18,
|
static void interleave_stage_v2(struct hle_t* hle, musyx_t *musyx,
|
||||||
|
uint16_t mask_16, uint32_t ptr_18,
|
||||||
uint32_t ptr_1c, uint32_t output_ptr)
|
uint32_t ptr_1c, uint32_t output_ptr)
|
||||||
{
|
{
|
||||||
unsigned i, k;
|
unsigned i, k;
|
||||||
|
@ -930,14 +948,15 @@ static void interleave_stage_v2(usf_state_t* state, musyx_t *musyx, uint16_t mas
|
||||||
uint32_t *dst;
|
uint32_t *dst;
|
||||||
uint16_t mask;
|
uint16_t mask;
|
||||||
|
|
||||||
DebugMessage(state, M64MSG_VERBOSE, "mask_16=%04x ptr_18=%08x ptr_1c=%08x output_ptr=%08x",
|
HleVerboseMessage(hle->user_defined,
|
||||||
mask_16, ptr_18, ptr_1c, output_ptr);
|
"mask_16=%04x ptr_18=%08x ptr_1c=%08x output_ptr=%08x",
|
||||||
|
mask_16, ptr_18, ptr_1c, output_ptr);
|
||||||
|
|
||||||
/* compute L_total, R_total and update subframe @ptr_1c */
|
/* compute L_total, R_total and update subframe @ptr_1c */
|
||||||
memset(subframe, 0, SUBFRAME_SIZE*sizeof(subframe[0]));
|
memset(subframe, 0, SUBFRAME_SIZE*sizeof(subframe[0]));
|
||||||
|
|
||||||
for(i = 0; i < SUBFRAME_SIZE; ++i) {
|
for(i = 0; i < SUBFRAME_SIZE; ++i) {
|
||||||
int16_t v = *dram_u16(state, ptr_1c + i*2);
|
int16_t v = *dram_u16(hle, ptr_1c + i*2);
|
||||||
musyx->left[i] = v;
|
musyx->left[i] = v;
|
||||||
musyx->right[i] = clamp_s16(-v);
|
musyx->right[i] = clamp_s16(-v);
|
||||||
}
|
}
|
||||||
|
@ -949,18 +968,18 @@ static void interleave_stage_v2(usf_state_t* state, musyx_t *musyx, uint16_t mas
|
||||||
if ((mask_16 & mask) == 0)
|
if ((mask_16 & mask) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
address = *dram_u32(state, ptr_18);
|
address = *dram_u32(hle, ptr_18);
|
||||||
hgain = *dram_u16(state, ptr_18 + 4);
|
hgain = *dram_u16(hle, ptr_18 + 4);
|
||||||
|
|
||||||
for(i = 0; i < SUBFRAME_SIZE; ++i, address += 2) {
|
for(i = 0; i < SUBFRAME_SIZE; ++i, address += 2) {
|
||||||
mix_samples(&musyx->left[i], *dram_u16(state, address), hgain);
|
mix_samples(&musyx->left[i], *dram_u16(hle, address), hgain);
|
||||||
mix_samples(&musyx->right[i], *dram_u16(state, address + 2*SUBFRAME_SIZE), hgain);
|
mix_samples(&musyx->right[i], *dram_u16(hle, address + 2*SUBFRAME_SIZE), hgain);
|
||||||
mix_samples(&subframe[i], *dram_u16(state, address + 4*SUBFRAME_SIZE), hgain);
|
mix_samples(&subframe[i], *dram_u16(hle, address + 4*SUBFRAME_SIZE), hgain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* interleave L_total and R_total */
|
/* interleave L_total and R_total */
|
||||||
dst = dram_u32(state, output_ptr);
|
dst = dram_u32(hle, output_ptr);
|
||||||
for(i = 0; i < SUBFRAME_SIZE; ++i) {
|
for(i = 0; i < SUBFRAME_SIZE; ++i) {
|
||||||
uint16_t l = musyx->left[i];
|
uint16_t l = musyx->left[i];
|
||||||
uint16_t r = musyx->right[i];
|
uint16_t r = musyx->right[i];
|
||||||
|
@ -968,5 +987,5 @@ static void interleave_stage_v2(usf_state_t* state, musyx_t *musyx, uint16_t mas
|
||||||
}
|
}
|
||||||
|
|
||||||
/* writeback subframe @ptr_1c */
|
/* writeback subframe @ptr_1c */
|
||||||
dram_store_u16(state, (uint16_t*)subframe, ptr_1c, SUBFRAME_SIZE);
|
dram_store_u16(hle, (uint16_t*)subframe, ptr_1c, SUBFRAME_SIZE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,9 @@
|
||||||
#ifndef MUSYX_H
|
#ifndef MUSYX_H
|
||||||
#define MUSYX_H
|
#define MUSYX_H
|
||||||
|
|
||||||
void musyx_v1_task(usf_state_t* state);
|
struct hle_t;
|
||||||
void musyx_v2_task(usf_state_t* state);
|
|
||||||
|
void musyx_v1_task(struct hle_t* hle);
|
||||||
|
void musyx_v2_task(struct hle_t* hle);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
* Mupen64plus-rsp-hle - plugin.h *
|
* Mupen64plus-rsp-hle - alist_internal.h *
|
||||||
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||||
* Copyright (C) 2014 Bobby Smiles *
|
* Copyright (C) 2014 Bobby Smiles *
|
||||||
* *
|
* *
|
||||||
|
@ -19,14 +19,21 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
#ifndef PLUGIN_H
|
#ifndef _MYSTDBOOL_H_
|
||||||
#define PLUGIN_H
|
#define _MYSTDBOOL_H_
|
||||||
|
|
||||||
#define M64MSG_VERBOSE 0
|
#pragma once
|
||||||
#define M64MSG_WARNING 1
|
|
||||||
#define M64MSG_ERROR 2
|
|
||||||
|
|
||||||
void DebugMessage(usf_state_t * state, int level, const char *message, ...);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
typedef unsigned char my_bool;
|
||||||
|
enum { my_b_false = 0 };
|
||||||
|
enum { my_b_true = 1 };
|
||||||
|
|
||||||
|
#undef bool
|
||||||
|
#undef true
|
||||||
|
#undef false
|
||||||
|
|
||||||
|
#define bool my_bool
|
||||||
|
#define true my_b_true
|
||||||
|
#define false my_b_false
|
||||||
|
|
||||||
|
#endif
|
|
@ -26,26 +26,44 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "../usf.h"
|
#include "../usf.h"
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include "plugin.h"
|
|
||||||
|
|
||||||
#include "../main.h"
|
#include "../main.h"
|
||||||
|
|
||||||
#include "../usf_internal.h"
|
#include "../usf_internal.h"
|
||||||
|
|
||||||
/* Global functions */
|
#include "hle.h"
|
||||||
void DebugMessage(usf_state_t* state, int level, const char *message, ...)
|
|
||||||
|
/* Global functions needed by HLE core */
|
||||||
|
void HleVerboseMessage(void* user_defined, const char *message, ...)
|
||||||
{
|
{
|
||||||
char msgbuf[1024];
|
/* discard verbose message */
|
||||||
va_list args;
|
}
|
||||||
|
|
||||||
|
void HleErrorMessage(void* user_defined, const char *message, ...)
|
||||||
|
{
|
||||||
|
usf_state_t* state;
|
||||||
|
va_list ap;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if ( level < M64MSG_WARNING )
|
state = (usf_state_t*)user_defined;
|
||||||
return;
|
len = strlen( state->error_message );
|
||||||
|
|
||||||
|
if ( len )
|
||||||
|
state->error_message[ len++ ] = '\n';
|
||||||
|
|
||||||
|
va_start( ap, message );
|
||||||
|
vsprintf( state->error_message + len, message, ap );
|
||||||
|
va_end( ap );
|
||||||
|
|
||||||
|
state->last_error = state->error_message;
|
||||||
|
StopEmulation( state );
|
||||||
|
}
|
||||||
|
|
||||||
|
void HleWarnMessage(void* user_defined, const char *message, ...)
|
||||||
|
{
|
||||||
|
usf_state_t* state;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
state = (usf_state_t*)user_defined;
|
||||||
len = strlen( state->error_message );
|
len = strlen( state->error_message );
|
||||||
|
|
||||||
if ( len )
|
if ( len )
|
||||||
|
@ -58,3 +76,28 @@ void DebugMessage(usf_state_t* state, int level, const char *message, ...)
|
||||||
state->last_error = state->error_message;
|
state->last_error = state->error_message;
|
||||||
StopEmulation( state );
|
StopEmulation( state );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HleCheckInterrupts(void* user_defined)
|
||||||
|
{
|
||||||
|
CheckInterrupts((usf_state_t*)user_defined);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HleProcessDlistList(void* user_defined)
|
||||||
|
{
|
||||||
|
/* disabled */
|
||||||
|
}
|
||||||
|
|
||||||
|
void HleProcessAlistList(void* user_defined)
|
||||||
|
{
|
||||||
|
/* disabled */
|
||||||
|
}
|
||||||
|
|
||||||
|
void HleProcessRdpList(void* user_defined)
|
||||||
|
{
|
||||||
|
/* disabled */
|
||||||
|
}
|
||||||
|
|
||||||
|
void HleShowCFB(void* user_defined)
|
||||||
|
{
|
||||||
|
/* disabled */
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define _USF_INTERNAL_H_
|
#define _USF_INTERNAL_H_
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
#include "rsp_hle/hle.h"
|
||||||
|
|
||||||
struct usf_state_helper
|
struct usf_state_helper
|
||||||
{
|
{
|
||||||
|
@ -15,21 +16,6 @@ typedef uint32_t RCPREG;
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
// rsp_hle/alist_audio.c
|
|
||||||
enum { DMEM_BASE = 0x5c0 };
|
|
||||||
enum { N_SEGMENTS = 16 };
|
|
||||||
|
|
||||||
// rsp_hle/alist_naudio.c
|
|
||||||
enum { NAUDIO_COUNT = 0x170 }; /* ie 184 samples */
|
|
||||||
enum {
|
|
||||||
NAUDIO_MAIN = 0x4f0,
|
|
||||||
NAUDIO_MAIN2 = 0x660,
|
|
||||||
NAUDIO_DRY_LEFT = 0x9d0,
|
|
||||||
NAUDIO_DRY_RIGHT = 0xb40,
|
|
||||||
NAUDIO_WET_LEFT = 0xcb0,
|
|
||||||
NAUDIO_WET_RIGHT = 0xe20
|
|
||||||
};
|
|
||||||
|
|
||||||
struct usf_state
|
struct usf_state
|
||||||
{
|
{
|
||||||
// RSP vector registers, need to be aligned to 16 bytes
|
// RSP vector registers, need to be aligned to 16 bytes
|
||||||
|
@ -59,14 +45,6 @@ struct usf_state
|
||||||
short comp[8]; /* $vcc: low byte (VEQ, VNE, VLT, VGE, VCL, VCH, VCR) */
|
short comp[8]; /* $vcc: low byte (VEQ, VNE, VLT, VGE, VCL, VCH, VCR) */
|
||||||
short vce[8]; /* $vce: vector compare extension register */
|
short vce[8]; /* $vce: vector compare extension register */
|
||||||
|
|
||||||
// rsp_hle/mp3.c, let's see if aligning this helps anything
|
|
||||||
uint8_t mp3data[0x1000];
|
|
||||||
int32_t mp3_v[32];
|
|
||||||
uint32_t mp3_inPtr, mp3_outPtr;
|
|
||||||
uint32_t mp3_t6;/* = 0x08A0; - I think these are temporary storage buffers */
|
|
||||||
uint32_t mp3_t5;/* = 0x0AC0; */
|
|
||||||
uint32_t mp3_t4;/* = (w1 & 0x1E); */
|
|
||||||
|
|
||||||
// All further members of the structure need not be aligned
|
// All further members of the structure need not be aligned
|
||||||
|
|
||||||
// rsp/vu/divrom.h
|
// rsp/vu/divrom.h
|
||||||
|
@ -83,78 +61,8 @@ struct usf_state
|
||||||
int temp_PC;
|
int temp_PC;
|
||||||
short MFC0_count[32];
|
short MFC0_count[32];
|
||||||
|
|
||||||
// rsp_hle/alist.c
|
// rsp_hle
|
||||||
uint8_t BufferSpace[0x10000];
|
struct hle_t hle;
|
||||||
|
|
||||||
// rsp_hle/alist_audio.c
|
|
||||||
/* alist audio state */
|
|
||||||
struct {
|
|
||||||
/* segments */
|
|
||||||
uint32_t segments[N_SEGMENTS];
|
|
||||||
|
|
||||||
/* main buffers */
|
|
||||||
uint16_t in;
|
|
||||||
uint16_t out;
|
|
||||||
uint16_t count;
|
|
||||||
|
|
||||||
/* auxiliary buffers */
|
|
||||||
uint16_t dry_right;
|
|
||||||
uint16_t wet_left;
|
|
||||||
uint16_t wet_right;
|
|
||||||
|
|
||||||
/* gains */
|
|
||||||
int16_t dry;
|
|
||||||
int16_t wet;
|
|
||||||
|
|
||||||
/* envelopes (0:left, 1:right) */
|
|
||||||
int16_t vol[2];
|
|
||||||
int16_t target[2];
|
|
||||||
int32_t rate[2];
|
|
||||||
|
|
||||||
/* ADPCM loop point address */
|
|
||||||
uint32_t loop;
|
|
||||||
|
|
||||||
/* storage for ADPCM table and polef coefficients */
|
|
||||||
int16_t table[16 * 8];
|
|
||||||
} l_alist_audio;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
/* gains */
|
|
||||||
int16_t dry;
|
|
||||||
int16_t wet;
|
|
||||||
|
|
||||||
/* envelopes (0:left, 1:right) */
|
|
||||||
int16_t vol[2];
|
|
||||||
int16_t target[2];
|
|
||||||
int32_t rate[2];
|
|
||||||
|
|
||||||
/* ADPCM loop point address */
|
|
||||||
uint32_t loop;
|
|
||||||
|
|
||||||
/* storage for ADPCM table and polef coefficients */
|
|
||||||
int16_t table[16 * 8];
|
|
||||||
} l_alist_naudio;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
/* main buffers */
|
|
||||||
uint16_t in;
|
|
||||||
uint16_t out;
|
|
||||||
uint16_t count;
|
|
||||||
|
|
||||||
/* envmixer ramps */
|
|
||||||
uint16_t env_values[3];
|
|
||||||
uint16_t env_steps[3];
|
|
||||||
|
|
||||||
/* ADPCM loop point address */
|
|
||||||
uint32_t loop;
|
|
||||||
|
|
||||||
/* storage for ADPCM table and polef coefficients */
|
|
||||||
int16_t table[16 * 8];
|
|
||||||
|
|
||||||
/* filter audio command state */
|
|
||||||
uint16_t filter_count;
|
|
||||||
uint32_t filter_lut_address[2];
|
|
||||||
} l_alist_nead;
|
|
||||||
|
|
||||||
uint32_t cpu_running, cpu_stopped;
|
uint32_t cpu_running, cpu_stopped;
|
||||||
|
|
||||||
|
|
|
@ -1014,6 +1014,8 @@ static int usf_info(void * context, const char * name, const char * value)
|
||||||
|
|
||||||
usf_clear( state.emu_state );
|
usf_clear( state.emu_state );
|
||||||
|
|
||||||
|
//usf_set_hle_audio( state.emu_state, 1 );
|
||||||
|
|
||||||
emulatorCore = ( uint8_t * ) state.emu_state;
|
emulatorCore = ( uint8_t * ) state.emu_state;
|
||||||
|
|
||||||
if ( psf_load( [currentUrl UTF8String], &source_callbacks, 0x21, usf_loader, &state, usf_info, &state, 1 ) <= 0 )
|
if ( psf_load( [currentUrl UTF8String], &source_callbacks, 0x21, usf_loader, &state, usf_info, &state, 1 ) <= 0 )
|
||||||
|
|
Loading…
Reference in New Issue