Implemented 2SF format support

CQTexperiment
Chris Moeller 2013-10-13 13:02:19 -07:00
parent 9041ba977f
commit 24b53c6e71
44 changed files with 27444 additions and 18 deletions

View File

@ -0,0 +1,459 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
83DE0C14180A9BD400269051 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 83DE0C12180A9BD400269051 /* InfoPlist.strings */; };
83DE0C81180A9CA400269051 /* ARM9.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C46180A9CA400269051 /* ARM9.h */; };
83DE0C82180A9CA400269051 /* arm_instructions.c in Sources */ = {isa = PBXBuildFile; fileRef = 83DE0C47180A9CA400269051 /* arm_instructions.c */; };
83DE0C83180A9CA400269051 /* arm_instructions.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C48180A9CA400269051 /* arm_instructions.h */; };
83DE0C84180A9CA400269051 /* armcpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 83DE0C49180A9CA400269051 /* armcpu.c */; };
83DE0C85180A9CA400269051 /* armcpu.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C4A180A9CA400269051 /* armcpu.h */; };
83DE0C86180A9CA400269051 /* bios.c in Sources */ = {isa = PBXBuildFile; fileRef = 83DE0C4B180A9CA400269051 /* bios.c */; };
83DE0C87180A9CA400269051 /* bios.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C4C180A9CA400269051 /* bios.h */; };
83DE0C88180A9CA400269051 /* bits.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C4D180A9CA400269051 /* bits.h */; };
83DE0C89180A9CA400269051 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C4E180A9CA400269051 /* config.h */; };
83DE0C8A180A9CA400269051 /* COPYING in Resources */ = {isa = PBXBuildFile; fileRef = 83DE0C4F180A9CA400269051 /* COPYING */; };
83DE0C8B180A9CA400269051 /* cp15.c in Sources */ = {isa = PBXBuildFile; fileRef = 83DE0C50180A9CA400269051 /* cp15.c */; };
83DE0C8C180A9CA400269051 /* cp15.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C51180A9CA400269051 /* cp15.h */; };
83DE0C8D180A9CA400269051 /* debug.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C52180A9CA400269051 /* debug.h */; };
83DE0C8E180A9CA400269051 /* dscard.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C53180A9CA400269051 /* dscard.h */; };
83DE0C8F180A9CA400269051 /* FIFO.c in Sources */ = {isa = PBXBuildFile; fileRef = 83DE0C54180A9CA400269051 /* FIFO.c */; };
83DE0C90180A9CA400269051 /* FIFO.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C55180A9CA400269051 /* FIFO.h */; };
83DE0C91180A9CA400269051 /* GPU.c in Sources */ = {isa = PBXBuildFile; fileRef = 83DE0C56180A9CA400269051 /* GPU.c */; };
83DE0C92180A9CA400269051 /* GPU.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C57180A9CA400269051 /* GPU.h */; };
83DE0C93180A9CA400269051 /* instruction_tabdef.inc in Sources */ = {isa = PBXBuildFile; fileRef = 83DE0C58180A9CA400269051 /* instruction_tabdef.inc */; };
83DE0C94180A9CA400269051 /* matrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 83DE0C59180A9CA400269051 /* matrix.c */; };
83DE0C95180A9CA400269051 /* matrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C5A180A9CA400269051 /* matrix.h */; };
83DE0C96180A9CA400269051 /* mc.c in Sources */ = {isa = PBXBuildFile; fileRef = 83DE0C5B180A9CA400269051 /* mc.c */; };
83DE0C97180A9CA400269051 /* mc.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C5C180A9CA400269051 /* mc.h */; };
83DE0C98180A9CA400269051 /* mem.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C5D180A9CA400269051 /* mem.h */; };
83DE0C99180A9CA400269051 /* MMU.c in Sources */ = {isa = PBXBuildFile; fileRef = 83DE0C5E180A9CA400269051 /* MMU.c */; };
83DE0C9A180A9CA400269051 /* MMU.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C5F180A9CA400269051 /* MMU.h */; };
83DE0C9B180A9CA400269051 /* NDSSystem.c in Sources */ = {isa = PBXBuildFile; fileRef = 83DE0C60180A9CA400269051 /* NDSSystem.c */; };
83DE0C9C180A9CA400269051 /* NDSSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C61180A9CA400269051 /* NDSSystem.h */; };
83DE0C9D180A9CA400269051 /* registers.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C62180A9CA400269051 /* registers.h */; };
83DE0CA1180A9CA400269051 /* SPU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83DE0C66180A9CA400269051 /* SPU.cpp */; };
83DE0CA2180A9CA400269051 /* SPU.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C67180A9CA400269051 /* SPU.h */; };
83DE0CA3180A9CA400269051 /* spu_exports.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C68180A9CA400269051 /* spu_exports.h */; settings = {ATTRIBUTES = (Public, ); }; };
83DE0CA4180A9CA400269051 /* thumb_instructions.c in Sources */ = {isa = PBXBuildFile; fileRef = 83DE0C69180A9CA400269051 /* thumb_instructions.c */; };
83DE0CA5180A9CA400269051 /* thumb_instructions.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C6A180A9CA400269051 /* thumb_instructions.h */; };
83DE0CA6180A9CA400269051 /* thumb_tabdef.inc in Sources */ = {isa = PBXBuildFile; fileRef = 83DE0C6B180A9CA400269051 /* thumb_tabdef.inc */; };
83DE0CA7180A9CA400269051 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0C6C180A9CA400269051 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; };
83DE0CB8180A9FD000269051 /* state.c in Sources */ = {isa = PBXBuildFile; fileRef = 83DE0CB7180A9FD000269051 /* state.c */; };
83DE0CBE180B21DD00269051 /* state.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DE0CB9180A9FE300269051 /* state.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
83DE0C06180A9BD400269051 /* vio2sf.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = vio2sf.framework; sourceTree = BUILT_PRODUCTS_DIR; };
83DE0C11180A9BD400269051 /* vio2sf-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "vio2sf-Info.plist"; sourceTree = "<group>"; };
83DE0C13180A9BD400269051 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
83DE0C46180A9CA400269051 /* ARM9.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARM9.h; sourceTree = "<group>"; };
83DE0C47180A9CA400269051 /* arm_instructions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = arm_instructions.c; sourceTree = "<group>"; };
83DE0C48180A9CA400269051 /* arm_instructions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = arm_instructions.h; sourceTree = "<group>"; };
83DE0C49180A9CA400269051 /* armcpu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = armcpu.c; sourceTree = "<group>"; };
83DE0C4A180A9CA400269051 /* armcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = armcpu.h; sourceTree = "<group>"; };
83DE0C4B180A9CA400269051 /* bios.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bios.c; sourceTree = "<group>"; };
83DE0C4C180A9CA400269051 /* bios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bios.h; sourceTree = "<group>"; };
83DE0C4D180A9CA400269051 /* bits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bits.h; sourceTree = "<group>"; };
83DE0C4E180A9CA400269051 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
83DE0C4F180A9CA400269051 /* COPYING */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = COPYING; sourceTree = "<group>"; };
83DE0C50180A9CA400269051 /* cp15.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cp15.c; sourceTree = "<group>"; };
83DE0C51180A9CA400269051 /* cp15.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cp15.h; sourceTree = "<group>"; };
83DE0C52180A9CA400269051 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
83DE0C53180A9CA400269051 /* dscard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dscard.h; sourceTree = "<group>"; };
83DE0C54180A9CA400269051 /* FIFO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = FIFO.c; sourceTree = "<group>"; };
83DE0C55180A9CA400269051 /* FIFO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIFO.h; sourceTree = "<group>"; };
83DE0C56180A9CA400269051 /* GPU.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = GPU.c; sourceTree = "<group>"; };
83DE0C57180A9CA400269051 /* GPU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPU.h; sourceTree = "<group>"; };
83DE0C58180A9CA400269051 /* instruction_tabdef.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = instruction_tabdef.inc; sourceTree = "<group>"; };
83DE0C59180A9CA400269051 /* matrix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = matrix.c; sourceTree = "<group>"; };
83DE0C5A180A9CA400269051 /* matrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = matrix.h; sourceTree = "<group>"; };
83DE0C5B180A9CA400269051 /* mc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mc.c; sourceTree = "<group>"; };
83DE0C5C180A9CA400269051 /* mc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mc.h; sourceTree = "<group>"; };
83DE0C5D180A9CA400269051 /* mem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mem.h; sourceTree = "<group>"; };
83DE0C5E180A9CA400269051 /* MMU.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = MMU.c; sourceTree = "<group>"; };
83DE0C5F180A9CA400269051 /* MMU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMU.h; sourceTree = "<group>"; };
83DE0C60180A9CA400269051 /* NDSSystem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = NDSSystem.c; sourceTree = "<group>"; };
83DE0C61180A9CA400269051 /* NDSSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NDSSystem.h; sourceTree = "<group>"; };
83DE0C62180A9CA400269051 /* registers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = registers.h; sourceTree = "<group>"; };
83DE0C66180A9CA400269051 /* SPU.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SPU.cpp; sourceTree = "<group>"; };
83DE0C67180A9CA400269051 /* SPU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPU.h; sourceTree = "<group>"; };
83DE0C68180A9CA400269051 /* spu_exports.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spu_exports.h; sourceTree = "<group>"; };
83DE0C69180A9CA400269051 /* thumb_instructions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = thumb_instructions.c; sourceTree = "<group>"; };
83DE0C6A180A9CA400269051 /* thumb_instructions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = thumb_instructions.h; sourceTree = "<group>"; };
83DE0C6B180A9CA400269051 /* thumb_tabdef.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = thumb_tabdef.inc; sourceTree = "<group>"; };
83DE0C6C180A9CA400269051 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = "<group>"; };
83DE0CB7180A9FD000269051 /* state.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = state.c; sourceTree = "<group>"; };
83DE0CB9180A9FE300269051 /* state.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = state.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
83DE0C02180A9BD400269051 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
83DE0BFC180A9BD400269051 = {
isa = PBXGroup;
children = (
83DE0C0F180A9BD400269051 /* vio2sf */,
83DE0C08180A9BD400269051 /* Frameworks */,
83DE0C07180A9BD400269051 /* Products */,
);
sourceTree = "<group>";
};
83DE0C07180A9BD400269051 /* Products */ = {
isa = PBXGroup;
children = (
83DE0C06180A9BD400269051 /* vio2sf.framework */,
);
name = Products;
sourceTree = "<group>";
};
83DE0C08180A9BD400269051 /* Frameworks */ = {
isa = PBXGroup;
children = (
83DE0C0B180A9BD400269051 /* Other Frameworks */,
);
name = Frameworks;
sourceTree = "<group>";
};
83DE0C0B180A9BD400269051 /* Other Frameworks */ = {
isa = PBXGroup;
children = (
);
name = "Other Frameworks";
sourceTree = "<group>";
};
83DE0C0F180A9BD400269051 /* vio2sf */ = {
isa = PBXGroup;
children = (
83DE0C44180A9CA400269051 /* vio2sf */,
83DE0C10180A9BD400269051 /* Supporting Files */,
);
path = vio2sf;
sourceTree = "<group>";
};
83DE0C10180A9BD400269051 /* Supporting Files */ = {
isa = PBXGroup;
children = (
83DE0C11180A9BD400269051 /* vio2sf-Info.plist */,
83DE0C12180A9BD400269051 /* InfoPlist.strings */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
83DE0C44180A9CA400269051 /* vio2sf */ = {
isa = PBXGroup;
children = (
83DE0C45180A9CA400269051 /* desmume */,
);
name = vio2sf;
path = src/vio2sf;
sourceTree = "<group>";
};
83DE0C45180A9CA400269051 /* desmume */ = {
isa = PBXGroup;
children = (
83DE0C46180A9CA400269051 /* ARM9.h */,
83DE0C47180A9CA400269051 /* arm_instructions.c */,
83DE0C48180A9CA400269051 /* arm_instructions.h */,
83DE0C49180A9CA400269051 /* armcpu.c */,
83DE0C4A180A9CA400269051 /* armcpu.h */,
83DE0C4B180A9CA400269051 /* bios.c */,
83DE0C4C180A9CA400269051 /* bios.h */,
83DE0C4D180A9CA400269051 /* bits.h */,
83DE0C4E180A9CA400269051 /* config.h */,
83DE0C4F180A9CA400269051 /* COPYING */,
83DE0C50180A9CA400269051 /* cp15.c */,
83DE0C51180A9CA400269051 /* cp15.h */,
83DE0C52180A9CA400269051 /* debug.h */,
83DE0C53180A9CA400269051 /* dscard.h */,
83DE0C54180A9CA400269051 /* FIFO.c */,
83DE0C55180A9CA400269051 /* FIFO.h */,
83DE0C56180A9CA400269051 /* GPU.c */,
83DE0C57180A9CA400269051 /* GPU.h */,
83DE0C58180A9CA400269051 /* instruction_tabdef.inc */,
83DE0C59180A9CA400269051 /* matrix.c */,
83DE0C5A180A9CA400269051 /* matrix.h */,
83DE0C5B180A9CA400269051 /* mc.c */,
83DE0C5C180A9CA400269051 /* mc.h */,
83DE0C5D180A9CA400269051 /* mem.h */,
83DE0C5E180A9CA400269051 /* MMU.c */,
83DE0C5F180A9CA400269051 /* MMU.h */,
83DE0C60180A9CA400269051 /* NDSSystem.c */,
83DE0C61180A9CA400269051 /* NDSSystem.h */,
83DE0C62180A9CA400269051 /* registers.h */,
83DE0C66180A9CA400269051 /* SPU.cpp */,
83DE0C67180A9CA400269051 /* SPU.h */,
83DE0C68180A9CA400269051 /* spu_exports.h */,
83DE0C69180A9CA400269051 /* thumb_instructions.c */,
83DE0C6A180A9CA400269051 /* thumb_instructions.h */,
83DE0C6B180A9CA400269051 /* thumb_tabdef.inc */,
83DE0C6C180A9CA400269051 /* types.h */,
83DE0CB7180A9FD000269051 /* state.c */,
83DE0CB9180A9FE300269051 /* state.h */,
);
path = desmume;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
83DE0C03180A9BD400269051 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
83DE0CBE180B21DD00269051 /* state.h in Headers */,
83DE0CA3180A9CA400269051 /* spu_exports.h in Headers */,
83DE0CA7180A9CA400269051 /* types.h in Headers */,
83DE0C8E180A9CA400269051 /* dscard.h in Headers */,
83DE0C88180A9CA400269051 /* bits.h in Headers */,
83DE0C83180A9CA400269051 /* arm_instructions.h in Headers */,
83DE0C9D180A9CA400269051 /* registers.h in Headers */,
83DE0C97180A9CA400269051 /* mc.h in Headers */,
83DE0C8C180A9CA400269051 /* cp15.h in Headers */,
83DE0C95180A9CA400269051 /* matrix.h in Headers */,
83DE0C9C180A9CA400269051 /* NDSSystem.h in Headers */,
83DE0C89180A9CA400269051 /* config.h in Headers */,
83DE0C8D180A9CA400269051 /* debug.h in Headers */,
83DE0C98180A9CA400269051 /* mem.h in Headers */,
83DE0C90180A9CA400269051 /* FIFO.h in Headers */,
83DE0C92180A9CA400269051 /* GPU.h in Headers */,
83DE0CA2180A9CA400269051 /* SPU.h in Headers */,
83DE0C87180A9CA400269051 /* bios.h in Headers */,
83DE0C85180A9CA400269051 /* armcpu.h in Headers */,
83DE0CA5180A9CA400269051 /* thumb_instructions.h in Headers */,
83DE0C81180A9CA400269051 /* ARM9.h in Headers */,
83DE0C9A180A9CA400269051 /* MMU.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
83DE0C05180A9BD400269051 /* vio2sf */ = {
isa = PBXNativeTarget;
buildConfigurationList = 83DE0C2E180A9BD400269051 /* Build configuration list for PBXNativeTarget "vio2sf" */;
buildPhases = (
83DE0C01180A9BD400269051 /* Sources */,
83DE0C02180A9BD400269051 /* Frameworks */,
83DE0C03180A9BD400269051 /* Headers */,
83DE0C04180A9BD400269051 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = vio2sf;
productName = vio2sf;
productReference = 83DE0C06180A9BD400269051 /* vio2sf.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
83DE0BFD180A9BD400269051 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0500;
ORGANIZATIONNAME = "Christopher Snowhill";
};
buildConfigurationList = 83DE0C00180A9BD400269051 /* Build configuration list for PBXProject "vio2sf" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 83DE0BFC180A9BD400269051;
productRefGroup = 83DE0C07180A9BD400269051 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
83DE0C05180A9BD400269051 /* vio2sf */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
83DE0C04180A9BD400269051 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
83DE0C8A180A9CA400269051 /* COPYING in Resources */,
83DE0C14180A9BD400269051 /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
83DE0C01180A9BD400269051 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
83DE0C99180A9CA400269051 /* MMU.c in Sources */,
83DE0C8B180A9CA400269051 /* cp15.c in Sources */,
83DE0C8F180A9CA400269051 /* FIFO.c in Sources */,
83DE0CA1180A9CA400269051 /* SPU.cpp in Sources */,
83DE0C86180A9CA400269051 /* bios.c in Sources */,
83DE0CA6180A9CA400269051 /* thumb_tabdef.inc in Sources */,
83DE0C96180A9CA400269051 /* mc.c in Sources */,
83DE0C91180A9CA400269051 /* GPU.c in Sources */,
83DE0CA4180A9CA400269051 /* thumb_instructions.c in Sources */,
83DE0C84180A9CA400269051 /* armcpu.c in Sources */,
83DE0C94180A9CA400269051 /* matrix.c in Sources */,
83DE0C93180A9CA400269051 /* instruction_tabdef.inc in Sources */,
83DE0C9B180A9CA400269051 /* NDSSystem.c in Sources */,
83DE0CB8180A9FD000269051 /* state.c in Sources */,
83DE0C82180A9CA400269051 /* arm_instructions.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
83DE0C12180A9BD400269051 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
83DE0C13180A9BD400269051 /* en */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
83DE0C2C180A9BD400269051 /* 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.7;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
83DE0C2D180A9BD400269051 /* 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.7;
SDKROOT = macosx;
};
name = Release;
};
83DE0C2F180A9BD400269051 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
INFOPLIST_FILE = "vio2sf/vio2sf-Info.plist";
INSTALL_PATH = "@loader_path/../Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
WRAPPER_EXTENSION = framework;
};
name = Debug;
};
83DE0C30180A9BD400269051 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
INFOPLIST_FILE = "vio2sf/vio2sf-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 */
83DE0C00180A9BD400269051 /* Build configuration list for PBXProject "vio2sf" */ = {
isa = XCConfigurationList;
buildConfigurations = (
83DE0C2C180A9BD400269051 /* Debug */,
83DE0C2D180A9BD400269051 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
83DE0C2E180A9BD400269051 /* Build configuration list for PBXNativeTarget "vio2sf" */ = {
isa = XCConfigurationList;
buildConfigurations = (
83DE0C2F180A9BD400269051 /* Debug */,
83DE0C30180A9BD400269051 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
/* End XCConfigurationList section */
};
rootObject = 83DE0BFD180A9BD400269051 /* Project object */;
}

View File

@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */

View File

@ -0,0 +1,31 @@
#ifndef ARM9_H
#define ARM9_H
#include "types.h"
typedef struct ARM9_struct {
//ARM9 mem
u8 ARM9_ITCM[0x8000];
u8 ARM9_DTCM[0x4000];
u8 ARM9_WRAM[0x1000000];
u8 MAIN_MEM[0x400000];
u8 ARM9_REG[0x1000000];
u8 ARM9_BIOS[0x8000];
u8 ARM9_VMEM[0x800];
u8 ARM9_ABG[0x80000];
u8 ARM9_BBG[0x20000];
u8 ARM9_AOBJ[0x40000];
u8 ARM9_BOBJ[0x20000];
u8 ARM9_LCD[0xA4000];
u8 ARM9_OAM[0x800];
u8 * ExtPal[2][4];
u8 * ObjExtPal[2][2];
u8 * texPalSlot[4];
const u8 *textureSlotAddr[4];
u8 *blank_memory[0x20000];
} ARM9_struct;
#endif

View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -0,0 +1,65 @@
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
Copyright (C) 2007 shash
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "FIFO.h"
void FIFOInit(FIFO * fifo)
{
u32 i;
fifo->begin = 0;
fifo->end = 0;
for(i = 0; i<0x8000; ++i)
fifo->data[i] = 0;
fifo->full = FALSE;
fifo->empty = TRUE;
fifo->error = FALSE;
}
void FIFOAdd(FIFO * fifo, u32 v)
{
if(fifo->full)
{
fifo->error = TRUE;
return;
}
fifo->data[fifo->end] = v;
fifo->end = (fifo->end + 1)& 0x7FFF;
fifo->full = (fifo->end == fifo->begin);
fifo->empty = FALSE;
}
u32 FIFOValue(FIFO * fifo)
{
u32 v;
if(fifo->empty)
{
fifo->error = TRUE;
return 0;
}
v = fifo->data[fifo->begin];
fifo->begin = (fifo->begin + 1)& 0x7FFF;
fifo->empty = (fifo->begin == fifo->end);
return v;
}

View File

@ -0,0 +1,51 @@
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
Copyright (C) 2007 shash
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef FIFO_H
#define FIFO_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
u32 data[0x8000];
u32 begin;
u32 end;
BOOL full;
BOOL empty;
BOOL error;
} FIFO;
void FIFOInit(FIFO * fifo);
void FIFOAdd(FIFO * fifo, u32 v);
u32 FIFOValue(FIFO * fifo);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,95 @@
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
Copyright (C) 2006-2007 Theo Berkau
Copyright (C) 2007 shash
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// CONTENTS
// INITIALIZATION
// ENABLING / DISABLING LAYERS
// PARAMETERS OF BACKGROUNDS
// PARAMETERS OF ROTOSCALE
// PARAMETERS OF EFFECTS
// PARAMETERS OF WINDOWS
// ROUTINES FOR INSIDE / OUTSIDE WINDOW CHECKS
// PIXEL RENDERING
// BACKGROUND RENDERING -TEXT-
// BACKGROUND RENDERING -ROTOSCALE-
// BACKGROUND RENDERING -HELPER FUNCTIONS-
// SPRITE RENDERING -HELPER FUNCTIONS-
// SPRITE RENDERING
// SCREEN FUNCTIONS
// GRAPHICS CORE
// GPU_ligne
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "MMU.h"
#include "GPU.h"
#include "state.h"
//#define DEBUG_TRI
/*****************************************************************************/
// INITIALIZATION
/*****************************************************************************/
GPU * GPU_Init(u8 l)
{
GPU * g;
if ((g = (GPU *) malloc(sizeof(GPU))) == NULL)
return NULL;
GPU_Reset(g, l);
return g;
}
void GPU_Reset(GPU *g, u8 l)
{
memset(g, 0, sizeof(GPU));
}
void GPU_DeInit(GPU * gpu)
{
if (gpu) free(gpu);
}
int Screen_Init(NDS_state *state, int coreid) {
state->MainScreen->gpu = GPU_Init(0);
state->SubScreen->gpu = GPU_Init(1);
return 0;
}
void Screen_Reset(NDS_state *state) {
GPU_Reset(state->MainScreen->gpu, 0);
GPU_Reset(state->SubScreen->gpu, 1);
}
void Screen_DeInit(NDS_state *state) {
GPU_DeInit(state->MainScreen->gpu);
GPU_DeInit(state->SubScreen->gpu);
}

View File

@ -0,0 +1,808 @@
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
Copyright (C) 2006-2007 Theo Berkau
Copyright (C) 2007 shash
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef GPU_H
#define GPU_H
#include "ARM9.h"
#include <stdio.h>
#include "mem.h"
#include "registers.h"
#include "FIFO.h"
#include "MMU.h"
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
this structure is for display control,
it holds flags for general display
*******************************************************************************/
#ifdef WORDS_BIGENDIAN
struct _DISPCNT
{
/* 7*/ u8 ForceBlank:1; // A+B:
/* 6*/ u8 OBJ_BMP_mapping:1; // A+B: 0=2D (128KB), 1=1D (128..256KB)
/* 5*/ u8 OBJ_BMP_2D_dim:1; // A+B: 0=128x512, 1=256x256 pixels
/* 4*/ u8 OBJ_Tile_1D:1; // A+B: 0=2D (32KB), 1=1D (32..256KB)
/* 3*/ u8 BG0_3D:1; // A : 0=2D, 1=3D
/* 0*/ u8 BG_Mode:3; // A+B:
/*15*/ u8 WinOBJ_Enable:1; // A+B: 0=disable, 1=Enable
/*14*/ u8 Win1_Enable:1; // A+B: 0=disable, 1=Enable
/*13*/ u8 Win0_Enable:1; // A+B: 0=disable, 1=Enable
/*12*/ u8 OBJ_Enable:1; // A+B: 0=disable, 1=Enable
/*11*/ u8 BG3_Enable:1; // A+B: 0=disable, 1=Enable
/*10*/ u8 BG2_Enable:1; // A+B: 0=disable, 1=Enable
/* 9*/ u8 BG1_Enable:1; // A+B: 0=disable, 1=Enable
/* 8*/ u8 BG0_Enable:1; // A+B: 0=disable, 1=Enable
/*23*/ u8 OBJ_HBlank_process:1; // A+B: OBJ processed during HBlank (GBA bit5)
/*22*/ u8 OBJ_BMP_1D_Bound:1; // A :
/*20*/ u8 OBJ_Tile_1D_Bound:2; // A+B:
/*18*/ u8 VRAM_Block:2; // A : VRAM block (0..3=A..D)
/*16*/ u8 DisplayMode:2; // A+B: coreA(0..3) coreB(0..1) GBA(Green Swap)
// 0=off (white screen)
// 1=on (normal BG & OBJ layers)
// 2=VRAM display (coreA only)
// 3=RAM display (coreA only, DMA transfers)
/*31*/ u8 ExOBJPalette_Enable:1; // A+B: 0=disable, 1=Enable OBJ extended Palette
/*30*/ u8 ExBGxPalette_Enable:1; // A+B: 0=disable, 1=Enable BG extended Palette
/*27*/ u8 ScreenBase_Block:3; // A : Screen Base (64K step)
/*24*/ u8 CharacBase_Block:3; // A : Character Base (64K step)
};
#else
struct _DISPCNT
{
/* 0*/ u8 BG_Mode:3; // A+B:
/* 3*/ u8 BG0_3D:1; // A : 0=2D, 1=3D
/* 4*/ u8 OBJ_Tile_1D:1; // A+B: 0=2D (32KB), 1=1D (32..256KB)
/* 5*/ u8 OBJ_BMP_2D_dim:1; // A+B: 0=128x512, 1=256x256 pixels
/* 6*/ u8 OBJ_BMP_mapping:1; // A+B: 0=2D (128KB), 1=1D (128..256KB)
// 7-15 same as GBA
/* 7*/ u8 ForceBlank:1; // A+B:
/* 8*/ u8 BG0_Enable:1; // A+B: 0=disable, 1=Enable
/* 9*/ u8 BG1_Enable:1; // A+B: 0=disable, 1=Enable
/*10*/ u8 BG2_Enable:1; // A+B: 0=disable, 1=Enable
/*11*/ u8 BG3_Enable:1; // A+B: 0=disable, 1=Enable
/*12*/ u8 OBJ_Enable:1; // A+B: 0=disable, 1=Enable
/*13*/ u8 Win0_Enable:1; // A+B: 0=disable, 1=Enable
/*14*/ u8 Win1_Enable:1; // A+B: 0=disable, 1=Enable
/*15*/ u8 WinOBJ_Enable:1; // A+B: 0=disable, 1=Enable
/*16*/ u8 DisplayMode:2; // A+B: coreA(0..3) coreB(0..1) GBA(Green Swap)
// 0=off (white screen)
// 1=on (normal BG & OBJ layers)
// 2=VRAM display (coreA only)
// 3=RAM display (coreA only, DMA transfers)
/*18*/ u8 VRAM_Block:2; // A : VRAM block (0..3=A..D)
/*20*/ u8 OBJ_Tile_1D_Bound:2; // A+B:
/*22*/ u8 OBJ_BMP_1D_Bound:1; // A :
/*23*/ u8 OBJ_HBlank_process:1; // A+B: OBJ processed during HBlank (GBA bit5)
/*24*/ u8 CharacBase_Block:3; // A : Character Base (64K step)
/*27*/ u8 ScreenBase_Block:3; // A : Screen Base (64K step)
/*30*/ u8 ExBGxPalette_Enable:1; // A+B: 0=disable, 1=Enable BG extended Palette
/*31*/ u8 ExOBJPalette_Enable:1; // A+B: 0=disable, 1=Enable OBJ extended Palette
};
#endif
typedef union
{
struct _DISPCNT bits;
u32 val;
} DISPCNT;
#define BGxENABLED(cnt,num) ((num<8)? ((cnt.val>>8) & num):0)
/*******************************************************************************
this structure is for display control of a specific layer,
there are 4 background layers
their priority indicate which one to draw on top of the other
some flags indicate special drawing mode, size, FX
*******************************************************************************/
#ifdef WORDS_BIGENDIAN
struct _BGxCNT
{
/* 7*/ u8 Palette_256:1; // 0=16x16, 1=1*256 palette
/* 6*/ u8 Mosaic_Enable:1; // 0=disable, 1=Enable mosaic
/* 2*/ u8 CharacBase_Block:4; // individual character base offset (n*16KB)
/* 0*/ u8 Priority:2; // 0..3=high..low
/*14*/ u8 ScreenSize:2; // text : 256x256 512x256 256x512 512x512
// x/rot/s : 128x128 256x256 512x512 1024x1024
// bmp : 128x128 256x256 512x256 512x512
// large : 512x1024 1024x512 - -
/*13*/ u8 PaletteSet_Wrap:1; // BG0 extended palette set 0=set0, 1=set2
// BG1 extended palette set 0=set1, 1=set3
// BG2 overflow area wraparound 0=off, 1=wrap
// BG3 overflow area wraparound 0=off, 1=wrap
/* 8*/ u8 ScreenBase_Block:5; // individual screen base offset (text n*2KB, BMP n*16KB)
};
#else
struct _BGxCNT
{
/* 0*/ u8 Priority:2; // 0..3=high..low
/* 2*/ u8 CharacBase_Block:4; // individual character base offset (n*16KB)
/* 6*/ u8 Mosaic_Enable:1; // 0=disable, 1=Enable mosaic
/* 7*/ u8 Palette_256:1; // 0=16x16, 1=1*256 palette
/* 8*/ u8 ScreenBase_Block:5; // individual screen base offset (text n*2KB, BMP n*16KB)
/*13*/ u8 PaletteSet_Wrap:1; // BG0 extended palette set 0=set0, 1=set2
// BG1 extended palette set 0=set1, 1=set3
// BG2 overflow area wraparound 0=off, 1=wrap
// BG3 overflow area wraparound 0=off, 1=wrap
/*14*/ u8 ScreenSize:2; // text : 256x256 512x256 256x512 512x512
// x/rot/s : 128x128 256x256 512x512 1024x1024
// bmp : 128x128 256x256 512x256 512x512
// large : 512x1024 1024x512 - -
};
#endif
typedef union
{
struct _BGxCNT bits;
u16 val;
} BGxCNT;
/*******************************************************************************
this structure is for background offset
*******************************************************************************/
typedef struct {
u16 BGxHOFS;
u16 BGxVOFS;
} BGxOFS;
/*******************************************************************************
this structure is for rotoscale parameters
*******************************************************************************/
typedef struct {
s16 BGxPA;
s16 BGxPB;
s16 BGxPC;
s16 BGxPD;
s32 BGxX;
s32 BGxY;
} BGxPARMS;
/*******************************************************************************
these structures are for window description,
windows are square regions and can "subclass"
background layers or object layers (i.e window controls the layers)
screen
|
+-- Window0/Window1/OBJwindow/OutOfWindows
|
+-- BG0/BG1/BG2/BG3/OBJ
*******************************************************************************/
typedef union {
struct {
u8 end:8;
u8 start:8;
} bits ;
u16 val;
} WINxDIM;
#ifdef WORDS_BIGENDIAN
typedef struct {
/* 6*/ u8 :2;
/* 5*/ u8 WINx_Effect_Enable:1;
/* 4*/ u8 WINx_OBJ_Enable:1;
/* 3*/ u8 WINx_BG3_Enable:1;
/* 2*/ u8 WINx_BG2_Enable:1;
/* 1*/ u8 WINx_BG1_Enable:1;
/* 0*/ u8 WINx_BG0_Enable:1;
} WINxBIT;
#else
typedef struct {
/* 0*/ u8 WINx_BG0_Enable:1;
/* 1*/ u8 WINx_BG1_Enable:1;
/* 2*/ u8 WINx_BG2_Enable:1;
/* 3*/ u8 WINx_BG3_Enable:1;
/* 4*/ u8 WINx_OBJ_Enable:1;
/* 5*/ u8 WINx_Effect_Enable:1;
/* 6*/ u8 :2;
} WINxBIT;
#endif
#ifdef WORDS_BIGENDIAN
typedef union {
struct {
WINxBIT win0;
WINxBIT win1;
} bits;
struct {
u8 :3;
u8 win0_en:5;
u8 :3;
u8 win1_en:5;
} packed_bits;
struct {
u8 low;
u8 high;
} bytes;
u16 val ;
} WINxCNT ;
#else
typedef union {
struct {
WINxBIT win0;
WINxBIT win1;
} bits;
struct {
u8 win0_en:5;
u8 :3;
u8 win1_en:5;
u8 :3;
} packed_bits;
struct {
u8 low;
u8 high;
} bytes;
u16 val ;
} WINxCNT ;
#endif
/*
typedef struct {
WINxDIM WIN0H;
WINxDIM WIN1H;
WINxDIM WIN0V;
WINxDIM WIN1V;
WINxCNT WININ;
WINxCNT WINOUT;
} WINCNT;
*/
/*******************************************************************************
this structure is for miscellanous settings
//TODO: needs further description
*******************************************************************************/
typedef struct {
u16 MOSAIC;
u16 unused1;
u16 unused2;//BLDCNT;
u16 unused3;//BLDALPHA;
u16 unused4;//BLDY;
u16 unused5;
/*
u16 unused6;
u16 unused7;
u16 unused8;
u16 unused9;
*/
} MISCCNT;
/*******************************************************************************
this structure is for 3D settings
*******************************************************************************/
struct _DISP3DCNT
{
/* 0*/ u8 EnableTexMapping:1; //
/* 1*/ u8 PolygonShading:1; // 0=Toon Shading, 1=Highlight Shading
/* 2*/ u8 EnableAlphaTest:1; // see ALPHA_TEST_REF
/* 3*/ u8 EnableAlphaBlending:1; // see various Alpha values
/* 4*/ u8 EnableAntiAliasing:1; //
/* 5*/ u8 EnableEdgeMarking:1; // see EDGE_COLOR
/* 6*/ u8 FogOnlyAlpha:1; // 0=Alpha and Color, 1=Only Alpha (see FOG_COLOR)
/* 7*/ u8 EnableFog:1; // Fog Master Enable
/* 8*/ u8 FogShiftSHR:4; // 0..10 SHR-Divider (see FOG_OFFSET)
/*12*/ u8 AckColorBufferUnderflow:1; // Color Buffer RDLINES Underflow (0=None, 1=Underflow/Acknowledge)
/*13*/ u8 AckVertexRAMOverflow:1; // Polygon/Vertex RAM Overflow (0=None, 1=Overflow/Acknowledge)
/*14*/ u8 RearPlaneMode:1; // 0=Blank, 1=Bitmap
/*15*/ u8 :1;
/*16*/ u16 :16;
};
typedef union
{
struct _DISP3DCNT bits;
u32 val;
} DISP3DCNT;
/*******************************************************************************
this structure is for capture control (core A only)
source:
http://nocash.emubase.de/gbatek.htm#dsvideocaptureandmainmemorydisplaymode
*******************************************************************************/
struct _DISPCAPCNT
{
/* 0*/ u8 BlendFactor_A:5; // 0..16 = Blending Factor for Source A
/* 5*/ u8 :3; //
/* 8*/ u8 BlendFactor_B:5; // 0..16 = Blending Factor for Source B
/*13*/ u8 :3; //
/*16*/ u8 VRAM_Write_Block:2; // 0..3 = VRAM A..D
/*18*/ u8 VRAM_Write_Offset:2; // n x 0x08000
/*20*/ u8 Capture_Size:2; // 0=128x128, 1=256x64, 2=256x128, 3=256x192 dots
/*22*/ u8 :2; //
/*24*/ u8 Source_A:1; // 0=Graphics Screen BG+3D+OBJ, 1=3D Screen
/*25*/ u8 Source_B:1; // 0=VRAM, 1=Main Memory Display FIFO
/*26*/ u8 VRAM_Read_Offset:2; // n x 0x08000
/*28*/ u8 :1; //
/*29*/ u8 Capture_Source:2; // 0=Source A, 1=Source B, 2/3=Sources A+B blended
/*31*/ u8 Capture_Enable:1; // 0=Disable/Ready, 1=Enable/Busy
};
typedef union
{
struct _DISPCAPCNT bits;
u32 val;
} DISPCAPCNT;
/*******************************************************************************
this structure holds everything and should be mapped to
* core A : 0x04000000
* core B : 0x04001000
*******************************************************************************/
typedef struct _reg_dispx {
DISPCNT dispx_DISPCNT; // 0x0400x000
u16 dispA_DISPSTAT; // 0x04000004
u16 dispx_VCOUNT; // 0x0400x006
BGxCNT dispx_BGxCNT[4]; // 0x0400x008
BGxOFS dispx_BGxOFS[4]; // 0x0400x010
BGxPARMS dispx_BG2PARMS; // 0x0400x020
BGxPARMS dispx_BG3PARMS; // 0x0400x030
u8 filler[12]; // 0x0400x040
MISCCNT dispx_MISC; // 0x0400x04C
DISP3DCNT dispA_DISP3DCNT; // 0x04000060
DISPCAPCNT dispA_DISPCAPCNT; // 0x04000064
u32 dispA_DISPMMEMFIFO; // 0x04000068
} REG_DISPx ;
#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
#endif
#ifndef max
#define max(a,b) (((a)>(b))?(a):(b))
#endif
typedef BOOL (*fun_gl_Begin) (int screen);
typedef void (*fun_gl_End) (int screen);
// the GUI should use this function prior to all gl calls
// if call to beg succeeds opengl draw
void register_gl_fun(fun_gl_Begin beg,fun_gl_End end);
#define GPU_MAIN 0
#define GPU_SUB 1
/* human readable bitmask names */
#define ADDRESS_STEP_512B 0x00200
#define ADDRESS_STEP_1KB 0x00400
#define ADDRESS_STEP_2KB 0x00800
#define ADDRESS_STEP_4KB 0x01000
#define ADDRESS_STEP_8KB 0x02000
#define ADDRESS_STEP_16KB 0x04000
#define ADDRESS_STEP_32KB 0x08000
#define ADDRESS_STEP_64kB 0x10000
#ifdef WORDS_BIGENDIAN
struct _TILEENTRY
{
/*14*/ unsigned Palette:4;
/*13*/ unsigned VFlip:1; // VERTICAL FLIP (top<-->bottom)
/*12*/ unsigned HFlip:1; // HORIZONTAL FLIP (left<-->right)
/* 0*/ unsigned TileNum:10;
};
#else
struct _TILEENTRY
{
/* 0*/ unsigned TileNum:10;
/*12*/ unsigned HFlip:1; // HORIZONTAL FLIP (left<-->right)
/*13*/ unsigned VFlip:1; // VERTICAL FLIP (top<-->bottom)
/*14*/ unsigned Palette:4;
};
#endif
typedef union
{
struct _TILEENTRY bits;
u16 val;
} TILEENTRY;
struct _ROTOCOORD
{
/* 0*/ unsigned Fraction:8;
/* 8*/ signed Integer:24;
// /*28*/ unsigned :4;
};
typedef union
{
struct _ROTOCOORD bits;
s32 val;
} ROTOCOORD;
/*
this structure is for color representation,
it holds 5 meaningful bits per color channel (red,green,blue)
and 1 meaningful bit for alpha representation
this bit can be unused or used for special FX
*/
struct _COLOR { // abgr x555
#ifdef WORDS_BIGENDIAN
unsigned alpha:1; // sometimes it is unused (pad)
unsigned blue:5;
unsigned green:5;
unsigned red:5;
#else
unsigned red:5;
unsigned green:5;
unsigned blue:5;
unsigned alpha:1; // sometimes it is unused (pad)
#endif
};
struct _COLORx { // abgr x555
unsigned bgr:15;
unsigned alpha:1; // sometimes it is unused (pad)
};
typedef union
{
struct _COLOR bits;
struct _COLORx bitx;
u16 val;
} COLOR;
struct _COLOR32 { // ARGB
unsigned :3;
unsigned blue:5;
unsigned :3;
unsigned green:5;
unsigned :3;
unsigned red:5;
unsigned :7;
unsigned alpha:1; // sometimes it is unused (pad)
};
typedef union
{
struct _COLOR32 bits;
u32 val;
} COLOR32;
#define COLOR_16_32(w,i) \
/* doesnt matter who's 16bit who's 32bit */ \
i.bits.red = w.bits.red; \
i.bits.green = w.bits.green; \
i.bits.blue = w.bits.blue; \
i.bits.alpha = w.bits.alpha;
/*
this structure is for Sprite description,
it holds flags & transformations for 1 sprite
(max 128 OBJs / screen)
ref: http://www.bottledlight.com/ds/index.php/Video/Sprites
*/
typedef struct
{
#ifdef WORDS_BIGENDIAN
// attr0
/* 0*/ unsigned Y:8;
/*14*/ unsigned Shape:2; // (00: Square, 01: Wide, 10: Tall, 11: Illegal)
/*13*/ unsigned Depth:1; // (0: 16, 1: 256)
/*12*/ unsigned Mosaic:1; // (1: Enabled)
/*10*/ unsigned Mode:2; // (00: Normal, 01: Transparent, 10: Object window, 11: Bitmap)
/* 8*/ unsigned RotScale:2; // (00: Normal, 01: Rot/scale, 10: Disabled, 11: Double-size rot/scale)
// attr1
/* 0*/ signed X:9;
/*14*/ unsigned Size:2;
/*13*/ unsigned VFlip:1;
/*12*/ unsigned HFlip:1;
/* 9*/ unsigned RotScalIndex:3; // Rot/scale matrix index
// attr2
/* 0*/ unsigned TileIndex:10;
/*12*/ unsigned PaletteIndex:4;
/*10*/ unsigned Priority:2;
// attr3
unsigned attr3:16;
#else
// attr0
/* 0*/ unsigned Y:8;
/* 8*/ unsigned RotScale:2; // (00: Normal, 01: Rot/scale, 10: Disabled, 11: Double-size rot/scale)
/*10*/ unsigned Mode:2; // (00: Normal, 01: Transparent, 10: Object window, 11: Bitmap)
/*12*/ unsigned Mosaic:1; // (1: Enabled)
/*13*/ unsigned Depth:1; // (0: 16, 1: 256)
/*14*/ unsigned Shape:2; // (00: Square, 01: Wide, 10: Tall, 11: Illegal)
// attr1
/* 0*/ signed X:9;
/* 9*/ unsigned RotScalIndex:3; // Rot/scale matrix index
/*12*/ unsigned HFlip:1;
/*13*/ unsigned VFlip:1;
/*14*/ unsigned Size:2;
// attr2
/* 0*/ unsigned TileIndex:10;
/*10*/ unsigned Priority:2;
/*12*/ unsigned PaletteIndex:4;
// attr3
unsigned attr3:16;
#endif
} _OAM_;
typedef struct
{
u16 attr0;
u16 attr1;
u16 attr2;
u16 attr3;
} OAM;
typedef struct
{
s16 x;
s16 y;
} size;
/*
this structure holds information
for rendering.
*/
#define NB_PRIORITIES 4
#define NB_BG 4
typedef struct
{
u8 BGs[NB_BG], nbBGs;
u8 PixelsX[256];
// doh ! yoda says : 256 pixels we can have...
u16 nbPixelsX;
} itemsForPriority_t;
typedef struct _GPU GPU;
struct _GPU
{
// some structs are becoming redundant
// some functions too (no need to recopy some vars as it is done by MMU)
REG_DISPx * dispx_st;
DISPCAPCNT dispCapCnt;
BOOL LayersEnable[5];
itemsForPriority_t itemsForPriority[NB_PRIORITIES];
u8 sprWin[256][256];
#define BGBmpBB BG_bmp_ram
#define BGChBB BG_tile_ram
u8 *(BG_bmp_ram[4]);
u8 *(BG_tile_ram[4]);
u8 *(BG_map_ram[4]);
u8 BGExtPalSlot[4];
u32 BGSize[4][2];
u8 lcd;
u8 core;
u8 dispMode;
u8 vramBlock;
BOOL dispBG[4];
BOOL dispOBJ;
OAM * oam;
u8 * sprMem;
u8 sprBoundary;
u8 sprBMPBoundary;
u8 sprBMPMode;
u32 sprEnable;
u8 WIN0H0;
u8 WIN0H1;
u8 WIN0V0;
u8 WIN0V1;
u8 WIN1H0;
u8 WIN1H1;
u8 WIN1V0;
u8 WIN1V1;
u8 WININ0;
u8 WININ0_SPECIAL;
u8 WININ1;
u8 WININ1_SPECIAL;
u8 WINOUT;
u8 WINOUT_SPECIAL;
u8 WINOBJ;
u8 WINOBJ_SPECIAL;
u8 WIN0_ENABLED;
u8 WIN1_ENABLED;
u8 WINOBJ_ENABLED;
u16 BLDCNT;
u8 BLDALPHA_EVA;
u8 BLDALPHA_EVB;
u8 BLDY_EVY;
u8 MasterBrightMode;
u32 MasterBrightFactor;
BOOL (*setFinalColorSpr)(const GPU *gpu, u32 passing, u8 bgnum, u8 *dst, u16 color, u16 x, u16 y);
BOOL (*setFinalColorBck)(const GPU *gpu, u32 passing, u8 bgnum, u8 *dst, u16 color, u16 x, u16 y);
void (*spriteRender) (GPU * gpu, u16 l, u8 * dst, u8 * prioTab);
};
/*
// normally should have same addresses
static void REG_DISPx_pack_test(GPU * gpu)
{
REG_DISPx * r = gpu->dispx_st;
printf ("%08x %02x\n", r, (long)(&r->dispx_DISPCNT) - (long)r);
printf ("\t%02x\n", (long)(&r->dispA_DISPSTAT) - (long)r);
printf ("\t%02x\n", (long)(&r->dispx_VCOUNT) - (long)r);
printf ("\t%02x\n", (long)(&r->dispx_BGxCNT[0]) - (long)r);
printf ("\t%02x\n", (long)(&r->dispx_BGxOFS[0]) - (long)r);
printf ("\t%02x\n", (long)(&r->dispx_BG2PARMS) - (long)r);
printf ("\t%02x\n", (long)(&r->dispx_BG3PARMS) - (long)r);
printf ("\t%02x\n", (long)(&r->dispx_WINCNT) - (long)r);
printf ("\t%02x\n", (long)(&r->dispx_MISC) - (long)r);
printf ("\t%02x\n", (long)(&r->dispA_DISP3DCNT) - (long)r);
printf ("\t%02x\n", (long)(&r->dispA_DISPCAPCNT) - (long)r);
printf ("\t%02x\n", (long)(&r->dispA_DISPMMEMFIFO) - (long)r);
}
*/
extern u8 GPU_screen[4*256*192];
GPU * GPU_Init(u8 l);
void GPU_Reset(GPU *g, u8 l);
void GPU_DeInit(GPU *);
void textBG(const GPU * gpu, u8 num, u8 * DST); //Draw text based background
void rotBG(GPU * gpu, u8 num, u8 * DST);
void extRotBG(GPU * gpu, u8 num, u8 * DST);
void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab);
void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab);
extern short sizeTab[4][4][2];
extern size sprSizeTab[4][4];
extern s8 mode2type[8][4];
extern void (*modeRender[8][4])(GPU * gpu, u8 num, u16 l, u8 * DST);
typedef struct NDS_Screen {
GPU * gpu;
u16 offset;
} NDS_Screen;
int Screen_Init(NDS_state *state, int coreid);
void Screen_Reset(NDS_state *state);
void Screen_DeInit(NDS_state *state);
#define GFXCORE_DEFAULT -1
#define GFXCORE_DUMMY 0
#define GFXCORE_FULLSCREEN (1 << 0)
typedef struct
{
int id; // ID number for core(see above defines)
const char *Name; // Name of core
int flags; // What features the core supports(full screen, etc.)
int (*Init)(); // Initializes stuff related to core
void (*DeInit)(); // Deinitializes stuff related to core
void (*Resize)(int width, int height, BOOL fullscreen); // Resizes window or fullscreen
void (*OnScreenText)(char *string, ...); // For handling save state messages, etc.
} GraphicsInterface_struct;
extern GraphicsInterface_struct GFXDummy;
void GPU_setVideoProp(GPU *, u32 p);
void GPU_setBGProp(GPU *, u16 num, u16 p);
void GPU_setBLDCNT(GPU *gpu, u16 v) ;
void GPU_setBLDALPHA(GPU *gpu, u16 v) ;
void GPU_setBLDY(GPU *gpu, u16 v) ;
void GPU_setMOSAIC(GPU *gpu, u16 v) ;
void GPU_remove(GPU *, u8 num);
void GPU_addBack(GPU *, u8 num);
int GPU_ChangeGraphicsCore(int coreid);
void GPU_set_DISPCAPCNT(GPU * gpu, u32 val) ;
void GPU_ligne(NDS_Screen * screen, u16 l) ;
void GPU_setMasterBrightness (GPU *gpu, u16 val);
void GPU_setWIN0_H (GPU *gpu, u16 val);
void GPU_setWIN0_H0 (GPU *gpu, u8 val);
void GPU_setWIN0_H1 (GPU *gpu, u8 val);
void GPU_setWIN0_V (GPU *gpu, u16 val);
void GPU_setWIN0_V0 (GPU *gpu, u8 val);
void GPU_setWIN0_V1 (GPU *gpu, u8 val);
void GPU_setWIN1_H (GPU *gpu, u16 val);
void GPU_setWIN1_H0 (GPU *gpu, u8 val);
void GPU_setWIN1_H1 (GPU *gpu, u8 val);
void GPU_setWIN1_V (GPU *gpu, u16 val);
void GPU_setWIN1_V0 (GPU *gpu, u8 val);
void GPU_setWIN1_V1 (GPU *gpu, u8 val);
void GPU_setWININ (GPU *gpu, u16 val);
void GPU_setWININ0 (GPU *gpu, u8 val);
void GPU_setWININ1 (GPU *gpu, u8 val);
void GPU_setWINOUT16(GPU *gpu, u16 val);
void GPU_setWINOUT (GPU *gpu, u8 val);
void GPU_setWINOBJ (GPU *gpu, u8 val);
void GPU_setBLDCNT_LOW (GPU *gpu, u8 val);
void GPU_setBLDCNT_HIGH (GPU *gpu, u8 val);
void GPU_setBLDCNT (GPU *gpu, u16 val);
void GPU_setBLDALPHA (GPU *gpu, u16 val);
void GPU_setBLDALPHA_EVA(GPU *gpu, u8 val);
void GPU_setBLDALPHA_EVB(GPU *gpu, u8 val);
void GPU_setBLDY_EVY (GPU *gpu, u8 val);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,194 @@
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
Copyright (C) 2007 shash
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MMU_H
#define MMU_H
#include "FIFO.h"
#include "dscard.h"
#include "ARM9.h"
#include "mc.h"
#include "state.h"
#ifdef __cplusplus
extern "C" {
#endif
/* theses macros are designed for reading/writing in memory (m is a pointer to memory, like cpu->state->MMUMMU_MEM[proc], and a is an adress, like 0x04000000 */
#define MEM_8(m, a) (((u8*)(m[((a)>>20)&0xff]))[((a)&0xfff)])
/* theses ones for reading in rom data */
#define ROM_8(m, a) (((u8*)(m))[(a)])
#define IPCFIFO 0
#define MAIN_MEMORY_DISP_FIFO 2
typedef struct MMU_struct {
//ARM7 mem
u8 ARM7_BIOS[0x4000];
u8 ARM7_ERAM[0x10000];
u8 ARM7_REG[0x10000];
u8 ARM7_WIRAM[0x10000];
u8 vram_mode[9];
u8 vScreen;
//Shared ram
u8 SWIRAM[0x8000];
//Card rom & ram
u8 * CART_ROM;
u8 CART_RAM[0x10000];
//Unused ram
u8 UNUSED_RAM[4];
u8 * * MMU_MEM[2];
u32 * MMU_MASK[2];
u8 ARM9_RW_MODE;
FIFO fifos[16];
const u32 * MMU_WAIT16[2];
const u32 * MMU_WAIT32[2];
u32 DTCMRegion;
u32 ITCMRegion;
u16 timer[2][4];
s32 timerMODE[2][4];
u32 timerON[2][4];
u32 timerRUN[2][4];
u16 timerReload[2][4];
u32 reg_IME[2];
u32 reg_IE[2];
u32 reg_IF[2];
u32 DMAStartTime[2][4];
s32 DMACycle[2][4];
u32 DMACrt[2][4];
BOOL DMAing[2][4];
memory_chip_t fw;
memory_chip_t bupmem;
nds_dscard dscard[2];
u32 CheckTimers;
u32 CheckDMAs;
} MMU_struct;
struct armcpu_memory_iface {
/** the 32 bit instruction prefetch */
u32 FASTCALL (*prefetch32)( void *data, u32 adr);
/** the 16 bit instruction prefetch */
u16 FASTCALL (*prefetch16)( void *data, u32 adr);
/** read 8 bit data value */
u8 FASTCALL (*read8)( void *data, u32 adr);
/** read 16 bit data value */
u16 FASTCALL (*read16)( void *data, u32 adr);
/** read 32 bit data value */
u32 FASTCALL (*read32)( void *data, u32 adr);
/** write 8 bit data value */
void FASTCALL (*write8)( void *data, u32 adr, u8 val);
/** write 16 bit data value */
void FASTCALL (*write16)( void *data, u32 adr, u16 val);
/** write 32 bit data value */
void FASTCALL (*write32)( void *data, u32 adr, u32 val);
void *data;
};
static void mmu_select_savetype(NDS_state *state, int type, int *bmemtype, u32 *bmemsize) {
if (type<0 || type > 5) return;
*bmemtype=save_types[type][0];
*bmemsize=save_types[type][1];
mc_realloc(&state->MMU->bupmem, *bmemtype, *bmemsize);
}
void MMU_Init(NDS_state *);
void MMU_DeInit(NDS_state *);
void MMU_clearMem(NDS_state *);
void MMU_setRom(NDS_state *, u8 * rom, u32 mask);
void MMU_unsetRom(NDS_state *);
/**
* Memory reading
*/
u8 FASTCALL MMU_read8(NDS_state *, u32 proc, u32 adr);
u16 FASTCALL MMU_read16(NDS_state *, u32 proc, u32 adr);
u32 FASTCALL MMU_read32(NDS_state *, u32 proc, u32 adr);
#ifdef MMU_ENABLE_ACL
u8 FASTCALL MMU_read8_acl(NDS_state *, u32 proc, u32 adr, u32 access);
u16 FASTCALL MMU_read16_acl(NDS_state *, u32 proc, u32 adr, u32 access);
u32 FASTCALL MMU_read32_acl(NDS_state *, u32 proc, u32 adr, u32 access);
#else
#define MMU_read8_acl(state,proc,adr,access) MMU_read8(state,proc,adr)
#define MMU_read16_acl(state,proc,adr,access) MMU_read16(state,proc,adr)
#define MMU_read32_acl(state,proc,adr,access) MMU_read32(state,proc,adr)
#endif
/**
* Memory writing
*/
void FASTCALL MMU_write8(NDS_state *, u32 proc, u32 adr, u8 val);
void FASTCALL MMU_write16(NDS_state *, u32 proc, u32 adr, u16 val);
void FASTCALL MMU_write32(NDS_state *, u32 proc, u32 adr, u32 val);
#ifdef MMU_ENABLE_ACL
void FASTCALL MMU_write8_acl(NDS_state *, u32 proc, u32 adr, u8 val);
void FASTCALL MMU_write16_acl(NDS_state *, u32 proc, u32 adr, u16 val);
void FASTCALL MMU_write32_acl(NDS_state *, u32 proc, u32 adr, u32 val);
#else
#define MMU_write8_acl MMU_write8
#define MMU_write16_acl MMU_write16
#define MMU_write32_acl MMU_write32
#endif
void FASTCALL MMU_doDMA(NDS_state *, u32 proc, u32 num);
/*
* The base ARM memory interfaces
*/
extern struct armcpu_memory_iface arm9_base_memory_iface;
extern struct armcpu_memory_iface arm7_base_memory_iface;
extern struct armcpu_memory_iface arm9_direct_memory_iface;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,750 @@
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
#include <stdlib.h>
#include "state.h"
#include "NDSSystem.h"
#include "MMU.h"
//#include "cflash.h"
#include "spu_exports.h"
//#include "ROMReader.h"
/* the count of bytes copied from the firmware into memory */
#define NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT 0x70
static u32
calc_CRC16( u32 start, const u8 *data, int count) {
int i,j;
u32 crc = start & 0xffff;
static u16 val[] = { 0xC0C1,0xC181,0xC301,0xC601,0xCC01,0xD801,0xF001,0xA001 };
for(i = 0; i < count; i++)
{
crc = crc ^ data[i];
for(j = 0; j < 8; j++) {
int do_bit = 0;
if ( crc & 0x1)
do_bit = 1;
crc = crc >> 1;
if ( do_bit) {
crc = crc ^ (val[j] << (7-j));
}
}
}
return crc;
}
static int
copy_firmware_user_data( u8 *dest_buffer, const u8 *fw_data) {
/*
* Determine which of the two user settings in the firmware is the current
* and valid one and then copy this into the destination buffer.
*
* The current setting will have a greater count.
* Settings are only valid if its CRC16 is correct.
*/
int user1_valid = 0;
int user2_valid = 0;
u32 user_settings_offset;
u32 fw_crc;
u32 crc;
int copy_good = 0;
user_settings_offset = fw_data[0x20];
user_settings_offset |= fw_data[0x21] << 8;
user_settings_offset <<= 3;
if ( user_settings_offset <= 0x3FE00) {
s32 copy_settings_offset = -1;
crc = calc_CRC16( 0xffff, &fw_data[user_settings_offset],
NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT);
fw_crc = fw_data[user_settings_offset + 0x72];
fw_crc |= fw_data[user_settings_offset + 0x73] << 8;
if ( crc == fw_crc) {
user1_valid = 1;
}
crc = calc_CRC16( 0xffff, &fw_data[user_settings_offset + 0x100],
NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT);
fw_crc = fw_data[user_settings_offset + 0x100 + 0x72];
fw_crc |= fw_data[user_settings_offset + 0x100 + 0x73] << 8;
if ( crc == fw_crc) {
user2_valid = 1;
}
if ( user1_valid) {
if ( user2_valid) {
u16 count1, count2;
count1 = fw_data[user_settings_offset + 0x70];
count1 |= fw_data[user_settings_offset + 0x71] << 8;
count2 = fw_data[user_settings_offset + 0x100 + 0x70];
count2 |= fw_data[user_settings_offset + 0x100 + 0x71] << 8;
if ( count2 > count1) {
copy_settings_offset = user_settings_offset + 0x100;
}
else {
copy_settings_offset = user_settings_offset;
}
}
else {
copy_settings_offset = user_settings_offset;
}
}
else if ( user2_valid) {
/* copy the second user settings */
copy_settings_offset = user_settings_offset + 0x100;
}
if ( copy_settings_offset > 0) {
memcpy( dest_buffer, &fw_data[copy_settings_offset],
NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT);
copy_good = 1;
}
}
return copy_good;
}
#ifdef GDB_STUB
int NDS_Init( NDS_state *state,
struct armcpu_memory_iface *arm9_mem_if,
struct armcpu_ctrl_iface **arm9_ctrl_iface,
struct armcpu_memory_iface *arm7_mem_if,
struct armcpu_ctrl_iface **arm7_ctrl_iface) {
#else
int NDS_Init( NDS_state *state) {
#endif
state->nds->ARM9Cycle = 0;
state->nds->ARM7Cycle = 0;
state->nds->cycles = 0;
MMU_Init(state);
state->nds->nextHBlank = 3168;
state->nds->VCount = 0;
state->nds->lignerendu = FALSE;
if (Screen_Init(state, GFXCORE_DUMMY) != 0)
return -1;
#ifdef GDB_STUB
armcpu_new(state,state->NDS_ARM7,1, arm7_mem_if, arm7_ctrl_iface);
armcpu_new(state,state->NDS_ARM9,0, arm9_mem_if, arm9_ctrl_iface);
#else
armcpu_new(state,state->NDS_ARM7,1);
armcpu_new(state,state->NDS_ARM9,0);
#endif
if (SPU_Init(state, 0, 0) != 0)
return -1;
#ifdef EXPERIMENTAL_WIFI
WIFI_Init(&state->wifiMac) ;
#endif
return 0;
}
static void armcpu_deinit(armcpu_t *armcpu)
{
if(armcpu->coproc[15])
{
free(armcpu->coproc[15]);
armcpu->coproc[15] = 0;
}
}
void NDS_DeInit(NDS_state *state) {
if(state->MMU->CART_ROM != state->MMU->UNUSED_RAM)
NDS_FreeROM(state);
armcpu_deinit(state->NDS_ARM7);
armcpu_deinit(state->NDS_ARM9);
state->nds->nextHBlank = 3168;
SPU_DeInit(state);
Screen_DeInit(state);
MMU_DeInit(state);
}
BOOL NDS_SetROM(NDS_state *state, u8 * rom, u32 mask)
{
MMU_setRom(state, rom, mask);
return TRUE;
}
NDS_header * NDS_getROMHeader(NDS_state *state)
{
NDS_header * header = malloc(sizeof(NDS_header));
memcpy(header->gameTile, state->MMU->CART_ROM, 12);
memcpy(header->gameCode, state->MMU->CART_ROM + 12, 4);
header->makerCode = T1ReadWord(state->MMU->CART_ROM, 16);
header->unitCode = state->MMU->CART_ROM[18];
header->deviceCode = state->MMU->CART_ROM[19];
header->cardSize = state->MMU->CART_ROM[20];
memcpy(header->cardInfo, state->MMU->CART_ROM + 21, 8);
header->flags = state->MMU->CART_ROM[29];
header->ARM9src = T1ReadLong(state->MMU->CART_ROM, 32);
header->ARM9exe = T1ReadLong(state->MMU->CART_ROM, 36);
header->ARM9cpy = T1ReadLong(state->MMU->CART_ROM, 40);
header->ARM9binSize = T1ReadLong(state->MMU->CART_ROM, 44);
header->ARM7src = T1ReadLong(state->MMU->CART_ROM, 48);
header->ARM7exe = T1ReadLong(state->MMU->CART_ROM, 52);
header->ARM7cpy = T1ReadLong(state->MMU->CART_ROM, 56);
header->ARM7binSize = T1ReadLong(state->MMU->CART_ROM, 60);
header->FNameTblOff = T1ReadLong(state->MMU->CART_ROM, 64);
header->FNameTblSize = T1ReadLong(state->MMU->CART_ROM, 68);
header->FATOff = T1ReadLong(state->MMU->CART_ROM, 72);
header->FATSize = T1ReadLong(state->MMU->CART_ROM, 76);
header->ARM9OverlayOff = T1ReadLong(state->MMU->CART_ROM, 80);
header->ARM9OverlaySize = T1ReadLong(state->MMU->CART_ROM, 84);
header->ARM7OverlayOff = T1ReadLong(state->MMU->CART_ROM, 88);
header->ARM7OverlaySize = T1ReadLong(state->MMU->CART_ROM, 92);
header->unknown2a = T1ReadLong(state->MMU->CART_ROM, 96);
header->unknown2b = T1ReadLong(state->MMU->CART_ROM, 100);
header->IconOff = T1ReadLong(state->MMU->CART_ROM, 104);
header->CRC16 = T1ReadWord(state->MMU->CART_ROM, 108);
header->ROMtimeout = T1ReadWord(state->MMU->CART_ROM, 110);
header->ARM9unk = T1ReadLong(state->MMU->CART_ROM, 112);
header->ARM7unk = T1ReadLong(state->MMU->CART_ROM, 116);
memcpy(header->unknown3c, state->MMU->CART_ROM + 120, 8);
header->ROMSize = T1ReadLong(state->MMU->CART_ROM, 128);
header->HeaderSize = T1ReadLong(state->MMU->CART_ROM, 132);
memcpy(header->unknown5, state->MMU->CART_ROM + 136, 56);
memcpy(header->logo, state->MMU->CART_ROM + 192, 156);
header->logoCRC16 = T1ReadWord(state->MMU->CART_ROM, 348);
header->headerCRC16 = T1ReadWord(state->MMU->CART_ROM, 350);
memcpy(header->reserved, state->MMU->CART_ROM + 352, 160);
return header;
//return (NDS_header *)MMU->CART_ROM;
}
void NDS_FreeROM(NDS_state *state)
{
if (state->MMU->CART_ROM != state->MMU->UNUSED_RAM)
free(state->MMU->CART_ROM);
MMU_unsetRom(state);
// if (MMU->bupmem.fp)
// fclose(MMU->bupmem.fp);
// cpu->state->MMUbupmem.fp = NULL;
}
void NDS_Reset( NDS_state *state)
{
BOOL oldexecute=state->execute;
int i;
u32 src;
u32 dst;
NDS_header * header = NDS_getROMHeader(state);
if (!header) return ;
state->execute = FALSE;
MMU_clearMem(state);
src = header->ARM9src;
dst = header->ARM9cpy;
for(i = 0; i < (header->ARM9binSize>>2); ++i)
{
MMU_write32(state, 0, dst, T1ReadLong(state->MMU->CART_ROM, src));
dst += 4;
src += 4;
}
src = header->ARM7src;
dst = header->ARM7cpy;
for(i = 0; i < (header->ARM7binSize>>2); ++i)
{
MMU_write32(state, 1, dst, T1ReadLong(state->MMU->CART_ROM, src));
dst += 4;
src += 4;
}
armcpu_init(state->NDS_ARM7, header->ARM7exe);
armcpu_init(state->NDS_ARM9, header->ARM9exe);
state->nds->ARM9Cycle = 0;
state->nds->ARM7Cycle = 0;
state->nds->cycles = 0;
memset(state->nds->timerCycle, 0, sizeof(s32) * 2 * 4);
memset(state->nds->timerOver, 0, sizeof(BOOL) * 2 * 4);
state->nds->nextHBlank = 3168;
state->nds->VCount = 0;
state->nds->old = 0;
state->nds->diff = 0;
state->nds->lignerendu = FALSE;
state->nds->touchX = state->nds->touchY = 0;
MMU_write16(state, 0, 0x04000130, 0x3FF);
MMU_write16(state, 1, 0x04000130, 0x3FF);
MMU_write8(state, 1, 0x04000136, 0x43);
/*
* Setup a copy of the firmware user settings in memory.
* (this is what the DS firmware would do).
*/
{
u8 temp_buffer[NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT];
int fw_index;
if ( copy_firmware_user_data( temp_buffer, state->MMU->fw.data)) {
for ( fw_index = 0; fw_index < NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT; fw_index++) {
MMU_write8( state, 0, 0x027FFC80 + fw_index, temp_buffer[fw_index]);
}
}
}
// Copy the whole header to Main RAM 0x27FFE00 on startup.
// Reference: http://nocash.emubase.de/gbatek.htm#dscartridgeheader
for (i = 0; i < ((0x170+0x90)/4); i++)
{
MMU_write32 (state, 0, 0x027FFE00+i*4, LE_TO_LOCAL_32(((u32*)state->MMU->CART_ROM)[i]));
}
state->MainScreen->offset = 0;
state->SubScreen->offset = 192;
//MMU_write32(state, 0, 0x02007FFC, 0xE92D4030);
//ARM7 BIOS IRQ HANDLER
MMU_write32(state, 1, 0x00, 0xE25EF002);
MMU_write32(state, 1, 0x04, 0xEAFFFFFE);
MMU_write32(state, 1, 0x18, 0xEA000000);
MMU_write32(state, 1, 0x20, 0xE92D500F);
MMU_write32(state, 1, 0x24, 0xE3A00301);
MMU_write32(state, 1, 0x28, 0xE28FE000);
MMU_write32(state, 1, 0x2C, 0xE510F004);
MMU_write32(state, 1, 0x30, 0xE8BD500F);
MMU_write32(state, 1, 0x34, 0xE25EF004);
//ARM9 BIOS IRQ HANDLER
MMU_write32(state, 0, 0xFFFF0018, 0xEA000000);
MMU_write32(state, 0, 0xFFFF0020, 0xE92D500F);
MMU_write32(state, 0, 0xFFFF0024, 0xEE190F11);
MMU_write32(state, 0, 0xFFFF0028, 0xE1A00620);
MMU_write32(state, 0, 0xFFFF002C, 0xE1A00600);
MMU_write32(state, 0, 0xFFFF0030, 0xE2800C40);
MMU_write32(state, 0, 0xFFFF0034, 0xE28FE000);
MMU_write32(state, 0, 0xFFFF0038, 0xE510F004);
MMU_write32(state, 0, 0xFFFF003C, 0xE8BD500F);
MMU_write32(state, 0, 0xFFFF0040, 0xE25EF004);
MMU_write32(state, 0, 0x0000004, 0xE3A0010E);
MMU_write32(state, 0, 0x0000008, 0xE3A01020);
// MMU_write32(state, 0, 0x000000C, 0xE1B02110);
MMU_write32(state, 0, 0x000000C, 0xE1B02040);
MMU_write32(state, 0, 0x0000010, 0xE3B02020);
// MMU_write32(state, 0, 0x0000010, 0xE2100202);
free(header);
GPU_Reset(state->MainScreen->gpu, 0);
GPU_Reset(state->SubScreen->gpu, 1);
SPU_Reset(state);
state->execute = oldexecute;
}
static void dma_check(NDS_state *state)
{
if((state->MMU->DMAing[0][0])&&(state->MMU->DMACycle[0][0]<=state->nds->cycles))
{
T1WriteLong(state->ARM9Mem->ARM9_REG, 0xB8 + (0xC*0), T1ReadLong(state->ARM9Mem->ARM9_REG, 0xB8 + (0xC*0)) & 0x7FFFFFFF);
if((state->MMU->DMACrt[0][0])&(1<<30)) NDS_makeARM9Int(state, 8);
state->MMU->DMAing[0][0] = FALSE;
}
if((state->MMU->DMAing[0][1])&&(state->MMU->DMACycle[0][1]<=state->nds->cycles))
{
T1WriteLong(state->ARM9Mem->ARM9_REG, 0xB8 + (0xC*1), T1ReadLong(state->ARM9Mem->ARM9_REG, 0xB8 + (0xC*1)) & 0x7FFFFFFF);
if((state->MMU->DMACrt[0][1])&(1<<30)) NDS_makeARM9Int(state, 9);
state->MMU->DMAing[0][1] = FALSE;
}
if((state->MMU->DMAing[0][2])&&(state->MMU->DMACycle[0][2]<=state->nds->cycles))
{
T1WriteLong(state->ARM9Mem->ARM9_REG, 0xB8 + (0xC*2), T1ReadLong(state->ARM9Mem->ARM9_REG, 0xB8 + (0xC*2)) & 0x7FFFFFFF);
if((state->MMU->DMACrt[0][2])&(1<<30)) NDS_makeARM9Int(state, 10);
state->MMU->DMAing[0][2] = FALSE;
}
if((state->MMU->DMAing[0][3])&&(state->MMU->DMACycle[0][3]<=state->nds->cycles))
{
T1WriteLong(state->ARM9Mem->ARM9_REG, 0xB8 + (0xC*3), T1ReadLong(state->ARM9Mem->ARM9_REG, 0xB8 + (0xC*3)) & 0x7FFFFFFF);
if((state->MMU->DMACrt[0][3])&(1<<30)) NDS_makeARM9Int(state, 11);
state->MMU->DMAing[0][3] = FALSE;
}
if((state->MMU->DMAing[1][0])&&(state->MMU->DMACycle[1][0]<=state->nds->cycles))
{
T1WriteLong(state->MMU->ARM7_REG, 0xB8 + (0xC*0), T1ReadLong(state->MMU->ARM7_REG, 0xB8 + (0xC*0)) & 0x7FFFFFFF);
if((state->MMU->DMACrt[1][0])&(1<<30)) NDS_makeARM7Int(state, 8);
state->MMU->DMAing[1][0] = FALSE;
}
if((state->MMU->DMAing[1][1])&&(state->MMU->DMACycle[1][1]<=state->nds->cycles))
{
T1WriteLong(state->MMU->ARM7_REG, 0xB8 + (0xC*1), T1ReadLong(state->MMU->ARM7_REG, 0xB8 + (0xC*1)) & 0x7FFFFFFF);
if((state->MMU->DMACrt[1][1])&(1<<30)) NDS_makeARM7Int(state, 9);
state->MMU->DMAing[1][1] = FALSE;
}
if((state->MMU->DMAing[1][2])&&(state->MMU->DMACycle[1][2]<=state->nds->cycles))
{
T1WriteLong(state->MMU->ARM7_REG, 0xB8 + (0xC*2), T1ReadLong(state->MMU->ARM7_REG, 0xB8 + (0xC*2)) & 0x7FFFFFFF);
if((state->MMU->DMACrt[1][2])&(1<<30)) NDS_makeARM7Int(state, 10);
state->MMU->DMAing[1][2] = FALSE;
}
if((state->MMU->DMAing[1][3])&&(state->MMU->DMACycle[1][3]<=state->nds->cycles))
{
T1WriteLong(state->MMU->ARM7_REG, 0xB8 + (0xC*3), T1ReadLong(state->MMU->ARM7_REG, 0xB8 + (0xC*3)) & 0x7FFFFFFF);
if((state->MMU->DMACrt[1][3])&(1<<30)) NDS_makeARM7Int(state, 11);
state->MMU->DMAing[1][3] = FALSE;
}
if((state->MMU->reg_IF[0]&state->MMU->reg_IE[0]) && (state->MMU->reg_IME[0]))
{
#ifdef GDB_STUB
if ( armcpu_flagIrq( state->NDS_ARM9))
#else
if ( armcpu_irqExeption(state->NDS_ARM9))
#endif
{
state->nds->ARM9Cycle = state->nds->cycles;
}
}
if((state->MMU->reg_IF[1]&state->MMU->reg_IE[1]) && (state->MMU->reg_IME[1]))
{
#ifdef GDB_STUB
if ( armcpu_flagIrq( state->NDS_ARM7))
#else
if ( armcpu_irqExeption(state->NDS_ARM7))
#endif
{
state->nds->ARM7Cycle = state->nds->cycles;
}
}
}
static void timer_check(NDS_state *state)
{
int p, t;
for (p = 0; p < 2; p++)
{
for (t = 0; t < 4; t++)
{
state->nds->timerOver[p][t] = 0;
if(state->MMU->timerON[p][t])
{
if(state->MMU->timerRUN[p][t])
{
switch(state->MMU->timerMODE[p][t])
{
case 0xFFFF :
if(t > 0 && state->nds->timerOver[p][t - 1])
{
++(state->MMU->timer[p][t]);
state->nds->timerOver[p][t] = !state->MMU->timer[p][t];
if (state->nds->timerOver[p][t])
{
if (p == 0)
{
if(T1ReadWord(state->ARM9Mem->ARM9_REG, 0x102 + (t << 2)) & 0x40)
NDS_makeARM9Int(state, 3 + t);
}
else
{
if(T1ReadWord(state->MMU->ARM7_REG, 0x102 + (t << 2)) & 0x40)
NDS_makeARM7Int(state, 3 + t);
}
state->MMU->timer[p][t] = state->MMU->timerReload[p][t];
}
}
break;
default :
{
state->nds->diff = (state->nds->cycles >> state->MMU->timerMODE[p][t]) - (state->nds->timerCycle[p][t] >> state->MMU->timerMODE[p][t]);
state->nds->old = state->MMU->timer[p][t];
state->MMU->timer[p][t] += state->nds->diff;
state->nds->timerCycle[p][t] += state->nds->diff << state->MMU->timerMODE[p][t];
state->nds->timerOver[p][t] = state->nds->old >= state->MMU->timer[p][t];
if(state->nds->timerOver[p][t])
{
if (p == 0)
{
if(T1ReadWord(state->ARM9Mem->ARM9_REG, 0x102 + (t << 2)) & 0x40)
NDS_makeARM9Int(state, 3 + t);
}
else
{
if(T1ReadWord(state->MMU->ARM7_REG, 0x102 + (t << 2)) & 0x40)
NDS_makeARM7Int(state, 3 + t);
}
state->MMU->timer[p][t] = state->MMU->timerReload[p][t] + state->MMU->timer[p][t] - state->nds->old;
}
}
break;
}
}
else
{
state->MMU->timerRUN[p][t] = TRUE;
state->nds->timerCycle[p][t] = state->nds->cycles;
}
}
}
}
}
void NDS_exec_hframe(NDS_state *state, int cpu_clockdown_level_arm9, int cpu_clockdown_level_arm7)
{
int h;
for (h = 0; h < 2; h++)
{
s32 nb = state->nds->cycles + (h ? (99 * 12) : (256 * 12));
while (nb > state->nds->ARM9Cycle && !state->NDS_ARM9->waitIRQ)
state->nds->ARM9Cycle += armcpu_exec(state->NDS_ARM9) << (cpu_clockdown_level_arm9);
if (state->NDS_ARM9->waitIRQ) state->nds->ARM9Cycle = nb;
while (nb > state->nds->ARM7Cycle && !state->NDS_ARM7->waitIRQ)
state->nds->ARM7Cycle += armcpu_exec(state->NDS_ARM7) << (1 + (cpu_clockdown_level_arm7));
if (state->NDS_ARM7->waitIRQ) state->nds->ARM7Cycle = nb;
state->nds->cycles = (state->nds->ARM9Cycle<state->nds->ARM7Cycle)?state->nds->ARM9Cycle : state->nds->ARM7Cycle;
/* HBLANK */
if (h)
{
T1WriteWord(state->ARM9Mem->ARM9_REG, 4, T1ReadWord(state->ARM9Mem->ARM9_REG, 4) | 2);
T1WriteWord(state->MMU->ARM7_REG, 4, T1ReadWord(state->MMU->ARM7_REG, 4) | 2);
NDS_ARM9HBlankInt(state);
NDS_ARM7HBlankInt(state);
if(state->nds->VCount<192)
{
if(state->MMU->DMAStartTime[0][0] == 2)
MMU_doDMA(state, 0, 0);
if(state->MMU->DMAStartTime[0][1] == 2)
MMU_doDMA(state, 0, 1);
if(state->MMU->DMAStartTime[0][2] == 2)
MMU_doDMA(state, 0, 2);
if(state->MMU->DMAStartTime[0][3] == 2)
MMU_doDMA(state, 0, 3);
}
}
else
{
/* HDISP */
u32 vmatch;
state->nds->nextHBlank += 4260;
++state->nds->VCount;
T1WriteWord(state->ARM9Mem->ARM9_REG, 4, T1ReadWord(state->ARM9Mem->ARM9_REG, 4) & 0xFFFD);
T1WriteWord(state->MMU->ARM7_REG, 4, T1ReadWord(state->MMU->ARM7_REG, 4) & 0xFFFD);
if(state->MMU->DMAStartTime[0][0] == 3)
MMU_doDMA(state, 0, 0);
if(state->MMU->DMAStartTime[0][1] == 3)
MMU_doDMA(state, 0, 1);
if(state->MMU->DMAStartTime[0][2] == 3)
MMU_doDMA(state, 0, 2);
if(state->MMU->DMAStartTime[0][3] == 3)
MMU_doDMA(state, 0, 3);
// Main memory display
if(state->MMU->DMAStartTime[0][0] == 4)
{
MMU_doDMA(state, 0, 0);
state->MMU->DMAStartTime[0][0] = 0;
}
if(state->MMU->DMAStartTime[0][1] == 4)
{
MMU_doDMA(state, 0, 1);
state->MMU->DMAStartTime[0][1] = 0;
}
if(state->MMU->DMAStartTime[0][2] == 4)
{
MMU_doDMA(state, 0, 2);
state->MMU->DMAStartTime[0][2] = 0;
}
if(state->MMU->DMAStartTime[0][3] == 4)
{
MMU_doDMA(state, 0, 3);
state->MMU->DMAStartTime[0][3] = 0;
}
if(state->MMU->DMAStartTime[1][0] == 4)
{
MMU_doDMA(state, 1, 0);
state->MMU->DMAStartTime[1][0] = 0;
}
if(state->MMU->DMAStartTime[1][1] == 4)
{
MMU_doDMA(state, 1, 1);
state->MMU->DMAStartTime[0][1] = 0;
}
if(state->MMU->DMAStartTime[1][2] == 4)
{
MMU_doDMA(state, 1, 2);
state->MMU->DMAStartTime[1][2] = 0;
}
if(state->MMU->DMAStartTime[1][3] == 4)
{
MMU_doDMA(state, 1, 3);
state->MMU->DMAStartTime[1][3] = 0;
}
if(state->nds->VCount == 192)
{
/* VBLANK */
T1WriteWord(state->ARM9Mem->ARM9_REG, 4, T1ReadWord(state->ARM9Mem->ARM9_REG, 4) | 1);
T1WriteWord(state->MMU->ARM7_REG, 4, T1ReadWord(state->MMU->ARM7_REG, 4) | 1);
NDS_ARM9VBlankInt(state);
NDS_ARM7VBlankInt(state);
if(state->MMU->DMAStartTime[0][0] == 1)
MMU_doDMA(state, 0, 0);
if(state->MMU->DMAStartTime[0][1] == 1)
MMU_doDMA(state, 0, 1);
if(state->MMU->DMAStartTime[0][2] == 1)
MMU_doDMA(state, 0, 2);
if(state->MMU->DMAStartTime[0][3] == 1)
MMU_doDMA(state, 0, 3);
if(state->MMU->DMAStartTime[1][0] == 1)
MMU_doDMA(state, 1, 0);
if(state->MMU->DMAStartTime[1][1] == 1)
MMU_doDMA(state, 1, 1);
if(state->MMU->DMAStartTime[1][2] == 1)
MMU_doDMA(state, 1, 2);
if(state->MMU->DMAStartTime[1][3] == 1)
MMU_doDMA(state, 1, 3);
}
else if(state->nds->VCount == 263)
{
const int cycles_per_frame = (263 * (99 * 12 + 256 * 12));
/* VDISP */
state->nds->nextHBlank = 3168;
state->nds->VCount = 0;
T1WriteWord(state->ARM9Mem->ARM9_REG, 4, T1ReadWord(state->ARM9Mem->ARM9_REG, 4) & 0xFFFE);
T1WriteWord(state->MMU->ARM7_REG, 4, T1ReadWord(state->MMU->ARM7_REG, 4) & 0xFFFE);
state->nds->cycles -= cycles_per_frame;
state->nds->ARM9Cycle -= cycles_per_frame;
state->nds->ARM7Cycle -= cycles_per_frame;
nb -= cycles_per_frame;
if(state->MMU->timerON[0][0])
state->nds->timerCycle[0][0] -= cycles_per_frame;
if(state->MMU->timerON[0][1])
state->nds->timerCycle[0][1] -= cycles_per_frame;
if(state->MMU->timerON[0][2])
state->nds->timerCycle[0][2] -= cycles_per_frame;
if(state->MMU->timerON[0][3])
state->nds->timerCycle[0][3] -= cycles_per_frame;
if(state->MMU->timerON[1][0])
state->nds->timerCycle[1][0] -= cycles_per_frame;
if(state->MMU->timerON[1][1])
state->nds->timerCycle[1][1] -= cycles_per_frame;
if(state->MMU->timerON[1][2])
state->nds->timerCycle[1][2] -= cycles_per_frame;
if(state->MMU->timerON[1][3])
state->nds->timerCycle[1][3] -= cycles_per_frame;
if(state->MMU->DMAing[0][0])
state->MMU->DMACycle[0][0] -= cycles_per_frame;
if(state->MMU->DMAing[0][1])
state->MMU->DMACycle[0][1] -= cycles_per_frame;
if(state->MMU->DMAing[0][2])
state->MMU->DMACycle[0][2] -= cycles_per_frame;
if(state->MMU->DMAing[0][3])
state->MMU->DMACycle[0][3] -= cycles_per_frame;
if(state->MMU->DMAing[1][0])
state->MMU->DMACycle[1][0] -= cycles_per_frame;
if(state->MMU->DMAing[1][1])
state->MMU->DMACycle[1][1] -= cycles_per_frame;
if(state->MMU->DMAing[1][2])
state->MMU->DMACycle[1][2] -= cycles_per_frame;
if(state->MMU->DMAing[1][3])
state->MMU->DMACycle[1][3] -= cycles_per_frame;
}
T1WriteWord(state->ARM9Mem->ARM9_REG, 6, state->nds->VCount);
T1WriteWord(state->MMU->ARM7_REG, 6, state->nds->VCount);
vmatch = T1ReadWord(state->ARM9Mem->ARM9_REG, 4);
if((state->nds->VCount==(vmatch>>8)|((vmatch<<1)&(1<<8))))
{
T1WriteWord(state->ARM9Mem->ARM9_REG, 4, T1ReadWord(state->ARM9Mem->ARM9_REG, 4) | 4);
if(T1ReadWord(state->ARM9Mem->ARM9_REG, 4) & 32)
NDS_makeARM9Int(state, 2);
}
else
T1WriteWord(state->ARM9Mem->ARM9_REG, 4, T1ReadWord(state->ARM9Mem->ARM9_REG, 4) & 0xFFFB);
vmatch = T1ReadWord(state->MMU->ARM7_REG, 4);
if((state->nds->VCount==(vmatch>>8)|((vmatch<<1)&(1<<8))))
{
T1WriteWord(state->MMU->ARM7_REG, 4, T1ReadWord(state->MMU->ARM7_REG, 4) | 4);
if(T1ReadWord(state->MMU->ARM7_REG, 4) & 32)
NDS_makeARM7Int(state, 2);
}
else
T1WriteWord(state->MMU->ARM7_REG, 4, T1ReadWord(state->MMU->ARM7_REG, 4) & 0xFFFB);
timer_check(state);
dma_check(state);
}
}
}
void NDS_exec_frame(NDS_state *state, int cpu_clockdown_level_arm9, int cpu_clockdown_level_arm7)
{
int v;
for (v = 0; v < 263; v++)
{
NDS_exec_hframe(state, cpu_clockdown_level_arm9, cpu_clockdown_level_arm7);
}
}

View File

@ -0,0 +1,250 @@
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef NDSSYSTEM_H
#define NDSSYSTEM_H
#include "armcpu.h"
#include "MMU.h"
#include "GPU.h"
#include "mem.h"
//#include "wifi.h"
#include "ARM9.h"
#include "state.h"
#ifdef __cplusplus
extern "C" {
#endif
extern volatile BOOL execute;
extern BOOL click;
/*
* The firmware language values
*/
#define NDS_FW_LANG_JAP 0
#define NDS_FW_LANG_ENG 1
#define NDS_FW_LANG_FRE 2
#define NDS_FW_LANG_GER 3
#define NDS_FW_LANG_ITA 4
#define NDS_FW_LANG_SPA 5
#define NDS_FW_LANG_CHI 6
#define NDS_FW_LANG_RES 7
//#define LOG_ARM9
//#define LOG_ARM7
typedef struct
{
char gameTile[12];
char gameCode[4];
u16 makerCode;
u8 unitCode;
u8 deviceCode;
u8 cardSize;
u8 cardInfo[8];
u8 flags;
u32 ARM9src;
u32 ARM9exe;
u32 ARM9cpy;
u32 ARM9binSize;
u32 ARM7src;
u32 ARM7exe;
u32 ARM7cpy;
u32 ARM7binSize;
u32 FNameTblOff;
u32 FNameTblSize;
u32 FATOff;
u32 FATSize;
u32 ARM9OverlayOff;
u32 ARM9OverlaySize;
u32 ARM7OverlayOff;
u32 ARM7OverlaySize;
u32 unknown2a;
u32 unknown2b;
u32 IconOff;
u16 CRC16;
u16 ROMtimeout;
u32 ARM9unk;
u32 ARM7unk;
u8 unknown3c[8];
u32 ROMSize;
u32 HeaderSize;
u8 unknown5[56];
u8 logo[156];
u16 logoCRC16;
u16 headerCRC16;
u8 reserved[160];
} NDS_header;
typedef struct NDSSystem
{
s32 ARM9Cycle;
s32 ARM7Cycle;
s32 cycles;
s32 timerCycle[2][4];
BOOL timerOver[2][4];
s32 nextHBlank;
u32 VCount;
u32 old;
s32 diff;
BOOL lignerendu;
u16 touchX;
u16 touchY;
} NDSSystem;
/** /brief A touchscreen calibration point.
*/
struct NDS_fw_touchscreen_cal {
u16 adc_x;
u16 adc_y;
u8 screen_x;
u8 screen_y;
};
/** /brief The type of DS
*/
enum nds_fw_ds_type {
NDS_FW_DS_TYPE_FAT,
NDS_FW_DS_TYPE_LITE
};
#define MAX_FW_NICKNAME_LENGTH 10
#define MAX_FW_MESSAGE_LENGTH 26
struct NDS_fw_config_data {
enum nds_fw_ds_type ds_type;
u8 fav_colour;
u8 birth_month;
u8 birth_day;
u16 nickname[MAX_FW_NICKNAME_LENGTH];
u8 nickname_len;
u16 message[MAX_FW_MESSAGE_LENGTH];
u8 message_len;
u8 language;
/* touchscreen calibration */
struct NDS_fw_touchscreen_cal touch_cal[2];
};
#ifdef GDB_STUB
int NDS_Init( NDS_state *,
struct armcpu_memory_iface *arm9_mem_if,
struct armcpu_ctrl_iface **arm9_ctrl_iface,
struct armcpu_memory_iface *arm7_mem_if,
struct armcpu_ctrl_iface **arm7_ctrl_iface);
#else
int NDS_Init ( NDS_state * );
#endif
void NDS_DeInit(NDS_state *);
void
NDS_FillDefaultFirmwareConfigData( NDS_state *, struct NDS_fw_config_data *fw_config);
BOOL NDS_SetROM(NDS_state *, u8 * rom, u32 mask);
NDS_header * NDS_getROMHeader(NDS_state *);
void NDS_setTouchPos(NDS_state *, u16 x, u16 y);
void NDS_releasTouch(NDS_state *);
void NDS_FreeROM(NDS_state *);
void NDS_Reset(NDS_state *);
int NDS_CreateDummyFirmware( NDS_state *, struct NDS_fw_config_data *user_settings);
u32
NDS_exec(NDS_state *, s32 nb, BOOL force);
static INLINE void NDS_ARM9HBlankInt(NDS_state *state)
{
if(T1ReadWord(state->ARM9Mem->ARM9_REG, 4) & 0x10)
{
state->MMU->reg_IF[0] |= 2;// & (MMU->reg_IME[0] << 1);// (MMU->reg_IE[0] & (1<<1));
state->NDS_ARM9->wIRQ = TRUE;
}
}
static INLINE void NDS_ARM7HBlankInt(NDS_state *state)
{
if(T1ReadWord(state->MMU->ARM7_REG, 4) & 0x10)
{
state->MMU->reg_IF[1] |= 2;// & (MMU->reg_IME[1] << 1);// (MMU->reg_IE[1] & (1<<1));
state->NDS_ARM7->wIRQ = TRUE;
}
}
static INLINE void NDS_ARM9VBlankInt(NDS_state *state)
{
if(T1ReadWord(state->ARM9Mem->ARM9_REG, 4) & 0x8)
{
state->MMU->reg_IF[0] |= 1;// & (MMU->reg_IME[0]);// (MMU->reg_IE[0] & 1);
state->NDS_ARM9->wIRQ = TRUE;
//execute = FALSE;
/*logcount++;*/
}
}
static INLINE void NDS_ARM7VBlankInt(NDS_state *state)
{
if(T1ReadWord(state->MMU->ARM7_REG, 4) & 0x8)
state->MMU->reg_IF[1] |= 1;// & (MMU->reg_IME[1]);// (MMU->reg_IE[1] & 1);
state->NDS_ARM7->wIRQ = TRUE;
//execute = FALSE;
}
static INLINE void NDS_swapScreen(NDS_state *state)
{
u16 tmp = state->MainScreen->offset;
state->MainScreen->offset = state->SubScreen->offset;
state->SubScreen->offset = tmp;
}
void NDS_exec_frame(NDS_state *, int cpu_clockdown_level_arm9, int cpu_clockdown_level_arm7);
void NDS_exec_hframe(NDS_state *, int cpu_clockdown_level_arm9, int cpu_clockdown_level_arm7);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,186 @@
/* SPU.h
Copyright 2006 Theo Berkau
Copyright (C) 2006-2009 DeSmuME team
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef SPU_H
#define SPU_H
#include <string>
#include "types.h"
#include <math.h>
#include <assert.h>
#define FORCEINLINE __forceinline
FORCEINLINE u32 u32floor(float f)
{
#ifdef ENABLE_SSE2
return (u32)_mm_cvtt_ss2si(_mm_set_ss(f));
#else
return (u32)f;
#endif
}
FORCEINLINE u32 u32floor(double d)
{
#ifdef ENABLE_SSE2
return (u32)_mm_cvttsd_si32(_mm_set_sd(d));
#else
return (u32)d;
#endif
}
//same as above but works for negative values too.
//be sure that the results are the same thing as floorf!
FORCEINLINE s32 s32floor(float f)
{
#ifdef ENABLE_SSE2
return _mm_cvtss_si32( _mm_add_ss(_mm_set_ss(-0.5f),_mm_add_ss(_mm_set_ss(f), _mm_set_ss(f))) ) >> 1;
#else
return (s32)floorf(f);
#endif
}
static FORCEINLINE u32 sputrunc(float f) { return u32floor(f); }
static FORCEINLINE u32 sputrunc(double d) { return u32floor(d); }
static FORCEINLINE s32 spumuldiv7(s32 val, u8 multiplier) {
assert(multiplier <= 127);
return (multiplier == 127) ? val : ((val * multiplier) >> 7);
}
#define SNDCORE_DEFAULT -1
#define SNDCORE_DUMMY 0
#define CHANSTAT_STOPPED 0
#define CHANSTAT_PLAY 1
typedef struct NDS_state;
enum SPUInterpolationMode
{
SPUInterpolation_None = 0,
SPUInterpolation_Linear = 1,
SPUInterpolation_Cosine = 2
};
typedef struct NDS_state NDS_state;
typedef struct SoundInterface_struct
{
int id;
const char *Name;
int (*Init)(NDS_state *, int buffersize);
void (*DeInit)(NDS_state *);
void (*UpdateAudio)(NDS_state *, s16 *buffer, u32 num_samples);
u32 (*GetAudioSpace)(NDS_state *);
void (*MuteAudio)(NDS_state *);
void (*UnMuteAudio)(NDS_state *);
void (*SetVolume)(NDS_state *, int volume);
} SoundInterface_struct;
extern SoundInterface_struct SNDDummy;
extern SoundInterface_struct SNDFile;
struct channel_struct
{
channel_struct()
{}
u32 num;
u8 vol;
u8 datashift;
u8 hold;
u8 pan;
u8 waveduty;
u8 repeat;
u8 format;
u8 status;
u32 addr;
u16 timer;
u16 loopstart;
u32 length;
u32 totlength;
double double_totlength_shifted;
union {
s8 *buf8;
s16 *buf16;
};
double sampcnt;
double sampinc;
// ADPCM specific
u32 lastsampcnt;
s16 pcm16b, pcm16b_last;
s16 loop_pcm16b;
int index;
int loop_index;
u16 x;
s16 psgnoise_last;
} ;
class SPU_struct
{
public:
SPU_struct(NDS_state *state, int buffersize);
u32 bufpos;
u32 buflength;
s32 *sndbuf;
s16 *outbuf;
u32 bufsize;
NDS_state *state;
channel_struct channels[16];
void reset();
~SPU_struct();
void KeyOn(int channel);
void WriteByte(u32 addr, u8 val);
void WriteWord(u32 addr, u16 val);
void WriteLong(u32 addr, u32 val);
//kills all channels but leaves SPU otherwise running normally
void ShutUp();
};
SoundInterface_struct *SPU_SoundCore(NDS_state *);
void SPU_Pause(NDS_state *, int pause);
void SPU_SetVolume(NDS_state *, int volume);
void SPU_KeyOn(NDS_state *, int channel);
void SPU_Emulate_core(NDS_state *);
void SPU_Emulate_user(NDS_state *, bool mix = true);
class WavWriter
{
public:
WavWriter();
bool open(const std::string & fname);
void close();
void update(void* soundData, int numSamples);
bool isRecording() const;
private:
FILE *spufp;
};
void WAV_End(NDS_state *);
bool WAV_Begin(NDS_state *, const char* fname);
bool WAV_IsRecording(NDS_state *);
void WAV_WavSoundUpdate(NDS_state *, void* soundData, int numSamples);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef ARMINSTRUCTION_H
#define ARMINSTRUCTION_H
#include "types.h"
#include "armcpu.h"
extern u32 (FASTCALL* arm_instructions_set[4096])(armcpu_t * cpu);
#endif

View File

@ -0,0 +1,582 @@
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "arm_instructions.h"
#include "thumb_instructions.h"
#include "cp15.h"
#include "bios.h"
#include "MMU.h"
#include <stdlib.h>
#include <stdio.h>
const unsigned char arm_cond_table[16*16] = {
/* N=0, Z=0, C=0, V=0 */
0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,
0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20,
/* N=0, Z=0, C=0, V=1 */
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x00,
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
/* N=0, Z=0, C=1, V=0 */
0x00,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
/* N=0, Z=0, C=1, V=1 */
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,
0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
/* N=0, Z=1, C=0, V=0 */
0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
/* N=0, Z=1, C=0, V=1 */
0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x00,
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
/* N=0, Z=1, C=1, V=0 */
0xFF,0x00,0xFF,0x00,0x00,0xFF,0x00,0xFF,
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
/* N=0, Z=1, C=1, V=1 */
0xFF,0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00,
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
/* N=1, Z=0, C=0, V=0 */
0x00,0xFF,0x00,0xFF,0xFF,0x00,0x00,0xFF,
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
/* N=1, Z=0, C=0, V=1 */
0x00,0xFF,0x00,0xFF,0xFF,0x00,0xFF,0x00,
0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20,
/* N=1, Z=0, C=1, V=0 */
0x00,0xFF,0xFF,0x00,0xFF,0x00,0x00,0xFF,
0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
/* N=1, Z=0, C=1, V=1 */
0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x00,
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
/* N=1, Z=1, C=0, V=0 */
0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
/* N=1, Z=1, C=0, V=1 */
0xFF,0x00,0x00,0xFF,0xFF,0x00,0xFF,0x00,
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
/* N=1, Z=1, C=1, V=0 */
0xFF,0x00,0xFF,0x00,0xFF,0x00,0x00,0xFF,
0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
/* N=1, Z=1, C=1, V=1 */
0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
};
armcpu_t NDS_ARM7;
armcpu_t NDS_ARM9;
#define SWAP(a, b, c) do \
{ \
c=a; \
a=b; \
b=c; \
} \
while(0)
#ifdef GDB_STUB
#define STALLED_CYCLE_COUNT 10
static void
stall_cpu( void *instance) {
armcpu_t *armcpu = (armcpu_t *)instance;
armcpu->stalled = 1;
}
static void
unstall_cpu( void *instance) {
armcpu_t *armcpu = (armcpu_t *)instance;
armcpu->stalled = 0;
}
static void
install_post_exec_fn( void *instance,
void (*ex_fn)( void *, u32 adr, int thumb),
void *fn_data) {
armcpu_t *armcpu = (armcpu_t *)instance;
armcpu->post_ex_fn = ex_fn;
armcpu->post_ex_fn_data = fn_data;
}
static void
remove_post_exec_fn( void *instance) {
armcpu_t *armcpu = (armcpu_t *)instance;
armcpu->post_ex_fn = NULL;
}
#endif
static u32
read_cpu_reg( void *instance, u32 reg_num) {
armcpu_t *armcpu = (armcpu_t *)instance;
u32 reg_value = 0;
if ( reg_num <= 14) {
reg_value = armcpu->R[reg_num];
}
else if ( reg_num == 15) {
reg_value = armcpu->next_instruction;
}
else if ( reg_num == 16) {
/* CPSR */
reg_value = armcpu->CPSR.val;
}
return reg_value;
}
static void
set_cpu_reg( void *instance, u32 reg_num, u32 value) {
armcpu_t *armcpu = (armcpu_t *)instance;
if ( reg_num <= 14) {
armcpu->R[reg_num] = value;
}
else if ( reg_num == 15) {
armcpu->next_instruction = value;
}
else if ( reg_num == 16) {
/* FIXME: setting the CPSR */
}
}
#ifdef GDB_STUB
int armcpu_new( NDS_state *state, armcpu_t *armcpu, u32 id,
struct armcpu_memory_iface *mem_if,
struct armcpu_ctrl_iface **ctrl_iface_ret)
#else
int armcpu_new( NDS_state *state, armcpu_t *armcpu, u32 id)
#endif
{
armcpu->state = state;
armcpu->proc_ID = id;
if(id==0)
armcpu->swi_tab = ARM9_swi_tab;
else
armcpu->swi_tab = ARM7_swi_tab;
#ifdef GDB_STUB
armcpu->mem_if = mem_if;
/* populate the control interface */
armcpu->ctrl_iface.stall = stall_cpu;
armcpu->ctrl_iface.unstall = unstall_cpu;
armcpu->ctrl_iface.read_reg = read_cpu_reg;
armcpu->ctrl_iface.set_reg = set_cpu_reg;
armcpu->ctrl_iface.install_post_ex_fn = install_post_exec_fn;
armcpu->ctrl_iface.remove_post_ex_fn = remove_post_exec_fn;
armcpu->ctrl_iface.data = armcpu;
*ctrl_iface_ret = &armcpu->ctrl_iface;
armcpu->stalled = 0;
armcpu->post_ex_fn = NULL;
#endif
armcpu_init(armcpu, 0);
return 0;
}
void armcpu_init(armcpu_t *armcpu, u32 adr)
{
u32 i;
armcpu->LDTBit = (armcpu->proc_ID==0); //Si ARM9 utiliser le syte v5 pour le load
armcpu->intVector = 0xFFFF0000 * (armcpu->proc_ID==0);
armcpu->waitIRQ = FALSE;
armcpu->wirq = FALSE;
#ifdef GDB_STUB
armcpu->irq_flag = 0;
#endif
if(armcpu->coproc[15]) free(armcpu->coproc[15]);
for(i = 0; i < 15; ++i)
{
armcpu->R[i] = 0;
armcpu->coproc[i] = NULL;
}
armcpu->CPSR.val = armcpu->SPSR.val = SYS;
armcpu->R13_usr = armcpu->R14_usr = 0;
armcpu->R13_svc = armcpu->R14_svc = 0;
armcpu->R13_abt = armcpu->R14_abt = 0;
armcpu->R13_und = armcpu->R14_und = 0;
armcpu->R13_irq = armcpu->R14_irq = 0;
armcpu->R8_fiq = armcpu->R9_fiq = armcpu->R10_fiq = armcpu->R11_fiq = armcpu->R12_fiq = armcpu->R13_fiq = armcpu->R14_fiq = 0;
armcpu->SPSR_svc.val = armcpu->SPSR_abt.val = armcpu->SPSR_und.val = armcpu->SPSR_irq.val = armcpu->SPSR_fiq.val = 0;
#ifdef GDB_STUB
armcpu->instruct_adr = adr;
armcpu->R[15] = adr + 8;
#else
armcpu->R[15] = adr;
#endif
armcpu->next_instruction = adr;
armcpu->coproc[15] = (armcp_t*)armcp15_new(armcpu);
#ifndef GDB_STUB
armcpu_prefetch(armcpu);
#endif
}
u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode)
{
u32 oldmode = armcpu->CPSR.bits.mode;
switch(oldmode)
{
case USR :
case SYS :
armcpu->R13_usr = armcpu->R[13];
armcpu->R14_usr = armcpu->R[14];
break;
case FIQ :
{
u32 tmp;
SWAP(armcpu->R[8], armcpu->R8_fiq, tmp);
SWAP(armcpu->R[9], armcpu->R9_fiq, tmp);
SWAP(armcpu->R[10], armcpu->R10_fiq, tmp);
SWAP(armcpu->R[11], armcpu->R11_fiq, tmp);
SWAP(armcpu->R[12], armcpu->R12_fiq, tmp);
armcpu->R13_fiq = armcpu->R[13];
armcpu->R14_fiq = armcpu->R[14];
armcpu->SPSR_fiq = armcpu->SPSR;
break;
}
case IRQ :
armcpu->R13_irq = armcpu->R[13];
armcpu->R14_irq = armcpu->R[14];
armcpu->SPSR_irq = armcpu->SPSR;
break;
case SVC :
armcpu->R13_svc = armcpu->R[13];
armcpu->R14_svc = armcpu->R[14];
armcpu->SPSR_svc = armcpu->SPSR;
break;
case ABT :
armcpu->R13_abt = armcpu->R[13];
armcpu->R14_abt = armcpu->R[14];
armcpu->SPSR_abt = armcpu->SPSR;
break;
case UND :
armcpu->R13_und = armcpu->R[13];
armcpu->R14_und = armcpu->R[14];
armcpu->SPSR_und = armcpu->SPSR;
break;
default :
break;
}
switch(mode)
{
case USR :
case SYS :
armcpu->R[13] = armcpu->R13_usr;
armcpu->R[14] = armcpu->R14_usr;
//SPSR = CPSR;
break;
case FIQ :
{
u32 tmp;
SWAP(armcpu->R[8], armcpu->R8_fiq, tmp);
SWAP(armcpu->R[9], armcpu->R9_fiq, tmp);
SWAP(armcpu->R[10], armcpu->R10_fiq, tmp);
SWAP(armcpu->R[11], armcpu->R11_fiq, tmp);
SWAP(armcpu->R[12], armcpu->R12_fiq, tmp);
armcpu->R[13] = armcpu->R13_fiq;
armcpu->R[14] = armcpu->R14_fiq;
armcpu->SPSR = armcpu->SPSR_fiq;
break;
}
case IRQ :
armcpu->R[13] = armcpu->R13_irq;
armcpu->R[14] = armcpu->R14_irq;
armcpu->SPSR = armcpu->SPSR_irq;
break;
case SVC :
armcpu->R[13] = armcpu->R13_svc;
armcpu->R[14] = armcpu->R14_svc;
armcpu->SPSR = armcpu->SPSR_svc;
break;
case ABT :
armcpu->R[13] = armcpu->R13_abt;
armcpu->R[14] = armcpu->R14_abt;
armcpu->SPSR = armcpu->SPSR_abt;
break;
case UND :
armcpu->R[13] = armcpu->R13_und;
armcpu->R[14] = armcpu->R14_und;
armcpu->SPSR = armcpu->SPSR_und;
break;
default :
break;
}
armcpu->CPSR.bits.mode = mode & 0x1F;
return oldmode;
}
static u32
armcpu_prefetch(armcpu_t *armcpu)
{
u32 temp_instruction;
if(armcpu->CPSR.bits.T == 0)
{
#ifdef GDB_STUB
temp_instruction =
armcpu->mem_if->prefetch32( armcpu->mem_if->data,
armcpu->next_instruction);
if ( !armcpu->stalled) {
armcpu->instruction = temp_instruction;
armcpu->instruct_adr = armcpu->next_instruction;
armcpu->next_instruction += 4;
armcpu->R[15] = armcpu->next_instruction + 4;
}
#else
armcpu->instruction = MMU_read32_acl(armcpu->state, armcpu->proc_ID, armcpu->next_instruction,CP15_ACCESS_EXECUTE);
armcpu->instruct_adr = armcpu->next_instruction;
armcpu->next_instruction += 4;
armcpu->R[15] = armcpu->next_instruction + 4;
#endif
return armcpu->state->MMU->MMU_WAIT32[armcpu->proc_ID][(armcpu->instruct_adr>>24)&0xF];
}
#ifdef GDB_STUB
temp_instruction =
armcpu->mem_if->prefetch16( armcpu->mem_if->data,
armcpu->next_instruction);
if ( !armcpu->stalled) {
armcpu->instruction = temp_instruction;
armcpu->instruct_adr = armcpu->next_instruction;
armcpu->next_instruction = armcpu->next_instruction + 2;
armcpu->R[15] = armcpu->next_instruction + 2;
}
#else
armcpu->instruction = MMU_read16_acl(armcpu->state, armcpu->proc_ID, armcpu->next_instruction,CP15_ACCESS_EXECUTE);
armcpu->instruct_adr = armcpu->next_instruction;
armcpu->next_instruction += 2;
armcpu->R[15] = armcpu->next_instruction + 2;
#endif
return armcpu->state->MMU->MMU_WAIT16[armcpu->proc_ID][(armcpu->instruct_adr>>24)&0xF];
}
static BOOL FASTCALL test_EQ(Status_Reg CPSR) { return ( CPSR.bits.Z); }
static BOOL FASTCALL test_NE(Status_Reg CPSR) { return (!CPSR.bits.Z); }
static BOOL FASTCALL test_CS(Status_Reg CPSR) { return ( CPSR.bits.C); }
static BOOL FASTCALL test_CC(Status_Reg CPSR) { return (!CPSR.bits.C); }
static BOOL FASTCALL test_MI(Status_Reg CPSR) { return ( CPSR.bits.N); }
static BOOL FASTCALL test_PL(Status_Reg CPSR) { return (!CPSR.bits.N); }
static BOOL FASTCALL test_VS(Status_Reg CPSR) { return ( CPSR.bits.V); }
static BOOL FASTCALL test_VC(Status_Reg CPSR) { return (!CPSR.bits.V); }
static BOOL FASTCALL test_HI(Status_Reg CPSR) { return (CPSR.bits.C) && (!CPSR.bits.Z); }
static BOOL FASTCALL test_LS(Status_Reg CPSR) { return (CPSR.bits.Z) || (!CPSR.bits.C); }
static BOOL FASTCALL test_GE(Status_Reg CPSR) { return (CPSR.bits.N==CPSR.bits.V); }
static BOOL FASTCALL test_LT(Status_Reg CPSR) { return (CPSR.bits.N!=CPSR.bits.V); }
static BOOL FASTCALL test_GT(Status_Reg CPSR) { return (!CPSR.bits.Z) && (CPSR.bits.N==CPSR.bits.V); }
static BOOL FASTCALL test_LE(Status_Reg CPSR) { return ( CPSR.bits.Z) || (CPSR.bits.N!=CPSR.bits.V); }
static BOOL FASTCALL test_AL(Status_Reg CPSR) { return 1; }
static BOOL (FASTCALL* test_conditions[])(Status_Reg CPSR)= {
test_EQ , test_NE ,
test_CS , test_CC ,
test_MI , test_PL ,
test_VS , test_VC ,
test_HI , test_LS ,
test_GE , test_LT ,
test_GT , test_LE ,
test_AL
};
#define TEST_COND2(cond, CPSR) \
(cond<15&&test_conditions[cond](CPSR))
BOOL armcpu_irqExeption(armcpu_t *armcpu)
{
Status_Reg tmp;
if(armcpu->CPSR.bits.I) return FALSE;
#ifdef GDB_STUB
armcpu->irq_flag = 0;
#endif
tmp = armcpu->CPSR;
armcpu_switchMode(armcpu, IRQ);
#ifdef GDB_STUB
armcpu->R[14] = armcpu->next_instruction + 4;
#else
armcpu->R[14] = armcpu->instruct_adr + 4;
#endif
armcpu->SPSR = tmp;
armcpu->CPSR.bits.T = 0;
armcpu->CPSR.bits.I = 1;
armcpu->next_instruction = armcpu->intVector + 0x18;
armcpu->waitIRQ = 0;
#ifndef GDB_STUB
armcpu->R[15] = armcpu->next_instruction + 8;
armcpu_prefetch(armcpu);
#endif
return TRUE;
}
/*
static BOOL armcpu_prefetchExeption(armcpu_t *armcpu)
{
Status_Reg tmp;
if(armcpu->CPSR.bits.I) return FALSE;
tmp = armcpu->CPSR;
armcpu_switchMode(armcpu, ABT);
armcpu->R[14] = armcpu->next_instruction + 4;
armcpu->SPSR = tmp;
armcpu->CPSR.bits.T = 0;
armcpu->CPSR.bits.I = 1;
armcpu->next_instruction = armcpu->intVector + 0xC;
armcpu->R[15] = armcpu->next_instruction + 8;
armcpu->waitIRQ = 0;
return TRUE;
}
*/
static BOOL armcpu_prefetchExeption(armcpu_t *armcpu)
{
Status_Reg tmp;
if(armcpu->CPSR.bits.I) return FALSE;
tmp = armcpu->CPSR;
armcpu_switchMode(armcpu, ABT);
#ifdef GDB_STUB
armcpu->R[14] = armcpu->next_instruction + 4;
#else
armcpu->R[14] = armcpu->instruct_adr + 4;
#endif
armcpu->SPSR = tmp;
armcpu->CPSR.bits.T = 0;
armcpu->CPSR.bits.I = 1;
armcpu->next_instruction = armcpu->intVector + 0xC;
armcpu->waitIRQ = 0;
#ifdef GDB_STUB
armcpu->R[15] = armcpu->next_instruction + 8;
#else
armcpu->R[15] = armcpu->next_instruction;
armcpu_prefetch(armcpu);
#endif
return TRUE;
}
BOOL
armcpu_flagIrq( armcpu_t *armcpu) {
if(armcpu->CPSR.bits.I) return FALSE;
armcpu->waitIRQ = 0;
#ifdef GDB_STUB
armcpu->irq_flag = 1;
#endif
return TRUE;
}
u32 armcpu_exec(armcpu_t *armcpu)
{
u32 c = 1;
#ifdef GDB_STUB
if ( armcpu->stalled)
return STALLED_CYCLE_COUNT;
/* check for interrupts */
if ( armcpu->irq_flag) {
armcpu_irqExeption( armcpu);
}
c = armcpu_prefetch(armcpu);
if ( armcpu->stalled) {
return c;
}
#endif
if(armcpu->CPSR.bits.T == 0)
{
/* if((TEST_COND(CONDITION(armcpu->instruction), armcpu->CPSR)) || ((CONDITION(armcpu->instruction)==0xF)&&(CODE(armcpu->instruction)==0x5)))*/
if((TEST_COND(CONDITION(armcpu->instruction), CODE(armcpu->instruction), armcpu->CPSR)))
{
c += arm_instructions_set[INSTRUCTION_INDEX(armcpu->instruction)](armcpu);
}
#ifdef GDB_STUB
if ( armcpu->post_ex_fn != NULL) {
/* call the external post execute function */
armcpu->post_ex_fn( armcpu->post_ex_fn_data,
armcpu->instruct_adr, 0);
}
#else
c += armcpu_prefetch(armcpu);
#endif
return c;
}
c += thumb_instructions_set[armcpu->instruction>>6](armcpu);
#ifdef GDB_STUB
if ( armcpu->post_ex_fn != NULL) {
/* call the external post execute function */
armcpu->post_ex_fn( armcpu->post_ex_fn_data, armcpu->instruct_adr, 1);
}
#else
c += armcpu_prefetch(armcpu);
#endif
return c;
}

View File

@ -0,0 +1,290 @@
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef ARM_CPU
#define ARM_CPU
#include "types.h"
#include "bits.h"
#include "MMU.h"
#include "state.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ARMCPU_ARM7 1
#define ARMCPU_ARM9 0
#define CODE(i) (((i)>>25)&0X7)
#define OPCODE(i) (((i)>>21)&0xF)
#define SIGNEBIT(i) BIT_N(i,20)
#define INSTRUCTION_INDEX(i) ((((i)>>16)&0xFF0)|(((i)>>4)&0xF))
#define ROR(i, j) ((((u32)(i))>>(j)) | (((u32)(i))<<(32-(j))))
#define UNSIGNED_OVERFLOW(a,b,c) ((BIT31(a)&BIT31(b)) | \
((BIT31(a)|BIT31(b))&BIT31(~c)))
#define UNSIGNED_UNDERFLOW(a,b,c) ((BIT31(~a)&BIT31(b)) | \
((BIT31(~a)|BIT31(b))&BIT31(c)))
#define SIGNED_OVERFLOW(a,b,c) ((BIT31(a)&BIT31(b)&BIT31(~c))|\
(BIT31(~a)&BIT31(~(b))&BIT31(c)))
#define SIGNED_UNDERFLOW(a,b,c) ((BIT31(a)&BIT31(~(b))&BIT31(~c))|\
(BIT31(~a)&BIT31(b)&BIT31(c)))
#define EQ 0x0
#define NE 0x1
#define CS 0x2
#define CC 0x3
#define MI 0x4
#define PL 0x5
#define VS 0x6
#define VC 0x7
#define HI 0x8
#define LS 0x9
#define GE 0xA
#define LT 0xB
#define GT 0xC
#define LE 0xD
#define AL 0xE
/*
#define TEST_COND(cond, CPSR) (((cond)==AL) ||\
(((cond)==EQ) && ( CPSR.bits.Z))||\
(((cond)==NE) && (!CPSR.bits.Z))||\
(((cond)==CS) && ( CPSR.bits.C))||\
(((cond)==CC) && (!CPSR.bits.C))||\
(((cond)==MI) && ( CPSR.bits.N))||\
(((cond)==PL) && (!CPSR.bits.N))||\
(((cond)==VS) && ( CPSR.bits.V))||\
(((cond)==VC) && (!CPSR.bits.V))||\
(((cond)==HI) && (CPSR.bits.C) && (!CPSR.bits.Z))||\
(((cond)==LS) && ((CPSR.bits.Z) || (!CPSR.bits.C)))||\
(((cond)==GE) && (CPSR.bits.N==CPSR.bits.V))||\
(((cond)==LT) && (CPSR.bits.N!=CPSR.bits.V))||\
(((cond)==GT) && (CPSR.bits.Z==0) && (CPSR.bits.N==CPSR.bits.V))||\
(((cond)==LE) && ((CPSR.bits.Z) || (CPSR.bits.N!=CPSR.bits.V))))
*/
extern const unsigned char arm_cond_table[16*16];
#define TEST_COND(cond, inst, CPSR) ((arm_cond_table[((CPSR.val >> 24) & 0xf0)+(cond)] >> (inst)) & 1)
enum Mode
{
USR = 0x10,
FIQ = 0x11,
IRQ = 0x12,
SVC = 0x13,
ABT = 0x17,
UND = 0x1B,
SYS = 0x1F
};
#ifdef WORDS_BIGENDIAN
typedef union
{
struct
{
u32 N : 1,
Z : 1,
C : 1,
V : 1,
Q : 1,
RAZ : 19,
I : 1,
F : 1,
T : 1,
mode : 5;
} bits;
u32 val;
} Status_Reg;
#else
typedef union
{
struct
{
u32 mode : 5,
T : 1,
F : 1,
I : 1,
RAZ : 19,
Q : 1,
V : 1,
C : 1,
Z : 1,
N : 1;
} bits;
u32 val;
} Status_Reg;
#endif
/**
* The control interface to a CPU
*/
struct armcpu_ctrl_iface {
/** stall the processor */
void (*stall)( void *instance);
/** unstall the processor */
void (*unstall)( void *instance);
/** read a register value */
u32 (*read_reg)( void *instance, u32 reg_num);
/** set a register value */
void (*set_reg)( void *instance, u32 reg_num, u32 value);
/** install the post execute function */
void (*install_post_ex_fn)( void *instance,
void (*fn)( void *, u32 adr, int thumb),
void *fn_data);
/** remove the post execute function */
void (*remove_post_ex_fn)( void *instance);
/** the private data passed to all interface functions */
void *data;
};
typedef void* armcp_t;
typedef struct armcpu_t
{
u32 proc_ID;
u32 instruction; //4
u32 instruct_adr; //8
u32 next_instruction; //12
u32 R[16]; //16
Status_Reg CPSR; //80
Status_Reg SPSR;
u32 R13_usr, R14_usr;
u32 R13_svc, R14_svc;
u32 R13_abt, R14_abt;
u32 R13_und, R14_und;
u32 R13_irq, R14_irq;
u32 R8_fiq, R9_fiq, R10_fiq, R11_fiq, R12_fiq, R13_fiq, R14_fiq;
Status_Reg SPSR_svc, SPSR_abt, SPSR_und, SPSR_irq, SPSR_fiq;
armcp_t *coproc[16];
u32 intVector;
u8 LDTBit; //1 : ARMv5 style 0 : non ARMv5
BOOL waitIRQ;
BOOL wIRQ;
BOOL wirq;
u32 (* *swi_tab)(struct armcpu_t * cpu);
NDS_state *state;
#ifdef GDB_STUB
/** there is a pending irq for the cpu */
int irq_flag;
/** the post executed function (if installed) */
void (*post_ex_fn)( void *, u32 adr, int thumb);
/** data for the post executed function */
void *post_ex_fn_data;
/** flag indicating if the processor is stalled */
int stalled;
/** the memory interface */
struct armcpu_memory_iface *mem_if;
/** the ctrl interface */
struct armcpu_ctrl_iface ctrl_iface;
#endif
} armcpu_t;
#ifdef GDB_STUB
int armcpu_new( NDS_state *, armcpu_t *armcpu, u32 id, struct armcpu_memory_iface *mem_if,
struct armcpu_ctrl_iface **ctrl_iface_ret);
#else
int armcpu_new( NDS_state *, armcpu_t *armcpu, u32 id);
#endif
void armcpu_init(armcpu_t *armcpu, u32 adr);
u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode);
static u32 armcpu_prefetch(armcpu_t *armcpu);
u32 armcpu_exec(armcpu_t *armcpu);
BOOL armcpu_irqExeption(armcpu_t *armcpu);
//BOOL armcpu_prefetchExeption(armcpu_t *armcpu);
BOOL
armcpu_flagIrq( armcpu_t *armcpu);
static INLINE void NDS_makeARM9Int(NDS_state *state, u32 num)
{
/* flag the interrupt request source */
state->MMU->reg_IF[0] |= (1<<num);
/* generate the interrupt if enabled */
if ((state->MMU->reg_IE[0] & (1 << num)) && state->MMU->reg_IME[0])
{
state->NDS_ARM9->wIRQ = TRUE;
state->NDS_ARM9->waitIRQ = FALSE;
}
}
static INLINE void NDS_makeARM7Int(NDS_state *state, u32 num)
{
/* flag the interrupt request source */
state->MMU->reg_IF[1] |= (1<<num);
/* generate the interrupt if enabled */
if ((state->MMU->reg_IE[1] & (1 << num)) && state->MMU->reg_IME[1])
{
state->NDS_ARM7->wIRQ = TRUE;
state->NDS_ARM7->waitIRQ = FALSE;
}
}
static INLINE void NDS_makeInt(NDS_state *state, u8 proc_ID,u32 num)
{
switch (proc_ID)
{
case 0:
NDS_makeARM9Int(state, num) ;
break ;
case 1:
NDS_makeARM7Int(state, num) ;
break ;
}
}
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef BIOS_H
#define BIOS_H
#include "armcpu.h"
extern u32 (* ARM9_swi_tab[32])(armcpu_t * cpu);
extern u32 (* ARM7_swi_tab[32])(armcpu_t * cpu);
extern u32 wait4IRQ(armcpu_t * cpu);
#endif

View File

@ -0,0 +1,44 @@
#ifndef BITS_H
#define BITS_H
#define BIT(n) (1<<(n))
#define BIT_N(i,n) (((i)>>(n))&1)
#define BIT0(i) ((i)&1)
#define BIT1(i) BIT_N(i,1)
#define BIT2(i) BIT_N(i,2)
#define BIT3(i) BIT_N(i,3)
#define BIT4(i) BIT_N(i,4)
#define BIT5(i) BIT_N(i,5)
#define BIT6(i) BIT_N(i,6)
#define BIT7(i) BIT_N(i,7)
#define BIT8(i) BIT_N(i,8)
#define BIT9(i) BIT_N(i,9)
#define BIT10(i) BIT_N(i,10)
#define BIT11(i) BIT_N(i,11)
#define BIT12(i) BIT_N(i,12)
#define BIT13(i) BIT_N(i,13)
#define BIT14(i) BIT_N(i,14)
#define BIT15(i) BIT_N(i,15)
#define BIT16(i) BIT_N(i,16)
#define BIT17(i) BIT_N(i,17)
#define BIT18(i) BIT_N(i,18)
#define BIT19(i) BIT_N(i,19)
#define BIT20(i) BIT_N(i,20)
#define BIT21(i) BIT_N(i,21)
#define BIT22(i) BIT_N(i,22)
#define BIT23(i) BIT_N(i,23)
#define BIT24(i) BIT_N(i,24)
#define BIT25(i) BIT_N(i,25)
#define BIT26(i) BIT_N(i,26)
#define BIT27(i) BIT_N(i,27)
#define BIT28(i) BIT_N(i,28)
#define BIT29(i) BIT_N(i,29)
#define BIT30(i) BIT_N(i,30)
#define BIT31(i) ((i)>>31)
#define CONDITION(i) (i)>>28
#define REG_POS(i,n) (((i)>>n)&0xF)
#endif

View File

@ -0,0 +1,28 @@
/* Copyright (C) 2006 thoduv
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __CONFIG_H__
#define __CONFIG_H__
#include <stdio.h>
#include "debug.h"
#endif /*__CONFIG_H__*/

View File

@ -0,0 +1,592 @@
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdlib.h>
#include "cp15.h"
#include "debug.h"
#include "MMU.h"
#include "state.h"
armcp15_t *armcp15_new(armcpu_t * c)
{
int i;
armcp15_t *armcp15 = (armcp15_t*)malloc(sizeof(armcp15_t));
if(!armcp15) return NULL;
armcp15->cpu = c;
armcp15->IDCode = 0x41049460;
armcp15->cacheType = 0x0F0D2112;
armcp15->TCMSize = 0x00140140;
armcp15->ctrl = 0x00000000;
armcp15->DCConfig = 0x0;
armcp15->ICConfig = 0x0;
armcp15->writeBuffCtrl = 0x0;
armcp15->und = 0x0;
armcp15->DaccessPerm = 0x22222222;
armcp15->IaccessPerm = 0x22222222;
armcp15->protectBaseSize0 = 0x0;
armcp15->protectBaseSize1 = 0x0;
armcp15->protectBaseSize2 = 0x0;
armcp15->protectBaseSize3 = 0x0;
armcp15->protectBaseSize4 = 0x0;
armcp15->protectBaseSize5 = 0x0;
armcp15->protectBaseSize6 = 0x0;
armcp15->protectBaseSize7 = 0x0;
armcp15->cacheOp = 0x0;
armcp15->DcacheLock = 0x0;
armcp15->IcacheLock = 0x0;
armcp15->ITCMRegion = 0x0C;
armcp15->DTCMRegion = 0x0080000A;
armcp15->processID = 0;
/* preset calculated regionmasks */
for (i=0;i<8;i++) {
armcp15->regionWriteMask_USR[i] = 0 ;
armcp15->regionWriteMask_SYS[i] = 0 ;
armcp15->regionReadMask_USR[i] = 0 ;
armcp15->regionReadMask_SYS[i] = 0 ;
armcp15->regionExecuteMask_USR[i] = 0 ;
armcp15->regionExecuteMask_SYS[i] = 0 ;
armcp15->regionWriteSet_USR[i] = 0 ;
armcp15->regionWriteSet_SYS[i] = 0 ;
armcp15->regionReadSet_USR[i] = 0 ;
armcp15->regionReadSet_SYS[i] = 0 ;
armcp15->regionExecuteSet_USR[i] = 0 ;
armcp15->regionExecuteSet_SYS[i] = 0 ;
} ;
return armcp15;
}
#define ACCESSTYPE(val,n) (((val) >> (4*n)) & 0x0F)
#define SIZEIDENTIFIER(val) ((((val) >> 1) & 0x1F))
#define SIZEBINARY(val) (1 << (SIZEIDENTIFIER(val)+1))
#define MASKFROMREG(val) (~((SIZEBINARY(val)-1) | 0x3F))
#define SETFROMREG(val) ((val) & MASKFROMREG(val))
/* sets the precalculated regions to mask,set for the affected accesstypes */
void armcp15_setSingleRegionAccess(armcp15_t *armcp15,unsigned long dAccess,unsigned long iAccess,unsigned char num, unsigned long mask,unsigned long set) {
switch (ACCESSTYPE(dAccess,num)) {
case 4: /* UNP */
case 7: /* UNP */
case 8: /* UNP */
case 9: /* UNP */
case 10: /* UNP */
case 11: /* UNP */
case 12: /* UNP */
case 13: /* UNP */
case 14: /* UNP */
case 15: /* UNP */
case 0: /* no access at all */
armcp15->regionWriteMask_USR[num] = 0 ;
armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
armcp15->regionReadMask_USR[num] = 0 ;
armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ;
armcp15->regionWriteMask_SYS[num] = 0 ;
armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ;
armcp15->regionReadMask_SYS[num] = 0 ;
armcp15->regionReadSet_SYS[num] = 0xFFFFFFFF ;
break ;
case 1: /* no access at USR, all to sys */
armcp15->regionWriteMask_USR[num] = 0 ;
armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
armcp15->regionReadMask_USR[num] = 0 ;
armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ;
armcp15->regionWriteMask_SYS[num] = mask ;
armcp15->regionWriteSet_SYS[num] = set ;
armcp15->regionReadMask_SYS[num] = mask ;
armcp15->regionReadSet_SYS[num] = set ;
break ;
case 2: /* read at USR, all to sys */
armcp15->regionWriteMask_USR[num] = 0 ;
armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
armcp15->regionReadMask_USR[num] = mask ;
armcp15->regionReadSet_USR[num] = set ;
armcp15->regionWriteMask_SYS[num] = mask ;
armcp15->regionWriteSet_SYS[num] = set ;
armcp15->regionReadMask_SYS[num] = mask ;
armcp15->regionReadSet_SYS[num] = set ;
break ;
case 3: /* all to USR, all to sys */
armcp15->regionWriteMask_USR[num] = mask ;
armcp15->regionWriteSet_USR[num] = set ;
armcp15->regionReadMask_USR[num] = mask ;
armcp15->regionReadSet_USR[num] = set ;
armcp15->regionWriteMask_SYS[num] = mask ;
armcp15->regionWriteSet_SYS[num] = set ;
armcp15->regionReadMask_SYS[num] = mask ;
armcp15->regionReadSet_SYS[num] = set ;
break ;
case 5: /* no access at USR, read to sys */
armcp15->regionWriteMask_USR[num] = 0 ;
armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
armcp15->regionReadMask_USR[num] = 0 ;
armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ;
armcp15->regionWriteMask_SYS[num] = 0 ;
armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ;
armcp15->regionReadMask_SYS[num] = mask ;
armcp15->regionReadSet_SYS[num] = set ;
break ;
case 6: /* read at USR, read to sys */
armcp15->regionWriteMask_USR[num] = 0 ;
armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ;
armcp15->regionReadMask_USR[num] = mask ;
armcp15->regionReadSet_USR[num] = set ;
armcp15->regionWriteMask_SYS[num] = 0 ;
armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ;
armcp15->regionReadMask_SYS[num] = mask ;
armcp15->regionReadSet_SYS[num] = set ;
break ;
}
switch (ACCESSTYPE(iAccess,num)) {
case 4: /* UNP */
case 7: /* UNP */
case 8: /* UNP */
case 9: /* UNP */
case 10: /* UNP */
case 11: /* UNP */
case 12: /* UNP */
case 13: /* UNP */
case 14: /* UNP */
case 15: /* UNP */
case 0: /* no access at all */
armcp15->regionExecuteMask_USR[num] = 0 ;
armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ;
armcp15->regionExecuteMask_SYS[num] = 0 ;
armcp15->regionExecuteSet_SYS[num] = 0xFFFFFFFF ;
break ;
case 1:
armcp15->regionExecuteMask_USR[num] = 0 ;
armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ;
armcp15->regionExecuteMask_SYS[num] = mask ;
armcp15->regionExecuteSet_SYS[num] = set ;
break ;
case 2:
case 3:
case 6:
armcp15->regionExecuteMask_USR[num] = mask ;
armcp15->regionExecuteSet_USR[num] = set ;
armcp15->regionExecuteMask_SYS[num] = mask ;
armcp15->regionExecuteSet_SYS[num] = set ;
break ;
}
} ;
/* precalculate region masks/sets from cp15 register */
void armcp15_maskPrecalc(armcp15_t *armcp15)
{
#define precalc(num) { \
u32 mask = 0, set = 0xFFFFFFFF ; /* (x & 0) == 0xFF..FF is allways false (disabled) */ \
if (BIT_N(armcp15->protectBaseSize##num,0)) /* if region is enabled */ \
{ /* reason for this define: naming includes var */ \
mask = MASKFROMREG(armcp15->protectBaseSize##num) ; \
set = SETFROMREG(armcp15->protectBaseSize##num) ; \
if (SIZEIDENTIFIER(armcp15->protectBaseSize##num)==0x1F) \
{ /* for the 4GB region, u32 suffers wraparound */ \
mask = 0 ; set = 0 ; /* (x & 0) == 0 is allways true (enabled) */ \
} \
} \
armcp15_setSingleRegionAccess(armcp15,armcp15->DaccessPerm,armcp15->IaccessPerm,num,mask,set) ; \
}
precalc(0) ;
precalc(1) ;
precalc(2) ;
precalc(3) ;
precalc(4) ;
precalc(5) ;
precalc(6) ;
precalc(7) ;
}
INLINE BOOL armcp15_isAccessAllowed(armcp15_t *armcp15,u32 address,u32 access)
{
int i ;
if (!(armcp15->ctrl & 1)) return TRUE ; /* protection checking is not enabled */
for (i=0;i<8;i++) {
switch (access) {
case CP15_ACCESS_WRITEUSR:
if ((address & armcp15->regionWriteMask_USR[i]) == armcp15->regionWriteSet_USR[i]) return TRUE ;
break ;
case CP15_ACCESS_WRITESYS:
if ((address & armcp15->regionWriteMask_SYS[i]) == armcp15->regionWriteSet_SYS[i]) return TRUE ;
break ;
case CP15_ACCESS_READUSR:
if ((address & armcp15->regionReadMask_USR[i]) == armcp15->regionReadSet_USR[i]) return TRUE ;
break ;
case CP15_ACCESS_READSYS:
if ((address & armcp15->regionReadMask_SYS[i]) == armcp15->regionReadSet_SYS[i]) return TRUE ;
break ;
case CP15_ACCESS_EXECUSR:
if ((address & armcp15->regionExecuteMask_USR[i]) == armcp15->regionExecuteSet_USR[i]) return TRUE ;
break ;
case CP15_ACCESS_EXECSYS:
if ((address & armcp15->regionExecuteMask_SYS[i]) == armcp15->regionExecuteSet_SYS[i]) return TRUE ;
break ;
}
}
/* when protections are enabled, but no region allows access, deny access */
return FALSE ;
}
BOOL armcp15_dataProcess(armcp15_t *armcp15, u8 CRd, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2)
{
return FALSE;
}
BOOL armcp15_load(armcp15_t *armcp15, u8 CRd, u8 adr)
{
return FALSE;
}
BOOL armcp15_store(armcp15_t *armcp15, u8 CRd, u8 adr)
{
return FALSE;
}
BOOL armcp15_moveCP2ARM(armcp15_t *armcp15, u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2)
{
if(armcp15->cpu->CPSR.bits.mode == USR) return FALSE;
switch(CRn)
{
case 0 :
if((opcode1 == 0)&&(CRm==0))
{
switch(opcode2)
{
case 1 :
*R = armcp15->cacheType;
return TRUE;
case 2 :
*R = armcp15->TCMSize;
return TRUE;
default :
*R = armcp15->IDCode;
return TRUE;
}
}
return FALSE;
case 1 :
if((opcode1==0) && (opcode2==0) && (CRm==0))
{
*R = armcp15->ctrl;
return TRUE;
}
return FALSE;
case 2 :
if((opcode1==0) && (CRm==0))
{
switch(opcode2)
{
case 0 :
*R = armcp15->DCConfig;
return TRUE;
case 1 :
*R = armcp15->ICConfig;
return TRUE;
default :
return FALSE;
}
}
return FALSE;
case 3 :
if((opcode1==0) && (opcode2==0) && (CRm==0))
{
*R = armcp15->writeBuffCtrl;
return TRUE;
}
return FALSE;
case 5 :
if((opcode1==0) && (CRm==0))
{
switch(opcode2)
{
case 2 :
*R = armcp15->DaccessPerm;
return TRUE;
case 3 :
*R = armcp15->IaccessPerm;
return TRUE;
default :
return FALSE;
}
}
return FALSE;
case 6 :
if((opcode1==0) && (opcode2==0))
{
switch(CRm)
{
case 0 :
*R = armcp15->protectBaseSize0;
return TRUE;
case 1 :
*R = armcp15->protectBaseSize1;
return TRUE;
case 2 :
*R = armcp15->protectBaseSize2;
return TRUE;
case 3 :
*R = armcp15->protectBaseSize3;
return TRUE;
case 4 :
*R = armcp15->protectBaseSize4;
return TRUE;
case 5 :
*R = armcp15->protectBaseSize5;
return TRUE;
case 6 :
*R = armcp15->protectBaseSize6;
return TRUE;
case 7 :
*R = armcp15->protectBaseSize7;
return TRUE;
default :
return FALSE;
}
}
return FALSE;
case 9 :
if((opcode1==0))
{
switch(CRm)
{
case 0 :
switch(opcode2)
{
case 0 :
*R = armcp15->DcacheLock;
return TRUE;
case 1 :
*R = armcp15->IcacheLock;
return TRUE;
default :
return FALSE;
}
case 1 :
switch(opcode2)
{
case 0 :
*R = armcp15->DTCMRegion;
return TRUE;
case 1 :
*R = armcp15->ITCMRegion;
return TRUE;
default :
return FALSE;
}
}
}
return FALSE;
default :
return FALSE;
}
}
u32 CP15wait4IRQ(armcpu_t *cpu)
{
/* on the first call, wirq is not set */
if(cpu->wirq)
{
/* check wether an irq was issued */
if(!cpu->waitIRQ)
{
cpu->waitIRQ = 0;
cpu->wirq = 0;
return 1; /* return execution */
}
/* otherwise, repeat this instruction */
cpu->R[15] = cpu->instruct_adr;
cpu->next_instruction = cpu->R[15];
return 1;
}
/* first run, set us into waiting state */
cpu->waitIRQ = 1;
cpu->wirq = 1;
/* and set next instruction to repeat this */
cpu->R[15] = cpu->instruct_adr;
cpu->next_instruction = cpu->R[15];
/* CHECKME: IME shouldn't be modified (?) */
cpu->state->MMU->reg_IME[0] = 1;
return 1;
}
BOOL armcp15_moveARM2CP(armcp15_t *armcp15, u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2)
{
if(armcp15->cpu->CPSR.bits.mode == USR) return FALSE;
switch(CRn)
{
case 1 :
if((opcode1==0) && (opcode2==0) && (CRm==0))
{
armcp15->ctrl = val;
armcp15->cpu->state->MMU->ARM9_RW_MODE = BIT7(val);
armcp15->cpu->intVector = 0x0FFF0000 * (BIT13(val));
armcp15->cpu->LDTBit = !BIT15(val); //TBit
/*if(BIT17(val))
{
log::ajouter("outch !!!!!!!");
}
if(BIT19(val))
{
log::ajouter("outch !!!!!!!");
}*/
return TRUE;
}
return FALSE;
case 2 :
if((opcode1==0) && (CRm==0))
{
switch(opcode2)
{
case 0 :
armcp15->DCConfig = val;
return TRUE;
case 1 :
armcp15->ICConfig = val;
return TRUE;
default :
return FALSE;
}
}
return FALSE;
case 3 :
if((opcode1==0) && (opcode2==0) && (CRm==0))
{
armcp15->writeBuffCtrl = val;
return TRUE;
}
return FALSE;
if((opcode1==0) && (CRm==0))
{
switch(opcode2)
{
case 2 :
armcp15->DaccessPerm = val;
armcp15_maskPrecalc(armcp15);
return TRUE;
case 3 :
armcp15->IaccessPerm = val;
armcp15_maskPrecalc(armcp15);
return TRUE;
default :
return FALSE;
}
}
return FALSE;
case 6 :
if((opcode1==0) && (opcode2==0))
{
switch(CRm)
{
case 0 :
armcp15->protectBaseSize0 = val;
armcp15_maskPrecalc(armcp15) ;
return TRUE;
case 1 :
armcp15->protectBaseSize1 = val;
armcp15_maskPrecalc(armcp15) ;
return TRUE;
case 2 :
armcp15->protectBaseSize2 = val;
armcp15_maskPrecalc(armcp15) ;
return TRUE;
case 3 :
armcp15->protectBaseSize3 = val;
armcp15_maskPrecalc(armcp15) ;
return TRUE;
case 4 :
armcp15->protectBaseSize4 = val;
armcp15_maskPrecalc(armcp15) ;
return TRUE;
case 5 :
armcp15->protectBaseSize5 = val;
armcp15_maskPrecalc(armcp15) ;
return TRUE;
case 6 :
armcp15->protectBaseSize6 = val;
armcp15_maskPrecalc(armcp15) ;
return TRUE;
case 7 :
armcp15->protectBaseSize7 = val;
armcp15_maskPrecalc(armcp15) ;
return TRUE;
default :
return FALSE;
}
}
return FALSE;
case 7 :
if((CRm==0)&&(opcode1==0)&&((opcode2==4)))
{
CP15wait4IRQ(armcp15->cpu);
return TRUE;
}
return FALSE;
case 9 :
if((opcode1==0))
{
switch(CRm)
{
case 0 :
switch(opcode2)
{
case 0 :
armcp15->DcacheLock = val;
return TRUE;
case 1 :
armcp15->IcacheLock = val;
return TRUE;
default :
return FALSE;
}
case 1 :
switch(opcode2)
{
case 0 :
armcp15->DTCMRegion = val;
armcp15->cpu->state->MMU->DTCMRegion = val & 0x0FFFFFFC0;
/*sprintf(logbuf, "%08X", val);
log::ajouter(logbuf);*/
return TRUE;
case 1 :
armcp15->ITCMRegion = val;
/* ITCM base is not writeable! */
armcp15->cpu->state->MMU->ITCMRegion = 0;
return TRUE;
default :
return FALSE;
}
}
}
return FALSE;
default :
return FALSE;
}
}

View File

@ -0,0 +1,94 @@
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __CP15_H__
#define __CP15_H__
#include "armcpu.h"
typedef struct
{
u32 IDCode;
u32 cacheType;
u32 TCMSize;
u32 ctrl;
u32 DCConfig;
u32 ICConfig;
u32 writeBuffCtrl;
u32 und;
u32 DaccessPerm;
u32 IaccessPerm;
u32 protectBaseSize0;
u32 protectBaseSize1;
u32 protectBaseSize2;
u32 protectBaseSize3;
u32 protectBaseSize4;
u32 protectBaseSize5;
u32 protectBaseSize6;
u32 protectBaseSize7;
u32 cacheOp;
u32 DcacheLock;
u32 IcacheLock;
u32 ITCMRegion;
u32 DTCMRegion;
u32 processID;
u32 RAM_TAG;
u32 testState;
u32 cacheDbg;
/* calculated bitmasks for the regions to decide rights uppon */
/* calculation is done in the MCR instead of on mem access for performance */
u32 regionWriteMask_USR[8] ;
u32 regionWriteMask_SYS[8] ;
u32 regionReadMask_USR[8] ;
u32 regionReadMask_SYS[8] ;
u32 regionExecuteMask_USR[8] ;
u32 regionExecuteMask_SYS[8] ;
u32 regionWriteSet_USR[8] ;
u32 regionWriteSet_SYS[8] ;
u32 regionReadSet_USR[8] ;
u32 regionReadSet_SYS[8] ;
u32 regionExecuteSet_USR[8] ;
u32 regionExecuteSet_SYS[8] ;
armcpu_t * cpu;
} armcp15_t;
armcp15_t *armcp15_new(armcpu_t *c);
BOOL armcp15_dataProcess(armcp15_t *armcp15, u8 CRd, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2);
BOOL armcp15_load(armcp15_t *armcp15, u8 CRd, u8 adr);
BOOL armcp15_store(armcp15_t *armcp15, u8 CRd, u8 adr);
BOOL armcp15_moveCP2ARM(armcp15_t *armcp15, u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2);
BOOL armcp15_moveARM2CP(armcp15_t *armcp15, u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2);
INLINE BOOL armcp15_isAccessAllowed(armcp15_t *armcp15,u32 address,u32 access) ;
#define CP15_ACCESS_WRITE 0
#define CP15_ACCESS_READ 2
#define CP15_ACCESS_EXECUTE 4
#define CP15_ACCESS_WRITEUSR CP15_ACCESS_WRITE
#define CP15_ACCESS_WRITESYS 1
#define CP15_ACCESS_READUSR CP15_ACCESS_READ
#define CP15_ACCESS_READSYS 3
#define CP15_ACCESS_EXECUSR CP15_ACCESS_EXECUTE
#define CP15_ACCESS_EXECSYS 5
#endif /* __CP15_H__*/

View File

@ -0,0 +1,11 @@
#ifndef DEBUG_H
#define DEBUG_H
#define LOG(...)
#define GPULOG(...)
#define DIVLOG(...)
#define SQRTLOG(...)
#define CARDLOG(...)
#define DMALOG(...)
#endif

View File

@ -0,0 +1,34 @@
/* Copyright (C) 2006 thoduv
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __DSCARD_H__
#define __DSCARD_H__
typedef struct
{
u32 adress;
u32 transfer_count;
} nds_dscard;
#endif /*__DSCARD_H__*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,257 @@
/*
Copyright (C) 2006-2007 shash
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "matrix.h"
void MatrixInit (float *matrix)
{
memset (matrix, 0, sizeof(float)*16);
matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1.f;
}
void MatrixMultVec4x4 (float *matrix, float *vecPtr)
{
float x = vecPtr[0];
float y = vecPtr[1];
float z = vecPtr[2];
vecPtr[0] = x * matrix[0] + y * matrix[4] + z * matrix[ 8] + matrix[12];
vecPtr[1] = x * matrix[1] + y * matrix[5] + z * matrix[ 9] + matrix[13];
vecPtr[2] = x * matrix[2] + y * matrix[6] + z * matrix[10] + matrix[14];
}
void MatrixMultVec3x3 (float *matrix, float *vecPtr)
{
float x = vecPtr[0];
float y = vecPtr[1];
float z = vecPtr[2];
vecPtr[0] = x * matrix[0] + y * matrix[4] + z * matrix[ 8];
vecPtr[1] = x * matrix[1] + y * matrix[5] + z * matrix[ 9];
vecPtr[2] = x * matrix[2] + y * matrix[6] + z * matrix[10];
}
void MatrixIdentity (float *matrix)
{
memset (matrix, 0, sizeof(float)*16);
matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1.f;
}
void MatrixMultiply (float *matrix, float *rightMatrix)
{
float tmpMatrix[16];
tmpMatrix[0] = (matrix[0]*rightMatrix[0])+(matrix[4]*rightMatrix[1])+(matrix[8]*rightMatrix[2])+(matrix[12]*rightMatrix[3]);
tmpMatrix[1] = (matrix[1]*rightMatrix[0])+(matrix[5]*rightMatrix[1])+(matrix[9]*rightMatrix[2])+(matrix[13]*rightMatrix[3]);
tmpMatrix[2] = (matrix[2]*rightMatrix[0])+(matrix[6]*rightMatrix[1])+(matrix[10]*rightMatrix[2])+(matrix[14]*rightMatrix[3]);
tmpMatrix[3] = (matrix[3]*rightMatrix[0])+(matrix[7]*rightMatrix[1])+(matrix[11]*rightMatrix[2])+(matrix[15]*rightMatrix[3]);
tmpMatrix[4] = (matrix[0]*rightMatrix[4])+(matrix[4]*rightMatrix[5])+(matrix[8]*rightMatrix[6])+(matrix[12]*rightMatrix[7]);
tmpMatrix[5] = (matrix[1]*rightMatrix[4])+(matrix[5]*rightMatrix[5])+(matrix[9]*rightMatrix[6])+(matrix[13]*rightMatrix[7]);
tmpMatrix[6] = (matrix[2]*rightMatrix[4])+(matrix[6]*rightMatrix[5])+(matrix[10]*rightMatrix[6])+(matrix[14]*rightMatrix[7]);
tmpMatrix[7] = (matrix[3]*rightMatrix[4])+(matrix[7]*rightMatrix[5])+(matrix[11]*rightMatrix[6])+(matrix[15]*rightMatrix[7]);
tmpMatrix[8] = (matrix[0]*rightMatrix[8])+(matrix[4]*rightMatrix[9])+(matrix[8]*rightMatrix[10])+(matrix[12]*rightMatrix[11]);
tmpMatrix[9] = (matrix[1]*rightMatrix[8])+(matrix[5]*rightMatrix[9])+(matrix[9]*rightMatrix[10])+(matrix[13]*rightMatrix[11]);
tmpMatrix[10] = (matrix[2]*rightMatrix[8])+(matrix[6]*rightMatrix[9])+(matrix[10]*rightMatrix[10])+(matrix[14]*rightMatrix[11]);
tmpMatrix[11] = (matrix[3]*rightMatrix[8])+(matrix[7]*rightMatrix[9])+(matrix[11]*rightMatrix[10])+(matrix[15]*rightMatrix[11]);
tmpMatrix[12] = (matrix[0]*rightMatrix[12])+(matrix[4]*rightMatrix[13])+(matrix[8]*rightMatrix[14])+(matrix[12]*rightMatrix[15]);
tmpMatrix[13] = (matrix[1]*rightMatrix[12])+(matrix[5]*rightMatrix[13])+(matrix[9]*rightMatrix[14])+(matrix[13]*rightMatrix[15]);
tmpMatrix[14] = (matrix[2]*rightMatrix[12])+(matrix[6]*rightMatrix[13])+(matrix[10]*rightMatrix[14])+(matrix[14]*rightMatrix[15]);
tmpMatrix[15] = (matrix[3]*rightMatrix[12])+(matrix[7]*rightMatrix[13])+(matrix[11]*rightMatrix[14])+(matrix[15]*rightMatrix[15]);
memcpy (matrix, tmpMatrix, sizeof(float)*16);
}
/*
void MatrixMulti (float* right)
{
float tmpMatrix[16];
tmpMatrix[0] = (matrix[0]*right[0])+(matrix[4]*right[1])+(matrix[8]*right[2])+(matrix[12]*right[3]);
tmpMatrix[1] = (matrix[1]*right[0])+(matrix[5]*right[1])+(matrix[9]*right[2])+(matrix[13]*right[3]);
tmpMatrix[2] = (matrix[2]*right[0])+(matrix[6]*right[1])+(matrix[10]*right[2])+(matrix[14]*right[3]);
tmpMatrix[3] = (matrix[3]*right[0])+(matrix[7]*right[1])+(matrix[11]*right[2])+(matrix[15]*right[3]);
tmpMatrix[4] = (matrix[0]*right[4])+(matrix[4]*right[5])+(matrix[8]*right[6])+(matrix[12]*right[7]);
tmpMatrix[5] = (matrix[1]*right[4])+(matrix[5]*right[5])+(matrix[9]*right[6])+(matrix[13]*right[7]);
tmpMatrix[6] = (matrix[2]*right[4])+(matrix[6]*right[5])+(matrix[10]*right[6])+(matrix[14]*right[7]);
tmpMatrix[7] = (matrix[3]*right[4])+(matrix[7]*right[5])+(matrix[11]*right[6])+(matrix[15]*right[7]);
tmpMatrix[8] = (matrix[0]*right[8])+(matrix[4]*right[9])+(matrix[8]*right[10])+(matrix[12]*right[11]);
tmpMatrix[9] = (matrix[1]*right[8])+(matrix[5]*right[9])+(matrix[9]*right[10])+(matrix[13]*right[11]);
tmpMatrix[10] = (matrix[2]*right[8])+(matrix[6]*right[9])+(matrix[10]*right[10])+(matrix[14]*right[11]);
tmpMatrix[11] = (matrix[3]*right[8])+(matrix[7]*right[9])+(matrix[11]*right[10])+(matrix[15]*right[11]);
tmpMatrix[12] = (matrix[0]*right[12])+(matrix[4]*right[13])+(matrix[8]*right[14])+(matrix[12]*right[15]);
tmpMatrix[13] = (matrix[1]*right[12])+(matrix[5]*right[13])+(matrix[9]*right[14])+(matrix[13]*right[15]);
tmpMatrix[14] = (matrix[2]*right[12])+(matrix[6]*right[13])+(matrix[10]*right[14])+(matrix[14]*right[15]);
tmpMatrix[15] = (matrix[3]*right[12])+(matrix[7]*right[13])+(matrix[11]*right[14])+(matrix[15]*right[15]);
memcpy (matrix, tmpMatrix, sizeof(float)*16);
}
float* Matrix::Get (void)
{
return matrix;
}
float MatrixGet (float *matrix, int index)
{
return matrix[index];
}
*/
float MatrixGetMultipliedIndex (int index, float *matrix, float *rightMatrix)
{
int iMod = index%4, iDiv = (index>>2)<<2;
return (matrix[iMod ]*rightMatrix[iDiv ])+(matrix[iMod+ 4]*rightMatrix[iDiv+1])+
(matrix[iMod+8]*rightMatrix[iDiv+2])+(matrix[iMod+12]*rightMatrix[iDiv+3]);
}
void MatrixSet (float *matrix, int x, int y, float value)
{
matrix [x+(y<<2)] = value;
}
/*
void Matrix::Set (int pos, float value)
{
matrix [pos] = value;
}
*/
void MatrixCopy (float *matrixDST, float *matrixSRC)
{
memcpy (matrixDST, matrixSRC, sizeof(float)*16);
}
void MatrixTranslate (float *matrix, float *ptr)
{
matrix[12] += (matrix[0]*ptr[0])+(matrix[4]*ptr[1])+(matrix[ 8]*ptr[2]);
matrix[13] += (matrix[1]*ptr[0])+(matrix[5]*ptr[1])+(matrix[ 9]*ptr[2]);
matrix[14] += (matrix[2]*ptr[0])+(matrix[6]*ptr[1])+(matrix[10]*ptr[2]);
matrix[15] += (matrix[3]*ptr[0])+(matrix[7]*ptr[1])+(matrix[11]*ptr[2]);
}
void MatrixScale (float *matrix, float *ptr)
{
matrix[0] *= ptr[0];
matrix[1] *= ptr[0];
matrix[2] *= ptr[0];
matrix[3] *= ptr[0];
matrix[4] *= ptr[1];
matrix[5] *= ptr[1];
matrix[6] *= ptr[1];
matrix[7] *= ptr[1];
matrix[8] *= ptr[2];
matrix[9] *= ptr[2];
matrix[10] *= ptr[2];
matrix[11] *= ptr[2];
}
/*
void Matrix::Set (float a11, float a21, float a31, float a41,
float a12, float a22, float a32, float a42,
float a13, float a23, float a33, float a43,
float a14, float a24, float a34, float a44)
{
}
*/
//-----------------------------------------
void MatrixStackInit (MatrixStack *stack)
{
stack->matrix = NULL;
stack->position = 0;
stack->size = 0;
}
void MatrixStackSetMaxSize (MatrixStack *stack, int size)
{
int i = 0;
stack->size = size;
if (stack->matrix == NULL)
{
stack->matrix = (float*) malloc (stack->size*16*sizeof(float));
}
else
{
free (stack->matrix);
stack->matrix = (float*) malloc (stack->size*16*sizeof(float));
}
for (i = 0; i < stack->size; i++)
{
MatrixInit (&stack->matrix[i*16]);
}
stack->size--;
}
void MatrixStackSetStackPosition (MatrixStack *stack, int pos)
{
stack->position += pos;
if (stack->position < 0)
stack->position = 0;
else if (stack->position > stack->size)
stack->position = stack->size;
}
void MatrixStackPushMatrix (MatrixStack *stack, float *ptr)
{
MatrixCopy (&stack->matrix[stack->position*16], ptr);
MatrixStackSetStackPosition (stack, 1);
}
float * MatrixStackPopMatrix (MatrixStack *stack, int size)
{
MatrixStackSetStackPosition(stack, -size);
return &stack->matrix[stack->position*16];
}
float * MatrixStackGetPos (MatrixStack *stack, int pos)
{
return &stack->matrix[pos*16];
}
float * MatrixStackGet (MatrixStack *stack)
{
return &stack->matrix[stack->position*16];
}
void MatrixStackLoadMatrix (MatrixStack *stack, int pos, float *ptr)
{
MatrixCopy (&stack->matrix[pos*16], ptr);
}

View File

@ -0,0 +1,51 @@
/*
Copyright (C) 2006-2007 shash
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MATRIX_H
#define MATRIX_H
typedef struct MatrixStack
{
float *matrix;
int position;
int size;
} MatrixStack;
void MatrixInit (float *matrix);
void MatrixMultVec3x3 (float *matrix, float *vecPtr);
void MatrixMultVec4x4 (float *matrix, float *vecPtr);
void MatrixIdentity (float *matrix);
void MatrixMultiply (float *matrix, float *rightMatrix);
float MatrixGetMultipliedIndex(int index, float *matrix, float *rightMatrix);
void MatrixSet (float *matrix, int x, int y, float value);
void MatrixCopy (float *matrixDST, float *matrixSRC);
void MatrixTranslate (float *matrix, float *ptr);
void MatrixScale (float *matrix, float *ptr);
void MatrixStackInit (MatrixStack *stack);
void MatrixStackSetMaxSize (MatrixStack *stack, int size);
void MatrixStackSetStackPosition (MatrixStack *stack, int pos);
void MatrixStackPushMatrix (MatrixStack *stack, float *ptr);
float* MatrixStackPopMatrix (MatrixStack *stack, int size);
float* MatrixStackGetPos (MatrixStack *stack, int pos);
float* MatrixStackGet (MatrixStack *stack);
void MatrixStackLoadMatrix (MatrixStack *stack, int pos, float *ptr);
#endif

View File

@ -0,0 +1,121 @@
/* Copyright (C) 2006 thoduv
Copyright (C) 2006-2007 Theo Berkau
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdlib.h>
#include "debug.h"
#include "types.h"
#include "mc.h"
#define FW_CMD_READ 0x3
#define FW_CMD_WRITEDISABLE 0x4
#define FW_CMD_READSTATUS 0x5
#define FW_CMD_WRITEENABLE 0x6
#define FW_CMD_PAGEWRITE 0xA
#define BM_CMD_AUTODETECT 0xFF
#define BM_CMD_WRITESTATUS 0x1
#define BM_CMD_WRITELOW 0x2
#define BM_CMD_READLOW 0x3
#define BM_CMD_WRITEDISABLE 0x4
#define BM_CMD_READSTATUS 0x5
#define BM_CMD_WRITEENABLE 0x6
#define BM_CMD_WRITEHIGH 0xA
#define BM_CMD_READHIGH 0xB
/* FLASH*/
#define COMM_PAGE_WRITE 0x0A
#define COMM_PAGE_ERASE 0xDB
#define COMM_SECTOR_ERASE 0xD8
#define COMM_CHIP_ERASE 0xC7
#define CARDFLASH_READ_BYTES_FAST 0x0B /* Not used*/
#define CARDFLASH_DEEP_POWDOWN 0xB9 /* Not used*/
#define CARDFLASH_WAKEUP 0xAB /* Not used*/
void mc_init(memory_chip_t *mc, int type)
{
mc->com = 0;
mc->addr = 0;
mc->addr_shift = 0;
mc->data = NULL;
mc->size = 0;
mc->write_enable = FALSE;
mc->writeable_buffer = FALSE;
mc->type = type;
mc->autodetectsize = 0;
switch(mc->type)
{
case MC_TYPE_EEPROM1:
mc->addr_size = 1;
break;
case MC_TYPE_EEPROM2:
case MC_TYPE_FRAM:
mc->addr_size = 2;
break;
case MC_TYPE_FLASH:
mc->addr_size = 3;
break;
default: break;
}
}
u8 *mc_alloc(memory_chip_t *mc, u32 size)
{
u8 *buffer;
buffer = malloc(size);
mc->data = buffer;
if(!buffer) { return NULL; }
mc->size = size;
mc->writeable_buffer = TRUE;
return buffer;
}
void mc_free(memory_chip_t *mc)
{
if(mc->data)
{
free(mc->data);
mc->data = 0;
}
mc_init(mc, 0);
}
void mc_realloc(memory_chip_t *mc, int type, u32 size)
{
mc_free(mc);
mc_init(mc, type);
mc_alloc(mc, size);
}
void mc_reset_com(memory_chip_t *mc)
{
}
u8 fw_transfer(memory_chip_t *mc, u8 data)
{
return 0;
}
u8 bm_transfer(memory_chip_t *mc, u8 data)
{
return 0;
}

View File

@ -0,0 +1,94 @@
/* Copyright (C) 2006 thoduv
Copyright (C) 2006 Theo Berkau
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __FW_H__
#define __FW_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include "types.h"
#define MC_TYPE_AUTODETECT 0x0
#define MC_TYPE_EEPROM1 0x1
#define MC_TYPE_EEPROM2 0x2
#define MC_TYPE_FLASH 0x3
#define MC_TYPE_FRAM 0x4
#define MC_SIZE_4KBITS 0x000200
#define MC_SIZE_64KBITS 0x002000
#define MC_SIZE_256KBITS 0x008000
#define MC_SIZE_512KBITS 0x010000
#define MC_SIZE_1MBITS 0x020000
#define MC_SIZE_2MBITS 0x040000
#define MC_SIZE_4MBITS 0x080000
#define MC_SIZE_8MBITS 0x100000
#define MC_SIZE_16MBITS 0x200000
#define MC_SIZE_64MBITS 0x800000
static int save_types[6][2] = {
{MC_TYPE_AUTODETECT,1},
{MC_TYPE_EEPROM1,MC_SIZE_4KBITS},
{MC_TYPE_EEPROM2,MC_SIZE_64KBITS},
{MC_TYPE_EEPROM2,MC_SIZE_512KBITS},
{MC_TYPE_FLASH,MC_SIZE_256KBITS},
{MC_TYPE_FRAM,MC_SIZE_2MBITS}
};
typedef struct
{
u8 com; /* persistent command actually handled */
u32 addr; /* current address for reading/writing */
u8 addr_shift; /* shift for address (since addresses are transfered by 3 bytes units) */
u8 addr_size; /* size of addr when writing/reading */
BOOL write_enable; /* is write enabled ? */
u8 *data; /* memory data */
u32 size; /* memory size */
BOOL writeable_buffer; /* is "data" writeable ? */
int type; /* type of Memory */
char *filename;
FILE *fp;
u8 autodetectbuf[32768];
int autodetectsize;
} memory_chip_t;
#define NDS_FW_SIZE_V1 (256 * 1024) /* size of fw memory on nds v1 */
#define NDS_FW_SIZE_V2 (512 * 1024) /* size of fw memory on nds v2 */
void mc_init(memory_chip_t *mc, int type); /* reset and init values for memory struct */
u8 *mc_alloc(memory_chip_t *mc, u32 size); /* alloc mc memory */
void mc_realloc(memory_chip_t *mc, int type, u32 size); /* realloc mc memory */
void mc_load_file(memory_chip_t *mc, const char* filename); /* load save file and setup fp */
int mc_load_duc(memory_chip_t *mc, const char* filename); /* load Action Replay DS save file */
void mc_free(memory_chip_t *mc); /* delete mc memory */
void mc_reset_com(memory_chip_t *mc); /* reset communication with mc */
u8 fw_transfer(memory_chip_t *mc, u8 data); /* transfer to, then receive data from firmware */
u8 bm_transfer(memory_chip_t *mc, u8 data); /* transfer to, then receive data from backup memory */
#ifdef __cplusplus
}
#endif
#endif /*__FW_H__*/

View File

@ -0,0 +1,141 @@
/* Copyright 2005-2006 Guillaume Duhamel
Copyright 2005 Theo Berkau
This file is part of Yabause.
Yabause is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Yabause is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Yabause; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MEM_H
#define MEM_H
#include <stdlib.h>
#include "types.h"
/* Type 1 Memory, faster for byte (8 bits) accesses */
static INLINE u8 T1ReadByte(u8 * mem, u32 addr)
{
return mem[addr];
}
static INLINE u16 T1ReadWord(u8 * mem, u32 addr)
{
#ifdef WORDS_BIGENDIAN
return (mem[addr + 1] << 8) | mem[addr];
#else
return *((u16 *) (mem + addr));
#endif
}
static INLINE u32 T1ReadLong(u8 * mem, u32 addr)
{
#ifdef WORDS_BIGENDIAN
return (mem[addr + 3] << 24 | mem[addr + 2] << 16 |
mem[addr + 1] << 8 | mem[addr]);
#else
return *((u32 *)mem + (addr>>2));
#endif
}
static INLINE u64 T1ReadQuad(u8 * mem, u32 addr)
{
#ifdef WORDS_BIGENDIAN
return (mem[addr + 7] << 56 | mem[addr + 6] << 48 |
mem[addr + 5] << 40 | mem[addr + 4] << 32 |
mem[addr + 3] << 24 | mem[addr + 2] << 16 |
mem[addr + 1] << 8 | mem[addr]);
#else
return *((u64 *) (mem + addr));
#endif
}
static INLINE void T1WriteByte(u8 * mem, u32 addr, u8 val)
{
mem[addr] = val;
}
static INLINE void T1WriteWord(u8 * mem, u32 addr, u16 val)
{
#ifdef WORDS_BIGENDIAN
mem[addr + 1] = val >> 8;
mem[addr] = val & 0xFF;
#else
*((u16 *) (mem + addr)) = val;
#endif
}
static INLINE void T1WriteLong(u8 * mem, u32 addr, u32 val)
{
#ifdef WORDS_BIGENDIAN
mem[addr + 3] = val >> 24;
mem[addr + 2] = (val >> 16) & 0xFF;
mem[addr + 1] = (val >> 8) & 0xFF;
mem[addr] = val & 0xFF;
#else
*((u32 *) (mem + addr)) = val;
#endif
}
/* Type 2 Memory, faster for word (16 bits) accesses */
static INLINE u8 T2ReadByte(u8 * mem, u32 addr)
{
#ifdef WORDS_BIGENDIAN
return mem[addr ^ 1];
#else
return mem[addr];
#endif
}
static INLINE u16 T2ReadWord(u8 * mem, u32 addr)
{
return *((u16 *) (mem + addr));
}
static INLINE u32 T2ReadLong(u8 * mem, u32 addr)
{
#ifdef WORDS_BIGENDIAN
return *((u16 *) (mem + addr + 2)) << 16 | *((u16 *) (mem + addr));
#else
return *((u32 *) (mem + addr));
#endif
}
static INLINE void T2WriteByte(u8 * mem, u32 addr, u8 val)
{
#ifdef WORDS_BIGENDIAN
mem[addr ^ 1] = val;
#else
mem[addr] = val;
#endif
}
static INLINE void T2WriteWord(u8 * mem, u32 addr, u16 val)
{
*((u16 *) (mem + addr)) = val;
}
static INLINE void T2WriteLong(u8 * mem, u32 addr, u32 val)
{
#ifdef WORDS_BIGENDIAN
*((u16 *) (mem + addr + 2)) = val >> 16;
*((u16 *) (mem + addr)) = val & 0xFFFF;
#else
*((u32 *) (mem + addr)) = val;
#endif
}
#endif

View File

@ -0,0 +1,333 @@
/* Copyright (C) 2006 Theo Berkau
Ideas borrowed from Stephane Dallongeville's SCSP core
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef REGISTERS_H
#define REGISTERS_H
#define REG_REGION_MASK 0x0FFFEF80
#define REG_BASE_DISPx 0x04000000
#define REG_BASE_DISPA 0x04000000
#define REG_BASE_DISPB 0x04001000
#define REG_BASE_DMA 0x04000080
#define REG_BASE_SIORTCTIMERS 0x04000100
#define REG_BASE_ROMIPC 0x04000180
#define REG_BASE_MEMIRQ 0x04000200
#define REG_BASE_MATH 0x04000280
#define REG_BASE_OTHER 0x04000300
#define REG_BASE_RCVPORTS 0x04100000
// Display Engine A
#define REG_DISPA_DISPCNT 0x04000000
#define REG_DISPA_VCOUNT 0x04000006
#define REG_DISPA_BG0CNT 0x04000008
#define REG_DISPA_BG1CNT 0x0400000A
#define REG_DISPA_BG2CNT 0x0400000C
#define REG_DISPA_BG3CNT 0x0400000E
#define REG_DISPA_BG0HOFS 0x04000010
#define REG_DISPA_BG0VOFS 0x04000012
#define REG_DISPA_BG1HOFS 0x04000014
#define REG_DISPA_BG1VOFS 0x04000016
#define REG_DISPA_BG2HOFS 0x04000018
#define REG_DISPA_BG2VOFS 0x0400001A
#define REG_DISPA_BG3HOFS 0x0400001C
#define REG_DISPA_BG3VOFS 0x0400001E
#define REG_DISPA_BG2PA 0x04000020
#define REG_DISPA_BG2PB 0x04000022
#define REG_DISPA_BG2PC 0x04000024
#define REG_DISPA_BG2PD 0x04000026
#define REG_DISPA_BG2XL 0x04000028
#define REG_DISPA_BG2XH 0x0400002A
#define REG_DISPA_BG2YL 0x0400002C
#define REG_DISPA_BG2YH 0x0400002E
#define REG_DISPA_BG3PA 0x04000030
#define REG_DISPA_BG3PB 0x04000032
#define REG_DISPA_BG3PC 0x04000034
#define REG_DISPA_BG3PD 0x04000036
#define REG_DISPA_BG3XL 0x04000038
#define REG_DISPA_BG3XH 0x0400003A
#define REG_DISPA_BG3YL 0x0400003C
#define REG_DISPA_BG3YH 0x0400003E
#define REG_DISPA_WIN0H 0x04000040
#define REG_DISPA_WIN1H 0x04000042
#define REG_DISPA_WIN0V 0x04000044
#define REG_DISPA_WIN1V 0x04000046
#define REG_DISPA_WININ 0x04000048
#define REG_DISPA_WINOUT 0x0400004A
#define REG_DISPA_MOSAIC 0x0400004C
#define REG_DISPA_BLDCNT 0x04000050
#define REG_DISPA_BLDALPHA 0x04000052
#define REG_DISPA_BLDY 0x04000054
#define REG_DISPA_MASTERBRIGHT 0x0400006C
// DMA
#define REG_DMA0SAD 0x040000B0
#define REG_DMA0DAD 0x040000B4
#define REG_DMA0CNTL 0x040000B8
#define REG_DMA0CNTH 0x040000BA
#define REG_DMA1SAD 0x040000BC
#define REG_DMA1DAD 0x040000C0
#define REG_DMA1CNTL 0x040000C4
#define REG_DMA1CNTH 0x040000C6
#define REG_DMA2SAD 0x040000C8
#define REG_DMA2DAD 0x040000CC
#define REG_DMA2CNTL 0x040000D0
#define REG_DMA2CNTH 0x040000D2
#define REG_DMA3SAD 0x040000D4
#define REG_DMA3DAD 0x040000D8
#define REG_DMA3CNTL 0x040000DC
#define REG_DMA3CNTH 0x040000DE
#define REG_DMA0FILL 0x040000E0
#define REG_DMA1FILL 0x040000E4
#define REG_DMA2FILL 0x040000E8
#define REG_DMA3FILL 0x040000EC
// Timers
#define REG_TM0CNTL 0x04000100
#define REG_TM0CNTH 0x04000102
#define REG_TM1CNTL 0x04000104
#define REG_TM1CNTH 0x04000106
#define REG_TM2CNTL 0x04000108
#define REG_TM2CNTH 0x0400010A
#define REG_TM3CNTL 0x0400010C
#define REG_TM3CNTH 0x0400010E
// SIO/Keypad Input/RTC
#define REG_SIODATA32 0x04000120
#define REG_SIOCNT 0x04000128
#define REG_KEYINPUT 0x04000130
#define REG_KEYCNT 0x04000132
#define REG_RCNT 0x04000134
#define REG_EXTKEYIN 0x04000136
#define REG_RTC 0x04000138
// IPC
#define REG_IPCSYNC 0x04000180
#define REG_IPCFIFOCNT 0x04000184
#define REG_IPCFIFOSEND 0x04000188
// ROM
#define REG_AUXSPICNT 0x040001A0
#define REG_AUXSPIDATA 0x040001A2
#define REG_GCROMCTRL 0x040001A4
#define REG_GCCMDOUT 0x040001A8
#define REG_ENCSEED0L 0x040001B0
#define REG_ENCSEED1L 0x040001B4
#define REG_ENCSEED0H 0x040001B8
#define REG_ENCSEED1H 0x040001BC
#define REG_SPICNT 0x040001C0
#define REG_SPIDATA 0x040001C2
// Memory/IRQ
#define REG_EXMEMCNT 0x04000204
#define REG_WIFIWAITCNT 0x04000206
#define REG_IME 0x04000208
#define REG_IE 0x04000210
#define REG_IF 0x04000214
#define REG_VRAMCNTA 0x04000240
#define REG_VRAMSTAT 0x04000240
#define REG_VRAMCNTB 0x04000241
#define REG_WRAMSTAT 0x04000241
#define REG_VRAMCNTC 0x04000242
#define REG_VRAMCNTD 0x04000243
#define REG_VRAMCNTE 0x04000244
#define REG_VRAMCNTF 0x04000245
#define REG_VRAMCNTG 0x04000246
#define REG_WRAMCNT 0x04000247
#define REG_VRAMCNTH 0x04000248
#define REG_VRAMCNTI 0x04000249
// Math
#define REG_DIVCNT 0x04000280
#define REG_DIVNUMER 0x04000290
#define REG_DIVDENOM 0x04000298
#define REG_DIVRESULT 0x040002A0
#define REG_DIVREMRESULT 0x040002A8
#define REG_SQRTCNT 0x040002B0
#define REG_SQRTRESULT 0x040002B4
#define REG_SQRTPARAM 0x040002B8
// Other
#define REG_POSTFLG 0x04000300
#define REG_HALTCNT 0x04000301
#define REG_POWCNT1 0x04000304
#define REG_POWCNT2 0x04000304
#define REG_BIOSPROT 0x04000308
#define REG_DISPB_DISPCNT 0x04001000
#define REG_DISPB_BG0CNT 0x04001008
#define REG_DISPB_BG1CNT 0x0400100A
#define REG_DISPB_BG2CNT 0x0400100C
#define REG_DISPB_BG3CNT 0x0400100E
#define REG_DISPB_BG0HOFS 0x04001010
#define REG_DISPB_BG0VOFS 0x04001012
#define REG_DISPB_BG1HOFS 0x04001014
#define REG_DISPB_BG1VOFS 0x04001016
#define REG_DISPB_BG2HOFS 0x04001018
#define REG_DISPB_BG2VOFS 0x0400101A
#define REG_DISPB_BG3HOFS 0x0400101C
#define REG_DISPB_BG3VOFS 0x0400101E
#define REG_DISPB_BG2PA 0x04001020
#define REG_DISPB_BG2PB 0x04001022
#define REG_DISPB_BG2PC 0x04001024
#define REG_DISPB_BG2PD 0x04001026
#define REG_DISPB_BG2XL 0x04001028
#define REG_DISPB_BG2XH 0x0400102A
#define REG_DISPB_BG2YL 0x0400102C
#define REG_DISPB_BG2YH 0x0400102E
#define REG_DISPB_BG3PA 0x04001030
#define REG_DISPB_BG3PB 0x04001032
#define REG_DISPB_BG3PC 0x04001034
#define REG_DISPB_BG3PD 0x04001036
#define REG_DISPB_BG3XL 0x04001038
#define REG_DISPB_BG3XH 0x0400103A
#define REG_DISPB_BG3YL 0x0400103C
#define REG_DISPB_BG3YH 0x0400103E
#define REG_DISPB_WIN0H 0x04001040
#define REG_DISPB_WIN1H 0x04001042
#define REG_DISPB_WIN0V 0x04001044
#define REG_DISPB_WIN1V 0x04001046
#define REG_DISPB_WININ 0x04001048
#define REG_DISPB_WINOUT 0x0400104A
#define REG_DISPB_MOSAIC 0x0400104C
#define REG_DISPB_BLDCNT 0x04001050
#define REG_DISPB_BLDALPHA 0x04001052
#define REG_DISPB_BLDY 0x04001054
#define REG_DISPB_MASTERBRIGHT 0x0400106C
// Receive ports
#define REG_IPCFIFORECV 0x04100000
#define REG_GCDATAIN 0x04100010
#define REG_DISPB 0x00001000
// core A and B specific
#define REG_DISPx_DISPCNT 0x04000000
#define REG_DISPx_VCOUNT 0x04000006
#define REG_DISPx_BG0CNT 0x04000008
#define REG_DISPx_BG1CNT 0x0400000A
#define REG_DISPx_BG2CNT 0x0400000C
#define REG_DISPx_BG3CNT 0x0400000E
#define REG_DISPx_BG0HOFS 0x04000010
#define REG_DISPx_BG0VOFS 0x04000012
#define REG_DISPx_BG1HOFS 0x04000014
#define REG_DISPx_BG1VOFS 0x04000016
#define REG_DISPx_BG2HOFS 0x04000018
#define REG_DISPx_BG2VOFS 0x0400001A
#define REG_DISPx_BG3HOFS 0x0400001C
#define REG_DISPx_BG3VOFS 0x0400001E
#define REG_DISPx_BG2PA 0x04000020
#define REG_DISPx_BG2PB 0x04000022
#define REG_DISPx_BG2PC 0x04000024
#define REG_DISPx_BG2PD 0x04000026
#define REG_DISPx_BG2XL 0x04000028
#define REG_DISPx_BG2XH 0x0400002A
#define REG_DISPx_BG2YL 0x0400002C
#define REG_DISPx_BG2YH 0x0400002E
#define REG_DISPx_BG3PA 0x04000030
#define REG_DISPx_BG3PB 0x04000032
#define REG_DISPx_BG3PC 0x04000034
#define REG_DISPx_BG3PD 0x04000036
#define REG_DISPx_BG3XL 0x04000038
#define REG_DISPx_BG3XH 0x0400003A
#define REG_DISPx_BG3YL 0x0400003C
#define REG_DISPx_BG3YH 0x0400003E
#define REG_DISPx_WIN0H 0x04000040
#define REG_DISPx_WIN1H 0x04000042
#define REG_DISPx_WIN0V 0x04000044
#define REG_DISPx_WIN1V 0x04000046
#define REG_DISPx_WININ 0x04000048
#define REG_DISPx_WINOUT 0x0400004A
#define REG_DISPx_MOSAIC 0x0400004C
#define REG_DISPx_BLDCNT 0x04000050
#define REG_DISPx_BLDALPHA 0x04000052
#define REG_DISPx_BLDY 0x04000054
#define REG_DISPx_MASTERBRIGHT 0x0400006C
// core A specific
#define REG_DISPA_DISPSTAT 0x04000004
#define REG_DISPA_DISP3DCNT 0x04000060
#define REG_DISPA_DISPCAPCNT 0x04000064
#define REG_DISPA_DISPMMEMFIFO 0x04000068
#define eng_3D_RDLINES_COUNT 0x04000320
#define eng_3D_EDGE_COLOR 0x04000330
#define eng_3D_ALPHA_TEST_REF 0x04000340
#define eng_3D_CLEAR_COLOR 0x04000350
#define eng_3D_CLEAR_DEPTH 0x04000354
#define eng_3D_CLRIMAGE_OFFSET 0x04000356
#define eng_3D_FOG_COLOR 0x04000358
#define eng_3D_FOG_OFFSET 0x0400035C
#define eng_3D_FOG_TABLE 0x04000360
#define eng_3D_TOON_TABLE 0x04000380
#define eng_3D_GXFIFO 0x04000400
// 3d commands
#define cmd_3D_MTX_MODE 0x04000440
#define cmd_3D_MTX_PUSH 0x04000444
#define cmd_3D_MTX_POP 0x04000448
#define cmd_3D_MTX_STORE 0x0400044C
#define cmd_3D_MTX_RESTORE 0x04000450
#define cmd_3D_MTX_IDENTITY 0x04000454
#define cmd_3D_MTX_LOAD_4x4 0x04000458
#define cmd_3D_MTX_LOAD_4x3 0x0400045C
#define cmd_3D_MTX_MULT_4x4 0x04000460
#define cmd_3D_MTX_MULT_4x3 0x04000464
#define cmd_3D_MTX_MULT_3x3 0x04000468
#define cmd_3D_MTX_SCALE 0x0400046C
#define cmd_3D_MTX_TRANS 0x04000470
#define cmd_3D_COLOR 0x04000480
#define cmd_3D_NORMA 0x04000484
#define cmd_3D_TEXCOORD 0x04000488
#define cmd_3D_VTX_16 0x0400048C
#define cmd_3D_VTX_10 0x04000490
#define cmd_3D_VTX_XY 0x04000494
#define cmd_3D_VTX_XZ 0x04000498
#define cmd_3D_VTX_YZ 0x0400049C
#define cmd_3D_VTX_DIFF 0x040004A0
#define cmd_3D_POLYGON_ATTR 0x040004A4
#define cmd_3D_TEXIMAGE_PARAM 0x040004A8
#define cmd_3D_PLTT_BASE 0x040004AC
#define cmd_3D_DIF_AMB 0x040004C0
#define cmd_3D_SPE_EMI 0x040004C4
#define cmd_3D_LIGHT_VECTOR 0x040004C8
#define cmd_3D_LIGHT_COLOR 0x040004CC
#define cmd_3D_SHININESS 0x040004D0
#define cmd_3D_BEGIN_VTXS 0x04000500
#define cmd_3D_END_VTXS 0x04000504
#define cmd_3D_SWAP_BUFFERS 0x04000540
#define cmd_3D_VIEWPORT 0x04000580
#define cmd_3D_BOX_TEST 0x040005C0
#define cmd_3D_POS_TEST 0x040005C4
#define cmd_3D_VEC_TEST 0x040005C8
#define eng_3D_GXSTAT 0x04000600
#define eng_3D_RAM_COUNT 0x04000604
#define eng_3D_DISP_1DOT_DEPTH 0x04000610
#define eng_3D_POS_RESULT 0x04000620
#define eng_3D_VEC_RESULT 0x04000630
#define eng_3D_CLIPMTX_RESULT 0x04000640
#define eng_3D_VECMTX_RESULT 0x04000680
#endif

View File

@ -0,0 +1,36 @@
#ifndef _SPU_EXPORTS_H
#define _SPU_EXPORTS_H
#ifndef _SPU_CPP_
#include "types.h"
typedef struct NDS_state NDS_state;
void SPU_WriteLong(NDS_state *, u32 addr, u32 val);
void SPU_WriteByte(NDS_state *, u32 addr, u8 val);
void SPU_WriteWord(NDS_state *, u32 addr, u16 val);
void SPU_EmulateSamples(NDS_state *, int numsamples);
int SPU_ChangeSoundCore(NDS_state *, int coreid, int buffersize);
void SPU_Reset(NDS_state *);
int SPU_Init(NDS_state *, int, int);
void SPU_DeInit(NDS_state *);
void SPU_Pause(NDS_state *state, int pause);
void SPU_SetVolume(NDS_state *state, int volume);
typedef struct SoundInterface_struct
{
int id;
const char *Name;
int (*Init)(NDS_state *, int buffersize);
void (*DeInit)(NDS_state *);
void (*UpdateAudio)(NDS_state *, s16 *buffer, u32 num_samples);
u32 (*GetAudioSpace)(NDS_state *);
void (*MuteAudio)(NDS_state *);
void (*UnMuteAudio)(NDS_state *);
void (*SetVolume)(NDS_state *, int volume);
} SoundInterface_struct;
#endif _SPU_CPP_
#endif //_SPU_EXPORTS_H

View File

@ -0,0 +1,766 @@
//
// state.c
// vio2sf
//
// Created by Christopher Snowhill on 10/13/13.
// Copyright (c) 2013 Christopher Snowhill. All rights reserved.
//
#include <assert.h>
#include "NDSSystem.h"
#include "MMU.h"
#include "GPU.h"
#include "armcpu.h"
#include "cp15.h"
#include "spu_exports.h"
#include "state.h"
#define ROM_MASK 3
#define SNDCORE_DUMMY 0
#define SNDCORE_STATE 0
#ifdef GDB_STUB
static struct armcpu_ctrl_iface *arm9_ctrl_iface = 0;
static struct armcpu_ctrl_iface *arm7_ctrl_iface = 0;
#endif
int state_init(struct NDS_state *state)
{
int i;
memset(state, 0, sizeof(NDS_state));
state->nds = (NDSSystem *) calloc(1, sizeof(NDSSystem));
if (!state->nds)
return -1;
state->NDS_ARM7 = (armcpu_t *) calloc(1, sizeof(armcpu_t));
if (!state->NDS_ARM7)
return -1;
state->NDS_ARM9 = (armcpu_t *) calloc(1, sizeof(armcpu_t));
if (!state->NDS_ARM9)
return -1;
state->MMU = (MMU_struct *) calloc(1, sizeof(MMU_struct));
if (!state->MMU)
return -1;
state->ARM9Mem = (ARM9_struct *) calloc(1, sizeof(ARM9_struct));
if (!state->ARM9Mem)
return -1;
state->MainScreen = (NDS_Screen *) calloc(1, sizeof(NDS_Screen));
if (!state->MainScreen)
return -1;
state->SubScreen = (NDS_Screen *) calloc(1, sizeof(NDS_Screen));
if (!state->SubScreen)
return -1;
for (i = 0; i < 0x10; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = state->ARM9Mem->ARM9_ITCM;
state->MMU_ARM9_MEM_MASK[i] = 0x00007FFF;
}
for (; i < 0x20; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = state->ARM9Mem->ARM9_WRAM;
state->MMU_ARM9_MEM_MASK[i] = 0x00FFFFFF;
}
for (; i < 0x30; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = state->ARM9Mem->MAIN_MEM;
state->MMU_ARM9_MEM_MASK[i] = 0x003FFFFF;
}
for (; i < 0x40; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = state->MMU->SWIRAM;
state->MMU_ARM9_MEM_MASK[i] = 0x00007FFF;
}
for (; i < 0x50; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = state->ARM9Mem->ARM9_REG;
state->MMU_ARM9_MEM_MASK[i] = 0x00FFFFFF;
}
for (; i < 0x60; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = state->ARM9Mem->ARM9_VMEM;
state->MMU_ARM9_MEM_MASK[i] = 0x000007FF;
}
for (; i < 0x62; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = state->ARM9Mem->ARM9_ABG;
state->MMU_ARM9_MEM_MASK[i] = 0x0007FFFF;
}
for (; i < 0x64; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = state->ARM9Mem->ARM9_BBG;
state->MMU_ARM9_MEM_MASK[i] = 0x0001FFFF;
}
for (; i < 0x66; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = state->ARM9Mem->ARM9_AOBJ;
state->MMU_ARM9_MEM_MASK[i] = 0x0003FFFF;
}
for (; i < 0x68; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = state->ARM9Mem->ARM9_BOBJ;
state->MMU_ARM9_MEM_MASK[i] = 0x0001FFFF;
}
for (; i < 0x70; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = state->ARM9Mem->ARM9_OAM;
state->MMU_ARM9_MEM_MASK[i] = 0x000FFFFF;
}
for (; i < 0x80; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = state->ARM9Mem->ARM9_OAM;
state->MMU_ARM9_MEM_MASK[i] = 0x000007FF;
}
for (; i < 0xA0; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = NULL;
state->MMU_ARM9_MEM_MASK[i] = ROM_MASK;
}
for (; i < 0xB0; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = state->MMU->CART_RAM;
state->MMU_ARM9_MEM_MASK[i] = 0x0000FFFF;
}
for (; i < 0xF0; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = state->MMU->UNUSED_RAM;
state->MMU_ARM9_MEM_MASK[i] = 0x00000003;
}
for (; i < 0x100; ++i)
{
state->MMU_ARM9_MEM_MAP[i] = state->ARM9Mem->ARM9_BIOS;
state->MMU_ARM9_MEM_MASK[i] = 0x00007FFF;
}
for (i = 0; i < 0x10; ++i)
{
state->MMU_ARM7_MEM_MAP[i] = state->MMU->ARM7_BIOS;
state->MMU_ARM7_MEM_MASK[i] = 0x00003FFF;
}
for (; i < 0x20; ++i)
{
state->MMU_ARM7_MEM_MAP[i] = state->MMU->UNUSED_RAM;
state->MMU_ARM7_MEM_MASK[i] = 0x00000003;
}
for (; i < 0x30; ++i)
{
state->MMU_ARM7_MEM_MAP[i] = state->ARM9Mem->MAIN_MEM;
state->MMU_ARM7_MEM_MASK[i] = 0x003FFFFF;
}
for (; i < 0x38; ++i)
{
state->MMU_ARM7_MEM_MAP[i] = state->MMU->SWIRAM;
state->MMU_ARM7_MEM_MASK[i] = 0x00007FFF;
}
for (; i < 0x40; ++i)
{
state->MMU_ARM7_MEM_MAP[i] = state->MMU->ARM7_ERAM;
state->MMU_ARM7_MEM_MASK[i] = 0x0000FFFF;
}
for (; i < 0x48; ++i)
{
state->MMU_ARM7_MEM_MAP[i] = state->MMU->ARM7_REG;
state->MMU_ARM7_MEM_MASK[i] = 0x00FFFFFF;
}
for (; i < 0x50; ++i)
{
state->MMU_ARM7_MEM_MAP[i] = state->MMU->ARM7_WIRAM;
state->MMU_ARM7_MEM_MASK[i] = 0x0000FFFF;
}
for (; i < 0x60; ++i)
{
state->MMU_ARM7_MEM_MAP[i] = state->MMU->UNUSED_RAM;
state->MMU_ARM7_MEM_MASK[i] = 0x00000003;
}
for (; i < 0x70; ++i)
{
state->MMU_ARM7_MEM_MAP[i] = state->ARM9Mem->ARM9_ABG;
state->MMU_ARM7_MEM_MASK[i] = 0x0003FFFF;
}
for (; i < 0x80; ++i)
{
state->MMU_ARM7_MEM_MAP[i] = state->MMU->UNUSED_RAM;
state->MMU_ARM7_MEM_MASK[i] = 0x00000003;
}
for (; i < 0xA0; ++i)
{
state->MMU_ARM7_MEM_MAP[i] = NULL;
state->MMU_ARM7_MEM_MASK[i] = ROM_MASK;
}
for (; i < 0xB0; ++i)
{
state->MMU_ARM7_MEM_MAP[i] = state->MMU->CART_RAM;
state->MMU_ARM7_MEM_MASK[i] = 0x0000FFFF;
}
for (; i < 0x100; ++i)
{
state->MMU_ARM7_MEM_MAP[i] = state->MMU->UNUSED_RAM;
state->MMU_ARM7_MEM_MASK[i] = 0x00000003;
}
state->partie = 1;
state->SPU_currentCoreNum = SNDCORE_DUMMY;
#ifdef GDB_STUB
if (NDS_Init(state, &arm9_base_memory_iface, &arm9_ctrl_iface, &arm7_base_memory_iface, &arm7_ctrl_iface))
#else
if (NDS_Init(state))
#endif
return -1;
SPU_ChangeSoundCore(state, 0, 44100);
state->execute = FALSE;
MMU_unsetRom(state);
state->cycles = 0;
return 0;
}
void state_deinit(struct NDS_state *state)
{
MMU_unsetRom(state);
NDS_DeInit(state);
if (state->nds) free(state->nds);
state->nds = NULL;
if (state->NDS_ARM7) free(state->NDS_ARM7);
state->NDS_ARM7 = NULL;
if (state->NDS_ARM9) free(state->NDS_ARM9);
state->NDS_ARM9 = NULL;
if (state->MMU) free(state->MMU);
state->MMU = NULL;
if (state->ARM9Mem) free(state->ARM9Mem);
state->ARM9Mem = NULL;
if (state->MainScreen) free(state->MainScreen);
state->MainScreen = NULL;
if (state->SubScreen) free(state->SubScreen);
state->SubScreen = NULL;
}
void state_setrom(struct NDS_state *state, const u8 * rom, u32 rom_size)
{
assert(!(rom_size & (rom_size - 1)));
NDS_SetROM(state, rom, rom_size - 1);
NDS_Reset(state);
state->execute = TRUE;
}
static void load_setstate(struct NDS_state *state, const u8 *ss, u32 ss_size);
void state_loadstate(struct NDS_state *state, const u8 *ss, u32 ss_size)
{
if (ss && ss_size)
{
armcp15_t *c9 = (armcp15_t *)state->NDS_ARM9->coproc[15];
int proc;
if (state->initial_frames == -1)
{
/* set initial ARM9 coprocessor state */
armcp15_moveARM2CP(c9, 0x00000000, 0x01, 0x00, 0, 0);
armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x05, 0, 0);
armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x06, 0, 0);
armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x0a, 0, 4);
armcp15_moveARM2CP(c9, 0x04000033, 0x06, 0x00, 0, 4);
armcp15_moveARM2CP(c9, 0x0200002d, 0x06, 0x01, 0, 0);
armcp15_moveARM2CP(c9, 0x027e0021, 0x06, 0x02, 0, 0);
armcp15_moveARM2CP(c9, 0x08000035, 0x06, 0x03, 0, 0);
armcp15_moveARM2CP(c9, 0x027e001b, 0x06, 0x04, 0, 0);
armcp15_moveARM2CP(c9, 0x0100002f, 0x06, 0x05, 0, 0);
armcp15_moveARM2CP(c9, 0xffff001d, 0x06, 0x06, 0, 0);
armcp15_moveARM2CP(c9, 0x027ff017, 0x06, 0x07, 0, 0);
armcp15_moveARM2CP(c9, 0x00000020, 0x09, 0x01, 0, 1);
armcp15_moveARM2CP(c9, 0x027e000a, 0x09, 0x01, 0, 0);
armcp15_moveARM2CP(c9, 0x00000042, 0x02, 0x00, 0, 1);
armcp15_moveARM2CP(c9, 0x00000042, 0x02, 0x00, 0, 0);
armcp15_moveARM2CP(c9, 0x00000002, 0x03, 0x00, 0, 0);
armcp15_moveARM2CP(c9, 0x05100011, 0x05, 0x00, 0, 3);
armcp15_moveARM2CP(c9, 0x15111011, 0x05, 0x00, 0, 2);
armcp15_moveARM2CP(c9, 0x07dd1e10, 0x01, 0x00, 0, 0);
armcp15_moveARM2CP(c9, 0x0005707d, 0x01, 0x00, 0, 0);
armcp15_moveARM2CP(c9, 0x00000000, 0x07, 0x0a, 0, 4);
armcp15_moveARM2CP(c9, 0x02004000, 0x07, 0x05, 0, 1);
armcp15_moveARM2CP(c9, 0x02004000, 0x07, 0x0e, 0, 1);
/* set initial timer state */
MMU_write16(state, 0, REG_TM0CNTL, 0x0000);
MMU_write16(state, 0, REG_TM0CNTH, 0x00C1);
MMU_write16(state, 1, REG_TM0CNTL, 0x0000);
MMU_write16(state, 1, REG_TM0CNTH, 0x00C1);
MMU_write16(state, 1, REG_TM1CNTL, 0xf7e7);
MMU_write16(state, 1, REG_TM1CNTH, 0x00C1);
/* set initial interrupt state */
state->MMU->reg_IME[0] = 0x00000001;
state->MMU->reg_IE[0] = 0x00042001;
state->MMU->reg_IME[1] = 0x00000001;
state->MMU->reg_IE[1] = 0x0104009d;
}
else if (state->initial_frames > 0)
{
/* execute boot code */
int i;
for (i=0; i<state->initial_frames; i++)
NDS_exec_frame(state, 0, 0);
i = 0;
}
/* load state */
load_setstate(state, ss, ss_size);
if (state->initial_frames == -1)
{
armcp15_moveARM2CP(c9, (state->NDS_ARM9->R13_irq & 0x0fff0000) | 0x0a, 0x09, 0x01, 0, 0);
}
/* restore timer state */
for (proc = 0; proc < 2; proc++)
{
MMU_write16(state, proc, REG_TM0CNTH, T1ReadWord(state->MMU->MMU_MEM[proc][0x40], REG_TM0CNTH & 0xFFF));
MMU_write16(state, proc, REG_TM1CNTH, T1ReadWord(state->MMU->MMU_MEM[proc][0x40], REG_TM1CNTH & 0xFFF));
MMU_write16(state, proc, REG_TM2CNTH, T1ReadWord(state->MMU->MMU_MEM[proc][0x40], REG_TM2CNTH & 0xFFF));
MMU_write16(state, proc, REG_TM3CNTH, T1ReadWord(state->MMU->MMU_MEM[proc][0x40], REG_TM3CNTH & 0xFFF));
}
}
else if (state->initial_frames > 0)
{
/* skip 1 sec */
int i;
for (i=0; i<state->initial_frames; i++)
NDS_exec_frame(state, 0, 0);
}
state->execute = TRUE;
}
void state_render(struct NDS_state *state, s16 * buffer, int sample_count)
{
s16 * ptr = buffer;
while (sample_count)
{
unsigned remain_samples = state->sample_pointer;
if (remain_samples > 0)
{
if (remain_samples > sample_count)
{
memcpy(ptr, state->sample_buffer, sample_count * sizeof(s16) * 2);
memmove(state->sample_buffer, state->sample_buffer + sample_count * 2, ( remain_samples - sample_count ) * sizeof(s16) * 2 );
state->sample_pointer -= sample_count;
ptr += sample_count * 2;
remain_samples -= sample_count; /**/
sample_count = 0; /**/
break;
}
else
{
memcpy(ptr, state->sample_buffer, remain_samples * sizeof(s16) * 2);
state->sample_pointer = 0;
ptr += remain_samples * 2;
sample_count -= remain_samples;
remain_samples = 0;
}
}
if (remain_samples == 0)
{
/*
#define HBASE_CYCLES (16756000*2)
#define HBASE_CYCLES (33512000*1)
#define HBASE_CYCLES (33509300.322234)
*/
#define HBASE_CYCLES (33509300.322234)
#define HLINE_CYCLES (6 * (99 + 256))
#define HSAMPLES ((u32)((44100.0 * HLINE_CYCLES) / HBASE_CYCLES))
#define VDIVISION 100
#define VLINES 263
#define VBASE_CYCLES (((double)HBASE_CYCLES) / VDIVISION)
#define VSAMPLES ((u32)((44100.0 * HLINE_CYCLES * VLINES) / HBASE_CYCLES))
int numsamples;
if (state->sync_type == 1)
{
/* vsync */
state->cycles += ((44100 / VDIVISION) * HLINE_CYCLES * VLINES);
if (state->cycles >= (u32)(VBASE_CYCLES * (VSAMPLES + 1)))
{
numsamples = (VSAMPLES + 1);
state->cycles -= (u32)(VBASE_CYCLES * (VSAMPLES + 1));
}
else
{
numsamples = (VSAMPLES + 0);
state->cycles -= (u32)(VBASE_CYCLES * (VSAMPLES + 0));
}
NDS_exec_frame(state, state->arm9_clockdown_level, state->arm7_clockdown_level);
}
else
{
/* hsync */
state->cycles += (44100 * HLINE_CYCLES);
if (state->cycles >= (u32)(HBASE_CYCLES * (HSAMPLES + 1)))
{
numsamples = (HSAMPLES + 1);
state->cycles -= (u32)(HBASE_CYCLES * (HSAMPLES + 1));
}
else
{
numsamples = (HSAMPLES + 0);
state->cycles -= (u32)(HBASE_CYCLES * (HSAMPLES + 0));
}
NDS_exec_hframe(state, state->arm9_clockdown_level, state->arm7_clockdown_level);
}
SPU_EmulateSamples(state, numsamples);
}
}
}
static int SNDStateInit(NDS_state *state, int buffersize)
{
state->sample_buffer = (s16 *) malloc(buffersize * sizeof(s16) * 2);
state->sample_pointer = 0;
state->sample_size = buffersize;
return state->sample_buffer == NULL ? -1 : 0;
}
static void SNDStateDeInit(NDS_state *state)
{
if ( state->sample_buffer ) free( state->sample_buffer );
state->sample_buffer = NULL;
}
static void SNDStateUpdateAudio(NDS_state *state, s16 *buffer, u32 num_samples)
{
memcpy( state->sample_buffer + state->sample_pointer * 2, buffer, num_samples * sizeof(s16) * 2);
state->sample_pointer += num_samples;
}
static u32 SNDStateGetAudioSpace(NDS_state *state)
{
return state->sample_size - state->sample_pointer;
}
static void SNDStateMuteAudio(NDS_state *state)
{
(void)state;
}
static void SNDStateUnMuteAudio(NDS_state *state)
{
(void)state;
}
static void SNDStateSetVolume(NDS_state *state, int volume)
{
(void)state;
(void)volume;
}
SoundInterface_struct SNDState = {
SNDCORE_STATE,
"State Sound Interface",
SNDStateInit,
SNDStateDeInit,
SNDStateUpdateAudio,
SNDStateGetAudioSpace,
SNDStateMuteAudio,
SNDStateUnMuteAudio,
SNDStateSetVolume
};
SoundInterface_struct *SNDCoreList[2] = {
&SNDState,
NULL
};
static u16 getwordle(const unsigned char *pData)
{
return pData[0] | (((u16)pData[1]) << 8);
}
static u32 getdwordle(const unsigned char *pData)
{
return pData[0] | (((u32)pData[1]) << 8) | (((u32)pData[2]) << 16) | (((u32)pData[3]) << 24);
}
static void load_getsta(Status_Reg *ptr, unsigned l, const u8 **ss, const u8 *sse)
{
unsigned s = l << 2;
unsigned i;
if ((*ss >= sse) || ((*ss + s) > sse))
return;
for (i = 0; i < l; i++)
{
u32 st = getdwordle(*ss + (i << 2));
ptr[i].bits.N = (st >> 31) & 1;
ptr[i].bits.Z = (st >> 30) & 1;
ptr[i].bits.C = (st >> 29) & 1;
ptr[i].bits.V = (st >> 28) & 1;
ptr[i].bits.Q = (st >> 27) & 1;
ptr[i].bits.RAZ = (st >> 8) & ((1 << 19) - 1);
ptr[i].bits.I = (st >> 7) & 1;
ptr[i].bits.F = (st >> 6) & 1;
ptr[i].bits.T = (st >> 5) & 1;
ptr[i].bits.mode = (st >> 0) & 0x1f;
}
*ss += s;
}
static void load_getbool(BOOL *ptr, unsigned l, const u8 **ss, const u8 *sse)
{
unsigned s = l << 2;
unsigned i;
if ((*ss >= sse) || ((*ss + s) > sse))
return;
for (i = 0; i < l; i++)
ptr[i] = (BOOL)getdwordle(*ss + (i << 2));
*ss += s;
}
#if defined(SIGNED_IS_NOT_2S_COMPLEMENT)
/* 2's complement */
#define u32tos32(v) ((s32)((((s64)(v)) ^ 0x80000000) - 0x80000000))
#else
/* 2's complement */
#define u32tos32(v) ((s32)v)
#endif
static void load_gets32(s32 *ptr, unsigned l, const u8 **ss, const u8 *sse)
{
unsigned s = l << 2;
unsigned i;
if ((*ss >= sse) || ((*ss + s) > sse))
return;
for (i = 0; i < l; i++)
ptr[i] = u32tos32(getdwordle(*ss + (i << 2)));
*ss += s;
}
static void load_getu32(u32 *ptr, unsigned l, const u8 **ss, const u8 *sse)
{
unsigned s = l << 2;
unsigned i;
if ((*ss >= sse) || ((*ss + s) > sse))
return;
for (i = 0; i < l; i++)
ptr[i] = getdwordle(*ss + (i << 2));
*ss += s;
}
static void load_getu16(u16 *ptr, unsigned l, const u8 **ss, const u8 *sse)
{
unsigned s = l << 1;
unsigned i;
if ((*ss >= sse) || ((*ss + s) > sse))
return;
for (i = 0; i < l; i++)
ptr[i] = getwordle(*ss + (i << 1));
*ss += s;
}
static void load_getu8(u8 *ptr, unsigned l, const u8 **ss, const u8 *sse)
{
unsigned s = l;
unsigned i;
if ((*ss >= sse) || ((*ss + s) > sse))
return;
for (i = 0; i < l; i++)
ptr[i] = *ss[i];
*ss += s;
}
void gdb_stub_fix(armcpu_t *armcpu)
{
/* armcpu->R[15] = armcpu->instruct_adr; */
armcpu->next_instruction = armcpu->instruct_adr;
if(armcpu->CPSR.bits.T == 0)
{
armcpu->instruction = MMU_read32_acl(armcpu->state, armcpu->proc_ID, armcpu->next_instruction,CP15_ACCESS_EXECUTE);
armcpu->instruct_adr = armcpu->next_instruction;
armcpu->next_instruction += 4;
armcpu->R[15] = armcpu->next_instruction + 4;
}
else
{
armcpu->instruction = MMU_read16_acl(armcpu->state, armcpu->proc_ID, armcpu->next_instruction,CP15_ACCESS_EXECUTE);
armcpu->instruct_adr = armcpu->next_instruction;
armcpu->next_instruction += 2;
armcpu->R[15] = armcpu->next_instruction + 2;
}
}
static void load_setstate(struct NDS_state *state, const u8 *ss, u32 ss_size)
{
const u8 *sse = ss + ss_size;
if (!ss || !ss_size)
return;
/* Skip over "Desmume Save File" crap */
ss += 0x17;
/* Read ARM7 cpu registers */
load_getu32(&state->NDS_ARM7->proc_ID, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->instruction, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->instruct_adr, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->next_instruction, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R, 16, &ss, sse);
load_getsta(&state->NDS_ARM7->CPSR, 1, &ss, sse);
load_getsta(&state->NDS_ARM7->SPSR, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R13_usr, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R14_usr, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R13_svc, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R14_svc, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R13_abt, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R14_abt, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R13_und, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R14_und, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R13_irq, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R14_irq, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R8_fiq, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R9_fiq, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R10_fiq, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R11_fiq, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R12_fiq, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R13_fiq, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->R14_fiq, 1, &ss, sse);
load_getsta(&state->NDS_ARM7->SPSR_svc, 1, &ss, sse);
load_getsta(&state->NDS_ARM7->SPSR_abt, 1, &ss, sse);
load_getsta(&state->NDS_ARM7->SPSR_und, 1, &ss, sse);
load_getsta(&state->NDS_ARM7->SPSR_irq, 1, &ss, sse);
load_getsta(&state->NDS_ARM7->SPSR_fiq, 1, &ss, sse);
load_getu32(&state->NDS_ARM7->intVector, 1, &ss, sse);
load_getu8(&state->NDS_ARM7->LDTBit, 1, &ss, sse);
load_getbool(&state->NDS_ARM7->waitIRQ, 1, &ss, sse);
load_getbool(&state->NDS_ARM7->wIRQ, 1, &ss, sse);
load_getbool(&state->NDS_ARM7->wirq, 1, &ss, sse);
/* Read ARM9 cpu registers */
load_getu32(&state->NDS_ARM9->proc_ID, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->instruction, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->instruct_adr, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->next_instruction, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R, 16, &ss, sse);
load_getsta(&state->NDS_ARM9->CPSR, 1, &ss, sse);
load_getsta(&state->NDS_ARM9->SPSR, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R13_usr, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R14_usr, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R13_svc, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R14_svc, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R13_abt, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R14_abt, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R13_und, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R14_und, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R13_irq, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R14_irq, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R8_fiq, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R9_fiq, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R10_fiq, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R11_fiq, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R12_fiq, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R13_fiq, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->R14_fiq, 1, &ss, sse);
load_getsta(&state->NDS_ARM9->SPSR_svc, 1, &ss, sse);
load_getsta(&state->NDS_ARM9->SPSR_abt, 1, &ss, sse);
load_getsta(&state->NDS_ARM9->SPSR_und, 1, &ss, sse);
load_getsta(&state->NDS_ARM9->SPSR_irq, 1, &ss, sse);
load_getsta(&state->NDS_ARM9->SPSR_fiq, 1, &ss, sse);
load_getu32(&state->NDS_ARM9->intVector, 1, &ss, sse);
load_getu8(&state->NDS_ARM9->LDTBit, 1, &ss, sse);
load_getbool(&state->NDS_ARM9->waitIRQ, 1, &ss, sse);
load_getbool(&state->NDS_ARM9->wIRQ, 1, &ss, sse);
load_getbool(&state->NDS_ARM9->wirq, 1, &ss, sse);
/* Read in other internal variables that are important */
load_gets32(&state->nds->ARM9Cycle, 1, &ss, sse);
load_gets32(&state->nds->ARM7Cycle, 1, &ss, sse);
load_gets32(&state->nds->cycles, 1, &ss, sse);
load_gets32(&state->nds->timerCycle[0], 4, &ss, sse);
load_gets32(&state->nds->timerCycle[1], 4, &ss, sse);
load_getbool(&state->nds->timerOver[0], 4, &ss, sse);
load_getbool(&state->nds->timerOver[1], 4, &ss, sse);
load_gets32(&state->nds->nextHBlank, 1, &ss, sse);
load_getu32(&state->nds->VCount, 1, &ss, sse);
load_getu32(&state->nds->old, 1, &ss, sse);
load_gets32(&state->nds->diff, 1, &ss, sse);
load_getbool(&state->nds->lignerendu, 1, &ss, sse);
load_getu16(&state->nds->touchX, 1, &ss, sse);
load_getu16(&state->nds->touchY, 1, &ss, sse);
/* Read in memory/registers specific to the ARM9 */
load_getu8 (state->ARM9Mem->ARM9_ITCM, 0x8000, &ss, sse);
load_getu8 (state->ARM9Mem->ARM9_DTCM, 0x4000, &ss, sse);
load_getu8 (state->ARM9Mem->ARM9_WRAM, 0x1000000, &ss, sse);
load_getu8 (state->ARM9Mem->MAIN_MEM, 0x400000, &ss, sse);
load_getu8 (state->ARM9Mem->ARM9_REG, 0x10000, &ss, sse);
load_getu8 (state->ARM9Mem->ARM9_VMEM, 0x800, &ss, sse);
load_getu8 (state->ARM9Mem->ARM9_OAM, 0x800, &ss, sse);
load_getu8 (state->ARM9Mem->ARM9_ABG, 0x80000, &ss, sse);
load_getu8 (state->ARM9Mem->ARM9_BBG, 0x20000, &ss, sse);
load_getu8 (state->ARM9Mem->ARM9_AOBJ, 0x40000, &ss, sse);
load_getu8 (state->ARM9Mem->ARM9_BOBJ, 0x20000, &ss, sse);
load_getu8 (state->ARM9Mem->ARM9_LCD, 0xA4000, &ss, sse);
/* Read in memory/registers specific to the ARM7 */
load_getu8 (state->MMU->ARM7_ERAM, 0x10000, &ss, sse);
load_getu8 (state->MMU->ARM7_REG, 0x10000, &ss, sse);
load_getu8 (state->MMU->ARM7_WIRAM, 0x10000, &ss, sse);
/* Read in shared memory */
load_getu8 (state->MMU->SWIRAM, 0x8000, &ss, sse);
#ifdef GDB_STUB
#else
gdb_stub_fix(state->NDS_ARM9);
gdb_stub_fix(state->NDS_ARM7);
#endif
}

View File

@ -0,0 +1,96 @@
//
// state.h
// vio2sf
//
// Created by Christopher Snowhill on 10/13/13.
// Copyright (c) 2013 Christopher Snowhill. All rights reserved.
//
#ifndef vio2sf_state_h
#define vio2sf_state_h
#include "types.h"
#include "spu_exports.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct SoundInterface_struct SoundInterface_struct;
extern SoundInterface_struct *SNDCoreList[2];
typedef struct NDS_state
{
// configuration
unsigned long dwInterpolation;
unsigned long dwChannelMute;
// state setup info, from tags
int initial_frames;
int sync_type;
int arm9_clockdown_level;
int arm7_clockdown_level;
u32 cycles;
struct NDSSystem * nds;
struct armcpu_t * NDS_ARM7;
struct armcpu_t * NDS_ARM9;
struct MMU_struct * MMU;
struct ARM9_struct * ARM9Mem;
struct NDS_Screen * MainScreen;
struct NDS_Screen * SubScreen;
u8 * MMU_ARM9_MEM_MAP[256];
u32 MMU_ARM9_MEM_MASK[256];
u8 * MMU_ARM7_MEM_MAP[256];
u32 MMU_ARM7_MEM_MASK[256];
BOOL execute;
u16 partie; /* = 1; */
u16 SPI_CNT; /* = 0;*/
u16 SPI_CMD; /* = 0;*/
u16 AUX_SPI_CNT; /* = 0;*/
u16 AUX_SPI_CMD; /* = 0;*/
u32 rom_mask; /* = 0;*/
u32 DMASrc[2][4]; /* = {{0, 0, 0, 0}, {0, 0, 0, 0}};*/
u32 DMADst[2][4]; /* = {{0, 0, 0, 0}, {0, 0, 0, 0}};*/
struct SPU_struct *SPU_core;
struct SPU_struct *SPU_user;
double samples;
int SPU_currentCoreNum; /* = SNDCORE_DUMMY;*/
int spu_core_samples;
long tot_samples;
SoundInterface_struct *SNDCore;
s16 *sample_buffer;
unsigned long sample_pointer;
unsigned long sample_size;
} NDS_state;
int state_init(NDS_state *state);
void state_deinit(NDS_state *state);
void state_setrom(NDS_state *state, const u8 * rom, u32 rom_size);
void state_loadstate(NDS_state *state, const u8 * ss, u32 ss_size);
void state_render(NDS_state *state, s16 * buffer, int sample_count);
#ifdef __cplusplus
};
#endif
#endif

View File

@ -0,0 +1,944 @@
/*
Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
Code added on 18/08/2006 by shash
- Missing missaligned addresses correction
(reference in http://nocash.emubase.de/gbatek.htm#cpumemoryalignments)
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "bios.h"
#include "debug.h"
#include "MMU.h"
#include "state.h"
#define REG_NUM(i, n) (((i)>>n)&0x7)
// Use this macros for reading/writing, so the GDB stub isn't broken
#ifdef GDB_STUB
#define READ32(a,b) cpu->mem_if->read32(a,b)
#define WRITE32(a,b,c) cpu->mem_if->write32(a,b,c)
#define READ16(a,b) cpu->mem_if->read16(a,b)
#define WRITE16(a,b,c) cpu->mem_if->write16(a,b,c)
#define READ8(a,b) cpu->mem_if->read8(a,b)
#define WRITE8(a,b,c) cpu->mem_if->write8(a,b,c)
#else
#define READ32(a,b) MMU_read32(cpu->state, cpu->proc_ID, b)
#define WRITE32(a,b,c) MMU_write32(cpu->state, cpu->proc_ID,b,c)
#define READ16(a,b) MMU_read16(cpu->state, cpu->proc_ID, b)
#define WRITE16(a,b,c) MMU_write16(cpu->state, cpu->proc_ID,b,c)
#define READ8(a,b) MMU_read8(cpu->state, cpu->proc_ID, b)
#define WRITE8(a,b,c) MMU_write8(cpu->state, cpu->proc_ID,b,c)
#endif
static u32 FASTCALL OP_UND_THUMB(armcpu_t *cpu)
{
cpu->state->execute = FALSE;
return 1;
}
static u32 FASTCALL OP_LSL_0(armcpu_t *cpu)
{
u32 i = cpu->instruction;
cpu->R[REG_NUM(i, 0)] = cpu->R[REG_NUM(i, 3)];
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 2;
}
static u32 FASTCALL OP_LSL(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 v = (i>>6) & 0x1F;
cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], 32-v);
cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] << v);
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 2;
}
static u32 FASTCALL OP_LSR_0(armcpu_t *cpu)
{
u32 i = cpu->instruction;
// cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]);
cpu->R[REG_NUM(i, 0)] = 0;
cpu->CPSR.bits.N = 0;
cpu->CPSR.bits.Z = 1;
return 2;
}
static u32 FASTCALL OP_LSR(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 v = (i>>6) & 0x1F;
cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] >> v);
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 2;
}
static u32 FASTCALL OP_ASR_0(armcpu_t *cpu)
{
u32 i = cpu->instruction;
cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]);
cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 3)])*0xFFFFFFFF;
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 2;
}
static u32 FASTCALL OP_ASR(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 v = (i>>6) & 0x1F;
cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], v-1);
cpu->R[REG_NUM(i, 0)] = (((s32)cpu->R[REG_NUM(i, 3)]) >> v);
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 2;
}
static u32 FASTCALL OP_ADD_REG(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 a = cpu->R[REG_NUM(i, 3)];
u32 b = cpu->R[REG_NUM(i, 6)];
cpu->R[REG_NUM(i, 0)] = a + b;
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.V = SIGNED_OVERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
return 3;
}
static u32 FASTCALL OP_SUB_REG(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 a = cpu->R[REG_NUM(i, 3)];
u32 b = cpu->R[REG_NUM(i, 6)];
cpu->R[REG_NUM(i, 0)] = a - b;
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
return 3;
}
static u32 FASTCALL OP_ADD_IMM3(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 a = cpu->R[REG_NUM(i, 3)];
cpu->R[REG_NUM(i, 0)] = a + REG_NUM(i, 6);
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.V = SIGNED_OVERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
return 2;
}
static u32 FASTCALL OP_SUB_IMM3(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 a = cpu->R[REG_NUM(i, 3)];
cpu->R[REG_NUM(i, 0)] = a - REG_NUM(i, 6);
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
return 2;
}
static u32 FASTCALL OP_MOV_IMM8(armcpu_t *cpu)
{
u32 i = cpu->instruction;
cpu->R[REG_NUM(i, 8)] = i & 0xFF;
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 8)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 8)] == 0;
return 2;
}
static u32 FASTCALL OP_CMP_IMM8(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF);
cpu->CPSR.bits.N = BIT31(tmp);
cpu->CPSR.bits.Z = tmp == 0;
cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
return 2;
}
static u32 FASTCALL OP_ADD_IMM8(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 tmp = cpu->R[REG_NUM(i, 8)] + (i & 0xFF);
cpu->CPSR.bits.N = BIT31(tmp);
cpu->CPSR.bits.Z = tmp == 0;
cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
cpu->R[REG_NUM(i, 8)] = tmp;
return 2;
}
static u32 FASTCALL OP_SUB_IMM8(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF);
cpu->CPSR.bits.N = BIT31(tmp);
cpu->CPSR.bits.Z = tmp == 0;
cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
cpu->R[REG_NUM(i, 8)] = tmp;
return 2;
}
static u32 FASTCALL OP_AND(armcpu_t *cpu)
{
u32 i = cpu->instruction;
cpu->R[REG_NUM(i, 0)] &= cpu->R[REG_NUM(i, 3)];
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
static u32 FASTCALL OP_EOR(armcpu_t *cpu)
{
u32 i = cpu->instruction;
cpu->R[REG_NUM(i, 0)] ^= cpu->R[REG_NUM(i, 3)];
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
static u32 FASTCALL OP_LSL_REG(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
if(!v)
{
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
if(v<32)
{
cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], 32-v);
cpu->R[REG_NUM(i, 0)] <<= v;
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
if(v==32)
cpu->CPSR.bits.C = BIT0(cpu->R[REG_NUM(i, 0)]);
else
cpu->CPSR.bits.C = 0;
cpu->R[REG_NUM(i, 0)] = 0;
cpu->CPSR.bits.N = 0;
cpu->CPSR.bits.Z = 1;
return 3;
}
static u32 FASTCALL OP_LSR_REG(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
if(!v)
{
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
if(v<32)
{
cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
cpu->R[REG_NUM(i, 0)] >>= v;
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
if(v==32)
cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
else
cpu->CPSR.bits.C = 0;
cpu->R[REG_NUM(i, 0)] = 0;
cpu->CPSR.bits.N = 0;
cpu->CPSR.bits.Z = 1;
return 3;
}
static u32 FASTCALL OP_ASR_REG(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
if(!v)
{
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
if(v<32)
{
cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
cpu->R[REG_NUM(i, 0)] = (u32)(((s32)cpu->R[REG_NUM(i, 0)]) >> v);
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 0)])*0xFFFFFFFF;
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
static u32 FASTCALL OP_ADC_REG(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 a = cpu->R[REG_NUM(i, 0)];
u32 b = cpu->R[REG_NUM(i, 3)];
u32 tmp = b + cpu->CPSR.bits.C;
u32 res = a + tmp;
cpu->R[REG_NUM(i, 0)] = res;
cpu->CPSR.bits.N = BIT31(res);
cpu->CPSR.bits.Z = res == 0;
cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(b, cpu->CPSR.bits.C, tmp) | UNSIGNED_OVERFLOW(tmp, a, res);
cpu->CPSR.bits.V = SIGNED_OVERFLOW(b, cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(tmp, a, res);
return 3;
}
static u32 FASTCALL OP_SBC_REG(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 a = cpu->R[REG_NUM(i, 0)];
u32 b = cpu->R[REG_NUM(i, 3)];
u32 tmp = a - (!cpu->CPSR.bits.C);
u32 res = tmp - b;
cpu->R[REG_NUM(i, 0)] = res;
cpu->CPSR.bits.N = BIT31(res);
cpu->CPSR.bits.Z = res == 0;
cpu->CPSR.bits.C = (!UNSIGNED_UNDERFLOW(a, !cpu->CPSR.bits.C, tmp)) & (!UNSIGNED_OVERFLOW(tmp, b, res));
cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, !cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(tmp, b, res);
return 3;
}
static u32 FASTCALL OP_ROR_REG(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
if(v == 0)
{
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
v &= 0xF;
if(v == 0)
{
cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
cpu->R[REG_NUM(i, 0)] = ROR(cpu->R[REG_NUM(i, 0)], v);
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
static u32 FASTCALL OP_TST(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 tmp = cpu->R[REG_NUM(i, 0)] & cpu->R[REG_NUM(i, 3)];
cpu->CPSR.bits.N = BIT31(tmp);
cpu->CPSR.bits.Z = tmp == 0;
return 3;
}
static u32 FASTCALL OP_NEG(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 a = cpu->R[REG_NUM(i, 3)];
cpu->R[REG_NUM(i, 0)] = -((signed int)a);
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(0, a, cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.V = SIGNED_UNDERFLOW(0, a, cpu->R[REG_NUM(i, 0)]);
return 3;
}
static u32 FASTCALL OP_CMP(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 tmp = cpu->R[REG_NUM(i, 0)] -cpu->R[REG_NUM(i, 3)];
cpu->CPSR.bits.N = BIT31(tmp);
cpu->CPSR.bits.Z = tmp == 0;
cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
return 3;
}
static u32 FASTCALL OP_CMN(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 tmp = cpu->R[REG_NUM(i, 0)] + cpu->R[REG_NUM(i, 3)];
//cpu->state->execute = FALSE;
//log::ajouter("OP_CMN THUMB");
cpu->CPSR.bits.N = BIT31(tmp);
cpu->CPSR.bits.Z = tmp == 0;
cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
return 3;
}
static u32 FASTCALL OP_ORR(armcpu_t *cpu)
{
u32 i = cpu->instruction;
cpu->R[REG_NUM(i, 0)] |= cpu->R[REG_NUM(i, 3)];
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
static u32 FASTCALL OP_MUL_REG(armcpu_t *cpu)
{
u32 i = cpu->instruction;
cpu->R[REG_NUM(i, 0)] *= cpu->R[REG_NUM(i, 3)];
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
static u32 FASTCALL OP_BIC(armcpu_t *cpu)
{
u32 i = cpu->instruction;
cpu->R[REG_NUM(i, 0)] &= (~cpu->R[REG_NUM(i, 3)]);
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
static u32 FASTCALL OP_MVN(armcpu_t *cpu)
{
u32 i = cpu->instruction;
cpu->R[REG_NUM(i, 0)] = (~cpu->R[REG_NUM(i, 3)]);
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
return 3;
}
static u32 FASTCALL OP_ADD_SPE(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 Rd = (i&7) | ((i>>4)&8);
cpu->R[Rd] += cpu->R[REG_POS(i, 3)];
if(Rd==15)
cpu->next_instruction = cpu->R[15];
return 2;
}
static u32 FASTCALL OP_CMP_SPE(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 Rn = (i&7) | ((i>>4)&8);
u32 tmp = cpu->R[Rn] -cpu->R[REG_POS(i, 3)];
cpu->CPSR.bits.N = BIT31(tmp);
cpu->CPSR.bits.Z = tmp == 0;
cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[Rn], cpu->R[REG_POS(i, 3)], tmp);
cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[Rn], cpu->R[REG_POS(i, 3)], tmp);
return 3;
}
static u32 FASTCALL OP_MOV_SPE(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 Rd = (i&7) | ((i>>4)&8);
cpu->R[Rd] = cpu->R[REG_POS(i, 3)];
if(Rd==15)
cpu->next_instruction = cpu->R[15];
return 2;
}
static u32 FASTCALL OP_BX_THUMB(armcpu_t *cpu)
{
u32 Rm = cpu->R[REG_POS(cpu->instruction, 3)];
cpu->CPSR.bits.T = BIT0(Rm);
cpu->R[15] = (Rm & 0xFFFFFFFE);
cpu->next_instruction = cpu->R[15];
return 3;
}
static u32 FASTCALL OP_BLX_THUMB(armcpu_t *cpu)
{
u32 Rm = cpu->R[REG_POS(cpu->instruction, 3)];
cpu->CPSR.bits.T = BIT0(Rm);
cpu->R[14] = cpu->next_instruction | 1;
cpu->R[15] = (Rm & 0xFFFFFFFE);
cpu->next_instruction = cpu->R[15];
return 3;
}
static u32 FASTCALL OP_LDR_PCREL(armcpu_t *cpu)
{
u32 adr = (cpu->R[15]&0xFFFFFFFC) + ((cpu->instruction&0xFF)<<2);
cpu->R[REG_NUM(cpu->instruction, 8)] = READ32(cpu->mem_if->data, adr);
return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_STR_REG_OFF(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[REG_NUM(i, 6)] + cpu->R[REG_NUM(i, 3)];
WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]);
return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_STRH_REG_OFF(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
WRITE16(cpu->mem_if->data, adr, ((u16)cpu->R[REG_NUM(i, 0)]));
return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_STRB_REG_OFF(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
WRITE8(cpu->mem_if->data, adr, ((u8)cpu->R[REG_NUM(i, 0)]));
return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_LDRSB_REG_OFF(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
cpu->R[REG_NUM(i, 0)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_LDR_REG_OFF(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = (cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]);
u32 tempValue = READ32(cpu->mem_if->data, adr&0xFFFFFFFC);
adr = (adr&3)*8;
tempValue = (tempValue>>adr) | (tempValue<<(32-adr));
cpu->R[REG_NUM(i, 0)] = tempValue;
return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_LDRH_REG_OFF(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
cpu->R[REG_NUM(i, 0)] = (u32)READ16(cpu->mem_if->data, adr);
return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_LDRB_REG_OFF(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
cpu->R[REG_NUM(i, 0)] = (u32)READ8(cpu->mem_if->data, adr);
return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_LDRSH_REG_OFF(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
cpu->R[REG_NUM(i, 0)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_STR_IMM_OFF(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C);
WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]);
return 2 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_LDR_IMM_OFF(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C);
u32 tempValue = READ32(cpu->mem_if->data, adr&0xFFFFFFFC);
adr = (adr&3)*8;
tempValue = (tempValue>>adr) | (tempValue<<(32-adr));
cpu->R[REG_NUM(i, 0)] = tempValue;
return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_STRB_IMM_OFF(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F);
WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_NUM(i, 0)]);
return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_LDRB_IMM_OFF(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F);
cpu->R[REG_NUM(i, 0)] = READ8(cpu->mem_if->data, adr);
return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_STRH_IMM_OFF(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E);
WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_NUM(i, 0)]);
return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_LDRH_IMM_OFF(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E);
cpu->R[REG_NUM(i, 0)] = READ16(cpu->mem_if->data, adr);
return 3 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_STR_SPREL(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[13] + ((i&0xFF)<<2);
WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 8)]);
return 2 + cpu->state->MMU->MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_LDR_SPREL(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[13] + ((i&0xFF)<<2);
cpu->R[REG_NUM(i, 8)] = READ32(cpu->mem_if->data, adr);
return 3 + cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
}
static u32 FASTCALL OP_ADD_2PC(armcpu_t *cpu)
{
u32 i = cpu->instruction;
cpu->R[REG_NUM(i, 8)] = (cpu->R[15]&0xFFFFFFFC) + ((i&0xFF)<<2);
return 5;
}
static u32 FASTCALL OP_ADD_2SP(armcpu_t *cpu)
{
u32 i = cpu->instruction;
cpu->R[REG_NUM(i, 8)] = cpu->R[13] + ((i&0xFF)<<2);
return 2;
}
static u32 FASTCALL OP_ADJUST_P_SP(armcpu_t *cpu)
{
cpu->R[13] += ((cpu->instruction&0x7F)<<2);
return 1;
}
static u32 FASTCALL OP_ADJUST_M_SP(armcpu_t *cpu)
{
cpu->R[13] -= ((cpu->instruction&0x7F)<<2);
return 1;
}
static u32 FASTCALL OP_PUSH(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[13] - 4;
u32 c = 0, j;
for(j = 0; j<8; ++j)
if(BIT_N(i, 7-j))
{
WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]);
c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
adr -= 4;
}
cpu->R[13] = adr + 4;
return c + 3;
}
static u32 FASTCALL OP_PUSH_LR(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[13] - 4;
u32 c = 0, j;
WRITE32(cpu->mem_if->data, adr, cpu->R[14]);
c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
adr -= 4;
for(j = 0; j<8; ++j)
if(BIT_N(i, 7-j))
{
WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]);
c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
adr -= 4;
}
cpu->R[13] = adr + 4;
return c + 4;
}
static u32 FASTCALL OP_POP(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[13];
u32 c = 0, j;
for(j = 0; j<8; ++j)
if(BIT_N(i, j))
{
cpu->R[j] = READ32(cpu->mem_if->data, adr);
c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
adr += 4;
}
cpu->R[13] = adr;
return c + 2;
}
static u32 FASTCALL OP_POP_PC(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[13];
u32 c = 0, j;
u32 v;
for(j = 0; j<8; ++j)
if(BIT_N(i, j))
{
cpu->R[j] = READ32(cpu->mem_if->data, adr);
c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
adr += 4;
}
v = READ32(cpu->mem_if->data, adr);
c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
cpu->R[15] = v & 0xFFFFFFFE;
cpu->next_instruction = v & 0xFFFFFFFE;
if(cpu->proc_ID==0)
cpu->CPSR.bits.T = BIT0(v);
adr += 4;
cpu->R[13] = adr;
return c + 5;
}
static u32 FASTCALL OP_BKPT_THUMB(armcpu_t *cpu)
{
return 1;
}
static u32 FASTCALL OP_STMIA_THUMB(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[REG_NUM(i, 8)];
u32 c = 0, j;
for(j = 0; j<8; ++j)
if(BIT_N(i, j))
{
WRITE32(cpu->mem_if->data, adr, cpu->R[j]);
c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
adr += 4;
}
cpu->R[REG_NUM(i, 8)] = adr;
return c + 2;
}
static u32 FASTCALL OP_LDMIA_THUMB(armcpu_t *cpu)
{
u32 i = cpu->instruction;
u32 adr = cpu->R[REG_NUM(i, 8)];
u32 c = 0, j;
for(j = 0; j<8; ++j)
if(BIT_N(i, j))
{
cpu->R[j] = READ32(cpu->mem_if->data, adr);
c += cpu->state->MMU->MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
adr += 4;
}
cpu->R[REG_NUM(i, 8)] = adr;
return c + 3;
}
static u32 FASTCALL OP_B_COND(armcpu_t *cpu)
{
u32 i = cpu->instruction;
if(!TEST_COND((i>>8)&0xF, 0, cpu->CPSR))
return 1;
cpu->R[15] += ((s32)((s8)(i&0xFF)))<<1;
cpu->next_instruction = cpu->R[15];
return 3;
}
static u32 FASTCALL OP_SWI_THUMB(armcpu_t *cpu)
{
if (((cpu->intVector != 0) ^ (cpu->proc_ID == ARMCPU_ARM9)))
{
/* we use an irq thats not in the irq tab, as
it was replaced duie to a changed intVector */
Status_Reg tmp = cpu->CPSR;
armcpu_switchMode(cpu, SVC); /* enter svc mode */
cpu->R[14] = cpu->R[15] - 4; /* jump to swi Vector */
cpu->SPSR = tmp; /* save old CPSR as new SPSR */
cpu->CPSR.bits.T = 0; /* handle as ARM32 code */
cpu->CPSR.bits.I = cpu->SPSR.bits.I; /* keep int disable flag */
cpu->R[15] = cpu->intVector + 0x08;
cpu->next_instruction = cpu->R[15];
return 3;
}
else
{
u32 swinum = cpu->instruction & 0xFF;
return cpu->swi_tab[swinum](cpu) + 3;
}
//return 3;
}
#define SIGNEEXT_IMM11(i) (((i)&0x7FF) | (BIT10(i) * 0xFFFFF800))
static u32 FASTCALL OP_B_UNCOND(armcpu_t *cpu)
{
u32 i = cpu->instruction;
cpu->R[15] += (SIGNEEXT_IMM11(i)<<1);
cpu->next_instruction = cpu->R[15];
return 3;
}
static u32 FASTCALL OP_BLX(armcpu_t *cpu)
{
u32 i = cpu->instruction;
cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1))&0xFFFFFFFC;
cpu->R[14] = cpu->next_instruction | 1;
cpu->next_instruction = cpu->R[15];
cpu->CPSR.bits.T = 0;
return 3;
}
static u32 FASTCALL OP_BL_10(armcpu_t *cpu)
{
u32 i = cpu->instruction;
cpu->R[14] = cpu->R[15] + (SIGNEEXT_IMM11(i)<<12);
return 1;
}
static u32 FASTCALL OP_BL_THUMB(armcpu_t *cpu)
{
u32 i = cpu->instruction;
cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1));
cpu->R[14] = cpu->next_instruction | 1;
cpu->next_instruction = cpu->R[15];
return 3;
}
#define TYPE_RETOUR u32
#define CALLTYPE FASTCALL
#define PARAMETRES armcpu_t *cpu
#define NOM_THUMB_TAB thumb_instructions_set
#include "thumb_tabdef.inc"

View File

@ -0,0 +1,30 @@
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef THUMB_INSTRUCTIONS_H
#define THUMB_INSTRUCTIONS_H
#include "armcpu.h"
extern u32 (FASTCALL* thumb_instructions_set[1024])(armcpu_t * cpu);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,151 @@
/* Copyright (C) 2005 Guillaume Duhamel
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TYPES_HPP
#define TYPES_HPP
#ifndef FASTCALL
#ifdef __MINGW32__
#define FASTCALL __attribute__((fastcall))
#elif defined (__i386__)
#define FASTCALL __attribute__((regparm(3)))
#else
#define FASTCALL
#endif
#endif
#ifndef INLINE
#ifdef _MSC_VER
#define INLINE _inline
#else
#define INLINE inline
#endif
#endif
#ifdef DESMUME_COCOA
#ifdef __BIG_ENDIAN__
#define WORDS_BIGENDIAN
#endif
#endif
#include <stdint.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef uintptr_t pointer;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef u8 uint8;
typedef u16 uint16;
#ifndef OBJ_C
typedef u32 uint32;
#else
#define uint32 u32 //uint32 is defined in Leopard somewhere, avoid conflicts
#endif
/*---------- GPU3D fixed-points types -----------*/
typedef s32 f32;
#define inttof32(n) ((n) << 12)
#define f32toint(n) ((n) >> 12)
#define floattof32(n) ((int32)((n) * (1 << 12)))
#define f32tofloat(n) (((float)(n)) / (float)(1<<12))
typedef s16 t16;
#define f32tot16(n) ((t16)(n >> 8))
#define inttot16(n) ((n) << 4)
#define t16toint(n) ((n) >> 4)
#define floattot16(n) ((t16)((n) * (1 << 4)))
#define t16ofloat(n) (((float)(n)) / (float)(1<<4))
typedef s16 v16;
#define inttov16(n) ((n) << 12)
#define f32tov16(n) (n)
#define floattov16(n) ((v16)((n) * (1 << 12)))
#define v16toint(n) ((n) >> 12)
#define v16tofloat(n) (((float)(n)) / (float)(1<<12))
typedef s16 v10;
#define inttov10(n) ((n) << 9)
#define f32tov10(n) ((v10)(n >> 3))
#define v10toint(n) ((n) >> 9)
#define floattov10(n) ((v10)((n) * (1 << 9)))
#define v10tofloat(n) (((float)(n)) / (float)(1<<9))
/*----------------------*/
#ifndef OBJ_C
typedef signed char BOOL;
#else
//apple also defines BOOL
typedef int desmume_BOOL;
#define BOOL desmume_BOOL
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifdef __GNUC__
#define PACKED __attribute__((packed))
#endif
#ifdef WORDS_BIGENDIAN
# define LOCAL_BE
#else
# define LOCAL_LE
#endif
/* little endian (ds' endianess) to local endianess convert macros */
#ifdef LOCAL_BE /* local arch is big endian */
# define LE_TO_LOCAL_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff))
# define LE_TO_LOCAL_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff))
# define LOCAL_TO_LE_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff))
# define LOCAL_TO_LE_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff))
#else /* local arch is little endian */
# define LE_TO_LOCAL_16(x) (x)
# define LE_TO_LOCAL_32(x) (x)
# define LOCAL_TO_LE_16(x) (x)
# define LOCAL_TO_LE_32(x) (x)
#endif
/* kilobytes and megabytes macro */
#define MB(x) ((x)*1024*1024)
#define KB(x) ((x)*1024)
#define CPU_STR(c) ((c==ARM9)?"ARM9":"ARM7")
typedef enum
{
ARM9 = 0,
ARM7 = 1
} cpu_id_t;
#define __PACKED __attribute__((__packed__))
#endif

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.vio2sf</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 © 2013 Christopher Snowhill. All rights reserved.</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@ -22,6 +22,21 @@
<key>CFBundleTypeRole</key>
<string>None</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>2sf</string>
<string>mini2sf</string>
</array>
<key>LSTypeIsPackage</key>
<false/>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>CFBundleTypeIconFile</key>
<string>vg.icns</string>
<key>CFBundleTypeName</key>
<string>Nintendo DS Audio File</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>

View File

@ -21,6 +21,9 @@
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 */; };
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 */; };
83F18C3917F9301400471B6C /* HighlyExperimental.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8360EF4417F92C92005208A4 /* HighlyExperimental.framework */; };
/* End PBXBuildFile section */
@ -109,6 +112,20 @@
remoteGlobalIDString = 83848FB71807623F00E7332D;
remoteInfo = SSEQPlayer;
};
83DE0C39180A9BD500269051 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 83DE0C34180A9BD400269051 /* vio2sf.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 83DE0C06180A9BD400269051;
remoteInfo = vio2sf;
};
83DE0CBA180B02C500269051 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 83DE0C34180A9BD400269051 /* vio2sf.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 83DE0C05180A9BD400269051;
remoteInfo = vio2sf;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
@ -118,6 +135,7 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
83DE0CBD180B02D800269051 /* vio2sf.framework in CopyFiles */,
8384904B180764C200E7332D /* SSEQPlayer.framework in CopyFiles */,
834379A617F97EB000584396 /* HighlyAdvanced.framework in CopyFiles */,
8343792A17F96F2600584396 /* HighlyQuixotic.framework in CopyFiles */,
@ -148,6 +166,8 @@
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>"; };
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; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -155,6 +175,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
83DE0CC0180B27C200269051 /* libz.dylib in Frameworks */,
83DE0CBC180B02CC00269051 /* vio2sf.framework in Frameworks */,
8384904A180764B500E7332D /* SSEQPlayer.framework in Frameworks */,
834379A517F97EA100584396 /* HighlyAdvanced.framework in Frameworks */,
8343792917F96F1D00584396 /* HighlyQuixotic.framework in Frameworks */,
@ -220,6 +242,7 @@
8360EEE617F92AC8005208A4 /* Frameworks */ = {
isa = PBXGroup;
children = (
83DE0CBF180B27C200269051 /* libz.dylib */,
8360EEE717F92AC8005208A4 /* Cocoa.framework */,
8360EEE917F92AC8005208A4 /* Other Frameworks */,
8360EF3E17F92C91005208A4 /* HighlyExperimental.xcodeproj */,
@ -228,6 +251,7 @@
8343790C17F96E2600584396 /* HighlyQuixotic.xcodeproj */,
8343796317F97BDB00584396 /* HighlyAdvanced.xcodeproj */,
83848FE61807623F00E7332D /* SSEQPlayer.xcodeproj */,
83DE0C34180A9BD400269051 /* vio2sf.xcodeproj */,
);
name = Frameworks;
sourceTree = "<group>";
@ -280,6 +304,14 @@
name = Products;
sourceTree = "<group>";
};
83DE0C35180A9BD400269051 /* Products */ = {
isa = PBXGroup;
children = (
83DE0C3A180A9BD500269051 /* vio2sf.framework */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -295,6 +327,7 @@
buildRules = (
);
dependencies = (
83DE0CBB180B02C500269051 /* PBXTargetDependency */,
83849049180764AC00E7332D /* PBXTargetDependency */,
834379A417F97E9C00584396 /* PBXTargetDependency */,
8343792817F96F1900584396 /* PBXTargetDependency */,
@ -351,6 +384,10 @@
ProductGroup = 83848FE71807623F00E7332D /* Products */;
ProjectRef = 83848FE61807623F00E7332D /* SSEQPlayer.xcodeproj */;
},
{
ProductGroup = 83DE0C35180A9BD400269051 /* Products */;
ProjectRef = 83DE0C34180A9BD400269051 /* vio2sf.xcodeproj */;
},
);
projectRoot = "";
targets = (
@ -402,6 +439,13 @@
remoteRef = 83848FEB1807624000E7332D /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
83DE0C3A180A9BD500269051 /* vio2sf.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = vio2sf.framework;
remoteRef = 83DE0C39180A9BD500269051 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
@ -457,6 +501,11 @@
name = SSEQPlayer;
targetProxy = 83849048180764AC00E7332D /* PBXContainerItemProxy */;
};
83DE0CBB180B02C500269051 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = vio2sf;
targetProxy = 83DE0CBA180B02C500269051 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */

View File

@ -28,6 +28,10 @@
#import <SSEQPlayer/SDAT.h>
#import <SSEQPlayer/Player.h>
#import <vio2sf/state.h>
#include <zlib.h>
@interface psf_file_container : NSObject {
NSLock * lock;
NSMutableDictionary * list;
@ -267,16 +271,6 @@ static int psf_info_meta(void * context, const char * name, const char * value)
{
state->utf8 = true;
}
else if ([taglc hasPrefix:@"_lib"])
{
}
else if ([taglc isEqualToString:@"_refresh"])
{
}
else if ([taglc hasPrefix:@"_"])
{
return -1;
}
else if ([taglc isEqualToString:@"title"] ||
[taglc isEqualToString:@"artist"] ||
[taglc isEqualToString:@"album"] ||
@ -473,7 +467,7 @@ struct qsf_loader_state
uint32_t sample_size;
};
static int upload_section( struct qsf_loader_state * state, const char * section, uint32_t start,
static int upload_gsf_section( struct qsf_loader_state * state, const char * section, uint32_t start,
const uint8_t * data, uint32_t size )
{
uint8_t ** array = NULL;
@ -517,7 +511,7 @@ static int qsf_loader(void * context, const uint8_t * exe, size_t exe_size,
if ( datasize > exe_size )
return -1;
if ( upload_section( state, s, dataofs, exe, datasize ) < 0 )
if ( upload_gsf_section( state, s, dataofs, exe, datasize ) < 0 )
return -1;
exe += datasize;
@ -535,7 +529,7 @@ struct gsf_loader_state
size_t data_size;
};
int gsf_loader(void * context, const uint8_t * exe, size_t exe_size,
static int gsf_loader(void * context, const uint8_t * exe, size_t exe_size,
const uint8_t * reserved, size_t reserved_size)
{
if ( exe_size < 12 ) return -1;
@ -637,7 +631,7 @@ struct ncsf_loader_state
ncsf_loader_state() : sseq( 0 ) { }
};
int ncsf_loader(void * context, const uint8_t * exe, size_t exe_size,
static int ncsf_loader(void * context, const uint8_t * exe, size_t exe_size,
const uint8_t * reserved, size_t reserved_size)
{
struct ncsf_loader_state * state = ( struct ncsf_loader_state * ) context;
@ -662,6 +656,227 @@ int ncsf_loader(void * context, const uint8_t * exe, size_t exe_size,
return 0;
}
struct twosf_loader_state
{
uint8_t * rom;
uint8_t * state;
size_t rom_size;
size_t state_size;
int initial_frames;
int sync_type;
int clockdown;
int arm9_clockdown_level;
int arm7_clockdown_level;
};
static int load_twosf_map(struct twosf_loader_state *state, int issave, const unsigned char *udata, unsigned usize)
{
if (usize < 8) return -1;
unsigned char *iptr;
size_t isize;
unsigned char *xptr;
unsigned xsize = get_le32(udata + 4);
unsigned xofs = get_le32(udata + 0);
if (issave)
{
iptr = state->state;
isize = state->state_size;
state->state = 0;
state->state_size = 0;
}
else
{
iptr = state->rom;
isize = state->rom_size;
state->rom = 0;
state->rom_size = 0;
}
if (!iptr)
{
size_t rsize = xofs + xsize;
if (!issave)
{
rsize -= 1;
rsize |= rsize >> 1;
rsize |= rsize >> 2;
rsize |= rsize >> 4;
rsize |= rsize >> 8;
rsize |= rsize >> 16;
rsize += 1;
}
iptr = (unsigned char *) malloc(rsize + 10);
if (!iptr)
return -1;
memset(iptr, 0, rsize + 10);
isize = rsize;
}
else if (isize < xofs + xsize)
{
size_t rsize = xofs + xsize;
if (!issave)
{
rsize -= 1;
rsize |= rsize >> 1;
rsize |= rsize >> 2;
rsize |= rsize >> 4;
rsize |= rsize >> 8;
rsize |= rsize >> 16;
rsize += 1;
}
xptr = (unsigned char *) realloc(iptr, xofs + rsize + 10);
if (!xptr)
{
free(iptr);
return -1;
}
iptr = xptr;
isize = rsize;
}
memcpy(iptr + xofs, udata + 8, xsize);
if (issave)
{
state->state = iptr;
state->state_size = isize;
}
else
{
state->rom = iptr;
state->rom_size = isize;
}
return 0;
}
static int load_twosf_mapz(struct twosf_loader_state *state, int issave, const unsigned char *zdata, unsigned zsize, unsigned zcrc)
{
int ret;
int zerr;
uLongf usize = 8;
uLongf rsize = usize;
unsigned char *udata;
unsigned char *rdata;
udata = (unsigned char *) malloc(usize);
if (!udata)
return -1;
while (Z_OK != (zerr = uncompress(udata, &usize, zdata, zsize)))
{
if (Z_MEM_ERROR != zerr && Z_BUF_ERROR != zerr)
{
free(udata);
return -1;
}
if (usize >= 8)
{
usize = get_le32(udata + 4) + 8;
if (usize < rsize)
{
rsize += rsize;
usize = rsize;
}
else
rsize = usize;
}
else
{
rsize += rsize;
usize = rsize;
}
rdata = (unsigned char *) realloc(udata, usize);
if (!rdata)
{
free(udata);
return -1;
}
udata = rdata;
}
rdata = (unsigned char *) realloc(udata, usize);
if (!rdata)
{
free(udata);
return -1;
}
if (0)
{
uLong ccrc = crc32(crc32(0L, Z_NULL, 0), rdata, (uInt) usize);
if (ccrc != zcrc)
return -1;
}
ret = load_twosf_map(state, issave, rdata, (unsigned) usize);
free(rdata);
return ret;
}
static int twosf_loader(void * context, const uint8_t * exe, size_t exe_size,
const uint8_t * reserved, size_t reserved_size)
{
struct twosf_loader_state * state = ( struct twosf_loader_state * ) context;
if ( exe_size >= 8 )
{
if ( load_twosf_map(state, 0, exe, (unsigned) exe_size) )
return -1;
}
if ( reserved_size )
{
size_t resv_pos = 0;
if ( reserved_size < 16 )
return -1;
while ( resv_pos + 12 < reserved_size )
{
unsigned save_size = get_le32(reserved + resv_pos + 4);
unsigned save_crc = get_le32(reserved + resv_pos + 8);
if (get_le32(reserved + resv_pos + 0) == 0x45564153)
{
if (resv_pos + 12 + save_size > reserved_size)
return -1;
if (load_twosf_mapz(state, 1, reserved + resv_pos + 12, save_size, save_crc))
return -1;
}
resv_pos += 12 + save_size;
}
}
return 0;
}
static int twosf_info(void * context, const char * name, const char * value)
{
struct twosf_loader_state * state = ( struct twosf_loader_state * ) context;
NSString * sname = [[NSString stringWithUTF8String:name] lowercaseString];
NSString * svalue = [NSString stringWithUTF8String:value];
if ( [sname isEqualToString:@"_frames"] )
{
state->initial_frames = [svalue intValue];
}
else if ( [sname isEqualToString:@"_clockdown"] )
{
state->clockdown = [svalue intValue];
}
else if ( [sname isEqualToString:@"_vio2sf_sync_type"] )
{
state->sync_type = [svalue intValue];
}
else if ( [sname isEqualToString:@"_vio2sf_arm9_clockdown_level"] )
{
state->arm9_clockdown_level = [svalue intValue];
}
else if ( [sname isEqualToString:@"_vio2sf_arm7_clockdown_level"] )
{
state->arm7_clockdown_level = [svalue intValue];
}
return 0;
}
- (BOOL)initializeDecoder
{
if ( type == 1 )
@ -760,6 +975,45 @@ int ncsf_loader(void * context, const uint8_t * exe, size_t exe_size,
CPUInit( system );
CPUReset( system );
}
else if ( type == 0x24 )
{
struct twosf_loader_state state;
memset( &state, 0, sizeof(state) );
state.initial_frames = -1;
if ( psf_load( [currentUrl UTF8String], &source_callbacks, 0x24, twosf_loader, &state, twosf_info, &state) <= 0 )
{
if (state.rom) free(state.rom);
if (state.state) free(state.state);
return NO;
}
if ( state.rom_size > UINT_MAX || state.state_size > UINT_MAX )
{
if (state.rom) free(state.rom);
if (state.state) free(state.state);
return NO;
}
NDS_state * core = ( NDS_state * ) calloc(1, sizeof(NDS_state));
if (!core)
{
if (state.rom) free(state.rom);
if (state.state) free(state.state);
return NO;
}
emulatorCore = ( uint8_t * ) core;
emulatorExtra = state.rom;
if ( state_init(core) )
return NO;
if ( state.rom )
state_setrom(core, state.rom, (u32) state.rom_size );
state_loadstate(core, state.state, (u32) state.state_size);
}
else if ( type == 0x25 )
{
struct ncsf_loader_state * state = new struct ncsf_loader_state;
@ -928,6 +1182,11 @@ int ncsf_loader(void * context, const uint8_t * exe, size_t exe_size,
}
sound_out->samples_written = frames_rendered;
}
else if ( type == 0x24 )
{
NDS_state * state = ( NDS_state * ) emulatorCore;
state_render(state, (s16*) buf, frames);
}
else if ( type == 0x25 )
{
size_t buffer_size = frames * sizeof(int16_t) * 2;
@ -944,8 +1203,8 @@ int ncsf_loader(void * context, const uint8_t * exe, size_t exe_size,
frames = howmany;
}
if ( framesRead >= framesLength ) {
long fadeStart = framesRead;
if ( framesRead + frames > framesLength ) {
long fadeStart = (framesLength > framesRead) ? framesLength : framesRead;
long fadeEnd = framesRead + frames;
long fadeTotal = totalFrames - framesLength;
long fadePos;
@ -976,7 +1235,11 @@ int ncsf_loader(void * context, const uint8_t * exe, size_t exe_size,
CPUCleanUp( system );
soundShutdown( system );
delete system;
} else if ( type == 0x25 ) {
} else if ( type == 0x24 ) {
NDS_state * state = ( NDS_state * ) emulatorCore;
state_deinit(state);
free(state);
}else if ( type == 0x25 ) {
Player * player = ( Player * ) emulatorCore;
delete player;
} else {
@ -991,6 +1254,9 @@ int ncsf_loader(void * context, const uint8_t * exe, size_t exe_size,
} else if ( type == 0x22 && emulatorExtra ) {
delete ( gsf_sound_out * ) emulatorExtra;
emulatorExtra = nil;
} else if ( type == 0x24 && emulatorExtra ) {
free( emulatorExtra );
emulatorExtra = nil;
} else if ( type == 0x25 && emulatorExtra ) {
struct ncsf_loader_state * state = ( struct ncsf_loader_state * ) emulatorExtra;
delete state;
@ -1058,6 +1324,24 @@ int ncsf_loader(void * context, const uint8_t * exe, size_t exe_size,
CPULoop( system, 250000 );
} while ( frames_to_run );
}
else if ( type == 0x24 )
{
NDS_state * state = ( NDS_state * ) emulatorCore;
s16 temp[2048];
long frames_to_run = frame - framesRead;
while ( frames_to_run )
{
unsigned frames_this_run = 1024;
if ( frames_this_run > frames_to_run )
frames_this_run = (unsigned) frames_to_run;
state_render(state, temp, frames_this_run);
frames_to_run -= frames_this_run;
}
}
else if ( type == 0x25 )
{
std::vector<uint8_t> buffer;
@ -1126,7 +1410,7 @@ int ncsf_loader(void * context, const uint8_t * exe, size_t exe_size,
+ (NSArray *)fileTypes
{
return [NSArray arrayWithObjects:@"psf",@"minipsf",@"psf2", @"minipsf2", @"ssf", @"minissf", @"dsf", @"minidsf", @"qsf", @"miniqsf", @"gsf", @"minigsf", @"ncsf", @"minincsf", nil];
return [NSArray arrayWithObjects:@"psf",@"minipsf",@"psf2", @"minipsf2", @"ssf", @"minissf", @"dsf", @"minidsf", @"qsf", @"miniqsf", @"gsf", @"minigsf", @"ncsf", @"minincsf", @"2sf", @"mini2sf", nil];
}
+ (NSArray *)mimeTypes