Imported lazyusf in its new library form and removed the external app
parent
6985aa3ae6
commit
f086d8c9bf
|
@ -0,0 +1,621 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
83C8B6AB18AF58080071B040 /* audio.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8B65918AF58080071B040 /* audio.c */; };
|
||||
83C8B6AC18AF58080071B040 /* audio.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B65A18AF58080071B040 /* audio.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
83C8B6AD18AF58080071B040 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B65B18AF58080071B040 /* config.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
83C8B6AE18AF58080071B040 /* cpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8B65C18AF58080071B040 /* cpu.c */; };
|
||||
83C8B6AF18AF58080071B040 /* cpu.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B65D18AF58080071B040 /* cpu.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
83C8B6B018AF58080071B040 /* dma.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8B65E18AF58080071B040 /* dma.c */; };
|
||||
83C8B6B118AF58080071B040 /* dma.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B65F18AF58080071B040 /* dma.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
83C8B6B218AF58080071B040 /* exception.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8B66018AF58080071B040 /* exception.c */; };
|
||||
83C8B6B318AF58080071B040 /* exception.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B66118AF58080071B040 /* exception.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
83C8B6B418AF58080071B040 /* interpreter_cpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8B66218AF58080071B040 /* interpreter_cpu.c */; };
|
||||
83C8B6B518AF58080071B040 /* interpreter_cpu.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B66318AF58080071B040 /* interpreter_cpu.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
83C8B6B618AF58080071B040 /* interpreter_ops.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8B66418AF58080071B040 /* interpreter_ops.c */; };
|
||||
83C8B6B718AF58080071B040 /* interpreter_ops.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B66518AF58080071B040 /* interpreter_ops.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
83C8B6B818AF58080071B040 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8B66618AF58080071B040 /* main.c */; };
|
||||
83C8B6B918AF58080071B040 /* main.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B66718AF58080071B040 /* main.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
83C8B6BA18AF58080071B040 /* memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8B66818AF58080071B040 /* memory.c */; };
|
||||
83C8B6BB18AF58080071B040 /* memory.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B66918AF58080071B040 /* memory.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
83C8B6BC18AF58080071B040 /* opcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B66A18AF58080071B040 /* opcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
83C8B6BD18AF58080071B040 /* pif.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8B66B18AF58080071B040 /* pif.c */; };
|
||||
83C8B6BE18AF58080071B040 /* pif.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B66C18AF58080071B040 /* pif.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
83C8B6BF18AF58080071B040 /* registers.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8B66D18AF58080071B040 /* registers.c */; };
|
||||
83C8B6C018AF58080071B040 /* registers.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B66E18AF58080071B040 /* registers.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
83C8B6C118AF58080071B040 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B67018AF58080071B040 /* config.h */; };
|
||||
83C8B6C218AF58080071B040 /* execute.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B67118AF58080071B040 /* execute.h */; };
|
||||
83C8B6C318AF58080071B040 /* rsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8B67218AF58080071B040 /* rsp.c */; };
|
||||
83C8B6C418AF58080071B040 /* rsp.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B67318AF58080071B040 /* rsp.h */; };
|
||||
83C8B6C518AF58080071B040 /* su.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B67418AF58080071B040 /* su.h */; };
|
||||
83C8B6C618AF58080071B040 /* cf.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B67618AF58080071B040 /* cf.h */; };
|
||||
83C8B6C718AF58080071B040 /* clamp.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B67718AF58080071B040 /* clamp.h */; };
|
||||
83C8B6C818AF58080071B040 /* divrom.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B67818AF58080071B040 /* divrom.h */; };
|
||||
83C8B6C918AF58080071B040 /* shuffle.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B67918AF58080071B040 /* shuffle.h */; };
|
||||
83C8B6CA18AF58080071B040 /* vabs.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B67A18AF58080071B040 /* vabs.h */; };
|
||||
83C8B6CB18AF58080071B040 /* vadd.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B67B18AF58080071B040 /* vadd.h */; };
|
||||
83C8B6CC18AF58080071B040 /* vaddc.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B67C18AF58080071B040 /* vaddc.h */; };
|
||||
83C8B6CD18AF58080071B040 /* vand.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B67D18AF58080071B040 /* vand.h */; };
|
||||
83C8B6CE18AF58080071B040 /* vch.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B67E18AF58080071B040 /* vch.h */; };
|
||||
83C8B6CF18AF58080071B040 /* vcl.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B67F18AF58080071B040 /* vcl.h */; };
|
||||
83C8B6D018AF58080071B040 /* vcr.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68018AF58080071B040 /* vcr.h */; };
|
||||
83C8B6D118AF58080071B040 /* veq.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68118AF58080071B040 /* veq.h */; };
|
||||
83C8B6D218AF58080071B040 /* vge.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68218AF58080071B040 /* vge.h */; };
|
||||
83C8B6D318AF58080071B040 /* vlt.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68318AF58080071B040 /* vlt.h */; };
|
||||
83C8B6D418AF58080071B040 /* vmacf.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68418AF58080071B040 /* vmacf.h */; };
|
||||
83C8B6D518AF58080071B040 /* vmacq.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68518AF58080071B040 /* vmacq.h */; };
|
||||
83C8B6D618AF58080071B040 /* vmacu.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68618AF58080071B040 /* vmacu.h */; };
|
||||
83C8B6D718AF58080071B040 /* vmadh.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68718AF58080071B040 /* vmadh.h */; };
|
||||
83C8B6D818AF58080071B040 /* vmadl.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68818AF58080071B040 /* vmadl.h */; };
|
||||
83C8B6D918AF58080071B040 /* vmadm.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68918AF58080071B040 /* vmadm.h */; };
|
||||
83C8B6DA18AF58080071B040 /* vmadn.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68A18AF58080071B040 /* vmadn.h */; };
|
||||
83C8B6DB18AF58080071B040 /* vmov.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68B18AF58080071B040 /* vmov.h */; };
|
||||
83C8B6DC18AF58080071B040 /* vmrg.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68C18AF58080071B040 /* vmrg.h */; };
|
||||
83C8B6DD18AF58080071B040 /* vmudh.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68D18AF58080071B040 /* vmudh.h */; };
|
||||
83C8B6DE18AF58080071B040 /* vmudl.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68E18AF58080071B040 /* vmudl.h */; };
|
||||
83C8B6DF18AF58080071B040 /* vmudm.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B68F18AF58080071B040 /* vmudm.h */; };
|
||||
83C8B6E018AF58080071B040 /* vmudn.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69018AF58080071B040 /* vmudn.h */; };
|
||||
83C8B6E118AF58080071B040 /* vmulf.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69118AF58080071B040 /* vmulf.h */; };
|
||||
83C8B6E218AF58080071B040 /* vmulu.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69218AF58080071B040 /* vmulu.h */; };
|
||||
83C8B6E318AF58080071B040 /* vnand.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69318AF58080071B040 /* vnand.h */; };
|
||||
83C8B6E418AF58080071B040 /* vne.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69418AF58080071B040 /* vne.h */; };
|
||||
83C8B6E518AF58080071B040 /* vnop.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69518AF58080071B040 /* vnop.h */; };
|
||||
83C8B6E618AF58080071B040 /* vnor.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69618AF58080071B040 /* vnor.h */; };
|
||||
83C8B6E718AF58080071B040 /* vnxor.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69718AF58080071B040 /* vnxor.h */; };
|
||||
83C8B6E818AF58080071B040 /* vor.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69818AF58080071B040 /* vor.h */; };
|
||||
83C8B6E918AF58080071B040 /* vrcp.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69918AF58080071B040 /* vrcp.h */; };
|
||||
83C8B6EA18AF58090071B040 /* vrcph.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69A18AF58080071B040 /* vrcph.h */; };
|
||||
83C8B6EB18AF58090071B040 /* vrcpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69B18AF58080071B040 /* vrcpl.h */; };
|
||||
83C8B6EC18AF58090071B040 /* vrsq.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69C18AF58080071B040 /* vrsq.h */; };
|
||||
83C8B6ED18AF58090071B040 /* vrsqh.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69D18AF58080071B040 /* vrsqh.h */; };
|
||||
83C8B6EE18AF58090071B040 /* vrsql.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69E18AF58080071B040 /* vrsql.h */; };
|
||||
83C8B6EF18AF58090071B040 /* vsaw.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B69F18AF58080071B040 /* vsaw.h */; };
|
||||
83C8B6F018AF58090071B040 /* vsub.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B6A018AF58080071B040 /* vsub.h */; };
|
||||
83C8B6F118AF58090071B040 /* vsubc.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B6A118AF58080071B040 /* vsubc.h */; };
|
||||
83C8B6F218AF58090071B040 /* vu.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B6A218AF58080071B040 /* vu.h */; };
|
||||
83C8B6F318AF58090071B040 /* vxor.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B6A318AF58080071B040 /* vxor.h */; };
|
||||
83C8B6F418AF58090071B040 /* rsp.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B6A418AF58080071B040 /* rsp.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
83C8B6F518AF58090071B040 /* tlb.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8B6A518AF58080071B040 /* tlb.c */; };
|
||||
83C8B6F618AF58090071B040 /* tlb.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B6A618AF58080071B040 /* tlb.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
83C8B6F718AF58090071B040 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B6A718AF58080071B040 /* types.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
83C8B6F818AF58090071B040 /* usf_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B6A818AF58080071B040 /* usf_internal.h */; };
|
||||
83C8B6F918AF58090071B040 /* usf.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C8B6A918AF58080071B040 /* usf.c */; };
|
||||
83C8B6FA18AF58090071B040 /* usf.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C8B6AA18AF58080071B040 /* usf.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
83C8B6FE18AF59E70071B040 /* lazyusf-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 83C8B6FD18AF59E70071B040 /* lazyusf-Info.plist */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
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>"; };
|
||||
83C8B65A18AF58080071B040 /* audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audio.h; sourceTree = "<group>"; };
|
||||
83C8B65B18AF58080071B040 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
|
||||
83C8B65C18AF58080071B040 /* cpu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cpu.c; sourceTree = "<group>"; };
|
||||
83C8B65D18AF58080071B040 /* cpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cpu.h; sourceTree = "<group>"; };
|
||||
83C8B65E18AF58080071B040 /* dma.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dma.c; sourceTree = "<group>"; };
|
||||
83C8B65F18AF58080071B040 /* dma.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dma.h; sourceTree = "<group>"; };
|
||||
83C8B66018AF58080071B040 /* exception.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = exception.c; sourceTree = "<group>"; };
|
||||
83C8B66118AF58080071B040 /* exception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = exception.h; sourceTree = "<group>"; };
|
||||
83C8B66218AF58080071B040 /* interpreter_cpu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = interpreter_cpu.c; sourceTree = "<group>"; };
|
||||
83C8B66318AF58080071B040 /* interpreter_cpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = interpreter_cpu.h; sourceTree = "<group>"; };
|
||||
83C8B66418AF58080071B040 /* interpreter_ops.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = interpreter_ops.c; sourceTree = "<group>"; };
|
||||
83C8B66518AF58080071B040 /* interpreter_ops.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = interpreter_ops.h; sourceTree = "<group>"; };
|
||||
83C8B66618AF58080071B040 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
|
||||
83C8B66718AF58080071B040 /* main.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = main.h; sourceTree = "<group>"; };
|
||||
83C8B66818AF58080071B040 /* memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = memory.c; sourceTree = "<group>"; };
|
||||
83C8B66918AF58080071B040 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memory.h; sourceTree = "<group>"; };
|
||||
83C8B66A18AF58080071B040 /* opcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opcode.h; sourceTree = "<group>"; };
|
||||
83C8B66B18AF58080071B040 /* pif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pif.c; sourceTree = "<group>"; };
|
||||
83C8B66C18AF58080071B040 /* pif.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pif.h; sourceTree = "<group>"; };
|
||||
83C8B66D18AF58080071B040 /* registers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = registers.c; sourceTree = "<group>"; };
|
||||
83C8B66E18AF58080071B040 /* registers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = registers.h; sourceTree = "<group>"; };
|
||||
83C8B67018AF58080071B040 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
|
||||
83C8B67118AF58080071B040 /* execute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = execute.h; sourceTree = "<group>"; };
|
||||
83C8B67218AF58080071B040 /* rsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsp.c; sourceTree = "<group>"; };
|
||||
83C8B67318AF58080071B040 /* rsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rsp.h; sourceTree = "<group>"; };
|
||||
83C8B67418AF58080071B040 /* su.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = su.h; sourceTree = "<group>"; };
|
||||
83C8B67618AF58080071B040 /* cf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cf.h; sourceTree = "<group>"; };
|
||||
83C8B67718AF58080071B040 /* clamp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = clamp.h; sourceTree = "<group>"; };
|
||||
83C8B67818AF58080071B040 /* divrom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = divrom.h; sourceTree = "<group>"; };
|
||||
83C8B67918AF58080071B040 /* shuffle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shuffle.h; sourceTree = "<group>"; };
|
||||
83C8B67A18AF58080071B040 /* vabs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vabs.h; sourceTree = "<group>"; };
|
||||
83C8B67B18AF58080071B040 /* vadd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vadd.h; sourceTree = "<group>"; };
|
||||
83C8B67C18AF58080071B040 /* vaddc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vaddc.h; sourceTree = "<group>"; };
|
||||
83C8B67D18AF58080071B040 /* vand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vand.h; sourceTree = "<group>"; };
|
||||
83C8B67E18AF58080071B040 /* vch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vch.h; sourceTree = "<group>"; };
|
||||
83C8B67F18AF58080071B040 /* vcl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vcl.h; sourceTree = "<group>"; };
|
||||
83C8B68018AF58080071B040 /* vcr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vcr.h; sourceTree = "<group>"; };
|
||||
83C8B68118AF58080071B040 /* veq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = veq.h; sourceTree = "<group>"; };
|
||||
83C8B68218AF58080071B040 /* vge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vge.h; sourceTree = "<group>"; };
|
||||
83C8B68318AF58080071B040 /* vlt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vlt.h; sourceTree = "<group>"; };
|
||||
83C8B68418AF58080071B040 /* vmacf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmacf.h; sourceTree = "<group>"; };
|
||||
83C8B68518AF58080071B040 /* vmacq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmacq.h; sourceTree = "<group>"; };
|
||||
83C8B68618AF58080071B040 /* vmacu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmacu.h; sourceTree = "<group>"; };
|
||||
83C8B68718AF58080071B040 /* vmadh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmadh.h; sourceTree = "<group>"; };
|
||||
83C8B68818AF58080071B040 /* vmadl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmadl.h; sourceTree = "<group>"; };
|
||||
83C8B68918AF58080071B040 /* vmadm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmadm.h; sourceTree = "<group>"; };
|
||||
83C8B68A18AF58080071B040 /* vmadn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmadn.h; sourceTree = "<group>"; };
|
||||
83C8B68B18AF58080071B040 /* vmov.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmov.h; sourceTree = "<group>"; };
|
||||
83C8B68C18AF58080071B040 /* vmrg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmrg.h; sourceTree = "<group>"; };
|
||||
83C8B68D18AF58080071B040 /* vmudh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmudh.h; sourceTree = "<group>"; };
|
||||
83C8B68E18AF58080071B040 /* vmudl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmudl.h; sourceTree = "<group>"; };
|
||||
83C8B68F18AF58080071B040 /* vmudm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmudm.h; sourceTree = "<group>"; };
|
||||
83C8B69018AF58080071B040 /* vmudn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmudn.h; sourceTree = "<group>"; };
|
||||
83C8B69118AF58080071B040 /* vmulf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmulf.h; sourceTree = "<group>"; };
|
||||
83C8B69218AF58080071B040 /* vmulu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmulu.h; sourceTree = "<group>"; };
|
||||
83C8B69318AF58080071B040 /* vnand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vnand.h; sourceTree = "<group>"; };
|
||||
83C8B69418AF58080071B040 /* vne.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vne.h; sourceTree = "<group>"; };
|
||||
83C8B69518AF58080071B040 /* vnop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vnop.h; sourceTree = "<group>"; };
|
||||
83C8B69618AF58080071B040 /* vnor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vnor.h; sourceTree = "<group>"; };
|
||||
83C8B69718AF58080071B040 /* vnxor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vnxor.h; sourceTree = "<group>"; };
|
||||
83C8B69818AF58080071B040 /* vor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vor.h; sourceTree = "<group>"; };
|
||||
83C8B69918AF58080071B040 /* vrcp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vrcp.h; sourceTree = "<group>"; };
|
||||
83C8B69A18AF58080071B040 /* vrcph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vrcph.h; sourceTree = "<group>"; };
|
||||
83C8B69B18AF58080071B040 /* vrcpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vrcpl.h; sourceTree = "<group>"; };
|
||||
83C8B69C18AF58080071B040 /* vrsq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vrsq.h; sourceTree = "<group>"; };
|
||||
83C8B69D18AF58080071B040 /* vrsqh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vrsqh.h; sourceTree = "<group>"; };
|
||||
83C8B69E18AF58080071B040 /* vrsql.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vrsql.h; sourceTree = "<group>"; };
|
||||
83C8B69F18AF58080071B040 /* vsaw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vsaw.h; sourceTree = "<group>"; };
|
||||
83C8B6A018AF58080071B040 /* vsub.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vsub.h; sourceTree = "<group>"; };
|
||||
83C8B6A118AF58080071B040 /* vsubc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vsubc.h; sourceTree = "<group>"; };
|
||||
83C8B6A218AF58080071B040 /* vu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vu.h; sourceTree = "<group>"; };
|
||||
83C8B6A318AF58080071B040 /* vxor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vxor.h; sourceTree = "<group>"; };
|
||||
83C8B6A418AF58080071B040 /* rsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rsp.h; sourceTree = "<group>"; };
|
||||
83C8B6A518AF58080071B040 /* tlb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tlb.c; sourceTree = "<group>"; };
|
||||
83C8B6A618AF58080071B040 /* tlb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tlb.h; sourceTree = "<group>"; };
|
||||
83C8B6A718AF58080071B040 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = "<group>"; };
|
||||
83C8B6A818AF58080071B040 /* usf_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = usf_internal.h; sourceTree = "<group>"; };
|
||||
83C8B6A918AF58080071B040 /* usf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = usf.c; sourceTree = "<group>"; };
|
||||
83C8B6AA18AF58080071B040 /* usf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = usf.h; sourceTree = "<group>"; };
|
||||
83C8B6FD18AF59E70071B040 /* lazyusf-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "lazyusf-Info.plist"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
83C8B61E18AF57770071B040 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
83C8B61818AF57770071B040 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
83C8B62B18AF57770071B040 /* lazyusf */,
|
||||
83C8B62418AF57770071B040 /* Frameworks */,
|
||||
83C8B62318AF57770071B040 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83C8B62318AF57770071B040 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
83C8B62218AF57770071B040 /* lazyusf.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83C8B62418AF57770071B040 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
83C8B62718AF57770071B040 /* Other Frameworks */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83C8B62718AF57770071B040 /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
name = "Other Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83C8B62B18AF57770071B040 /* lazyusf */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
83C8B6FD18AF59E70071B040 /* lazyusf-Info.plist */,
|
||||
83C8B65918AF58080071B040 /* audio.c */,
|
||||
83C8B65A18AF58080071B040 /* audio.h */,
|
||||
83C8B65B18AF58080071B040 /* config.h */,
|
||||
83C8B65C18AF58080071B040 /* cpu.c */,
|
||||
83C8B65D18AF58080071B040 /* cpu.h */,
|
||||
83C8B65E18AF58080071B040 /* dma.c */,
|
||||
83C8B65F18AF58080071B040 /* dma.h */,
|
||||
83C8B66018AF58080071B040 /* exception.c */,
|
||||
83C8B66118AF58080071B040 /* exception.h */,
|
||||
83C8B66218AF58080071B040 /* interpreter_cpu.c */,
|
||||
83C8B66318AF58080071B040 /* interpreter_cpu.h */,
|
||||
83C8B66418AF58080071B040 /* interpreter_ops.c */,
|
||||
83C8B66518AF58080071B040 /* interpreter_ops.h */,
|
||||
83C8B66618AF58080071B040 /* main.c */,
|
||||
83C8B66718AF58080071B040 /* main.h */,
|
||||
83C8B66818AF58080071B040 /* memory.c */,
|
||||
83C8B66918AF58080071B040 /* memory.h */,
|
||||
83C8B66A18AF58080071B040 /* opcode.h */,
|
||||
83C8B66B18AF58080071B040 /* pif.c */,
|
||||
83C8B66C18AF58080071B040 /* pif.h */,
|
||||
83C8B66D18AF58080071B040 /* registers.c */,
|
||||
83C8B66E18AF58080071B040 /* registers.h */,
|
||||
83C8B66F18AF58080071B040 /* rsp */,
|
||||
83C8B6A418AF58080071B040 /* rsp.h */,
|
||||
83C8B6A518AF58080071B040 /* tlb.c */,
|
||||
83C8B6A618AF58080071B040 /* tlb.h */,
|
||||
83C8B6A718AF58080071B040 /* types.h */,
|
||||
83C8B6A818AF58080071B040 /* usf_internal.h */,
|
||||
83C8B6A918AF58080071B040 /* usf.c */,
|
||||
83C8B6AA18AF58080071B040 /* usf.h */,
|
||||
83C8B62C18AF57770071B040 /* Supporting Files */,
|
||||
);
|
||||
path = lazyusf;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83C8B62C18AF57770071B040 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83C8B66F18AF58080071B040 /* rsp */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
83C8B67018AF58080071B040 /* config.h */,
|
||||
83C8B67118AF58080071B040 /* execute.h */,
|
||||
83C8B67218AF58080071B040 /* rsp.c */,
|
||||
83C8B67318AF58080071B040 /* rsp.h */,
|
||||
83C8B67418AF58080071B040 /* su.h */,
|
||||
83C8B67518AF58080071B040 /* vu */,
|
||||
);
|
||||
path = rsp;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83C8B67518AF58080071B040 /* vu */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
83C8B67618AF58080071B040 /* cf.h */,
|
||||
83C8B67718AF58080071B040 /* clamp.h */,
|
||||
83C8B67818AF58080071B040 /* divrom.h */,
|
||||
83C8B67918AF58080071B040 /* shuffle.h */,
|
||||
83C8B67A18AF58080071B040 /* vabs.h */,
|
||||
83C8B67B18AF58080071B040 /* vadd.h */,
|
||||
83C8B67C18AF58080071B040 /* vaddc.h */,
|
||||
83C8B67D18AF58080071B040 /* vand.h */,
|
||||
83C8B67E18AF58080071B040 /* vch.h */,
|
||||
83C8B67F18AF58080071B040 /* vcl.h */,
|
||||
83C8B68018AF58080071B040 /* vcr.h */,
|
||||
83C8B68118AF58080071B040 /* veq.h */,
|
||||
83C8B68218AF58080071B040 /* vge.h */,
|
||||
83C8B68318AF58080071B040 /* vlt.h */,
|
||||
83C8B68418AF58080071B040 /* vmacf.h */,
|
||||
83C8B68518AF58080071B040 /* vmacq.h */,
|
||||
83C8B68618AF58080071B040 /* vmacu.h */,
|
||||
83C8B68718AF58080071B040 /* vmadh.h */,
|
||||
83C8B68818AF58080071B040 /* vmadl.h */,
|
||||
83C8B68918AF58080071B040 /* vmadm.h */,
|
||||
83C8B68A18AF58080071B040 /* vmadn.h */,
|
||||
83C8B68B18AF58080071B040 /* vmov.h */,
|
||||
83C8B68C18AF58080071B040 /* vmrg.h */,
|
||||
83C8B68D18AF58080071B040 /* vmudh.h */,
|
||||
83C8B68E18AF58080071B040 /* vmudl.h */,
|
||||
83C8B68F18AF58080071B040 /* vmudm.h */,
|
||||
83C8B69018AF58080071B040 /* vmudn.h */,
|
||||
83C8B69118AF58080071B040 /* vmulf.h */,
|
||||
83C8B69218AF58080071B040 /* vmulu.h */,
|
||||
83C8B69318AF58080071B040 /* vnand.h */,
|
||||
83C8B69418AF58080071B040 /* vne.h */,
|
||||
83C8B69518AF58080071B040 /* vnop.h */,
|
||||
83C8B69618AF58080071B040 /* vnor.h */,
|
||||
83C8B69718AF58080071B040 /* vnxor.h */,
|
||||
83C8B69818AF58080071B040 /* vor.h */,
|
||||
83C8B69918AF58080071B040 /* vrcp.h */,
|
||||
83C8B69A18AF58080071B040 /* vrcph.h */,
|
||||
83C8B69B18AF58080071B040 /* vrcpl.h */,
|
||||
83C8B69C18AF58080071B040 /* vrsq.h */,
|
||||
83C8B69D18AF58080071B040 /* vrsqh.h */,
|
||||
83C8B69E18AF58080071B040 /* vrsql.h */,
|
||||
83C8B69F18AF58080071B040 /* vsaw.h */,
|
||||
83C8B6A018AF58080071B040 /* vsub.h */,
|
||||
83C8B6A118AF58080071B040 /* vsubc.h */,
|
||||
83C8B6A218AF58080071B040 /* vu.h */,
|
||||
83C8B6A318AF58080071B040 /* vxor.h */,
|
||||
);
|
||||
path = vu;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
83C8B61F18AF57770071B040 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
83C8B6FA18AF58090071B040 /* usf.h in Headers */,
|
||||
83C8B6AC18AF58080071B040 /* audio.h in Headers */,
|
||||
83C8B6B118AF58080071B040 /* dma.h in Headers */,
|
||||
83C8B6AD18AF58080071B040 /* config.h in Headers */,
|
||||
83C8B6B518AF58080071B040 /* interpreter_cpu.h in Headers */,
|
||||
83C8B6B918AF58080071B040 /* main.h in Headers */,
|
||||
83C8B6F418AF58090071B040 /* rsp.h in Headers */,
|
||||
83C8B6C018AF58080071B040 /* registers.h in Headers */,
|
||||
83C8B6BE18AF58080071B040 /* pif.h in Headers */,
|
||||
83C8B6F618AF58090071B040 /* tlb.h in Headers */,
|
||||
83C8B6F718AF58090071B040 /* types.h in Headers */,
|
||||
83C8B6BB18AF58080071B040 /* memory.h in Headers */,
|
||||
83C8B6BC18AF58080071B040 /* opcode.h in Headers */,
|
||||
83C8B6B718AF58080071B040 /* interpreter_ops.h in Headers */,
|
||||
83C8B6B318AF58080071B040 /* exception.h in Headers */,
|
||||
83C8B6AF18AF58080071B040 /* cpu.h in Headers */,
|
||||
83C8B6F118AF58090071B040 /* vsubc.h in Headers */,
|
||||
83C8B6F018AF58090071B040 /* vsub.h in Headers */,
|
||||
83C8B6E018AF58080071B040 /* vmudn.h in Headers */,
|
||||
83C8B6EF18AF58090071B040 /* vsaw.h in Headers */,
|
||||
83C8B6C918AF58080071B040 /* shuffle.h in Headers */,
|
||||
83C8B6DD18AF58080071B040 /* vmudh.h in Headers */,
|
||||
83C8B6E118AF58080071B040 /* vmulf.h in Headers */,
|
||||
83C8B6CE18AF58080071B040 /* vch.h in Headers */,
|
||||
83C8B6CB18AF58080071B040 /* vadd.h in Headers */,
|
||||
83C8B6D618AF58080071B040 /* vmacu.h in Headers */,
|
||||
83C8B6C618AF58080071B040 /* cf.h in Headers */,
|
||||
83C8B6E818AF58080071B040 /* vor.h in Headers */,
|
||||
83C8B6D918AF58080071B040 /* vmadm.h in Headers */,
|
||||
83C8B6E318AF58080071B040 /* vnand.h in Headers */,
|
||||
83C8B6D218AF58080071B040 /* vge.h in Headers */,
|
||||
83C8B6C518AF58080071B040 /* su.h in Headers */,
|
||||
83C8B6C218AF58080071B040 /* execute.h in Headers */,
|
||||
83C8B6E518AF58080071B040 /* vnop.h in Headers */,
|
||||
83C8B6E418AF58080071B040 /* vne.h in Headers */,
|
||||
83C8B6D418AF58080071B040 /* vmacf.h in Headers */,
|
||||
83C8B6DC18AF58080071B040 /* vmrg.h in Headers */,
|
||||
83C8B6C718AF58080071B040 /* clamp.h in Headers */,
|
||||
83C8B6D718AF58080071B040 /* vmadh.h in Headers */,
|
||||
83C8B6F318AF58090071B040 /* vxor.h in Headers */,
|
||||
83C8B6EC18AF58090071B040 /* vrsq.h in Headers */,
|
||||
83C8B6D018AF58080071B040 /* vcr.h in Headers */,
|
||||
83C8B6EA18AF58090071B040 /* vrcph.h in Headers */,
|
||||
83C8B6F818AF58090071B040 /* usf_internal.h in Headers */,
|
||||
83C8B6EE18AF58090071B040 /* vrsql.h in Headers */,
|
||||
83C8B6D118AF58080071B040 /* veq.h in Headers */,
|
||||
83C8B6CA18AF58080071B040 /* vabs.h in Headers */,
|
||||
83C8B6DB18AF58080071B040 /* vmov.h in Headers */,
|
||||
83C8B6ED18AF58090071B040 /* vrsqh.h in Headers */,
|
||||
83C8B6E618AF58080071B040 /* vnor.h in Headers */,
|
||||
83C8B6DE18AF58080071B040 /* vmudl.h in Headers */,
|
||||
83C8B6DA18AF58080071B040 /* vmadn.h in Headers */,
|
||||
83C8B6E218AF58080071B040 /* vmulu.h in Headers */,
|
||||
83C8B6CC18AF58080071B040 /* vaddc.h in Headers */,
|
||||
83C8B6D518AF58080071B040 /* vmacq.h in Headers */,
|
||||
83C8B6C418AF58080071B040 /* rsp.h in Headers */,
|
||||
83C8B6E918AF58080071B040 /* vrcp.h in Headers */,
|
||||
83C8B6D318AF58080071B040 /* vlt.h in Headers */,
|
||||
83C8B6C118AF58080071B040 /* config.h in Headers */,
|
||||
83C8B6DF18AF58080071B040 /* vmudm.h in Headers */,
|
||||
83C8B6D818AF58080071B040 /* vmadl.h in Headers */,
|
||||
83C8B6EB18AF58090071B040 /* vrcpl.h in Headers */,
|
||||
83C8B6CD18AF58080071B040 /* vand.h in Headers */,
|
||||
83C8B6CF18AF58080071B040 /* vcl.h in Headers */,
|
||||
83C8B6E718AF58080071B040 /* vnxor.h in Headers */,
|
||||
83C8B6C818AF58080071B040 /* divrom.h in Headers */,
|
||||
83C8B6F218AF58090071B040 /* vu.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
83C8B62118AF57770071B040 /* lazyusf */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 83C8B64A18AF57770071B040 /* Build configuration list for PBXNativeTarget "lazyusf" */;
|
||||
buildPhases = (
|
||||
83C8B61D18AF57770071B040 /* Sources */,
|
||||
83C8B61E18AF57770071B040 /* Frameworks */,
|
||||
83C8B61F18AF57770071B040 /* Headers */,
|
||||
83C8B62018AF57770071B040 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = lazyusf;
|
||||
productName = lazyusf;
|
||||
productReference = 83C8B62218AF57770071B040 /* lazyusf.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
83C8B61918AF57770071B040 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0500;
|
||||
ORGANIZATIONNAME = "Christopher Snowhill";
|
||||
};
|
||||
buildConfigurationList = 83C8B61C18AF57770071B040 /* Build configuration list for PBXProject "lazyusf" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 83C8B61818AF57770071B040;
|
||||
productRefGroup = 83C8B62318AF57770071B040 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
83C8B62118AF57770071B040 /* lazyusf */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
83C8B62018AF57770071B040 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
83C8B6FE18AF59E70071B040 /* lazyusf-Info.plist in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
83C8B61D18AF57770071B040 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
83C8B6F518AF58090071B040 /* tlb.c in Sources */,
|
||||
83C8B6C318AF58080071B040 /* rsp.c in Sources */,
|
||||
83C8B6BD18AF58080071B040 /* pif.c in Sources */,
|
||||
83C8B6B418AF58080071B040 /* interpreter_cpu.c in Sources */,
|
||||
83C8B6B618AF58080071B040 /* interpreter_ops.c in Sources */,
|
||||
83C8B6BA18AF58080071B040 /* memory.c in Sources */,
|
||||
83C8B6B018AF58080071B040 /* dma.c in Sources */,
|
||||
83C8B6AE18AF58080071B040 /* cpu.c in Sources */,
|
||||
83C8B6AB18AF58080071B040 /* audio.c in Sources */,
|
||||
83C8B6B218AF58080071B040 /* exception.c in Sources */,
|
||||
83C8B6BF18AF58080071B040 /* registers.c in Sources */,
|
||||
83C8B6F918AF58090071B040 /* usf.c in Sources */,
|
||||
83C8B6B818AF58080071B040 /* main.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
83C8B64818AF57770071B040 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
83C8B64918AF57770071B040 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
83C8B64B18AF57770071B040 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
ARCH_MIN_SSE2,
|
||||
);
|
||||
INFOPLIST_FILE = "lazyusf/lazyusf-Info.plist";
|
||||
INSTALL_PATH = "@loader_path/../Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
83C8B64C18AF57770071B040 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherit)",
|
||||
ARCH_MIN_SSE2,
|
||||
);
|
||||
INFOPLIST_FILE = "lazyusf/lazyusf-Info.plist";
|
||||
INSTALL_PATH = "@loader_path/../Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
83C8B61C18AF57770071B040 /* Build configuration list for PBXProject "lazyusf" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
83C8B64818AF57770071B040 /* Debug */,
|
||||
83C8B64918AF57770071B040 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
83C8B64A18AF57770071B040 /* Build configuration list for PBXNativeTarget "lazyusf" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
83C8B64B18AF57770071B040 /* Debug */,
|
||||
83C8B64C18AF57770071B040 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 83C8B61918AF57770071B040 /* Project object */;
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
#include "usf.h"
|
||||
#include "memory.h"
|
||||
#include "audio.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "usf_internal.h"
|
||||
|
||||
void AddBuffer(usf_state_t *state, unsigned char *buf, unsigned int length) {
|
||||
int32_t i, do_max;
|
||||
int16_t * sample_buffer = state->sample_buffer;
|
||||
|
||||
if(!state->cpu_running)
|
||||
return;
|
||||
|
||||
do_max = length >> 2;
|
||||
if ( do_max > state->sample_buffer_count )
|
||||
do_max = state->sample_buffer_count;
|
||||
|
||||
for (i = 0; i < do_max; ++i)
|
||||
{
|
||||
*sample_buffer++ = ((int16_t*)buf)[1];
|
||||
*sample_buffer++ = ((int16_t*)buf)[0];
|
||||
buf += 4;
|
||||
}
|
||||
|
||||
state->sample_buffer_count -= do_max;
|
||||
state->sample_buffer = sample_buffer;
|
||||
|
||||
length -= do_max << 2;
|
||||
|
||||
if ( length )
|
||||
{
|
||||
sample_buffer = state->samplebuf;
|
||||
do_max = length >> 2;
|
||||
for (i = 0; i < do_max; ++i)
|
||||
{
|
||||
*sample_buffer++ = ((int16_t*)buf)[1];
|
||||
*sample_buffer++ = ((int16_t*)buf)[0];
|
||||
buf += 4;
|
||||
}
|
||||
|
||||
state->samples_in_buffer = do_max;
|
||||
state->cpu_running = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void AiLenChanged(usf_state_t * state) {
|
||||
int32_t length = 0;
|
||||
uint32_t address = (AI_DRAM_ADDR_REG & 0x00FFFFF8);
|
||||
|
||||
length = AI_LEN_REG & 0x3FFF8;
|
||||
|
||||
AddBuffer(state, state->RDRAM+address, length);
|
||||
|
||||
if(length && !(AI_STATUS_REG&0x80000000)) {
|
||||
const float VSyncTiming = 789000.0f;
|
||||
double BytesPerSecond = 48681812.0 / (AI_DACRATE_REG + 1) * 4;
|
||||
double CountsPerSecond = (double)((((double)VSyncTiming) * (double)60.0)) * 2.0;
|
||||
double CountsPerByte = (double)CountsPerSecond / (double)BytesPerSecond;
|
||||
unsigned int IntScheduled = (unsigned int)((double)AI_LEN_REG * CountsPerByte);
|
||||
|
||||
ChangeTimer(state,AiTimer,IntScheduled);
|
||||
}
|
||||
|
||||
if(state->enableFIFOfull) {
|
||||
if(AI_STATUS_REG&0x40000000)
|
||||
AI_STATUS_REG|=0x80000000;
|
||||
}
|
||||
|
||||
AI_STATUS_REG|=0x40000000;
|
||||
}
|
||||
|
||||
unsigned int AiReadLength(usf_state_t * state) {
|
||||
AI_LEN_REG = 0;
|
||||
return AI_LEN_REG;
|
||||
}
|
||||
|
||||
void AiDacrateChanged(usf_state_t * state, unsigned int value) {
|
||||
AI_DACRATE_REG = value;
|
||||
state->SampleRate = 48681812 / (AI_DACRATE_REG + 1);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef _AUDIO_H_
|
||||
#define _AUDIO_H_
|
||||
|
||||
#include "usf.h"
|
||||
#include "cpu.h"
|
||||
#include "memory.h"
|
||||
|
||||
uint32_t AiReadLength(usf_state_t *);
|
||||
void AiLenChanged(usf_state_t *);
|
||||
void AiDacrateChanged(usf_state_t *, uint32_t value);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,63 @@
|
|||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "lazyusf"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "lazyusf"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "lazyusf 1.0.0"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "lazyusf"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "1.0.0"
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "1.0.0"
|
||||
|
||||
/* Define to 1 if the X Window System is missing or not being used. */
|
||||
/* #undef X_DISPLAY_MISSING */
|
|
@ -0,0 +1,551 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "main.h"
|
||||
#include "cpu.h"
|
||||
#include "usf.h"
|
||||
#include "audio.h"
|
||||
#include "registers.h"
|
||||
#include "rsp.h"
|
||||
|
||||
#include "usf_internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void ChangeCompareTimer(usf_state_t * state) {
|
||||
uint32_t NextCompare = COMPARE_REGISTER - COUNT_REGISTER;
|
||||
if ((NextCompare & 0x80000000) != 0) { NextCompare = 0x7FFFFFFF; }
|
||||
if (NextCompare == 0) { NextCompare = 0x1; }
|
||||
ChangeTimer(state,CompareTimer,NextCompare);
|
||||
}
|
||||
|
||||
void ChangeTimer(usf_state_t * state, int32_t Type, int32_t Value) {
|
||||
if (Value == 0) {
|
||||
state->Timers->NextTimer[Type] = 0;
|
||||
state->Timers->Active[Type] = 0;
|
||||
return;
|
||||
}
|
||||
state->Timers->NextTimer[Type] = Value - state->Timers->Timer;
|
||||
state->Timers->Active[Type] = 1;
|
||||
CheckTimer(state);
|
||||
}
|
||||
|
||||
void CheckTimer (usf_state_t * state) {
|
||||
int32_t count;
|
||||
|
||||
for (count = 0; count < MaxTimers; count++) {
|
||||
if (!state->Timers->Active[count]) { continue; }
|
||||
if (!(count == CompareTimer && state->Timers->NextTimer[count] == 0x7FFFFFFF)) {
|
||||
state->Timers->NextTimer[count] += state->Timers->Timer;
|
||||
}
|
||||
}
|
||||
state->Timers->CurrentTimerType = -1;
|
||||
state->Timers->Timer = 0x7FFFFFFF;
|
||||
for (count = 0; count < MaxTimers; count++) {
|
||||
if (!state->Timers->Active[count]) { continue; }
|
||||
if (state->Timers->NextTimer[count] >= state->Timers->Timer) { continue; }
|
||||
state->Timers->Timer = state->Timers->NextTimer[count];
|
||||
state->Timers->CurrentTimerType = count;
|
||||
}
|
||||
if (state->Timers->CurrentTimerType == -1) {
|
||||
DisplayError("No active timers ???\nEmulation Stoped");
|
||||
StopEmulation(state);
|
||||
}
|
||||
for (count = 0; count < MaxTimers; count++) {
|
||||
if (!state->Timers->Active[count]) { continue; }
|
||||
if (!(count == CompareTimer && state->Timers->NextTimer[count] == 0x7FFFFFFF)) {
|
||||
state->Timers->NextTimer[count] -= state->Timers->Timer;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->Timers->NextTimer[CompareTimer] == 0x7FFFFFFF) {
|
||||
uint32_t NextCompare = COMPARE_REGISTER - COUNT_REGISTER;
|
||||
if ((NextCompare & 0x80000000) == 0 && NextCompare != 0x7FFFFFFF) {
|
||||
ChangeCompareTimer(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CloseCpu (usf_state_t * state) {
|
||||
uint32_t count = 0;
|
||||
|
||||
if(!state->MemChunk) return;
|
||||
if (!state->cpu_running) { return; }
|
||||
|
||||
state->cpu_running = 0;
|
||||
|
||||
for (count = 0; count < 3; count ++ ) {
|
||||
state->CPU_Action->CloseCPU = 1;
|
||||
state->CPU_Action->DoSomething = 1;
|
||||
}
|
||||
|
||||
state->CPURunning = 0;
|
||||
}
|
||||
|
||||
int32_t DelaySlotEffectsCompare (usf_state_t * state, uint32_t PC, uint32_t Reg1, uint32_t Reg2) {
|
||||
OPCODE Command;
|
||||
|
||||
if (!r4300i_LW_VAddr(state, PC + 4, (uint32_t*)&Command.Hex)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (Command.op) {
|
||||
case R4300i_SPECIAL:
|
||||
switch (Command.funct) {
|
||||
case R4300i_SPECIAL_SLL:
|
||||
case R4300i_SPECIAL_SRL:
|
||||
case R4300i_SPECIAL_SRA:
|
||||
case R4300i_SPECIAL_SLLV:
|
||||
case R4300i_SPECIAL_SRLV:
|
||||
case R4300i_SPECIAL_SRAV:
|
||||
case R4300i_SPECIAL_MFHI:
|
||||
case R4300i_SPECIAL_MTHI:
|
||||
case R4300i_SPECIAL_MFLO:
|
||||
case R4300i_SPECIAL_MTLO:
|
||||
case R4300i_SPECIAL_DSLLV:
|
||||
case R4300i_SPECIAL_DSRLV:
|
||||
case R4300i_SPECIAL_DSRAV:
|
||||
case R4300i_SPECIAL_ADD:
|
||||
case R4300i_SPECIAL_ADDU:
|
||||
case R4300i_SPECIAL_SUB:
|
||||
case R4300i_SPECIAL_SUBU:
|
||||
case R4300i_SPECIAL_AND:
|
||||
case R4300i_SPECIAL_OR:
|
||||
case R4300i_SPECIAL_XOR:
|
||||
case R4300i_SPECIAL_NOR:
|
||||
case R4300i_SPECIAL_SLT:
|
||||
case R4300i_SPECIAL_SLTU:
|
||||
case R4300i_SPECIAL_DADD:
|
||||
case R4300i_SPECIAL_DADDU:
|
||||
case R4300i_SPECIAL_DSUB:
|
||||
case R4300i_SPECIAL_DSUBU:
|
||||
case R4300i_SPECIAL_DSLL:
|
||||
case R4300i_SPECIAL_DSRL:
|
||||
case R4300i_SPECIAL_DSRA:
|
||||
case R4300i_SPECIAL_DSLL32:
|
||||
case R4300i_SPECIAL_DSRL32:
|
||||
case R4300i_SPECIAL_DSRA32:
|
||||
if (Command.rd == 0) { return 0; }
|
||||
if (Command.rd == Reg1) { return 1; }
|
||||
if (Command.rd == Reg2) { return 1; }
|
||||
break;
|
||||
case R4300i_SPECIAL_MULT:
|
||||
case R4300i_SPECIAL_MULTU:
|
||||
case R4300i_SPECIAL_DIV:
|
||||
case R4300i_SPECIAL_DIVU:
|
||||
case R4300i_SPECIAL_DMULT:
|
||||
case R4300i_SPECIAL_DMULTU:
|
||||
case R4300i_SPECIAL_DDIV:
|
||||
case R4300i_SPECIAL_DDIVU:
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case R4300i_CP0:
|
||||
switch (Command.rs) {
|
||||
case R4300i_COP0_MT: break;
|
||||
case R4300i_COP0_MF:
|
||||
if (Command.rt == 0) { return 0; }
|
||||
if (Command.rt == Reg1) { return 1; }
|
||||
if (Command.rt == Reg2) { return 1; }
|
||||
break;
|
||||
default:
|
||||
if ( (Command.rs & 0x10 ) != 0 ) {
|
||||
switch( state->Opcode.funct ) {
|
||||
case R4300i_COP0_CO_TLBR: break;
|
||||
case R4300i_COP0_CO_TLBWI: break;
|
||||
case R4300i_COP0_CO_TLBWR: break;
|
||||
case R4300i_COP0_CO_TLBP: break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case R4300i_CP1:
|
||||
switch (Command.fmt) {
|
||||
case R4300i_COP1_MF:
|
||||
if (Command.rt == 0) { return 0; }
|
||||
if (Command.rt == Reg1) { return 1; }
|
||||
if (Command.rt == Reg2) { return 1; }
|
||||
break;
|
||||
case R4300i_COP1_CF: break;
|
||||
case R4300i_COP1_MT: break;
|
||||
case R4300i_COP1_CT: break;
|
||||
case R4300i_COP1_S: break;
|
||||
case R4300i_COP1_D: break;
|
||||
case R4300i_COP1_W: break;
|
||||
case R4300i_COP1_L: break;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case R4300i_ANDI:
|
||||
case R4300i_ORI:
|
||||
case R4300i_XORI:
|
||||
case R4300i_LUI:
|
||||
case R4300i_ADDI:
|
||||
case R4300i_ADDIU:
|
||||
case R4300i_SLTI:
|
||||
case R4300i_SLTIU:
|
||||
case R4300i_DADDI:
|
||||
case R4300i_DADDIU:
|
||||
case R4300i_LB:
|
||||
case R4300i_LH:
|
||||
case R4300i_LW:
|
||||
case R4300i_LWL:
|
||||
case R4300i_LWR:
|
||||
case R4300i_LDL:
|
||||
case R4300i_LDR:
|
||||
case R4300i_LBU:
|
||||
case R4300i_LHU:
|
||||
case R4300i_LD:
|
||||
case R4300i_LWC1:
|
||||
case R4300i_LDC1:
|
||||
if (Command.rt == 0) { return 0; }
|
||||
if (Command.rt == Reg1) { return 1; }
|
||||
if (Command.rt == Reg2) { return 1; }
|
||||
break;
|
||||
case R4300i_CACHE: break;
|
||||
case R4300i_SB: break;
|
||||
case R4300i_SH: break;
|
||||
case R4300i_SW: break;
|
||||
case R4300i_SWR: break;
|
||||
case R4300i_SWL: break;
|
||||
case R4300i_SWC1: break;
|
||||
case R4300i_SDC1: break;
|
||||
case R4300i_SD: break;
|
||||
default:
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t DelaySlotEffectsJump (usf_state_t * state, uint32_t JumpPC) {
|
||||
OPCODE Command;
|
||||
|
||||
if (!r4300i_LW_VAddr(state, JumpPC, &Command.Hex)) { return 1; }
|
||||
|
||||
switch (Command.op) {
|
||||
case R4300i_SPECIAL:
|
||||
switch (Command.funct) {
|
||||
case R4300i_SPECIAL_JR: return DelaySlotEffectsCompare(state,JumpPC,Command.rs,0);
|
||||
case R4300i_SPECIAL_JALR: return DelaySlotEffectsCompare(state,JumpPC,Command.rs,31);
|
||||
}
|
||||
break;
|
||||
case R4300i_REGIMM:
|
||||
switch (Command.rt) {
|
||||
case R4300i_REGIMM_BLTZ:
|
||||
case R4300i_REGIMM_BGEZ:
|
||||
case R4300i_REGIMM_BLTZL:
|
||||
case R4300i_REGIMM_BGEZL:
|
||||
case R4300i_REGIMM_BLTZAL:
|
||||
case R4300i_REGIMM_BGEZAL:
|
||||
return DelaySlotEffectsCompare(state,JumpPC,Command.rs,0);
|
||||
}
|
||||
break;
|
||||
case R4300i_JAL:
|
||||
case R4300i_SPECIAL_JALR: return DelaySlotEffectsCompare(state,JumpPC,31,0); break;
|
||||
case R4300i_J: return 0;
|
||||
case R4300i_BEQ:
|
||||
case R4300i_BNE:
|
||||
case R4300i_BLEZ:
|
||||
case R4300i_BGTZ:
|
||||
return DelaySlotEffectsCompare(state,JumpPC,Command.rs,Command.rt);
|
||||
case R4300i_CP1:
|
||||
switch (Command.fmt) {
|
||||
case R4300i_COP1_BC:
|
||||
switch (Command.ft) {
|
||||
case R4300i_COP1_BC_BCF:
|
||||
case R4300i_COP1_BC_BCT:
|
||||
case R4300i_COP1_BC_BCFL:
|
||||
case R4300i_COP1_BC_BCTL:
|
||||
{
|
||||
int32_t EffectDelaySlot;
|
||||
OPCODE NewCommand;
|
||||
|
||||
if (!r4300i_LW_VAddr(state, JumpPC + 4, &NewCommand.Hex)) { return 1; }
|
||||
|
||||
EffectDelaySlot = 0;
|
||||
if (NewCommand.op == R4300i_CP1) {
|
||||
if (NewCommand.fmt == R4300i_COP1_S && (NewCommand.funct & 0x30) == 0x30 ) {
|
||||
EffectDelaySlot = 1;
|
||||
}
|
||||
if (NewCommand.fmt == R4300i_COP1_D && (NewCommand.funct & 0x30) == 0x30 ) {
|
||||
EffectDelaySlot = 1;
|
||||
}
|
||||
}
|
||||
return EffectDelaySlot;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case R4300i_BEQL:
|
||||
case R4300i_BNEL:
|
||||
case R4300i_BLEZL:
|
||||
case R4300i_BGTZL:
|
||||
return DelaySlotEffectsCompare(state,JumpPC,Command.rs,Command.rt);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void DoSomething ( usf_state_t * state ) {
|
||||
if (state->CPU_Action->CloseCPU) {
|
||||
//StopEmulation();
|
||||
state->cpu_running = 0;
|
||||
//printf("Stopping?\n");
|
||||
}
|
||||
if (state->CPU_Action->CheckInterrupts) {
|
||||
state->CPU_Action->CheckInterrupts = 0;
|
||||
CheckInterrupts(state);
|
||||
}
|
||||
if (state->CPU_Action->DoInterrupt) {
|
||||
state->CPU_Action->DoInterrupt = 0;
|
||||
DoIntrException(state, 0);
|
||||
}
|
||||
|
||||
|
||||
state->CPU_Action->DoSomething = 0;
|
||||
|
||||
if (state->CPU_Action->DoInterrupt) { state->CPU_Action->DoSomething = 1; }
|
||||
}
|
||||
|
||||
void InPermLoop ( usf_state_t * state ) {
|
||||
// *** Changed ***/
|
||||
if (state->CPU_Action->DoInterrupt) { return; }
|
||||
|
||||
/* Interrupts enabled */
|
||||
if (( STATUS_REGISTER & STATUS_IE ) == 0 ) { goto InterruptsDisabled; }
|
||||
if (( STATUS_REGISTER & STATUS_EXL ) != 0 ) { goto InterruptsDisabled; }
|
||||
if (( STATUS_REGISTER & STATUS_ERL ) != 0 ) { goto InterruptsDisabled; }
|
||||
if (( STATUS_REGISTER & 0xFF00) == 0) { goto InterruptsDisabled; }
|
||||
|
||||
/* check sound playing */
|
||||
|
||||
/* check RSP running */
|
||||
/* check RDP running */
|
||||
if (state->Timers->Timer >= 0) {
|
||||
COUNT_REGISTER += state->Timers->Timer + 1;
|
||||
state->Timers->Timer = -1;
|
||||
}
|
||||
return;
|
||||
|
||||
InterruptsDisabled:
|
||||
DisplayError("Stuck in Permanent Loop");
|
||||
StopEmulation(state);
|
||||
}
|
||||
|
||||
void ReadFromMem(const void * source, void * target, uint32_t length, uint32_t *offset) {
|
||||
memcpy((uint8_t*)target,((uint8_t*)source)+*offset,length);
|
||||
*offset+=length;
|
||||
}
|
||||
|
||||
|
||||
uint32_t Machine_LoadStateFromRAM(usf_state_t * state, void * savestatespace) {
|
||||
uint8_t LoadHeader[0x40];
|
||||
uint32_t Value, count, SaveRDRAMSize, offset=0;
|
||||
|
||||
ReadFromMem( savestatespace,&Value,sizeof(Value),&offset);
|
||||
if (Value != 0x23D8A6C8) { return 0; }
|
||||
ReadFromMem( savestatespace,&SaveRDRAMSize,sizeof(SaveRDRAMSize),&offset);
|
||||
ReadFromMem( savestatespace,&LoadHeader,0x40,&offset);
|
||||
|
||||
state->Timers->CurrentTimerType = -1;
|
||||
state->Timers->Timer = 0;
|
||||
for (count = 0; count < MaxTimers; count ++) { state->Timers->Active[count] = 0; }
|
||||
|
||||
//fix rdram size
|
||||
if (SaveRDRAMSize != state->RdramSize) {
|
||||
// dothis :)
|
||||
}
|
||||
|
||||
state->RdramSize = SaveRDRAMSize;
|
||||
|
||||
ReadFromMem( savestatespace,&Value,sizeof(Value),&offset);
|
||||
ChangeTimer(state,ViTimer,Value);
|
||||
ReadFromMem( savestatespace,&state->PROGRAM_COUNTER,sizeof(state->PROGRAM_COUNTER),&offset);
|
||||
ReadFromMem( savestatespace,state->GPR,sizeof(int64_t)*32,&offset);
|
||||
ReadFromMem( savestatespace,state->FPR,sizeof(int64_t)*32,&offset);
|
||||
ReadFromMem( savestatespace,state->CP0,sizeof(uint32_t)*32,&offset);
|
||||
ReadFromMem( savestatespace,state->FPCR,sizeof(uint32_t)*32,&offset);
|
||||
ReadFromMem( savestatespace,&state->HI,sizeof(int64_t),&offset);
|
||||
ReadFromMem( savestatespace,&state->LO,sizeof(int64_t),&offset);
|
||||
ReadFromMem( savestatespace,state->RegRDRAM,sizeof(uint32_t)*10,&offset);
|
||||
ReadFromMem( savestatespace,state->RegSP,sizeof(uint32_t)*10,&offset);
|
||||
ReadFromMem( savestatespace,state->RegDPC,sizeof(uint32_t)*10,&offset);
|
||||
ReadFromMem( savestatespace,state->RegMI,sizeof(uint32_t)*4,&offset);
|
||||
ReadFromMem( savestatespace,state->RegVI,sizeof(uint32_t)*14,&offset);
|
||||
ReadFromMem( savestatespace,state->RegAI,sizeof(uint32_t)*6,&offset);
|
||||
ReadFromMem( savestatespace,state->RegPI,sizeof(uint32_t)*13,&offset);
|
||||
ReadFromMem( savestatespace,state->RegRI,sizeof(uint32_t)*8,&offset);
|
||||
ReadFromMem( savestatespace,state->RegSI,sizeof(uint32_t)*4,&offset);
|
||||
ReadFromMem( savestatespace,state->tlb,sizeof(TLB)*32,&offset);
|
||||
ReadFromMem( savestatespace,(uint8_t*)state->PIF_Ram,0x40,&offset);
|
||||
ReadFromMem( savestatespace,state->RDRAM,SaveRDRAMSize,&offset);
|
||||
ReadFromMem( savestatespace,state->DMEM,0x1000,&offset);
|
||||
ReadFromMem( savestatespace,state->IMEM,0x1000,&offset);
|
||||
|
||||
state->CP0[32] = 0;
|
||||
|
||||
SetupTLB(state);
|
||||
ChangeCompareTimer(state);
|
||||
AI_STATUS_REG = 0;
|
||||
AiDacrateChanged(state, AI_DACRATE_REG);
|
||||
|
||||
// StartAiInterrupt(state);
|
||||
|
||||
SetFpuLocations(state); // important if FR=1
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void StartEmulationFromSave ( usf_state_t * state, void * savestate ) {
|
||||
uint32_t count = 0;
|
||||
|
||||
//printf("Starting generic Cpu\n");
|
||||
|
||||
//CloseCpu();
|
||||
memset(state->N64MEM, 0, state->RdramSize);
|
||||
|
||||
memset(state->DMEM, 0, 0x1000);
|
||||
memset(state->IMEM, 0, 0x1000);
|
||||
memset(state->TLB_Map, 0, 0x100000 * sizeof(uintptr_t) + 0x10000);
|
||||
|
||||
memset(state->CPU_Action,0,sizeof(state->CPU_Action));
|
||||
state->WrittenToRom = 0;
|
||||
|
||||
InitilizeTLB(state);
|
||||
|
||||
SetupRegisters(state, state->Registers);
|
||||
|
||||
BuildInterpreter(state);
|
||||
|
||||
state->Timers->CurrentTimerType = -1;
|
||||
state->Timers->Timer = 0;
|
||||
|
||||
for (count = 0; count < MaxTimers; count ++) { state->Timers->Active[count] = 0; }
|
||||
ChangeTimer(state,ViTimer,5000);
|
||||
ChangeCompareTimer(state);
|
||||
state->ViFieldNumber = 0;
|
||||
state->CPURunning = 1;
|
||||
*state->WaitMode = 0;
|
||||
|
||||
init_rsp(state);
|
||||
|
||||
Machine_LoadStateFromRAM(state, savestate);
|
||||
|
||||
state->SampleRate = 48681812 / (AI_DACRATE_REG + 1);
|
||||
|
||||
if(state->enableFIFOfull) {
|
||||
const float VSyncTiming = 789000.0f;
|
||||
double BytesPerSecond = 48681812.0 / (AI_DACRATE_REG + 1) * 4;
|
||||
double CountsPerSecond = (double)(((double)VSyncTiming) * (double)60.0);
|
||||
double CountsPerByte = (double)CountsPerSecond / (double)BytesPerSecond;
|
||||
uint32_t IntScheduled = (uint32_t)((double)AI_LEN_REG * CountsPerByte);
|
||||
|
||||
ChangeTimer(state,AiTimer,IntScheduled);
|
||||
AI_STATUS_REG|=0x40000000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RefreshScreen (usf_state_t * state){
|
||||
ChangeTimer(state, ViTimer, 300000);
|
||||
|
||||
}
|
||||
|
||||
void RunRsp (usf_state_t * state) {
|
||||
if ( ( SP_STATUS_REG & SP_STATUS_HALT ) == 0) {
|
||||
if ( ( SP_STATUS_REG & SP_STATUS_BROKE ) == 0 ) {
|
||||
|
||||
uint32_t Task = *( uint32_t *)(state->DMEM + 0xFC0);
|
||||
|
||||
switch (Task) {
|
||||
case 1: {
|
||||
MI_INTR_REG |= 0x20;
|
||||
|
||||
SP_STATUS_REG |= (0x0203 );
|
||||
if ((SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0 )
|
||||
MI_INTR_REG |= 1;
|
||||
|
||||
CheckInterrupts(state);
|
||||
|
||||
DPC_STATUS_REG &= ~0x0002;
|
||||
return;
|
||||
|
||||
}
|
||||
break;
|
||||
case 2: {
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
real_run_rsp(state, 100);
|
||||
SP_STATUS_REG |= (0x0203 );
|
||||
if ((SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0 ) {
|
||||
MI_INTR_REG |= 1;
|
||||
CheckInterrupts(state);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimerDone (usf_state_t * state) {
|
||||
switch (state->Timers->CurrentTimerType) {
|
||||
case CompareTimer:
|
||||
if(state->enablecompare)
|
||||
FAKE_CAUSE_REGISTER |= CAUSE_IP7;
|
||||
//CheckInterrupts();
|
||||
ChangeCompareTimer(state);
|
||||
break;
|
||||
case ViTimer:
|
||||
RefreshScreen(state);
|
||||
MI_INTR_REG |= MI_INTR_VI;
|
||||
CheckInterrupts(state);
|
||||
*state->WaitMode=0;
|
||||
break;
|
||||
case AiTimer:
|
||||
ChangeTimer(state,AiTimer,0);
|
||||
AI_STATUS_REG=0;
|
||||
state->AudioIntrReg|=4;
|
||||
//CheckInterrupts(state);
|
||||
break;
|
||||
}
|
||||
CheckTimer(state);
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
#ifndef _CPU_H_
|
||||
#define _CPU_H_
|
||||
|
||||
#include "interpreter_cpu.h"
|
||||
#include "interpreter_ops.h"
|
||||
#include "registers.h"
|
||||
#include "tlb.h"
|
||||
#include "memory.h"
|
||||
#include "dma.h"
|
||||
#include "exception.h"
|
||||
#include "pif.h"
|
||||
#include "opcode.h"
|
||||
#include "usf.h"
|
||||
|
||||
typedef struct {
|
||||
int32_t DoSomething;
|
||||
int32_t CloseCPU;
|
||||
int32_t CheckInterrupts;
|
||||
int32_t DoInterrupt;
|
||||
} CPU_ACTION;
|
||||
|
||||
#define MaxTimers 3
|
||||
#define CompareTimer 0
|
||||
#define ViTimer 1
|
||||
#define AiTimer 2
|
||||
|
||||
typedef struct {
|
||||
int32_t NextTimer[MaxTimers];
|
||||
int32_t Active[MaxTimers];
|
||||
int32_t CurrentTimerType;
|
||||
int32_t Timer;
|
||||
} SYSTEM_TIMERS;
|
||||
|
||||
void ChangeCompareTimer ( usf_state_t * );
|
||||
void ChangeTimer ( usf_state_t *, int32_t Type, int32_t Value );
|
||||
void CheckTimer ( usf_state_t * );
|
||||
void CloseCpu ( usf_state_t * );
|
||||
int32_t DelaySlotEffectsCompare ( usf_state_t *, uint32_t PC, uint32_t Reg1, uint32_t Reg2 );
|
||||
int32_t DelaySlotEffectsJump ( usf_state_t *, uint32_t JumpPC);
|
||||
void DoSomething ( usf_state_t * );
|
||||
void InPermLoop ( usf_state_t * );
|
||||
void InitiliazeCPUFlags ( usf_state_t * );
|
||||
void RefreshScreen ( usf_state_t * );
|
||||
void RunRsp ( usf_state_t * );
|
||||
void StartEmulation ( usf_state_t * );
|
||||
void TimerDone ( usf_state_t * );
|
||||
void RecompileTimerDone ( usf_state_t * );
|
||||
|
||||
#define NORMAL 0
|
||||
#define DO_DELAY_SLOT 1
|
||||
#define DO_END_DELAY_SLOT 2
|
||||
#define DELAY_SLOT 3
|
||||
#define END_DELAY_SLOT 4
|
||||
#define LIKELY_DELAY_SLOT 5
|
||||
#define JUMP 6
|
||||
#define DELAY_SLOT_DONE 7
|
||||
#define LIKELY_DELAY_SLOT_DONE 8
|
||||
#define END_BLOCK 9
|
||||
|
||||
enum SaveType {
|
||||
Auto,
|
||||
Eeprom_4K,
|
||||
Eeprom_16K,
|
||||
Sram,
|
||||
FlashRam
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
#include "main.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include "usf.h"
|
||||
#include "usf_internal.h"
|
||||
|
||||
void PI_DMA_READ (usf_state_t * state) {
|
||||
|
||||
PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
MI_INTR_REG |= MI_INTR_PI;
|
||||
CheckInterrupts(state);
|
||||
return;
|
||||
}
|
||||
|
||||
void PI_DMA_WRITE (usf_state_t * state) {
|
||||
uint32_t i;
|
||||
PI_STATUS_REG |= PI_STATUS_DMA_BUSY;
|
||||
if ( PI_DRAM_ADDR_REG + PI_WR_LEN_REG + 1 > state->RdramSize) {
|
||||
PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
MI_INTR_REG |= MI_INTR_PI;
|
||||
CheckInterrupts(state);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( PI_CART_ADDR_REG >= 0x08000000 && PI_CART_ADDR_REG <= 0x08010000) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( PI_CART_ADDR_REG >= 0x10000000 && PI_CART_ADDR_REG <= 0x1FBFFFFF) {
|
||||
PI_CART_ADDR_REG -= 0x10000000;
|
||||
for (i = 0; i < PI_WR_LEN_REG + 1; i ++) {
|
||||
*(state->N64MEM+((PI_DRAM_ADDR_REG + i) ^ 3)) = *PageROM(state, (PI_CART_ADDR_REG + i) ^ 3);
|
||||
}
|
||||
PI_CART_ADDR_REG += 0x10000000;
|
||||
|
||||
PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
MI_INTR_REG |= MI_INTR_PI;
|
||||
CheckInterrupts(state);
|
||||
CheckTimer(state);
|
||||
return;
|
||||
}
|
||||
|
||||
PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
MI_INTR_REG |= MI_INTR_PI;
|
||||
CheckInterrupts(state);
|
||||
}
|
||||
|
||||
|
||||
void SI_DMA_READ (usf_state_t * state) {
|
||||
|
||||
if ((int32_t)SI_DRAM_ADDR_REG > (int32_t)state->RdramSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
PifRamRead(state);
|
||||
SI_DRAM_ADDR_REG &= 0xFFFFFFF8;
|
||||
if ((int32_t)SI_DRAM_ADDR_REG < 0) {
|
||||
int32_t count, RdramPos;
|
||||
|
||||
RdramPos = (int32_t)SI_DRAM_ADDR_REG;
|
||||
for (count = 0; count < 0x40; count++, RdramPos++) {
|
||||
if (RdramPos < 0) { continue; }
|
||||
state->N64MEM[RdramPos ^3] = state->PIF_Ram[count];
|
||||
}
|
||||
} else {
|
||||
int32_t count, RdramPos;
|
||||
|
||||
RdramPos = (uint32_t)SI_DRAM_ADDR_REG;
|
||||
for (count = 0; count < 0x40; count++, RdramPos++) {
|
||||
if (RdramPos < 0) { continue; }
|
||||
state->N64MEM[RdramPos ^3] = state->PIF_Ram[count];
|
||||
}
|
||||
}
|
||||
|
||||
MI_INTR_REG |= MI_INTR_SI;
|
||||
SI_STATUS_REG |= SI_STATUS_INTERRUPT;
|
||||
CheckInterrupts(state);
|
||||
}
|
||||
|
||||
|
||||
void SI_DMA_WRITE (usf_state_t * state) {
|
||||
|
||||
if ((int32_t)SI_DRAM_ADDR_REG > (int32_t)state->RdramSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
SI_DRAM_ADDR_REG &= 0xFFFFFFF8;
|
||||
if ((int32_t)SI_DRAM_ADDR_REG < 0) {
|
||||
int32_t count, RdramPos;
|
||||
|
||||
RdramPos = (int32_t)SI_DRAM_ADDR_REG;
|
||||
for (count = 0; count < 0x40; count++, RdramPos++) {
|
||||
if (RdramPos < 0) { state->PIF_Ram[count] = 0; continue; }
|
||||
state->PIF_Ram[count] = state->N64MEM[RdramPos ^3];
|
||||
}
|
||||
} else {
|
||||
int32_t count, RdramPos;
|
||||
|
||||
RdramPos = (int32_t)SI_DRAM_ADDR_REG;
|
||||
for (count = 0; count < 0x40; count++, RdramPos++) {
|
||||
if (RdramPos < 0) { state->PIF_Ram[count] = 0; continue; }
|
||||
state->PIF_Ram[count] = state->N64MEM[RdramPos ^3];
|
||||
}
|
||||
}
|
||||
|
||||
PifRamWrite(state);
|
||||
|
||||
MI_INTR_REG |= MI_INTR_SI;
|
||||
SI_STATUS_REG |= SI_STATUS_INTERRUPT;
|
||||
CheckInterrupts(state);
|
||||
|
||||
}
|
||||
|
||||
void SP_DMA_READ (usf_state_t * state) {
|
||||
SP_DRAM_ADDR_REG &= 0x1FFFFFFF;
|
||||
|
||||
if (SP_DRAM_ADDR_REG > state->RdramSize) {
|
||||
SP_DMA_BUSY_REG = 0;
|
||||
SP_STATUS_REG &= ~SP_STATUS_DMA_BUSY;
|
||||
return;
|
||||
}
|
||||
|
||||
if (SP_RD_LEN_REG + 1 + (SP_MEM_ADDR_REG & 0xFFF) > 0x1000) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy( state->DMEM + (SP_MEM_ADDR_REG & 0x1FFF), state->N64MEM + SP_DRAM_ADDR_REG,
|
||||
SP_RD_LEN_REG + 1 );
|
||||
|
||||
SP_DMA_BUSY_REG = 0;
|
||||
SP_STATUS_REG &= ~SP_STATUS_DMA_BUSY;
|
||||
MI_INTR_REG &= ~MI_INTR_SP;
|
||||
CheckInterrupts(state);
|
||||
CheckTimer(state);
|
||||
}
|
||||
|
||||
void SP_DMA_WRITE (usf_state_t * state) {
|
||||
if (SP_DRAM_ADDR_REG > state->RdramSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (SP_WR_LEN_REG + 1 + (SP_MEM_ADDR_REG & 0xFFF) > 0x1000) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy( state->N64MEM + SP_DRAM_ADDR_REG, state->DMEM + (SP_MEM_ADDR_REG & 0x1FFF),
|
||||
SP_WR_LEN_REG + 1);
|
||||
|
||||
SP_DMA_BUSY_REG = 0;
|
||||
SP_STATUS_REG &= ~SP_STATUS_DMA_BUSY;
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
void PI_DMA_READ ( usf_state_t * );
|
||||
void PI_DMA_WRITE ( usf_state_t * );
|
||||
void SI_DMA_READ ( usf_state_t * );
|
||||
void SI_DMA_WRITE ( usf_state_t * );
|
||||
void SP_DMA_READ ( usf_state_t * );
|
||||
void SP_DMA_WRITE ( usf_state_t * );
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include "usf_internal.h"
|
||||
|
||||
void CheckInterrupts ( usf_state_t * state ) {
|
||||
|
||||
MI_INTR_REG &= ~MI_INTR_AI;
|
||||
MI_INTR_REG |= (state->AudioIntrReg & MI_INTR_AI);
|
||||
if ((MI_INTR_MASK_REG & MI_INTR_REG) != 0) {
|
||||
FAKE_CAUSE_REGISTER |= CAUSE_IP2;
|
||||
} else {
|
||||
FAKE_CAUSE_REGISTER &= ~CAUSE_IP2;
|
||||
}
|
||||
|
||||
if (( STATUS_REGISTER & STATUS_IE ) == 0 ) { return; }
|
||||
if (( STATUS_REGISTER & STATUS_EXL ) != 0 ) { return; }
|
||||
if (( STATUS_REGISTER & STATUS_ERL ) != 0 ) { return; }
|
||||
|
||||
if (( STATUS_REGISTER & FAKE_CAUSE_REGISTER & 0xFF00) != 0) {
|
||||
if (!state->CPU_Action->DoInterrupt) {
|
||||
state->CPU_Action->DoSomething = 1;
|
||||
state->CPU_Action->DoInterrupt = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoAddressError ( usf_state_t * state, uint32_t DelaySlot, uint32_t BadVaddr, uint32_t FromRead) {
|
||||
if (FromRead) {
|
||||
CAUSE_REGISTER = EXC_RADE;
|
||||
} else {
|
||||
CAUSE_REGISTER = EXC_WADE;
|
||||
}
|
||||
BAD_VADDR_REGISTER = BadVaddr;
|
||||
if (DelaySlot) {
|
||||
CAUSE_REGISTER |= CAUSE_BD;
|
||||
EPC_REGISTER = state->PROGRAM_COUNTER - 4;
|
||||
} else {
|
||||
EPC_REGISTER = state->PROGRAM_COUNTER;
|
||||
}
|
||||
STATUS_REGISTER |= STATUS_EXL;
|
||||
state->PROGRAM_COUNTER = 0x80000180;
|
||||
}
|
||||
|
||||
void DoBreakException ( usf_state_t * state, uint32_t DelaySlot) {
|
||||
CAUSE_REGISTER = EXC_BREAK;
|
||||
if (DelaySlot) {
|
||||
CAUSE_REGISTER |= CAUSE_BD;
|
||||
EPC_REGISTER = state->PROGRAM_COUNTER - 4;
|
||||
} else {
|
||||
EPC_REGISTER = state->PROGRAM_COUNTER;
|
||||
}
|
||||
STATUS_REGISTER |= STATUS_EXL;
|
||||
state->PROGRAM_COUNTER = 0x80000180;
|
||||
}
|
||||
|
||||
void DoCopUnusableException ( usf_state_t * state, uint32_t DelaySlot, uint32_t Coprocessor ) {
|
||||
CAUSE_REGISTER = EXC_CPU;
|
||||
if (Coprocessor == 1) { CAUSE_REGISTER |= 0x10000000; }
|
||||
if (DelaySlot) {
|
||||
CAUSE_REGISTER |= CAUSE_BD;
|
||||
EPC_REGISTER = state->PROGRAM_COUNTER - 4;
|
||||
} else {
|
||||
EPC_REGISTER = state->PROGRAM_COUNTER;
|
||||
}
|
||||
STATUS_REGISTER |= STATUS_EXL;
|
||||
state->PROGRAM_COUNTER = 0x80000180;
|
||||
}
|
||||
|
||||
void DoIntrException ( usf_state_t * state, uint32_t DelaySlot ) {
|
||||
|
||||
if (( STATUS_REGISTER & STATUS_IE ) == 0 ) { return; }
|
||||
if (( STATUS_REGISTER & STATUS_EXL ) != 0 ) { return; }
|
||||
if (( STATUS_REGISTER & STATUS_ERL ) != 0 ) { return; }
|
||||
CAUSE_REGISTER = FAKE_CAUSE_REGISTER;
|
||||
CAUSE_REGISTER |= EXC_INT;
|
||||
EPC_REGISTER = state->PROGRAM_COUNTER;
|
||||
if (DelaySlot) {
|
||||
CAUSE_REGISTER |= CAUSE_BD;
|
||||
EPC_REGISTER -= 4;
|
||||
}
|
||||
STATUS_REGISTER |= STATUS_EXL;
|
||||
state->PROGRAM_COUNTER = 0x80000180;
|
||||
}
|
||||
|
||||
void DoTLBMiss ( usf_state_t * state, uint32_t DelaySlot, uint32_t BadVaddr ) {
|
||||
|
||||
CAUSE_REGISTER = EXC_RMISS;
|
||||
BAD_VADDR_REGISTER = BadVaddr;
|
||||
CONTEXT_REGISTER &= 0xFF80000F;
|
||||
CONTEXT_REGISTER |= (BadVaddr >> 9) & 0x007FFFF0;
|
||||
ENTRYHI_REGISTER = (BadVaddr & 0xFFFFE000);
|
||||
if ((STATUS_REGISTER & STATUS_EXL) == 0) {
|
||||
if (DelaySlot) {
|
||||
CAUSE_REGISTER |= CAUSE_BD;
|
||||
EPC_REGISTER = state->PROGRAM_COUNTER - 4;
|
||||
} else {
|
||||
EPC_REGISTER = state->PROGRAM_COUNTER;
|
||||
}
|
||||
if (AddressDefined(state, BadVaddr)) {
|
||||
state->PROGRAM_COUNTER = 0x80000180;
|
||||
} else {
|
||||
state->PROGRAM_COUNTER = 0x80000000;
|
||||
}
|
||||
STATUS_REGISTER |= STATUS_EXL;
|
||||
} else {
|
||||
state->PROGRAM_COUNTER = 0x80000180;
|
||||
}
|
||||
}
|
||||
|
||||
void DoSysCallException ( usf_state_t * state, uint32_t DelaySlot) {
|
||||
CAUSE_REGISTER = EXC_SYSCALL;
|
||||
if (DelaySlot) {
|
||||
CAUSE_REGISTER |= CAUSE_BD;
|
||||
EPC_REGISTER = state->PROGRAM_COUNTER - 4;
|
||||
} else {
|
||||
EPC_REGISTER = state->PROGRAM_COUNTER;
|
||||
}
|
||||
STATUS_REGISTER |= STATUS_EXL;
|
||||
state->PROGRAM_COUNTER = 0x80000180;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
#define EXC_CODE(x) ((x)<<2)
|
||||
#define EXC_INT EXC_CODE(0) /* interrupt */
|
||||
#define EXC_MOD EXC_CODE(1) /* TLB mod */
|
||||
#define EXC_RMISS EXC_CODE(2) /* Read TLB Miss */
|
||||
#define EXC_WMISS EXC_CODE(3) /* Write TLB Miss */
|
||||
#define EXC_RADE EXC_CODE(4) /* Read Address Error */
|
||||
#define EXC_WADE EXC_CODE(5) /* Write Address Error */
|
||||
#define EXC_IBE EXC_CODE(6) /* Instruction Bus Error */
|
||||
#define EXC_DBE EXC_CODE(7) /* Data Bus Error */
|
||||
#define EXC_SYSCALL EXC_CODE(8) /* SYSCALL */
|
||||
#define EXC_BREAK EXC_CODE(9) /* BREAKpoint */
|
||||
#define EXC_II EXC_CODE(10)/* Illegal Instruction */
|
||||
#define EXC_CPU EXC_CODE(11)/* CoProcessor Unusable */
|
||||
#define EXC_OV EXC_CODE(12)/* OVerflow */
|
||||
#define EXC_TRAP EXC_CODE(13)/* Trap exception */
|
||||
#define EXC_VCEI EXC_CODE(14)/* Virt. Coherency on Inst. fetch */
|
||||
#define EXC_FPE EXC_CODE(15)/* Floating Point Exception */
|
||||
#define EXC_WATCH EXC_CODE(23)/* Watchpoint reference */
|
||||
#define EXC_VCED EXC_CODE(31)/* Virt. Coherency on data read */
|
||||
|
||||
#define Exception_Name(Except)\
|
||||
(Except) == EXC_INT ? "interrupt" :\
|
||||
(Except) == EXC_MOD ? "TLB mod" :\
|
||||
(Except) == EXC_RMISS ? "Read TLB Miss" :\
|
||||
(Except) == EXC_WMISS ? "Write TLB Miss" :\
|
||||
(Except) == EXC_RADE ? "Read Address Error" :\
|
||||
(Except) == EXC_WADE ? "Write Address Error" :\
|
||||
(Except) == EXC_IBE ? "Instruction Bus Error" :\
|
||||
(Except) == EXC_DBE ? "Data Bus Error" :\
|
||||
(Except) == EXC_SYSCALL ? "SYSCALL" :\
|
||||
(Except) == EXC_BREAK ? "Break" :\
|
||||
(Except) == EXC_II ? "Illegal Instruction" :\
|
||||
(Except) == EXC_CPU ? "CoProcessor Unusable" :\
|
||||
(Except) == EXC_OV ? "OVerflow" :\
|
||||
(Except) == EXC_TRAP ? "Trap exception" :\
|
||||
(Except) == EXC_VCEI ? "Virt. Coherency on Inst. fetch" :\
|
||||
(Except) == EXC_FPE ? "Floating Point Exception" :\
|
||||
(Except) == EXC_WATCH ? "Watchpoint reference" :\
|
||||
(Except) == EXC_VCED ? "Virt. Coherency on data read" :\
|
||||
"Unkown"
|
||||
|
||||
void AiCheckInterrupts ( usf_state_t * );
|
||||
void CheckInterrupts ( usf_state_t * );
|
||||
void DoAddressError ( usf_state_t *, uint32_t DelaySlot, uint32_t BadVaddr, uint32_t FromRead );
|
||||
void DoBreakException ( usf_state_t *, uint32_t DelaySlot );
|
||||
void DoCopUnusableException ( usf_state_t *, uint32_t DelaySlot, uint32_t Coprocessor );
|
||||
void DoIntrException ( usf_state_t *, uint32_t DelaySlot );
|
||||
void DoTLBMiss ( usf_state_t *, uint32_t DelaySlot, uint32_t BadVaddr );
|
||||
void DoSysCallException ( usf_state_t *, uint32_t DelaySlot);
|
||||
|
|
@ -0,0 +1,738 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
#include <float.h>
|
||||
#include "main.h"
|
||||
#include "cpu.h"
|
||||
#include "usf.h"
|
||||
#include "memory.h"
|
||||
|
||||
#include "usf_internal.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void (* R4300i_Opcode[64])(usf_state_t *);
|
||||
void (* R4300i_Special[64])(usf_state_t *);
|
||||
void (* R4300i_Regimm[32])(usf_state_t *);
|
||||
void (* R4300i_CoP0[32])(usf_state_t *);
|
||||
void (* R4300i_CoP0_Function[64])(usf_state_t *);
|
||||
void (* R4300i_CoP1[32])(usf_state_t *);
|
||||
void (* R4300i_CoP1_BC[32])(usf_state_t *);
|
||||
void (* R4300i_CoP1_S[64])(usf_state_t *);
|
||||
void (* R4300i_CoP1_D[64])(usf_state_t *);
|
||||
void (* R4300i_CoP1_W[64])(usf_state_t *);
|
||||
void (* R4300i_CoP1_L[64])(usf_state_t *);
|
||||
|
||||
void R4300i_opcode_SPECIAL (usf_state_t * state) {
|
||||
((void (*)()) R4300i_Special[ state->Opcode.funct ])(state);
|
||||
}
|
||||
|
||||
void R4300i_opcode_REGIMM (usf_state_t * state) {
|
||||
((void (*)()) R4300i_Regimm[ state->Opcode.rt ])(state);
|
||||
}
|
||||
|
||||
void R4300i_opcode_COP0 (usf_state_t * state) {
|
||||
((void (*)()) R4300i_CoP0[ state->Opcode.rs ])(state);
|
||||
}
|
||||
|
||||
void R4300i_opcode_COP0_CO (usf_state_t * state) {
|
||||
((void (*)()) R4300i_CoP0_Function[ state->Opcode.funct ])(state);
|
||||
}
|
||||
|
||||
void R4300i_opcode_COP1 (usf_state_t * state) {
|
||||
((void (*)()) R4300i_CoP1[ state->Opcode.fmt ])(state);
|
||||
}
|
||||
|
||||
void R4300i_opcode_COP1_BC (usf_state_t * state) {
|
||||
((void (*)()) R4300i_CoP1_BC[ state->Opcode.ft ])(state);
|
||||
}
|
||||
|
||||
void R4300i_opcode_COP1_S (usf_state_t * state) {
|
||||
// controlfp(RoundingModel);
|
||||
((void (*)()) R4300i_CoP1_S[ state->Opcode.funct ])(state);
|
||||
}
|
||||
|
||||
void R4300i_opcode_COP1_D (usf_state_t * state) {
|
||||
// controlfp(RoundingModel);
|
||||
((void (*)()) R4300i_CoP1_D[ state->Opcode.funct ])(state);
|
||||
}
|
||||
|
||||
void R4300i_opcode_COP1_W (usf_state_t * state) {
|
||||
((void (*)()) R4300i_CoP1_W[ state->Opcode.funct ])(state);
|
||||
}
|
||||
|
||||
void R4300i_opcode_COP1_L (usf_state_t * state) {
|
||||
((void (*)()) R4300i_CoP1_L[ state->Opcode.funct ])(state);
|
||||
}
|
||||
|
||||
|
||||
void BuildInterpreter (usf_state_t * state) {
|
||||
R4300i_Opcode[ 0] = R4300i_opcode_SPECIAL;
|
||||
R4300i_Opcode[ 1] = R4300i_opcode_REGIMM;
|
||||
R4300i_Opcode[ 2] = r4300i_J;
|
||||
R4300i_Opcode[ 3] = r4300i_JAL;
|
||||
R4300i_Opcode[ 4] = r4300i_BEQ;
|
||||
R4300i_Opcode[ 5] = r4300i_BNE;
|
||||
R4300i_Opcode[ 6] = r4300i_BLEZ;
|
||||
R4300i_Opcode[ 7] = r4300i_BGTZ;
|
||||
R4300i_Opcode[ 8] = r4300i_ADDI;
|
||||
R4300i_Opcode[ 9] = r4300i_ADDIU;
|
||||
R4300i_Opcode[10] = r4300i_SLTI;
|
||||
R4300i_Opcode[11] = r4300i_SLTIU;
|
||||
R4300i_Opcode[12] = r4300i_ANDI;
|
||||
R4300i_Opcode[13] = r4300i_ORI;
|
||||
R4300i_Opcode[14] = r4300i_XORI;
|
||||
R4300i_Opcode[15] = r4300i_LUI;
|
||||
R4300i_Opcode[16] = R4300i_opcode_COP0;
|
||||
R4300i_Opcode[17] = R4300i_opcode_COP1;
|
||||
R4300i_Opcode[18] = R4300i_UnknownOpcode;
|
||||
R4300i_Opcode[19] = R4300i_UnknownOpcode;
|
||||
R4300i_Opcode[20] = r4300i_BEQL;
|
||||
R4300i_Opcode[21] = r4300i_BNEL;
|
||||
R4300i_Opcode[22] = r4300i_BLEZL;
|
||||
R4300i_Opcode[23] = r4300i_BGTZL;
|
||||
R4300i_Opcode[24] = R4300i_UnknownOpcode;
|
||||
R4300i_Opcode[25] = r4300i_DADDIU;
|
||||
R4300i_Opcode[26] = r4300i_LDL;
|
||||
R4300i_Opcode[27] = r4300i_LDR;
|
||||
R4300i_Opcode[28] = R4300i_UnknownOpcode;
|
||||
R4300i_Opcode[29] = R4300i_UnknownOpcode;
|
||||
R4300i_Opcode[30] = R4300i_UnknownOpcode;
|
||||
R4300i_Opcode[31] = R4300i_UnknownOpcode;
|
||||
R4300i_Opcode[32] = r4300i_LB;
|
||||
R4300i_Opcode[33] = r4300i_LH;
|
||||
R4300i_Opcode[34] = r4300i_LWL;
|
||||
R4300i_Opcode[35] = r4300i_LW;
|
||||
R4300i_Opcode[36] = r4300i_LBU;
|
||||
R4300i_Opcode[37] = r4300i_LHU;
|
||||
R4300i_Opcode[38] = r4300i_LWR;
|
||||
R4300i_Opcode[39] = r4300i_LWU;
|
||||
R4300i_Opcode[40] = r4300i_SB;
|
||||
R4300i_Opcode[41] = r4300i_SH;
|
||||
R4300i_Opcode[42] = r4300i_SWL;
|
||||
R4300i_Opcode[43] = r4300i_SW;
|
||||
R4300i_Opcode[44] = r4300i_SDL;
|
||||
R4300i_Opcode[45] = r4300i_SDR;
|
||||
R4300i_Opcode[46] = r4300i_SWR;
|
||||
R4300i_Opcode[47] = r4300i_CACHE;
|
||||
R4300i_Opcode[48] = r4300i_LL;
|
||||
R4300i_Opcode[49] = r4300i_LWC1;
|
||||
R4300i_Opcode[50] = R4300i_UnknownOpcode;
|
||||
R4300i_Opcode[51] = R4300i_UnknownOpcode;
|
||||
R4300i_Opcode[52] = R4300i_UnknownOpcode;
|
||||
R4300i_Opcode[53] = r4300i_LDC1;
|
||||
R4300i_Opcode[54] = R4300i_UnknownOpcode;
|
||||
R4300i_Opcode[55] = r4300i_LD;
|
||||
R4300i_Opcode[56] = r4300i_SC;
|
||||
R4300i_Opcode[57] = r4300i_SWC1;
|
||||
R4300i_Opcode[58] = R4300i_UnknownOpcode;
|
||||
R4300i_Opcode[59] = R4300i_UnknownOpcode;
|
||||
R4300i_Opcode[60] = R4300i_UnknownOpcode;
|
||||
R4300i_Opcode[61] = r4300i_SDC1;
|
||||
R4300i_Opcode[62] = R4300i_UnknownOpcode;
|
||||
R4300i_Opcode[63] = r4300i_SD;
|
||||
|
||||
R4300i_Special[ 0] = r4300i_SPECIAL_SLL;
|
||||
R4300i_Special[ 1] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[ 2] = r4300i_SPECIAL_SRL;
|
||||
R4300i_Special[ 3] = r4300i_SPECIAL_SRA;
|
||||
R4300i_Special[ 4] = r4300i_SPECIAL_SLLV;
|
||||
R4300i_Special[ 5] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[ 6] = r4300i_SPECIAL_SRLV;
|
||||
R4300i_Special[ 7] = r4300i_SPECIAL_SRAV;
|
||||
R4300i_Special[ 8] = r4300i_SPECIAL_JR;
|
||||
R4300i_Special[ 9] = r4300i_SPECIAL_JALR;
|
||||
R4300i_Special[10] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[11] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[12] = r4300i_SPECIAL_SYSCALL;
|
||||
R4300i_Special[13] = r4300i_SPECIAL_BREAK;
|
||||
R4300i_Special[14] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[15] = r4300i_SPECIAL_SYNC;
|
||||
R4300i_Special[16] = r4300i_SPECIAL_MFHI;
|
||||
R4300i_Special[17] = r4300i_SPECIAL_MTHI;
|
||||
R4300i_Special[18] = r4300i_SPECIAL_MFLO;
|
||||
R4300i_Special[19] = r4300i_SPECIAL_MTLO;
|
||||
R4300i_Special[20] = r4300i_SPECIAL_DSLLV;
|
||||
R4300i_Special[21] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[22] = r4300i_SPECIAL_DSRLV;
|
||||
R4300i_Special[23] = r4300i_SPECIAL_DSRAV;
|
||||
R4300i_Special[24] = r4300i_SPECIAL_MULT;
|
||||
R4300i_Special[25] = r4300i_SPECIAL_MULTU;
|
||||
R4300i_Special[26] = r4300i_SPECIAL_DIV;
|
||||
R4300i_Special[27] = r4300i_SPECIAL_DIVU;
|
||||
R4300i_Special[28] = r4300i_SPECIAL_DMULT;
|
||||
R4300i_Special[29] = r4300i_SPECIAL_DMULTU;
|
||||
R4300i_Special[30] = r4300i_SPECIAL_DDIV;
|
||||
R4300i_Special[31] = r4300i_SPECIAL_DDIVU;
|
||||
R4300i_Special[32] = r4300i_SPECIAL_ADD;
|
||||
R4300i_Special[33] = r4300i_SPECIAL_ADDU;
|
||||
R4300i_Special[34] = r4300i_SPECIAL_SUB;
|
||||
R4300i_Special[35] = r4300i_SPECIAL_SUBU;
|
||||
R4300i_Special[36] = r4300i_SPECIAL_AND;
|
||||
R4300i_Special[37] = r4300i_SPECIAL_OR;
|
||||
R4300i_Special[38] = r4300i_SPECIAL_XOR;
|
||||
R4300i_Special[39] = r4300i_SPECIAL_NOR;
|
||||
R4300i_Special[40] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[41] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[42] = r4300i_SPECIAL_SLT;
|
||||
R4300i_Special[43] = r4300i_SPECIAL_SLTU;
|
||||
R4300i_Special[44] = r4300i_SPECIAL_DADD;
|
||||
R4300i_Special[45] = r4300i_SPECIAL_DADDU;
|
||||
R4300i_Special[46] = r4300i_SPECIAL_DSUB;
|
||||
R4300i_Special[47] = r4300i_SPECIAL_DSUBU;
|
||||
R4300i_Special[48] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[49] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[50] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[51] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[52] = r4300i_SPECIAL_TEQ;
|
||||
R4300i_Special[53] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[54] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[55] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[56] = r4300i_SPECIAL_DSLL;
|
||||
R4300i_Special[57] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[58] = r4300i_SPECIAL_DSRL;
|
||||
R4300i_Special[59] = r4300i_SPECIAL_DSRA;
|
||||
R4300i_Special[60] = r4300i_SPECIAL_DSLL32;
|
||||
R4300i_Special[61] = R4300i_UnknownOpcode;
|
||||
R4300i_Special[62] = r4300i_SPECIAL_DSRL32;
|
||||
R4300i_Special[63] = r4300i_SPECIAL_DSRA32;
|
||||
|
||||
R4300i_Regimm[ 0] = r4300i_REGIMM_BLTZ;
|
||||
R4300i_Regimm[ 1] = r4300i_REGIMM_BGEZ;
|
||||
R4300i_Regimm[ 2] = r4300i_REGIMM_BLTZL;
|
||||
R4300i_Regimm[ 3] = r4300i_REGIMM_BGEZL;
|
||||
R4300i_Regimm[ 4] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[ 5] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[ 6] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[ 7] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[ 8] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[ 9] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[10] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[11] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[12] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[13] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[14] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[15] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[16] = r4300i_REGIMM_BLTZAL;
|
||||
R4300i_Regimm[17] = r4300i_REGIMM_BGEZAL;
|
||||
R4300i_Regimm[18] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[19] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[20] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[21] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[22] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[23] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[24] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[25] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[26] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[27] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[28] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[29] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[30] = R4300i_UnknownOpcode;
|
||||
R4300i_Regimm[31] = R4300i_UnknownOpcode;
|
||||
|
||||
R4300i_CoP0[ 0] = r4300i_COP0_MF;
|
||||
R4300i_CoP0[ 1] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0[ 2] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0[ 3] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0[ 4] = r4300i_COP0_MT;
|
||||
R4300i_CoP0[ 5] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0[ 6] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0[ 7] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0[ 8] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0[ 9] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0[10] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0[11] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0[12] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0[13] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0[14] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0[15] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0[16] = R4300i_opcode_COP0_CO;
|
||||
R4300i_CoP0[17] = R4300i_opcode_COP0_CO;
|
||||
R4300i_CoP0[18] = R4300i_opcode_COP0_CO;
|
||||
R4300i_CoP0[19] = R4300i_opcode_COP0_CO;
|
||||
R4300i_CoP0[20] = R4300i_opcode_COP0_CO;
|
||||
R4300i_CoP0[21] = R4300i_opcode_COP0_CO;
|
||||
R4300i_CoP0[22] = R4300i_opcode_COP0_CO;
|
||||
R4300i_CoP0[23] = R4300i_opcode_COP0_CO;
|
||||
R4300i_CoP0[24] = R4300i_opcode_COP0_CO;
|
||||
R4300i_CoP0[25] = R4300i_opcode_COP0_CO;
|
||||
R4300i_CoP0[26] = R4300i_opcode_COP0_CO;
|
||||
R4300i_CoP0[27] = R4300i_opcode_COP0_CO;
|
||||
R4300i_CoP0[28] = R4300i_opcode_COP0_CO;
|
||||
R4300i_CoP0[29] = R4300i_opcode_COP0_CO;
|
||||
R4300i_CoP0[30] = R4300i_opcode_COP0_CO;
|
||||
R4300i_CoP0[31] = R4300i_opcode_COP0_CO;
|
||||
|
||||
R4300i_CoP0_Function[ 0] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[ 1] = r4300i_COP0_CO_TLBR;
|
||||
R4300i_CoP0_Function[ 2] = r4300i_COP0_CO_TLBWI;
|
||||
R4300i_CoP0_Function[ 3] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[ 4] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[ 5] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[ 6] = r4300i_COP0_CO_TLBWR;
|
||||
R4300i_CoP0_Function[ 7] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[ 8] = r4300i_COP0_CO_TLBP;
|
||||
R4300i_CoP0_Function[ 9] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[10] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[11] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[12] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[13] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[14] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[15] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[16] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[17] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[18] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[19] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[20] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[21] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[22] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[23] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[24] = r4300i_COP0_CO_ERET;
|
||||
R4300i_CoP0_Function[25] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[26] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[27] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[28] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[29] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[30] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[31] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[32] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[33] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[34] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[35] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[36] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[37] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[38] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[39] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[40] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[41] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[42] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[43] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[44] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[45] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[46] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[47] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[48] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[49] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[50] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[51] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[52] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[53] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[54] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[55] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[56] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[57] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[58] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[59] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[60] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[61] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[62] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP0_Function[63] = R4300i_UnknownOpcode;
|
||||
|
||||
R4300i_CoP1[ 0] = r4300i_COP1_MF;
|
||||
R4300i_CoP1[ 1] = r4300i_COP1_DMF;
|
||||
R4300i_CoP1[ 2] = r4300i_COP1_CF;
|
||||
R4300i_CoP1[ 3] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[ 4] = r4300i_COP1_MT;
|
||||
R4300i_CoP1[ 5] = r4300i_COP1_DMT;
|
||||
R4300i_CoP1[ 6] = r4300i_COP1_CT;
|
||||
R4300i_CoP1[ 7] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[ 8] = R4300i_opcode_COP1_BC;
|
||||
R4300i_CoP1[ 9] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[10] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[11] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[12] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[13] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[14] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[15] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[16] = R4300i_opcode_COP1_S;
|
||||
R4300i_CoP1[17] = R4300i_opcode_COP1_D;
|
||||
R4300i_CoP1[18] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[19] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[20] = R4300i_opcode_COP1_W;
|
||||
R4300i_CoP1[21] = R4300i_opcode_COP1_L;
|
||||
R4300i_CoP1[22] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[23] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[24] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[25] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[26] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[27] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[28] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[29] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[30] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1[31] = R4300i_UnknownOpcode;
|
||||
|
||||
R4300i_CoP1_BC[ 0] = r4300i_COP1_BCF;
|
||||
R4300i_CoP1_BC[ 1] = r4300i_COP1_BCT;
|
||||
R4300i_CoP1_BC[ 2] = r4300i_COP1_BCFL;
|
||||
R4300i_CoP1_BC[ 3] = r4300i_COP1_BCTL;
|
||||
R4300i_CoP1_BC[ 4] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[ 5] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[ 6] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[ 7] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[ 8] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[ 9] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[10] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[11] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[12] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[13] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[14] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[15] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[16] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[17] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[18] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[19] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[20] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[21] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[22] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[23] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[24] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[25] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[26] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[27] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[28] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[29] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[30] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_BC[31] = R4300i_UnknownOpcode;
|
||||
|
||||
R4300i_CoP1_S[ 0] = r4300i_COP1_S_ADD;
|
||||
R4300i_CoP1_S[ 1] = r4300i_COP1_S_SUB;
|
||||
R4300i_CoP1_S[ 2] = r4300i_COP1_S_MUL;
|
||||
R4300i_CoP1_S[ 3] = r4300i_COP1_S_DIV;
|
||||
R4300i_CoP1_S[ 4] = r4300i_COP1_S_SQRT;
|
||||
R4300i_CoP1_S[ 5] = r4300i_COP1_S_ABS;
|
||||
R4300i_CoP1_S[ 6] = r4300i_COP1_S_MOV;
|
||||
R4300i_CoP1_S[ 7] = r4300i_COP1_S_NEG;
|
||||
R4300i_CoP1_S[ 8] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[ 9] = r4300i_COP1_S_TRUNC_L;
|
||||
R4300i_CoP1_S[10] = r4300i_COP1_S_CEIL_L; //added by Witten
|
||||
R4300i_CoP1_S[11] = r4300i_COP1_S_FLOOR_L; //added by Witten
|
||||
R4300i_CoP1_S[12] = r4300i_COP1_S_ROUND_W;
|
||||
R4300i_CoP1_S[13] = r4300i_COP1_S_TRUNC_W;
|
||||
R4300i_CoP1_S[14] = r4300i_COP1_S_CEIL_W; //added by Witten
|
||||
R4300i_CoP1_S[15] = r4300i_COP1_S_FLOOR_W;
|
||||
R4300i_CoP1_S[16] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[17] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[18] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[19] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[20] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[21] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[22] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[23] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[24] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[25] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[26] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[27] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[28] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[29] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[30] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[31] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[32] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[33] = r4300i_COP1_S_CVT_D;
|
||||
R4300i_CoP1_S[34] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[35] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[36] = r4300i_COP1_S_CVT_W;
|
||||
R4300i_CoP1_S[37] = r4300i_COP1_S_CVT_L;
|
||||
R4300i_CoP1_S[38] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[39] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[40] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[41] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[42] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[43] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[44] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[45] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[46] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[47] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_S[48] = r4300i_COP1_S_CMP;
|
||||
R4300i_CoP1_S[49] = r4300i_COP1_S_CMP;
|
||||
R4300i_CoP1_S[50] = r4300i_COP1_S_CMP;
|
||||
R4300i_CoP1_S[51] = r4300i_COP1_S_CMP;
|
||||
R4300i_CoP1_S[52] = r4300i_COP1_S_CMP;
|
||||
R4300i_CoP1_S[53] = r4300i_COP1_S_CMP;
|
||||
R4300i_CoP1_S[54] = r4300i_COP1_S_CMP;
|
||||
R4300i_CoP1_S[55] = r4300i_COP1_S_CMP;
|
||||
R4300i_CoP1_S[56] = r4300i_COP1_S_CMP;
|
||||
R4300i_CoP1_S[57] = r4300i_COP1_S_CMP;
|
||||
R4300i_CoP1_S[58] = r4300i_COP1_S_CMP;
|
||||
R4300i_CoP1_S[59] = r4300i_COP1_S_CMP;
|
||||
R4300i_CoP1_S[60] = r4300i_COP1_S_CMP;
|
||||
R4300i_CoP1_S[61] = r4300i_COP1_S_CMP;
|
||||
R4300i_CoP1_S[62] = r4300i_COP1_S_CMP;
|
||||
R4300i_CoP1_S[63] = r4300i_COP1_S_CMP;
|
||||
|
||||
R4300i_CoP1_D[ 0] = r4300i_COP1_D_ADD;
|
||||
R4300i_CoP1_D[ 1] = r4300i_COP1_D_SUB;
|
||||
R4300i_CoP1_D[ 2] = r4300i_COP1_D_MUL;
|
||||
R4300i_CoP1_D[ 3] = r4300i_COP1_D_DIV;
|
||||
R4300i_CoP1_D[ 4] = r4300i_COP1_D_SQRT;
|
||||
R4300i_CoP1_D[ 5] = r4300i_COP1_D_ABS;
|
||||
R4300i_CoP1_D[ 6] = r4300i_COP1_D_MOV;
|
||||
R4300i_CoP1_D[ 7] = r4300i_COP1_D_NEG;
|
||||
R4300i_CoP1_D[ 8] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[ 9] = r4300i_COP1_D_TRUNC_L; //added by Witten
|
||||
R4300i_CoP1_D[10] = r4300i_COP1_D_CEIL_L; //added by Witten
|
||||
R4300i_CoP1_D[11] = r4300i_COP1_D_FLOOR_L; //added by Witten
|
||||
R4300i_CoP1_D[12] = r4300i_COP1_D_ROUND_W;
|
||||
R4300i_CoP1_D[13] = r4300i_COP1_D_TRUNC_W;
|
||||
R4300i_CoP1_D[14] = r4300i_COP1_D_CEIL_W; //added by Witten
|
||||
R4300i_CoP1_D[15] = r4300i_COP1_D_FLOOR_W; //added by Witten
|
||||
R4300i_CoP1_D[16] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[17] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[18] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[19] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[20] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[21] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[22] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[23] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[24] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[25] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[26] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[27] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[28] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[29] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[30] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[31] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[32] = r4300i_COP1_D_CVT_S;
|
||||
R4300i_CoP1_D[33] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[34] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[35] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[36] = r4300i_COP1_D_CVT_W;
|
||||
R4300i_CoP1_D[37] = r4300i_COP1_D_CVT_L;
|
||||
R4300i_CoP1_D[38] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[39] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[40] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[41] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[42] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[43] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[44] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[45] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[46] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[47] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_D[48] = r4300i_COP1_D_CMP;
|
||||
R4300i_CoP1_D[49] = r4300i_COP1_D_CMP;
|
||||
R4300i_CoP1_D[50] = r4300i_COP1_D_CMP;
|
||||
R4300i_CoP1_D[51] = r4300i_COP1_D_CMP;
|
||||
R4300i_CoP1_D[52] = r4300i_COP1_D_CMP;
|
||||
R4300i_CoP1_D[53] = r4300i_COP1_D_CMP;
|
||||
R4300i_CoP1_D[54] = r4300i_COP1_D_CMP;
|
||||
R4300i_CoP1_D[55] = r4300i_COP1_D_CMP;
|
||||
R4300i_CoP1_D[56] = r4300i_COP1_D_CMP;
|
||||
R4300i_CoP1_D[57] = r4300i_COP1_D_CMP;
|
||||
R4300i_CoP1_D[58] = r4300i_COP1_D_CMP;
|
||||
R4300i_CoP1_D[59] = r4300i_COP1_D_CMP;
|
||||
R4300i_CoP1_D[60] = r4300i_COP1_D_CMP;
|
||||
R4300i_CoP1_D[61] = r4300i_COP1_D_CMP;
|
||||
R4300i_CoP1_D[62] = r4300i_COP1_D_CMP;
|
||||
R4300i_CoP1_D[63] = r4300i_COP1_D_CMP;
|
||||
|
||||
R4300i_CoP1_W[ 0] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[ 1] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[ 2] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[ 3] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[ 4] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[ 5] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[ 6] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[ 7] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[ 8] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[ 9] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[10] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[11] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[12] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[13] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[14] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[15] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[16] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[17] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[18] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[19] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[20] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[21] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[22] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[23] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[24] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[25] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[26] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[27] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[28] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[29] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[30] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[31] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[32] = r4300i_COP1_W_CVT_S;
|
||||
R4300i_CoP1_W[33] = r4300i_COP1_W_CVT_D;
|
||||
R4300i_CoP1_W[34] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[35] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[36] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[37] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[38] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[39] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[40] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[41] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[42] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[43] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[44] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[45] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[46] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[47] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[48] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[49] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[50] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[51] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[52] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[53] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[54] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[55] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[56] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[57] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[58] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[59] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[60] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[61] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[62] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_W[63] = R4300i_UnknownOpcode;
|
||||
|
||||
R4300i_CoP1_L[ 0] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[ 1] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[ 2] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[ 3] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[ 4] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[ 5] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[ 6] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[ 7] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[ 8] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[ 9] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[10] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[11] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[12] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[13] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[14] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[15] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[16] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[17] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[18] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[19] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[20] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[21] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[22] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[23] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[24] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[25] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[26] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[27] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[28] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[29] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[30] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[31] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[32] = r4300i_COP1_L_CVT_S;
|
||||
R4300i_CoP1_L[33] = r4300i_COP1_L_CVT_D;
|
||||
R4300i_CoP1_L[34] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[35] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[36] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[37] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[38] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[39] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[40] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[41] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[42] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[43] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[44] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[45] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[46] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[47] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[48] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[49] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[50] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[51] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[52] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[53] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[54] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[55] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[56] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[57] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[58] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[59] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[60] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[61] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[62] = R4300i_UnknownOpcode;
|
||||
R4300i_CoP1_L[63] = R4300i_UnknownOpcode;
|
||||
}
|
||||
|
||||
|
||||
void ExecuteInterpreterOpCode (usf_state_t * state) {
|
||||
|
||||
|
||||
if (*state->WaitMode) state->Timers->Timer = -1;
|
||||
|
||||
if (!r4300i_LW_VAddr(state, state->PROGRAM_COUNTER, &state->Opcode.Hex)) {
|
||||
DoTLBMiss(state, state->NextInstruction == JUMP,state->PROGRAM_COUNTER);
|
||||
state->NextInstruction = NORMAL;
|
||||
return;
|
||||
}
|
||||
|
||||
COUNT_REGISTER += 2;
|
||||
state->Timers->Timer -= 2;
|
||||
|
||||
RANDOM_REGISTER -= 1;
|
||||
if ((int32_t)RANDOM_REGISTER < (int32_t)WIRED_REGISTER) {
|
||||
RANDOM_REGISTER = 31;
|
||||
}
|
||||
|
||||
R4300i_Opcode[ state->Opcode.op ](state);
|
||||
|
||||
if (state->GPR[0].DW != 0) {
|
||||
state->GPR[0].DW = 0;
|
||||
}
|
||||
|
||||
switch (state->NextInstruction) {
|
||||
case NORMAL:
|
||||
state->PROGRAM_COUNTER += 4;
|
||||
break;
|
||||
case DELAY_SLOT:
|
||||
state->NextInstruction = JUMP;
|
||||
state->PROGRAM_COUNTER += 4;
|
||||
break;
|
||||
case JUMP:
|
||||
state->PROGRAM_COUNTER = state->JumpToLocation;
|
||||
state->NextInstruction = NORMAL;
|
||||
if ((int32_t)state->Timers->Timer < 0) { TimerDone(state); }
|
||||
if (state->CPU_Action->DoSomething) { DoSomething(state); }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void StartInterpreterCPU (usf_state_t * state) {
|
||||
state->NextInstruction = NORMAL;
|
||||
|
||||
while(state->cpu_running) {
|
||||
ExecuteInterpreterOpCode(state);
|
||||
}
|
||||
|
||||
state->cpu_stopped = 1;
|
||||
|
||||
}
|
||||
|
||||
void TestInterpreterJump (usf_state_t * state, uint32_t PC, uint32_t TargetPC, int32_t Reg1, int32_t Reg2) {
|
||||
if (PC != TargetPC) { return; }
|
||||
if (DelaySlotEffectsCompare(state,PC,Reg1,Reg2)) { return; }
|
||||
InPermLoop(state);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
void BuildInterpreter ( usf_state_t * );
|
||||
void ExecuteInterpreterOpCode ( usf_state_t * );
|
||||
void StartInterpreterCPU ( usf_state_t * );
|
||||
void TestInterpreterJump ( usf_state_t *, uint32_t PC, uint32_t TargetPC, int32_t Reg1, int32_t Reg2 );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern void (* R4300i_Opcode[64])(usf_state_t *);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
/************************* OpCode functions *************************/
|
||||
void r4300i_J ( usf_state_t * );
|
||||
void r4300i_JAL ( usf_state_t * );
|
||||
void r4300i_BNE ( usf_state_t * );
|
||||
void r4300i_BEQ ( usf_state_t * );
|
||||
void r4300i_BLEZ ( usf_state_t * );
|
||||
void r4300i_BGTZ ( usf_state_t * );
|
||||
void r4300i_ADDI ( usf_state_t * );
|
||||
void r4300i_ADDIU ( usf_state_t * );
|
||||
void r4300i_SLTI ( usf_state_t * );
|
||||
void r4300i_SLTIU ( usf_state_t * );
|
||||
void r4300i_ANDI ( usf_state_t * );
|
||||
void r4300i_ORI ( usf_state_t * );
|
||||
void r4300i_XORI ( usf_state_t * );
|
||||
void r4300i_LUI ( usf_state_t * );
|
||||
void r4300i_BEQL ( usf_state_t * );
|
||||
void r4300i_BNEL ( usf_state_t * );
|
||||
void r4300i_BLEZL ( usf_state_t * );
|
||||
void r4300i_BGTZL ( usf_state_t * );
|
||||
void r4300i_DADDIU ( usf_state_t * );
|
||||
void r4300i_LDL ( usf_state_t * );
|
||||
void r4300i_LDR ( usf_state_t * );
|
||||
void r4300i_LB ( usf_state_t * );
|
||||
void r4300i_LH ( usf_state_t * );
|
||||
void r4300i_LWL ( usf_state_t * );
|
||||
void r4300i_LW ( usf_state_t * );
|
||||
void r4300i_LBU ( usf_state_t * );
|
||||
void r4300i_LHU ( usf_state_t * );
|
||||
void r4300i_LWR ( usf_state_t * );
|
||||
void r4300i_LWU ( usf_state_t * );
|
||||
void r4300i_SB ( usf_state_t * );
|
||||
void r4300i_SH ( usf_state_t * );
|
||||
void r4300i_SWL ( usf_state_t * );
|
||||
void r4300i_SW ( usf_state_t * );
|
||||
void r4300i_SDL ( usf_state_t * );
|
||||
void r4300i_SDR ( usf_state_t * );
|
||||
void r4300i_SWR ( usf_state_t * );
|
||||
void r4300i_CACHE ( usf_state_t * );
|
||||
void r4300i_LL ( usf_state_t * );
|
||||
void r4300i_LWC1 ( usf_state_t * );
|
||||
void r4300i_LDC1 ( usf_state_t * );
|
||||
void r4300i_LD ( usf_state_t * );
|
||||
void r4300i_SC ( usf_state_t * );
|
||||
void r4300i_SWC1 ( usf_state_t * );
|
||||
void r4300i_SDC1 ( usf_state_t * );
|
||||
void r4300i_SD ( usf_state_t * );
|
||||
|
||||
/********************** R4300i OpCodes: Special **********************/
|
||||
void r4300i_SPECIAL_SLL ( usf_state_t * );
|
||||
void r4300i_SPECIAL_SRL ( usf_state_t * );
|
||||
void r4300i_SPECIAL_SRA ( usf_state_t * );
|
||||
void r4300i_SPECIAL_SLLV ( usf_state_t * );
|
||||
void r4300i_SPECIAL_SRLV ( usf_state_t * );
|
||||
void r4300i_SPECIAL_SRAV ( usf_state_t * );
|
||||
void r4300i_SPECIAL_JR ( usf_state_t * );
|
||||
void r4300i_SPECIAL_JALR ( usf_state_t * );
|
||||
void r4300i_SPECIAL_SYSCALL ( usf_state_t * );
|
||||
void r4300i_SPECIAL_BREAK ( usf_state_t * );
|
||||
void r4300i_SPECIAL_SYNC ( usf_state_t * );
|
||||
void r4300i_SPECIAL_MFHI ( usf_state_t * );
|
||||
void r4300i_SPECIAL_MTHI ( usf_state_t * );
|
||||
void r4300i_SPECIAL_MFLO ( usf_state_t * );
|
||||
void r4300i_SPECIAL_MTLO ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DSLLV ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DSRLV ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DSRAV ( usf_state_t * );
|
||||
void r4300i_SPECIAL_MULT ( usf_state_t * );
|
||||
void r4300i_SPECIAL_MULTU ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DIV ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DIVU ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DMULT ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DMULTU ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DDIV ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DDIVU ( usf_state_t * );
|
||||
void r4300i_SPECIAL_ADD ( usf_state_t * );
|
||||
void r4300i_SPECIAL_ADDU ( usf_state_t * );
|
||||
void r4300i_SPECIAL_SUB ( usf_state_t * );
|
||||
void r4300i_SPECIAL_SUBU ( usf_state_t * );
|
||||
void r4300i_SPECIAL_AND ( usf_state_t * );
|
||||
void r4300i_SPECIAL_OR ( usf_state_t * );
|
||||
void r4300i_SPECIAL_XOR ( usf_state_t * );
|
||||
void r4300i_SPECIAL_NOR ( usf_state_t * );
|
||||
void r4300i_SPECIAL_SLT ( usf_state_t * );
|
||||
void r4300i_SPECIAL_SLTU ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DADD ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DADDU ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DSUB ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DSUBU ( usf_state_t * );
|
||||
void r4300i_SPECIAL_TEQ ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DSLL ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DSRL ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DSRA ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DSLL32 ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DSRL32 ( usf_state_t * );
|
||||
void r4300i_SPECIAL_DSRA32 ( usf_state_t * );
|
||||
|
||||
/********************** R4300i OpCodes: RegImm **********************/
|
||||
void r4300i_REGIMM_BLTZ ( usf_state_t * );
|
||||
void r4300i_REGIMM_BGEZ ( usf_state_t * );
|
||||
void r4300i_REGIMM_BLTZL ( usf_state_t * );
|
||||
void r4300i_REGIMM_BGEZL ( usf_state_t * );
|
||||
void r4300i_REGIMM_BLTZAL ( usf_state_t * );
|
||||
void r4300i_REGIMM_BGEZAL ( usf_state_t * );
|
||||
|
||||
/************************** COP0 functions **************************/
|
||||
void r4300i_COP0_MF ( usf_state_t * );
|
||||
void r4300i_COP0_MT ( usf_state_t * );
|
||||
|
||||
/************************** COP0 CO functions ***********************/
|
||||
void r4300i_COP0_CO_TLBR ( usf_state_t * );
|
||||
void r4300i_COP0_CO_TLBWI ( usf_state_t * );
|
||||
void r4300i_COP0_CO_TLBWR ( usf_state_t * );
|
||||
void r4300i_COP0_CO_TLBP ( usf_state_t * );
|
||||
void r4300i_COP0_CO_ERET ( usf_state_t * );
|
||||
|
||||
/************************** COP1 functions **************************/
|
||||
void r4300i_COP1_MF ( usf_state_t * );
|
||||
void r4300i_COP1_DMF ( usf_state_t * );
|
||||
void r4300i_COP1_CF ( usf_state_t * );
|
||||
void r4300i_COP1_MT ( usf_state_t * );
|
||||
void r4300i_COP1_DMT ( usf_state_t * );
|
||||
void r4300i_COP1_CT ( usf_state_t * );
|
||||
|
||||
/************************* COP1: BC1 functions ***********************/
|
||||
void r4300i_COP1_BCF ( usf_state_t * );
|
||||
void r4300i_COP1_BCT ( usf_state_t * );
|
||||
void r4300i_COP1_BCFL ( usf_state_t * );
|
||||
void r4300i_COP1_BCTL ( usf_state_t * );
|
||||
|
||||
/************************** COP1: S functions ************************/
|
||||
void r4300i_COP1_S_ADD ( usf_state_t * );
|
||||
void r4300i_COP1_S_SUB ( usf_state_t * );
|
||||
void r4300i_COP1_S_MUL ( usf_state_t * );
|
||||
void r4300i_COP1_S_DIV ( usf_state_t * );
|
||||
void r4300i_COP1_S_SQRT ( usf_state_t * );
|
||||
void r4300i_COP1_S_ABS ( usf_state_t * );
|
||||
void r4300i_COP1_S_MOV ( usf_state_t * );
|
||||
void r4300i_COP1_S_NEG ( usf_state_t * );
|
||||
void r4300i_COP1_S_TRUNC_L ( usf_state_t * );
|
||||
void r4300i_COP1_S_CEIL_L ( usf_state_t * ); //added by Witten
|
||||
void r4300i_COP1_S_FLOOR_L ( usf_state_t * ); //added by Witten
|
||||
void r4300i_COP1_S_ROUND_W ( usf_state_t * );
|
||||
void r4300i_COP1_S_TRUNC_W ( usf_state_t * );
|
||||
void r4300i_COP1_S_CEIL_W ( usf_state_t * ); //added by Witten
|
||||
void r4300i_COP1_S_FLOOR_W ( usf_state_t * );
|
||||
void r4300i_COP1_S_CVT_D ( usf_state_t * );
|
||||
void r4300i_COP1_S_CVT_W ( usf_state_t * );
|
||||
void r4300i_COP1_S_CVT_L ( usf_state_t * );
|
||||
void r4300i_COP1_S_CMP ( usf_state_t * );
|
||||
|
||||
/************************** COP1: D functions ************************/
|
||||
void r4300i_COP1_D_ADD ( usf_state_t * );
|
||||
void r4300i_COP1_D_SUB ( usf_state_t * );
|
||||
void r4300i_COP1_D_MUL ( usf_state_t * );
|
||||
void r4300i_COP1_D_DIV ( usf_state_t * );
|
||||
void r4300i_COP1_D_SQRT ( usf_state_t * );
|
||||
void r4300i_COP1_D_ABS ( usf_state_t * );
|
||||
void r4300i_COP1_D_MOV ( usf_state_t * );
|
||||
void r4300i_COP1_D_NEG ( usf_state_t * );
|
||||
void r4300i_COP1_D_TRUNC_L ( usf_state_t * ); //added by Witten
|
||||
void r4300i_COP1_D_CEIL_L ( usf_state_t * ); //added by Witten
|
||||
void r4300i_COP1_D_FLOOR_L ( usf_state_t * ); //added by Witten
|
||||
void r4300i_COP1_D_ROUND_W ( usf_state_t * );
|
||||
void r4300i_COP1_D_TRUNC_W ( usf_state_t * );
|
||||
void r4300i_COP1_D_CEIL_W ( usf_state_t * ); //added by Witten
|
||||
void r4300i_COP1_D_FLOOR_W ( usf_state_t * ); //added by Witten
|
||||
void r4300i_COP1_D_CVT_S ( usf_state_t * );
|
||||
void r4300i_COP1_D_CVT_W ( usf_state_t * );
|
||||
void r4300i_COP1_D_CVT_L ( usf_state_t * );
|
||||
void r4300i_COP1_D_CMP ( usf_state_t * );
|
||||
|
||||
/************************** COP1: W functions ************************/
|
||||
void r4300i_COP1_W_CVT_S ( usf_state_t * );
|
||||
void r4300i_COP1_W_CVT_D ( usf_state_t * );
|
||||
|
||||
/************************** COP1: L functions ************************/
|
||||
void r4300i_COP1_L_CVT_S ( usf_state_t * );
|
||||
void r4300i_COP1_L_CVT_D ( usf_state_t * );
|
||||
|
||||
/************************** Other functions **************************/
|
||||
void R4300i_UnknownOpcode ( usf_state_t * );
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>net.kode54.lazyusf</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2014 Christopher Snowhill. All rights reserved.</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "usf.h"
|
||||
#include "cpu.h"
|
||||
#include "memory.h"
|
||||
|
||||
#include "usf_internal.h"
|
||||
|
||||
void StopEmulation(usf_state_t * state)
|
||||
{
|
||||
//asm("int $3");
|
||||
//printf("Arrivederci!\n\n");
|
||||
//Release_Memory();
|
||||
//exit(0);
|
||||
state->cpu_running = 0;
|
||||
}
|
||||
|
||||
void DisplayError (char * Message, ...) {
|
||||
//char Msg[1000];
|
||||
//va_list ap;
|
||||
|
||||
//va_start( ap, Message );
|
||||
//vsprintf( Msg, Message, ap );
|
||||
//va_end( ap );
|
||||
|
||||
//printf("Error: %s\n", Msg);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "usf.h"
|
||||
|
||||
#define CPU_Default -1
|
||||
#define CPU_Interpreter 0
|
||||
#define CPU_Recompiler 1
|
||||
|
||||
void DisplayError (char * Message, ...);
|
||||
void StopEmulation(usf_state_t *);
|
|
@ -0,0 +1,748 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "usf.h"
|
||||
#include "main.h"
|
||||
#include "cpu.h"
|
||||
#include "audio.h"
|
||||
#include "rsp.h"
|
||||
|
||||
#include "usf_internal.h"
|
||||
|
||||
uint8_t * PageROM(usf_state_t * state, uint32_t addr) {
|
||||
return (state->ROMPages[addr/0x10000])?state->ROMPages[addr/0x10000]+(addr%0x10000):&state->EmptySpace;
|
||||
}
|
||||
|
||||
int32_t Allocate_Memory ( void * state ) {
|
||||
uint32_t i = 0;
|
||||
//RdramSize = 0x800000;
|
||||
|
||||
// Allocate the N64MEM and TLB_Map so that they are in each others 4GB range
|
||||
// Also put the registers there :)
|
||||
|
||||
|
||||
// the mmap technique works craptacular when the regions don't overlay
|
||||
|
||||
USF_STATE->MemChunk = mmap(NULL, 0x100000 * sizeof(uintptr_t) + 0x1D000 + USF_STATE->RdramSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, 0, 0);
|
||||
|
||||
USF_STATE->TLB_Map = (uintptr_t*)USF_STATE->MemChunk;
|
||||
if (USF_STATE->TLB_Map == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(USF_STATE->TLB_Map, 0, 0x100000 * sizeof(uintptr_t) + 0x10000);
|
||||
|
||||
USF_STATE->N64MEM = mmap((uintptr_t)USF_STATE->MemChunk + 0x100000 * sizeof(uintptr_t) + 0x10000, 0xD000 + USF_STATE->RdramSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_FIXED, 0, 0);
|
||||
if(USF_STATE->N64MEM == NULL) {
|
||||
DisplayError("Failed to allocate N64MEM");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//memset(state->N64MEM, 0, state->RdramSize);
|
||||
|
||||
USF_STATE->NOMEM = mmap((uintptr_t)USF_STATE->N64MEM + USF_STATE->RdramSize, 0xD000, PROT_NONE, MAP_PRIVATE | MAP_ANON | MAP_FIXED, 0, 0);
|
||||
|
||||
if(USF_STATE->RdramSize == 0x400000)
|
||||
{
|
||||
// munmap(N64MEM + 0x400000, 0x400000);
|
||||
}
|
||||
|
||||
USF_STATE->Registers = (N64_REGISTERS *)((uintptr_t)USF_STATE->MemChunk + 0x100000 * sizeof(uintptr_t));
|
||||
//USF_STATE->TLBLoadAddress = (uint32_t *)((uintptr_t)USF_STATE->Registers + 0x500);
|
||||
//USF_STATE->Timers = (SYSTEM_TIMERS*)(USF_STATE->TLBLoadAddress + 4);
|
||||
USF_STATE->Timers = (SYSTEM_TIMERS*)((uintptr_t)USF_STATE->Registers + 0x500);
|
||||
USF_STATE->WaitMode = (uint32_t *)(USF_STATE->Timers + sizeof(SYSTEM_TIMERS));
|
||||
USF_STATE->CPU_Action = (CPU_ACTION *)(USF_STATE->WaitMode + 4);
|
||||
//USF_STATE->RSP_GPR = (struct RSP_GPR_TYPE *)(USF_STATE->CPU_Action + sizeof(CPU_ACTION));
|
||||
//USF_STATE->DMEM = (uint8_t *)(USF_STATE->RSP_GPR + (32 * 16));
|
||||
USF_STATE->DMEM = (uint8_t *)(USF_STATE->CPU_Action + sizeof(CPU_ACTION));
|
||||
//state->RSP_ACCUM = (struct RSP_ACCUM_TYPE *)(USF_STATE->DMEM + 0x2000);
|
||||
|
||||
USF_STATE->RDRAM = (uint8_t *)(USF_STATE->N64MEM);
|
||||
USF_STATE->IMEM = USF_STATE->DMEM + 0x1000;
|
||||
|
||||
USF_STATE->MemoryState = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int PreAllocate_Memory(usf_state_t * state) {
|
||||
int i = 0;
|
||||
|
||||
// Moved the savestate allocation here :) (for better management later)
|
||||
state->savestatespace = malloc(0x80275C);
|
||||
|
||||
if(state->savestatespace == 0)
|
||||
return 0;
|
||||
|
||||
memset(state->savestatespace, 0, 0x80275C);
|
||||
|
||||
for (i = 0; i < 0x400; i++) {
|
||||
state->ROMPages[i] = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Release_Memory ( usf_state_t * state ) {
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < 0x400; i++) {
|
||||
if (state->ROMPages[i]) {
|
||||
free(state->ROMPages[i]); state->ROMPages[i] = 0;
|
||||
}
|
||||
}
|
||||
//printf("Freeing memory\n");
|
||||
|
||||
state->MemoryState = 0;
|
||||
|
||||
if (state->MemChunk != 0) {munmap(state->MemChunk, 0x100000 * sizeof(uintptr_t) + 0x10000); state->MemChunk=0;}
|
||||
if (state->N64MEM != 0) {munmap(state->N64MEM, state->RdramSize); state->N64MEM=0;}
|
||||
if (state->NOMEM != 0) {munmap(state->NOMEM, 0xD000); state->NOMEM=0;}
|
||||
|
||||
if(state->savestatespace)
|
||||
free(state->savestatespace);
|
||||
state->savestatespace = NULL;
|
||||
}
|
||||
|
||||
|
||||
int32_t r4300i_LB_NonMemory ( usf_state_t * state, uint32_t PAddr, uint32_t * Value, uint32_t SignExtend ) {
|
||||
if (PAddr >= 0x10000000 && PAddr < 0x16000000) {
|
||||
if (state->WrittenToRom) { return 0; }
|
||||
if ((PAddr & 2) == 0) { PAddr = (PAddr + 4) ^ 2; }
|
||||
if ((PAddr - 0x10000000) < state->RomFileSize) {
|
||||
if (SignExtend) {
|
||||
*Value = (char)*PageROM(state, (PAddr - 0x10000000)^3);
|
||||
|
||||
} else {
|
||||
*Value = *PageROM(state, (PAddr - 0x10000000)^3);
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
*Value = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (PAddr & 0xFFF00000) {
|
||||
default:
|
||||
* Value = 0;
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t r4300i_LB_VAddr ( usf_state_t * state, uint32_t VAddr, uint8_t * Value ) {
|
||||
if (state->TLB_Map[VAddr >> 12] == 0) { return 0; }
|
||||
*Value = *(uint8_t *)(state->TLB_Map[VAddr >> 12] + (VAddr ^ 3));
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t r4300i_LD_VAddr ( usf_state_t * state, uint32_t VAddr, uint64_t * Value ) {
|
||||
if (state->TLB_Map[VAddr >> 12] == 0) { return 0; }
|
||||
*((uint32_t *)(Value) + 1) = *(uint32_t *)(state->TLB_Map[VAddr >> 12] + VAddr);
|
||||
*((uint32_t *)(Value)) = *(uint32_t *)(state->TLB_Map[VAddr >> 12] + VAddr + 4);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t r4300i_LH_NonMemory ( usf_state_t * state, uint32_t PAddr, uint32_t * Value, int32_t SignExtend ) {
|
||||
switch (PAddr & 0xFFF00000) {
|
||||
default:
|
||||
* Value = 0;
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t r4300i_LH_VAddr ( usf_state_t * state, uint32_t VAddr, uint16_t * Value ) {
|
||||
if (state->TLB_Map[VAddr >> 12] == 0) { return 0; }
|
||||
*Value = *(uint16_t *)(state->TLB_Map[VAddr >> 12] + (VAddr ^ 2));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t r4300i_LW_NonMemory ( usf_state_t * state, uint32_t PAddr, uint32_t * Value ) {
|
||||
if (PAddr >= 0x10000000 && PAddr < 0x16000000) {
|
||||
if (state->WrittenToRom) {
|
||||
*Value = state->WroteToRom;
|
||||
//LogMessage("%X: Read crap from Rom %X from %X",PROGRAM_COUNTER,*Value,PAddr);
|
||||
state->WrittenToRom = 0;
|
||||
return 1;
|
||||
}
|
||||
if ((PAddr - 0x10000000) < state->RomFileSize) {
|
||||
*Value = *(uint32_t *)PageROM(state, (PAddr - 0x10000000));
|
||||
return 1;
|
||||
} else {
|
||||
*Value = PAddr & 0xFFFF;
|
||||
*Value = (*Value << 16) | *Value;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (PAddr & 0xFFF00000) {
|
||||
case 0x03F00000:
|
||||
switch (PAddr) {
|
||||
case 0x03F00000: * Value = RDRAM_CONFIG_REG; break;
|
||||
case 0x03F00004: * Value = RDRAM_DEVICE_ID_REG; break;
|
||||
case 0x03F00008: * Value = RDRAM_DELAY_REG; break;
|
||||
case 0x03F0000C: * Value = RDRAM_MODE_REG; break;
|
||||
case 0x03F00010: * Value = RDRAM_REF_INTERVAL_REG; break;
|
||||
case 0x03F00014: * Value = RDRAM_REF_ROW_REG; break;
|
||||
case 0x03F00018: * Value = RDRAM_RAS_INTERVAL_REG; break;
|
||||
case 0x03F0001C: * Value = RDRAM_MIN_INTERVAL_REG; break;
|
||||
case 0x03F00020: * Value = RDRAM_ADDR_SELECT_REG; break;
|
||||
case 0x03F00024: * Value = RDRAM_DEVICE_MANUF_REG; break;
|
||||
default:
|
||||
* Value = 0;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04000000:
|
||||
switch (PAddr) {
|
||||
case 0x04040010: *Value = SP_STATUS_REG; break;
|
||||
case 0x04040014: *Value = SP_DMA_FULL_REG; break;
|
||||
case 0x04040018: *Value = SP_DMA_BUSY_REG; break;
|
||||
case 0x04080000: *Value = SP_PC_REG; break;
|
||||
default:
|
||||
* Value = 0;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04100000:
|
||||
switch (PAddr) {
|
||||
case 0x0410000C: *Value = DPC_STATUS_REG; break;
|
||||
case 0x04100010: *Value = DPC_CLOCK_REG; break;
|
||||
case 0x04100014: *Value = DPC_BUFBUSY_REG; break;
|
||||
case 0x04100018: *Value = DPC_PIPEBUSY_REG; break;
|
||||
case 0x0410001C: *Value = DPC_TMEM_REG; break;
|
||||
default:
|
||||
* Value = 0;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04300000:
|
||||
switch (PAddr) {
|
||||
case 0x04300000: * Value = MI_MODE_REG; break;
|
||||
case 0x04300004: * Value = MI_VERSION_REG; break;
|
||||
case 0x04300008: * Value = MI_INTR_REG; break;
|
||||
case 0x0430000C: * Value = MI_INTR_MASK_REG; break;
|
||||
default:
|
||||
* Value = 0;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04400000:
|
||||
switch (PAddr) {
|
||||
case 0x04400000: *Value = VI_STATUS_REG; break;
|
||||
case 0x04400004: *Value = VI_ORIGIN_REG; break;
|
||||
case 0x04400008: *Value = VI_WIDTH_REG; break;
|
||||
case 0x0440000C: *Value = VI_INTR_REG; break;
|
||||
case 0x04400010:
|
||||
*Value = 0;
|
||||
break;
|
||||
case 0x04400014: *Value = VI_BURST_REG; break;
|
||||
case 0x04400018: *Value = VI_V_SYNC_REG; break;
|
||||
case 0x0440001C: *Value = VI_H_SYNC_REG; break;
|
||||
case 0x04400020: *Value = VI_LEAP_REG; break;
|
||||
case 0x04400024: *Value = VI_H_START_REG; break;
|
||||
case 0x04400028: *Value = VI_V_START_REG ; break;
|
||||
case 0x0440002C: *Value = VI_V_BURST_REG; break;
|
||||
case 0x04400030: *Value = VI_X_SCALE_REG; break;
|
||||
case 0x04400034: *Value = VI_Y_SCALE_REG; break;
|
||||
default:
|
||||
* Value = 0;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04500000:
|
||||
switch (PAddr) {
|
||||
case 0x04500004: *Value = AiReadLength(state); break;
|
||||
case 0x0450000C: *Value = AI_STATUS_REG; break;
|
||||
default:
|
||||
* Value = 0;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04600000:
|
||||
switch (PAddr) {
|
||||
case 0x04600010: *Value = PI_STATUS_REG; break;
|
||||
case 0x04600014: *Value = PI_DOMAIN1_REG; break;
|
||||
case 0x04600018: *Value = PI_BSD_DOM1_PWD_REG; break;
|
||||
case 0x0460001C: *Value = PI_BSD_DOM1_PGS_REG; break;
|
||||
case 0x04600020: *Value = PI_BSD_DOM1_RLS_REG; break;
|
||||
case 0x04600024: *Value = PI_DOMAIN2_REG; break;
|
||||
case 0x04600028: *Value = PI_BSD_DOM2_PWD_REG; break;
|
||||
case 0x0460002C: *Value = PI_BSD_DOM2_PGS_REG; break;
|
||||
case 0x04600030: *Value = PI_BSD_DOM2_RLS_REG; break;
|
||||
default:
|
||||
* Value = 0;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04700000:
|
||||
switch (PAddr) {
|
||||
case 0x04700000: * Value = RI_MODE_REG; break;
|
||||
case 0x04700004: * Value = RI_CONFIG_REG; break;
|
||||
case 0x04700008: * Value = RI_CURRENT_LOAD_REG; break;
|
||||
case 0x0470000C: * Value = RI_SELECT_REG; break;
|
||||
case 0x04700010: * Value = RI_REFRESH_REG; break;
|
||||
case 0x04700014: * Value = RI_LATENCY_REG; break;
|
||||
case 0x04700018: * Value = RI_RERROR_REG; break;
|
||||
case 0x0470001C: * Value = RI_WERROR_REG; break;
|
||||
default:
|
||||
* Value = 0;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04800000:
|
||||
switch (PAddr) {
|
||||
case 0x04800018: *Value = SI_STATUS_REG; break;
|
||||
default:
|
||||
*Value = 0;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x05000000:
|
||||
*Value = PAddr & 0xFFFF;
|
||||
*Value = (*Value << 16) | *Value;
|
||||
return 0;
|
||||
case 0x08000000:
|
||||
*Value = 0;
|
||||
break;
|
||||
default:
|
||||
*Value = PAddr & 0xFFFF;
|
||||
*Value = (*Value << 16) | *Value;
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void r4300i_LW_PAddr ( usf_state_t * state, uint32_t PAddr, uint32_t * Value ) {
|
||||
*Value = *(uint32_t *)(state->N64MEM+PAddr);
|
||||
}
|
||||
|
||||
uint32_t r4300i_LW_VAddr ( usf_state_t * state, uint32_t VAddr, uint32_t * Value ) {
|
||||
uintptr_t address = (state->TLB_Map[VAddr >> 12] + VAddr);
|
||||
|
||||
if (state->TLB_Map[VAddr >> 12] == 0) { return 0; }
|
||||
|
||||
if((address - (uintptr_t)state->RDRAM) > state->RdramSize) {
|
||||
address = address - (uintptr_t)state->RDRAM;
|
||||
return r4300i_LW_NonMemory(state, address, Value);
|
||||
}
|
||||
*Value = *(uint32_t *)address;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t r4300i_SB_NonMemory ( usf_state_t * state, uint32_t PAddr, uint8_t Value ) {
|
||||
switch (PAddr & 0xFFF00000) {
|
||||
case 0x00000000:
|
||||
case 0x00100000:
|
||||
case 0x00200000:
|
||||
case 0x00300000:
|
||||
case 0x00400000:
|
||||
case 0x00500000:
|
||||
case 0x00600000:
|
||||
case 0x00700000:
|
||||
if (PAddr < state->RdramSize) {
|
||||
*(uint8_t *)(state->N64MEM+PAddr) = Value;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t r4300i_SB_VAddr ( usf_state_t * state, uint32_t VAddr, uint8_t Value ) {
|
||||
if (state->TLB_Map[VAddr >> 12] == 0) { return 0; }
|
||||
*(uint8_t *)(state->TLB_Map[VAddr >> 12] + (VAddr ^ 3)) = Value;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t r4300i_SH_NonMemory ( usf_state_t * state, uint32_t PAddr, uint16_t Value ) {
|
||||
switch (PAddr & 0xFFF00000) {
|
||||
case 0x00000000:
|
||||
case 0x00100000:
|
||||
case 0x00200000:
|
||||
case 0x00300000:
|
||||
case 0x00400000:
|
||||
case 0x00500000:
|
||||
case 0x00600000:
|
||||
case 0x00700000:
|
||||
if (PAddr < state->RdramSize) {
|
||||
*(uint16_t *)(state->N64MEM+PAddr) = Value;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t r4300i_SD_VAddr ( usf_state_t * state, uint32_t VAddr, uint64_t Value ) {
|
||||
if (state->TLB_Map[VAddr >> 12] == 0) { return 0; }
|
||||
*(uint32_t *)(state->TLB_Map[VAddr >> 12] + VAddr) = *((uint32_t *)(&Value) + 1);
|
||||
*(uint32_t *)(state->TLB_Map[VAddr >> 12] + VAddr + 4) = *((uint32_t *)(&Value));
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t r4300i_SH_VAddr ( usf_state_t * state, uint32_t VAddr, uint16_t Value ) {
|
||||
if (state->TLB_Map[VAddr >> 12] == 0) { return 0; }
|
||||
*(uint16_t *)(state->TLB_Map[VAddr >> 12] + (VAddr ^ 2)) = Value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t r4300i_SW_NonMemory ( usf_state_t * state, uint32_t PAddr, uint32_t Value ) {
|
||||
if (PAddr >= 0x10000000 && PAddr < 0x16000000) {
|
||||
if ((PAddr - 0x10000000) < state->RomFileSize) {
|
||||
state->WrittenToRom = 1;
|
||||
state->WroteToRom = Value;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (PAddr & 0xFFF00000) {
|
||||
case 0x00000000:
|
||||
case 0x00100000:
|
||||
case 0x00200000:
|
||||
case 0x00300000:
|
||||
case 0x00400000:
|
||||
case 0x00500000:
|
||||
case 0x00600000:
|
||||
case 0x00700000:
|
||||
if (PAddr < state->RdramSize) {
|
||||
*(uint32_t *)(state->N64MEM+PAddr) = Value;
|
||||
}
|
||||
break;
|
||||
case 0x03F00000:
|
||||
switch (PAddr) {
|
||||
case 0x03F00000: RDRAM_CONFIG_REG = Value; break;
|
||||
case 0x03F00004: RDRAM_DEVICE_ID_REG = Value; break;
|
||||
case 0x03F00008: RDRAM_DELAY_REG = Value; break;
|
||||
case 0x03F0000C: RDRAM_MODE_REG = Value; break;
|
||||
case 0x03F00010: RDRAM_REF_INTERVAL_REG = Value; break;
|
||||
case 0x03F00014: RDRAM_REF_ROW_REG = Value; break;
|
||||
case 0x03F00018: RDRAM_RAS_INTERVAL_REG = Value; break;
|
||||
case 0x03F0001C: RDRAM_MIN_INTERVAL_REG = Value; break;
|
||||
case 0x03F00020: RDRAM_ADDR_SELECT_REG = Value; break;
|
||||
case 0x03F00024: RDRAM_DEVICE_MANUF_REG = Value; break;
|
||||
case 0x03F04004: break;
|
||||
case 0x03F08004: break;
|
||||
case 0x03F80004: break;
|
||||
case 0x03F80008: break;
|
||||
case 0x03F8000C: break;
|
||||
case 0x03F80014: break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04000000:
|
||||
if (PAddr < 0x04002000) {
|
||||
*(uint32_t *)(state->N64MEM+PAddr) = Value;
|
||||
return 1;
|
||||
}
|
||||
switch (PAddr) {
|
||||
case 0x04040000: SP_MEM_ADDR_REG = Value; break;
|
||||
case 0x04040004: SP_DRAM_ADDR_REG = Value; break;
|
||||
case 0x04040008:
|
||||
SP_RD_LEN_REG = Value;
|
||||
SP_DMA_READ(state);
|
||||
break;
|
||||
case 0x0404000C:
|
||||
SP_WR_LEN_REG = Value;
|
||||
SP_DMA_WRITE(state);
|
||||
break;
|
||||
case 0x04040010:
|
||||
if ( ( Value & SP_CLR_HALT ) != 0) { SP_STATUS_REG &= ~SP_STATUS_HALT; }
|
||||
if ( ( Value & SP_SET_HALT ) != 0) { SP_STATUS_REG |= SP_STATUS_HALT; }
|
||||
if ( ( Value & SP_CLR_BROKE ) != 0) { SP_STATUS_REG &= ~SP_STATUS_BROKE; }
|
||||
if ( ( Value & SP_CLR_INTR ) != 0) {
|
||||
MI_INTR_REG &= ~MI_INTR_SP;
|
||||
CheckInterrupts(state);
|
||||
}
|
||||
if ( ( Value & SP_CLR_SSTEP ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SSTEP; }
|
||||
if ( ( Value & SP_SET_SSTEP ) != 0) { SP_STATUS_REG |= SP_STATUS_SSTEP; }
|
||||
if ( ( Value & SP_CLR_INTR_BREAK ) != 0) { SP_STATUS_REG &= ~SP_STATUS_INTR_BREAK; }
|
||||
if ( ( Value & SP_SET_INTR_BREAK ) != 0) { SP_STATUS_REG |= SP_STATUS_INTR_BREAK; }
|
||||
if ( ( Value & SP_CLR_SIG0 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG0; }
|
||||
if ( ( Value & SP_SET_SIG0 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG0; }
|
||||
if ( ( Value & SP_CLR_SIG1 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG1; }
|
||||
if ( ( Value & SP_SET_SIG1 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG1; }
|
||||
if ( ( Value & SP_CLR_SIG2 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG2; }
|
||||
if ( ( Value & SP_SET_SIG2 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG2; }
|
||||
if ( ( Value & SP_CLR_SIG3 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG3; }
|
||||
if ( ( Value & SP_SET_SIG3 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG3; }
|
||||
if ( ( Value & SP_CLR_SIG4 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG4; }
|
||||
if ( ( Value & SP_SET_SIG4 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG4; }
|
||||
if ( ( Value & SP_CLR_SIG5 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG5; }
|
||||
if ( ( Value & SP_SET_SIG5 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG5; }
|
||||
if ( ( Value & SP_CLR_SIG6 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG6; }
|
||||
if ( ( Value & SP_SET_SIG6 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG6; }
|
||||
if ( ( Value & SP_CLR_SIG7 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG7; }
|
||||
if ( ( Value & SP_SET_SIG7 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG7; }
|
||||
|
||||
RunRsp(state);
|
||||
|
||||
break;
|
||||
case 0x0404001C: SP_SEMAPHORE_REG = 0; break;
|
||||
case 0x04080000: SP_PC_REG = Value & 0xFFC; break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04100000:
|
||||
switch (PAddr) {
|
||||
case 0x04100000:
|
||||
DPC_START_REG = Value;
|
||||
DPC_CURRENT_REG = Value;
|
||||
break;
|
||||
case 0x04100004:
|
||||
DPC_END_REG = Value;
|
||||
break;
|
||||
case 0x04100008: DPC_CURRENT_REG = Value; break;
|
||||
case 0x0410000C:
|
||||
if ( ( Value & DPC_CLR_XBUS_DMEM_DMA ) != 0) { DPC_STATUS_REG &= ~DPC_STATUS_XBUS_DMEM_DMA; }
|
||||
if ( ( Value & DPC_SET_XBUS_DMEM_DMA ) != 0) { DPC_STATUS_REG |= DPC_STATUS_XBUS_DMEM_DMA; }
|
||||
if ( ( Value & DPC_CLR_FREEZE ) != 0) { DPC_STATUS_REG &= ~DPC_STATUS_FREEZE; }
|
||||
if ( ( Value & DPC_SET_FREEZE ) != 0) { DPC_STATUS_REG |= DPC_STATUS_FREEZE; }
|
||||
if ( ( Value & DPC_CLR_FLUSH ) != 0) { DPC_STATUS_REG &= ~DPC_STATUS_FLUSH; }
|
||||
if ( ( Value & DPC_SET_FLUSH ) != 0) { DPC_STATUS_REG |= DPC_STATUS_FLUSH; }
|
||||
if ( ( Value & DPC_CLR_FREEZE ) != 0)
|
||||
{
|
||||
if ( ( SP_STATUS_REG & SP_STATUS_HALT ) == 0)
|
||||
{
|
||||
if ( ( SP_STATUS_REG & SP_STATUS_BROKE ) == 0 )
|
||||
{
|
||||
RunRsp(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04300000:
|
||||
switch (PAddr) {
|
||||
case 0x04300000:
|
||||
MI_MODE_REG &= ~0x7F;
|
||||
MI_MODE_REG |= (Value & 0x7F);
|
||||
if ( ( Value & MI_CLR_INIT ) != 0 ) { MI_MODE_REG &= ~MI_MODE_INIT; }
|
||||
if ( ( Value & MI_SET_INIT ) != 0 ) { MI_MODE_REG |= MI_MODE_INIT; }
|
||||
if ( ( Value & MI_CLR_EBUS ) != 0 ) { MI_MODE_REG &= ~MI_MODE_EBUS; }
|
||||
if ( ( Value & MI_SET_EBUS ) != 0 ) { MI_MODE_REG |= MI_MODE_EBUS; }
|
||||
if ( ( Value & MI_CLR_DP_INTR ) != 0 ) {
|
||||
MI_INTR_REG &= ~MI_INTR_DP;
|
||||
CheckInterrupts(state);
|
||||
}
|
||||
if ( ( Value & MI_CLR_RDRAM ) != 0 ) { MI_MODE_REG &= ~MI_MODE_RDRAM; }
|
||||
if ( ( Value & MI_SET_RDRAM ) != 0 ) { MI_MODE_REG |= MI_MODE_RDRAM; }
|
||||
break;
|
||||
case 0x0430000C:
|
||||
if ( ( Value & MI_INTR_MASK_CLR_SP ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_SP; }
|
||||
if ( ( Value & MI_INTR_MASK_SET_SP ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_SP; }
|
||||
if ( ( Value & MI_INTR_MASK_CLR_SI ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_SI; }
|
||||
if ( ( Value & MI_INTR_MASK_SET_SI ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_SI; }
|
||||
if ( ( Value & MI_INTR_MASK_CLR_AI ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_AI; }
|
||||
if ( ( Value & MI_INTR_MASK_SET_AI ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_AI; }
|
||||
if ( ( Value & MI_INTR_MASK_CLR_VI ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_VI; }
|
||||
if ( ( Value & MI_INTR_MASK_SET_VI ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_VI; }
|
||||
if ( ( Value & MI_INTR_MASK_CLR_PI ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_PI; }
|
||||
if ( ( Value & MI_INTR_MASK_SET_PI ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_PI; }
|
||||
if ( ( Value & MI_INTR_MASK_CLR_DP ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_DP; }
|
||||
if ( ( Value & MI_INTR_MASK_SET_DP ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_DP; }
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04400000:
|
||||
switch (PAddr) {
|
||||
case 0x04400000:
|
||||
//if (VI_STATUS_REG != Value) {
|
||||
VI_STATUS_REG = Value;
|
||||
// if (ViStatusChanged != NULL ) { ViStatusChanged(); }
|
||||
//}
|
||||
break;
|
||||
case 0x04400004:
|
||||
|
||||
VI_ORIGIN_REG = (Value & 0xFFFFFF);
|
||||
//if (UpdateScreen != NULL ) { UpdateScreen(); }
|
||||
break;
|
||||
case 0x04400008:
|
||||
//if (VI_WIDTH_REG != Value) {
|
||||
VI_WIDTH_REG = Value;
|
||||
// if (ViWidthChanged != NULL ) { ViWidthChanged(); }
|
||||
//}
|
||||
break;
|
||||
case 0x0440000C: VI_INTR_REG = Value; break;
|
||||
case 0x04400010:
|
||||
MI_INTR_REG &= ~MI_INTR_VI;
|
||||
CheckInterrupts(state);
|
||||
break;
|
||||
case 0x04400014: VI_BURST_REG = Value; break;
|
||||
case 0x04400018: VI_V_SYNC_REG = Value; break;
|
||||
case 0x0440001C: VI_H_SYNC_REG = Value; break;
|
||||
case 0x04400020: VI_LEAP_REG = Value; break;
|
||||
case 0x04400024: VI_H_START_REG = Value; break;
|
||||
case 0x04400028: VI_V_START_REG = Value; break;
|
||||
case 0x0440002C: VI_V_BURST_REG = Value; break;
|
||||
case 0x04400030: VI_X_SCALE_REG = Value; break;
|
||||
case 0x04400034: VI_Y_SCALE_REG = Value; break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04500000:
|
||||
switch (PAddr) {
|
||||
case 0x04500000: AI_DRAM_ADDR_REG = Value; break;
|
||||
case 0x04500004:
|
||||
AI_LEN_REG = Value;
|
||||
AiLenChanged(state);
|
||||
break;
|
||||
case 0x04500008: AI_CONTROL_REG = (Value & 0x1); break;
|
||||
case 0x0450000C:
|
||||
/* Clear Interrupt */;
|
||||
MI_INTR_REG &= ~MI_INTR_AI;
|
||||
state->AudioIntrReg &= ~MI_INTR_AI;
|
||||
CheckInterrupts(state);
|
||||
break;
|
||||
case 0x04500010:
|
||||
AI_DACRATE_REG = Value;
|
||||
//if (AiDacrateChanged != NULL) { AiDacrateChanged(SYSTEM_NTSC); }
|
||||
break;
|
||||
case 0x04500014: AI_BITRATE_REG = Value; break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04600000:
|
||||
switch (PAddr) {
|
||||
case 0x04600000: PI_DRAM_ADDR_REG = Value; break;
|
||||
case 0x04600004: PI_CART_ADDR_REG = Value; break;
|
||||
case 0x04600008:
|
||||
PI_RD_LEN_REG = Value;
|
||||
PI_DMA_READ(state);
|
||||
break;
|
||||
case 0x0460000C:
|
||||
PI_WR_LEN_REG = Value;
|
||||
PI_DMA_WRITE(state);
|
||||
break;
|
||||
case 0x04600010:
|
||||
//if ((Value & PI_SET_RESET) != 0 ) { DisplayError("reset Controller"); }
|
||||
if ((Value & PI_CLR_INTR) != 0 ) {
|
||||
MI_INTR_REG &= ~MI_INTR_PI;
|
||||
CheckInterrupts(state);
|
||||
}
|
||||
break;
|
||||
case 0x04600014: PI_DOMAIN1_REG = (Value & 0xFF); break;
|
||||
case 0x04600018: PI_BSD_DOM1_PWD_REG = (Value & 0xFF); break;
|
||||
case 0x0460001C: PI_BSD_DOM1_PGS_REG = (Value & 0xFF); break;
|
||||
case 0x04600020: PI_BSD_DOM1_RLS_REG = (Value & 0xFF); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04700000:
|
||||
switch (PAddr) {
|
||||
case 0x04700000: RI_MODE_REG = Value; break;
|
||||
case 0x04700004: RI_CONFIG_REG = Value; break;
|
||||
case 0x04700008: RI_CURRENT_LOAD_REG = Value; break;
|
||||
case 0x0470000C: RI_SELECT_REG = Value; break;
|
||||
case 0x04700010: RI_REFRESH_REG = Value; break;
|
||||
case 0x04700014: RI_LATENCY_REG = Value; break;
|
||||
case 0x04700018: RI_RERROR_REG = Value; break;
|
||||
case 0x0470001C: RI_WERROR_REG = Value; break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x04800000:
|
||||
switch (PAddr) {
|
||||
case 0x04800000: SI_DRAM_ADDR_REG = Value; break;
|
||||
case 0x04800004:
|
||||
SI_PIF_ADDR_RD64B_REG = Value;
|
||||
SI_DMA_READ (state);
|
||||
break;
|
||||
case 0x04800010:
|
||||
SI_PIF_ADDR_WR64B_REG = Value;
|
||||
SI_DMA_WRITE(state);
|
||||
break;
|
||||
case 0x04800018:
|
||||
MI_INTR_REG &= ~MI_INTR_SI;
|
||||
SI_STATUS_REG &= ~SI_STATUS_INTERRUPT;
|
||||
CheckInterrupts(state);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 0x08000000:
|
||||
if (PAddr != 0x08010000) { return 0; }
|
||||
break;
|
||||
case 0x1FC00000:
|
||||
if (PAddr < 0x1FC007C0) {
|
||||
return 0;
|
||||
} else if (PAddr < 0x1FC00800) {
|
||||
|
||||
if (PAddr == 0x1FC007FC) {
|
||||
PifRamWrite(state);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t r4300i_SW_VAddr ( usf_state_t * state, uint32_t VAddr, uint32_t Value ) {
|
||||
uintptr_t address = (state->TLB_Map[VAddr >> 12] + VAddr);
|
||||
|
||||
if (state->TLB_Map[VAddr >> 12] == 0) { return 0; }
|
||||
|
||||
if((address - (uintptr_t)state->RDRAM) > state->RdramSize) {
|
||||
address = address - (uintptr_t)state->RDRAM;
|
||||
return r4300i_SW_NonMemory(state, address, Value);
|
||||
}
|
||||
*(uint32_t *)address = Value;
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
#define LargeCompileBufferSize 0x03200000
|
||||
#define NormalCompileBufferSize 0x01500000
|
||||
|
||||
#define RSP_RECOMPMEM_SIZE 0x400000
|
||||
#define RSP_SECRECOMPMEM_SIZE 0x200000
|
||||
|
||||
#define ROM_IN_MAPSPACE
|
||||
|
||||
/* Memory Control */
|
||||
int Allocate_Memory ( void * );
|
||||
void Release_Memory ( usf_state_t * );
|
||||
int PreAllocate_Memory( usf_state_t * );
|
||||
|
||||
/* CPU memory functions */
|
||||
//int r4300i_Command_MemoryFilter ( uint32_t dwExptCode, LPEXCEPTION_POINTERS lpEP );
|
||||
//int r4300i_CPU_MemoryFilter ( uint32_t dwExptCode, LPEXCEPTION_POINTERS lpEP );
|
||||
int32_t r4300i_LB_NonMemory ( usf_state_t *, uint32_t PAddr, uint32_t * Value, uint32_t SignExtend );
|
||||
uint32_t r4300i_LB_VAddr ( usf_state_t *, uint32_t VAddr, uint8_t * Value );
|
||||
uint32_t r4300i_LD_VAddr ( usf_state_t *, uint32_t VAddr, uint64_t * Value );
|
||||
int32_t r4300i_LH_NonMemory ( usf_state_t *, uint32_t PAddr, uint32_t * Value, int32_t SignExtend );
|
||||
uint32_t r4300i_LH_VAddr ( usf_state_t *, uint32_t VAddr, uint16_t * Value );
|
||||
int32_t r4300i_LW_NonMemory ( usf_state_t *, uint32_t PAddr, uint32_t * Value );
|
||||
void r4300i_LW_PAddr ( usf_state_t *, uint32_t PAddr, uint32_t * Value );
|
||||
uint32_t r4300i_LW_VAddr ( usf_state_t *, uint32_t VAddr, uint32_t * Value );
|
||||
int32_t r4300i_SB_NonMemory ( usf_state_t *, uint32_t PAddr, uint8_t Value );
|
||||
uint32_t r4300i_SB_VAddr ( usf_state_t *, uint32_t VAddr, uint8_t Value );
|
||||
uint32_t r4300i_SD_VAddr ( usf_state_t *, uint32_t VAddr, uint64_t Value );
|
||||
int32_t r4300i_SH_NonMemory ( usf_state_t *, uint32_t PAddr, uint16_t Value );
|
||||
uint32_t r4300i_SH_VAddr ( usf_state_t *, uint32_t VAddr, uint16_t Value );
|
||||
int32_t r4300i_SW_NonMemory ( usf_state_t *, uint32_t PAddr, uint32_t Value );
|
||||
uint32_t r4300i_SW_VAddr ( usf_state_t *, uint32_t VAddr, uint32_t Value );
|
||||
|
||||
uint8_t * PageROM(usf_state_t *, uint32_t addr);
|
|
@ -0,0 +1,274 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
#ifndef __OpCode
|
||||
#define __OpCode
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
|
||||
uint32_t Hex;
|
||||
uint8_t Ascii[4];
|
||||
|
||||
struct {
|
||||
unsigned offset : 16;
|
||||
unsigned rt : 5;
|
||||
unsigned rs : 5;
|
||||
unsigned op : 6;
|
||||
};
|
||||
|
||||
struct {
|
||||
unsigned immediate : 16;
|
||||
unsigned : 5;
|
||||
unsigned base : 5;
|
||||
unsigned : 6;
|
||||
};
|
||||
|
||||
struct {
|
||||
unsigned target : 26;
|
||||
unsigned : 6;
|
||||
};
|
||||
|
||||
struct {
|
||||
unsigned funct : 6;
|
||||
unsigned sa : 5;
|
||||
unsigned rd : 5;
|
||||
unsigned : 5;
|
||||
unsigned : 5;
|
||||
unsigned : 6;
|
||||
};
|
||||
|
||||
struct {
|
||||
unsigned : 6;
|
||||
unsigned fd : 5;
|
||||
unsigned fs : 5;
|
||||
unsigned ft : 5;
|
||||
unsigned fmt : 5;
|
||||
unsigned : 6;
|
||||
};
|
||||
};
|
||||
|
||||
} OPCODE;
|
||||
|
||||
//R4300i OpCodes
|
||||
#define R4300i_SPECIAL 0
|
||||
#define R4300i_REGIMM 1
|
||||
#define R4300i_J 2
|
||||
#define R4300i_JAL 3
|
||||
#define R4300i_BEQ 4
|
||||
#define R4300i_BNE 5
|
||||
#define R4300i_BLEZ 6
|
||||
#define R4300i_BGTZ 7
|
||||
#define R4300i_ADDI 8
|
||||
#define R4300i_ADDIU 9
|
||||
#define R4300i_SLTI 10
|
||||
#define R4300i_SLTIU 11
|
||||
#define R4300i_ANDI 12
|
||||
#define R4300i_ORI 13
|
||||
#define R4300i_XORI 14
|
||||
#define R4300i_LUI 15
|
||||
#define R4300i_CP0 16
|
||||
#define R4300i_CP1 17
|
||||
#define R4300i_BEQL 20
|
||||
#define R4300i_BNEL 21
|
||||
#define R4300i_BLEZL 22
|
||||
#define R4300i_BGTZL 23
|
||||
#define R4300i_DADDI 24
|
||||
#define R4300i_DADDIU 25
|
||||
#define R4300i_LDL 26
|
||||
#define R4300i_LDR 27
|
||||
#define R4300i_LB 32
|
||||
#define R4300i_LH 33
|
||||
#define R4300i_LWL 34
|
||||
#define R4300i_LW 35
|
||||
#define R4300i_LBU 36
|
||||
#define R4300i_LHU 37
|
||||
#define R4300i_LWR 38
|
||||
#define R4300i_LWU 39
|
||||
#define R4300i_SB 40
|
||||
#define R4300i_SH 41
|
||||
#define R4300i_SWL 42
|
||||
#define R4300i_SW 43
|
||||
#define R4300i_SDL 44
|
||||
#define R4300i_SDR 45
|
||||
#define R4300i_SWR 46
|
||||
#define R4300i_CACHE 47
|
||||
#define R4300i_LL 48
|
||||
#define R4300i_LWC1 49
|
||||
#define R4300i_LWC2 0x32
|
||||
#define R4300i_LLD 0x34
|
||||
#define R4300i_LDC1 53
|
||||
#define R4300i_LDC2 0x36
|
||||
#define R4300i_LD 55
|
||||
#define R4300i_SC 0x38
|
||||
#define R4300i_SWC1 57
|
||||
#define R4300i_SWC2 0x3A
|
||||
#define R4300i_SCD 0x3C
|
||||
#define R4300i_SDC1 61
|
||||
#define R4300i_SDC2 62
|
||||
#define R4300i_SD 63
|
||||
|
||||
/* R4300i Special opcodes */
|
||||
#define R4300i_SPECIAL_SLL 0
|
||||
#define R4300i_SPECIAL_SRL 2
|
||||
#define R4300i_SPECIAL_SRA 3
|
||||
#define R4300i_SPECIAL_SLLV 4
|
||||
#define R4300i_SPECIAL_SRLV 6
|
||||
#define R4300i_SPECIAL_SRAV 7
|
||||
#define R4300i_SPECIAL_JR 8
|
||||
#define R4300i_SPECIAL_JALR 9
|
||||
#define R4300i_SPECIAL_SYSCALL 12
|
||||
#define R4300i_SPECIAL_BREAK 13
|
||||
#define R4300i_SPECIAL_SYNC 15
|
||||
#define R4300i_SPECIAL_MFHI 16
|
||||
#define R4300i_SPECIAL_MTHI 17
|
||||
#define R4300i_SPECIAL_MFLO 18
|
||||
#define R4300i_SPECIAL_MTLO 19
|
||||
#define R4300i_SPECIAL_DSLLV 20
|
||||
#define R4300i_SPECIAL_DSRLV 22
|
||||
#define R4300i_SPECIAL_DSRAV 23
|
||||
#define R4300i_SPECIAL_MULT 24
|
||||
#define R4300i_SPECIAL_MULTU 25
|
||||
#define R4300i_SPECIAL_DIV 26
|
||||
#define R4300i_SPECIAL_DIVU 27
|
||||
#define R4300i_SPECIAL_DMULT 28
|
||||
#define R4300i_SPECIAL_DMULTU 29
|
||||
#define R4300i_SPECIAL_DDIV 30
|
||||
#define R4300i_SPECIAL_DDIVU 31
|
||||
#define R4300i_SPECIAL_ADD 32
|
||||
#define R4300i_SPECIAL_ADDU 33
|
||||
#define R4300i_SPECIAL_SUB 34
|
||||
#define R4300i_SPECIAL_SUBU 35
|
||||
#define R4300i_SPECIAL_AND 36
|
||||
#define R4300i_SPECIAL_OR 37
|
||||
#define R4300i_SPECIAL_XOR 38
|
||||
#define R4300i_SPECIAL_NOR 39
|
||||
#define R4300i_SPECIAL_SLT 42
|
||||
#define R4300i_SPECIAL_SLTU 43
|
||||
#define R4300i_SPECIAL_DADD 44
|
||||
#define R4300i_SPECIAL_DADDU 45
|
||||
#define R4300i_SPECIAL_DSUB 46
|
||||
#define R4300i_SPECIAL_DSUBU 47
|
||||
#define R4300i_SPECIAL_TGE 48
|
||||
#define R4300i_SPECIAL_TGEU 49
|
||||
#define R4300i_SPECIAL_TLT 50
|
||||
#define R4300i_SPECIAL_TLTU 51
|
||||
#define R4300i_SPECIAL_TEQ 52
|
||||
#define R4300i_SPECIAL_TNE 54
|
||||
#define R4300i_SPECIAL_DSLL 56
|
||||
#define R4300i_SPECIAL_DSRL 58
|
||||
#define R4300i_SPECIAL_DSRA 59
|
||||
#define R4300i_SPECIAL_DSLL32 60
|
||||
#define R4300i_SPECIAL_DSRL32 62
|
||||
#define R4300i_SPECIAL_DSRA32 63
|
||||
|
||||
/* R4300i RegImm opcodes */
|
||||
#define R4300i_REGIMM_BLTZ 0
|
||||
#define R4300i_REGIMM_BGEZ 1
|
||||
#define R4300i_REGIMM_BLTZL 2
|
||||
#define R4300i_REGIMM_BGEZL 3
|
||||
#define R4300i_REGIMM_TGEI 0x08
|
||||
#define R4300i_REGIMM_TGEIU 0x09
|
||||
#define R4300i_REGIMM_TLTI 0x0A
|
||||
#define R4300i_REGIMM_TLTIU 0x0B
|
||||
#define R4300i_REGIMM_TEQI 0x0C
|
||||
#define R4300i_REGIMM_TNEI 0x0E
|
||||
#define R4300i_REGIMM_BLTZAL 0x10
|
||||
#define R4300i_REGIMM_BGEZAL 17
|
||||
#define R4300i_REGIMM_BLTZALL 0x12
|
||||
#define R4300i_REGIMM_BGEZALL 0x13
|
||||
|
||||
/* R4300i COP0 opcodes */
|
||||
#define R4300i_COP0_MF 0
|
||||
#define R4300i_COP0_MT 4
|
||||
|
||||
/* R4300i COP0 CO opcodes */
|
||||
#define R4300i_COP0_CO_TLBR 1
|
||||
#define R4300i_COP0_CO_TLBWI 2
|
||||
#define R4300i_COP0_CO_TLBWR 6
|
||||
#define R4300i_COP0_CO_TLBP 8
|
||||
#define R4300i_COP0_CO_ERET 24
|
||||
|
||||
/* R4300i COP1 opcodes */
|
||||
#define R4300i_COP1_MF 0
|
||||
#define R4300i_COP1_DMF 1
|
||||
#define R4300i_COP1_CF 2
|
||||
#define R4300i_COP1_MT 4
|
||||
#define R4300i_COP1_DMT 5
|
||||
#define R4300i_COP1_CT 6
|
||||
#define R4300i_COP1_BC 8
|
||||
#define R4300i_COP1_S 16
|
||||
#define R4300i_COP1_D 17
|
||||
#define R4300i_COP1_W 20
|
||||
#define R4300i_COP1_L 21
|
||||
|
||||
/* R4300i COP1 BC opcodes */
|
||||
#define R4300i_COP1_BC_BCF 0
|
||||
#define R4300i_COP1_BC_BCT 1
|
||||
#define R4300i_COP1_BC_BCFL 2
|
||||
#define R4300i_COP1_BC_BCTL 3
|
||||
|
||||
#define R4300i_COP1_FUNCT_ADD 0
|
||||
#define R4300i_COP1_FUNCT_SUB 1
|
||||
#define R4300i_COP1_FUNCT_MUL 2
|
||||
#define R4300i_COP1_FUNCT_DIV 3
|
||||
#define R4300i_COP1_FUNCT_SQRT 4
|
||||
#define R4300i_COP1_FUNCT_ABS 5
|
||||
#define R4300i_COP1_FUNCT_MOV 6
|
||||
#define R4300i_COP1_FUNCT_NEG 7
|
||||
#define R4300i_COP1_FUNCT_ROUND_L 8
|
||||
#define R4300i_COP1_FUNCT_TRUNC_L 9
|
||||
#define R4300i_COP1_FUNCT_CEIL_L 10
|
||||
#define R4300i_COP1_FUNCT_FLOOR_L 11
|
||||
#define R4300i_COP1_FUNCT_ROUND_W 12
|
||||
#define R4300i_COP1_FUNCT_TRUNC_W 13
|
||||
#define R4300i_COP1_FUNCT_CEIL_W 14
|
||||
#define R4300i_COP1_FUNCT_FLOOR_W 15
|
||||
#define R4300i_COP1_FUNCT_CVT_S 32
|
||||
#define R4300i_COP1_FUNCT_CVT_D 33
|
||||
#define R4300i_COP1_FUNCT_CVT_W 36
|
||||
#define R4300i_COP1_FUNCT_CVT_L 37
|
||||
#define R4300i_COP1_FUNCT_C_F 48
|
||||
#define R4300i_COP1_FUNCT_C_UN 49
|
||||
#define R4300i_COP1_FUNCT_C_EQ 50
|
||||
#define R4300i_COP1_FUNCT_C_UEQ 51
|
||||
#define R4300i_COP1_FUNCT_C_OLT 52
|
||||
#define R4300i_COP1_FUNCT_C_ULT 53
|
||||
#define R4300i_COP1_FUNCT_C_OLE 54
|
||||
#define R4300i_COP1_FUNCT_C_ULE 55
|
||||
#define R4300i_COP1_FUNCT_C_SF 56
|
||||
#define R4300i_COP1_FUNCT_C_NGLE 57
|
||||
#define R4300i_COP1_FUNCT_C_SEQ 58
|
||||
#define R4300i_COP1_FUNCT_C_NGL 59
|
||||
#define R4300i_COP1_FUNCT_C_LT 60
|
||||
#define R4300i_COP1_FUNCT_C_NGE 61
|
||||
#define R4300i_COP1_FUNCT_C_LE 62
|
||||
#define R4300i_COP1_FUNCT_C_NGT 63
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
#include "usf.h"
|
||||
#include "main.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include "usf_internal.h"
|
||||
|
||||
// Skeletal support so USFs that read the controller won't fail (bad practice, though)
|
||||
|
||||
void ProcessControllerCommand ( usf_state_t * state, int32_t Control, uint8_t * Command);
|
||||
|
||||
void PifRamRead (usf_state_t * state) {
|
||||
int32_t Channel, CurPos;
|
||||
|
||||
Channel = 0;
|
||||
CurPos = 0;
|
||||
|
||||
do {
|
||||
switch(state->PIF_Ram[CurPos]) {
|
||||
case 0x00:
|
||||
Channel += 1;
|
||||
if (Channel > 6) { CurPos = 0x40; }
|
||||
break;
|
||||
case 0xFE: CurPos = 0x40; break;
|
||||
case 0xFF: break;
|
||||
case 0xB4: case 0x56: case 0xB8: break; /* ??? */
|
||||
default:
|
||||
if ((state->PIF_Ram[CurPos] & 0xC0) == 0) {
|
||||
CurPos += state->PIF_Ram[CurPos] + (state->PIF_Ram[CurPos + 1] & 0x3F) + 1;
|
||||
Channel += 1;
|
||||
} else {
|
||||
CurPos = 0x40;
|
||||
}
|
||||
break;
|
||||
}
|
||||
CurPos += 1;
|
||||
} while( CurPos < 0x40 );
|
||||
}
|
||||
|
||||
void PifRamWrite (usf_state_t * state) {
|
||||
int Channel, CurPos;
|
||||
|
||||
Channel = 0;
|
||||
|
||||
for (CurPos = 0; CurPos < 0x40; CurPos++){
|
||||
switch(state->PIF_Ram[CurPos]) {
|
||||
case 0x00:
|
||||
Channel += 1;
|
||||
if (Channel > 6) { CurPos = 0x40; }
|
||||
break;
|
||||
case 0xFE: CurPos = 0x40; break;
|
||||
case 0xFF: break;
|
||||
case 0xB4: case 0x56: case 0xB8: break; /* ??? */
|
||||
default:
|
||||
if ((state->PIF_Ram[CurPos] & 0xC0) == 0) {
|
||||
if (Channel < 4) {
|
||||
ProcessControllerCommand(state,Channel,&state->PIF_Ram[CurPos]);
|
||||
}
|
||||
CurPos += state->PIF_Ram[CurPos] + (state->PIF_Ram[CurPos + 1] & 0x3F) + 1;
|
||||
Channel += 1;
|
||||
} else
|
||||
CurPos = 0x40;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
state->PIF_Ram[0x3F] = 0;
|
||||
}
|
||||
|
||||
// always return failure
|
||||
void ProcessControllerCommand ( usf_state_t * state, int32_t Control, uint8_t * Command) {
|
||||
Command[1] |= 0x80;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
extern uint8_t *PIF_Ram;
|
||||
|
||||
void PifRamWrite ( usf_state_t * );
|
||||
void PifRamRead ( usf_state_t * );
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
|
||||
// #ifdef EXT_REGS
|
||||
|
||||
#include "usf.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "cpu.h"
|
||||
#include "types.h"
|
||||
|
||||
#include "usf_internal.h"
|
||||
|
||||
void SetupRegisters(usf_state_t * state, N64_REGISTERS * n64_Registers) {
|
||||
state->PROGRAM_COUNTER = n64_Registers->PROGRAM_COUNTER;
|
||||
state->HI.DW = n64_Registers->HI.DW;
|
||||
state->LO.DW = n64_Registers->LO.DW;
|
||||
state->CP0 = n64_Registers->CP0;
|
||||
state->GPR = n64_Registers->GPR;
|
||||
state->FPR = n64_Registers->FPR;
|
||||
state->FPCR = n64_Registers->FPCR;
|
||||
state->RegRDRAM = n64_Registers->RDRAM;
|
||||
state->RegSP = n64_Registers->SP;
|
||||
state->RegDPC = n64_Registers->DPC;
|
||||
state->RegMI = n64_Registers->MI;
|
||||
state->RegVI = n64_Registers->VI;
|
||||
state->RegAI = n64_Registers->AI;
|
||||
state->RegPI = n64_Registers->PI;
|
||||
state->RegRI = n64_Registers->RI;
|
||||
state->RegSI = n64_Registers->SI;
|
||||
state->PIF_Ram = n64_Registers->PIF_Ram;
|
||||
}
|
||||
|
||||
void ChangeMiIntrMask (usf_state_t * state) {
|
||||
if ( ( state->RegModValue & MI_INTR_MASK_CLR_SP ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_SP; }
|
||||
if ( ( state->RegModValue & MI_INTR_MASK_SET_SP ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_SP; }
|
||||
if ( ( state->RegModValue & MI_INTR_MASK_CLR_SI ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_SI; }
|
||||
if ( ( state->RegModValue & MI_INTR_MASK_SET_SI ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_SI; }
|
||||
if ( ( state->RegModValue & MI_INTR_MASK_CLR_AI ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_AI; }
|
||||
if ( ( state->RegModValue & MI_INTR_MASK_SET_AI ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_AI; }
|
||||
if ( ( state->RegModValue & MI_INTR_MASK_CLR_VI ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_VI; }
|
||||
if ( ( state->RegModValue & MI_INTR_MASK_SET_VI ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_VI; }
|
||||
if ( ( state->RegModValue & MI_INTR_MASK_CLR_PI ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_PI; }
|
||||
if ( ( state->RegModValue & MI_INTR_MASK_SET_PI ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_PI; }
|
||||
if ( ( state->RegModValue & MI_INTR_MASK_CLR_DP ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_DP; }
|
||||
if ( ( state->RegModValue & MI_INTR_MASK_SET_DP ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_DP; }
|
||||
}
|
||||
|
||||
void ChangeMiModeReg (usf_state_t * state) {
|
||||
MI_MODE_REG &= ~0x7F;
|
||||
MI_MODE_REG |= (state->RegModValue & 0x7F);
|
||||
if ( ( state->RegModValue & MI_CLR_INIT ) != 0 ) { MI_MODE_REG &= ~MI_MODE_INIT; }
|
||||
if ( ( state->RegModValue & MI_SET_INIT ) != 0 ) { MI_MODE_REG |= MI_MODE_INIT; }
|
||||
if ( ( state->RegModValue & MI_CLR_EBUS ) != 0 ) { MI_MODE_REG &= ~MI_MODE_EBUS; }
|
||||
if ( ( state->RegModValue & MI_SET_EBUS ) != 0 ) { MI_MODE_REG |= MI_MODE_EBUS; }
|
||||
if ( ( state->RegModValue & MI_CLR_DP_INTR ) != 0 ) { MI_INTR_REG &= ~MI_INTR_DP; }
|
||||
if ( ( state->RegModValue & MI_CLR_RDRAM ) != 0 ) { MI_MODE_REG &= ~MI_MODE_RDRAM; }
|
||||
if ( ( state->RegModValue & MI_SET_RDRAM ) != 0 ) { MI_MODE_REG |= MI_MODE_RDRAM; }
|
||||
}
|
||||
|
||||
void ChangeSpStatus (usf_state_t * state) {
|
||||
if ( ( state->RegModValue & SP_CLR_HALT ) != 0) { SP_STATUS_REG &= ~SP_STATUS_HALT; }
|
||||
if ( ( state->RegModValue & SP_SET_HALT ) != 0) { SP_STATUS_REG |= SP_STATUS_HALT; }
|
||||
if ( ( state->RegModValue & SP_CLR_BROKE ) != 0) { SP_STATUS_REG &= ~SP_STATUS_BROKE; }
|
||||
if ( ( state->RegModValue & SP_CLR_INTR ) != 0) {
|
||||
MI_INTR_REG &= ~MI_INTR_SP;
|
||||
CheckInterrupts(state);
|
||||
}
|
||||
|
||||
if ( ( state->RegModValue & SP_CLR_SSTEP ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SSTEP; }
|
||||
if ( ( state->RegModValue & SP_SET_SSTEP ) != 0) { SP_STATUS_REG |= SP_STATUS_SSTEP; }
|
||||
if ( ( state->RegModValue & SP_CLR_INTR_BREAK ) != 0) { SP_STATUS_REG &= ~SP_STATUS_INTR_BREAK; }
|
||||
if ( ( state->RegModValue & SP_SET_INTR_BREAK ) != 0) { SP_STATUS_REG |= SP_STATUS_INTR_BREAK; }
|
||||
if ( ( state->RegModValue & SP_CLR_SIG0 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG0; }
|
||||
if ( ( state->RegModValue & SP_SET_SIG0 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG0; }
|
||||
if ( ( state->RegModValue & SP_CLR_SIG1 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG1; }
|
||||
if ( ( state->RegModValue & SP_SET_SIG1 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG1; }
|
||||
if ( ( state->RegModValue & SP_CLR_SIG2 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG2; }
|
||||
if ( ( state->RegModValue & SP_SET_SIG2 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG2; }
|
||||
if ( ( state->RegModValue & SP_CLR_SIG3 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG3; }
|
||||
if ( ( state->RegModValue & SP_SET_SIG3 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG3; }
|
||||
if ( ( state->RegModValue & SP_CLR_SIG4 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG4; }
|
||||
if ( ( state->RegModValue & SP_SET_SIG4 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG4; }
|
||||
if ( ( state->RegModValue & SP_CLR_SIG5 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG5; }
|
||||
if ( ( state->RegModValue & SP_SET_SIG5 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG5; }
|
||||
if ( ( state->RegModValue & SP_CLR_SIG6 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG6; }
|
||||
if ( ( state->RegModValue & SP_SET_SIG6 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG6; }
|
||||
if ( ( state->RegModValue & SP_CLR_SIG7 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG7; }
|
||||
if ( ( state->RegModValue & SP_SET_SIG7 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG7; }
|
||||
|
||||
RunRsp(state);
|
||||
|
||||
}
|
||||
|
||||
void UpdateCurrentHalfLine (usf_state_t * state) {
|
||||
if (state->Timers->Timer < 0) {
|
||||
state->HalfLine = 0;
|
||||
return;
|
||||
}
|
||||
state->HalfLine = (state->Timers->Timer / 1500);
|
||||
state->HalfLine &= ~1;
|
||||
state->HalfLine += state->ViFieldNumber;
|
||||
}
|
||||
|
||||
void SetFpuLocations (usf_state_t * state) {
|
||||
int count;
|
||||
|
||||
if ((STATUS_REGISTER & STATUS_FR) == 0) {
|
||||
for (count = 0; count < 32; count ++) {
|
||||
state->FPRFloatLocation[count] = (void *)(&state->FPR[count >> 1].W[count & 1]);
|
||||
//state->FPRDoubleLocation[count] = state->FPRFloatLocation[count];
|
||||
state->FPRDoubleLocation[count] = (void *)(&state->FPR[count >> 1].DW);
|
||||
}
|
||||
} else {
|
||||
for (count = 0; count < 32; count ++) {
|
||||
state->FPRFloatLocation[count] = (void *)(&state->FPR[count].W[1]);
|
||||
//state->FPRFloatLocation[count] = (void *)(&state->FPR[count].W[1]);
|
||||
//state->FPRDoubleLocation[count] = state->FPRFloatLocation[count];
|
||||
state->FPRDoubleLocation[count] = (void *)(&state->FPR[count].DW);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,378 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef REGISTERS_H
|
||||
#define REGISTERS_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define INDEX_REGISTER state->CP0[0]
|
||||
#define RANDOM_REGISTER state->CP0[1]
|
||||
#define ENTRYLO0_REGISTER state->CP0[2]
|
||||
#define ENTRYLO1_REGISTER state->CP0[3]
|
||||
#define CONTEXT_REGISTER state->CP0[4]
|
||||
#define PAGE_MASK_REGISTER state->CP0[5]
|
||||
#define WIRED_REGISTER state->CP0[6]
|
||||
#define BAD_VADDR_REGISTER state->CP0[8]
|
||||
#define COUNT_REGISTER state->CP0[9]
|
||||
#define ENTRYHI_REGISTER state->CP0[10]
|
||||
#define COMPARE_REGISTER state->CP0[11]
|
||||
#define STATUS_REGISTER state->CP0[12]
|
||||
#define CAUSE_REGISTER state->CP0[13]
|
||||
#define EPC_REGISTER state->CP0[14]
|
||||
#define CONFIG_REGISTER state->CP0[16]
|
||||
#define TAGLO_REGISTER state->CP0[28]
|
||||
#define TAGHI_REGISTER state->CP0[29]
|
||||
#define ERROREPC_REGISTER state->CP0[30]
|
||||
#define FAKE_CAUSE_REGISTER state->CP0[32]
|
||||
|
||||
#define COMPARE_REGISTER_NO 11
|
||||
#define STATUS_REGISTER_NO 12
|
||||
#define CAUSE_REGISTER_NO 13
|
||||
|
||||
#define REVISION_REGISTER state->FPCR[0]
|
||||
#define FSTATUS_REGISTER state->FPCR[31]
|
||||
|
||||
#define GPR_S0 state->GPR[16]
|
||||
#define GPR_S1 state->GPR[17]
|
||||
#define GPR_S2 state->GPR[18]
|
||||
#define GPR_S3 state->GPR[19]
|
||||
#define GPR_S4 state->GPR[20]
|
||||
#define GPR_S5 state->GPR[21]
|
||||
#define GPR_S6 state->GPR[22]
|
||||
#define GPR_S7 state->GPR[23]
|
||||
#define GPR_SP state->GPR[29]
|
||||
#define GPR_RA state->GPR[31]
|
||||
|
||||
#define RDRAM_CONFIG_REG state->RegRDRAM[0]
|
||||
#define RDRAM_DEVICE_TYPE_REG state->RegRDRAM[0]
|
||||
#define RDRAM_DEVICE_ID_REG state->RegRDRAM[1]
|
||||
#define RDRAM_DELAY_REG state->RegRDRAM[2]
|
||||
#define RDRAM_MODE_REG state->RegRDRAM[3]
|
||||
#define RDRAM_REF_INTERVAL_REG state->RegRDRAM[4]
|
||||
#define RDRAM_REF_ROW_REG state->RegRDRAM[5]
|
||||
#define RDRAM_RAS_INTERVAL_REG state->RegRDRAM[6]
|
||||
#define RDRAM_MIN_INTERVAL_REG state->RegRDRAM[7]
|
||||
#define RDRAM_ADDR_SELECT_REG state->RegRDRAM[8]
|
||||
#define RDRAM_DEVICE_MANUF_REG state->RegRDRAM[9]
|
||||
|
||||
#define SP_MEM_ADDR_REG state->RegSP[0]
|
||||
#define SP_DRAM_ADDR_REG state->RegSP[1]
|
||||
#define SP_RD_LEN_REG state->RegSP[2]
|
||||
#define SP_WR_LEN_REG state->RegSP[3]
|
||||
#define SP_STATUS_REG state->RegSP[4]
|
||||
#define SP_DMA_FULL_REG state->RegSP[5]
|
||||
#define SP_DMA_BUSY_REG state->RegSP[6]
|
||||
#define SP_SEMAPHORE_REG state->RegSP[7]
|
||||
#define SP_PC_REG state->RegSP[8]
|
||||
#define SP_IBIST_REG state->RegSP[9]
|
||||
|
||||
#define DPC_START_REG state->RegDPC[0]
|
||||
#define DPC_END_REG state->RegDPC[1]
|
||||
#define DPC_CURRENT_REG state->RegDPC[2]
|
||||
#define DPC_STATUS_REG state->RegDPC[3]
|
||||
#define DPC_CLOCK_REG state->RegDPC[4]
|
||||
#define DPC_BUFBUSY_REG state->RegDPC[5]
|
||||
#define DPC_PIPEBUSY_REG state->RegDPC[6]
|
||||
#define DPC_TMEM_REG state->RegDPC[7]
|
||||
|
||||
#define MI_INIT_MODE_REG state->RegMI[0]
|
||||
#define MI_MODE_REG state->RegMI[0]
|
||||
#define MI_VERSION_REG state->RegMI[1]
|
||||
#define MI_NOOP_REG state->RegMI[1]
|
||||
#define MI_INTR_REG state->RegMI[2]
|
||||
#define MI_INTR_MASK_REG state->RegMI[3]
|
||||
|
||||
#define VI_STATUS_REG state->RegVI[0]
|
||||
#define VI_CONTROL_REG state->RegVI[0]
|
||||
#define VI_ORIGIN_REG state->RegVI[1]
|
||||
#define VI_DRAM_ADDR_REG state->RegVI[1]
|
||||
#define VI_WIDTH_REG state->RegVI[2]
|
||||
#define VI_H_WIDTH_REG state->RegVI[2]
|
||||
#define VI_INTR_REG state->RegVI[3]
|
||||
#define VI_V_INTR_REG state->RegVI[3]
|
||||
#define VI_CURRENT_REG state->RegVI[4]
|
||||
#define VI_V_CURRENT_LINE_REG state->RegVI[4]
|
||||
#define VI_BURST_REG state->RegVI[5]
|
||||
#define VI_TIMING_REG state->RegVI[5]
|
||||
#define VI_V_SYNC_REG state->RegVI[6]
|
||||
#define VI_H_SYNC_REG state->RegVI[7]
|
||||
#define VI_LEAP_REG state->RegVI[8]
|
||||
#define VI_H_SYNC_LEAP_REG state->RegVI[8]
|
||||
#define VI_H_START_REG state->RegVI[9]
|
||||
#define VI_H_VIDEO_REG state->RegVI[9]
|
||||
#define VI_V_START_REG state->RegVI[10]
|
||||
#define VI_V_VIDEO_REG state->RegVI[10]
|
||||
#define VI_V_BURST_REG state->RegVI[11]
|
||||
#define VI_X_SCALE_REG state->RegVI[12]
|
||||
#define VI_Y_SCALE_REG state->RegVI[13]
|
||||
|
||||
#define AI_DRAM_ADDR_REG state->RegAI[0]
|
||||
#define AI_LEN_REG state->RegAI[1]
|
||||
#define AI_CONTROL_REG state->RegAI[2]
|
||||
#define AI_STATUS_REG state->RegAI[3]
|
||||
#define AI_DACRATE_REG state->RegAI[4]
|
||||
#define AI_BITRATE_REG state->RegAI[5]
|
||||
|
||||
#define PI_DRAM_ADDR_REG state->RegPI[0]
|
||||
#define PI_CART_ADDR_REG state->RegPI[1]
|
||||
#define PI_RD_LEN_REG state->RegPI[2]
|
||||
#define PI_WR_LEN_REG state->RegPI[3]
|
||||
#define PI_STATUS_REG state->RegPI[4]
|
||||
#define PI_BSD_DOM1_LAT_REG state->RegPI[5]
|
||||
#define PI_DOMAIN1_REG state->RegPI[5]
|
||||
#define PI_BSD_DOM1_PWD_REG state->RegPI[6]
|
||||
#define PI_BSD_DOM1_PGS_REG state->RegPI[7]
|
||||
#define PI_BSD_DOM1_RLS_REG state->RegPI[8]
|
||||
#define PI_BSD_DOM2_LAT_REG state->RegPI[9]
|
||||
#define PI_DOMAIN2_REG state->RegPI[9]
|
||||
#define PI_BSD_DOM2_PWD_REG state->RegPI[10]
|
||||
#define PI_BSD_DOM2_PGS_REG state->RegPI[11]
|
||||
#define PI_BSD_DOM2_RLS_REG state->RegPI[12]
|
||||
|
||||
#define RI_MODE_REG state->RegRI[0]
|
||||
#define RI_CONFIG_REG state->RegRI[1]
|
||||
#define RI_CURRENT_LOAD_REG state->RegRI[2]
|
||||
#define RI_SELECT_REG state->RegRI[3]
|
||||
#define RI_COUNT_REG state->RegRI[4]
|
||||
#define RI_REFRESH_REG state->RegRI[4]
|
||||
#define RI_LATENCY_REG state->RegRI[5]
|
||||
#define RI_RERROR_REG state->RegRI[6]
|
||||
#define RI_WERROR_REG state->RegRI[7]
|
||||
|
||||
#define SI_DRAM_ADDR_REG state->RegSI[0]
|
||||
#define SI_PIF_ADDR_RD64B_REG state->RegSI[1]
|
||||
#define SI_PIF_ADDR_WR64B_REG state->RegSI[2]
|
||||
#define SI_STATUS_REG state->RegSI[3]
|
||||
|
||||
#define STATUS_IE 0x00000001
|
||||
#define STATUS_EXL 0x00000002
|
||||
#define STATUS_ERL 0x00000004
|
||||
#define STATUS_IP0 0x00000100
|
||||
#define STATUS_IP1 0x00000200
|
||||
#define STATUS_IP2 0x00000400
|
||||
#define STATUS_IP3 0x00000800
|
||||
#define STATUS_IP4 0x00001000
|
||||
#define STATUS_IP5 0x00002000
|
||||
#define STATUS_IP6 0x00004000
|
||||
#define STATUS_IP7 0x00008000
|
||||
#define STATUS_BEV 0x00400000
|
||||
#define STATUS_FR 0x04000000
|
||||
#define STATUS_CU0 0x10000000
|
||||
#define STATUS_CU1 0x20000000
|
||||
|
||||
#define CAUSE_EXC_CODE 0xFF
|
||||
#define CAUSE_IP0 0x100
|
||||
#define CAUSE_IP1 0x200
|
||||
#define CAUSE_IP2 0x400
|
||||
#define CAUSE_IP3 0x800
|
||||
#define CAUSE_IP4 0x1000
|
||||
#define CAUSE_IP5 0x2000
|
||||
#define CAUSE_IP6 0x4000
|
||||
#define CAUSE_IP7 0x8000
|
||||
#define CAUSE_BD 0x80000000
|
||||
|
||||
#define SP_CLR_HALT 0x00001 /* Bit 0: clear halt */
|
||||
#define SP_SET_HALT 0x00002 /* Bit 1: set halt */
|
||||
#define SP_CLR_BROKE 0x00004 /* Bit 2: clear broke */
|
||||
#define SP_CLR_INTR 0x00008 /* Bit 3: clear intr */
|
||||
#define SP_SET_INTR 0x00010 /* Bit 4: set intr */
|
||||
#define SP_CLR_SSTEP 0x00020 /* Bit 5: clear sstep */
|
||||
#define SP_SET_SSTEP 0x00040 /* Bit 6: set sstep */
|
||||
#define SP_CLR_INTR_BREAK 0x00080 /* Bit 7: clear intr on break */
|
||||
#define SP_SET_INTR_BREAK 0x00100 /* Bit 8: set intr on break */
|
||||
#define SP_CLR_SIG0 0x00200 /* Bit 9: clear signal 0 */
|
||||
#define SP_SET_SIG0 0x00400 /* Bit 10: set signal 0 */
|
||||
#define SP_CLR_SIG1 0x00800 /* Bit 11: clear signal 1 */
|
||||
#define SP_SET_SIG1 0x01000 /* Bit 12: set signal 1 */
|
||||
#define SP_CLR_SIG2 0x02000 /* Bit 13: clear signal 2 */
|
||||
#define SP_SET_SIG2 0x04000 /* Bit 14: set signal 2 */
|
||||
#define SP_CLR_SIG3 0x08000 /* Bit 15: clear signal 3 */
|
||||
#define SP_SET_SIG3 0x10000 /* Bit 16: set signal 3 */
|
||||
#define SP_CLR_SIG4 0x20000 /* Bit 17: clear signal 4 */
|
||||
#define SP_SET_SIG4 0x40000 /* Bit 18: set signal 4 */
|
||||
#define SP_CLR_SIG5 0x80000 /* Bit 19: clear signal 5 */
|
||||
#define SP_SET_SIG5 0x100000 /* Bit 20: set signal 5 */
|
||||
#define SP_CLR_SIG6 0x200000 /* Bit 21: clear signal 6 */
|
||||
#define SP_SET_SIG6 0x400000 /* Bit 22: set signal 6 */
|
||||
#define SP_CLR_SIG7 0x800000 /* Bit 23: clear signal 7 */
|
||||
#define SP_SET_SIG7 0x1000000 /* Bit 24: set signal 7 */
|
||||
|
||||
#define SP_STATUS_HALT 0x001 /* Bit 0: halt */
|
||||
#define SP_STATUS_BROKE 0x002 /* Bit 1: broke */
|
||||
#define SP_STATUS_DMA_BUSY 0x004 /* Bit 2: dma busy */
|
||||
#define SP_STATUS_DMA_FULL 0x008 /* Bit 3: dma full */
|
||||
#define SP_STATUS_IO_FULL 0x010 /* Bit 4: io full */
|
||||
#define SP_STATUS_SSTEP 0x020 /* Bit 5: single step */
|
||||
#define SP_STATUS_INTR_BREAK 0x040 /* Bit 6: interrupt on break */
|
||||
#define SP_STATUS_SIG0 0x080 /* Bit 7: signal 0 set */
|
||||
#define SP_STATUS_SIG1 0x100 /* Bit 8: signal 1 set */
|
||||
#define SP_STATUS_SIG2 0x200 /* Bit 9: signal 2 set */
|
||||
#define SP_STATUS_SIG3 0x400 /* Bit 10: signal 3 set */
|
||||
#define SP_STATUS_SIG4 0x800 /* Bit 11: signal 4 set */
|
||||
#define SP_STATUS_SIG5 0x1000 /* Bit 12: signal 5 set */
|
||||
#define SP_STATUS_SIG6 0x2000 /* Bit 13: signal 6 set */
|
||||
#define SP_STATUS_SIG7 0x4000 /* Bit 14: signal 7 set */
|
||||
|
||||
#define DPC_CLR_XBUS_DMEM_DMA 0x0001 /* Bit 0: clear xbus_dmem_dma */
|
||||
#define DPC_SET_XBUS_DMEM_DMA 0x0002 /* Bit 1: set xbus_dmem_dma */
|
||||
#define DPC_CLR_FREEZE 0x0004 /* Bit 2: clear freeze */
|
||||
#define DPC_SET_FREEZE 0x0008 /* Bit 3: set freeze */
|
||||
#define DPC_CLR_FLUSH 0x0010 /* Bit 4: clear flush */
|
||||
#define DPC_SET_FLUSH 0x0020 /* Bit 5: set flush */
|
||||
#define DPC_CLR_TMEM_CTR 0x0040 /* Bit 6: clear tmem ctr */
|
||||
#define DPC_CLR_PIPE_CTR 0x0080 /* Bit 7: clear pipe ctr */
|
||||
#define DPC_CLR_CMD_CTR 0x0100 /* Bit 8: clear cmd ctr */
|
||||
#define DPC_CLR_CLOCK_CTR 0x0200 /* Bit 9: clear clock ctr */
|
||||
|
||||
#define DPC_STATUS_XBUS_DMEM_DMA 0x001 /* Bit 0: xbus_dmem_dma */
|
||||
#define DPC_STATUS_FREEZE 0x002 /* Bit 1: freeze */
|
||||
#define DPC_STATUS_FLUSH 0x004 /* Bit 2: flush */
|
||||
#define DPC_STATUS_START_GCLK 0x008 /* Bit 3: start gclk */
|
||||
#define DPC_STATUS_TMEM_BUSY 0x010 /* Bit 4: tmem busy */
|
||||
#define DPC_STATUS_PIPE_BUSY 0x020 /* Bit 5: pipe busy */
|
||||
#define DPC_STATUS_CMD_BUSY 0x040 /* Bit 6: cmd busy */
|
||||
#define DPC_STATUS_CBUF_READY 0x080 /* Bit 7: cbuf ready */
|
||||
#define DPC_STATUS_DMA_BUSY 0x100 /* Bit 8: dma busy */
|
||||
#define DPC_STATUS_END_VALID 0x200 /* Bit 9: end valid */
|
||||
#define DPC_STATUS_START_VALID 0x400 /* Bit 10: start valid */
|
||||
|
||||
#define MI_CLR_INIT 0x0080 /* Bit 7: clear init mode */
|
||||
#define MI_SET_INIT 0x0100 /* Bit 8: set init mode */
|
||||
#define MI_CLR_EBUS 0x0200 /* Bit 9: clear ebus test */
|
||||
#define MI_SET_EBUS 0x0400 /* Bit 10: set ebus test mode */
|
||||
#define MI_CLR_DP_INTR 0x0800 /* Bit 11: clear dp interrupt */
|
||||
#define MI_CLR_RDRAM 0x1000 /* Bit 12: clear RDRAM reg */
|
||||
#define MI_SET_RDRAM 0x2000 /* Bit 13: set RDRAM reg mode */
|
||||
|
||||
#define MI_MODE_INIT 0x0080 /* Bit 7: init mode */
|
||||
#define MI_MODE_EBUS 0x0100 /* Bit 8: ebus test mode */
|
||||
#define MI_MODE_RDRAM 0x0200 /* Bit 9: RDRAM reg mode */
|
||||
|
||||
#define MI_INTR_MASK_CLR_SP 0x0001 /* Bit 0: clear SP mask */
|
||||
#define MI_INTR_MASK_SET_SP 0x0002 /* Bit 1: set SP mask */
|
||||
#define MI_INTR_MASK_CLR_SI 0x0004 /* Bit 2: clear SI mask */
|
||||
#define MI_INTR_MASK_SET_SI 0x0008 /* Bit 3: set SI mask */
|
||||
#define MI_INTR_MASK_CLR_AI 0x0010 /* Bit 4: clear AI mask */
|
||||
#define MI_INTR_MASK_SET_AI 0x0020 /* Bit 5: set AI mask */
|
||||
#define MI_INTR_MASK_CLR_VI 0x0040 /* Bit 6: clear VI mask */
|
||||
#define MI_INTR_MASK_SET_VI 0x0080 /* Bit 7: set VI mask */
|
||||
#define MI_INTR_MASK_CLR_PI 0x0100 /* Bit 8: clear PI mask */
|
||||
#define MI_INTR_MASK_SET_PI 0x0200 /* Bit 9: set PI mask */
|
||||
#define MI_INTR_MASK_CLR_DP 0x0400 /* Bit 10: clear DP mask */
|
||||
#define MI_INTR_MASK_SET_DP 0x0800 /* Bit 11: set DP mask */
|
||||
|
||||
#define MI_INTR_MASK_SP 0x01 /* Bit 0: SP intr mask */
|
||||
#define MI_INTR_MASK_SI 0x02 /* Bit 1: SI intr mask */
|
||||
#define MI_INTR_MASK_AI 0x04 /* Bit 2: AI intr mask */
|
||||
#define MI_INTR_MASK_VI 0x08 /* Bit 3: VI intr mask */
|
||||
#define MI_INTR_MASK_PI 0x10 /* Bit 4: PI intr mask */
|
||||
#define MI_INTR_MASK_DP 0x20 /* Bit 5: DP intr mask */
|
||||
|
||||
#define MI_INTR_SP 0x01 /* Bit 0: SP intr */
|
||||
#define MI_INTR_SI 0x02 /* Bit 1: SI intr */
|
||||
#define MI_INTR_AI 0x04 /* Bit 2: AI intr */
|
||||
#define MI_INTR_VI 0x08 /* Bit 3: VI intr */
|
||||
#define MI_INTR_PI 0x10 /* Bit 4: PI intr */
|
||||
#define MI_INTR_DP 0x20 /* Bit 5: DP intr */
|
||||
|
||||
#define PI_STATUS_DMA_BUSY 0x01
|
||||
#define PI_STATUS_IO_BUSY 0x02
|
||||
#define PI_STATUS_ERROR 0x04
|
||||
|
||||
#define PI_SET_RESET 0x01
|
||||
#define PI_CLR_INTR 0x02
|
||||
|
||||
#define SI_STATUS_DMA_BUSY 0x0001
|
||||
#define SI_STATUS_RD_BUSY 0x0002
|
||||
#define SI_STATUS_DMA_ERROR 0x0008
|
||||
#define SI_STATUS_INTERRUPT 0x1000
|
||||
|
||||
#define FPCSR_FS 0x01000000 /* flush denorm to zero */
|
||||
#define FPCSR_C 0x00800000 /* condition bit */
|
||||
#define FPCSR_CE 0x00020000 /* cause: unimplemented operation */
|
||||
#define FPCSR_CV 0x00010000 /* cause: invalid operation */
|
||||
#define FPCSR_CZ 0x00008000 /* cause: division by zero */
|
||||
#define FPCSR_CO 0x00004000 /* cause: overflow */
|
||||
#define FPCSR_CU 0x00002000 /* cause: underflow */
|
||||
#define FPCSR_CI 0x00001000 /* cause: inexact operation */
|
||||
#define FPCSR_EV 0x00000800 /* enable: invalid operation */
|
||||
#define FPCSR_EZ 0x00000400 /* enable: division by zero */
|
||||
#define FPCSR_EO 0x00000200 /* enable: overflow */
|
||||
#define FPCSR_EU 0x00000100 /* enable: underflow */
|
||||
#define FPCSR_EI 0x00000080 /* enable: inexact operation */
|
||||
#define FPCSR_FV 0x00000040 /* flag: invalid operation */
|
||||
#define FPCSR_FZ 0x00000020 /* flag: division by zero */
|
||||
#define FPCSR_FO 0x00000010 /* flag: overflow */
|
||||
#define FPCSR_FU 0x00000008 /* flag: underflow */
|
||||
#define FPCSR_FI 0x00000004 /* flag: inexact operation */
|
||||
#define FPCSR_RM_MASK 0x00000003 /* rounding mode mask */
|
||||
#define FPCSR_RM_RN 0x00000000 /* round to nearest */
|
||||
#define FPCSR_RM_RZ 0x00000001 /* round to zero */
|
||||
#define FPCSR_RM_RP 0x00000002 /* round to positive infinity */
|
||||
#define FPCSR_RM_RM 0x00000003 /* round to negative infinity */
|
||||
|
||||
#define FPR_Type(Reg) (Reg) == R4300i_COP1_S ? "S" : (Reg) == R4300i_COP1_D ? "D" :\
|
||||
(Reg) == R4300i_COP1_W ? "W" : "L"
|
||||
|
||||
typedef struct {
|
||||
uint32_t PROGRAM_COUNTER;
|
||||
MIPS_DWORD GPR[32];
|
||||
MIPS_DWORD FPR[32];
|
||||
uint32_t CP0[33];
|
||||
uint32_t FPCR[32];
|
||||
MIPS_DWORD HI;
|
||||
MIPS_DWORD LO;
|
||||
uint32_t RDRAM[10];
|
||||
uint32_t SP[10];
|
||||
uint32_t DPC[10];
|
||||
uint32_t MI[4];
|
||||
uint32_t VI[14];
|
||||
uint32_t AI[6];
|
||||
uint32_t PI[13];
|
||||
uint32_t RI[8];
|
||||
uint32_t SI[4];
|
||||
int8_t PIF_Ram[0x40];
|
||||
} N64_REGISTERS;
|
||||
|
||||
enum FPU_Format {
|
||||
FPU_Unkown,FPU_Dword, FPU_Qword, FPU_Float, FPU_Double
|
||||
};
|
||||
|
||||
enum FPU_RoundingModel {
|
||||
RoundUnknown, RoundDefault, RoundTruncate, RoundNearest, RoundDown, RoundUp
|
||||
};
|
||||
|
||||
void ChangeMiIntrMask ( usf_state_t * );
|
||||
void ChangeMiModeReg ( usf_state_t * );
|
||||
void ChangeSpStatus ( usf_state_t * );
|
||||
void InitalizeR4300iRegisters ( usf_state_t * );
|
||||
void UpdateCurrentHalfLine ( usf_state_t * );
|
||||
void SetFpuLocations ( usf_state_t * );
|
||||
|
||||
void SetupRegisters(usf_state_t *, N64_REGISTERS * n64_Registers);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef RSP_H
|
||||
#define RSP_H
|
||||
|
||||
#include "usf.h"
|
||||
#include "usf_internal.h"
|
||||
|
||||
void real_run_rsp(usf_state_t *, uint32_t cycles);
|
||||
|
||||
int32_t init_rsp(usf_state_t *);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,60 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.12.04 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
/*
|
||||
* This is only here for people using modern Microsoft compilers.
|
||||
* Usually the default warning level complains over "deprecated" CRT methods.
|
||||
* It's basically Microsoft's way of saying they're better than everyone.
|
||||
*/
|
||||
|
||||
#define MINIMUM_MESSAGE_PRIORITY 1
|
||||
#define EXTERN_COMMAND_LIST_GBI
|
||||
#define EXTERN_COMMAND_LIST_ABI
|
||||
#define SEMAPHORE_LOCK_CORRECTIONS
|
||||
#define WAIT_FOR_CPU_HOST
|
||||
#define EMULATE_STATIC_PC
|
||||
|
||||
#ifdef EMULATE_STATIC_PC
|
||||
#define CONTINUE {continue;}
|
||||
#define JUMP {goto BRANCH;}
|
||||
#else
|
||||
#define CONTINUE {break;}
|
||||
#define JUMP {break;}
|
||||
#endif
|
||||
|
||||
#if (0)
|
||||
#define SP_EXECUTE_LOG
|
||||
#define VU_EMULATE_SCALAR_ACCUMULATOR_READ
|
||||
#endif
|
||||
|
||||
#define CFG_HLE_GFX (0)
|
||||
#define CFG_HLE_AUD (0)
|
||||
#define CFG_HLE_VID (0) /* reserved/unused */
|
||||
#define CFG_HLE_JPG (0) /* unused */
|
||||
#define CFG_QUEUE_E_DRAM (0)
|
||||
#define CFG_QUEUE_E_DMEM (0)
|
||||
#define CFG_QUEUE_E_IMEM (0)
|
||||
/*
|
||||
* Note: This never actually made it into the configuration system.
|
||||
* Instead, DMEM and IMEM are always exported on every call to DllConfig().
|
||||
*/
|
||||
|
||||
/*
|
||||
* Special switches.
|
||||
* (generally for correcting RSP clock behavior on Project64 2.x)
|
||||
* Also includes RSP register states debugger.
|
||||
*/
|
||||
#define CFG_WAIT_FOR_CPU_HOST (1)
|
||||
#define CFG_MEND_SEMAPHORE_LOCK (0)
|
||||
#define CFG_TRACE_RSP_REGISTERS (0)
|
|
@ -0,0 +1,475 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.12.11 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "rsp.h"
|
||||
|
||||
#include "su.h"
|
||||
#include "vu/vu.h"
|
||||
|
||||
#define FIT_IMEM(PC) (PC & 0xFFF & 0xFFC)
|
||||
|
||||
NOINLINE void run_task(usf_state_t * state)
|
||||
{
|
||||
register int PC;
|
||||
|
||||
if (CFG_WAIT_FOR_CPU_HOST != 0)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
state->MFC0_count[i] = 0;
|
||||
}
|
||||
PC = FIT_IMEM(SP_PC_REG);
|
||||
while ((SP_STATUS_REG & 0x00000001) == 0x00000000)
|
||||
{
|
||||
register uint32_t inst;
|
||||
|
||||
inst = *(uint32_t *)(state->IMEM + FIT_IMEM(PC));
|
||||
#ifdef EMULATE_STATIC_PC
|
||||
PC = (PC + 0x004);
|
||||
EX:
|
||||
#endif
|
||||
#ifdef SP_EXECUTE_LOG
|
||||
step_SP_commands(inst);
|
||||
#endif
|
||||
if (inst >> 25 == 0x25) /* is a VU instruction */
|
||||
{
|
||||
const int opcode = inst % 64; /* inst.R.func */
|
||||
const int vd = (inst & 0x000007FF) >> 6; /* inst.R.sa */
|
||||
const int vs = (unsigned short)(inst) >> 11; /* inst.R.rd */
|
||||
const int vt = (inst >> 16) & 31; /* inst.R.rt */
|
||||
const int e = (inst >> 21) & 0xF; /* rs & 0xF */
|
||||
|
||||
COP2_C2[opcode](state, vd, vs, vt, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int op = inst >> 26;
|
||||
const int rs = inst >> 21; /* &= 31 */
|
||||
const int rt = (inst >> 16) & 31;
|
||||
const int rd = (unsigned short)(inst) >> 11;
|
||||
const int element = (inst & 0x000007FF) >> 7;
|
||||
const int base = (inst >> 21) & 31;
|
||||
|
||||
#if (0)
|
||||
state->SR[0] = 0x00000000; /* already handled on per-instruction basis */
|
||||
#endif
|
||||
switch (op)
|
||||
{
|
||||
signed int offset;
|
||||
register uint32_t addr;
|
||||
|
||||
case 000: /* SPECIAL */
|
||||
switch (inst % 64)
|
||||
{
|
||||
case 000: /* SLL */
|
||||
state->SR[rd] = state->SR[rt] << MASK_SA(inst >> 6);
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 002: /* SRL */
|
||||
state->SR[rd] = (unsigned)(state->SR[rt]) >> MASK_SA(inst >> 6);
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 003: /* SRA */
|
||||
state->SR[rd] = (signed)(state->SR[rt]) >> MASK_SA(inst >> 6);
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 004: /* SLLV */
|
||||
state->SR[rd] = state->SR[rt] << MASK_SA(state->SR[rs]);
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 006: /* SRLV */
|
||||
state->SR[rd] = (unsigned)(state->SR[rt]) >> MASK_SA(state->SR[rs]);
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 007: /* SRAV */
|
||||
state->SR[rd] = (signed)(state->SR[rt]) >> MASK_SA(state->SR[rs]);
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 011: /* JALR */
|
||||
state->SR[rd] = (PC + LINK_OFF) & 0x00000FFC;
|
||||
state->SR[0] = 0x00000000;
|
||||
case 010: /* JR */
|
||||
set_PC(state, state->SR[rs]);
|
||||
JUMP
|
||||
case 015: /* BREAK */
|
||||
SP_STATUS_REG |= 0x00000003; /* BROKE | HALT */
|
||||
if (SP_STATUS_REG & 0x00000040)
|
||||
{ /* SP_STATUS_INTR_BREAK */
|
||||
MI_INTR_REG |= 0x00000001;
|
||||
CheckInterrupts(state);
|
||||
}
|
||||
CONTINUE
|
||||
case 040: /* ADD */
|
||||
case 041: /* ADDU */
|
||||
state->SR[rd] = state->SR[rs] + state->SR[rt];
|
||||
state->SR[0] = 0x00000000; /* needed for Rareware ucodes */
|
||||
CONTINUE
|
||||
case 042: /* SUB */
|
||||
case 043: /* SUBU */
|
||||
state->SR[rd] = state->SR[rs] - state->SR[rt];
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 044: /* AND */
|
||||
state->SR[rd] = state->SR[rs] & state->SR[rt];
|
||||
state->SR[0] = 0x00000000; /* needed for Rareware ucodes */
|
||||
CONTINUE
|
||||
case 045: /* OR */
|
||||
state->SR[rd] = state->SR[rs] | state->SR[rt];
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 046: /* XOR */
|
||||
state->SR[rd] = state->SR[rs] ^ state->SR[rt];
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 047: /* NOR */
|
||||
state->SR[rd] = ~(state->SR[rs] | state->SR[rt]);
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 052: /* SLT */
|
||||
state->SR[rd] = ((signed)(state->SR[rs]) < (signed)(state->SR[rt]));
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 053: /* SLTU */
|
||||
state->SR[rd] = ((unsigned)(state->SR[rs]) < (unsigned)(state->SR[rt]));
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
default:
|
||||
res_S(state);
|
||||
CONTINUE
|
||||
}
|
||||
CONTINUE
|
||||
case 001: /* REGIMM */
|
||||
switch (rt)
|
||||
{
|
||||
case 020: /* BLTZAL */
|
||||
state->SR[31] = (PC + LINK_OFF) & 0x00000FFC;
|
||||
case 000: /* BLTZ */
|
||||
if (!(state->SR[base] < 0))
|
||||
CONTINUE
|
||||
set_PC(state, PC + 4*inst + SLOT_OFF);
|
||||
JUMP
|
||||
case 021: /* BGEZAL */
|
||||
state->SR[31] = (PC + LINK_OFF) & 0x00000FFC;
|
||||
case 001: /* BGEZ */
|
||||
if (!(state->SR[base] >= 0))
|
||||
CONTINUE
|
||||
set_PC(state, PC + 4*inst + SLOT_OFF);
|
||||
JUMP
|
||||
default:
|
||||
res_S(state);
|
||||
CONTINUE
|
||||
}
|
||||
CONTINUE
|
||||
case 003: /* JAL */
|
||||
state->SR[31] = (PC + LINK_OFF) & 0x00000FFC;
|
||||
case 002: /* J */
|
||||
set_PC(state, 4*inst);
|
||||
JUMP
|
||||
case 004: /* BEQ */
|
||||
if (!(state->SR[base] == state->SR[rt]))
|
||||
CONTINUE
|
||||
set_PC(state, PC + 4*inst + SLOT_OFF);
|
||||
JUMP
|
||||
case 005: /* BNE */
|
||||
if (!(state->SR[base] != state->SR[rt]))
|
||||
CONTINUE
|
||||
set_PC(state, PC + 4*inst + SLOT_OFF);
|
||||
JUMP
|
||||
case 006: /* BLEZ */
|
||||
if (!((signed)state->SR[base] <= 0x00000000))
|
||||
CONTINUE
|
||||
set_PC(state, PC + 4*inst + SLOT_OFF);
|
||||
JUMP
|
||||
case 007: /* BGTZ */
|
||||
if (!((signed)state->SR[base] > 0x00000000))
|
||||
CONTINUE
|
||||
set_PC(state, PC + 4*inst + SLOT_OFF);
|
||||
JUMP
|
||||
case 010: /* ADDI */
|
||||
case 011: /* ADDIU */
|
||||
state->SR[rt] = state->SR[base] + (signed short)(inst);
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 012: /* SLTI */
|
||||
state->SR[rt] = ((signed)(state->SR[base]) < (signed short)(inst));
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 013: /* SLTIU */
|
||||
state->SR[rt] = ((unsigned)(state->SR[base]) < (unsigned short)(inst));
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 014: /* ANDI */
|
||||
state->SR[rt] = state->SR[base] & (unsigned short)(inst);
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 015: /* ORI */
|
||||
state->SR[rt] = state->SR[base] | (unsigned short)(inst);
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 016: /* XORI */
|
||||
state->SR[rt] = state->SR[base] ^ (unsigned short)(inst);
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 017: /* LUI */
|
||||
state->SR[rt] = inst << 16;
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 020: /* COP0 */
|
||||
switch (base)
|
||||
{
|
||||
case 000: /* MFC0 */
|
||||
MFC0(state, rt, rd & 0xF);
|
||||
CONTINUE
|
||||
case 004: /* MTC0 */
|
||||
MTC0[rd & 0xF](state, rt);
|
||||
CONTINUE
|
||||
default:
|
||||
res_S(state);
|
||||
CONTINUE
|
||||
}
|
||||
CONTINUE
|
||||
case 022: /* COP2 */
|
||||
switch (base)
|
||||
{
|
||||
case 000: /* MFC2 */
|
||||
MFC2(state, rt, rd, element);
|
||||
CONTINUE
|
||||
case 002: /* CFC2 */
|
||||
CFC2(state, rt, rd);
|
||||
CONTINUE
|
||||
case 004: /* MTC2 */
|
||||
MTC2(state, rt, rd, element);
|
||||
CONTINUE
|
||||
case 006: /* CTC2 */
|
||||
CTC2(state, rt, rd);
|
||||
CONTINUE
|
||||
default:
|
||||
res_S(state);
|
||||
CONTINUE
|
||||
}
|
||||
CONTINUE
|
||||
case 040: /* LB */
|
||||
offset = (signed short)(inst);
|
||||
addr = (state->SR[base] + offset) & 0x00000FFF;
|
||||
state->SR[rt] = state->DMEM[BES(addr)];
|
||||
state->SR[rt] = (signed char)(state->SR[rt]);
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 041: /* LH */
|
||||
offset = (signed short)(inst);
|
||||
addr = (state->SR[base] + offset) & 0x00000FFF;
|
||||
if (addr%0x004 == 0x003)
|
||||
{
|
||||
SR_B(rt, 2) = state->DMEM[addr - BES(0x000)];
|
||||
addr = (addr + 0x00000001) & 0x00000FFF;
|
||||
SR_B(rt, 3) = state->DMEM[addr + BES(0x000)];
|
||||
state->SR[rt] = (signed short)(state->SR[rt]);
|
||||
}
|
||||
else
|
||||
{
|
||||
addr -= HES(0x000)*(addr%0x004 - 1);
|
||||
state->SR[rt] = *(signed short *)(state->DMEM + addr);
|
||||
}
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 043: /* LW */
|
||||
offset = (signed short)(inst);
|
||||
addr = (state->SR[base] + offset) & 0x00000FFF;
|
||||
if (addr%0x004 != 0x000)
|
||||
ULW(state, rt, addr);
|
||||
else
|
||||
state->SR[rt] = *(int32_t *)(state->DMEM + addr);
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 044: /* LBU */
|
||||
offset = (signed short)(inst);
|
||||
addr = (state->SR[base] + offset) & 0x00000FFF;
|
||||
state->SR[rt] = state->DMEM[BES(addr)];
|
||||
state->SR[rt] = (unsigned char)(state->SR[rt]);
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 045: /* LHU */
|
||||
offset = (signed short)(inst);
|
||||
addr = (state->SR[base] + offset) & 0x00000FFF;
|
||||
if (addr%0x004 == 0x003)
|
||||
{
|
||||
SR_B(rt, 2) = state->DMEM[addr - BES(0x000)];
|
||||
addr = (addr + 0x00000001) & 0x00000FFF;
|
||||
SR_B(rt, 3) = state->DMEM[addr + BES(0x000)];
|
||||
state->SR[rt] = (unsigned short)(state->SR[rt]);
|
||||
}
|
||||
else
|
||||
{
|
||||
addr -= HES(0x000)*(addr%0x004 - 1);
|
||||
state->SR[rt] = *(unsigned short *)(state->DMEM + addr);
|
||||
}
|
||||
state->SR[0] = 0x00000000;
|
||||
CONTINUE
|
||||
case 050: /* SB */
|
||||
offset = (signed short)(inst);
|
||||
addr = (state->SR[base] + offset) & 0x00000FFF;
|
||||
state->DMEM[BES(addr)] = (unsigned char)(state->SR[rt]);
|
||||
CONTINUE
|
||||
case 051: /* SH */
|
||||
offset = (signed short)(inst);
|
||||
addr = (state->SR[base] + offset) & 0x00000FFF;
|
||||
if (addr%0x004 == 0x003)
|
||||
{
|
||||
state->DMEM[addr - BES(0x000)] = SR_B(rt, 2);
|
||||
addr = (addr + 0x00000001) & 0x00000FFF;
|
||||
state->DMEM[addr + BES(0x000)] = SR_B(rt, 3);
|
||||
CONTINUE
|
||||
}
|
||||
addr -= HES(0x000)*(addr%0x004 - 1);
|
||||
*(short *)(state->DMEM + addr) = (short)(state->SR[rt]);
|
||||
CONTINUE
|
||||
case 053: /* SW */
|
||||
offset = (signed short)(inst);
|
||||
addr = (state->SR[base] + offset) & 0x00000FFF;
|
||||
if (addr%0x004 != 0x000)
|
||||
USW(state, rt, addr);
|
||||
else
|
||||
*(int32_t *)(state->DMEM + addr) = state->SR[rt];
|
||||
CONTINUE
|
||||
case 062: /* LWC2 */
|
||||
offset = SE(inst, 6);
|
||||
switch (rd)
|
||||
{
|
||||
case 000: /* LBV */
|
||||
LBV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 001: /* LSV */
|
||||
LSV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 002: /* LLV */
|
||||
LLV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 003: /* LDV */
|
||||
LDV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 004: /* LQV */
|
||||
LQV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 005: /* LRV */
|
||||
LRV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 006: /* LPV */
|
||||
LPV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 007: /* LUV */
|
||||
LUV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 010: /* LHV */
|
||||
LHV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 011: /* LFV */
|
||||
LFV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 013: /* LTV */
|
||||
LTV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
default:
|
||||
res_S(state);
|
||||
CONTINUE
|
||||
}
|
||||
CONTINUE
|
||||
case 072: /* SWC2 */
|
||||
offset = SE(inst, 6);
|
||||
switch (rd)
|
||||
{
|
||||
case 000: /* SBV */
|
||||
SBV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 001: /* SSV */
|
||||
SSV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 002: /* SLV */
|
||||
SLV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 003: /* SDV */
|
||||
SDV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 004: /* SQV */
|
||||
SQV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 005: /* SRV */
|
||||
SRV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 006: /* SPV */
|
||||
SPV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 007: /* SUV */
|
||||
SUV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 010: /* SHV */
|
||||
SHV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 011: /* SFV */
|
||||
SFV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 012: /* SWV */
|
||||
SWV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
case 013: /* STV */
|
||||
STV(state, rt, element, offset, base);
|
||||
CONTINUE
|
||||
default:
|
||||
res_S(state);
|
||||
CONTINUE
|
||||
}
|
||||
CONTINUE
|
||||
default:
|
||||
res_S(state);
|
||||
CONTINUE
|
||||
}
|
||||
}
|
||||
#ifndef EMULATE_STATIC_PC
|
||||
if (state->stage == 2) /* branch phase of scheduler */
|
||||
{
|
||||
state->stage = 0*stage;
|
||||
PC = state->temp_PC & 0x00000FFC;
|
||||
SP_PC_REG = state->temp_PC;
|
||||
}
|
||||
else
|
||||
{
|
||||
state->stage = 2*state->stage; /* next IW in branch delay slot? */
|
||||
PC = (PC + 0x004) & 0xFFC;
|
||||
SP_PC_REG = 0x04001000 + PC;
|
||||
}
|
||||
continue;
|
||||
#else
|
||||
continue;
|
||||
BRANCH:
|
||||
inst = *(uint32_t *)(state->IMEM + FIT_IMEM(PC));
|
||||
PC = state->temp_PC & 0x00000FFC;
|
||||
goto EX;
|
||||
#endif
|
||||
}
|
||||
SP_PC_REG = 0x04001000 | FIT_IMEM(PC);
|
||||
if (SP_STATUS_REG & 0x00000002) /* normal exit, from executing BREAK */
|
||||
return;
|
||||
else if (MI_INTR_REG & 0x00000001) /* interrupt set by MTC0 to break */
|
||||
CheckInterrupts(state);
|
||||
else if (CFG_WAIT_FOR_CPU_HOST != 0) /* plugin system hack to re-sync */
|
||||
{}
|
||||
else if (SP_SEMAPHORE_REG != 0x00000000) /* semaphore lock fixes */
|
||||
{}
|
||||
else /* ??? unknown, possibly external intervention from CPU memory map */
|
||||
{
|
||||
message("SP_SET_HALT", 3);
|
||||
return;
|
||||
}
|
||||
SP_STATUS_REG &= ~0x00000001; /* CPU restarts with the correct SIGs. */
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.12.12 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../usf.h"
|
||||
|
||||
#include "../dma.h"
|
||||
#include "../exception.h"
|
||||
#include "../memory.h"
|
||||
#include "../registers.h"
|
||||
|
||||
#include "../usf_internal.h"
|
||||
|
||||
#undef JUMP
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "rsp.h"
|
||||
|
||||
void real_run_rsp(usf_state_t * state, uint32_t cycles)
|
||||
{
|
||||
if (SP_STATUS_REG & 0x00000003)
|
||||
{
|
||||
message("SP_STATUS_HALT", 3);
|
||||
return;
|
||||
}
|
||||
run_task(state);
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t init_rsp(usf_state_t * state)
|
||||
{
|
||||
state->CR[0x0] = &SP_MEM_ADDR_REG;
|
||||
state->CR[0x1] = &SP_DRAM_ADDR_REG;
|
||||
state->CR[0x2] = &SP_RD_LEN_REG;
|
||||
state->CR[0x3] = &SP_WR_LEN_REG;
|
||||
state->CR[0x4] = &SP_STATUS_REG;
|
||||
state->CR[0x5] = &SP_DMA_FULL_REG;
|
||||
state->CR[0x6] = &SP_DMA_BUSY_REG;
|
||||
state->CR[0x7] = &SP_SEMAPHORE_REG;
|
||||
state->CR[0x8] = &DPC_START_REG;
|
||||
state->CR[0x9] = &DPC_END_REG;
|
||||
state->CR[0xA] = &DPC_CURRENT_REG;
|
||||
state->CR[0xB] = &DPC_STATUS_REG;
|
||||
state->CR[0xC] = &DPC_CLOCK_REG;
|
||||
state->CR[0xD] = &DPC_BUFBUSY_REG;
|
||||
state->CR[0xE] = &DPC_PIPEBUSY_REG;
|
||||
state->CR[0xF] = &DPC_TMEM_REG;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.12.12 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#ifndef _RSP_H_
|
||||
#define _RSP_H_
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define INLINE __inline
|
||||
#define NOINLINE __declspec(noinline)
|
||||
#define ALIGNED _declspec(align(16))
|
||||
#else
|
||||
#define INLINE __attribute__((forceinline))
|
||||
#define NOINLINE __attribute__((noinline))
|
||||
#define ALIGNED __attribute__((aligned(16)))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Streaming SIMD Extensions version import management
|
||||
*/
|
||||
#ifdef ARCH_MIN_SSSE3
|
||||
#define ARCH_MIN_SSE2
|
||||
#include <tmmintrin.h>
|
||||
#endif
|
||||
#ifdef ARCH_MIN_SSE2
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
typedef uint32_t RCPREG;
|
||||
|
||||
NOINLINE void message(const char* body, int priority)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Update RSP configuration memory from local file resource.
|
||||
*/
|
||||
#define CHARACTERS_PER_LINE (80)
|
||||
/* typical standard DOS text file limit per line */
|
||||
NOINLINE void update_conf(const char* source)
|
||||
{
|
||||
}
|
||||
|
||||
#include "su.h"
|
||||
#include "vu/vu.h"
|
||||
|
||||
/* Allocate the RSP CPU loop to its own functional space. */
|
||||
NOINLINE extern void run_task(usf_state_t * state);
|
||||
#include "execute.h"
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,191 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.12.04 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#ifndef _CF_H
|
||||
#define _CF_H
|
||||
|
||||
/*
|
||||
* For a non-cycle-accurate RSP emulator using SSE2, the following
|
||||
* scalar definitions of the control registers are obsolete.
|
||||
*/
|
||||
#if (0)
|
||||
/*
|
||||
* Many vector units have pairs of "vector condition flags" registers.
|
||||
* In SGI's vector unit implementation, these are denoted as the
|
||||
* "vector control registers" under coprocessor 2.
|
||||
*
|
||||
* VCF-0 is the carry-out flags register: $vco.
|
||||
* VCF-1 is the compare code flags register: $vcc.
|
||||
* VCF-2 is the compare extension flags register: $vce.
|
||||
* There is no fourth RSP flags register.
|
||||
*/
|
||||
|
||||
unsigned short VCO;
|
||||
unsigned short VCC;
|
||||
unsigned char VCE;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These normally should have type `int` because they are Boolean T/F arrays.
|
||||
* However, since SSE2 uses 128-bit XMM's, and Win32 `int` storage is 32-bit,
|
||||
* we have the problem of 32*8 > 128 bits, so we use `short` to reduce packs.
|
||||
*/
|
||||
|
||||
#ifndef ARCH_MIN_SSE2
|
||||
unsigned short get_VCO(usf_state_t * state)
|
||||
{
|
||||
register unsigned short VCO;
|
||||
|
||||
VCO = 0x0000
|
||||
| (state->ne[0xF % 8] << 0xF)
|
||||
| (state->ne[0xE % 8] << 0xE)
|
||||
| (state->ne[0xD % 8] << 0xD)
|
||||
| (state->ne[0xC % 8] << 0xC)
|
||||
| (state->ne[0xB % 8] << 0xB)
|
||||
| (state->ne[0xA % 8] << 0xA)
|
||||
| (state->ne[0x9 % 8] << 0x9)
|
||||
| (state->ne[0x8 % 8] << 0x8)
|
||||
| (state->co[0x7 % 8] << 0x7)
|
||||
| (state->co[0x6 % 8] << 0x6)
|
||||
| (state->co[0x5 % 8] << 0x5)
|
||||
| (state->co[0x4 % 8] << 0x4)
|
||||
| (state->co[0x3 % 8] << 0x3)
|
||||
| (state->co[0x2 % 8] << 0x2)
|
||||
| (state->co[0x1 % 8] << 0x1)
|
||||
| (state->co[0x0 % 8] << 0x0);
|
||||
return (VCO); /* Big endian becomes little. */
|
||||
}
|
||||
unsigned short get_VCC(usf_state_t * state)
|
||||
{
|
||||
register unsigned short VCC;
|
||||
|
||||
VCC = 0x0000
|
||||
| (state->clip[0xF % 8] << 0xF)
|
||||
| (state->clip[0xE % 8] << 0xE)
|
||||
| (state->clip[0xD % 8] << 0xD)
|
||||
| (state->clip[0xC % 8] << 0xC)
|
||||
| (state->clip[0xB % 8] << 0xB)
|
||||
| (state->clip[0xA % 8] << 0xA)
|
||||
| (state->clip[0x9 % 8] << 0x9)
|
||||
| (state->clip[0x8 % 8] << 0x8)
|
||||
| (state->comp[0x7 % 8] << 0x7)
|
||||
| (state->comp[0x6 % 8] << 0x6)
|
||||
| (state->comp[0x5 % 8] << 0x5)
|
||||
| (state->comp[0x4 % 8] << 0x4)
|
||||
| (state->comp[0x3 % 8] << 0x3)
|
||||
| (state->comp[0x2 % 8] << 0x2)
|
||||
| (state->comp[0x1 % 8] << 0x1)
|
||||
| (state->comp[0x0 % 8] << 0x0);
|
||||
return (VCC); /* Big endian becomes little. */
|
||||
}
|
||||
unsigned char get_VCE(usf_state_t * state)
|
||||
{
|
||||
register unsigned char VCE;
|
||||
|
||||
VCE = 0x00
|
||||
| (state->vce[07] << 0x7)
|
||||
| (state->vce[06] << 0x6)
|
||||
| (state->vce[05] << 0x5)
|
||||
| (state->vce[04] << 0x4)
|
||||
| (state->vce[03] << 0x3)
|
||||
| (state->vce[02] << 0x2)
|
||||
| (state->vce[01] << 0x1)
|
||||
| (state->vce[00] << 0x0);
|
||||
return (VCE); /* Big endian becomes little. */
|
||||
}
|
||||
#else
|
||||
unsigned short get_VCO(usf_state_t * state)
|
||||
{
|
||||
__m128i xmm, hi, lo;
|
||||
register unsigned short VCO;
|
||||
|
||||
hi = _mm_load_si128((__m128i *)state->ne);
|
||||
lo = _mm_load_si128((__m128i *)state->co);
|
||||
|
||||
/*
|
||||
* Rotate Boolean storage from LSB to MSB.
|
||||
*/
|
||||
hi = _mm_slli_epi16(hi, 15);
|
||||
lo = _mm_slli_epi16(lo, 15);
|
||||
|
||||
xmm = _mm_packs_epi16(lo, hi); /* Decompress INT16 Booleans to INT8 ones. */
|
||||
VCO = _mm_movemask_epi8(xmm) & 0x0000FFFF; /* PMOVMSKB combines each MSB. */
|
||||
return (VCO);
|
||||
}
|
||||
unsigned short get_VCC(usf_state_t * state)
|
||||
{
|
||||
__m128i xmm, hi, lo;
|
||||
register unsigned short VCC;
|
||||
|
||||
hi = _mm_load_si128((__m128i *)state->clip);
|
||||
lo = _mm_load_si128((__m128i *)state->comp);
|
||||
|
||||
/*
|
||||
* Rotate Boolean storage from LSB to MSB.
|
||||
*/
|
||||
hi = _mm_slli_epi16(hi, 15);
|
||||
lo = _mm_slli_epi16(lo, 15);
|
||||
|
||||
xmm = _mm_packs_epi16(lo, hi); /* Decompress INT16 Booleans to INT8 ones. */
|
||||
VCC = _mm_movemask_epi8(xmm) & 0x0000FFFF; /* PMOVMSKB combines each MSB. */
|
||||
return (VCC);
|
||||
}
|
||||
unsigned char get_VCE(usf_state_t * state)
|
||||
{
|
||||
__m128i xmm, hi, lo;
|
||||
register unsigned char VCE;
|
||||
|
||||
hi = _mm_setzero_si128();
|
||||
lo = _mm_load_si128((__m128i *)state->vce);
|
||||
|
||||
lo = _mm_slli_epi16(lo, 15); /* Rotate Boolean storage from LSB to MSB. */
|
||||
|
||||
xmm = _mm_packs_epi16(lo, hi); /* Decompress INT16 Booleans to INT8 ones. */
|
||||
VCE = _mm_movemask_epi8(xmm) & 0x000000FF; /* PMOVMSKB combines each MSB. */
|
||||
return (VCE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CTC2 resources
|
||||
* not sure how to vectorize going the other direction into SSE2
|
||||
*/
|
||||
void set_VCO(usf_state_t * state, unsigned short VCO)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
state->co[i] = (VCO >> (i + 0x0)) & 1;
|
||||
for (i = 0; i < 8; i++)
|
||||
state->ne[i] = (VCO >> (i + 0x8)) & 1;
|
||||
return; /* Little endian becomes big. */
|
||||
}
|
||||
void set_VCC(usf_state_t * state, unsigned short VCC)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
state->comp[i] = (VCC >> (i + 0x0)) & 1;
|
||||
for (i = 0; i < 8; i++)
|
||||
state->clip[i] = (VCC >> (i + 0x8)) & 1;
|
||||
return; /* Little endian becomes big. */
|
||||
}
|
||||
void set_VCE(usf_state_t * state, unsigned char VCE)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
state->vce[i] = (VCE >> i) & 1;
|
||||
return; /* Little endian becomes big. */
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,255 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.10.07 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#ifndef _CLAMP_H
|
||||
#define _CLAMP_H
|
||||
|
||||
/*
|
||||
* for ANSI compliance (null INLINE attribute if not already set to `inline`)
|
||||
* Include "rsp.h" for active, non-ANSI inline definition.
|
||||
*/
|
||||
#ifndef INLINE
|
||||
#define INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* dependency for 48-bit accumulator access
|
||||
*/
|
||||
#include "vu.h"
|
||||
|
||||
/*
|
||||
* vector select merge (`VMRG`) formula
|
||||
*
|
||||
* This is really just a vectorizer for ternary conditional storage.
|
||||
* I've named it so because it directly maps to the VMRG op-code.
|
||||
* -- example --
|
||||
* for (i = 0; i < N; i++)
|
||||
* if (c_pass)
|
||||
* dest = element_a;
|
||||
* else
|
||||
* dest = element_b;
|
||||
*/
|
||||
static INLINE void merge(short* VD, short* cmp, short* pass, short* fail)
|
||||
{
|
||||
register int i;
|
||||
#if (0)
|
||||
/* Do not use this version yet, as it still does not vectorize to SSE2. */
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] = (cmp[i] != 0) ? pass[i] : fail[i];
|
||||
#else
|
||||
short diff[N];
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
diff[i] = pass[i] - fail[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] = fail[i] + cmp[i]*diff[i]; /* actually `(cmp[i] != 0)*diff[i]` */
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef ARCH_MIN_SSE2
|
||||
static INLINE void vector_copy(short* VD, short* VS)
|
||||
{
|
||||
#if (0)
|
||||
memcpy(VD, VS, N*sizeof(short));
|
||||
#else
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] = VS[i];
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
static INLINE void SIGNED_CLAMP_ADD(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
int32_t sum[N];
|
||||
short hi[N], lo[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
sum[i] = VS[i] + VT[i] + state->co[i];
|
||||
for (i = 0; i < N; i++)
|
||||
lo[i] = (sum[i] + 0x8000) >> 31;
|
||||
for (i = 0; i < N; i++)
|
||||
hi[i] = (0x7FFF - sum[i]) >> 31;
|
||||
vector_copy(VD, VACC_L);
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] &= ~lo[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] |= hi[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] ^= 0x8000 & (hi[i] | lo[i]);
|
||||
return;
|
||||
}
|
||||
static INLINE void SIGNED_CLAMP_SUB(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
int32_t dif[N];
|
||||
short hi[N], lo[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
dif[i] = VS[i] - VT[i] - state->co[i];
|
||||
for (i = 0; i < N; i++)
|
||||
lo[i] = (dif[i] + 0x8000) >> 31;
|
||||
for (i = 0; i < N; i++)
|
||||
hi[i] = (0x7FFF - dif[i]) >> 31;
|
||||
vector_copy(VD, VACC_L);
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] &= ~lo[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] |= hi[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] ^= 0x8000 & (hi[i] | lo[i]);
|
||||
return;
|
||||
}
|
||||
static INLINE void SIGNED_CLAMP_AM(usf_state_t * state, short* VD)
|
||||
{ /* typical sign-clamp of accumulator-mid (bits 31:16) */
|
||||
short hi[N], lo[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
lo[i] = (VACC_H[i] < ~0);
|
||||
for (i = 0; i < N; i++)
|
||||
lo[i] |= (VACC_H[i] < 0) & !(VACC_M[i] < 0);
|
||||
for (i = 0; i < N; i++)
|
||||
hi[i] = (VACC_H[i] > 0);
|
||||
for (i = 0; i < N; i++)
|
||||
hi[i] |= (VACC_H[i] == 0) & (VACC_M[i] < 0);
|
||||
vector_copy(VD, VACC_M);
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] &= -(lo[i] ^ 1);
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] |= -(hi[i] ^ 0);
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] ^= 0x8000 * (hi[i] | lo[i]);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* We actually need to write explicit SSE2 code for this because GCC 4.8.1
|
||||
* (and possibly later versions) has a code generation bug with vectorizing
|
||||
* the accumulator when it's a signed short (but not when it's unsigned, for
|
||||
* some stupid and buggy reason).
|
||||
*
|
||||
* In addition, as of the more stable GCC 4.7.2 release, while vectorizing
|
||||
* the accumulator write-backs into SSE2 for me is successfully done, we save
|
||||
* just one extra scalar x86 instruction for every RSP vector op-code when we
|
||||
* use SSE2 explicitly for this particular goal instead of letting GCC do it.
|
||||
*/
|
||||
static INLINE void vector_copy(short* VD, short* VS)
|
||||
{
|
||||
__m128i xmm;
|
||||
|
||||
xmm = _mm_load_si128((__m128i *)VS);
|
||||
_mm_store_si128((__m128i *)VD, xmm);
|
||||
return;
|
||||
}
|
||||
|
||||
static INLINE void SIGNED_CLAMP_ADD(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
__m128i dst, src, vco;
|
||||
__m128i max, min;
|
||||
|
||||
src = _mm_load_si128((__m128i *)VS);
|
||||
dst = _mm_load_si128((__m128i *)VT);
|
||||
vco = _mm_load_si128((__m128i *)state->co);
|
||||
|
||||
/*
|
||||
* Due to premature clamping in between adds, sometimes we need to add the
|
||||
* LESSER of two integers, either VS or VT, to the carry-in flag matching the
|
||||
* current vector register slice, BEFORE finally adding the greater integer.
|
||||
*/
|
||||
max = _mm_max_epi16(dst, src);
|
||||
min = _mm_min_epi16(dst, src);
|
||||
|
||||
min = _mm_adds_epi16(min, vco);
|
||||
max = _mm_adds_epi16(max, min);
|
||||
_mm_store_si128((__m128i *)VD, max);
|
||||
return;
|
||||
}
|
||||
static INLINE void SIGNED_CLAMP_SUB(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
__m128i dst, src, vco;
|
||||
__m128i dif, res, xmm;
|
||||
|
||||
src = _mm_load_si128((__m128i *)VS);
|
||||
dst = _mm_load_si128((__m128i *)VT);
|
||||
vco = _mm_load_si128((__m128i *)state->co);
|
||||
|
||||
res = _mm_subs_epi16(src, dst);
|
||||
|
||||
/*
|
||||
* Due to premature clamps in-between subtracting two of the three operands,
|
||||
* we must be careful not to offset the result accidentally when subtracting
|
||||
* the corresponding VCO flag AFTER the saturation from doing (VS - VT).
|
||||
*/
|
||||
dif = _mm_add_epi16(res, vco);
|
||||
dif = _mm_xor_si128(dif, res); /* Adding one suddenly inverts the sign? */
|
||||
dif = _mm_and_si128(dif, dst); /* Sign change due to subtracting a neg. */
|
||||
xmm = _mm_sub_epi16(src, dst);
|
||||
src = _mm_andnot_si128(src, dif); /* VS must be >= 0x0000 for overflow. */
|
||||
xmm = _mm_and_si128(xmm, src); /* VS + VT != INT16_MIN; VS + VT >= +32768 */
|
||||
xmm = _mm_srli_epi16(xmm, 15); /* src = (INT16_MAX + 1 === INT16_MIN) ? */
|
||||
|
||||
xmm = _mm_andnot_si128(xmm, vco); /* If it's NOT overflow, keep flag. */
|
||||
res = _mm_subs_epi16(res, xmm);
|
||||
_mm_store_si128((__m128i *)VD, res);
|
||||
return;
|
||||
}
|
||||
static INLINE void SIGNED_CLAMP_AM(usf_state_t * state, short* VD)
|
||||
{ /* typical sign-clamp of accumulator-mid (bits 31:16) */
|
||||
__m128i dst, src;
|
||||
__m128i pvd, pvs;
|
||||
|
||||
pvs = _mm_load_si128((__m128i *)VACC_H);
|
||||
pvd = _mm_load_si128((__m128i *)VACC_M);
|
||||
dst = _mm_unpacklo_epi16(pvd, pvs);
|
||||
src = _mm_unpackhi_epi16(pvd, pvs);
|
||||
|
||||
dst = _mm_packs_epi32(dst, src);
|
||||
_mm_store_si128((__m128i *)VD, dst);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
static INLINE void UNSIGNED_CLAMP(usf_state_t * state, short* VD)
|
||||
{ /* sign-zero hybrid clamp of accumulator-mid (bits 31:16) */
|
||||
short cond[N];
|
||||
short temp[N];
|
||||
register int i;
|
||||
|
||||
SIGNED_CLAMP_AM(state, temp); /* no direct map in SSE, but closely based on this */
|
||||
for (i = 0; i < N; i++)
|
||||
cond[i] = -(temp[i] > VACC_M[i]); /* VD |= -(ACC47..16 > +32767) */
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] = temp[i] & ~(temp[i] >> 15); /* Only this clamp is unsigned. */
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] = VD[i] | cond[i];
|
||||
return;
|
||||
}
|
||||
static INLINE void SIGNED_CLAMP_AL(usf_state_t * state, short* VD)
|
||||
{ /* sign-clamp accumulator-low (bits 15:0) */
|
||||
short cond[N];
|
||||
short temp[N];
|
||||
register int i;
|
||||
|
||||
SIGNED_CLAMP_AM(state, temp); /* no direct map in SSE, but closely based on this */
|
||||
for (i = 0; i < N; i++)
|
||||
cond[i] = (temp[i] != VACC_M[i]); /* result_clamped != result_raw ? */
|
||||
for (i = 0; i < N; i++)
|
||||
temp[i] ^= 0x8000; /* half-assed unsigned saturation mix in the clamp */
|
||||
merge(VD, cond, temp, VACC_L);
|
||||
return;
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,278 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.12.04 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#ifndef _SHUFFLE_H
|
||||
#define _SHUFFLE_H
|
||||
|
||||
/*
|
||||
* for ANSI compliance (null INLINE attribute if not already set to `inline`)
|
||||
* Include "rsp.h" for active, non-ANSI inline definition.
|
||||
*/
|
||||
#ifndef INLINE
|
||||
#define INLINE
|
||||
#endif
|
||||
|
||||
#ifndef ARCH_MIN_SSE2
|
||||
/*
|
||||
* vector-scalar element decoding
|
||||
* Obsolete. Consider using at least the SSE2 algorithms instead.
|
||||
*/
|
||||
static const int ei[16][8] = {
|
||||
{ 00, 01, 02, 03, 04, 05, 06, 07 }, /* none (vector-only operand) */
|
||||
{ 00, 01, 02, 03, 04, 05, 06, 07 },
|
||||
{ 00, 00, 02, 02, 04, 04, 06, 06 }, /* 0Q */
|
||||
{ 01, 01, 03, 03, 05, 05, 07, 07 }, /* 1Q */
|
||||
{ 00, 00, 00, 00, 04, 04, 04, 04 }, /* 0H */
|
||||
{ 01, 01, 01, 01, 05, 05, 05, 05 }, /* 1H */
|
||||
{ 02, 02, 02, 02, 06, 06, 06, 06 }, /* 2H */
|
||||
{ 03, 03, 03, 03, 07, 07, 07, 07 }, /* 3H */
|
||||
{ 00, 00, 00, 00, 00, 00, 00, 00 }, /* 0 */
|
||||
{ 01, 01, 01, 01, 01, 01, 01, 01 }, /* 1 */
|
||||
{ 02, 02, 02, 02, 02, 02, 02, 02 }, /* 2 */
|
||||
{ 03, 03, 03, 03, 03, 03, 03, 03 }, /* 3 */
|
||||
{ 04, 04, 04, 04, 04, 04, 04, 04 }, /* 4 */
|
||||
{ 05, 05, 05, 05, 05, 05, 05, 05 }, /* 5 */
|
||||
{ 06, 06, 06, 06, 06, 06, 06, 06 }, /* 6 */
|
||||
{ 07, 07, 07, 07, 07, 07, 07, 07 } /* 7 */
|
||||
};
|
||||
|
||||
int sub_mask[16] = {
|
||||
0x0,
|
||||
0x0,
|
||||
0x1, 0x1,
|
||||
0x3, 0x3, 0x3, 0x3,
|
||||
0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7
|
||||
};
|
||||
|
||||
INLINE static void SHUFFLE_VECTOR(short* VD, short* VT, const int e)
|
||||
{
|
||||
short SV[8];
|
||||
register int i, j;
|
||||
#if (0 == 0)
|
||||
j = sub_mask[e];
|
||||
for (i = 0; i < N; i++)
|
||||
SV[i] = VT[(i & ~j) | (e & j)];
|
||||
#else
|
||||
if (e & 0x8)
|
||||
for (i = 0; i < N; i++)
|
||||
SV[i] = VT[(i & 0x0) | (e & 0x7)];
|
||||
else if (e & 0x4)
|
||||
for (i = 0; i < N; i++)
|
||||
SV[i] = VT[(i & 0xC) | (e & 0x3)];
|
||||
else if (e & 0x2)
|
||||
for (i = 0; i < N; i++)
|
||||
SV[i] = VT[(i & 0xE) | (e & 0x1)];
|
||||
else /* if ((e == 0b0000) || (e == 0b0001)) */
|
||||
for (i = 0; i < N; i++)
|
||||
SV[i] = VT[(i & 0x7) | (e & 0x0)];
|
||||
#endif
|
||||
for (i = 0; i < N; i++)
|
||||
*(VD + i) = *(SV + i);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
#ifdef ARCH_MIN_SSSE3
|
||||
static const unsigned char smask[16][16] = {
|
||||
{0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF},
|
||||
{0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF},
|
||||
{0x0,0x1,0x0,0x1,0x4,0x5,0x4,0x5,0x8,0x9,0x8,0x9,0xC,0xD,0xC,0xD},
|
||||
{0x2,0x3,0x2,0x3,0x6,0x7,0x6,0x7,0xA,0xB,0xA,0xB,0xE,0xF,0xE,0xF},
|
||||
{0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x8,0x9,0x8,0x9,0x8,0x9,0x8,0x9},
|
||||
{0x2,0x3,0x2,0x3,0x2,0x3,0x2,0x3,0xA,0xB,0xA,0xB,0xA,0xB,0xA,0xB},
|
||||
{0x4,0x5,0x4,0x5,0x4,0x5,0x4,0x5,0xC,0xD,0xC,0xD,0xC,0xD,0xC,0xD},
|
||||
{0x6,0x7,0x6,0x7,0x6,0x7,0x6,0x7,0xE,0xF,0xE,0xF,0xE,0xF,0xE,0xF},
|
||||
{0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1},
|
||||
{0x2,0x3,0x2,0x3,0x2,0x3,0x2,0x3,0x2,0x3,0x2,0x3,0x2,0x3,0x2,0x3},
|
||||
{0x4,0x5,0x4,0x5,0x4,0x5,0x4,0x5,0x4,0x5,0x4,0x5,0x4,0x5,0x4,0x5},
|
||||
{0x6,0x7,0x6,0x7,0x6,0x7,0x6,0x7,0x6,0x7,0x6,0x7,0x6,0x7,0x6,0x7},
|
||||
{0x8,0x9,0x8,0x9,0x8,0x9,0x8,0x9,0x8,0x9,0x8,0x9,0x8,0x9,0x8,0x9},
|
||||
{0xA,0xB,0xA,0xB,0xA,0xB,0xA,0xB,0xA,0xB,0xA,0xB,0xA,0xB,0xA,0xB},
|
||||
{0xC,0xD,0xC,0xD,0xC,0xD,0xC,0xD,0xC,0xD,0xC,0xD,0xC,0xD,0xC,0xD},
|
||||
{0xE,0xF,0xE,0xF,0xE,0xF,0xE,0xF,0xE,0xF,0xE,0xF,0xE,0xF,0xE,0xF}
|
||||
};
|
||||
|
||||
INLINE static void SHUFFLE_VECTOR(short* VD, short* VT, const int e)
|
||||
{ /* SSSE3 shuffling method was written entirely by CEN64 author MarathonMan. */
|
||||
__m128i xmm;
|
||||
__m128i key;
|
||||
|
||||
xmm = _mm_load_si128((__m128i *)VT);
|
||||
key = _mm_load_si128((__m128i *)(smask[e]));
|
||||
xmm = _mm_shuffle_epi8(xmm, key);
|
||||
_mm_store_si128((__m128i *)VD, xmm);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
#define B(x) ((x) & 3)
|
||||
#define SHUFFLE(a,b,c,d) ((B(d)<<6) | (B(c)<<4) | (B(b)<<2) | (B(a)<<0))
|
||||
|
||||
static const int simm[16] = {
|
||||
SHUFFLE(00, 01, 02, 03), /* vector operands */
|
||||
SHUFFLE(00, 01, 02, 03),
|
||||
SHUFFLE(00, 00, 02, 02), /* scalar quarters */
|
||||
SHUFFLE(01, 01, 03, 03),
|
||||
SHUFFLE(00, 00, 00, 00), /* scalar halves */
|
||||
SHUFFLE(01, 01, 01, 01),
|
||||
SHUFFLE(02, 02, 02, 02),
|
||||
SHUFFLE(03, 03, 03, 03),
|
||||
SHUFFLE(00, 00, 00, 00), /* scalar wholes */
|
||||
SHUFFLE(01, 01, 01, 01),
|
||||
SHUFFLE(02, 02, 02, 02),
|
||||
SHUFFLE(03, 03, 03, 03),
|
||||
SHUFFLE(04, 04, 04, 04),
|
||||
SHUFFLE(05, 05, 05, 05),
|
||||
SHUFFLE(06, 06, 06, 06),
|
||||
SHUFFLE(07, 07, 07, 07)
|
||||
};
|
||||
|
||||
static __m128i shuffle_none(__m128i xmm)
|
||||
{/*
|
||||
const int order = simm[0x0];
|
||||
|
||||
xmm = _mm_shufflehi_epi16(xmm, order);
|
||||
xmm = _mm_shufflelo_epi16(xmm, order);*/
|
||||
return (xmm);
|
||||
}
|
||||
static __m128i shuffle_0q(__m128i xmm)
|
||||
{
|
||||
const int order = simm[0x2];
|
||||
|
||||
xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(00, 00, 02, 02));
|
||||
xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(00, 00, 02, 02));
|
||||
return (xmm);
|
||||
}
|
||||
static __m128i shuffle_1q(__m128i xmm)
|
||||
{
|
||||
const int order = simm[0x3];
|
||||
|
||||
xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(01, 01, 03, 03));
|
||||
xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(01, 01, 03, 03));
|
||||
return (xmm);
|
||||
}
|
||||
static __m128i shuffle_0h(__m128i xmm)
|
||||
{
|
||||
const int order = simm[0x4];
|
||||
|
||||
xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(00, 00, 00, 00));
|
||||
xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(00, 00, 00, 00));
|
||||
return (xmm);
|
||||
}
|
||||
static __m128i shuffle_1h(__m128i xmm)
|
||||
{
|
||||
const int order = simm[0x5];
|
||||
|
||||
xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(01, 01, 01, 01));
|
||||
xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(01, 01, 01, 01));
|
||||
return (xmm);
|
||||
}
|
||||
static __m128i shuffle_2h(__m128i xmm)
|
||||
{
|
||||
const int order = simm[0x6];
|
||||
|
||||
xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(02, 02, 02, 02));
|
||||
xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(02, 02, 02, 02));
|
||||
return (xmm);
|
||||
}
|
||||
static __m128i shuffle_3h(__m128i xmm)
|
||||
{
|
||||
const int order = simm[0x7];
|
||||
|
||||
xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(03, 03, 03, 03));
|
||||
xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(03, 03, 03, 03));
|
||||
return (xmm);
|
||||
}
|
||||
static __m128i shuffle_0w(__m128i xmm)
|
||||
{
|
||||
const int order = simm[0x8];
|
||||
|
||||
xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(00, 00, 00, 00));
|
||||
xmm = _mm_unpacklo_epi16(xmm, xmm);
|
||||
return (xmm);
|
||||
}
|
||||
static __m128i shuffle_1w(__m128i xmm)
|
||||
{
|
||||
const int order = simm[0x9];
|
||||
|
||||
xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(01, 01, 01, 01));
|
||||
xmm = _mm_unpacklo_epi16(xmm, xmm);
|
||||
return (xmm);
|
||||
}
|
||||
static __m128i shuffle_2w(__m128i xmm)
|
||||
{
|
||||
const int order = simm[0xA];
|
||||
|
||||
xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(02, 02, 02, 02));
|
||||
xmm = _mm_unpacklo_epi16(xmm, xmm);
|
||||
return (xmm);
|
||||
}
|
||||
static __m128i shuffle_3w(__m128i xmm)
|
||||
{
|
||||
const int order = simm[0xB];
|
||||
|
||||
xmm = _mm_shufflelo_epi16(xmm, SHUFFLE(03, 03, 03, 03));
|
||||
xmm = _mm_unpacklo_epi16(xmm, xmm);
|
||||
return (xmm);
|
||||
}
|
||||
static __m128i shuffle_4w(__m128i xmm)
|
||||
{
|
||||
const int order = simm[0xC];
|
||||
|
||||
xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(04, 04, 04, 04));
|
||||
xmm = _mm_unpackhi_epi16(xmm, xmm);
|
||||
return (xmm);
|
||||
}
|
||||
static __m128i shuffle_5w(__m128i xmm)
|
||||
{
|
||||
const int order = simm[0xD];
|
||||
|
||||
xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(05, 05, 05, 05));
|
||||
xmm = _mm_unpackhi_epi16(xmm, xmm);
|
||||
return (xmm);
|
||||
}
|
||||
static __m128i shuffle_6w(__m128i xmm)
|
||||
{
|
||||
const int order = simm[0xE];
|
||||
|
||||
xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(06, 06, 06, 06));
|
||||
xmm = _mm_unpackhi_epi16(xmm, xmm);
|
||||
return (xmm);
|
||||
}
|
||||
static __m128i shuffle_7w(__m128i xmm)
|
||||
{
|
||||
const int order = simm[0xF];
|
||||
|
||||
xmm = _mm_shufflehi_epi16(xmm, SHUFFLE(07, 07, 07, 07));
|
||||
xmm = _mm_unpackhi_epi16(xmm, xmm);
|
||||
return (xmm);
|
||||
}
|
||||
|
||||
static __m128i (*SSE2_SHUFFLE_16[16])(__m128i) = {
|
||||
shuffle_none, shuffle_none,
|
||||
shuffle_0q, shuffle_1q,
|
||||
shuffle_0h, shuffle_1h, shuffle_2h, shuffle_3h,
|
||||
shuffle_0w, shuffle_1w, shuffle_2w, shuffle_3w,
|
||||
shuffle_4w, shuffle_5w, shuffle_6w, shuffle_7w
|
||||
};
|
||||
|
||||
INLINE static void SHUFFLE_VECTOR(short* VD, short* VT, const int e)
|
||||
{
|
||||
__m128i xmm;
|
||||
|
||||
xmm = _mm_load_si128((__m128i *)VT);
|
||||
xmm = SSE2_SHUFFLE_16[e](xmm);
|
||||
_mm_store_si128((__m128i *)VD, xmm);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,77 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
/*
|
||||
* -1: VT *= -1, because VS < 0 // VT ^= -2 if even, or ^= -1, += 1
|
||||
* 0: VT *= 0, because VS = 0 // VT ^= VT
|
||||
* +1: VT *= +1, because VS > 0 // VT ^= 0
|
||||
* VT ^= -1, "negate" -32768 as ~+32767 (corner case hack for N64 SP)
|
||||
*/
|
||||
INLINE static void do_abs(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
short neg[N], pos[N];
|
||||
short nez[N], cch[N]; /* corner case hack -- abs(-32768) == +32767 */
|
||||
short res[N];
|
||||
register int i;
|
||||
|
||||
vector_copy(res, VT);
|
||||
#ifndef ARCH_MIN_SSE2
|
||||
#define MASK_XOR
|
||||
#endif
|
||||
for (i = 0; i < N; i++)
|
||||
neg[i] = (VS[i] < 0x0000);
|
||||
for (i = 0; i < N; i++)
|
||||
pos[i] = (VS[i] > 0x0000);
|
||||
for (i = 0; i < N; i++)
|
||||
nez[i] = 0;
|
||||
#ifdef MASK_XOR
|
||||
for (i = 0; i < N; i++)
|
||||
neg[i] = -neg[i];
|
||||
for (i = 0; i < N; i++)
|
||||
nez[i] += neg[i];
|
||||
#else
|
||||
for (i = 0; i < N; i++)
|
||||
nez[i] -= neg[i];
|
||||
#endif
|
||||
for (i = 0; i < N; i++)
|
||||
nez[i] += pos[i];
|
||||
#ifdef MASK_XOR
|
||||
for (i = 0; i < N; i++)
|
||||
res[i] ^= nez[i];
|
||||
for (i = 0; i < N; i++)
|
||||
cch[i] = (res[i] != -32768);
|
||||
for (i = 0; i < N; i++)
|
||||
res[i] += cch[i]; /* -(x) === (x ^ -1) + 1 */
|
||||
#else
|
||||
for (i = 0; i < N; i++)
|
||||
res[i] *= nez[i];
|
||||
for (i = 0; i < N; i++)
|
||||
cch[i] = (res[i] == -32768);
|
||||
for (i = 0; i < N; i++)
|
||||
res[i] -= cch[i];
|
||||
#endif
|
||||
vector_copy(VACC_L, res);
|
||||
vector_copy(VD, VACC_L);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VABS(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_abs(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void clr_ci(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{ /* clear CARRY and carry in to accumulators */
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = VS[i] + VT[i] + state->co[i];
|
||||
SIGNED_CLAMP_ADD(state, VD, VS, VT);
|
||||
for (i = 0; i < N; i++)
|
||||
state->ne[i] = 0;
|
||||
for (i = 0; i < N; i++)
|
||||
state->co[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static void VADD(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
clr_ci(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void set_co(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{ /* set CARRY and carry out from sum */
|
||||
int32_t sum[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
sum[i] = (unsigned short)(VS[i]) + (unsigned short)(VT[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = VS[i] + VT[i];
|
||||
vector_copy(VD, VACC_L);
|
||||
for (i = 0; i < N; i++)
|
||||
state->ne[i] = 0;
|
||||
for (i = 0; i < N; i++)
|
||||
state->co[i] = sum[i] >> 16; /* native: (sum[i] > +65535) */
|
||||
return;
|
||||
}
|
||||
|
||||
static void VADDC(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
set_co(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE void do_and(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = VS[i] & VT[i];
|
||||
vector_copy(VD, VACC_L);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VAND(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_and(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_ch(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
short eq[N], ge[N], le[N];
|
||||
short sn[N];
|
||||
short VC[N];
|
||||
short diff[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VC[i] = VT[i];
|
||||
for (i = 0; i < N; i++)
|
||||
sn[i] = (VS[i] ^ VC[i]) < 0;
|
||||
for (i = 0; i < N; i++)
|
||||
VC[i] ^= -sn[i]; /* if (sn == ~0) {VT = ~VT;} else {VT = VT;} */
|
||||
for (i = 0; i < N; i++)
|
||||
state->vce[i] = (VS[i] == VC[i]); /* (VR[vs][i] + ~VC[i] == ~1); */
|
||||
for (i = 0; i < N; i++)
|
||||
state->vce[i] &= sn[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VC[i] += sn[i]; /* converts ~(VT) into -(VT) if (sign) */
|
||||
for (i = 0; i < N; i++)
|
||||
eq[i] = (VS[i] == VC[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
eq[i] |= state->vce[i];
|
||||
|
||||
#if (0)
|
||||
for (i = 0; i < N; i++)
|
||||
le[i] = sn[i] ? (VS[i] <= VC[i]) : (VC[i] < 0);
|
||||
for (i = 0; i < N; i++)
|
||||
ge[i] = sn[i] ? (VC[i] > 0x0000) : (VS[i] >= VC[i]);
|
||||
#elif (0)
|
||||
for (i = 0; i < N; i++)
|
||||
le[i] = sn[i] ? (VT[i] <= -VS[i]) : (VT[i] <= ~0x0000);
|
||||
for (i = 0; i < N; i++)
|
||||
ge[i] = sn[i] ? (~0x0000 >= VT[i]) : (VS[i] >= VT[i]);
|
||||
#else
|
||||
for (i = 0; i < N; i++)
|
||||
diff[i] = -VS[i] | -(sn[i] ^ 1);
|
||||
for (i = 0; i < N; i++)
|
||||
le[i] = VT[i] <= diff[i];
|
||||
for (i = 0; i < N; i++)
|
||||
diff[i] = +VS[i] | -(sn[i] ^ 0);
|
||||
for (i = 0; i < N; i++)
|
||||
ge[i] = diff[i] >= VT[i];
|
||||
#endif
|
||||
|
||||
merge(state->comp, sn, le, ge);
|
||||
merge(VACC_L, state->comp, VC, VS);
|
||||
vector_copy(VD, VACC_L);
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
state->clip[i] = ge[i];
|
||||
for (i = 0; i < N; i++)
|
||||
state->comp[i] = le[i];
|
||||
for (i = 0; i < N; i++)
|
||||
state->ne[i] = eq[i] ^ 1;
|
||||
for (i = 0; i < N; i++)
|
||||
state->co[i] = sn[i];
|
||||
return;
|
||||
}
|
||||
|
||||
static void VCH(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_ch(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_cl(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
short eq[N], ge[N], le[N];
|
||||
short gen[N], len[N], lz[N], uz[N], sn[N];
|
||||
short diff[N];
|
||||
short cmp[N];
|
||||
unsigned short VB[N], VC[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VB[i] = VS[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VC[i] = VT[i];
|
||||
|
||||
/*
|
||||
for (i = 0; i < N; i++)
|
||||
ge[i] = clip[i];
|
||||
for (i = 0; i < N; i++)
|
||||
le[i] = comp[i];
|
||||
*/
|
||||
for (i = 0; i < N; i++)
|
||||
eq[i] = state->ne[i] ^ 1;
|
||||
for (i = 0; i < N; i++)
|
||||
sn[i] = state->co[i];
|
||||
/*
|
||||
* Now that we have extracted all the flags, we will essentially be masking
|
||||
* them back in where they came from redundantly, unless the corresponding
|
||||
* NOTEQUAL bit from VCO upper was not set....
|
||||
*/
|
||||
for (i = 0; i < N; i++)
|
||||
VC[i] = VC[i] ^ -sn[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VC[i] = VC[i] + sn[i]; /* conditional negation, if sn */
|
||||
for (i = 0; i < N; i++)
|
||||
diff[i] = VB[i] - VC[i];
|
||||
for (i = 0; i < N; i++)
|
||||
uz[i] = (VB[i] - VC[i] - 0xFFFF) >> 31;
|
||||
for (i = 0; i < N; i++)
|
||||
lz[i] = (diff[i] == 0x0000);
|
||||
for (i = 0; i < N; i++)
|
||||
gen[i] = lz[i] | uz[i];
|
||||
for (i = 0; i < N; i++)
|
||||
len[i] = lz[i] & uz[i];
|
||||
for (i = 0; i < N; i++)
|
||||
gen[i] = gen[i] & state->vce[i];
|
||||
for (i = 0; i < N; i++)
|
||||
len[i] = len[i] & (state->vce[i] ^ 1);
|
||||
for (i = 0; i < N; i++)
|
||||
len[i] = len[i] | gen[i];
|
||||
for (i = 0; i < N; i++)
|
||||
gen[i] = (VB[i] >= VC[i]);
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
cmp[i] = eq[i] & sn[i];
|
||||
merge(le, cmp, len, state->comp);
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
cmp[i] = eq[i] & (sn[i] ^ 1);
|
||||
merge(ge, cmp, gen, state->clip);
|
||||
|
||||
merge(cmp, sn, le, ge);
|
||||
merge(VACC_L, cmp, (short *)VC, VS);
|
||||
vector_copy(VD, VACC_L);
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
state->clip[i] = ge[i];
|
||||
for (i = 0; i < N; i++)
|
||||
state->comp[i] = le[i];
|
||||
for (i = 0; i < N; i++)
|
||||
state->ne[i] = 0;
|
||||
for (i = 0; i < N; i++)
|
||||
state->co[i] = 0;
|
||||
for (i = 0; i < N; i++)
|
||||
state->vce[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static void VCL(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_cl(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_cr(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
short ge[N], le[N], sn[N];
|
||||
short VC[N];
|
||||
short cmp[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VC[i] = VT[i];
|
||||
for (i = 0; i < N; i++)
|
||||
sn[i] = (signed short)(VS[i] ^ VT[i]) >> 15;
|
||||
#if (0)
|
||||
for (i = 0; i < N; i++)
|
||||
le[i] = sn[i] ? (VT[i] <= ~VS[i]) : (VT[i] <= ~0x0000);
|
||||
for (i = 0; i < N; i++)
|
||||
ge[i] = sn[i] ? (~0x0000 >= VT[i]) : (VS[i] >= VT[i]);
|
||||
#else
|
||||
for (i = 0; i < N; i++)
|
||||
cmp[i] = ~(VS[i] & sn[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
le[i] = (VT[i] <= cmp[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
cmp[i] = (VS[i] | sn[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
ge[i] = (cmp[i] >= VT[i]);
|
||||
#endif
|
||||
for (i = 0; i < N; i++)
|
||||
VC[i] ^= sn[i]; /* if (sn == ~0) {VT = ~VT;} else {VT = VT;} */
|
||||
merge(VACC_L, le, VC, VS);
|
||||
vector_copy(VD, VACC_L);
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
state->clip[i] = ge[i];
|
||||
for (i = 0; i < N; i++)
|
||||
state->comp[i] = le[i];
|
||||
for (i = 0; i < N; i++)
|
||||
state->ne[i] = 0;
|
||||
for (i = 0; i < N; i++)
|
||||
state->co[i] = 0;
|
||||
for (i = 0; i < N; i++)
|
||||
state->vce[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static void VCR(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_cr(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_eq(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
state->clip[i] = 0;
|
||||
for (i = 0; i < N; i++)
|
||||
state->comp[i] = (VS[i] == VT[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
state->comp[i] = state->comp[i] & (state->ne[i] ^ 1);
|
||||
#if (0)
|
||||
merge(VACC_L, state->comp, VS, VT); /* correct but redundant */
|
||||
#else
|
||||
vector_copy(VACC_L, VT);
|
||||
#endif
|
||||
vector_copy(VD, VACC_L);
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
state->ne[i] = 0;
|
||||
for (i = 0; i < N; i++)
|
||||
state->co[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static void VEQ(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_eq(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_ge(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
short ce[N];
|
||||
short eq[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
eq[i] = (VS[i] == VT[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
ce[i] = (state->ne[i] & state->co[i]) ^ 1;
|
||||
for (i = 0; i < N; i++)
|
||||
eq[i] = eq[i] & ce[i];
|
||||
for (i = 0; i < N; i++)
|
||||
state->clip[i] = 0;
|
||||
for (i = 0; i < N; i++)
|
||||
state->comp[i] = (VS[i] > VT[i]); /* greater than */
|
||||
for (i = 0; i < N; i++)
|
||||
state->comp[i] = state->comp[i] | eq[i]; /* ... or equal (commonly) */
|
||||
|
||||
merge(VACC_L, state->comp, VS, VT);
|
||||
vector_copy(VD, VACC_L);
|
||||
for (i = 0; i < N; i++)
|
||||
state->ne[i] = 0;
|
||||
for (i = 0; i < N; i++)
|
||||
state->co[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static void VGE(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_ge(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_lt(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
short cn[N];
|
||||
short eq[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
eq[i] = (VS[i] == VT[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
cn[i] = state->ne[i] & state->co[i];
|
||||
for (i = 0; i < N; i++)
|
||||
eq[i] = eq[i] & cn[i];
|
||||
for (i = 0; i < N; i++)
|
||||
state->clip[i] = 0;
|
||||
for (i = 0; i < N; i++)
|
||||
state->comp[i] = (VS[i] < VT[i]); /* less than */
|
||||
for (i = 0; i < N; i++)
|
||||
state->comp[i] = state->comp[i] | eq[i]; /* ... or equal (uncommonly) */
|
||||
|
||||
merge(VACC_L, state->comp, VS, VT);
|
||||
vector_copy(VD, VACC_L);
|
||||
for (i = 0; i < N; i++)
|
||||
state->ne[i] = 0;
|
||||
for (i = 0; i < N; i++)
|
||||
state->co[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static void VLT(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_lt(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_macf(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
int32_t product[N];
|
||||
uint32_t addend[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
product[i] = VS[i] * VT[i];
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (product[i] << 1) & 0x00000000FFFF;
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (unsigned short)(VACC_L[i]) + addend[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = (short)(addend[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (addend[i] >> 16) + (unsigned short)(product[i] >> 15);
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (unsigned short)(VACC_M[i]) + addend[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_M[i] = (short)(addend[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_H[i] -= (product[i] < 0);
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_H[i] += addend[i] >> 16;
|
||||
SIGNED_CLAMP_AM(state, VD);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VMACF(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_macf(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
static void VMACQ(int vd, int vs, int vt, int e)
|
||||
{
|
||||
vd &= vs &= vt &= e &= 0; /* unused */
|
||||
if (vd != vs || vt != e)
|
||||
return;
|
||||
message("VMACQ\nUnimplemented.", 3); /* untested, any N64 ROMs use this?? */
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_macu(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
int32_t product[N];
|
||||
uint32_t addend[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
product[i] = VS[i] * VT[i];
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (product[i] << 1) & 0x00000000FFFF;
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (unsigned short)(VACC_L[i]) + addend[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = (short)(addend[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (addend[i] >> 16) + (unsigned short)(product[i] >> 15);
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (unsigned short)(VACC_M[i]) + addend[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_M[i] = (short)(addend[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_H[i] -= (product[i] < 0);
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_H[i] += addend[i] >> 16;
|
||||
UNSIGNED_CLAMP(state, VD);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VMACU(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_macu(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_madh(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
int32_t product[N];
|
||||
uint32_t addend[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
product[i] = (signed short)(VS[i]) * (signed short)(VT[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (unsigned short)(VACC_M[i]) + (unsigned short)(product[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_M[i] += (short)(VS[i] * VT[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_H[i] += (addend[i] >> 16) + (product[i] >> 16);
|
||||
SIGNED_CLAMP_AM(state, VD);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VMADH(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_madh(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_madl(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
int32_t product[N];
|
||||
uint32_t addend[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
product[i] = (unsigned short)(VS[i]) * (unsigned short)(VT[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (product[i] & 0x0000FFFF0000) >> 16;
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (unsigned short)(VACC_L[i]) + addend[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = (short)(addend[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (unsigned short)(addend[i] >> 16);
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (unsigned short)(VACC_M[i]) + addend[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_M[i] = (short)(addend[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_H[i] += addend[i] >> 16;
|
||||
SIGNED_CLAMP_AL(state, VD);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VMADL(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_madl(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_madm(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
uint32_t addend[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (unsigned short)(VACC_L[i]) + (unsigned short)(VS[i]*VT[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] += (short)(VS[i] * VT[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (addend[i] >> 16) + (VS[i]*(unsigned short)(VT[i]) >> 16);
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (unsigned short)(VACC_M[i]) + addend[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_M[i] = (short)addend[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_H[i] += addend[i] >> 16;
|
||||
SIGNED_CLAMP_AM(state, VD);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VMADM(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_madm(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_madn(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
uint32_t addend[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (unsigned short)(VACC_L[i]) + (unsigned short)(VS[i]*VT[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] += (short)(VS[i] * VT[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (addend[i] >> 16) + ((unsigned short)(VS[i])*VT[i] >> 16);
|
||||
for (i = 0; i < N; i++)
|
||||
addend[i] = (unsigned short)(VACC_M[i]) + addend[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_M[i] = (short)addend[i];
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_H[i] += addend[i] >> 16;
|
||||
SIGNED_CLAMP_AL(state, VD);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VMADN(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_madn(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
static void VMOV(usf_state_t * state, int vd, int de, int vt, int e)
|
||||
{
|
||||
SHUFFLE_VECTOR(VACC_L, state->VR[vt], e);
|
||||
state->VR[vd][de &= 07] = VACC_L[e & 07];
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_mrg(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
merge(VACC_L, state->comp, VS, VT);
|
||||
vector_copy(VD, VACC_L);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VMRG(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_mrg(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_mudh(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = 0x0000;
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_M[i] = (short)(VS[i]*VT[i] >> 0);
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_H[i] = (short)(VS[i]*VT[i] >> 16);
|
||||
SIGNED_CLAMP_AM(state, VD);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VMUDH(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_mudh(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_mudl(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = (unsigned short)(VS[i])*(unsigned short)(VT[i]) >> 16;
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_M[i] = 0x0000;
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_H[i] = 0x0000;
|
||||
vector_copy(VD, VACC_L); /* no possibilities to clamp */
|
||||
return;
|
||||
}
|
||||
|
||||
static void VMUDL(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_mudl(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_mudm(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = (VS[i]*(unsigned short)(VT[i]) & 0x00000000FFFF) >> 0;
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_M[i] = (VS[i]*(unsigned short)(VT[i]) & 0x0000FFFF0000) >> 16;
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_H[i] = -(VACC_M[i] < 0);
|
||||
vector_copy(VD, VACC_M); /* no possibilities to clamp */
|
||||
return;
|
||||
}
|
||||
|
||||
static void VMUDM(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_mudm(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.10.11 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_mudn(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = ((unsigned short)(VS[i])*VT[i] & 0x00000000FFFF) >> 0;
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_M[i] = ((unsigned short)(VS[i])*VT[i] & 0x0000FFFF0000) >> 16;
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_H[i] = -(VACC_M[i] < 0);
|
||||
vector_copy(VD, VACC_L); /* no possibilities to clamp */
|
||||
return;
|
||||
}
|
||||
|
||||
static void VMUDN(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_mudn(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
#ifndef SEMIFRAC
|
||||
/*
|
||||
* acc = VS * VT;
|
||||
* acc = acc + 0x8000; // rounding value
|
||||
* acc = acc << 1; // partial value shifting
|
||||
*
|
||||
* Wrong: ACC(HI) = -((INT32)(acc) < 0)
|
||||
* Right: ACC(HI) = -(SEMIFRAC < 0)
|
||||
*/
|
||||
#define SEMIFRAC (VS[i]*VT[i]*2/2 + 0x8000/2)
|
||||
#endif
|
||||
|
||||
INLINE static void do_mulf(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = (SEMIFRAC << 1) >> 0;
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_M[i] = (SEMIFRAC << 1) >> 16;
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_H[i] = -((VACC_M[i] < 0) & (VS[i] != VT[i])); /* -32768 * -32768 */
|
||||
#ifndef ARCH_MIN_SSE2
|
||||
vector_copy(VD, VACC_M);
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] -= (VACC_M[i] < 0) & (VS[i] == VT[i]); /* ACC b 31 set, min*min */
|
||||
#else
|
||||
SIGNED_CLAMP_AM(state, VD);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
static void VMULF(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_mulf(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
#ifndef SEMIFRAC
|
||||
/*
|
||||
* acc = VS * VT;
|
||||
* acc = acc + 0x8000; // rounding value
|
||||
* acc = acc << 1; // partial value shifting
|
||||
*
|
||||
* Wrong: ACC(HI) = -((INT32)(acc) < 0)
|
||||
* Right: ACC(HI) = -(SEMIFRAC < 0)
|
||||
*/
|
||||
#define SEMIFRAC (VS[i]*VT[i]*2/2 + 0x8000/2)
|
||||
#endif
|
||||
|
||||
INLINE static void do_mulu(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = (SEMIFRAC << 1) >> 0;
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_M[i] = (SEMIFRAC << 1) >> 16;
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_H[i] = -((VACC_M[i] < 0) & (VS[i] != VT[i])); /* -32768 * -32768 */
|
||||
#if (0)
|
||||
UNSIGNED_CLAMP(state, VD);
|
||||
#else
|
||||
vector_copy(VD, VACC_M);
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] |= (VACC_M[i] >> 15); /* VD |= -(result == 0x000080008000) */
|
||||
for (i = 0; i < N; i++)
|
||||
VD[i] &= ~(VACC_H[i] >> 0); /* VD &= -(result >= 0x000000000000) */
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
static void VMULU(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_mulu(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE void do_nand(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = ~(VS[i] & VT[i]);
|
||||
vector_copy(VD, VACC_L);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VNAND(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_nand(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void do_ne(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
state->clip[i] = 0;
|
||||
for (i = 0; i < N; i++)
|
||||
state->comp[i] = (VS[i] != VT[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
state->comp[i] = state->comp[i] | state->ne[i];
|
||||
#if (0)
|
||||
merge(VACC_L, state->comp, VS, VT); /* correct but redundant */
|
||||
#else
|
||||
vector_copy(VACC_L, VS);
|
||||
#endif
|
||||
vector_copy(VD, VACC_L);
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
state->ne[i] = 0;
|
||||
for (i = 0; i < N; i++)
|
||||
state->co[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static void VNE(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_ne(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
static void VNOP(int vd, int vs, int vt, int e)
|
||||
{
|
||||
const int WB_inhibit = vd = vs = vt = e = 1;
|
||||
|
||||
if (WB_inhibit)
|
||||
return; /* message("VNOP", WB_inhibit); */
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE void do_nor(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = ~(VS[i] | VT[i]);
|
||||
vector_copy(VD, VACC_L);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VNOR(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_nor(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE void do_nxor(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = ~(VS[i] ^ VT[i]);
|
||||
vector_copy(VD, VACC_L);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VNXOR(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_nxor(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE void do_or(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = VS[i] | VT[i];
|
||||
vector_copy(VD, VACC_L);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VOR(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_or(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
#include "divrom.h"
|
||||
|
||||
static void VRCP(usf_state_t * state, int vd, int de, int vt, int e)
|
||||
{
|
||||
state->DivIn = (int)state->VR[vt][e & 07];
|
||||
do_div(state, state->DivIn, SP_DIV_SQRT_NO, SP_DIV_PRECISION_SINGLE);
|
||||
SHUFFLE_VECTOR(VACC_L, state->VR[vt], e);
|
||||
state->VR[vd][de &= 07] = (short)state->DivOut;
|
||||
state->DPH = SP_DIV_PRECISION_SINGLE;
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
#include "divrom.h"
|
||||
|
||||
static void VRCPH(usf_state_t * state, int vd, int de, int vt, int e)
|
||||
{
|
||||
state->DivIn = state->VR[vt][e & 07] << 16;
|
||||
SHUFFLE_VECTOR(VACC_L, state->VR[vt], e);
|
||||
state->VR[vd][de &= 07] = state->DivOut >> 16;
|
||||
state->DPH = SP_DIV_PRECISION_DOUBLE;
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
#include "divrom.h"
|
||||
|
||||
static void VRCPL(usf_state_t * state, int vd, int de, int vt, int e)
|
||||
{
|
||||
state->DivIn &= -state->DPH;
|
||||
state->DivIn |= (unsigned short)state->VR[vt][e & 07];
|
||||
do_div(state, state->DivIn, SP_DIV_SQRT_NO, state->DPH);
|
||||
SHUFFLE_VECTOR(VACC_L, state->VR[vt], e);
|
||||
state->VR[vd][de &= 07] = (short)state->DivOut;
|
||||
state->DPH = SP_DIV_PRECISION_SINGLE;
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
#include "divrom.h"
|
||||
|
||||
static void VRSQ(usf_state_t * state, int vd, int de, int vt, int e)
|
||||
{
|
||||
message("VRSQ\nUntested.", 1);
|
||||
state->DivIn = (int)state->VR[vt][e & 07];
|
||||
do_div(state, state->DivIn, SP_DIV_SQRT_YES, SP_DIV_PRECISION_SINGLE);
|
||||
SHUFFLE_VECTOR(VACC_L, state->VR[vt], e);
|
||||
state->VR[vd][de &= 07] = (short)state->DivOut;
|
||||
state->DPH = SP_DIV_PRECISION_SINGLE;
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
#include "divrom.h"
|
||||
|
||||
static void VRSQH(usf_state_t * state, int vd, int de, int vt, int e)
|
||||
{
|
||||
state->DivIn = state->VR[vt][e & 07] << 16;
|
||||
SHUFFLE_VECTOR(VACC_L, state->VR[vt], e);
|
||||
state->VR[vd][de &= 07] = state->DivOut >> 16;
|
||||
state->DPH = SP_DIV_PRECISION_DOUBLE;
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
#include "divrom.h"
|
||||
|
||||
static void VRSQL(usf_state_t * state, int vd, int de, int vt, int e)
|
||||
{
|
||||
state->DivIn &= -state->DPH;
|
||||
state->DivIn |= (unsigned short)state->VR[vt][e & 07];
|
||||
do_div(state, state->DivIn, SP_DIV_SQRT_YES, state->DPH);
|
||||
SHUFFLE_VECTOR(VACC_L, state->VR[vt], e);
|
||||
state->VR[vd][de &= 07] = (short)state->DivOut;
|
||||
state->DPH = SP_DIV_PRECISION_SINGLE;
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
#ifdef VU_EMULATE_SCALAR_ACCUMULATOR_READ
|
||||
static void VSAR(int vd, int vs, int vt, int e)
|
||||
{
|
||||
short oldval[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
oldval[i] = VR[vs][i];
|
||||
vt = 0;
|
||||
/* Even though VT is ignored in VSAR, according to official sources as well
|
||||
* as reversing, lots of games seem to specify it as non-zero, possibly to
|
||||
* avoid register stalling or other VU hazards. Not really certain why yet.
|
||||
*/
|
||||
e ^= 0x8;
|
||||
/* Or, for exception overrides, should this be `e &= 0x7;` ?
|
||||
* Currently this code is safer because &= is less likely to catch oddities.
|
||||
* Either way, documentation shows that the switch range is 0:2, not 8:A.
|
||||
*/
|
||||
if (e > 2)
|
||||
{
|
||||
message("VSAR\nInvalid mask.", 2);
|
||||
for (i = 0; i < N; i++)
|
||||
VR[vd][i] = 0x0000; /* override behavior (zilmar) */
|
||||
}
|
||||
else
|
||||
for (i = 0; i < N; i++)
|
||||
VR[vd][i] = VACC[e][i];
|
||||
for (i = 0; i < N; i++)
|
||||
VACC[e][i] = oldval[i]; /* ... = VS */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void VSAW(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
register int i;
|
||||
|
||||
vs = 0; /* unused--old VSAR algorithm */
|
||||
vt = 0; /* unused but mysteriously set many times */
|
||||
if (vs | vt)
|
||||
return;
|
||||
e ^= 0x8; /* &= 7 */
|
||||
|
||||
if (e > 0x2)
|
||||
{ /* branch very unlikely...never seen a game do VSAW illegally */
|
||||
message("VSAW\nIllegal mask.", 2);
|
||||
for (i = 0; i < N; i++)
|
||||
state->VR[vd][i] = 0x0000; /* override behavior (zilmar) */
|
||||
return;
|
||||
}
|
||||
vector_copy(state->VR[vd], state->VACC[e]);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void clr_bi(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{ /* clear CARRY and borrow in to accumulators */
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = VS[i] - VT[i] - state->co[i];
|
||||
SIGNED_CLAMP_SUB(state, VD, VS, VT);
|
||||
for (i = 0; i < N; i++)
|
||||
state->ne[i] = 0;
|
||||
for (i = 0; i < N; i++)
|
||||
state->co[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static void VSUB(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
clr_bi(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE static void set_bo(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{ /* set CARRY and borrow out from difference */
|
||||
int32_t dif[N];
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
dif[i] = (unsigned short)(VS[i]) - (unsigned short)(VT[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = VS[i] - VT[i];
|
||||
vector_copy(VD, VACC_L);
|
||||
for (i = 0; i < N; i++)
|
||||
state->ne[i] = (VS[i] != VT[i]);
|
||||
for (i = 0; i < N; i++)
|
||||
state->co[i] = (dif[i] < 0);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VSUBC(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
set_bo(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
/******************************************************************************\
|
||||
* Project: MSP Emulation Layer for Vector Unit Computational Operations *
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#ifndef _VU_H
|
||||
#define _VU_H
|
||||
|
||||
#define N 8
|
||||
/* N: number of processor elements in SIMD processor */
|
||||
|
||||
/*
|
||||
* RSP virtual registers (of vector unit)
|
||||
* The most important are the 32 general-purpose vector registers.
|
||||
* The correct way to accurately store these is using big-endian vectors.
|
||||
*
|
||||
* For ?WC2 we may need to do byte-precision access just as directly.
|
||||
* This is amended by using the `VU_S` and `VU_B` macros defined in `rsp.h`.
|
||||
*/
|
||||
|
||||
/*
|
||||
* accumulator-indexing macros (inverted access dimensions, suited for SSE)
|
||||
*/
|
||||
#define HI 00
|
||||
#define MD 01
|
||||
#define LO 02
|
||||
|
||||
#define VACC_L (state->VACC[LO])
|
||||
#define VACC_M (state->VACC[MD])
|
||||
#define VACC_H (state->VACC[HI])
|
||||
|
||||
#define ACC_L(i) (VACC_L[i])
|
||||
#define ACC_M(i) (VACC_M[i])
|
||||
#define ACC_H(i) (VACC_H[i])
|
||||
|
||||
#include "shuffle.h"
|
||||
#include "clamp.h"
|
||||
#include "cf.h"
|
||||
|
||||
static void res_V(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
register int i;
|
||||
|
||||
vs = vt = e = 0;
|
||||
if (vs != vt || vt != e)
|
||||
return;
|
||||
message("C2\nRESERVED", 2); /* uncertain how to handle reserved, untested */
|
||||
for (i = 0; i < N; i++)
|
||||
state->VR[vd][i] = 0x0000; /* override behavior (bpoint) */
|
||||
return;
|
||||
}
|
||||
static void res_M(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
message("VMUL IQ", 2);
|
||||
res_V(state, vd, vs, vt, e);
|
||||
return; /* Ultra64 OS did have these, so one could implement this ext. */
|
||||
}
|
||||
|
||||
#include "vabs.h"
|
||||
#include "vadd.h"
|
||||
#include "vaddc.h"
|
||||
#include "vand.h"
|
||||
#include "vch.h"
|
||||
#include "vcl.h"
|
||||
#include "vcr.h"
|
||||
#include "veq.h"
|
||||
#include "vge.h"
|
||||
#include "vlt.h"
|
||||
#include "vmacf.h"
|
||||
#include "vmacq.h"
|
||||
#include "vmacu.h"
|
||||
#include "vmadh.h"
|
||||
#include "vmadl.h"
|
||||
#include "vmadm.h"
|
||||
#include "vmadn.h"
|
||||
#include "vmov.h"
|
||||
#include "vmrg.h"
|
||||
#include "vmudh.h"
|
||||
#include "vmudl.h"
|
||||
#include "vmudm.h"
|
||||
#include "vmudn.h"
|
||||
#include "vmulf.h"
|
||||
#include "vmulu.h"
|
||||
#include "vnand.h"
|
||||
#include "vne.h"
|
||||
#include "vnop.h"
|
||||
#include "vnor.h"
|
||||
#include "vnxor.h"
|
||||
#include "vor.h"
|
||||
#include "vrcp.h"
|
||||
#include "vrcph.h"
|
||||
#include "vrcpl.h"
|
||||
#include "vrsq.h"
|
||||
#include "vrsqh.h"
|
||||
#include "vrsql.h"
|
||||
#include "vsaw.h"
|
||||
#include "vsub.h"
|
||||
#include "vsubc.h"
|
||||
#include "vxor.h"
|
||||
|
||||
static void (*COP2_C2[64])(usf_state_t *, int, int, int, int) = {
|
||||
VMULF ,VMULU ,res_M ,res_M ,VMUDL ,VMUDM ,VMUDN ,VMUDH , /* 000 */
|
||||
VMACF ,VMACU ,res_M ,VMACQ ,VMADL ,VMADM ,VMADN ,VMADH , /* 001 */
|
||||
VADD ,VSUB ,res_V ,VABS ,VADDC ,VSUBC ,res_V ,res_V , /* 010 */
|
||||
res_V ,res_V ,res_V ,res_V ,res_V ,VSAW ,res_V ,res_V , /* 011 */
|
||||
VLT ,VEQ ,VNE ,VGE ,VCL ,VCH ,VCR ,VMRG , /* 100 */
|
||||
VAND ,VNAND ,VOR ,VNOR ,VXOR ,VNXOR ,res_V ,res_V , /* 101 */
|
||||
VRCP ,VRCPL ,VRCPH ,VMOV ,VRSQ ,VRSQL ,VRSQH ,VNOP , /* 110 */
|
||||
res_V ,res_V ,res_V ,res_V ,res_V ,res_V ,res_V ,res_V , /* 111 */
|
||||
}; /* 000 001 010 011 100 101 110 111 */
|
||||
#endif
|
|
@ -0,0 +1,33 @@
|
|||
/******************************************************************************\
|
||||
* Authors: Iconoclast *
|
||||
* Release: 2013.11.26 *
|
||||
* License: CC0 Public Domain Dedication *
|
||||
* *
|
||||
* To the extent possible under law, the author(s) have dedicated all copyright *
|
||||
* and related and neighboring rights to this software to the public domain *
|
||||
* worldwide. This software is distributed without any warranty. *
|
||||
* *
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along *
|
||||
* with this software. *
|
||||
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. *
|
||||
\******************************************************************************/
|
||||
#include "vu.h"
|
||||
|
||||
INLINE void do_xor(usf_state_t * state, short* VD, short* VS, short* VT)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
VACC_L[i] = VS[i] ^ VT[i];
|
||||
vector_copy(VD, VACC_L);
|
||||
return;
|
||||
}
|
||||
|
||||
static void VXOR(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
short ST[N];
|
||||
|
||||
SHUFFLE_VECTOR(ST, state->VR[vt], e);
|
||||
do_xor(state, state->VR[vd], state->VR[vs], ST);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include "usf_internal.h"
|
||||
|
||||
void SetupTLB_Entry (usf_state_t * state, int32_t Entry);
|
||||
|
||||
uint32_t AddressDefined ( usf_state_t * state, uintptr_t VAddr) {
|
||||
uint32_t i;
|
||||
|
||||
if (VAddr >= 0x80000000 && VAddr <= 0xBFFFFFFF) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
if (state->FastTlb[i].ValidEntry == 0) { continue; }
|
||||
if (VAddr >= state->FastTlb[i].VSTART && VAddr <= state->FastTlb[i].VEND) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InitilizeTLB (usf_state_t * state) {
|
||||
uint32_t count;
|
||||
|
||||
for (count = 0; count < 32; count++) { state->tlb[count].EntryDefined = 0; }
|
||||
for (count = 0; count < 64; count++) { state->FastTlb[count].ValidEntry = 0; }
|
||||
SetupTLB(state);
|
||||
}
|
||||
|
||||
void SetupTLB (usf_state_t * state) {
|
||||
uint32_t count;
|
||||
|
||||
memset(state->TLB_Map,0,(0xFFFFF * sizeof(uintptr_t)));
|
||||
for (count = 0x80000000; count < 0xC0000000; count += 0x1000) {
|
||||
state->TLB_Map[count >> 12] = ((uintptr_t)state->N64MEM + (count & 0x1FFFFFFF)) - count;
|
||||
}
|
||||
for (count = 0; count < 32; count ++) { SetupTLB_Entry(state, count); }
|
||||
}
|
||||
/*
|
||||
test=(BYTE *) VirtualAlloc( 0x10, 0x70000, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
if(test == 0) {
|
||||
//printf("FAIL!\n");
|
||||
exit(0);
|
||||
}
|
||||
*/
|
||||
|
||||
void SetupTLB_Entry (usf_state_t * state, int Entry) {
|
||||
uint32_t FastIndx;
|
||||
|
||||
|
||||
if (!state->tlb[Entry].EntryDefined) { return; }
|
||||
FastIndx = Entry << 1;
|
||||
state->FastTlb[FastIndx].VSTART=state->tlb[Entry].EntryHi.VPN2 << 13;
|
||||
state->FastTlb[FastIndx].VEND = state->FastTlb[FastIndx].VSTART + (state->tlb[Entry].PageMask.Mask << 12) + 0xFFF;
|
||||
state->FastTlb[FastIndx].PHYSSTART = state->tlb[Entry].EntryLo0.PFN << 12;
|
||||
state->FastTlb[FastIndx].VALID = state->tlb[Entry].EntryLo0.V;
|
||||
state->FastTlb[FastIndx].DIRTY = state->tlb[Entry].EntryLo0.D;
|
||||
state->FastTlb[FastIndx].GLOBAL = state->tlb[Entry].EntryLo0.GLOBAL & state->tlb[Entry].EntryLo1.GLOBAL;
|
||||
state->FastTlb[FastIndx].ValidEntry = 0;
|
||||
|
||||
FastIndx = (Entry << 1) + 1;
|
||||
state->FastTlb[FastIndx].VSTART=(state->tlb[Entry].EntryHi.VPN2 << 13) + ((state->tlb[Entry].PageMask.Mask << 12) + 0xFFF + 1);
|
||||
state->FastTlb[FastIndx].VEND = state->FastTlb[FastIndx].VSTART + (state->tlb[Entry].PageMask.Mask << 12) + 0xFFF;
|
||||
state->FastTlb[FastIndx].PHYSSTART = state->tlb[Entry].EntryLo1.PFN << 12;
|
||||
state->FastTlb[FastIndx].VALID = state->tlb[Entry].EntryLo1.V;
|
||||
state->FastTlb[FastIndx].DIRTY = state->tlb[Entry].EntryLo1.D;
|
||||
state->FastTlb[FastIndx].GLOBAL = state->tlb[Entry].EntryLo0.GLOBAL & state->tlb[Entry].EntryLo1.GLOBAL;
|
||||
state->FastTlb[FastIndx].ValidEntry = 0;
|
||||
|
||||
for ( FastIndx = Entry << 1; FastIndx <= (Entry << 1) + 1; FastIndx++) {
|
||||
uint32_t count;
|
||||
|
||||
if (!state->FastTlb[FastIndx].VALID) {
|
||||
state->FastTlb[FastIndx].ValidEntry = 1;
|
||||
continue;
|
||||
}
|
||||
if (state->FastTlb[FastIndx].VEND <= state->FastTlb[FastIndx].VSTART) {
|
||||
continue;
|
||||
}
|
||||
if (state->FastTlb[FastIndx].VSTART >= 0x80000000 && state->FastTlb[FastIndx].VEND <= 0xBFFFFFFF) {
|
||||
continue;
|
||||
}
|
||||
if (state->FastTlb[FastIndx].PHYSSTART > 0x1FFFFFFF) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//test if overlap
|
||||
state->FastTlb[FastIndx].ValidEntry = 1;
|
||||
for (count = state->FastTlb[FastIndx].VSTART; count < state->FastTlb[FastIndx].VEND; count += 0x1000) {
|
||||
state->TLB_Map[count >> 12] = ((uintptr_t)state->N64MEM + (count - state->FastTlb[FastIndx].VSTART + state->FastTlb[FastIndx].PHYSSTART)) - count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TLB_Probe (usf_state_t * state) {
|
||||
uint32_t Counter;
|
||||
|
||||
|
||||
INDEX_REGISTER |= 0x80000000;
|
||||
for (Counter = 0; Counter < 32; Counter ++) {
|
||||
uint32_t TlbValue = state->tlb[Counter].EntryHi.Value & (~state->tlb[Counter].PageMask.Mask << 13);
|
||||
uint32_t EntryHi = ENTRYHI_REGISTER & (~state->tlb[Counter].PageMask.Mask << 13);
|
||||
|
||||
if (TlbValue == EntryHi) {
|
||||
uint32_t Global = (state->tlb[Counter].EntryHi.Value & 0x100) != 0;
|
||||
uint32_t SameAsid = ((state->tlb[Counter].EntryHi.Value & 0xFF) == (ENTRYHI_REGISTER & 0xFF));
|
||||
|
||||
if (Global || SameAsid) {
|
||||
INDEX_REGISTER = Counter;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TLB_Read (usf_state_t * state) {
|
||||
uint32_t index = INDEX_REGISTER & 0x1F;
|
||||
|
||||
PAGE_MASK_REGISTER = state->tlb[index].PageMask.Value ;
|
||||
ENTRYHI_REGISTER = (state->tlb[index].EntryHi.Value & ~state->tlb[index].PageMask.Value) ;
|
||||
ENTRYLO0_REGISTER = state->tlb[index].EntryLo0.Value;
|
||||
ENTRYLO1_REGISTER = state->tlb[index].EntryLo1.Value;
|
||||
}
|
||||
|
||||
uint32_t TranslateVaddr ( usf_state_t * state, uintptr_t * Addr) {
|
||||
if (state->TLB_Map[((*Addr) & 0xffffffff) >> 12] == 0) { return 0; }
|
||||
*Addr = (uintptr_t)((uint8_t *)(state->TLB_Map[((*Addr) & 0xffffffff) >> 12] + ((*Addr) & 0xffffffff)) - (uintptr_t)state->N64MEM);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void WriteTLBEntry (usf_state_t * state, int32_t index) {
|
||||
uint32_t FastIndx;
|
||||
|
||||
FastIndx = index << 1;
|
||||
if ((state->PROGRAM_COUNTER >= state->FastTlb[FastIndx].VSTART &&
|
||||
state->PROGRAM_COUNTER < state->FastTlb[FastIndx].VEND &&
|
||||
state->FastTlb[FastIndx].ValidEntry && state->FastTlb[FastIndx].VALID)
|
||||
||
|
||||
(state->PROGRAM_COUNTER >= state->FastTlb[FastIndx + 1].VSTART &&
|
||||
state->PROGRAM_COUNTER < state->FastTlb[FastIndx + 1].VEND &&
|
||||
state->FastTlb[FastIndx + 1].ValidEntry && state->FastTlb[FastIndx + 1].VALID))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (state->tlb[index].EntryDefined) {
|
||||
uint32_t count;
|
||||
|
||||
for ( FastIndx = index << 1; FastIndx <= (index << 1) + 1; FastIndx++) {
|
||||
if (!state->FastTlb[FastIndx].ValidEntry) { continue; }
|
||||
if (!state->FastTlb[FastIndx].VALID) { continue; }
|
||||
for (count = state->FastTlb[FastIndx].VSTART; count < state->FastTlb[FastIndx].VEND; count += 0x1000) {
|
||||
state->TLB_Map[count >> 12] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
state->tlb[index].PageMask.Value = PAGE_MASK_REGISTER;
|
||||
state->tlb[index].EntryHi.Value = ENTRYHI_REGISTER;
|
||||
state->tlb[index].EntryLo0.Value = ENTRYLO0_REGISTER;
|
||||
state->tlb[index].EntryLo1.Value = ENTRYLO1_REGISTER;
|
||||
state->tlb[index].EntryDefined = 1;
|
||||
|
||||
|
||||
SetupTLB_Entry(state, index);
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
#ifndef _TLB_H_
|
||||
#define _TLB_H_
|
||||
|
||||
typedef struct {
|
||||
uint32_t EntryDefined;
|
||||
union {
|
||||
uint32_t Value;
|
||||
uint8_t A[4];
|
||||
|
||||
struct {
|
||||
unsigned zero : 13;
|
||||
unsigned Mask : 12;
|
||||
unsigned zero2 : 7;
|
||||
} ;
|
||||
|
||||
} PageMask;
|
||||
|
||||
union {
|
||||
uint32_t Value;
|
||||
uint8_t A[4];
|
||||
|
||||
struct {
|
||||
unsigned ASID : 8;
|
||||
unsigned Zero : 4;
|
||||
unsigned G : 1;
|
||||
unsigned VPN2 : 19;
|
||||
};
|
||||
|
||||
} EntryHi;
|
||||
|
||||
union {
|
||||
uint32_t Value;
|
||||
uint8_t A[4];
|
||||
|
||||
struct {
|
||||
unsigned GLOBAL: 1;
|
||||
unsigned V : 1;
|
||||
unsigned D : 1;
|
||||
unsigned C : 3;
|
||||
unsigned PFN : 20;
|
||||
unsigned ZERO: 6;
|
||||
};
|
||||
|
||||
} EntryLo0;
|
||||
|
||||
union {
|
||||
uint32_t Value;
|
||||
uint8_t A[4];
|
||||
|
||||
struct {
|
||||
unsigned GLOBAL: 1;
|
||||
unsigned V : 1;
|
||||
unsigned D : 1;
|
||||
unsigned C : 3;
|
||||
unsigned PFN : 20;
|
||||
unsigned ZERO: 6;
|
||||
} ;
|
||||
|
||||
} EntryLo1;
|
||||
} TLB;
|
||||
|
||||
typedef struct {
|
||||
uint32_t VSTART;
|
||||
uint32_t VEND;
|
||||
uint32_t PHYSSTART;
|
||||
uint32_t VALID;
|
||||
uint32_t DIRTY;
|
||||
uint32_t GLOBAL;
|
||||
uint32_t ValidEntry;
|
||||
} FASTTLB;
|
||||
|
||||
uint32_t AddressDefined ( usf_state_t *, uintptr_t VAddr);
|
||||
void InitilizeTLB ( usf_state_t * );
|
||||
void SetupTLB ( usf_state_t * );
|
||||
void TLB_Probe ( usf_state_t * );
|
||||
void TLB_Read ( usf_state_t * );
|
||||
uint32_t TranslateVaddr ( usf_state_t *, uintptr_t * Addr);
|
||||
void WriteTLBEntry ( usf_state_t *, int32_t index );
|
||||
|
||||
#endif
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Project 64 - A Nintendo 64 emulator.
|
||||
*
|
||||
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
||||
* Jabo (jabo@emulation64.com).
|
||||
*
|
||||
* pj64 homepage: www.pj64.net
|
||||
*
|
||||
* Permission to use, copy, modify and distribute Project64 in both binary and
|
||||
* source form, for non-commercial purposes, is hereby granted without fee,
|
||||
* providing that this license information and copyright notice appear with
|
||||
* all copies and any derived work.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event shall the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
||||
* seek permission of the copyright holders first. Commercial use includes
|
||||
* charging money for Project64 or software derived from Project64.
|
||||
*
|
||||
* The copyright holders request that bug fixes and improvements to the code
|
||||
* should be forwarded to them so if they want them.
|
||||
*
|
||||
*/
|
||||
#ifndef __Types_h
|
||||
#define __Types_h
|
||||
|
||||
#include <stdint.h>
|
||||
typedef uint64_t QWORD;
|
||||
|
||||
typedef union tagVect {
|
||||
double FD[2];
|
||||
int64_t DW[2];
|
||||
uint64_t UDW[2];
|
||||
int32_t W[4];
|
||||
float FS[4];
|
||||
uint32_t UW[4];
|
||||
int16_t HW[8];
|
||||
uint16_t UHW[8];
|
||||
int8_t B[16];
|
||||
uint8_t UB[16];
|
||||
} VECTOR;
|
||||
|
||||
typedef union tagUWORD {
|
||||
int32_t W;
|
||||
uint32_t UW;
|
||||
int16_t HW[2];
|
||||
uint16_t UHW[2];
|
||||
int8_t B[4];
|
||||
uint8_t UB[4];
|
||||
float F;
|
||||
} MIPS_WORD;
|
||||
|
||||
typedef union tagUDWORD {
|
||||
double D;
|
||||
int64_t DW;
|
||||
uint64_t UDW;
|
||||
int32_t W[2];
|
||||
uint32_t UW[2];
|
||||
int16_t HW[4];
|
||||
uint16_t UHW[4];
|
||||
int8_t B[8];
|
||||
uint8_t UB[8];
|
||||
float F[2];
|
||||
} MIPS_DWORD;
|
||||
|
||||
typedef MIPS_WORD MIPSUWORD;
|
||||
typedef MIPS_DWORD MIPSUDWORD;
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,221 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "usf.h"
|
||||
#include "cpu.h"
|
||||
#include "memory.h"
|
||||
#include "audio.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include "usf_internal.h"
|
||||
|
||||
ssize_t get_usf_state_size()
|
||||
{
|
||||
return sizeof(usf_state_t) + 8192 + 8192 + 0x100000 * sizeof(uintptr_t) + 0x1D000 + 0x800000;
|
||||
}
|
||||
|
||||
void usf_clear(void * state)
|
||||
{
|
||||
ssize_t offset, offset_memchunk;
|
||||
memset(state, 0, get_usf_state_size());
|
||||
offset = 4096 - (((uintptr_t)state) & 4095);
|
||||
USF_STATE_HELPER->offset_to_structure = offset;
|
||||
|
||||
offset_memchunk = ( offset + sizeof(usf_state_t) + 4095 ) & ~4095;
|
||||
USF_STATE_HELPER->offset_to_memchunk = offset + offset_memchunk;
|
||||
|
||||
//USF_STATE->savestatespace = NULL;
|
||||
//USF_STATE->cpu_running = 0;
|
||||
USF_STATE->cpu_stopped = 1;
|
||||
|
||||
//USF_STATE->enablecompare = 0;
|
||||
//USF_STATE->enableFIFOfull = 0;
|
||||
|
||||
//USF_STATE->NextInstruction = 0;
|
||||
//USF_STATE->JumpToLocation = 0;
|
||||
//USF_STATE->AudioIntrReg = 0;
|
||||
//USF_STATE->CPU_Action = 0;
|
||||
//USF_STATE->Timers = 0;
|
||||
//USF_STATE->CPURunning = 0;
|
||||
//USF_STATE->SPHack = 0;
|
||||
//USF_STATE->WaitMode = 0;
|
||||
|
||||
//USF_STATE->TLB_Map = 0;
|
||||
//USF_STATE->MemChunk = 0;
|
||||
USF_STATE->RdramSize = 0x800000;
|
||||
USF_STATE->SystemRdramSize = 0x800000;
|
||||
USF_STATE->RomFileSize = 0x4000000;
|
||||
|
||||
//USF_STATE->N64MEM = 0;
|
||||
//USF_STATE->RDRAM = 0;
|
||||
//USF_STATE->DMEM = 0;
|
||||
//USF_STATE->IMEM = 0;
|
||||
|
||||
//memset(USF_STATE->ROMPages, 0, sizeof(USF_STATE->ROMPages));
|
||||
//USF_STATE->savestatespace = 0;
|
||||
//USF_STATE->NOMEM = 0;
|
||||
|
||||
//USF_STATE->WrittenToRom = 0;
|
||||
//USF_STATE->WroteToRom = 0;
|
||||
//USF_STATE->TempValue = 0;
|
||||
//USF_STATE->MemoryState = 0;
|
||||
//USF_STATE->EmptySpace = 0;
|
||||
|
||||
//USF_STATE->Registers = 0;
|
||||
|
||||
//USF_STATE->PIF_Ram = 0;
|
||||
|
||||
PreAllocate_Memory(USF_STATE);
|
||||
}
|
||||
|
||||
void usf_set_compare(void * state, int enable)
|
||||
{
|
||||
USF_STATE->enablecompare = enable;
|
||||
}
|
||||
|
||||
void usf_set_fifo_full(void * state, int enable)
|
||||
{
|
||||
USF_STATE->enableFIFOfull = enable;
|
||||
}
|
||||
|
||||
static uint32_t get_le32( const void * _p )
|
||||
{
|
||||
const uint8_t * p = (const uint8_t *) _p;
|
||||
return p[0] + p[1] * 0x100 + p[2] * 0x10000 + p[3] * 0x1000000;
|
||||
}
|
||||
|
||||
int usf_upload_section(void * state, const uint8_t * data, ssize_t size)
|
||||
{
|
||||
uint32_t temp;
|
||||
|
||||
if ( size < 4 ) return -1;
|
||||
temp = get_le32( data ); data += 4; size -= 4;
|
||||
|
||||
if(temp == 0x34365253) { //there is a rom section
|
||||
uint32_t len, start;
|
||||
|
||||
if ( size < 4 ) return -1;
|
||||
len = get_le32( data ); data += 4; size -= 4;
|
||||
|
||||
while(len) {
|
||||
if ( size < 4 ) return -1;
|
||||
start = get_le32( data ); data += 4; size -= 4;
|
||||
|
||||
while(len) {
|
||||
int page = start >> 16;
|
||||
int readLen = ( ((start + len) >> 16) > page) ? (((page + 1) << 16) - start) : len;
|
||||
|
||||
if( USF_STATE->ROMPages[page] == 0 ) {
|
||||
USF_STATE->ROMPages[page] = malloc(0x10000);
|
||||
if ( USF_STATE->ROMPages[page] == 0 )
|
||||
return -1;
|
||||
|
||||
memset(USF_STATE->ROMPages[page], 0, 0x10000);
|
||||
}
|
||||
|
||||
if ( size < readLen )
|
||||
return -1;
|
||||
|
||||
memcpy( USF_STATE->ROMPages[page] + (start & 0xffff), data, readLen );
|
||||
data += readLen; size -= readLen;
|
||||
|
||||
start += readLen;
|
||||
len -= readLen;
|
||||
}
|
||||
|
||||
if ( size < 4 ) return -1;
|
||||
len = get_le32( data ); data += 4; size -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
if ( size < 4 ) return -1;
|
||||
temp = get_le32( data ); data += 4; size -= 4;
|
||||
|
||||
if(temp == 0x34365253) {
|
||||
uint32_t len, start;
|
||||
|
||||
if ( size < 4 ) return -1;
|
||||
len = get_le32( data ); data += 4; size -= 4;
|
||||
|
||||
while(len) {
|
||||
if ( size < 4 ) return -1;
|
||||
start = get_le32( data ); data += 4; size -= 4;
|
||||
|
||||
if ( size < len ) return -1;
|
||||
memcpy( USF_STATE->savestatespace + start, data, len );
|
||||
data += len; size -= len;
|
||||
|
||||
if ( size < 4 ) return -1;
|
||||
len = get_le32( data ); data += 4; size -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usf_startup(void * state)
|
||||
{
|
||||
// Detect the Ramsize before the memory allocation
|
||||
|
||||
if(*(uint32_t*)(USF_STATE->savestatespace + 4) == 0x400000) {
|
||||
void * savestate;
|
||||
USF_STATE->RdramSize = 0x400000;
|
||||
savestate = realloc(USF_STATE->savestatespace, 0x40275c);
|
||||
if ( savestate )
|
||||
USF_STATE->savestatespace = savestate;
|
||||
} else if(*(uint32_t*)(USF_STATE->savestatespace + 4) == 0x800000)
|
||||
USF_STATE->RdramSize = 0x800000;
|
||||
|
||||
Allocate_Memory(state);
|
||||
|
||||
StartEmulationFromSave(USF_STATE, USF_STATE->savestatespace);
|
||||
}
|
||||
|
||||
void usf_render(void * state, int16_t * buffer, ssize_t count, int32_t * sample_rate)
|
||||
{
|
||||
if ( !USF_STATE->MemoryState )
|
||||
usf_startup( USF_STATE );
|
||||
|
||||
if ( USF_STATE->samples_in_buffer )
|
||||
{
|
||||
ssize_t do_max = USF_STATE->samples_in_buffer;
|
||||
if ( do_max > count )
|
||||
do_max = count;
|
||||
|
||||
memcpy( buffer, USF_STATE->samplebuf, sizeof(int16_t) * 2 * do_max );
|
||||
|
||||
USF_STATE->samples_in_buffer -= do_max;
|
||||
|
||||
if ( sample_rate )
|
||||
*sample_rate = USF_STATE->SampleRate;
|
||||
|
||||
if ( USF_STATE->samples_in_buffer )
|
||||
{
|
||||
memmove( USF_STATE->samplebuf, USF_STATE->samplebuf + do_max, sizeof(int16_t) * 2 * USF_STATE->samples_in_buffer );
|
||||
return;
|
||||
}
|
||||
|
||||
buffer += 2 * do_max;
|
||||
count -= do_max;
|
||||
}
|
||||
|
||||
USF_STATE->sample_buffer = buffer;
|
||||
USF_STATE->sample_buffer_count = count;
|
||||
|
||||
USF_STATE->cpu_stopped = 0;
|
||||
USF_STATE->cpu_running = 1;
|
||||
|
||||
StartInterpreterCPU(USF_STATE);
|
||||
|
||||
if ( sample_rate )
|
||||
*sample_rate = USF_STATE->SampleRate;
|
||||
}
|
||||
|
||||
void usf_shutdown(void * state)
|
||||
{
|
||||
Release_Memory(USF_STATE);
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef _USF_H_
|
||||
#define _USF_H_
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct usf_state usf_state_t;
|
||||
|
||||
typedef struct usf_state_helper usf_state_helper_t;
|
||||
|
||||
#include "usf.h"
|
||||
#include "cpu.h"
|
||||
#include "memory.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
ssize_t get_usf_state_size();
|
||||
|
||||
void usf_clear(void * state);
|
||||
|
||||
void usf_set_compare(void * state, int enable);
|
||||
void usf_set_fifo_full(void * state, int enable);
|
||||
|
||||
int usf_upload_section(void * state, const uint8_t * data, ssize_t size);
|
||||
|
||||
void usf_render(void * state, int16_t * buffer, ssize_t count, int32_t * sample_rate);
|
||||
|
||||
void usf_shutdown(void * state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,105 @@
|
|||
#ifndef _USF_INTERNAL_H_
|
||||
#define _USF_INTERNAL_H_
|
||||
|
||||
struct usf_state_helper
|
||||
{
|
||||
ssize_t offset_to_structure;
|
||||
ssize_t offset_to_memchunk;
|
||||
};
|
||||
|
||||
typedef uint32_t RCPREG;
|
||||
|
||||
struct usf_state
|
||||
{
|
||||
// RSP vector registers, need to be aligned to 16 bytes
|
||||
short VR[32][8];
|
||||
short VACC[3][8];
|
||||
|
||||
// RSP virtual registers
|
||||
int SR[32];
|
||||
|
||||
// rsp/rsp.c
|
||||
RCPREG* CR[16];
|
||||
|
||||
// rsp/vu/cf.h
|
||||
short ne[8]; /* $vco: high byte "NOTEQUAL" */
|
||||
short co[8]; /* $vco: low byte "carry/borrow in/out" */
|
||||
short clip[8]; /* $vcc: high byte (clip tests: VCL, VCH, VCR) */
|
||||
short comp[8]; /* $vcc: low byte (VEQ, VNE, VLT, VGE, VCL, VCH, VCR) */
|
||||
short vce[8]; /* $vce: vector compare extension register */
|
||||
|
||||
// rsp/vu/divrom.h
|
||||
int DivIn; /* buffered numerator of division read from vector file */
|
||||
int DivOut; /* global division result set by VRCP/VRCPL/VRSQ/VRSQH */
|
||||
#if (0)
|
||||
int MovIn; /* We do not emulate this register (obsolete, for VMOV). */
|
||||
#endif
|
||||
|
||||
int DPH;
|
||||
|
||||
// rsp/rsp.h
|
||||
int temp_PC;
|
||||
short MFC0_count[32];
|
||||
|
||||
uint32_t cpu_running, cpu_stopped;
|
||||
|
||||
// options from file tags
|
||||
uint32_t enablecompare, enableFIFOfull;
|
||||
|
||||
// buffering for rendered sample data
|
||||
ssize_t sample_buffer_count;
|
||||
int16_t * sample_buffer;
|
||||
|
||||
// audio.c
|
||||
int32_t SampleRate;
|
||||
int16_t samplebuf[16384];
|
||||
ssize_t samples_in_buffer;
|
||||
|
||||
// cpu.c
|
||||
uint32_t NextInstruction, JumpToLocation, AudioIntrReg;
|
||||
CPU_ACTION * CPU_Action;
|
||||
SYSTEM_TIMERS * Timers;
|
||||
OPCODE Opcode;
|
||||
uint32_t CPURunning, SPHack;
|
||||
uint32_t * WaitMode;
|
||||
|
||||
// interpreter_ops.c
|
||||
uint32_t SWL_MASK[4], SWR_MASK[4], LWL_MASK[4], LWR_MASK[4];
|
||||
int32_t SWL_SHIFT[4], SWR_SHIFT[4], LWL_SHIFT[4], LWR_SHIFT[4];
|
||||
int32_t RoundingModel;
|
||||
|
||||
// memory.c
|
||||
uintptr_t *TLB_Map;
|
||||
uint8_t * MemChunk;
|
||||
uint32_t RdramSize, SystemRdramSize, RomFileSize;
|
||||
uint8_t * N64MEM, * RDRAM, * DMEM, * IMEM, * ROMPages[0x400], * savestatespace, * NOMEM;
|
||||
|
||||
uint32_t WrittenToRom;
|
||||
uint32_t WroteToRom;
|
||||
uint32_t TempValue;
|
||||
uint32_t MemoryState;
|
||||
|
||||
uint8_t EmptySpace;
|
||||
|
||||
// pif.c
|
||||
uint8_t *PIF_Ram;
|
||||
|
||||
// registers.c
|
||||
uint32_t PROGRAM_COUNTER, * CP0,*FPCR,*RegRDRAM,*RegSP,*RegDPC,*RegMI,*RegVI,*RegAI,*RegPI,
|
||||
*RegRI,*RegSI, HalfLine, RegModValue, ViFieldNumber, LLBit, LLAddr;
|
||||
void * FPRDoubleLocation[32], * FPRFloatLocation[32];
|
||||
MIPS_DWORD *GPR, *FPR, HI, LO;
|
||||
int32_t fpuControl;
|
||||
N64_REGISTERS * Registers;
|
||||
|
||||
// tlb.c
|
||||
FASTTLB FastTlb[64];
|
||||
TLB tlb[32];
|
||||
};
|
||||
|
||||
#define USF_STATE_HELPER ((usf_state_helper_t *)(state))
|
||||
|
||||
#define USF_STATE ((usf_state_t *)(((uint8_t *)(state))+((usf_state_helper_t *)(state))->offset_to_structure))
|
||||
#define USF_CHUNK (((uint8_t*)(state))+((usf_state_helper_t *)(state))->offset_to_memchunk)
|
||||
|
||||
#endif
|
|
@ -21,7 +21,8 @@
|
|||
8360EF6E17F92E86005208A4 /* HighlyExperimental.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8360EF4417F92C92005208A4 /* HighlyExperimental.framework */; };
|
||||
8384904A180764B500E7332D /* SSEQPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83848FEC1807624000E7332D /* SSEQPlayer.framework */; };
|
||||
8384904B180764C200E7332D /* SSEQPlayer.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83848FEC1807624000E7332D /* SSEQPlayer.framework */; };
|
||||
83D4481E18ACA5C8000F443A /* lazyusf in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83D4481B18ACA5AD000F443A /* lazyusf */; };
|
||||
83C8B6FB18AF58FA0071B040 /* lazyusf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83C8B65618AF57770071B040 /* lazyusf.framework */; };
|
||||
83C8B6FC18AF59080071B040 /* lazyusf.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83C8B65618AF57770071B040 /* lazyusf.framework */; };
|
||||
83DE0CBC180B02CC00269051 /* vio2sf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83DE0C3A180A9BD500269051 /* vio2sf.framework */; };
|
||||
83DE0CBD180B02D800269051 /* vio2sf.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83DE0C3A180A9BD500269051 /* vio2sf.framework */; };
|
||||
83DE0CC0180B27C200269051 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83DE0CBF180B27C200269051 /* libz.dylib */; };
|
||||
|
@ -113,6 +114,13 @@
|
|||
remoteGlobalIDString = 83848FB71807623F00E7332D;
|
||||
remoteInfo = SSEQPlayer;
|
||||
};
|
||||
83C8B65518AF57770071B040 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 83C8B65018AF57770071B040 /* lazyusf.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 83C8B62218AF57770071B040;
|
||||
remoteInfo = lazyusf;
|
||||
};
|
||||
83DE0C39180A9BD500269051 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 83DE0C34180A9BD400269051 /* vio2sf.xcodeproj */;
|
||||
|
@ -136,7 +144,6 @@
|
|||
dstPath = "";
|
||||
dstSubfolderSpec = 6;
|
||||
files = (
|
||||
83D4481E18ACA5C8000F443A /* lazyusf in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -146,6 +153,7 @@
|
|||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
83C8B6FC18AF59080071B040 /* lazyusf.framework in CopyFiles */,
|
||||
83DE0CBD180B02D800269051 /* vio2sf.framework in CopyFiles */,
|
||||
8384904B180764C200E7332D /* SSEQPlayer.framework in CopyFiles */,
|
||||
834379A617F97EB000584396 /* HighlyAdvanced.framework in CopyFiles */,
|
||||
|
@ -178,7 +186,7 @@
|
|||
8360EEF317F92AC8005208A4 /* HighlyComplete-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "HighlyComplete-Prefix.pch"; sourceTree = "<group>"; };
|
||||
8360EF3E17F92C91005208A4 /* HighlyExperimental.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = HighlyExperimental.xcodeproj; path = ../../Frameworks/HighlyExperimental/HighlyExperimental.xcodeproj; sourceTree = "<group>"; };
|
||||
83848FE61807623F00E7332D /* SSEQPlayer.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SSEQPlayer.xcodeproj; path = ../../Frameworks/SSEQPlayer/SSEQPlayer.xcodeproj; sourceTree = "<group>"; };
|
||||
83D4481B18ACA5AD000F443A /* lazyusf */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = lazyusf; path = ../../ThirdParty/lazyusf/lazyusf; sourceTree = "<group>"; };
|
||||
83C8B65018AF57770071B040 /* lazyusf.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = lazyusf.xcodeproj; path = ../../Frameworks/lazyusf/lazyusf.xcodeproj; sourceTree = "<group>"; };
|
||||
83DE0C34180A9BD400269051 /* vio2sf.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = vio2sf.xcodeproj; path = ../../Frameworks/vio2sf/vio2sf.xcodeproj; sourceTree = "<group>"; };
|
||||
83DE0CBF180B27C200269051 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
|
||||
83FAF8A318ADD27F00057CAF /* PlaylistController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlaylistController.h; path = ../../../Playlist/PlaylistController.h; sourceTree = "<group>"; };
|
||||
|
@ -189,6 +197,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
83C8B6FB18AF58FA0071B040 /* lazyusf.framework in Frameworks */,
|
||||
83DE0CC0180B27C200269051 /* libz.dylib in Frameworks */,
|
||||
83DE0CBC180B02CC00269051 /* vio2sf.framework in Frameworks */,
|
||||
8384904A180764B500E7332D /* SSEQPlayer.framework in Frameworks */,
|
||||
|
@ -239,7 +248,6 @@
|
|||
8360EEDB17F92AC8005208A4 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
83D4481D18ACA5B1000F443A /* External */,
|
||||
8360EEED17F92AC8005208A4 /* HighlyComplete */,
|
||||
8360EEE617F92AC8005208A4 /* Frameworks */,
|
||||
8360EEE517F92AC8005208A4 /* Products */,
|
||||
|
@ -267,6 +275,7 @@
|
|||
8343796317F97BDB00584396 /* HighlyAdvanced.xcodeproj */,
|
||||
83848FE61807623F00E7332D /* SSEQPlayer.xcodeproj */,
|
||||
83DE0C34180A9BD400269051 /* vio2sf.xcodeproj */,
|
||||
83C8B65018AF57770071B040 /* lazyusf.xcodeproj */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
|
@ -321,12 +330,12 @@
|
|||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83D4481D18ACA5B1000F443A /* External */ = {
|
||||
83C8B65118AF57770071B040 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
83D4481B18ACA5AD000F443A /* lazyusf */,
|
||||
83C8B65618AF57770071B040 /* lazyusf.framework */,
|
||||
);
|
||||
name = External;
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83DE0C35180A9BD400269051 /* Products */ = {
|
||||
|
@ -402,6 +411,10 @@
|
|||
ProductGroup = 8343789D17F9658E00584396 /* Products */;
|
||||
ProjectRef = 8343789C17F9658E00584396 /* HighlyTheoretical.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 83C8B65118AF57770071B040 /* Products */;
|
||||
ProjectRef = 83C8B65018AF57770071B040 /* lazyusf.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 8343784B17F93CB500584396 /* Products */;
|
||||
ProjectRef = 8343784A17F93CB500584396 /* psflib.xcodeproj */;
|
||||
|
@ -465,6 +478,13 @@
|
|||
remoteRef = 83848FEB1807624000E7332D /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
83C8B65618AF57770071B040 /* lazyusf.framework */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.framework;
|
||||
path = lazyusf.framework;
|
||||
remoteRef = 83C8B65518AF57770071B040 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
83DE0C3A180A9BD500269051 /* vio2sf.framework */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.framework;
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#import <vio2sf/state.h>
|
||||
|
||||
#import <lazyusf/usf.h>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
@ -896,197 +898,10 @@ static int twosf_info(void * context, const char * name, const char * value)
|
|||
|
||||
struct usf_loader_state
|
||||
{
|
||||
#ifdef USF_LOG
|
||||
FILE * log;
|
||||
#endif
|
||||
NSTask * task;
|
||||
NSPipe * pipe_stdin;
|
||||
NSPipe * pipe_stdout;
|
||||
NSFileHandle * file_stdin;
|
||||
NSFileHandle * file_stdout;
|
||||
bool donewriting;
|
||||
uint32_t enablecompare;
|
||||
uint32_t enablefifofull;
|
||||
uint32_t samplerate;
|
||||
uint32_t pairsleft;
|
||||
|
||||
BOOL error_occurred;
|
||||
|
||||
usf_loader_state()
|
||||
:
|
||||
#ifdef USF_LOG
|
||||
log(NULL),
|
||||
#endif
|
||||
task(nil), pipe_stdin(nil), pipe_stdout(nil),
|
||||
enablecompare(0), enablefifofull(0),
|
||||
samplerate(0), pairsleft(0),
|
||||
error_occurred(NO) { }
|
||||
|
||||
~usf_loader_state()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void fwrite( const void * buf, ssize_t size, ssize_t count )
|
||||
{
|
||||
if ( error_occurred )
|
||||
return;
|
||||
|
||||
@try
|
||||
{
|
||||
[file_stdin writeData:[NSData dataWithBytes:buf length:size * count]];
|
||||
}
|
||||
@catch (NSException *)
|
||||
{
|
||||
error_occurred = YES;
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef USF_LOG
|
||||
if ( log )
|
||||
{
|
||||
::fwrite( buf, size, count, log );
|
||||
fflush( log );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t fread( void * buf, ssize_t size, ssize_t count )
|
||||
{
|
||||
if ( error_occurred )
|
||||
return 0;
|
||||
|
||||
NSData * data = nil;
|
||||
@try
|
||||
{
|
||||
data = [file_stdout readDataOfLength:size * count];
|
||||
}
|
||||
@catch (NSException *)
|
||||
{
|
||||
error_occurred = YES;
|
||||
close();
|
||||
return 0;
|
||||
}
|
||||
if ( data && [data length] )
|
||||
{
|
||||
memcpy( buf, [data bytes], [data length] );
|
||||
return [data length] / size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void open()
|
||||
{
|
||||
close();
|
||||
|
||||
#ifdef USF_LOG
|
||||
log = fopen("/tmp/lazyusf_transaction", "w");
|
||||
#endif
|
||||
Dl_info info;
|
||||
dladdr( (void*) &twosf_info, &info );
|
||||
|
||||
NSString * base_path = [[NSString stringWithUTF8String:info.dli_fname] stringByDeletingLastPathComponent];
|
||||
|
||||
task = [[NSTask alloc] init];
|
||||
[task setLaunchPath:[base_path stringByAppendingPathComponent:@"lazyusf"]];
|
||||
|
||||
pipe_stdin = [[NSPipe alloc] init];
|
||||
pipe_stdout = [[NSPipe alloc] init];
|
||||
|
||||
[task setStandardInput:pipe_stdin];
|
||||
[task setStandardOutput:pipe_stdout];
|
||||
|
||||
file_stdin = [pipe_stdin fileHandleForWriting];
|
||||
file_stdout = [pipe_stdout fileHandleForReading];
|
||||
|
||||
@try
|
||||
{
|
||||
[task launch];
|
||||
}
|
||||
@catch (NSException *)
|
||||
{
|
||||
error_occurred = YES;
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
fwrite( &enablecompare, sizeof(enablecompare), 1 );
|
||||
fwrite( &enablefifofull, sizeof(enablefifofull), 1 );
|
||||
donewriting = false;
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
if (task != nil)
|
||||
{
|
||||
if ( !error_occurred )
|
||||
{
|
||||
uint32_t zero = 0;
|
||||
fwrite( &zero, sizeof(uint32_t), 1 );
|
||||
}
|
||||
[task release];
|
||||
task = nil;
|
||||
[pipe_stdin release];
|
||||
pipe_stdin = nil;
|
||||
[pipe_stdout release];
|
||||
pipe_stdout = nil;
|
||||
}
|
||||
#ifdef USF_LOG
|
||||
if (log) fclose(log);
|
||||
log = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool opened()
|
||||
{
|
||||
return task != nil;
|
||||
}
|
||||
|
||||
void write_reserved( const uint8_t * reserved, uint32_t reserved_size )
|
||||
{
|
||||
fwrite( &reserved_size, sizeof(reserved_size), 1 );
|
||||
if ( reserved_size ) fwrite( reserved, 1, reserved_size );
|
||||
}
|
||||
|
||||
BOOL read_samples( int16_t * out, ssize_t out_pairs )
|
||||
{
|
||||
if ( !donewriting )
|
||||
{
|
||||
write_reserved( NULL, 0 );
|
||||
#ifdef USF_LOG
|
||||
fclose( log ); log = NULL;
|
||||
#endif
|
||||
donewriting = true;
|
||||
}
|
||||
while ( out_pairs )
|
||||
{
|
||||
if ( !pairsleft )
|
||||
{
|
||||
if (fread( &samplerate, sizeof(samplerate), 1 ) < 1) return NO;
|
||||
if (fread( &pairsleft, sizeof(pairsleft), 1 ) < 1) return NO;
|
||||
pairsleft >>= 1;
|
||||
}
|
||||
if ( pairsleft )
|
||||
{
|
||||
if ( pairsleft > out_pairs )
|
||||
{
|
||||
if (fread( out, sizeof(int16_t) * 2, out_pairs ) < out_pairs) return NO;
|
||||
pairsleft -= out_pairs;
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (fread( out, sizeof(int16_t) * 2, pairsleft ) < pairsleft) return NO;
|
||||
out += pairsleft * 2;
|
||||
out_pairs -= pairsleft;
|
||||
pairsleft = 0;
|
||||
|
||||
uint32_t one = 1;
|
||||
fwrite( &one, sizeof(one), 1 );
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
void * emu_state;
|
||||
};
|
||||
|
||||
static int usf_loader(void * context, const uint8_t * exe, size_t exe_size,
|
||||
|
@ -1094,15 +909,8 @@ static int usf_loader(void * context, const uint8_t * exe, size_t exe_size,
|
|||
{
|
||||
struct usf_loader_state * uUsf = ( struct usf_loader_state * ) context;
|
||||
if ( exe && exe_size > 0 ) return -1;
|
||||
|
||||
if ( !uUsf->opened() ) uUsf->open();
|
||||
|
||||
uUsf->write_reserved( reserved, (uint32_t) reserved_size );
|
||||
|
||||
if ( uUsf->error_occurred )
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
return usf_upload_section( uUsf->emu_state, reserved, reserved_size );
|
||||
}
|
||||
|
||||
static int usf_info(void * context, const char * name, const char * value)
|
||||
|
@ -1189,12 +997,20 @@ static int usf_info(void * context, const char * name, const char * value)
|
|||
}
|
||||
else if ( type == 0x21 )
|
||||
{
|
||||
struct usf_loader_state * uUsf = new usf_loader_state;
|
||||
struct usf_loader_state state;
|
||||
memset( &state, 0, sizeof(state) );
|
||||
|
||||
state.emu_state = malloc( get_usf_state_size() );
|
||||
|
||||
emulatorCore = (uint8_t *) uUsf;
|
||||
usf_clear( state.emu_state );
|
||||
|
||||
if ( psf_load( [currentUrl UTF8String], &source_callbacks, 0x21, usf_loader, uUsf, usf_info, uUsf ) <= 0 )
|
||||
emulatorCore = ( uint8_t * ) state.emu_state;
|
||||
|
||||
if ( psf_load( [currentUrl UTF8String], &source_callbacks, 0x21, usf_loader, &state, usf_info, &state ) <= 0 )
|
||||
return NO;
|
||||
|
||||
usf_set_compare( state.emu_state, state.enablecompare );
|
||||
usf_set_fifo_full( state.emu_state, state.enablefifofull );
|
||||
}
|
||||
else if ( type == 0x22 )
|
||||
{
|
||||
|
@ -1474,12 +1290,11 @@ static int usf_info(void * context, const char * name, const char * value)
|
|||
}
|
||||
else if ( type == 0x21 )
|
||||
{
|
||||
struct usf_loader_state * uUsf = ( struct usf_loader_state * ) emulatorCore;
|
||||
int32_t samplerate;
|
||||
|
||||
usf_render( emulatorCore, (int16_t*) buf, frames, &samplerate );
|
||||
|
||||
if ( !uUsf->read_samples( (int16_t *) buf, frames ) )
|
||||
return 0;
|
||||
|
||||
sampleRate = uUsf->samplerate;
|
||||
sampleRate = samplerate;
|
||||
}
|
||||
else if ( type == 0x22 )
|
||||
{
|
||||
|
@ -1595,8 +1410,8 @@ static int usf_info(void * context, const char * name, const char * value)
|
|||
{
|
||||
if ( emulatorCore ) {
|
||||
if ( type == 0x21 ) {
|
||||
struct usf_loader_state * uUsf = ( struct usf_loader_state * ) emulatorCore;
|
||||
delete uUsf;
|
||||
usf_shutdown( emulatorCore );
|
||||
free( emulatorCore );
|
||||
} else if ( type == 0x22 ) {
|
||||
GBASystem * system = ( GBASystem * ) emulatorCore;
|
||||
CPUCleanUp( system );
|
||||
|
@ -1690,13 +1505,12 @@ static int usf_info(void * context, const char * name, const char * value)
|
|||
}
|
||||
else if ( type == 0x21 )
|
||||
{
|
||||
struct usf_loader_state * uUsf = ( struct usf_loader_state * ) emulatorCore;
|
||||
int16_t temp[2048];
|
||||
do
|
||||
{
|
||||
ssize_t howmany = frame - framesRead;
|
||||
if (howmany > 1024) howmany = 1024;
|
||||
if (!uUsf->read_samples( temp, howmany )) return -1;
|
||||
usf_render(emulatorCore, temp, howmany, NULL);
|
||||
framesRead += howmany;
|
||||
} while (framesRead < frame);
|
||||
}
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue