Imported lazyusf in its new library form and removed the external app

CQTexperiment
Chris Moeller 2014-02-15 01:37:59 -08:00
parent 6985aa3ae6
commit f086d8c9bf
85 changed files with 12655 additions and 215 deletions

View File

@ -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 */;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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 */

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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 * );

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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

View File

@ -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 * );

View File

@ -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>

View File

@ -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);
}

View File

@ -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 *);

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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 * );

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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.